#
zhou zhou
17 小时以前 f9cfb2169361c046a00f4fa14ea342bd5710f8b4
pages/outbound/orderOut/orderDetlList.vue
@@ -1,91 +1,130 @@
<template>
   <view class="page-container">
      <!-- 订单信息头部 -->
      <view class="order-header" v-if="order">
      <view
         class="order-header"
         v-if="order"
      >
         <view class="header-content">
            <view class="header-row">
               <text class="header-label">单据号</text>
               <text class="header-value">{{order.code}}</text>
               <text class="header-value">{{ order.code }}</text>
            </view>
            <view class="header-row">
               <text class="header-label">单据类型</text>
               <text class="header-value">{{order.wkType$ || '-'}}</text>
               <text class="header-value">{{ order.wkType$ || '-' }}</text>
            </view>
         </view>
      </view>
      <!-- 搜索框 -->
      <!-- <view class="search-bar">
         <uni-search-bar v-model="condition" placeholder=" 扫码 / 输入物料" bgColor="#F5F5F5" @confirm="search" @cancel="onCancelSearch" />
      </view> -->
      <!-- 明细列表 -->
      <view class="padding-lr margin-top-sm">
         <block v-for="(item, index) in filterList" :key="index">
            <view class="cu-list menu sm-border margin-bottom-sm" @click="chose(item)">
         <block
            v-for="(item, index) in filterList"
            :key="index"
         >
            <view
               class="cu-list menu sm-border margin-bottom-sm"
               @click="chose(item)"
            >
               <view class="cu-bar bg-white solid-bottom">
                  <view class="action">
                     <view class="index">{{index+1}}</view>
                     <view class="index">{{ index + 1 }}</view>
                     <view class="text-blue">
                        编码: {{item.matnrCode}}
                        编码: {{ item.matnrCode }}
                     </view>
                  </view>
                  <view class="action">
                     <text :class="getRemaining(item) > 0 ? 'text-blue' : 'text-green'">
                        {{getRemaining(item) > 0 ? '剩余 ' + getRemaining(item) : '已完成'}}
                     <text
                        :class="
                           getRemaining(item) > 0
                              ? 'text-blue'
                              : 'text-green'
                        "
                     >
                        {{
                           getRemaining(item) > 0
                              ? '剩余 ' + getRemaining(item)
                              : '已完成'
                        }}
                     </text>
                  </view>
               </view>
               <view class="cu-item">
                  <view class="content">
                     <text class="text-black">物料名称:</text>
                     <text class="text-grey text-sm margin-left-xs">{{item.maktx || '-'}}</text>
                     <text class="text-grey text-sm margin-left-xs">
                        {{ item.maktx || '-' }}
                     </text>
                  </view>
               </view>
               <view class="cu-item">
                  <view class="content">
                     <text class="text-black">规格:</text>
                     <text class="text-grey margin-left-xs">{{item.specs || '-'}}</text>
                     <text class="text-grey margin-left-xs">
                        {{ item.specs || '-' }}
                     </text>
                  </view>
                  <view class="action">
                     <text class="text-black">批次:</text>
                     <text class="text-grey margin-left-xs">{{item.splrBatch || '-'}}</text>
                     <text class="text-grey margin-left-xs">
                        {{ item.splrBatch || '-' }}
                     </text>
                  </view>
               </view>
               <view class="cu-item">
                  <view class="content">
                     <text class="text-black">订单数量:</text>
                     <text class="text-blue margin-left-xs">{{item.anfme}}</text>
                     <text class="text-blue margin-left-xs">
                        {{ item.anfme }}
                     </text>
                  </view>
                  <view class="action">
                     <text class="text-black">已完成:</text>
                     <text class="text-green margin-left-xs">{{item.qty}}</text>
                     <text class="text-green margin-left-xs">
                        {{ item.qty }}
                     </text>
                  </view>
               </view>
            </view>
         </block>
      </view>
      <!-- 空状态 -->
      <view class="empty-state" v-if="filterList.length === 0 && !loading">
         <uni-icons type="info" size="60" color="#CCCCCC"></uni-icons>
      <view
         class="empty-state"
         v-if="filterList.length === 0 && !loading"
      >
         <uni-icons
            type="info"
            size="60"
            color="#CCCCCC"
         ></uni-icons>
         <text class="empty-text">暂无明细数据</text>
      </view>
      <!-- 统计信息 -->
      <view class="stats-bar" v-if="menuList.length > 0">
      <view
         class="stats-bar"
         v-if="menuList.length > 0"
      >
         <view class="stats-item">
            <text class="stats-value">{{menuList.length}}</text>
            <text class="stats-value">{{ menuList.length }}</text>
            <text class="stats-label">总明细</text>
         </view>
         <view class="stats-divider"></view>
         <view class="stats-item">
            <text class="stats-value">{{pendingCount}}</text>
            <text class="stats-value">{{ pendingCount }}</text>
            <text class="stats-label">待处理</text>
         </view>
         <view class="stats-divider"></view>
         <view class="stats-item">
            <text class="stats-value">{{completedCount}}</text>
            <text class="stats-value">{{ completedCount }}</text>
            <text class="stats-label">已完成</text>
         </view>
      </view>
