shaogen1995 11 hours ago
parent
commit
ab2d17cd6d

+ 3 - 0
.env

@@ -0,0 +1,3 @@
+# .env.production
+GENERATE_SOURCEMAP = false
+# 关闭映射

+ 121 - 0
src/pages/D3role/D3add/index.module.scss

@@ -0,0 +1,121 @@
+.D3add {
+  :global {
+    .ant-modal-close {
+      display: none;
+    }
+
+    .ant-modal {
+      top: 30px !important;
+      width: 980px !important;
+    }
+
+    .ant-modal-body {
+      border-top: 1px solid #ccc;
+
+      .ant-form-item-label {
+        max-width: 100px;
+      }
+    }
+
+    .D3aMain {
+      width: 900px;
+      position: relative;
+      padding-top: 15px;
+      .fromRow2 {
+        position: relative;
+
+        .fromRowTit {
+          position: absolute;
+          left: 200px;
+          top: 5px;
+          color: #999;
+          font-size: 12px;
+        }
+      }
+      .fromRow {
+        display: flex;
+        align-items: center;
+        margin-bottom: 24px;
+        .fromRowll {
+          width: 94px;
+          text-align: right;
+          position: relative;
+        }
+        .fromRowrr {
+          width: calc(100% - 94px);
+        }
+      }
+
+      .Z5Rtit {
+        pointer-events: none;
+        width: 142px;
+        text-align: center;
+        .ant-radio {
+          display: none;
+        }
+      }
+
+      // 功能权限和数据权限
+      .D3abox {
+        display: flex;
+        .D3aboxll {
+          width: 100px;
+          text-align: right;
+          & > span {
+            color: #ff4d4f;
+          }
+        }
+        .D3aboxrr {
+          width: calc(100% - 100px);
+          .D3aRow {
+            margin-bottom: 10px;
+            display: flex;
+
+            .D3aRow1 {
+              width: 70px;
+              font-weight: 700;
+              text-align: right;
+              margin-right: 10px;
+            }
+
+            .D3aRow2 {
+              width: calc(100% - 80px);
+            }
+          }
+
+          .D3aErr {
+            margin-bottom: 20px;
+            text-align: center;
+            color: #ff4d4f;
+            opacity: 0;
+            pointer-events: none;
+            transition: all 0.3s;
+            position: relative;
+            top: -10px;
+          }
+
+          .D3aErrAc {
+            opacity: 1;
+            top: 0;
+          }
+          .D3aboxrr_1 {
+            margin-top: 5px;
+          }
+        }
+        .D3aboxrr2 {
+          margin-bottom: 15px;
+        }
+      }
+      .D3abox0 {
+        margin-top: -24px;
+      }
+      .D3abox1 {
+        .D3aboxll {
+          width: 150px;
+          text-align: left;
+        }
+        padding-left: 110px;
+      }
+    }
+  }
+}

+ 187 - 0
src/pages/D3role/D3add/index.tsx

