From c08553f33b79d9a31da912d2842452a683986b87 Mon Sep 17 00:00:00 2001
From: wangyu <823267011@qq.com>
Date: Thu, 14 May 2026 15:36:14 +0800
Subject: [PATCH] =?UTF-8?q?=E8=A7=84=E7=A8=8B=E4=BF=AE=E6=AD=A3=E4=BB=A5?=
=?UTF-8?q?=E5=8F=8A=E5=8A=A0=E5=BC=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../views/wms/processSpec/coilSpecBind.vue | 298 +++++++++++++-----
1 file changed, 220 insertions(+), 78 deletions(-)
diff --git a/klp-ui/src/views/wms/processSpec/coilSpecBind.vue b/klp-ui/src/views/wms/processSpec/coilSpecBind.vue
index 83ce5b82..04d6bb24 100644
--- a/klp-ui/src/views/wms/processSpec/coilSpecBind.vue
+++ b/klp-ui/src/views/wms/processSpec/coilSpecBind.vue
@@ -178,75 +178,78 @@
-
-
- 暂无参数数据
-
-
-
-
- {{ group.segmentName || group.segmentType || '—' }}
- {{ group.pointName }}
- {{ group.pointCode }}
-
-
-
+
+
+
-
+
+
+
+
暂无参数数据
+
+
+ {{ group.pointName }}
+ {{ group.pointCode }}
+
+
+
+
+
+ {{ row.unit || '—' }}
+
+
+
+ {{ fmtNum(row.targetValue) }}
+
+
+
+ {{ fmtNum(row.lowerLimit) }}
+
+
+ {{ fmtNum(row.upperLimit) }}
+
+
+
+ {{ fmtNum(row._actualMax) }}
+ —
+
+
+
+
+ {{ fmtNum(row._actualMin) }}
+ —
+
+
+
+
+
+ {{ fmtNum(row._anomalyType === 'UPPER' ? row._deviationMax : row._deviationMin) }}
+
+ —
+
+
+
+
+
+ {{ row._anomalyType === 'UPPER' ? '超上限' : row._anomalyType === 'LOWER' ? '低于下限' : '异常' }}
+
+ 正常
+
+
+
+
+
+
+
@@ -391,9 +394,41 @@
import { listProcessCoilRecord, batchRebindCoilRecord } from '@/api/wms/processCoilRecord'
import { listProcessSpec } from '@/api/wms/processSpec'
import { listProcessSpecVersion } from '@/api/wms/processSpecVersion'
-import { listProcessPlan } from '@/api/wms/processPlan'
-import { listProcessPlanParam } from '@/api/wms/processPlanParam'
+import { listProcessPlan, addProcessPlan } from '@/api/wms/processPlan'
+import { listProcessPlanParam, addProcessPlanParam } from '@/api/wms/processPlanParam'
import { listAllProcessAnomaly } from '@/api/wms/processAnomaly'
+import { getPresetSetupByCoilId } from '@/api/l2/timing'
+
+// 三段 L1 预设设定值的结构定义(对应 PLTCM_PRESET_SETUP 表)
+const PRESET_PLANS = [
+ {
+ segmentType: 'INLET', segmentName: '入口段', pointName: '入口设定值', pointCode: 'PRESET_INLET', sortOrder: 10,
+ params: [
+ { paramCode: 'POR_TEN', paramName: '开卷机单位张力', unit: 'N/mm²' },
+ { paramCode: 'CEL_TEN', paramName: '入口活套单位张力', unit: 'N/mm²' },
+ { paramCode: 'FLAT_MESH_1', paramName: '矫直机1#辊插入量', unit: 'mm' },
+ { paramCode: 'FLAT_MESH_2', paramName: '矫直机2#辊插入量', unit: 'mm' }
+ ]
+ },
+ {
+ segmentType: 'PROCESS', segmentName: '工艺段', pointName: '工艺设定值', pointCode: 'PRESET_PROCESS', sortOrder: 20,
+ params: [
+ { paramCode: 'TLV_TEN', paramName: '拉弯矫直机单位张力', unit: 'N/mm²' },
+ { paramCode: 'TLV_ELONG', paramName: '拉弯矫直机延伸率', unit: '%' },
+ { paramCode: 'TLV_MESH_1', paramName: '弯曲辊1#弯辊量', unit: 'mm' },
+ { paramCode: 'TLV_MESH_2', paramName: '弯曲辊2#弯辊量', unit: 'mm' }
+ ]
+ },
+ {
+ segmentType: 'OUTLET', segmentName: '出口段', pointName: '出口设定值', pointCode: 'PRESET_OUTLET', sortOrder: 30,
+ params: [
+ { paramCode: 'TR_TEN', paramName: '酸洗出口张力辊张力', unit: 'N/mm²' },
+ { paramCode: 'TRIM_TEN', paramName: '切边段单位张力', unit: 'N/mm²' },
+ { paramCode: 'TEL_TEN', paramName: '联机活套单位张力', unit: 'N/mm²' },
+ { paramCode: 'CXL_TEN', paramName: '出口活套单位张力', unit: 'N/mm²' }
+ ]
+ }
+]
const VERSION_STATUS = [
{ value: 'DRAFT', label: '草稿' },
@@ -422,6 +457,7 @@ export default {
detailLoading: false,
detailRow: null,
detailParams: [],
+ detailActiveTab: 'INLET',
bindDialogVisible: false,
removeOldRecord: false,
@@ -456,6 +492,23 @@ export default {
}
return Object.values(planMap).sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))
},
+ detailSegmentTabs() {
+ const SEG_ORDER = ['INLET', 'PROCESS', 'OUTLET']
+ const SEG_LABELS = { INLET: '入口段', PROCESS: '工艺段', OUTLET: '出口段' }
+ const map = {}
+ for (const g of this.detailParamGroups) {
+ const seg = g.segmentType || 'OTHER'
+ if (!map[seg]) {
+ map[seg] = { segmentType: seg, segmentLabel: SEG_LABELS[seg] || seg, anomalyCount: 0, groups: [] }
+ }
+ map[seg].groups.push(g)
+ map[seg].anomalyCount += g.params.filter(p => p._hasAnomaly).length
+ }
+ for (const seg of SEG_ORDER) {
+ if (!map[seg]) map[seg] = { segmentType: seg, segmentLabel: SEG_LABELS[seg], anomalyCount: 0, groups: [] }
+ }
+ return SEG_ORDER.map(s => map[s])
+ },
// 选中行是否全来自同一个版本(决定是否可以"移除旧记录")
singleSourceVersion() {
if (!this.selected.length) return false
@@ -580,6 +633,7 @@ export default {
openDetail(row) {
this.detailRow = row
this.detailParams = []
+ this.detailActiveTab = 'INLET'
this.detailDrawerVisible = true
this.loadDetailData(row)
},
@@ -587,6 +641,45 @@ export default {
this.detailRow = null
this.detailParams = []
},
+ // Returns true if any preset plan points were auto-created
+ async autoInitPresetParams(row, existingPlans) {
+ try {
+ const existingCodes = new Set(existingPlans.map(p => p.pointCode))
+ const missing = PRESET_PLANS.filter(p => !existingCodes.has(p.pointCode))
+ if (!missing.length) return false
+ const srcId = row.enCoilId || row.coilId
+ if (!srcId) return false
+ const presetRes = await getPresetSetupByCoilId(srcId)
+ const preset = (presetRes && presetRes.data && presetRes.data.data) || {}
+ for (const def of missing) {
+ const planRes = await addProcessPlan({
+ versionId: row.versionId,
+ segmentType: def.segmentType,
+ segmentName: def.segmentName,
+ pointName: def.pointName,
+ pointCode: def.pointCode,
+ sortOrder: def.sortOrder
+ })
+ const planId = planRes.data
+ for (const p of def.params) {
+ const val = preset[p.paramCode.toLowerCase()] ?? preset[p.paramCode]
+ await addProcessPlanParam({
+ planId,
+ paramCode: p.paramCode,
+ paramName: p.paramName,
+ unit: p.unit,
+ targetValue: (val !== null && val !== undefined && val !== '') ? Number(val) : null,
+ presetSrcId: srcId
+ })
+ }
+ }
+ return true
+ } catch (e) {
+ console.error('[autoInitPresetParams] failed', e)
+ return false
+ }
+ },
+
async loadDetailData(row) {
if (!row.versionId) return
this.detailLoading = true
@@ -595,7 +688,14 @@ export default {
listProcessPlan({ versionId: row.versionId, pageNum: 1, pageSize: 200 }),
listAllProcessAnomaly({ coilId: row.coilId, versionId: row.versionId })
])
- const plans = plansRes.rows || []
+ let plans = plansRes.rows || []
+
+ const added = await this.autoInitPresetParams(row, plans)
+ if (added) {
+ const refreshed = await listProcessPlan({ versionId: row.versionId, pageNum: 1, pageSize: 200 })
+ plans = refreshed.rows || []
+ }
+
const anomalyList = anomalyRes.data || []
const anomalyMap = {}
for (const a of anomalyList) {
@@ -910,6 +1010,54 @@ export default {
min-width: 0;
flex: 1;
}
+/* ── 分段 Tab ── */
+.seg-tabs { margin-top: 0; }
+.seg-tab-bar {
+ display: inline-flex;
+ background: #f0f2f5;
+ border-radius: 8px;
+ padding: 3px;
+ margin-bottom: 14px;
+ gap: 2px;
+}
+.seg-tab-btn {
+ border: none;
+ background: transparent;
+ border-radius: 6px;
+ padding: 6px 20px;
+ font-size: 13px;
+ color: #606266;
+ cursor: pointer;
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ transition: background .15s, color .15s, box-shadow .15s;
+ white-space: nowrap;
+ outline: none;
+}
+.seg-tab-btn:hover:not(.is-active) { background: #e4e7ed; color: #303133; }
+.seg-tab-btn.is-active {
+ background: #fff;
+ color: #303133;
+ font-weight: 600;
+ box-shadow: 0 1px 5px rgba(0,0,0,.1);
+}
+.seg-badge {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 16px;
+ height: 16px;
+ padding: 0 4px;
+ background: #f56c6c;
+ color: #fff;
+ border-radius: 8px;
+ font-size: 10px;
+ font-weight: 700;
+ line-height: 1;
+}
+.seg-tab-pane {}
+
.param-group { margin-bottom: 20px; }
.param-group-hd {
display: flex;
@@ -918,15 +1066,8 @@ export default {
margin-bottom: 6px;
padding: 0 2px;
}
-.pg-segment {
- font-size: 11px;
- color: #fff;
- background: #5F7BA0;
- padding: 1px 9px;
- border-radius: 10px;
-}
.pg-point { font-size: 13px; font-weight: 600; color: #303133; }
-.pg-code { font-size: 11px; color: #909399; margin-left: 5px; }
+.pg-code { font-size: 11px; color: #909399; }
.val-danger { color: #f56c6c; font-weight: 600; }
.val-ok { color: #67c23a; }
.val-anomaly { color: #e6a23c; font-weight: 600; }
@@ -936,6 +1077,7 @@ export default {
font-size: 13px;
color: #c0c4cc;
}
+.param-group :deep(.row-anomaly td) { background: #fff8f0 !important; }
::v-deep .row-anomaly td { background: #fff8f8 !important; }
::v-deep .el-drawer__header { padding: 16px 20px 12px; font-size: 15px; font-weight: 600; color: #303133; margin-bottom: 0; border-bottom: 1px solid #f0f2f5; }
::v-deep .el-drawer__body { overflow: hidden; }