From 14817696a26eb142ccae03fa7c43050840e057f5 Mon Sep 17 00:00:00 2001
From: hsy <1029150275@qq.com>
Date: 星期一, 17 八月 2026 09:35:03 +0800
Subject: [PATCH] feat(mes): 优化生产订单与排产任务列表显示,新增启停工及校验逻辑 1. 生产订单列表展示优化 (WorkOrder)   - 新增「生产状态」列,全局注册 `ORDER_PRODUCTION_STATUS` 常量并绑定系统动态字典。   - 彻底重构「工序生产进度」单元格显示:弃用臃肿的 Steps 组件,改为极简横向布局(彩色状态圆点 + 进度百分比),解决表格行高被强行撑开及内容截断问题,支持横向滚动。   - 优化「完成进度」列宽及展示样式,将百分比数值外置同行显示,更加直观。 2. 排产任务列表改造 (Task)   - 顶部表头重构,由单一标题重构为「全部 / 未完成 / 已完成」的 Tabs 标签页切换结构。   - 重写数据过滤逻辑,剥离写死的 status 查询,改为使用 `scheduleStatus` 字段动态响应 Tabs 切换 (0: 未完成, 1: 已完成)。 3. 工单业务逻辑增强与状态流转   - 落实「工单查询逻辑设计方案」,优化底层的工单条件检索逻辑。   - 实现「添加工单启停功能」与「停工状态」,支持工单在执行过程中的暂停与恢复业务流转。   - 强化容错与防呆设计:操作「完成订单」时增加前置校验 `handleCheckFinish`,若生产状态为未完成,强制弹出二次确认 Modal,避免误操作。 # 相关讨论/参考方案 # - 添加工单启停功能 # - 停工状态功能设计方案 # - 工单查询逻辑设计方案 # - 工单完成进度显示优化

---
 src/views/wls/barcode/components/detail.vue |  139 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 107 insertions(+), 32 deletions(-)

diff --git a/src/views/wls/barcode/components/detail.vue b/src/views/wls/barcode/components/detail.vue
index 17a9f37..c9abe98 100644
--- a/src/views/wls/barcode/components/detail.vue
+++ b/src/views/wls/barcode/components/detail.vue
@@ -24,6 +24,7 @@
   column: 1,
   schema: useBarcodeDetailSchema(),
   useCard: false,
+  labelStyle: { width: '80px', whiteSpace: 'nowrap' },
 });
 
 function openModal(row: Partial<MesWmBarcodeApi.Barcode>) {
@@ -98,11 +99,86 @@
     message.warning('鏉$爜鐢熸垚澶辫触锛屾棤娉曚笅杞�');
     return;
   }
