继电器页面添加编辑以及去除无关功能

This commit is contained in:
1 2025-07-08 09:32:07 +08:00
parent a36957d9a3
commit 8eafdac1d7
7 changed files with 699 additions and 472 deletions

191
node_modules/.package-lock.json generated vendored
View File

@ -7,7 +7,6 @@
"node_modules/@babel/helper-string-parser": { "node_modules/@babel/helper-string-parser": {
"version": "7.25.9", "version": "7.25.9",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
@ -15,7 +14,6 @@
"node_modules/@babel/helper-validator-identifier": { "node_modules/@babel/helper-validator-identifier": {
"version": "7.25.9", "version": "7.25.9",
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
} }
@ -23,7 +21,6 @@
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.27.0", "version": "7.27.0",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/types": "^7.27.0" "@babel/types": "^7.27.0"
}, },
@ -37,7 +34,6 @@
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.27.0", "version": "7.27.0",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/helper-string-parser": "^7.25.9", "@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9" "@babel/helper-validator-identifier": "^7.25.9"
@ -92,7 +88,6 @@
"node_modules/@vue/compiler-core": { "node_modules/@vue/compiler-core": {
"version": "3.5.13", "version": "3.5.13",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/parser": "^7.25.3", "@babel/parser": "^7.25.3",
"@vue/shared": "3.5.13", "@vue/shared": "3.5.13",
@ -104,7 +99,6 @@
"node_modules/@vue/compiler-dom": { "node_modules/@vue/compiler-dom": {
"version": "3.5.13", "version": "3.5.13",
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@vue/compiler-core": "3.5.13", "@vue/compiler-core": "3.5.13",
"@vue/shared": "3.5.13" "@vue/shared": "3.5.13"
@ -181,8 +175,30 @@
}, },
"node_modules/@vue/shared": { "node_modules/@vue/shared": {
"version": "3.5.13", "version": "3.5.13",
"license": "MIT"
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT", "license": "MIT",
"peer": true "dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/async": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
"dev": true,
"license": "MIT"
}, },
"node_modules/async-limiter": { "node_modules/async-limiter": {
"version": "1.0.1", "version": "1.0.1",
@ -273,6 +289,72 @@
"readable-stream": "> 1.0.0 < 3.0.0" "readable-stream": "> 1.0.0 < 3.0.0"
} }
}, },
"node_modules/chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/code-inspector-core": {
"version": "0.20.15",
"resolved": "https://registry.npmjs.org/code-inspector-core/-/code-inspector-core-0.20.15.tgz",
"integrity": "sha512-2PKFKkrdacwieS/A0e8nHf6AfqOGN4OQx4HtIPh8H+GfQry1jwsLdi+uCMMoBP4w/Cujy6onVYVg55Iu5w2OYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "^3.5.13",
"chalk": "^4.1.1",
"dotenv": "^16.1.4",
"launch-ide": "1.0.7",
"portfinder": "^1.0.28"
}
},
"node_modules/code-inspector-plugin": {
"version": "0.20.15",
"resolved": "https://registry.npmjs.org/code-inspector-plugin/-/code-inspector-plugin-0.20.15.tgz",
"integrity": "sha512-JIFNpBor45i1SnyD28TqbTsB6bND57kYzGR4c3gqIhZj9bO1nxSd51ef8OOSbsBXxhMpNjbldwYoBuQExdFAVA==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "4.1.1",
"code-inspector-core": "0.20.15",
"dotenv": "^16.3.1",
"esbuild-code-inspector-plugin": "0.20.15",
"vite-code-inspector-plugin": "0.20.15",
"webpack-code-inspector-plugin": "0.20.15"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true,
"license": "MIT"
},
"node_modules/commist": { "node_modules/commist": {
"version": "1.1.0", "version": "1.1.0",
"license": "MIT", "license": "MIT",
@ -333,6 +415,19 @@
} }
} }
}, },
"node_modules/dotenv": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/duplexify": { "node_modules/duplexify": {
"version": "3.7.1", "version": "3.7.1",
"license": "MIT", "license": "MIT",
@ -353,7 +448,6 @@
"node_modules/entities": { "node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"peer": true,
"engines": { "engines": {
"node": ">=0.12" "node": ">=0.12"
}, },
@ -422,6 +516,16 @@
"node": ">=0.12" "node": ">=0.12"
} }
}, },
"node_modules/esbuild-code-inspector-plugin": {
"version": "0.20.15",
"resolved": "https://registry.npmjs.org/esbuild-code-inspector-plugin/-/esbuild-code-inspector-plugin-0.20.15.tgz",
"integrity": "sha512-iCTPL4plbWPX+KerG1VUMK/+iuxm/RB9DLBKGVCgB2z7viw3O00+C2HIVua9QBcb13kU33Ws61BuIP7nfz74PQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"code-inspector-core": "0.20.15"
}
},
"node_modules/esniff": { "node_modules/esniff": {
"version": "2.0.1", "version": "2.0.1",
"license": "ISC", "license": "ISC",
@ -437,8 +541,7 @@
}, },
"node_modules/estree-walker": { "node_modules/estree-walker": {
"version": "2.0.2", "version": "2.0.2",
"license": "MIT", "license": "MIT"
"peer": true
}, },
"node_modules/event-emitter": { "node_modules/event-emitter": {
"version": "0.3.5", "version": "0.3.5",
@ -508,6 +611,16 @@
"node": ">= 0.10" "node": ">= 0.10"
} }
}, },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/help-me": { "node_modules/help-me": {
"version": "1.1.0", "version": "1.1.0",
"license": "MIT", "license": "MIT",
@ -622,6 +735,17 @@
"version": "1.0.1", "version": "1.0.1",
"license": "MIT" "license": "MIT"
}, },
"node_modules/launch-ide": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/launch-ide/-/launch-ide-1.0.7.tgz",
"integrity": "sha512-wJMTq6U2sVYqxrlp544KQxtl8cHoXFfQa2ivDtKJ6ock2ARneiEHqUFce/NQsnNP1aZNg4OXB6g00oFRvni1/Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.1.1",
"dotenv": "^16.1.4"
}
},
"node_modules/leven": { "node_modules/leven": {
"version": "2.1.0", "version": "2.1.0",
"license": "MIT", "license": "MIT",
@ -754,6 +878,20 @@
"license": "ISC", "license": "ISC",
"peer": true "peer": true
}, },
"node_modules/portfinder": {
"version": "1.0.37",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.37.tgz",
"integrity": "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw==",
"dev": true,
"license": "MIT",
"dependencies": {
"async": "^3.2.6",
"debug": "^4.3.6"
},
"engines": {
"node": ">= 10.12"
}
},
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.5.3", "version": "8.5.3",
"funding": [ "funding": [
@ -872,6 +1010,19 @@
"safe-buffer": "~5.1.0" "safe-buffer": "~5.1.0"
} }
}, },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/through2": { "node_modules/through2": {
"version": "2.0.5", "version": "2.0.5",
"license": "MIT", "license": "MIT",
@ -930,6 +1081,16 @@
"version": "1.0.2", "version": "1.0.2",
"license": "MIT" "license": "MIT"
}, },
"node_modules/vite-code-inspector-plugin": {
"version": "0.20.15",
"resolved": "https://registry.npmjs.org/vite-code-inspector-plugin/-/vite-code-inspector-plugin-0.20.15.tgz",
"integrity": "sha512-Zd6dFN5/uqz0zkys6F+pNG//ToWw5nBGerPfwsD4KWMgEauXbPsQl78k20Fur/4dsrmUDXtM2uGG6FSdAsVT9A==",
"dev": true,
"license": "MIT",
"dependencies": {
"code-inspector-core": "0.20.15"
}
},
"node_modules/vue": { "node_modules/vue": {
"version": "3.5.13", "version": "3.5.13",
"license": "MIT", "license": "MIT",
@ -968,6 +1129,16 @@
"vue": "^3.0.0" "vue": "^3.0.0"
} }
}, },
"node_modules/webpack-code-inspector-plugin": {
"version": "0.20.15",
"resolved": "https://registry.npmjs.org/webpack-code-inspector-plugin/-/webpack-code-inspector-plugin-0.20.15.tgz",
"integrity": "sha512-CaaIAMHOVCjWT2TEvhutZdR4SW/F0AAmRDtfafirRnhgmGH7fRHn8UB4hTI5z1AnS4FtLOt/RrW+UZkMMZc8+Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"code-inspector-core": "0.20.15"
}
},
"node_modules/websocket-stream": { "node_modules/websocket-stream": {
"version": "5.5.2", "version": "5.5.2",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",

View File

@ -21,5 +21,8 @@
"fastbee" "fastbee"
], ],
"author": "fastbee", "author": "fastbee",
"license": "ISC" "license": "ISC",
"devDependencies": {
"code-inspector-plugin": "^0.20.15"
}
} }

