Commit 1b2f1b0047ffb71c27ae947b0fb5a953bba8dc0b

Authored by xp.Huang
2 parents 74283102 dde63339

Merge branch 'perf/device-create-add-code-type-field' into 'main_dev'

fix: 修复设备创建新增codeType字段

See merge request yunteng/thingskit-front!757
@@ -10,6 +10,9 @@ import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; @@ -10,6 +10,9 @@ import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel';
10 import { toRaw, unref } from 'vue'; 10 import { toRaw, unref } from 'vue';
11 import ObjectModelValidateForm from '/@/components/Form/src/externalCompns/components/ObjectModelValidateForm/ObjectModelValidateForm.vue'; 11 import ObjectModelValidateForm from '/@/components/Form/src/externalCompns/components/ObjectModelValidateForm/ObjectModelValidateForm.vue';
12 import { CommandDeliveryWayEnum, ServiceCallTypeEnum } from '/@/enums/toolEnum'; 12 import { CommandDeliveryWayEnum, ServiceCallTypeEnum } from '/@/enums/toolEnum';
  13 +import { TaskTypeEnum } from '/@/views/task/center/config';
  14 +import { AddressTypeEnum } from '/@/views/task/center/components/PollCommandInput';
  15 +
13 useComponentRegister('JSONEditor', JSONEditor); 16 useComponentRegister('JSONEditor', JSONEditor);
14 useComponentRegister('ObjectModelValidateForm', ObjectModelValidateForm); 17 useComponentRegister('ObjectModelValidateForm', ObjectModelValidateForm);
15 18
@@ -17,6 +20,7 @@ export enum TypeEnum { @@ -17,6 +20,7 @@ export enum TypeEnum {
17 IS_GATEWAY = 'GATEWAY', 20 IS_GATEWAY = 'GATEWAY',
18 SENSOR = 'SENSOR', 21 SENSOR = 'SENSOR',
19 } 22 }
  23 +
