浏览代码

feat(config): update config

Lind 4 年之前
父节点
当前提交
33618a3671

+ 1 - 1
config/defaultSettings.ts

@@ -17,7 +17,7 @@ const Settings: LayoutSettings & {
   colorWeak: false,
   title: 'Jetlinks',
   pwa: false,
-  logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
+  logo: '/logo.svg',
   iconfontUrl: '',
 };
 

+ 2 - 0
config/proxy.ts

@@ -9,6 +9,8 @@
 export default {
   dev: {
     '/jetlinks': {
+      // target: 'http://192.168.22.222:8844/',
+      // ws: 'ws://192.168.22.222:8844/',
       ws: 'ws://demo.jetlinks.cn/jetlinks',
       target: 'http://demo.jetlinks.cn/jetlinks',
       changeOrigin: true,

+ 13 - 1
config/routes.ts

@@ -27,6 +27,10 @@
     icon: 'crown',
     routes: [
       {
+        path: '/system',
+        redirect: '/system/user',
+      },
+      {
         path: '/system/user',
         name: 'user',
         icon: 'smile',
@@ -70,6 +74,10 @@
     icon: 'crown',
     routes: [
       {
+        path: '/device',
+        redirect: '/device/product',
+      },
+      {
         path: '/device/product',
         name: 'product',
         icon: 'smile',
@@ -109,11 +117,15 @@
     ],
   },
   {
-    path: 'log',
+    path: '/log',
     name: 'log',
     icon: 'crown',
     routes: [
       {
+        path: '/log',
+        redirect: '/log/access',
+      },
+      {
         path: '/log/access',
         name: 'access',
         icon: 'smile',

+ 9 - 8
package.json

@@ -58,19 +58,20 @@
     "@ant-design/pro-descriptions": "^1.6.8",
     "@ant-design/pro-form": "^1.18.3",
     "@ant-design/pro-layout": "^6.15.3",
-    "@ant-design/pro-table": "^2.30.8",
     "@ant-design/pro-list": "^1.10.8",
+    "@ant-design/pro-table": "^2.30.8",
     "@dabeng/react-orgchart": "^1.0.0",
-    "@formily/antd": "2.0.0-beta.77",
-    "@formily/core": "2.0.0-beta.77",
-    "@formily/json-schema": "2.0.0-beta.77",
-    "@formily/react": "2.0.0-beta.77",
-    "@formily/reactive": "2.0.0-beta.77",
-    "@formily/reactive-react": "2.0.0-beta.77",
-    "@formily/shared": "2.0.0-beta.77",
+    "@formily/antd": "2.0.0-beta.83",
+    "@formily/core": "2.0.0-beta.83",
+    "@formily/json-schema": "2.0.0-beta.83",
+    "@formily/react": "2.0.0-beta.83",
+    "@formily/reactive": "2.0.0-beta.83",
+    "@formily/reactive-react": "2.0.0-beta.83",
+    "@formily/shared": "2.0.0-beta.83",
     "@umijs/route-utils": "^1.0.36",
     "antd": "^4.14.0",
     "classnames": "^2.2.6",
+    "isomorphic-form-data": "^2.0.0",
     "jetlinks-store": "^0.0.3",
     "lodash": "^4.17.11",
     "moment": "^2.25.3",

二进制
public/logo.png


文件差异内容过多而无法显示
+ 239 - 1
public/logo.svg


+ 97 - 8
src/pages/device/Product/Detail/BaseInfo/index.tsx

@@ -1,12 +1,101 @@
-import { observer } from '@formily/react';
-import { productModel } from '@/pages/device/Product';
+import { createSchemaField, observer } from '@formily/react';
+import { productModel, service } from '@/pages/device/Product';
+import { Form, FormItem, FormGrid, Password, FormLayout, PreviewText, Input } from '@formily/antd';
+import { createForm } from '@formily/core';
+import { Card, Empty } from 'antd';
+import type { ISchema } from '@formily/json-schema';
+import { useEffect, useState } from 'react';
+import type { ConfigMetadata, ConfigProperty } from '@/pages/device/Product/typings';
 
+const componentMap = {
+  string: 'Input',
+  password: 'Password',
+};
 const BaseInfo = observer(() => {
-  return (
-    <div>
-      基础信息
-      {JSON.stringify(productModel.current)}
-    </div>
-  );
+  const id = productModel.current?.id;
+  const [metadata, setMetadata] = useState<ConfigMetadata[]>([]);
+  const [state, setState] = useState<boolean>(false);
+
+  const form = createForm({
+    validateFirst: true,
+    readPretty: state,
+    initialValues: productModel.current?.configuration,
+  });
+
+  useEffect(() => {
+    if (id) {
+      service.getConfigMetadata(id).then((config) => {
+        setMetadata(config.result);
+      });
+    }
+
+    return () => {};
+  }, [id]);
+
+  const SchemaField = createSchemaField({
+    components: {
+      FormItem,
+      Input,
+      Password,
+      FormGrid,
+      PreviewText,
+    },
+  });
+
+  const configToSchema = (data: ConfigProperty[]) => {
+    const config = {};
+    data.forEach((item) => {
+      config[item.property] = {
+        type: 'string',
+        title: item.name,
+        'x-decorator': 'FormItem',
+        'x-component': componentMap[item.type.type],
+        'x-decorator-props': {
+          tooltip: item.description,
+        },
+      };
+    });
+    return config;
+  };
+
+  const renderConfigCard = () => {
+    return metadata ? (
+      metadata?.map((item) => {
+        const itemSchema: ISchema = {
+          type: 'object',
+          properties: {
+            grid: {
+              type: 'void',
+              'x-component': 'FormGrid',
+              'x-component-props': {
+                minColumns: [2],
+                maxColumns: [2],
+              },
+              properties: configToSchema(item.properties),
+            },
+          },
+        };
+
+        return (
+          <Card
+            title={item.name}
+            extra={<a onClick={() => setState(!state)}>{state ? '编辑' : '保存'}</a>}
+          >
+            <PreviewText.Placeholder value="-">
+              <Form form={form}>
+                <FormLayout labelCol={6} wrapperCol={16}>
+                  <SchemaField schema={itemSchema} />
+                </FormLayout>
+              </Form>
+            </PreviewText.Placeholder>
+          </Card>
+        );
+      })
+    ) : (
+      <Empty />
+    );
+  };
+
+  return <>{renderConfigCard()}</>;
 });
 export default BaseInfo;

+ 13 - 9
src/pages/device/Product/index.tsx

@@ -1,6 +1,6 @@
 import { PageContainer } from '@ant-design/pro-layout';
 import ProList from '@ant-design/pro-list';
-import { Badge, Button, Card, message, Space, Tag, Tooltip } from 'antd';
+import { Badge, Button, Card, message, Space, Tag, Tooltip, Typography } from 'antd';
 import type { ProductItem } from '@/pages/device/Product/typings';
 import {
   CloseCircleOutlined,
@@ -17,8 +17,9 @@ import Service from '@/pages/device/Product/service';
 import { observer } from '@formily/react';
 import { Link } from '@umijs/preset-dumi/lib/theme';
 import { model } from '@formily/reactive';
+import encodeQuery from '@/utils/encodeQuery';
 
-const service = new Service('device-product');
+export const service = new Service('device-product');
 export const statusMap = {
   1: <Badge status="processing" text="已发布" />,
   0: <Badge status="error" text="未发布" />,
@@ -47,9 +48,9 @@ const Product = observer(() => {
           rowKey={'id'}
           headerTitle="产品列表"
           request={async (params = {}) => {
-            return await lastValueFrom(service.list(params));
-            // console.log(ii, 'i')
-            // return await service.query(params);
+            return await lastValueFrom(
+              service.list(encodeQuery({ ...params, sorts: { id: 'ascend' } })),
+            );
           }}
           pagination={{
             pageSize: 5,
@@ -93,7 +94,10 @@ const Product = observer(() => {
                     }}
                   >
                     <div>ID</div>
-                    {row.id}
+                    <Typography.Paragraph copyable={{ text: row.id }}>
+                      {' '}
+                      {row.id}
+                    </Typography.Paragraph>
                   </div>
                   <div
                     style={{
@@ -193,17 +197,17 @@ const Product = observer(() => {
               ],
               search: false,
             },
-            status: {
+            state: {
               // 自己扩展的字段,主要用于筛选,不在列表中显示
               title: '状态',
               valueType: 'select',
               valueEnum: {
                 all: { text: '全部', status: 'Default' },
-                0: {
+                1: {
                   text: '已发布',
                   status: 'Error',
                 },
-                1: {
+                0: {
                   text: '未发布',
                   status: 'Success',
                 },

+ 9 - 7
src/pages/device/Product/service.ts

@@ -2,22 +2,21 @@ import BaseService from '@/utils/BaseService';
 import type { ProductItem } from '@/pages/device/Product/typings';
 import { request } from 'umi';
 import SystemConst from '@/utils/const';
-import { from, toArray } from 'rxjs';
-import { map, mergeMap } from 'rxjs/operators';
+import { concatMap, from, toArray } from 'rxjs';
+import { map } from 'rxjs/operators';
 import encodeQuery from '@/utils/encodeQuery';
 import type { Response } from '@/utils/typings';
 import _ from 'lodash';
 
 class Service extends BaseService<ProductItem> {
-  public instanceCount = (params: Record<string, any>) => {
-    return request(`/${SystemConst.API_BASE}/device-instance/_count`, { params, method: 'GET' });
-  };
+  public instanceCount = (params: Record<string, any>) =>
+    request(`/${SystemConst.API_BASE}/device-instance/_count`, { params, method: 'GET' });
 
   public list = (params: any) =>
     from(this.query(params)).pipe(
-      mergeMap((i: Response<ProductItem>) =>
+      concatMap((i: Response<ProductItem>) =>
         from(i.result.data as ProductItem[]).pipe(
-          mergeMap((t: ProductItem) =>
+          concatMap((t: ProductItem) =>
             from(this.instanceCount(encodeQuery({ terms: { productId: t.id } }))).pipe(
               map((count) => ({ ...t, count: count.result })),
             ),
@@ -27,6 +26,9 @@ class Service extends BaseService<ProductItem> {
         ),
       ),
     );
+
+  public getConfigMetadata = (id: string) =>
+    request(`/${SystemConst.API_BASE}/device/product/${id}/config-metadata`, { method: 'GET' });
 }
 
 export default Service;

+ 19 - 0
src/pages/device/Product/typings.d.ts

@@ -18,3 +18,22 @@ export type ProductItem = {
   state: number;
   transportProtocol: string;
 };
+
+export type ConfigProperty = {
+  property: string;
+  name: string;
+  description: string;
+  type: {
+    name: string;
+    id: string;
+    type: string;
+  };
+  scopes: any[];
+};
+
+export type ConfigMetadata = {
+  name: string;
+  description: string;
+  scopes: any[];
+  properties: ConfigProperty[];
+};