562 lines
14 KiB
TypeScript
Raw Normal View History

2025-12-31 15:08:21 +08:00
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<string, string> = {
'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',
},
},
]);