import type { VxeGridProps } from '#/adapter/vxe-table'; import { computed, h } from 'vue'; import { z } from '@vben/common-ui'; import dayjs from 'dayjs'; import { getCommonGetSelectList, postAggregationIoTplatformGetIoTplatformProductInfoAsync, } from '#/api-client'; import { $t } from '#/locales'; export const querySchema = computed(() => [ { component: 'Input', fieldName: 'searchKeyword', label: '搜索关键字', componentProps: { placeholder: '请输入产品名称', }, }, { component: 'ApiSelect', fieldName: 'ioTPlatform', label: $t('abp.deviceInfos.ioTPlatform'), componentProps: { api: getCommonGetSelectList, params: { query: { typeName: 'IoTPlatformTypeEnum', }, }, labelField: 'value', valueField: 'key', optionsPropName: 'options', immediate: true, allowClear: true, placeholder: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatform')}`, afterFetch: (res: any) => { if (Array.isArray(res)) { return res; } if (res && Array.isArray(res.items)) { return res.items; } if (res && Array.isArray(res.data)) { return res.data; } return []; }, }, }, { component: 'ApiSelect', fieldName: 'ioTPlatformProductId', label: $t('common.BelongingProductName'), dependencies: { show(values: any) { return !!values.ioTPlatform; }, triggerFields: ['ioTPlatform'], }, componentProps: (formValues: any) => { const platform = formValues?.ioTPlatform; return { api: platform ? postAggregationIoTplatformGetIoTplatformProductInfoAsync : null, params: platform ? { body: { ioTPlatformType: typeof platform === 'string' ? Number.parseInt(platform) : platform, }, } : {}, labelField: 'productName', valueField: 'ioTPlatformProductId', optionsPropName: 'options', immediate: false, allowClear: true, placeholder: $t('common.pleaseSelect') + $t('common.BelongingProductName'), afterFetch: (res: any) => { if (Array.isArray(res)) { return res; } if (res && Array.isArray(res.items)) { return res.items; } if (res && Array.isArray(res.data)) { return res.data; } if (res && res.data && Array.isArray(res.data.items)) { return res.data.items; } return []; }, }; }, }, ]); export const tableSchema: any = computed((): VxeGridProps['columns'] => [ { title: $t('common.seq'), type: 'seq', width: 50 }, { field: 'ioTPlatform', title: $t('common.BelongingIoTPlatform'), minWidth: '150', formatter: ({ cellValue }) => { const platformMap: Record = { '1': 'CTWing', '2': 'OneNET', }; return platformMap[String(cellValue)] || cellValue || '-'; }, }, { field: 'ioTPlatformProductName', title: $t('common.BelongingProductName'), minWidth: '150', }, { field: 'firmwareVersion', title: '固件版本', minWidth: '150', }, { field: 'firmwareFileName', title: '固件文件名称', minWidth: '200', slots: { default: 'firmwareFileName' }, }, { field: 'firmwareLength', title: '文件大小', minWidth: '120', formatter: ({ cellValue }) => { if (!cellValue) return '-'; const bytes = Number(cellValue); if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`; if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`; }, }, { field: 'firmwareHashCode', title: '哈希值', minWidth: '200', showOverflow: 'tooltip', }, { field: 'isEnable', title: '是否启用', minWidth: '100', slots: { default: 'isEnable' }, }, { field: 'creationTime', title: '创建时间', minWidth: '180', formatter: ({ cellValue }) => { return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : ''; }, }, { title: $t('common.action'), field: 'action', fixed: 'right', width: '200', slots: { default: 'action' }, }, ]); export const addFirmwareFormSchema: any = computed(() => [ { component: 'ApiSelect', fieldName: 'ioTPlatform', label: $t('abp.deviceInfos.ioTPlatform'), componentProps: { api: getCommonGetSelectList, params: { query: { typeName: 'IoTPlatformTypeEnum', }, }, labelField: 'value', valueField: 'key', optionsPropName: 'options', immediate: true, allowClear: true, placeholder: $t('common.pleaseSelect') + $t('abp.deviceInfos.ioTPlatform'), afterFetch: (res: any) => { if (Array.isArray(res)) { return res; } if (res && Array.isArray(res.items)) { return res.items; } if (res && Array.isArray(res.data)) { return res.data; } return []; }, }, rules: z.string().min(1, { message: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatform')}`, }), }, { component: 'ApiSelect', fieldName: 'ioTPlatformProductId', label: $t('common.BelongingProductName'), dependencies: { show(values: any) { return !!values.ioTPlatform; }, rules(values: any) { if (values.ioTPlatform) { return 'required'; } return null; }, triggerFields: ['ioTPlatform'], }, componentProps: (formValues: any) => { const platform = formValues?.ioTPlatform; return { api: platform ? postAggregationIoTplatformGetIoTplatformProductInfoAsync : null, params: platform ? { body: { ioTPlatformType: typeof platform === 'string' ? Number.parseInt(platform) : platform, }, } : {}, labelField: 'productName', valueField: 'ioTPlatformProductId', optionsPropName: 'options', immediate: false, allowClear: true, placeholder: $t('common.pleaseSelect') + $t('common.BelongingProductName'), afterFetch: (res: any) => { if (Array.isArray(res)) { return res; } if (res && Array.isArray(res.items)) { return res.items; } if (res && Array.isArray(res.data)) { return res.data; } if (res && res.data && Array.isArray(res.data.items)) { return res.data.items; } return []; }, }; }, rules: z.string().optional(), }, { component: 'Input', fieldName: 'firmwareVersion', label: '固件版本', componentProps: { placeholder: '请输入固件版本', }, rules: z.string().min(1, { message: '请输入固件版本', }), }, { component: 'Input', fieldName: 'firmwareFileName', label: '固件文件名称', componentProps: { placeholder: '请选择文件', readonly: true, addonAfter: h( 'button', { type: 'button', style: 'border: none; background: #1890ff; color: white; padding: 4px 8px; border-radius: 4px; cursor: pointer;', onClick: () => { const input = document.createElement('input'); input.type = 'file'; input.accept = '*/*'; input.addEventListener('change', (e: any) => { const file = e.target.files[0]; if (file) { const currentInput = document.querySelector( 'input[placeholder="请选择文件"]', ) as HTMLInputElement; if (currentInput) { currentInput.value = file.name; currentInput.dispatchEvent( new Event('input', { bubbles: true }), ); currentInput.dispatchEvent( new Event('change', { bubbles: true }), ); // 存储文件对象到全局变量 (window as any).__selectedFirmwareFile = file; } } }); input.click(); }, }, '选择文件', ), }, rules: z.string().min(1, { message: '请选择固件文件', }), }, { component: 'Input', fieldName: 'firmwareFileId', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'firmwareHashCode', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'firmwareLength', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'ioTPlatformProductName', label: '', componentProps: { type: 'hidden', }, }, ]); export const editFirmwareFormSchema: any = computed(() => [ { component: 'ApiSelect', fieldName: 'ioTPlatform', label: $t('abp.deviceInfos.ioTPlatform'), componentProps: { api: getCommonGetSelectList, params: { query: { typeName: 'IoTPlatformTypeEnum', }, }, labelField: 'value', valueField: 'key', optionsPropName: 'options', immediate: true, allowClear: true, placeholder: $t('common.pleaseSelect') + $t('abp.deviceInfos.ioTPlatform'), afterFetch: (res: any) => { if (Array.isArray(res)) { return res; } if (res && Array.isArray(res.items)) { return res.items; } if (res && Array.isArray(res.data)) { return res.data; } return []; }, }, rules: z.string().min(1, { message: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatform')}`, }), }, { component: 'ApiSelect', fieldName: 'ioTPlatformProductId', label: $t('common.BelongingProductName'), dependencies: { show(values: any) { return !!values.ioTPlatform; }, rules(values: any) { if (values.ioTPlatform) { return 'required'; } return null; }, triggerFields: ['ioTPlatform'], }, componentProps: (formValues: any) => { const platform = formValues?.ioTPlatform; return { api: platform ? postAggregationIoTplatformGetIoTplatformProductInfoAsync : null, params: platform ? { body: { ioTPlatformType: typeof platform === 'string' ? Number.parseInt(platform) : platform, }, } : {}, labelField: 'productName', valueField: 'ioTPlatformProductId', optionsPropName: 'options', immediate: false, allowClear: true, placeholder: $t('common.pleaseSelect') + $t('common.BelongingProductName'), afterFetch: (res: any) => { if (Array.isArray(res)) { return res; } if (res && Array.isArray(res.items)) { return res.items; } if (res && Array.isArray(res.data)) { return res.data; } if (res && res.data && Array.isArray(res.data.items)) { return res.data.items; } return []; }, }; }, rules: z.string().optional(), }, { component: 'Input', fieldName: 'firmwareVersion', label: '固件版本', componentProps: { placeholder: '请输入固件版本', }, rules: z.string().min(1, { message: '请输入固件版本', }), }, { component: 'Input', fieldName: 'firmwareFileName', label: '固件文件名称', componentProps: { placeholder: '请选择文件', readonly: true, addonAfter: h( 'button', { type: 'button', style: 'border: none; background: #1890ff; color: white; padding: 4px 8px; border-radius: 4px; cursor: pointer;', onClick: () => { const input = document.createElement('input'); input.type = 'file'; input.accept = '*/*'; input.addEventListener('change', (e: any) => { const file = e.target.files[0]; if (file) { const currentInput = document.querySelector( 'input[placeholder="请选择文件"]', ) as HTMLInputElement; if (currentInput) { currentInput.value = file.name; currentInput.dispatchEvent( new Event('input', { bubbles: true }), ); currentInput.dispatchEvent( new Event('change', { bubbles: true }), ); // 存储文件对象到全局变量 (window as any).__selectedFirmwareFile = file; } } }); input.click(); }, }, '选择文件', ), }, rules: z.string().min(1, { message: '请选择固件文件', }), }, { component: 'Input', fieldName: 'firmwareFileId', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'firmwareHashCode', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'firmwareLength', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'ioTPlatformProductName', label: '', componentProps: { type: 'hidden', }, }, { component: 'Input', fieldName: 'id', label: '', componentProps: { type: 'hidden', }, }, ]);