快乐的昕的电脑
2025-10-15 a3298d4e03b929a1fb9e00f3211baa577338b9c8
components/WorkOrderPrint.vue
@@ -1,5 +1,6 @@
<template>
   <view class="page">
   <!-- 根元素增加动态类,弹窗出现时附加 has-overlay,用于控制底层交互与层级 -->
   <view class="page" :class="{'has-overlay': (isShowUserSelect || isShow || barcodeIsShow)}">
      <view class="status-section">
         <!-- 报工记录表 -->
         <view class="report-table-wrapper">
@@ -23,7 +24,7 @@
               <tbody>
                  <tr>
                     <td>{{ nowTime }}</td>
                     <td>{{ staffNo || '-' }}</td>
                     <td>{{ staffName || '-' }}</td>
                     <td>{{ orderNo || '-' }}</td>
                     <td>{{ order.daa003 || '-' }}</td>
                     <td>{{ planQtyDisplay }}</td>
@@ -38,7 +39,7 @@
            </table>
         </view>
         <!-- 统计行(刷新按钮移到这里右侧) -->
         <!-- 统计行 -->
         <view class="status-row">
            <view class="status-box">
               <text>机台面板数:</text>
@@ -68,32 +69,12 @@
            </view>
         </view>
         <!-- 基础信息(已去掉 图号 / 材质 / 颜色) -->
         <view class="basic-info">
            <view class="form-row">
               <view class="form-item">
                  <label>产品编码:</label>
                  <input class="inp" type="text" v-model="order.daa002" disabled />
               </view>
               <view class="form-item">
                  <label>产品名称:</label>
                  <superwei-combox :candidates="DAA003List" v-model="order.daa003"
                               @select="onDaa003Change" class="inp"></superwei-combox>
               </view>
               <view class="form-item">
                  <label>产品规格:</label>
                  <input class="inp" type="text" v-model="order.daa004" disabled />
               </view>
            </view>
         </view>
         <!-- 不良数量 -->
         <view class="print-section" style="margin-top:10px;">
            <view class="barcode-info">
               <view class="user-select">
                  <text style="display:inline-block;float:left;">不良数量:</text>
                  <input v-model="customAmount" class="inp"
                        style="width:55%;height:60px;border:3px solid #808080;font-size:32px;text-align:center;margin-top:5px;"
                  <text>不良数量:</text>
                  <input v-model="customAmount" class="inp bad-input"
                        placeholder="请输入数量" />
               </view>
               <view class="user-select" style="margin-left:30px;">
@@ -103,13 +84,28 @@
         </view>
         <!-- 报工人选择 -->
         <view>
            <view class="reason-section" style="margin-bottom:-10px">
               <text>报工人:</text>
               <view class="reason-buttons" style="font-size:20px;">
                  <button v-for="(u,index) in users" :key="index"
                        :class="{'reason-btn':true,'selected': staffNo===u}"
                        @click="toggleUser(u)" v-text="u"></button>
         <view class="current-user-section">
            <text>当前报工人:</text>
            <text class="current-user-name">{{ staffName || '未选择' }}</text>
            <button class="select-user-btn" @click="isShowUserSelect = true">选人</button>
         </view>
         <!-- 选人弹窗 -->
         <view v-if="isShowUserSelect" class="overlay">
            <view class="popup user-select-popup">
               <view class="user-list-scroll">
                  <view class="user-list-grid">
                     <button v-for="(u, index) in users"
                           :key="index"
                           class="user-list-btn"
                           :class="{'selected': u === staffNo}"
                           @click="selectUser(u)">
                        {{ u.split(':')[1] }}
                     </button>
                  </view>
               </view>
               <view class="user-popup-footer">
                  <button class="clean-btn" style="width: 60%;" @click="isShowUserSelect = false">关闭</button>
               </view>
            </view>
         </view>
@@ -120,7 +116,7 @@
            <button class="cancel-btn" @click="cancel">取消</button>
         </view>
         <!-- 保留弹窗 -->
         <!-- 弹窗保留 -->
         <view v-if="isShow" class="overlay">
            <view class="popup">
               <view class="bottom-section1">
@@ -153,9 +149,7 @@
                     <uni-td align="center"><input v-model="item.okQty" /></uni-td>
                  </uni-tr>
               </uni-table>
               <view>
                  <button class="clean-btn" type="warn" @click="barcodeIsShow=false">关闭</button>
               </view>
               <view><button class="clean-btn" type="warn" @click="barcodeIsShow=false">关闭</button></view>
            </view>
         </view>
      </view>
