Showing
6 changed files
with
266 additions
and
7 deletions
... | ... | @@ -40,6 +40,7 @@ import StructForm from './externalCompns/components/StructForm/StructForm.vue'; |
40 | 40 | import ApiSelectScrollLoad from './components/ApiSelectScrollLoad.vue'; |
41 | 41 | import TransferModal from './components/TransferModal.vue'; |
42 | 42 | import TransferTableModal from './components/TransferTableModal.vue'; |
43 | +import ObjectModelValidateForm from './externalCompns/components/ObjectModelValidateForm/ObjectModelValidateForm.vue'; | |
43 | 44 | |
44 | 45 | const componentMap = new Map<ComponentType, Component>(); |
45 | 46 | |
... | ... | @@ -87,6 +88,7 @@ componentMap.set('StructForm', StructForm); |
87 | 88 | componentMap.set('ApiSelectScrollLoad', ApiSelectScrollLoad); |
88 | 89 | componentMap.set('TransferModal', TransferModal); |
89 | 90 | componentMap.set('TransferTableModal', TransferTableModal); |
91 | +componentMap.set('ObjectModelValidateForm', ObjectModelValidateForm); | |
90 | 92 | |
91 | 93 | export function add(compName: ComponentType, component: Component) { |
92 | 94 | componentMap.set(compName, component); | ... | ... |
1 | +<script lang="ts" setup> | |
2 | + import { Card } from 'ant-design-vue'; | |
3 | + import { nextTick, onBeforeUpdate, onUpdated } from 'vue'; | |
4 | + import { DataTypeEnum } from '../StructForm/config'; | |
5 | + import { BasicCreateFormParams } from './type'; | |
6 | + import { DynamicProps } from '/#/utils'; | |
7 | + import { Specs, StructJSON } from '/@/api/device/model/modelOfMatterModel'; | |
8 | + import { BasicForm, FormProps, FormSchema, useForm } from '/@/components/Form'; | |
9 | + | |
10 | + const props = withDefaults( | |
11 | + defineProps<{ | |
12 | + inputData?: StructJSON[]; | |
13 | + formProps?: FormProps; | |
14 | + value?: Recordable; | |
15 | + }>(), | |
16 | + { | |
17 | + inputData: () => [] as StructJSON[], | |
18 | + formProps: () => ({}), | |
19 | + value: () => ({}), | |
20 | + } | |
21 | + ); | |
22 | + | |
23 | + const emit = defineEmits(['update:value']); | |
24 | + | |
25 | + const [register, { setProps, getFieldsValue, setFieldsValue }] = useForm({ | |
26 | + schemas: [], | |
27 | + showActionButtonGroup: false, | |
28 | + layout: 'inline', | |
29 | + labelWidth: 80, | |
30 | + wrapperCol: { span: 12 }, | |
31 | + ...(props.formProps || ({} as unknown as Partial<DynamicProps<FormProps>>)), | |
32 | + }); | |
33 | + | |
34 | + const syncValue = (key: string, value: any) => { | |
35 | + const record = getFieldsValue(); | |
36 | + emit('update:value', { ...record, [key]: value }); | |
37 | + }; | |
38 | + | |
39 | + const createInputNumber = ({ | |
40 | + identifier, | |
41 | + functionName, | |
42 | + specs, | |
43 | + }: BasicCreateFormParams): FormSchema => { | |
44 | + const { valueRange } = specs! as Partial<Specs>; | |
45 | + const { max = 2147483647, min = -2147483648 } = valueRange || {}; | |
46 | + return { | |
47 | + field: identifier, | |
48 | + label: functionName, | |
49 | + component: 'InputNumber', | |
50 | + rules: [ | |
51 | + { | |
52 | + type: 'number', | |
53 | + trigger: 'change', | |
54 | + validator: (_rule, value) => { | |
55 | + if (value < min || value > max) { | |
56 | + return Promise.reject(`${functionName}取值范围在${min}~${max}之间`); | |
57 | + } | |
58 | + return Promise.resolve(value); | |
59 | + }, | |
60 | + }, | |
61 | + ], | |
62 | + componentProps: { | |
63 | + max, | |
64 | + min, | |
65 | + // step: step, | |
66 | + // formatter: (value: string) => value, | |
67 | + // parser: (string: string) => { | |
68 | + // if (dataType === DataTypeEnum.IS_NUMBER_INT) { | |
69 | + // return Number(Number(string).toFixed()); | |
70 | + // } | |
71 | + // return Number(string); | |
72 | + // }, | |
73 | + onChange: (value: string) => { | |
74 | + syncValue(identifier, value); | |
75 | + }, | |
76 | + }, | |
77 | + } as FormSchema; | |
78 | + }; | |
79 | + | |
80 | + const createInput = ({ identifier, functionName, specs }: BasicCreateFormParams): FormSchema => { | |
81 | + const { length = 10240 } = specs! as Partial<Specs>; | |
82 | + return { | |
83 | + field: identifier, | |
84 | + label: functionName, | |
85 | + component: 'Input', | |
86 | + rules: [ | |
87 | + { | |
88 | + type: 'string', | |
89 | + trigger: 'change', | |
90 | + validator: (_rule, value) => { | |
91 | + if (value.length > length) { | |
92 | + return Promise.reject(`${functionName}数据长度应该小于${length}`); | |
93 | + } | |
94 | + return Promise.resolve(value); | |
95 | + }, | |
96 | + }, | |
97 | + ], | |
98 | + componentProps: { | |
99 | + maxLength: length, | |
100 | + onChange: (value: InputEvent) => { | |
101 | + syncValue(identifier, (value.target as HTMLInputElement).value); | |
102 | + }, | |
103 | + }, | |
104 | + } as FormSchema; | |
105 | + }; | |
106 | + | |
107 | + const createSelect = ({ identifier, functionName, specs }: BasicCreateFormParams): FormSchema => { | |
108 | + const { boolClose, boolOpen } = specs! as Partial<Specs>; | |
109 | + return { | |
110 | + field: identifier, | |
111 | + label: functionName, | |
112 | + component: 'Select', | |
113 | + componentProps: { | |
114 | + options: [ | |
115 | + { label: `${boolClose}-0`, value: 0 }, | |
116 | + { label: `${boolOpen}-0`, value: 1 }, | |
117 | + ], | |
118 | + onChange: (value: string) => { | |
119 | + syncValue(identifier, value); | |
120 | + }, | |
121 | + }, | |
122 | + }; | |
123 | + }; | |
124 | + | |
125 | + const createInputJson = ({ identifier, functionName }: BasicCreateFormParams): FormSchema => { | |
126 | + return { | |
127 | + field: identifier, | |
128 | + label: functionName, | |
129 | + component: 'InputTextArea', | |
130 | + componentProps: { | |
131 | + onChange: (value: InputEvent) => { | |
132 | + syncValue(identifier, (value.target as HTMLInputElement).value); | |
133 | + }, | |
134 | + }, | |
135 | + }; | |
136 | + }; | |
137 | + | |
138 | + const transformToFormSchema = (inputData: StructJSON[]) => { | |
139 | + const schemas: FormSchema[] = []; | |
140 | + for (const item of inputData) { | |
141 | + const { dataType, identifier, functionName } = item; | |
142 | + const { type, specs } = dataType! || {}; | |
143 | + | |
144 | + const params: BasicCreateFormParams = { | |
145 | + identifier: identifier!, | |
146 | + functionName: functionName!, | |
147 | + dataType: dataType! as unknown as DataTypeEnum, | |
148 | + specs: specs as Partial<Specs>, | |
149 | + }; | |
150 | + if (type === DataTypeEnum.IS_NUMBER_INT || type === DataTypeEnum.IS_NUMBER_DOUBLE) { | |
151 | + schemas.push(createInputNumber(params)); | |
152 | + } | |
153 | + | |
154 | + if (type === DataTypeEnum.IS_BOOL) { | |
155 | + schemas.push(createSelect(params)); | |
156 | + } | |
157 | + | |
158 | + if (type === DataTypeEnum.IS_STRING) { | |
159 | + schemas.push(createInput(params)); | |
160 | + } | |
161 | + | |
162 | + if (type === DataTypeEnum.IS_STRUCT) { | |
163 | + schemas.push(createInputJson(params)); | |
164 | + } | |
165 | + } | |
166 | + | |
167 | + return schemas; | |
168 | + }; | |
169 | + | |
170 | + onBeforeUpdate(() => { | |
171 | + if (props.inputData && props.inputData.length) { | |
172 | + const schemas = transformToFormSchema(props.inputData); | |
173 | + setProps({ schemas }); | |
174 | + } | |
175 | + }); | |
176 | + | |
177 | + onUpdated(async () => { | |
178 | + if (props.inputData && props.inputData.length) { | |
179 | + await nextTick(); | |
180 | + setFieldsValue(props.value); | |
181 | + } | |
182 | + }); | |
183 | +</script> | |
184 | + | |
185 | +<template> | |
186 | + <Card bordered class="!border-dashed !rounded-lg !border-2px"> | |
187 | + <!-- <Alert class="!mb-4 w-32" message="服务参数配置" type="info" /> --> | |
188 | + <BasicForm class="object-model-validate-form" @register="register" /> | |
189 | + </Card> | |
190 | +</template> | |
191 | + | |
192 | +<style lang="less"> | |
193 | + .object-model-validate-form { | |
194 | + .ant-input-number { | |
195 | + width: 100% !important; | |
196 | + } | |
197 | + } | |
198 | +</style> | ... | ... |
... | ... | @@ -20,6 +20,11 @@ export type TOption = { |
20 | 20 | value: string; |
21 | 21 | }; |
22 | 22 | |
23 | +export enum CommandTypeEnum { | |
24 | + CUSTOM = 0, | |
25 | + SERVICE = 1, | |
26 | +} | |
27 | + | |
23 | 28 | /** |
24 | 29 | * 所使用的枚举值 |
25 | 30 | */ |
... | ... | @@ -575,11 +580,28 @@ export const actionSchema: FormSchema[] = [ |
575 | 580 | span: 6, |
576 | 581 | }, |
577 | 582 | componentProps: ({ formModel, formActionType }) => { |
578 | - const { setFieldsValue } = formActionType; | |
579 | - const deviceProfileId = formModel['deviceProfileId']; | |
583 | + const { updateSchema } = formActionType; | |
584 | + const deviceProfileId = Reflect.get(formModel, 'deviceProfileId'); | |
585 | + const thingsModelId = Reflect.get(formModel, 'thingsModelId'); | |
580 | 586 | return { |
581 | 587 | placeholder: '请选择服务', |
582 | - api: getModelServices, | |
588 | + api: async (params: Recordable) => { | |
589 | + try { | |
590 | + const record = await getModelServices(params as Record<'deviceProfileId', string>); | |
591 | + const selected = record.find((item) => item.id === thingsModelId); | |
592 | + selected && | |
593 | + updateSchema({ | |
594 | + field: 'serviceInputValue', | |
595 | + componentProps: { | |
596 | + inputData: selected?.functionJson.inputData, | |
597 | + }, | |
598 | + }); | |
599 | + return record; | |
600 | + } catch (error) { | |
601 | + console.error(error); | |
602 | + return []; | |
603 | + } | |
604 | + }, | |
583 | 605 | params: { |
584 | 606 | deviceProfileId, |
585 | 607 | }, |
... | ... | @@ -587,7 +609,15 @@ export const actionSchema: FormSchema[] = [ |
587 | 609 | valueField: 'id', |
588 | 610 | getPopupContainer: () => document.body, |
589 | 611 | onChange: (_, options: ModelOfMatterParams) => { |
590 | - setFieldsValue({ doContext: { ...options.functionJson, callType: options.callType } }); | |
612 | + if (options) { | |
613 | + // setFieldsValue({ doContext: { ...options.functionJson, callType: options.callType } }); | |
614 | + updateSchema({ | |
615 | + field: 'serviceInputValue', | |
616 | + componentProps: { | |
617 | + inputData: options.functionJson.inputData, | |
618 | + }, | |
619 | + }); | |
620 | + } | |
591 | 621 | }, |
592 | 622 | }; |
593 | 623 | }, |
... | ... | @@ -665,6 +695,18 @@ export const actionSchema: FormSchema[] = [ |
665 | 695 | }, |
666 | 696 | slot: 'clearAlarm', |
667 | 697 | }, |
698 | + { | |
699 | + field: 'serviceInputValue', | |
700 | + component: 'ObjectModelValidateForm', | |
701 | + label: '', | |
702 | + changeEvent: 'update:value', | |
703 | + valueField: 'value', | |
704 | + show: ({ values }) => values['thingsModelId'], | |
705 | + colProps: { | |
706 | + span: 24, | |
707 | + }, | |
708 | + componentProps: {}, | |
709 | + }, | |
668 | 710 | ]; |
669 | 711 | |
670 | 712 | export const alarmScheduleSchemas: FormSchema[] = [ | ... | ... |
... | ... | @@ -103,7 +103,7 @@ |
103 | 103 | import { BasicForm, useForm } from '/@/components/Form/index'; |
104 | 104 | import { Tooltip, Select, Checkbox, Card } from 'ant-design-vue'; |
105 | 105 | import { Icon } from '/@/components/Icon'; |
106 | - import { actionSchema } from '../config/config.data'; | |
106 | + import { actionSchema, CommandTypeEnum } from '../config/config.data'; | |
107 | 107 | import jsoneditor from 'jsoneditor'; |
108 | 108 | import 'jsoneditor/dist/jsoneditor.min.css'; |
109 | 109 | import { QuestionCircleOutlined, PlusOutlined } from '@ant-design/icons-vue'; |
... | ... | @@ -261,19 +261,26 @@ |
261 | 261 | //TODO-fengtao-设备验证 |
262 | 262 | const value = getFieldsValue(); |
263 | 263 | const doContext = unref(jsonInstance)?.get() || {}; |
264 | + const serviceInputValue = Reflect.get(value, 'serviceInputValue'); | |
265 | + | |
264 | 266 | return { |
265 | 267 | ...value, |
266 | - ...(Number(value.commandType) === 0 ? { doContext } : {}), | |
268 | + ...(Number(value.commandType) === CommandTypeEnum.CUSTOM | |
269 | + ? { doContext } | |
270 | + : { doContext: serviceInputValue }), | |
267 | 271 | clearRule, |
268 | 272 | }; |
269 | 273 | }; |
270 | 274 | |
271 | 275 | const setFieldsFormValueFun = (fieldsValue) => { |
276 | + const doContext = Reflect.get(fieldsValue, 'doContext'); | |
277 | + const commandType = Reflect.get(fieldsValue, 'commandType'); | |
272 | 278 | setFieldsValue({ |
273 | 279 | ...fieldsValue, |
274 | 280 | ...(isNumber(fieldsValue.commandType) |
275 | 281 | ? { commandType: String(fieldsValue.commandType) } |
276 | 282 | : {}), |
283 | + serviceInputValue: commandType === CommandTypeEnum.SERVICE ? doContext.params || {} : {}, | |
277 | 284 | }); |
278 | 285 | }; |
279 | 286 | //ft-add | ... | ... |