refactor: 重构配置模块

This commit is contained in:
2024-10-26 17:37:09 +08:00
parent 0283e018de
commit 5eb78c35c2
22 changed files with 1110 additions and 833 deletions

View File

@@ -29,16 +29,22 @@ const Content = Layout.Content;
function getFlattenRoutes(routes) {
const mod = import.meta.glob('./pages/**/[a-z[]*.tsx');
const res = [];
function travel(_routes) {
_routes.forEach((route) => {
if (route.key && !route.children) {
try {
route.component = lazyload(mod[`./pages/${route.key}/index.tsx`]);
res.push(route);
} catch (error) {
console.error(`cannot found /pages/${route.key}/index.tsx`)
}
} else if (isArray(route.children) && route.children.length) {
travel(route.children);
}
});
}
travel(routes);
return res;
}

View File

@@ -0,0 +1,61 @@
import React from 'react';
import {
Typography,
TableColumnProps,
Button,
Popconfirm,
Space,
} from '@arco-design/web-react';
import {genderDict, getDictValue, tableStatusDict} from "@/enum/dict";
import {dayjs} from "@arco-design/web-react/es/_util/dayjs";
const {Text} = Typography;
export const enum TableOptions {
EDIT = 'edit',
DELETE = 'delete',
}
export function getColumns(callback: (type: TableOptions, record: any) => Promise<void>): TableColumnProps[] {
return [
{
title: '唯一编码',
dataIndex: 'key',
render: (value) => <Text copyable>{value}</Text>,
},
{
title: '配置值',
dataIndex: 'value'
},
{
title: '备注',
dataIndex: 'remark'
},
{
title: '创建时间',
dataIndex: 'createdAt',
width: '15%',
render: (value) => dayjs(value).format('YYYY-MM-DD HH:mm:ss'),
},
{
title: '操作',
dataIndex: 'operations',
align: 'center',
width: '300px',
render: (_, record) => (
<Space>
<Button size='small' onClick={() => callback(TableOptions.EDIT, record)} type="text" status="default"></Button>
<Popconfirm
focusLock
title="删除数据"
content="确认删除该条数据吗?"
onOk={() => callback(TableOptions.DELETE, record)}
>
<Button size='small' type="text" status="danger"></Button>
</Popconfirm>
</Space>
)
}
]
}

View File

