فهرست منبع

feat(merge): merge xyh

Next xyh
Lind 3 سال پیش
والد
کامیت
0fa056196c

+ 2 - 0
src/components/ProTableCard/index.less

@@ -160,11 +160,13 @@
       height: 100%;
       color: #fff;
       background-color: rgba(#000, 0);
+      visibility: hidden;
       cursor: pointer;
       transition: all 0.3s;
 
       &.show {
         background-color: rgba(#000, 0.5);
+        visibility: visible;
       }
     }
   }

+ 64 - 0
src/hooks/permission/index.ts

@@ -0,0 +1,64 @@
+import { useEffect, useState } from 'react';
+import { BUTTON_PERMISSION_ENUM } from '@/utils/menu/router';
+import type { MENUS_CODE_TYPE } from '@/utils/menu/router';
+import { MENUS_BUTTONS_CACHE } from '@/utils/menu';
+
+type permissionKeyType = keyof typeof BUTTON_PERMISSION_ENUM;
+type permissionType = Record<permissionKeyType, boolean>;
+
+const usePermissions = (
+  code: MENUS_CODE_TYPE,
+): {
+  /**
+   * 是否有改权限
+   */
+  permission: Partial<permissionType>;
+  /**
+   * 获取额外权限,比如组合权限
+   * @example getOtherPermission(['add', 'delete']) => boolean
+   * @return Boolean
+   */
+  getOtherPermission: (permission: string | string[]) => boolean;
+} => {
+  const [permission, setPermission] = useState<Partial<permissionType>>({});
+
+  let buttons = {};
+  const permissionButton: Partial<permissionType> = {};
+
+  try {
+    const buttonString = localStorage.getItem(MENUS_BUTTONS_CACHE);
+    buttons = JSON.parse(buttonString || '{}');
+  } catch (e) {
+    console.warn(e);
+  }
+
+  const getOtherPermission = (permissionCode: string | string[]) => {
+    if (!!Object.keys(buttons).length && permissionCode) {
+      const _buttonArray = buttons[code];
+      if (!_buttonArray) {
+        return false;
+      }
+      return _buttonArray.some((btnId: string) => {
+        if (typeof permissionCode === 'string') {
+          return permissionCode === btnId;
+        } else {
+          return permissionCode.includes(btnId);
+        }
+        return false;
+      });
+    }
+    return false;
+  };
+
+  useEffect(() => {
+    Object.keys(BUTTON_PERMISSION_ENUM).forEach((key) => {
+      permissionButton[key] = getOtherPermission[key];
+    });
+
+    setPermission(permissionButton);
+  }, [code]);
+
+  return { permission, getOtherPermission };
+};
+
+export default usePermissions;

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

