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

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": {
"version": "7.25.9",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -15,7 +14,6 @@
"node_modules/@babel/helper-validator-identifier": {
"version": "7.25.9",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.9.0"
}
@ -23,7 +21,6 @@
"node_modules/@babel/parser": {
"version": "7.27.0",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/types": "^7.27.0"
},
@ -37,7 +34,6 @@
"node_modules/@babel/types": {
"version": "7.27.0",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.25.9",
"@babel/helper-validator-identifier": "^7.25.9"
@ -92,7 +88,6 @@
"node_modules/@vue/compiler-core": {
"version": "3.5.13",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/parser": "^7.25.3",
"@vue/shared": "3.5.13",
@ -104,7 +99,6 @@
"node_modules/@vue/compiler-dom": {
"version": "3.5.13",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.5.13",
"@vue/shared": "3.5.13"
@ -181,8 +175,30 @@
},
"node_modules/@vue/shared": {
"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",
"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": {
"version": "1.0.1",
@ -273,6 +289,72 @@
"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": {
"version": "1.1.0",
"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": {
"version": "3.7.1",
"license": "MIT",
@ -353,7 +448,6 @@
"node_modules/entities": {
"version": "4.5.0",
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=0.12"
},
@ -422,6 +516,16 @@
"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": {
"version": "2.0.1",
"license": "ISC",
@ -437,8 +541,7 @@
},
"node_modules/estree-walker": {
"version": "2.0.2",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/event-emitter": {
"version": "0.3.5",
@ -508,6 +611,16 @@
"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": {
"version": "1.1.0",
"license": "MIT",
@ -622,6 +735,17 @@
"version": "1.0.1",
"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": {
"version": "2.1.0",
"license": "MIT",
@ -754,6 +878,20 @@
"license": "ISC",
"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": {
"version": "8.5.3",
"funding": [
@ -872,6 +1010,19 @@
"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": {
"version": "2.0.5",
"license": "MIT",
@ -930,6 +1081,16 @@
"version": "1.0.2",
"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": {
"version": "3.5.13",
"license": "MIT",
@ -968,6 +1129,16 @@
"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": {
"version": "5.5.2",
"license": "BSD-2-Clause",

View File

@ -21,5 +21,8 @@
"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"
: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-monitor>
</device-monitor> -->
<!-- 视频监控 -->
<video-monitor v-show="baseTabIndex == 2" ref="videoMonitor"
: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>
</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>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/time_black.png">
</image>
</u-tabbar-item>
</u-tabbar-item> -->
<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>
@ -254,12 +254,12 @@
src="/static/home/tabBar/statistic_black.png">
</image>
</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>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/scada_black.png">
</image>
</u-tabbar-item>
</u-tabbar-item> -->
</u-tabbar>
<u-modal :show="showScada" content="暂无组态,请先去网页端配置模板组态" @confirm="() => showScada = false"
@cancel="() => showScada = false" showCancelButton></u-modal>
@ -309,11 +309,14 @@
tabbarIndex: 0,
baseTabList: [{
name: this.$tt('deviceDetail.overview')
}, {
name: this.$tt('deviceDetail.monitor')
}, {
name: this.$tt('deviceDetail.Surveillance')
}, {
},
// {
// name: this.$tt('deviceDetail.monitor')
// },
// {
// name: this.$tt('deviceDetail.Surveillance')
// },
{
name: this.$tt('deviceDetail.alert')
}],
videoTabList: [{

View File

@ -1,17 +1,19 @@
<template>
<view class="device-status">
<view class="title-wrap">
<view style="width: 175px;">
<!-- <view style="width: 175px;">
<u-subsection :list="modeList" mode="subsection" :current="current"
@change="sectionChange"></u-subsection>
</view>
</view> -->
<u--text iconStyle="color: #486ff2; margin-right: 4px; font-size: 22px;" type="primary"
prefixIcon="list-dot" align="right" text="设备详情" @click="handleGoToDeviceDetail"></u--text>
</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>
</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>
</view>
<view class="relay-control" v-if="isRelayProduct">

View File

@ -36,12 +36,12 @@
</view>
<view class="relay-state" :class="{'active': item.status === 1}">
{{item.status === 1 ? '开启' : '关闭'}}
当前状态{{item.status === 1 ? '吸合' : '断开'}}
</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">
{{item.status === 1 ? '关闭' : '开启'}}
{{item.status === 1 ? '断开' : '吸合'}}
</u-button>
</view>
</view>
@ -118,6 +118,10 @@
</view>
<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)"
:disabled="device.status !== 3">
删除
@ -128,10 +132,10 @@
</view>
<!-- 添加时间方案弹窗 -->
<u-popup :show="showPopup" mode="center">
<!-- 添加/编辑时间方案弹窗 -->
<u-popup :show="showPopup" mode="center" @close="closeSchedulePopup">
<view class="popup-content">
<view class="popup-title">添加时间方案</view>
<view class="popup-title">{{isEditing ? '编辑时间方案' : '添加时间方案'}}</view>
<u--form :model="scheduleForm" ref="uForm">
<u-form-item label="时间">
<u-input v-model="scheduleForm.time" placeholder="请选择时间" @focus="openTimePicker" />
@ -163,8 +167,8 @@
</u--form>
<view class="popup-buttons">
<u-button @click="showPopup = false">取消</u-button>
<u-button type="primary" @click="addSchedule">确定</u-button>
<u-button @click="closeSchedulePopup">取消</u-button>
<u-button type="primary" @click="isEditing ? updateSchedule() : addSchedule()">{{isEditing ? '更新' : '确定'}}</u-button>
</view>
</view>
</u-popup>
@ -263,7 +267,9 @@
action: 1,
relayIndexes: [],
weekdays: []
}
},
isEditing: false, //
editingIndex: -1 //
}
},
@ -554,6 +560,10 @@
showAddSchedule() {
if (!this.checkOnline()) return;
//
this.isEditing = false;
this.editingIndex = -1;
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
@ -701,24 +711,120 @@
});
}
},
//
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>
<style lang="scss" scoped>
/* 添加禁用状态的样式 */
.u-button[disabled] {
<style lang="scss">
/* 添加禁用状态的样式 */
.u-button[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
}
.relay-name[disabled] {
.relay-name[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
}
/* 继电器名称样式 */
.relay-name {
/* 继电器名称样式 */
.relay-name {
color: #333;
font-weight: 500;
margin-bottom: 10rpx;
@ -728,23 +834,23 @@
gap: 8rpx;
padding: 8rpx;
border-radius: 8rpx;
}
}
.relay-name:active {
.relay-name:active {
background-color: #f0f0f0;
}
}
/* 编辑图标样式 */
.u-icon-edit-pen {
/* 编辑图标样式 */
.u-icon-edit-pen {
opacity: 0.6;
transition: opacity 0.3s;
}
}
.relay-name:hover .u-icon-edit-pen {
.relay-name:hover .u-icon-edit-pen {
opacity: 1;
}
}
.empty-tip {
.empty-tip {
display: flex;
flex-direction: column;
align-items: center;
@ -753,9 +859,9 @@
color: #c0c4cc;
font-size: 28rpx;
gap: 20rpx;
}
}
.card {
.card {
box-shadow: 0 1px 0px 0 rgba(0, 0, 0, 0.1);
border-radius: 20rpx;
background-color: #fff;
@ -787,21 +893,9 @@
text-align: left;
font-style: normal;
}
}
}
// 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;
.relay-status,
@ -856,7 +950,6 @@
flex-direction: column;
gap: 12rpx;
padding-left: 28rpx;
/* 对齐图标 */
}
.schedule-row {
@ -881,30 +974,7 @@
display: flex;
justify-content: flex-end;
margin-top: 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;
}
gap: 10rpx;
}
.status-title,
@ -925,7 +995,6 @@
padding: 15rpx 28rpx;
}
.relay-grid {
display: grid;
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 {
background-color: #fff;
padding: 30rpx;
border-radius: 12rpx;
width: 600rpx;
width: 80vw;
max-height: 80vh;
overflow-y: auto;
.popup-title {
text-align: center;
@ -988,95 +1039,84 @@
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 {
display: flex;
justify-content: space-around;
margin-top: 30rpx;
}
gap: 20rpx;
//
::v-deep .u-form-item {
margin-bottom: 20rpx;
.u-form-item__body {
padding: 10rpx 0;
.u-button {
flex: 1;
}
}
//
::v-deep .u-checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
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;
/* 响应式调整 */
@media (min-width: 768px) {
.schedule-card {
flex-direction: row;
align-items: center;
justify-content: center;
min-height: 50rpx;
border: 1px solid #eee;
margin: 0 auto;
width: 90%;
&:hover {
background-color: #f0f0f0;
justify-content: space-between;
}
//
::v-deep text {
white-space: normal !important;
word-break: break-all;
line-height: 1.2;
font-size: 26rpx;
color: #333;
margin-left: 6rpx;
.schedule-content {
flex: 1;
flex-direction: row;
flex-wrap: wrap;
gap: 15rpx 30rpx;
}
//
::v-deep .u-checkbox__icon-wrap {
margin: 0;
transform: scale(0.85);
}
.schedule-row {
margin-bottom: 0;
}
//
::v-deep .u-form {
width: 100%;
}
//
::v-deep .u-form-item__body {
padding: 0;
width: 100%;
}
//
::v-deep .u-radio-group {
display: flex;
gap: 30rpx;
padding: 10rpx 0;
}
}
.schedule-actions {
margin-top: 0;
}
}
</style>

View File

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