@@ -0,0 +1,187 @@
+import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
+import styles from './index.module.scss'
+import { Button, Checkbox, Form, FormInstance, Input, InputNumber, Modal } from 'antd'
+import { MessageFu } from '@/utils/message'
+import { TypeD3Role } from '../data'
+import classNmaes from 'classnames'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import TextArea from 'antd/es/input/TextArea'
+import { D3_APIgetAddTreeList, D3_APIgetInfo, D3_APIsave } from '@/store/action/D3role'
+
+type Props = {
+  sId: number
+  closeFu: () => void
+  addTableFu: () => void
+  editTableFu: () => void
+}
+
+function D3add({ sId, closeFu, addTableFu, editTableFu }: Props) {
+  // 设置表单ref
+  const FormBoxRef = useRef<FormInstance>(null)
+
+  const [loding, setLoding] = useState(false)
+
+  // 编辑进来获取详情
+  const getInfoFu = useCallback(async (id: number) => {
+    const res = await D3_APIgetInfo(id)
+    if (res.code === 0) {
+      FormBoxRef.current?.setFieldsValue(res.data.role)
+      setRoleArr(res.data.permission)
+      setLoding(true)
+    }
+  }, [])
+
+  // 新增的默认数据
+  const [roleArr, setRoleArr] = useState<TypeD3Role[]>([])
+
+  const getAddInfoFu = useCallback(async () => {
+    const res = await D3_APIgetAddTreeList()
+    if (res.code === 0) {
+      setRoleArr(res.data || [])
+      setLoding(true)
+    }
+  }, [])
+
+  useEffect(() => {
+    if (sId > 0) getInfoFu(sId)
+    else {
+      FormBoxRef.current?.setFieldsValue({ sort: 999 })
+      getAddInfoFu()
+    }
+  }, [getAddInfoFu, getInfoFu, sId])
+
+  // 多选框变化
+  const onChange = useCallback(
+    (val: boolean, id: number) => {
+      setRoleArr(
+        roleArr.map(v => ({
+          ...v,
+          authority: v.id === id ? val : v.authority
+        }))
+      )
+    },
+    [roleArr]
+  )
+
+  // 二级选中的数组id集合
+  const checkIds = useMemo(() => {
+    const arr: number[] = []
+    roleArr.forEach(v => {
+      if (v.authority) arr.push(v.id)
+    })
+    return arr
+  }, [roleArr])
+
+  // 没有通过校验
+  const onFinishFailed = useCallback(async () => {
+    // return MessageFu.warning("有表单不符号规则!");
+  }, [])
+
+  // 通过校验点击确定
+  const onFinish = useCallback(
+    async (values: any) => {
+      const obj = {
+        ...values,
+        id: sId > 0 ? sId : null,
+        resources: checkIds
+      }
+
+      const res = await D3_APIsave(obj)
+
+      if (res.code === 0) {
+        MessageFu.success(sId > 0 ? '编辑成功' : '新增成功')
+        sId > 0 ? editTableFu() : addTableFu()
+        closeFu()
+      }
+    },
+    [addTableFu, checkIds, closeFu, editTableFu, sId]
+  )
+
+  return (
+    <Modal
+      wrapClassName={styles.D3add}
+      open={true}
+      title={sId > 0 ? '编辑' : '新增'}
+      footer={
+        [] // 设置footer为空,去掉 取消 确定默认按钮
+      }
+    >
+      <div className='D3aMain'>
+        <Form
+          scrollToFirstError={true}
+          ref={FormBoxRef}
+          name='basic'
+          labelCol={{ span: 3 }}
+          onFinish={onFinish}
+          onFinishFailed={onFinishFailed}
+          autoComplete='off'
+        >
+          <Form.Item
+            label='角色名称'
+            name='roleName'
+            rules={[{ required: true, message: '请输入角色名称' }]}
+          >
+            <Input maxLength={10} showCount placeholder='请输入内容' />
+          </Form.Item>
+
+          <Form.Item label='角色说明' name='roleDesc'>
+            <TextArea maxLength={100} showCount placeholder='请输入内容' />
+          </Form.Item>
+
+          <div className='fromRow2'>
+            <Form.Item
+              label='排序值'
+              name='sort'
+              rules={[{ required: true, message: '请输入排序值!' }]}
+            >
+              <InputNumber min={1} max={999} precision={0} placeholder='请输入' />
+            </Form.Item>
+            <div className='fromRowTit'>
+              请输入1~999的数字。数字越小,排序越靠前。数字相同时,更新发布的内容排在前面
+            </div>
+          </div>
+
+          <div className='D3abox'>
+            <div className='D3aboxll'>
+              <span> * </span> 功能权限:
+            </div>
+            <div className='D3aboxrr'>
+              {roleArr.map(v => (
+                <div key={v.id} className='D3aRow'>
+                  <Checkbox
+                    key={v.id}
+                    checked={v.authority}
+                    onChange={e => {
+                      onChange(e.target.checked, v.id)
+                    }}
+                  >
+                    {v.name}
+                  </Checkbox>
+                </div>
+              ))}
+
+              <div
+                className={classNmaes('D3aErr', checkIds.length <= 0 && loding ? 'D3aErrAc' : '')}
+              >
+                至少选中一个
+              </div>
+            </div>
+          </div>
+          {/* 确定和取消按钮 */}
+          <br />
+          <Form.Item wrapperCol={{ offset: 11, span: 16 }}>
+            <Button type='primary' htmlType='submit' disabled={checkIds.length <= 0}>
+              提交
+            </Button>
+            &emsp;
+            <MyPopconfirm txtK='取消' onConfirm={closeFu} />
+          </Form.Item>
+        </Form>
+      </div>
+    </Modal>
+  )
+}
+
+const MemoD3add = React.memo(D3add)
+
+export default MemoD3add

