xieyonghong 3 سال پیش
والد
کامیت
fbdca21a43

+ 3 - 0
src/components/BaseCrud/index.tsx

@@ -46,6 +46,7 @@ export type Props<T> = {
   form?: Form;
   form?: Form;
   /** @name 用于存储搜索历史记录的标记*/
   /** @name 用于存储搜索历史记录的标记*/
   moduleName?: string; //
   moduleName?: string; //
+  footer?: React.ReactNode;
 };
 };
 
 
 const BaseCrud = <T extends Record<string, any>>(props: Props<T>) => {
 const BaseCrud = <T extends Record<string, any>>(props: Props<T>) => {
@@ -68,6 +69,7 @@ const BaseCrud = <T extends Record<string, any>>(props: Props<T>) => {
     formEffect,
     formEffect,
     form,
     form,
     moduleName,
     moduleName,
+    footer,
   } = props;
   } = props;
 
 
   const [param, setParam] = useState({});
   const [param, setParam] = useState({});
@@ -151,6 +153,7 @@ const BaseCrud = <T extends Record<string, any>>(props: Props<T>) => {
         modelConfig={modelConfig}
         modelConfig={modelConfig}
         formEffect={formEffect}
         formEffect={formEffect}
         customForm={form}
         customForm={form}
+        footer={footer}
       />
       />
     </>
     </>
   );
   );

+ 32 - 8
src/components/BaseCrud/save/index.tsx