20 export const isGateWay = (type: string) => { 24 export const isGateWay = (type: string) => {
21 return type === TypeEnum.IS_GATEWAY; 25 return type === TypeEnum.IS_GATEWAY;
22 }; 26 };
@@ -112,8 +116,60 @@ export const step1Schemas: FormSchema[] = [ @@ -112,8 +116,60 @@ export const step1Schemas: FormSchema[] = [
112 }, 116 },
113 }, 117 },
114 { 118 {
  119 + field: 'codeType',
  120 + label: '标识符类型',
  121 + component: 'Select',
  122 + dynamicRules({ values }) {
  123 + return [
  124 + {
  125 + required:
  126 + (values?.transportType === TransportTypeEnum.TCP &&
  127 + values?.deviceType === DeviceTypeEnum.SENSOR) ||
  128 + values?.deviceType === DeviceTypeEnum.GATEWAY,
  129 + message: '请输入设备标识符',
  130 + },
  131 + ];
  132 + },
  133 + ifShow: ({ values }) =>
  134 + values?.transportType === TransportTypeEnum.TCP &&
  135 + (values.deviceType === DeviceTypeEnum.SENSOR || values.deviceType === DeviceTypeEnum.GATEWAY),
  136 + componentProps: ({}) => {
  137 + return {
  138 + options: [
  139 + { label: '自定义', value: TaskTypeEnum.CUSTOM },
  140 + { label: 'ModBus', value: TaskTypeEnum.MODBUS },
  141 + ],
  142 + };
  143 + },
  144 + },
  145 + {
  146 + field: 'addressCode',
  147 + label: '地址码',
  148 + dynamicRules({ values }) {
  149 + return [
  150 + {
  151 + required:
  152 + values?.transportType === TransportTypeEnum.TCP &&
  153 + values?.deviceType === DeviceTypeEnum.SENSOR,
  154 + message: '请输入设备地址码',
  155 + },
  156 + ];
  157 + },
  158 + component: 'RegisterAddressInput',
  159 + changeEvent: 'update:value',
  160 + valueField: 'value',
  161 + componentProps: {
  162 + type: AddressTypeEnum.HEX,
  163 + maxValue: Number(247).toString(16),
  164 + minValue: 0,
  165 + },
  166 + ifShow: ({ values }) => {
  167 + return values?.codeType === TaskTypeEnum.MODBUS;
  168 + },
  169 + },
  170 + {
115 field: 'code', 171 field: 'code',
116 - label: '设备标识/地址码', 172 + label: '设备标识',
117 dynamicRules({ values }) { 173 dynamicRules({ values }) {
118 return [ 174 return [
119 { 175 {
@@ -125,15 +181,17 @@ export const step1Schemas: FormSchema[] = [ @@ -125,15 +181,17 @@ export const step1Schemas: FormSchema[] = [
125 ]; 181 ];
126 }, 182 },
127 component: 'Input', 183 component: 'Input',
128 - componentProps: {  
129 - maxLength: 255,  
130 - placeholder: '请输入设备标识或设备地址码', 184 + componentProps: () => {
  185 + return {
  186 + maxLength: 255,
  187 + placeholder: '请输入设备标识或设备地址码',
  188 + };
  189 + },
  190 + ifShow: ({ values }) => {
  191 + return values?.codeType === TaskTypeEnum.CUSTOM;
131 }, 192 },
132 - helpMessage: ['标准Modbus地址码值为16进制1-247值', '其他协议自定义'],  
133 - ifShow: ({ values }) =>  
134 - values?.transportType === TransportTypeEnum.TCP &&  
135 - (values.deviceType === DeviceTypeEnum.SENSOR || values.deviceType === DeviceTypeEnum.GATEWAY),  
136 }, 193 },
  194 +
137 { 195 {
138 field: 'brand', 196 field: 'brand',
139 component: 'ApiRadioGroup', 197 component: 'ApiRadioGroup',
@@ -127,6 +127,7 @@ @@ -127,6 +127,7 @@
127 import { copyTransFun } from '/@/utils/fnUtils'; 127 import { copyTransFun } from '/@/utils/fnUtils';
128 import { useDrawer } from '/@/components/Drawer'; 128 import { useDrawer } from '/@/components/Drawer';
129 import DeptDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; 129 import DeptDrawer from '/@/views/system/organization/OrganizationDrawer.vue';
  130 + import { TaskTypeEnum } from '/@/views/task/center/config';
130 131
131 export default defineComponent({ 132 export default defineComponent({
132 components: { 133 components: {
@@ -385,11 +386,21 @@ @@ -385,11 +386,21 @@
385 positionState.latitude = deviceInfo.latitude; 386 positionState.latitude = deviceInfo.latitude;
386 positionState.address = deviceInfo.address; 387 positionState.address = deviceInfo.address;
387 devicePic.value = deviceInfo.avatar; 388 devicePic.value = deviceInfo.avatar;
388 - setFieldsValue(data); 389 + setFieldsValue({
  390 + ...data,
  391 + code: data?.code,
  392 + deviceCode: data?.code,
  393 + });
389 } 394 }
390 // 父组件调用获取字段值的方法 395 // 父组件调用获取字段值的方法
391 function parentGetFieldsValue() { 396 function parentGetFieldsValue() {
392 - return getFieldsValue(); 397 + const value = getFieldsValue();
  398 + return {
  399 + ...value,
  400 + ...(value?.code || value?.deviceCode
  401 + ? { code: value?.codeType === TaskTypeEnum.CUSTOM ? value?.code : value?.deviceCode }
  402 + : {}),
  403 + };
393 } 404 }
394 405
395 // 父组件调用表单验证 406 // 父组件调用表单验证
@@ -183,8 +183,8 @@ export const formSchemas: FormSchema[] = [ @@ -183,8 +183,8 @@ export const formSchemas: FormSchema[] = [
183 value: TaskTypeEnum.CUSTOM, 183 value: TaskTypeEnum.CUSTOM,
184 }, 184 },
185 { 185 {
186 - label: TaskTypeNameEnum.MODBUS_RTU,  
187 - value: TaskTypeEnum.MODBUS_RTU, 186 + label: TaskTypeNameEnum.MODBUS,
  187 + value: TaskTypeEnum.MODBUS,
188 disabled: transportType ? transportType && transportType !== PushWayEnum.TCP : true, 188 disabled: transportType ? transportType && transportType !== PushWayEnum.TCP : true,
189 }, 189 },
190 ], 190 ],
@@ -240,7 +240,7 @@ export const formSchemas: FormSchema[] = [ @@ -240,7 +240,7 @@ export const formSchemas: FormSchema[] = [
240 label: 'ModbusRTU轮询', 240 label: 'ModbusRTU轮询',
241 rules: [{ required: true, message: '请输入Modbus RTU 轮询指令' }], 241 rules: [{ required: true, message: '请输入Modbus RTU 轮询指令' }],
242 ifShow: ({ model }) => 242 ifShow: ({ model }) =>
243 - model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS_RTU && 243 + model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS &&
244 model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.TCP, 244 model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.TCP,
245 valueField: 'value', 245 valueField: 'value',
246 changeEvent: 'update:value', 246 changeEvent: 'update:value',
1 <script lang="ts" setup> 1 <script lang="ts" setup>
2 - import { InputGroup, InputNumber, Select, Input } from 'ant-design-vue';  
3 - import { unref, watch } from 'vue';  
4 - import { computed } from 'vue';  
5 - import { ref } from 'vue'; 2 + import { Select, InputGroup, Input } from 'ant-design-vue';
  3 + import { ref, unref, computed } from 'vue';
  4 + import { isNullOrUnDef } from '/@/utils/is';
6 5
7 enum AddressTypeEnum { 6 enum AddressTypeEnum {
8 DEC = 'DEC', 7 DEC = 'DEC',
9 HEX = 'HEX', 8 HEX = 'HEX',
10 } 9 }
11 -  
12 const emit = defineEmits(['update:value']); 10 const emit = defineEmits(['update:value']);
13 11
14 - const DEC_MAX_VALUE = parseInt('0xffff', 16);  
15 -  
16 const props = withDefaults( 12 const props = withDefaults(
17 defineProps<{ 13 defineProps<{
18 value?: number | string; 14 value?: number | string;
19 - inputProps?: Recordable;  
20 disabled?: boolean; 15 disabled?: boolean;
  16 + maxValue?: number | string;
  17 + minValue?: number | string;
  18 + type?: AddressTypeEnum;
  19 + toUpperCase?: boolean;
21 }>(), 20 }>(),
22 { 21 {
23 - value: 0,  
24 inputProps: () => ({}), 22 inputProps: () => ({}),
  23 + type: AddressTypeEnum.DEC,
  24 + maxValue: parseInt('FFFF', 16),
  25 + minValue: 0,
  26 + toUpperCase: true,
25 } 27 }
26 ); 28 );
27 29
  30 + const maxHexPadLength = computed(() => {
  31 + const { maxValue, type } = props;
  32 + if (type === AddressTypeEnum.DEC) {
  33 + return Number(maxValue).toString(16).length;
  34 + } else {
  35 + return maxValue.toString().length;
  36 + }
  37 + });
  38 +
  39 + const inputType = ref(props.type);
  40 +
  41 + const getInputValue = computed(() => {
  42 + const { type, value, toUpperCase } = props;
  43 +
  44 + if (isNullOrUnDef(value)) return value;
  45 +
  46 + if (type === AddressTypeEnum.DEC) {
  47 + if (unref(inputType) === AddressTypeEnum.DEC) {
  48 + return Number(value);
  49 + } else {
  50 + const _value = Number(value).toString(16);
  51 + return toUpperCase ? _value.toUpperCase() : _value;
  52 + }
  53 + } else {
  54 + if (unref(inputType) === AddressTypeEnum.DEC) {
  55 + return parseInt(value, 16);
  56 + } else {
  57 + return toUpperCase ? value.toString().toUpperCase() : value;
  58 + }
  59 + }
  60 + });
  61 +
  62 + const getValueOpposite = computed(() => {
  63 + if (isNullOrUnDef(unref(getInputValue))) {
  64 + if (unref(inputType) === AddressTypeEnum.DEC) {
  65 + return `0x${decToHex(props.minValue).padStart(unref(maxHexPadLength), '0').toUpperCase()}`;
  66 + } else {
  67 + return hexToDec(props.minValue);
  68 + }
  69 + }
  70 +
  71 + if (unref(inputType) === AddressTypeEnum.DEC)
  72 + return `0x${decToHex(unref(getInputValue)!)
  73 + .toString()
  74 + .padStart(unref(maxHexPadLength), '0')
  75 + .toUpperCase()}`;
  76 + else return hexToDec(unref(getInputValue)!);
  77 + });
  78 +
28 const addressTypeOptions = [ 79 const addressTypeOptions = [
29 { label: AddressTypeEnum.DEC, value: AddressTypeEnum.DEC }, 80 { label: AddressTypeEnum.DEC, value: AddressTypeEnum.DEC },
30 { label: AddressTypeEnum.HEX, value: AddressTypeEnum.HEX }, 81 { label: AddressTypeEnum.HEX, value: AddressTypeEnum.HEX },
31 ]; 82 ];
32 83
33 - const type = ref(AddressTypeEnum.DEC); 84 + const getValueByInputType = (value: string | number) => {
  85 + let { type, toUpperCase, maxValue, minValue } = props;
34 86
35 - const inputValue = ref<number | string>(props.value); 87 + if (type === AddressTypeEnum.DEC) {
  88 + if (unref(inputType) === AddressTypeEnum.HEX) {
  89 + value = hexToDec(value);
  90 + }
  91 + value = Number(value);
  92 + maxValue = Number(maxValue);
  93 + minValue = Number(minValue);
  94 + value = value > maxValue ? maxValue : value;
  95 + value = value < minValue ? minValue : value;
  96 + } else {
  97 + if (unref(inputType) === AddressTypeEnum.DEC) {
  98 + value = decToHex(value);
  99 + }
36 100
37 - const getHexValue = computed(() => {  
38 - return parseInt(unref(inputValue) || 0, 16);  
39 - }); 101 + const _maxValue = parseInt(maxValue, 16);
  102 + const _minValue = parseInt(minValue, 16);
40 103
41 - const getDecValue = computed(() => {  
42 - let formatValue = Number(unref(inputValue) || 0).toString(16);  
43 - formatValue = `0x${formatValue.padStart(4, '0')}`;  
44 - return (inputValue.value as number) > DEC_MAX_VALUE ? '0x0000' : formatValue;  
45 - }); 104 + value = parseInt(value, 16) > _maxValue ? maxValue : value;
  105 + value = parseInt(value, 16) < _minValue ? minValue : value;
46 106
47 - const toDEC = (value: number | string) => {  
48 - return unref(type) === AddressTypeEnum.DEC  
49 - ? isNaN(value as number)  
50 - ? 0  
51 - : Number(value)  
52 - : parseInt(value, 16);  
53 - }; 107 + value = toUpperCase ? value.toString().toUpperCase() : value;
  108 + }
54 109
55 - const handleEmit = () => {  
56 - const syncValue = toDEC(unref(inputValue));  
57 - emit('update:value', syncValue); 110 + return value;
58 }; 111 };
59 112
60 - const handleChange = (value: AddressTypeEnum) => {  
61 - const syncValue = value === AddressTypeEnum.DEC ? unref(getHexValue) : unref(getDecValue);  
62 - inputValue.value = syncValue;  
63 - emit('update:value', toDEC(syncValue)); 113 + const validate = (value: string | number) => {
  114 + if (unref(inputType) === AddressTypeEnum.DEC) {
  115 + return /^[1-9]\d*$/.test(value.toString());
  116 + } else {
  117 + return /(0x)?[0-9a-fA-F]+/.test(value.toString());
  118 + }
64 }; 119 };
65 120
66 - const stop = watch(  
67 - () => props.value,  
68 - (value) => {  
69 - inputValue.value = value;  
70 - stop(); 121 + const handleSyncValue = (event: ChangeEvent) => {
  122 + const value = (event.target as HTMLInputElement).value;
  123 + if (isNullOrUnDef(value) || value === '') {
  124 + emit('update:value', null);
  125 + return;
71 } 126 }
72 - ); 127 + if (!validate(value)) return;
  128 + const syncValue = getValueByInputType(value);
  129 + emit('update:value', syncValue);
  130 + };
  131 +
  132 + function decToHex(value: number | string) {
  133 + return Number(value).toString(16);
  134 + }
  135 +
  136 + function hexToDec(value: number | string) {
  137 + return parseInt(value, 16);
  138 + }
73 </script> 139 </script>
74 140
75 <template> 141 <template>
76 <InputGroup compact class="!flex"> 142 <InputGroup compact class="!flex">
77 <Select 143 <Select
78 - v-model:value="type" 144 + v-model:value="inputType"
79 :options="addressTypeOptions" 145 :options="addressTypeOptions"
80 - @change="handleChange"  
81 :disabled="disabled" 146 :disabled="disabled"
82 class="bg-gray-200 max-w-20" 147 class="bg-gray-200 max-w-20"
83 /> 148 />
84 - <InputNumber  
85 - v-if="type === AddressTypeEnum.DEC"  
86 - v-model:value="inputValue"  
87 - :step="1"  
88 - class="flex-1" 149 +
  150 + <Input
  151 + :value="getInputValue"
  152 + @change="handleSyncValue"
89 :disabled="disabled" 153 :disabled="disabled"
90 - v-bind="inputProps"  
91 - @change="handleEmit" 154 + :placeholder="`请输入${inputType === AddressTypeEnum.DEC ? '十进制' : '十六进制'}设备地址码`"
92 /> 155 />
93 - <Input v-if="type === AddressTypeEnum.HEX" v-model:value="inputValue" @change="handleEmit" />  
94 <div class="text-center h-8 leading-8 px-2 bg-gray-200 cursor-pointer rounded-1 w-20"> 156 <div class="text-center h-8 leading-8 px-2 bg-gray-200 cursor-pointer rounded-1 w-20">
95 - <div v-if="type === AddressTypeEnum.DEC">{{ getDecValue }}</div>  
96 - <div v-if="type === AddressTypeEnum.HEX">{{ getHexValue }}</div> 157 + <div>{{ getValueOpposite }}</div>
97 </div> 158 </div>
98 </InputGroup> 159 </InputGroup>
99 </template> 160 </template>
1 import { findDictItemByCode } from '/@/api/system/dict'; 1 import { findDictItemByCode } from '/@/api/system/dict';
2 import { FormSchema, useComponentRegister } from '/@/components/Form'; 2 import { FormSchema, useComponentRegister } from '/@/components/Form';
3 import { DictEnum } from '/@/enums/dictEnum'; 3 import { DictEnum } from '/@/enums/dictEnum';
4 -import RegisterAddressInput from './RegisterAddressInput.vue';  
5 import { createPickerSearch } from '/@/utils/pickerSearch'; 4 import { createPickerSearch } from '/@/utils/pickerSearch';
6 import { ControlGroup } from '../ControlGroup'; 5 import { ControlGroup } from '../ControlGroup';
7 6
  7 +useComponentRegister('ControlGroup', ControlGroup);
  8 +
8 export enum FormFieldsEnum { 9 export enum FormFieldsEnum {
9 // 设备地址码 10 // 设备地址码
10 DEVICE_CODE = 'deviceCode', 11 DEVICE_CODE = 'deviceCode',
@@ -28,9 +29,6 @@ export enum FormFieldsEnum { @@ -28,9 +29,6 @@ export enum FormFieldsEnum {
28 REGISTER_VALUES = 'registerValues', 29 REGISTER_VALUES = 'registerValues',
29 } 30 }
30 31
31 -useComponentRegister('RegisterAddressInput', RegisterAddressInput);  
32 -useComponentRegister('ControlGroup', ControlGroup);  
33 -  
34 export enum FunctionCodeEnum { 32 export enum FunctionCodeEnum {
35 // 读取线圈状态01 33 // 读取线圈状态01
36 READ_COIL_STATE_01 = '01', 34 READ_COIL_STATE_01 = '01',
@@ -3,3 +3,8 @@ export enum ModeEnum { @@ -3,3 +3,8 @@ export enum ModeEnum {
3 JSON = 'application/json', 3 JSON = 'application/json',
4 NORMAL = 'normal', 4 NORMAL = 'normal',
5 } 5 }
  6 +
  7 +export enum AddressTypeEnum {
  8 + DEC = 'DEC',
  9 + HEX = 'HEX',
  10 +}
@@ -27,11 +27,11 @@ export enum TaskTargetNameEnum { @@ -27,11 +27,11 @@ export enum TaskTargetNameEnum {
27 27
28 export enum TaskTypeEnum { 28 export enum TaskTypeEnum {
29 CUSTOM = 'CUSTOM', 29 CUSTOM = 'CUSTOM',
30 - MODBUS_RTU = 'MODBUS_RTU', 30 + MODBUS = 'MODBUS',
31 } 31 }
32 32
33 export enum TaskTypeNameEnum { 33 export enum TaskTypeNameEnum {
34 - MODBUS_RTU = 'MODBUS_RTU轮询', 34 + MODBUS = 'MODBUS_RTU轮询',
35 CUSTOM = '自定义数据下发', 35 CUSTOM = '自定义数据下发',
36 } 36 }
37 37