From ac343f006afccddf3278f32357c56535f0b93e5a Mon Sep 17 00:00:00 2001 From: fhysy <1149505133@qq.com> Date: Tue, 16 Sep 2025 17:10:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=87=8D=E6=9E=84=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD=E3=80=81=E8=8E=B7=E5=8F=96=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E8=AE=BE=E5=A4=87=E5=9B=BE=E7=89=87=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=E5=88=B0vuex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 重构了设备列表页面的布局和样式,增加了卡片视图和列表视图的切换功能 - 添加了设备默认图片功能,新建或编辑设备时自动加载默认图片 - 优化了设备列表的搜索、筛选和分页功能 - 更新了设备详情和编辑页面的样式 - 调整了产品列表和设备列表的关联逻辑 --- apps/web-antd/src/layouts/basic.vue | 7 +- apps/web-antd/src/store/device.ts | 14 + .../components/running/FunctionPanel.vue | 1 + .../src/views/device/device/device-drawer.vue | 23 +- .../src/views/device/device/index.vue | 770 +++++++++++++----- .../src/views/device/product/detail/index.vue | 8 +- .../src/views/device/product/index.vue | 76 +- .../views/device/product/product-drawer.vue | 22 +- apps/web-antd/vite.config.mts | 3 +- 9 files changed, 670 insertions(+), 254 deletions(-) diff --git a/apps/web-antd/src/layouts/basic.vue b/apps/web-antd/src/layouts/basic.vue index 24ef10b..83f0676 100644 --- a/apps/web-antd/src/layouts/basic.vue +++ b/apps/web-antd/src/layouts/basic.vue @@ -28,12 +28,14 @@ import { TenantToggle } from '#/components/tenant-toggle'; import { $t } from '#/locales'; import { resetRoutes } from '#/router'; import { useAuthStore, useNotifyStore } from '#/store'; +import { useDeviceStore } from '#/store/device'; import { useTenantStore } from '#/store/tenant'; import LoginForm from '#/views/_core/authentication/login.vue'; const userStore = useUserStore(); const authStore = useAuthStore(); const accessStore = useAccessStore(); +const deviceStore = useDeviceStore(); const router = useRouter(); const { destroyWatermark, updateWatermark } = useWatermark(); @@ -106,7 +108,10 @@ async function handleLogout() { } const notifyStore = useNotifyStore(); -onMounted(() => notifyStore.startListeningMessage()); +onMounted(() => { + notifyStore.startListeningMessage(); + deviceStore.updateDefaultDeviceImgId(); // 这样调用 +}); function handleViewAll() { message.warning('暂未开放'); diff --git a/apps/web-antd/src/store/device.ts b/apps/web-antd/src/store/device.ts index 7729dcc..20c4394 100644 --- a/apps/web-antd/src/store/device.ts +++ b/apps/web-antd/src/store/device.ts @@ -1,18 +1,21 @@ import { defineStore } from 'pinia'; import { deviceInfo } from '#/api/device/device'; +import { configInfoByKey } from '#/api/system/config'; export const useDeviceStore = defineStore('device', { state: () => ({ currentDevice: {} as any, tabActiveKey: 'BasicInfo', deviceCount: 0, + defaultDeviceImgId: '', }), getters: { getCurrentDevice: (state) => state.currentDevice, getTabActiveKey: (state) => state.tabActiveKey, getDeviceCount: (state) => state.deviceCount, + getDefaultDeviceImgId: (state) => state.defaultDeviceImgId, }, actions: { @@ -32,6 +35,17 @@ export const useDeviceStore = defineStore('device', { this.currentDevice.deviceState = state; }, + async updateDefaultDeviceImgId() { + try { + const res = await configInfoByKey('device.defaultDeviceImgId'); + this.defaultDeviceImgId = res; + return res; + } catch (error) { + console.error('获取设备默认图片失败:', error); + throw error; + } + }, + async getDetail(id: string) { try { const res = await deviceInfo(id); diff --git a/apps/web-antd/src/views/device/device/detail/components/running/FunctionPanel.vue b/apps/web-antd/src/views/device/device/detail/components/running/FunctionPanel.vue index 1fccd0c..60c07c6 100644 --- a/apps/web-antd/src/views/device/device/detail/components/running/FunctionPanel.vue +++ b/apps/web-antd/src/views/device/device/detail/components/running/FunctionPanel.vue @@ -103,6 +103,7 @@ const loadList = async () => { productKey: props.deviceInfo.productObj.productKey, msgId: messageId.value?.trim() || undefined, funcId: selectedFuncId.value || undefined, + orderByColumn: 'createTime', isAsc: 'desc', pageNum: pagination.value.current, pageSize: pagination.value.pageSize, diff --git a/apps/web-antd/src/views/device/device/device-drawer.vue b/apps/web-antd/src/views/device/device/device-drawer.vue index c83d720..23ecba9 100644 --- a/apps/web-antd/src/views/device/device/device-drawer.vue +++ b/apps/web-antd/src/views/device/device/device-drawer.vue @@ -8,12 +8,15 @@ import { cloneDeep } from '@vben/utils'; import { useVbenForm } from '#/adapter/form'; import { deviceAdd, deviceInfo, deviceUpdate } from '#/api/device/device'; import { productList } from '#/api/device/product'; +import { useDeviceStore } from '#/store/device'; import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup'; import { drawerSchema } from './data'; const emit = defineEmits<{ reload: [] }>(); +const deviceStore = useDeviceStore(); + const isUpdate = ref(false); const title = computed(() => { return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add'); @@ -35,10 +38,12 @@ const [BasicForm, formApi] = useVbenForm({ wrapperClass: 'grid-cols-2', }); -const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff({ - initializedGetter: defaultFormValueGetter(formApi), - currentGetter: defaultFormValueGetter(formApi), -}); +const { onBeforeClose, markInitialized, resetInitialized } = useBeforeCloseDiff( + { + initializedGetter: defaultFormValueGetter(formApi), + currentGetter: defaultFormValueGetter(formApi), + }, +); const [BasicDrawer, drawerApi] = useVbenDrawer({ // 在这里更改宽度 @@ -63,7 +68,10 @@ const [BasicDrawer, drawerApi] = useVbenDrawer({ if (isUpdate.value && id) { const record = await deviceInfo(id); await formApi.setValues(record); + } else { + await formApi.setFieldValue('imgId', deviceStore.getDefaultDeviceImgId); } + await markInitialized(); drawerApi.drawerLoading(false); @@ -80,6 +88,9 @@ async function handleConfirm() { } // getValues获取为一个readonly的对象 需要修改必须先深拷贝一次 const data = cloneDeep(await formApi.getValues()); + if (data.imgId === undefined || data.imgId === '') { + data.imgId = deviceStore.getDefaultDeviceImgId; + } await (isUpdate.value ? deviceUpdate(data) : deviceAdd(data)); resetInitialized(); emit('reload'); @@ -120,7 +131,9 @@ async function getProductOptionList() { onChange: (value: number | string) => { // 当产品选择变化时,自动设置设备图片 if (value) { - const selectedProduct = productOptions.find((option) => option.value === value); + const selectedProduct = productOptions.find( + (option) => option.value === value, + ); formApi.setFieldValue('imgId', selectedProduct?.imgId || ''); } }, diff --git a/apps/web-antd/src/views/device/device/index.vue b/apps/web-antd/src/views/device/device/index.vue index ec317c7..0c82c0b 100644 --- a/apps/web-antd/src/views/device/device/index.vue +++ b/apps/web-antd/src/views/device/device/index.vue @@ -1,274 +1,634 @@ - - - - + + + + + + + + + + + + + {{ opt.label }} + + + + + + + {{ opt.label }} + + + + + + + {{ opt.label }} + + + + + + + 查询 + 重置 + + + + + + + + 设备列表 - {{ $t('pages.common.export') }} - - + {{ $t('pages.common.delete') }} - - + {{ $t('pages.common.add') }} - + + + + - - - - {{ - deviceTypeOptions.find((option) => option.value === row.deviceType) - ?.label - }} - - - - + + + + + {{ getDeviceTypeLabel(text) }} + + + + {{ getDeviceStateMeta(text).label }} + + + + + + 详情 + + + {{ $t('pages.common.edit') }} + + + + {{ $t('pages.common.delete') }} + + + + + + + + + + + + + + + + + + + + {{ item.deviceName || '-' }} + + + 所属产品:{{ item.productObj?.productName || '-' }} + + + 设备类型:{{ getDeviceTypeLabel(item.deviceType) }} + + + {{ getDeviceStateMeta(item.deviceState).label }} + + + + + + {{ $t('pages.common.edit') }} + + + + {{ $t('pages.common.delete') }} + + + + + + + + + + + { + pagination.current = p; + pagination.pageSize = s; + fetchData(); + } " - > - {{ - deviceStateOptions.find( - (option) => option.value === row.deviceState, - )?.label - }} - - - - - - 详情 - - - {{ $t('pages.common.edit') }} - - - - {{ $t('pages.common.delete') }} - - - - - - + @show-size-change=" + (p, s) => { + pagination.current = 1; + pagination.pageSize = s; + fetchData(); + } + " + /> + + + + - diff --git a/apps/web-antd/src/views/device/product/detail/index.vue b/apps/web-antd/src/views/device/product/detail/index.vue index 97791a4..7e6ebb9 100644 --- a/apps/web-antd/src/views/device/product/detail/index.vue +++ b/apps/web-antd/src/views/device/product/detail/index.vue @@ -23,7 +23,6 @@ const productStore = useProductStore(); const productId = computed(() => route.params.id as string); const activeTab = computed(() => productStore.getTabActiveKey); -const deviceCount = computed(() => productStore.getDeviceCount); const currentProduct = computed(() => productStore.getCurrentProduct); // 加载产品信息 @@ -74,9 +73,9 @@ const handleApplyConfig = async () => { // 跳转到设备列表 const jumpToDevices = () => { router.push({ - path: '/device/instance', + path: '/device/device', query: { - productId: productId.value, + productId: currentProduct.value.id, }, }); }; @@ -148,7 +147,8 @@ onUnmounted(() => { - 设备数量:{{ deviceCount }} + 设备数量: + {{ currentProduct.deviceCount }} diff --git a/apps/web-antd/src/views/device/product/index.vue b/apps/web-antd/src/views/device/product/index.vue index be40a20..ef7d845 100644 --- a/apps/web-antd/src/views/device/product/index.vue +++ b/apps/web-antd/src/views/device/product/index.vue @@ -1,4 +1,4 @@ -