设备遥测日志展示

This commit is contained in:
ChenYi 2025-08-05 17:33:47 +08:00
parent 7cf5167728
commit 57459751dc
10 changed files with 231 additions and 527 deletions

View File

@ -1717,6 +1717,24 @@ export const DeleteTextTemplateInputSchema = {
description: '删除模板' description: '删除模板'
} as const; } as const;
export const DeviceCommandForApiInputSchema = {
required: ['commandContent'],
type: 'object',
properties: {
id: {
type: 'string',
format: 'uuid'
},
commandContent: {
minLength: 1,
type: 'string',
description: '设备在物联网平台中发送的命令内容JSON格式'
}
},
additionalProperties: false,
description: '设备命令'
} as const;
export const DeviceManagementInfoDtoSchema = { export const DeviceManagementInfoDtoSchema = {
type: 'object', type: 'object',
properties: { properties: {
@ -4258,196 +4276,6 @@ export const MessageTypeSchema = {
'说明:': '广播消息=10,普通文本消息=20' '说明:': '广播消息=10,普通文本消息=20'
} as const; } as const;
export const MeterReadingPacketInfoDtoSchema = {
type: 'object',
properties: {
dataBaseName: {
type: 'string',
description: '数据库名称,用于构建存储路径,来自系统配置',
nullable: true
},
ioTDataType: {
type: 'string',
description: `数据类型,用于构建存储路径
JiShe.ServicePro.Consts.IoTDBDataTypeConst`,
nullable: true
},
deviceType: {
type: 'string',
description: `设备类型集中器、电表、水表、流量计、传感器等,用于构建存储路径
JiShe.ServicePro.Enums.DeviceTypeEnum`,
nullable: true
},
deviceAddress: {
type: 'string',
description: '设备地址,数据生成者,例如集中器地址,电表地址、水表地址、流量计地址、传感器地址等',
nullable: true
},
timestamps: {
type: 'integer',
description: '时标,也就是业务时间戳,单位毫秒,必须通过DateTimeOffset获取',
format: 'int64'
},
formattedTimestamps: {
type: 'string',
description: '时标格式化以后的本地时间',
format: 'date-time',
readOnly: true
},
devicePath: {
type: 'string',
description: '设备路径,树模型使用,表模型会在数据插入的时候直接获取继承类的名称作为表明',
nullable: true
},
scoreValue: {
type: 'string',
description: '排序索引分数值,具体值可以根据不同业务场景进行定义,例如时间戳、或者某一个固定的标识',
nullable: true
},
packetType: {
type: 'integer',
description: '数据包类型',
format: 'int32'
},
manualOrNot: {
type: 'boolean',
description: '是否手动操作'
},
taskMark: {
type: 'string',
description: '任务数据唯一标记',
nullable: true
},
isTimeout: {
type: 'boolean',
description: '是否超时'
},
pendingCopyReadTime: {
type: 'string',
description: '待抄读时间',
format: 'date-time'
},
focusId: {
type: 'integer',
description: '集中器Id',
format: 'int32'
},
focusAddress: {
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: '是否已上报'
}
},
additionalProperties: false,
description: '抄读任务数据 Dto'
} as const;
export const MeterReadingPacketInfoPageInputSchema = { export const MeterReadingPacketInfoPageInputSchema = {
type: 'object', type: 'object',
properties: { properties: {
@ -4500,9 +4328,9 @@ export const MeterReadingPacketInfoPageInputSchema = {
format: 'date-time', format: 'date-time',
nullable: true nullable: true
}, },
meterAddress: { ioTPlatformDeviceOpenInfo: {
type: 'string', type: 'string',
description: '表地址', description: '物联网平台设备ID',
nullable: true nullable: true
} }
}, },
@ -4551,22 +4379,37 @@ JiShe.ServicePro.Enums.DeviceTypeEnum`,
description: '设备路径,树模型使用,表模型会在数据插入的时候直接获取继承类的名称作为表明', description: '设备路径,树模型使用,表模型会在数据插入的时候直接获取继承类的名称作为表明',
nullable: true nullable: true
}, },
productId: { ioTPlatformProductId: {
type: 'string', type: 'string',
description: '物联网平台产品Id', description: '物联网平台产品Id',
nullable: true nullable: true
}, },
platformDeviceId: { ioTPlatformDeviceOpenInfo: {
type: 'string', type: 'string',
description: '物联网平台设备ID', description: '物联网平台设备ID',
nullable: true nullable: true
}, },
ioTPlatformProductName: {
type: 'string',
description: '物联网平台中对应的产品Name',
nullable: true
},
ioTPlatformAccountId: {
type: 'string',
description: '物联网平台中对应的账号Id',
nullable: true
},
accountPhoneNumber: {
type: 'string',
description: '账户手机号',
nullable: true
},
messageType: { messageType: {
type: 'string', type: 'string',
description: '消息类型', description: '消息类型',
nullable: true nullable: true
}, },
rawMessage: { issueRawMessage: {
type: 'string', type: 'string',
description: '下发消息体原始内容', description: '下发消息体原始内容',
nullable: true nullable: true
@ -4581,7 +4424,7 @@ JiShe.ServicePro.Enums.DeviceTypeEnum`,
description: '下发结果原始内容', description: '下发结果原始内容',
nullable: true nullable: true
}, },
responseResult: { responsePayload: {
type: 'string', type: 'string',
description: '下发结果', description: '下发结果',
nullable: true nullable: true
@ -7645,7 +7488,7 @@ export const QueryCTWingAepReceiveMessageInputSchema = {
format: 'date-time', format: 'date-time',
nullable: true nullable: true
}, },
platformDeviceId: { ioTPlatformDeviceOpenInfo: {
type: 'string', type: 'string',
description: '物联网平台设备ID', description: '物联网平台设备ID',
nullable: true nullable: true
@ -7711,7 +7554,7 @@ JiShe.ServicePro.Enums.DeviceTypeEnum`,
description: '物联网平台服务Id', description: '物联网平台服务Id',
nullable: true nullable: true
}, },
platformDeviceId: { ioTPlatformDeviceOpenInfo: {
type: 'string', type: 'string',
description: '物联网平台设备ID', description: '物联网平台设备ID',
nullable: true nullable: true
@ -7836,7 +7679,7 @@ export const QueryOneNETReceiveMessageInputSchema = {
format: 'date-time', format: 'date-time',
nullable: true nullable: true
}, },
platformDeviceId: { ioTPlatformDeviceOpenInfo: {
type: 'string', type: 'string',
description: '物联网平台设备ID', description: '物联网平台设备ID',
nullable: true nullable: true
@ -7892,7 +7735,7 @@ JiShe.ServicePro.Enums.DeviceTypeEnum`,
description: '物联网平台产品Id', description: '物联网平台产品Id',
nullable: true nullable: true
}, },
platformDeviceId: { ioTPlatformDeviceOpenInfo: {
type: 'string', type: 'string',
description: '物联网平台设备ID', description: '物联网平台设备ID',
nullable: true nullable: true
@ -8141,11 +7984,11 @@ export const ResetTwoFactorInputSchema = {
} as const; } as const;
export const ResponeResultEnumSchema = { export const ResponeResultEnumSchema = {
enum: [0, 1, 2, 3, 4, 5, 6, 200, 201, 400, 401, 403, 404, 500, 503, 504, -102, -101], enum: [0, 1, 2, 3, 4, 5, 6, 200, 201, 400, 401, 403, 404, 500, 503, 504, 10421, -102, -101],
type: 'integer', type: 'integer',
description: '响应结果枚举', description: '响应结果枚举',
format: 'int32', format: 'int32',
'说明:': 'Success=0,Fail=1,LoginOut=2,TimeOut=3,Exception=4,NotAllowed=5,NotLoggedIn=6,OK=200,NoData=201,BadRequest=400,Unauthorized=401,Forbidden=403,NotFound=404,AepInternalError=500,ServiceUnavailable=503,AsyncService=504,HandlerException=-102,HandlerFail=-101' '说明:': 'Success=0,Fail=1,LoginOut=2,TimeOut=3,Exception=4,NotAllowed=5,NotLoggedIn=6,OK=200,NoData=201,BadRequest=400,Unauthorized=401,Forbidden=403,NotFound=404,AepInternalError=500,ServiceUnavailable=503,AsyncService=504,DeviceNotOnline=10421,HandlerException=-102,HandlerFail=-101'
} as const; } as const;
export const ReturnValueApiDescriptionModelSchema = { export const ReturnValueApiDescriptionModelSchema = {

File diff suppressed because one or more lines are too long

View File

@ -891,6 +891,17 @@ export type DeleteTextTemplateInput = {
id?: string; id?: string;
}; };
/**
*
*/
export type DeviceCommandForApiInput = {
id?: string;
/**
* JSON格式
*/
commandContent: string;
};
export type DeviceManagementInfoDto = { export type DeviceManagementInfoDto = {
id?: string; id?: string;
creationTime?: string; creationTime?: string;
@ -1954,158 +1965,6 @@ export type MessageLevel = 10 | 20 | 30;
*/ */
export type MessageType = 10 | 20; export type MessageType = 10 | 20;
/**
* Dto
*/
export type MeterReadingPacketInfoDto = {
/**
* ,
*/
dataBaseName?: (string) | null;
/**
*
* JiShe.ServicePro.Consts.IoTDBDataTypeConst
*/
ioTDataType?: (string) | null;
/**
* ,
* JiShe.ServicePro.Enums.DeviceTypeEnum
*/
deviceType?: (string) | null;
/**
* ,,
*/
deviceAddress?: (string) | null;
/**
* ,DateTimeOffset获取
*/
timestamps?: number;
/**
*
*/
readonly formattedTimestamps?: string;
/**
* ,使
*/
devicePath?: (string) | null;
/**
*
*/
scoreValue?: (string) | null;
/**
*
*/
packetType?: number;
/**
*
*/
manualOrNot?: boolean;
/**
*
*/
taskMark?: (string) | null;
/**
*
*/
isTimeout?: boolean;
/**
*
*/
pendingCopyReadTime?: string;
/**
* Id
*/
focusId?: number;
/**
*
*/
focusAddress?: (string) | null;
/**
*
*/
meterAddress?: (string) | null;
/**
* ID
*/
databaseBusiID?: 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;
};
/** /**
* *
*/ */
@ -2147,9 +2006,9 @@ export type MeterReadingPacketInfoPageInput = {
*/ */
endCreationTime?: (string) | null; endCreationTime?: (string) | null;
/** /**
* * ID
*/ */
meterAddress?: (string) | null; ioTPlatformDeviceOpenInfo?: (string) | null;
}; };
/** /**
@ -2189,11 +2048,23 @@ export type MeterReadingPacketInfoPageOutput = {
/** /**
* Id * Id
*/ */
productId?: (string) | null; ioTPlatformProductId?: (string) | null;
/** /**
* ID * ID
*/ */
platformDeviceId?: (string) | null; ioTPlatformDeviceOpenInfo?: (string) | null;
/**
* Name
*/
ioTPlatformProductName?: (string) | null;
/**
* Id
*/
ioTPlatformAccountId?: (string) | null;
/**
*
*/
accountPhoneNumber?: (string) | null;
/** /**
* *
*/ */
@ -2201,7 +2072,7 @@ export type MeterReadingPacketInfoPageOutput = {
/** /**
* *
*/ */
rawMessage?: (string) | null; issueRawMessage?: (string) | null;
/** /**
* *
*/ */
@ -2213,7 +2084,7 @@ export type MeterReadingPacketInfoPageOutput = {
/** /**
* *
*/ */
responseResult?: (string) | null; responsePayload?: (string) | null;
/** /**
* *
*/ */
@ -3921,7 +3792,7 @@ export type QueryCTWingAepReceiveMessageInput = {
/** /**
* ID * ID
*/ */
platformDeviceId?: (string) | null; ioTPlatformDeviceOpenInfo?: (string) | null;
}; };
/** /**
@ -3973,7 +3844,7 @@ export type QueryCTWingAepReceiveMessageOutput = {
/** /**
* ID * ID
*/ */
platformDeviceId?: (string) | null; ioTPlatformDeviceOpenInfo?: (string) | null;
/** /**
* *
*/ */
@ -4060,7 +3931,7 @@ export type QueryOneNETReceiveMessageInput = {
/** /**
* ID * ID
*/ */
platformDeviceId?: (string) | null; ioTPlatformDeviceOpenInfo?: (string) | null;
}; };
/** /**
@ -4104,7 +3975,7 @@ export type QueryOneNETReceiveMessageOutput = {
/** /**
* ID * ID
*/ */
platformDeviceId?: (string) | null; ioTPlatformDeviceOpenInfo?: (string) | null;
/** /**
* *
*/ */
@ -4207,7 +4078,7 @@ export type ResetTwoFactorInput = {
/** /**
* *
*/ */
export type ResponeResultEnum = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 200 | 201 | 400 | 401 | 403 | 404 | 500 | 503 | 504 | -102 | -101; export type ResponeResultEnum = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 200 | 201 | 400 | 401 | 403 | 404 | 500 | 503 | 504 | 10421 | -102 | -101;
export type ReturnValueApiDescriptionModel = { export type ReturnValueApiDescriptionModel = {
type?: (string) | null; type?: (string) | null;
@ -4965,6 +4836,16 @@ export type PostAggregationDeviceRepushDeviceInfoToIoTplatformResponse = (Device
export type PostAggregationDeviceRepushDeviceInfoToIoTplatformError = unknown; export type PostAggregationDeviceRepushDeviceInfoToIoTplatformError = unknown;
export type PostAggregationDeviceDeviceCommandForApiAsyncData = {
query?: {
input?: DeviceCommandForApiInput;
};
};
export type PostAggregationDeviceDeviceCommandForApiAsyncResponse = (boolean);
export type PostAggregationDeviceDeviceCommandForApiAsyncError = unknown;
export type PostDeviceInfoFindByDeviceAddressData = { export type PostDeviceInfoFindByDeviceAddressData = {
query?: { query?: {
deviceAddress?: string; deviceAddress?: string;
@ -5594,26 +5475,6 @@ export type PostTableModelPacketInfoPageResponse = (MeterReadingPacketInfoPageOu
export type PostTableModelPacketInfoPageError = unknown; export type PostTableModelPacketInfoPageError = unknown;
export type PostTableModelPacketInfoInsertData = {
query?: {
input?: MeterReadingPacketInfoDto;
};
};
export type PostTableModelPacketInfoInsertResponse = (unknown);
export type PostTableModelPacketInfoInsertError = unknown;
export type PostTableModelPacketInfoBatchInsertData = {
query?: {
input?: Array<MeterReadingPacketInfoDto>;
};
};
export type PostTableModelPacketInfoBatchInsertResponse = (unknown);
export type PostTableModelPacketInfoBatchInsertError = unknown;
export type PostTableModelDeviceDataInfoPageData = { export type PostTableModelDeviceDataInfoPageData = {
body?: DeviceTableModelDataInfoPageInput; body?: DeviceTableModelDataInfoPageInput;
}; };

View File

@ -311,5 +311,12 @@
"CreationTime": "CreationTime", "CreationTime": "CreationTime",
"LastModificationTime": "LastModificationTime", "LastModificationTime": "LastModificationTime",
"CannotDeleteAccountWithProducts": "Cannot delete account with products" "CannotDeleteAccountWithProducts": "Cannot delete account with products"
},
"telemetryLog": {
"IssueRawMessage": "IssueRawMessage",
"IssuePayload": "IssuePayload",
"ResponseRawMessage": "ResponseRawMessage",
"ResponsePayload": "ResponsePayload",
"TelemetrySourceName": "TelemetrySourceName"
} }
} }

View File

@ -84,7 +84,6 @@
"deviceInfo": "设备信息", "deviceInfo": "设备信息",
"deviceId": "设备ID", "deviceId": "设备ID",
"timestamps": "时标", "timestamps": "时标",
"manualOrNot": "是否手动操作",
"isTimeout": "是否超时", "isTimeout": "是否超时",
"afn": "AFN功能码", "afn": "AFN功能码",
"fn": "抄读功能码", "fn": "抄读功能码",
@ -92,12 +91,6 @@
"itemCode": "采集项编码", "itemCode": "采集项编码",
"isSend": "是否发送", "isSend": "是否发送",
"sendNum": "发送次数", "sendNum": "发送次数",
"nextSendTime": "下次发送时间",
"issuedMessageHexString": "下发消息内容",
"receivedMessageHexString": "消息上报内容",
"receivedTime": "消息上报时间",
"isReceived": "是否已上报",
"receivedRemark": "上报报文解析备注",
"title": "日志" "title": "日志"
}, },
"message": { "message": {
@ -313,5 +306,12 @@
"CreationTime": "创建时间", "CreationTime": "创建时间",
"LastModificationTime": "更新时间", "LastModificationTime": "更新时间",
"CannotDeleteAccountWithProducts": "该账号下存在产品,无法删除" "CannotDeleteAccountWithProducts": "该账号下存在产品,无法删除"
},
"telemetryLog": {
"IssueRawMessage": "下发消息体原始内容",
"IssuePayload": "下发消息体",
"ResponseRawMessage": "下发结果原始内容",
"ResponsePayload": "下发结果",
"TelemetrySourceName": "遥测指令来源"
} }
} }

View File

@ -21,6 +21,7 @@ import {
postAggregationDeviceBatchCreateAsync, postAggregationDeviceBatchCreateAsync,
postAggregationDeviceCreateAsync, postAggregationDeviceCreateAsync,
postAggregationDeviceDeleteAsync, postAggregationDeviceDeleteAsync,
postAggregationDeviceDeviceCommandForApiAsync,
postAggregationDeviceRepushDeviceInfoToIoTplatform, postAggregationDeviceRepushDeviceInfoToIoTplatform,
postDeviceInfoCacheDeviceDataToRedis, postDeviceInfoCacheDeviceDataToRedis,
postDeviceInfoPage, postDeviceInfoPage,
@ -366,7 +367,7 @@ const repushDeviceInfo = async (row: Record<string, any>) => {
} else { } else {
Message.error('重推设备信息失败'); Message.error('重推设备信息失败');
} }
} catch (error) { } catch {
Message.error('重推设备信息失败'); Message.error('重推设备信息失败');
} finally { } finally {
pageLoading.value = false; pageLoading.value = false;
@ -393,16 +394,24 @@ async function submitCommand() {
try { try {
commandModalApi.setState({ loading: true, confirmLoading: true }); commandModalApi.setState({ loading: true, confirmLoading: true });
// TODO: //
console.log('指令内容:', formValues.command); const result = await postAggregationDeviceDeviceCommandForApiAsync({
console.log('设备信息:', commandRow.value); body: {
Id: commandRow.value.id,
CommandContent: formValues.CommandContent,
},
});
Message.success($t('common.operationSuccess')); if (result.data) {
Message.success('指令下发成功');
commandModalApi.close(); commandModalApi.close();
commandRow.value = {}; commandRow.value = {};
} else {
Message.error('指令下发失败');
}
} catch (error) { } catch (error) {
console.error('指令发送失败:', error); console.error('指令发送失败:', error);
Message.error($t('common.operationFailed')); Message.error('指令下发失败');
} finally { } finally {
commandModalApi.setState({ loading: false, confirmLoading: false }); commandModalApi.setState({ loading: false, confirmLoading: false });
} }
@ -530,7 +539,9 @@ watch(
addressLines.value = 0; addressLines.value = 0;
return; return;
} }
const lines = addressList.split('\n').filter((line: string) => line.trim()); const lines = addressList
.split('\n')
.filter((line: string) => line.trim());
addressLines.value = lines.length; addressLines.value = lines.length;
console.log('备用方案更新行数:', addressLines.value); console.log('备用方案更新行数:', addressLines.value);
} catch { } catch {
@ -564,14 +575,16 @@ const startLineCheck = () => {
const rawValues = batchAddFormApi.getValues(); const rawValues = batchAddFormApi.getValues();
console.log('原始表单值:', rawValues); console.log('原始表单值:', rawValues);
addressList = rawValues?.addressList || ''; addressList = rawValues?.addressList || '';
} catch (e) { } catch (error) {
console.log('方式2失败:', e); console.log('方式2失败:', error);
} }
} }
// 3DOM // 3DOM
if (!addressList) { if (!addressList) {
const textarea = document.querySelector('textarea[name="addressList"]') as HTMLTextAreaElement; const textarea = document.querySelector(
'textarea[name="addressList"]',
) as HTMLTextAreaElement;
if (textarea) { if (textarea) {
addressList = textarea.value; addressList = textarea.value;
console.log('从DOM获取的地址列表:', addressList); console.log('从DOM获取的地址列表:', addressList);
@ -581,9 +594,16 @@ const startLineCheck = () => {
console.log('获取到的地址列表:', addressList); console.log('获取到的地址列表:', addressList);
if (addressList && typeof addressList === 'string') { if (addressList && typeof addressList === 'string') {
const lines = addressList.split('\n').filter((line: string) => line.trim()); const lines = addressList
.split('\n')
.filter((line: string) => line.trim());
const newLineCount = lines.length; const newLineCount = lines.length;
console.log('计算出的行数:', newLineCount, '当前行数:', addressLines.value); console.log(
'计算出的行数:',
newLineCount,
'当前行数:',
addressLines.value,
);
if (newLineCount !== addressLines.value) { if (newLineCount !== addressLines.value) {
console.log('定时器更新行数:', newLineCount); console.log('定时器更新行数:', newLineCount);
addressLines.value = newLineCount; addressLines.value = newLineCount;
@ -768,19 +788,18 @@ const toolbarActions = computed(() => [
<div class="text-sm text-gray-500"> <div class="text-sm text-gray-500">
<span v-if="addressLines > 0"> <span v-if="addressLines > 0">
{{ addressLines }} 行设备地址 {{ addressLines }} 行设备地址
<span v-if="isOverLineLimit" style="color: #ff4d4f;"> <span v-if="isOverLineLimit" style="color: #ff4d4f">
(超过100行限制) (超过100行限制)
</span> </span>
</span> </span>
<span v-else> <span v-else> 当前行数: {{ addressLines }} (调试信息) </span>
当前行数: {{ addressLines }} (调试信息)
</span>
</div> </div>
<div class="flex gap-2"> <div class="flex gap-2">
<Button @click="batchAddModalApi.close()"> <Button @click="batchAddModalApi.close()">
{{ $t('common.cancel') }} {{ $t('common.cancel') }}
</Button> </Button>
<Button type="primary" :loading="batchAddModalState?.confirmLoading" @click="submitBatchAdd" :disabled="isOverLineLimit"> <Button type="primary" :loading="batchAddModalState?.confirmLoading" @click="submitBatchAdd"
:disabled="isOverLineLimit">
{{ $t('common.confirm') }} {{ $t('common.confirm') }}
</Button> </Button>
</div> </div>

View File

@ -4,6 +4,8 @@ import { computed } from 'vue';
import { z } from '@vben/common-ui'; import { z } from '@vben/common-ui';
import dayjs from 'dayjs';
import { import {
getCommonGetSelectList, getCommonGetSelectList,
postCtWingAccountListAsync, postCtWingAccountListAsync,
@ -63,11 +65,17 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
field: 'lastOnlineTime', field: 'lastOnlineTime',
title: $t('abp.deviceInfos.LastOnlineTime'), title: $t('abp.deviceInfos.LastOnlineTime'),
minWidth: '150', minWidth: '150',
formatter: ({ cellValue }) => {
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
},
}, },
{ {
field: 'lastOfflineTime', field: 'lastOfflineTime',
title: $t('abp.deviceInfos.LastOfflineTime'), title: $t('abp.deviceInfos.LastOfflineTime'),
minWidth: '150', minWidth: '150',
formatter: ({ cellValue }) => {
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
},
}, },
{ {
field: 'platformPassword', field: 'platformPassword',
@ -652,7 +660,7 @@ export const editDeviceFormSchemaEdit: any = computed(() => [
export const commandFormSchema: any = computed(() => [ export const commandFormSchema: any = computed(() => [
{ {
component: 'Textarea', component: 'Textarea',
fieldName: 'command', fieldName: 'CommandContent',
label: $t('abp.IoTDBBase.Command'), label: $t('abp.IoTDBBase.Command'),
componentProps: { componentProps: {
rows: 8, rows: 8,
@ -673,9 +681,11 @@ export const batchAddDeviceFormSchema: any = computed(() => [
label: $t('abp.deviceInfos.deviceAddress'), label: $t('abp.deviceInfos.deviceAddress'),
componentProps: { componentProps: {
rows: 4, rows: 4,
placeholder: $t('common.pleaseInput') + $t('abp.deviceInfos.deviceAddress') + ',每行一个设备地址', placeholder: `${
$t('common.pleaseInput') + $t('abp.deviceInfos.deviceAddress')
}`,
showCount: false, showCount: false,
maxLength: 10000, maxLength: 10_000,
style: { style: {
resize: 'vertical', resize: 'vertical',
minHeight: '32px', minHeight: '32px',

View File

@ -287,6 +287,18 @@ onMounted(async () => {
<DeviceSelect ref="deviceSelectRef" v-model:value="model[field]" <DeviceSelect ref="deviceSelectRef" v-model:value="model[field]"
:placeholder="$t('common.pleaseSelect') + $t('abp.log.deviceInfo')" allow-clear /> :placeholder="$t('common.pleaseSelect') + $t('abp.log.deviceInfo')" allow-clear />
</template> </template>
<template #ioTPlatformName="{ row }">
<span :style="{
color:
row.ioTPlatform === 2 || row.ioTPlatform === '2'
? '#0B34BE'
: '#048CD1',
fontWeight: 'bold',
}">
{{ row.ioTPlatformName }}
</span>
</template>
</Grid> </Grid>
</Page> </Page>
</template> </template>

View File

@ -1,3 +1,9 @@
/*
* @Description:
* @Author:
* @Date: 2025-06-25 17:07:53
* @LastEditors:
*/
import type { VxeGridProps } from '#/adapter/vxe-table'; import type { VxeGridProps } from '#/adapter/vxe-table';
import { computed } from 'vue'; import { computed } from 'vue';
@ -18,6 +24,32 @@ export const querySchema = computed(() => [
export const tableSchema: any = computed((): VxeGridProps['columns'] => [ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
{ title: $t('common.seq'), type: 'seq', width: 50 }, { title: $t('common.seq'), type: 'seq', width: 50 },
{
field: 'formattedTimestamps',
title: $t('abp.IoTDBBase.FormattedTimestamps'),
minWidth: '150',
},
{
field: 'ioTPlatformName',
title: $t('common.BelongingIoTPlatform'),
minWidth: '120',
slots: { default: 'ioTPlatformName' },
},
{
field: 'accountPhoneNumber',
title: $t('common.BelongingAccountName'),
minWidth: '120',
},
{
field: 'ioTPlatformProductName',
title: $t('common.BelongingProductName'),
minWidth: '120',
},
{
field: 'ioTPlatformDeviceOpenInfo',
title: $t('abp.deviceInfos.ioTPlatformDeviceOpenInfo'),
minWidth: '150',
},
{ {
field: 'ioTDataType', field: 'ioTDataType',
title: $t('abp.IoTDBBase.IoTDataType'), title: $t('abp.IoTDBBase.IoTDataType'),
@ -33,54 +65,34 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
title: $t('abp.IoTDBBase.DeviceAddress'), title: $t('abp.IoTDBBase.DeviceAddress'),
minWidth: '120', minWidth: '120',
}, },
{
field: 'formattedTimestamps',
title: $t('abp.IoTDBBase.FormattedTimestamps'),
minWidth: '150',
},
{
field: 'productId',
title: $t('abp.CTWingLog.ProductId'),
minWidth: '120',
},
{
field: 'platformDeviceId',
title: $t('abp.CTWingLog.PlatformDeviceId'),
minWidth: '150',
},
{ {
field: 'messageType', field: 'messageType',
title: $t('abp.CTWingLog.MessageType'), title: $t('abp.CTWingLog.MessageType'),
minWidth: '120', minWidth: '120',
}, },
{ {
field: 'rawMessage', field: 'issueRawMessage',
title: $t('abp.CTWingLog.RawMessage'), title: $t('abp.telemetryLog.IssueRawMessage'),
minWidth: '200', minWidth: '200',
}, },
{ {
field: 'issuePayload', field: 'issuePayload',
title: $t('abp.log.issuedMessageHexString'), title: $t('abp.telemetryLog.IssuePayload'),
minWidth: '200', minWidth: '200',
}, },
{ {
field: 'responseRawMessage', field: 'responseRawMessage',
title: $t('abp.log.receivedMessageHexString'), title: $t('abp.telemetryLog.ResponseRawMessage'),
minWidth: '200', minWidth: '200',
}, },
{ {
field: 'responseResult', field: 'responsePayload',
title: $t('abp.log.receivedRemark'), title: $t('abp.telemetryLog.ResponsePayload'),
minWidth: '150', minWidth: '150',
}, },
{ {
field: 'telemetrySourceName', field: 'telemetrySourceName',
title: $t('abp.log.manualOrNot'), title: $t('abp.telemetryLog.TelemetrySourceName'),
minWidth: '120',
},
{
field: 'ioTPlatformName',
title: $t('abp.deviceInfos.ioTPlatformName'),
minWidth: '120', minWidth: '120',
}, },
]); ]);

View File

@ -4,6 +4,8 @@ import { computed, h } from 'vue';
import { z } from '@vben/common-ui'; import { z } from '@vben/common-ui';
import dayjs from 'dayjs';
import { postOneNetAccountListAsync } from '#/api-client'; import { postOneNetAccountListAsync } from '#/api-client';
import { $t } from '#/locales'; import { $t } from '#/locales';
@ -57,84 +59,32 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
field: 'productCreateTime', field: 'productCreateTime',
title: $t('abp.OneNETManagement.IoTPlatformProductCreateTime'), title: $t('abp.OneNETManagement.IoTPlatformProductCreateTime'),
minWidth: '150', minWidth: '150',
formatter: ({ cellValue }: any) => { formatter: ({ cellValue }) => {
if (!cellValue) return '-'; return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
const date = new Date(cellValue);
if (isNaN(date.getTime())) return '-';
return date
.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replaceAll('/', '-');
}, },
}, },
{ {
field: 'productUpdateTime', field: 'productUpdateTime',
title: $t('abp.OneNETManagement.IoTPlatformProductUpdateTime'), title: $t('abp.OneNETManagement.IoTPlatformProductUpdateTime'),
minWidth: '150', minWidth: '150',
formatter: ({ cellValue }: any) => { formatter: ({ cellValue }) => {
if (!cellValue) return '-'; return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
const date = new Date(cellValue);
if (isNaN(date.getTime())) return '-';
return date
.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replaceAll('/', '-');
}, },
}, },
{ {
field: 'creationTime', field: 'creationTime',
title: $t('abp.OneNETManagement.CreationTime'), title: $t('abp.OneNETManagement.CreationTime'),
minWidth: '150', minWidth: '150',
formatter: ({ cellValue }: any) => { formatter: ({ cellValue }) => {
if (!cellValue) return '-'; return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
const date = new Date(cellValue);
if (isNaN(date.getTime())) return '-';
return date
.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replaceAll('/', '-');
}, },
}, },
{ {
field: 'lastModificationTime', field: 'lastModificationTime',
title: $t('abp.OneNETManagement.LastModificationTime'), title: $t('abp.OneNETManagement.LastModificationTime'),
minWidth: '150', minWidth: '150',
formatter: ({ cellValue }: any) => { formatter: ({ cellValue }) => {
if (!cellValue) return '-'; return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
const date = new Date(cellValue);
if (isNaN(date.getTime())) return '-';
return date
.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false,
})
.replaceAll('/', '-');
}, },
}, },
{ {