From 2bb9a863e75312fe90869ea3deea137b46b1bb1e Mon Sep 17 00:00:00 2001 From: haoxuan <haoxuan> Date: 星期一, 06 十一月 2023 17:46:43 +0800 Subject: [PATCH] 拉代码 --- src/views/dashboard/components/TaskControl.vue | 14 +- src/views/dashboard/components/CurrentDateTime.vue | 3 src/views/dashboard/components/TaskStep.vue | 71 ++++++++++++++ src/components.d.ts | 1 src/stores/tasks.ts | 11 + src/api/index.ts | 24 ++++ src/components/CommonModal.vue | 2 src/stores/craftModel.ts | 41 +++++++- src/views/dashboard/components/DeviceCheckList.vue | 81 +++++++++++---- index.html | 2 src/stores/devices.ts | 9 - public/favicon.ico | 0 src/views/dashboard/components/DashboardTitle.vue | 31 +++++- 13 files changed, 234 insertions(+), 56 deletions(-) diff --git a/index.html b/index.html index 39aff6e..28e6a80 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,7 @@ <meta charset="UTF-8" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>鐪嬫澘</title> + <title>鏅鸿兘宸ヤ綔鍙�</title> </head> <body> <div id="app"></div> diff --git a/public/favicon.ico b/public/favicon.ico index df36fcf..765befd 100644 --- a/public/favicon.ico +++ b/public/favicon.ico Binary files differ diff --git a/src/api/index.ts b/src/api/index.ts index 6b41213..e474d51 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -11,6 +11,13 @@ msg: string } +export interface ListResponse<T = any> { + code: number + data: T + msg: string + total: number +} + export interface TaskListParams { /** 1鏈畬鎴�2浠婂ぉ鏈畬鎴�3宸插畬鎴� */ type: 1 | 2 | 3 @@ -108,6 +115,21 @@ }) } +export interface SetCurrentDeviceParams { + currentDeviceID: string +} + +/** + * 鑾峰彇褰撳墠闈㈡澘缁戝畾鐨勮澶囧垪琛� + */ +export function apiSetCurrentDevice(data: SetCurrentDeviceParams) { + return request<BaseResponse<Devices>>({ + url: `/v1/device/setCurrentDeviceId`, + method: 'post', + data + }) +} + export interface CraftModelListParams { procedureId: number page: number @@ -119,7 +141,7 @@ * @param params */ export function apiGetCraftModelList(params: CraftModelListParams) { - return request<BaseResponse<CraftModel[]>>({ + return request<ListResponse<CraftModel[]>>({ url: '/v1/processModel/list', method: 'get', params diff --git a/src/components.d.ts b/src/components.d.ts index 5374a8f..e028f6c 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -24,6 +24,7 @@ ElSteps: typeof import('element-plus/es')['ElSteps'] ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] + ElText: typeof import('element-plus/es')['ElText'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] } diff --git a/src/components/CommonModal.vue b/src/components/CommonModal.vue index 372690b..43c79aa 100644 --- a/src/components/CommonModal.vue +++ b/src/components/CommonModal.vue @@ -28,7 +28,7 @@ /** 鏄惁灞曠ず妯℃�佹 */ modelValue: boolean /** 鏇村鐗堟湰 */ - wider: boolean + wider?: boolean } const props = withDefaults(defineProps<BaseModalProps>(), { modelValue: false, diff --git a/src/stores/craftModel.ts b/src/stores/craftModel.ts index 9b8afbd..b550e86 100644 --- a/src/stores/craftModel.ts +++ b/src/stores/craftModel.ts @@ -1,22 +1,25 @@ -import { ref, watch } from 'vue' +import { computed, ref, watch } from 'vue' import { defineStore } from 'pinia' import type { CraftModel } from '@/api/craftModel' import { apiGetCraftModelList } from '@/api' import { useTasksStore } from '@/stores/tasks' const watcher = ref() - +const page = ref(1) +const total = ref(0) export const useCraftModelStore = defineStore('craftModel', () => { - const craftModelList = ref<CraftModel[]>() + const craftModelList = ref<CraftModel[]>([]) const taskStore = useTasksStore() function getCraftModelList() { if (taskStore.activeTask?.Procedure.ID) { + craftModelList.value = [] apiGetCraftModelList({ procedureId: taskStore.activeTask?.Procedure.ID, - page: 1, - pageSize: 999 + page: page.value, + pageSize: 6 }).then((res) => { craftModelList.value = res.data ?? [] + total.value = res.total }) } } @@ -25,10 +28,36 @@ watch( () => taskStore.activeTask, () => { + page.value = 1 getCraftModelList() } ) } - return { craftModelList, getCraftModelList } + const loading = ref(false) + + function loadMore() { + if (taskStore.activeTask?.Procedure.ID && !loading.value && hasMore.value) { + page.value++ + loading.value = true + apiGetCraftModelList({ + procedureId: taskStore.activeTask?.Procedure.ID, + page: page.value, + pageSize: 6 + }) + .then((res) => { + craftModelList.value = [...craftModelList.value, ...(res.data ?? [])] + total.value = res.total + }) + .finally(() => { + loading.value = false + }) + } + } + + const hasMore = computed(() => { + return total.value > craftModelList.value.length + }) + + return { craftModelList, getCraftModelList, hasMore, loading, loadMore } }) diff --git a/src/stores/devices.ts b/src/stores/devices.ts index fb0fd53..a23d468 100644 --- a/src/stores/devices.ts +++ b/src/stores/devices.ts @@ -1,4 +1,4 @@ -import { computed, onUnmounted } from 'vue' +import { computed } from 'vue' import { defineStore } from 'pinia' import { getDeviceList } from '@/api' import { useRequest } from 'vue-hooks-plus' @@ -7,6 +7,9 @@ export const useDevicesStore = defineStore('device', () => { const deviceInfo = computed(() => { + if (deviceInfo?.value) { + deviceRes.value.data.currentDeviceID = 'wwwwwwww222222' + } return deviceRes?.value?.data as Devices }) @@ -27,10 +30,6 @@ cancelDevicePolling() startDevicePolling() } - - onUnmounted(() => { - cancelDevicePolling() - }) return { deviceInfo, startPollingDevice } }) diff --git a/src/stores/tasks.ts b/src/stores/tasks.ts index 3a97ead..e115738 100644 --- a/src/stores/tasks.ts +++ b/src/stores/tasks.ts @@ -77,10 +77,14 @@ /** * 鍒锋柊鎵�鏈夋暟鎹� */ - function reload(channel: number) { + function reloadChannel(channel: number) { getChannels(currentType.value).then(() => { autoSelectTask(channel) }) + } + + function reloadAllData() { + getChannels(currentType.value) } function moreChannelTasksBtn(channelNumber: number) { @@ -128,9 +132,10 @@ getChannels, moreBtnStatus, activeTask, - reload, + reloadChannel, setActiveTask, moreChannelTasksBtn, - foldChannelTasksBtn + foldChannelTasksBtn, + reloadAllData } }) diff --git a/src/views/dashboard/components/CurrentDateTime.vue b/src/views/dashboard/components/CurrentDateTime.vue index 3097eab..2a41bcd 100644 --- a/src/views/dashboard/components/CurrentDateTime.vue +++ b/src/views/dashboard/components/CurrentDateTime.vue @@ -13,9 +13,8 @@ $color: #30decd; .current-date-time { - width: 370px; color: $color; - font-size: 24px; + font-size: 20px; font-weight: 600; } </style> diff --git a/src/views/dashboard/components/DashboardTitle.vue b/src/views/dashboard/components/DashboardTitle.vue index 637ef35..015694a 100644 --- a/src/views/dashboard/components/DashboardTitle.vue +++ b/src/views/dashboard/components/DashboardTitle.vue @@ -1,29 +1,39 @@ <template> <div class="dashboard-title"> <div class="title-text"> - 鏅鸿兘宸ヤ綔鍙� 鈥� {{ deviceStore?.deviceInfo?.currentDeviceID ?? '' }} + 鏅鸿兘宸ヤ綔鍙� 鈥� + <el-popover + placement="bottom" + :width="200" + trigger="click" + :content="deviceStore?.deviceInfo?.currentDeviceID ?? ''" + > + <template #reference> + <el-text truncated class="device-name">{{ deviceStore?.deviceInfo?.currentDeviceID ?? '' }}</el-text> + </template> + </el-popover> <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="openProblemsModal"> - <el-icon size="30" :color="problemsIconStatus ? '#00ff00' : '#ff0000'"> + <el-icon size="26" :color="problemsIconStatus ? '#00ff00' : '#ff0000'"> <AlertLightIcon></AlertLightIcon> </el-icon> </div> <div class="cloud-connection-status"> - <el-icon v-if="cloudConnectionIconStatus" size="45" color="#00ff00"> + <el-icon v-if="cloudConnectionIconStatus" size="38" color="#00ff00"> <IconCloudDone></IconCloudDone> </el-icon> - <el-icon v-else size="45" color="#ff0000"> + <el-icon v-else size="38" color="#ff0000"> <IconCloudOff></IconCloudOff> </el-icon> </div> </div> </div> - <DeviceCheckList v-model="showDevicesModal" :devices="deviceList"></DeviceCheckList> + <DeviceCheckList v-model="showDevicesModal" @should-reload="emits('shouldReload')"></DeviceCheckList> <TroubleTrackerModal v-model="showProblemsModal" :problems="problemList"></TroubleTrackerModal> </template> <script setup lang="ts"> @@ -38,6 +48,10 @@ import { useRequest } from 'vue-hooks-plus' import { apiGetProblemList } from '@/api' import { PROBLEMS_POLLING_DURATION } from '@/common/constants' + +const emits = defineEmits<{ + shouldReload: [] +}>() // 鏄惁鏄剧ず闂璇婃柇modal const showProblemsModal = ref(false) @@ -117,10 +131,15 @@ align-items: center; position: absolute; top: 16px; - right: 40px; + right: 6px; } .connection-info { margin-right: 10px; cursor: pointer; } +.device-name { + max-width: 340px; + font-size: 40px; + color: #fff; +} </style> diff --git a/src/views/dashboard/components/DeviceCheckList.vue b/src/views/dashboard/components/DeviceCheckList.vue index 3091543..b63dfe5 100644 --- a/src/views/dashboard/components/DeviceCheckList.vue +++ b/src/views/dashboard/components/DeviceCheckList.vue @@ -4,18 +4,18 @@ <template #title>璁惧閫夋嫨</template> <div class="device-box"> <el-scrollbar always class="scroller"> - <template v-if="devices?.length"> + <template v-if="deviceInfo?.deviceIDList?.length"> <div - v-for="(item, index) in devices" + v-for="(item, index) in deviceInfo?.deviceIDList" :key="index" - :class="item.checked ? 'device-item check-item' : 'device-item'" - @click="deviceClick(index)" + :class="selectedDevice === item ? 'device-item check-item' : 'device-item'" + @click="deviceClick(item)" > <div class="item-l"> - <span>{{ item.number }}</span> - {{ item.name }} + <span>{{ item }}</span> + <!-- {{ item }}--> </div> - <div v-if="item.checked" class="item-r"> + <div v-if="selectedDevice === item" class="item-r"> <el-icon class="item-icon" size="22" color="#00ff00"><CircleCheckFilled /></el-icon> </div> </div> @@ -35,7 +35,11 @@ import { useVModel } from '@vueuse/core' import { CircleCheckFilled } from '@element-plus/icons-vue' import BigButton from '@/views/dashboard/components/BigButton.vue' -import { ref } from 'vue' +import { useDevicesStore } from '@/stores/devices' +import { storeToRefs } from 'pinia' +import { ref, watch } from 'vue' +import { apiSetCurrentDevice } from '@/api' +import { ElMessage } from 'element-plus' export interface DeviceCheckListProps { modelValue: boolean } @@ -45,28 +49,57 @@ const emit = defineEmits<{ 'update:modelValue': [show: boolean] + shouldReload: [] }>() const modelData = useVModel(props, 'modelValue', emit) +const deviceStore = useDevicesStore() +const { deviceInfo } = storeToRefs(deviceStore) -const devices = ref([ - { - number: '111', - name: '璁惧A', - checked: true - }, - { - number: '222', - name: '璁惧b' +// 寮圭獥鎵撳紑鏃惰瀹氬綋鍓嶉�変腑鐨勮澶� +const selectedDevice = ref<string>('') +watch(modelData, () => { + if (modelData.value) { + selectedDevice.value = deviceInfo.value?.currentDeviceID ?? '' } -]) +}) + +function deviceClick(deviceId: string) { + selectedDevice.value = deviceId +} + +function saveModal() { + if (!selectedDevice.value) { + ElMessage({ + message: '璇峰厛閫変腑涓�涓澶�', + type: 'error', + duration: 3 * 1000 + }) + return + } + apiSetCurrentDevice({ currentDeviceID: selectedDevice.value }) + .then(() => { + ElMessage({ + message: '璁惧畾鎴愬姛', + type: 'success', + duration: 2 * 1000 + }) + modelData.value = false + emit('shouldReload') + }) + .catch((err) => { + console.error(err) + ElMessage({ + message: err.msg, + type: 'error', + duration: 3 * 1000 + }) + }) + .finally(() => { + deviceStore.startPollingDevice() + }) +} function closeModal() { modelData.value = false -} -function saveModal() {} -const deviceClick = (index) => { - devices.value.find((ele) => (ele.checked = false)) - - devices.value[index].checked = true } </script> <style scoped lang="scss"> diff --git a/src/views/dashboard/components/TaskControl.vue b/src/views/dashboard/components/TaskControl.vue index 47b9945..3d22b64 100644 --- a/src/views/dashboard/components/TaskControl.vue +++ b/src/views/dashboard/components/TaskControl.vue @@ -42,11 +42,7 @@ </template> </div> </div> - <TaskControlModal - v-model="showTaskControlModal" - :task="task" - @produce-start="emit('shouldReload', task)" - ></TaskControlModal> + <TaskControlModal v-model="showTaskControlModal" :task="task" @produce-start="onProduceStart"></TaskControlModal> </template> <script setup lang="ts"> import type { Task } from '@/api/task' @@ -80,14 +76,14 @@ * 瀹屾垚浠诲姟 */ function finishTaskProduce() { - if (task?.value?.Procedure?.ID) { + if (task?.value && task.value?.Procedure?.ID) { finishTask({ id: task!.value.Procedure.ID }).then( (res) => { ElMessage({ message: '鎿嶄綔鎴愬姛锛�', type: 'success' }) - emit('shouldReload', task.value) + emit('shouldReload', task.value as Task) }, (err) => { console.error(err) @@ -105,6 +101,10 @@ } } +function onProduceStart() { + emit('shouldReload', task!.value as Task) +} + /** * 鏍煎紡鍖栨椂闂存埑 * @param timestamp 鍚庣杩旂殑10浣嶆椂闂存埑 diff --git a/src/views/dashboard/components/TaskStep.vue b/src/views/dashboard/components/TaskStep.vue new file mode 100644 index 0000000..b9f02b6 --- /dev/null +++ b/src/views/dashboard/components/TaskStep.vue @@ -0,0 +1,71 @@ +<template> + <div class="task-step"> + <div v-for="(item, index) in props.steps" :key="index" class="task-step-item" :style="{ 'flex-basis': flexBasis }"> + <el-icon v-if="index + 1 < active" class="icon" size="22" color="#01f304"><CircleCheck /></el-icon> + + <el-icon v-if="index + 1 === active" class="icon" size="22" color="#c25915"><Clock /></el-icon> + <el-icon v-if="index + 1 > active" class="icon" size="22" color="#7d7f83"><Clock /></el-icon> + <span class="text" :class="{ green: index + 1 < active, red: index + 1 === active, gray: index + 1 > active }"> + {{ item }} + </span> + <span class="line"></span> + </div> + </div> +</template> +<script setup lang="ts"> +import { CircleCheck, Clock } from '@element-plus/icons-vue' +import { computed } from 'vue' + +export interface TaskStepProps { + active: number + steps: string[] +} +const props = defineProps<TaskStepProps>() + +const flexBasis = computed(() => { + if (props.steps.length) { + return `${Math.floor((1 / props.steps.length) * 100)}%` + } + return '0' +}) +</script> +<style scoped lang="scss"> +.task-step { + display: flex; + align-items: center; +} +.task-step-item { + display: flex; + align-items: center; + flex: 1; + &:last-child { + flex-basis: auto !important; + flex-shrink: 0; + flex-grow: 0; + & > .line { + display: none; + } + } + .icon { + margin-right: 6px; + } + .green { + color: #01f304; + } + .red { + color: #c25915; + } + .gray { + color: #7d7f83; + } +} +.text { + flex-shrink: 0; +} +.line { + display: inline-block; + height: 1px; + background-color: #fff; + width: 100%; +} +</style> -- Gitblit v1.8.0