From 223e200a69aff78811cd93de72f6053532f97d3c Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期三, 18 三月 2026 12:47:27 +0800
Subject: [PATCH] #
---
src/main/webapp/views/debugParam/debugParam.html | 1040 +++++++++++++++++++++++++++++++++++++++++++--------------
1 files changed, 776 insertions(+), 264 deletions(-)
diff --git a/src/main/webapp/views/debugParam/debugParam.html b/src/main/webapp/views/debugParam/debugParam.html
index 7dd00a9..94fb9bc 100644
--- a/src/main/webapp/views/debugParam/debugParam.html
+++ b/src/main/webapp/views/debugParam/debugParam.html
@@ -1,299 +1,811 @@
<!DOCTYPE html>
-<html lang="en">
+<html lang="zh-CN">
- <head>
- <meta charset="UTF-8">
- <title>璋冭瘯鍙傛暟</title>
- <link rel="stylesheet" href="../../static/vue/element/element.css">
- <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
- <script type="text/javascript" src="../../static/js/common.js?v=20260309_i18n_fix1"></script>
- <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
- <script type="text/javascript" src="../../static/vue/element/element.js"></script>
- <style>
- .show-box {
- width: 20%;
- display: flex;
- justify-content: flex-start;
- align-items: center;
- margin-bottom: 30px;
- }
- </style>
- </head>
+<head>
+ <meta charset="UTF-8">
+ <title>璋冭瘯鍙傛暟</title>
+ <link rel="stylesheet" href="../../static/vue/element/element.css">
+ <script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
+ <script type="text/javascript" src="../../static/js/common.js"></script>
+ <script type="text/javascript" src="../../static/vue/js/vue.min.js"></script>
+ <script type="text/javascript" src="../../static/vue/element/element.js"></script>
+ <style>
+ body {
+ margin: 0;
+ padding: 16px;
+ background: #f5f7fa;
+ color: #303133;
+ box-sizing: border-box;
+ }
- <body>
- <div id="app">
- <div>
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>璋冨害鍙傛暟</span>
- </div>
+ * {
+ box-sizing: border-box;
+ }
- <div style="display: flex;flex-wrap: wrap;">
- <div class="show-box">
- <div>璋冨害灏忚溅鍚屽眰鏈�澶ф暟閲�</div>
- <el-input v-model="codeMap.dispatchShuttleMaxNum" style="width: 60%;"></el-input>
- </div>
+ .page-shell {
+ max-width: 1600px;
+ margin: 0 auto;
+ }
- <div class="show-box">
- <div>鍏ュ簱棰勭暀灏忚溅</div>
- <el-input v-model="codeMap.shuttleWrkInObligateCount" style="width: 60%;"></el-input>
- </div>
+ .hero-card,
+ .filter-card,
+ .group-card {
+ margin-bottom: 16px;
+ }
- <div class="show-box">
- <div>閬块殰鍐呭湀鍗婂緞</div>
- <el-input v-model="codeMap.avoidInnerCircle" style="width: 60%;"></el-input>
- </div>
+ .hero-header,
+ .group-header,
+ .filter-bar {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ gap: 16px;
+ flex-wrap: wrap;
+ }
- <div class="show-box">
- <div>閬块殰澶栧湀鍗婂緞</div>
- <el-input v-model="codeMap.avoidOuterCircle" style="width: 60%;"></el-input>
- </div>
+ .hero-title {
+ font-size: 20px;
+ font-weight: 600;
+ line-height: 1.2;
+ margin: 0 0 4px;
+ }
- <div class="show-box">
- <div>鍦板浘姣嶈建鏂瑰悜(x,y)</div>
- <el-input v-model="codeMap.direction_map" style="width: 60%;"></el-input>
- </div>
+ .hero-desc,
+ .group-desc {
+ margin: 0;
+ color: #606266;
+ line-height: 1.5;
+ }
- <div class="show-box">
- <div>灏忚溅(x,y)鍛戒护杩愯鏂瑰悜棰犲��</div>
- <el-radio border v-model="codeMap.shuttleDirectionReverse" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.shuttleDirectionReverse" label="N">鍏�</el-radio>
- </div>
+ .hero-actions,
+ .group-actions,
+ .row-actions,
+ .group-tags {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+ }
- <div class="show-box">
- <div>灏忚溅鍑烘彁鍗囨満杩戠偣璺濈</div>
- <el-input v-model="codeMap.shuttleOutLiftLocationDistance" style="width: 60%;"></el-input>
- </div>
+ .summary-strip {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 10px;
+ }
- <div class="show-box">
- <div>灏忚溅绉诲姩杩炵画涓嬪彂鎸囦护</div>
- <el-radio border v-model="codeMap.shuttleMoveCommandsContinuously" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.shuttleMoveCommandsContinuously" label="N">鍏�</el-radio>
- </div>
+ .summary-pill {
+ display: inline-flex;
+ align-items: center;
+ gap: 8px;
+ padding: 6px 10px;
+ border-radius: 999px;
+ background: #f7f9fc;
+ border: 1px solid #ebeef5;
+ font-size: 12px;
+ color: #606266;
+ line-height: 1.4;
+ }
- <div class="show-box">
- <div>鍏佽浜ょ閲嶆柊瑙勫垝璺緞</div>
- <el-radio border v-model="codeMap.trafficControlRestartCalcPath" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.trafficControlRestartCalcPath" label="N">鍏�</el-radio>
- </div>
+ .summary-pill strong {
+ font-size: 14px;
+ color: #303133;
+ }
- <div class="show-box">
- <div>杈撳嚭RCS璋冭瘯鏃ュ織</div>
- <el-radio border v-model="codeMap.wcsDebugShowLog" label="true">寮�</el-radio>
- <el-radio border v-model="codeMap.wcsDebugShowLog" label="false">鍏�</el-radio>
- </div>
- </div>
+ .filter-item {
+ min-width: 220px;
+ flex: 1 1 260px;
+ }
- <div style="margin-top: 20px;">
- <el-button type="primary" @click="saveParam('shuttle')">淇濆瓨</el-button>
- </div>
- </el-card>
- </div>
+ .group-title {
+ font-size: 18px;
+ font-weight: 600;
+ margin-bottom: 6px;
+ }
- <div style="margin-top: 20px;">
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>鍏呯數鍙傛暟</span>
- </div>
+ .code-cell {
+ font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
+ color: #606266;
+ font-size: 12px;
+ line-height: 1.6;
+ word-break: break-all;
+ }
- <div style="display: flex;flex-wrap: wrap;">
- <div class="show-box">
- <div>灏忚溅鍏呯數鏈�澶ч槇鍊�</div>
- <el-input v-model="codeMap.chargeMaxValue" style="width: 60%;"></el-input>
- </div>
+ .config-name {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ line-height: 1.5;
+ }
- <div class="show-box">
- <div>灏忚溅鐢甸噺棰勮闃堝��</div>
- <el-input v-model="codeMap.shuttlePowerEarlyValue" style="width: 60%;"></el-input>
- </div>
+ .config-name-main {
+ font-weight: 600;
+ color: #303133;
+ }
- <div class="show-box">
- <div>灏忚溅婊$數鏍″噯</div>
- <el-radio border v-model="codeMap.shuttleMaxPowerVerify" label="true">寮�</el-radio>
- <el-radio border v-model="codeMap.shuttleMaxPowerVerify" label="false">鍏�</el-radio>
- </div>
+ .config-name-sub {
+ font-size: 12px;
+ color: #909399;
+ }
- <div class="show-box">
- <div>瀹氭椂鍏呯數寮�鍏�</div>
- <el-radio border v-model="codeMap.timedCharge" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.timedCharge" label="N">鍏�</el-radio>
- </div>
+ .editor-cell {
+ min-width: 320px;
+ }
- <div class="show-box">
- <div>瀹氭椂鍏呯數鏃堕棿娈�</div>
- <el-input v-model="codeMap.timedChargeRange" style="width: 60%;"></el-input>
- </div>
+ .status-cell {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+ }
- <div class="show-box">
- <div>灏忚溅榛樿鍏呯數绾�</div>
- <el-input v-model="codeMap.shuttleDefaultChargePowerLine" style="width: 60%;"></el-input>
- </div>
+ .empty-wrap {
+ padding: 32px 0 8px;
+ background: #fff;
+ border-radius: 8px;
+ }
- <div class="show-box">
- <div>灏忚溅瀹氭椂鍏呯數绾�</div>
- <el-input v-model="codeMap.timedChargePowerLine" style="width: 60%;"></el-input>
- </div>
- </div>
+ .el-card__header {
+ padding: 16px 20px;
+ }
- <div style="margin-top: 20px;">
- <el-button type="primary" @click="saveParam('charge')">淇濆瓨</el-button>
- </div>
- </el-card>
- </div>
+ .el-card__body {
+ padding: 18px 20px;
+ }
- <div style="margin-top: 20px;">
- <el-card class="box-card">
- <div slot="header" class="clearfix">
- <span>婕旂ず妯″紡鍙傛暟</span>
- </div>
- <div style="display: flex;flex-wrap: wrap;">
- <div class="show-box">
- <div>绉诲姩婕旂ず妯″紡-妤煎眰</div>
- <el-input v-model="codeMap.demoRunLev" style="width: 60%;"></el-input>
- </div>
+ .hero-card .el-card__body {
+ padding: 14px 18px;
+ }
- <div class="show-box">
- <div>绉诲姩婕旂ず妯″紡-鏄惁鎹㈠眰</div>
- <el-radio border v-model="codeMap.demoSwitchLev" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.demoSwitchLev" label="N">鍏�</el-radio>
- </div>
+ @media (max-width: 900px) {
+ body {
+ padding: 12px;
+ }
- <div class="show-box">
- <div>婕旂ず妯″紡-璐х墿鎼繍</div>
- <el-radio border v-model="codeMap.demoCargoMove" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.demoCargoMove" label="N">鍏�</el-radio>
- </div>
+ .editor-cell {
+ min-width: 0;
+ }
+ }
+ </style>
+</head>
- <div class="show-box">
- <div>婕旂ず妯″紡-璺戝簱</div>
- <el-radio border v-model="codeMap.demoModeRunLoc" label="Y">寮�</el-radio>
- <el-radio border v-model="codeMap.demoModeRunLoc" label="N">鍏�</el-radio>
- </div>
+<body>
+<div id="app" class="page-shell" v-loading="loading">
+ <el-card shadow="never" class="hero-card">
+ <div class="hero-header">
+ <div>
+ <h1 class="hero-title">璋冭瘯鍙傛暟</h1>
+ <p class="hero-desc">
+ 鍩轰簬褰撳墠璁惧鎷撴墤鍜� <code>sys_config</code> 瀹炴椂灞曠ず杩愯鍙傛暟銆�
+ </p>
+ </div>
+ <div class="hero-actions">
+ <el-button icon="el-icon-refresh" @click="reloadData">鍒锋柊鏁版嵁</el-button>
+ <el-button type="primary"
+ icon="el-icon-check"
+ :loading="saveAllLoading"
+ :disabled="!hasChanges"
+ @click="saveAll">
+ 淇濆瓨鍏ㄩ儴鍙樻洿
+ </el-button>
+ </div>
+ </div>
- </div>
+ <div class="summary-strip">
+ <div class="summary-pill" v-for="item in summaryCards" :key="item.key">
+ <span>{{ item.label }}</span>
+ <strong>{{ item.value }}</strong>
+ </div>
+ </div>
+ </el-card>
- <div style="margin-top: 20px;">
- <el-button type="primary" @click="saveParam('demo')">淇濆瓨</el-button>
- </div>
- </el-card>
- </div>
- </div>
- <script>
- var app = new Vue({
- el: '#app',
- data: {
- codeMap: {},
- },
- created() {
- this.init()
- },
- methods: {
- init() {
- this.getConfigData()
- },
- getConfigData() {
- let that = this;
- $.ajax({
- url: baseUrl + "/config/listAll/auth",
- headers: {
- 'token': localStorage.getItem('token')
- },
- data: {},
- dataType: 'json',
- contentType: 'application/json;charset=UTF-8',
- method: 'GET',
- success: function(res) {
- if (res.code == 200) {
- let codeMap = {}
- res.data.forEach((item) => {
- codeMap[item.code] = item.value
- })
- that.codeMap = codeMap;
- } else if (res.code === 403) {
- top.location.href = baseUrl + "/";
- } else {
- that.$message({
- message: res.msg,
- type: 'error'
- });
- }
- }
- });
- },
- saveParam(type) {
- let that = this;
- let codeList = this.getParamData(type)
- let updateCodeList = [];
+ <el-card shadow="never" class="filter-card">
+ <div class="filter-bar">
+ <div class="filter-item">
+ <el-input v-model.trim="searchText"
+ clearable
+ prefix-icon="el-icon-search"
+ placeholder="鎸夐厤缃悕绉版垨缂栫爜绛涢��">
+ </el-input>
+ </div>
+ <div style="width: 240px;">
+ <el-select v-model="selectedType" filterable style="width: 100%;">
+ <el-option label="鍏ㄩ儴鍒嗙粍" value="all"></el-option>
+ <el-option v-for="type in selectTypeOptions"
+ :key="type"
+ :label="getGroupLabel(type)"
+ :value="type">
+ </el-option>
+ </el-select>
+ </div>
+ <div>
+ <el-switch v-model="changedOnly" active-text="浠呯湅宸蹭慨鏀�"></el-switch>
+ </div>
+ <div class="group-tags">
+ <el-tag size="small">鍙傛暟 {{ configList.length }} 椤�</el-tag>
+ <el-tag size="small">鍒嗙粍 {{ selectTypeOptions.length }} 涓�</el-tag>
+ <el-tag v-if="hasChanges" type="warning" size="small">寰呬繚瀛� {{ changedCount }} 椤�</el-tag>
+ </div>
+ </div>
+ </el-card>
- codeList.forEach((key) => {
- let value = this.codeMap[key]
- updateCodeList.push({
- code: key,
- value: value
- })
- })
+ <div v-if="filteredGroups.length === 0" class="empty-wrap">
+ <el-empty description="褰撳墠绛涢�夋潯浠朵笅娌℃湁鍙樉绀虹殑鍙傛暟"></el-empty>
+ </div>
- console.log(updateCodeList)
+ <el-card v-for="group in filteredGroups" :key="group.type" shadow="never" class="group-card">
+ <div slot="header" class="group-header">
+ <div>
+ <div class="group-title">{{ group.label }}</div>
+ <p class="group-desc">{{ group.desc }}</p>
+ <div class="group-tags" style="margin-top: 10px;">
+ <el-tag size="mini">{{ group.items.length }} 椤�</el-tag>
+ <el-tag v-if="group.deviceText" type="success" size="mini">{{ group.deviceText }}</el-tag>
+ <el-tag v-if="group.changedCount > 0" type="warning" size="mini">宸蹭慨鏀� {{ group.changedCount }} 椤�</el-tag>
+ </div>
+ </div>
+ <div class="group-actions">
+ <el-button size="mini"
+ :disabled="group.changedCount === 0"
+ :loading="saveGroupLoading[group.type]"
+ type="primary"
+ @click="saveGroup(group)">
+ 淇濆瓨鏈粍
+ </el-button>
+ </div>
+ </div>
- $.ajax({
- url: baseUrl + "/config/updateBatch",
- headers: {
- 'token': localStorage.getItem('token')
- },
- data: JSON.stringify(updateCodeList),
- dataType: 'json',
- contentType: 'application/json;charset=UTF-8',
- method: 'POST',
- success: function(res) {
- if (res.code == 200) {
- that.$message({
- message: '淇濆瓨鎴愬姛',
- type: 'success'
- });
- } else if (res.code === 403) {
- top.location.href = baseUrl + "/";
- } else {
- that.$message({
- message: res.msg,
- type: 'error'
- });
- }
- }
- });
- },
- getParamData(type) {
- let data = []
- if(type == "shuttle") {
- data.push('dispatchShuttleMaxNum');
- data.push('shuttleWrkInObligateCount');
- data.push('avoidInnerCircle');
- data.push('avoidOuterCircle');
- data.push('direction_map');
- data.push('shuttleDirectionReverse');
- data.push('shuttleOutLiftLocationDistance');
- data.push('shuttleMoveCommandsContinuously');
- data.push('trafficControlRestartCalcPath');
- data.push('wcsDebugShowLog');
- }else if (type == "charge") {
- data.push('chargeMaxValue');
- data.push('shuttlePowerEarlyValue');
- data.push('shuttleMaxPowerVerify');
- data.push('timedCharge');
- data.push('timedChargeRange');
- data.push('shuttleDefaultChargePowerLine');
- data.push('timedChargePowerLine');
- }else if (type == "demo") {
- data.push('demoRunLev');
- data.push('demoSwitchLev');
- data.push('demoCargoMove');
- data.push('demoModeRunLoc');
- }
+ <el-table :data="group.items" border stripe size="mini">
+ <el-table-column label="鍙傛暟" min-width="260">
+ <template slot-scope="scope">
+ <div class="config-name">
+ <span class="config-name-main">{{ scope.row.name || scope.row.code }}</span>
+ <span class="config-name-sub">
+ {{ getValueTypeText(scope.row) }}
+ <span v-if="scope.row.status === 0"> / 宸茬鐢�</span>
+ </span>
+ </div>
+ </template>
+ </el-table-column>
- return data;
- },
- },
- })
- </script>
- </body>
+ <el-table-column label="缂栫爜" min-width="210">
+ <template slot-scope="scope">
+ <div class="code-cell">{{ scope.row.code }}</div>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="褰撳墠鍊�" min-width="420">
+ <template slot-scope="scope">
+ <div class="editor-cell">
+ <el-radio-group v-if="resolveEditor(scope.row) === 'boolean'"
+ v-model="codeMap[scope.row.code]"
+ size="mini">
+ <el-radio-button v-for="option in getBooleanOptions(scope.row)"
+ :key="option.value"
+ :label="option.value">
+ {{ option.label }}
+ </el-radio-button>
+ </el-radio-group>
+
+ <el-input v-else-if="resolveEditor(scope.row) === 'textarea'"
+ v-model="codeMap[scope.row.code]"
+ type="textarea"
+ resize="vertical"
+ :autosize="{ minRows: 2, maxRows: 5 }">
+ </el-input>
+
+ <el-input v-else
+ v-model="codeMap[scope.row.code]"
+ clearable>
+ </el-input>
+ </div>
+ </template>
+ </el-table-column>
+
+ <el-table-column label="鐘舵��" width="170">
+ <template slot-scope="scope">
+ <div class="status-cell">
+ <el-tag v-if="isChanged(scope.row.code)" type="warning" size="mini">寰呬繚瀛�</el-tag>
+ <el-tag v-else type="success" size="mini">宸插悓姝�</el-tag>
+ <el-button v-if="isChanged(scope.row.code)"
+ type="text"
+ size="mini"
+ @click="resetConfig(scope.row.code)">
+ 杩樺師
+ </el-button>
+ </div>
+ </template>
+ </el-table-column>
+ </el-table>
+ </el-card>
+</div>
+
+<script>
+ new Vue({
+ el: '#app',
+ data: {
+ loading: false,
+ saveAllLoading: false,
+ saveGroupLoading: {},
+ configList: [],
+ deviceList: [],
+ codeMap: {},
+ originalCodeMap: {},
+ searchText: '',
+ selectedType: 'all',
+ changedOnly: false,
+ groupOrder: ['system', 'solver', 'crn', 'fake', 'notify', 'String', 'other']
+ },
+ computed: {
+ selectTypeOptions: function () {
+ var typeMap = {};
+ (this.configList || []).forEach(function (item) {
+ var type = item && item.selectType ? item.selectType : 'other';
+ typeMap[type] = true;
+ });
+ return this.sortTypes(Object.keys(typeMap));
+ },
+ deviceTypeCountMap: function () {
+ var result = {};
+ (this.deviceList || []).forEach(function (item) {
+ if (!item || !item.deviceType) {
+ return;
+ }
+ result[item.deviceType] = (result[item.deviceType] || 0) + 1;
+ });
+ return result;
+ },
+ fakeDeviceCount: function () {
+ var total = 0;
+ (this.deviceList || []).forEach(function (item) {
+ if (item && String(item.fake) === '1') {
+ total += 1;
+ }
+ });
+ return total;
+ },
+ changedCount: function () {
+ var self = this;
+ var total = 0;
+ Object.keys(this.codeMap || {}).forEach(function (code) {
+ if (self.isChanged(code)) {
+ total += 1;
+ }
+ });
+ return total;
+ },
+ hasChanges: function () {
+ return this.changedCount > 0;
+ },
+ summaryCards: function () {
+ return [
+ {
+ key: 'crn',
+ label: '鍫嗗灈鏈�',
+ value: this.deviceTypeCountMap.Crn || 0,
+ hint: '褰撳墠宸查厤缃殑鍗曞伐浣嶅爢鍨涙満鏁伴噺'
+ },
+ {
+ key: 'dualCrn',
+ label: '鍙屽伐浣嶅爢鍨涙満',
+ value: this.deviceTypeCountMap.DualCrn || 0,
+ hint: '褰撳墠宸查厤缃殑鍙屽伐浣嶅爢鍨涙満鏁伴噺'
+ },
+ {
+ key: 'devp',
+ label: '杈撻�佺珯鎺у埗鍣�',
+ value: this.deviceTypeCountMap.Devp || 0,
+ hint: '褰撳墠绔欏彴/杈撻�佺嚎鎺у埗鍣ㄦ暟閲�'
+ },
+ {
+ key: 'rgv',
+ label: 'RGV',
+ value: this.deviceTypeCountMap.Rgv || 0,
+ hint: '褰撳墠 RGV 鎺у埗鍣ㄦ暟閲�'
+ },
+ {
+ key: 'fake',
+ label: '浠跨湡璁惧',
+ value: this.fakeDeviceCount,
+ hint: 'device_config 涓� fake=1 鐨勮澶囨暟'
+ },
+ {
+ key: 'groups',
+ label: '閰嶇疆鍒嗙粍',
+ value: this.selectTypeOptions.length,
+ hint: '鏉ヨ嚜 sys_config.select_type'
+ },
+ {
+ key: 'configs',
+ label: '鍙傛暟鎬绘暟',
+ value: this.configList.length,
+ hint: '褰撳墠椤甸潰绾冲叆绠$悊鐨� sys_config 鏁伴噺'
+ },
+ {
+ key: 'changed',
+ label: '寰呬繚瀛樺彉鏇�',
+ value: this.changedCount,
+ hint: this.changedCount > 0 ? '瀛樺湪灏氭湭鎻愪氦鐨勫弬鏁版敼鍔�' : '褰撳墠娌℃湁鏈繚瀛樼殑鏀瑰姩'
+ }
+ ];
+ },
+ filteredGroups: function () {
+ var self = this;
+ var groups = {};
+ var keyword = (this.searchText || '').toLowerCase();
+ var list = Array.isArray(this.configList) ? this.configList.slice() : [];
+ list.sort(function (a, b) {
+ return (a.id || 0) - (b.id || 0);
+ });
+
+ list.forEach(function (item) {
+ if (!item || !item.code) {
+ return;
+ }
+ var type = item.selectType || 'other';
+ if (self.selectedType !== 'all' && self.selectedType !== type) {
+ return;
+ }
+ if (keyword) {
+ var text = ((item.name || '') + ' ' + item.code).toLowerCase();
+ if (text.indexOf(keyword) === -1) {
+ return;
+ }
+ }
+ if (self.changedOnly && !self.isChanged(item.code)) {
+ return;
+ }
+ if (!groups[type]) {
+ groups[type] = {
+ type: type,
+ label: self.getGroupLabel(type),
+ desc: self.getGroupDesc(type),
+ deviceText: self.getGroupDeviceText(type),
+ items: [],
+ changedCount: 0
+ };
+ }
+ groups[type].items.push(item);
+ if (self.isChanged(item.code)) {
+ groups[type].changedCount += 1;
+ }
+ });
+
+ return self.sortTypes(Object.keys(groups)).map(function (type) {
+ return groups[type];
+ });
+ }
+ },
+ created: function () {
+ this.reloadData();
+ },
+ methods: {
+ reloadData: function () {
+ var self = this;
+ var pending = 2;
+ var failed = false;
+ self.loading = true;
+
+ function finish() {
+ pending -= 1;
+ if (pending <= 0) {
+ self.loading = false;
+ if (failed) {
+ self.$message.error('閮ㄥ垎鏁版嵁鍔犺浇澶辫触');
+ }
+ }
+ }
+
+ $.ajax({
+ url: baseUrl + "/config/listAll/auth",
+ headers: self.authHeaders(),
+ dataType: 'json',
+ method: 'GET',
+ success: function (res) {
+ if (self.handleForbidden(res)) {
+ return;
+ }
+ if (!res || res.code !== 200 || !Array.isArray(res.data)) {
+ failed = true;
+ finish();
+ return;
+ }
+ self.configList = res.data.slice();
+ self.rebuildCodeMaps();
+ finish();
+ },
+ error: function () {
+ failed = true;
+ finish();
+ }
+ });
+
+ $.ajax({
+ url: baseUrl + "/deviceConfig/list/auth",
+ headers: self.authHeaders(),
+ dataType: 'json',
+ method: 'GET',
+ data: {
+ curr: 1,
+ limit: 200
+ },
+ success: function (res) {
+ if (self.handleForbidden(res)) {
+ return;
+ }
+ if (!res || res.code !== 200 || !res.data) {
+ failed = true;
+ finish();
+ return;
+ }
+ self.deviceList = Array.isArray(res.data.records) ? res.data.records : [];
+ finish();
+ },
+ error: function () {
+ failed = true;
+ finish();
+ }
+ });
+ },
+ rebuildCodeMaps: function () {
+ var current = {};
+ (this.configList || []).forEach(function (item) {
+ if (item && item.code) {
+ current[item.code] = item.value == null ? '' : String(item.value);
+ }
+ });
+ this.codeMap = $.extend({}, current);
+ this.originalCodeMap = $.extend({}, current);
+ },
+ authHeaders: function () {
+ return {
+ token: localStorage.getItem('token')
+ };
+ },
+ handleForbidden: function (res) {
+ if (res && res.code === 403) {
+ top.location.href = baseUrl + "/";
+ return true;
+ }
+ return false;
+ },
+ sortTypes: function (types) {
+ var self = this;
+ return (types || []).slice().sort(function (a, b) {
+ var aIndex = self.groupOrder.indexOf(a);
+ var bIndex = self.groupOrder.indexOf(b);
+ if (aIndex === -1) {
+ aIndex = self.groupOrder.length + 100;
+ }
+ if (bIndex === -1) {
+ bIndex = self.groupOrder.length + 100;
+ }
+ if (aIndex !== bIndex) {
+ return aIndex - bIndex;
+ }
+ return String(a).localeCompare(String(b));
+ });
+ },
+ getGroupLabel: function (type) {
+ var labels = {
+ system: '绯荤粺杩愯鍙傛暟',
+ solver: '姹傝В鍣ㄤ笌璋冨害鍙傛暟',
+ crn: '鍫嗗灈鏈烘帶鍒跺弬鏁�',
+ fake: '浠跨湡妯″紡鍙傛暟',
+ notify: '閫氱煡涓婃姤鍙傛暟',
+ String: '绔欑偣璺緞鍙傛暟',
+ other: '鍏朵粬鍙傛暟'
+ };
+ return labels[type] || type;
+ },
+ getGroupDesc: function (type) {
+ var descMap = {
+ system: '瑕嗙洊 WMS 鑱斿姩銆佽澶囨棩蹇椼�佽緭閫佺嚎浠诲姟鍜岀洃鎺у湴鍥剧瓑绯荤粺绾у弬鏁般��',
+ solver: '鐢ㄤ簬鍫嗗灈鏈鸿皟搴︿笌姹傝В鍣ㄦ墽琛岋紝鍖呮嫭閫熷害銆佹潈閲嶃�佹渶澶ф眰瑙f椂闀跨瓑銆�',
+ crn: '閽堝鍫嗗灈鏈烘帶鍒堕摼璺殑璋冭瘯鍙傛暟锛屼紭鍏堢敤浜庡紓甯稿洖婊氬拰鎵ц淇濇姢銆�',
+ fake: '浠跨湡寮�鍏充笌浠诲姟鐢熸垚绛栫暐锛岄�傚悎鑱旇皟鎴栨紨绀虹幆澧冦��',
+ notify: '澶栭儴娑堟伅閫氱煡銆侀拤閽夊憡璀﹀拰 WMS 鍥炶皟閲嶈瘯绛栫暐銆�',
+ String: '绔欑偣璺緞璇勫垎涓庨粯璁ゆā鏉块�夋嫨锛屽奖鍝嶈緭閫佺珯鐐瑰寰勭粨鏋溿��',
+ other: '褰撳墠鏈綊绫荤殑閰嶇疆椤广��'
+ };
+ return descMap[type] || '褰撳墠鍒嗙粍鏈厤缃鏄庛��';
+ },
+ getGroupDeviceText: function (type) {
+ var crnCount = this.deviceTypeCountMap.Crn || 0;
+ var dualCrnCount = this.deviceTypeCountMap.DualCrn || 0;
+ var devpCount = this.deviceTypeCountMap.Devp || 0;
+ var rgvCount = this.deviceTypeCountMap.Rgv || 0;
+ if (type === 'system') {
+ return '璁惧鑼冨洿锛氬爢鍨涙満 ' + crnCount + ' 鍙� / 鍙屽伐浣� ' + dualCrnCount + ' 鍙� / 杈撻�佺珯鎺у埗鍣� ' + devpCount + ' 鍙� / RGV ' + rgvCount + ' 鍙�';
+ }
+ if (type === 'solver' || type === 'crn') {
+ return '鍏宠仈鍫嗗灈鏈猴細鍗曞伐浣� ' + crnCount + ' 鍙� / 鍙屽伐浣� ' + dualCrnCount + ' 鍙�';
+ }
+ if (type === 'fake') {
+ return '浠跨湡璁惧锛�' + this.fakeDeviceCount + ' 鍙�';
+ }
+ if (type === 'notify') {
+ return '澶栭儴閾捐矾锛歐MS / 閽夐拤 / 閫氱煡閲嶈瘯';
+ }
+ if (type === 'String') {
+ return '璺緞閰嶇疆锛氳緭閫佺珯鐐硅瘎鍒嗕笌妯℃澘';
+ }
+ return '';
+ },
+ getValueTypeText: function (config) {
+ if (config && config.type === 2) {
+ return 'JSON';
+ }
+ if (this.resolveEditor(config) === 'boolean') {
+ return '甯冨皵寮�鍏�';
+ }
+ if (this.resolveEditor(config) === 'textarea') {
+ return '闀挎枃鏈�';
+ }
+ return '瀛楃涓�';
+ },
+ resolveEditor: function (config) {
+ var value = this.getCodeValue(config.code);
+ if (config && config.type === 2) {
+ return 'textarea';
+ }
+ if (this.isBooleanValue(value)) {
+ return 'boolean';
+ }
+ if ((config && /url|uri|path/i.test(config.code || '')) || String(value || '').length > 60) {
+ return 'textarea';
+ }
+ return 'input';
+ },
+ isBooleanValue: function (value) {
+ var text = value == null ? '' : String(value);
+ return text === 'Y' || text === 'N' || text === 'true' || text === 'false';
+ },
+ getBooleanOptions: function (config) {
+ var value = this.getCodeValue(config.code);
+ if (String(value) === 'Y' || String(value) === 'N') {
+ return [
+ { label: '寮�', value: 'Y' },
+ { label: '鍏�', value: 'N' }
+ ];
+ }
+ return [
+ { label: '寮�', value: 'true' },
+ { label: '鍏�', value: 'false' }
+ ];
+ },
+ getCodeValue: function (code) {
+ if (!code) {
+ return '';
+ }
+ return this.codeMap[code] == null ? '' : String(this.codeMap[code]);
+ },
+ isChanged: function (code) {
+ return this.getCodeValue(code) !== (this.originalCodeMap[code] == null ? '' : String(this.originalCodeMap[code]));
+ },
+ resetConfig: function (code) {
+ this.$set(this.codeMap, code, this.originalCodeMap[code] == null ? '' : String(this.originalCodeMap[code]));
+ },
+ collectChangedItems: function (items) {
+ var self = this;
+ return (items || []).filter(function (item) {
+ return item && item.code && self.isChanged(item.code);
+ });
+ },
+ validateItems: function (items) {
+ var error = '';
+ (items || []).some(function (item) {
+ if (!item) {
+ return false;
+ }
+ if (item.type === 2) {
+ try {
+ JSON.parse(item.value);
+ } catch (e) {
+ error = (item.name || item.code) + ' JSON 鏍煎紡涓嶆纭�';
+ return true;
+ }
+ }
+ return false;
+ });
+ return error;
+ },
+ doSave: function (items, saveKey) {
+ var self = this;
+ var changedItems = self.collectChangedItems(items);
+ if (changedItems.length === 0) {
+ self.$message({
+ message: '褰撳墠娌℃湁闇�瑕佷繚瀛樼殑鍙樻洿',
+ type: 'info'
+ });
+ return;
+ }
+
+ var payload = changedItems.map(function (item) {
+ return {
+ id: item.id,
+ name: item.name,
+ code: item.code,
+ value: self.getCodeValue(item.code),
+ type: item.type,
+ status: item.status,
+ selectType: item.selectType
+ };
+ });
+
+ var validateMsg = self.validateItems(payload);
+ if (validateMsg) {
+ self.$message({
+ message: validateMsg,
+ type: 'error'
+ });
+ return;
+ }
+
+ if (saveKey === 'all') {
+ self.saveAllLoading = true;
+ } else {
+ self.$set(self.saveGroupLoading, saveKey, true);
+ }
+
+ $.ajax({
+ url: baseUrl + "/config/updateBatch",
+ headers: self.authHeaders(),
+ data: JSON.stringify(payload.map(function (item) {
+ return {
+ code: item.code,
+ value: item.value
+ };
+ })),
+ dataType: 'json',
+ contentType: 'application/json;charset=UTF-8',
+ method: 'POST',
+ success: function (res) {
+ if (saveKey === 'all') {
+ self.saveAllLoading = false;
+ } else {
+ self.$set(self.saveGroupLoading, saveKey, false);
+ }
+ if (self.handleForbidden(res)) {
+ return;
+ }
+ if (!res || res.code !== 200) {
+ self.$message({
+ message: res && res.msg ? res.msg : '淇濆瓨澶辫触',
+ type: 'error'
+ });
+ return;
+ }
+ payload.forEach(function (item) {
+ self.originalCodeMap[item.code] = item.value == null ? '' : String(item.value);
+ });
+ self.$message({
+ message: '淇濆瓨鎴愬姛锛岃繍琛岀紦瀛樺凡鍚屾鍒锋柊',
+ type: 'success'
+ });
+ },
+ error: function () {
+ if (saveKey === 'all') {
+ self.saveAllLoading = false;
+ } else {
+ self.$set(self.saveGroupLoading, saveKey, false);
+ }
+ self.$message({
+ message: '淇濆瓨澶辫触',
+ type: 'error'
+ });
+ }
+ });
+ },
+ saveGroup: function (group) {
+ this.doSave(group.items, group.type);
+ },
+ saveAll: function () {
+ this.doSave(this.configList, 'all');
+ }
+ }
+ });
+</script>
+</body>
</html>
--
Gitblit v1.9.1