From c77086ad2d7949ab36dd0c4e0b59907e672dd64f Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 18 九月 2026 15:04:42 +0800
Subject: [PATCH] Merge remote-tracking branch 'refs/remotes/origin/dev_pro2.0' into dev_宁夏_九泓化工

---
 src/views/mes/pro/task/index.vue |  109 +++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 71 insertions(+), 38 deletions(-)

diff --git a/src/views/mes/pro/task/index.vue b/src/views/mes/pro/task/index.vue
index bd75f40..ba6ff48 100644
--- a/src/views/mes/pro/task/index.vue
+++ b/src/views/mes/pro/task/index.vue
@@ -1,42 +1,40 @@
-锘�<script lang="ts" setup>
+<script lang="ts" setup>
 import type { VxeTableGridOptions } from '#/adapter/vxe-table';
-import type { MesProWorkOrderApi } from '#/api/mes/pro/workorder';
+import {getWorkOrderSchedulePage, type MesProWorkOrderApi} from '#/api/mes/pro/workorder';
 
 import { onMounted, ref } from 'vue';
 import { useRouter } from 'vue-router';
 
 import { Page, useVbenModal } from '@vben/common-ui';
 import {
+  MesProWorkOrderProductionStatusEnum,
   MesProWorkOrderStatusEnum,
   MesProWorkOrderTypeEnum,
 } from '@vben/constants';
 
-import { Button, Card, message } from 'ant-design-vue';
+import { Button, Card, Progress, Tabs } from 'ant-design-vue';
 
 import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
-import { getGanttTaskList, previewAutoGenerate, autoGenerateTasks } from '#/api/mes/pro/task';
+import { getGanttTaskList } from '#/api/mes/pro/task';
 import { getWorkOrderPage } from '#/api/mes/pro/workorder';
 
 import ArchiveDetail from '#/views/mes/pd/archive/modules/detail.vue';
 import { GanttChart } from './components';
 import { useGridColumns, useGridFormSchema } from './data';
 import ScheduleForm from './modules/schedule-form.vue';
-import SchedulePreview from '../workorder-center/modules/schedule-preview.vue';
 
 const router = useRouter();
 const ganttTasks = ref<any[]>([]); // 鐢樼壒鍥鹃瑙堟暟鎹�
 const archiveVisible = ref(false);
 const archiveProductCode = ref('');
 
+const activeTab = ref('PENDING'); // 榛樿閫変腑寰呮帓浜�
+
 const [ScheduleModal, scheduleModalApi] = useVbenModal({
   connectedComponent: ScheduleForm,
   destroyOnClose: true,
 });
 
-const [SchedulePreviewModal, schedulePreviewModalApi] = useVbenModal({
-  connectedComponent: SchedulePreview,
-  destroyOnClose: true,
-});
 
 /** 鍒锋柊琛ㄦ牸 */
 function handleRefresh() {
@@ -63,28 +61,6 @@
 }
 
 /** 涓�閿帓浜ч瑙� */
