shaogen1995 2 lat temu
rodzic
commit
a0b74403c8

+ 3 - 1
src/pages/Layout/index.tsx

@@ -19,6 +19,7 @@ import encodeStr from "@/utils/pass";
 import { getDictListAPI, passWordEditAPI } from "@/store/action/login";
 import { getTokenInfo, removeTokenInfo } from "@/utils/storage";
 import { useDispatch } from "react-redux";
+import { getPermissionsAPI } from "@/store/action/role";
 
 function Layout() {
   const dispatch = useDispatch();
@@ -72,9 +73,10 @@ function Layout() {
 
   const [list, setList] = useState(listTemp);
 
-  // 进页面获取所有下拉信息
+  // 进页面获取所有下拉信息和权限信息
   useEffect(() => {
     dispatch(getDictListAPI());
+    dispatch(getPermissionsAPI())
   }, [dispatch]);
 
   // 点击跳转

+ 49 - 0
src/pages/Role/RoleAdd/index.css

@@ -0,0 +1,49 @@
+.roleAdd .ant-modal-close {
+  display: none;
+}
+.roleAdd .roleAddMain {
+  border-top: 1px solid #999999;
+  padding-top: 15px;
+  width: 100%;
+}
+.roleAdd .roleAddMain .row {
+  margin-bottom: 20px;
+  position: relative;
+  display: flex;
+  padding: 0 24px 0 0px;
+  text-align: right;
+}
+.roleAdd .roleAddMain .row .rowSpan {
+  display: inline-block;
+  width: 80px;
+  line-height: 32px;
+}
+.roleAdd .roleAddMain .row .bs::before {
+  content: '*';
+  position: absolute;
+  top: 2px;
+  left: 2px;
+  z-index: 10;
+  color: #ff4d4f;
+}
+.roleAdd .roleAddMain .row .inputBox {
+  width: calc(100% - 90px);
+}
+.roleAdd .roleAddMain .row .inputBoxCheck {
+  width: 155px;
+}
+.roleAdd .roleAddMain .row .inputBoxCheck .rowCheck {
+  display: block;
+  display: flex;
+  margin-left: 4px;
+  margin-top: 5px;
+}
+.roleAdd .roleAddMain .rowThree {
+  margin-top: -26px;
+}
+.roleAdd .roleAddMain .roleAddButton {
+  text-align: center;
+}
+.roleAdd .lookRole .row {
+  pointer-events: none;
+}

+ 66 - 0
src/pages/Role/RoleAdd/index.less

@@ -0,0 +1,66 @@
+.roleAdd {
+  .ant-modal-close {
+    display: none;
+  }
+
+  .roleAddMain {
+    border-top: 1px solid #999999;
+    padding-top: 15px;
+    width: 100%;
+
+    .row {
+      margin-bottom: 20px;
+      position: relative;
+      display: flex;
+      padding: 0 24px 0 0px;
+      text-align: right;
+
+      .rowSpan {
+        display: inline-block;
+        width: 80px;
+        line-height: 32px;
+      }
+
+      .bs {
+        &::before {
+          content: '*';
+          position: absolute;
+          top: 2px;
+          left: 2px;
+          z-index: 10;
+          color: #ff4d4f;
+        }
+      }
+
+      .inputBox {
+        width: calc(100% - 90px);
+
+      }
+
+      .inputBoxCheck {
+        width: 155px;
+
+        .rowCheck {
+          display: block;
+          display: flex;
+          margin-left: 4px;
+          margin-top: 5px;
+        }
+      }
+    }
+
+    .rowThree {
+      margin-top: -26px;
+    }
+
+    .roleAddButton {
+      text-align: center;
+    }
+  }
+
+  .lookRole {
+    .row {
+      pointer-events: none;
+    }
+  }
+}

+ 173 - 0
src/pages/Role/RoleAdd/index.tsx

@@ -0,0 +1,173 @@
+import { getRoleInfoByIdAPI, roleSaveAPI } from "@/store/action/role";
+import {
+  AddRoleType,
+  PermissionsAPIType,
+  RoleTableType,
+} from "@/types/api/role";
+import { Button, Checkbox, Input, message, Modal, Popconfirm } from "antd";
+import React, { useCallback, useEffect, useState } from "react";
+import classNames from "classnames";
+import "./index.css";
+const { TextArea } = Input;
+
+type Props = {
+  id: any;
+  closePage: () => void;
+  upTableList: () => void;
+  addTableList: () => void;
+};
+
+function RoleAdd({ id, closePage, upTableList, addTableList }: Props) {
+  // 角色名称
+  const [roleName, setRoleName] = useState("");
+
+  // 角色描述
+  const [roleDesc, setRoleDesc] = useState("");
+
+  // 页面权限的选择
+  const [list, setList] = useState<PermissionsAPIType[]>([
+    { id: 100, name: "热度统计", authority: true },
+    { id: 200, name: "万物墙管理", authority: true },
+    { id: 300, name: "馆藏管理", authority: true },
+  ]);
+
+  const checkChangeFu = useCallback(
+    (checked: boolean, id: number) => {
+      const newList = list.map((v) => {
+        return {
+          ...v,
+          authority: v.id === id ? checked : v.authority,
+        };
+      });
+      setList(newList);
+    },
+    [list]
+  );
+
+  const getRoleInfoByIdFu = useCallback(async (id: number) => {
+    const res = await getRoleInfoByIdAPI(id);
+    const info: RoleTableType = res.data.role;
+    const authPageArr: PermissionsAPIType[] = res.data.permission;
+    setRoleName(info.roleName);
+    setRoleDesc(info.roleDesc);
+    setList(authPageArr);
+  }, []);
+  // 如果是编辑
+  useEffect(() => {
+    if (id) getRoleInfoByIdFu(id);
+  }, [getRoleInfoByIdFu, id]);
+
+  // 点击提交
+  const btnOkFu = useCallback(async () => {
+    if (roleName === "") return message.warning("请输入角色名称!");
+    const obj: AddRoleType = {
+      id: id ? id : null,
+      resources: list.filter((v) => v.authority).map((v) => v.id),
+      roleDesc: roleDesc,
+      roleName: roleName,
+    };
+    const res: any = await roleSaveAPI(obj);
+
+    if (res.code === 0) {
+      message.success(id ? "编辑成功!" : "新增成功!");
+      closePage();
+      if (id) addTableList();
+      else upTableList();
+    }
+  }, [addTableList, closePage, id, list, roleDesc, roleName, upTableList]);
+
+  return (
+    <Modal
+      wrapClassName="roleAdd"
+      destroyOnClose
+      open={true}
+      title={id ? (id === 1 ? "查看角色" : "编辑角色") : "新增角色"}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className={classNames("roleAddMain", id === 1 ? "lookRole" : "")}>
+        <div className="row">
+          <span className="bs rowSpan">角色名称:</span>
+          <div className="inputBox">
+            <Input
+              maxLength={8}
+              value={roleName}
+              onChange={(e) => setRoleName(e.target.value.replace(/\s+/g, ""))}
+              showCount
+              placeholder="请输入内容"
+            />
+          </div>
+        </div>
+
+        <div className="row">
+          <span className="rowSpan">角色描述:</span>
+          <div className="inputBox">
+            <TextArea
+              rows={4}
+              placeholder="请输入内容"
+              maxLength={100}
+              showCount
+              value={roleDesc}
+              onChange={(e) => setRoleDesc(e.target.value.replace(/\s+/g, ""))}
+            />
+          </div>
+        </div>
+
+        <div className="row rowThree">
+          <span className="rowSpan">权限设置:</span>
+          <div className="inputBox inputBoxCheck">
+            {list.map((v) => (
+              <Checkbox
+                className="rowCheck"
+                key={v.id}
+                checked={v.authority}
+                onChange={(e) => checkChangeFu(e.target.checked, v.id)}
+              >
+                {v.name}
+              </Checkbox>
+            ))}
+            {id === 1 ? (
+              <>
+                <Checkbox className="rowCheck" defaultChecked={true}>
+                  用户管理
+                </Checkbox>
+                <Checkbox className="rowCheck" defaultChecked={true}>
+                  角色管理
+                </Checkbox>
+                <Checkbox className="rowCheck" defaultChecked={true}>
+                  操作日志
+                </Checkbox>
+              </>
+            ) : null}
+          </div>
+        </div>
+
+        <div className="roleAddButton">
+          {id !== 1 ? (
+            <>
+              <Button type="primary" onClick={btnOkFu}>
+                提交
+              </Button>
+              &emsp;
+              <Popconfirm
+                title="放弃编辑后,信息将不会保存!"
+                okText="放弃"
+                cancelText="取消"
+                onConfirm={closePage}
+              >
+                <Button>取消</Button>
+              </Popconfirm>
+            </>
+          ) : (
+            <Button onClick={closePage}>关闭</Button>
+          )}
+        </div>
+      </div>
+    </Modal>
+  );
+}
+
+const MemoRoleAdd = React.memo(RoleAdd);
+
+export default MemoRoleAdd;

+ 17 - 1
src/pages/Role/index.module.scss

@@ -1,5 +1,21 @@
 .Role{
   :global{
-    
+    .roleTop{
+      height: 95px;
+      border-radius: 10px;
+      background-color: #fff;
+      .searchTop{
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 5px 40px 5px 24px;
+      }
+    }
+    .roleMain{
+      margin-top: 15px;
+      height: calc(100% - 105px);
+      border-radius: 10px;
+      background-color: #fff;
+    }
   }
 }

+ 228 - 5
src/pages/Role/index.tsx

@@ -1,12 +1,235 @@
-import React from "react";
+import { RootState } from "@/store";
+import {
+  getRoleListAPI,
+  roleDisplayAPI,
+  roleRemoveAPI,
+} from "@/store/action/role";
+import { RoleTableType } from "@/types/api/role";
+import { Button, Input, message, Popconfirm, Switch, Table } from "antd";
+import React, {
+  useCallback,
+  useEffect,
+  useMemo,
+  useRef,
+  useState,
+} from "react";
+import { useDispatch, useSelector } from "react-redux";
 import styles from "./index.module.scss";
- function Role() {
-  
+import RoleAdd from "./RoleAdd";
+function Role() {
+  const dispatch = useDispatch();
+
+  // 顶部筛选
+
+  type TableListType = {
+    pageNum: number;
+    pageSize: number;
+    searchKey: string;
+  };
+
+  const [tableSelect, setTableSelect] = useState<TableListType>({
+    pageNum: 1,
+    pageSize: 10,
+    searchKey: "",
+  });
+
+  useEffect(() => {
+    dispatch(getRoleListAPI(tableSelect));
+  }, [dispatch, tableSelect]);
+
+  // 角色名的输入
+  const nameTime = useRef(-1);
+  const nameChange = useCallback(
+    (e: React.ChangeEvent<HTMLInputElement>) => {
+      clearTimeout(nameTime.current);
+      nameTime.current = window.setTimeout(() => {
+        setTableSelect({
+          ...tableSelect,
+          searchKey: e.target.value,
+          pageNum: 1,
+        });
+      }, 500);
+    },
+    [tableSelect]
+  );
+
+  // 角色名的重置
+  const [inputKey, setInputKey] = useState(1);
+  const resetSelectFu = useCallback(() => {
+    // 把2个输入框和时间选择器清空
+    setInputKey(Date.now());
+    setTableSelect({
+      pageNum: 1,
+      pageSize: 10,
+      searchKey: "",
+    });
+  }, []);
+
+  // 切换表格中的启用停用状态
+  const isEnabledClickFu = useCallback(
+    async (val: boolean, id: number) => {
+      const isDisable = val ? 1 : 0;
+      const res: any = await roleDisplayAPI(id, isDisable);
+      if (res.code === 0) dispatch(getRoleListAPI(tableSelect));
+    },
+    [dispatch, tableSelect]
+  );
+
+  // 点击删除
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res: any = await roleRemoveAPI(id);
+      if (res.code === 0) {
+        message.success("删除成功!");
+        dispatch(getRoleListAPI(tableSelect));
+      }
+    },
+    [dispatch, tableSelect]
+  );
+
+  // 点击新增和编辑
+  const [editPageShow, setEditPageShow] = useState(false);
+  const editId = useRef(0);
+  const openEditPageFu = useCallback((id: number) => {
+    editId.current = id;
+    setEditPageShow(true);
+  }, []);
+
+  // 从仓库中获取表格数据
+  const tableInfo = useSelector(
+    (state: RootState) => state.RoleReducer.tableInfo
+  );
+
+  // 页码变化
+  const paginationChange = useCallback(
+    () => (pageNum: number, pageSize: number) => {
+      setTableSelect({ ...tableSelect, pageNum, pageSize });
+    },
+    [tableSelect]
+  );
+
+  const columns = useMemo(() => {
+    return [
+      // {
+      //   width: 80,
+      //   title: "序号",
+      //   render: (text: any, record: any, index: any) =>
+      //     index + 1 + (pageNumRef.current - 1) * pagePageRef.current,
+      // },
+      {
+        title: "角色名称",
+        dataIndex: "roleName",
+      },
+      {
+        title: "角色描述",
+        render: (item: RoleTableType) =>
+          item.roleDesc ? item.roleDesc : "(空)",
+      },
+      {
+        title: "成员数量",
+        dataIndex: "count",
+      },
+      {
+        title: "最后编辑时间",
+        dataIndex: "updateTime",
+      },
+
+      {
+        title: "启用状态",
+        render: (item: RoleTableType) => (
+          <Switch
+            disabled={item.roleKey === "sys_admin"}
+            checkedChildren="启用"
+            unCheckedChildren="停用"
+            checked={item.isEnabled === 1}
+            onChange={(val) => isEnabledClickFu(val, item.id!)}
+          />
+        ),
+      },
+
+      {
+        title: "操作",
+        render: (item: RoleTableType) => {
+          return (
+            <>
+              <Button
+                size="small"
+                type="text"
+                onClick={() => openEditPageFu(item.id!)}
+              >
+                {item.roleKey === "sys_admin" ? "查看" : "编辑"}
+              </Button>
+              {item.roleKey !== "sys_admin" ? (
+                <Popconfirm
+                  title="删除后无法恢复,是否删除?"
+                  okText="删除"
+                  cancelText="取消"
+                  onConfirm={() => delTableFu(item.id!)}
+                >
+                  <Button size="small" type="text" danger>
+                    删除
+                  </Button>
+                </Popconfirm>
+              ) : null}
+            </>
+          );
+        },
+      },
+    ];
+  }, [delTableFu, isEnabledClickFu, openEditPageFu]);
+
   return (
     <div className={styles.Role}>
-      <h1>Role</h1>
+      <div className="roleTop">
+        <div className="pageTitlt">角色管理</div>
+        <div className="searchTop">
+          <div className="row">
+            <span>角色名:</span>
+            <Input
+              key={inputKey}
+              maxLength={8}
+              style={{ width: 200 }}
+              placeholder="请输入"
+              allowClear
+              onChange={(e) => nameChange(e)}
+            />
+          </div>
+          <div className="row">
+            <Button type="primary" onClick={() => openEditPageFu(0)}>
+              新增
+            </Button>
+          </div>
+        </div>
+      </div>
+
+      <div className="roleMain">
+        <Table
+          scroll={{ y: 575 }}
+          dataSource={tableInfo.list}
+          columns={columns}
+          rowKey="id"
+          pagination={{
+            showQuickJumper: true,
+            position: ["bottomCenter"],
+            showSizeChanger: true,
+            current: tableSelect.pageNum,
+            pageSize: tableSelect.pageSize,
+            total: tableInfo.total,
+            onChange: paginationChange(),
+          }}
+        />
+      </div>
+      {/* 点击新增或者编辑 */}
+      {editPageShow ? (
+        <RoleAdd
+          id={editId.current}
+          closePage={() => setEditPageShow(false)}
+          upTableList={() => dispatch(getRoleListAPI(tableSelect))}
+          addTableList={resetSelectFu}
+        />
+      ) : null}
     </div>
-  )
+  );
 }
 
 const MemoRole = React.memo(Role);

