shaogen1995 1 年間 前
コミット
6944d3b9f2

+ 43 - 14
src/pages/Layout/data.ts

@@ -3,56 +3,85 @@ import React from "react";
 
 const tabLeftArr: RouterType = [
   {
-    id: "1",
+    id: 1,
     name: "业务配置",
     son: [
       {
-        id: "1.1",
+        id: 100,
         name: "用户管理",
         path: "/",
         Com: React.lazy(() => import("../A1wxuser")),
-        done: true,
       },
       {
-        id: "1.2",
+        id: 200,
         name: "积分管理",
         path: "/integral",
         Com: React.lazy(() => import("../A2integral")),
-        done: true,
       },
       {
-        id: "1.3",
+        id: 300,
         name: "积分记录",
         path: "/record",
         Com: React.lazy(() => import("../A3record")),
-        done: true,
       },
       {
-        id: "1.4",
+        id: 400,
         name: "积分商城",
         path: "/store",
         Com: React.lazy(() => import("../A4store")),
-        done: true,
       },
+      // {
+      //   id: 500,
+      //   name: "兑换记录",
+      //   path: "/store",
+      //   Com: React.lazy(() => import("../A4store")),
+      //
+      // },
+      // {
+      //   id: 600,
+      //   name: "留言反馈",
+      //   path: "/store",
+      //   Com: React.lazy(() => import("../A4store")),
+      //
+      // },
+      // {
+      //   id: 700,
+      //   name: "学习资料",
+      //   path: "/store",
+      //   Com: React.lazy(() => import("../A4store")),
+      //
+      // },
+      // {
+      //   id: 800,
+      //   name: "云城介绍",
+      //   path: "/store",
+      //   Com: React.lazy(() => import("../A4store")),
+      //
+      // },
+      // {
+      //   id: 900,
+      //   name: "数据看板",
+      //   path: "/store",
+      //   Com: React.lazy(() => import("../A4store")),
+      //
+      // },
     ],
   },
   {
-    id: "2",
+    id: 2,
     name: "系统管理",
     son: [
       {
-        id: "3.1",
+        id: 2100,
         name: "后台账户管理",
         path: "/user",
         Com: React.lazy(() => import("../Z1user")),
-        done: false,
       },
       {
-        id: "3.2",
+        id: 2200,
         name: "系统日志",
         path: "/log",
         Com: React.lazy(() => import("../Z2log")),
-        done: false,
       },
     ],
   },

+ 80 - 64
src/pages/Layout/index.tsx

@@ -1,10 +1,4 @@
-import React, {
-  useCallback,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from "react";
+import React, { useCallback, useEffect, useRef, useState } from "react";
 import { CaretUpOutlined, CaretDownOutlined } from "@ant-design/icons";
 import styles from "./index.module.scss";
 import SpinLoding from "@/components/SpinLoding";
@@ -24,31 +18,10 @@ import NotFound from "@/components/NotFound";
 import { RouterType, RouterTypeRow } from "@/types";
 import tabLeftArr from "./data";
 import MyPopconfirm from "@/components/MyPopconfirm";
+import { UserListType } from "../Z1user/Z1auth";
+import { Z1_APIgetAuthByUserId } from "@/store/action/Z1user";
 
 function Layout() {
-  // 左侧菜单 和 路由 信息
-  const [list, setList] = useState([] as RouterType);
-
-  // useEffect(()=>{
-  //   console.log(123,list);
-    
-  // },[list])
-
-  useEffect(() => {
-    const arr = [...tabLeftArr];
-
-    // 超级管理员才有 用户管理 和 系统日志
-    const flag = getTokenInfo().user.isAdmin === 1;
-    arr[1].son[0].done = flag;
-    arr[1].son[1].done = flag;
-    setList(arr);
-  }, []);
-
-  // 点击跳转
-  const pathCutFu = useCallback((path: string) => {
-    history.push(path);
-  }, []);
-
   // 当前路径选中的左侧菜单
   const location = useLocation();
   const [path, setPath] = useState("");
@@ -61,6 +34,70 @@ function Layout() {
     setPath(pathTemp);
   }, [location]);
 
+  // 获取用户权限信息
+  const getUserAuthFu = useCallback(async () => {
+    const userInfo = getTokenInfo().user;
+
+    const res = await Z1_APIgetAuthByUserId(userInfo.id);
+    if (res.code === 0) {
+      const tempList: UserListType[] = res.data || [];
+      const isOkIdArr = tempList.filter((c) => c.authority).map((v) => v.id);
+      // 是管理员
+      if (userInfo.isAdmin === 1) {
+        isOkIdArr.push(2100);
+        isOkIdArr.push(2200);
+      }
+
+      const tempArr: RouterTypeRow = [];
+
+      tabLeftArr.forEach((v1) => {
+        if (v1.son && v1.son[0]) {
+          v1.son.forEach((v2) => {
+            if (isOkIdArr.includes(v2.id)) {
+              tempArr.push(v2);
+            }
+          });
+        }
+      });
+
+      setRouterCom(tempArr);
+
+      // 如果当前页面没有权限了,跳转有权限的第一个页面
+      const urlAll = window.location.hash;
+      const isNowPath = urlAll.replace("#", "");
+      const pathArr = tempArr.map((v) => v.path);
+      if (!pathArr.includes(isNowPath)) {
+        history.push(pathArr[0]);
+      }
+
+      const resList = tabLeftArr.map((v) => ({
+        ...v,
+        son: v.son.filter((c) => isOkIdArr.includes(c.id)),
+      }));
+
+      setList(resList);
+    }
+  }, []);
+
+  useEffect(() => {
+    getUserAuthFu();
+  }, [getUserAuthFu]);
+
+  // 左侧菜单 信息
+  const [list, setList] = useState([] as RouterType);
+
+  // 路由信息(过滤之后的)
+  const [RouterCom, setRouterCom] = useState<RouterTypeRow>([]);
+
+  // useEffect(() => {
+  //   console.log(123, list);
+  // }, [list]);
+
+  // 点击跳转
+  const pathCutFu = useCallback((path: string) => {
+    history.push(path);
+  }, []);
+
   // 修改密码相关
   const [open, setOpen] = useState(false);
 
@@ -94,25 +131,6 @@ function Layout() {
     history.push("/login");
   };
 
-  // 路由信息(过滤之后的)
-  const RouterCom = useMemo(() => {
-    const arr: RouterTypeRow = [];
-    list.forEach((v) => {
-      if (v.son && v.son[0]) {
-        v.son.forEach((v2) => {
-          if (v2.done) arr.push(v2);
-        });
-      }
-    });
-    return arr;
-  }, [list]);
-
-  // 第一个页面不是 项目 管理 的时候 动态 跳转
-  useEffect(() => {
-    if (RouterCom && RouterCom[0] && RouterCom[0].id !== "1.1")
-      history.replace(RouterCom[0].path);
-  }, [RouterCom]);
-
   return (
     <div className={styles.Layout}>
       {/* 左边 */}
@@ -126,24 +144,22 @@ function Layout() {
             <div
               className={classNames("layoutLRowBox")}
               key={v.id}
-              hidden={v.son.every((c) => !c.done)}
+              hidden={!v.son.length}
             >
               {/* 这个项目没有一级目录 */}
               {/* <div className="layoutLRowBoxTxt">{v.name}</div> */}
-              {v.son
-                .filter((c2) => c2.done)
-                .map((v2) => (
-                  <div
-                    key={v2.id}
-                    className={classNames(
-                      "layoutLRowBoxRow",
-                      path === v2.path ? "active" : ""
-                    )}
-                    onClick={() => pathCutFu(v2.path)}
-                  >
-                    {v2.name}
-                  </div>
-                ))}
+              {v.son.map((v2) => (
+                <div
+                  key={v2.id}
+                  className={classNames(
+                    "layoutLRowBoxRow",
+                    path === v2.path ? "active" : ""
+                  )}
+                  onClick={() => pathCutFu(v2.path)}
+                >
+                  {v2.name}
+                </div>
+              ))}
             </div>
           ))}
         </div>

+ 105 - 0
src/pages/Z1user/Z1auth.tsx

@@ -0,0 +1,105 @@
+import React, { useCallback, useEffect, useMemo, useState } from "react";
+import styles from "./index.module.scss";
+import { Button, Checkbox, Modal } from "antd";
+import MyPopconfirm from "@/components/MyPopconfirm";
+import { Z1_APIgetAuthByUserId, Z1_APIsetAuth } from "@/store/action/Z1user";
+import classNmaes from "classnames";
+import { MessageFu } from "@/utils/message";
+
+export type UserListType = {
+  authority: boolean;
+  id: number;
+  name: string;
+  resourceType: string;
+};
+
+type Props = {
+  authInfo: { id: number; name: string };
+  closeFu: () => void;
+};
+
+function Z1auth({ authInfo, closeFu }: Props) {
+  const getAuthByUserIdFu = useCallback(async () => {
+    const res = await Z1_APIgetAuthByUserId(authInfo.id);
+    if (res.code === 0) setList(res.data);
+  }, [authInfo.id]);
+
+  useEffect(() => {
+    getAuthByUserIdFu();
+  }, [getAuthByUserIdFu]);
+
+  const [list, setList] = useState<UserListType[]>([]);
+
+  // 多选框变化
+  const onChange = useCallback(
+    (val: boolean, id: number) => {
+      setList(
+        list.map((v) => ({
+          ...v,
+          authority: v.id === id ? val : v.authority,
+        }))
+      );
+    },
+    [list]
+  );
+
+  // 至少选中一个
+  const isOneRes = useMemo(() => {
+    return list.filter((v) => v.authority).length <= 0;
+  }, [list]);
+
+  // 点击确定
+  const btnOkFu = useCallback(async () => {
+    const obj = {
+      userId: authInfo.id,
+      resources: list.filter((c) => c.authority).map((v) => v.id),
+    };
+
+    const res = await Z1_APIsetAuth(obj);
+
+    if (res.code === 0) {
+      MessageFu.success("授权成功!");
+      closeFu();
+    }
+  }, [authInfo.id, closeFu, list]);
+
+  return (
+    <Modal
+      wrapClassName={styles.Z1auth}
+      open={true}
+      title={`${authInfo.name} - 授权管理`}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className="Z1aEmain">
+        {list.map((v) => (
+          <div key={v.id} className="Z1aRow">
+            <Checkbox
+              checked={v.authority}
+              onChange={(e) => onChange(e.target.checked, v.id)}
+            >
+              {v.name}
+            </Checkbox>
+          </div>
+        ))}
+
+        <div className={classNmaes("Z1aErr", isOneRes ? "Z1aErrAc" : "")}>
+          至少选中一个
+        </div>
+
+        <div className="Z1aEbtn">
+          <Button type="primary" onClick={btnOkFu} disabled={isOneRes}>
+            提交
+          </Button>
+          &emsp;
+          <MyPopconfirm txtK="取消" onConfirm={closeFu} />
+        </div>
+      </div>
+    </Modal>
+  );
+}
+
+const MemoZ1auth = React.memo(Z1auth);
+
+export default MemoZ1auth;

+ 45 - 0
src/pages/Z1user/index.module.scss

@@ -16,4 +16,49 @@
       background-color: #fff;
     }
   }