@@ -169,61 +163,30 @@
      props: { orderNo: String, orderId: Number, machineNo: String },
      data() {
         return {
            isShowUserSelect: false,
            currentUser: '',
            barcodeAmount: '',
            users: [],
            userForm: [],
            staff: [],
            user: {},
            productionCount: 0,
            printedCount: 0,
            defectiveCount: 0,
            order: {},
            icount: 1,
            bqty: 0,
            sQuantity: 0,
            kgQty: 0,
            initialValue: 0,
            qqty: 0,
            ngStaid: 0,
            bufferData: '',
            dataToPrint: [],
            isLoading: false,
            but: false,
            DAA003List: [],
            lineList: [],
            isShow: false,
            barcodeIsShow: false,
            barcodeList: [],
            staffNo: '',
            printStr: '',
            printMac: '',
            bluetoothSocket: {},
            device: '',
            uuid: '',
            printNum: 1,
            reportingList: [],
            printLoading: false,
            customAmount: '',
            isGeneratingBarcode: false,
            lastGenerateTime: 0,
            generateRequestId: null,
            nowTimeTimer: null,
            nowTime: ''
         };
            users: [], userForm: [], staff: [], user: {},
            productionCount: 0, printedCount: 0, defectiveCount: 0, order: {},
            icount: 1, bqty: 0, sQuantity: 0, kgQty: 0, initialValue: 0, qqty: 0,
            ngStaid: 0, bufferData: '', dataToPrint: [], isLoading: false, but: false,
            DAA003List: [], lineList: [], isShow: false, barcodeIsShow: false, barcodeList: [],
            staffNo: '', printStr: '', printMac: '', bluetoothSocket: {}, device: '', uuid: '',
            printNum: 1, reportingList: [], printLoading: false, customAmount: '',
            isGeneratingBarcode: false, lastGenerateTime: 0, generateRequestId: null,
            nowTimeTimer: null, nowTime: ''
         }
      },
      computed: {
         calculatedCurrentCount() {
            return (this.productionCount || 0) - (this.initialValue || 0);
         },
         calculatedTotalProduction() {
            return (this.kgQty || 0) + this.calculatedCurrentCount;
         },
         calculatedDefectiveCount() {
            return this.calculatedTotalProduction - (this.sQuantity || 0);
         },
         planQtyDisplay() {
            return this.order.planQty || this.order.planQuantity || this.order.daa007 || this.order.daa010 || 0;
         calculatedCurrentCount() { return (this.productionCount || 0) - (this.initialValue || 0); },
         calculatedTotalProduction() { return (this.kgQty || 0) + this.calculatedCurrentCount; },
         calculatedDefectiveCount() { return this.calculatedTotalProduction - (this.sQuantity || 0); },
         planQtyDisplay() { return this.order.planQty || this.order.planQuantity || this.order.daa007 || this.order.daa010 || 0; },
         // 新增:解析姓名
         staffName() {
            if (!this.staffNo) return '';
            const parts = this.staffNo.split(':');
            return parts.length > 1 ? parts[1] : this.staffNo;
         }
      },
      created() {
@@ -234,10 +197,13 @@
         this.updateNowTime();
         this.nowTimeTimer = setInterval(this.updateNowTime, 60000);
      },
      beforeDestroy() {
         if (this.nowTimeTimer) clearInterval(this.nowTimeTimer);
      },
      beforeDestroy() { if (this.nowTimeTimer) clearInterval(this.nowTimeTimer); },
      methods: {
         // 选择人员
         selectUser(u) {
            this.staffNo = u;
            this.isShowUserSelect = false;
         },
         updateNowTime() {
            const d = new Date(), p = n => n.toString().padStart(2, '0');
            this.nowTime = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
@@ -249,9 +215,7 @@
            this.isGeneratingBarcode = false; this.lastGenerateTime = 0; this.generateRequestId = null;
         },
         resetGenerateState() {
            this.isGeneratingBarcode = false;
            this.generateRequestId = null;
            this.lastGenerateTime = 0;
            this.isGeneratingBarcode = false; this.generateRequestId = null; this.lastGenerateTime = 0;
            this.$showMessage("已重置条码生成状态");
         },
         refresh() {
@@ -259,9 +223,7 @@
               url: "http://192.168.0.94:9095/Numerical/RefreshDev",
               data: { machineNo: this.order.machineNo },
               contentType: "application/json"
            }).then(r => {
               if (r.code == 200) this.fetchData(true); else this.$showMessage("同步失败");
            });
            }).then(r => { r.code == 200 ? this.fetchData(true) : this.$showMessage("同步失败"); });
         },
         onDaa003Change(v) {
            let o = this.lineList[this.DAA003List.indexOf(v)];
@@ -318,10 +280,11 @@
               });
         },
         getXS0101() {
            this.$post({ url: "/MesStaff/GetAllXS0101" }).then(res => {
               this.staff = res.data.tbBillList;
               this.users = this.staff.map(s => s.staffNo + ":" + s.staffName);
            });
            this.$post({ url: "/MesStaff/GetAllXS0101" })
               .then(res => {
                  this.staff = res.data.tbBillList;
                  this.users = this.staff.map(s => s.staffNo + ":" + s.staffName);
               });
         },
         getWomdaaPrintById() {
            this.$post({ url: "/Womdaa/GetWomdaaPrintById", data: { orderId: this.orderId } })
@@ -343,7 +306,7 @@
         init() {
            try {
               const v = this.getAndroidVersion();
               if (v >= 12) this.initForAndroid12Plus(); else this.initForAndroidLegacy();
               v >= 12 ? this.initForAndroid12Plus() : this.initForAndroidLegacy();
            } catch (e) { console.error(e); }
         },
         getAndroidVersion() {
@@ -389,16 +352,11 @@
            this.isShow = false;
            this.isGeneratingBarcode = false;
            this.generateRequestId = null;
            this.bufferData = '';
            this.dataToPrint = [];
            this.staffNo = null;
            this.user = '';
            this.barcodeAmount = '';
            this.icount = 1;
            this.staff = null;
            this.bufferData = ''; this.dataToPrint = [];
            this.staffNo = null; this.user = ''; this.barcodeAmount = ''; this.icount = 1; this.staff = null;
         }
      }
   };
   }
