diff --git a/.env.development b/.env.development index 76f6148..e8eb91d 100644 --- a/.env.development +++ b/.env.development @@ -1,2 +1,2 @@ VITE_BASE_URL = 'http://192.168.1.3:48080' -VITE_SOCKET_SERVER = 'http://192.168.1.3:7080' +VITE_SOCKET_SERVER = 'http://192.168.1.3:48080' diff --git a/components.d.ts b/components.d.ts index c150e25..47eb26d 100644 --- a/components.d.ts +++ b/components.d.ts @@ -21,10 +21,20 @@ declare module 'vue' { EdfsTable: typeof import('./src/components/dashboard/Edfs-table/index.vue')['default'] EdfsWrap: typeof import('./src/components/dashboard/Edfs-wrap.vue')['default'] Editor: typeof import('./src/components/dashboard/Editor/src/Editor.vue')['default'] + ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElButton: typeof import('element-plus/es')['ElButton'] ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup'] + ElCard: typeof import('element-plus/es')['ElCard'] + ElCascader: typeof import('element-plus/es')['ElCascader'] + ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] + ElCol: typeof import('element-plus/es')['ElCol'] + ElCollapse: typeof import('element-plus/es')['ElCollapse'] + ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] + ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] + ElDialog: typeof import('element-plus/es')['ElDialog'] ElDivider: typeof import('element-plus/es')['ElDivider'] + ElDrawer: typeof import('element-plus/es')['ElDrawer'] ElDropdown: typeof import('element-plus/es')['ElDropdown'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] @@ -32,20 +42,40 @@ declare module 'vue' { ElFormItem: typeof import('element-plus/es')['ElFormItem'] ElHeader: typeof import('element-plus/es')['ElHeader'] ElIcon: typeof import('element-plus/es')['ElIcon'] + ElImageViewer: typeof import('element-plus/es')['ElImageViewer'] ElInput: typeof import('element-plus/es')['ElInput'] + ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] + ElLink: typeof import('element-plus/es')['ElLink'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] + ElOption: typeof import('element-plus/es')['ElOption'] ElPagination: typeof import('element-plus/es')['ElPagination'] ElPopover: typeof import('element-plus/es')['ElPopover'] + ElProgress: typeof import('element-plus/es')['ElProgress'] + ElRadio: typeof import('element-plus/es')['ElRadio'] + ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] + ElRow: typeof import('element-plus/es')['ElRow'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] + ElSelect: typeof import('element-plus/es')['ElSelect'] + ElSpace: typeof import('element-plus/es')['ElSpace'] ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] + ElSwitch: typeof import('element-plus/es')['ElSwitch'] + ElTable: typeof import('element-plus/es')['ElTable'] + ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] ElTabPane: typeof import('element-plus/es')['ElTabPane'] ElTabs: typeof import('element-plus/es')['ElTabs'] + ElTag: typeof import('element-plus/es')['ElTag'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] + ElTree: typeof import('element-plus/es')['ElTree'] + ElTreeSelect: typeof import('element-plus/es')['ElTreeSelect'] + ElUpload: typeof import('element-plus/es')['ElUpload'] Form: typeof import('./src/components/dashboard/Form/src/Form.vue')['default'] FormItemInput: typeof import('./src/components/dashboard/FormItemInput.vue')['default'] FormItemSelect: typeof import('./src/components/dashboard/FormItemSelect.vue')['default'] Icon: typeof import('./src/components/dashboard/Icon/src/Icon.vue')['default'] IconSelect: typeof import('./src/components/dashboard/Icon/src/IconSelect.vue')['default'] + IEpUploadFilled: typeof import('~icons/ep/upload-filled')['default'] ImageViewer: typeof import('./src/components/dashboard/ImageViewer/src/ImageViewer.vue')['default'] InputPassword: typeof import('./src/components/dashboard/InputPassword/src/InputPassword.vue')['default'] LegendItem: typeof import('./src/components/map_tool/legend/LegendItem.vue')['default'] @@ -63,4 +93,7 @@ declare module 'vue' { XButton: typeof import('./src/components/dashboard/XButton/src/XButton.vue')['default'] XTextButton: typeof import('./src/components/dashboard/XButton/src/XTextButton.vue')['default'] } + export interface ComponentCustomProperties { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } } diff --git a/src/api/module/eam/device/firmware.ts b/src/api/module/eam/device/firmware.ts index 5501bf7..3e65ae4 100644 --- a/src/api/module/eam/device/firmware.ts +++ b/src/api/module/eam/device/firmware.ts @@ -26,10 +26,10 @@ export function createFirmware(data: any) { }) } -export function getSimpleFirmwareList(params: { type: number }) { +export function getSimpleFirmwareList(params: { type: string }) { return eamServer({ url: '/firmware/simple-list', method: 'get', params, }) -} +} \ No newline at end of file diff --git a/src/api/module/eam/device/index.ts b/src/api/module/eam/device/index.ts index 786b751..e673f92 100644 --- a/src/api/module/eam/device/index.ts +++ b/src/api/module/eam/device/index.ts @@ -16,17 +16,21 @@ export interface IDevice { testSheetId: number testSheetStatus: string testSheetDetail: string + currentFirmwareId: string + targetFirmwareId: string } export interface IDeviceOV { id?: number - name: string + name?: string categoryId: string templateId: string serialNo?: string sn: string description: string cost: string + currentFirmwareId: string + targetFirmwareId: string } export const operantDevice = (type: OperantAction, data: IDeviceOV) => { @@ -82,6 +86,13 @@ export const getDeviceSummaryByStatus = () => { }) } +export const getSimpleDeviceList = (params: { categoryId: string }) => + eamServer({ + url: `/device/simple-list`, + method: 'get', + params, + }) + // ============== 测试工单相关 ============== export const operantDeviceTestSheet = (type: OperantAction, params: any) => { diff --git a/src/api/module/eam/device/task.ts b/src/api/module/eam/device/task.ts index 6776487..bccbc40 100644 --- a/src/api/module/eam/device/task.ts +++ b/src/api/module/eam/device/task.ts @@ -2,7 +2,7 @@ import { eamServer } from '../../index' export function getTaskList(params: PageParam) { return eamServer({ - url: '/device/task/page', + url: '/task/page', method: 'get', params, }) @@ -10,7 +10,7 @@ export function getTaskList(params: PageParam) { export function getTaskDetails(id: string) { return eamServer({ - url: '/device/task/details', + url: '/task/details', method: 'get', params: { id }, }) @@ -18,7 +18,7 @@ export function getTaskDetails(id: string) { export function createTask(data: any) { return eamServer({ - url: '/device/firmware/remote-update', + url: '/firmware/remote-update', method: 'post', data, }) diff --git a/src/pages/deviceInfo/components/BasicInfo.vue b/src/pages/deviceInfo/components/BasicInfo.vue index 73b6ed6..26f3abb 100644 --- a/src/pages/deviceInfo/components/BasicInfo.vue +++ b/src/pages/deviceInfo/components/BasicInfo.vue @@ -13,16 +13,6 @@ > -
-
设备名称:
- -
设备SN:
@@ -34,8 +24,6 @@ clearable />
- -
设备类别:
+
+
+
+
设备固件:
+ + + +
测试模板:
+
+
当前固件:
+ +
备注:
@@ -95,6 +113,13 @@ v-if="isShowSaveButton" @click="onSave" /> +
@@ -103,15 +128,17 @@ import { isEmpty } from '@/utils/is' import numberInput from '@/components/dashboard/Edfs-number-item-input.vue' import EdfsButton from '@/components/dashboard/Edfs-button/index.vue' +import { getSimpleFirmwareList } from '@/api/module/eam/device/firmware' import FormItemSelect from '@/components/dashboard/FormItemSelect.vue' import { operantDevice, type IDevice, type IDeviceOV } from '@/api/module/eam/device' import { cloneDeep } from 'lodash' import { isResError, useMessage } from '@/hooks/useMessage' import { getDeviceTempSimpleList } from '@/api/module/eam/device/template' import { getCategoryTree, type ICategoryTree } from '@/api/module/eam/device/category' -import { useRoute } from 'vue-router' +import { useRoute, useRouter } from 'vue-router' import type { OptAction } from '../utils' const route = useRoute() +const router = useRouter() const action = route.query.action as OptAction const message = useMessage() const props = defineProps<{ @@ -122,20 +149,29 @@ const props = defineProps<{ const emit = defineEmits(['on-save']) const paramsData: IDeviceOV = { - name: '', + currentFirmwareId: '', categoryId: '', templateId: '', sn: '', serialNo: '', description: '', cost: '', + targetFirmwareId: '', } const isShowSaveButton = computed(() => { - if(action === 'view') return false + if (action === 'view') return false return props.info?.status === undefined ? true : props.info.status < 2 }) +const isShowFirmwareUpgradeButton = computed(() => { + if (action === 'view') return false + + return props.info?.status === undefined + ? false + : props.info.status >= 1 && props.info.targetFirmwareId +}) + const params = ref(cloneDeep(paramsData)) async function onSave() { @@ -144,9 +180,6 @@ async function onSave() { const type = !!params.value.serialNo ? 'update' : 'create' const options = cloneDeep(params.value) if (type === 'update') options.id = props.info?.id - options.categoryId = Array.isArray(options.categoryId) - ? options.categoryId[options.categoryId.length - 1] - : options.categoryId const res = await operantDevice(type, options) if (isResError(res)) return message.success('基础信息提交成功') @@ -162,34 +195,40 @@ watch( params.value[key] = info[key] ?? '' } } - console.log(params.value) }, { immediate: true } ) +watch( + () => params.value.categoryId, + val => { + params.value.targetFirmwareId = '' + } +) + function validate() { - if (isEmpty(params.value.name)) { - message.error('设备名称不能为空') + if (isEmpty(params.value.targetFirmwareId)) { + message.error('请选择固件') return false } if (isEmpty(params.value.sn)) { - message.error('设备SN不能为空') + message.error('请输入设备SN') return false } if (isEmpty(params.value.categoryId)) { - message.error('设备类别不能为空') + message.error('请选择设备类别') return false } if (isEmpty(params.value.templateId)) { - message.error('测试模板不能为空') + message.error('请选择测试模板') return false } if (isEmpty(params.value.cost)) { - message.error('设备成本不能为空') + message.error('请输入设备成本') return false } @@ -212,6 +251,34 @@ async function loadDeviceTypeTree() { categoryTreeData.value = res.data } } + +const firmwareList = ref([]) +async function loadFirmwareList(value: boolean) { + if (!value) return + if (isEmpty(params.value.categoryId)) { + message.error('请选择设备类别') + return + } + const res = await getSimpleFirmwareList({ type: params.value.categoryId as any }) + if (!isResError(res)) { + firmwareList.value = res.data + } +} + +function onFirmwareUpgrade() { + if (!props.info) return + + router.push({ + path: '/ota/upgradeTask', + query: { + type: 'create', + categoryId: props.info.categoryId, + deviceSn: props.info.sn, + firmwareId: props.info.targetFirmwareId, + }, + }) +} + onMounted(() => { loadDeviceTypeTree() loadTemplateList() diff --git a/src/pages/deviceInfo/components/data-filter.vue b/src/pages/deviceInfo/components/data-filter.vue index 35d6484..044836c 100644 --- a/src/pages/deviceInfo/components/data-filter.vue +++ b/src/pages/deviceInfo/components/data-filter.vue @@ -37,8 +37,8 @@
- - + +
@@ -67,6 +67,7 @@ checkStrictly: true, value: 'id', label: 'name', + emitPath: false, }" /> @@ -109,16 +110,16 @@ type FilterKeys = keyof typeof filterData.value const filterData = ref({ startDay: '', endDay: '', - name: '', + sn: '', status: '', serialNo: '', - categoryId: [], + categoryId: '', }) const checkbox = ref>({ startDay: false, endDay: false, - name: false, + sn: false, serialNo: false, status: false, categoryId: false, @@ -147,14 +148,16 @@ function onReset() { filterData.value = { startDay: '', endDay: '', - name: '', + sn: '', + status: '', serialNo: '', categoryId: [], } checkbox.value = { startDay: false, endDay: false, - name: false, + sn: false, + status: false, serialNo: false, categoryId: false, } diff --git a/src/pages/deviceInfo/index.vue b/src/pages/deviceInfo/index.vue index 80f1c14..73264e4 100644 --- a/src/pages/deviceInfo/index.vue +++ b/src/pages/deviceInfo/index.vue @@ -130,9 +130,7 @@ const getList = async () => { } loading.value = true - const options = Object.assign({}, queryParams, filter.value, { - categoryId: filter.value.categoryId?.[filter.value.categoryId.length - 1], - }) + const options = Object.assign({}, queryParams, filter.value) const res = await getDevicePage(options) diff --git a/src/pages/deviceInfo/utils.ts b/src/pages/deviceInfo/utils.ts index eac1e69..1efa998 100644 --- a/src/pages/deviceInfo/utils.ts +++ b/src/pages/deviceInfo/utils.ts @@ -5,11 +5,11 @@ export enum DeviceStatus { 已出库, } export const deviceTableCol = [ + { label: '设备sn', prop: 'sn', minWidth: '10%' }, { label: '设备编号', prop: 'serialNo', minWidth: '16%' }, - { label: '设备名称', prop: 'name', minWidth: '10%' }, + // { label: '设备名称', prop: 'name', minWidth: '10%' }, { label: '设备类型', prop: 'categoryName', minWidth: '10%' }, { label: '设备状态', prop: 'status', minWidth: '10%' }, - { label: '设备sn', prop: 'sn', minWidth: '10%' }, { label: '创建时间', prop: 'createTime', minWidth: '10%' }, ] diff --git a/src/pages/deviceStorage/utils.ts b/src/pages/deviceStorage/utils.ts index 2268dfb..d5e6689 100644 --- a/src/pages/deviceStorage/utils.ts +++ b/src/pages/deviceStorage/utils.ts @@ -1,5 +1,5 @@ export const tableCol = [ - { label: '设备名称', prop: 'deviceName', minWidth: '10%' }, + // { label: '设备名称', prop: 'deviceName', minWidth: '10%' }, { label: '设备sn', prop: 'sn', minWidth: '10%' }, { label: '库存状态', prop: 'status', minWidth: '10%' }, { label: '客户', prop: 'customerName', minWidth: '14%' }, diff --git a/src/pages/deviceTest/testPlan/components/InfoDlg.vue b/src/pages/deviceTest/testPlan/components/InfoDlg.vue index 36fd56b..bf2637e 100644 --- a/src/pages/deviceTest/testPlan/components/InfoDlg.vue +++ b/src/pages/deviceTest/testPlan/components/InfoDlg.vue @@ -22,6 +22,7 @@ checkStrictly: true, value: 'id', label: 'name', + emitPath: false, }" clearable /> @@ -86,9 +87,7 @@ async function onSave() { if (!validate()) return loading.value = true const params = cloneDeep(formData.value) - params.categoryId = Array.isArray(params.categoryId) - ? params.categoryId[params.categoryId.length - 1] - : params.categoryId + let res if (props.action === 'create') { res = await createdDeviceTemp(params) @@ -109,7 +108,7 @@ function validate() { return false } - if (formData.value.categoryId.length === 0) { + if (isEmpty(formData.value.categoryId)) { message.error('请选择设备类型') return false } diff --git a/src/pages/layout.vue b/src/pages/layout.vue index ff2a7a8..5c80ca9 100644 --- a/src/pages/layout.vue +++ b/src/pages/layout.vue @@ -111,6 +111,7 @@ import Avatar from './avatar.png' import { useI18n } from 'vue-i18n' import { useTheme } from '@/utils/useTheme' import { THEME_KEY, INIT_OPTIONS_KEY } from 'vue-echarts' +import { openSocket, closeSocket } from '@/pages/socket_server/index' import { registerTheme } from 'echarts/core' const { theme, toggle } = useTheme() import { customDark, customLight } from '@/utils/dark' @@ -121,6 +122,8 @@ provide(INIT_OPTIONS_KEY, { devicePixelRatio: 2, }) +openSocket() + const route = useRoute() const breadcrumbItems = computed(() => { @@ -236,7 +239,9 @@ async function loginOut() { } catch {} } - +onUnmounted(() => { + closeSocket() +})