-  const link = document.createElement('a');
-  link.href = base64;
-  link.download = `barcode_${barcodeData.value.bizCode || 'unknown'}_${Date.now()}.png`;
-  link.click();
-  message.success('涓嬭浇鎴愬姛');
+
+  const canvas = document.createElement('canvas');
+  const ctx = canvas.getContext('2d');
+  if (!ctx) {
+    message.error('Canvas 鍒濆鍖栧け璐�');
+    return;
+  }
+
+  const img = new Image();
+  img.onload = () => {
+    const padding = 20;
+    const infoX = img.width + padding * 2;
+    const infoWidth = 320;
+    canvas.width = infoX + infoWidth + padding;
+    canvas.height = Math.max(img.height + padding * 2, 360);
+
+    ctx.fillStyle = '#ffffff';
+    ctx.fillRect(0, 0, canvas.width, canvas.height);
+
+    ctx.drawImage(img, padding, padding);
+
+    ctx.fillStyle = '#000000';
+    let y = padding + 10;
+    const lineHeight = 26;
+
+    // 鑾峰彇瀛楀吀鏂囨湰鐨勮緟鍔╁嚱鏁�
+    const getFormatText = (val?: number) => {
+      const map: Record<number, string> = { 1: 'QR_CODE', 2: 'CODE_128', 3: 'CODE_39', 4: 'EAN_13', 5: 'UPC_A' };
+      return map[val || 1] || 'QR_CODE';
+    };
+    const getBizTypeText = (val?: number) => {
+      const map: Record<number, string> = { 1: '浠撳簱', 2: '搴撳尯', 3: '搴撲綅', 4: '鐗╂枡', 5: '瀹㈡埛', 6: '渚涘簲鍟�', 7: '宸ュ崟', 8: '璁惧', 9: '宸ュ叿', 10: '浜哄憳', 11: '宸ヤ綔绔�', 12: '杞﹂棿', 13: '搴撳瓨', 14: '娴佽浆鍗�', 15: '瑁呯鍗�', 16: '鎵规' };
+      return map[val || 1] || '-';
+    };
+    const getStatusText = (val?: number) => val === 0 ? '绂佺敤' : '鍚敤';
+
+    const items = [
+      { label: '鏉$爜鏍煎紡', value: getFormatText(barcodeData.value.format) },
+      { label: '涓氬姟绫诲瀷', value: getBizTypeText(barcodeData.value.bizType) },
+      { label: '涓氬姟缂栫爜', value: barcodeData.value.bizCode },
+      { label: '涓氬姟鍚嶇О', value: barcodeData.value.bizName },
+      { label: '鏉$爜鍐呭', value: barcodeData.value.content },
+      { label: '鐘舵��', value: getStatusText(barcodeData.value.status) },
+    ];
+
+    items.forEach((item) => {
+      ctx.font = 'bold 13px Arial, sans-serif';
+      ctx.fillText(`${item.label}:`, infoX, y);
+      y += 18;
+      ctx.font = '13px Arial, sans-serif';
+      const text = item.value || '-';
+      // 澶勭悊闀挎枃鏈崲琛�
+      const maxWidth = infoWidth - 10;
+      if (ctx.measureText(text).width > maxWidth) {
+        let currentText = text;
+        while (currentText.length > 0) {
+          let line = '';
+          for (let i = 0; i < currentText.length; i++) {
+            const testLine = line + currentText[i];
+            if (ctx.measureText(testLine).width > maxWidth) break;
+            line = testLine;
+          }
+          ctx.fillText(line, infoX + 5, y);
+          y += 16;
+          currentText = currentText.slice(line.length);
+        }
+        y += 6;
+      } else {
+        ctx.fillText(text, infoX + 5, y);
+        y += lineHeight;
+      }
+    });
+
+    const link = document.createElement('a');
+    link.href = canvas.toDataURL('image/png');
+    link.download = `barcode_${barcodeData.value.bizCode || 'unknown'}_${Date.now()}.png`;
+    link.click();
+    message.success('涓嬭浇鎴愬姛');
+  };
+  img.src = base64;
 }
 
 async function handleGenerate() {
@@ -126,36 +202,35 @@
 </script>
 
 <template>
-  <Modal v-model:open="open" title="鏌ョ湅鏉$爜" width="500px">
+  <Modal v-model:open="open" title="鏌ョ湅鏉$爜" width="750px">
     <div>
-      <div
-        class="mb-5 flex min-h-50 items-center justify-center rounded bg-gray-100 p-5"
-      >
-        <div
-          v-if="barcodeData.content"
-          class="flex items-center justify-center"
-        >
-          <WlsBarcode
-            ref="barcodeRef"
-            :content="barcodeData.content"
-            :format="barcodeData.format"
-            :height="150"
-            :width="400"
-          />
+      <div class="mb-5 flex min-h-50 items-center rounded bg-gray-100 p-5">
+        <div v-if="barcodeData.content" class="flex w-full items-center gap-6">
+          <div class="flex-shrink-0">
+            <WlsBarcode
+              ref="barcodeRef"
+              :content="barcodeData.content"
+              :format="barcodeData.format"
+              :height="150"
+              :width="280"
+            />
+          </div>
+          <div class="flex-1">
+            <Descriptions :data="barcodeData">
+              <template #content>
+                <Tooltip :title="barcodeData.content">
+                  <span
+                    class="inline-block max-w-60 overflow-hidden text-ellipsis whitespace-nowrap"
+                  >
+                    {{ barcodeData.content }}
+                  </span>
+                </Tooltip>
+              </template>
+            </Descriptions>
+          </div>
         </div>
-        <Empty v-else description="鏆傛棤鏉$爜鏁版嵁" />
+        <Empty v-else description="鏆傛棤鏉$爜鏁版嵁" class="flex-1" />
       </div>
-      <Descriptions :data="barcodeData">
-        <template #content>
-          <Tooltip :title="barcodeData.content">
-            <span
-              class="inline-block max-w-75 overflow-hidden text-ellipsis whitespace-nowrap"
-            >
-              {{ barcodeData.content }}
-            </span>
-          </Tooltip>
-        </template>
-      </Descriptions>
     </div>
     <template #footer>
       <Button v-if="!barcodeData.content" @click="handleGenerate">

--
Gitblit v1.9.3