From f1bbacb6322aa26ff08122d0165f6e7043b4e342 Mon Sep 17 00:00:00 2001 From: "DESKTOP-HR0JS52\\jun" Date: Thu, 13 Oct 2022 22:54:12 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E9=80=9A=E7=94=A8=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=B0=81=E8=A3=85=E3=80=81=E8=A7=92=E8=89=B2?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E9=A1=B5=E9=9D=A2=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mock/date/index.js | 65 ++++++++++++- mock/server.js | 2 + mock/system/index.js | 12 +++ src/common/service/system/index.ts | 13 +++ src/components/Table/index.module.scss | 12 +++ src/components/Table/index.tsx | 93 +++++++++++++++++++ .../apps/management/system/role/index.tsx | 91 +++++++++++++++++- 7 files changed, 286 insertions(+), 2 deletions(-) create mode 100644 mock/system/index.js create mode 100644 src/common/service/system/index.ts create mode 100644 src/components/Table/index.module.scss create mode 100644 src/components/Table/index.tsx diff --git a/mock/date/index.js b/mock/date/index.js index 5bc2dcd..ece1886 100644 --- a/mock/date/index.js +++ b/mock/date/index.js @@ -46,6 +46,69 @@ const userInfo = Mock.mock({ } }) +const roleList = Mock.mock({ + "list": [ + { + "id": 1, + "roleName": "系统管理员", + "privileges": '*' + }, + { + "id": 2, + "roleName": "总经理", + "privileges": [ + { + id: 1, + name: '权限管理', + pid: 0 + }, + { + id: 2, + name: '角色管理', + pid: 0 + }, + { + id: 3, + name: '员工管理', + pid: 0 + }, + { + id: 4, + name: '报表管理', + pid: 0 + }, + { + id: 5, + name: '考勤管理', + pid: 0 + }, + { + id: 6, + name: '绩效管理', + pid: 0 + } + ] + }, + { + "id": 3, + "roleName": "部门经理", + "privileges": [ + { + id: 1, + name: '权限管理', + pid: 0 + }, + { + id: 2, + name: '角色管理', + pid: 0 + } + ] + } + ] +}) + module.exports = { - userInfo + userInfo, + roleList } diff --git a/mock/server.js b/mock/server.js index 1836b48..ee1ca67 100644 --- a/mock/server.js +++ b/mock/server.js @@ -21,6 +21,8 @@ app.get('/', function(req, res) { router.use('/user/', require('./user/index')) +router.use('/system/', require('./system/index')) + app.use('/api', router) app.listen(3080) diff --git a/mock/system/index.js b/mock/system/index.js new file mode 100644 index 0000000..a146249 --- /dev/null +++ b/mock/system/index.js @@ -0,0 +1,12 @@ +const data = require("../date"); +const result = require("../result"); +const express = require("express"); +const router = express.Router() + +router.use("/getRoleList",function (req, res) { + //调用mock方法模拟数据 + const roleList = data.roleList + return res.json(result(roleList)) +}) + +module.exports = router diff --git a/src/common/service/system/index.ts b/src/common/service/system/index.ts new file mode 100644 index 0000000..b282b59 --- /dev/null +++ b/src/common/service/system/index.ts @@ -0,0 +1,13 @@ +import { Callback, post } from '@utils/request' +import { RoleData } from '@apps/management/system/role' + +export interface ResRoleList { + data: { + list: RoleData[] + } + code: number +} + +export const getRoleList = (success: Callback) => { + post('/api/system/getRoleList', {}, success) +} diff --git a/src/components/Table/index.module.scss b/src/components/Table/index.module.scss new file mode 100644 index 0000000..18f4c05 --- /dev/null +++ b/src/components/Table/index.module.scss @@ -0,0 +1,12 @@ +.tableBox { + position: relative; +} + +.tableHeader { + display: flex; + margin-bottom: 10px; +} + +.search { + flex-grow: 1; +} diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx new file mode 100644 index 0000000..33b08a0 --- /dev/null +++ b/src/components/Table/index.tsx @@ -0,0 +1,93 @@ +import React from 'react' +import styles from './index.module.scss' +import { PlusOutlined, DeleteOutlined, RedoOutlined } from '@ant-design/icons' +import { Button, Space, Table as TableComponent, Input } from 'antd' +import { TablePaginationConfig } from 'antd/es/table' +import { FilterValue } from 'antd/es/table/interface' + +export interface Search { + placeholder?: string + onSearch: { (value: string): void } + width?: number +} + +interface Props { + dataSource: any[] + columns: any[] + rowKey: string + pagination: TablePaginationConfig | false | undefined + search?: Search + loading?: boolean + reload?: { (values: any): void } +} + +interface TableParams { + pagination?: TablePaginationConfig + sortField?: string + sortOrder?: string + filters?: Record +} + +const Table: React.FC = ({ + dataSource, + columns, + rowKey, + pagination = false, + search, + loading = false, + reload +}) => { + const searchRef = React.useRef(null) + return ( +
+
+
+ {search && ( + search.onSearch(value)} + enterButton + /> + )} +
+
+ + {reload && ( + + )} + + + +
+
+ +
+ ) +} + +export default Table diff --git a/src/pages/apps/management/system/role/index.tsx b/src/pages/apps/management/system/role/index.tsx index 9d2cfbd..dc8a6a9 100644 --- a/src/pages/apps/management/system/role/index.tsx +++ b/src/pages/apps/management/system/role/index.tsx @@ -1,10 +1,99 @@ import React from 'react' +import View from '@/components/View' +import { Space, Button } from 'antd' +import type { ColumnsType, TablePaginationConfig } from 'antd/es/table' +import type { FilterValue, SorterResult } from 'antd/es/table/interface' import styles from './index.module.scss' +import { getRoleList } from '@/common/service/system' +import { DeleteOutlined, EditOutlined } from '@ant-design/icons' +import Table from '@/components/Table' interface Props {} +interface PrivilegesData { + id: string + name: string + pid: string +} + +export interface RoleData { + id: string + roleName: string + privileges: PrivilegesData[] | '*' +} + +interface TableParams { + pagination?: TablePaginationConfig + sortField?: string + sortOrder?: string + filters?: Record +} + const Role: React.FC = () => { - return
角色管理
+ const [dataSource, setDataSource] = React.useState([]) + const [tableParams, setTableParams] = React.useState({ + pagination: { + current: 1, + pageSize: 10 + } + }) + React.useEffect(() => { + getRoleList(res => { + const { data } = res + setDataSource(data.list || []) + }) + }, []) + const columns = [ + { + title: '角色名', + dataIndex: 'roleName', + key: 'roleName', + width: 120 + }, + { + title: '权限', + dataIndex: 'privileges', + key: 'privileges', + render: (privileges: PrivilegesData[] | '*') => + privileges === '*' + ? '*' + : privileges.map((row: PrivilegesData) => row.name).join(',') + }, + { + title: '操作', + dataIndex: 'id', + width: 100, + render: (id: string, record: RoleData) => { + return ( + + + + + + console.log(id)} /> + + + ) + } + } + ] + return ( +
+ + + console.log(values) + }} + reload={values => console.log(values)} + /> + + + ) } export default Role -- Gitee From b0c0ab1e88467057f90ad378cd535dd33b44d14a Mon Sep 17 00:00:00 2001 From: "DESKTOP-HR0JS52\\jun" Date: Fri, 14 Oct 2022 14:30:56 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E8=A7=92=E8=89=B2=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E9=80=9A=E7=94=A8=E8=A1=A8=E6=A0=BC=E5=B0=81=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mock/date/index.js | 35 +++++ src/common/service/system/index.ts | 22 ++- src/common/style/vars.scss | 3 + src/components/Table/index.module.scss | 22 +++ src/components/Table/index.tsx | 141 ++++++++++++++---- .../management/system/privileges/index.tsx | 3 +- .../apps/management/system/role/index.tsx | 62 ++++---- 7 files changed, 224 insertions(+), 64 deletions(-) diff --git a/mock/date/index.js b/mock/date/index.js index ece1886..987b5eb 100644 --- a/mock/date/index.js +++ b/mock/date/index.js @@ -47,6 +47,9 @@ const userInfo = Mock.mock({ }) const roleList = Mock.mock({ + "current": 1, + "totalPage": 5, + "total": 50, "list": [ { "id": 1, @@ -104,6 +107,38 @@ const roleList = Mock.mock({ pid: 0 } ] + }, + { + "id": 4, + "roleName": "员工1", + "privileges": [ + { + id: 1, + name: '权限管理', + pid: 0 + }, + { + id: 2, + name: '角色管理', + pid: 0 + } + ] + }, + { + "id": 5, + "roleName": "员工3", + "privileges": [ + { + id: 1, + name: '权限管理', + pid: 0 + }, + { + id: 2, + name: '角色管理', + pid: 0 + } + ] } ] }) diff --git a/src/common/service/system/index.ts b/src/common/service/system/index.ts index b282b59..e45a9e1 100644 --- a/src/common/service/system/index.ts +++ b/src/common/service/system/index.ts @@ -1,13 +1,25 @@ import { Callback, post } from '@utils/request' import { RoleData } from '@apps/management/system/role' +export interface RoleListData { + current: number + totalPage: number + total: number + list: RoleData[] +} + export interface ResRoleList { - data: { - list: RoleData[] - } + data: RoleListData code: number } -export const getRoleList = (success: Callback) => { - post('/api/system/getRoleList', {}, success) +export interface RoleListParams { + roleName: string +} + +export const getRoleList = ( + params: RoleListParams, + success: Callback +) => { + post('/api/system/getRoleList', params, success) } diff --git a/src/common/style/vars.scss b/src/common/style/vars.scss index fd5a693..495e756 100644 --- a/src/common/style/vars.scss +++ b/src/common/style/vars.scss @@ -26,6 +26,9 @@ $start-menu-height: 550px; $view-border-color: #555; +$font-color1: #fff; +$font-color2: #555; + :export { startToolsBarHeight: $start-tools-bar-height; rightMouseMenuWidth: $right-mouse-menu-width; diff --git a/src/components/Table/index.module.scss b/src/components/Table/index.module.scss index 18f4c05..900bbc9 100644 --- a/src/components/Table/index.module.scss +++ b/src/components/Table/index.module.scss @@ -10,3 +10,25 @@ .search { flex-grow: 1; } + +.table { + position: relative; +} + +.dataBox { + position: absolute; + bottom: 25px; + left: 10px; + display: flex; + font-size: 12px; + color: $font-color2; +} + +.current { + margin-right: 2px; + margin-left: 8px; +} + +.totalPage { + margin-left: 2px; +} diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 33b08a0..22d6a1d 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -1,24 +1,35 @@ import React from 'react' import styles from './index.module.scss' import { PlusOutlined, DeleteOutlined, RedoOutlined } from '@ant-design/icons' +import type { PaginationProps, TableProps } from 'antd' import { Button, Space, Table as TableComponent, Input } from 'antd' import { TablePaginationConfig } from 'antd/es/table' import { FilterValue } from 'antd/es/table/interface' export interface Search { placeholder?: string - onSearch: { (value: string): void } + name: string width?: number } +export interface DataSource { + list: any[] + current?: number + totalPage?: number + total?: number +} + interface Props { - dataSource: any[] + dataSource: DataSource columns: any[] rowKey: string - pagination: TablePaginationConfig | false | undefined + pagination?: TablePaginationConfig | null search?: Search loading?: boolean - reload?: { (values: any): void } + reload?: boolean + getData: { (values: any): void } + deleteFun?: { (values: React.Key[]): void } + addFun?: { (): void } } interface TableParams { @@ -32,12 +43,65 @@ const Table: React.FC = ({ dataSource, columns, rowKey, - pagination = false, + pagination, search, loading = false, - reload + reload, + getData, + deleteFun, + addFun }) => { const searchRef = React.useRef(null) + let initPaginationConfig = null + if (pagination === undefined) { + initPaginationConfig = { + current: 1, + pageSize: 10 + } + } else { + if (pagination === null) { + pagination = null + } else { + initPaginationConfig = pagination + } + } + const [paginationConfig, setPaginationConfig] = + React.useState(initPaginationConfig) + const [selectRowKeys, setSelectRowKeys] = React.useState([]) + const onShowSizeChange: PaginationProps['onShowSizeChange'] = ( + current, + pageSize + ) => { + setPaginationConfig(prevState => ({ + ...prevState, + current, + pageSize + })) + } + React.useEffect(() => { + getData({ ...paginationConfig }) + }, [paginationConfig]) // eslint-disable-line + const tableProps: TableProps = { + rowKey: rowKey, + dataSource: dataSource.list, + columns: columns, + loading: loading + } + if (paginationConfig) { + tableProps.pagination = { + showSizeChanger: true, + onShowSizeChange: onShowSizeChange, + ...paginationConfig + } + } + if (deleteFun) { + tableProps.rowSelection = { + type: 'checkbox', + onChange: (selectedRowKeys: React.Key[]) => { + setSelectRowKeys(selectedRowKeys) + } + } + } return (
@@ -47,7 +111,12 @@ const Table: React.FC = ({ ref={searchRef} style={{ width: search.width || 400 }} placeholder={search.placeholder || '请输入搜索内容'} - onSearch={(value: string) => search.onSearch(value)} + onSearch={(value: string) => + getData({ + ...paginationConfig, + [search.name]: value + }) + } enterButton /> )} @@ -58,34 +127,50 @@ const Table: React.FC = ({ )} - - + {addFun && ( + + )} + {deleteFun && ( + + )}
- +
+ +
+ {dataSource.total &&
共50条
} + {paginationConfig && ( + <> +
第1页
/ +
共5页
+ + )} +
+
) } diff --git a/src/pages/apps/management/system/privileges/index.tsx b/src/pages/apps/management/system/privileges/index.tsx index 9e4b8e9..4b68f24 100644 --- a/src/pages/apps/management/system/privileges/index.tsx +++ b/src/pages/apps/management/system/privileges/index.tsx @@ -6,7 +6,6 @@ import type { DataNode } from 'antd/es/tree' import View from '@/components/View' import useMethods from '@utils/useMethods' -interface Props {} interface Data extends DataNode { pid: string @@ -77,7 +76,7 @@ interface PrivilegesData { pid: string } -const Privileges: React.FC = () => { +const Privileges: React.FC = () => { const [data, setData] = React.useState(initData) const [open, setOpen] = React.useState(false) const [form] = Form.useForm() diff --git a/src/pages/apps/management/system/role/index.tsx b/src/pages/apps/management/system/role/index.tsx index dc8a6a9..16c1ecd 100644 --- a/src/pages/apps/management/system/role/index.tsx +++ b/src/pages/apps/management/system/role/index.tsx @@ -1,15 +1,15 @@ import React from 'react' import View from '@/components/View' -import { Space, Button } from 'antd' -import type { ColumnsType, TablePaginationConfig } from 'antd/es/table' -import type { FilterValue, SorterResult } from 'antd/es/table/interface' +import { Space } from 'antd' import styles from './index.module.scss' -import { getRoleList } from '@/common/service/system' +import { + getRoleList, + RoleListData, + RoleListParams +} from '@/common/service/system' import { DeleteOutlined, EditOutlined } from '@ant-design/icons' import Table from '@/components/Table' -interface Props {} - interface PrivilegesData { id: string name: string @@ -22,27 +22,27 @@ export interface RoleData { privileges: PrivilegesData[] | '*' } -interface TableParams { - pagination?: TablePaginationConfig - sortField?: string - sortOrder?: string - filters?: Record -} - -const Role: React.FC = () => { - const [dataSource, setDataSource] = React.useState([]) - const [tableParams, setTableParams] = React.useState({ - pagination: { - current: 1, - pageSize: 10 - } +const Role: React.FC = () => { + const [dataSource, setDataSource] = React.useState({ + current: 0, + list: [], + total: 0, + totalPage: 0 }) - React.useEffect(() => { - getRoleList(res => { - const { data } = res - setDataSource(data.list || []) - }) - }, []) + const [tableLoading, setTableLoading] = React.useState(false) + const getList = (values: RoleListParams) => { + setTableLoading(true) + const params = { + ...values + } + setTimeout(() => { + getRoleList(params, res => { + const { data } = res + setDataSource(data) + setTableLoading(false) + }) + }, 1000) + } const columns = [ { title: '角色名', @@ -83,13 +83,17 @@ const Role: React.FC = () => {
console.log(values) + placeholder: '请输入角色名搜索', + name: 'roleName' }} - reload={values => console.log(values)} + reload + getData={getList} + addFun={() => console.log('add')} + deleteFun={values => console.log(values)} /> -- Gitee From 63138228aecb6f6b2e7c069df3dca4b50fdb4689 Mon Sep 17 00:00:00 2001 From: "DESKTOP-HR0JS52\\jun" Date: Fri, 14 Oct 2022 15:13:23 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E9=80=9A=E7=94=A8table=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Table.md" | 104 ++++++++++++++++++ src/components/Table/index.tsx | 6 +- .../management/system/privileges/index.tsx | 1 - 3 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 "docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" diff --git "a/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" "b/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" new file mode 100644 index 0000000..add04c7 --- /dev/null +++ "b/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" @@ -0,0 +1,104 @@ +# Table 通用表格组件 + +## 基本用法 + +```typescript jsx +import Table from '@/components/Table' + +const [tableLoading, setTableLoading] = React.useState(false) +const [dataSource, setDataSource] = React.useState({ + current: 0, + list: [], + total: 0, + totalPage: 0 +}) + +const getList = (values: RoleListParams) => { + setTableLoading(true) + const params = { + ...values + } + getRoleList(params, res => { + const { data } = res + setDataSource(data) + setTableLoading(false) + }) +} + +const columns = [ + { + title: '角色名', + dataIndex: 'roleName', + key: 'roleName', + width: 120 + }, + { + title: '操作', + dataIndex: 'id', + width: 100, + render: (id: string, record: RoleData) => { + return ( + + + + + + console.log(id)} /> + + + ) + } + } +]; + +
console.log('add')} + deleteFun={values => console.log(values)} +/> +``` + +## API + +| 参数 | 说明 | 类型 | 默认值 | 必传 | +|------------|--------------------------|------------------------------------------------------------------|---------------------------|:----------:| +| dataSource | 表格数据 | [DataSource](#DataSource) | - | 是 | +| columns | 表格列配置 | [ColumnsType](https://ant.design/components/table-cn/#Column) [] | - | 是 | +| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string / (record): string | key | 否 | +| pagination | 分页器,设为 null 或 false 时不分页 | object | {current: 1,pageSize: 10} | 否 | +| search | 表格搜索框功能 | [Search](#Search) | - | 否 | +| loading | 页面是否加载中 | boolean | - | 否 | +| reload | 页面是否显示刷新按钮 | boolean | - | 否 | +| getData | 请求接口数据方法 | (values: any): void | - | 是 | +| deleteFun | 批量删除方法 | (values: React.Key[]): void | - | 否 | +| addFun | 批量删除方法 | (): void | - | 否 | + +###
DataSource
+ +```typescript jsx +export interface DataSource { + current: number + totalPage: number + total: number + list: [] +} +``` + +### + +```typescript jsx +export interface Search { + placeholder?: string + name: string + width?: number +} +``` diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 22d6a1d..9e046a3 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -22,8 +22,8 @@ export interface DataSource { interface Props { dataSource: DataSource columns: any[] - rowKey: string - pagination?: TablePaginationConfig | null + rowKey?: string | { (record: any): string } + pagination?: TablePaginationConfig | null | false search?: Search loading?: boolean reload?: boolean @@ -59,7 +59,7 @@ const Table: React.FC = ({ pageSize: 10 } } else { - if (pagination === null) { + if (pagination === null || pagination === false) { pagination = null } else { initPaginationConfig = pagination diff --git a/src/pages/apps/management/system/privileges/index.tsx b/src/pages/apps/management/system/privileges/index.tsx index 4b68f24..467249a 100644 --- a/src/pages/apps/management/system/privileges/index.tsx +++ b/src/pages/apps/management/system/privileges/index.tsx @@ -6,7 +6,6 @@ import type { DataNode } from 'antd/es/tree' import View from '@/components/View' import useMethods from '@utils/useMethods' - interface Data extends DataNode { pid: string children?: Data[] -- Gitee From 25c927a766cb4e9b15c8b9d6a1245e889c2850de Mon Sep 17 00:00:00 2001 From: "DESKTOP-HR0JS52\\jun" Date: Fri, 14 Oct 2022 16:47:31 +0800 Subject: [PATCH 4/5] rowSelection --- .../Table.md" | 25 ++++++++++--------- src/components/Table/index.tsx | 8 +++++- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git "a/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" "b/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" index add04c7..d6b9894 100644 --- "a/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" +++ "b/docs/\345\205\254\345\205\261\347\273\204\344\273\266/Table.md" @@ -69,18 +69,19 @@ const columns = [ ## API -| 参数 | 说明 | 类型 | 默认值 | 必传 | -|------------|--------------------------|------------------------------------------------------------------|---------------------------|:----------:| -| dataSource | 表格数据 | [DataSource](#DataSource) | - | 是 | -| columns | 表格列配置 | [ColumnsType](https://ant.design/components/table-cn/#Column) [] | - | 是 | -| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string / (record): string | key | 否 | -| pagination | 分页器,设为 null 或 false 时不分页 | object | {current: 1,pageSize: 10} | 否 | -| search | 表格搜索框功能 | [Search](#Search) | - | 否 | -| loading | 页面是否加载中 | boolean | - | 否 | -| reload | 页面是否显示刷新按钮 | boolean | - | 否 | -| getData | 请求接口数据方法 | (values: any): void | - | 是 | -| deleteFun | 批量删除方法 | (values: React.Key[]): void | - | 否 | -| addFun | 批量删除方法 | (): void | - | 否 | +| 参数 | 说明 | 类型 | 默认值 | 必传 | +|--------------|--------------------------|---------------------------------------------------------------------------|---------------------------|:---:| +| dataSource | 表格数据 | [DataSource](#DataSource) | - | 是 | +| columns | 表格列配置 | [ColumnsType](https://ant.design/components/table-cn/#Column) [] | - | 是 | +| rowKey | 表格行 key 的取值,可以是字符串或一个函数 | string / (record): string | key | 否 | +| pagination | 分页器,设为 null 或 false 时不分页 | object | {current: 1,pageSize: 10} | 否 | +| search | 表格搜索框功能 | [Search](#Search) | - | 否 | +| loading | 页面是否加载中 | boolean | - | 否 | +| reload | 页面是否显示刷新按钮 | boolean | - | 否 | +| getData | 请求接口数据方法 | (values: any): void | - | 是 | +| deleteFun | 批量删除方法 | (values: React.Key[]): void | - | 否 | +| addFun | 批量删除方法 | (): void | - | 否 | +| rowSelection | 表格行是否可选择 | [TableRowSelection](https://ant.design/components/table-cn/#rowSelection) | - | 否 | ###
DataSource
diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 9e046a3..30f5fbc 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -2,6 +2,7 @@ import React from 'react' import styles from './index.module.scss' import { PlusOutlined, DeleteOutlined, RedoOutlined } from '@ant-design/icons' import type { PaginationProps, TableProps } from 'antd' +import { TableRowSelection } from 'antd/lib/table/interface' import { Button, Space, Table as TableComponent, Input } from 'antd' import { TablePaginationConfig } from 'antd/es/table' import { FilterValue } from 'antd/es/table/interface' @@ -30,6 +31,7 @@ interface Props { getData: { (values: any): void } deleteFun?: { (values: React.Key[]): void } addFun?: { (): void } + rowSelection?: TableRowSelection } interface TableParams { @@ -49,7 +51,8 @@ const Table: React.FC = ({ reload, getData, deleteFun, - addFun + addFun, + rowSelection }) => { const searchRef = React.useRef(null) let initPaginationConfig = null @@ -102,6 +105,9 @@ const Table: React.FC = ({ } } } + if (rowSelection) { + tableProps.rowSelection = rowSelection + } return (
-- Gitee From 109102c65f128c65d7fd435f1144fdc206455ce0 Mon Sep 17 00:00:00 2001 From: "DESKTOP-HR0JS52\\jun" Date: Fri, 14 Oct 2022 22:06:04 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E8=A7=92=E8=89=B2=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E3=80=81=E8=A1=A8=E5=8D=95=EF=BC=8C=E9=80=9A=E7=94=A8=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E6=89=93=E5=BC=80=E9=85=8D=E7=BD=AE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/main.md | 1 + mock/date/index.js | 73 +++++++++++- mock/system/index.js | 6 + src/common/service/system/index.ts | 10 ++ src/common/style/vars.scss | 2 + src/common/utils/windowOpenConfig.ts | 42 +++++++ src/components/Table/index.tsx | 2 +- src/index.scss | 1 + src/pages/apps/management/index.tsx | 11 +- .../management/system/privileges/index.tsx | 104 +++++------------- .../system/role/RoleForm/index.module.scss | 0 .../management/system/role/RoleForm/index.tsx | 91 +++++++++++++++ .../management/system/role/index.module.scss | 1 + .../apps/management/system/role/index.tsx | 104 ++++++++++++++---- src/pages/desktop/RightMouseMenu/index.tsx | 27 ++--- src/pages/desktop/StartMenu/Control/index.tsx | 10 +- src/store/windowSlice.ts | 2 +- 17 files changed, 364 insertions(+), 123 deletions(-) create mode 100644 src/common/utils/windowOpenConfig.ts create mode 100644 src/pages/apps/management/system/role/RoleForm/index.module.scss create mode 100644 src/pages/apps/management/system/role/RoleForm/index.tsx diff --git a/docs/main.md b/docs/main.md index 3c079b5..cbc62ac 100644 --- a/docs/main.md +++ b/docs/main.md @@ -9,3 +9,4 @@ ## 公共组件 * [View](./公共组件/View.md) * [ImageComponent](./公共组件/ImageComponent.md) +* [Table](./公共组件/Table.md) diff --git a/mock/date/index.js b/mock/date/index.js index 987b5eb..ea103cd 100644 --- a/mock/date/index.js +++ b/mock/date/index.js @@ -46,6 +46,65 @@ const userInfo = Mock.mock({ } }) +const privilegesData = [ + { + title: 'parent 1', + key: 1, + pid: '0', + children: [ + { + title: 'parent 1-0', + key: 2, + pid: '0-0', + children: [ + { title: 'leaf', key: 3, pid: '0-0-0' }, + { + title: 'multiple', + pid: '0-0-0', + key: 4 + }, + { title: 'leaf', key: 5, pid: '0-0-0' } + ] + }, + { + title: 'parent 1-1', + key: 6, + pid: '0-0', + children: [{ title: 'leaf', key: 7, pid: '0-0-1' }] + }, + { + title: 'parent 1-2', + key: 8, + pid: '0-0', + children: [ + { title: 'leaf', key: 9, pid: '0-0-2' }, + { + title: 'leaf', + pid: '0-0-2', + key: 10 + } + ] + } + ] + }, + { + title: 'parent 2', + key: 11, + pid: '0', + children: [ + { + title: 'parent 2-0', + key: 12, + pid: '0-1', + children: [ + { title: 'leaf', key: 13, pid: '0-1-0' }, + { title: 'leaf', key: 14, pid: '0-1-0' } + ] + } + ] + } +] + const roleList = Mock.mock({ "current": 1, "totalPage": 5, @@ -97,12 +156,12 @@ const roleList = Mock.mock({ "roleName": "部门经理", "privileges": [ { - id: 1, + id: 4, name: '权限管理', pid: 0 }, { - id: 2, + id: 5, name: '角色管理', pid: 0 } @@ -113,12 +172,12 @@ const roleList = Mock.mock({ "roleName": "员工1", "privileges": [ { - id: 1, + id: 4, name: '权限管理', pid: 0 }, { - id: 2, + id: 5, name: '角色管理', pid: 0 } @@ -129,12 +188,12 @@ const roleList = Mock.mock({ "roleName": "员工3", "privileges": [ { - id: 1, + id: 7, name: '权限管理', pid: 0 }, { - id: 2, + id: 8, name: '角色管理', pid: 0 } @@ -143,7 +202,9 @@ const roleList = Mock.mock({ ] }) + module.exports = { userInfo, + privilegesData, roleList } diff --git a/mock/system/index.js b/mock/system/index.js index a146249..fb4f4fa 100644 --- a/mock/system/index.js +++ b/mock/system/index.js @@ -3,6 +3,12 @@ const result = require("../result"); const express = require("express"); const router = express.Router() +router.use("/getPrivileges",function (req, res) { + //调用mock方法模拟数据 + const privilegesData = data.privilegesData + return res.json(result(privilegesData)) +}) + router.use("/getRoleList",function (req, res) { //调用mock方法模拟数据 const roleList = data.roleList diff --git a/src/common/service/system/index.ts b/src/common/service/system/index.ts index e45a9e1..2163ad5 100644 --- a/src/common/service/system/index.ts +++ b/src/common/service/system/index.ts @@ -1,5 +1,6 @@ import { Callback, post } from '@utils/request' import { RoleData } from '@apps/management/system/role' +import { PrivilegesData } from '@apps/management/system/privileges' export interface RoleListData { current: number @@ -17,6 +18,15 @@ export interface RoleListParams { roleName: string } +export interface ResPrivileges { + data: PrivilegesData[] + code: number +} + +export const getPrivileges = (success: Callback) => { + post('/api/system/getPrivileges', {}, success) +} + export const getRoleList = ( params: RoleListParams, success: Callback diff --git a/src/common/style/vars.scss b/src/common/style/vars.scss index 495e756..685fc0a 100644 --- a/src/common/style/vars.scss +++ b/src/common/style/vars.scss @@ -24,6 +24,8 @@ $start-tools-bar-height: 48px; $start-menu-width: 600px; $start-menu-height: 550px; +$content-min-width: 710px; + $view-border-color: #555; $font-color1: #fff; diff --git a/src/common/utils/windowOpenConfig.ts b/src/common/utils/windowOpenConfig.ts new file mode 100644 index 0000000..9dd6281 --- /dev/null +++ b/src/common/utils/windowOpenConfig.ts @@ -0,0 +1,42 @@ +import { IMAGE_TYPE, WINDOW_OPEN_WITH } from '@/common/constants' + +const windowOpenConfig = { + userinfo: { + id: 9997, + title: '个人中心', + image: { + type: IMAGE_TYPE.ANTD, + name: 'UserOutlined' + }, + openWith: { + type: WINDOW_OPEN_WITH.COMPONENT, + name: 'userinfo' + } + }, + systemSet: { + id: 9998, + title: '系统设置', + image: { + type: IMAGE_TYPE.ANTD, + name: 'SettingOutlined' + }, + openWith: { + type: WINDOW_OPEN_WITH.IFRAME, + path: '/apps/manage/privileges?type=menu' + } + }, + backgroundSet: { + id: 9999, + title: '背景设置', + image: { + type: IMAGE_TYPE.ANTD, + name: 'PictureOutlined' + }, + openWith: { + type: WINDOW_OPEN_WITH.COMPONENT, + name: 'backgroundSet' + } + } +} + +export default windowOpenConfig diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 30f5fbc..881c11f 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -115,7 +115,7 @@ const Table: React.FC = ({ {search && ( getData({ diff --git a/src/index.scss b/src/index.scss index aefb196..bd041bf 100644 --- a/src/index.scss +++ b/src/index.scss @@ -56,6 +56,7 @@ code { div { &::-webkit-scrollbar { width: 8px; + height: 8px; } &::-webkit-scrollbar-thumb { diff --git a/src/pages/apps/management/index.tsx b/src/pages/apps/management/index.tsx index 2f74436..3d02add 100644 --- a/src/pages/apps/management/index.tsx +++ b/src/pages/apps/management/index.tsx @@ -1,6 +1,10 @@ import React from 'react' import Routers from './Routers' -import { AlignLeftOutlined, UserOutlined } from '@ant-design/icons' +import { + AlignLeftOutlined, + UserOutlined, + UserSwitchOutlined +} from '@ant-design/icons' import { useSearchParams, useLocation } from 'react-router-dom' import styles from './index.module.scss' import LeftRight from '@/components/Layout/LeftRight' @@ -21,6 +25,11 @@ const Management: React.FC = () => { { label: '角色管理', key: '/apps/manage/role', + icon: + }, + { + label: '个人中心', + key: '/apps/manage/userinfo', icon: } ]} diff --git a/src/pages/apps/management/system/privileges/index.tsx b/src/pages/apps/management/system/privileges/index.tsx index 467249a..73ecee5 100644 --- a/src/pages/apps/management/system/privileges/index.tsx +++ b/src/pages/apps/management/system/privileges/index.tsx @@ -5,85 +5,25 @@ import styles from './index.module.scss' import type { DataNode } from 'antd/es/tree' import View from '@/components/View' import useMethods from '@utils/useMethods' +import { getPrivileges } from '@/common/service/system' -interface Data extends DataNode { - pid: string - children?: Data[] -} - -const initData = [ - { - title: 'parent 1', - key: '0-0', - pid: '0', - children: [ - { - title: 'parent 1-0', - key: '0-0-0', - pid: '0-0', - children: [ - { title: 'leaf', key: '0-0-0-0', pid: '0-0-0' }, - { - title: 'multiple', - pid: '0-0-0', - key: '0-0-0-1' - }, - { title: 'leaf', key: '0-0-0-2', pid: '0-0-0' } - ] - }, - { - title: 'parent 1-1', - key: '0-0-1', - pid: '0-0', - children: [{ title: 'leaf', key: '0-0-1-0', pid: '0-0-1' }] - }, - { - title: 'parent 1-2', - key: '0-0-2', - pid: '0-0', - children: [ - { title: 'leaf', key: '0-0-2-0', pid: '0-0-2' }, - { - title: 'leaf', - pid: '0-0-2', - key: '0-0-2-1' - } - ] - } - ] - }, - { - title: 'parent 2', - key: '0-1', - pid: '0', - children: [ - { - title: 'parent 2-0', - key: '0-1-0', - pid: '0-1', - children: [ - { title: 'leaf', key: '0-1-0-0', pid: '0-1-0' }, - { title: 'leaf', key: '0-1-0-1', pid: '0-1-0' } - ] - } - ] - } -] - -interface PrivilegesData { - name: string +export interface PrivilegesData extends DataNode { + title: string | React.ReactNode + key: string pid: string + children?: PrivilegesData[] } const Privileges: React.FC = () => { - const [data, setData] = React.useState(initData) + const [data, setData] = React.useState([]) + const [isLoad, setIsLoad] = React.useState(false) const [open, setOpen] = React.useState(false) const [form] = Form.useForm() const [confirmLoading, setConfirmLoading] = React.useState(false) - const { generalData } = useMethods({ - generalData(data: Data[]) { + const { generalData, getPrivilegesData } = useMethods({ + generalData(data: PrivilegesData[]) { return data.map(row => { - const obj: Data = { + const obj: PrivilegesData = { ...row, title: ( <> @@ -115,8 +55,17 @@ const Privileges: React.FC = () => { } return obj }) + }, + getPrivilegesData() { + getPrivileges(res => { + setIsLoad(true) + return setData(res.data) + }) } }) + React.useEffect(() => { + getPrivilegesData() + }, []) // eslint-disable-line const treeData = React.useMemo(() => { return generalData(data) }, [data]) // eslint-disable-line @@ -162,12 +111,14 @@ const Privileges: React.FC = () => { 新增权限
- + {isLoad && ( + + )} { rules={[{ required: true, message: '请输入权限名称!' }]}> - +} + +export interface OnRef { + submit: { (callBack: { (values: RoleFormValues): void }): void } +} + +export interface RoleFormValues { + id: string + roleName: string + privileges: number[] +} + +const RoleForm: React.FC = ({ initialValues, onRef }) => { + const [privileges, setPrivileges] = React.useState([]) + const [isLoad, setIsLoad] = React.useState(false) + const [selectPrivileges, setSelectPrivileges] = React.useState( + initialValues?.privileges || [] + ) + const [form] = Form.useForm() + useImperativeHandle(onRef, () => ({ + submit(callback) { + form + .validateFields() + .then(values => { + if (selectPrivileges.length === 0) { + message.error('请选择权限!').then(r => r) + return + } + callback({ + ...values, + privileges: selectPrivileges + } as RoleFormValues) + }) + .catch(error => console.log(error)) + } + })) + + const onCheck: TreeProps['onCheck'] = checkedKeys => { + setSelectPrivileges(checkedKeys as number[]) + } + React.useEffect(() => { + getPrivileges(res => { + setIsLoad(true) + return setPrivileges(res.data) + }) + }, []) + + return ( +
+
{}} + onFinishFailed={() => {}} + autoComplete="off"> + + + + + {isLoad && ( + + )} + + +
+ ) +} + +export default RoleForm diff --git a/src/pages/apps/management/system/role/index.module.scss b/src/pages/apps/management/system/role/index.module.scss index 9301178..8ef8107 100644 --- a/src/pages/apps/management/system/role/index.module.scss +++ b/src/pages/apps/management/system/role/index.module.scss @@ -1,3 +1,4 @@ .role { display: block; + min-width: $content-min-width; } diff --git a/src/pages/apps/management/system/role/index.tsx b/src/pages/apps/management/system/role/index.tsx index 16c1ecd..715666b 100644 --- a/src/pages/apps/management/system/role/index.tsx +++ b/src/pages/apps/management/system/role/index.tsx @@ -1,6 +1,6 @@ import React from 'react' import View from '@/components/View' -import { Space } from 'antd' +import { Space, Modal } from 'antd' import styles from './index.module.scss' import { getRoleList, @@ -9,6 +9,8 @@ import { } from '@/common/service/system' import { DeleteOutlined, EditOutlined } from '@ant-design/icons' import Table from '@/components/Table' +import useMethods from '@utils/useMethods' +import RoleForm, { OnRef } from './RoleForm' interface PrivilegesData { id: string @@ -22,6 +24,13 @@ export interface RoleData { privileges: PrivilegesData[] | '*' } +export interface FormModal { + open: boolean + loading: boolean + title: string + initValues?: RoleData +} + const Role: React.FC = () => { const [dataSource, setDataSource] = React.useState({ current: 0, @@ -30,19 +39,48 @@ const Role: React.FC = () => { totalPage: 0 }) const [tableLoading, setTableLoading] = React.useState(false) - const getList = (values: RoleListParams) => { - setTableLoading(true) - const params = { - ...values - } - setTimeout(() => { - getRoleList(params, res => { - const { data } = res - setDataSource(data) - setTableLoading(false) - }) - }, 1000) + const initFormModal = { + title: '', + open: false, + loading: false } + const [formModal, setFormModal] = React.useState(initFormModal) + const roleFormRef = React.useRef() + const { getList, submit, openEditRoleForm } = useMethods({ + getList(values: RoleListParams) { + setTableLoading(true) + const params = { + ...values + } + setTimeout(() => { + getRoleList(params, res => { + const { data } = res + setDataSource(data) + setTableLoading(false) + }) + }, 1000) + }, + openEditRoleForm(record) { + setFormModal(prevState => { + const initValues = { + id: record.id, + roleName: record.roleName, + privileges: record.privileges.map((row: PrivilegesData) => row.id) + } + return { + ...prevState, + title: `编辑角色-${record.roleName}`, + open: true, + initValues + } + }) + }, + submit: () => { + roleFormRef.current?.submit(values => { + console.log(values) + }) + } + }) const columns = [ { title: '角色名', @@ -66,12 +104,20 @@ const Role: React.FC = () => { render: (id: string, record: RoleData) => { return ( - - - - - console.log(id)} /> - + {record.privileges !== '*' && ( + <> + + { + openEditRoleForm(record) + }} + /> + + + console.log(id)} /> + + + )} ) } @@ -92,10 +138,28 @@ const Role: React.FC = () => { }} reload getData={getList} - addFun={() => console.log('add')} + addFun={() => { + setFormModal(prevState => ({ + ...prevState, + open: true, + title: '新增角色' + })) + }} deleteFun={values => console.log(values)} /> + setFormModal(initFormModal)} + destroyOnClose={true}> + {formModal.open && ( + + )} +
) } diff --git a/src/pages/desktop/RightMouseMenu/index.tsx b/src/pages/desktop/RightMouseMenu/index.tsx index 77a95b0..b61583a 100644 --- a/src/pages/desktop/RightMouseMenu/index.tsx +++ b/src/pages/desktop/RightMouseMenu/index.tsx @@ -10,7 +10,7 @@ import { import styles from './index.module.scss' import classnames from 'classnames' import useStore, { MyState } from '@/store' -import { WINDOW_OPEN_WITH, IMAGE_TYPE } from '@/common/constants' +import windowOpenConfig from '@utils/windowOpenConfig' const RightMouseMenu: React.FC = () => { const rightMouseMenu = useStore((state: MyState) => state.rightMouseMenu) @@ -57,7 +57,11 @@ const RightMouseMenu: React.FC = () => {
F5
-
+
{ + openWindow(windowOpenConfig.systemSet) + }}>
@@ -65,7 +69,11 @@ const RightMouseMenu: React.FC = () => { 设置
-
+
{ + openWindow(windowOpenConfig.userinfo) + }}>
@@ -76,18 +84,7 @@ const RightMouseMenu: React.FC = () => {
{ - openWindow({ - id: 9999, - title: '背景设置', - image: { - type: IMAGE_TYPE.ANTD, - name: 'PictureOutlined' - }, - openWith: { - type: WINDOW_OPEN_WITH.COMPONENT, - name: 'backgroundSet' - } - }) + openWindow(windowOpenConfig.backgroundSet) }}>
diff --git a/src/pages/desktop/StartMenu/Control/index.tsx b/src/pages/desktop/StartMenu/Control/index.tsx index 0fead91..bcead69 100644 --- a/src/pages/desktop/StartMenu/Control/index.tsx +++ b/src/pages/desktop/StartMenu/Control/index.tsx @@ -10,9 +10,11 @@ import { Tooltip, Modal } from 'antd' import styles from './index.module.scss' import useMethods from '@utils/useMethods' import useStore, { MyState } from '@/store' +import windowOpenConfig from '@utils/windowOpenConfig' const Control: React.FC = () => { const setShowStartMenu = useStore((state: MyState) => state.setShowStartMenu) + const openWindow = useStore((state: MyState) => state.openWindow) const { logout } = useMethods({ logout() { Modal.confirm({ @@ -47,7 +49,9 @@ const Control: React.FC = () => { overlayClassName={styles.description} placement="right" title="设置"> -
+
openWindow(windowOpenConfig.systemSet)}>
@@ -55,7 +59,9 @@ const Control: React.FC = () => { overlayClassName={styles.description} placement="right" title="个人中心"> -
+
openWindow(windowOpenConfig.userinfo)}>
diff --git a/src/store/windowSlice.ts b/src/store/windowSlice.ts index b7e7e89..fa7f6af 100644 --- a/src/store/windowSlice.ts +++ b/src/store/windowSlice.ts @@ -8,7 +8,7 @@ import { WINDOW_STATUS } from '@/common/constants' const defaultWindowStyle = { display: 'block', - width: 900, + width: 920, height: 600, top: 100, left: 50, -- Gitee