Commit 3bf5203619839108a860a64453256cd2973c4db9

Authored by xp.Huang
2 parents aee2e0b8 b65d9399

Merge branch 'main_dev' into 'main'

fix: 修复更改设备类型为网关子设备时关联网关设备组织关系

See merge request yunteng/thingskit-front!1121
... ... @@ -49,6 +49,7 @@ enum DeviceUrl {
49 49 GET_DEVICE_ATTRIBUTE = '/device/attributes',
50 50 GET_DEVICE = '/device/list',
51 51 GET_DEVICE_RELATION = '/device/device/relation',
  52 + GET_GATEWAY_LIST = '/device/gateway/list',
52 53 }
53 54
54 55 /**
... ... @@ -240,6 +241,15 @@ export const sendCommandTwoway = (params: SendCommandParams) => {
240 241 );
241 242 };
242 243
  244 +export const getMeetTheConditionsGatewayDevice = (
  245 + params?: Partial<Record<'organizationId' | 'transportType', string>>
  246 +) => {
  247 + return defHttp.get<DeviceRecord[]>({
  248 + url: DeviceUrl.GET_GATEWAY_LIST,
  249 + params,
  250 + });
  251 +};
  252 +
243 253 export const getDeviceRelation = (params: { deviceId: string; isSlave: boolean }) => {
244 254 return defHttp.get<string>({
245 255 url: DeviceUrl.GET_DEVICE_RELATION,
... ...
... ... @@ -186,6 +186,7 @@ export interface DeviceRecord {
186 186 alias?: string;
187 187 brand?: string;
188 188 deviceProfileId: string;
  189 + organizationId: string;
189 190 deviceProfile: {
190 191 default: boolean;
191 192 name: string;
... ...
... ... @@ -2,7 +2,7 @@
2 2 import { ApiTreeSelect } from '/@/components/Form';
3 3 import { Button } from 'ant-design-vue';
4 4 import { getOrganizationList } from '/@/api/system/system';
5   - import { computed, ref, unref } from 'vue';
  5 + import { computed, ref, unref, watch } from 'vue';
6 6 import OrganizationDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
7 7 import { useDrawer } from '/@/components/Drawer';
8 8 import { OrganizationListItem } from '/@/api/system/model/systemModel';
... ... @@ -79,6 +79,11 @@
79 79 needReload.value = true;
80 80 timespan.value = Date.now();
81 81 };
  82 +
  83 + watch(
  84 + () => props.apiTreeSelectProps,
  85 + () => handleReload()
  86 + );
82 87 </script>
83 88
84 89 <template>
... ...
... ... @@ -4,10 +4,10 @@ import { getGatewayDevice, queryDeviceProfileBy } from '/@/api/device/deviceMana
4 4 import { TransportTypeEnum } from '../../profiles/components/TransportDescript/const';
5 5 import { JSONEditorValidator } from '/@/components/CodeEditor/src/JSONEditor';
6 6 import { JSONEditor } from '/@/components/CodeEditor';
7   -import { DeviceTypeEnum } from '/@/api/device/model/deviceModel';
  7 +import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
8 8 import { getModelServices } from '/@/api/device/modelOfMatter';
9 9 import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
10   -import { h, nextTick, toRaw, unref } from 'vue';
  10 +import { h, toRaw, unref } from 'vue';
11 11 import ObjectModelValidateForm from '/@/components/Form/src/externalCompns/components/ObjectModelValidateForm/ObjectModelValidateForm.vue';
12 12 import { CommandDeliveryWayEnum, ServiceCallTypeEnum } from '/@/enums/toolEnum';
13 13 import { TaskTypeEnum } from '/@/views/task/center/config';
... ... @@ -15,9 +15,6 @@ import { AddressTypeEnum } from '/@/views/task/center/components/PollCommandInpu
15 15 import { FileItem } from '/@/components/Form/src/components/ApiUpload.vue';
16 16 import { createImgPreview } from '/@/components/Preview';
17 17 import { uploadThumbnail } from '/@/api/configuration/center/configurationCenter';
18   -
19   -import { getOrganizationList } from '/@/api/system/system';
20   -import { copyTransFun } from '/@/utils/fnUtils';
21 18 import LockControlGroup from '/@/components/Form/src/components/LockControlGroup.vue';
22 19 import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
23 20
... ... @@ -305,7 +302,7 @@ export const step1Schemas: FormSchema[] = [
305 302 ifShow: ({ values }) => values.deviceType === 'SENSOR',
306 303 componentProps: ({ formModel, formActionType }) => {
307 304 const { transportType } = formModel;
308   - const { validateFields } = formActionType;
  305 + const { setFieldsValue } = formActionType;
309 306 if (!transportType) return {};
310 307 return {
311 308 api: async (params: Recordable) => {
... ... @@ -320,22 +317,23 @@ export const step1Schemas: FormSchema[] = [
320 317 params: {
321 318 transportType,
322 319 },
  320 + placeholder: '请选择网关设备',
323 321 valueField: 'tbDeviceId',
324 322 labelField: 'alias',
325   - onChange: async (value, options) => {
326   - await nextTick();
327   - if (value) {
328   - const data = await getOrganizationList({ organizationId: options?.organizationId });
329   - copyTransFun(data as any as any[]);
330   - formModel.organizationList = data;
  323 + onChange: async (_value: string, option: DeviceRecord) => {
  324 + setFieldsValue({ sensorOrganizationId: option?.organizationId, organizationId: null });
  325 + },
  326 + onOptionsChange(options: (DeviceRecord & Record<'value', string>)[]) {
  327 + if (formModel?.deviceType === DeviceTypeEnum.SENSOR && formModel?.gatewayId) {
  328 + const result = options.find((item) => item.value === formModel?.gatewayId);
  329 + result && setFieldsValue({ sensorOrganizationId: result?.organizationId });
331 330 }
332   - validateFields(['gatewayId']);
333 331 },
334 332 };
335 333 },
336 334 },
337 335 {
338   - field: 'organizationList',
  336 + field: 'sensorOrganizationId',
339 337 label: '依据网关设备请求的组织数组',
340 338 component: 'Input',
341 339 ifShow: false,
... ... @@ -354,6 +352,13 @@ export const step1Schemas: FormSchema[] = [
354 352 return {
355 353 component: 'OrgTreeSelect',
356 354 defaultLockStatus: !!formModel?.isUpdate,
  355 + componentProps: {
  356 + apiTreeSelectProps: {
  357 + params: {
  358 + organizationId: formModel?.sensorOrganizationId,
  359 + },
  360 + },
  361 + },
357 362 };
358 363 },
359 364 },
... ...
1 1 import { Options } from './type';
2   -import { getMeetTheConditionsDevice } from '/@/api/dataBoard';
  2 +import { getMeetTheConditionsGatewayDevice } from '/@/api/dataBoard';
3 3 import { queryDeviceProfileBy } from '/@/api/device/deviceManager';
4 4 import { DeviceRecord, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
5 5 import { findDictItemByCode } from '/@/api/system/dict';
6   -import { getOrganizationList } from '/@/api/system/system';
7   -import { FormSchema } from '/@/components/Form';
  6 +import { FormSchema, useComponentRegister } from '/@/components/Form';
8 7 import { BasicColumn } from '/@/components/Table';
9   -import { copyTransFun } from '/@/utils/fnUtils';
  8 +import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
10 9 import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
11 10 import XLSX, { CellObject } from 'xlsx';
12 11
  12 +useComponentRegister('OrgTreeSelect', OrgTreeSelect);
  13 +
13 14 export enum FieldsEnum {
14 15 ORGANIZATION_ID = 'organizationId',
15 16 DEVICE_TYPE = 'deviceTypeEnum',
... ... @@ -23,6 +24,8 @@ export enum FieldsEnum {
23 24 IS_TCP_DEVICE_PROFILE = 'isTcpDeviceProfile',
24 25 TRANSPORT_TYPE = 'transportType',
25 26 PRODUCTION_NAME = 'productionName',
  27 +
  28 + GATEWAY_ORGANIZATION_ID = 'gatewayOrganizationId',
26 29 }
27 30
28 31 export enum DelimiterEnum {
... ... @@ -108,30 +111,6 @@ export enum CredentialsNameEnum {
108 111
109 112 export const basicInfoForm: FormSchema[] = [
110 113 {
111   - field: FieldsEnum.ORGANIZATION_ID,
112   - label: '所属组织',
113   - component: 'ApiTreeSelect',
114   - rules: [{ required: true, message: '所属组织为必填项' }],
115   - componentProps: ({ formModel, formActionType }) => {
116   - const { setFieldsValue } = formActionType;
117   - return {
118   - maxLength: 250,
119   - placeholder: '请选择所属组织',
120   - api: async () => {
121   - const data = (await getOrganizationList()) as unknown as Recordable[];
122   - copyTransFun(data);
123   - return data;
124   - },
125   - getPopupContainer: () => document.body,
126   - onChange(e) {
127   - if (e != formModel?.[FieldsEnum.ORGANIZATION_ID]) {
128   - setFieldsValue({ [FieldsEnum.GATEWAY_TB_DEVICE_ID]: null });
129   - }
130   - },
131   - };
132   - },
133   - },
134   - {
135 114 field: FieldsEnum.DEVICE_TYPE,
136 115 label: '设备类型',
137 116 component: 'ApiSelect',
... ... @@ -150,6 +129,7 @@ export const basicInfoForm: FormSchema[] = [
150 129 [FieldsEnum.DEVICE_TYPE_NAME]: value ? options.label : null,
151 130 [FieldsEnum.TK_DEVICE_PROFILE_ID]: null,
152 131 [FieldsEnum.GATEWAY_TB_DEVICE_ID]: null,
  132 + [FieldsEnum.ORGANIZATION_ID]: null,
153 133 });
154 134 clearValidate();
155 135 },
... ... @@ -181,6 +161,7 @@ export const basicInfoForm: FormSchema[] = [
181 161 [FieldsEnum.GATEWAY_TB_DEVICE_ID]: null,
182 162 [FieldsEnum.TRANSPORT_TYPE]: options?.transportType,
183 163 [FieldsEnum.PRODUCTION_NAME]: options?.label,
  164 + [FieldsEnum.ORGANIZATION_ID]: null,
184 165 });
185 166 },
186 167 showSearch: true,
... ... @@ -203,30 +184,29 @@ export const basicInfoForm: FormSchema[] = [
203 184 show: false,
204 185 },
205 186 {
  187 + field: FieldsEnum.GATEWAY_ORGANIZATION_ID,
  188 + label: '',
  189 + component: 'Input',
  190 + show: false,
  191 + },
  192 + {
206 193 field: FieldsEnum.GATEWAY_TB_DEVICE_ID,
207 194 component: 'ApiSelect',
208 195 label: '网关设备',
209 196 ifShow: ({ model }) => model[FieldsEnum.DEVICE_TYPE] === DeviceTypeEnum.SENSOR,
210 197 required: true,
211   - componentProps: ({ formModel }) => {
212   - const organizationId = formModel[FieldsEnum.ORGANIZATION_ID];
213   - const transportType = formModel[FieldsEnum.TRANSPORT_TYPE];
  198 + componentProps: ({ formModel, formActionType }) => {
  199 + const transportType: string = formModel[FieldsEnum.TRANSPORT_TYPE];
214 200 return {
215 201 api: async () => {
216 202 try {
217   - if (!organizationId) return;
218   - const result = await getMeetTheConditionsDevice({
219   - deviceType: DeviceTypeEnum.GATEWAY,
220   - organizationId,
  203 + const result = await getMeetTheConditionsGatewayDevice({ transportType });
  204 + return result.map((item) => {
  205 + return {
  206 + ...item,
  207 + name: item.alias || item.name,
  208 + };
221 209 });
222   - return result
223   - .map((item) => {
224   - return {
225   - ...item,
226   - name: item.alias || item.name,
227   - };
228   - })
229   - .filter((item) => item.transportType === transportType);
230 210 } catch (error) {
231 211 return [];
232 212 }
... ... @@ -239,6 +219,28 @@ export const basicInfoForm: FormSchema[] = [
239 219 return options.label.includes(inputValue);
240 220 },
241 221 placeholder: '请选择网关设备',
  222 + onChange(_value: string, option: DeviceRecord) {
  223 + const { setFieldsValue } = formActionType;
  224 + setFieldsValue({
  225 + [FieldsEnum.GATEWAY_ORGANIZATION_ID]: option?.organizationId,
  226 + [FieldsEnum.ORGANIZATION_ID]: null,
  227 + });
  228 + },
  229 + };
  230 + },
  231 + },
  232 + {
  233 + field: FieldsEnum.ORGANIZATION_ID,
  234 + label: '所属组织',
  235 + component: 'OrgTreeSelect',
  236 + rules: [{ required: true, message: '所属组织为必填项' }],
  237 + componentProps: ({ formModel }) => {
  238 + return {
  239 + apiTreeSelectProps: {
  240 + params: {
  241 + organizationId: formModel?.[FieldsEnum.GATEWAY_ORGANIZATION_ID],
  242 + },
  243 + },
242 244 };
243 245 },
244 246 },
... ...
... ... @@ -201,13 +201,6 @@
201 201 slots: { customRender: 'action' },
202 202 fixed: 'right',
203 203 },
204   - rowSelection: {
205   - getCheckboxProps: (record: ModelOfMatterItemRecordType) => {
206   - return {
207   - disabled: record.status === 1,
208   - };
209   - },
210   - },
211 204 });
212 205
213 206 const getHasBatchDelete = computed(() => !getRowSelection().selectedRowKeys?.length);
... ...