+}
+
+// 授权
+.Z1auth {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      width: 800px !important;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+    }
+
+    .Z1aEmain {
+      padding-top: 15px;
+
+      .Z1aRow {
+        margin-bottom: 10px;
+      }
+
+      .Z1aErr {
+        margin-bottom: 20px;
+        text-align: center;
+        color: #ff4d4f;
+        opacity: 0;
+        pointer-events: none;
+        transition: all .3s;
+        position: relative;
+        top: -10px;
+      }
+
+      .Z1aErrAc {
+        opacity: 1;
+        top: 0;
+      }
+
+      .Z1aEbtn {
+        text-align: center;
+      }
+    }
+  }
 }

+ 23 - 2
src/pages/Z1user/index.tsx

@@ -20,6 +20,7 @@ import UserAdd from "./UserAdd";
 import MyTable from "@/components/MyTable";
 import { Z1tableC } from "@/utils/tableData";
 import MyPopconfirm from "@/components/MyPopconfirm";
+import Z1auth from "./Z1auth";
 
 function Z1user() {
   const dispatch = useDispatch();
@@ -96,8 +97,8 @@ function Z1user() {
 
   const openEditPageFu = useCallback(
     (id: number) => {
-      if (id === 0 && tableInfo.list.length >= 50)
-        return MessageFu.warning("最多支持50个用户!");
+      if (id === 0 && tableInfo.list.length >= 20)
+        return MessageFu.warning("最多支持20个用户!");
 
       editId.current = id;
       setEditPageShow(true);
@@ -131,6 +132,15 @@ function Z1user() {
               >
                 编辑
               </Button>
+              <Button
+                size="small"
+                type="text"
+                onClick={() =>
+                  setAuthInfo({ id: item.id, name: item.userName })
+                }
+              >
+                权限管理
+              </Button>
               <MyPopconfirm txtK="删除" onConfirm={() => delTableFu(item.id)} />
             </>
           );
@@ -139,6 +149,9 @@ function Z1user() {
     ];
   }, [delTableFu, openEditPageFu, resetPassFu]);
 
+  // 点击授权
+  const [authInfo, setAuthInfo] = useState({ id: 0, name: "" });
+
   return (
     <div className={styles.Z1user}>
       <div className="pageTitle">后台账户管理</div>
@@ -191,6 +204,14 @@ function Z1user() {
           addTableList={resetSelectFu}
         />
       ) : null}
+
+      {/* 点击授权 */}
+      {authInfo.id ? (
+        <Z1auth
+          authInfo={authInfo}
+          closeFu={() => setAuthInfo({ id: 0, name: "" })}
+        />
+      ) : null}
     </div>
   );
 }

+ 14 - 0
src/store/action/Z1user.ts

@@ -45,3 +45,17 @@ export const userSaveAPI = (data: SaveUserType) => {
 export const getUserInfoByIdAPI = (id: number) => {
   return http.get(`sys/user/detail/${id}`);
 };
+
+/**
+ * 角色授权-获取
+ */
+export const Z1_APIgetAuthByUserId = (userId: number) => {
+  return http.get(`sys/user/perm/getUserTree/${userId}`);
+};
+
+/**
+ * 角色授权-设置
+ */
+export const Z1_APIsetAuth = (data: any) => {
+  return http.post("sys/user/perm/auth", data);
+};

+ 2 - 3
src/types/api/layot.d.ts

@@ -5,15 +5,14 @@ export type LookDomType = {
 };
 
 export type RouterTypeRow = {
-  id: string;
+  id: number;
   name: string;
   path: string;
   Com: React.LazyExoticComponent<React.MemoExoticComponent<() => JSX.Element>>;
-  done: boolean;
 }[];
 
 export type RouterType = {
-  id: string;
+  id: number;
   name: string;
   son: RouterTypeRow;
 }[];