m0_70156489 11 saat önce
ebeveyn
işleme
9c7750a64b

+ 47 - 57
src/view/performance/WorkScoreReporting/gongfenbaogong.vue

@@ -1523,7 +1523,7 @@ const confirmSubmitWorkScore = async () => {
     const response = await ReportingWork(pendingReportData.value)
 
     if (response.code === 0) {
-      ElMessage.success('提交成功')
+      yellowTopTip('提交成功')
       workScoreConfirmVisible.value = false
       workScoreDialogVisible.value = false
       await getGongfenHistory()
@@ -1791,7 +1791,7 @@ const deleteReportingWork = async (row) => {
     
     const deleteId = row?.id ?? row?.ID
     if (deleteId === undefined || deleteId === null || deleteId === '') {
-      ElMessage.warning('缺少报工记录ID,无法删除')
+      warningres('缺少报工记录ID,无法删除')
       return
     }
     const response = await DeleteReportingWork({
@@ -1799,16 +1799,16 @@ const deleteReportingWork = async (row) => {
     });
     
     if (response.code === 0) {
-      ElMessage.success('删除成功');
+      yellowTopTip('删除成功')
       await getGongfenHistory();
       await refreshProcessProduction();
     } else {
-      ElMessage.error(response.msg || '删除失败');
+      errorres(response.msg || '删除失败');
     }
   } catch (error) {
     if (error !== 'cancel') {
       console.error('删除报工记录失败:', error);
-      ElMessage.error('删除失败');
+      errorres('删除失败');
     }
   }
 };
@@ -1894,7 +1894,7 @@ const resolveUnfinishedForEditRow = async (row) => {
 const openEditReportingQty = async (row) => {
   const id = row?.id ?? row?.ID
   if (id === undefined || id === null || id === '') {
-    ElMessage.warning('缺少报工记录ID,无法修改')
+    warningres('缺少报工记录ID,无法修改')
     return
   }
   const number = filterQtyDigits(String(row.number ?? row['数量'] ?? ''))
@@ -1922,7 +1922,7 @@ const submitEditReportingQty = async () => {
   const numberStr = String(editReportingQtyForm.value.number ?? '').trim()
   const qty = Number(numberStr)
   if (!numberStr || Number.isNaN(qty) || qty <= 0) {
-    ElMessage.warning('请输入大于 0 的数量')
+    warningres('请输入大于 0 的数量')
     return
   }
 
@@ -1949,16 +1949,16 @@ const submitEditReportingQty = async () => {
       mod_id,
     })
     if (res?.code === 0) {
-      ElMessage.success(res.msg || '修改成功')
+      yellowTopTip(res.msg || '修改成功')
       editReportingQtyVisible.value = false
       await getGongfenHistory()
       await refreshProcessProduction()
     } else {
-      ElMessage.error(res?.msg || '修改失败')
+      errorres(res?.msg || '修改失败')
     }
   } catch (e) {
     console.error(e)
-    ElMessage.error(e?.response?.data?.msg || e?.message || '修改失败')
+    errorres(e?.response?.data?.msg || e?.message || '修改失败')
   } finally {
     editReportingQtyLoading.value = false
   }
@@ -2064,60 +2064,47 @@ const handleSizeChange = (val) => {
 
 
 
-// 成功 / 失败 / 警告(支持单行字符串或多行数组)
-const buildLargeMessageHtml = (content, bgColor, textColor = '#000') => {
-  const lines = Array.isArray(content) ? content : [String(content || '')]
-  const linesHtml = lines.map((line, index) => {
-    const fontSize = lines.length > 1 && index === 0 ? '56px' : '48px'
-    return `<div style="font-size:${fontSize};line-height:1.35;font-weight:700;color:${textColor};white-space:nowrap;">${line}</div>`
-  }).join('')
-  return `<div style="background-color:${bgColor};padding:28px 40px;text-align:center;display:inline-block;">${linesHtml}</div>`
-}
-
-// 成功
-const successres = (arr) => {
-    ElMessage({
-        type: '',
-        dangerouslyUseHTMLString: true,
-        message: buildLargeMessageHtml(arr, '#80FA80'),
-        customClass: 'custom-warning-message'
-    });
-}
-
-// 失败
-const errorres = (arr) => {
-    ElMessage({
-        type: '',
-        dangerouslyUseHTMLString: true,
-        message: buildLargeMessageHtml(arr, 'red', '#fff'),
-        customClass: 'custom-warning-message'
-    });
-}
+// 统一提示:顶部居中、固定宽度(与扫描框一带)
+const TIP_OFFSET = 90
+const TIP_WIDTH = 520
+const TIP_CLASS = 'custom-warning-message gongfen-unified-tip'
 
-// 警告
-const warningres = (arr) => {
-    ElMessage.closeAll()
-    ElMessage({
-        type: '',
-        dangerouslyUseHTMLString: true,
-        message: buildLargeMessageHtml(arr, '#f5ff2f'),
-        customClass: 'custom-warning-message'
-    });
+const buildTipHtml = (content, bgColor, textColor = '#000') => {
+  const lines = Array.isArray(content) ? content : [String(content || '')]
+  const linesHtml = lines.map((line) => (
+    `<div style="font-size:32px;line-height:1.35;font-weight:700;color:${textColor};word-break:break-word;white-space:normal;">${line}</div>`
+  )).join('')
+  return `<div style="background-color:${bgColor};padding:16px 24px;text-align:center;display:block;width:${TIP_WIDTH}px;box-sizing:border-box;border-radius:4px;">${linesHtml}</div>`
 }
 
-/** 机台相关:黄色弹窗缩小版,略往下避开顶栏 */
-const machineTip = (text) => {
-  const tip = text || '未获取到机台编号,重启电脑或重新打开系统尝试'
+const showUnifiedTip = (content, { bg = '#f5ff2f', color = '#000', duration = 3000 } = {}) => {
   ElMessage.closeAll()
   ElMessage({
     type: '',
     dangerouslyUseHTMLString: true,
-    duration: 4000,
-    offset: 110,
-    message: `<strong style="font-size: 28px; color: black; background-color: #f5ff2f; padding: 14px 36px; line-height: 1.4; text-align: center; display: inline-block; border-radius: 4px;">${tip}</strong>`,
-    customClass: 'custom-warning-message machine-tip-msg',
+    duration,
+    offset: TIP_OFFSET,
+    message: buildTipHtml(content, bg, color),
+    customClass: TIP_CLASS,
   })
 }
+
+const successres = (arr) => showUnifiedTip(arr, { bg: '#80FA80' })
+const errorres = (arr) => showUnifiedTip(arr, { bg: 'red', color: '#fff' })
+const warningres = (arr) => showUnifiedTip(arr, { bg: '#f5ff2f' })
+
+/** 机台相关:同位置黄色提示 */
+const machineTip = (text) => {
+  showUnifiedTip(
+    text || '未获取到机台编号,重启电脑或重新打开系统尝试',
+    { duration: 4000 }
+  )
+}
+
+/** 提交/修改/删除成功:同位置黄色提示 */
+const yellowTopTip = (text) => {
+  showUnifiedTip(String(text || '').trim() || '操作成功')
+}
 </script>
 
 <style scoped>
@@ -3305,9 +3292,12 @@ const machineTip = (text) => {
 .custom-warning-message .el-message__closeBtn {
   display: none !important;
 }
-.machine-tip-msg.el-message {
-  left: 68% !important;
+.gongfen-unified-tip.el-message {
+  left: 50% !important;
   transform: translateX(-50%) !important;
+  width: 520px !important;
+  min-width: 520px !important;
+  max-width: 520px !important;
 }
 
 .gy-detail-filter-popper {

+ 206 - 54
src/view/yunyin/shengchanguanli/MonthlySampleGarments.vue

@@ -11,8 +11,8 @@
         </layout-header>
 
         <layout>
-          <layout-sider :resize-directions="['right']" :width="190" style="margin-right: 10px;">
-            <div class="JKWTree-tree" style="height: 200px">
+          <layout-sider :resize-directions="['right']" :width="150" class="monthly-sample-sider">
+            <div class="JKWTree-tree">
               <h3>样衣生产月份</h3>
               <el-tree
                 ref="menuTreeRef"
@@ -32,10 +32,11 @@
           <el-main>
             <div class="gva-table-box">
               <el-table ref="multipleTable" style="width: 100%;height: 70vh" tooltip-effect="dark"
-                        :row-style="{ height: '25px' }" :header-cell-style="{ padding: '0px' }"
-                        :cell-style="{ padding: '0px' }" :header-row-style="{ height: '20px' }"
+                        :row-style="{ height: '32px' }" :header-cell-style="{ padding: '0px' }"
+                        :cell-style="{ padding: '0px' }" :header-row-style="{ height: '32px' }"
                         :data="tableData" border :row-key="rowKeyOf"
                         size="small"
+                        class="monthly-sample-table"
                         :cell-class-name="gxbgCellClass"
                         highlight-current-row="true"
                         @row-click="tableRowClick" :show-overflow-tooltip="true" 
@@ -52,7 +53,7 @@
                    <div v-else class="cell-span">{{ row.客户编号 || '\u00A0' }}</div>
                  </template>
                </el-table-column>
-               <el-table-column sortable align="center" label="款号" prop="款号" width="120">
+               <el-table-column sortable align="left" label="款号" prop="款号" width="140">
                  <template #default="{ row }">
                    <el-input v-if="isEditing(row, '款号')"
                              v-model="row.款号"
@@ -62,7 +63,7 @@
                    <div v-else class="cell-span">{{ row.款号 || '\u00A0' }}</div>
                  </template>
                </el-table-column>
-               <el-table-column sortable align="center" label="款式" prop="款式" width="90">
+               <el-table-column sortable align="left" label="款式" prop="款式" width="160">
                  <template #default="{ row }">
                    <el-input v-if="isEditing(row, '款式')"
                              v-model="row.款式"
@@ -177,8 +178,9 @@
                    <div v-else class="cell-span">{{ row.实际交办日期 || '\u00A0' }}</div>
                  </template>
                </el-table-column>
-               <el-table-column sortable align="center" label="备注" prop="备注" width="150">
+               <el-table-column sortable align="center" label="备注" prop="备注" width="200">
                  <template #default="{ row }">
+                  
                    <el-input v-if="isEditing(row, '备注')"
                              v-model="row.备注"
                              @blur="handleCellBlur(row, '备注')"
@@ -197,18 +199,33 @@
               </el-table>
 
               <div class="gva-pagination">
-                <el-pagination layout="total" :current-page="page" :page-size="pageSize"
-                 :total="total" @current-change="handleCurrentChange" @size-change="handleSizeChange" />
+                <el-pagination
+                  v-model:current-page="page"
+                  :page-size="pageSize"
+                  :total="total"
+                  layout="total, prev, pager, next, jumper"
+                  background
+                  @current-change="handleCurrentChange"
+                />
               </div>
 
-              <el-dialog title="修改记录" v-model="logDialogVisible" width="800px">
-                <el-table :data="logTableData" border size="small">
-                  <el-table-column prop="ModifyField" label="修改字段" width="120" />
-                  <el-table-column prop="OriginalValue" label="原值" width="150" />
-                  <el-table-column prop="Modified" label="新值" width="150" />
-                  <el-table-column prop="修改人" label="修改人" width="100" />
-                  <el-table-column prop="修改日期" label="修改日期" width="180" />
-                </el-table>
+              <el-dialog
+                title="修改记录"
+                v-model="logDialogVisible"
+                width="800px"
+                class="monthly-sample-log-dialog"
+                align-center
+                destroy-on-close
+              >
+                <div class="monthly-sample-log-body">
+                  <el-table :data="logTableData" border size="small" height="100%">
+                    <el-table-column prop="ModifyField" label="修改字段" width="120" align="center" header-align="center" />
+                    <el-table-column prop="OriginalValue" label="原值" width="150" align="center" header-align="center" />
+                    <el-table-column prop="Modified" label="新值" width="150" align="center" header-align="center" />
+                    <el-table-column prop="修改人" label="修改人" width="100" align="center" header-align="center" />
+                    <el-table-column prop="修改日期" label="修改日期" min-width="180" align="center" header-align="center" />
+                  </el-table>
+                </div>
               </el-dialog>
             </div>
           </el-main>
@@ -245,7 +262,7 @@ const multipleTable = ref(null)
 const _noderq = ref('')
 const _nodecode = ref('')
 const page = ref(1)
-const pageSize = ref(20)
+const pageSize = ref(30)
 const total = ref(0)
 const editingCell = reactive({ rowId: null, prop: null })
 const editingOriginalValue = ref('')
@@ -292,20 +309,32 @@ const rowKeyOf = (row) => row.UniqId || row.tempId
 const isEditing = (row, prop) =>
   editingCell.rowId === rowKeyOf(row) && editingCell.prop === prop
 
-const loadListByMonth = async (sys_rq, customer = '') => {
+/** 列表查询参数:带分页 page / pageSize(limit 兼容部分接口) */
+const buildListParams = (extra = {}) => {
+  const params = {
+    page: page.value,
+    pageSize: pageSize.value,
+    limit: pageSize.value,
+    ...extra,
+  }
+  return params
+}
+
+const loadListByMonth = async (sys_rq, customer = '', { resetPage = true } = {}) => {
   _noderq.value = sys_rq || ''
   _nodecode.value = customer || ''
+  if (resetPage) page.value = 1
   if (!sys_rq) {
     tableData.value = [createEmptyRow()]
     total.value = 0
     return
   }
-  const params = { sys_rq }
+  const params = buildListParams({ sys_rq })
   if (customer) params.customer = customer
   const res = await getMonthlyGarmentsList(params)
   if (res.code === 0) {
     tableData.value = res.data.result || []
-    total.value = res.data.total ?? tableData.value.length
+    total.value = Number(res.data.total ?? tableData.value.length) || 0
   } else {
     tableData.value = []
     total.value = 0
@@ -314,18 +343,22 @@ const loadListByMonth = async (sys_rq, customer = '') => {
 }
 
 const highlightTreeNode = (node) => {
-  const allNodes = document.querySelectorAll('.treecolor .el-tree-node')
-  allNodes.forEach((el) => {
-    const label = el.querySelector('.el-tree-node__label')
-    if (label) label.style.color = ''
-  })
-  const clickedNodeId = node?.['$treeNodeId']
-  if (!clickedNodeId) return
-  const clickedNode = document.querySelector(`.treecolor .el-tree-node[data-key="${clickedNodeId}"]`)
-  if (clickedNode) {
-    const label = clickedNode.querySelector('.el-tree-node__label')
-    if (label) label.style.color = 'red'
+  const key = node?.id || node?.['$treeNodeId']
+  if (key) {
+    currentTreeKey.value = key
+    menuTreeRef.value?.setCurrentKey?.(key)
   }
+  // 兼容旧逻辑:直接把当前节点文字标红(覆盖默认蓝色)
+  nextTick(() => {
+    document.querySelectorAll('.treecolor .el-tree-node__label').forEach((el) => {
+      el.style.color = ''
+    })
+    const clickedNode = key
+      ? document.querySelector(`.treecolor .el-tree-node[data-key="${key}"]`)
+      : null
+    const label = clickedNode?.querySelector?.('.el-tree-node__label')
+    if (label) label.style.color = 'red'
+  })
 }
 
 const buildTreeData = (data) => {
@@ -367,11 +400,15 @@ const getTree = async () => {
       await nextTick()
       menuTreeRef.value?.setCurrentKey?.(monthNode.id)
     } else {
+      tableData.value = []
+      total.value = 0
       ensureEditableRows()
     }
   } catch (error) {
     ElMessage.error('获取数据失败')
     console.error('获取树形数据失败:', error)
+    tableData.value = []
+    total.value = 0
     ensureEditableRows()
   }
 }
@@ -379,7 +416,6 @@ getTree()
 
 const handleNodeClick = async (node) => {
   highlightTreeNode(node)
-  currentTreeKey.value = node.id || ''
   // 月份节点:查当月全部;客户节点:按客户过滤
   if (node.children) {
     await loadListByMonth(node.yearMonth || node.label)
@@ -397,18 +433,31 @@ const onSubmit = async () => {
     ElMessage.warning('请输入搜索内容')
     return
   }
-  const res = await getMonthlyGarmentsList({ search: searchInfo.value })
+  page.value = 1
+  const res = await getMonthlyGarmentsList(buildListParams({ search: searchInfo.value }))
   if (res.code === 0) {
-    tableData.value = res.data.result
-    total.value = res.data.total || res.data.result.length
+    tableData.value = res.data.result || []
+    total.value = Number(res.data.total ?? tableData.value.length) || 0
     ensureEditableRows()
   }
 }
 
 const tableRowClick = () => {}
 const handleSelectionChange = () => {}
-const handleCurrentChange = (val) => { page.value = val }
-const handleSizeChange = (val) => { pageSize.value = val }
+const handleCurrentChange = async (val) => {
+  page.value = val
+  if (searchInfo.value) {
+    const res = await getMonthlyGarmentsList(buildListParams({ search: searchInfo.value }))
+    if (res.code === 0) {
+      tableData.value = res.data.result || []
+      total.value = Number(res.data.total ?? tableData.value.length) || 0
+      ensureEditableRows()
+    }
+    return
+  }
+  if (!_noderq.value) return
+  await loadListByMonth(_noderq.value, _nodecode.value, { resetPage: false })
+}
 const gxbgCellClass = () => ''
 
 const addRow = (index) => {
@@ -440,10 +489,15 @@ const deleteRow = async (row, index) => {
       }
     }
     tableData.value.splice(index, 1)
-    total.value = countSavedRows()
+    if (row.UniqId && total.value > 0) total.value -= 1
     ensureEditableRows()
     ElMessage.success('删除成功')
     await refreshTreePreserveSelection()
+    // 当前页删空且不是第一页时,回退一页并重新拉接口
+    if (!tableData.value.some((r) => r.UniqId) && page.value > 1 && total.value > 0) {
+      page.value -= 1
+      await loadListByMonth(_noderq.value, _nodecode.value, { resetPage: false })
+    }
   } catch (error) {
     ElMessage.error('删除失败')
     console.error('删除失败:', error)
@@ -607,7 +661,7 @@ const handleCellBlur = async (row, prop) => {
         // 就地转成已保存行,不整表重载,避免接口暂时查不到时只剩最新一条 + 自动空白行
         row.UniqId = newId
         delete row.tempId
-        total.value = countSavedRows()
+        total.value = countSavedRows() > total.value ? countSavedRows() : total.value + 1
         await refreshTreePreserveSelection()
         await restoreEditedRow(newId)
       } else {
@@ -645,40 +699,92 @@ const exportToExcel = (data, filename = '导出数据.xlsx', sheetName = 'Sheet1
   }
 }
 
-const hzToExcel = () => {
-  if (tableData.value.length === 0) {
+const hzToExcel = async () => {
+  const rows = await fetchAllForExport()
+  if (!rows.length) {
     ElMessage.warning('暂无数据可导出')
     return
   }
-  exportToExcel(tableData.value, '月份样衣生产进度表.xlsx', '月份样衣生产进度表')
+  exportToExcel(rows, '月份样衣生产进度表.xlsx', '月份样衣生产进度表')
 }
 
-const mxToExcel = () => {
-  if (tableData.value.length === 0) {
+const mxToExcel = async () => {
+  const rows = await fetchAllForExport()
+  if (!rows.length) {
     ElMessage.warning('暂无数据可导出')
     return
   }
-  exportToExcel(tableData.value, '月份样衣生产进度明细表.xlsx', '月份样衣生产进度明细表')
+  exportToExcel(rows, '月份样衣生产进度明细表.xlsx', '月份样衣生产进度明细表')
+}
+
+/** 导出时按当前筛选条件拉全量(大 pageSize) */
+const fetchAllForExport = async () => {
+  const params = {
+    page: 1,
+    pageSize: Math.max(total.value, 9999),
+    limit: Math.max(total.value, 9999),
+  }
+  if (searchInfo.value) {
+    params.search = searchInfo.value
+  } else if (_noderq.value) {
+    params.sys_rq = _noderq.value
+    if (_nodecode.value) params.customer = _nodecode.value
+  } else {
+    return tableData.value.filter((r) => r.UniqId)
+  }
+  const res = await getMonthlyGarmentsList(params)
+  if (res.code === 0) return res.data.result || []
+  return []
 }
 </script>
 
 <style scoped>
+.monthly-sample-sider {
+  margin-right: 0 !important;
+  padding: 0 !important;
+}
+.monthly-sample-sider :deep(.arco-layout-sider-children) {
+  padding: 0 !important;
+  overflow: hidden;
+}
 .JKWTree-tree {
   background-color: #fff;
-  padding: 10px;
-  margin-right: 20px;
+  padding: 8px 6px;
+  margin-right: 0;
+  height: 100%;
+  box-sizing: border-box;
 }
 .JKWTree-tree h3 {
-  font-size: 15px;
+  font-size: 14px;
   font-weight: 700;
-  margin: 10px 0;
+  margin: 6px 0 8px;
+}
+/* 左侧树:选中节点文字红色 */
+:deep(.treecolor .el-tree-node__content) {
+  color: var(--el-text-color-regular);
+}
+:deep(.treecolor .el-tree-node.is-current > .el-tree-node__content) {
+  color: red !important;
+  font-weight: 600;
+  background-color: var(--el-color-primary-light-9, #ecf5ff) !important;
+}
+:deep(.treecolor .el-tree-node.is-current > .el-tree-node__content .el-tree-node__label) {
+  color: red !important;
+}
+:deep(.el-main) {
+  padding: 0 0 0 8px !important;
 }
 :deep(.el-table__body tr.current-row) > td {
   background: #ff80ff !important;
 }
 :deep(.el-table td .cell) {
-  line-height: 20px !important;
-  min-height: 24px;
+  line-height: 32px !important;
+  min-height: 32px;
+  height: 32px;
+  padding: 0 4px !important;
+  display: flex;
+  align-items: center;
+  justify-content: center;
 }
 .gva-table-box {
   padding: 0px !important;
@@ -686,13 +792,59 @@ const mxToExcel = () => {
 .cell-span {
   display: block;
   width: 100%;
-  min-height: 24px;
-  line-height: 24px;
+  height: 32px;
+  min-height: 32px;
+  line-height: 32px;
   cursor: pointer;
   box-sizing: border-box;
   padding: 0 4px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
 }
 :deep(.el-table td.el-table__cell) {
   cursor: pointer;
+  height: 32px !important;
+  padding: 0 !important;
+}
+:deep(.el-table__body tr) {
+  height: 32px !important;
+}
+:deep(.el-table__header tr) {
+  height: 32px !important;
+}
+/* 编辑态输入/日期与普通行同高,避免点击后行被撑高 */
+.monthly-sample-table :deep(.el-input),
+.monthly-sample-table :deep(.el-date-editor) {
+  width: 100%;
+  height: 28px !important;
+}
+.monthly-sample-table :deep(.el-input__wrapper),
+.monthly-sample-table :deep(.el-date-editor .el-input__wrapper) {
+  height: 28px !important;
+  min-height: 28px !important;
+  padding: 0 8px !important;
+  box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;
+}
+.monthly-sample-table :deep(.el-input__inner) {
+  height: 28px !important;
+  line-height: 28px !important;
+}
+</style>
+
+<style>
+.monthly-sample-log-dialog.el-dialog {
+  margin-top: 8vh !important;
+}
+.monthly-sample-log-dialog .el-dialog__body {
+  padding: 10px 16px 16px;
+  height: 60vh;
+  max-height: 60vh;
+  overflow: hidden;
+  box-sizing: border-box;
+}
+.monthly-sample-log-dialog .monthly-sample-log-body {
+  height: 100%;
+  overflow: hidden;
 }
 </style>