From a34c1293e82c0afacacecfc1fb850afe27b4873b Mon Sep 17 00:00:00 2001
From: songshankun <songshankun@foxmail.com>
Date: 星期五, 03 十一月 2023 11:31:58 +0800
Subject: [PATCH] feat: 问题诊断列表弹窗对接接口数据,抽离轮询时间配置,添加设备切换按钮
---
src/stores/plc.ts | 3
src/components/icons/AlertLightIcon.vue | 2
src/views/dashboard/components/TroubleTrackerModal.vue | 36 +++-----
package-lock.json | 19 ++++
src/views/dashboard/components/DeviceNumberInfo.vue | 2
src/common/constants/index.ts | 10 +-
package.json | 1
src/stores/devices.ts | 3
src/api/device.ts | 1
src/api/index.ts | 11 ++
src/api/problem.ts | 6 +
src/views/dashboard/components/DashboardTitle.vue | 88 ++++++++++++++++++---
12 files changed, 137 insertions(+), 45 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 1451e6f..6d767bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -22,6 +22,7 @@
"xstate": "^4.38.3"
},
"devDependencies": {
+ "@iconify-json/bx": "^1.1.7",
"@iconify-json/material-symbols-light": "^1.1.0",
"@iconify-json/mdi": "^1.1.55",
"@rushstack/eslint-patch": "^1.3.3",
@@ -811,6 +812,15 @@
"resolved": "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz",
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
"dev": true
+ },
+ "node_modules/@iconify-json/bx": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmmirror.com/@iconify-json/bx/-/bx-1.1.7.tgz",
+ "integrity": "sha512-Ugh8uUU9VtK8fI9BBnhLA7VvhPh7erSmJz+eqjvl8HCRRjkz5mbMO5/KYpCOriUVdiiKB9Yv1ObMqS73WLMSwA==",
+ "dev": true,
+ "dependencies": {
+ "@iconify/types": "*"
+ }
},
"node_modules/@iconify-json/material-symbols-light": {
"version": "1.1.0",
@@ -5463,6 +5473,15 @@
"integrity": "sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==",
"dev": true
},
+ "@iconify-json/bx": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmmirror.com/@iconify-json/bx/-/bx-1.1.7.tgz",
+ "integrity": "sha512-Ugh8uUU9VtK8fI9BBnhLA7VvhPh7erSmJz+eqjvl8HCRRjkz5mbMO5/KYpCOriUVdiiKB9Yv1ObMqS73WLMSwA==",
+ "dev": true,
+ "requires": {
+ "@iconify/types": "*"
+ }
+ },
"@iconify-json/material-symbols-light": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/@iconify-json/material-symbols-light/-/material-symbols-light-1.1.0.tgz",
diff --git a/package.json b/package.json
index 99df410..9360d7f 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"xstate": "^4.38.3"
},
"devDependencies": {
+ "@iconify-json/bx": "^1.1.7",
"@iconify-json/material-symbols-light": "^1.1.0",
"@iconify-json/mdi": "^1.1.55",
"@rushstack/eslint-patch": "^1.3.3",
diff --git a/src/api/device.ts b/src/api/device.ts
index 6023675..83a9c45 100644
--- a/src/api/device.ts
+++ b/src/api/device.ts
@@ -1,4 +1,5 @@
export interface Devices {
+ /** 鏈満璁惧缂栫爜 */
systemDeviceID: string
currentDeviceID: string
systemDeviceStatus: number
diff --git a/src/api/index.ts b/src/api/index.ts
index afab391..84fceb8 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -3,6 +3,7 @@
import type { PLCResponse } from './plc'
import type { Devices } from './device'
import type { CraftModel } from './craftModel'
+import type { Problem } from './problem'
export interface BaseResponse<T = any> {
code: number
@@ -141,3 +142,13 @@
data: params
})
}
+
+/**
+ * 鑾峰彇闂璇婃柇闂鍒楄〃
+ */
+export function apiGetProblemList() {
+ return request<BaseResponse<Problem[]>>({
+ url: '/v1/system/problemList',
+ method: 'get'
+ })
+}
diff --git a/src/api/problem.ts b/src/api/problem.ts
new file mode 100644
index 0000000..af784f6
--- /dev/null
+++ b/src/api/problem.ts
@@ -0,0 +1,6 @@
+export interface Problem {
+ /** true姝e父 false寮傚父 */
+ CheckResult: boolean
+ ItemCode: string
+ ItemName: string
+}
diff --git a/src/common/constants/index.ts b/src/common/constants/index.ts
index 995f28e..a739be6 100644
--- a/src/common/constants/index.ts
+++ b/src/common/constants/index.ts
@@ -17,7 +17,9 @@
7: 'G'
}
-export const DEVICE_STATUS_NAME_MAP = {
- 1: '姝e父',
- 2: '寮傚父'
-}
+// plc 杞闂撮殧
+export const PLC_POLLING_DURATION = 6_000
+// 璁惧淇℃伅 杞闂撮殧
+export const DEVICE_INFO_POLLING_DURATION = 15_000
+// 闂璇婃柇
+export const PROBLEMS_POLLING_DURATION = 30_000
diff --git a/src/components/icons/AlertLightIcon.vue b/src/components/icons/AlertLightIcon.vue
index 3a70684..27c398b 100644
--- a/src/components/icons/AlertLightIcon.vue
+++ b/src/components/icons/AlertLightIcon.vue
@@ -19,14 +19,12 @@
<g>
<path
style="opacity: 0.988"
- fill="#d71d05"
d="M 87.5,-0.5 C 95.1667,-0.5 102.833,-0.5 110.5,-0.5C 146.888,7.72465 167.388,30.3913 172,67.5C 172.5,101.165 172.667,134.832 172.5,168.5C 123.833,168.5 75.1667,168.5 26.5,168.5C 26.3333,132.498 26.5,96.4985 27,60.5C 33.9986,27.0017 54.1653,6.66837 87.5,-0.5 Z M 101.5,40.5 C 103.678,52.6006 105.011,64.9339 105.5,77.5C 116.858,77.4139 128.191,77.9139 139.5,79C 123.945,100.223 108.778,121.723 94,143.5C 93.167,128.176 92.667,112.842 92.5,97.5C 80.4954,97.6665 68.4954,97.4999 56.5,97C 71.8692,78.4097 86.8692,59.5764 101.5,40.5 Z"
/>
</g>
<g>
<path
style="opacity: 0.995"
- fill="#d81d05"
d="M 199.5,183.5 C 199.5,186.833 199.5,190.167 199.5,193.5C 197.167,195.167 195.167,197.167 193.5,199.5C 130.833,199.5 68.1667,199.5 5.5,199.5C 3.83333,197.167 1.83333,195.167 -0.5,193.5C -0.5,190.167 -0.5,186.833 -0.5,183.5C 1.67098,181.5 4.00432,179.666 6.5,178C 68.5,177.333 130.5,177.333 192.5,178C 194.996,179.666 197.329,181.5 199.5,183.5 Z"
/>
</g>
diff --git a/src/stores/devices.ts b/src/stores/devices.ts
index 4c74113..fb0fd53 100644
--- a/src/stores/devices.ts
+++ b/src/stores/devices.ts
@@ -3,6 +3,7 @@
import { getDeviceList } from '@/api'
import { useRequest } from 'vue-hooks-plus'
import type { Devices } from '@/api/device'
+import { DEVICE_INFO_POLLING_DURATION } from '@/common/constants'
export const useDevicesStore = defineStore('device', () => {
const deviceInfo = computed(() => {
@@ -18,7 +19,7 @@
cancel: cancelDevicePolling
} = useRequest(getDeviceList, {
manual: true,
- pollingInterval: 6000,
+ pollingInterval: DEVICE_INFO_POLLING_DURATION,
pollingWhenHidden: false
})
diff --git a/src/stores/plc.ts b/src/stores/plc.ts
index 50e7926..b42f370 100644
--- a/src/stores/plc.ts
+++ b/src/stores/plc.ts
@@ -5,6 +5,7 @@
import { useRequest } from 'vue-hooks-plus'
import { useTasksStore } from '@/stores/tasks'
import type { PLCResponse } from '@/api/plc'
+import { PLC_POLLING_DURATION } from '@/common/constants'
// 鍏ㄥ眬 watcher ref 闃叉澶氭璋冪敤 usePLCStore 鏃堕噸澶嶆敞鍐屼睛鍚櫒
const unwatch = ref()
@@ -31,7 +32,7 @@
} as ProductProgressParams),
{
manual: true,
- pollingInterval: 6000,
+ pollingInterval: PLC_POLLING_DURATION,
pollingWhenHidden: false
}
)
diff --git a/src/views/dashboard/components/DashboardTitle.vue b/src/views/dashboard/components/DashboardTitle.vue
index b55e9fb..57f1a01 100644
--- a/src/views/dashboard/components/DashboardTitle.vue
+++ b/src/views/dashboard/components/DashboardTitle.vue
@@ -1,41 +1,103 @@
<template>
<div class="dashboard-title">
- <div class="title-text">鏅鸿兘宸ヤ綔鍙� 鈥� {{ deviceStore?.deviceInfo?.currentDeviceID ?? '' }}</div>
+ <div class="title-text">
+ 鏅鸿兘宸ヤ綔鍙� 鈥� {{ deviceStore?.deviceInfo?.currentDeviceID ?? '' }}
+ <el-icon size="32" color="#0db7f5" style="margin-left: 20px; cursor: pointer" @click="openDevicesModal">
+ <IconSlider></IconSlider>
+ </el-icon>
+ </div>
<div class="title-status">
- <div class="connection-info" @click="openSelectDeviceModal">
- <el-icon size="30" color="red">
+ <div class="connection-info" @click="openProblemsModal">
+ <el-icon size="30" :color="problemsIconStatus ? '#00ff00' : '#ff0000'">
<AlertLightIcon></AlertLightIcon>
</el-icon>
</div>
<div class="cloud-connection-status">
- <el-icon size="45" color="#ff0000">
- <IconCloudOff></IconCloudOff>
+ <el-icon v-if="cloudConnectionIconStatus" size="45" color="#00ff00">
+ <IconCloudDone></IconCloudDone>
</el-icon>
- <el-icon size="45" color="#00ff00">
- <IconCloudDone></IconCloudDone>
+ <el-icon v-else size="45" color="#ff0000">
+ <IconCloudOff></IconCloudOff>
</el-icon>
</div>
</div>
</div>
- <TroubleTrackerModal v-model="showModal"></TroubleTrackerModal>
+ <TroubleTrackerModal v-model="showProblemsModal" :problems="problemList"></TroubleTrackerModal>
</template>
<script setup lang="ts">
import AlertLightIcon from '@/components/icons/AlertLightIcon.vue'
-import { ref } from 'vue'
+import { computed, onUnmounted, ref } from 'vue'
import { useDevicesStore } from '@/stores/devices'
import TroubleTrackerModal from '@/views/dashboard/components/TroubleTrackerModal.vue'
import IconCloudDone from '~icons/material-symbols-light/cloud-done-outline'
import IconCloudOff from '~icons/material-symbols-light/cloud-off-outline'
+import IconSlider from '~icons/bx/slider'
+import { useRequest } from 'vue-hooks-plus'
+import { apiGetProblemList } from '@/api'
+import { PROBLEMS_POLLING_DURATION } from '@/common/constants'
-const showModal = ref(false)
-
-function openSelectDeviceModal() {
- showModal.value = true
+// 鏄惁鏄剧ず闂璇婃柇modal
+const showProblemsModal = ref(false)
+/**
+ * 鎵撳紑闂璇婃柇modal
+ */
+function openProblemsModal() {
+ showProblemsModal.value = true
}
+// 鏄惁鏄剧ず璁惧鍒囨崲modal
+const showDevicesModal = ref(false)
+/**
+ * 鎵撳紑璁惧鍒囨崲modal
+ */
+function openDevicesModal() {
+ showDevicesModal.value = true
+}
+
+// 鑾峰彇褰撳墠璁惧鍚�
const deviceStore = useDevicesStore()
+
+// 闂璇婃柇鍒楄〃
+const problemList = computed(() => {
+ return problemsRes?.value?.data ?? []
+})
+// 闂璇婃柇icon鐘舵��, 闂鍒楄〃涓湁涓�鏉″紓甯稿嵆涓虹孩鐏� 鍚﹀垯鏄豢鐏� true缁跨伅
+const problemsIconStatus = computed(() => {
+ if (!problemList.value || !problemList.value?.length) {
+ // 榛樿缁跨伅, 鎷垮埌涓�娆℃暟鎹悗鎵嶄互鎺ュ彛涓哄噯
+ return true
+ }
+ return !problemList.value.some((ele) => !ele.CheckResult)
+})
+// 浜戠杩炴帴icon鐘舵��, 闂鍒楄〃涓湁涓�鏉′唬琛ㄤ簯绔摼鎺ョ殑, 寮傚父鍗充负绾㈣壊浜慽con 鍚﹀垯鏄豢鑹� true缁夸簯
+const cloudConnectionIconStatus = computed(() => {
+ if (!problemList.value || !problemList.value?.length) {
+ // 榛樿缁跨伅, 鎷垮埌涓�娆℃暟鎹悗鎵嶄互鎺ュ彛涓哄噯
+ return true
+ }
+ // 娌℃暟鎹氨褰撴槸閾炬帴姝e父
+ const cloudConnection = problemList.value.find((ele) => ele.ItemCode === 'cloud')
+ return cloudConnection ? cloudConnection?.CheckResult : true
+})
+
+/**
+ * 杞闂璇婃柇
+ */
+const {
+ data: problemsRes,
+ run: startProblemsPolling,
+ cancel: cancelProblemsPolling
+} = useRequest(apiGetProblemList, {
+ manual: true,
+ pollingInterval: PROBLEMS_POLLING_DURATION,
+ pollingWhenHidden: false
+})
+startProblemsPolling()
+onUnmounted(() => {
+ cancelProblemsPolling()
+})
</script>
<style scoped lang="scss">
diff --git a/src/views/dashboard/components/DeviceNumberInfo.vue b/src/views/dashboard/components/DeviceNumberInfo.vue
index eaff37b..82086ed 100644
--- a/src/views/dashboard/components/DeviceNumberInfo.vue
+++ b/src/views/dashboard/components/DeviceNumberInfo.vue
@@ -4,7 +4,7 @@
<div class="device-t">鏈満璁惧缂栫爜</div>
<div class="device-b">
<div class="device-info">
- {{ deviceInfo?.currentDeviceID }}
+ {{ deviceInfo?.systemDeviceID }}
</div>
</div>
</div>
diff --git a/src/views/dashboard/components/TroubleTrackerModal.vue b/src/views/dashboard/components/TroubleTrackerModal.vue
index 31c8c01..d5ef715 100644
--- a/src/views/dashboard/components/TroubleTrackerModal.vue
+++ b/src/views/dashboard/components/TroubleTrackerModal.vue
@@ -4,17 +4,17 @@
<template #title>闂璇婃柇 </template>
<div class="modal-content">
<el-scrollbar always class="scroller">
- <div v-if="fakeTroubles?.length" class="trouble">
- <div v-for="(item, index) in fakeTroubles" :key="index" class="trouble-item">
+ <div v-if="problems?.length" class="trouble">
+ <div v-for="(item, index) in problems" :key="index" class="trouble-item">
<div class="trouble-content">
<div class="trouble-icon">
- <el-icon v-if="item.status === 2" size="30" color="#ff0000"><WarnTriangleFilled /></el-icon>
- <el-icon v-if="item.status === 1" size="30" color="#00ff00"><CircleCheckFilled /></el-icon>
+ <el-icon v-if="item.CheckResult" size="30" color="#00ff00"><CircleCheckFilled /></el-icon>
+ <el-icon v-if="!item.CheckResult" size="30" color="#ff0000"><WarnTriangleFilled /></el-icon>
</div>
- <div class="trouble-text">{{ item.content }}</div>
+ <div class="trouble-text">{{ item.ItemName }}</div>
</div>
- <div class="trouble-status" :class="{ green: item.status === 1, red: item.status === 2 }">
- {{ DEVICE_STATUS_NAME_MAP[item.status] }}
+ <div class="trouble-status" :class="{ green: item.CheckResult, red: !item.CheckResult }">
+ {{ item.CheckResult ? '姝e父' : '寮傚父' }}
</div>
</div>
</div>
@@ -25,15 +25,18 @@
</template>
<script setup lang="ts">
import { useVModel } from '@vueuse/core'
-import { ref } from 'vue'
import { CircleCheckFilled, WarnTriangleFilled } from '@element-plus/icons-vue'
-import { DEVICE_STATUS_NAME_MAP } from '@/common/constants'
+import type { Problem } from '@/api/problem'
+import { toRefs } from 'vue'
export interface TroubleTrackerModalProps {
modelValue: boolean
+ problems?: Problem[]
}
const props = withDefaults(defineProps<TroubleTrackerModalProps>(), {
- modelValue: false
+ modelValue: false,
+ problems: undefined
})
+const { problems } = toRefs(props)
const emit = defineEmits<{
'update:modelValue': [show: boolean]
}>()
@@ -42,19 +45,6 @@
function closeModal() {
modelData.value = false
}
-
-const fakeTroubles = ref<{ content: string; status: 1 | 2 }[]>([{ content: '浜戠缃戠粶杩炴帴', status: 1 }])
-// TODO: 绛夋帴鍙�
-fakeTroubles.value.push(
- ...Array(100)
- .fill(0)
- .map(() => {
- return {
- content: '浜戠缃戠粶杩炴帴',
- status: Math.ceil(Math.random() + 1)
- } as { content: string; status: 1 | 2 }
- })
-)
</script>
<style scoped lang="scss">
.modal-content {
--
Gitblit v1.8.0