Jelajahi Sumber

feat(metadata): extract metadata component :Array\Boolean\Enum\JSON

Lind 4 tahun lalu
induk
melakukan
362647fa51

+ 22 - 0
src/components/Metadata/ArrayParam/index.less

@@ -0,0 +1,22 @@
+@import '~antd/es/style/themes/default.less';
+
+.config-array {
+  width: 100%;
+
+  .ant-formily-editable-content {
+    justify-content: center;
+    width: 100%;
+    padding: 4px 15px;
+    font-size: 14px;
+    border: 1px dashed #d9d9d9;
+  }
+
+  .ant-formily-editable-content:hover {
+    color: @primary-color;
+    border-color: @primary-color;
+
+    span {
+      color: @primary-color;
+    }
+  }
+}

+ 189 - 0
src/components/Metadata/ArrayParam/index.tsx

@@ -0,0 +1,189 @@
+import { createSchemaField } from '@formily/react';
+import { FormLayout, Editable, Select, FormItem, Input, NumberPicker } from '@formily/antd';
+import type { ISchema } from '@formily/json-schema';
+import './index.less';
+import { DataTypeList, DateTypeList, FileTypeList } from '@/pages/device/data';
+import { Store } from 'jetlinks-store';
+import JsonParam from '@/components/Metadata/JsonParam';
+import EnumParam from '@/components/Metadata/EnumParam';
+import BooleanEnum from '@/components/Metadata/BooleanParam';
+
+const ArrayParam = () => {
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      Select,
+      Editable,
+      FormLayout,
+      NumberPicker,
+      JsonParam,
+      ArrayParam,
+      EnumParam,
+      BooleanEnum,
+    },
+  });
+
+  const schema: ISchema = {
+    type: 'object',
+    properties: {
+      config: {
+        type: 'void',
+        title: '配置元素',
+        'x-component': 'FormLayout',
+        'x-component-props': {
+          layout: 'vertical',
+        },
+        'x-decorator': 'Editable.Popover',
+        'x-decorator-props': {
+          className: 'config-array',
+          placement: 'left',
+        },
+        'x-reactions':
+          "{{(field) => field.title = field.query('.void.date2').get('value') || field.title}}",
+        properties: {
+          type: {
+            title: '元素类型',
+            'x-decorator': 'FormItem',
+            'x-component': 'Select',
+            enum: DataTypeList.filter((item) => item.value !== 'array'),
+          },
+
+          scale: {
+            title: '精度',
+            'x-decorator': 'FormItem',
+            'x-component': 'NumberPicker',
+            'x-reactions': {
+              dependencies: ['.type'],
+              fulfill: {
+                state: {
+                  visible: "{{['float','double'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          units: {
+            title: '单位',
+            'x-decorator': 'FormItem',
+            'x-component': 'Select',
+            'x-visible': false,
+            enum: Store.get('units'),
+            'x-reactions': {
+              dependencies: ['.type'],
+              fulfill: {
+                state: {
+                  visible: "{{['int','float','long','double'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          maxLength: {
+            title: '最大长度',
+            'x-decorator': 'FormItem',
+            'x-component': 'NumberPicker',
+            'x-reactions': {
+              dependencies: ['.type'],
+              fulfill: {
+                state: {
+                  visible: "{{['string'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          booleanConfig: {
+            title: '布尔值',
+            'x-decorator': 'FormItem',
+            'x-component': 'BooleanEnum',
+            'x-reactions': {
+              dependencies: ['.type'],
+              fulfill: {
+                state: {
+                  visible: "{{['boolean'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          enumConfig: {
+            title: '枚举项',
+            'x-decorator': 'FormItem',
+            'x-component': 'EnumParam',
+            'x-reactions': {
+              dependencies: ['.type'],
+              fulfill: {
+                state: {
+                  visible: "{{['enum'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          'valueType.elementType.fileType': {
+            title: '文件类型',
+            'x-decorator': 'FormItem',
+            'x-component': 'Select',
+            'x-visible': false,
+            enum: FileTypeList,
+            'x-reactions': {
+              dependencies: ['...type'],
+              fulfill: {
+                state: {
+                  visible: "{{['file'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          jsonConfig: {
+            title: 'JSON对象',
+            'x-decorator': 'FormItem',
+            'x-component': 'JsonParam',
+            'x-reactions': {
+              dependencies: ['.type'],
+              fulfill: {
+                state: {
+                  visible: "{{['object'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          'valueType.elementType.expands.maxLength': {
+            title: '密码长度',
+            'x-decorator': 'FormItem',
+            'x-component': 'NumberPicker',
+            'x-decorator-props': {
+              tooltip: '字节',
+            },
+            'x-visible': false,
+            'x-reactions': {
+              dependencies: ['....type'],
+              fulfill: {
+                state: {
+                  visible: "{{['password'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          'valueType.elementType.format': {
+            title: '时间格式',
+            'x-decorator': 'FormItem',
+            'x-component': 'Select',
+            enum: DateTypeList,
+            'x-reactions': {
+              dependencies: ['...type'],
+              fulfill: {
+                state: {
+                  visible: "{{['date'].includes($deps[0])}}",
+                },
+              },
+            },
+          },
+          description: {
+            title: '描述',
+            'x-decorator': 'FormItem',
+            'x-component': 'Input.TextArea',
+          },
+        },
+      },
+    },
+  };
+  return <SchemaField schema={schema} />;
+};
+export default ArrayParam;

+ 81 - 0
src/components/Metadata/BooleanParam/index.tsx

@@ -0,0 +1,81 @@
+import { createSchemaField } from '@formily/react';
+import { FormGrid, FormItem, Input } from '@formily/antd';
+import type { ISchema } from '@formily/json-schema';
+
+const BooleanParam = () => {
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      FormGrid,
+    },
+  });
+
+  const schema: ISchema = {
+    type: 'object',
+    properties: {
+      config: {
+        'x-component': 'FormGrid',
+        'x-component-props': {
+          maxColumns: 2,
+          minColumns: 2,
+        },
+        type: 'void',
+        properties: {
+          trueText: {
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            default: '是',
+            'x-decorator-props': {
+              gridSpan: 1,
+            },
+            'x-component-props': {
+              placeholder: 'trueText',
+            },
+          },
+          trueValue: {
+            title: '-',
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            default: true,
+
+            'x-decorator-props': {
+              gridSpan: 1,
+              colon: false,
+            },
+            'x-component-props': {
+              placeholder: 'trueValue',
+            },
+          },
+          falseText: {
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            default: '否',
+            'x-decorator-props': {
+              gridSpan: 1,
+            },
+            'x-component-props': {
+              placeholder: 'falseText',
+            },
+          },
+          falseValue: {
+            'x-decorator': 'FormItem',
+            'x-component': 'Input',
+            default: false,
+            title: '-',
+            'x-decorator-props': {
+              gridSpan: 1,
+              colon: false,
+            },
+            'x-component-props': {
+              placeholder: 'falseValue',
+            },
+          },
+        },
+      },
+    },
+  };
+
+  return <SchemaField schema={schema} />;
+};
+export default BooleanParam;

+ 90 - 0
src/components/Metadata/EnumParam/index.tsx

@@ -0,0 +1,90 @@
+import { createSchemaField } from '@formily/react';
+import { ArrayItems, Editable, FormItem, FormLayout, Input } from '@formily/antd';
+import type { ISchema } from '@formily/json-schema';
+
+const EnumParam = () => {
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      ArrayItems,
+      Editable,
+      FormLayout,
+    },
+  });
+
+  const schema: ISchema = {
+    type: 'void',
+    properties: {
+      config: {
+        type: 'array',
+        'x-component': 'ArrayItems',
+        items: {
+          type: 'void',
+          'x-component': 'ArrayItems.Item',
+          properties: {
+            sort: {
+              type: 'void',
+              'x-decorator': 'FormItem',
+              'x-component': 'ArrayItems.SortHandle',
+            },
+            popover: {
+              type: 'object',
+              title: '枚举项配置',
+              'x-decorator': 'Editable.Popover',
+              'x-component': 'FormLayout',
+              'x-component-props': {
+                layout: 'vertical',
+              },
+              'x-reactions': [
+                {
+                  fulfill: {
+                    schema: {
+                      title: '{{$self.query(".label").value()}}',
+                    },
+                  },
+                },
+              ],
+              properties: {
+                label: {
+                  type: 'string',
+                  title: 'Label',
+                  required: true,
+                  'x-decorator': 'FormItem',
+                  'x-component': 'Input',
+                  'x-component-props': {
+                    placeholder: '标识',
+                  },
+                },
+                value: {
+                  type: 'string',
+                  title: 'Value',
+                  required: true,
+                  'x-decorator': 'FormItem',
+                  'x-component': 'Input',
+                  'x-component-props': {
+                    placeholder: '对该枚举项的描述',
+                  },
+                },
+              },
+            },
+            remove: {
+              type: 'void',
+              'x-decorator': 'FormItem',
+              'x-component': 'ArrayItems.Remove',
+            },
+          },
+        },
+        properties: {
+          addition: {
+            type: 'void',
+            title: '新增枚举项',
+            'x-component': 'ArrayItems.Addition',
+          },
+        },
+      },
+    },
+  };
+  return <SchemaField schema={schema} />;
+};
+export default EnumParam;

+ 8 - 24
src/components/MetadataParam/index.tsx

@@ -4,39 +4,28 @@ import {
   Editable,
   ArrayItems,
   FormItem,
-  Form,
   Input,
   Select,
 } from '@formily/antd';
-import { createForm } from '@formily/core';
-import { connect, createSchemaField } from '@formily/react';
+import { createSchemaField } from '@formily/react';
 import type { ISchema } from '@formily/json-schema';
 import { DataTypeList } from '@/pages/device/data';
 import { Store } from 'jetlinks-store';
 
-interface Props {
-  value: Record<string, unknown>;
-  onChange: () => void;
-}
-
-const MetadataParam = connect((props: Props) => {
-  const form = createForm({
-    initialValues: props.value,
-  });
-
+// 不算是自定义组件。只是抽离了JSONSchema
+const JsonParam = () => {
   const SchemaField = createSchemaField({
     components: {
       FormItem,
       Input,
       Select,
-      MetadataParam,
+      JsonParam,
       ArrayItems,
       Editable,
       FormLayout,
       NumberPicker,
     },
   });
-
   const schema: ISchema = {
     type: 'object',
     properties: {
@@ -121,7 +110,7 @@ const MetadataParam = connect((props: Props) => {
                   title: 'JSON对象',
                   'x-visible': false,
                   'x-decorator': 'FormItem',
-                  'x-component': 'MetadataParam',
+                  'x-component': 'JsonParam',
                   'x-reactions': {
                     dependencies: ['.valueType.type'],
                     fulfill: {
@@ -150,11 +139,6 @@ const MetadataParam = connect((props: Props) => {
       },
     },
   };
-
-  return (
-    <Form form={form} layout={'vertical'} size={'small'}>
-      <SchemaField schema={schema} />
-    </Form>
-  );
-});
-export default MetadataParam;
+  return <SchemaField schema={schema} />;
+};
+export default JsonParam;

+ 27 - 137
src/pages/device/Product/Detail/Metadata/Base/Edit/index.tsx

@@ -27,7 +27,10 @@ import { service } from '@/pages/device/Product';
 import { Store } from 'jetlinks-store';
 import type { UnitType } from '@/pages/device/Product/typings';
 import { useIntl } from 'umi';
-import MetadataParam from '@/components/MetadataParam';
+import JsonParam from '@/components/Metadata/JsonParam';
+import ArrayParam from '@/components/Metadata/ArrayParam';
+import EnumParam from '@/components/Metadata/EnumParam';
+import BooleanEnum from '@/components/Metadata/BooleanParam';
 
 const Edit = () => {
   const form = createForm({
@@ -45,7 +48,10 @@ const Edit = () => {
       ArrayItems,
       Space,
       FormLayout,
-      MetadataParam,
+      JsonParam,
+      ArrayParam,
+      EnumParam,
+      BooleanEnum,
     },
   });
 
@@ -93,172 +99,57 @@ const Edit = () => {
           },
         },
       },
-      'valueType.elementType.type': {
-        title: '元素类型',
+      jsonConfig: {
+        title: 'JSON对象',
         'x-decorator': 'FormItem',
-        'x-component': 'Select',
-        enum: DataTypeList,
+        'x-component': 'JsonParam',
         'x-reactions': {
-          dependencies: ['valueType.type'],
+          dependencies: ['.valueType.type'],
           fulfill: {
             state: {
-              visible: "{{['array'].includes($deps[0])}}",
+              visible: "{{['object'].includes($deps[0])}}",
             },
           },
         },
       },
-      jsonConfig: {
-        title: 'JSON对象',
-        'x-decorator': 'FormItem',
-        'x-component': 'MetadataParam',
-      },
-      enumConfig: {
-        title: '枚举项',
-        type: 'array',
+      arrayConfig: {
+        title: '元素配置',
         'x-decorator': 'FormItem',
-        'x-component': 'ArrayItems',
-        items: {
-          type: 'object',
-          'x-component': 'ArrayItems.Item',
-          properties: {
-            sort: {
-              type: 'void',
-              'x-decorator': 'FormItem',
-              'x-component': 'ArrayItems.SortHandle',
-            },
-            popover: {
-              type: 'void',
-              title: '枚举项配置',
-              'x-decorator': 'Editable.Popover',
-              'x-component': 'FormLayout',
-              'x-component-props': {
-                layout: 'vertical',
-              },
-              'x-reactions': [
-                {
-                  fulfill: {
-                    schema: {
-                      title: '{{$self.query(".label").value() : $self.query(".value").value() }}',
-                    },
-                  },
-                },
-              ],
-              properties: {
-                label: {
-                  type: 'string',
-                  title: 'Label',
-                  required: true,
-                  'x-decorator': 'FormItem',
-                  'x-component': 'Input',
-                  'x-component-props': {
-                    placeholder: '标识',
-                  },
-                },
-                value: {
-                  type: 'string',
-                  title: 'Value',
-                  required: true,
-                  'x-decorator': 'FormItem',
-                  'x-component': 'Input',
-                  'x-component-props': {
-                    placeholder: '对该枚举项的描述',
-                  },
-                },
-              },
-            },
-            remove: {
-              type: 'void',
-              'x-decorator': 'FormItem',
-              'x-component': 'ArrayItems.Remove',
-            },
-          },
-        },
-        properties: {
-          addition: {
-            type: 'void',
-            title: '新增枚举项',
-            'x-component': 'ArrayItems.Addition',
-          },
-        },
+        'x-component': 'ArrayParam',
         'x-reactions': {
-          dependencies: ['valueType.type'],
+          dependencies: ['.valueType.type'],
           fulfill: {
             state: {
-              visible: "{{['enum'].includes($deps[0])}}",
+              visible: "{{['array'].includes($deps[0])}}",
             },
           },
         },
       },
-      trueConfig: {
-        title: '布尔值',
-        type: 'void',
+      enumConfig: {
+        title: '枚举项',
         'x-decorator': 'FormItem',
-        'x-decorator-props': {
-          asterisk: true,
-          feedbackLayout: 'none',
-        },
+        'x-component': 'EnumParam',
         'x-reactions': {
-          dependencies: ['valueType.type'],
+          dependencies: ['.valueType.type'],
           fulfill: {
             state: {
-              visible: "{{['boolean'].includes($deps[0])}}",
-            },
-          },
-        },
-        'x-component': 'Space',
-        properties: {
-          'valueType.elementType.trueText': {
-            'x-decorator': 'FormItem',
-            'x-component': 'Input',
-            default: '是',
-            'x-component-props': {
-              placeholder: 'trueText',
-            },
-          },
-          'valueType.elementType.trueValue': {
-            'x-decorator': 'FormItem',
-            'x-component': 'Input',
-            default: true,
-            'x-component-props': {
-              placeholder: 'trueValue',
+              visible: "{{['enum'].includes($deps[0])}}",
             },
           },
         },
       },
-      falseConfig: {
-        type: 'void',
+      booleanConfig: {
+        title: '布尔值',
         'x-decorator': 'FormItem',
-        'x-decorator-props': {
-          asterisk: true,
-          feedbackLayout: 'none',
-        },
+        'x-component': 'BooleanEnum',
         'x-reactions': {
-          dependencies: ['valueType.type'],
+          dependencies: ['.valueType.type'],
           fulfill: {
             state: {
               visible: "{{['boolean'].includes($deps[0])}}",
             },
           },
         },
-        'x-component': 'Space',
-        properties: {
-          'valueType.elementType.falseText': {
-            'x-decorator': 'FormItem',
-            'x-component': 'Input',
-            default: '否',
-            'x-component-props': {
-              placeholder: 'falseText',
-            },
-          },
-          'valueType.elementType.falseValue': {
-            'x-decorator': 'FormItem',
-            'x-component': 'Input',
-            default: false,
-            'x-component-props': {
-              placeholder: 'falseValue',
-            },
-          },
-        },
       },
       'valueType.elementType.format': {
         title: '时间格式',
@@ -549,7 +440,6 @@ const Edit = () => {
           console.log(data, '提交数据');
         }}
       >
-        {' '}
         获取数据
       </Button>
     </Drawer>