上一章我们完成了整个用户管理模块的功能,能够正确的增、删、改、查用户。但其中有很多判断实际上是其他类似的模块也会有的,例如:
难道我们每写一个类似的模块,都要去写一遍这些重复的逻辑代码吗?
显然是没必要的,所以我们需要将其抽离成公共列表组件提供给其他模块使用,避免大量的做重复的事情,并让代码更容易维护。本章还将完成用例项目管理功能,它主要用于管理不同类型(API、UI),不同项目、项目状态等。
由于博主本身也才开始使用ts,很多类型都是用any
来定义的,后续会逐渐完善。
项目在线演示地址:http://121.43.43.59/ (帐号:admin 密码:123456)
实现效果如下:
在src/components
下创建ComTable
文件夹,并在其下创建index.tsx
文件,它的代码如下:
import React, { useImperativeHandle, useRef, useState } from 'react';
import ProTable from '@ant-design/pro-table';
import { Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import { reqList, reqDelete } from '@/globalEnum';
interface ActionType {
reload: () => void;
fetchMore: () => void;
reset: () => void;
}
const Table: React.FC<any> = ({
actionRef,
func,
headerTitle,
showModal,
columns,
}) => {
const ref = useRef<ActionType | any>();
const [params, setParams] = useState<any>({ page: 1, page_size: 10 }); //默认请求第一页,10条数据
const [dataLength, setDataLength] = useState<number>(0); //列表返回数据的长度(行数)
const handlePagination: any = {
pageSize: params.page_size,
showSizeChanger: false,
page: params.page,
onChange: (current: number, size: number) => {
setParams({ page: current, page_size: size });
},
};
useImperativeHandle(actionRef, () => ({
tableRef: ref,
comDeleteData: (func: any, record_id: any) => {
func(record_id, reqDelete).then((res: any) => {
if (params.page > 1 && dataLength <= 1) {
//在非首页的最后一条数据被删除时,改变页码为前一页进行请求
setParams({ ...params, ...{ page: params.page - 1 } });
}
ref.current.reload();
});
}
}));
return (
<ProTable
actionRef={ref}
columns={columns}
scroll={{ y: 'calc(100vh - 300px)' }}
request={(...tableParams) => {
var filters: object = tableParams[2];
for (let key in filters) {
//删除查询条件为空的
if (!filters[key]) {
delete filters[key];
}
}
setParams({ ...params, ...filters });
return func({ ...params, ...filters }, reqList).then((res: any) => {
setDataLength(res.data.length);
return res;
});
}}
rowKey="id"
pagination={handlePagination}
size="middle"
headerTitle={< h3 style={{ fontWeight: 'bold' }}> {headerTitle}</h3 >}
search={false}
toolBarRender={() => [
<Button
type="primary"
icon={<PlusOutlined />}
onClick={() => showModal('create')}
>
新建
</Button>,
]}
dateFormatter="string"
/>
);
};
export default React.memo<any>(Table);
这里只是简单封装,可以根据自己的需求进行diy
公共Table完成后,可以将我们之前用户模块代码进行接入,完整代码如下:
import React, { useState, useEffect, useRef } from 'react';
import { ProColumns } from '@ant-design/pro-table';
import { message } from 'antd';
import { reqCreate, reqUpdate } from '@/globalEnum';
import { UserAll } from '@/services/users';
import Form from './form';
import ComTable from '@/components/ComTable';
const User: React.FC = () => {
const ref = useRef<any>();
const [tableRef, setTableRef] = useState<any>({});
const [formData, setFormData] = useState<any>({}); //传递给弹窗显示的数据
const [formVisible, setFormVisible] = useState<boolean>(false); //控制弹窗显示还是隐藏
useEffect(() => {
setTableRef(ref.current.tableRef)
}, []);
const columns: ProColumns[] = [
{
title: '姓名',
dataIndex: 'name',
key: 'name',
width: 100,
render: (v: any, record: any) => (
<span>{`${record.last_name}${record.first_name}`}</span>
),
},
{
title: '用户名',
key: 'username',
width: 100,
dataIndex: 'username',
},
{
title: '邮箱地址',
key: 'email',
dataIndex: 'email',
width: 200,
},
{
title: '加入时间',
key: 'date_joined',
dataIndex: 'date_joined',
width: 200,
valueType: 'dateTime',
},
{
title: '状态',
dataIndex: 'is_active',
width: 100,
filters: true,
filterMultiple: false,
valueEnum: {
true: { text: '启用', status: 'Success' },
false: { text: '禁用', status: 'Error' },
},
},
{
title: '操作',
key: 'option',
dataIndex: 'option',
width: 120,
valueType: 'option',
render: (v: any, record: any) => [
<a key={record.id} onClick={() => showModal('update', record)}>
修改
</a>,
<a
key={record.id}
onClick={() => { ref.current.comDeleteData(UserAll, record.id) }}
>
删除
</a>,
],
},
];
//点击新建/修改,执行的代码
const showModal = (type: string, values = {}) => {
values['formType'] = type;
setFormData(values);
setFormVisible(true);
};
// 弹窗点确认按钮执行的方法
const onFormFinish = async (values: any, formType: string) => {
var reqType: string;
if (formType === 'create') {
reqType = reqCreate;
} else {
reqType = reqUpdate;
values.id = formData.id;
}
return await UserAll(values, reqType).then((res) => {
message.success('操作成功!');
setFormVisible(false);
formType === 'create' ? tableRef.current.reloadAndRest() : tableRef.current.reload();
});
};
return (
<>
<Form
formData={formData}
onFinish={(values: object, formType: string) =>
onFormFinish(values, formType)
}
cancel={() => setFormVisible(false)}
visible={formVisible}
/>
<ComTable
actionRef={ref}
columns={columns}
func={UserAll}
showModal={showModal}
headerTitle="用户列表"
/>
</>
);
};
export default React.memo(User);
首先在代码项目下执行创建项目模块的命令:
django-admin startapp project
为了让后面创建的表都有创建时间
、结束时间
这两个字段,需要先在comFunc
文件夹中创建一个comModel.py
的文件,用于放置公共的数据库模型,这样需要拥有公共模型字段的模型继承公共模型即可。
拥有创建时间
、结束时间
的公共模型代码如下:
from django.db import models
class ComModel(models.Model):
""" 公共模型 """
created = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
updated = models.DateTimeField(auto_now=True, verbose_name='修改时间', null=True, blank=True)
class Meta:
abstract = True
然后在model.py
中添加项目的数据库模型代码:
from django.db import models
from comFunc.comModel import ComModel
class Project(ComModel):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32, verbose_name="项目名称")
remark = models.TextField(blank=True, null=True, verbose_name="备注")
status = models.IntegerField(verbose_name="项目状态")
type = models.IntegerField(verbose_name="项目类型")
class Meta:
verbose_name = '项目表'
db_table = 'project'
再在settings.py
配置里的INSTALLED_APPS
中加入project
进行注册,然后执行模型迁移的命令即可:
python manage.py makemigrations
python manage.py migrate
这样我们就把项目模块的数据库表建立成功了,再按照user模块中的代码、代码结构并结合之前的教程进行代码开发即可。
1)在前端项目下,执行创建project
模块文件的命令:
npx umi g page project/index --typescript
2)在.umirc.ts
文件配置路由中加入project的跳转:
routes: [
...
{
name: '项目管理',
path: '/project',
icon: 'users',
component: '@/pages/project',
},
...
],
这样我们就把项目模块的基础页面建立好了,再按照user模块的代码并结合之前的教程进行代码开发即可,实现后的效果如下:
需要注意的是,在用例类型的筛选中,自定义了proTable的valueType实现,教程文档地址:自定义valueType
这一章主要涉及技术的教学只有一个公共列表组件的抽离和使用,其他都是重复的CURD了,所以只给了数据库表模型,没有直接贴代码。
需要源码的可以点击下方的演示地址进行获取:
在线演示地址:http://121.43.43.59/ (帐号:admin 密码:123456)
欢迎在文章头部右上角订阅本专栏,及时获取最新教程分享!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/momoda118/article/details/122059778
内容来源于网络,如有侵权,请联系作者删除!