@@ -18,6 +18,7 @@ export default {
   'pages.data.option.disabled.tips': '确认禁用?',
   'pages.data.option.enabled': '启用',
   'pages.data.option.enabled.tips': '确认启用?',
+  'pages.data.option.noPermission': '暂无权限,请联系管理员',
   'pages.data.option.add': '新增',
   'pages.data.option.edit': '编辑',
   'pages.data.option.preview': '预览',

+ 18 - 0
src/models/location.ts

@@ -0,0 +1,18 @@
+export default {
+  namespace: 'location',
+  state: {
+    locationState: {},
+    path: '',
+  },
+  reducers: {
+    push(s: any, payload: any) {
+      return payload.payload;
+    },
+    cleanLocationState() {
+      return {
+        locationState: {},
+        path: '',
+      };
+    },
+  },
+};

+ 38 - 14
src/pages/device/Instance/index.tsx

@@ -1,10 +1,10 @@
-import {PageContainer} from '@ant-design/pro-layout';
-import type {ActionType, ProColumns} from '@jetlinks/pro-table';
-import type {DeviceInstance} from '@/pages/device/Instance/typings';
+import { PageContainer } from '@ant-design/pro-layout';
+import type { ActionType, ProColumns } from '@jetlinks/pro-table';
+import type { DeviceInstance } from '@/pages/device/Instance/typings';
 import moment from 'moment';
-import {Badge, Button, Dropdown, Menu, message, Popconfirm, Tooltip} from 'antd';
-import {useRef, useState} from 'react';
-import {useHistory} from 'umi';
+import { Badge, Button, Dropdown, Menu, message, Popconfirm, Tooltip } from 'antd';
+import { useEffect, useRef, useState } from 'react';
+import { useHistory } from 'umi';
 import {
   CheckCircleOutlined,
   DeleteOutlined,
@@ -16,23 +16,21 @@ import {
   StopOutlined,
   SyncOutlined,
 } from '@ant-design/icons';
-import {model} from '@formily/reactive';
+import { model } from '@formily/reactive';
 import Service from '@/pages/device/Instance/service';
 import type { MetadataItem } from '@/pages/device/Product/typings';
-import { useIntl, useLocation } from 'umi';
+import { useIntl, connect } from 'umi';
 import Save from './Save';
 import Export from './Export';
 import Import from './Import';
 import Process from './Process';
 import SearchComponent from '@/components/SearchComponent';
-import {ProTableCard} from '@/components';
+import { ProTableCard } from '@/components';
 import SystemConst from '@/utils/const';
 import Token from '@/utils/token';
 import DeviceCard from '@/components/ProTableCard/CardItems/device';
 
 import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
-import { withRouter } from 'react-router-dom';
-
 
 export const statusMap = new Map();
 statusMap.set('在线', 'success');
@@ -70,9 +68,23 @@ const Instance = (props: any) => {
   const [bindKeys, setBindKeys] = useState<any[]>([]);
   const history = useHistory<Record<string, string>>();
   const intl = useIntl();
-  const location = useLocation();
 
-  console.log(location, props.location.query);
+  useEffect(() => {
+    console.log(searchParams);
+    if (props.path) {
+      const _terms: any[] = [];
+      Object.keys(props.locationState).forEach((key) => {
+        _terms.push({
+          column: key,
+          value: props.locationState[key],
+        });
+      });
+      setSearchParams({
+        terms: _terms,
+      });
+      props.cleanLocationState();
+    }
+  }, [props.path]);
 
   const tools = (record: DeviceInstance) => [
     <Button
@@ -599,4 +611,16 @@ const Instance = (props: any) => {
     </PageContainer>
   );
 };
-export default withRouter(Instance);
+
+const mapState = (state: any) => {
+  return {
+    locationState: state.location.locationState,
+    path: state.location.path,
+  };
+};
+
+const actionCreate = {
+  cleanLocationState: (payload: any) => ({ type: 'location/clean', payload }),
+};
+
+export default connect(mapState, actionCreate)(Instance);

+ 22 - 5
src/pages/device/Product/Detail/index.tsx

@@ -16,9 +16,8 @@ import BaseInfo from '@/pages/device/Product/Detail/BaseInfo';
 import { observer } from '@formily/react';
 import { productModel, service } from '@/pages/device/Product';
 import { useCallback, useEffect, useState } from 'react';
-import { useIntl } from '@@/plugin-locale/localeExports';
+import { useIntl, connect } from 'umi';
 import Metadata from '@/pages/device/components/Metadata';
-// import Alarm from '@/pages/device/components/Alarm';
 import Access from '@/pages/device/Product/Detail/Access';
 import type { DeviceMetadata } from '@/pages/device/Product/typings';
 import { Store } from 'jetlinks-store';
@@ -34,7 +33,7 @@ export const ModelEnum = {
   access: 'access',
 };
 
-const ProductDetail = observer(() => {
+const ProductDetail = observer((props: any) => {
   const intl = useIntl();
   const [mode, setMode] = useState('base');
   const param = useParams<{ id: string }>();
@@ -207,9 +206,15 @@ const ProductDetail = observer(() => {
                 type={'link'}
                 style={{ padding: 0, height: 'auto' }}
                 onClick={() => {
-                  history.push(getMenuPathByCode(MENUS_CODE['device/Instance']), {
+                  const url = getMenuPathByCode(MENUS_CODE['device/Instance']);
+                  const params = {
                     productId: productModel.current?.id,
+                  };
+                  props.push({
+                    locationState: params,
+                    path: url,
                   });
+                  history.push(url, params);
                 }}
               >
                 {productModel.current?.count || 0}
@@ -326,4 +331,16 @@ const ProductDetail = observer(() => {
     </PageContainer>
   );
 });
-export default ProductDetail;
+
+const mapState = (state: any) => ({
+  state: state.state,
+  path: state.path,
+});
+
+const actionCreate = {
+  push: (payload: any) => {
+    return { type: 'location/push', payload };
+  },
+};
+
+export default connect(mapState, actionCreate)(ProductDetail);

+ 19 - 18
src/pages/system/Department/index.tsx

@@ -22,6 +22,7 @@ import { model } from '@formily/reactive';
 import Save from './save';
 import SearchComponent from '@/components/SearchComponent';
 import { getButtonPermission, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
+import usePermissions from '@/hooks/permission';
 
 export const service = new Service('organization');
 
@@ -64,7 +65,7 @@ export default observer(() => {
   const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>([]);
   const [treeData, setTreeData] = useState<any[]>([]);
   const [sortParam, setSortParam] = useState<any>({ name: 'sortIndex', order: 'asc' });
-
+  const { permission, getOtherPermission } = usePermissions('system/Department');
   const rowKeys = useRef<React.Key[]>([]);
 
   /**
@@ -110,29 +111,29 @@ export default observer(() => {
       valueType: 'option',
       width: 240,
       render: (text, record) => [
-        <Button
-          style={{ padding: 0 }}
-          type="link"
-          disabled={getButtonPermission('system/Department', ['update'])}
-          key="editable"
-          onClick={() => {
-            State.current = record;
-            State.visible = true;
-          }}
+        <Tooltip
+          title={intl.formatMessage({
+            id: permission.update ? 'pages.data.option.edit' : 'pages.data.option.noPermission',
+            defaultMessage: '编辑',
+          })}
         >
-          <Tooltip
-            title={intl.formatMessage({
-              id: 'pages.data.option.edit',
-              defaultMessage: '编辑',
-            })}
+          <Button
+            style={{ padding: 0 }}
+            type="link"
+            disabled={!permission.update}
+            key="editable"
+            onClick={() => {
+              State.current = record;
+              State.visible = true;
+            }}
           >
             <EditOutlined />
-          </Tooltip>
-        </Button>,
+          </Button>
+        </Tooltip>,
         <Button
           style={{ padding: 0 }}
           type="link"
-          disabled={getButtonPermission('system/Department', ['add'])}
+          disabled={!getOtherPermission(['add'])}
           key="editable"
           onClick={() => {
             State.current = {

+ 12 - 10
src/utils/menu/router.ts

@@ -106,16 +106,18 @@ export enum MENUS_CODE {
 
 export type MENUS_CODE_TYPE = keyof typeof MENUS_CODE;
 
-export type BUTTON_PERMISSION =
-  | 'add'
-  | 'delete'
-  | 'import'
-  | 'view'
-  | 'export'
-  | 'update'
-  | 'action'
-  | 'push'
-  | string;
+export enum BUTTON_PERMISSION_ENUM {
+  'add' = 'add',
+  'delete' = 'delete',
+  'import' = 'import',
+  'view' = 'view',
+  'export' = 'export',
+  'update' = 'update',
+  'action' = 'action',
+  'push' = 'push',
+}
+
+export type BUTTON_PERMISSION = keyof typeof BUTTON_PERMISSION_ENUM | string;
 
 export const getDetailNameByCode = {
   'system/Menu/Detail': '菜单详情',