View File

@ -23,9 +23,9 @@
<running-status v-show="baseTabIndex === 0" ref="runningStatus" <running-status v-show="baseTabIndex === 0" ref="runningStatus"
:device="deviceForm"></running-status> :device="deviceForm"></running-status>
<!-- 设备实时监测 --> <!-- 设备实时监测 -->
<device-monitor v-show="baseTabIndex == 1" ref="deviceMonitor" :show="baseTabIndex == 1" <!-- <device-monitor v-show="baseTabIndex == 1" ref="deviceMonitor" :show="baseTabIndex == 1"
:device="deviceForm"> :device="deviceForm">
</device-monitor> </device-monitor> -->
<!-- 视频监控 --> <!-- 视频监控 -->
<video-monitor v-show="baseTabIndex == 2" ref="videoMonitor" <video-monitor v-show="baseTabIndex == 2" ref="videoMonitor"
:device="deviceForm"></video-monitor> :device="deviceForm"></video-monitor>
@ -235,12 +235,12 @@
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/device_black.png"> <image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/device_black.png">
</image> </image>
</u-tabbar-item> </u-tabbar-item>
<u-tabbar-item :text="$tt('deviceDetail.timing')" @click="tabbarClick(1)"> <!-- <u-tabbar-item :text="$tt('deviceDetail.timing')" @click="tabbarClick(1)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/time_blue.png"> <image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/time_blue.png">
</image> </image>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/time_black.png"> <image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/time_black.png">
</image> </image>
</u-tabbar-item> </u-tabbar-item> -->
<u-tabbar-item :text="$tt('deviceDetail.journal')" @click="tabbarClick(2)"> <u-tabbar-item :text="$tt('deviceDetail.journal')" @click="tabbarClick(2)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/log_blue.png"> <image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/log_blue.png">
</image> </image>
@ -254,12 +254,12 @@
src="/static/home/tabBar/statistic_black.png"> src="/static/home/tabBar/statistic_black.png">
</image> </image>
</u-tabbar-item> </u-tabbar-item>
<u-tabbar-item :text="$tt('deviceDetail.scada')" @click="tabbarClick(4)"> <!-- <u-tabbar-item :text="$tt('deviceDetail.scada')" @click="tabbarClick(4)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/scada_blue.png"> <image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/scada_blue.png">
</image> </image>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/scada_black.png"> <image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/scada_black.png">
</image> </image>
</u-tabbar-item> </u-tabbar-item> -->
</u-tabbar> </u-tabbar>
<u-modal :show="showScada" content="暂无组态,请先去网页端配置模板组态" @confirm="() => showScada = false" <u-modal :show="showScada" content="暂无组态,请先去网页端配置模板组态" @confirm="() => showScada = false"
@cancel="() => showScada = false" showCancelButton></u-modal> @cancel="() => showScada = false" showCancelButton></u-modal>
@ -309,11 +309,14 @@
tabbarIndex: 0, tabbarIndex: 0,
baseTabList: [{ baseTabList: [{
name: this.$tt('deviceDetail.overview') name: this.$tt('deviceDetail.overview')
}, { },
name: this.$tt('deviceDetail.monitor') // {
}, { // name: this.$tt('deviceDetail.monitor')
name: this.$tt('deviceDetail.Surveillance') // },
}, { // {
// name: this.$tt('deviceDetail.Surveillance')
// },
{
name: this.$tt('deviceDetail.alert') name: this.$tt('deviceDetail.alert')
}], }],
videoTabList: [{ videoTabList: [{

View File

@ -1,17 +1,19 @@
<template> <template>
<view class="device-status"> <view class="device-status">
<view class="title-wrap"> <view class="title-wrap">
<view style="width: 175px;"> <!-- <view style="width: 175px;">
<u-subsection :list="modeList" mode="subsection" :current="current" <u-subsection :list="modeList" mode="subsection" :current="current"
@change="sectionChange"></u-subsection> @change="sectionChange"></u-subsection>
</view> </view> -->
<u--text iconStyle="color: #486ff2; margin-right: 4px; font-size: 22px;" type="primary" <u--text iconStyle="color: #486ff2; margin-right: 4px; font-size: 22px;" type="primary"
prefixIcon="list-dot" align="right" text="设备详情" @click="handleGoToDeviceDetail"></u--text> prefixIcon="list-dot" align="right" text="设备详情" @click="handleGoToDeviceDetail"></u--text>
</view> </view>
<view class="running-status" v-if="current==0 && !isRelayProduct && !isVoiceProduct && !isGatewayProduct&&!isdisplay"> <view class="running-status"
v-if="current==0 && !isRelayProduct && !isVoiceProduct && !isGatewayProduct&&!isdisplay">
<base-status :device="device" ref="baseStatus"></base-status> <base-status :device="device" ref="baseStatus"></base-status>
</view> </view>
<view class="deviceVariable" v-if="current==1 && !isRelayProduct && !isVoiceProduct && !isGatewayProduct&&isdisplay"> <view class="deviceVariable"
v-if="current==1 && !isRelayProduct && !isVoiceProduct && !isGatewayProduct&&isdisplay">
<device-variable ref="deviceVariable" :device="device"></device-variable> <device-variable ref="deviceVariable" :device="device"></device-variable>
</view> </view>
<view class="relay-control" v-if="isRelayProduct"> <view class="relay-control" v-if="isRelayProduct">

View File

@ -36,12 +36,12 @@
</view> </view>
<view class="relay-state" :class="{'active': item.status === 1}"> <view class="relay-state" :class="{'active': item.status === 1}">
{{item.status === 1 ? '开启' : '关闭'}} 当前状态{{item.status === 1 ? '吸合' : '断开'}}
</view> </view>
<u-button type="primary" size="mini" @click="checkOnline(toggleRelay, index)" <u-button type="primary" size="normal" @click="checkOnline(toggleRelay, index)"
:disabled="device.status !== 3"> :disabled="device.status !== 3">
{{item.status === 1 ? '关闭' : '开启'}} {{item.status === 1 ? '断开' : '吸合'}}
</u-button> </u-button>
</view> </view>
</view> </view>
@ -118,6 +118,10 @@
</view> </view>
<view class="schedule-actions"> <view class="schedule-actions">
<u-button type="primary" size="mini" plain @click="checkOnline(editSchedule, index)"
:disabled="device.status !== 3">
编辑
</u-button>
<u-button type="error" size="mini" plain @click="checkOnline(deleteSchedule, index)" <u-button type="error" size="mini" plain @click="checkOnline(deleteSchedule, index)"
:disabled="device.status !== 3"> :disabled="device.status !== 3">
删除 删除
@ -128,10 +132,10 @@
</view> </view>
<!-- 添加时间方案弹窗 --> <!-- 添加/编辑时间方案弹窗 -->
<u-popup :show="showPopup" mode="center"> <u-popup :show="showPopup" mode="center" @close="closeSchedulePopup">
<view class="popup-content"> <view class="popup-content">
<view class="popup-title">添加时间方案</view> <view class="popup-title">{{isEditing ? '编辑时间方案' : '添加时间方案'}}</view>
<u--form :model="scheduleForm" ref="uForm"> <u--form :model="scheduleForm" ref="uForm">
<u-form-item label="时间"> <u-form-item label="时间">
<u-input v-model="scheduleForm.time" placeholder="请选择时间" @focus="openTimePicker" /> <u-input v-model="scheduleForm.time" placeholder="请选择时间" @focus="openTimePicker" />
@ -163,8 +167,8 @@
</u--form> </u--form>
<view class="popup-buttons"> <view class="popup-buttons">
<u-button @click="showPopup = false">取消</u-button> <u-button @click="closeSchedulePopup">取消</u-button>
<u-button type="primary" @click="addSchedule">确定</u-button> <u-button type="primary" @click="isEditing ? updateSchedule() : addSchedule()">{{isEditing ? '更新' : '确定'}}</u-button>
</view> </view>
</view> </view>
</u-popup> </u-popup>
@ -263,7 +267,9 @@
action: 1, action: 1,
relayIndexes: [], relayIndexes: [],
weekdays: [] weekdays: []
} },
isEditing: false, //
editingIndex: -1 //
} }
}, },
@ -554,6 +560,10 @@
showAddSchedule() { showAddSchedule() {
if (!this.checkOnline()) return; if (!this.checkOnline()) return;
//
this.isEditing = false;
this.editingIndex = -1;
const now = new Date(); const now = new Date();
const hours = now.getHours().toString().padStart(2, '0'); const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0'); const minutes = now.getMinutes().toString().padStart(2, '0');
@ -701,11 +711,107 @@
}); });
} }
}, },
//
editSchedule(index) {
if (!this.checkOnline()) return;
//
this.isEditing = true;
this.editingIndex = index;
//
const schedule = this.scheduleList[index];
//
this.scheduleForm = {
time: schedule.time,
action: schedule.action,
relayIndexes: [...schedule.relayIndexes], //
weekdays: [...schedule.weekdays] //
};
//
this.showPopup = true;
},
//
async updateSchedule() {
try {
// 1.
const updatedSchedule = {
...this.scheduleForm
};
//
if (this.scheduleList[this.editingIndex].originalData) {
updatedSchedule.originalData = this.scheduleList[this.editingIndex].originalData;
}
this.scheduleList[this.editingIndex] = updatedSchedule;
this.showPopup = false;
// 2.
const deviceSchedule = this.convertToDeviceSchedule(updatedSchedule);
console.log('【updateSchedule】deviceSchedule:', deviceSchedule);
// 3.
const scheduleConfig = {
shedule: this.scheduleList.map(s => s.originalData || this.convertToDeviceSchedule(s))
};
console.log('【updateSchedule】scheduleConfig:', scheduleConfig);
// 4. cfg_param
const cfgParamModel = this.device.thingsModels.find(item => item.id === 'cfg_param');
if (!cfgParamModel) {
throw new Error('找不到定时配置模型');
}
// 5.
cfgParamModel.shadow = `JSON=${JSON.stringify(scheduleConfig)}`;
// 6. MQTT
await this.mqttPublish(this.device, cfgParamModel);
// 7.
this.isEditing = false;
this.editingIndex = -1;
uni.showToast({
title: '时间方案更新成功',
icon: 'success'
});
} catch (error) {
console.error('更新时间方案失败:', error);
uni.showToast({
title: '更新失败: ' + error.message,
icon: 'none'
});
}
},
//
closeSchedulePopup() {
this.showPopup = false;
this.resetScheduleForm();
},
//
resetScheduleForm() {
this.scheduleForm = {
time: '12:00:00',
action: 1,
relayIndexes: [],
weekdays: []
};
this.isEditing = false;
this.editingIndex = -1;
},
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
/* 添加禁用状态的样式 */ /* 添加禁用状态的样式 */
.u-button[disabled] { .u-button[disabled] {
opacity: 0.6; opacity: 0.6;
@ -789,18 +895,6 @@
} }
} }
// u-checkbox-group
::v-deep .repeat-weekdays-group {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 15rpx;
padding: 10rpx 0;
.custom-checkbox {
justify-content: center;
}
}
.relay-control { .relay-control {
padding: 20rpx; padding: 20rpx;
@ -856,7 +950,6 @@
flex-direction: column; flex-direction: column;
gap: 12rpx; gap: 12rpx;
padding-left: 28rpx; padding-left: 28rpx;
/* 对齐图标 */
} }
.schedule-row { .schedule-row {
@ -881,30 +974,7 @@
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
margin-top: 10rpx; margin-top: 10rpx;
} gap: 10rpx;
/* 响应式调整 */
@media (min-width: 768px) {
.schedule-card {
flex-direction: row;
align-items: center;
justify-content: space-between;
}
.schedule-content {
flex: 1;
flex-direction: row;
flex-wrap: wrap;
gap: 15rpx 30rpx;
}
.schedule-row {
margin-bottom: 0;
}
.schedule-actions {
margin-top: 0;
}
} }
.status-title, .status-title,
@ -925,7 +995,6 @@
padding: 15rpx 28rpx; padding: 15rpx 28rpx;
} }
.relay-grid { .relay-grid {
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
@ -954,32 +1023,14 @@
} }
} }
.schedule-list { /* 弹窗专属样式 */
.schedule-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx;
border-bottom: 1px solid #eee;
.schedule-info {
display: flex;
flex-direction: column;
gap: 10rpx;
}
}
}
.add-schedule {
margin-top: 20rpx;
text-align: center;
}
.popup-content { .popup-content {
background-color: #fff; background-color: #fff;
padding: 30rpx; padding: 30rpx;
border-radius: 12rpx; border-radius: 12rpx;
width: 600rpx; width: 80vw;
max-height: 80vh;
overflow-y: auto;
.popup-title { .popup-title {
text-align: center; text-align: center;
@ -988,95 +1039,84 @@
margin-bottom: 30rpx; margin-bottom: 30rpx;
} }
/* 重复日期复选框组 - 垂直排列 */
::v-deep .repeat-weekdays-group {
display: flex;
flex-direction: column;
gap: 15rpx;
padding: 10rpx 0;
}
/* 继电器选择复选框组 - 垂直排列 */
::v-deep .u-checkbox-group {
display: flex !important;
flex-direction: column !important;
gap: 15rpx;
padding: 10rpx 0;
}
/* 复选框通用样式 */
.custom-checkbox {
width: 100% !important;
margin: 0 !important;
padding: 12rpx 8rpx;
border-radius: 6rpx;
background-color: #f8f8f8;
border: 1px solid #eee;
box-sizing: border-box;
display: flex;
align-items: center;
::v-deep text {
font-size: 26rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
/* 表单输入框样式 */
::v-deep .u-input {
padding: 12rpx 20rpx;
background-color: #f8f8f8;
border-radius: 8rpx;
}
/* 按钮区域 */
.popup-buttons { .popup-buttons {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
margin-top: 30rpx; margin-top: 30rpx;
gap: 20rpx;
.u-button {
flex: 1;
}
} }
//
::v-deep .u-form-item {
margin-bottom: 20rpx;
.u-form-item__body {
padding: 10rpx 0;
} }
} }
// /* 响应式调整 */
::v-deep .u-checkbox-group { @media (min-width: 768px) {
display: grid; .schedule-card {
grid-template-columns: repeat(2, 1fr); flex-direction: row;
gap: 15rpx;
padding: 10rpx 0;
}
//
//
::v-deep .u-checkbox-group+.u-checkbox-group {
width: 100%;
display: grid;
grid-template-columns: repeat(4, 1fr);
/* 每行放4个 */
grid-auto-rows: auto;
/* 高度自适应 */
gap: 15rpx;
padding: 10rpx 0;
justify-content: center;
}
//
::v-deep .custom-checkbox {
background-color: #f8f8f8;
padding: 12rpx 8rpx;
border-radius: 6rpx;
text-align: center;
display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: space-between;
min-height: 50rpx;
border: 1px solid #eee;
margin: 0 auto;
width: 90%;
&:hover {
background-color: #f0f0f0;
} }
// .schedule-content {
::v-deep text { flex: 1;
white-space: normal !important; flex-direction: row;
word-break: break-all; flex-wrap: wrap;
line-height: 1.2; gap: 15rpx 30rpx;
font-size: 26rpx;
color: #333;
margin-left: 6rpx;
} }
// .schedule-row {
::v-deep .u-checkbox__icon-wrap { margin-bottom: 0;
margin: 0;
transform: scale(0.85);
}
} }
// .schedule-actions {
::v-deep .u-form { margin-top: 0;
width: 100%;
}
//
::v-deep .u-form-item__body {
padding: 0;
width: 100%;
}
//
::v-deep .u-radio-group {
display: flex;
gap: 30rpx;
padding: 10rpx 0;
}
} }
} }
</style> </style>

