From 1566e4c7604d85737ea67fe6757e71b8185fa48e Mon Sep 17 00:00:00 2001
From: huang <1532065656@qq.com>
Date: 星期二, 18 十一月 2025 16:52:42 +0800
Subject: [PATCH] 添加设备管理页面,添加测试设备任务监控页面
---
mes-web/src/views/device/DeviceEditDialog.vue | 485 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 481 insertions(+), 4 deletions(-)
diff --git a/mes-web/src/views/device/DeviceEditDialog.vue b/mes-web/src/views/device/DeviceEditDialog.vue
index 773dd73..881ab73 100644
--- a/mes-web/src/views/device/DeviceEditDialog.vue
+++ b/mes-web/src/views/device/DeviceEditDialog.vue
@@ -106,13 +106,20 @@
</el-form-item>
<el-form-item label="閫氳鍗忚" prop="protocolType">
- <el-select v-model="deviceForm.protocolType" placeholder="閫夋嫨閫氳鍗忚" style="width: 100%;">
+ <el-select
+ v-model="deviceForm.protocolType"
+ placeholder="閫夋嫨閫氳鍗忚"
+ style="width: 100%;"
+ @change="handleProtocolTypeChange"
+ >
+ <el-option label="S7 Communication" value="S7 Communication" />
<el-option label="Modbus TCP" value="Modbus TCP" />
<el-option label="OPC UA" value="OPC UA" />
<el-option label="EtherNet/IP" value="EtherNet/IP" />
<el-option label="Profinet" value="Profinet" />
<el-option label="鍏朵粬" value="鍏朵粬" />
</el-select>
+ <span class="form-tip">S7绯诲垪PLC閫氬父浣跨敤S7 Communication鍗忚</span>
</el-form-item>
<el-form-item label="瓒呮椂鏃堕棿(绉�)" prop="timeout">
@@ -240,6 +247,200 @@
</div>
</el-card>
+ <!-- 璁惧閫昏緫閰嶇疆 -->
+ <el-card class="form-section" shadow="never" style="margin-top: 20px;" v-if="deviceForm.deviceType">
+ <template #header>
+ <span class="section-title">璁惧閫昏緫閰嶇疆</span>
+ <span class="form-tip">鏍规嵁璁惧绫诲瀷閰嶇疆鐗瑰畾鐨勪笟鍔¢�昏緫鍙傛暟</span>
+ </template>
+
+ <!-- 涓婂ぇ杞﹁澶囬�昏緫閰嶇疆 -->
+ <div v-if="deviceForm.deviceType === '涓婂ぇ杞�'">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="杞﹁締瀹归噺">
+ <el-input-number
+ v-model="deviceLogicParams.vehicleCapacity"
+ :min="1"
+ :max="10000"
+ :step="100"
+ style="width: 100%;"
+ />
+ <span class="form-tip">杞﹁締鏈�澶у閲�</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鐜荤拑闂撮殧(ms)">
+ <el-input-number
+ v-model="deviceLogicParams.glassIntervalMs"
+ :min="100"
+ :max="10000"
+ :step="100"
+ style="width: 100%;"
+ />
+ <span class="form-tip">鐜荤拑涓婃枡闂撮殧鏃堕棿锛堟绉掞級</span>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鑷姩涓婃枡">
+ <el-switch v-model="deviceLogicParams.autoFeed" />
+ <span class="form-tip">鏄惁鑷姩瑙﹀彂涓婃枡璇锋眰</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈�澶ч噸璇曟鏁�">
+ <el-input-number
+ v-model="deviceLogicParams.maxRetryCount"
+ :min="0"
+ :max="10"
+ :step="1"
+ style="width: 100%;"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-form-item label="浣嶇疆鏄犲皠">
+ <div class="position-mapping">
+ <div
+ v-for="(value, key, index) in deviceLogicParams.positionMapping"
+ :key="index"
+ class="mapping-item"
+ >
+ <el-input
+ v-model="mappingKeys[index]"
+ placeholder="浣嶇疆浠g爜"
+ size="small"
+ style="width: 150px; margin-right: 10px;"
+ @input="updatePositionMapping(index, $event, value)"
+ />
+ <el-input-number
+ v-model="deviceLogicParams.positionMapping[mappingKeys[index] || key]"
+ :min="0"
+ :max="100"
+ size="small"
+ style="width: 120px; margin-right: 10px;"
+ />
+ <el-button
+ type="danger"
+ size="small"
+ @click="removePositionMapping(key)"
+ >
+ 鍒犻櫎
+ </el-button>
+ </div>
+ <el-button type="primary" size="small" @click="addPositionMapping">
+ 娣诲姞浣嶇疆鏄犲皠
+ </el-button>
+ </div>
+ </el-form-item>
+ </div>
+
+ <!-- 澶х悊鐗囪澶囬�昏緫閰嶇疆 -->
+ <div v-if="deviceForm.deviceType === '澶х悊鐗�'">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鐜荤拑灏哄">
+ <el-input-number
+ v-model="deviceLogicParams.glassSize"
+ :min="100"
+ :max="5000"
+ :step="100"
+ style="width: 100%;"
+ />
+ <span class="form-tip">鐜荤拑灏哄锛坢m锛�</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="澶勭悊鏃堕棿(ms)">
+ <el-input-number
+ v-model="deviceLogicParams.processingTime"
+ :min="1000"
+ :max="60000"
+ :step="1000"
+ style="width: 100%;"
+ />
+ <span class="form-tip">鐜荤拑澶勭悊鏃堕棿锛堟绉掞級</span>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鑷姩澶勭悊">
+ <el-switch v-model="deviceLogicParams.autoProcess" />
+ <span class="form-tip">鏄惁鑷姩瑙﹀彂澶勭悊璇锋眰</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鏈�澶ч噸璇曟鏁�">
+ <el-input-number
+ v-model="deviceLogicParams.maxRetryCount"
+ :min="0"
+ :max="10"
+ :step="1"
+ style="width: 100%;"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </div>
+
+ <!-- 鐜荤拑瀛樺偍璁惧閫昏緫閰嶇疆 -->
+ <div v-if="deviceForm.deviceType === '鐜荤拑瀛樺偍'">
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="瀛樺偍瀹归噺">
+ <el-input-number
+ v-model="deviceLogicParams.storageCapacity"
+ :min="1"
+ :max="1000"
+ :step="1"
+ style="width: 100%;"
+ />
+ <span class="form-tip">鏈�澶у瓨鍌ㄦ暟閲�</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鍙栬揣妯″紡">
+ <el-select v-model="deviceLogicParams.retrievalMode" style="width: 100%;">
+ <el-option label="鍏堣繘鍏堝嚭 (FIFO)" value="FIFO" />
+ <el-option label="鍚庤繘鍏堝嚭 (LIFO)" value="LIFO" />
+ <el-option label="闅忔満 (RANDOM)" value="RANDOM" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鑷姩瀛樺偍">
+ <el-switch v-model="deviceLogicParams.autoStore" />
+ <span class="form-tip">鏄惁鑷姩瑙﹀彂瀛樺偍璇锋眰</span>
+ </el-form-item>
+ </el-col>
+ <el-col :span="12">
+ <el-form-item label="鑷姩鍙栬揣">
+ <el-switch v-model="deviceLogicParams.autoRetrieve" />
+ <span class="form-tip">鏄惁鑷姩瑙﹀彂鍙栬揣璇锋眰</span>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <el-form-item label="鏈�澶ч噸璇曟鏁�">
+ <el-input-number
+ v-model="deviceLogicParams.maxRetryCount"
+ :min="0"
+ :max="10"
+ :step="1"
+ style="width: 100%;"
+ />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </div>
+ </el-card>
+
<!-- 鎻忚堪淇℃伅 -->
<el-card class="form-section" shadow="never" style="margin-top: 20px;">
<template #header>
@@ -317,6 +518,28 @@
const saving = ref(false)
const testing = ref(false)
const testResult = ref(null)
+
+// 璁惧閫昏緫鍙傛暟锛堟牴鎹澶囩被鍨嬪姩鎬佹樉绀猴級
+const deviceLogicParams = reactive({
+ // 涓婂ぇ杞﹀弬鏁�
+ vehicleCapacity: 6000,
+ glassIntervalMs: 1000,
+ autoFeed: true,
+ maxRetryCount: 5,
+ positionMapping: {},
+ // 澶х悊鐗囧弬鏁�
+ glassSize: 2000,
+ processingTime: 5000,
+ autoProcess: true,
+ // 鐜荤拑瀛樺偍鍙傛暟
+ storageCapacity: 100,
+ retrievalMode: 'FIFO',
+ autoStore: true,
+ autoRetrieve: true
+})
+
+// 浣嶇疆鏄犲皠鐨勯敭鏁扮粍锛堢敤浜巚-for锛�
+const mappingKeys = ref([])
// 璁惧琛ㄥ崟鏁版嵁
const getDefaultForm = () => ({
@@ -420,6 +643,27 @@
emit('update:modelValue', newVal)
})
+// 鐩戝惉PLC绫诲瀷鍙樺寲锛岃嚜鍔ㄨ缃�氳鍗忚
+watch(() => deviceForm.plcType, (newPlcType) => {
+ // 濡傛灉閫夋嫨鐨勬槸S7绯诲垪PLC锛岃嚜鍔ㄨ缃�氳鍗忚涓篠7 Communication
+ if (newPlcType && (newPlcType.startsWith('S') || newPlcType.includes('S7'))) {
+ if (!deviceForm.protocolType || deviceForm.protocolType === '鍏朵粬') {
+ deviceForm.protocolType = 'S7 Communication'
+ }
+ }
+})
+
+// 澶勭悊閫氳鍗忚鍙樺寲
+const handleProtocolTypeChange = (value) => {
+ // 濡傛灉閫夋嫨浜嗛潪S7鍗忚锛屼絾PLC绫诲瀷鏄疭7绯诲垪锛岀粰鍑烘彁绀�
+ if (value && value !== 'S7 Communication' && deviceForm.plcType) {
+ const s7Types = ['S1200', 'S1500', 'S400', 'S300', 'S200', 'S200_SMART']
+ if (s7Types.includes(deviceForm.plcType)) {
+ ElMessage.warning('S7绯诲垪PLC閫氬父浣跨敤S7 Communication鍗忚锛岃纭鍗忚閫夋嫨鏄惁姝g‘')
+ }
+ }
+}
+
// 鏂规硶瀹氫箟
const parseJsonSafe = (str, defaultValue = null) => {
if (!str) return defaultValue
@@ -453,11 +697,182 @@
deviceForm.dbArea = plcConfig.dbArea || 'DB1'
deviceForm.beginIndex = plcConfig.beginIndex ?? 0
deviceForm.autoModeInterval = plcConfig.autoModeInterval ?? 5000
+
+ // 鍔犺浇閰嶇疆鍙傛暟锛堜粠 configJson锛�
+ // 鍏煎涓ょ鏍煎紡锛�
+ // 1. 鏁扮粍鏍煎紡锛歔{ paramKey, paramValue, description }]
+ // 2. 瀵硅薄鏍煎紡锛堟棫鏍煎紡锛夛細{ fieldName: offset } - 鑷姩杞崲涓烘暟缁勬牸寮�
+ loadConfigParams(data?.configJson)
+
+ // 鍔犺浇璁惧閫昏緫鍙傛暟
+ const deviceLogic = extraObj.deviceLogic || {}
+ loadDeviceLogicParams(deviceLogic, data?.deviceType)
+}
+
+// 鍔犺浇閰嶇疆鍙傛暟锛堝吋瀹规棫鐨勫璞℃牸寮忥級
+const loadConfigParams = (configJson) => {
+ if (!configJson) {
+ deviceForm.configParams = []
+ return
+ }
+
+ try {
+ const parsed = typeof configJson === 'string' ? JSON.parse(configJson) : configJson
+
+ // 濡傛灉鏄暟缁勬牸寮忥紝鐩存帴浣跨敤
+ if (Array.isArray(parsed)) {
+ deviceForm.configParams = parsed
+ }
+ // 濡傛灉鏄璞℃牸寮忥紙瀛楁鍚� 鈫� 鍋忕Щ閲忥級锛岃浆鎹负鏁扮粍鏍煎紡
+ else if (typeof parsed === 'object' && parsed !== null) {
+ // 瀛楁鍚嶅埌涓枃鎻忚堪鐨勬槧灏�
+ const fieldDescriptionMap = {
+ 'plcRequest': 'PLC璇锋眰瀛�',
+ 'inPosition': '杩涚墖浣嶇疆',
+ 'plcGlassId1': '鐜荤拑id1',
+ 'plcGlassId2': '鐜荤拑id2',
+ 'plcGlassId3': '鐜荤拑id3',
+ 'plcGlassId4': '鐜荤拑id4',
+ 'plcGlassId5': '鐜荤拑id5',
+ 'plcGlassId6': '鐜荤拑id6',
+ 'plcGlassCount': '鐜荤拑鏁伴噺',
+ 'onlineState': '鑱旀満鐘舵��',
+ 'plcReport': 'PLC姹囨姤',
+ 'state1': '鐘舵��1',
+ 'state2': '鐘舵��2',
+ 'state3': '鐘舵��3',
+ 'state4': '鐘舵��4',
+ 'state5': '鐘舵��5',
+ 'state6': '鐘舵��6',
+ 'mesSend': 'MES鍙戦��',
+ 'mesConfirm': 'MES纭',
+ 'trainInfo': '鍒楄溅淇℃伅',
+ 'start1': '璧峰1',
+ 'start2': '璧峰2',
+ 'start3': '璧峰3',
+ 'start4': '璧峰4',
+ 'start5': '璧峰5',
+ 'start6': '璧峰6',
+ 'target1': '鐩爣1',
+ 'target2': '鐩爣2',
+ 'target3': '鐩爣3',
+ 'target4': '鐩爣4',
+ 'target5': '鐩爣5',
+ 'target6': '鐩爣6',
+ 'mesWidth1': 'MES瀹藉害1',
+ 'mesWidth2': 'MES瀹藉害2',
+ 'mesWidth3': 'MES瀹藉害3',
+ 'mesWidth4': 'MES瀹藉害4',
+ 'mesWidth5': 'MES瀹藉害5',
+ 'mesWidth6': 'MES瀹藉害6',
+ 'mesHeight1': 'MES楂樺害1',
+ 'mesHeight2': 'MES楂樺害2',
+ 'mesHeight3': 'MES楂樺害3',
+ 'mesHeight4': 'MES楂樺害4',
+ 'mesHeight5': 'MES楂樺害5',
+ 'mesHeight6': 'MES楂樺害6',
+ 'mesThickness1': 'MES鍘氬害1',
+ 'mesThickness2': 'MES鍘氬害2',
+ 'mesThickness3': 'MES鍘氬害3',
+ 'mesThickness4': 'MES鍘氬害4',
+ 'mesThickness5': 'MES鍘氬害5',
+ 'mesThickness6': 'MES鍘氬害6',
+ 'edgeDistance1': '杈圭紭璺濈1',
+ 'edgeDistance2': '杈圭紭璺濈2',
+ 'edgeDistance3': '杈圭紭璺濈3',
+ 'edgeDistance4': '杈圭紭璺濈4',
+ 'edgeDistance5': '杈圭紭璺濈5',
+ 'edgeDistance6': '杈圭紭璺濈6',
+ 'targetEdgeDistance1': '鐩爣杈圭紭璺濈1',
+ 'targetEdgeDistance2': '鐩爣杈圭紭璺濈2',
+ 'targetEdgeDistance3': '鐩爣杈圭紭璺濈3',
+ 'targetEdgeDistance4': '鐩爣杈圭紭璺濈4',
+ 'targetEdgeDistance5': '鐩爣杈圭紭璺濈5',
+ 'targetEdgeDistance6': '鐩爣杈圭紭璺濈6',
+ 'alarmInfo': '鎶ヨ淇℃伅'
+ }
+
+ // 杞崲涓烘暟缁勬牸寮�
+ deviceForm.configParams = Object.keys(parsed).map(fieldName => ({
+ paramKey: fieldName,
+ paramValue: String(parsed[fieldName]),
+ description: fieldDescriptionMap[fieldName] || fieldName
+ }))
+ } else {
+ deviceForm.configParams = []
+ }
+ } catch (error) {
+ console.warn('瑙f瀽configJson澶辫触', error)
+ deviceForm.configParams = []
+ }
+}
+
+// 鍔犺浇璁惧閫昏緫鍙傛暟
+const loadDeviceLogicParams = (deviceLogic, deviceType) => {
+ if (deviceType === '涓婂ぇ杞�') {
+ deviceLogicParams.vehicleCapacity = deviceLogic.vehicleCapacity ?? 6000
+ deviceLogicParams.glassIntervalMs = deviceLogic.glassIntervalMs ?? 1000
+ deviceLogicParams.autoFeed = deviceLogic.autoFeed ?? true
+ deviceLogicParams.maxRetryCount = deviceLogic.maxRetryCount ?? 5
+ deviceLogicParams.positionMapping = deviceLogic.positionMapping || {}
+ mappingKeys.value = Object.keys(deviceLogicParams.positionMapping)
+ } else if (deviceType === '澶х悊鐗�') {
+ deviceLogicParams.glassSize = deviceLogic.glassSize ?? 2000
+ deviceLogicParams.processingTime = deviceLogic.processingTime ?? 5000
+ deviceLogicParams.autoProcess = deviceLogic.autoProcess ?? true
+ deviceLogicParams.maxRetryCount = deviceLogic.maxRetryCount ?? 3
+ } else if (deviceType === '鐜荤拑瀛樺偍') {
+ deviceLogicParams.storageCapacity = deviceLogic.storageCapacity ?? 100
+ deviceLogicParams.retrievalMode = deviceLogic.retrievalMode || 'FIFO'
+ deviceLogicParams.autoStore = deviceLogic.autoStore ?? true
+ deviceLogicParams.autoRetrieve = deviceLogic.autoRetrieve ?? true
+ deviceLogicParams.maxRetryCount = deviceLogic.maxRetryCount ?? 3
+ }
+}
+
+// 浣嶇疆鏄犲皠鐩稿叧鏂规硶
+const addPositionMapping = () => {
+ const newKey = `POS${Object.keys(deviceLogicParams.positionMapping).length + 1}`
+ deviceLogicParams.positionMapping[newKey] = 1
+ mappingKeys.value.push(newKey)
+}
+
+const removePositionMapping = (key) => {
+ delete deviceLogicParams.positionMapping[key]
+ mappingKeys.value = mappingKeys.value.filter(k => k !== key)
+}
+
+const updatePositionMapping = (index, newKey, oldValue) => {
+ const oldKey = mappingKeys.value[index]
+ if (oldKey && oldKey !== newKey) {
+ delete deviceLogicParams.positionMapping[oldKey]
+ }
+ mappingKeys.value[index] = newKey
+ if (newKey) {
+ deviceLogicParams.positionMapping[newKey] = oldValue || 1
+ }
}
const resetForm = () => {
Object.assign(deviceForm, getDefaultForm())
deviceFormRef.value?.clearValidate()
+
+ // 閲嶇疆璁惧閫昏緫鍙傛暟
+ deviceLogicParams.vehicleCapacity = 6000
+ deviceLogicParams.glassIntervalMs = 1000
+ deviceLogicParams.autoFeed = true
+ deviceLogicParams.maxRetryCount = 5
+ deviceLogicParams.positionMapping = {}
+ mappingKeys.value = []
+
+ deviceLogicParams.glassSize = 2000
+ deviceLogicParams.processingTime = 5000
+ deviceLogicParams.autoProcess = true
+
+ deviceLogicParams.storageCapacity = 100
+ deviceLogicParams.retrievalMode = 'FIFO'
+ deviceLogicParams.autoStore = true
+ deviceLogicParams.autoRetrieve = true
}
const addConfigParam = () => {
@@ -531,6 +946,44 @@
plcType: deviceForm.plcType
}
+ // 淇濆瓨璁惧閫昏緫鍙傛暟
+ const deviceLogic = {}
+ if (deviceForm.deviceType === '涓婂ぇ杞�') {
+ deviceLogic.vehicleCapacity = deviceLogicParams.vehicleCapacity
+ deviceLogic.glassIntervalMs = deviceLogicParams.glassIntervalMs
+ deviceLogic.autoFeed = deviceLogicParams.autoFeed
+ deviceLogic.maxRetryCount = deviceLogicParams.maxRetryCount
+ deviceLogic.positionMapping = deviceLogicParams.positionMapping
+ } else if (deviceForm.deviceType === '澶х悊鐗�') {
+ deviceLogic.glassSize = deviceLogicParams.glassSize
+ deviceLogic.processingTime = deviceLogicParams.processingTime
+ deviceLogic.autoProcess = deviceLogicParams.autoProcess
+ deviceLogic.maxRetryCount = deviceLogicParams.maxRetryCount
+ } else if (deviceForm.deviceType === '鐜荤拑瀛樺偍') {
+ deviceLogic.storageCapacity = deviceLogicParams.storageCapacity
+ deviceLogic.retrievalMode = deviceLogicParams.retrievalMode
+ deviceLogic.autoStore = deviceLogicParams.autoStore
+ deviceLogic.autoRetrieve = deviceLogicParams.autoRetrieve
+ deviceLogic.maxRetryCount = deviceLogicParams.maxRetryCount
+ }
+
+ if (Object.keys(deviceLogic).length > 0) {
+ extraObj.deviceLogic = deviceLogic
+ }
+
+ // 鏋勫缓 configJson锛氬皢 configParams 鏁扮粍杞崲涓� JSON 瀛楃涓�
+ // configParams 缁撴瀯: [{ paramKey: '', paramValue: '', description: '' }]
+ let configJsonValue = null
+ if (deviceForm.configParams && deviceForm.configParams.length > 0) {
+ // 杩囨护鎺夌┖鍙傛暟
+ const validParams = deviceForm.configParams.filter(
+ param => param.paramKey && param.paramKey.trim() !== ''
+ )
+ if (validParams.length > 0) {
+ configJsonValue = JSON.stringify(validParams)
+ }
+ }
+
const saveData = {
deviceName: deviceForm.deviceName,
deviceCode: deviceForm.deviceCode,
@@ -542,9 +995,7 @@
isPrimary: deviceForm.isPrimary,
enabled: deviceForm.enabled,
description: deviceForm.description,
- configJson: deviceForm.configParams.length > 0
- ? JSON.stringify(deviceForm.configParams)
- : null,
+ configJson: configJsonValue, // 淇濆瓨閰嶇疆鍙傛暟JSON
extraParams: JSON.stringify(extraObj)
}
@@ -562,6 +1013,18 @@
handleClose()
} catch (error) {
console.error('淇濆瓨璁惧閰嶇疆澶辫触:', error)
+ // 濡傛灉鏄〃鍗曢獙璇侀敊璇紝鏄剧ず鏇磋缁嗙殑閿欒淇℃伅
+ if (error && typeof error === 'object' && !error.response) {
+ const errorFields = Object.keys(error)
+ if (errorFields.length > 0) {
+ const firstError = error[errorFields[0]]
+ const errorMessage = Array.isArray(firstError)
+ ? firstError[0]?.message || firstError[0]
+ : firstError?.message || firstError
+ ElMessage.error(`琛ㄥ崟楠岃瘉澶辫触: ${errorMessage}`)
+ return
+ }
+ }
ElMessage.error(isEdit.value ? '鏇存柊璁惧閰嶇疆澶辫触' : '鍒涘缓璁惧閰嶇疆澶辫触')
} finally {
saving.value = false
@@ -647,4 +1110,18 @@
:deep(.el-card__body) {
padding: 20px;
}
+
+.position-mapping {
+ width: 100%;
+}
+
+.mapping-item {
+ display: flex;
+ align-items: center;
+ margin-bottom: 12px;
+ padding: 12px;
+ border: 1px solid #ebeef5;
+ border-radius: 6px;
+ background-color: #fafafa;
+}
</style>
\ No newline at end of file
--
Gitblit v1.8.0