瀏覽代碼

feat(部门管理): 1.对接部门资产分配接口;2.添加部门管理国际化

xieyonghong 3 年之前
父節點
當前提交
13c4d79b49

+ 2 - 2
config/routes.ts

@@ -84,14 +84,14 @@
       {
         hideInMenu: true,
         path: '/system/department/:id/assets',
-        name: 'Assets',
+        name: 'assets',
         icon: 'smile',
         component: './system/Department/Assets',
       },
       {
         hideInMenu: true,
         path: '/system/department/:id/user',
-        name: 'Member',
+        name: 'member',
         icon: 'smile',
         component: './system/Department/Member',
       },

+ 3 - 0
src/locales/zh-CN/menu.ts

@@ -11,6 +11,9 @@ export default {
   'menu.system.permission': '权限管理',
   'menu.system.tenant': '租户管理',
   'menu.system.datasource': '数据源管理',
+  'menu.system.department': '部门管理',
+  'menu.system.assets': '资产分配',
+  'menu.system.member': '用户',
   'menu.device': '设备管理',
   'menu.device.product': '产品',
   'menu.device.product-detail': '产品详情',

+ 3 - 0
src/locales/zh-CN/pages.ts

@@ -28,6 +28,7 @@ export default {
   'pages.data.option.download': '下载',
   'pages.data.option.record': '通知记录',
   'pages.data.option.save': '保存',
+  'pages.data.option.assets': '资产分配',
   'pages.searchTable.new': '新建',
   'pages.searchTable.titleStatus': '状态',
   'pages.searchTable.titleStatus.all': '全部',
@@ -121,6 +122,8 @@ export default {
   'pages.system.org.option.bindUser': '绑定用户',
   'pages.system.org.option.permission': '权限分配',
   'pages.system.org.option.add': '添加下级',
+  // 系统设置-部门管理
+  'pages.system.department.user': '用户',
   // 系统设置-第三方平台
   'pages.system.openApi': '第三方平台',
   'pages.system.openApi.username': '用户名',

+ 77 - 31
src/pages/system/Department/Assets/deivce/bind.tsx

@@ -1,14 +1,15 @@
 // 资产-产品分类-绑定
 import type { ProColumns, ActionType } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { service } from './index';
+import { DeviceBadge, service } from './index';
 import { Modal } from 'antd';
 import { useParams } from 'umi';
 import Models from './model';
-import { useRef } from 'react';
+import { useEffect, useRef, useState } from 'react';
 import { observer } from '@formily/react';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import type { ProductCategoryItem } from '@/pages/system/Department/typings';
+import type { DeviceItem } from '@/pages/system/Department/typings';
+import PermissionModal from '@/pages/system/Department/Assets/permissionModal';
 
 interface Props {
   reload: () => void;
@@ -20,46 +21,68 @@ const Bind = observer((props: Props) => {
   const intl = useIntl();
   const param = useParams<{ id: string }>();
   const actionRef = useRef<ActionType>();
-  const columns: ProColumns<ProductCategoryItem>[] = [
+  const [perVisible, setPerVisible] = useState(false);
+
+  const columns: ProColumns<DeviceItem>[] = [
+    {
+      dataIndex: 'id',
+      title: 'ID',
+      width: 220,
+    },
     {
       dataIndex: 'name',
       title: intl.formatMessage({
-        id: 'pages.system.name',
-        defaultMessage: '姓名',
+        id: 'pages.table.name',
+        defaultMessage: '名',
       }),
       search: {
         transform: (value) => ({ name$LIKE: value }),
       },
     },
     {
-      dataIndex: 'username',
       title: intl.formatMessage({
-        id: 'pages.system.username',
-        defaultMessage: '用户名',
+        id: 'pages.device.firmware.productName',
+        defaultMessage: '所属产品',
       }),
-      search: {
-        transform: (value) => ({ username$LIKE: value }),
+      dataIndex: 'configuration',
+      render: (_, row) => {
+        return row.productName;
       },
+      search: false,
+    },
+    {
+      title: intl.formatMessage({
+        id: 'pages.device.instance.registrationTime',
+        defaultMessage: '注册时间',
+      }),
+      dataIndex: 'registryTime',
+      search: false,
+    },
+    {
+      title: intl.formatMessage({
+        id: 'pages.searchTable.titleStatus',
+        defaultMessage: '状态',
+      }),
+      dataIndex: 'state',
+      render: (_, row) => <DeviceBadge type={row.state.value} text={row.state.text} />,
+      search: false,
     },
   ];
 
   const handleBind = () => {
-    if (Models.bindUsers.length) {
-      // service.handleUser(param.id, Models.bindUsers, 'bind').subscribe({
-      //   next: () => message.success('操作成功'),
-      //   error: () => message.error('操作失败'),
-      //   complete: () => {
-      //     Models.bindUsers = [];
-      //     actionRef.current?.reload();
-      //     props.reload();
-      //     props.onCancel()
-      //   },
-      // });
+    if (Models.bindKeys.length) {
+      setPerVisible(true);
     } else {
       props.onCancel();
     }
   };
 
+  useEffect(() => {
+    if (props.visible) {
+      actionRef.current?.reload();
+    }
+  }, [props.visible]);
+
   return (
     <Modal
       visible={props.visible}
@@ -68,7 +91,19 @@ const Bind = observer((props: Props) => {
       width={990}
       title="绑定"
     >
-      <ProTable<ProductCategoryItem>
+      <PermissionModal
+        visible={perVisible}
+        type="device"
+        bindKeys={Models.bindKeys}
+        onCancel={(type) => {
+          setPerVisible(false);
+          if (type) {
+            props.reload();
+            props.onCancel();
+          }
+        }}
+      />
+      <ProTable<DeviceItem>
         actionRef={actionRef}
         columns={columns}
         rowKey="id"
@@ -76,17 +111,28 @@ const Bind = observer((props: Props) => {
           pageSize: 5,
         }}
         rowSelection={{
-          selectedRowKeys: Models.bindUsers.map((item) => item.userId),
+          selectedRowKeys: Models.bindKeys,
           onChange: (selectedRowKeys, selectedRows) => {
-            Models.bindUsers = selectedRows.map((item) => ({
-              name: item.name,
-              userId: item.id,
-            }));
+            Models.bindKeys = selectedRows.map((item) => item.id);
           },
         }}
-        request={(params) => service.queryProductCategoryList(params)}
-        defaultParams={{
-          'id$tenant-user$not': param.id,
+        request={(params) => service.queryDeviceList(params)}
+        params={{
+          terms: [
+            {
+              column: 'id',
+              termType: 'dim-assets$not',
+              value: {
+                assetType: 'device',
+                targets: [
+                  {
+                    type: 'org',
+                    id: param.id,
+                  },
+                ],
+              },
+            },
+          ],
         }}
       />
     </Modal>

+ 126 - 75
src/pages/system/Department/Assets/deivce/index.tsx

@@ -2,16 +2,30 @@
 import ProTable from '@jetlinks/pro-table';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { Button, Popconfirm, Tooltip } from 'antd';
+import { Button, message, Popconfirm, Tooltip, Badge } from 'antd';
 import { useRef } from 'react';
 import { useParams } from 'umi';
 import { observer } from '@formily/react';
-import type { ProductItem } from '@/pages/system/Department/typings';
+import type { DeviceItem } from '@/pages/system/Department/typings';
 import { DisconnectOutlined, PlusOutlined } from '@ant-design/icons';
-import Models from '@/pages/system/Department/Assets/productCategory/model';
+import Models from './model';
 import Service from '@/pages/system/Department/Assets/service';
+import Bind from './bind';
 
-export const service = new Service<ProductItem>();
+export const service = new Service<DeviceItem>();
+
+type DeviceBadgeProps = {
+  type: string;
+  text: string;
+};
+export const DeviceBadge = (props: DeviceBadgeProps) => {
+  const STATUS = {
+    notActive: 'processing',
+    offline: 'error',
+    online: 'success',
+  };
+  return <Badge status={STATUS[props.type]} text={props.text} />;
+};
 
 export default observer(() => {
   const intl = useIntl();
@@ -19,15 +33,27 @@ export default observer(() => {
 
   const param = useParams<{ id: string }>();
 
+  /**
+   * 解除资产绑定
+   */
   const handleUnBind = () => {
-    // service.handleUser(param.id, Models.unBindUsers, 'unbind').subscribe({
-    //   next: () => message.success('操作成功'),
-    //   error: () => message.error('操作失败'),
-    //   complete: () => {
-    //     Models.unBindUsers = [];
-    //     actionRef.current?.reload();
-    //   },
-    // });
+    service
+      .unBind('device', [
+        {
+          targetType: 'org',
+          targetId: param.id,
+          assetType: 'device',
+          assetIdList: Models.unBindKeys,
+        },
+      ])
+      .subscribe({
+        next: () => message.success('操作成功'),
+        error: () => message.error('操作失败'),
+        complete: () => {
+          Models.unBindKeys = [];
+          actionRef.current?.reload();
+        },
+      });
   };
 
   const singleUnBind = (key: string) => {
@@ -35,17 +61,17 @@ export default observer(() => {
     handleUnBind();
   };
 
-  const columns: ProColumns<ProductItem>[] = [
+  const columns: ProColumns<DeviceItem>[] = [
     {
-      dataIndex: 'index',
-      valueType: 'indexBorder',
-      width: 48,
+      dataIndex: 'id',
+      title: 'ID',
+      width: 220,
     },
     {
       dataIndex: 'name',
       title: intl.formatMessage({
-        id: 'pages.system.name',
-        defaultMessage: '名',
+        id: 'pages.table.name',
+        defaultMessage: '名',
       }),
       search: {
         transform: (value) => ({ name$LIKE: value }),
@@ -53,11 +79,21 @@ export default observer(() => {
     },
     {
       title: intl.formatMessage({
-        id: 'pages.system.tenant.memberManagement.administrators',
-        defaultMessage: '管理员',
+        id: 'pages.device.firmware.productName',
+        defaultMessage: '所属产品',
+      }),
+      dataIndex: 'configuration',
+      render: (_, row) => {
+        return row.productName;
+      },
+      search: false,
+    },
+    {
+      title: intl.formatMessage({
+        id: 'pages.device.instance.registrationTime',
+        defaultMessage: '注册时间',
       }),
-      dataIndex: 'adminMember',
-      renderText: (text) => (text ? '是' : '否'),
+      dataIndex: 'registryTime',
       search: false,
     },
     {
@@ -66,7 +102,7 @@ export default observer(() => {
         defaultMessage: '状态',
       }),
       dataIndex: 'state',
-      renderText: (text) => text.text,
+      render: (_, row) => <DeviceBadge type={row.state.value} text={row.state.text} />,
       search: false,
     },
     {
@@ -103,63 +139,78 @@ export default observer(() => {
     },
   ];
 
+  const closeModal = () => {
+    Models.bind = false;
+    Models.bindKeys = [];
+  };
+
   return (
-    <ProTable<ProductItem>
-      actionRef={actionRef}
-      columns={columns}
-      // schema={schema}
-      rowKey="id"
-      defaultParams={{
-        id: {
-          termType: 'dim-assets',
-          value: {
-            assetType: 'device',
-            targets: [
-              {
-                type: 'org',
-                id: param.id,
+    <>
+      <Bind
+        visible={Models.bind}
+        onCancel={closeModal}
+        reload={() => actionRef.current?.reload()}
+      />
+      <ProTable<DeviceItem>
+        actionRef={actionRef}
+        columns={columns}
+        // schema={schema}
+        rowKey="id"
+        params={{
+          terms: [
+            {
+              column: 'id',
+              termType: 'dim-assets',
+              value: {
+                assetType: 'device',
+                targets: [
+                  {
+                    type: 'org',
+                    id: param.id,
+                  },
+                ],
               },
-            ],
+            },
+          ],
+        }}
+        request={(params) => service.queryDeviceList(params)}
+        rowSelection={{
+          selectedRowKeys: Models.unBindKeys,
+          onChange: (selectedRowKeys, selectedRows) => {
+            Models.unBindKeys = selectedRows.map((item) => item.id);
           },
-        },
-      }}
-      request={(params) => service.queryDeviceList(params)}
-      rowSelection={{
-        selectedRowKeys: Models.unBindKeys,
-        onChange: (selectedRowKeys, selectedRows) => {
-          Models.unBindKeys = selectedRows.map((item) => item.id);
-        },
-      }}
-      toolBarRender={() => [
-        <Button
-          onClick={() => {
-            Models.bind = true;
-          }}
-          icon={<PlusOutlined />}
-          type="primary"
-          key="bind"
-        >
-          {intl.formatMessage({
-            id: 'pages.system.role.option.bindUser',
-            defaultMessage: '分配资产',
-          })}
-        </Button>,
-        <Popconfirm
-          title={intl.formatMessage({
-            id: 'pages.system.role.option.unBindUser',
-            defaultMessage: '是否批量解除绑定',
-          })}
-          key="unBind"
-          onConfirm={handleUnBind}
-        >
-          <Button icon={<DisconnectOutlined />} key="bind">
+        }}
+        toolBarRender={() => [
+          <Button
+            onClick={() => {
+              Models.bind = true;
+            }}
+            icon={<PlusOutlined />}
+            type="primary"
+            key="bind"
+          >
             {intl.formatMessage({
+              id: 'pages.data.option.assets',
+              defaultMessage: '资产分配',
+            })}
+          </Button>,
+          <Popconfirm
+            title={intl.formatMessage({
               id: 'pages.system.role.option.unBindUser',
-              defaultMessage: '批量解绑',
+              defaultMessage: '是否批量解除绑定',
             })}
-          </Button>
-        </Popconfirm>,
-      ]}
-    />
+            key="unBind"
+            onConfirm={handleUnBind}
+          >
+            <Button icon={<DisconnectOutlined />} key="bind">
+              {intl.formatMessage({
+                id: 'pages.system.role.option.unBindUser',
+                defaultMessage: '批量解绑',
+              })}
+            </Button>
+          </Popconfirm>,
+        ]}
+      />
+    </>
   );
 });

+ 4 - 4
src/pages/system/Department/Assets/deivce/model.ts

@@ -3,14 +3,14 @@ import { model } from '@formily/reactive';
 
 type ModelType = {
   bind: boolean;
-  bindUsers: { name: string; userId: string }[];
-  unBindUsers: string[];
+  bindKeys: string[];
+  unBindKeys: string[];
 };
 
 const Models = model<ModelType>({
   bind: false,
-  bindUsers: [],
-  unBindUsers: [],
+  bindKeys: [],
+  unBindKeys: [],
 });
 
 export default Models;

+ 6 - 2
src/pages/system/Department/Assets/permissionModal.tsx

@@ -78,8 +78,12 @@ export default (props: PerModalProps) => {
         type: 'array',
         title: '资产权限',
         'x-decorator': 'FormItem',
-        'x-component': 'Checkbox',
-        'x-options': [],
+        'x-component': 'Checkbox.Group',
+        enum: [
+          { label: '查看', value: 'read' },
+          { label: '编辑', value: 'save' },
+          { label: '删除', value: 'delete' },
+        ],
       },
     },
   };

+ 50 - 22
src/pages/system/Department/Assets/product/bind.tsx

@@ -5,10 +5,11 @@ import { service } from './index';
 import { Modal } from 'antd';
 import { useParams } from 'umi';
 import Models from './model';
-import { useRef } from 'react';
+import { useEffect, useRef, useState } from 'react';
 import { observer } from '@formily/react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import type { ProductCategoryItem } from '@/pages/system/Department/typings';
+import PermissionModal from '@/pages/system/Department/Assets/permissionModal';
 
 interface Props {
   reload: () => void;
@@ -20,11 +21,18 @@ const Bind = observer((props: Props) => {
   const intl = useIntl();
   const param = useParams<{ id: string }>();
   const actionRef = useRef<ActionType>();
+  const [perVisible, setPerVisible] = useState(false);
+
   const columns: ProColumns<ProductCategoryItem>[] = [
     {
+      dataIndex: 'id',
+      title: 'ID',
+      width: 220,
+    },
+    {
       dataIndex: 'name',
       title: intl.formatMessage({
-        id: 'pages.system.name',
+        id: 'pages.table.name',
         defaultMessage: '姓名',
       }),
       search: {
@@ -34,7 +42,7 @@ const Bind = observer((props: Props) => {
     {
       dataIndex: 'username',
       title: intl.formatMessage({
-        id: 'pages.system.username',
+        id: 'pages.table.describe',
         defaultMessage: '用户名',
       }),
       search: {
@@ -44,22 +52,19 @@ const Bind = observer((props: Props) => {
   ];
 
   const handleBind = () => {
-    if (Models.bindUsers.length) {
-      // service.handleUser(param.id, Models.bindUsers, 'bind').subscribe({
-      //   next: () => message.success('操作成功'),
-      //   error: () => message.error('操作失败'),
-      //   complete: () => {
-      //     Models.bindUsers = [];
-      //     actionRef.current?.reload();
-      //     props.reload();
-      //     props.onCancel()
-      //   },
-      // });
+    if (Models.bindKeys.length) {
+      setPerVisible(true);
     } else {
       props.onCancel();
     }
   };
 
+  useEffect(() => {
+    if (props.visible) {
+      actionRef.current?.reload();
+    }
+  }, [props.visible]);
+
   return (
     <Modal
       visible={props.visible}
@@ -68,6 +73,18 @@ const Bind = observer((props: Props) => {
       width={990}
       title="绑定"
     >
+      <PermissionModal
+        visible={perVisible}
+        type="product"
+        bindKeys={Models.bindKeys}
+        onCancel={(type) => {
+          setPerVisible(false);
+          if (type) {
+            props.reload();
+            props.onCancel();
+          }
+        }}
+      />
       <ProTable<ProductCategoryItem>
         actionRef={actionRef}
         columns={columns}
@@ -76,17 +93,28 @@ const Bind = observer((props: Props) => {
           pageSize: 5,
         }}
         rowSelection={{
-          selectedRowKeys: Models.bindUsers.map((item) => item.userId),
+          selectedRowKeys: Models.bindKeys,
           onChange: (selectedRowKeys, selectedRows) => {
-            Models.bindUsers = selectedRows.map((item) => ({
-              name: item.name,
-              userId: item.id,
-            }));
+            Models.bindKeys = selectedRows.map((item) => item.id);
           },
         }}
-        request={(params) => service.queryProductCategoryList(params)}
-        defaultParams={{
-          'id$tenant-user$not': param.id,
+        request={(params) => service.queryProductList(params)}
+        params={{
+          terms: [
+            {
+              column: 'id',
+              termType: 'dim-assets$not',
+              value: {
+                assetType: 'product',
+                targets: [
+                  {
+                    type: 'org',
+                    id: param.id,
+                  },
+                ],
+              },
+            },
+          ],
         }}
       />
     </Modal>

+ 94 - 75
src/pages/system/Department/Assets/product/index.tsx

@@ -2,14 +2,15 @@
 import ProTable from '@jetlinks/pro-table';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { Button, Popconfirm, Tooltip } from 'antd';
+import { Button, message, Popconfirm, Tooltip } from 'antd';
 import { useRef } from 'react';
 import { useParams } from 'umi';
 import { observer } from '@formily/react';
 import type { ProductItem } from '@/pages/system/Department/typings';
 import { DisconnectOutlined, PlusOutlined } from '@ant-design/icons';
-import Models from '@/pages/system/Department/Assets/productCategory/model';
 import Service from '@/pages/system/Department/Assets/service';
+import Models from './model';
+import Bind from './bind';
 
 export const service = new Service<ProductItem>();
 
@@ -19,15 +20,27 @@ export default observer(() => {
 
   const param = useParams<{ id: string }>();
 
+  /**
+   * 解除资产绑定
+   */
   const handleUnBind = () => {
-    // service.handleUser(param.id, Models.unBindUsers, 'unbind').subscribe({
-    //   next: () => message.success('操作成功'),
-    //   error: () => message.error('操作失败'),
-    //   complete: () => {
-    //     Models.unBindUsers = [];
-    //     actionRef.current?.reload();
-    //   },
-    // });
+    service
+      .unBind('product', [
+        {
+          targetType: 'org',
+          targetId: param.id,
+          assetType: 'product',
+          assetIdList: Models.unBindKeys,
+        },
+      ])
+      .subscribe({
+        next: () => message.success('操作成功'),
+        error: () => message.error('操作失败'),
+        complete: () => {
+          Models.unBindKeys = [];
+          actionRef.current?.reload();
+        },
+      });
   };
 
   const singleUnBind = (key: string) => {
@@ -37,15 +50,15 @@ export default observer(() => {
 
   const columns: ProColumns<ProductItem>[] = [
     {
-      dataIndex: 'index',
-      valueType: 'indexBorder',
-      width: 48,
+      dataIndex: 'id',
+      title: 'ID',
+      width: 220,
     },
     {
       dataIndex: 'name',
       title: intl.formatMessage({
         id: 'pages.system.name',
-        defaultMessage: '名',
+        defaultMessage: '名',
       }),
       search: {
         transform: (value) => ({ name$LIKE: value }),
@@ -62,15 +75,6 @@ export default observer(() => {
     },
     {
       title: intl.formatMessage({
-        id: 'pages.searchTable.titleStatus',
-        defaultMessage: '状态',
-      }),
-      dataIndex: 'state',
-      renderText: (text) => text.text,
-      search: false,
-    },
-    {
-      title: intl.formatMessage({
         id: 'pages.data.option',
         defaultMessage: '操作',
       }),
@@ -103,63 +107,78 @@ export default observer(() => {
     },
   ];
 
+  const closeModal = () => {
+    Models.bind = false;
+    Models.bindKeys = [];
+  };
+
   return (
-    <ProTable<ProductItem>
-      actionRef={actionRef}
-      columns={columns}
-      // schema={schema}
-      rowKey="id"
-      defaultParams={{
-        id: {
-          termType: 'dim-assets',
-          value: {
-            assetType: 'product',
-            targets: [
-              {
-                type: 'org',
-                id: param.id,
+    <>
+      <Bind
+        visible={Models.bind}
+        onCancel={closeModal}
+        reload={() => actionRef.current?.reload()}
+      />
+      <ProTable<ProductItem>
+        actionRef={actionRef}
+        columns={columns}
+        // schema={schema}
+        rowKey="id"
+        params={{
+          terms: [
+            {
+              column: 'id',
+              termType: 'dim-assets',
+              value: {
+                assetType: 'product',
+                targets: [
+                  {
+                    type: 'org',
+                    id: param.id,
+                  },
+                ],
               },
-            ],
+            },
+          ],
+        }}
+        request={(params) => service.queryProductList(params)}
+        rowSelection={{
+          selectedRowKeys: Models.unBindKeys,
+          onChange: (selectedRowKeys, selectedRows) => {
+            Models.unBindKeys = selectedRows.map((item) => item.id);
           },
-        },
-      }}
-      request={(params) => service.queryProductList(params)}
-      rowSelection={{
-        selectedRowKeys: Models.unBindKeys,
-        onChange: (selectedRowKeys, selectedRows) => {
-          Models.unBindKeys = selectedRows.map((item) => item.id);
-        },
-      }}
-      toolBarRender={() => [
-        <Button
-          onClick={() => {
-            Models.bind = true;
-          }}
-          icon={<PlusOutlined />}
-          type="primary"
-          key="bind"
-        >
-          {intl.formatMessage({
-            id: 'pages.system.role.option.bindUser',
-            defaultMessage: '分配资产',
-          })}
-        </Button>,
-        <Popconfirm
-          title={intl.formatMessage({
-            id: 'pages.system.role.option.unBindUser',
-            defaultMessage: '是否批量解除绑定',
-          })}
-          key="unBind"
-          onConfirm={handleUnBind}
-        >
-          <Button icon={<DisconnectOutlined />} key="bind">
+        }}
+        toolBarRender={() => [
+          <Button
+            onClick={() => {
+              Models.bind = true;
+            }}
+            icon={<PlusOutlined />}
+            type="primary"
+            key="bind"
+          >
             {intl.formatMessage({
+              id: 'pages.data.option.assets',
+              defaultMessage: '资产分配',
+            })}
+          </Button>,
+          <Popconfirm
+            title={intl.formatMessage({
               id: 'pages.system.role.option.unBindUser',
-              defaultMessage: '批量解绑',
+              defaultMessage: '是否批量解除绑定',
             })}
-          </Button>
-        </Popconfirm>,
-      ]}
-    />
+            key="unBind"
+            onConfirm={handleUnBind}
+          >
+            <Button icon={<DisconnectOutlined />} key="bind">
+              {intl.formatMessage({
+                id: 'pages.system.role.option.unBindUser',
+                defaultMessage: '批量解绑',
+              })}
+            </Button>
+          </Popconfirm>,
+        ]}
+      />
+    </>
   );
 });

+ 4 - 4
src/pages/system/Department/Assets/product/model.ts

@@ -3,14 +3,14 @@ import { model } from '@formily/reactive';
 
 type ModelType = {
   bind: boolean;
-  bindUsers: { name: string; userId: string }[];
-  unBindUsers: string[];
+  bindKeys: string[];
+  unBindKeys: string[];
 };
 
 const Models = model<ModelType>({
   bind: false,
-  bindUsers: [],
-  unBindUsers: [],
+  bindKeys: [],
+  unBindKeys: [],
 });
 
 export default Models;

+ 25 - 26
src/pages/system/Department/Assets/productCategory/bind.tsx

@@ -1,11 +1,11 @@
 // 资产-产品分类-绑定
 import type { ProColumns, ActionType } from '@jetlinks/pro-table';
 import ProTable from '@jetlinks/pro-table';
-import { service } from './index';
+import { service, getTableKeys } from './index';
 import { Modal } from 'antd';
 import { useParams } from 'umi';
 import Models from './model';
-import { useRef, useState } from 'react';
+import { useRef, useState, useEffect } from 'react';
 import { observer } from '@formily/react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import type { ProductCategoryItem } from '@/pages/system/Department/typings';
@@ -22,11 +22,12 @@ const Bind = observer((props: Props) => {
   const param = useParams<{ id: string }>();
   const actionRef = useRef<ActionType>();
   const [perVisible, setPerVisible] = useState(false);
+
   const columns: ProColumns<ProductCategoryItem>[] = [
     {
       dataIndex: 'id',
       title: 'ID',
-      width: 48,
+      width: 220,
     },
     {
       dataIndex: 'key',
@@ -50,30 +51,18 @@ const Bind = observer((props: Props) => {
 
   const handleBind = () => {
     if (Models.bindKeys.length) {
-      // service.bind('deviceCategory', [{
-      //   "targetType": "org",
-      //   "targetId": param.id,
-      //   "assetType": "deviceCategory",
-      //   "assetIdList": Models.bindKeys,
-      //   "permission": [
-      //     "read"
-      //   ]
-      // }]).subscribe({
-      //   next: () => message.success('操作成功'),
-      //   error: () => message.error('操作失败'),
-      //   complete: () => {
-      //     Models.bindKeys = [];
-      //     actionRef.current?.reload();
-      //     props.reload();
-      //     props.onCancel()
-      //   },
-      // });
       setPerVisible(true);
     } else {
       props.onCancel();
     }
   };
 
+  useEffect(() => {
+    if (props.visible) {
+      actionRef.current?.reload();
+    }
+  }, [props.visible]);
+
   return (
     <Modal
       visible={props.visible}
@@ -98,13 +87,11 @@ const Bind = observer((props: Props) => {
         actionRef={actionRef}
         columns={columns}
         rowKey="id"
-        pagination={{
-          pageSize: 5,
-        }}
+        pagination={false}
         rowSelection={{
           selectedRowKeys: Models.bindKeys,
           onChange: (selectedRowKeys, selectedRows) => {
-            Models.bindKeys = selectedRows.map((item) => item.id);
+            Models.bindKeys = getTableKeys(selectedRows);
           },
         }}
         params={{
@@ -124,7 +111,19 @@ const Bind = observer((props: Props) => {
             },
           ],
         }}
-        request={(params) => service.queryProductCategoryList(params)}
+        request={async (params) => {
+          const response = await service.queryProductCategoryList(params);
+          return {
+            code: response.message,
+            result: {
+              data: response.result,
+              pageIndex: 0,
+              pageSize: 0,
+              total: 0,
+            },
+            status: response.status,
+          };
+        }}
       />
     </Modal>
   );

+ 49 - 17
src/pages/system/Department/Assets/productCategory/index.tsx

@@ -2,7 +2,7 @@
 import ProTable from '@jetlinks/pro-table';
 import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { useIntl } from '@@/plugin-locale/localeExports';
-import { Button, Popconfirm, Tooltip } from 'antd';
+import { Button, Popconfirm, Tooltip, message } from 'antd';
 import { useRef } from 'react';
 import { useParams } from 'umi';
 import { observer } from '@formily/react';
@@ -14,22 +14,44 @@ import Bind from './bind';
 
 export const service = new Service<ProductCategoryItem>('assets');
 
+export const getTableKeys = (rows: ProductCategoryItem[]): string[] => {
+  let keys: string[] = [];
+  rows.forEach((item) => {
+    keys.push(item.id);
+    if (item.children && item.children.length) {
+      const childrenKeys = getTableKeys(item.children);
+      keys = [...keys, ...childrenKeys];
+    }
+  });
+  return keys;
+};
+
 export default observer(() => {
   const intl = useIntl();
   const actionRef = useRef<ActionType>();
-
   const param = useParams<{ id: string }>();
 
+  /**
+   * 解除资产绑定
+   */
   const handleUnBind = () => {
-    // service.unBind({})
-    // service.handleUser(param.id, Models.unBindUsers, 'unbind').subscribe({
-    //   next: () => message.success('操作成功'),
-    //   error: () => message.error('操作失败'),
-    //   complete: () => {
-    //     Models.unBindUsers = [];
-    //     actionRef.current?.reload();
-    //   },
-    // });
+    service
+      .unBind('deviceCategory', [
+        {
+          targetType: 'org',
+          targetId: param.id,
+          assetType: 'deviceCategory',
+          assetIdList: Models.unBindKeys,
+        },
+      ])
+      .subscribe({
+        next: () => message.success('操作成功'),
+        error: () => message.error('操作失败'),
+        complete: () => {
+          Models.unBindKeys = [];
+          actionRef.current?.reload();
+        },
+      });
   };
 
   const singleUnBind = (key: string) => {
@@ -41,7 +63,7 @@ export default observer(() => {
     {
       dataIndex: 'id',
       title: 'ID',
-      width: 48,
+      width: 220,
     },
     {
       dataIndex: 'key',
@@ -105,6 +127,7 @@ export default observer(() => {
 
   const closeModal = () => {
     Models.bind = false;
+    Models.bindKeys = [];
   };
 
   return (
@@ -136,9 +159,18 @@ export default observer(() => {
             },
           ],
         }}
-        request={(params) => {
-          console.log(params);
-          return service.queryProductCategoryList(params);
+        request={async (params) => {
+          const response = await service.queryProductCategoryList(params);
+          return {
+            code: response.message,
+            result: {
+              data: response.result,
+              pageIndex: 0,
+              pageSize: 0,
+              total: 0,
+            },
+            status: response.status,
+          };
         }}
         postData={(data) => {
           console.log(data);
@@ -160,8 +192,8 @@ export default observer(() => {
             key="bind"
           >
             {intl.formatMessage({
-              id: 'pages.system.role.option.bindUser',
-              defaultMessage: '分配资产',
+              id: 'pages.data.option.assets',
+              defaultMessage: '资产分配',
             })}
           </Button>,
           <Popconfirm

+ 15 - 6
src/pages/system/Department/Assets/service.ts

@@ -7,20 +7,23 @@ import { filter, map } from 'rxjs/operators';
 class Service<T> extends BaseService<T> {
   // 资产绑定
   bind = (type: string, params: any) =>
-    defer(() => from(request(`${this.uri}/bind/${type}`, { method: 'POST', params }))).pipe(
+    defer(() => from(request(`${this.uri}/bind/${type}`, { method: 'POST', data: params }))).pipe(
       filter((item) => item.status === 200),
       map((item) => item.result),
     );
 
   // 资产解绑
   unBind = (type: string, params: any) =>
-    request(`${this.uri}/unbind/${type}`, { method: 'POST', params });
+    defer(() => from(request(`${this.uri}/unbind/${type}`, { method: 'POST', data: params }))).pipe(
+      filter((item) => item.status === 200),
+      map((item) => item.result),
+    );
 
   // 资产-产品分类
   queryProductCategoryList = (params: any) => {
     return request(`${SystemConst.API_BASE}/device/category/_tree`, {
-      method: 'GET',
-      params: {
+      method: 'POST',
+      data: {
         ...params,
         paging: false,
       },
@@ -28,11 +31,17 @@ class Service<T> extends BaseService<T> {
   };
   // 资产-设备
   queryDeviceList = (params: any) => {
-    return request<T>(`${SystemConst.API_BASE}/device/instance/_query`, { method: 'GET', params });
+    return request<T>(`${SystemConst.API_BASE}/device/instance/_query`, {
+      method: 'POST',
+      data: params,
+    });
   };
   // 资产-产品
   queryProductList = (params: any) => {
-    return request<T>(`${SystemConst.API_BASE}/device-product/_query`, { method: 'GET', params });
+    return request<T>(`${SystemConst.API_BASE}/device-product/_query`, {
+      method: 'POST',
+      data: params,
+    });
   };
 }
 

+ 14 - 7
src/pages/system/Department/index.tsx

@@ -5,7 +5,14 @@ import type { ActionType, ProColumns } from '@jetlinks/pro-table';
 import { useRef } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { Button, message, Popconfirm, Tooltip } from 'antd';
-import { EditOutlined, PlusOutlined } from '@ant-design/icons';
+import {
+  EditOutlined,
+  PlusOutlined,
+  PlusCircleOutlined,
+  TeamOutlined,
+  MedicineBoxOutlined,
+  DeleteOutlined,
+} from '@ant-design/icons';
 import Service from '@/pages/system/Department/service';
 import type { ISchema } from '@formily/json-schema';
 import type { DepartmentItem } from '@/pages/system/Department/typings';
@@ -103,27 +110,27 @@ export default observer(() => {
               defaultMessage: '新增子部门',
             })}
           >
-            <EditOutlined />
+            <PlusCircleOutlined />
           </Tooltip>
         </a>,
         <Link key="assets" to={`/system/department/${record.id}/assets`}>
           <Tooltip
             title={intl.formatMessage({
-              id: 'pages.data.option.edit',
+              id: 'pages.data.option.assets',
               defaultMessage: '资产分配',
             })}
           >
-            <EditOutlined />
+            <MedicineBoxOutlined />
           </Tooltip>
         </Link>,
         <Link key="user" to={`/system/department/${record.id}/user`}>
           <Tooltip
             title={intl.formatMessage({
-              id: 'pages.data.option.edit',
+              id: 'pages.system.department.user',
               defaultMessage: '用户',
             })}
           >
-            <EditOutlined />
+            <TeamOutlined />
           </Tooltip>
         </Link>,
         <Popconfirm
@@ -143,7 +150,7 @@ export default observer(() => {
             })}
           >
             <a key="delete">
-              <EditOutlined />
+              <DeleteOutlined />
             </a>
           </Tooltip>
         </Popconfirm>,

+ 1 - 1
src/pages/system/Department/typings.d.ts

@@ -30,7 +30,7 @@ export type ProductItem = {
 };
 
 // 产品分类
-export type ProductCategoryItem = { key: string } & ProductItem;
+export type ProductCategoryItem = { key: string; children: ProductCategoryItem[] } & ProductItem;
 
 // 设备
 export type DeviceItem = {