-async function handleAutoSchedulePreview(row: MesProWorkOrderApi.WorkOrder) {
-  try {
-    const preview = await previewAutoGenerate({ workOrderId: row.id! });
-    schedulePreviewModalApi
-      .setData({ workOrder: row, preview })
-      .open();
-  } catch {
-    message.error('鑾峰彇鎺掍骇棰勮澶辫触');
-  }
-}
-
-/** 涓�閿帓浜ф墽琛� */
-async function handleAutoSchedule(row: MesProWorkOrderApi.WorkOrder) {
-  try {
-    const result = await autoGenerateTasks({ workOrderId: row.id! });
-    message.success(`鎺掍骇鎴愬姛锛岀敓鎴� ${result.taskIds?.length || 0} 涓换鍔);
-    handleRefresh();
-  } catch {
-    message.error('鎺掍骇澶辫触');
-  }
-}
-
 /** 鎵撳紑褰掓。璇︽儏 */
 function handleArchive(row: MesProWorkOrderApi.WorkOrder) {
   archiveProductCode.value = row.productCode || '';
@@ -94,6 +70,30 @@
 /** 鎵撳紑鐢樼壒鍥剧紪杈戦〉闈� */
 function handleGanttEdit() {
   router.push({ name: 'MesProTaskGanttEdit' });
+}
+
+/** 鍒ゆ柇璁㈠崟鏄惁涓衡�滃凡瀹屾垚绫诲瀷鈥濓細璁㈠崟鐘舵��=宸插畬鎴� 鎴� 鐢熶骇鐘舵��=鐢熶骇瀹屾垚 */
+function isCompletedWorkOrder(row: MesProWorkOrderApi.WorkOrder): boolean {
+  return (
+    row.status === MesProWorkOrderStatusEnum.FINISHED ||
+    row.productionStatus === MesProWorkOrderProductionStatusEnum.FINISHED
+  );
+}
+
+/**
+ * 宸插畬鎴愮被鍨嬭鐨勨�滃畬鎴愭�佲�濆厹搴曞睍绀猴細
+ * 宸茬敓浜ф暟閲忔寜璁㈠崟鏁伴噺灞曠ず锛堣嫢浣庝簬璁㈠崟鏁伴噺锛夛紝浣垮畬鎴愯繘搴︽樉绀轰负 100%銆�
+ * 浠呬綔鐢ㄤ簬鏈〉鍒楄〃灞曠ず锛屼笉淇敼鍚庣鏁版嵁锛屼笉褰卞搷搴撳瓨/鎶ュ伐/瀵煎嚭绛夌湡瀹炲彛寰勩��
+ */
+function normalizeCompletionDisplay(row: MesProWorkOrderApi.WorkOrder): void {
+  if (!isCompletedWorkOrder(row)) {
+    return;
+  }
+  const quantity = row.quantity ?? 0;
+  const produced = row.quantityProduced ?? 0;
+  if (produced < quantity) {
+    row.quantityProduced = quantity;
+  }
 }
 
 const [Grid, gridApi] = useVbenVxeGrid({
@@ -106,13 +106,27 @@
     proxyConfig: {
       ajax: {
         query: async ({ page }, formValues) => {
-          return await getWorkOrderPage({
+          let scheduleStatus: number | undefined = undefined;
+
+          if (activeTab.value === 'PENDING') {
+            scheduleStatus = 0; // 鏈畬鎴�
+          } else if (activeTab.value === 'FINISHED') {
+            scheduleStatus = 1; // 宸插畬鎴�
+          }
+          // activeTab === 'ALL' 鏃朵笉浼�
+
+          const res = await getWorkOrderSchedulePage({
             pageNo: page.currentPage,
             pageSize: page.pageSize,
-            status: MesProWorkOrderStatusEnum.CONFIRMED,
+            scheduleStatus,
             type: MesProWorkOrderTypeEnum.SELF,
             ...formValues,
           });
+          // 宸插畬鎴愮被鍨嬭锛氬凡鐢熶骇鏁伴噺/瀹屾垚杩涘害鍋氣�滃畬鎴愭�佲�濆厹搴曞睍绀猴紙浠呮湰椤靛睍绀猴紝涓嶆敼搴擄級
+          if (res?.list) {
+            res.list.forEach(normalizeCompletionDisplay);
+          }
+          return res;
         },
       },
     },
@@ -140,14 +154,25 @@
 <template>
   <Page auto-content-height>
     <ScheduleModal @success="handleRefresh" />
-    <SchedulePreviewModal @success="handleRefresh" />
-
     <!-- 鎺掍骇鐢樼壒鍥鹃瑙� -->
     <Card title="鎺掍骇鐢樼壒鍥�" class="mb-4">
+      <template #extra>
+        <span class="text-xs text-gray-400">灞曠ず宸茬‘璁よ嚜鍒惰鍗曠殑浠诲姟璁″垝</span>
+      </template>
       <GanttChart :height="350" :readonly="true" :tasks="ganttTasks" />
     </Card>
 
-    <Grid table-title="寰呮帓浜ц鍗�">
+    <Grid>
+      <template #table-title>
+        <div class="flex flex-col gap-2">
+          <span class="text-base font-medium">鐢熶骇璁㈠崟鍒楄〃</span>
+          <Tabs v-model:activeKey="activeTab" @change="handleRefresh" :tabBarStyle="{ margin: 0, borderBottom: 0 }">
+            <Tabs.TabPane key="ALL" tab="鍏ㄩ儴" />
+            <Tabs.TabPane key="PENDING" tab="鏈畬鎴�" />
+            <Tabs.TabPane key="FINISHED" tab="宸插畬鎴�" />
+          </Tabs>
+        </div>
+      </template>
       <template #toolbar-tools>
         <TableAction
           :actions="[
@@ -165,14 +190,22 @@
           {{ row.code }}
         </Button>
       </template>
+      <template #progressPercent="{ row }">
+        <Progress
+          :percent="Math.min(100, Math.round((row.quantity ? ((row.quantityProduced || 0) / row.quantity) * 100 : 0)))"
+          size="small"
+        />
+      </template>
       <template #actions="{ row }">
         <TableAction
           :actions="[
             {
-              label: '鎺掍骇',
+              label: '鎺掍骇缁存姢',
               type: 'link',
               auth: ['mes:pro-task:create'],
-              ifShow: row.status === MesProWorkOrderStatusEnum.CONFIRMED,
+              ifShow:
+                row.status === MesProWorkOrderStatusEnum.CONFIRMED &&
+                !isCompletedWorkOrder(row),
               onClick: handleSchedule.bind(null, row),
             },
             {

--
Gitblit v1.9.3