+ 1 - 1
src/pages/User/UserAdd/index.tsx

@@ -46,7 +46,7 @@ function UserAdd({ id, closePage, upTableList, addTableList }: Props) {
       wrapClassName="userAdd"
       destroyOnClose
       open={true}
-      title={id ? "编辑" : "新增"}
+      title={id ? "编辑用户" : "新增用户"}
       footer={
         [] // 设置footer为空,去掉 取消 确定默认按钮
       }

+ 9 - 12
src/pages/User/index.tsx

@@ -219,18 +219,15 @@ function User() {
 
       {
         title: "启用状态",
-        render: (item: UserTableListType) => {
-          return item.isAdmin === 1 ? (
-            "-"
-          ) : (
-            <Switch
-              checkedChildren="启用"
-              unCheckedChildren="停用"
-              checked={item.isEnabled === 1}
-              onChange={(val) => isEnabledClickFu(val, item.id!)}
-            />
-          );
-        },
+        render: (item: UserTableListType) => (
+          <Switch
+            disabled={item.isAdmin === 1}
+            checkedChildren="启用"
+            unCheckedChildren="停用"
+            checked={item.isEnabled === 1}
+            onChange={(val) => isEnabledClickFu(val, item.id!)}
+          />
+        ),
       },
 
       {

+ 56 - 0
src/store/action/role.ts

@@ -0,0 +1,56 @@
+import { AddRoleType } from "@/types/api/role";
+import http from "@/utils/http";
+import { AppDispatch } from "..";
+/**
+ * 获取角色表格列表数据
+ */
+export const getRoleListAPI = (data: any) => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post("sys/role/listCountPage", data);
+
+    const obj = {
+      list: res.data.records,
+      total: res.data.total,
+    };
+
+    dispatch({ type: "Role/getList", payload: obj });
+  };
+};
+
+/**
+ * 删除角色
+ */
+export const roleRemoveAPI = (id: number) => {
+  return http.get(`sys/role/remove/${id}`);
+};
+
+/**
+ * 用户-是否显示
+ */
+export const roleDisplayAPI = (id: number, display: number) => {
+  return http.get(`sys/role/editStatus/${id}/${display}`);
+};
+
+/**
+ * 获取用户的权限信息
+ */
+export const getPermissionsAPI = () => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.get("sys/resource/getTreePermissions");
+    dispatch({ type: "login/setAuthPageArr", payload: res.data });
+  };
+};
+
+/**
+ * 新增或修改角色
+ */
+export const roleSaveAPI = (data: AddRoleType) => {
+  return http.post("sys/role/save", data);
+};
+
+/**
+ * 通过id获取角色详情
+ */
+export const getRoleInfoByIdAPI = (id: number) => {
+  return http.get(`sys/role/detail/${id}`);
+};

