songshankun
2023-11-15 15e2f2216d3d6c81eb495b979cdb1a46e20361c4
feat: 添加设备切换弹窗组件, 添加设备切换功能,切换后刷新数据
1个文件已添加
3个文件已修改
297 ■■■■■ 已修改文件
src/api/home/index.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/DeviceSelectModal.vue 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/index.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/visualization.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/home/index.js
@@ -161,3 +161,14 @@
    data
  })
}
/**
 * 设定当前设备
 */
export function apiSetCurrentDevice(data) {
  return request({
    url: `/v1/device/setCurrentDeviceId`,
    method: 'post',
    data
  })
}
src/components/DeviceSelectModal.vue
New file
@@ -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>
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: {
  }
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>