shaogen1995 2 년 전
부모
커밋
86f7ab515f

+ 1 - 1
src/assets/styles/base.css

@@ -74,7 +74,7 @@ textarea {
   align-items: center;
   justify-content: center;
 }
-#root .iconHoverTit .iconHoverTitTxt {
+#root .iconHoverTitTxt {
   background-color: var(--themeColor);
   color: #fff;
   width: 16px;

+ 10 - 11
src/assets/styles/base.less

@@ -87,17 +87,16 @@ textarea {
     display: flex;
     align-items: center;
     justify-content: center;
-
-    .iconHoverTitTxt {
-      background-color: var(--themeColor);
-      color: #fff;
-      width: 16px;
-      height: 16px;
-      line-height: 16px;
-      text-align: center;
-      font-size: 12px;
-      border-radius: 50%;
-    }
+  }
+  .iconHoverTitTxt {
+    background-color: var(--themeColor);
+    color: #fff;
+    width: 16px;
+    height: 16px;
+    line-height: 16px;
+    text-align: center;
+    font-size: 12px;
+    border-radius: 50%;
   }
 
   // a {

+ 18 - 0
src/components/AuthCom.tsx

@@ -0,0 +1,18 @@
+import { RootState } from "@/store";
+import React, { ReactNode } from "react";
+import { useSelector } from "react-redux";
+
+type Props = {
+  aId: string;
+  children: ReactNode;
+};
+
+function AuthCom({ aId, children }: Props) {
+  const arr = useSelector((state: RootState) => state.A4Role.A4RoleAll);
+
+  return <>{arr.find((v) => v === aId) ? children : null}</>;
+}
+
+const MemoAuthCom = React.memo(AuthCom);
+
+export default MemoAuthCom;

+ 8 - 11
src/pages/A1Project/A1Add/index.tsx