+ 3 - 1
src/store/reducer/index.ts

@@ -5,6 +5,7 @@ import logReducer from './log'
 
 // 导入 登录 模块的 reducer
 import loginReducer from './login'
+import RoleReducer from './role'
 import userReducer from './user'
 import wallReducer from './wall'
 
@@ -14,7 +15,8 @@ const rootReducer = combineReducers({
   wallReducer:wallReducer,
   goodsReducer:goodsReducer,
   userReducer:userReducer,
-  logReducer:logReducer
+  logReducer:logReducer,
+  RoleReducer:RoleReducer
 })
 
 // 默认导出

+ 8 - 1
src/store/reducer/login.ts

@@ -1,4 +1,5 @@
 import { DictListTypeObj } from "@/types";
+import { PermissionsAPIType } from "@/types/api/role";
 
 // 初始化状态
 const initState = {
@@ -18,6 +19,8 @@ const initState = {
     level: [],
     source: [],
   } as DictListTypeObj,
+  // 有关权限的信息
+  authPageArr: [] as PermissionsAPIType[],
 };
 
 // 定义 action 类型
@@ -25,7 +28,8 @@ type LoginActionType =
   | { type: "login/lookBigImg"; payload: { url: string; show: boolean } }
   | { type: "login/asyncLoding"; payload: boolean }
   | { type: "login/lookVideo"; payload: string }
