m0_70156489 4 days ago
parent
commit
c347b523a5

+ 2 - 0
src/main.js

@@ -2,6 +2,8 @@ import 'element-plus/es/components/message/style/css'
 import 'element-plus/es/components/loading/style/css'
 import 'element-plus/es/components/notification/style/css'
 import 'element-plus/es/components/message-box/style/css'
+import 'element-plus/es/components/upload/style/css'
+import 'element-plus/es/components/image-viewer/style/css'
 import './style/element_visiable.scss'
 import { createApp } from 'vue'
 // 引入gin-vue-admin前端初始化相关内容

+ 26 - 6
src/view/SalaryManage/ProcessProduction.vue

@@ -80,8 +80,11 @@
           stripe
           row-key="rowKey"
           style="width: 100%;height: 65vh;"
-          :row-style="{ height: '32px' }"
-          :header-row-style="{ height: '36px' }"
+          size="small"
+          :row-style="{ height: '26px' }"
+          :header-row-style="{ height: '28px' }"
+          :cell-style="{ padding: '2px 0' }"
+          :header-cell-style="{ padding: '2px 0' }"
           :span-method="tableSpanMethod"
           :row-class-name="processTableRowClassName"
           @row-click="onProcessTableRowClick"
@@ -823,7 +826,7 @@ defineExpose({ loadByWorkorder })
 }
 
 .process-production-inner {
-  padding: 0 16px 12px;
+  padding: 0 12px 8px;
   box-sizing: border-box;
   max-width: 100%;
 }