@@ -93,275 +132,309 @@
</template>
<script>
   import { request } from '@/common/request.js'
   export default {
      data() {
         return {
            data: '',
            condition: '',
            menuList: [],
            order: '',
            loading: false,
import { request } from '@/common/request.js'
export default {
   data() {
      return {
         data: '',
         condition: '',
         menuList: [],
         order: '',
         loading: false
      }
   },
   computed: {
      // 过滤后的列表(优先显示有剩余数量的)
      filterList() {
         if (!this.condition.trim()) {
            // 排序:有剩余数量的排前面
            return [...this.menuList].sort((a, b) => {
               if (a.ableQty > 0 && b.ableQty <= 0) return -1
               if (a.ableQty <= 0 && b.ableQty > 0) return 1
               return 0
            })
         }
         const keyword = this.condition.toLowerCase()
         return this.menuList.filter((item) => {
            return (
               (item.matnr &&
                  item.matnr.toLowerCase().includes(keyword)) ||
               (item.maktx &&
                  item.maktx.toLowerCase().includes(keyword)) ||
               (item.batch && item.batch.toLowerCase().includes(keyword))
            )
         })
      },
      computed: {
         // 过滤后的列表(优先显示有剩余数量的)
         filterList() {
            if (!this.condition.trim()) {
               // 排序:有剩余数量的排前面
               return [...this.menuList].sort((a, b) => {
                  if (a.ableQty > 0 && b.ableQty <= 0) return -1;
                  if (a.ableQty <= 0 && b.ableQty > 0) return 1;
                  return 0;
               });
            }
            const keyword = this.condition.toLowerCase();
            return this.menuList.filter(item => {
               return (item.matnr && item.matnr.toLowerCase().includes(keyword)) ||
                     (item.maktx && item.maktx.toLowerCase().includes(keyword)) ||
                     (item.batch && item.batch.toLowerCase().includes(keyword));
            });
         },
         // 待处理数量
         pendingCount() {
            return this.menuList.filter(item => item.enableQty > 0).length;
         },
         // 已完成数量
         completedCount() {
            return this.menuList.filter(item => item.enableQty <= 0).length;
      // 待处理数量
      pendingCount() {
         return this.menuList.filter((item) => item.enableQty > 0).length
      },
      // 已完成数量
      completedCount() {
         return this.menuList.filter((item) => item.enableQty <= 0).length
      }
   },
   onLoad() {
      let that = this
      const eventChannel = this.getOpenerEventChannel()
      if (eventChannel) {
         eventChannel.on('data', function (data) {
            that.order = data.data
            that.getOrderNoList(that.order)
         })
      }
   },
   onShow() {
      if (this.order) {
         this.getOrderNoList(this.order)
      }
   },
   methods: {
      // 获取剩余数量
      getRemaining(item) {
         if (item.ableQty !== undefined && item.ableQty !== null) {
            return Number(item.ableQty)
         }
         // 降级逻辑:订单数量 - 已完成数量
         return Number(item.anfme || 0) - Number(item.qty || 0)
      },
      onLoad() {
         let that = this;
         const eventChannel = this.getOpenerEventChannel();
         if (eventChannel) {
            eventChannel.on('data', function(data) {
               that.order = data.data;
               that.getOrderNoList(that.order);
            });
      // 搜索
      async search() {
         if (!this.condition.trim()) {
            this.getOrderNoList(this.order)
            return
         }
      },
      onShow() {
         if (this.order) {
            this.getOrderNoList(this.order);
         }
      },
      methods: {
         // 获取剩余数量
         getRemaining(item) {
            if (item.ableQty !== undefined && item.ableQty !== null) {
               return Number(item.ableQty);
            }
            // 降级逻辑:订单数量 - 已完成数量
            return Number(item.anfme || 0) - Number(item.qty || 0);
         },
         // 搜索
         async search() {
            if (!this.condition.trim()) {
               this.getOrderNoList(this.order);
               return;
            }
            this.loading = true;
            try {
               const res = await request('/orderDetl/search/pda/auth', {
         this.loading = true
         try {
            const res = await request(
               '/orderDetl/search/pda/auth',
               {
                  condition: this.condition,
                  order: this.order.code
               }, 'POST', true);
               if (res.code === 200) {
                  let list = res.data || [];
                  list.forEach(item => {
                     if (item.enableQty === undefined || item.enableQty === null) {
                        item.enableQty = Number(item.anfme || 0) - Number(item.qty || 0);
                     }
                  });
                  this.menuList = list;
               } else if (res.code === 403) {
                  uni.showToast({ title: res.msg, icon: "none", position: 'top' });
                  setTimeout(() => {
                     uni.reLaunch({ url: '../login/login' });
                  }, 1000);
               } else {
                  uni.showToast({ title: res.msg, icon: "none", position: 'top' });
               }
            } catch (err) {
               // request.js 已经处理了错误提示
            } finally {
               this.loading = false;
            }
         },
         // 取消搜索
         onCancelSearch() {
            this.condition = '';
            this.getOrderNoList(this.order);
         },
         // 获取订单明细列表
         async getOrderNoList(order) {
            if (!order || !order.code) return;
            this.loading = true;
            try {
               const res = await request('/orderOut/detlList', {
                  orderNo: order.code
               }, 'GET', true);
               if (res.code === 200) {
                  let list = res.data || [];
                  list.forEach(item => {
                     if (item.enableQty === undefined || item.enableQty === null) {
                        item.enableQty = Number(item.anfme || 0) - Number(item.qty || 0);
                     }
                  });
                  this.menuList = list;
               } else {
                  this.menuList = res.data || [];
               }
            } catch (err) {
               // request.js 已经处理了错误提示
            } finally {
               this.loading = false;
            }
         },
         // 选择明细进行出库
         chose(item) {
            if (item.enableQty <= 0) {
               uni.showToast({ title: '该明细已完成', icon: "none", position: 'top' });
               return;
            }
            let that = this;
            uni.navigateTo({
               url: "./outLocView",
               success: function(res) {
                  res.eventChannel.emit('orderItem', {
                     item: item
                  });
               },
               events: {
                  acceptDataFromOpenedPage: function(data) {
                     // 返回后刷新数据
                  },
               },
            });
               'POST',
               true
            )
            if (res.code === 200) {
               let list = res.data || []
               list.forEach((item) => {
                  if (
                     item.ableQty === undefined ||
                     item.ableQty === null
                  ) {
                     item.ableQty =
                        Number(item.anfme || 0) - Number(item.qty || 0)
                  }
               })
               this.menuList = list
            } else if (res.code === 403) {
               uni.showToast({
                  title: res.msg,
                  icon: 'none',
                  position: 'top'
               })
               setTimeout(() => {
                  uni.reLaunch({ url: '../login/login' })
               }, 1000)
            } else {
               uni.showToast({
                  title: res.msg,
                  icon: 'none',
                  position: 'top'
               })
            }
         } catch (err) {
            // request.js 已经处理了错误提示
         } finally {
            this.loading = false
         }
      },
      // 取消搜索
      onCancelSearch() {
         this.condition = ''
         this.getOrderNoList(this.order)
      },
      // 获取订单明细列表
      async getOrderNoList(order) {
         if (!order || !order.code) return
         this.loading = true
         try {
            const res = await request(
               '/orderOut/detlList',
               {
                  orderNo: order.code
               },
               'GET',
               true
            )
            if (res.code === 200) {
               let list = res.data || []
               list.forEach((item) => {
                  if (
                     item.enableQty === undefined ||
                     item.enableQty === null
                  ) {
                     item.enableQty =
                        Number(item.anfme || 0) - Number(item.qty || 0)
                  }
               })
               this.menuList = list
            } else {
               this.menuList = res.data || []
            }
         } catch (err) {
            // request.js 已经处理了错误提示
         } finally {
            this.loading = false
         }
      },
      // 选择明细进行出库
      chose(item) {
         if (item.ableQty <= 0) {
            uni.showToast({
               title: '该明细已完成',
               icon: 'none',
               position: 'top'
            })
            return
         }
         let that = this
         uni.navigateTo({
            url: './outLocView',
            success: function (res) {
               res.eventChannel.emit('orderItem', {
                  item: item
               })
            },
            events: {
               acceptDataFromOpenedPage: function (data) {
                  // 返回后刷新数据
               }
            }
         })
      }
   }
}
</script>
<style>
   /* 引入公共样式 */
   @import url('@/static/css/common.scss');
/* 引入公共样式 */
@import url('@/static/css/common.scss');
   .page-container {
      padding-bottom: 120rpx;
   }
   /* 订单头部 */
   .order-header {
      background: linear-gradient(135deg, #0081ff 0%, #1890ff 100%);
      padding: 16rpx 20rpx;
   }
   .header-content {
      background: rgba(255, 255, 255, 0.15);
      border-radius: 10rpx;
      padding: 12rpx 16rpx;
   }
   .header-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 4rpx 0;
   }
   .header-label {
      font-size: 24rpx;
      color: rgba(255, 255, 255, 0.7);
   }
   .header-value {
      font-size: 26rpx;
      color: #ffffff;
      font-weight: 500;
   }
   /* 搜索栏 */
   .search-bar {
      padding: 0rpx 8rpx;
      background: #ffffff;
      box-shadow: 0 2rpx 8rpx rgba(0, 129, 255, 0.08);
   }
.page-container {
   padding-bottom: 120rpx;
}
   /* 列表样式迁移 from rece/other.vue */
   .index {
      border: 1px solid #e54d42;
      color: #e54d42;
      border-radius: 50%;
      display: block;
      width: 50rpx;
      height: 50rpx;
      line-height: 48rpx;
      text-align: center;
      margin-right: 20rpx;
      font-size: 30rpx;
   }
/* 订单头部 */
.order-header {
   background: linear-gradient(135deg, #0081ff 0%, #1890ff 100%);
   padding: 16rpx 20rpx;
}
   .act {
      border: 1px solid #e54d42;
   }
.header-content {
   background: rgba(255, 255, 255, 0.15);
   border-radius: 10rpx;
   padding: 12rpx 16rpx;
}
   .text-blue {
      color: #0081ff !important;
   }
   .text-green {
      color: #39b54a !important;
   }
   /* 空状态 */
   .empty-state {
      padding: 60rpx 0;
   }
   .empty-text {
      margin-top: 20rpx;
   }
   /* 统计栏 */
   .stats-bar {
      position: fixed;
      bottom: 0;
      left: 0;
      right: 0;
      display: flex;
      align-items: center;
      justify-content: space-around;
      background: #ffffff;
      padding: 16rpx 0;
      box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
   }
   .stats-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      flex: 1;
   }
   .stats-value {
      font-size: 32rpx;
      color: #303133;
      font-weight: 600;
   }
   .stats-label {
      font-size: 20rpx;
      color: #909399;
      margin-top: 4rpx;
   }
   .stats-divider {
      width: 1rpx;
      height: 50rpx;
      background: #e8e8e8;
   }
.header-row {
   display: flex;
   justify-content: space-between;
   align-items: center;
   padding: 4rpx 0;
}
.header-label {
   font-size: 24rpx;
   color: rgba(255, 255, 255, 0.7);
}
.header-value {
   font-size: 26rpx;
   color: #ffffff;
   font-weight: 500;
}
/* 搜索栏 */
.search-bar {
   padding: 0rpx 8rpx;
   background: #ffffff;
   box-shadow: 0 2rpx 8rpx rgba(0, 129, 255, 0.08);
}
/* 列表样式迁移 from rece/other.vue */
.index {
   border: 1px solid #e54d42;
   color: #e54d42;
   border-radius: 50%;
   display: block;
   width: 50rpx;
   height: 50rpx;
   line-height: 48rpx;
   text-align: center;
   margin-right: 20rpx;
   font-size: 30rpx;
}
.act {
   border: 1px solid #e54d42;
}
.text-blue {
   color: #0081ff !important;
}
.text-green {
   color: #39b54a !important;
}
/* 空状态 */
.empty-state {
   padding: 60rpx 0;
}
.empty-text {
   margin-top: 20rpx;
}
/* 统计栏 */
.stats-bar {
   position: fixed;
   bottom: 0;
   left: 0;
   right: 0;
   display: flex;
   align-items: center;
   justify-content: space-around;
   background: #ffffff;
   padding: 16rpx 0;
   box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
}
.stats-item {
   display: flex;
   flex-direction: column;
   align-items: center;
   flex: 1;
}
.stats-value {
   font-size: 32rpx;
   color: #303133;
   font-weight: 600;
}
.stats-label {
   font-size: 20rpx;
   color: #909399;
   margin-top: 4rpx;
}
.stats-divider {
   width: 1rpx;
   height: 50rpx;
   background: #e8e8e8;
}
</style>