-  | { type: "login/getDictList"; payload: DictListTypeObj };
+  | { type: "login/getDictList"; payload: DictListTypeObj }
+  | { type: "login/setAuthPageArr"; payload: PermissionsAPIType[] };
 
 // 频道 reducer
 export default function loginReducer(
@@ -45,6 +49,9 @@ export default function loginReducer(
     // 所有的下拉框数据
     case "login/getDictList":
       return { ...state, dictList: action.payload };
+    // 有关权限的信息
+    case "login/setAuthPageArr":
+      return { ...state, authPageArr: action.payload };
     default:
       return state;
   }

+ 27 - 0
src/store/reducer/role.ts

@@ -0,0 +1,27 @@
+import { RoleTableType } from "@/types/api/role";
+
+// 初始化状态
+const initState = {
+  // 列表数据
+  tableInfo: {
+    list: [] as RoleTableType[],
+    total: 0,
+  },
+};
+
+// 定义 action 类型
+type RoleActionType = {
+  type: "Role/getList";
+  payload: { list: RoleTableType[]; total: number };
+};
+
+// 频道 reducer
+export default function RoleReducer(state = initState, action: RoleActionType) {
+  switch (action.type) {
+    // 获取列表数据
+    case "Role/getList":
+      return { ...state, tableInfo: action.payload };
+    default:
+      return state;
+  }
+}

+ 30 - 0
src/types/api/role.d.ts

@@ -0,0 +1,30 @@
+export type RoleTableType = {
+  count: number;
+  createTime: string;
+  creatorId: null;
+  creatorName: string;
+  id: number;
+  isEnabled: number;
+  roleDesc: string;
+  roleKey: string;
+  roleName: string;
+  sort: string;
+  updateTime: string;
+};
+
+
+export type PermissionsAPIType = {
+  authority: boolean;
+  children?: null;
+  id: number;
+  name: string;
+  parentId?: null;
+  resourceType?: string;
+}
+
+export type AddRoleType ={
+  id:number|null
+  roleName:string
+  roleDesc:string
+  resources:number[]
+}