From 15e2f2216d3d6c81eb495b979cdb1a46e20361c4 Mon Sep 17 00:00:00 2001 From: songshankun <songshankun@foxmail.com> Date: 星期三, 15 十一月 2023 15:30:42 +0800 Subject: [PATCH] feat: 添加设备切换弹窗组件, 添加设备切换功能,切换后刷新数据 --- src/components/DeviceSelectModal.vue | 189 +++++++++++++++++++++++++++++++++++++ src/store/index.js | 17 +++ src/views/visualization.vue | 80 +++++++++++----- src/api/home/index.js | 11 ++ 4 files changed, 272 insertions(+), 25 deletions(-) diff --git a/src/api/home/index.js b/src/api/home/index.js index 92b940c..50760f3 100644 --- a/src/api/home/index.js +++ b/src/api/home/index.js @@ -161,3 +161,14 @@ data }) } + +/** + * 璁惧畾褰撳墠璁惧 + */ +export function apiSetCurrentDevice(data) { + return request({ + url: `/v1/device/setCurrentDeviceId`, + method: 'post', + data + }) +} diff --git a/src/components/DeviceSelectModal.vue b/src/components/DeviceSelectModal.vue new file mode 100644 index 0000000..f41724a --- /dev/null +++ b/src/components/DeviceSelectModal.vue @@ -0,0 +1,189 @@ +<template xmlns=""> + <div class="device-select-modal"> + <el-dialog + title="璁惧閫夋嫨" + :visible.sync="visible" + width="30%" + :before-close="handleClose"> + <div class="device-box"> + <template v-if="deviceInfo?.deviceList?.length"> + <div + v-for="item in deviceInfo?.deviceList" + :key="item.deviceID" + :class="selectedDevice === item.deviceID ? 'device-item check-item' : 'device-item'" + @click="deviceClick(item.deviceID)" + > + <div class="item-l"> + <span>{{ item.deviceID }}</span> + {{ item.deviceName }} + </div> + <div v-if="selectedDevice === item.deviceID" class="item-r"> + <i class="el-icon-success checked-icon"></i> + </div> + </div> + </template> + </div> + <span slot="footer" class="dialog-footer"> + <el-button class="submit" @click="saveModal">纭� 瀹�</el-button> + </span> + </el-dialog> + </div> +</template> + +<script> +import {mapState} from "vuex"; +import {apiSetCurrentDevice} from "@/api/home"; + +export default { + name: "DeviceSelectModal", + props: { + visible: { + type: Boolean, + default: false + } + }, + data() { + return { + selectedDevice:null + } + }, + watch: { + visible(val) { + if (val) { + this.selectedDevice = this.deviceInfo?.currentDeviceID ?? '' + } + } + }, + computed: { + ...mapState(['deviceInfo']) + }, + methods: { + handleClose() { + this.$emit('update:visible', false) + this.$emit('close') + }, + deviceClick(deviceId) { + this.selectedDevice = deviceId + }, + saveModal() { + if (!this.selectedDevice) { + this.$message.error('璇峰厛閫変腑涓�涓澶�') + return + } + apiSetCurrentDevice({ currentDeviceID: this.selectedDevice }) + .then(() => { + this.$message.success({message:'璁惧畾鎴愬姛',duration:2000}) + this.$emit('update:visible',false) + this.$emit('should-reload') + }) + .catch((err) => { + console.error(err) + this.$message.error('err.msg') + }) + } + } +} +</script> + +<style scoped lang="scss"> +::v-deep { + .el-dialog { + background-color: #10256c; + color: #fff; + } + + .el-dialog__title, .el-dialog__body { + color: #fff; + } +} + +.submit { + background-color: #0dfde6; + outline: none; + border: none; + color: #333333; + width: 100px; + height: 40px; + font-size: 14px; + font-weight: 500; + + &:hover { + background-color: #0dfde6; + color: #333333; + } + + &:focus { + background-color: #0dfde6; + color: #333333; + } + + &:active { + background-color: #0dfde6; + color: #333333; + } +} + +$status-done: #0dfde6; +$status-d: #213e9e; +.device-box { + overflow-y: auto; + height: 300px; + padding-right: 12px; + .check-item { + border: 1px solid $status-done; + } + .device-item { + box-sizing: border-box; + width: 100%; + height: 45px; + line-height: 45px; + padding: 0 10px; + border-radius: 6px; + font-size: 14px; + color: #fff; + cursor: pointer; + .item-l { + width: calc(100% - 80px); + float: left; + span { + margin-right: 10px; + } + } + .item-icon { + height: 100%; + display: flex; + align-items: center; + } + .item-r { + height: 100%; + float: right; + } + } +} +.device-b { + width: 210px; + margin: 10px auto 10px; + display: flex; + align-items: center; + .btn, + .btn1 { + width: 100px; + height: 40px; + line-height: 40px; + border-radius: 4px; + float: left; + color: #333; + font-size: 14px; + cursor: pointer; + text-align: center; + } + .btn1 { + color: #fff; + margin-right: 10px; + } +} +.checked-icon{ + color: #00ff00; + font-size: 22px; +} +</style> diff --git a/src/store/index.js b/src/store/index.js index ceffa8e..1a46caf 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -1,16 +1,33 @@ import Vue from 'vue' import Vuex from 'vuex' +import {getDeviceList} from "@/api/home"; Vue.use(Vuex) export default new Vuex.Store({ state: { + deviceInfo:null }, getters: { + currentDeviceName (state){ + return state.deviceInfo?.deviceList?.find((ele) => ele?.deviceID === state.deviceInfo?.currentDeviceID) + ?.deviceName ?? '' + } }, mutations: { + setDeviceInfo(state,deviceInfo){ + state.deviceInfo = deviceInfo + } }, actions: { + getDeviceInfo({commit}){ + return getDeviceList().then(res=>{ + commit('setDeviceInfo',res.data) + }).catch(err=>{ + console.error(err) + commit('setDeviceInfo',null) + }) + } }, modules: { } diff --git a/src/views/visualization.vue b/src/views/visualization.vue index 65eda1a..8f94cce 100644 --- a/src/views/visualization.vue +++ b/src/views/visualization.vue @@ -4,8 +4,9 @@ <!-- v-if="Tasks&&Tasks.length>0" --> <template > <div class="left"> - <p class="title"> - <template v-if="Number(ChannelAmount)>1"> + <div class="title"> + <div class="dashboard-channels"> + <template v-if="Number(ChannelAmount)>1"> <span class="font set-title" style="float: left; margin-right: 15px;" @@ -16,41 +17,48 @@ <img style="width:32px;" src="../../public/one.png" /> </span> </span> - <span class="font set-title" style="float: left;margin-right: 15px;" @click="cutClick(2)"> + <span class="font set-title" style="float: left;margin-right: 15px;" @click="cutClick(2)"> <img style="width:32px;" v-if="activeName == 2" src="../../public/two-blue.png" /> <img style="width:32px;" v-else src="../../public/two.png" /> </span> - <span - class="font set-title" - style="float: left;" - @click="cutClick(3)" - > + <span + class="font set-title" + style="float: left;" + @click="cutClick(3)" + > <img style="width:32px;" v-if="activeName == 3" src="../../public/right-blue.png" /> <span v-else> <img style="width:32px;" src="../../public/right.png" /> </span> </span> - </template> - 鏅鸿兘宸ヤ綔鍙� - <span - class="font el-icon-setting set-title" - style="float: right" - @click="setUrl" - ></span> - <span - class="font el-icon-s-tools set-title" - style="float: right;margin-right: 6px" - @click="openParamsConfigModal" - ></span> - <span - style="float: right;margin-right:20px;font-size:28px;line-height:25px;" - @click="taskClick" - > + </template> + </div> + <div class="dashboard-title"> + 鏅鸿兘宸ヤ綔鍙� 鈥� {{currentDeviceName}} + + <i @click="showDeviceModal=true" class="el-icon" style="font-size: 26px; height: 32px; color: #0db7f5; margin-left: 20px; cursor: pointer;"><svg data-v-c3da359e="" viewBox="0 0 24 24" width="1.2em" height="1.2em"><path fill="currentColor" d="M13 5h9v2h-9zM2 7h7v2h2V3H9v2H2zm7 10h13v2H9zm10-6h3v2h-3zm-2 4V9.012h-2V11H2v2h13v2zM7 21v-6H5v2H2v2h3v2z"></path></svg></i> + </div> + <div class="dashboard-btn"> + <span + class="font el-icon-setting set-title" + style="float: right" + @click="setUrl" + ></span> + <span + class="font el-icon-s-tools set-title" + style="float: right;margin-right: 6px" + @click="openParamsConfigModal" + ></span> + <span + style="float: right;margin-right:20px;font-size:28px;line-height:25px;" + @click="taskClick" + > <el-badge :value="TaskCount" :class="(TaskCount==0||isTipShow)?'item color_666':'item color_fff'"> <i class="el-icon-chat-dot-round" /> </el-badge> </span> - </p> + </div> + </div> <div :class="(activeName == 1||activeName == 3) ? 'active-one' : 'active-two'" v-for="(taskData, index) in Tasks" @@ -599,6 +607,7 @@ @updateGet="updateGet" /> <ParamsConfigModal :visible="paramsConfigIsShow" @close="closeParamsConfigModal"></ParamsConfigModal> + <DeviceSelectModal :visible.sync="showDeviceModal" @should-reload="reloadAllData"></DeviceSelectModal> </div> </template> @@ -623,8 +632,11 @@ import {channelNameConfig} from "@/common/constants"; import _ from 'lodash' import ParamsConfigModal from "@/components/ParamsConfigModal.vue"; +import DeviceSelectModal from "@/components/DeviceSelectModal.vue"; +import {mapActions, mapGetters, mapState} from "vuex"; export default { components: { + DeviceSelectModal, ParamsConfigModal, TaskControlModal, Card, @@ -635,6 +647,7 @@ }, data() { return { + showDeviceModal:false, pollingTaskCountTimer: null, activeName: 1, progress: 70, //杩涘害 @@ -782,6 +795,7 @@ this.activeName = channelType this.getTaskInfo(channelType); this.getTaskCountStatistics() + this.getDeviceInfo() }, beforeDestroy() { clearTimeout(this.pollingTaskCountTimer) @@ -796,6 +810,8 @@ // } }, computed:{ + ...mapState(['deviceInfo']), + ...mapGetters(['currentDeviceName']), displayPLCStatus(){ let PLCStatus = [] if (this.activeName===1){ @@ -812,6 +828,13 @@ } }, methods: { + ...mapActions(["getDeviceInfo"]), + reloadAllData(){ + console.log(1) + this.getTaskInfo(this.activeName); + this.getTaskCountStatistics() + this.getDeviceInfo() + }, newTaskPlaceholder(channel){ return { Order: {}, @@ -1847,6 +1870,9 @@ padding: 30px; padding-top: 20px; .title { + display: flex; + align-items: center; + justify-content: space-between; font-size: 30px; font-weight: 600; height:40px; @@ -2329,4 +2355,8 @@ display: none; } } +.dashboard-title{ + display: flex; + align-items: center; +} </style> -- Gitblit v1.8.0