View File

@ -104,9 +104,11 @@
</view> </view>
<view class="audio-actions"> <view class="audio-actions">
<u-switch v-model="item.status" :active-value="'启用'" :inactive-value="'禁用'" <u-switch v-model="item.status" :active-value="'启用'" :inactive-value="'禁用'"
@change="(value) => handleStatusChange(index, value)" size="22"></u-switch> @change="(value) => handleStatusChange(index, value)" size="22" :disabled="device.status !== 3"></u-switch>
<u-icon name="edit-pen" size="18" color="#2979ff" @click="editDefault(index)"></u-icon> <u-icon name="edit-pen" size="18" color="#2979ff" v-if="device.status === 3" @click="editDefault(index)"></u-icon>
<u-icon name="trash" size="18" color="#ff4d4f" @click="deleteDefault(index)"></u-icon> <u-icon name="edit-pen" size="18" color="#ccc" v-else></u-icon>
<u-icon name="trash" size="18" color="#ff4d4f" v-if="device.status === 3" @click="deleteDefault(index)"></u-icon>
<u-icon name="trash" size="18" color="#ccc" v-else></u-icon>
</view> </view>
</view> </view>
</view> </view>
@ -298,6 +300,7 @@
}, },
watch: { watch: {
device: function(newVal, oldVal) { device: function(newVal, oldVal) {
console.log("newVal", newVal)
if (newVal.deviceName !== '') { if (newVal.deviceName !== '') {
this.deviceInfo = newVal; this.deviceInfo = newVal;
if (this.deviceInfo.deviceType != 3) { if (this.deviceInfo.deviceType != 3) {
@ -511,14 +514,17 @@
let productId = topics[1]; let productId = topics[1];
let deviceNum = topics[2]; let deviceNum = topics[2];
message = JSON.parse(message.toString()); message = JSON.parse(message.toString());
//
if (this.deviceInfo.serialNumber !== deviceNum) return;
if (topics[3] == 'status') { if (topics[3] == 'status') {
if (this.deviceInfo.serialNumber == deviceNum) {
this.deviceInfo.status = message.status; this.deviceInfo.status = message.status;
this.deviceInfo.isShadow = message.isShadow; this.deviceInfo.isShadow = message.isShadow;
this.deviceInfo.rssi = message.rssi; this.deviceInfo.rssi = message.rssi;
this.deviceInfo = Object.assign({}, this.deviceInfo);
this.updateDeviceStatus(this.deviceInfo); this.updateDeviceStatus(this.deviceInfo);
this.updateBasicSettings(); this.updateBasicSettings();
} this.$forceUpdate();
} }
if (topics[4] == 'reply') { if (topics[4] == 'reply') {
uni.showToast({ uni.showToast({
@ -527,98 +533,66 @@
}) })
} }
if (topics[3] == 'property' || topics[3] == 'function' || topic.endsWith('ws/service')) { if (topics[3] == 'property' || topics[3] == 'function' || topic.endsWith('ws/service')) {
if (this.deviceInfo.serialNumber == deviceNum) { if (Array.isArray(message.message)) {
for (let j = 0; j < message.message.length; j++) { let mp3ListChanged = false;
let isComplete = false; let playListChanged = false;
for (let k = 0; k < this.deviceInfo.thingsModels.length && !isComplete; k++) { message.message.forEach(item => {
if (this.deviceInfo.thingsModels[k].id == message.message[j].id) { if (item.id === '103#mp3List') mp3ListChanged = true;
this.deviceInfo.thingsModels[k].shadow = message.message[j].value; if (item.id === '103#playList') playListChanged = true;
isComplete = true; //
break; });
} else if (this.deviceInfo.thingsModels[k].datatype.type == "object") { if (mp3ListChanged) {
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.params const mp3ListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#mp3List');
.length; n++) { if (mp3ListModel && mp3ListModel.shadow) {
if (this.deviceInfo.thingsModels[k].datatype.params[n].id == message try {
.message[j].id) { const jsonStr = mp3ListModel.shadow.replace('JSON=', '');
this.deviceInfo.thingsModels[k].datatype.params[n].shadow = message const data = JSON.parse(jsonStr);
.message[j].value; if (data && data.mp3_list) {
isComplete = true; this.audioList = data.mp3_list.map((item, index) => {
break; const [id, ...nameArr] = item.split('_');
} const name = nameArr.join('_') || item;
} return {
} else if (this.deviceInfo.thingsModels[k].datatype.type == "array") { id: Number(id),
if (this.deviceInfo.thingsModels[k].datatype.arrayType == "object") { name: name,
if (String(message.message[j].id).indexOf("array_") == 0) { filename: item
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype
.arrayParams.length; n++) {
for (let m = 0; m < this.deviceInfo.thingsModels[k].datatype
.arrayParams[n].length; m++) {
if (this.deviceInfo.thingsModels[k].datatype.arrayParams[n]
[m].id == message.message[j].id) {
this.deviceInfo.thingsModels[k].datatype.arrayParams[n]
[m].shadow = message.message[j].value;
isComplete = true;
break;
}
}
if (isComplete) {
break;
}
}
} else {
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype
.arrayParams.length; n++) {
for (let m = 0; m < this.deviceInfo.thingsModels[k].datatype
.arrayParams[n].length; m++) {
let index = n > 9 ? String(n) : '0' + k;
let prefix = 'array_' + index + '_';
if (this.deviceInfo.thingsModels[k].datatype.arrayParams[n]
[m].id == prefix + message.message[j].id) {
this.deviceInfo.thingsModels[k].datatype.arrayParams[n]
[m].shadow = message.message[j].value;
isComplete = true;
}
}
if (isComplete) {
break;
}
}
}
} else {
for (let n = 0; n < this.deviceInfo.thingsModels[k].datatype.arrayModel
.length; n++) {
if (this.deviceInfo.thingsModels[k].datatype.arrayModel[n].id ==
message.message[j].id) {
this.deviceInfo.thingsModels[k].datatype.arrayModel[n].shadow =
message.message[j].value;
isComplete = true;
break;
}
}
}
}
}; };
for (let k = 0; k < this.deviceInfo.chartList.length && !isComplete; k++) { });
if (this.deviceInfo.chartList[k].id.indexOf("array_") == 0) { this.audioList = [...this.audioList];
if (this.deviceInfo.chartList[k].id == message.message[j].id) {
this.deviceInfo.chartList[k].shadow = message.message[j].value;
isComplete = true;
break;
} }
} else { } catch (error) {
if (this.deviceInfo.chartList[k].id == message.message[j].id) { console.error('解析音频列表失败:', error);
this.deviceInfo.chartList[k].shadow = message.message[j].value;
isComplete = true;
break;
} }
} }
if (isComplete) {
break;
} }
if (playListChanged) {
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
if (playListModel && playListModel.shadow) {
try {
const jsonStr = playListModel.shadow.replace('JSON=', '');
const data = JSON.parse(jsonStr);
if (data && data.play_list) {
this.defaultList = data.play_list.map((item, index) => {
const beginTime = this.formatSecondsToTime(item.time.begin);
const endTime = this.formatSecondsToTime(item.time.end);
const weekdays = this.convertWeekToArray(item.time.week);
return {
id: index + 1,
name: item.play.filename,
playTime: `${beginTime} - ${endTime}`,
weekdays: weekdays.join(', '),
radarEnabled: item.speed.en === 1,
status: item.play.en === 1 ? '启用' : '禁用',
radarSpeed: item.speed.en === 1 ? `${item.speed.min}-${item.speed.max}km/h` : ''
}; };
});
this.defaultList = [...this.defaultList];
}
} catch (error) {
console.error('解析播放列表失败:', error);
}
}
} }
} }
this.updateBasicSettings();
} }
}); });
}, },
@ -860,10 +834,15 @@
weekValue |= (1 << day); weekValue |= (1 << day);
}); });
const audioIndex = this.audioList.findIndex(a => a.name === this.newDefault.audioFile.name);
const filename = this.newDefault.audioFile.filename;
const newPlayItem = { const newPlayItem = {
play: { play: {
num: this.isEditDefault && this.editDefaultIndex !== null && data.play_list[this.editDefaultIndex] ? data.play_list[this.editDefaultIndex].play.num : maxNum + 1, num: this.isEditDefault && this.editDefaultIndex !== null && data.play_list[this
filename: this.newDefault.audioFile.name, .editDefaultIndex] ? data.play_list[this.editDefaultIndex].play.num :
maxNum + 1,
filename: filename,
en: 1 en: 1
}, },
time: { time: {
@ -883,7 +862,7 @@
} else { } else {
data.play_list.push(newPlayItem); data.play_list.push(newPlayItem);
} }
console.log(JSON.stringify(data))
playListModel.shadow = 'JSON=' + JSON.stringify(data); playListModel.shadow = 'JSON=' + JSON.stringify(data);
try { try {
@ -973,6 +952,8 @@
} }
}, },
deleteDefault(index) { deleteDefault(index) {
if (!this.checkOnline()) return;
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '确认删除该播放项吗?', content: '确认删除该播放项吗?',
@ -1115,12 +1096,16 @@
if (data && data.mp3_list) { if (data && data.mp3_list) {
this.audioList = data.mp3_list.map((item, index) => { this.audioList = data.mp3_list.map((item, index) => {
const name = item.split('_')[1] || item; const [id, ...nameArr] = item.split('_');
const name = nameArr.join('_') || item;
return { return {
id: index + 1, id: Number(id),
name: name name: name,
filename: item
}; };
}); });
//
this.audioList = [...this.audioList];
} }
} catch (error) { } catch (error) {
console.error('解析音频列表失败:', error); console.error('解析音频列表失败:', error);
@ -1150,6 +1135,8 @@
'' ''
}; };
}); });
//
this.defaultList = [...this.defaultList];
} }
} catch (error) { } catch (error) {
console.error('解析播放列表失败:', error); console.error('解析播放列表失败:', error);
@ -1171,6 +1158,8 @@
return weekdays; return weekdays;
}, },
async handleStatusChange(index, value) { async handleStatusChange(index, value) {
if (!this.checkOnline()) return;
const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList'); const playListModel = this.deviceInfo.thingsModels.find(model => model.id === '103#playList');
if (playListModel) { if (playListModel) {
try { try {
@ -1225,16 +1214,19 @@
}); });
}, },
editDefault(index) { editDefault(index) {
if (!this.checkOnline()) return;
const item = this.defaultList[index]; const item = this.defaultList[index];
const audioFile = this.audioList.find(a => a.name === item.name); const audioFile = this.audioList.find(a => a.filename === item.name || a.name === item.name);
const audioIndex = this.audioList.findIndex(a => a.name === item.name); const audioIndex = this.audioList.findIndex(a => a.filename === item.name || a.name === item.name);
this.newDefault = { this.newDefault = {
startTime: item.playTime.split(' - ')[0], startTime: item.playTime.split(' - ')[0],
endTime: item.playTime.split(' - ')[1], endTime: item.playTime.split(' - ')[1],
repeatDays: this.weekDays.map((d, i) => item.weekdays.includes(d) ? i : -1).filter(i => i !== -1), repeatDays: this.weekDays.map((d, i) => item.weekdays.includes(d) ? i : -1).filter(i => i !== -1),
radarEnabled: item.radarEnabled, radarEnabled: item.radarEnabled,
minSpeed: item.radarEnabled && item.radarSpeed ? item.radarSpeed.split('-')[0] : '', minSpeed: item.radarEnabled && item.radarSpeed ? item.radarSpeed.split('-')[0] : '',
maxSpeed: item.radarEnabled && item.radarSpeed ? item.radarSpeed.split('-')[1].replace('km/h', '') : '', maxSpeed: item.radarEnabled && item.radarSpeed ? item.radarSpeed.split('-')[1].replace('km/h',
'') : '',
audioFile: audioFile audioFile: audioFile
}; };
this.audioIndex = audioIndex; this.audioIndex = audioIndex;
@ -1681,6 +1673,7 @@
.slider-with-value { .slider-with-value {
width: 100% !important; width: 100% !important;
display: block !important; display: block !important;
.custom-slider { .custom-slider {
width: 100% !important; width: 100% !important;
min-width: 0 !important; min-width: 0 !important;

View File

@ -0,0 +1,15 @@
// vue.config.js
const {
codeInspectorPlugin
} = require('code-inspector-plugin');
module.exports = {
// ...other code
chainWebpack: (config) => {
config.plugin('code-inspector-plugin').use(
codeInspectorPlugin({
bundler: 'webpack',
})
);
},
};