</script>
<style scoped>
@@ -408,6 +366,14 @@
      flex-direction: column;
      box-sizing: border-box;
   }
      .page.has-overlay .status-section > :not(.overlay) {
         pointer-events: none;
      }
      .page.has-overlay .status-section > .overlay {
         pointer-events: auto;
      }
   .report-table-wrapper {
      margin-bottom: 8px;
@@ -511,25 +477,6 @@
      padding: 6px 14px;
   }
   .basic-info .form-row {
      display: flex;
      justify-content: space-between;
      margin: 4px 0 10px;
   }
   .form-item {
      width: 32%;
   }
   .inp {
      width: 100%;
      padding: 6px;
      font-size: 14px;
      border: 1px solid #808080;
      border-radius: 6px;
      box-sizing: border-box;
   }
   .print-section {
      padding: 4px 0 10px;
      margin-bottom: 8px;
@@ -539,6 +486,23 @@
      display: flex;
      align-items: flex-start;
      gap: 20px;
   }
   .inp {
      padding: 6px;
      font-size: 14px;
      border: 1px solid #808080;
      border-radius: 6px;
      box-sizing: border-box;
   }
   .bad-input {
      width: 55%;
      height: 60px;
      border: 3px solid #808080;
      font-size: 32px;
      text-align: center;
      margin-top: 5px;
   }
   .details-btn {
@@ -580,6 +544,8 @@
      display: flex;
      justify-content: space-between;
      margin-top: 12px;
      position: relative;
      z-index: 10;
   }
   .save-btn, .cancel-btn {
@@ -602,6 +568,7 @@
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 1000;
   }
   .popup {
@@ -615,6 +582,7 @@
      max-height: 80vh;
      overflow-y: auto;
      border-radius: 8px;
      z-index: 1001;
   }
   .clean-btn {
@@ -634,6 +602,80 @@
      border-spacing: 3px;
   }
   .current-user-section {
      display: flex;
      align-items: center;
      margin: 16px 0;
      font-size: 18px;
      border: 1.5px solid #f00;
      border-radius: 8px;
      padding: 12px 18px;
      background: #fff;
      width: fit-content;
      gap: 10px;
   }
   .current-user-name {
      font-weight: bold;
      font-size: 20px;
      margin: 0 10px;
   }
   .select-user-btn {
      padding: 4px 18px;
      background: #eee;
      border: 1px solid #aaa;
      border-radius: 6px;
      font-size: 16px;
      margin-left: 8px;
   }
   .user-select-popup {
      width: 480px;
      max-width: 96vw;
      max-height: 80vh;
      padding: 0;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
   }
   .user-list-scroll {
      flex: 1 1 auto;
      overflow-y: auto;
      padding: 32px 24px 0 24px;
   }
   .user-list-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 18px 18px;
      margin-bottom: 0;
   }
   .user-popup-footer {
      flex-shrink: 0;
      padding: 18px 24px 24px 24px;
      background: #fff;
      text-align: center;
   }
   .user-list-btn {
      padding: 18px 0;
      font-size: 20px;
      background: #00a2e9;
      color: #fff;
      border: none;
      border-radius: 8px;
      cursor: pointer;
      width: 100%;
      box-sizing: border-box;
   }
      .user-list-btn.selected {
         background: #ff9500;
      }
   @media (max-width:1400px) {
      input.highlight {
         font-size: 14px;