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