批量设备添加

This commit is contained in:
ChenYi 2025-08-04 17:36:09 +08:00
parent 934043edde
commit d241a1a6b9
6 changed files with 545 additions and 357 deletions

View File

@ -1231,7 +1231,7 @@ export const CreateDeviceAggregationInputSchema = {
ioTPlatformProductId: {
minLength: 1,
type: 'string',
description: '集中器在物联网平台中对应的产品Id'
description: '设备在物联网平台中对应的产品Id'
},
deviceSourceTypeEnum: {
'$ref': '#/components/schemas/DeviceSourceTypeEnum'
@ -4551,154 +4551,62 @@ JiShe.ServicePro.Enums.DeviceTypeEnum`,
description: '设备路径,树模型使用,表模型会在数据插入的时候直接获取继承类的名称作为表明',
nullable: true
},
scoreValue: {
productId: {
type: 'string',
description: '排序索引分数值,具体值可以根据不同业务场景进行定义,例如时间戳、或者某一个固定的标识',
description: '物联网平台产品Id',
nullable: true
},
packetType: {
platformDeviceId: {
type: 'string',
description: '物联网平台设备ID',
nullable: true
},
messageType: {
type: 'string',
description: '消息类型',
nullable: true
},
rawMessage: {
type: 'string',
description: '下发消息体原始内容',
nullable: true
},
issuePayload: {
type: 'string',
description: '下发消息体',
nullable: true
},
responseRawMessage: {
type: 'string',
description: '下发结果原始内容',
nullable: true
},
responseResult: {
type: 'string',
description: '下发结果',
nullable: true
},
telemetrySource: {
type: 'integer',
description: '数据包类型',
description: '遥测指令来源',
format: 'int32'
},
manualOrNot: {
type: 'boolean',
description: '是否手动操作'
},
taskMark: {
telemetrySourceName: {
type: 'string',
description: '任务数据唯一标记',
nullable: true
description: '遥测指令来源',
nullable: true,
readOnly: true
},
isTimeout: {
type: 'boolean',
description: '是否超时'
},
pendingCopyReadTime: {
type: 'string',
description: '待抄读时间',
format: 'date-time'
},
focusId: {
ioTPlatform: {
type: 'integer',
description: '集中器Id',
description: `设备指令发送平台
IoTPlatformTypeEnum`,
format: 'int32'
},
focusAddress: {
ioTPlatformName: {
type: 'string',
description: '集中器地址',
nullable: true
},
meterAddress: {
type: 'string',
description: '表地址',
nullable: true
},
databaseBusiID: {
type: 'integer',
description: '数据库业务ID',
format: 'int32'
},
afn: {
type: 'integer',
description: 'AFN功能码',
format: 'int32'
},
fn: {
type: 'integer',
description: '抄读功能码',
format: 'int32'
},
pn: {
type: 'integer',
description: '抄读计量点',
format: 'int32'
},
itemCode: {
type: 'string',
description: '采集项编码',
nullable: true
},
subItemCode: {
type: 'string',
description: '子项编码,一般用于透明转发的编码',
nullable: true
},
seq: {
type: 'integer',
description: '帧序列域 SEQ',
format: 'int32'
},
msa: {
type: 'integer',
description: '地址域A3的主站地址MSA',
format: 'int32'
},
isSend: {
type: 'boolean',
description: '是否发送'
},
sendNum: {
type: 'integer',
description: '发送次数',
format: 'int32',
nullable: true
},
nextSendTime: {
type: 'string',
description: '下次发送时间',
format: 'date-time',
nullable: true
},
creationTime: {
type: 'string',
description: '创建时间',
format: 'date-time'
},
issuedMessageHexString: {
type: 'string',
description: '下发消息内容',
nullable: true
},
issuedMessageId: {
type: 'string',
description: '下发消息Id',
nullable: true
},
focusDensity: {
type: 'integer',
description: '集中器采集密度',
format: 'int32'
},
receivedMessageHexString: {
type: 'string',
description: '消息上报内容',
nullable: true
},
receivedTime: {
type: 'string',
description: '消息上报时间',
format: 'date-time',
nullable: true
},
receivedMessageId: {
type: 'string',
description: '上报消息Id',
nullable: true
},
receivedRemark: {
type: 'string',
description: '上报报文解析备注,异常情况下才有',
nullable: true
},
isReceived: {
type: 'boolean',
description: '是否已上报'
},
times: {
type: 'string',
description: '时标',
format: 'date-time',
description: '设备指令发送平台',
nullable: true,
readOnly: true
}
},

View File

@ -224,7 +224,7 @@ export type CreateDeviceAggregationInput = {
deviceAddress: string;
ioTPlatform: IoTPlatformTypeEnum;
/**
* Id
* Id
*/
ioTPlatformProductId: string;
deviceSourceTypeEnum?: DeviceSourceTypeEnum;
@ -2187,125 +2187,50 @@ export type MeterReadingPacketInfoPageOutput = {
*/
devicePath?: (string) | null;
/**
*
* Id
*/
scoreValue?: (string) | null;
productId?: (string) | null;
/**
*
* ID
*/
packetType?: number;
platformDeviceId?: (string) | null;
/**
*
*
*/
manualOrNot?: boolean;
messageType?: (string) | null;
/**
*
*
*/
taskMark?: (string) | null;
rawMessage?: (string) | null;
/**
*
*
*/
isTimeout?: boolean;
issuePayload?: (string) | null;
/**
*
*
*/
pendingCopyReadTime?: string;
responseRawMessage?: (string) | null;
/**
* Id
*
*/
focusId?: number;
responseResult?: (string) | null;
/**
*
*
*/
focusAddress?: (string) | null;
telemetrySource?: number;
/**
*
*
*/
meterAddress?: (string) | null;
readonly telemetrySourceName?: (string) | null;
/**
* ID
*
* IoTPlatformTypeEnum
*/
databaseBusiID?: number;
ioTPlatform?: number;
/**
* AFN功能码
*
*/
afn?: number;
/**
*
*/
fn?: number;
/**
*
*/
pn?: number;
/**
*
*/
itemCode?: (string) | null;
/**
*
*/
subItemCode?: (string) | null;
/**
* SEQ
*/
seq?: number;
/**
* A3的主站地址MSA
*/
msa?: number;
/**
*
*/
isSend?: boolean;
/**
*
*/
sendNum?: (number) | null;
/**
*
*/
nextSendTime?: (string) | null;
/**
*
*/
creationTime?: string;
/**
*
*/
issuedMessageHexString?: (string) | null;
/**
* Id
*/
issuedMessageId?: (string) | null;
/**
*
*/
focusDensity?: number;
/**
*
*/
receivedMessageHexString?: (string) | null;
/**
*
*/
receivedTime?: (string) | null;
/**
* Id
*/
receivedMessageId?: (string) | null;
/**
*
*/
receivedRemark?: (string) | null;
/**
*
*/
isReceived?: boolean;
/**
*
*/
readonly times?: string;
readonly ioTPlatformName?: (string) | null;
};
export type MeterReadingPacketInfoPageOutputPagedResultDto = {

View File

@ -20,6 +20,7 @@ import { useVbenVxeGrid } from '#/adapter/vxe-table';
import {
postAggregationDeviceCreateAsync,
postAggregationDeviceDeleteAsync,
postAggregationDeviceBatchCreateAsync,
postDeviceInfoCacheDeviceDataToRedis,
postDeviceInfoPage,
} from '#/api-client';
@ -30,6 +31,7 @@ import { $t } from '#/locales';
import {
addDeviceFormSchema,
batchAddDeviceFormSchema,
commandFormSchema,
editDeviceFormSchemaEdit,
querySchema,
@ -150,6 +152,31 @@ const [CommandForm, commandFormApi] = useVbenForm({
showDefaultActions: false,
});
const [BatchAddForm, batchAddFormApi] = useVbenForm({
//
collapsed: false,
//
commonConfig: {
labelWidth: 110,
componentProps: {
class: 'w-4/5',
},
},
layout: 'horizontal',
schema: batchAddDeviceFormSchema.value,
showCollapseButton: false,
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const [BatchAddModal, batchAddModalApi] = useVbenModal({
draggable: true,
onConfirm: submitBatchAdd,
onBeforeClose: () => {
return true;
},
});
//
async function submit() {
const isEdit = !!editRow.value.id;
@ -339,20 +366,94 @@ async function submitCommand() {
}
}
//
async function submitBatchAdd() {
const { valid } = await batchAddFormApi.validate();
if (!valid) return;
const formValues = await batchAddFormApi.getValues();
//
const addressList = formValues.addressList
.split('\n')
.map((address: string) => address.trim())
.filter((address: string) => address.length > 0);
if (addressList.length === 0) {
Message.error('请输入至少一个设备地址');
return;
}
//
const invalidAddresses = addressList.filter((address: string) => !address || address.length < 3);
if (invalidAddresses.length > 0) {
Message.error(`以下设备地址格式不正确: ${invalidAddresses.join(', ')}`);
return;
}
//
let ioTPlatformProductId = '';
if (formValues.ioTPlatform === 2 || formValues.ioTPlatform === '2') {
// OneNET
ioTPlatformProductId = formValues.oneNETProductId;
} else if (formValues.ioTPlatform === 1 || formValues.ioTPlatform === '1') {
// CTWing
ioTPlatformProductId = formValues.ctWingProductId;
}
if (!ioTPlatformProductId) {
Message.error('请选择产品');
return;
}
const batchCreateParams = {
addressList,
ioTPlatform: formValues.ioTPlatform,
ioTPlatformProductId,
};
try {
batchAddModalApi.setState({ loading: true, confirmLoading: true });
const resp = await postAggregationDeviceBatchCreateAsync({
body: batchCreateParams,
});
if (resp.data) {
Message.success(`批量添加设备成功,共添加 ${addressList.length} 个设备`);
batchAddModalApi.close();
batchAddFormApi.resetForm();
gridApi.reload();
} else {
Message.error('批量添加设备失败');
}
} catch (error) {
console.error('批量添加设备失败:', error);
Message.error('批量添加设备失败');
} finally {
batchAddModalApi.setState({ loading: false, confirmLoading: false });
}
}
//
const openBatchAddModal = () => {
batchAddFormApi.resetForm();
batchAddModalApi.open();
};
//
const handleCacheRefresh = async () => {
if (cacheRefreshLoading.value) return; //
cacheRefreshLoading.value = true;
pageLoading.value = true;
try {
await postDeviceInfoCacheDeviceDataToRedis({
body: {},
});
Message.success($t('common.operationSuccess'));
cacheRefreshLoading.value = true;
pageLoading.value = true;
const result = await postDeviceInfoCacheDeviceDataToRedis();
if (result.data) {
Message.success('缓存刷新成功');
gridApi.reload();
} else {
Message.error('缓存刷新失败');
}
} catch (error) {
console.error('缓存刷新失败:', error);
Message.error($t('common.operationFailed'));
Message.error('缓存刷新失败');
} finally {
cacheRefreshLoading.value = false;
pageLoading.value = false;
@ -368,11 +469,18 @@ const toolbarActions = computed(() => [
onClick: openAddModal.bind(null),
auth: ['AbpIdentity.Users.Create'],
},
{
label: '批量添加',
type: 'primary',
icon: 'ant-design:plus-outlined',
onClick: openBatchAddModal.bind(null),
auth: ['AbpIdentity.Users.Create'],
},
{
label: cacheRefreshLoading.value
? $t('common.loading')
: $t('abp.IoTDBBase.CacheRefresh'),
type: 'primary',
type: 'default',
icon: cacheRefreshLoading.value
? 'ant-design:loading-outlined'
: 'ant-design:reload-outlined',
@ -460,14 +568,8 @@ const toolbarActions = computed(() => [
style=" padding: 4px 8px;text-align: left">
{{ $t('abp.IoTDBBase.TelemetryLog') }}
</Button>
<Button type="text" size="small" @click="
() => {
Modal.confirm({
title: $t('common.askConfirmDelete'),
onOk: () => onDel(row),
});
}
" style=" padding: 4px 8px; color: #ff4d4f;text-align: left">
<Button type="text" size="small" @click="onDel.bind(null, row)()"
style=" padding: 4px 8px; color: #ff4d4f;text-align: left">
{{ $t('common.delete') }}
</Button>
</div>
@ -487,5 +589,8 @@ const toolbarActions = computed(() => [
<CommandModal :title="$t('abp.IoTDBBase.Command')" class="w-[600px]">
<CommandForm />
</CommandModal>
<BatchAddModal title="批量添加设备" class="w-[800px]">
<BatchAddForm />
</BatchAddModal>
</Page>
</template>

View File

@ -665,3 +665,292 @@ export const commandFormSchema: any = computed(() => [
}),
},
]);
export const batchAddDeviceFormSchema: 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;
}
// 如果是包装在 items 中的,提取出来
if (res && Array.isArray(res.items)) {
return res.items;
}
// 如果是包装在 data 中的,提取出来
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: 'oneNETAccountId',
label: $t('abp.deviceInfos.ioTPlatformAccountName'),
dependencies: {
show(values: any) {
return values.ioTPlatform === 2 || values.ioTPlatform === '2'; // OneNET平台
},
rules(values: any) {
if (values.ioTPlatform === 2 || values.ioTPlatform === '2') {
return 'required';
}
return null;
},
triggerFields: ['ioTPlatform'],
},
componentProps: {
api: postOneNetAccountListAsync,
params: {
body: {
pageIndex: 1,
pageSize: 1000,
},
},
labelField: 'accountName',
valueField: 'oneNETAccountId',
immediate: true,
afterFetch: (res: any) => {
// 如果是 Axios 响应对象,提取 data
if (res && res.data) {
const data = res.data;
// 确保返回的是数组格式
if (Array.isArray(data)) {
return data;
}
// 如果是包装在 items 中的,提取出来
if (data && Array.isArray(data.items)) {
return data.items;
}
// 如果是包装在 data 中的,提取出来
if (data && Array.isArray(data.data)) {
return data.data;
}
}
// 如果都不是,返回空数组
return [];
},
placeholder: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatformAccountName')}`,
},
rules: z.string().optional(),
},
{
component: 'ApiSelect',
fieldName: 'ctWingAccountId',
label: $t('abp.deviceInfos.ioTPlatformAccountName'),
dependencies: {
show(values: any) {
return values.ioTPlatform === 1 || values.ioTPlatform === '1'; // CTWing平台
},
rules(values: any) {
if (values.ioTPlatform === 1 || values.ioTPlatform === '1') {
return 'required';
}
return null;
},
triggerFields: ['ioTPlatform'], // 添加这一行,使其能够响应平台切换
},
componentProps: {
api: postCtWingAccountListAsync,
params: {
body: {
pageIndex: 1,
pageSize: 1000,
},
},
labelField: 'accountName',
valueField: 'accountId',
immediate: true,
afterFetch: (res: any) => {
// 如果是 Axios 响应对象,提取 data
if (res && res.data) {
const data = res.data;
// 确保返回的是数组格式
if (Array.isArray(data)) {
return data;
}
// 如果是包装在 items 中的,提取出来
if (data && Array.isArray(data.items)) {
return data.items;
}
// 如果是包装在 data 中的,提取出来
if (data && Array.isArray(data.data)) {
return data.data;
}
}
// 如果都不是,返回空数组
return [];
},
placeholder: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatformAccountName')}`,
},
rules: z.string().optional(),
},
{
component: 'ApiSelect',
fieldName: 'oneNETProductId',
label: $t('abp.deviceInfos.ioTPlatformProductName'),
dependencies: {
show(values: any) {
return (
(values.ioTPlatform === 2 || values.ioTPlatform === '2') &&
values.oneNETAccountId
); // OneNET平台且已选择账号
},
rules(values: any) {
if (
(values.ioTPlatform === 2 || values.ioTPlatform === '2') &&
values.oneNETAccountId
) {
return 'required';
}
return null;
},
triggerFields: ['ioTPlatform', 'oneNETAccountId'],
},
componentProps: {
api: postOneNetProductListAsync,
params: (formValues: any) => ({
body: {
pageIndex: 1,
pageSize: 1000,
oneNETAccountId: formValues.oneNETAccountId,
},
}),
labelField: 'productName',
valueField: 'ioTPlatformProductId',
immediate: true,
afterFetch: (res: any) => {
// 如果是 Axios 响应对象,提取 data
if (res && res.data) {
const data = res.data;
// 确保返回的是数组格式
let items = [];
if (Array.isArray(data)) {
items = data;
} else if (data && Array.isArray(data.items)) {
items = data.items;
} else if (data && Array.isArray(data.data)) {
items = data.data;
}
// 为每个产品项添加组合标签
return items.map((item: any) => ({
...item,
label: `${item.productName || ''} (${item.ioTPlatformProductId || ''})`,
}));
}
// 如果都不是,返回空数组
return [];
},
placeholder: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatformProductName')}`,
},
rules: z.string().optional(),
},
{
component: 'ApiSelect',
fieldName: 'ctWingProductId',
label: $t('abp.deviceInfos.ioTPlatformProductName'),
dependencies: {
show(values: any) {
return (
(values.ioTPlatform === 1 || values.ioTPlatform === '1') &&
values.ctWingAccountId
); // CTWing平台且已选择账号
},
rules(values: any) {
if (
(values.ioTPlatform === 1 || values.ioTPlatform === '1') &&
values.ctWingAccountId
) {
return 'required';
}
return null;
},
triggerFields: ['ioTPlatform', 'ctWingAccountId'],
},
componentProps: {
api: postCtWingProductListAsync,
params: (formValues: any) => ({
body: {
pageIndex: 1,
pageSize: 1000,
ctWingAccountId: formValues.ctWingAccountId,
},
}),
labelField: 'productName',
valueField: 'ioTPlatformProductId',
immediate: true,
afterFetch: (res: any) => {
// 如果是 Axios 响应对象,提取 data
if (res && res.data) {
const data = res.data;
// 确保返回的是数组格式
let items = [];
if (Array.isArray(data)) {
items = data;
} else if (data && Array.isArray(data.items)) {
items = data.items;
} else if (data && Array.isArray(data.data)) {
items = data.data;
}
// 为每个产品项添加组合标签并确保产品ID是字符串类型
return items.map((item: any) => ({
...item,
ioTPlatformProductId: String(item.ioTPlatformProductId || ''),
label: `${item.productName || ''} (${item.ioTPlatformProductId || ''})`,
}));
}
// 如果都不是,返回空数组
return [];
},
placeholder: `${$t('common.pleaseSelect')}${$t('abp.deviceInfos.ioTPlatformProductName')}`,
},
rules: z.string().optional(),
},
{
component: 'Textarea',
fieldName: 'addressList',
label: $t('abp.deviceInfos.deviceAddress'),
componentProps: {
rows: 8,
placeholder: $t('common.pleaseInput') + $t('abp.deviceInfos.deviceAddress') + ',每行一个设备地址',
showCount: true,
maxLength: 2000,
},
rules: z.string().min(1, {
message: `${$t('common.pleaseInput')}${$t('abp.deviceInfos.deviceAddress')}`,
}),
},
]);

