From f770f1735c127574f14042aa34801ab0984f62f2 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 14 九月 2026 12:21:26 +0800
Subject: [PATCH] feat(productionOrder): 优化生产订单表格展示和交互体验
---
src/views/productionManagement/productionOrder/index.vue | 173 +++++++++++++++++++++++++++++++++++----------------------
public/favicon.ico | 0
src/assets/logo/logo.png | 0
3 files changed, 105 insertions(+), 68 deletions(-)
diff --git a/public/favicon.ico b/public/favicon.ico
index ce783dc..34f130e 100644
--- a/public/favicon.ico
+++ b/public/favicon.ico
Binary files differ
diff --git a/src/assets/logo/logo.png b/src/assets/logo/logo.png
index 78b143d..61470dd 100644
--- a/src/assets/logo/logo.png
+++ b/src/assets/logo/logo.png
Binary files differ
diff --git a/src/views/productionManagement/productionOrder/index.vue b/src/views/productionManagement/productionOrder/index.vue
index 55edf93..6697c09 100644
--- a/src/views/productionManagement/productionOrder/index.vue
+++ b/src/views/productionManagement/productionOrder/index.vue
@@ -78,6 +78,11 @@
:selectable="row => !row.endOrder"
@selection-change="handleSelectionChange"
@pagination="pagination">
+ <template #planCompleteTime="{ row }">
+ <span :title="deliveryHint(row)">
+ {{ row.planCompleteTime ? dayjs(row.planCompleteTime).format('YYYY-MM-DD') : '' }}
+ </span>
+ </template>
<template #completionStatus="{ row }">
<el-progress :percentage="toProgressPercentage(row?.completionStatus)"
:color="progressColor(toProgressPercentage(row?.completionStatus))"
@@ -89,10 +94,11 @@
type="success"
size="small">鍏ㄩ儴瀹屾垚</el-tag>
<div v-else
- class="current-process-name">
+ class="current-process-name"
+ :title="`${getCurrentProcess(row).name} 路 ${getCurrentProcess(row).pct}%`">
<span class="process-color-dot"
:style="{ background: getCurrentProcess(row).color || '#909399' }"></span>
- <span :style="getCurrentProcess(row).color ? { color: getCurrentProcess(row).color } : {}">{{ getCurrentProcess(row).name }}</span>
+ <span :style="readableTextColor(getCurrentProcess(row).color) ? { color: readableTextColor(getCurrentProcess(row).color) } : {}">{{ getCurrentProcess(row).name }}</span>
</div>
</template>
<span v-else>-</span>
@@ -105,18 +111,13 @@
class="process-step">
<div class="step-content">
<div class="step-circle"
- :class="{ 'is-completed': item.percentage >= 100 }">
- <span class="step-percentage"
- :style="{ color: item.percentage >= 70 ? item.percentage >= 100 ? '#67c23a' : '#f56c6c' : '#000' }">{{ item.percentage }}%</span>
- </div>
- <div class="step-name">
- <span v-if="item.color"
- :style="{ display: 'inline-block', width: '8px', height: '8px', borderRadius: '50%', marginRight: '4px', background: item.color }"></span>
- <span>{{ item.name }}</span>
- </div>
+ :title="`${item.name} ${item.percentage}%`"
+ :style="{ background: item.color || '#409EFF', opacity: item.percentage >= 100 ? 1 : item.percentage > 0 ? 0.6 : 0.25 }"></div>
+ <div class="step-name">{{ item.name }}</div>
</div>
<div v-if="index < row.processRouteStatus.length - 1"
- class="step-line"></div>
+ class="step-line"
+ :style="{ background: item.percentage >= 100 ? '#67c23a' : '#dcdfe6' }"></div>
</div>
</div>
<span v-else>-</span>
@@ -125,7 +126,8 @@
</div>
<el-dialog v-model="bindRouteDialogVisible"
title="缁戝畾宸ヨ壓璺嚎"
- width="500px">
+ width="500px"
+ :close-on-click-modal="false">
<el-form label-width="90px">
<el-form-item label="宸ヨ壓璺嚎">
<el-select v-model="bindForm.routeId"
@@ -151,7 +153,8 @@
<!-- 鏉ユ簮鏁版嵁寮圭獥 -->
<el-dialog v-model="sourceDataDialogVisible"
title="鏉ユ簮鏁版嵁"
- width="1200px">
+ width="1200px"
+ :close-on-click-modal="false">
<div v-if="sourceRowData"
class="applyno-summary1">
<div class="summary-item">
@@ -288,14 +291,15 @@
total: 0,
});
+ // 姣忔鍥哄畾鍗犲锛氬悕绉板尯96px + 杩炴帴绾�34px锛岄暱鍚嶇О鎹㈣锛屼繚璇佸渾鍦�-杩炵嚎鑺傚涓�鑷�
+ const PROCESS_STEP_WIDTH = 130;
const processColumnWidth = computed(() => {
if (!tableData.value || tableData.value.length === 0) return "200px";
const maxProcesses = Math.max(
...tableData.value.map(row => row.processRouteStatus?.length || 0)
);
if (maxProcesses === 0) return "100px";
- // 姣忎釜宸ュ簭鍦嗗湀 36px + 绾挎潯 30px = 66px锛岄澶栧姞 60px 杈硅窛鍜屾枃瀛楃┖闂�
- return `${maxProcesses * 66 + 60}px`;
+ return `${maxProcesses * PROCESS_STEP_WIDTH + 40}px`;
});
const tableColumn = computed(() => [
@@ -309,6 +313,7 @@
prop: "currentProcess",
dataType: "slot",
slot: "currentProcess",
+ align: "center",
width: 160,
},
{
@@ -332,6 +337,7 @@
: val === 5
? "宸茬粨鏉�"
: "宸插彇娑�",
+ // 宸茬粨鏉熶负姝e父鍏抽棴锛堜腑鎬х伆锛夛紝宸插彇娑堟墠鏄紓甯告搷浣滐紙绾級
formatType: val =>
val === 1
? "primary"
@@ -340,8 +346,8 @@
: val === 3
? "success"
: val === 5
- ? "danger"
- : "info",
+ ? "info"
+ : "danger",
},
{
label: "浜у搧鍚嶇О",
@@ -395,7 +401,8 @@
{
label: "璁″垝瀹屾垚鏃堕棿",
prop: "planCompleteTime",
- formatData: val => (val ? dayjs(val).format("YYYY-MM-DD") : ""),
+ dataType: "slot",
+ slot: "planCompleteTime",
width: 120,
},
{
@@ -403,7 +410,7 @@
label: "鎿嶄綔",
align: "center",
fixed: "right",
- width: 280,
+ width: 420,
operation: [
{
name: "宸ヨ壓璺嚎",
@@ -474,7 +481,7 @@
{
name: "鐢熶骇杩芥函",
type: "text",
- color: "#409eff",
+ color: "var(--el-color-primary)",
clickFun: row => {
router.push({
path: "/productionManagement/productionTraceability",
@@ -489,7 +496,7 @@
{
name: "缁撴潫璁㈠崟",
type: "text",
- color: "red",
+ color: "var(--el-color-danger)",
showHide: row => !row.endOrder,
clickFun: row => {
handleEndOrder(row);
@@ -537,6 +544,27 @@
return "#67c23a";
};
+ // hex 鑹茶浆 rgba锛堢敤浜庡厜鏅�/娣″簳锛夛紝闈� hex 杩斿洖绌轰覆
+ const hexToRgba = (hex, alpha) => {
+ if (typeof hex !== "string") return "";
+ const m = hex.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);
+ if (!m) return "";
+ let n = m[1];
+ if (n.length === 3) n = n.split("").map(c => c + c).join("");
+ const v = parseInt(n, 16);
+ return `rgba(${(v >> 16) & 255}, ${(v >> 8) & 255}, ${v & 255}, ${alpha})`;
+ };
+
+ // 杩囨祬鐨勫伐搴忚壊鍦ㄧ櫧搴曚笂鏂囧瓧涓嶅彲璇伙紝鍥為��甯歌鏂囧瓧鑹�
+ const isLightColor = hex => {
+ const rgba = hexToRgba(hex, 1);
+ if (!rgba) return false;
+ const [r, g, b] = rgba.match(/\d+/g).map(Number);
+ return (0.299 * r + 0.587 * g + 0.114 * b) / 255 > 0.72;
+ };
+ const readableTextColor = color =>
+ !color || isLightColor(color) ? "" : color;
+
// 褰撳墠宸ュ簭锛氱涓�閬撳畬鎴愬害涓嶈冻100%鐨勫伐搴忥紱鍏ㄩ儴瀹屾垚杩斿洖 done
const getCurrentProcess = row => {
const list = row.processRouteStatus;
@@ -547,7 +575,20 @@
done: false,
name: current.name || "鏈煡宸ュ簭",
color: current.color || "",
+ pct: toProgressPercentage(current.percentage),
};
+ };
+
+ // 浜ゆ湡棰勮鐨勬枃瀛楁彁绀猴紙棰滆壊涔嬪鐨勬棤闅滅鍐椾綑鎸囩ず锛�
+ const deliveryHint = row => {
+ if (!row.planCompleteTime || row.isFh) return "";
+ const diff = row.deliveryDaysDiff;
+ if (diff === 15) return "璺濅氦鏈熻繕鍓� 15 澶�";
+ if (diff === 10) return "璺濅氦鏈熻繕鍓� 10 澶�";
+ if (diff === 2) return "璺濅氦鏈熶粎鍓� 2 澶╋紝鏃堕棿绱у紶";
+ if (diff < 0) return `宸查�炬湡 ${-diff} 澶╋紝璇峰敖蹇鐞哷;
+ if (diff < 2) return `璺濅氦鏈熶粎鍓� ${diff} 澶╋紝绱ф�;
+ return "";
};
// 娣诲姞琛ㄨ绫诲悕鏂规硶
@@ -557,13 +598,13 @@
const diff = row.deliveryDaysDiff;
if (diff === 15) {
- return "yellow";
+ return "due-15";
} else if (diff === 10) {
- return "pink";
+ return "due-10";
} else if (diff === 2) {
- return "purple";
+ return "due-2";
} else if (diff < 2) {
- return "red";
+ return "due-critical";
}
};
@@ -884,39 +925,44 @@
gap: 8px;
}
- :deep(.yellow) {
- background-color: #faf0de;
+ // 浜ゆ湡涓磋繎锛氶粍鈫掓鈫掓祬绾⑩啋绾� 鑹茬浉閫掕繘锛屽叏閮ㄤ繚鎸佹枃瀛楀彲璇�
+ :deep(.due-15) {
+ background-color: #fdf6ec;
}
- :deep(.pink) {
- background-color: #fae1de;
+ :deep(.due-10) {
+ background-color: #faecd8;
}
- :deep(.red) {
- background-color: #f80202;
+ :deep(.due-2) {
+ background-color: #fde2e2;
}
- :deep(.purple) {
- background-color: #f4defa;
+ :deep(.due-critical) {
+ background-color: #fbc4c4;
+
+ td:first-child {
+ box-shadow: inset 3px 0 0 #f56c6c;
+ }
}
.table_list {
margin-top: unset;
}
.current-process-name {
- display: flex;
- align-items: center;
- font-size: 12px;
+ display: inline-flex;
+ flex-direction: column;
+ align-items: stretch; // 鑹叉潯瀹藉害鐢辨枃瀛楁拺寮�锛屼袱鑰呯瓑瀹�
+ padding: 4px 0;
+ font-size: 14px;
color: #303133;
- }
- .process-color-dot {
- display: inline-block;
- width: 8px;
- height: 8px;
- border-radius: 50%;
- margin-right: 4px;
- flex-shrink: 0;
+ .process-color-dot {
+ display: block;
+ height: 16px;
+ border-radius: 4px;
+ margin-bottom: 6px;
+ }
}
.process-progress-container {
@@ -927,52 +973,43 @@
.process-step {
display: flex;
- align-items: center;
+ align-items: flex-start;
position: relative;
.step-content {
display: flex;
flex-direction: column;
align-items: center;
+ width: 96px;
+ flex-shrink: 0;
z-index: 1;
.step-circle {
width: 36px;
height: 36px;
border-radius: 50%;
- border: 2px solid #409eff;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: #fff;
+ box-sizing: border-box;
margin-bottom: 4px;
-
- .step-percentage {
- font-size: 11px;
- font-weight: bold;
- }
-
- &.is-completed {
- border-color: #67c23a;
- .step-percentage {
- color: #67c23a;
- }
- }
}
.step-name {
font-size: 12px;
color: #606266;
- white-space: nowrap;
+ line-height: 1.4;
+ max-height: 34px; // 鏈�澶氫袱琛�
+ overflow: hidden;
+ text-align: center;
+ word-break: break-all;
}
}
.step-line {
- width: 30px;
- height: 1px;
+ width: 130px; // 璐┛鐩搁偦涓ゅ渾蹇冿紝涓ょ琚渾鍦堬紙z-index鏇撮珮锛夐伄鎸�
+ height: 2px;
+ border-radius: 1px;
background-color: #dcdfe6;
- margin: 0 -2px;
- margin-top: -20px; // 鍚戜笂鍋忕Щ浠ュ榻愬渾蹇�
+ flex-shrink: 0;
+ margin: 17px -48px 0; // 绾垮湪34px妲戒綅灞呬腑锛�(130-34)/2=48锛涢《杈�17px瀵瑰噯鍦嗗績
}
}
}
--
Gitblit v1.9.3