数据推送配置

This commit is contained in:
ChenYi 2026-03-11 11:47:29 +08:00
parent 59ab5facd5
commit 3b73411d09
7 changed files with 490 additions and 63 deletions

View File

@ -1917,6 +1917,14 @@ export const DataEncryptionEnumSchema = {
'说明:': 'sm1=1,sm2=2,sm4=3,dtls=4,明文只支持MQTT/LWM2M=5,量子加密=6'
} as const;
export const DataPushTypeEnumSchema = {
enum: [1, 2, 3],
type: 'integer',
description: '数据推送类型枚举',
format: 'int32',
'说明:': 'HttpPost推送=1,Redis订阅推送=2,Redis列表推送=3'
} as const;
export const DateTimeFormatDtoSchema = {
type: 'object',
properties: {
@ -2260,6 +2268,62 @@ export const DeviceFirmwareInfoDtoPagedResultDtoSchema = {
additionalProperties: false
} as const;
export const DeviceLoginModelSchema = {
required: ['clientid', 'password', 'username'],
type: 'object',
properties: {
clientid: {
minLength: 1,
type: 'string',
description: '设备端客户端Id也就是OneNET平台的设备名称'
},
deviceAddress: {
type: 'string',
description: '原始的设备地址',
nullable: true,
readOnly: true
},
username: {
minLength: 1,
type: 'string',
description: '登录用户名也就是OneNET平台的产品名称'
},
password: {
minLength: 1,
type: 'string',
description: '登录密码也就是OneNET平台的签名Token'
}
},
additionalProperties: false,
description: '设备登录'
} as const;
export const DeviceLoginResultSchema = {
type: 'object',
properties: {
result: {
type: 'string',
description: '鉴权结果 JiShe.ServicePro.Core.DeviceEMQXLoginResultConsts',
nullable: true
},
is_superuser: {
type: 'boolean',
description: '是否超级用户'
},
client_attrs: {
type: 'object',
additionalProperties: {
type: 'string',
nullable: true
},
description: '设备属性(键值均为字符串)',
nullable: true
}
},
additionalProperties: false,
description: '设备登录结果'
} as const;
export const DeviceManagementInfoDtoSchema = {
type: 'object',
properties: {
@ -7086,6 +7150,31 @@ export const OneNETAccountInfoDtoPagedResultDtoSchema = {
additionalProperties: false
} as const;
export const OneNETDataFlowConfigInputSchema = {
type: 'object',
properties: {
id: {
type: 'string',
description: '产品数据ID',
format: 'uuid'
},
isNeedPushData: {
type: 'boolean',
description: '是否需要推送数据'
},
dataPushType: {
'$ref': '#/components/schemas/DataPushTypeEnum'
},
dataPushInfo: {
type: 'string',
description: '数据推送信息,HTTP推送就是推送地址Reist推送主题或者key',
nullable: true
}
},
additionalProperties: false,
description: '数据流转配置输入参数'
} as const;
export const OneNETProductInfoDtoSchema = {
type: 'object',
properties: {
@ -7285,6 +7374,18 @@ export const OneNETProductInfoDtoSchema = {
type: 'string',
description: '平台物模型信息',
nullable: true
},
isNeedPushData: {
type: 'boolean',
description: '是否需要推送数据'
},
dataPushType: {
'$ref': '#/components/schemas/DataPushTypeEnum'
},
dataPushInfo: {
type: 'string',
description: '数据推送信息,HTTP推送就是推送地址Reist推送主题或者key',
nullable: true
}
},
additionalProperties: false
@ -7549,6 +7650,19 @@ export const OneNetProductInfoModifyInputSchema = {
type: 'string',
description: '物模型文件名称',
nullable: true
},
isNeedPushData: {
type: 'boolean',
description: '是否需要推送数据',
nullable: true
},
dataPushType: {
'$ref': '#/components/schemas/DataPushTypeEnum'
},
dataPushInfo: {
type: 'string',
description: '数据推送信息,HTTP推送就是推送地址Reist推送主题或者key',
nullable: true
}
},
additionalProperties: false,
@ -7563,12 +7677,6 @@ export const OpenApiDeviceInfoInputSchema = {
description: '网关设备或直连设备地址,此数据自研设备在生产的时候就已经入库',
nullable: true
},
businessSystemDeviceDataId: {
type: 'integer',
description: '业务系统设备数据Id一般指集中器Id',
format: 'int64',
nullable: true
},
subDeviceName: {
type: 'string',
description: '子设备名称',
@ -10306,16 +10414,6 @@ JiShe.ServicePro.Enums.DeviceTypeEnum`,
description: '通信协议',
nullable: true
},
focusAddress: {
type: 'string',
description: '集中器地址',
nullable: true
},
meterAddress: {
type: 'string',
description: '表地址',
nullable: true
},
rawMessage: {
type: 'string',
description: '消息上报原始内容',

File diff suppressed because one or more lines are too long

View File

@ -1059,6 +1059,11 @@ export type DataDictionaryDetailInfoDto = {
*/
export type DataEncryptionEnum = 1 | 2 | 3 | 4 | 5 | 6;
/**
*
*/
export type DataPushTypeEnum = 1 | 2 | 3;
export type DateTimeFormatDto = {
calendarAlgorithmType?: (string) | null;
dateTimeFormatLong?: (string) | null;
@ -1249,6 +1254,48 @@ export type DeviceFirmwareInfoDtoPagedResultDto = {
totalCount?: number;
};
/**
*
*/
export type DeviceLoginModel = {
/**
* IdOneNET平台的设备名称
*/
clientid: string;
/**
*
*/
readonly deviceAddress?: (string) | null;
/**
* OneNET平台的产品名称
*/
username: string;
/**
* OneNET平台的签名Token
*/
password: string;
};
/**
*
*/
export type DeviceLoginResult = {
/**
* JiShe.ServicePro.Core.DeviceEMQXLoginResultConsts
*/
result?: (string) | null;
/**
*
*/
is_superuser?: boolean;
/**
*
*/
client_attrs?: {
[key: string]: ((string) | null);
} | null;
};
export type DeviceManagementInfoDto = {
id?: string;
creationTime?: string;
@ -3821,6 +3868,25 @@ export type OneNetAccountModifyInput = {
accountAccesskey: string;
};
/**
*
*/
export type OneNETDataFlowConfigInput = {
/**
* ID
*/
id?: string;
/**
*
*/
isNeedPushData?: boolean;
dataPushType?: DataPushTypeEnum;
/**
* ,HTTP推送就是推送地址Reist推送主题或者key
*/
dataPushInfo?: (string) | null;
};
export type OneNETProductInfoDto = {
id?: string;
creationTime?: string;
@ -3954,6 +4020,15 @@ export type OneNETProductInfoDto = {
*
*/
thingModelInfos?: (string) | null;
/**
*
*/
isNeedPushData?: boolean;
dataPushType?: DataPushTypeEnum;
/**
* ,HTTP推送就是推送地址Reist推送主题或者key
*/
dataPushInfo?: (string) | null;
};
export type OneNETProductInfoDtoPagedResultDto = {
@ -4066,6 +4141,15 @@ export type OneNetProductInfoModifyInput = {
*
*/
thingModelFileName?: (string) | null;
/**
*
*/
isNeedPushData?: (boolean) | null;
dataPushType?: DataPushTypeEnum;
/**
* ,HTTP推送就是推送地址Reist推送主题或者key
*/
dataPushInfo?: (string) | null;
};
/**
@ -4076,10 +4160,6 @@ export type OpenApiDeviceInfoInput = {
*
*/
deviceAddress?: (string) | null;
/**
* IdId
*/
businessSystemDeviceDataId?: (number) | null;
/**
*
*/
@ -5703,14 +5783,6 @@ export type QueryOneNETReceiveMessageOutput = {
*
*/
protocol?: (string) | null;
/**
*
*/
focusAddress?: (string) | null;
/**
*
*/
meterAddress?: (string) | null;
/**
*
*/
@ -6374,7 +6446,7 @@ export type PostAuditLogsPageResponse = (PagingAuditLogOutputPagedResultDto);
export type PostAuditLogsPageError = (RemoteServiceErrorResponse);
export type PostAggregationBusinessReceiveCommandInfoAsyncData = {
export type PostAggregationBusinessReceiveSetCommandInfoAsyncData = {
query?: {
/**
*
@ -6383,9 +6455,9 @@ export type PostAggregationBusinessReceiveCommandInfoAsyncData = {
};
};
export type PostAggregationBusinessReceiveCommandInfoAsyncResponse = (HttpDataResult);
export type PostAggregationBusinessReceiveSetCommandInfoAsyncResponse = (HttpDataResult);
export type PostAggregationBusinessReceiveCommandInfoAsyncError = unknown;
export type PostAggregationBusinessReceiveSetCommandInfoAsyncError = unknown;
export type PostAggregationBusinessBatchQueryDeviceDataInfoAsyncData = {
query?: {
@ -6400,6 +6472,19 @@ export type PostAggregationBusinessBatchQueryDeviceDataInfoAsyncResponse = (Http
export type PostAggregationBusinessBatchQueryDeviceDataInfoAsyncError = unknown;
export type PostAggregationBusinessQueryDeviceDataInfoAsyncData = {
query?: {
/**
*
*/
input?: OpenApiRequest;
};
};
export type PostAggregationBusinessQueryDeviceDataInfoAsyncResponse = (HttpDataResult);
export type PostAggregationBusinessQueryDeviceDataInfoAsyncError = unknown;
export type PostAggregationBusinessBatchCreateDeviceInfoAsyncData = {
query?: {
/**
@ -6413,6 +6498,19 @@ export type PostAggregationBusinessBatchCreateDeviceInfoAsyncResponse = (HttpDat
export type PostAggregationBusinessBatchCreateDeviceInfoAsyncError = unknown;
export type PostAggregationBusinessReceiveGetCommandInfoAsyncData = {
query?: {
/**
*
*/
input?: OpenApiRequest;
};
};
export type PostAggregationBusinessReceiveGetCommandInfoAsyncResponse = (HttpDataResult);
export type PostAggregationBusinessReceiveGetCommandInfoAsyncError = unknown;
export type GetCommonGetSelectListData = {
query?: {
input?: SelectResultListInput;
@ -6839,6 +6937,19 @@ export type PostDeviceInfoCacheDeviceDataToRedisResponse = (boolean);
export type PostDeviceInfoCacheDeviceDataToRedisError = unknown;
export type PostDeviceInfoMqttDeviceLoginData = {
query?: {
/**
*
*/
loginModel?: DeviceLoginModel;
};
};
export type PostDeviceInfoMqttDeviceLoginResponse = (DeviceLoginResult);
export type PostDeviceInfoMqttDeviceLoginError = unknown;
export type PostDeviceThingModelManagementCreateAsyncData = {
query?: {
input?: DeviceThingModelCreateInput;
@ -7663,6 +7774,19 @@ export type PostOneNetProductListAsyncResponse = (OneNETProductInfoDtoPagedResul
export type PostOneNetProductListAsyncError = unknown;
export type PostOneNetProductOneNetDataFlowConfigData = {
query?: {
/**
*
*/
input?: OneNETDataFlowConfigInput;
};
};
export type PostOneNetProductOneNetDataFlowConfigResponse = (OneNETProductInfoDto);
export type PostOneNetProductOneNetDataFlowConfigError = unknown;
export type PostOneNetServiceReceivePlaintextDataChangeData = {
query?: {
msg?: string;
@ -7721,6 +7845,10 @@ export type GetOneNetServiceCheckLocalMemroyResponse = (unknown);
export type GetOneNetServiceCheckLocalMemroyError = unknown;
export type PostDataServerReceiveEmqxDataResponse = (unknown);
export type PostDataServerReceiveEmqxDataError = unknown;
export type PostOrganizationUnitsTreeResponse = (Array<TreeOutput>);
export type PostOrganizationUnitsTreeError = (RemoteServiceErrorResponse);

View File

@ -312,6 +312,7 @@
"IoTPlatformProductUpdateTime": "ProductUpdateTime",
"IoTPlatformProductCreateTime": "ProductCreateTime",
"CreationTime": "CreationTime",
"IsNeedPushData": "IsNeedPushData",
"LastModificationTime": "LastModificationTime"
},
"CTWingManagement": {

View File

@ -307,6 +307,7 @@
"IoTPlatformProductUpdateTime": "平台更新时间",
"IoTPlatformProductCreateTime": "平台创建时间",
"CreationTime": "创建时间",
"IsNeedPushData": "是否数据推送",
"LastModificationTime": "更新时间"
},
"CTWingManagement": {

View File

@ -20,6 +20,7 @@ import {
postOneNetProductListAsync,
postOneNetProductModifyAsync,
postOneNetProductProductStatusChangeAsync,
postOneNetProductOneNetDataFlowConfig,
} from '#/api-client';
import { TableAction } from '#/components/table-action';
import { $t } from '#/locales';
@ -31,6 +32,7 @@ import {
setFileSelectedCallback,
tableSchema,
} from './schema';
import { getCommonGetSelectList } from '#/api-client';
defineOptions({
name: 'OneNETProduct',
@ -148,6 +150,75 @@ const [EditForm, editFormApi] = useVbenForm({
wrapperClass: 'grid-cols-2',
});
const [DataFlowForm, dataFlowFormApi] = useVbenForm({
collapsed: false,
layout: 'horizontal',
showCollapseButton: false,
showDefaultActions: false,
schema: [
{
component: 'Switch',
fieldName: 'isNeedPushData',
label: '是否需要推送数据',
componentProps: {
checkedValue: true,
unCheckedValue: false,
checkedChildren: '是',
unCheckedChildren: '否',
},
},
{
component: 'ApiSelect',
fieldName: 'dataPushType',
label: '数据推送类型',
componentProps: {
api: getCommonGetSelectList,
params: {
query: {
typeName: 'DataPushTypeEnum',
},
},
labelField: 'value',
valueField: 'key',
optionsPropName: 'options',
immediate: true,
allowClear: true,
placeholder: '请选择数据推送类型',
afterFetch: (res: any) => {
let items = [];
if (Array.isArray(res)) {
items = res;
} else if (res && Array.isArray(res.items)) {
items = res.items;
} else if (res && Array.isArray(res.data)) {
items = res.data;
}
return items.map((item: any) => ({
...item,
key: String(item.key || item.value),
}));
},
},
},
{
component: 'Input',
fieldName: 'dataPushInfo',
label: '数据推送信息',
componentProps: {
placeholder: 'HTTP 为推送地址Redis 为主题或 key',
},
},
],
});
const [DataFlowModal, dataFlowModalApi] = useVbenModal({
draggable: true,
footer: true,
showCancelButton: true,
showConfirmButton: true,
onConfirm: submitDataFlowConfig,
});
//
async function submit() {
const isEdit = !!editRow.value.id;
@ -310,6 +381,59 @@ async function onStatusChange(record: any) {
}
}
async function onDataFlowConfig(record: any) {
if (!record.id) {
Message.error('产品数据ID不存在无法进行数据流转配置');
return;
}
//
editRow.value = record;
dataFlowFormApi.setValues({
isNeedPushData: record.isNeedPushData ?? false,
dataPushType: record.dataPushType,
dataPushInfo: record.dataPushInfo,
});
dataFlowModalApi.open();
}
async function submitDataFlowConfig() {
if (!editRow.value.id) {
Message.error('产品数据ID不存在无法进行数据流转配置');
return;
}
const { valid } = await dataFlowFormApi.validate();
if (!valid) {
return;
}
const values = await dataFlowFormApi.getValues();
try {
const resp = await postOneNetProductOneNetDataFlowConfig({
body: {
id: editRow.value.id,
isNeedPushData: values.isNeedPushData ?? false,
dataPushType:
values.dataPushType !== undefined && values.dataPushType !== null
? Number(values.dataPushType)
: undefined,
dataPushInfo: values.dataPushInfo,
},
});
if (resp.data) {
Message.success('数据流转配置成功');
dataFlowModalApi.close();
gridApi.reload();
} else {
Message.error('数据流转配置失败');
}
} catch {
Message.error('数据流转配置失败');
}
}
//
function onDeviceManagement(record: any) {
console.log('设备管理按钮被点击', record);
@ -434,6 +558,13 @@ async function onThingModelUpdate(record: any) {
" />
</template>
<template #isNeedPushData="{ row }">
<component :is="h(Tag, { color: row.isNeedPushData ? 'green' : 'red' }, () =>
row.isNeedPushData ? $t('common.yes') : $t('common.no'),
)
" />
</template>
<template #thingModelFileName="{ row }">
<a v-if="row.thingModelFileName && row.deviceThingModelFileId" @click="onDownloadFile(row)"
style="color: #1890ff; text-decoration: underline; cursor: pointer">
@ -444,34 +575,46 @@ async function onThingModelUpdate(record: any) {
<template #action="{ row }">
<TableAction :actions="getRowActions(row)" :drop-down-actions="[
{
label: row.isEnabled
? $t('common.disabled')
: $t('common.enabled'),
icon: 'ant-design:edit-filled',
type: 'primary',
danger: row.isEnabled,
size: 'small',
auth: ['AbpIdentity.Users.Update'],
popConfirm: {
title: `确定要${row.isEnabled ? $t('common.disabled') : $t('common.enabled')}该产品吗?`,
confirm: onStatusChange.bind(null, row),
},
{
label: row.isEnabled
? $t('common.disabled')
: $t('common.enabled'),
icon: 'ant-design:edit-filled',
type: 'primary',
danger: row.isEnabled,
size: 'small',
auth: ['AbpIdentity.Users.Update'],
popConfirm: {
title: `确定要${row.isEnabled ? $t('common.disabled') : $t('common.enabled')
}该产品吗`,
confirm: onStatusChange.bind(null, row),
},
{
label: $t('common.delete'),
icon: 'ant-design:delete-outlined',
type: 'primary',
popConfirm: {
title: $t('common.askConfirmDelete'),
confirm: onDel.bind(null, row),
},
},
{
label: '数据流转配置',
icon: 'ant-design:setting-outlined',
type: 'primary',
size: 'small',
onClick: onDataFlowConfig.bind(null, row),
},
{
label: $t('common.delete'),
icon: 'ant-design:delete-outlined',
type: 'primary',
popConfirm: {
title: $t('common.askConfirmDelete'),
confirm: onDel.bind(null, row),
},
]" />
},
]" />
</template>
</Grid>
<UserModal :title="editRow.id ? $t('common.edit') : $t('common.add')" class="w-[800px]">
<component :is="editRow.id ? EditForm : AddForm" />
</UserModal>
<DataFlowModal title="数据流转配置" class="w-[600px]">
<DataFlowForm />
</DataFlowModal>
</Page>
</template>

View File

@ -49,6 +49,18 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
title: $t('abp.OneNETManagement.CommunicationAddressTLS'),
minWidth: '150',
},
{
field: 'isEnabled',
title: $t('common.isEnable'),
minWidth: '130',
slots: { default: 'isEnable' },
},
{
field: 'isNeedPushData',
title: $t('abp.OneNETManagement.IsNeedPushData'),
minWidth: '150',
slots: { default: 'isNeedPushData' },
},
{
field: 'thingModelFileName',
title: $t('abp.OneNETManagement.ThingModelFileName'),
@ -87,12 +99,6 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
},
},
{
field: 'isEnabled',
title: $t('common.isEnable'),
minWidth: '150',
slots: { default: 'isEnable' },
},
{
title: $t('common.action'),
field: 'action',