完善主站切换

This commit is contained in:
ChenYi 2026-07-13 14:47:53 +08:00
parent 90e0463306
commit 15cc3c7b14
4 changed files with 113 additions and 26 deletions

View File

@ -2232,7 +2232,7 @@ export const DeviceAuthenticationModeEnumSchema = {
} as const; } as const;
export const DeviceBatchMasterSwitchInputSchema = { export const DeviceBatchMasterSwitchInputSchema = {
required: ['addressList', 'ioTPlatform', 'ioTPlatformProductId', 'masterStationAddress'], required: ['addressList', 'backupMasterStation', 'ioTPlatform', 'ioTPlatformProductId', 'masterStation'],
type: 'object', type: 'object',
properties: { properties: {
addressList: { addressList: {
@ -2250,10 +2250,11 @@ export const DeviceBatchMasterSwitchInputSchema = {
type: 'string', type: 'string',
description: '物联网平台中对应的产品Id' description: '物联网平台中对应的产品Id'
}, },
masterStationAddress: { masterStation: {
minLength: 1, '$ref': '#/components/schemas/MasterStationInput'
type: 'string', },
description: '目标主站地址从主站下拉列表接口获取OneNET 静态地址或 EMQX 配置地址)' backupMasterStation: {
'$ref': '#/components/schemas/MasterStationInput'
} }
}, },
additionalProperties: false, additionalProperties: false,
@ -2951,7 +2952,7 @@ export const DeviceManagementInfoDtoPagedResultDtoHttpDataResultSchema = {
} as const; } as const;
export const DeviceMasterSwitchInputSchema = { export const DeviceMasterSwitchInputSchema = {
required: ['id', 'ioTPlatformProductId', 'masterStationAddress'], required: ['backupMasterStation', 'id', 'ioTPlatformProductId', 'masterStation'],
type: 'object', type: 'object',
properties: { properties: {
id: { id: {
@ -2963,10 +2964,11 @@ export const DeviceMasterSwitchInputSchema = {
type: 'string', type: 'string',
description: '物联网平台中对应的产品Id' description: '物联网平台中对应的产品Id'
}, },
masterStationAddress: { masterStation: {
minLength: 1, '$ref': '#/components/schemas/MasterStationInput'
type: 'string', },
description: '目标主站地址从主站下拉列表接口获取OneNET 静态地址或 EMQX 配置地址)' backupMasterStation: {
'$ref': '#/components/schemas/MasterStationInput'
} }
}, },
additionalProperties: false, additionalProperties: false,
@ -7307,6 +7309,23 @@ export const LoginResultTypeSchema = {
type: 'string' type: 'string'
} as const; } as const;
export const MasterStationInputSchema = {
required: ['ioTPlatform', 'masterStationAddress'],
type: 'object',
properties: {
masterStationAddress: {
minLength: 1,
type: 'string',
description: '主站地址host:port'
},
ioTPlatform: {
'$ref': '#/components/schemas/IoTPlatformTypeEnum'
}
},
additionalProperties: false,
description: '主站信息入参(切换主站时选定的目标主站,地址与平台类型成对传入,取值来源为主站下拉列表接口)'
} as const;
export const MasterStationOutputSchema = { export const MasterStationOutputSchema = {
type: 'object', type: 'object',
properties: { properties: {

File diff suppressed because one or more lines are too long

View File

@ -1264,10 +1264,8 @@ export type DeviceBatchMasterSwitchInput = {
* Id * Id
*/ */
ioTPlatformProductId: string; ioTPlatformProductId: string;
/** masterStation: MasterStationInput;
* OneNET EMQX backupMasterStation: MasterStationInput;
*/
masterStationAddress: string;
}; };
/** /**
@ -1724,10 +1722,8 @@ export type DeviceMasterSwitchInput = {
* Id * Id
*/ */
ioTPlatformProductId: string; ioTPlatformProductId: string;
/** masterStation: MasterStationInput;
* OneNET EMQX backupMasterStation: MasterStationInput;
*/
masterStationAddress: string;
}; };
/** /**
@ -3971,6 +3967,17 @@ export type LoginOutput = {
export type LoginResultType = 'Success' | 'InvalidUserNameOrPassword' | 'NotAllowed' | 'LockedOut' | 'RequiresTwoFactor'; export type LoginResultType = 'Success' | 'InvalidUserNameOrPassword' | 'NotAllowed' | 'LockedOut' | 'RequiresTwoFactor';
/**
*
*/
export type MasterStationInput = {
/**
* host:port
*/
masterStationAddress: string;
ioTPlatform: IoTPlatformTypeEnum;
};
/** /**
* OneNET EMQX * OneNET EMQX
*/ */
@ -8566,6 +8573,10 @@ export type PostOneNetServiceDataServerReceiveEmqxDataResponse = (unknown);
export type PostOneNetServiceDataServerReceiveEmqxDataError = unknown; export type PostOneNetServiceDataServerReceiveEmqxDataError = unknown;
export type PostOneNetServiceDataServerReceiveEmqxDeviceStatusResponse = (unknown);
export type PostOneNetServiceDataServerReceiveEmqxDeviceStatusError = unknown;
export type PostOrganizationUnitsTreeResponse = (Array<TreeOutput>); export type PostOrganizationUnitsTreeResponse = (Array<TreeOutput>);
export type PostOrganizationUnitsTreeError = (RemoteServiceErrorResponse); export type PostOrganizationUnitsTreeError = (RemoteServiceErrorResponse);

View File

@ -3056,7 +3056,9 @@ const masterStationOptions = ref<
Array<{ ioTPlatform?: number; label: string; value: string }> Array<{ ioTPlatform?: number; label: string; value: string }>
>([]); >([]);
const masterStationLoading = ref(false); const masterStationLoading = ref(false);
// /
const selectedMasterAddress = ref<string | undefined>(undefined); const selectedMasterAddress = ref<string | undefined>(undefined);
const selectedBackupMasterAddress = ref<string | undefined>(undefined);
// //
function getGridCheckboxRecords(): any[] { function getGridCheckboxRecords(): any[] {
@ -3109,12 +3111,28 @@ async function fetchMasterStationOptions() {
} }
} }
// +
function resolveMasterStation(address: string | undefined) {
if (!address) {
return undefined;
}
const option = masterStationOptions.value.find((m) => m.value === address);
if (!option || option.ioTPlatform === undefined) {
return undefined;
}
return {
masterStationAddress: address,
ioTPlatform: option.ioTPlatform,
};
}
const [MasterSwitchModal, masterSwitchModalApi] = useVbenModal({ const [MasterSwitchModal, masterSwitchModalApi] = useVbenModal({
draggable: true, draggable: true,
onConfirm: submitBatchMasterSwitch, onConfirm: submitBatchMasterSwitch,
onBeforeClose: () => { onBeforeClose: () => {
masterSwitchRows.value = []; masterSwitchRows.value = [];
selectedMasterAddress.value = undefined; selectedMasterAddress.value = undefined;
selectedBackupMasterAddress.value = undefined;
return true; return true;
}, },
onOpenChange: async (isOpen: boolean) => { onOpenChange: async (isOpen: boolean) => {
@ -3168,6 +3186,7 @@ function openBatchMasterSwitchModal() {
masterSwitchRows.value = checkboxRecords; masterSwitchRows.value = checkboxRecords;
selectedMasterAddress.value = undefined; selectedMasterAddress.value = undefined;
selectedBackupMasterAddress.value = undefined;
masterSwitchModalApi.open(); masterSwitchModalApi.open();
} }
@ -3178,8 +3197,17 @@ async function submitBatchMasterSwitch() {
Message.warning('没有选中的设备'); Message.warning('没有选中的设备');
return; return;
} }
if (!selectedMasterAddress.value) { const masterStation = resolveMasterStation(selectedMasterAddress.value);
Message.warning('请选择目标主站'); if (!masterStation) {
Message.warning('请选择主用主站');
return;
}
const backupMasterStation = resolveMasterStation(
selectedBackupMasterAddress.value,
);
if (!backupMasterStation) {
Message.warning('请选择备用主站');
return; return;
} }
@ -3200,7 +3228,8 @@ async function submitBatchMasterSwitch() {
addressList, addressList,
ioTPlatform, ioTPlatform,
ioTPlatformProductId: String(firstRow.ioTPlatformProductId), ioTPlatformProductId: String(firstRow.ioTPlatformProductId),
masterStationAddress: selectedMasterAddress.value, masterStation,
backupMasterStation,
}, },
}); });
@ -3792,18 +3821,34 @@ const [DeviceDataFlowModal, deviceDataFlowModalApi] = useVbenModal({
</div> </div>
<div> <div>
<div class="mb-2 text-sm">目标主站</div> <div class="mb-2 text-sm">
主用主站 <span class="text-red-500">*</span>
</div>
<Select <Select
v-model:value="selectedMasterAddress" v-model:value="selectedMasterAddress"
class="w-full" class="w-full"
placeholder="请选择要切换到的目标主站" placeholder="请选择设备优先接入的主站"
:options="masterStationOptions"
:loading="masterStationLoading"
allow-clear
/>
</div>
<div>
<div class="mb-2 text-sm">
备用主站 <span class="text-red-500">*</span>
</div>
<Select
v-model:value="selectedBackupMasterAddress"
class="w-full"
placeholder="请选择主用主站不可用时回落的主站"
:options="masterStationOptions" :options="masterStationOptions"
:loading="masterStationLoading" :loading="masterStationLoading"
allow-clear allow-clear
/> />
</div> </div>
<div class="text-xs text-gray-400"> <div class="text-xs text-gray-400">
切换主站指令将下发到所选设备指令下发成功不代表设备已完成切换最终以设备上报的主站切换事件为准 主用与备用主站一次性下发设备侧主备主站表整体刷新现场只有一个主站时两者可选同一个
指令下发成功不代表设备已完成切换最终以设备上报的主站切换事件为准
</div> </div>
</div> </div>
<template #footer> <template #footer>
@ -3814,7 +3859,7 @@ const [DeviceDataFlowModal, deviceDataFlowModalApi] = useVbenModal({
<Button <Button
type="primary" type="primary"
:loading="masterSwitchModalState?.confirmLoading" :loading="masterSwitchModalState?.confirmLoading"
:disabled="!selectedMasterAddress" :disabled="!selectedMasterAddress || !selectedBackupMasterAddress"
@click="submitBatchMasterSwitch" @click="submitBatchMasterSwitch"
> >
{{ $t('common.confirm') }} {{ $t('common.confirm') }}