@@ -47,12 +47,9 @@ type Props = {
 };
 
 function A1Add({ pageType, closeFu, addFu, editFu }: Props) {
-
-
-  useEffect(()=>{
-    console.log('进来编辑和新增项目的页面~~~~~~~');
-    
-  },[])
+  useEffect(() => {
+    console.log("进来编辑和新增项目的页面~~~~~~~");
+  }, []);
 
   // 表单的ref
   const FormBoxRef = useRef<FormInstance>(null);
@@ -369,10 +366,6 @@ function A1Add({ pageType, closeFu, addFu, editFu }: Props) {
           <div className="A1AddBtn">
             {pageType.txt === "look" ? null : ( // <Button onClick={closeFu}>关 闭</Button>
               <>
-                <Button type="primary" htmlType="submit">
-                  保存
-                </Button>
-                &emsp;&emsp;
                 <Popconfirm
                   title="放弃编辑后,信息将不会保存!"
                   okText="放弃"
@@ -381,7 +374,11 @@ function A1Add({ pageType, closeFu, addFu, editFu }: Props) {
                   okButtonProps={{ loading: false }}
                 >
                   <Button>取消</Button>
-                </Popconfirm>
+                </Popconfirm>{" "}
+                &emsp;&emsp;
+                <Button type="primary" htmlType="submit">
+                  保存
+                </Button>
               </>
             )}
           </div>

+ 10 - 11
src/pages/A2Dict/A2Tab2/A2Tab2Add/A2Tab2AddTable.tsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect, useMemo, useState } from "react";
+import { useCallback, useEffect, useMemo, useState } from "react";
 import { A5TableType } from "@/types";
 import { Radio, Table } from "antd";
 import { forwardRef, useImperativeHandle } from "react";
@@ -17,12 +17,12 @@ function A2Tab2AddTable({ data, type, valAc }: Props, ref: any) {
     if (valAc) setValue(valAc);
   }, [valAc]);
 
-  const kongGeFu = useCallback((level: 1 | 2 | 3 | 4, name: string) => {
+  const kongGeFu = useCallback((level: 1 | 2 | 3 | 4) => {
     let arr = "";
-    for (let i = 1; i < level; i++) {
-      arr += "&emsp;";
-    }
-    return arr + name;
+    if (level === 2) return <>&emsp;{arr}</>;
+    else if (level === 3) return <>&emsp;&emsp;{arr}</>;
+    else if (level === 4) return <>&emsp;&emsp;&emsp;{arr}</>;
+    else return <></>;
   }, []);
 
   const A2Tab2AddTableResFu = useCallback(() => {
@@ -54,11 +54,10 @@ function A2Tab2AddTable({ data, type, valAc }: Props, ref: any) {
       {
         title: `${type}名称`,
         render: (item: A5TableType) => (
-          <span
-            dangerouslySetInnerHTML={{
-              __html: kongGeFu(item.level, item.name),
-            }}
-          ></span>
+          <span>
+            {kongGeFu(item.level)}
+            {item.name}
+          </span>
         ),
       },
     ];

+ 1 - 1
src/pages/A2Dict/A2Tab2/A2Tab2Add/index.tsx

@@ -122,7 +122,7 @@ function A2Tab2Add({ info, closeFu, addFu }: Props) {
         description,
         deptId: id3 + "",
         stageId: id4 + "",
-        suffix: row3 === "指定格式" ? row3Txt : null,
+        suffix: row3 === "指定格式" ? row3Txt : "",
         formatType: row3 === "所有格式" ? "0" : "1",
         type: "内控文件",
       };

+ 4 - 2
src/pages/A2Dict/A2Tab2/index.tsx

@@ -55,11 +55,13 @@ function A2Tab2() {
       },
       {
         title: "责任部门",
-        render: (item: A2Tab2Type) => (item.deptName ? item.deptName : "(空)"),
+        render: (item: A2Tab2Type) =>
+          item.deptName ? item.deptName : "(空)",
       },
       {
         title: "所属阶段",
-        render: (item: A2Tab2Type) => (item.stageName ? item.stageName : "(空)"),
+        render: (item: A2Tab2Type) =>
+          item.stageName ? item.stageName : "(空)",
       },
       {
         title: "操作",

+ 165 - 0
src/pages/A4Role/A4Auth/A4AuRR.tsx

@@ -0,0 +1,165 @@
+import { RootState } from "@/store";
+import { Checkbox, Radio } from "antd";
+import { useCallback, useEffect, useState } from "react";
+import { useSelector } from "react-redux";
+import { forwardRef, useImperativeHandle } from "react";
+
+const arr1 = [
+  { id: 1, name: "本部门-自己创建的项目" },
+  { id: 2, name: "本部门-所有用户创建的项目" },
+  { id: 3, name: "跨部门数据" },
+];
+
+type Props = {
+  info: {
+    dataScope: 1 | 2 | 3;
+    scopeDept: string;
+  };
+  ref: any;
+};
+
+function A4AuRR({ info }: Props, ref: any) {
+  useEffect(() => {
+    if (info.dataScope) setValue(info.dataScope);
+    if (info.scopeDept) setCheckArr(info.scopeDept.split(","));
+  }, [info.dataScope, info.scopeDept]);
+
+  // 获取部门信息
+  const arrAll = useSelector((state: RootState) => state.A5Section.tableList);
+
+  // 顶部的单选
+  const [value, setValue] = useState<1 | 2 | 3>(1);
+
+  // 跨部门的多选
+  const [checkArr, setCheckArr] = useState([] as string[]);
+
+  const onChangeFu = useCallback(
+    (val: boolean, id: string) => {
+      if (val) setCheckArr([...checkArr, id]);
+      else setCheckArr(checkArr.filter((v) => v !== id));
+    },
+    [checkArr]
+  );
+
+  // 给父组件调用
+  const sonRes = useCallback(() => {
+    let flag = true;
+    let txt = "";
+    if (value === 3) {
+      txt = checkArr.join(",");
+      if (checkArr.length <= 0) flag = false;
+    }
+
+    return { flag, txt, value };
+  }, [checkArr, value]);
+
+  // 可以让父组件调用子组件的方法
+  useImperativeHandle(ref, () => ({
+    sonRes,
+  }));
+
+  return (
+    <div className="A4AuRR">
+      <div className="A4ATit">数据权限</div>
+      <div className="A4AR_1">
+        {arr1.map((v) => (
+          <div
+            className="A4AR_1Row"
+            key={v.id}
+            onClick={() => setValue(v.id as 1 | 2 | 3)}
+          >
+            <Radio checked={value === v.id}>{v.name}</Radio>
+          </div>
+        ))}
+      </div>
+
+      {/* 跨部门的树渲染 */}
+      <div className="A4AR_2" hidden={value !== 3}>
+        {arrAll.map((v1) => (
+          <div className="A4AR_2_1" key={v1.id}>
+            <div className="A4AR_2Row">
+              {!v1.children ? (
+                <Checkbox
+                  checked={checkArr.includes(v1.id)}
+                  onChange={(e) => onChangeFu(e.target.checked, v1.id)}
+                >
+                  {v1.name}
+                </Checkbox>
+              ) : (
+                v1.name
+              )}
+            </div>
+
+            {v1.children && v1.children.length ? (
+              <>
+                {v1.children.map((v2) => (
+                  <div className="A4AR_2_2" key={v2.id}>
+                    <div className="A4AR_2Row">
+                      {!v2.children ? (
+                        <Checkbox
+                          checked={checkArr.includes(v2.id)}
+                          onChange={(e) => onChangeFu(e.target.checked, v2.id)}
+                        >
+                          {v2.name}
+                        </Checkbox>
+                      ) : (
+                        v2.name
+                      )}
+                    </div>
+                    {v2.children && v2.children.length ? (
+                      <>
+                        {v2.children.map((v3) => (
+                          <div className="A4AR_2_3" key={v3.id}>
+                            <div className="A4AR_2Row">
+                              {!v3.children ? (
+                                <Checkbox
+                                  checked={checkArr.includes(v3.id)}
+                                  onChange={(e) =>
+                                    onChangeFu(e.target.checked, v3.id)
+                                  }
+                                >
+                                  {v3.name}
+                                </Checkbox>
+                              ) : (
+                                v3.name
+                              )}
+                            </div>
+
+                            {v3.children && v3.children.length ? (
+                              <>
+                                {v3.children.map((v4) => (
+                                  <div className="A4AR_2_4" key={v4.id}>
+                                    <div className="A4AR_2Row">
+                                      {!v4.children ? (
+                                        <Checkbox
+                                          checked={checkArr.includes(v4.id)}
+                                          onChange={(e) =>
+                                            onChangeFu(e.target.checked, v4.id)
+                                          }
+                                        >
+                                          {v4.name}
+                                        </Checkbox>
+                                      ) : (
+                                        v4.name
+                                      )}
+                                    </div>
+                                  </div>
+                                ))}
+                              </>
+                            ) : null}
+                          </div>
+                        ))}
+                      </>
+                    ) : null}
+                  </div>
+                ))}
+              </>
+            ) : null}
+          </div>
+        ))}
+      </div>
+    </div>
+  );
+}
+
+export default forwardRef(A4AuRR);

+ 88 - 0
src/pages/A4Role/A4Auth/A4AuRR2.tsx

@@ -0,0 +1,88 @@
+import { RootState } from "@/store";
+import { Button, Checkbox, Empty } from "antd";
+import { useCallback, useEffect, useState } from "react";
+import { useSelector } from "react-redux";
+import { forwardRef, useImperativeHandle } from "react";
+import { A4_APIgetRoleFile } from "@/store/action/A4Role";
+import { A4getRoleFileType } from "@/types";
+
+type Props = {
+  ref: any;
+  mId: number;
+};
+
+function A4AuRR2({ mId }: Props, ref: any) {
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await A4_APIgetRoleFile(id);
+    if (res.code === 0) {
+      const arr: A4getRoleFileType[] = res.data;
+      const arr1 = arr.filter((v) => v.hasPerm).map((v) => v.id);
+      setCheckArr(arr1);
+    }
+  }, []);
+
+  useEffect(() => {
+    if (mId) getInfoFu(mId);
+  }, [getInfoFu, mId]);
+
+  const arr = useSelector((state: RootState) => state.A2Dict.A2Tab2Arr);
+
+  const [checkArr, setCheckArr] = useState([] as number[]);
+
+  const onChangeFu = useCallback(
+    (val: boolean, id: number) => {
+      if (val) setCheckArr([...checkArr, id]);
+      else setCheckArr(checkArr.filter((v) => v !== id));
+    },
+    [checkArr]
+  );
+
+  // 给父组件调用
+  const sonRes = useCallback(() => {
+    let flag2 = true;
+    if (checkArr.length <= 0) flag2 = false;
+    return {
+      flag2,
+      txt2: checkArr,
+    };
+  }, [checkArr]);
+
+  // 可以让父组件调用子组件的方法
+  useImperativeHandle(ref, () => ({
+    sonRes,
+  }));
+
+  return (
+    <div className="A4AuRR2">
+      <div className="A4ATit">
+        内控文件权限 &emsp;{" "}
+        {arr.length > 1 ? (
+          <Button
+            type="primary"
+            onClick={() => setCheckArr(arr.map((v) => v.id))}
+          >
+            全选
+          </Button>
+        ) : null}
+      </div>
+
+      {arr.length ? (
+        <div className="A4AR2Row">
+          {arr.map((v) => (
+            <Checkbox
+              key={v.id}
+              checked={checkArr.includes(v.id)}
+              onChange={(e) => onChangeFu(e.target.checked, v.id)}
+            >
+              {v.name}
+            </Checkbox>
+          ))}
+        </div>
+      ) : (
+        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
+      )}
+    </div>
+  );
+}
+
+export default forwardRef(A4AuRR2);

+ 122 - 0
src/pages/A4Role/A4Auth/index.module.scss

@@ -0,0 +1,122 @@
+.A4Auth {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 30;
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 20px;
+
+  :global {
+
+    .A4AcliBtn {
+      position: absolute;
+      left: 50%;
+      bottom: 15px;
+      transform: translateX(-50%);
+      z-index: 20;
+    }
+
+    .A4AMain {
+      width: 100%;
+      height: calc(100% - 50px);
+      display: flex;
+      justify-content: space-between;
+
+      .A4ATit {
+        font-weight: 700;
+        font-size: 20px;
+        margin-bottom: 15px;
+        display: flex;
+        align-items: center;
+      }
+
+      &>div {
+        border-radius: 10px;
+        width: 49%;
+        height: 100%;
+        overflow-y: auto;
+        border: 1px solid #ccc;
+        padding: 15px;
+      }
+
+
+      .A4AMainLL {
+
+        .iconHoverTitTxt {
+          background-color: black !important;
+        }
+
+        .A4A1CenRow1 {
+          margin-bottom: 5px;
+        }
+
+        .A4A1CenRow2 {
+          padding-left: 30px;
+          margin-bottom: 5px;
+        }
+
+        .A4A1CenRow3Box {
+          padding: 5px 0;
+          padding-left: 30px;
+
+        }
+
+        .A4A1CenRow3 {
+          display: inline-block;
+        }
+
+        .iconHoverTitTxt {
+          cursor: pointer;
+          display: inline-block;
+        }
+      }
+
+      // 右侧的 数据权限 和 内控文件权限的样式
+      .A4AMainRR {
+        .A4AR_1Row {
+          margin-bottom: 5px;
+        }
+
+        .A4AR_2 {
+          border-top: 1px solid var(--themeColor);
+          padding-top: 5px;
+
+          .A4AR_2Row {
+            margin-bottom: 5px;
+          }
+
+          padding-left: 24px;
+
+          .A4AR_2_2 {
+            padding-left: 28px;
+          }
+
+          .A4AR_2_3 {
+            padding-left: 28px;
+          }
+
+          .A4AR_2_4 {
+            padding-left: 28px;
+          }
+        }
+      }
+
+      .A4AR2Row {
+        .ant-checkbox-wrapper {
+          margin: 0 10px 5px 0;
+        }
+      }
+
+
+      .A4A1Btn {
+        margin-bottom: 15px;
+      }
+
+    }
+
+
+  }
+}

+ 305 - 0
src/pages/A4Role/A4Auth/index.tsx

@@ -0,0 +1,305 @@
+import React, { useCallback, useEffect, useRef, useState } from "react";
+import styles from "./index.module.scss";
+import { A4RolleAllType } from "@/types";
+import {
+  A4_APIgetRoleAll,
+  A4_APIsave1,
+  A4_APIsave2,
+  A4_APIsave3,
+  getRoleInfoByIdAPI,
+} from "@/store/action/A4Role";
+import { Button, Checkbox, Popconfirm, Tooltip } from "antd";
+import { MessageFu } from "@/utils/message";
+import { A4getStorage, A4setStorage } from "@/utils/storage";
+import A4AuRR from "./A4AuRR";
+import A4AuRR2 from "./A4AuRR2";
+import { useDispatch } from "react-redux";
+
+type Props = {
+  mId: number;
+  authColseFu: () => void;
+  authEditFu: () => void;
+};
+
+function A4Auth({ mId, authColseFu, authEditFu }: Props) {
+  const dispatch = useDispatch();
+
+  // 传递给子组件的数据权限信息
+  const [infoData, setInfoData] = useState(
+    {} as {
+      dataScope: 1 | 2 | 3;
+      scopeDept: string;
+    }
+  );
+
+  const [arr1, setArr1] = useState([] as A4RolleAllType[]);
+
+  const getInfo1Fu = useCallback(async (id: number) => {
+    const res = await getRoleInfoByIdAPI(id);
+    if (res.code === 0) {
+      setArr1(res.data.permission);
+
+      // 数据权限的回显
+      const temp = res.data.role;
+      setInfoData({
+        dataScope: temp.dataScope,
+        scopeDept: temp.scopeDept,
+      });
+    }
+  }, []);
+
+  useEffect(() => {
+    if (mId) {
+      // 获取角色 功能权限 信息
+      getInfo1Fu(mId);
+    }
+  }, [getInfo1Fu, mId]);
+
+  // 多选框的变化
+  const onChange1Fu = useCallback(
+    (val: boolean, ind: number, id: string) => {
+      const arr = [...arr1];
+
+      if (ind === 1) {
+        if (!val && arr.filter((v) => v.authority).length <= 1)
+          return MessageFu.warning("至少勾选一个 功能权限 的页面模块!");
+
+        // 第一级的选中
+        setArr1(
+          arr.map((v) => ({
+            ...v,
+            authority: v.id === id ? val : v.authority,
+          }))
+        );
+      } else if (ind === 2) {
+        // 第二级的选中
+        setArr1(
+          arr.map((v) => ({
+            ...v,
+            children: v.children?.map((v2) => ({
+              ...v2,
+              authority: v2.id === id ? val : v2.authority,
+            })),
+          }))
+        );
+      } else if (ind === 3) {
+        // 第三级的选中
+        setArr1(
+          arr.map((v) => ({
+            ...v,
+            children: v.children?.map((v2) => ({
+              ...v2,
+              children: v2.children?.map((v3) => ({
+                ...v3,
+                authority: v3.id === id ? val : v3.authority,
+              })),
+            })),
+          }))
+        );
+      }
+    },
+    [arr1]
+  );
+
+  // 点击复制权限配置
+  const copyRoleFu = useCallback(() => {
+    A4setStorage(arr1);
+    MessageFu.success("复制数据到本地成功!");
+  }, [arr1]);
+
+  // 点击应用权限配置
+  const setArr1Fu = useCallback(() => {
+    const arr = A4getStorage();
+    if (arr && arr.length) {
+      setArr1(arr);
+    } else MessageFu.warning("本地还没有关于功能权限的配置!");
+  }, []);
+
+  // 数据权限 组件 的 ref
+  const r2Ref = useRef<any>(null);
+
+  // 内控文件权限 组件 的 ref
+  const r3Ref = useRef<any>(null);
+
+  // 点击确定
+  const btnOkFu = useCallback(async () => {
+    if (arr1.filter((v) => v.authority).length <= 0)
+      return MessageFu.warning("至少勾选一个 功能权限 的页面模块!");
+
+    // 数据权限的信息
+    const { flag, txt, value } = r2Ref.current.sonRes();
+    if (!flag) return MessageFu.warning("至少勾选一个 数据权限 的跨部门数据!");
+
+    const { flag2, txt2 } = r3Ref.current.sonRes();
+    if (!flag2) return MessageFu.warning("至少勾选一个 内控文件权限 模块!");
+
+    // 处理功能权限
+    const tempArr: string[] = [];
+
+    arr1.forEach((v1) => {
+      if (v1.authority) {
+        tempArr.push(v1.id);
+        if (v1.children && v1.children.length) {
+          v1.children.forEach((v2) => {
+            if (v2.authority) {
+              tempArr.push(v2.id);
+              if (v2.children && v2.children.length) {
+                v2.children.forEach((v3) => {
+                  if (v3.authority) tempArr.push(v3.id);
+                });
+              }
+            }
+          });
+        }
+      }
+    });
+
+    const obj1 = {
+      resources: tempArr,
+      roleId: mId,
+    };
+
+    const res1 = await A4_APIsave1(obj1);
+
+    if (res1.code === 0) {
+      const obj2 = {
+        id: mId,
+        dataScope: value,
+        scopeDept: txt,
+      };
+
+      const res2 = await A4_APIsave2(obj2);
+
+      if (res2.code === 0) {
+        const obj3 = {
+          roleId: mId,
+          attrId: txt2,
+        };
+
+        const res3 = await A4_APIsave3(obj3);
+        if (res3.code === 0) {
+          MessageFu.success("授权成功!");
+          authEditFu();
+          authColseFu();
+
+          // 实时更新 权限 信息,用于控制页面和按钮
+          dispatch(A4_APIgetRoleAll());
+        }
+      }
+    }
+  }, [arr1, authColseFu, authEditFu, dispatch, mId]);
+
+  return (
+    <div className={styles.A4Auth}>
+      <div className="A4AMain">
+        <div className="A4AMainLL">
+          <div className="A4ATit">功能权限</div>
+          <div className="A4A1Btn">
+            <Button
+              type="primary"
+              size="small"
+              disabled={arr1.filter((v) => v.authority).length <= 0}
+              onClick={copyRoleFu}
+            >
+              复制权限配置
+            </Button>
+            &emsp;
+            <Button type="primary" size="small" onClick={setArr1Fu}>
+              应用权限配置
+            </Button>
+          </div>
+          <div className="A4A1Cen">
+            {arr1.map((v1) => (
+              <div className="A4A1CenRow" key={v1.id}>
+                <div className="A4A1CenRow1">
+                  <Checkbox
+                    checked={v1.authority}
+                    onChange={(e) => onChange1Fu(e.target.checked, 1, v1.id)}
+                  >
+                    {v1.name}
+                  </Checkbox>
+
+                  {v1.children && v1.children.length
+                    ? v1.children.map((v2) => (
+                        <div className="A4A1CenRow2" key={v2.id}>
+                          <>
+                            <Checkbox
+                              disabled={!v1.authority}
+                              checked={v2.authority}
+                              onChange={(e) =>
+                                onChange1Fu(e.target.checked, 2, v2.id)
+                              }
+                            >
+                              {v2.name}
+                            </Checkbox>
+                            {v2.description ? (
+                              <>
+                                <Tooltip title={v2.description}>
+                                  <div className="iconHoverTitTxt">?</div>
+                                </Tooltip>
+                              </>
+                            ) : null}
+                          </>
+                          {v2.children && v2.children.length ? (
+                            <div className="A4A1CenRow3Box">
+                              {v2.children.map((v3) => (
+                                <div className="A4A1CenRow3" key={v3.id}>
+                                  <Checkbox
+                                    disabled={!v2.authority || !v1.authority}
+                                    checked={v3.authority}
+                                    onChange={(e) =>
+                                      onChange1Fu(e.target.checked, 3, v3.id)
+                                    }
+                                  >
+                                    {v3.name}
+                                  </Checkbox>
+                                  {v3.description ? (
+                                    <>
+                                      <Tooltip title={v3.description}>
+                                        <div className="iconHoverTitTxt">?</div>
+                                      </Tooltip>
+                                      &emsp;
+                                    </>
+                                  ) : null}
+                                </div>
+                              ))}
+                            </div>
+                          ) : null}
+                        </div>
+                      ))
+                    : null}
+                </div>
+              </div>
+            ))}
+          </div>
+        </div>
+        {/* 右侧的 数据权限 和 内控文件权限*/}
+        <div className="A4AMainRR">
+          <A4AuRR ref={r2Ref} info={infoData} />
+          <br />
+          <A4AuRR2 ref={r3Ref} mId={mId} />
+        </div>
+      </div>
+
+      <div className="A4AcliBtn">
+        <Popconfirm
+          title="放弃编辑后,信息将不会保存!"
+          okText="放弃"
+          cancelText="取消"
+          onConfirm={authColseFu}
+          okButtonProps={{ loading: false }}
+        >
+          <Button>取消</Button>
+        </Popconfirm>
+        &emsp;&emsp;
+        <Button type="primary" onClick={btnOkFu}>
+          确定
+        </Button>
+      </div>
+    </div>
+  );
+}
+
+const MemoA4Auth = React.memo(A4Auth);
+
+export default MemoA4Auth;

+ 1 - 0
src/pages/A4Role/index.module.scss

@@ -1,4 +1,5 @@
 .A4Role {
+  position: relative;
   :global {
     .searchTop {
       border-radius: 10px;

+ 42 - 6
src/pages/A4Role/index.tsx

@@ -13,6 +13,7 @@ import React, {
 import { useDispatch, useSelector } from "react-redux";
 import styles from "./index.module.scss";
 import RoleAdd from "./RoleAdd";
+import A4Auth from "./A4Auth";
 function A4Role() {
   const dispatch = useDispatch();
 
@@ -108,19 +109,38 @@ function A4Role() {
       {
         title: "角色说明",
         render: (item: RoleTableType) =>
-          item.roleDesc ? item.roleDesc : "(空)",
+          item.roleDesc ? (
+            item.roleDesc.length >= 30 ? (
+              <span style={{ cursor: "pointer" }} title={item.roleDesc}>
+                {item.roleDesc.substring(0, 30) + "..."}
+              </span>
+            ) : (
+              item.roleDesc
+            )
+          ) : (
+            "(空)"
+          ),
       },
       {
         title: "功能权限",
-        dataIndex: "count",
+        render: (item: RoleTableType) =>
+          item.pcsPerm ? item.pcsPerm + "项" : "-",
       },
       {
         title: "应用权限",
-        dataIndex: "updateTime",
+        render: (item: RoleTableType) =>
+          item.dataScope === 1
+            ? "本部门-自己创建的项目"
+            : item.dataScope === 2
+            ? "本部门-所有用户创建的项目"
+            : item.dataScope === 3
+            ? "跨部门数据"
+            : "-",
       },
       {
         title: "内控文件权限",
-        dataIndex: "updateTime",
+        render: (item: RoleTableType) =>
+          item.pcsAttr ? item.pcsAttr + "项" : "-",
       },
 
       {
@@ -128,7 +148,11 @@ function A4Role() {
         render: (item: RoleTableType) => {
           return (
             <>
-              <Button size="small" type="text">
+              <Button
+                size="small"
+                type="text"
+                onClick={() => setAuthId(item.id)}
+              >
                 授权
               </Button>
 
@@ -158,9 +182,12 @@ function A4Role() {
     ];
   }, [delTableFu, openEditPageFu]);
 
+  // 点击授权出来的页面
+  const [authId, setAuthId] = useState(0);
+
   return (
     <div className={styles.A4Role}>
-      <div className="pageTitle">角色管理</div>
+      <div className="pageTitle">角色管理 {authId ? " > 授权" : null}</div>
       <div className="searchTop">
         <div className="searchTopRow">
           <span>角色名:</span>
@@ -207,6 +234,15 @@ function A4Role() {
           addTableList={resetSelectFu}
         />
       ) : null}
+
+      {/* 点击授权 */}
+      {authId ? (
+        <A4Auth
+          mId={authId}
+          authColseFu={() => setAuthId(0)}
+          authEditFu={() => dispatch(getRoleListAPI(tableSelect))}
+        />
+      ) : null}
     </div>
   );
 }

+ 9 - 0
src/pages/Layout/index.tsx

@@ -22,6 +22,8 @@ import { RouterType } from "@/types";
 import logoImg from "@/assets/img/logo.png";
 import { useDispatch } from "react-redux";
 import { A5_APIgetList } from "@/store/action/A5Section";
+import { A4_APIgetRoleAll } from "@/store/action/A4Role";
+import { A2_APIgetListFile } from "@/store/action/A2Dict";
 
 const NotFound = React.lazy(() => import("@/components/NotFound"));
 
@@ -32,6 +34,13 @@ function Layout() {
   useEffect(()=>{
     // 进页面获取 部门 列表 信息
     dispatch(A5_APIgetList())
+
+    // 获取权限信息
+    dispatch(A4_APIgetRoleAll())
+
+    // 获取字典的 -内控文件属性
+    dispatch(A2_APIgetListFile());
+
   },[dispatch])
 
 

+ 7 - 1
src/pages/Login/index.tsx

@@ -2,7 +2,7 @@ import styles from "./index.module.scss";
 
 import { Input, Button } from "antd";
 import { UserOutlined, LockOutlined } from "@ant-design/icons";
-import { useState } from "react";
+import { useEffect, useState } from "react";
 import { Base64 } from "js-base64";
 import encodeStr from "@/utils/pass";
 import { setTokenInfo } from "@/utils/storage";
@@ -10,12 +10,18 @@ import history from "@/utils/history";
 import { MessageFu } from "@/utils/message";
 import { userLoginAPI } from "@/store/action/layout";
 import loginLogoImg from "@/assets/img/logo.png";
+import store from "@/store";
 
 export default function Login() {
   // 账号密码
   const [userName, setUserName] = useState("");
   const [passWord, setPassWord] = useState("");
 
+  useEffect(() => {
+    //进入登录页 重置 权限信息为空
+    store.dispatch({ type: "A4RoleAll/getInfo", payload: [] });
+  }, []);
+
   // 键盘按下回车事件
   const keyUpEntFu = (e: React.KeyboardEvent<HTMLInputElement>) => {
     if (e.key === "Enter") loginClickFu();

+ 62 - 1
src/store/action/A4Role.ts

@@ -1,4 +1,4 @@
-import { AddRoleType } from "@/types";
+import { A4RolleAllType, AddRoleType } from "@/types";
 import http from "@/utils/http";
 import { AppDispatch } from "..";
 /**
@@ -56,3 +56,64 @@ export const roleSaveAPI = (data: AddRoleType) => {
 export const getRoleInfoByIdAPI = (id: number) => {
   return http.get(`sys/role/detail/${id}`);
 };
+
+/**
+ * 获取  用户  权限
+ */
+export const A4_APIgetRoleAll = () => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.get("sys/resource/getTreePermissions");
+    // 数据扁平化处理,且过滤掉没有权限的数据
+    const tempArr: A4RolleAllType[] = res.data;
+
+    const arrRes: string[] = [];
+
+    tempArr.forEach((v1) => {
+      if (v1.authority) {
+        arrRes.push(v1.id);
+        if (v1.children && v1.children.length) {
+          v1.children.forEach((v2) => {
+            if (v2.authority) {
+              arrRes.push(v2.id);
+              if (v2.children && v2.children.length) {
+                v2.children.forEach((v3) => {
+                  if (v3.authority) arrRes.push(v3.id);
+                });
+              }
+            }
+          });
+        }
+      }
+    });
+
+    dispatch({ type: "A4RoleAll/getInfo", payload: arrRes });
+  };
+};
+
+/**
+ * 获取角色内控文件权限列表
+ */
+export const A4_APIgetRoleFile = (id: number) => {
+  return http.get(`sys/role/getRoleAttribute?roleId=${id}`);
+};
+
+/**
+ * 功能授权
+ */
+export const A4_APIsave1 = (data: any) => {
+  return http.post("sys/role/savePerm", data);
+};
+
+/**
+ * 数据授权
+ */
+export const A4_APIsave2 = (data: any) => {
+  return http.post("sys/role/saveDataScope", data);
+};
+
+/**
+ * 内控文件授权
+ */
+export const A4_APIsave3 = (data: any) => {
+  return http.post("sys/role/saveRoleAttribute", data);
+};

+ 10 - 4
src/store/reducer/A4Role.ts

@@ -7,13 +7,15 @@ const initState = {
     list: [] as RoleTableType[],
     total: 0,
   },
+
+  // 用户的所有 权限信息(扁平化,且过滤掉没有权限的数据)
+  A4RoleAll: [] as string[],
 };
 
 // 定义 action 类型
-type Props = {
-  type: "Role/getList";
-  payload: { list: RoleTableType[]; total: number };
-};
+type Props =
+  | { type: "Role/getList"; payload: { list: RoleTableType[]; total: number } }
+  | { type: "A4RoleAll/getInfo"; payload: string[] };
 
 // 频道 reducer
 export default function RoleReducer(state = initState, action: Props) {
@@ -21,6 +23,10 @@ export default function RoleReducer(state = initState, action: Props) {
     // 获取列表数据
     case "Role/getList":
       return { ...state, tableInfo: action.payload };
+    // 用户的所有 权限信息
+    case "A4RoleAll/getInfo":
+      return { ...state, A4RoleAll: action.payload };
+
     default:
       return state;
   }

+ 27 - 8
src/types/api/A4Role.d.ts

@@ -1,17 +1,20 @@
 export type RoleTableType = {
-  count: number;
   createTime: string;
-  creatorId: null;
+  creatorId?: any;
   creatorName: string;
   id: number;
   isEnabled: number;
+  pcsAttr?: any;
+  pcsPerm?: any;
   roleDesc: string;
   roleKey: string;
   roleName: string;
   sort: string;
   updateTime: string;
-};
 
+  dataScope: 1 | 2 | 3;
+  scopeDept: string;
+};
 
 export type PermissionsAPIType = {
   authority: boolean;
@@ -19,10 +22,26 @@ export type PermissionsAPIType = {
   name: string;
   parentId?: null;
   resourceType?: string;
-}
+};
+
+export type AddRoleType = {
+  id: number | null;
+  roleName: string;
+  roleDesc: string;
+};
+
+export type A4RolleAllType = {
+  authority: boolean;
+  description: string;
+  children?: A4RolleAllType[];
+  id: string;
+  name: string;
+  parentId?: any;
+  resourceType: string;
+};
 
-export type AddRoleType ={
-  id:number|null
-  roleName:string
-  roleDesc:string
+export type A4getRoleFileType ={
+	hasPerm: boolean;
+	id: number;
+	name: string;
 }

+ 25 - 9
src/utils/storage.ts

@@ -1,34 +1,50 @@
 // ------------------------------------token的本地存储------------------------------------
 
 // 用户 Token 的本地缓存键名,自己定义
-const TOKEN_KEY = 'SWSDNBWJ_HT_USER_INFO'
+const TOKEN_KEY = "SWSDNBWJ_HT_USER_INFO";
 
 /**
  * 从本地缓存中获取 Token 信息
  */
 export const getTokenInfo = (): any => {
-  return JSON.parse(localStorage.getItem(TOKEN_KEY) || '{}')
-}
+  return JSON.parse(localStorage.getItem(TOKEN_KEY) || "{}");
+};
 
 /**
  * 将 Token 信息存入缓存
  * @param {Object} tokenInfo 从后端获取到的 Token 信息
  */
 export const setTokenInfo = (tokenInfo: any): void => {
-  localStorage.setItem(TOKEN_KEY, JSON.stringify(tokenInfo))
-}
+  localStorage.setItem(TOKEN_KEY, JSON.stringify(tokenInfo));
+};
 
 /**
  * 删除本地缓存中的 Token 信息
  */
 export const removeTokenInfo = (): void => {
-  localStorage.removeItem(TOKEN_KEY)
-}
+  localStorage.removeItem(TOKEN_KEY);
+};
 
 /**
  * 判断本地缓存中是否存在 Token 信息
  */
 export const hasToken = (): boolean => {
-  return Boolean(getTokenInfo().token)
-}
+  return Boolean(getTokenInfo().token);
+};
 
+// -------------------- 功能权限 的本地存储 --------------------
+const A4_KEY = "SWSDNBWJ_HT_A4_INFO";
+
+/**
+ * 从本地缓存中获取 功能权限 信息
+ */
+export const A4getStorage = (): any => {
+  return JSON.parse(localStorage.getItem(A4_KEY) || "[]");
+};
+
+/**
+ *  功能权限 信息 存入本地缓存
+ */
+export const A4setStorage = (info: any): void => {
+  localStorage.setItem(A4_KEY, JSON.stringify(info));
+};