@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from 'react';
+import React, { useEffect, useMemo, useState } from 'react';
 import { message, Modal, Spin } from 'antd';
 import { message, Modal, Spin } from 'antd';
 import {
 import {
   ArrayItems,
   ArrayItems,
@@ -43,20 +43,33 @@ interface Props<T> {
   modelConfig?: ModalProps & { loading?: boolean };
   modelConfig?: ModalProps & { loading?: boolean };
   formEffect?: () => void;
   formEffect?: () => void;
   customForm?: Form1;
   customForm?: Form1;
+  footer?: React.ReactNode;
 }
 }
 
 
 const Save = <T extends Record<string, any>>(props: Props<T>) => {
 const Save = <T extends Record<string, any>>(props: Props<T>) => {
   const intl = useIntl();
   const intl = useIntl();
-  const { service, schema, reload, schemaConfig, modelConfig, formEffect, customForm } = props;
+  const { service, schema, reload, schemaConfig, modelConfig, formEffect, customForm, footer } =
+    props;
 
 
   const [visible, setVisible] = useState<boolean>(false);
   const [visible, setVisible] = useState<boolean>(false);
   const [current, setCurrent] = useState<T>();
   const [current, setCurrent] = useState<T>();
   const [model, setModel] = useState<'edit' | 'add' | 'preview'>('edit');
   const [model, setModel] = useState<'edit' | 'add' | 'preview'>('edit');
 
 
+  const form = useMemo(
+    () =>
+      createForm({
+        validateFirst: true,
+        initialValues: current,
+        effects: formEffect,
+      }),
+    [current, model],
+  );
+
   useEffect(() => {
   useEffect(() => {
     const visibleSubscription = Store.subscribe(SystemConst.BASE_CURD_MODAL_VISIBLE, setVisible);
     const visibleSubscription = Store.subscribe(SystemConst.BASE_CURD_MODAL_VISIBLE, setVisible);
     const dataSubscription = Store.subscribe(SystemConst.BASE_CURD_CURRENT, setCurrent);
     const dataSubscription = Store.subscribe(SystemConst.BASE_CURD_CURRENT, setCurrent);
     const modelSubscription = Store.subscribe(SystemConst.BASE_CURD_MODEL, setModel);
     const modelSubscription = Store.subscribe(SystemConst.BASE_CURD_MODEL, setModel);
+
     return () => {
     return () => {
       visibleSubscription.unsubscribe();
       visibleSubscription.unsubscribe();
       dataSubscription.unsubscribe();
       dataSubscription.unsubscribe();
@@ -64,12 +77,6 @@ const Save = <T extends Record<string, any>>(props: Props<T>) => {
     };
     };
   }, [current]);
   }, [current]);
 
 
-  const form = createForm({
-    validateFirst: true,
-    initialValues: current,
-    effects: formEffect,
-  });
-
   const SchemaField = createSchemaField({
   const SchemaField = createSchemaField({
     components: {
     components: {
       FormItem,
       FormItem,
@@ -100,7 +107,9 @@ const Save = <T extends Record<string, any>>(props: Props<T>) => {
 
 
   const save = async () => {
   const save = async () => {
     const values: T = await (customForm || form).submit();
     const values: T = await (customForm || form).submit();
+    console.log(form.values, 'value', values);
     // 特殊处理通知模版
     // 特殊处理通知模版
+
     if (service?.getUri().includes('/notifier/template')) {
     if (service?.getUri().includes('/notifier/template')) {
       (values as T & { template: Record<string, any> | string }).template = JSON.stringify(
       (values as T & { template: Record<string, any> | string }).template = JSON.stringify(
         values.template,
         values.template,
@@ -121,6 +130,20 @@ const Save = <T extends Record<string, any>>(props: Props<T>) => {
     reload();
     reload();
   };
   };
 
 
+  useEffect(() => {
+    const subscription = Store.subscribe('save-data', async (callback: (values: any) => void) => {
+      if (!callback) return;
+      await save();
+      if (typeof callback === 'function') {
+        callback(form);
+      }
+    });
+    return () => {
+      Store.set('save-data', undefined);
+      subscription.unsubscribe();
+    };
+  }, [current]);
+
   return (
   return (
     <Modal
     <Modal
       title={intl.formatMessage({
       title={intl.formatMessage({
@@ -130,6 +153,7 @@ const Save = <T extends Record<string, any>>(props: Props<T>) => {
       maskClosable={false}
       maskClosable={false}
       visible={visible}
       visible={visible}
       onCancel={CurdModel.close}
       onCancel={CurdModel.close}
+      footer={footer}
       onOk={save}
       onOk={save}
       {...modelConfig}
       {...modelConfig}
     >
     >

+ 17 - 3
src/components/Metadata/JsonParam/index.tsx

@@ -1,10 +1,10 @@
 import {
 import {
-  NumberPicker,
-  FormLayout,
-  Editable,
   ArrayItems,
   ArrayItems,
+  Editable,
   FormItem,
   FormItem,
+  FormLayout,
   Input,
   Input,
+  NumberPicker,
   Select,
   Select,
 } from '@formily/antd';
 } from '@formily/antd';
 import { createSchemaField } from '@formily/react';
 import { createSchemaField } from '@formily/react';
@@ -65,6 +65,20 @@ const JsonParam = (props: Props) => {
                   required: true,
                   required: true,
                   'x-decorator': 'FormItem',
                   'x-decorator': 'FormItem',
                   'x-component': 'Input',
                   'x-component': 'Input',
+                  'x-validator': [
+                    {
+                      max: 64,
+                      message: '最多可输入64个字符',
+                    },
+                    {
+                      required: true,
+                      message: '请输入标识',
+                    },
+                    {
+                      validateId: true,
+                      message: 'ID只能由数字、26个英文字母或者下划线组成',
+                    },
+                  ],
                 },
                 },
                 name: {
                 name: {
                   title: '名称',
                   title: '名称',

+ 5 - 0
src/global.less

@@ -4,6 +4,8 @@ html,
 body,
 body,
 #root {
 #root {
   height: 100%;
   height: 100%;
+  // 变成灰色
+  //-webkit-filter: grayscale(.95);
 }
 }
 
 
 .colorWeak {
 .colorWeak {
@@ -13,6 +15,7 @@ body,
 .ant-layout {
 .ant-layout {
   min-height: 100vh;
   min-height: 100vh;
 }
 }
+
 .ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
 .ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
   left: unset;
   left: unset;
 }
 }
@@ -36,11 +39,13 @@ ol {
   .ant-table {
   .ant-table {
     width: 100%;
     width: 100%;
     overflow-x: auto;
     overflow-x: auto;
+
     &-thead > tr,
     &-thead > tr,
     &-tbody > tr {
     &-tbody > tr {
       > th,
       > th,
       > td {
       > td {
         white-space: pre;
         white-space: pre;
+
         > span {
         > span {
           display: block;
           display: block;
         }
         }

+ 2 - 0
src/pages/device/Product/Detail/Access/index.less

@@ -76,11 +76,13 @@
 
 
 .config {
 .config {
   width: 48%;
   width: 48%;
+
   .title {
   .title {
     width: 100%;
     width: 100%;
     margin-bottom: 10px;
     margin-bottom: 10px;
     font-weight: 600;
     font-weight: 600;
   }
   }
+
   .title::before {
   .title::before {
     margin-right: 10px;
     margin-right: 10px;
     background-color: #2810ff;
     background-color: #2810ff;

+ 2 - 2
src/pages/device/components/Metadata/Base/Edit/index.tsx

@@ -136,8 +136,8 @@ const Edit = observer((props: Props) => {
   registerValidateRules({
   registerValidateRules({
     validateId(value) {
     validateId(value) {
       if (!value) return '';
       if (!value) return '';
-      const reg = new RegExp('^\\w{3,20}$');
-      return reg.exec(value) ? '' : 'ID只能由数字、26个英文字母或者下划线组成';
+      const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
+      return reg.exec(value) ? '' : 'ID只能由数字、字母、下划线、中划线组成';
     },
     },
   });
   });
   const valueTypeConfig = {
   const valueTypeConfig = {

+ 5 - 0
src/pages/link/AccessConfig/Detail/Access/index.less

@@ -3,6 +3,7 @@
   flex-direction: column;
   flex-direction: column;
   align-items: center;
   align-items: center;
   margin: 20px 30px;
   margin: 20px 30px;
+
   .steps {
   .steps {
     width: 100%;
     width: 100%;
   }
   }
@@ -36,6 +37,7 @@
   display: flex;
   display: flex;
   margin-top: 10px;
   margin-top: 10px;
   color: rgba(0, 0, 0, 0.55);
   color: rgba(0, 0, 0, 0.55);
+
   .item {
   .item {
     width: 100%;
     width: 100%;
     margin: 5px 0;
     margin: 5px 0;
@@ -48,14 +50,17 @@
 .view {
 .view {
   display: flex;
   display: flex;
   justify-content: space-between;
   justify-content: space-between;
+
   .info,
   .info,
   .config {
   .config {
     width: 48%;
     width: 48%;
+
     .title {
     .title {
       width: 100%;
       width: 100%;
       margin-bottom: 10px;
       margin-bottom: 10px;
       font-weight: 600;
       font-weight: 600;
     }
     }
+
     .title::before {
     .title::before {
       margin-right: 10px;
       margin-right: 10px;
       background-color: #2810ff;
       background-color: #2810ff;

+ 33 - 6
src/pages/link/Protocol/index.tsx

@@ -2,14 +2,15 @@ import { PageContainer } from '@ant-design/pro-layout';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
 import { useRef } from 'react';
 import { useRef } from 'react';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
-import { Badge, message, Popconfirm, Tooltip } from 'antd';
+import { Badge, Button, message, Popconfirm, Tooltip } from 'antd';
 import { CheckCircleOutlined, DeleteOutlined, EditOutlined, StopOutlined } from '@ant-design/icons';
 import { CheckCircleOutlined, DeleteOutlined, EditOutlined, StopOutlined } from '@ant-design/icons';
 import BaseCrud from '@/components/BaseCrud';
 import BaseCrud from '@/components/BaseCrud';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import type { ISchema } from '@formily/json-schema';
 import type { ISchema } from '@formily/json-schema';
 import { CurdModel } from '@/components/BaseCrud/model';
 import { CurdModel } from '@/components/BaseCrud/model';
 import Service from '@/pages/link/Protocol/service';
 import Service from '@/pages/link/Protocol/service';
-import { onFormMount, registerValidateRules } from '@formily/core';
+import { onFormValuesChange, registerValidateRules } from '@formily/core';
+import { Store } from 'jetlinks-store';
 
 
 export const service = new Service('protocol');
 export const service = new Service('protocol');
 const Protocol = () => {
 const Protocol = () => {
@@ -19,9 +20,9 @@ const Protocol = () => {
   const modifyState = async (id: string, type: 'deploy' | 'un-deploy') => {
   const modifyState = async (id: string, type: 'deploy' | 'un-deploy') => {
     const resp = await service.modifyState(id, type);
     const resp = await service.modifyState(id, type);
     if (resp.status === 200) {
     if (resp.status === 200) {
-      message.success('操作成功!');
+      message.success('插件发布成功!');
     } else {
     } else {
-      message.error('操作失败!');
+      message.error('插件发布失败!');
     }
     }
     actionRef.current?.reload();
     actionRef.current?.reload();
   };
   };
@@ -137,7 +138,7 @@ const Protocol = () => {
   registerValidateRules({
   registerValidateRules({
     validateId(value) {
     validateId(value) {
       if (!value) return '';
       if (!value) return '';
-      const reg = new RegExp('^\\w{3,20}$');
+      const reg = new RegExp('^[0-9a-zA-Z_\\\\-]+$');
       return reg.exec(value) ? '' : 'ID只能由数字、26个英文字母或者下划线组成';
       return reg.exec(value) ? '' : 'ID只能由数字、26个英文字母或者下划线组成';
     },
     },
   });
   });
@@ -291,12 +292,38 @@ const Protocol = () => {
         schema={schema}
         schema={schema}
         actionRef={actionRef}
         actionRef={actionRef}
         formEffect={() => {
         formEffect={() => {
-          onFormMount((form) => {
+          onFormValuesChange((form) => {
             form.setFieldState('id', (state) => {
             form.setFieldState('id', (state) => {
               state.disabled = CurdModel.model === 'edit';
               state.disabled = CurdModel.model === 'edit';
             });
             });
           });
           });
         }}
         }}
+        footer={
+          <>
+            <Button onClick={CurdModel.close}>取消</Button>
+            <Button
+              type="primary"
+              onClick={() => {
+                Store.set('save-data', true);
+              }}
+            >
+              保存
+            </Button>
+            <Button
+              type="primary"
+              onClick={() => {
+                Store.set('save-data', async (data: any) => {
+                  // 获取到的保存的数据
+                  if (data.id) {
+                    await modifyState(data.id, 'deploy');
+                  }
+                });
+              }}
+            >
+              保存并发布
+            </Button>
+          </>
+        }
       />
       />
       {/* {visible && <Debug data={current} close={() => setVisible(!visible)} />} */}
       {/* {visible && <Debug data={current} close={() => setVisible(!visible)} />} */}
     </PageContainer>
     </PageContainer>

+ 10 - 4
src/pages/link/Type/Save/index.tsx

@@ -102,10 +102,16 @@ const Save = observer(() => {
         effects() {
         effects() {
           onFieldValueChange('type', (field, f) => {
           onFieldValueChange('type', (field, f) => {
             const value = (field as Field).value;
             const value = (field as Field).value;
-            f.deleteValuesIn('configuration');
-            f.deleteValuesIn('cluster');
-            f.clearErrors();
-
+            if (f.modified) {
+              f.deleteValuesIn('configuration');
+              f.deleteValuesIn('cluster');
+              f.clearErrors();
+              // 设置默认值
+              f.setFieldState('grid.configuration.panel1.layout2.host', (state) => {
+                state.value = '0.0.0.0';
+                state.disabled = true;
+              });
+            }
             const _host = filterConfigByType(_.cloneDeep(configRef.current), value);
             const _host = filterConfigByType(_.cloneDeep(configRef.current), value);
             f.setFieldState('grid.configuration.panel1.layout2.host', (state) => {
             f.setFieldState('grid.configuration.panel1.layout2.host', (state) => {
               state.dataSource = _host.map((item) => ({ label: item.host, value: item.host }));
               state.dataSource = _host.map((item) => ({ label: item.host, value: item.host }));

+ 4 - 12
src/pages/link/Type/index.tsx

@@ -87,7 +87,7 @@ const Network = () => {
         defaultMessage: '状态',
         defaultMessage: '状态',
       }),
       }),
       render: (text, record) => {
       render: (text, record) => {
-        if (record.state.value === 'disabled') {
+        if (record.state.value === 'enabled') {
           return <Badge color="lime" text="正常" />;
           return <Badge color="lime" text="正常" />;
         }
         }
         return <Badge color="red" text="禁用" />;
         return <Badge color="red" text="禁用" />;
@@ -140,10 +140,7 @@ const Network = () => {
         </a>,
         </a>,
         <a key="changeState">
         <a key="changeState">
           <Popconfirm
           <Popconfirm
-            title={intl.formatMessage({
-              id: `pages.data.option.${record.state.value}.tips`,
-              defaultMessage: `确认${record.state.value === 'enabled' ? '禁用' : '启用'}?`,
-            })}
+            title={`确认${record.state.value === 'enabled' ? '禁用' : '启用'}?`}
             onConfirm={async () => {
             onConfirm={async () => {
               // await service.update({
               // await service.update({
               //   id: record.id,
               //   id: record.id,
@@ -163,13 +160,8 @@ const Network = () => {
               actionRef.current?.reload();
               actionRef.current?.reload();
             }}
             }}
           >
           >
-            <Tooltip
-              title={intl.formatMessage({
-                id: `pages.data.option.${record.state.value}`,
-                defaultMessage: record.state.value === 'enabled' ? '禁用' : '启用',
-              })}
-            >
-              {record.state.value === 'disabled' ? <CloseCircleOutlined /> : <PlayCircleOutlined />}
+            <Tooltip title={record.state.value === 'enabled' ? '禁用' : '启用'}>
+              {record.state.value === 'enabled' ? <CloseCircleOutlined /> : <PlayCircleOutlined />}
             </Tooltip>
             </Tooltip>
           </Popconfirm>
           </Popconfirm>
         </a>,
         </a>,