View File

@ -67,7 +67,7 @@ const getDeviceInfoByAddress = (deviceAddress: string) => {
const formOptions: VbenFormProps = {
schema: querySchema.value,
initialValues: {
DeviceAddress: DeviceAddress as string,
deviceAddress: DeviceAddress as string,
},
// 使
submitOnChange: false,
@ -78,9 +78,9 @@ const formOptions: VbenFormProps = {
return;
}
// DeviceAddress selectedDeviceInfo
if (changedFields.includes('DeviceAddress')) {
const deviceAddress = values.DeviceAddress;
// deviceAddress selectedDeviceInfo
if (changedFields.includes('deviceAddress')) {
const deviceAddress = values.deviceAddress;
if (deviceAddress) {
// deviceOptions
@ -94,7 +94,7 @@ const formOptions: VbenFormProps = {
try {
// DeviceSelect
const deviceSelectRef =
gridApi.formApi.getFieldComponentRef('DeviceAddress');
gridApi.formApi.getFieldComponentRef('deviceAddress');
if (deviceSelectRef && deviceSelectRef.getSelectedDevice) {
device = deviceSelectRef.getSelectedDevice();
}
@ -110,7 +110,7 @@ const formOptions: VbenFormProps = {
setTimeout(() => {
try {
const deviceSelectRef =
gridApi.formApi.getFieldComponentRef('DeviceAddress');
gridApi.formApi.getFieldComponentRef('deviceAddress');
if (deviceSelectRef && deviceSelectRef.getSelectedDevice) {
const delayedDevice = deviceSelectRef.getSelectedDevice();
if (delayedDevice) {
@ -167,13 +167,13 @@ const gridOptions: VxeGridProps<any> = {
// API
const currentFormValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {};
// DeviceAddress使
if (!currentFormValues.DeviceAddress && DeviceAddress) {
currentFormValues.DeviceAddress = DeviceAddress as string;
// deviceAddress使
if (!currentFormValues.deviceAddress && DeviceAddress) {
currentFormValues.deviceAddress = DeviceAddress as string;
}
//
let deviceAddress = currentFormValues.DeviceAddress || '';
let deviceAddress = currentFormValues.deviceAddress || '';
// 使
const deviceInfo =
@ -190,9 +190,7 @@ const gridOptions: VxeGridProps<any> = {
const queryParams = {
pageIndex: page.currentPage,
pageSize: page.pageSize,
DeviceAddress: deviceAddress,
focusAddress: currentFormValues.focusAddress || '',
meterAddress: currentFormValues.meterAddress || '',
deviceAddress: deviceAddress,
};
const { data } = await postTableModelPacketInfoPage({
@ -222,10 +220,10 @@ const initializeGrid = async () => {
if (gridApi && gridApi.formApi) {
//
const currentValues = await gridApi.formApi.getValues();
if (!currentValues.DeviceAddress && DeviceAddress) {
if (!currentValues.deviceAddress && DeviceAddress) {
await gridApi.formApi.setValues({
...currentValues,
DeviceAddress: DeviceAddress as string,
deviceAddress: DeviceAddress as string,
});
}
//
@ -285,34 +283,10 @@ onMounted(async () => {
<template>
<Page auto-content-height>
<Grid>
<template #DeviceAddress="{ model, field }">
<template #deviceAddress="{ model, field }">
<DeviceSelect ref="deviceSelectRef" v-model:value="model[field]"
:placeholder="$t('common.pleaseSelect') + $t('abp.log.deviceInfo')" allow-clear />
</template>
<template #ismanualOrNot="{ row }">
<component :is="h(Tag, { color: row.manualOrNot ? 'green' : 'red' }, () =>
row.manualOrNot ? $t('common.yes') : $t('common.no'),
)
" />
</template>
<template #isTimeout="{ row }">
<component :is="h(Tag, { color: row.isTimeout ? 'green' : 'red' }, () =>
row.isTimeout ? $t('common.yes') : $t('common.no'),
)
" />
</template>
<template #isSend="{ row }">
<component :is="h(Tag, { color: row.isSend ? 'green' : 'red' }, () =>
row.isSend ? $t('common.yes') : $t('common.no'),
)
" />
</template>
<template #isReceived="{ row }">
<component :is="h(Tag, { color: row.isReceived ? 'green' : 'red' }, () =>
row.isReceived ? $t('common.yes') : $t('common.no'),
)
" />
</template>
</Grid>
</Page>
</template>

View File

@ -7,93 +7,80 @@ import { $t } from '#/locales';
export const querySchema = computed(() => [
{
component: 'DeviceSelect',
fieldName: 'DeviceAddress',
fieldName: 'deviceAddress',
label: $t('abp.log.deviceInfo'),
componentProps: {
placeholder: $t('common.pleaseSelect') + $t('abp.log.deviceInfo'),
allowClear: true,
},
},
{
component: 'Input',
fieldName: 'focusAddress',
label: $t('abp.focus.focusAddress'),
},
{
component: 'Input',
fieldName: 'meterAddress',
label: $t('abp.meters.meterAddress'),
},
]);
export const tableSchema: any = computed((): VxeGridProps['columns'] => [
{ title: $t('common.seq'), type: 'seq', width: 50 },
{
field: 'ioTDataType',
title: $t('abp.IoTDBBase.IoTDataType'),
minWidth: '120',
},
{
field: 'deviceType',
title: $t('abp.IoTDBBase.DeviceType'),
minWidth: '120',
},
{
field: 'deviceAddress',
title: $t('abp.focus.focusAddress'),
minWidth: '100',
title: $t('abp.IoTDBBase.DeviceAddress'),
minWidth: '120',
},
{
field: 'timestamps',
title: $t('abp.log.timestamps'),
minWidth: '100',
},
{
field: 'manualOrNot',
title: $t('abp.log.manualOrNot'),
minWidth: '150',
slots: { default: 'ismanualOrNot' },
},
{
field: 'isTimeout',
title: $t('abp.log.isTimeout'),
minWidth: '150',
slots: { default: 'isTimeout' },
},
{ field: 'afn', title: $t('abp.log.afn'), minWidth: '150' },
{ field: 'fn', title: $t('abp.log.fn'), minWidth: '100' },
{ field: 'pn', title: $t('abp.log.pn'), minWidth: '100' },
{ field: 'itemCode', title: $t('abp.log.itemCode'), minWidth: '100' },
{
field: 'isSend',
title: $t('abp.log.isSend'),
minWidth: '150',
slots: { default: 'isSend' },
},
{
field: 'sendNum',
title: $t('abp.log.sendNum'),
minWidth: '100',
},
{
field: 'nextSendTime',
title: $t('abp.log.nextSendTime'),
field: 'formattedTimestamps',
title: $t('abp.IoTDBBase.FormattedTimestamps'),
minWidth: '150',
},
{
field: 'issuedMessageHexString',
field: 'productId',
title: $t('abp.CTWingLog.ProductId'),
minWidth: '120',
},
{
field: 'platformDeviceId',
title: $t('abp.CTWingLog.PlatformDeviceId'),
minWidth: '150',
},
{
field: 'messageType',
title: $t('abp.CTWingLog.MessageType'),
minWidth: '120',
},
{
field: 'rawMessage',
title: $t('abp.CTWingLog.RawMessage'),
minWidth: '200',
},
{
field: 'issuePayload',
title: $t('abp.log.issuedMessageHexString'),
minWidth: '150',
minWidth: '200',
},
{
field: 'receivedMessageHexString',
field: 'responseRawMessage',
title: $t('abp.log.receivedMessageHexString'),
minWidth: '150',
minWidth: '200',
},
{
field: 'receivedTime',
title: $t('abp.log.receivedTime'),
minWidth: '150',
},
{
field: 'isReceived',
title: $t('abp.log.isReceived'),
minWidth: '150',
slots: { default: 'isReceived' },
},
{
field: 'receivedRemark',
field: 'responseResult',
title: $t('abp.log.receivedRemark'),
minWidth: '150',
},
{
field: 'telemetrySourceName',
title: $t('abp.log.manualOrNot'),
minWidth: '120',
},
{
field: 'ioTPlatformName',
title: $t('abp.deviceInfos.ioTPlatformName'),
minWidth: '120',
},
]);