Commit 1b2f1b0047ffb71c27ae947b0fb5a953bba8dc0b
Merge branch 'perf/device-create-add-code-type-field' into 'main_dev'
fix: 修复设备创建新增codeType字段 See merge request yunteng/thingskit-front!757
Showing
7 changed files
with
203 additions
and
70 deletions
| ... | ... | @@ -10,6 +10,9 @@ import { ModelOfMatterParams } from '/@/api/device/model/modelOfMatterModel'; |
| 10 | 10 | import { 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 | +import { TaskTypeEnum } from '/@/views/task/center/config'; | |
| 14 | +import { AddressTypeEnum } from '/@/views/task/center/components/PollCommandInput'; | |
| 15 | + | |
| 13 | 16 | useComponentRegister('JSONEditor', JSONEditor); |
| 14 | 17 | useComponentRegister('ObjectModelValidateForm', ObjectModelValidateForm); |
| 15 | 18 | |
| ... | ... | @@ -17,6 +20,7 @@ export enum TypeEnum { |
| 17 | 20 | IS_GATEWAY = 'GATEWAY', |
| 18 | 21 | SENSOR = 'SENSOR', |
| 19 | 22 | } |
| 23 | + | |
| 20 | 24 | export const isGateWay = (type: string) => { |
| 21 | 25 | return type === TypeEnum.IS_GATEWAY; |
| 22 | 26 | }; |
| ... | ... | @@ -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 | 171 | field: 'code', |
| 116 | - label: '设备标识/地址码', | |
| 172 | + label: '设备标识', | |
| 117 | 173 | dynamicRules({ values }) { |
| 118 | 174 | return [ |
| 119 | 175 | { |
| ... | ... | @@ -125,15 +181,17 @@ export const step1Schemas: FormSchema[] = [ |
| 125 | 181 | ]; |
| 126 | 182 | }, |
| 127 | 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 | 196 | field: 'brand', |
| 139 | 197 | component: 'ApiRadioGroup', | ... | ... |
| ... | ... | @@ -127,6 +127,7 @@ |
| 127 | 127 | import { copyTransFun } from '/@/utils/fnUtils'; |
| 128 | 128 | import { useDrawer } from '/@/components/Drawer'; |
| 129 | 129 | import DeptDrawer from '/@/views/system/organization/OrganizationDrawer.vue'; |
| 130 | + import { TaskTypeEnum } from '/@/views/task/center/config'; | |
| 130 | 131 | |
| 131 | 132 | export default defineComponent({ |
| 132 | 133 | components: { |
| ... | ... | @@ -385,11 +386,21 @@ |
| 385 | 386 | positionState.latitude = deviceInfo.latitude; |
| 386 | 387 | positionState.address = deviceInfo.address; |
| 387 | 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 | 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 | 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 | 188 | disabled: transportType ? transportType && transportType !== PushWayEnum.TCP : true, |
| 189 | 189 | }, |
| 190 | 190 | ], |
| ... | ... | @@ -240,7 +240,7 @@ export const formSchemas: FormSchema[] = [ |
| 240 | 240 | label: 'ModbusRTU轮询', |
| 241 | 241 | rules: [{ required: true, message: '请输入Modbus RTU 轮询指令' }], |
| 242 | 242 | ifShow: ({ model }) => |
| 243 | - model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS_RTU && | |
| 243 | + model[FormFieldsEnum.EXECUTE_CONTENT_TYPE] === TaskTypeEnum.MODBUS && | |
| 244 | 244 | model[FormFieldsEnum.PUSH_WAY] === PushWayEnum.TCP, |
| 245 | 245 | valueField: 'value', |
| 246 | 246 | changeEvent: 'update:value', | ... | ... |
| 1 | 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 | 6 | enum AddressTypeEnum { |
| 8 | 7 | DEC = 'DEC', |
| 9 | 8 | HEX = 'HEX', |
| 10 | 9 | } |
| 11 | - | |
| 12 | 10 | const emit = defineEmits(['update:value']); |
| 13 | 11 | |
| 14 | - const DEC_MAX_VALUE = parseInt('0xffff', 16); | |
| 15 | - | |
| 16 | 12 | const props = withDefaults( |
| 17 | 13 | defineProps<{ |
| 18 | 14 | value?: number | string; |
| 19 | - inputProps?: Recordable; | |
| 20 | 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 | 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 | 79 | const addressTypeOptions = [ |
| 29 | 80 | { label: AddressTypeEnum.DEC, value: AddressTypeEnum.DEC }, |
| 30 | 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 | 139 | </script> |
| 74 | 140 | |
| 75 | 141 | <template> |
| 76 | 142 | <InputGroup compact class="!flex"> |
| 77 | 143 | <Select |
| 78 | - v-model:value="type" | |
| 144 | + v-model:value="inputType" | |
| 79 | 145 | :options="addressTypeOptions" |
| 80 | - @change="handleChange" | |
| 81 | 146 | :disabled="disabled" |
| 82 | 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 | 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 | 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 | 158 | </div> |
| 98 | 159 | </InputGroup> |
| 99 | 160 | </template> | ... | ... |
| 1 | 1 | import { findDictItemByCode } from '/@/api/system/dict'; |
| 2 | 2 | import { FormSchema, useComponentRegister } from '/@/components/Form'; |
| 3 | 3 | import { DictEnum } from '/@/enums/dictEnum'; |
| 4 | -import RegisterAddressInput from './RegisterAddressInput.vue'; | |
| 5 | 4 | import { createPickerSearch } from '/@/utils/pickerSearch'; |
| 6 | 5 | import { ControlGroup } from '../ControlGroup'; |
| 7 | 6 | |
| 7 | +useComponentRegister('ControlGroup', ControlGroup); | |
| 8 | + | |
| 8 | 9 | export enum FormFieldsEnum { |
| 9 | 10 | // 设备地址码 |
| 10 | 11 | DEVICE_CODE = 'deviceCode', |
| ... | ... | @@ -28,9 +29,6 @@ export enum FormFieldsEnum { |
| 28 | 29 | REGISTER_VALUES = 'registerValues', |
| 29 | 30 | } |
| 30 | 31 | |
| 31 | -useComponentRegister('RegisterAddressInput', RegisterAddressInput); | |
| 32 | -useComponentRegister('ControlGroup', ControlGroup); | |
| 33 | - | |
| 34 | 32 | export enum FunctionCodeEnum { |
| 35 | 33 | // 读取线圈状态01 |
| 36 | 34 | READ_COIL_STATE_01 = '01', | ... | ... |
| ... | ... | @@ -27,11 +27,11 @@ export enum TaskTargetNameEnum { |
| 27 | 27 | |
| 28 | 28 | export enum TaskTypeEnum { |
| 29 | 29 | CUSTOM = 'CUSTOM', |
| 30 | - MODBUS_RTU = 'MODBUS_RTU', | |
| 30 | + MODBUS = 'MODBUS', | |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | export enum TaskTypeNameEnum { |
| 34 | - MODBUS_RTU = 'MODBUS_RTU轮询', | |
| 34 | + MODBUS = 'MODBUS_RTU轮询', | |
| 35 | 35 | CUSTOM = '自定义数据下发', |
| 36 | 36 | } |
| 37 | 37 | ... | ... |