+ 23 - 0
src/pages/D3role/data.ts

@@ -0,0 +1,23 @@
+export type D3listType = {
+  count?: any
+  createTime: string
+  creatorId?: any
+  creatorName?: any
+  dataScope?: any
+  id: number
+  isEnabled: number
+  roleDesc: string
+  roleKey: string
+  roleName: string
+  sort: number
+  updateTime: string
+}
+
+// 功能权限列表
+export type TypeD3Role = {
+  authority: boolean
+  children: TypeD3Role[]
+  id: number
+  name: string
+  resourceType: string
+}

+ 16 - 0
src/pages/D3role/index.module.scss

@@ -0,0 +1,16 @@
+.D3role {
+  background-color: #fff;
+  border-radius: 10px;
+  padding: 20px;
+  :global {
+    .D3top {
+      text-align: right;
+    }
+    .tableBox {
+      border-radius: 10px;
+      overflow: hidden;
+      margin-top: 15px;
+      height: calc(100% - 28px);
+    }
+  }
+}

+ 117 - 0
src/pages/D3role/index.tsx

@@ -0,0 +1,117 @@
+import React, { useCallback, useEffect, useMemo, useState } from 'react'
+import styles from './index.module.scss'
+import { useDispatch, useSelector } from 'react-redux'
+import { RootState } from '@/store'
+import { MessageFu } from '@/utils/message'
+import { D3listType } from './data'
+import { Button } from 'antd'
+import MyPopconfirm from '@/components/MyPopconfirm'
+import MyTable from '@/components/MyTable'
+import D3add from './D3add'
+import { D3_APIdel, D3_APIgetList } from '@/store/action/D3role'
+import { D3tableC } from '@/utils/tableData'
+function D3role() {
+  const dispatch = useDispatch()
+
+  // 顶部筛选
+  const [fromData, setFromData] = useState({
+    pageNum: 1,
+    pageSize: 10,
+    searchKey: ''
+  })
+
+  // 封装发送请求的函数
+  const getList = useCallback(() => {
+    dispatch(D3_APIgetList(fromData))
+  }, [dispatch, fromData])
+
+  useEffect(() => {
+    getList()
+  }, [getList])
+
+  // 从仓库中获取表格数据
+  const tableInfo = useSelector((state: RootState) => state.D3role.tableInfo)
+
+  // 点击删除
+  const delTableFu = useCallback(
+    async (id: number) => {
+      const res: any = await D3_APIdel(id)
+      if (res.code === 0) {
+        MessageFu.success('删除成功!')
+        getList()
+      }
+    },
+    [getList]
+  )
+
+  const tableLastBtn = useMemo(() => {
+    return [
+      {
+        title: '操作',
+        width: 200,
+        render: (item: D3listType) => {
+          return item.id === 1 ? (
+            '-'
+          ) : (
+            <>
+              <Button size='small' type='text' onClick={() => setEditId(item.id)}>
+                编辑
+              </Button>
+              <MyPopconfirm txtK='删除' onConfirm={() => delTableFu(item.id)} />
+            </>
+          )
+        }
+      }
+    ]
+  }, [delTableFu])
+
+  // 点击重置
+  const resetSelectFu = useCallback(() => {
+    setFromData({
+      pageNum: 1,
+      pageSize: 10,
+      searchKey: ''
+    })
+  }, [])
+
+  // 点击新增和编辑
+  const [editId, setEditId] = useState(0)
+
+  return (
+    <div className={styles.D3role}>
+      <div className='pageTitle'>角色管理</div>
+      <div className='D3top'>
+        <Button type='primary' onClick={() => setEditId(-1)}>
+          新增
+        </Button>
+      </div>
+      {/* 表格主体 */}
+      <div className='tableBox'>
+        <MyTable
+          yHeight={630}
+          list={tableInfo.list}
+          columnsTemp={D3tableC}
+          lastBtn={tableLastBtn}
+          pageNum={fromData.pageNum}
+          pageSize={fromData.pageSize}
+          total={tableInfo.total}
+          onChange={(pageNum, pageSize) => setFromData({ ...fromData, pageNum, pageSize })}
+        />
+      </div>
+
+      {/* 新增和编辑 */}
+      {editId ? (
+        <D3add
+          sId={editId}
+          closeFu={() => setEditId(0)}
+          addTableFu={resetSelectFu}
+          editTableFu={getList}
+        />
+      ) : null}
+    </div>
+  )
+}
+
+const MemoD3role = React.memo(D3role)
+
+export default MemoD3role