@@ -833,11 +836,11 @@ defineExpose({ loadByWorkorder })
 }
 
 .process-production-search {
-  margin-bottom: 8px;
+  margin-bottom: 6px;
 }
 
 .process-production-hint {
-  margin-bottom: 10px;
+  margin-bottom: 6px;
 }
 
 .process-production-search :deep(.el-form-item) {
@@ -934,7 +937,7 @@ defineExpose({ loadByWorkorder })
 
 .order-summary-desc {
   width: 100%;
-  margin-bottom: 10px;
+  margin-bottom: 6px;
 }
 
 .order-summary-desc :deep(.el-descriptions__label) {
@@ -948,6 +951,10 @@ defineExpose({ loadByWorkorder })
   color: #303133;
 }
 
+.order-summary-desc :deep(.el-descriptions__cell) {
+  padding: 6px 10px !important;
+}
+
 /* 不用 gva-table-box,避免全局白底卡片(main.scss: bg-white p-6 rounded) */
 .process-production-table-wrap {
   width: 100%;
@@ -956,6 +963,19 @@ defineExpose({ loadByWorkorder })
   border-radius: 0;
 }
 
+.process-production-table-wrap :deep(.el-table .cell) {
+  line-height: 20px;
+  padding-left: 6px;
+  padding-right: 6px;
+}
+
+.process-production-table-wrap :deep(.el-table__header th),
+.process-production-table-wrap :deep(.el-table__body td),
+.process-production-table-wrap :deep(.el-table__footer td) {
+  padding-top: 2px !important;
+  padding-bottom: 2px !important;
+}
+
 .process-production-table-wrap :deep(.el-table__footer-wrapper td) {
   font-weight: 600;
   color: #303133;

+ 453 - 32
src/view/performance/WorkScoreReporting/gongfenbaogong.vue

@@ -66,7 +66,7 @@
                         >
                         <el-table-column align="center" label="小组" prop="sys_id" :width="90" show-overflow-tooltip />
                         <el-table-column align="center" label="订单编号" prop="work_order" :width="100" />
-                        <el-table-column align="center" label="工序号" prop="process_code" :width="90" />
+                        <el-table-column align="center" label="工序号" prop="process_code" :width="90" />
                                   <el-table-column align="left" label="工序名称" prop="process_name" min-width="200" show-overflow-tooltip />
                                   <el-table-column align="center" label="员工姓名" prop="staff_name" :width="120">
                                     <template #header>
@@ -95,8 +95,9 @@
                                   </el-table-column>
                                   <el-table-column align="center" label="数量" prop="number" :width="90" />
                                   <el-table-column align="center" label="报工时间" prop="sys_rq" :width="180" show-overflow-tooltip />
-                                  <el-table-column align="center" label="操作" :width="100" fixed="right">
+                                  <el-table-column align="center" label="操作" :width="160" fixed="right">
                                     <template #default="scope">
+                                      <el-button type="primary" size="small" @click.stop="openEditReportingQty(scope.row)">修改</el-button>
                                       <el-button type="danger" size="small" @click.stop="deleteReportingWork(scope.row)">删除</el-button>
                                     </template>
                                   </el-table-column>
@@ -280,7 +281,7 @@
                                 <el-table-column prop="工艺编号" label="工序号" width="72" align="center" />
                                 <el-table-column prop="工艺名称" label="工序名称" min-width="240" />
                                 <el-table-column prop="本组完成数" label="本组完成数" min-width="88" align="center" />
-                                <el-table-column prop="累计完成数" label="累计完成数" min-width="60" align="center" />
+                                <el-table-column prop="累计完成数" label="累计完成数" min-width="70" align="center" />
                                 <el-table-column prop="未完成数" label="未完成数" min-width="60" align="center" />
                                 <el-table-column label="完工人员" width="120">
                                   <template #default="scope">
@@ -314,21 +315,23 @@
                                     <div v-if="getReportingData(selectedPartIndex, scope.$index).staffList">
                                       <div v-for="(staff, staffIndex) in getReportingData(selectedPartIndex, scope.$index).staffList" :key="staffIndex" class="work-score-staff-row">
                                         <el-input 
-                                          v-model.number="staff.number" 
-                                          type="number" 
+                                          :model-value="staff.number"
+                                          inputmode="numeric"
                                           class="work-score-qty-input"
+                                          :class="{ 'work-score-qty-over': isQtyOverUnfinished(selectedPartIndex, scope.$index) }"
                                           :disabled="isReportingFillDisabled(selectedPartIndex, scope.$index, staffIndex)"
-                                          @input="autoFillStaffOnQuantityInput(selectedPartIndex, scope.$index, staffIndex)"
+                                          @update:model-value="(v) => onQtyInput(selectedPartIndex, scope.$index, staffIndex, v)"
                                         />
                                       </div>
                                     </div>
                                     <el-input 
                                       v-else 
-                                      v-model.number="getReportingData(selectedPartIndex, scope.$index).number" 
-                                      type="number" 
+                                      :model-value="getReportingData(selectedPartIndex, scope.$index).number"
+                                      inputmode="numeric"
                                       class="work-score-qty-input"
+                                      :class="{ 'work-score-qty-over': isQtyOverUnfinished(selectedPartIndex, scope.$index) }"
                                       :disabled="isReportingFillDisabled(selectedPartIndex, scope.$index)"
-                                      @input="autoFillStaffOnQuantityInput(selectedPartIndex, scope.$index)"
+                                      @update:model-value="(v) => onQtyInput(selectedPartIndex, scope.$index, null, v)"
                                     />
                                   </template>
                                 </el-table-column>
@@ -366,30 +369,80 @@
                 <el-dialog
                   v-model="workScoreConfirmVisible"
                   title="确认报工"
-                  width="760px"
+                  width="1040px"
+                  top="8vh"
                   append-to-body
                   destroy-on-close
                   class="work-score-confirm-dialog"
+                  :close-on-click-modal="false"
                 >
-                  <p class="work-score-confirm-tip">请核对以下报工数据,确认无误后提交</p>
+                  <p class="work-score-confirm-tip">请核对以下报工数据,确认无误后提交</p>
                   <el-table
                     :data="workScoreConfirmRows"
                     border
                     stripe
-                    max-height="420"
+                    height="512"
                     :span-method="workScoreConfirmSpanMethod"
+                    :cell-class-name="workScoreConfirmCellClass"
+                    class="work-score-confirm-table"
                     style="width: 100%"
                   >
-                    <el-table-column label="工序编号" prop="工序编号" width="90" align="center" />
-                    <el-table-column label="工序名称" prop="工序名称" min-width="260" show-overflow-tooltip />
-                    <el-table-column label="员工姓名" prop="员工姓名" width="120" align="center" />
-                    <el-table-column label="完工数量" prop="完工数量" width="100" align="center" />
+                    <el-table-column label="部件" prop="部件" width="88" align="center" show-overflow-tooltip />
+                    <el-table-column label="工序号" prop="工序编号" width="68" align="center" />
+                    <el-table-column label="工序名称" prop="工序名称" min-width="150" align="left" show-overflow-tooltip />
+                    <el-table-column label="本组完成数" prop="本组完成数" width="96" align="center" />
+                    <el-table-column label="累计完成数" prop="累计完成数" width="96" align="center" />
+                    <el-table-column label="未完成数" prop="未完成数量" width="88" align="center" />
+                    <el-table-column label="完工人员" prop="员工姓名" width="88" align="center" />
+                    <el-table-column label="完工数量" prop="完工数量" width="88" align="center" />
+                    <el-table-column label="超出数量" prop="超出数量" width="88" align="center" />
                   </el-table>
                   <template #footer>
                     <el-button @click="workScoreConfirmVisible = false">返回修改</el-button>
                     <el-button type="primary" :loading="workScoreSubmitting" @click="confirmSubmitWorkScore">确认报工</el-button>
                   </template>
                 </el-dialog>
+
+                <!-- 当天报工记录:修改数量 -->
+                <el-dialog
+                  v-model="editReportingQtyVisible"
+                  title="修改数量"
+                  width="420px"
+                  top="32vh"
+                  append-to-body
+                  destroy-on-close
+                  :close-on-click-modal="false"
+                  class="edit-reporting-qty-dialog"
+                  @opened="focusEditReportingQtyInput"
+                >
+                  <el-form label-width="88px">
+                    <el-form-item label="工序号">
+                      <el-input :model-value="editReportingQtyForm.process_code" disabled />
+                    </el-form-item>
+                    <el-form-item label="工序名称">
+                      <el-input :model-value="editReportingQtyForm.process_name" disabled />
+                    </el-form-item>
+                    <el-form-item label="未完成数">
+                      <el-input :model-value="editReportingQtyForm.unfinished" disabled />
+                    </el-form-item>
+                    <el-form-item label="数量" required>
+                      <el-input
+                        ref="editReportingQtyInputRef"
+                        :model-value="editReportingQtyForm.number"
+                        inputmode="numeric"
+                        maxlength="5"
+                        placeholder="请输入修正后的数量"
+                        :class="{ 'edit-reporting-qty-over': isEditReportingQtyOver }"
+                        @update:model-value="(v) => { editReportingQtyForm.number = filterQtyDigits(v) }"
+                        @keyup.enter="submitEditReportingQty"
+                      />
+                    </el-form-item>
+                  </el-form>
+                  <template #footer>
+                    <el-button @click="editReportingQtyVisible = false">取消</el-button>
+                    <el-button type="primary" :loading="editReportingQtyLoading" @click="submitEditReportingQty">确定</el-button>
+                  </template>
+                </el-dialog>
         </layout-content>
       </layout>
     <SubOrderPage ref="SubOrderPageRef" />
@@ -457,7 +510,7 @@ import $ from 'jquery';
 import LuckyExcel from 'luckyexcel';
 import { Layout, LayoutSider, LayoutContent } from '@arco-design/web-vue';
 import {ref, reactive, computed, watch, nextTick, onUnmounted} from 'vue';
-import {getSpotList,getInfo,OrderAttachments,WorkOrderList,DeleteReportingWork} from '@/api/mes/job';
+import {getSpotList,getInfo,OrderAttachments,WorkOrderList,DeleteReportingWork,UpdateReportingWork} from '@/api/mes/job';
 import {getMac,getMajorprocessAndPerson,GetOrderProcess,GetCarProcess,ReportingWork,GetReportingWorkRecord} from '@/api/jixiaoguanli/baogong'
 import {getMachineMac} from '@/api/jixiaoguanli/jitairibaobiao'
 import {ElMessage,ElMessageBox} from "element-plus";
@@ -491,10 +544,22 @@ const add_searchInfo = ref('')
 const gongfenHistoryData = ref([])
 const gongfenHistoryTableRef = ref()
 const staffNameFilter = ref([])
+const currentOrderNo = ref('')
+
+/** 当天报工记录:仅当前查询订单 */
+const orderScopedGongfenHistoryData = computed(() => {
+  const list = gongfenHistoryData.value || []
+  const orderNo = String(currentOrderNo.value || '').trim()
+  if (!orderNo) return []
+  return list.filter((row) => {
+    const rowOrder = String(row.work_order ?? row['订单编号'] ?? '').trim()
+    return rowOrder === orderNo
+  })
+})
 
 const staffNameFilterOptions = computed(() => {
   const names = [...new Set(
-    (gongfenHistoryData.value || [])
+    (orderScopedGongfenHistoryData.value || [])
       .map(item => String(item.staff_name || '').trim())
       .filter(Boolean)
   )]
@@ -532,7 +597,7 @@ const syncStaffNameFilterAfterDataChange = () => {
 }
 
 const filteredGongfenHistoryData = computed(() => {
-  const list = gongfenHistoryData.value || []
+  const list = orderScopedGongfenHistoryData.value || []
   const options = staffNameFilterOptions.value
   const selected = staffNameFilter.value
   if (!selected.length) return []
@@ -542,7 +607,7 @@ const filteredGongfenHistoryData = computed(() => {
 })
 
 watch(
-  () => gongfenHistoryData.value,
+  () => [gongfenHistoryData.value, currentOrderNo.value],
   () => {
     syncStaffNameFilterAfterDataChange()
   },
@@ -1011,6 +1076,35 @@ const fillSelectedEmployee = (row, partIndex, processIndex, staffIndex = null) =
 }
 
 // 表格内输入完工数量时,若上方已选人员且本格人员为空,则自动填入
+const filterQtyDigits = (val) => String(val ?? '').replace(/[^\d]/g, '').slice(0, 5)
+
+const onQtyInput = (partIndex, processIndex, staffIndex, val) => {
+  const digits = filterQtyDigits(val)
+  const item = getReportingData(partIndex, processIndex)
+  if (item.staffList?.length) {
+    const idx = staffIndex !== null && staffIndex !== undefined ? staffIndex : 0
+    if (item.staffList[idx]) item.staffList[idx].number = digits
+  } else {
+    item.number = digits
+  }
+  autoFillStaffOnQuantityInput(partIndex, processIndex, staffIndex)
+}
+
+/** 本工序已填完工合计是否超出未完成数 */
+const isQtyOverUnfinished = (partIndex, processIndex) => {
+  const process = partProcesses.value?.[partIndex]?.[processIndex]
+  const unfinished = Number(process?.未完成数)
+  if (!Number.isFinite(unfinished)) return false
+  const item = getReportingData(partIndex, processIndex)
+  let sum = 0
+  if (item.staffList?.length) {
+    sum = item.staffList.reduce((s, st) => s + (Number(st.number) || 0), 0)
+  } else {
+    sum = Number(item.number) || 0
+  }
+  return sum > unfinished
+}
+
 const isReportingStaffEmpty = (partIndex, processIndex, staffIndex = null) => {
   const item = getReportingData(partIndex, processIndex)
   if (item.staffList?.length) {
@@ -1271,10 +1365,16 @@ const recomputeWorkScoreConfirmRowSpan = (rows) => {
   const result = []
   let i = 0
   while (i < rows.length) {
+    const partLabel = rows[i].部件
     const processCode = rows[i].工序编号
     const processName = rows[i].工序名称
     let j = i
-    while (j < rows.length && rows[j].工序编号 === processCode && rows[j].工序名称 === processName) {
+    while (
+      j < rows.length &&
+      rows[j].部件 === partLabel &&
+      rows[j].工序编号 === processCode &&
+      rows[j].工序名称 === processName
+    ) {
       j++
     }
     const group = rows.slice(i, j)
@@ -1286,18 +1386,73 @@ const recomputeWorkScoreConfirmRowSpan = (rows) => {
   return result
 }
 
+/** 左侧部件展示文案:编号-名称 */
+const resolvePartLabel = (partCode) => {
+  const code = String(partCode ?? '').trim()
+  const part = (processParts.value || []).find((p) => String(p?.['部件编号'] ?? '').trim() === code)
+  if (!part) return code
+  const name = String(part['部件名称'] ?? '').trim()
+  return name ? `${code}-${name}` : code
+}
+
+/** 从当前已加载工艺行取未完成数等 */
+const findProcessProgressByCode = (processCode, processName) => {
+  const code = String(processCode ?? '').trim()
+  const name = String(processName ?? '').trim()
+  for (const list of partProcesses.value || []) {
+    for (const p of list || []) {
+      const pCode = String(p?.工艺编号 ?? '').trim()
+      const pName = String(p?.工艺名称 ?? '').trim()
+      if (code && pCode === code && (!name || pName === name)) {
+        return {
+          unfinished: Number(p?.未完成数),
+          totalComplete: Number(p?.累计完成数),
+          groupComplete: Number(p?.本组完成数),
+        }
+      }
+    }
+  }
+  return { unfinished: NaN, totalComplete: NaN, groupComplete: NaN }
+}
+
 const buildWorkScoreConfirmRows = (reportData) => {
-  const rows = reportData.map(item => ({
-    工序编号: item.process_code,
-    工序名称: item.process_name,
-    员工姓名: item.staff_name,
-    完工数量: item.number,
-  }))
+  // 同一部件+工序多人报工时,按合计完工数再算超出
+  const processQtySum = {}
+  for (const item of reportData) {
+    const key = `${item.part_code}||${item.process_code}||${item.process_name}`
+    processQtySum[key] = (processQtySum[key] || 0) + (Number(item.number) || 0)
+  }
+
+  const rows = reportData.map((item) => {
+    const key = `${item.part_code}||${item.process_code}||${item.process_name}`
+    const progress = findProcessProgressByCode(item.process_code, item.process_name)
+    const unfinished = progress.unfinished
+    const groupComplete = progress.groupComplete
+    const totalComplete = progress.totalComplete
+    const hasUnfinished = Number.isFinite(unfinished)
+    const hasGroupComplete = Number.isFinite(groupComplete)
+    const hasTotalComplete = Number.isFinite(totalComplete)
+    const sumQty = processQtySum[key] || 0
+    const excess = hasUnfinished ? Math.max(0, sumQty - unfinished) : 0
+    return {
+      部件: resolvePartLabel(item.part_code),
+      工序编号: item.process_code,
+      工序名称: item.process_name,
+      本组完成数: hasGroupComplete ? groupComplete : '',
+      累计完成数: hasTotalComplete ? totalComplete : '',
+      未完成数量: hasUnfinished ? unfinished : '',
+      员工姓名: item.staff_name,
+      完工数量: item.number,
+      超出数量: excess > 0 ? excess : '',
+      _isOver: excess > 0,
+    }
+  })
   return recomputeWorkScoreConfirmRowSpan(rows)
 }
 
 const workScoreConfirmSpanMethod = ({ row, column }) => {
-  if (column.property !== '工序编号' && column.property !== '工序名称') {
+  const mergeProps = ['部件', '工序编号', '工序名称', '本组完成数', '累计完成数', '未完成数量', '超出数量']
+  if (!mergeProps.includes(column.property)) {
     return { rowspan: 1, colspan: 1 }
   }
   const rowspan = row._processRowSpan || 0
@@ -1307,6 +1462,12 @@ const workScoreConfirmSpanMethod = ({ row, column }) => {
   return { rowspan: 0, colspan: 0 }
 }
 
+const workScoreConfirmCellClass = ({ row, column }) => {
+  if (column.property === '超出数量' && row._isOver) return 'work-score-confirm-over-cell'
+  if (column.property === '完工数量' && row._isOver) return 'work-score-confirm-over-cell'
+  return ''
+}
+
 const submitWorkScore = () => {
   const reportData = buildWorkScoreReportData()
   if (!reportData) return
@@ -1420,7 +1581,6 @@ const _list = ref('');
 //订单信息数据
 const orderInfoList = reactive([]);
 /** 当前已加载订单编号(红框订单信息区,与搜索 input 解耦) */
-const currentOrderNo = ref('')
 const processProductionRef = ref(null)
 const processProductionRefreshKey = ref(0)
 
@@ -1547,6 +1707,156 @@ const deleteReportingWork = async (row) => {
   }
 };
 
+const editReportingQtyVisible = ref(false)
+const editReportingQtyLoading = ref(false)
+const editReportingQtyInputRef = ref(null)
+const editReportingQtyForm = ref({
+  id: '',
+  number: '',
+  original_number: '',
+  process_code: '',
+  process_name: '',
+  part_code: '',
+  unfinished: '',
+  standard_hour: '',
+  standard_score: '',
+  production_hour: '',
+  production_score: '',
+})
+
+const isEditReportingQtyOver = computed(() => {
+  const unfinished = Number(editReportingQtyForm.value.unfinished)
+  const original = Number(editReportingQtyForm.value.original_number) || 0
+  const qty = Number(editReportingQtyForm.value.number)
+  if (!Number.isFinite(unfinished) || !Number.isFinite(qty) || !qty) return false
+  // 未完成数已扣除本条原数量,可改上限 = 未完成数 + 原数量
+  return qty > unfinished + original
+})
+
+const focusEditReportingQtyInput = () => {
+  nextTick(() => {
+    const comp = editReportingQtyInputRef.value
+    const el = comp?.input || comp?.textarea || comp?.$el?.querySelector?.('input')
+    if (el && typeof el.focus === 'function') {
+      el.focus()
+      const len = String(el.value ?? '').length
+      try {
+        el.setSelectionRange(len, len)
+      } catch (_) { /* ignore */ }
+      return
+    }
+    comp?.focus?.()
+  })
+}
+
+const resolveUnfinishedForEditRow = async (row) => {
+  const processCode = String(row.process_code ?? row['工序编号'] ?? row['工序号'] ?? '').trim()
+  const processName = String(row.process_name ?? row['工序名称'] ?? '').trim()
+  const fromRow = Number(row.未完成数 ?? row.unfinished ?? row['未完成数量'])
+  if (Number.isFinite(fromRow)) return fromRow
+
+  const loaded = findProcessProgressByCode(processCode, processName)
+  if (Number.isFinite(loaded.unfinished)) return loaded.unfinished
+
+  const partCode = String(row.part_code ?? row['部件编号'] ?? '').trim()
+  if (!partCode || !getActiveOrderNo()) return ''
+
+  try {
+    const carParams = {
+      workorder: getActiveOrderNo(),
+      part_code: partCode,
+      majorprocess: add_formData['工序'],
+    }
+    const sysId = String(add_formData['组别'] || '').trim()
+    if (sysId) carParams.sys_id = sysId
+    const response = await GetCarProcess(carParams)
+    if (response.code !== 0 || !response.data) return ''
+    const processList = normalizeWorkScoreProcessList(response.data)
+    const hit = (processList || []).find((p) => {
+      const pCode = String(p?.['工艺编号'] ?? '').trim()
+      const pName = String(p?.['工艺名称'] ?? '').trim()
+      return processCode && pCode === processCode && (!processName || pName === processName)
+    })
+    const unfinished = Number(hit?.['未完成数'])
+    return Number.isFinite(unfinished) ? unfinished : ''
+  } catch (e) {
+    console.error('获取未完成数失败:', e)
+    return ''
+  }
+}
+
+const openEditReportingQty = async (row) => {
+  const id = row?.id ?? row?.ID
+  if (id === undefined || id === null || id === '') {
+    ElMessage.warning('缺少报工记录ID,无法修改')
+    return
+  }
+  const number = filterQtyDigits(String(row.number ?? row['数量'] ?? ''))
+  editReportingQtyForm.value = {
+    id,
+    number,
+    original_number: number,
+    process_code: String(row.process_code ?? row['工序编号'] ?? row['工序号'] ?? ''),
+    process_name: String(row.process_name ?? row['工序名称'] ?? ''),
+    part_code: String(row.part_code ?? row['部件编号'] ?? ''),
+    unfinished: '',
+    standard_hour: row.standard_hour ?? row['标准工时'] ?? '',
+    standard_score: row.standard_score ?? row['标准工分'] ?? row['标准分数'] ?? '',
+    production_hour: row.production_hour ?? row['生产工时'] ?? '',
+    production_score: row.production_score ?? row['生产分数'] ?? row['生产工分'] ?? '',
+  }
+  editReportingQtyVisible.value = true
+  const unfinished = await resolveUnfinishedForEditRow(row)
+  if (editReportingQtyForm.value.id === id) {
+    editReportingQtyForm.value.unfinished = unfinished === '' ? '' : String(unfinished)
+  }
+}
+
+const submitEditReportingQty = async () => {
+  const numberStr = String(editReportingQtyForm.value.number ?? '').trim()
+  const qty = Number(numberStr)
+  if (!numberStr || Number.isNaN(qty) || qty <= 0) {
+    ElMessage.warning('请输入大于 0 的数量')
+    return
+  }
+
+  const stdHour = Number(editReportingQtyForm.value.standard_hour)
+  const stdScore = Number(editReportingQtyForm.value.standard_score)
+  let production_hour = String(editReportingQtyForm.value.production_hour ?? '')
+  let production_score = String(editReportingQtyForm.value.production_score ?? '')
+  if (Number.isFinite(stdHour) && stdHour > 0) {
+    production_hour = (qty * stdHour).toFixed(2)
+  }
+  if (Number.isFinite(stdScore) && stdScore > 0) {
+    production_score = (qty * stdScore).toFixed(2)
+  }
+
+  const mod_id = userStore.userInfo?.nickName || userStore.userInfo?.userName || ''
+
+  editReportingQtyLoading.value = true
+  try {
+    const res = await UpdateReportingWork({
+      id: editReportingQtyForm.value.id,
+      number: String(qty),
+      production_hour,
+      production_score,
+      mod_id,
+    })
+    if (res?.code === 0) {
+      ElMessage.success(res.msg || '修改成功')
+      editReportingQtyVisible.value = false
+      await getGongfenHistory()
+    } else {
+      ElMessage.error(res?.msg || '修改失败')
+    }
+  } catch (e) {
+    console.error(e)
+    ElMessage.error(e?.response?.data?.msg || e?.message || '修改失败')
+  } finally {
+    editReportingQtyLoading.value = false
+  }
+}
+
 // 复选框选择
 const fjSelectionChange = (selection) => {
   console.log('选中的附件:', selection);
@@ -2226,8 +2536,9 @@ const warningres = (arr) => {
   font-size: 15px;
   color: #606266;
 }
-:deep(.work-score-confirm-dialog .el-dialog__body) {
-  padding-top: 8px;
+:deep(.work-score-confirm-over-cell) {
+  color: #f56c6c !important;
+  font-weight: 600;
 }
 .work-score-process-table-wrap :deep(.work-score-process-table .el-input__inner) {
   height: 30px;
@@ -2235,11 +2546,14 @@ const warningres = (arr) => {
 }
 .work-score-process-table-wrap :deep(.work-score-qty-input .el-input__inner) {
   height: 30px;
-  font-size: 15px;
+  font-size: 18px;
   font-weight: 600;
   text-align: center;
   color: #303133;
 }
+.work-score-process-table-wrap :deep(.work-score-qty-over .el-input__inner) {
+  color: #f56c6c !important;
+}
 .work-score-process-table-wrap :deep(.work-score-staff-input .el-input__inner) {
   height: 30px;
   font-size: 14px;
@@ -2698,6 +3012,113 @@ const warningres = (arr) => {
 </style>
 
 <style>
+/* 确认报工弹窗:固定尺寸 + 内容居中放大(append-to-body 用全局样式) */
+.work-score-confirm-dialog.el-dialog,
+.work-score-confirm-dialog {
+  width: 1040px !important;
+  margin-top: 8vh !important;
+}
+.work-score-confirm-dialog .el-dialog__header {
+  padding: 12px 12px 6px;
+}
+.work-score-confirm-dialog .el-dialog__title {
+  font-size: 20px;
+  font-weight: 600;
+}
+.work-score-confirm-dialog .el-dialog__body {
+  padding: 4px 12px 4px;
+  height: 556px;
+  box-sizing: border-box;
+  overflow: hidden;
+}
+.work-score-confirm-dialog .work-score-confirm-tip {
+  margin: 0 0 6px;
+  text-align: center;
+  font-size: 18px;
+  font-weight: 600;
+  color: #303133;
+  line-height: 1.3;
+}
+.work-score-confirm-dialog .work-score-confirm-table {
+  font-size: 15px;
+  width: 100% !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__inner-wrapper::before {
+  display: none;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header-wrapper,
+.work-score-confirm-dialog .work-score-confirm-table .el-table__body-wrapper {
+  overflow-x: hidden !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-scrollbar__bar.is-horizontal {
+  display: none !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header th {
+  color: #000 !important;
+  font-weight: 600;
+  font-size: 15px;
+  padding: 4px 0 !important;
+  height: 32px !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header th .cell {
+  color: #000 !important;
+  font-weight: 600;
+  line-height: 22px;
+  padding: 0 6px !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__body td {
+  font-size: 15px;
+  padding: 2px 0 !important;
+  height: 32px !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .cell {
+  line-height: 22px;
+  padding: 0 6px !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header th.is-center,
+.work-score-confirm-dialog .work-score-confirm-table .el-table__body td.is-center {
+  text-align: center !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header th.is-center .cell,
+.work-score-confirm-dialog .work-score-confirm-table .el-table__body td.is-center .cell {
+  text-align: center !important;
+  justify-content: center;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header th.is-left,
+.work-score-confirm-dialog .work-score-confirm-table .el-table__body td.is-left {
+  text-align: left !important;
+}
+.work-score-confirm-dialog .work-score-confirm-table .el-table__header th.is-left .cell,
+.work-score-confirm-dialog .work-score-confirm-table .el-table__body td.is-left .cell {
+  text-align: left !important;
+  justify-content: flex-start;
+}
+.work-score-confirm-dialog .work-score-confirm-over-cell {
+  color: #f56c6c !important;
+  font-weight: 600;
+  font-size: 17px !important;
+}
+.work-score-confirm-dialog .el-dialog__footer {
+  padding: 8px 12px 12px;
+}
+.work-score-confirm-dialog .el-dialog__footer .el-button {
+  min-width: 100px;
+  font-size: 15px;
+}
+.work-score-confirm-dialog .el-table__body tr:hover > td {
+  background-color: var(--el-table-tr-bg-color, #fff) !important;
+}
+.work-score-confirm-dialog .el-table__body tr.el-table__row--striped:hover > td {
+  background-color: var(--el-fill-color-lighter, #fafafa) !important;
+}
+
+/* 修改数量弹窗:超出未完成数时数量变红 */
+.edit-reporting-qty-dialog .edit-reporting-qty-over .el-input__inner,
+.edit-reporting-qty-dialog .edit-reporting-qty-over .el-input__wrapper input {
+  color: #f56c6c !important;
+  font-weight: 600;
+}
+
 .custom-warning-message {
   background: transparent !important;
   border: none !important;

+ 106 - 82
src/view/yunyin/shengchanguanli/gongdanziliao.vue

@@ -77,8 +77,8 @@
 				  <el-table-column align="left"   label="客户"     prop="客户编号" 		width="68" />
 				  <el-table-column align="left"   label="款号"     prop="生产款号"  width="200" />
 				  <el-table-column align="left"   label="款式"     prop="款式"   	width="100"/> 
-				  <el-table-column align="left"   label="数量"     prop="订单数量" 	width="60" />
-				  <el-table-column align="center" label="状态" 	   prop="gd_statu" width="85" sortable>
+				  <el-table-column align="left"   label="数量"     prop="订单数量" 	width="70" />
+				  <el-table-column align="center" label="状态" 	   prop="gd_statu" width="125" sortable>
 				      <template #default="{ row }">
 				        <el-tag :type="row.gd_statu === '1-计划中' ? 'warning' : 
 				                       (row.gd_statu === '已裁剪' ? 'primary' : 
@@ -450,8 +450,11 @@
              <el-date-picker
                v-model="gyDetailFormData.工单完工日期"
                type="date"
-               style="width: 120px;"
-               @blur="handleGyDetailFinishDateBlur"
+               value-format="YYYY-MM-DD"
+               format="YYYY-MM-DD"
+               clearable
+               placeholder="选择日期"
+               style="width: 140px;"
              />
            </div>
            <div style="display: flex; align-items: center; white-space: nowrap;">
@@ -464,10 +467,12 @@
 		               @click="startGyDetailPlanManufactureEdit"
 		             >计划制造工分:</span>
 		             <el-input
-		               v-model="gyDetailFormData.计划制造工分"
+		               :model-value="gyDetailFormData.计划制造工分"
 		               style="width: 80px;"
 		               :readonly="!gyDetailPlanManufactureEditing"
+		               inputmode="decimal"
 		               @click="startGyDetailPlanManufactureEdit"
+		               @update:model-value="onGyDetailPlanManufactureInput"
 		             />
 		             <template v-if="gyDetailPlanManufactureEditing">
                        <el-button style="margin-left: 10px;" @click="cancelGyDetailPlanManufactureEdit">取消</el-button>
@@ -488,8 +493,8 @@
 		           :height="gyDetailTableHeight"
 		           :min-width="gyDetailTableMinWidth"
 		           :data="gyDetailDisplayProcessList"
-		           :row-config="{ keyField: '_rowKey', isHover: true, isCurrent: true, height: 24 }"
-		           :cell-config="{ height: 24, padding: false }"
+		           :row-config="{ keyField: '_rowKey', isHover: true, isCurrent: true, height: 28 }"
+		           :cell-config="{ height: 28, padding: false }"
 		           :scroll-y="{ enabled: true, gt: 30 }"
 		           :scroll-x="{ enabled: true }"
 		           :column-config="{ resizable: true, minWidth: 56 }"
@@ -663,7 +668,7 @@
 		               </template>
 		             </template>
 		           </vxe-column>
-		           <vxe-column field="备注" title="备注" width="120" align="center" header-align="center">
+		           <vxe-column field="备注" title="备注" width="140" align="center" header-align="center">
 		             <template #default="{ row }">
 		               <span v-if="gyDetailReadonly">{{ row.备注 }}</span>
 		               <template v-else>
@@ -697,11 +702,12 @@
 		               </div>
 		             </template>
 		             <template #default="{ row }">
-		               <span>{{ formatGyDetailStatus(row.状态) }}</span>
+		               <div class="gy-detail-status-cell">{{ formatGyDetailStatus(row.状态) }}</div>
 		             </template>
 		           </vxe-column>
 		           <vxe-column field="_gyAction" title="操作" width="100" fixed="right" align="center" header-align="center">
 		             <template #default="{ row }">
+		               <div class="gy-detail-action-cell">
 		               <el-button
 		                 v-if="isGyDetailRowSplit(row)"
 		                 size="small"
@@ -714,6 +720,7 @@
 		                 type="success"
 		                 @click="handleSplitProcess(row)"
 		               >拆分</el-button>
+		               </div>
 		             </template>
 		           </vxe-column>
 		         </vxe-table>
@@ -993,7 +1000,7 @@
 					:limit="1"
 					accept="image/jpeg,image/png"
 				  >
-					<i class="el-icon-plus"></i>
+					<el-icon class="add-order-upload-plus"><Plus /></el-icon>
 				  </el-upload>
 				  <div class="add-order-upload-title">上传图片</div>
 				</div>
@@ -1381,7 +1388,7 @@
 					:limit="1"
 					accept="image/jpeg,image/png"
 				  >
-					<i class="el-icon-plus"></i>
+					<el-icon class="add-order-upload-plus"><Plus /></el-icon>
 				  </el-upload>
 				  <div class="add-order-upload-title">上传图片</div>
 				</div>
@@ -2510,6 +2517,7 @@
   import 'element-plus/es/components/upload/style/css'
   import 'element-plus/es/components/button/style/css'
   import 'element-plus/es/components/image-viewer/style/css'
+  import { Plus } from '@element-plus/icons-vue'
   import { ref, reactive, computed, nextTick, watch, onMounted, onBeforeUnmount, isRef } from 'vue'
   import axios from 'axios';
   import * as XLSX from 'xlsx';
@@ -3018,14 +3026,17 @@
 	  updateTotal()
   };
   
-  //自动计算制单数总计
+  //自动计算制单数总计(仅数字,自动去掉空格及其他字符)
   function updateTotal() {  
-	// 直接指定要累加的属性名  
-	const relevantKeys = ['zds1', 'zds2', 'zds3', 'zds4', 'zds5', 'zds6', 'zds7', 'zds8', 'zds9', 'zds10', 'zds11', 'zds12', 'zds13', 'zds14'];  
-	const values = relevantKeys.map(key => parseInt(zdsformdata[key], 10) || 0); // 使用 || 0 来处理可能的 NaN 或 undefined/null  
-	zdsformdata.zdtotal = values.reduce((sum, value) => sum + value, 0);  
-	const valuess = relevantKeys.map(key => parseInt(edit_zdsformdata[key], 10) || 0); // 使用 || 0 来处理可能的 NaN 或 undefined/null  
-	edit_zdsformdata.zdtotal = valuess.reduce((sum, value) => sum + value, 0);  
+	const relevantKeys = ['zds1', 'zds2', 'zds3', 'zds4', 'zds5', 'zds6', 'zds7', 'zds8', 'zds9', 'zds10', 'zds11', 'zds12', 'zds13', 'zds14'];
+	relevantKeys.forEach((key) => {
+	  zdsformdata[key] = String(zdsformdata[key] ?? '').replace(/[^\d]/g, '')
+	  edit_zdsformdata[key] = String(edit_zdsformdata[key] ?? '').replace(/[^\d]/g, '')
+	})
+	const values = relevantKeys.map(key => parseInt(zdsformdata[key], 10) || 0);
+	zdsformdata.zdtotal = values.reduce((sum, value) => sum + value, 0);
+	const valuess = relevantKeys.map(key => parseInt(edit_zdsformdata[key], 10) || 0);
+	edit_zdsformdata.zdtotal = valuess.reduce((sum, value) => sum + value, 0);
   }  
   
   //点击是否船样 改变子订单编号
@@ -3041,7 +3052,7 @@
   
   //修改颜色资料确认
   const ys_edit_Dialog = async () => {
-	  
+	  updateTotal()
 	  if (!edit_formData.value) return;
 	  
 	  //获取颜色编号id
@@ -3681,6 +3692,7 @@ function Input_handle() {
 
   //新增颜色资料确定
   const add_gdyjenterDialog =  async  () => {
+	  updateTotal()
 	  //必填
 	  if(add_yszlformdata['kh'] === ''){
 		  ElMessage({type: 'warning',message: '款号不能为空'})
@@ -5074,7 +5086,7 @@ const sortTableData = ref([])
     审核: '',
     订单数量: '',
     计划制造工分: '',
-    工单完工日期: '',
+    工单完工日期: null,
     备注: '',
     Sys_id: '',
     Sys_rq: '',
@@ -5149,7 +5161,8 @@ const sortTableData = ref([])
         gyDetailFormData.制单人 = sysId.includes('/') ? sysId.split('/')[1] : sysId
         gyDetailFormData.订单数量 = data['订单数量'] || ''
         gyDetailFormData.计划制造工分 = data['计划制造工分'] || ''
-        gyDetailFormData.工单完工日期 = data['工单完工日期'] || ''
+        const finishDateRaw = String(data['工单完工日期'] || '').trim()
+        gyDetailFormData.工单完工日期 = finishDateRaw || null
         gyDetailFormData.备注 = data['remark'] || ''
         gyDetailFormData.Sys_id = data['Sys_id'] || data['sys_id'] || row?.['Sys_id'] || row?.['sys_id'] || ''
         gyDetailFormData.Sys_rq = data['Sys_rq'] || data['sys_rq'] || ''
@@ -6319,6 +6332,15 @@ const sortTableData = ref([])
   const gyDetailFinishDateBackup = ref('')
   const gyDetailPlanManufactureSaving = ref(false)
 
+  const onGyDetailPlanManufactureInput = (val) => {
+    let s = String(val ?? '').replace(/[^\d.]/g, '')
+    const dot = s.indexOf('.')
+    if (dot !== -1) {
+      s = s.slice(0, dot + 1) + s.slice(dot + 1).replace(/\./g, '')
+    }
+    gyDetailFormData.计划制造工分 = s
+  }
+
   const startGyDetailPlanManufactureEdit = () => {
     if (gyDetailPlanManufactureEditing.value) return
     // 邢科芳账号不能修改计划制造工分
@@ -6340,14 +6362,7 @@ const sortTableData = ref([])
   const confirmGyDetailPlanManufactureEdit = async () => {
     gyDetailPlanManufactureSaving.value = true
     try {
-      let finishDate = ''
-      if (gyDetailFormData.工单完工日期) {
-        const date = new Date(gyDetailFormData.工单完工日期)
-        const year = date.getFullYear()
-        const month = String(date.getMonth() + 1).padStart(2, '0')
-        const day = String(date.getDate()).padStart(2, '0')
-        finishDate = `${year}-${month}-${day}`
-      }
+      const finishDate = String(gyDetailFormData.工单完工日期 || '').trim()
       
       const updatePromises = []
       
@@ -6394,46 +6409,13 @@ const sortTableData = ref([])
     }
   }
 
-  const handleGyDetailFinishDateBlur = async () => {
-    try {
-      let finishDate = ''
-      if (gyDetailFormData.工单完工日期) {
-        const date = new Date(gyDetailFormData.工单完工日期)
-        const year = date.getFullYear()
-        const month = String(date.getMonth() + 1).padStart(2, '0')
-        const day = String(date.getDate()).padStart(2, '0')
-        finishDate = `${year}-${month}-${day}`
-      }
-      
-      const res = await updateOrderRemarkAndFinishDate({
-        id: gyDetailFormData.Uniqid,
-        remark: gyDetailFormData.备注,
-        工单完工日期: finishDate,
-        sys_id: userStore.userInfo.nickName
-      })
-      
-      if (res?.code === 0) {
-        ElMessage.success('保存成功')
-      } else {
-        ElMessage.error('保存失败')
-      }
-    } catch (e) {
-      console.error('保存失败', e)
-      ElMessage.error('保存失败')
-    }
-  }
+  // 工单完工日期仅前端选择,不在失焦时调接口(随保存一并提交)
+  const handleGyDetailFinishDateBlur = async () => {}
 
   const handleGyDetailRemarkBlur = async () => {
     try {
       // 格式化日期为 YYYY-MM-DD 格式
-      let finishDate = ''
-      if (gyDetailFormData.工单完工日期) {
-        const date = new Date(gyDetailFormData.工单完工日期)
-        const year = date.getFullYear()
-        const month = String(date.getMonth() + 1).padStart(2, '0')
-        const day = String(date.getDate()).padStart(2, '0')
-        finishDate = `${year}-${month}-${day}`
-      }
+      const finishDate = String(gyDetailFormData.工单完工日期 || '').trim()
       
       await updateOrderRemarkAndFinishDate({
         id: gyDetailFormData.Uniqid,
@@ -8628,7 +8610,7 @@ const sortTableData = ref([])
     --vxe-table-row-current-background-color: #ff80ff;
     --vxe-table-row-hover-current-background-color: #ff80ff;
     --vxe-ui-table-row-current-background-color: #ff80ff;
-    --vxe-table-row-height: 24px;
+    --vxe-table-row-height: 28px;
     --vxe-table-cell-padding-left: 4px;
     --vxe-table-cell-padding-right: 4px;
     font-size: 13px;
@@ -8637,8 +8619,8 @@ const sortTableData = ref([])
   :deep(.gy-detail-vxe-table .vxe-table--body-wrapper .vxe-body--row),
   :deep(.gy-detail-vxe-table .vxe-table--header-wrapper .vxe-header--row),
   :deep(.gy-detail-vxe-table .vxe-table--footer-wrapper .vxe-footer--row) {
-    height: 24px !important;
-    line-height: 24px !important;
+    height: 28px !important;
+    line-height: 28px !important;
   }
 
   :deep(.gy-detail-vxe-table .vxe-header--column),
@@ -8648,9 +8630,42 @@ const sortTableData = ref([])
   :deep(.gy-detail-vxe-table .vxe-table--header-wrapper .vxe-header--cell),
   :deep(.gy-detail-vxe-table .vxe-table--footer-wrapper .vxe-footer--cell) {
     font-size: 13px;
-    height: 24px !important;
-    line-height: 24px !important;
+    height: 28px !important;
+    line-height: 28px !important;
     padding: 0 4px !important;
+    vertical-align: middle !important;
+  }
+
+  /* 单元格内容垂直居中,编辑框贴齐格子 */
+  :deep(.gy-detail-vxe-table .vxe-body--column .vxe-cell) {
+    display: flex !important;
+    align-items: center !important;
+    height: 100% !important;
+    min-height: 28px !important;
+    max-height: 28px !important;
+    overflow: hidden !important;
+    box-sizing: border-box !important;
+  }
+
+  /* align=center / 固定操作列:水平居中 */
+  :deep(.gy-detail-vxe-table .col--center .vxe-cell),
+  :deep(.gy-detail-vxe-table .vxe-header--column.col--center .vxe-cell),
+  :deep(.gy-detail-vxe-table .vxe-body--column.col--center .vxe-cell),
+  :deep(.gy-detail-vxe-table .vxe-footer--column.col--center .vxe-cell),
+  :deep(.gy-detail-vxe-table .col--fixed-right .vxe-cell),
+  :deep(.gy-detail-vxe-table .vxe-header--column.col--fixed-right .vxe-cell),
+  :deep(.gy-detail-vxe-table .vxe-body--column.col--fixed-right .vxe-cell),
+  :deep(.gy-detail-vxe-table .vxe-footer--column.col--fixed-right .vxe-cell) {
+    justify-content: center !important;
+    text-align: center !important;
+  }
+
+  .gy-detail-status-cell,
+  .gy-detail-action-cell {
+    width: 100%;
+    display: flex;
+    align-items: center;
+    justify-content: center;
   }
 
   :deep(.gy-detail-vxe-table .col--checkbox .vxe-cell),
@@ -8714,9 +8729,9 @@ const sortTableData = ref([])
   }
 
   .gy-detail-cell {
-    min-height: 22px;
-    height: 22px;
-    line-height: 22px;
+    min-height: 24px;
+    height: 24px;
+    line-height: 24px;
     padding: 0 4px;
     cursor: text;
     border-radius: 2px;
@@ -8726,17 +8741,19 @@ const sortTableData = ref([])
     text-align: center;
     color: var(--el-text-color-primary);
     box-sizing: border-box;
+    width: 100%;
   }
 
   .gy-detail-cell--wide {
     white-space: nowrap;
-    line-height: 22px;
-    min-height: 22px;
-    height: 22px;
+    line-height: 24px;
+    min-height: 24px;
+    height: 24px;
     display: flex;
     align-items: center;
     justify-content: flex-start;
     text-align: left;
+    width: 100%;
   }
 
   .gy-detail-cell:hover {
@@ -8751,24 +8768,31 @@ const sortTableData = ref([])
 
   .gy-detail-cell-input {
     width: 100%;
+    flex: 1;
+    min-width: 0;
+    position: relative;
+    z-index: 2;
   }
 
   .gy-detail-cell-select {
     display: block;
+    width: 100%;
   }
 
   .gy-detail-vxe-table .gy-detail-cell-select .el-select__wrapper {
-    min-height: 22px !important;
-    height: 22px !important;
-    padding: 0 4px;
+    min-height: 24px !important;
+    height: 24px !important;
+    padding: 0 6px;
     box-shadow: 0 0 0 1px var(--el-color-primary) inset;
+    box-sizing: border-box;
   }
 
   .gy-detail-vxe-table .gy-detail-cell-input .el-input__wrapper {
-    min-height: 22px !important;
-    height: 22px !important;
-    padding: 0 4px;
+    min-height: 24px !important;
+    height: 24px !important;
+    padding: 0 6px;
     box-shadow: 0 0 0 1px var(--el-color-primary) inset;
+    box-sizing: border-box;
   }
 
   .gy-detail-vxe-table .gy-detail-cell-input .el-input__inner {

+ 40 - 1
src/view/yunyin/shengchanguanli/yuedudahuoshengchanjindu.vue

@@ -48,7 +48,13 @@
 			 			<el-table-column   align="left" label="大烫完成数" prop="大烫"  width="90" />
 			 			<el-table-column   align="left" label="总检完成数" prop="总检"  width="90" />
 			 			<el-table-column   align="left" label="包装完成数" prop="包装"  width="90" />
-						<el-table-column   align="left" label="订单状态" prop="订单状态"  width="100" />
+						<el-table-column align="center" label="订单状态" prop="订单状态" width="125">
+						  <template #default="{ row }">
+						    <el-tag v-if="row.订单状态" :type="getOrderStatusTagType(row.订单状态)">
+						      {{ formatOrderStatusLabel(row.订单状态) }}
+						    </el-tag>
+						  </template>
+						</el-table-column>
 						<el-table-column   align="left" label="落货日期" prop="落货日期"  width="160" />
 			 			<el-table-column   align="left" label="日期" prop="日期"  width="90" />
 			  </el-table>
@@ -117,6 +123,39 @@ const seconds = String(today.getSeconds()).padStart(2, '0');
 const currentDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
 const currentDates = `${year}-${month}-${day}`;
 
+/** 订单状态样式:与订单资料管理「状态」列一致 */
+const getOrderStatusTagType = (status) => {
+  const s = String(status ?? '')
+  if (s === '1-计划中') return 'warning'
+  if (s === '已裁剪' || s === '已开裁') return 'primary'
+  if (s === '已车缝') return ''
+  if (s === '2-生产中') return 'success'
+  if (s.includes('总检已') || s.includes('已总检')) {
+    const n = parseInt(s.match(/\d+/)?.[0] ?? '0', 10)
+    return n >= 95 ? 'success' : 'info'
+  }
+  if (s === '已完工') return 'success'
+  return 'info'
+}
+
+const formatOrderStatusLabel = (status) => {
+  const s = String(status ?? '')
+  if (s === '1-计划中') return '计划中'
+  if (s === '已裁剪') return '已裁剪'
+  if (s === '已开裁') return '已开裁'
+  if (s === '已车缝') return '已车缝'
+  if (s === '2-生产中') return '生产中'
+  if (s.includes('总检已')) {
+    const n = parseInt(s.match(/\d+/)?.[0] ?? '0', 10)
+    return n >= 95 ? '已完工' : s.replace('总检已', '总检')
+  }
+  if (s.includes('已总检')) {
+    const n = parseInt(s.match(/\d+/)?.[0] ?? '0', 10)
+    return n >= 95 ? '已完工' : s
+  }
+  return s
+}
+
 // =========== 获取左侧树侧形结构 ===========
 const treeData = ref([]);  
 const _department_code = ref(null);