Procházet zdrojové kódy

merge(role): role

fix: 角色接口管理
Lind před 3 roky
rodič
revize
96e2a7732f

+ 9 - 10
src/pages/device/Instance/Export/index.tsx

@@ -1,7 +1,7 @@
-import { FormItem, FormLayout, Select } from '@formily/antd';
+import { FormItem, FormLayout, Select, Radio } from '@formily/antd';
 import { createForm } from '@formily/core';
 import { createSchemaField, FormProvider } from '@formily/react';
-import { Alert, Modal, Radio } from 'antd';
+import { Alert, Modal } from 'antd';
 import 'antd/lib/tree-select/style/index.less';
 import { useEffect, useState } from 'react';
 import { service } from '@/pages/device/Instance';
@@ -35,13 +35,13 @@ const Export = (props: Props) => {
           label: item.name,
           value: item.id,
         }));
-        console.log(list);
         setProductList(list);
       }
     });
   }, []);
 
   const form = createForm();
+
   const schema = {
     type: 'object',
     properties: {
@@ -62,9 +62,14 @@ const Export = (props: Props) => {
             enum: [...productList],
           },
           fileType: {
-            type: 'number',
             title: '文件格式',
             default: 'xlsx',
+            'x-decorator': 'FormItem',
+            'x-component': 'Radio.Group',
+            'x-component-props': {
+              optionType: 'button',
+              buttonStyle: 'solid',
+            },
             enum: [
               {
                 label: 'xlsx',
@@ -75,12 +80,6 @@ const Export = (props: Props) => {
                 value: 'csv',
               },
             ],
-            'x-decorator': 'FormItem',
-            'x-component': 'Radio.Group',
-            'x-component-props': {
-              optionType: 'button',
-              buttonStyle: 'solid',
-            },
           },
         },
       },

+ 66 - 53
src/pages/device/Instance/Import/index.tsx

@@ -76,11 +76,50 @@ const downloadTemplate = (type: string, product: string) => {
 };
 
 const NormalUpload = (props: any) => {
+  const [importLoading, setImportLoading] = useState(false);
+  const [flag, setFlag] = useState<boolean>(true);
+  const [count, setCount] = useState<number>(0);
+  const [errMessage, setErrMessage] = useState<string>('');
+
+  const submitData = (fileUrl: string) => {
+    if (!!fileUrl) {
+      setCount(0);
+      setErrMessage('');
+      setFlag(true);
+      const autoDeploy = !!props?.fileType?.autoDeploy || false;
+      setImportLoading(true);
+      let dt = 0;
+      const source = new EventSourcePolyfill(
+        `/${SystemConst.API_BASE}/device/instance/${
+          props.product
+        }/import?fileUrl=${fileUrl}&autoDeploy=${autoDeploy}&:X_Access_Token=${Token.get()}`,
+      );
+      source.onmessage = (e: any) => {
+        const res = JSON.parse(e.data);
+        if (res.success) {
+          props.onChange(false);
+          const temp = res.result.total;
+          dt += temp;
+          setCount(dt);
+        } else {
+          setErrMessage(res.message);
+        }
+      };
+      source.onerror = () => {
+        setFlag(false);
+        source.close();
+      };
+      source.onopen = () => {};
+    } else {
+      message.error('请先上传文件');
+    }
+  };
   return (
     <div>
       <Space>
         <Upload
           action={`/${SystemConst.API_BASE}/file/static`}
+          accept={`.${props?.fileType?.fileType || 'xlsx'}`}
           headers={{
             'X-Access-Token': Token.get(),
           }}
@@ -88,7 +127,7 @@ const NormalUpload = (props: any) => {
             if (info.file.status === 'done') {
               message.success('上传成功');
               const resp: any = info.file.response || { result: '' };
-              props.onChange(resp?.result || '');
+              submitData(resp?.result || '');
             }
           }}
           showUploadList={false}
@@ -115,6 +154,17 @@ const NormalUpload = (props: any) => {
           </a>
         </div>
       </Space>
+      {importLoading && (
+        <div style={{ marginLeft: 20 }}>
+          {flag ? (
+            <Badge status="processing" text="进行中" />
+          ) : (
+            <Badge status="success" text="已完成" />
+          )}
+          <span style={{ marginLeft: 15 }}>总数量:{count}</span>
+          <p style={{ color: 'red' }}>{errMessage}</p>
+        </div>
+      )}
     </div>
   );
 };
@@ -122,10 +172,6 @@ const NormalUpload = (props: any) => {
 const Import = (props: Props) => {
   const { visible, close } = props;
   const [productList, setProductList] = useState<any[]>([]);
-  const [importLoading, setImportLoading] = useState(false);
-  const [flag, setFlag] = useState<boolean>(true);
-  const [count, setCount] = useState<number>(0);
-  const [errMessage, setErrMessage] = useState<string>('');
 
   const SchemaField = createSchemaField({
     components: {
@@ -157,12 +203,24 @@ const Import = (props: Props) => {
         form.setFieldState('*(fileType, upload)', (state) => {
           state.visible = !!field.value;
         });
-        form.setFieldState('*(fileType)', (state) => {
+        form.setFieldState('*(upload)', (state) => {
           state.componentProps = {
             product: field.value,
           };
         });
       });
+      onFieldValueChange('fileType', (field) => {
+        form.setFieldState('*(upload)', (state) => {
+          state.componentProps = {
+            fileType: field.value,
+          };
+        });
+      });
+      onFieldValueChange('upload', (field) => {
+        if (!field.value) {
+          close();
+        }
+      });
     },
   });
 
@@ -204,52 +262,18 @@ const Import = (props: Props) => {
     },
   };
 
-  const submitData = () => {
-    const values = form.getFormState().values;
-    if (!!values?.upload) {
-      setCount(0);
-      setErrMessage('');
-      setFlag(true);
-      const autoDeploy = !!values?.fileType?.autoDeploy || false;
-      setImportLoading(true);
-      let dt = 0;
-      const source = new EventSourcePolyfill(
-        `/${SystemConst.API_BASE}/device/instance/${values.product}/import?fileUrl=${
-          values?.upload
-        }&autoDeploy=${autoDeploy}&:X_Access_Token=${Token.get()}`,
-      );
-      source.onmessage = (e: any) => {
-        const res = JSON.parse(e.data);
-        if (res.success) {
-          close();
-          const temp = res.result.total;
-          dt += temp;
-          setCount(dt);
-        } else {
-          setErrMessage(res.message);
-        }
-      };
-      source.onerror = () => {
-        setFlag(false);
-        source.close();
-      };
-      source.onopen = () => {};
-    } else {
-      message.error('请先上传文件');
-    }
-  };
   return (
     <Modal
       visible={visible}
       onCancel={() => close()}
       width="35vw"
       title="导出"
-      onOk={() => submitData()}
+      onOk={() => close()}
       footer={[
         <Button key="cancel" onClick={() => close()}>
           取消
         </Button>,
-        <Button key="ok" type="primary" onClick={() => submitData()}>
+        <Button key="ok" type="primary" onClick={() => close()}>
           确认
         </Button>,
       ]}
@@ -259,17 +283,6 @@ const Import = (props: Props) => {
           <SchemaField schema={schema} />
         </FormProvider>
       </div>
-      {importLoading && (
-        <div style={{ marginLeft: 20 }}>
-          {flag ? (
-            <Badge status="processing" text="进行中" />
-          ) : (
-            <Badge status="success" text="已完成" />
-          )}
-          <span style={{ marginLeft: 15 }}>总数量:{count}</span>
-          <p style={{ color: 'red' }}>{errMessage}</p>
-        </div>
-      )}
     </Modal>
   );
 };

+ 167 - 3
src/pages/device/Product/Detail/PropertyImport/index.tsx

@@ -1,16 +1,180 @@
 import { Modal } from 'antd';
 import MetadataModel from '@/pages/device/components/Metadata/Base/model';
+import { FormItem, FormLayout, Radio } from '@formily/antd';
+import { createForm, onFieldValueChange } from '@formily/core';
+import { createSchemaField, FormProvider } from '@formily/react';
+import { Button, message, Space, Upload } from 'antd';
+import 'antd/lib/tree-select/style/index.less';
+import { UploadOutlined } from '@ant-design/icons';
+import SystemConst from '@/utils/const';
+import Token from '@/utils/token';
+import { useParams } from 'umi';
+import { service } from '../..';
+
+const downloadTemplate = (type: string, productId: string) => {
+  const formElement = document.createElement('form');
+  formElement.style.display = 'display:none;';
+  formElement.method = 'GET';
+  formElement.action = `/${SystemConst.API_BASE}/device/product/${productId}/property-metadata/template.${type}`;
+  const inputElement = document.createElement('input');
+  inputElement.type = 'hidden';
+  inputElement.name = ':X_Access_Token';
+  inputElement.value = Token.get();
+  formElement.appendChild(inputElement);
+  document.body.appendChild(formElement);
+  formElement.submit();
+  document.body.removeChild(formElement);
+};
+
+const NormalUpload = (props: any) => {
+  const param = useParams<{ id: string }>();
+  console.log(props?.fileType);
+
+  return (
+    <div>
+      <Space>
+        <Upload
+          accept={`.${props?.fileType || 'xlsx'}`}
+          action={`/${SystemConst.API_BASE}/file/static`}
+          headers={{
+            'X-Access-Token': Token.get(),
+          }}
+          onChange={(info) => {
+            if (info.file.status === 'done') {
+              message.success('上传成功');
+              const resp: any = info.file.response || { result: '' };
+              service.importProductProperty(param.id, resp?.result).then(() => {
+                // 更新产品物模型属性信息
+              });
+            }
+          }}
+          showUploadList={false}
+        >
+          <Button icon={<UploadOutlined />}>上传文件</Button>
+        </Upload>
+        <div style={{ marginLeft: 20 }}>
+          下载模板
+          <a
+            style={{ marginLeft: 10 }}
+            onClick={() => {
+              downloadTemplate('xlsx', param?.id);
+            }}
+          >
+            .xlsx
+          </a>
+          <a
+            style={{ marginLeft: 10 }}
+            onClick={() => {
+              downloadTemplate('csv', param?.id);
+            }}
+          >
+            .csv
+          </a>
+        </div>
+      </Space>
+    </div>
+  );
+};
 
 const PropertyImport = () => {
+  const SchemaField = createSchemaField({
+    components: {
+      Radio,
+      FormItem,
+      FormLayout,
+      NormalUpload,
+    },
+  });
+
+  const form = createForm({
+    effects() {
+      onFieldValueChange('fileType', (field) => {
+        form.setFieldState('*(upload)', (state) => {
+          state.componentProps = {
+            fileType: field.value,
+          };
+        });
+      });
+    },
+  });
+
+  const schema = {
+    type: 'object',
+    properties: {
+      layout: {
+        type: 'void',
+        'x-component': 'FormLayout',
+        'x-component-props': {
+          labelCol: 4,
+          wrapperCol: 18,
+          labelAlign: 'right',
+        },
+        properties: {
+          fileType: {
+            title: '文件格式',
+            'x-decorator': 'FormItem',
+            'x-component': 'Radio.Group',
+            default: 'xlsx',
+            'x-component-props': {
+              buttonStyle: 'solid',
+              optionType: 'button',
+            },
+            enum: [
+              {
+                label: 'xlsx',
+                value: 'xlsx',
+              },
+              {
+                label: 'csv',
+                value: 'csv',
+              },
+            ],
+          },
+          upload: {
+            type: 'string',
+            title: '文件上传',
+            'x-decorator': 'FormItem',
+            'x-component': 'NormalUpload',
+          },
+        },
+      },
+    },
+  };
+
   return (
     <Modal
       visible
-      onCancel={() => {
+      onCancel={() => close()}
+      width="35vw"
+      title="导入属性"
+      onOk={() => {
         MetadataModel.importMetadata = false;
       }}
-      title="导入属性"
+      footer={[
+        <Button
+          key="cancel"
+          onClick={() => {
+            MetadataModel.importMetadata = false;
+          }}
+        >
+          取消
+        </Button>,
+        <Button
+          key="ok"
+          type="primary"
+          onClick={() => {
+            MetadataModel.importMetadata = false;
+          }}
+        >
+          确认
+        </Button>,
+      ]}
     >
-      ...
+      <div style={{ marginTop: '20px' }}>
+        <FormProvider form={form}>
+          <SchemaField schema={schema} />
+        </FormProvider>
+      </div>
     </Modal>
   );
 };

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

@@ -133,6 +133,15 @@ class Service extends BaseService<ProductItem> {
     request(`/${SystemConst.API_BASE}/protocol/${protocol}/transports`, {
       method: 'GET',
     });
+
+  //上传物模型属性
+  public importProductProperty = (productId: string, fileUrl: string) =>
+    request(
+      `/${SystemConst.API_BASE}/device/product/${productId}/property-metadata/import?fileUrl=${fileUrl}`,
+      {
+        method: 'POST',
+      },
+    );
 }
 
 export default Service;

+ 1 - 1
src/pages/system/Role/Edit/Permission/DataPermission.tsx

@@ -28,7 +28,7 @@ const DataPermission = (props: Props) => {
   useEffect(() => {
     if (typeList.length > 0) {
       typeList.map((item) => {
-        service.queryDimensionsList(item.id).subscribe((resp) => {
+        service.queryAssetsList(item.id).subscribe((resp) => {
           if (resp.status === 200) {
             dimensionsList[item.id] = resp.result;
             setDimensionsList({ ...dimensionsList });

+ 2 - 2
src/pages/system/Role/service.ts

@@ -41,10 +41,10 @@ class Service extends BaseService<RoleItem> {
         }),
       ),
     ).pipe(map((item) => item));
-  queryDimensionsList = (type: string) =>
+  queryAssetsList = (type: string) =>
     defer(() =>
       from(
-        request(`/${SystemConst.API_BASE}/asset/${type}/dimensions`, {
+        request(`/${SystemConst.API_BASE}/assets/access-support/${type}`, {
           method: 'GET',
         }),
       ),