Commit 6996c664caf5e3737f582ff20aaee165e7e08193

Authored by xp.Huang
2 parents 4fd1cc00 8fd2cefb

Merge branch 'fix/board-control-ordres' into 'main_dev'

fix: 修改看板控制组件选择tcp时的逻辑问题

See merge request yunteng/thingskit-front!803
... ... @@ -127,6 +127,9 @@ export interface MasterDeviceList {
127 127 label?: string;
128 128 value?: string;
129 129 alias?: string;
  130 + codeType?: string;
  131 + code?: string;
  132 + [key: string]: string | undefined;
130 133 }
131 134
132 135 export interface ComponentInfoDetail {
... ...
... ... @@ -125,23 +125,25 @@ export const step1Schemas: FormSchema[] = [
125 125 dynamicRules({ values }) {
126 126 return [
127 127 {
128   - required:
129   - (values?.transportType === TransportTypeEnum.TCP &&
130   - values?.deviceType === DeviceTypeEnum.SENSOR) ||
131   - values?.deviceType === DeviceTypeEnum.GATEWAY,
  128 + required: values?.transportType === TransportTypeEnum.TCP,
132 129 message: '请输入设备标识符',
133 130 },
134 131 ];
135 132 },
136   - ifShow: ({ values }) =>
137   - values?.transportType === TransportTypeEnum.TCP &&
138   - (values.deviceType === DeviceTypeEnum.SENSOR || values.deviceType === DeviceTypeEnum.GATEWAY),
139   - componentProps: ({}) => {
  133 + // ifShow: ({ values }) =>
  134 + // values?.transportType === TransportTypeEnum.TCP &&
  135 + // (values.deviceType === DeviceTypeEnum.SENSOR || values.deviceType === DeviceTypeEnum.GATEWAY),
  136 + ifShow: ({ values }) => values?.transportType === TransportTypeEnum.TCP,
  137 + componentProps: ({ formActionType }) => {
  138 + const { setFieldsValue } = formActionType;
140 139 return {
141 140 options: [
142 141 { label: '自定义', value: TaskTypeEnum.CUSTOM },
143 142 { label: 'ModBus', value: TaskTypeEnum.MODBUS_RTU },
144 143 ],
  144 + onChange() {
  145 + setFieldsValue({ addressCode: null });
  146 + },
145 147 };
146 148 },
147 149 },
... ... @@ -167,11 +169,17 @@ export const step1Schemas: FormSchema[] = [
167 169 minValue: 0,
168 170 disabledSwitch: true,
169 171 },
  172 + // ifShow: ({ values }) => {
  173 + // return (
  174 + // values?.transportType === TransportTypeEnum.TCP &&
  175 + // (values.deviceType === DeviceTypeEnum.SENSOR ||
  176 + // values.deviceType === DeviceTypeEnum.GATEWAY) &&
  177 + // values?.codeType === TaskTypeEnum.MODBUS_RTU
  178 + // );
  179 + // },
170 180 ifShow: ({ values }) => {
171 181 return (
172 182 values?.transportType === TransportTypeEnum.TCP &&
173   - (values.deviceType === DeviceTypeEnum.SENSOR ||
174   - values.deviceType === DeviceTypeEnum.GATEWAY) &&
175 183 values?.codeType === TaskTypeEnum.MODBUS_RTU
176 184 );
177 185 },
... ...
... ... @@ -31,6 +31,7 @@ export type TOption = {
31 31 export enum CommandTypeEnum {
32 32 CUSTOM = 0,
33 33 SERVICE = 1,
  34 + ATTRIBUTE = 2,
34 35 }
35 36
36 37 /**
... ...
... ... @@ -122,7 +122,7 @@
122 122 });
123 123 };
124 124
125   - const handleCopy = (record: DataSourceType) => {
  125 + const handleCopy = async (record: DataSourceType) => {
126 126 const { key } = props.componentConfig || {};
127 127 if (key == 'HumidityComponent2' && props.dataSource.length >= 6) {
128 128 createMessage.warning('绑定的数据源不能超过6条~');
... ... @@ -134,11 +134,12 @@
134 134 return;
135 135 }
136 136
137   - const allValues = getFormValues();
  137 + const allValues = await getFormValues();
138 138 const currentRecord = getFormValueByUUID(record.uuid);
139 139 const uuid = trackUpdate();
140 140 const raw = toRaw(record);
141 141
  142 + console.log(currentRecord, 'currentRecord');
142 143 emit('update:dataSource', [
143 144 ...allValues,
144 145 { componentInfo: raw.componentInfo, ...currentRecord, uuid },
... ...
... ... @@ -32,6 +32,10 @@
32 32 transportType: value.transportType,
33 33 service: value.service,
34 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 39 commandType: value.commandType,
36 40 callType: value.callType,
37 41 },
... ... @@ -45,6 +49,10 @@
45 49 ...record,
46 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 51 service: customCommand?.service || (record as Recordable).service,
  52 + openService: customCommand?.openService || (record as Recordable).openService,
  53 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  54 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  55 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
48 56 command: customCommand?.command || (record as Recordable).command,
49 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 58 callType: customCommand?.callType || (record as Recordable).callType,
... ...
... ... @@ -2,12 +2,13 @@
2 2 import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
3 3 import { option } from './config';
4 4 import { Spin } from 'ant-design-vue';
5   - import { computed, ref } from 'vue';
  5 + import { computed, ref, unref } from 'vue';
6 6 import { useComponentScale } from '../../../hook/useComponentScale';
7 7 import { useSendCommand } from '../../../hook/useSendCommand';
8 8 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
9 9 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
10 10 import { useDataFetch } from '../../../hook/socket/useSocket';
  11 + import { getSendValues } from '../config';
11 12
12 13 const props = defineProps<{
13 14 config: ComponentPropsConfigType<typeof option>;
... ... @@ -19,9 +20,23 @@
19 20
20 21 const getDesign = computed(() => {
21 22 const { option } = props.config;
22   - const { attribute, attributeRename, attributeName } = option;
  23 + const {
  24 + attribute,
  25 + attributeRename,
  26 + attributeName,
  27 + commandType,
  28 + extensionDesc,
  29 + codeType,
  30 + deviceCode,
  31 + customCommand,
  32 + } = option;
23 33 return {
24 34 attribute: attributeRename || attributeName || attribute,
  35 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  36 + commandType,
  37 + codeType,
  38 + deviceCode,
  39 + customCommand,
25 40 };
26 41 });
27 42
... ... @@ -29,8 +44,15 @@
29 44 const handleChange = async (event: Event) => {
30 45 const target = event.target as HTMLInputElement;
31 46 const value = target.checked;
  47 + const { option } = props.config || {};
32 48
33   - const flag = await sendCommand(props.config.option, value);
  49 + const { values, isModbusCommand, sendValue } = await getSendValues(
  50 + option,
  51 + unref(getDesign),
  52 + value
  53 + );
  54 +
  55 + const flag = await sendCommand(values, isModbusCommand ? sendValue : value, isModbusCommand);
34 56 if (flag) currentValue.value = value;
35 57 flag ? (currentValue.value = value) : (target.checked = !value);
36 58 };
... ...
... ... @@ -32,6 +32,10 @@
32 32 transportType: value.transportType,
33 33 service: value.service,
34 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 39 commandType: value.commandType,
36 40 callType: value.callType,
37 41 },
... ... @@ -41,14 +45,20 @@
41 45
42 46 const setFormValues = (record: DataSource) => {
43 47 const { customCommand } = record;
44   - return setFieldsValue({
  48 + const values = {
45 49 ...record,
46 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 51 service: customCommand?.service || (record as Recordable).service,
48 52 command: customCommand?.command || (record as Recordable).command,
  53 + openService: customCommand?.openService || (record as Recordable).openService,
  54 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  55 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  56 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
49 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 58 callType: customCommand?.callType || (record as Recordable).callType,
51   - } as unknown as Partial<CommonDataSourceBindValueType>);
  59 + } as unknown as Partial<CommonDataSourceBindValueType>;
  60 +
  61 + return setFieldsValue(values);
52 62 };
53 63
54 64 defineExpose({
... ...
... ... @@ -10,6 +10,7 @@
10 10 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
11 11 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
12 12 import { useDataFetch } from '../../../hook/socket/useSocket';
  13 + import { getSendValues } from '../config';
13 14
14 15 const props = defineProps<{
15 16 config: ComponentPropsConfigType<typeof option>;
... ... @@ -19,19 +20,88 @@
19 20
20 21 const getDesign = computed(() => {
21 22 const { option, persetOption } = props.config;
22   - const { componentInfo, attribute, attributeRename, attributeName } = option;
  23 + const {
  24 + componentInfo,
  25 + attribute,
  26 + attributeRename,
  27 + attributeName,
  28 + commandType,
  29 + extensionDesc,
  30 + codeType,
  31 + deviceCode,
  32 + customCommand,
  33 + } = option;
23 34 const { icon: presetIcon, iconColor: presetIconColor } = persetOption || {};
24 35 const { icon, iconColor } = componentInfo || {};
  36 +
25 37 return {
26 38 icon: icon ?? presetIcon,
27 39 iconColor: iconColor || presetIconColor,
28 40 attribute: attributeRename || attributeName || attribute,
  41 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  42 + commandType,
  43 + codeType,
  44 + deviceCode,
  45 + customCommand,
29 46 };
30 47 });
31 48
32 49 const { sendCommand, loading } = useSendCommand();
  50 +
33 51 const handleChange = async () => {
34   - const flag = await sendCommand(props.config.option, unref(checked));
  52 + const { option } = props.config || {};
  53 +
  54 + const { values, isModbusCommand, sendValue } = await getSendValues(
  55 + option,
  56 + unref(getDesign),
  57 + unref(checked)
  58 + );
  59 +
  60 + // const { values, sendValue, isModbusCommand } = getSendValues(
  61 + // values,
  62 + // unref(getDesign),
  63 + // unref(checked)
  64 + // );
  65 + // const isModbusCommand = ref<boolean>(false); //判断是否是TCP设备-> 且设备标识符是modeBUs,切选择是下发命令类型是属性
  66 + // const { extensionDesc, commandType, codeType, deviceCode, customCommand } =
  67 + // unref(getDesign) || {};
  68 + // const { registerAddress, actionType } = extensionDesc || {};
  69 + // const { openCommand, closeCommand, transportType } = customCommand || {};
  70 + // const modBUS = ref<any>({});
  71 + // const sendValue = ref();
  72 + // console.log(transportType, 'transportType', codeType, 'codeType');
  73 + // //判断是不是TCP类型设备
  74 + // if (transportType === TransportTypeEnum.TCP) {
  75 + // if (
  76 + // //判断TCP下发类型是否是自定义还是服务
  77 + // commandType === CommandTypeEnum.CUSTOM.toString() ||
  78 + // commandType == CommandTypeEnum.SERVICE.toString()
  79 + // ) {
  80 + // values.customCommand.command = unref(checked) ? openCommand : closeCommand;
  81 + // }
  82 + // if (
  83 + // //判断命令下发类型是不是属性
  84 + // commandType === CommandTypeEnum.ATTRIBUTE.toString() &&
  85 + // codeType === TaskTypeEnum.MODBUS_RTU
  86 + // ) {
  87 + // isModbusCommand.value = true;
  88 + // modBUS.value = {
  89 + // crc: 'CRC_16_LOWER',
  90 + // deviceCode: deviceCode,
  91 + // method: actionType == '16' ? '10' : actionType,
  92 + // registerAddress,
  93 + // registerNumber: 1,
  94 + // registerValues: [Number(unref(checked))],
  95 + // };
  96 + // sendValue.value = await genModbusCommand(unref(modBUS));
  97 + // }
  98 + // }
  99 +
  100 + const flag = await sendCommand(
  101 + values,
  102 + isModbusCommand ? sendValue : unref(checked),
  103 + isModbusCommand
  104 + );
35 105 if (!flag) checked.value = !unref(checked);
36 106 };
37 107
... ...
... ... @@ -32,6 +32,10 @@
32 32 transportType: value.transportType,
33 33 service: value.service,
34 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 39 commandType: value.commandType,
36 40 callType: value.callType,
37 41 },
... ... @@ -45,6 +49,10 @@
45 49 ...record,
46 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 51 service: customCommand?.service || (record as Recordable).service,
  52 + openService: customCommand?.openService || (record as Recordable).openService,
  53 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  54 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  55 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
48 56 command: customCommand?.command || (record as Recordable).command,
49 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 58 callType: customCommand?.callType || (record as Recordable).callType,
... ...
... ... @@ -2,12 +2,13 @@
2 2 import { ComponentPropsConfigType } from '/@/views/visual/packages/index.type';
3 3 import { option } from './config';
4 4 import { Spin } from 'ant-design-vue';
5   - import { computed, ref } from 'vue';
  5 + import { computed, ref, unref } from 'vue';
6 6 import { useComponentScale } from '../../../hook/useComponentScale';
7 7 import { useSendCommand } from '../../../hook/useSendCommand';
8 8 import { DeviceName } from '/@/views/visual/commonComponents/DeviceName';
9 9 import { DataFetchUpdateFn } from '../../../hook/socket/useSocket.type';
10 10 import { useDataFetch } from '../../../hook/socket/useSocket';
  11 + import { getSendValues } from '../config';
11 12
12 13 const props = defineProps<{
13 14 config: ComponentPropsConfigType<typeof option>;
... ... @@ -19,9 +20,23 @@
19 20
20 21 const getDesign = computed(() => {
21 22 const { option } = props.config;
22   - const { attribute, attributeRename, attributeName } = option;
  23 + const {
  24 + attribute,
  25 + attributeRename,
  26 + attributeName,
  27 + commandType,
  28 + extensionDesc,
  29 + codeType,
  30 + deviceCode,
  31 + customCommand,
  32 + } = option;
23 33 return {
24 34 attribute: attributeRename || attributeName || attribute,
  35 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  36 + commandType,
  37 + codeType,
  38 + deviceCode,
  39 + customCommand,
25 40 };
26 41 });
27 42
... ... @@ -29,7 +44,15 @@
29 44 const handleChange = async (event: Event) => {
30 45 const target = event.target as HTMLInputElement;
31 46 const value = target.checked;
32   - const flag = await sendCommand(props.config.option, value);
  47 + const { option } = props.config || {};
  48 +
  49 + const { values, isModbusCommand, sendValue } = await getSendValues(
  50 + option,
  51 + unref(getDesign),
  52 + value
  53 + );
  54 +
  55 + const flag = await sendCommand(values, isModbusCommand ? sendValue : value, isModbusCommand);
33 56 flag ? (currentValue.value = value) : (target.checked = !value);
34 57 };
35 58
... ...
... ... @@ -42,10 +42,10 @@
42 42 const { customCommand } = record;
43 43 return setFieldsValue({
44 44 ...record,
45   - transportType: customCommand?.transportType,
46   - service: customCommand?.service,
47   - command: customCommand?.command,
48   - commandType: customCommand?.commandType,
  45 + transportType: customCommand?.transportType || (record as Recordable).transportType,
  46 + service: customCommand?.service || (record as Recordable).service,
  47 + command: customCommand?.command || (record as Recordable).command,
  48 + commandType: customCommand?.commandType || (record as Recordable).command,
49 49 } as unknown as Partial<CommonDataSourceBindValueType>);
50 50 };
51 51
... ...
... ... @@ -32,6 +32,10 @@
32 32 transportType: value.transportType,
33 33 service: value.service,
34 34 command: value.command,
  35 + openService: value.openService,
  36 + closeService: value.closeService,
  37 + openCommand: value.openCommand,
  38 + closeCommand: value.closeCommand,
35 39 commandType: value.commandType,
36 40 callType: value.callType,
37 41 },
... ... @@ -45,6 +49,10 @@
45 49 ...record,
46 50 transportType: customCommand?.transportType || (record as Recordable).transportType,
47 51 service: customCommand?.service || (record as Recordable).service,
  52 + openService: customCommand?.openService || (record as Recordable).openService,
  53 + closeService: customCommand?.closeService || (record as Recordable).closeService,
  54 + openCommand: customCommand?.openCommand || (record as Recordable).openCommand,
  55 + closeCommand: customCommand?.closeCommand || (record as Recordable).closeCommand,
48 56 command: customCommand?.command || (record as Recordable).command,
49 57 commandType: customCommand?.commandType || (record as Recordable).commandType,
50 58 callType: customCommand?.callType || (record as Recordable).callType,
... ...
... ... @@ -13,6 +13,7 @@
13 13 import { useReceiveMessage } from '../../../hook/useReceiveMessage';
14 14 import { useReceiveValue } from '../../../hook/useReceiveValue';
15 15 import { DataSource } from '/@/views/visual/palette/types';
  16 + import { getSendValues, CommandTypeEnumLIst } from '../config';
16 17
17 18 const props = defineProps<{
18 19 config: ComponentPropsConfigType<typeof option>;
... ... @@ -55,8 +56,19 @@
55 56 return {
56 57 dataSource: dataSource.map((item) => {
57 58 const { fontColor, icon, iconColor, unit, showDeviceName } = item.componentInfo;
58   - const { attribute, attributeRename, attributeName, deviceId, deviceName, deviceRename } =
59   - item;
  59 + const {
  60 + attribute,
  61 + attributeRename,
  62 + attributeName,
  63 + deviceId,
  64 + deviceName,
  65 + deviceRename,
  66 + commandType,
  67 + extensionDesc,
  68 + codeType,
  69 + deviceCode,
  70 + customCommand,
  71 + } = item;
60 72 return {
61 73 unit: unit ?? persetUnit,
62 74 fontColor: fontColor ?? persetFontColor,
... ... @@ -67,6 +79,11 @@
67 79 showDeviceName,
68 80 deviceName: deviceRename || deviceName,
69 81 id: deviceId,
  82 + extensionDesc: extensionDesc ? JSON.parse(extensionDesc) : {},
  83 + commandType,
  84 + codeType,
  85 + deviceCode,
  86 + customCommand,
70 87 };
71 88 }),
72 89 };
... ... @@ -76,7 +93,6 @@
76 93 const handleChange = async (index: number, checked: Boolean) => {
77 94 const { heightPx, itemHeightRatio, itemWidthRatio, mode, widthPx, dataSource } =
78 95 props.config.option;
79   -
80 96 const data = {
81 97 ...dataSource?.[index],
82 98 heightPx,
... ... @@ -85,8 +101,13 @@
85 101 mode,
86 102 widthPx,
87 103 } as DataSource;
  104 + const { values, isModbusCommand, sendValue } = await getSendValues(
  105 + data,
  106 + unref(getDesign).dataSource[index],
  107 + checked
  108 + );
88 109
89   - const flag = await sendCommand(data, checked);
  110 + const flag = await sendCommand(values, isModbusCommand ? sendValue : checked, isModbusCommand);
90 111 if (!flag) controlList.value[index].checked = !checked;
91 112 };
92 113
... ... @@ -135,7 +156,11 @@
135 156 <div
136 157 class="text-gray-500 truncate ml-6"
137 158 :style="{ fontSize: getRatio ? '18px' : getRatio * 18 + 'px' }"
138   - >{{ `${item.deviceName} - ${item.attributeName}` }}</div
  159 + >{{
  160 + `${item.deviceName} - ${
  161 + item.commandType ? CommandTypeEnumLIst[item.commandType].name : item.attributeName
  162 + }`
  163 + }}</div
139 164 >
140 165 </div>
141 166
... ...
  1 +import { ref, unref } from 'vue';
  2 +import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
  3 +import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data';
  4 +import { TaskTypeEnum } from '/@/views/task/center/config';
  5 +import { genModbusCommand } from '/@/api/task';
  6 +
  7 +export const getSendValues = async (option, getDesign, checked) => {
  8 + const values: any = option;
  9 + const isModbusCommand = ref<boolean>(false); //判断是否是TCP设备-> 且设备标识符是modeBUs,切选择是下发命令类型是属性
  10 + const { extensionDesc, commandType, codeType, deviceCode, customCommand } = getDesign || {};
  11 + const { registerAddress, actionType } = extensionDesc || {};
  12 + const { openCommand, closeCommand, transportType } = customCommand || {};
  13 + const modBUS = ref<any>({});
  14 + const sendValue = ref();
  15 + //判断是不是TCP类型设备
  16 + if (transportType === TransportTypeEnum.TCP) {
  17 + if (
  18 + //判断TCP下发类型是否是自定义还是服务
  19 + commandType === CommandTypeEnum.CUSTOM.toString() ||
  20 + commandType == CommandTypeEnum.SERVICE.toString()
  21 + ) {
  22 + values.customCommand.command = checked ? openCommand : closeCommand;
  23 + }
  24 + if (
  25 + //判断命令下发类型是不是属性
  26 + commandType === CommandTypeEnum.ATTRIBUTE.toString() &&
  27 + codeType === TaskTypeEnum.MODBUS_RTU
  28 + ) {
  29 + isModbusCommand.value = true;
  30 + modBUS.value = {
  31 + crc: 'CRC_16_LOWER',
  32 + deviceCode: deviceCode,
  33 + method: actionType == '16' ? '10' : actionType,
  34 + registerAddress,
  35 + registerNumber: 1,
  36 + registerValues: [Number(checked)],
  37 + };
  38 + sendValue.value = await genModbusCommand(unref(modBUS));
  39 + }
  40 + }
  41 +
  42 + return { values, sendValue: unref(sendValue), isModbusCommand: unref(isModbusCommand) };
  43 +};
  44 +
  45 +export const CommandTypeEnumLIst = {
  46 + '0': { CUSTOM: 0, name: '自定义' },
  47 + '1': { CUSTOM: 0, name: '服务' },
  48 + '2': { CUSTOM: 0, name: '属性' },
  49 +};
... ...
... ... @@ -14,6 +14,7 @@ import { OrgTreeSelect } from '/@/views/common/OrgTreeSelect';
14 14 import { TransportTypeEnum } from '/@/views/device/profiles/components/TransportDescript/const';
15 15 import { CommandTypeEnum } from '/@/views/rule/linkedge/config/config.data';
16 16 import { DataActionModeEnum } from '/@/enums/toolEnum';
  17 +import { TaskTypeEnum } from '/@/views/task/center/config';
17 18
18 19 useComponentRegister('OrgTreeSelect', OrgTreeSelect);
19 20
... ... @@ -24,6 +25,7 @@ export interface CommonDataSourceBindValueType extends Record<DataSourceField, s
24 25 command?: string;
25 26 commandType?: string;
26 27 callType?: string;
  28 + [ksy: string]: string | undefined;
27 29 };
28 30 }
29 31
... ... @@ -33,6 +35,7 @@ export enum DataSourceField {
33 35 TRANSPORT_TYPE = 'transportType',
34 36 ORIGINATION_ID = 'organizationId',
35 37 DEVICE_ID = 'deviceId',
  38 + DEVICE_CODE = 'deviceCode', //设备地址码
36 39 DEVICE_PROFILE_ID = 'deviceProfileId',
37 40 ATTRIBUTE = 'attribute',
38 41 ATTRIBUTE_NAME = 'attributeName',
... ... @@ -41,10 +44,15 @@ export enum DataSourceField {
41 44 DEVICE_RENAME = 'deviceRename',
42 45 LONGITUDE_ATTRIBUTE = 'longitudeAttribute',
43 46 LATITUDE_ATTRIBUTE = 'latitudeAttribute',
44   -
  47 + CODE_TYPE = 'codeType',
45 48 COMMAND = 'command',
  49 + OPEN_COMMAND = 'openCommand',
  50 + CLOSE_COMMAND = 'closeCommand',
46 51 COMMAND_TYPE = 'commandType',
47 52 SERVICE = 'service',
  53 + OPEN_SERVICE = 'openService',
  54 + CLOSE_SERVICE = 'closeService',
  55 + EXTENSION_DESC = 'extensionDesc',
48 56 CALL_TYPE = 'callType',
49 57 }
50 58
... ... @@ -72,7 +80,7 @@ const getDeviceService = async (deviceProfileId: string) => {
72 80 const getDeviceAttribute = async (params: DeviceAttributeParams) => {
73 81 try {
74 82 const data = await getDeviceAttributes(params);
75   - if (data) return data.map((item) => ({ label: item.name, value: item.identifier }));
  83 + if (data) return data.map((item) => ({ ...item, label: item.name, value: item.identifier }));
76 84 } catch (error) {}
77 85 return [];
78 86 };
... ... @@ -82,7 +90,6 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
82 90 const isUpdate = unref(mode) === DataActionModeEnum.UPDATE;
83 91 const selectWidgetKeys = useSelectWidgetKeys();
84 92 const category = unref(selectWidgetKeys).categoryKey;
85   -
86 93 return [
87 94 {
88 95 field: DataSourceField.IS_GATEWAY_DEVICE,
... ... @@ -161,6 +168,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
161 168 [DataSourceField.ATTRIBUTE]: null,
162 169 [DataSourceField.ATTRIBUTE_NAME]: null,
163 170 [DataSourceField.TRANSPORT_TYPE]: option[DataSourceField.TRANSPORT_TYPE],
  171 + [DataSourceField.COMMAND_TYPE]: null,
164 172 });
165 173 },
166 174 getPopupContainer: () => document.body,
... ... @@ -228,6 +236,9 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
228 236 onChange(_value, record: MasterDeviceList) {
229 237 setFieldsValue({
230 238 [DataSourceField.DEVICE_NAME]: record?.label,
  239 + [DataSourceField.CODE_TYPE]: record?.codeType,
  240 + [DataSourceField.DEVICE_CODE]: record?.code,
  241 + [DataSourceField.COMMAND_TYPE]: null,
231 242 });
232 243 },
233 244 placeholder: '请选择设备',
... ... @@ -236,19 +247,94 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
236 247 },
237 248 },
238 249 {
  250 + field: DataSourceField.CODE_TYPE,
  251 + component: 'Input',
  252 + label: '设备标识符',
  253 + show: false,
  254 + },
  255 +
  256 + {
  257 + field: DataSourceField.DEVICE_CODE,
  258 + component: 'Input',
  259 + show: false,
  260 + label: '设备地址码',
  261 + },
  262 +
  263 + {
239 264 field: DataSourceField.ATTRIBUTE_NAME,
240 265 component: 'Input',
241 266 label: '属性名',
242 267 show: false,
243 268 },
244 269 {
  270 + field: DataSourceField.COMMAND_TYPE,
  271 + component: 'ApiSelect',
  272 + label: '命令类型',
  273 + defaultValue: CommandTypeEnum.CUSTOM.toString(),
  274 + rules: [{ required: true, message: '请选择命令类型' }],
  275 + colProps: { span: 8 },
  276 + ifShow: ({ model }) => {
  277 + return isControlComponent(category!) && isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]);
  278 + },
  279 + componentProps: ({ formActionType, formModel }) => {
  280 + const { setFieldsValue } = formActionType;
  281 + const { codeType } = formModel || {};
  282 + return {
  283 + // api: findDictItemByCode,
  284 + api: async (params: Recordable) => {
  285 + try {
  286 + const record = await findDictItemByCode(params);
  287 + if (unref(selectWidgetKeys).componentKey == 'LateralNumericalControl') {
  288 + return record.filter(
  289 + (item) => item.itemValue == CommandTypeEnum.ATTRIBUTE.toString()
  290 + );
  291 + }
  292 + if (codeType == TaskTypeEnum.MODBUS_RTU) {
  293 + // setFieldsValue({ [DataSourceField.COMMAND_TYPE]: undefined });
  294 + return record.filter(
  295 + (item) => item.itemValue !== CommandTypeEnum.CUSTOM.toString()
  296 + );
  297 + } else {
  298 + return record.filter(
  299 + (item) => item.itemValue !== CommandTypeEnum.ATTRIBUTE.toString()
  300 + );
  301 + }
  302 + } catch (error) {
  303 + console.log(error);
  304 + return [];
  305 + }
  306 + },
  307 + params: {
  308 + dictCode: 'custom_define',
  309 + },
  310 + labelField: 'itemText',
  311 + valueField: 'itemValue',
  312 + placeholder: '请选择命令类型',
  313 + getPopupContainer: () => document.body,
  314 + onChange() {
  315 + setFieldsValue({
  316 + [DataSourceField.COMMAND]: null,
  317 + [DataSourceField.SERVICE]: null,
  318 + [DataSourceField.OPEN_COMMAND]: null,
  319 + [DataSourceField.CLOSE_COMMAND]: null,
  320 + [DataSourceField.OPEN_SERVICE]: null,
  321 + [DataSourceField.CLOSE_SERVICE]: null,
  322 + [DataSourceField.CALL_TYPE]: null,
  323 + [DataSourceField.ATTRIBUTE]: null,
  324 + });
  325 + },
  326 + };
  327 + },
  328 + },
  329 + {
245 330 field: DataSourceField.ATTRIBUTE,
246 331 component: 'ApiSelect',
247 332 label: '属性',
248 333 colProps: { span: 8 },
249 334 rules: [{ required: true, message: '请选择属性' }],
250 335 ifShow: ({ model }) =>
251   - !(isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]) && isControlComponent(category!)),
  336 + !(isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]) && isControlComponent(category!)) ||
  337 + model[DataSourceField.COMMAND_TYPE] == 2,
252 338 componentProps({ formModel, formActionType }) {
253 339 const { setFieldsValue } = formActionType;
254 340 const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID];
... ... @@ -277,6 +363,16 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
277 363 [DataSourceField.ATTRIBUTE]: null,
278 364 });
279 365 }
  366 +
  367 + if (unref(selectWidgetKeys).componentKey == 'LateralNumericalControl') {
  368 + setFieldsValue({
  369 + [DataSourceField.COMMAND_TYPE]: 2,
  370 + });
  371 + return option.filter(
  372 + (item) =>
  373 + item.detail.dataType.type == 'INT' || item.detail.dataType.type == 'DOUBLE'
  374 + );
  375 + }
280 376 return option;
281 377 }
282 378 } catch (error) {}
... ... @@ -284,53 +380,79 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
284 380 },
285 381 placeholder: '请选择属性',
286 382 getPopupContainer: () => document.body,
287   - onChange(value: string, option: Record<'label' | 'value', string>) {
288   - setFieldsValue({ [DataSourceField.ATTRIBUTE_NAME]: value ? option.label : null });
  383 + onChange(value: string, option: Record<'label' | 'value' | any, string>) {
  384 + setFieldsValue({
  385 + [DataSourceField.ATTRIBUTE_NAME]: value ? option.label : null,
  386 + [DataSourceField.EXTENSION_DESC]: value ? JSON.stringify(option.extensionDesc) : '',
  387 + });
289 388 },
290 389 };
291 390 },
292 391 },
293 392 {
294   - field: DataSourceField.COMMAND_TYPE,
  393 + field: DataSourceField.EXTENSION_DESC,
  394 + component: 'Input',
  395 + show: false,
  396 + label: '扩展描述符',
  397 + },
  398 +
  399 + {
  400 + field: DataSourceField.CALL_TYPE,
  401 + component: 'Input',
  402 + ifShow: false,
  403 + label: 'callType',
  404 + },
  405 + {
  406 + field: DataSourceField.OPEN_SERVICE,
295 407 component: 'ApiSelect',
296   - label: '命令类型',
297   - defaultValue: CommandTypeEnum.CUSTOM.toString(),
298   - rules: [{ required: true, message: '请选择命令类型' }],
  408 + label: '开服务',
299 409 colProps: { span: 8 },
  410 + rules: [{ required: true, message: '请选择开服务' }],
300 411 ifShow: ({ model }) =>
301   - isControlComponent(category!) && isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
302   - componentProps: ({ formActionType }) => {
  412 + isControlComponent(category!) &&
  413 + model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.SERVICE.toString() &&
  414 + isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
  415 + componentProps({ formModel, formActionType }) {
303 416 const { setFieldsValue } = formActionType;
  417 + const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID];
  418 + const transportType = formModel[DataSourceField.TRANSPORT_TYPE];
  419 + if (isUpdate && ![deviceProfileId, transportType].every(Boolean))
  420 + return { placeholder: '请选择开服务', getPopupContainer: () => document.body };
304 421 return {
305   - api: findDictItemByCode,
306   - params: {
307   - dictCode: 'custom_define',
  422 + api: async () => {
  423 + try {
  424 + if (deviceProfileId) {
  425 + const services = await getDeviceService(deviceProfileId);
  426 + const value = formModel[DataSourceField.SERVICE];
  427 + if (value) {
  428 + const selected = services.find((item) => item.value === value);
  429 + selected && setFieldsValue({ [DataSourceField.CALL_TYPE]: selected.callType });
  430 + }
  431 + return services;
  432 + }
  433 + } catch (error) {}
  434 + return [];
308 435 },
309   - labelField: 'itemText',
310   - valueField: 'itemValue',
311   - placeholder: '请选择命令类型',
312   - onChange() {
  436 + placeholder: '请选择开服务',
  437 + getPopupContainer: () => document.body,
  438 + onChange(value: string, options: ModelOfMatterParams) {
  439 + const command = value
  440 + ? (options.functionJson.inputData || [])[0]?.serviceCommand
  441 + : null;
313 442 setFieldsValue({
314   - [DataSourceField.COMMAND]: null,
315   - [DataSourceField.SERVICE]: null,
316   - [DataSourceField.CALL_TYPE]: null,
  443 + [DataSourceField.OPEN_COMMAND]: command,
  444 + [DataSourceField.CALL_TYPE]: value ? options.callType : null,
317 445 });
318 446 },
319 447 };
320 448 },
321 449 },
322 450 {
323   - field: DataSourceField.CALL_TYPE,
324   - component: 'Input',
325   - ifShow: false,
326   - label: 'callType',
327   - },
328   - {
329   - field: DataSourceField.SERVICE,
  451 + field: DataSourceField.CLOSE_SERVICE,
330 452 component: 'ApiSelect',
331   - label: '服务',
  453 + label: '服务',
332 454 colProps: { span: 8 },
333   - rules: [{ required: true, message: '请选择服务' }],
  455 + rules: [{ required: true, message: '请选择服务' }],
334 456 ifShow: ({ model }) =>
335 457 isControlComponent(category!) &&
336 458 model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.SERVICE.toString() &&
... ... @@ -340,7 +462,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
340 462 const deviceProfileId = formModel[DataSourceField.DEVICE_PROFILE_ID];
341 463 const transportType = formModel[DataSourceField.TRANSPORT_TYPE];
342 464 if (isUpdate && ![deviceProfileId, transportType].every(Boolean))
343   - return { placeholder: '请选择服务', getPopupContainer: () => document.body };
  465 + return { placeholder: '请选择服务', getPopupContainer: () => document.body };
344 466 return {
345 467 api: async () => {
346 468 try {
... ... @@ -356,14 +478,14 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
356 478 } catch (error) {}
357 479 return [];
358 480 },
359   - placeholder: '请选择服务',
  481 + placeholder: '请选择服务',
360 482 getPopupContainer: () => document.body,
361 483 onChange(value: string, options: ModelOfMatterParams) {
362 484 const command = value
363 485 ? (options.functionJson.inputData || [])[0]?.serviceCommand
364 486 : null;
365 487 setFieldsValue({
366   - [DataSourceField.COMMAND]: command,
  488 + [DataSourceField.CLOSE_COMMAND]: command,
367 489 [DataSourceField.CALL_TYPE]: value ? options.callType : null,
368 490 });
369 491 },
... ... @@ -371,11 +493,27 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
371 493 },
372 494 },
373 495 {
374   - field: DataSourceField.COMMAND,
  496 + field: DataSourceField.OPEN_COMMAND,
  497 + component: 'Input',
  498 + label: '命令',
  499 + colProps: { span: 8 },
  500 + rules: [{ required: true, message: '请输入开下发命令' }],
  501 + // 是控制组件 && 自定义命令 && 传输协议为TCP
  502 + ifShow: ({ model }) =>
  503 + isControlComponent(category!) &&
  504 + model[DataSourceField.COMMAND_TYPE] === CommandTypeEnum.CUSTOM.toString() &&
  505 + model[DataSourceField.TRANSPORT_TYPE] &&
  506 + isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
  507 + componentProps: {
  508 + placeholder: '请输入开下发命令',
  509 + },
  510 + },
  511 + {
  512 + field: DataSourceField.CLOSE_COMMAND,
375 513 component: 'Input',
376 514 label: '命令',
377 515 colProps: { span: 8 },
378   - rules: [{ required: true, message: '请输入下发命令' }],
  516 + rules: [{ required: true, message: '请输入下发命令' }],
379 517 // 是控制组件 && 自定义命令 && 传输协议为TCP
380 518 ifShow: ({ model }) =>
381 519 isControlComponent(category!) &&
... ... @@ -383,7 +521,7 @@ export const commonDataSourceSchemas = (): FormSchema[] => {
383 521 model[DataSourceField.TRANSPORT_TYPE] &&
384 522 isTcpProfile(model[DataSourceField.TRANSPORT_TYPE]),
385 523 componentProps: {
386   - placeholder: '请输入下发命令',
  524 + placeholder: '请输入下发命令',
387 525 },
388 526 },
389 527 {
... ...
... ... @@ -14,7 +14,7 @@ export function useSendCommand() {
14 14 return false;
15 15 };
16 16
17   - const sendCommand = async (record: DataSource, value: any) => {
  17 + const sendCommand = async (record: DataSource, value: any, isModbusCommand = false) => {
18 18 if (!record) return false;
19 19 const { customCommand, attribute } = record || {};
20 20 const { deviceId } = record;
... ... @@ -25,16 +25,18 @@ export function useSendCommand() {
25 25 let params: string | Recordable = {
26 26 [attribute!]: Number(value),
27 27 };
  28 + if (isModbusCommand) {
  29 + params = value;
  30 + }
28 31
29 32 let sendCommandFn = sendCommandOneway;
30 33 // 如果是TCP设备从物模型中获取下发命令(TCP网关子设备无物模型服务与事件)
31   - if (customCommand?.transportType === TransportTypeEnum.TCP) {
  34 + if (customCommand?.transportType === TransportTypeEnum.TCP && !isModbusCommand) {
32 35 params = customCommand.command!;
33 36 if (customCommand.callType === ServiceCallTypeEnum.SYNC) {
34 37 sendCommandFn = sendCommandTwoway;
35 38 }
36 39 }
37   -
38 40 // 控制按钮下发命令为0 或 1
39 41 await sendCommandFn({
40 42 deviceId,
... ...
... ... @@ -28,6 +28,7 @@ export interface DataSource {
28 28 componentInfo: ComponentInfo;
29 29 customCommand: CustomCommand;
30 30 videoConfig?: VideoConfigType;
  31 + [key: string]: any;
31 32 }
32 33
33 34 export interface ExtraDataSource extends DataSource, PublicComponentOptions {
... ... @@ -71,6 +72,7 @@ export interface CustomCommand {
71 72 command: string;
72 73 service: string;
73 74 callType: string;
  75 + [key: string]: string | undefined;
74 76 }
75 77
76 78 export interface ComponentLayoutType {
... ...