Commit 7be76707fc87a1e2c4b505e49cacf65387161355

Authored by ww
1 parent 49198f16

feat: 场景联动服务调用新增根据物模型服务配置下发参数表单

... ... @@ -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>
... ...
  1 +import { DataTypeEnum } from '../StructForm/config';
  2 +import { Specs } from '/@/api/device/model/modelOfMatterModel';
  3 +
  4 +export interface BasicCreateFormParams {
  5 + identifier: string;
  6 + functionName: string;
  7 + dataType: DataTypeEnum;
  8 + specs: Partial<Specs>;
  9 +}
... ...
... ... @@ -121,4 +121,5 @@ export type ComponentType =
121 121 | 'StructForm'
122 122 | 'ApiSelectScrollLoad'
123 123 | 'TransferModal'
124   - | 'TransferTableModal';
  124 + | 'TransferTableModal'
  125 + | 'ObjectModelValidateForm';
... ...
... ... @@ -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
... ...