@@ -17,10 +17,13 @@ function FormComponent(props: Props) {
try {
setConfirmLoading(true);
const values = await form.validate();
const data = {
...values,
};
if (record?.key) {
await updateConfig(values);
await updateConfig(data);
} else {
await createConfig(values);
await createConfig(data);
}
Message.success(`${record?.key ? '更新' : '新增'}成功!`);
handleConfirm();
@@ -35,36 +38,37 @@ function FormComponent(props: Props) {
useEffect(() => {
record && form.setFieldsValue({
...record
...record,
});
}, [record]);
useEffect(() => {
!visible && form.resetFields();
!visible && form.resetFields()
}, [visible]);
return (
<div>
<Modal
title={<span>{`${record?.key ? '更新' : '新增'}配置信息`}</span>}
title={<span>{`${record?.key ? '更新' : '新增'}数据`}</span>}
visible={visible}
onOk={onOk}
onCancel={handleCancel}
confirmLoading={confirmLoading}
>
<Form form={form}>
<Form.Item disabled={record?.key} label="配置id" field="key" rules={[{ required: true }]}>
<Input placeholder="请输入配置id" />
<Form.Item disabled={record?.key} label="唯一编码" field="key" rules={[{required: true}]}>
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item label="配置值" field="value" rules={[{required: true}]}>
<Input placeholder="请输入配置值" />
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item label="备注" field="remark">
<Input placeholder="请输入备注" />
<Form.Item label="备注" field="remark" rules={[{required: false}]}>
<Input placeholder="请输入"/>
</Form.Item>
</Form>
</Modal>
</div>
);
}

View File

@@ -1,67 +1,28 @@
import React, { useState } from 'react';
import React, {useEffect, useState} from 'react';
import {
Card,
Table,
Typography,
TableColumnProps,
PaginationProps,
Button,
Popconfirm,
Divider,
Avatar, Space, Message
Card,
Message,
PaginationProps, Space,
Table,
TableColumnProps,
Typography
} from '@arco-design/web-react';
import {useQuery} from 'react-query';
import Form from './form';
import { deleteConfig, getConfig, syncConfig } from '@/api/config';
import SearchForm from "./searchForm";
import {IconPlus, IconSync} from '@arco-design/web-react/icon';
import {getColumns, TableOptions} from './constants';
import {useHistory} from "react-router";
import {getConfig, deleteConfig, syncConfig} from "@/api/config";
const { Title, Text } = Typography;
const {Title} = Typography;
export default function () {
const reactQueryKey = useHistory().location.pathname
function ConfigManage() {
const [visible, setVisible] = useState(false);
const [record, setRecord] = useState(null);
const columns: TableColumnProps[] = [
{
title: '配置id',
dataIndex: 'key',
render: (value) => <Text copyable>{value}</Text>,
align: 'center',
width:'25%'
},
{
title: '配置值',
dataIndex: 'value',
render: (value) => <Text copyable>{value}</Text>,
align: 'center',
width:'25%'
},
{
title: '备注',
dataIndex: 'remark',
align: 'center',
width:'25%'
},
{
title: '操作',
dataIndex: 'operations',
render: (_, record) => (
<>
<Button onClick={() => showModal(record)} type="text" status="default"></Button>
<Divider type="vertical" />
<Popconfirm
focusLock
title="删除数据"
content="确认删除该条数据吗?"
onOk={() => onDelete(record)}
>
<Button type="text" status="danger"></Button>
</Popconfirm>
</>
),
align: 'center'
}
];
const [pagination, setPagination] = useState<PaginationProps>({
sizeCanChange: true,
showTotal: true,
@@ -71,47 +32,9 @@ function ConfigManage() {
total: 0
});
const onDelete = async ({ key }) => {
await deleteConfig(key);
Message.success('删除成功!');
await refetch();
};
const onChangeTable = async ({ current, pageSize }) => {
setPagination({
...pagination,
current,
pageSize
});
};
const fetchData = async ({ queryKey }) => {
const [, { page, pageSize }] = queryKey;
const { data } = await getConfig({ page, pageSize });
setPagination(prevState => {
prevState.total = data.count;
return prevState;
});
if (page > 1 && data.list.length === 0) {
setPagination({
...pagination,
current: page - 1
});
}
return data;
};
const {
data,
isLoading,
isFetching,
refetch
} = useQuery(
['config', { page: pagination.current, pageSize: pagination.pageSize }],
fetchData,
{
refetchOnWindowFocus: false,
keepPreviousData: true
const [searchQuery, setSearchQuery] = useState<Record<string, any>>({
page: pagination.current,
pageSize: pagination.pageSize,
});
const showModal = (payload?) => {
@@ -119,6 +42,63 @@ function ConfigManage() {
setVisible(true);
};
const onDelete = async ({key}) => {
await deleteConfig(key);
Message.success('删除成功!');
await refetch();
};
const tableCallback = async (type: TableOptions, record: any) => {
switch (type) {
case TableOptions.EDIT:
showModal(record)
break;
case TableOptions.DELETE:
await onDelete(record);
break
}
}
const columns: TableColumnProps[] = getColumns(tableCallback)
const handleSearch = async (params) => {
setSearchQuery(prev => ({...prev, page: 1, ...params}))
}
const onChangeTable = async ({current, pageSize}) => {
setSearchQuery(prev => ({...prev, page: current, pageSize}));
};
const fetchData = async ({queryKey}) => {
const [, params] = queryKey;
const {data} = await getConfig(params);
setPagination(prev => ({
...prev,
total: data.count
}))
// 当前列表不存在数据回退1页
if (params.page > 1 && data.list.length === 0) {
setSearchQuery({
...searchQuery,
page: params.page - 1
});
}
return data;
};
const {data, isLoading, isFetching, refetch} = useQuery(
[reactQueryKey, {
page: pagination.current,
pageSize: pagination.pageSize,
...searchQuery
}],
fetchData);
const sync = async () => {
await syncConfig()
Message.success('配置已同步');
}
const handleConfirm = async () => {
setRecord(null);
setVisible(false);
@@ -130,10 +110,13 @@ function ConfigManage() {
setVisible(false);
};
const sync = async () => {
await syncConfig();
Message.success('配置已同步!');
};
useEffect(() => {
setPagination(prev => ({
...prev,
current: searchQuery.page,
pageSize: pagination.pageSize,
}))
}, [searchQuery])
return (
<>
@@ -146,9 +129,23 @@ function ConfigManage() {
/>
<Title heading={6}></Title>
<SearchForm onSearch={handleSearch}/>
<Space style={{marginBottom: 12}}>
<Button type="primary" onClick={() => showModal()}></Button>
<Button type="primary" onClick={() => sync()}>redis</Button>
<Button
type="primary"
icon={<IconPlus/>}
onClick={() => showModal()}
>
</Button>
<Button
type="primary"
icon={<IconSync/>}
onClick={() => sync()}
>
redis
</Button>
</Space>
@@ -164,6 +161,3 @@ function ConfigManage() {
</>
);
}
export default ConfigManage;

View File

@@ -0,0 +1,70 @@
import React from 'react';
import {
Form,
Input,
Button,
Grid,
Space, Divider, Select
} from '@arco-design/web-react';
import {IconRefresh, IconSearch} from '@arco-design/web-react/icon';
import {statusDict} from "@/enum/dict";
const {Row, Col} = Grid;
const {useForm} = Form;
function SearchForm(props: {
onSearch: (values: Record<string, any>) => void;
}) {
const [form] = useForm();
const handleSubmit = () => {
const values = form.getFieldsValue();
props.onSearch(values);
};
const handleReset = () => {
form.resetFields();
props.onSearch({});
};
const colSpan = 6
return (
<>
<Form
form={form}
labelCol={{span: 6}}
wrapperCol={{span: 18}}
labelAlign="left"
>
<Row gutter={24}>
<Col span={colSpan}>
<Form.Item label="唯一编码" field="key">
<Input placeholder="请输入唯一编码" allowClear/>
</Form.Item>
</Col>
<Col span={colSpan}>
<Form.Item label="配置值" field="value">
<Input placeholder="请输入配置值" allowClear/>
</Form.Item>
</Col>
<Col span={colSpan}>
<Form.Item>
<Space>
<Button type="primary" icon={<IconSearch/>} onClick={handleSubmit}>
</Button>
<Button icon={<IconRefresh/>} onClick={handleReset}>
</Button>
</Space>
</Form.Item>
</Col>
</Row>
</Form>
<Divider style={{margin: '0 0 20px 0'}}/>
</>
);
}
export default SearchForm;

View File

@@ -1,15 +0,0 @@
.search-form-wrapper {
display: flex;
border-bottom: 1px solid var(--color-border-1);
margin-bottom: 20px;
.right-button {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20px;
margin-bottom: 20px;
border-left: 1px solid var(--color-border-2);
box-sizing: border-box;
}
}

View File

@@ -0,0 +1,60 @@
import React from 'react';
import {
TableColumnProps,
Button,
Popconfirm,
Space,
} from '@arco-design/web-react';
export const enum TableOptions {
EDIT = 'edit',
DELETE = 'delete',
}
export function getColumns(callback: (type: TableOptions, record: any) => Promise<void>): TableColumnProps[] {
return [
{
title: '菜单id',
dataIndex: 'id',
align: 'center',
},
{
title: '菜单名称',
dataIndex: 'name',
align: 'center',
},
{
title: '菜单url',
dataIndex: 'url',
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
align: 'center',
},
{
title: '操作',
dataIndex: 'operations',
align: 'center',
width: '300px',
render: (_, record) => (
<Space>
<Button size='small' onClick={() => callback(TableOptions.EDIT, record)} type="text"
status="default"></Button>
<Popconfirm
focusLock
title="删除数据"
content="确认删除该条数据吗?"
onOk={() => callback(TableOptions.DELETE, record)}
>
<Button size='small' type="text" status="danger"></Button>
</Popconfirm>
</Space>
)
}
]
}

View File

@@ -5,62 +5,21 @@ import {
Typography,
TableColumnProps,
Button,
Popconfirm,
Divider,
Space,
Message
} from '@arco-design/web-react';
import {useQuery} from 'react-query';
import Form from './form';
import {deleteMenu, getTreeMenu} from '@/api/menu';
import {getColumns, TableOptions} from './constants';
import {useHistory} from "react-router";
const {Title} = Typography;
function ConfigManage() {
const reactQueryKey = useHistory().location.pathname;
const [visible, setVisible] = useState(false);
const [record, setRecord] = useState(null);
const columns: TableColumnProps[] = [
{
title: '菜单id',
dataIndex: 'id',
align: 'center',
},
{
title: '菜单名称',
dataIndex: 'name',
align: 'center',
},
{
title: '菜单url',
dataIndex: 'url',
align: 'center',
},
{
title: '排序',
dataIndex: 'sort',
align: 'center',
},
{
title: '操作',
dataIndex: 'operations',
width:'25%',
render: (_, record) => (
<>
<Button onClick={() => showModal(record)} type="text" status="default"></Button>
<Divider type="vertical" />
<Popconfirm
focusLock
title="删除数据"
content="确认删除该条数据吗?"
onOk={() => onDelete(record)}
>
<Button type="text" status="danger"></Button>
</Popconfirm>
</>
),
align: 'center'
}
];
const onDelete = async ({id}) => {
await deleteMenu(id);
@@ -68,6 +27,19 @@ function ConfigManage() {
await refetch();
};
const tableCallback = async (type: TableOptions, record: any) => {
switch (type) {
case TableOptions.EDIT:
showModal(record)
break;
case TableOptions.DELETE:
await onDelete(record);
break
}
}
const columns: TableColumnProps[] = getColumns(tableCallback)
const fetchData = async () => {
const {data} = await getTreeMenu();
return data
@@ -79,7 +51,7 @@ function ConfigManage() {
isFetching,
refetch
} = useQuery(
['menu'], fetchData, { refetchOnWindowFocus: false, keepPreviousData: true });
[reactQueryKey], fetchData);
const showModal = (payload?) => {
payload && setRecord(payload);

View File

@@ -1,15 +0,0 @@
.search-form-wrapper {
display: flex;
border-bottom: 1px solid var(--color-border-1);
margin-bottom: 20px;
.right-button {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20px;
margin-bottom: 20px;
border-left: 1px solid var(--color-border-2);
box-sizing: border-box;
}
}

View File

@@ -0,0 +1,79 @@
import React from 'react';
import {
Typography,
TableColumnProps,
Button,
Popconfirm,
Space,
} from '@arco-design/web-react';
import {getDictValue, tableStatusDict} from "@/enum/dict";
import {dayjs} from "@arco-design/web-react/es/_util/dayjs";
const {Text} = Typography;
export const enum TableOptions {
EDIT = 'edit',
DELETE = 'delete',
ASSIGN_PERMISSION = 'assign_permission',
}
export function getColumns(callback: (type: TableOptions, record: any) => Promise<void>): TableColumnProps[] {
return [
{
title: '角色id',
dataIndex: 'id',
render: (value) => <Text copyable>{value}</Text>,
align: 'center',
width: '20%',
},
{
title: '角色名称',
dataIndex: 'name',
align: 'center',
width: '20%',
},
{
title: '唯一编码',
dataIndex: 'code',
render: (value) => <Text copyable>{value}</Text>,
align: 'center',
width: '20%',
},
{
title: '创建时间',
dataIndex: 'createdAt',
width: '15%',
render: (value) => dayjs(value).format('YYYY-MM-DD HH:mm:ss'),
},
{
title: '状态',
dataIndex: 'status',
width: '10%',
render: (x) => getDictValue(tableStatusDict, x)
},
{
title: '操作',
dataIndex: 'operations',
width: '20%',
align: 'center',
render: (_, record) => (
<Space>
<Button size='small' onClick={() => callback(TableOptions.EDIT, record)} type="text"
status="default"></Button>
<Button size='small' onClick={() => callback(TableOptions.ASSIGN_PERMISSION, record)} type="text"
status="default"></Button>
<Popconfirm
focusLock
title="删除数据"
content="确认删除该条数据吗?"
onOk={() => callback(TableOptions.DELETE, record)}
>
<Button size='small' type="text" status="danger"></Button>
</Popconfirm>
</Space>
),
}
]
}

View File

@@ -1,6 +1,7 @@
import React, {useEffect, useState} from 'react';
import {Modal, Form, Input, Message, Select} from '@arco-design/web-react';
import {createRole, updateRole} from '@/api/role';
import {statusDict} from "@/enum/dict";
interface Props {
record: { [key: string]: any } | null,
@@ -44,7 +45,6 @@ function FormComponent(props: Props) {
}, [visible]);
return (
<div>
<Modal
@@ -64,8 +64,8 @@ function FormComponent(props: Props) {
<Form.Item disabled={record?.id} label="角色编码" field="code" rules={[{required: true}]}>
<Input placeholder="请输入角色编码"/>
</Form.Item>
<Form.Item label="状态" field="status" rules={[{ required: true }]}>
<Select placeholder="请选择" options={[{ label: '启用', value: 1 }, { label: '禁用', value: 0 }]} />
<Form.Item label="状态" field="status" rules={[{required: true}]} initialValue={1}>
<Select placeholder="请选择" options={statusDict}/>
</Form.Item>
</Form>
</Modal>

View File

@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Modal, Form, Input, Message, Tree, Checkbox } from '@arco-design/web-react';
import { Modal, Form, Input, Message, Tree } from '@arco-design/web-react';
import { getTreeMenu } from '@/api/menu';
import { getRoleMenuIds, grantPermission } from '@/api/permission';

View File

@@ -1,86 +1,31 @@
import React, { useState } from 'react';
import React, {useEffect, useState} from 'react';
import {
Card,
Table,
Typography,
TableColumnProps,
PaginationProps,
Button,
Popconfirm,
Divider,
Space,
Message, Badge
Card,
Message,
PaginationProps,
Table,
TableColumnProps,
Typography
} from '@arco-design/web-react';
import {useHistory} from "react-router";
import {useQuery} from 'react-query';
import Form from './form';
import { deleteRole, getRole } from '@/api/role';
import GrantPerm from './grantPerm';
import {IconPlus} from '@arco-design/web-react/icon';
import {getColumns, TableOptions} from './constants';
import {getRole,deleteRole} from "@/api/role";
import GrantRolesForm from "./grantPerm";
import SearchForm from "./searchForm";
const { Title, Text } = Typography;
function ConfigManage() {
const {Title} = Typography;
function UserManage() {
const reactQueryKey = useHistory().location.pathname
const [visible, setVisible] = useState(false);
const [visibleAssignRoles, setVisibleAssignRoles] = useState(false);
const [record, setRecord] = useState(null);
const [visibleGrantPerm, setVisibleGrantPerm] = useState(null);
const columns: TableColumnProps[] = [
{
title: '角色id',
dataIndex: 'id',
render: (value) => <Text copyable>{value}</Text>,
align: 'center',
width: '20%',
},
{
title: '角色名称',
dataIndex: 'name',
align: 'center',
width: '20%',
},
{
title: '唯一编码',
dataIndex: 'code',
render: (value) => <Text copyable>{value}</Text>,
align: 'center',
width: '20%',
},
{
title: '状态',
dataIndex: 'status',
align: 'center',
width: '20%',
render: (x) => {
if (x === 0) {
return <Badge status="error" text="禁用中"></Badge>;
}
return <Badge status="success" text="启用中"></Badge>;
}
},
{
title: '操作',
dataIndex: 'operations',
width: '20%',
render: (_, record) => (
<>
<Button onClick={() => showModal(record)} type="text" status="default"></Button>
<Divider type="vertical" />
<Button onClick={() => showGrantPerm(record)} type="text" status="default"></Button>
<Divider type="vertical" />
<Popconfirm
focusLock
title="删除数据"
content="确认删除该条数据吗?"
onOk={() => onDelete(record)}
>
<Button type="text" status="danger"></Button>
</Popconfirm>
</>
),
align: 'center'
}
];
const [pagination, setPagination] = useState<PaginationProps>({
sizeCanChange: true,
showTotal: true,
@@ -90,70 +35,97 @@ function ConfigManage() {
total: 0
});
const onDelete = async ({ id }) => {
await deleteRole(id);
Message.success('删除成功!');
await refetch();
};
const [searchQuery, setSearchQuery] = useState<Record<string, any>>({
page: pagination.current,
pageSize: pagination.pageSize,
});
const onChangeTable = async ({ current, pageSize }) => {
setPagination({
...pagination,
current,
pageSize
});
const showAssignRolesModal = (payload) => {
setRecord(payload);
setVisibleAssignRoles(true);
};
const fetchData = async ({ queryKey }) => {
const [, { page, pageSize }] = queryKey;
const { data } = await getRole({ page, pageSize });
setPagination(prevState => {
prevState.total = data.count;
return prevState;
});
if (page > 1 && data.list.length === 0) {
setPagination({
...pagination,
current: page - 1
});
}
return data;
};
const {
data,
isLoading,
isFetching,
refetch
} = useQuery(
['role', { page: pagination.current, pageSize: pagination.pageSize }],
fetchData,
{
refetchOnWindowFocus: false,
keepPreviousData: true
});
const showModal = (payload?) => {
payload && setRecord(payload);
setVisible(true);
};
const showGrantPerm = (payload) => {
setRecord(payload);
setVisibleGrantPerm(true);
const onDelete = async ({id}) => {
await deleteRole(id);
Message.success('删除成功!');
await refetch();
};
const tableCallback = async (type: TableOptions, record: any) => {
switch (type) {
case TableOptions.EDIT:
showModal(record)
break;
case TableOptions.DELETE:
await onDelete(record);
break
case TableOptions.ASSIGN_PERMISSION:
showAssignRolesModal(record);
break
}
}
const columns: TableColumnProps[] = getColumns(tableCallback)
const handleSearch = async (params) => {
setSearchQuery(prev => ({...prev, page: 1, ...params}))
}
const onChangeTable = async ({current, pageSize}) => {
setSearchQuery(prev => ({...prev, page: current, pageSize}));
};
const fetchData = async ({queryKey}) => {
const [, params] = queryKey;
const {data} = await getRole(params);
setPagination(prev => ({
...prev,
total: data.count
}))
// 当前列表不存在数据回退1页
if (params.page > 1 && data.list.length === 0) {
setSearchQuery({
...searchQuery,
page: params.page - 1
});
}
return data;
};
const {data, isLoading, isFetching, refetch} = useQuery(
[reactQueryKey, {
page: pagination.current,
pageSize: pagination.pageSize,
...searchQuery
}],
fetchData);
const handleConfirm = async () => {
handleCancel()
setRecord(null);
setVisible(false);
setVisibleAssignRoles(false);
await refetch();
};
const handleCancel = () => {
setRecord(null);
setVisible(false);
setVisibleGrantPerm(false)
setVisibleAssignRoles(false);
};
useEffect(() => {
setPagination(prev => ({
...prev,
current: searchQuery.page,
pageSize: pagination.pageSize,
}))
}, [searchQuery])
return (
<>
<Card>
@@ -163,19 +135,24 @@ function ConfigManage() {
visible={visible}
record={record}
/>
<GrantPerm
<GrantRolesForm
handleConfirm={handleConfirm}
handleCancel={handleCancel}
visible={visibleGrantPerm}
visible={visibleAssignRoles}
record={record}
/>
<Title heading={6}></Title>
<Space style={{ marginBottom: 12 }}>
<Button type="primary" onClick={() => showModal()}></Button>
</Space>
<SearchForm onSearch={handleSearch}/>
<Button
style={{marginBottom: 12}}
type="primary"
icon={<IconPlus/>}
onClick={() => showModal()}
>
</Button>
<Table
rowKey="id"
@@ -191,4 +168,4 @@ function ConfigManage() {
}
export default ConfigManage;
export default UserManage;

View File

@@ -0,0 +1,75 @@
import React from 'react';
import {
Form,
Input,
Button,
Grid,
Space, Divider, Select
} from '@arco-design/web-react';
import {IconRefresh, IconSearch} from '@arco-design/web-react/icon';
import {statusDict} from "@/enum/dict";
const {Row, Col} = Grid;
const {useForm} = Form;
function SearchForm(props: {
onSearch: (values: Record<string, any>) => void;
}) {
const [form] = useForm();
const handleSubmit = () => {
const values = form.getFieldsValue();
props.onSearch(values);
};
const handleReset = () => {
form.resetFields();
props.onSearch({});
};
const colSpan = 6
return (
<>
<Form
form={form}
labelCol={{span: 6}}
wrapperCol={{span: 18}}
labelAlign="left"
>
<Row gutter={24}>
<Col span={colSpan}>
<Form.Item label="角色名称" field="name">
<Input placeholder="请输入" allowClear/>
</Form.Item>
</Col>
<Col span={colSpan}>
<Form.Item label="唯一编码" field="code">
<Input placeholder="请输入" allowClear/>
</Form.Item>
</Col>
<Col span={colSpan}>
<Form.Item label="状态" field="status">
<Select placeholder="请选择" options={statusDict} allowClear/>
</Form.Item>
</Col>
<Col span={colSpan}>
<Form.Item>
<Space>
<Button type="primary" icon={<IconSearch/>} onClick={handleSubmit}>
</Button>
<Button icon={<IconRefresh/>} onClick={handleReset}>
</Button>
</Space>
</Form.Item>
</Col>
</Row>
</Form>
<Divider style={{margin: '0 0 20px 0'}}/>
</>
);
}
export default SearchForm;

View File

@@ -1,15 +0,0 @@
.search-form-wrapper {
display: flex;
border-bottom: 1px solid var(--color-border-1);
margin-bottom: 20px;
.right-button {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20px;
margin-bottom: 20px;
border-left: 1px solid var(--color-border-2);
box-sizing: border-box;
}
}

View File

@@ -19,8 +19,6 @@ export const enum TableOptions {
ASSIGN_ROLE = 'assign_role',
}
export const reactQueryKey = 'user'
export function getColumns(callback: (type: TableOptions, record: any) => Promise<void>): TableColumnProps[] {
return [
{

View File

@@ -14,11 +14,13 @@ import GrantRolesForm from './grantRoles';
import {deleteUser, getUsers} from '@/api/user';
import SearchForm from "./searchForm";
import {IconPlus} from '@arco-design/web-react/icon';
import {getColumns, TableOptions, reactQueryKey} from './constants';
import {getColumns, TableOptions} from './constants';
import {useHistory} from "react-router";
const {Title} = Typography;
function UserManage() {
const reactQueryKey = useHistory().location.pathname;
const [visible, setVisible] = useState(false);
const [visibleAssignRoles, setVisibleAssignRoles] = useState(false);
const [record, setRecord] = useState(null);
@@ -78,7 +80,6 @@ function UserManage() {
const fetchData = async ({queryKey}) => {
const [, params] = queryKey;
console.log(params)
const {data} = await getUsers(params);
setPagination(prev => ({
...prev,

View File

@@ -33,8 +33,8 @@ function SearchForm(props: {
<>
<Form
form={form}
labelCol={{span: 5}}
wrapperCol={{span: 19}}
labelCol={{span: 6}}
wrapperCol={{span: 18}}
labelAlign="left"
>
<Row gutter={24}>

View File

@@ -32,7 +32,8 @@ export class ConfigService {
await this.prisma.sysConfig.create({ data });
}
async findAll({ page, pageSize }: QueryListDto): Promise<QueryListResult> {
async findAll(dto: QueryListDto): Promise<QueryListResult> {
const { page, pageSize, key, value } = dto;
const query: Prisma.SysConfigFindManyArgs = {
select: {
key: true,
@@ -41,6 +42,10 @@ export class ConfigService {
},
skip: pageSize * (page - 1),
take: pageSize,
where: {
...(key && { key: { contains: key } }),
...(value && { value: { contains: value } }),
},
};
const [list, count] = await this.prisma.$transaction([

View File

@@ -1,3 +1,10 @@
import { PaginationDto } from 'src/common/dto/pagination.dto';
import { IsOptional } from 'class-validator';
export class QueryListDto extends PaginationDto {}
export class QueryListDto extends PaginationDto {
@IsOptional()
key?: string;
@IsOptional()
value?: string;
}

View File

@@ -1,3 +1,16 @@
import { PaginationDto } from 'src/common/dto/pagination.dto';
import { IsInt, IsOptional } from 'class-validator';
import { Type } from 'class-transformer';
export class QueryListDto extends PaginationDto {}
export class QueryListDto extends PaginationDto {
@IsOptional()
code?: string;
@IsOptional()
name?: string;
@IsOptional()
@Type(() => Number)
@IsInt()
status?: number;
}

View File

@@ -25,15 +25,15 @@ export class RoleService {
await this.prisma.sysRole.create({ data });
}
async findPage({ page, pageSize }: QueryListDto): Promise<QueryListResult> {
async findPage(dto: QueryListDto): Promise<QueryListResult> {
const { page, pageSize, code, status, name } = dto;
const query: Prisma.SysRoleFindManyArgs = {
skip: pageSize * (page - 1),
take: pageSize,
select: {
id: true,
name: true,
code: true,
status: true,
where: {
...(code && { code: { contains: code } }),
...(!isNaN(status) && { status }),
...(name && { name: { contains: name } }),
},
};
const [list, count] = await this.prisma.$transaction([