+ 6 - 0
src/pages/Layout/data.ts

@@ -87,6 +87,12 @@ const tabLeftArr: RouterType = [
         path: "/user",
         Com: React.lazy(() => import("../Z1user")),
       },
+         {
+        id: 2300,
+        name: "角色管理",
+        path: "/role",
+        Com: React.lazy(() => import("../D3role")),
+      },
       {
         id: 2200,
         name: "系统日志",

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

@@ -19,7 +19,7 @@ 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";
+import { D3_APIgetInfo } from "@/store/action/D3role";
 
 function Layout() {
   // 当前路径选中的左侧菜单
@@ -38,15 +38,20 @@ function Layout() {
   const getUserAuthFu = useCallback(async () => {
     const userInfo = getTokenInfo().user;
 
-    const res = await Z1_APIgetAuthByUserId(userInfo.id);
+    const res = await D3_APIgetInfo(userInfo.roleId);
     if (res.code === 0) {
-      const tempList: UserListType[] = res.data || [];
+
+      console.log(123456,res);
+      
+
+      const tempList: UserListType[] = res.data.permission || [];
       const isOkIdArr = tempList.filter((c) => c.authority).map((v) => v.id);
 
       // 是管理员
       if (userInfo.isAdmin === 1) {
         isOkIdArr.push(2100);
         isOkIdArr.push(2200);
+        isOkIdArr.push(2300);
       }
 
       const tempArr: RouterTypeRow = [];

+ 32 - 3
src/pages/Z1user/UserAdd/index.tsx

@@ -1,10 +1,13 @@
 import { getUserInfoByIdAPI, userSaveAPI } from "@/store/action/Z1user";
 import { SaveUserType } from "@/types";
 import { MessageFu } from "@/utils/message";
-import { Button, Form, FormInstance, Input, Modal } from "antd";
+import { Button, Form, FormInstance, Input, Modal, Select } from "antd";
 import React, { useCallback, useEffect, useRef } from "react";
 import styles from "./index.module.scss";
 import MyPopconfirm from "@/components/MyPopconfirm";
+import { useDispatch, useSelector } from "react-redux";
+import { D3_APIgetList } from "@/store/action/D3role";
+import { RootState } from "@/store";
 
 type Props = {
   id: any;
@@ -14,6 +17,21 @@ type Props = {
 };
 
 function UserAdd({ id, closePage, upTableList, addTableList }: Props) {
+
+  // 角色
+  const dispatch = useDispatch()
+  useEffect(() => {
+    dispatch(
+      D3_APIgetList({
+        pageNum: 1,
+        pageSize: 99999,
+        searchKey: ''
+      })
+    )
+  }, [dispatch])
+
+  const { list: roleList } = useSelector((state: RootState) => state.D3role.tableInfo)
+
   // 设置表单初始数据(区分编辑和新增)
   const FormBoxRef = useRef<FormInstance>(null);
 
@@ -41,8 +59,6 @@ function UserAdd({ id, closePage, upTableList, addTableList }: Props) {
       const obj: SaveUserType = {
         ...values,
         id: id ? id : null,
-        // 角色id写死 2=》普通用户
-        roleId: 2,
       };
 
       const res: any = await userSaveAPI(obj);
@@ -105,6 +121,19 @@ function UserAdd({ id, closePage, upTableList, addTableList }: Props) {
             <Input maxLength={8} showCount placeholder="请输入内容" />
           </Form.Item>
 
+            <Form.Item
+            label='角色'
+            name='roleId'
+            rules={[{ required: true, message: '请选择角色!' }]}
+          >
+            <Select
+              style={{ width: 240 }}
+              placeholder='请选择'
+              options={roleList.filter(v => v.id !== 1)}
+              fieldNames={{ value: 'id', label: 'roleName' }}
+            />
+          </Form.Item>
+
           {id ? null : <div className="passTit">* 默认密码 Aa147852</div>}
 
           {/* 确定和取消按钮 */}

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

@@ -132,7 +132,7 @@ function Z1user() {
               >
                 编辑
               </Button>
-              <Button
+              {/* <Button
                 size="small"
                 type="text"
                 onClick={() =>
@@ -140,7 +140,7 @@ function Z1user() {
                 }
               >
                 权限管理
-              </Button>
+              </Button> */}
               <MyPopconfirm txtK="删除" onConfirm={() => delTableFu(item.id)} />
             </>
           );

+ 46 - 0
src/store/action/D3role.ts

@@ -0,0 +1,46 @@
+import http from '@/utils/http'
+import { AppDispatch } from '..'
+/**
+ * 角色管理 -获取分页列表
+ */
+export const D3_APIgetList = (data: any): any => {
+  return async (dispatch: AppDispatch) => {
+    const res = await http.post('sys/role/listCountPage', data)
+    if (res.code === 0) {
+      const obj = {
+        list: res.data.records,
+        total: res.data.total
+      }
+
+      dispatch({ type: 'D3/getList', payload: obj })
+    }
+  }
+}
+
+/**
+ * 角色管理 -删除
+ */
+export const D3_APIdel = (id: number) => {
+  return http.get(`sys/role/remove/${id}`)
+}
+
+/**
+ * 角色管理 -新增--获取权限列表
+ */
+export const D3_APIgetAddTreeList = () => {
+  return http.get('sys/user/perm/getTree')
+}
+
+/**
+ * 角色管理 -新增/编辑
+ */
+export const D3_APIsave = (data: any) => {
+  return http.post('sys/role/save', data)
+}
+
+/**
+ * 角色管理 -获取详情
+ */
+export const D3_APIgetInfo = (id: number) => {
+  return http.get(`sys/role/detail/${id}`)
+}

+ 28 - 0
src/store/reducer/D3role.ts

@@ -0,0 +1,28 @@
+import { D3listType } from '@/pages/D3role/data'
+
+// 初始化状态
+const initState = {
+  // 列表数据
+  tableInfo: {
+    list: [] as D3listType[],
+    total: 0
+  }
+}
+
+// 定义 action 类型
+type Props = {
+  type: 'D3/getList'
+  payload: { list: D3listType[]; total: number }
+}
+
+// reducer
+export default function userReducer(state = initState, action: Props) {
+  switch (action.type) {
+    // 获取列表数据
+    case 'D3/getList':
+      return { ...state, tableInfo: action.payload }
+
+    default:
+      return state
+  }
+}

+ 2 - 0
src/store/reducer/index.ts

@@ -12,6 +12,7 @@ import A5cash from "./A5cash";
 import A6message from "./A6message";
 import A7_1charity from "./A7_1charity";
 import A7school from "./A7school";
+import D3role from "./D3role";
 import Z1user from "./Z1user";
 import Z2log from "./Z2log";
 
@@ -27,6 +28,7 @@ const rootReducer = combineReducers({
   A6message,
   A7_1charity,
   A7school,
+  D3role,
   Z1user,
   Z2log,
 });

+ 2 - 2
src/utils/http.ts

@@ -7,8 +7,8 @@ import { domShowFu } from "./domShow";
 
 const envFlag = process.env.NODE_ENV === "development";
 
-const baseUrlTemp = "https://sit-wuxicishan.4dage.com"; // 测试环境
-// const baseUrlTemp = "http://192.168.20.61:8066"; // 线下环境
+// const baseUrlTemp = "https://sit-wuxicishan.4dage.com"; // 测试环境
+const baseUrlTemp = "http://192.168.20.61:8066"; // 线下环境
 
 const baseFlag = baseUrlTemp.includes("https://");
 

+ 6 - 1
src/utils/tableData.ts

@@ -120,7 +120,7 @@ export const A7tableCtheme = [["txt", "采访主题", "name"]];
 
 export const Z1tableC = [
   ["txt", "用户名", "userName"],
-  ["txtChange", "角色", "isAdmin", { 1: "管理员", 0: "普通成员" }],
+  ["txt", "角色", "roleName"],
   ["txt", "真实姓名", "realName"],
   ["txt", "创建日期", "createTime"],
 ];
@@ -133,3 +133,8 @@ export const Z2tableC = [
   ["txt", "操作模块", "type"],
   ["txt", "操作事件", "description"],
 ];
+export const D3tableC = [
+  ["txt", "角色名称", "roleName"],
+  ["text", "角色说明", "roleDesc", "100"],
+  ["txt", "排序值", "sort"],
+];