Skip to content

新增功能示例

前提

数据表已经提前建好,本示例使用user表,包含增、删、改、查,比如字段如下

name > 姓名

tel > 手机号

age > 年龄

sex > 性别,1》男,2》女

create_time > 新增时间

update_time > 更新时间

后端操作

1、新建后端验证器

文件目录:app\common\validate\UserValidate.php

查看代码
php
<?php
namespace app\common\validate;

use taoser\Validate;

/**
 * 用户 验证器
 * */
class UserValidate extends Validate
{

    // 验证规则
    protected $rule = [
        'name|姓名' => 'require',
        'tel|手机号' => 'require|mobile',
    ];

}

2、新建后端模型

文件目录:app\common\model\UserModel.php

查看代码
php
<?php
namespace app\common\model;

/**
 * 用户 模型
 * */
class UserModel extends BaseModel
{

    // 表名
    protected $name = 'admin_user';

    // 自动时间戳
    protected $autoWriteTimestamp = true;

    // 姓名 搜索器
    public function searchNameAttr($query, $value, $data)
    {
        ($value != null) && $query->where('name', 'like', "%{$value}%");
    }

    // 手机号 搜索器
    public function searchTelAttr($query, $value, $data)
    {
        ($value != null) && $query->where('tel', 'like', "%{$value}%");
    }

    // 新增时间 搜索器
    public function searchCreateTimeAttr($query, $value, $data)
    {
        ($value && is_array($value)) && $query->where('create_time', 'between', ["{$value[0]} 00:00:00", "{$value[1]} 23:59:59"]);
    }
}

3、新建后端逻辑

文件目录:app\common\logic\UserLogic.php

查看代码
php
<?php
namespace app\common\logic;

use app\common\model\UserModel;
use app\common\validate\UserValidate;
use think\facade\Db;

/**
 * 用户 逻辑层
 * */
class UserLogic
{

    /**
     * 列表
     * @param array $params get参数
     * @param bool $page 是否需要翻页
     * */
    public static function getList(array $params = [], bool $page = true)
    {
        $list = UserModel::withSearch(['name', 'tel', 'create_time'], $params)
        ->order('id desc');

        return $page ? $list->paginate($params['pageSize'] ?? 20) : $list->select();
    }

    /**
     * 新增
     * @param array $params
     */
    public static function create(array $params)
    {
        Db::startTrans();
        try {
            validate(UserValidate::class)->check($params);

            UserModel::create($params);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            abort($e->getMessage());
        }
    }

    /**
     * 获取数据
     * @param int $id 数据id
     */
    public static function findData(int $id)
    {
        return UserModel::find($id);
    }

    /**
     * 更新
     * @param array $params
     */
    public static function update(array $params)
    {
        Db::startTrans();
        try {
            validate(UserValidate::class)->check($params);

            UserModel::update($params);
            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();
            abort($e->getMessage());
        }
    }

    /**
     * 删除
     * @param int|array $id 要删除的id
     */
    public static function delete(int|array $id)
    {
        UserModel::destroy($id);
    }
}

4、新建后端控制器

文件目录:app\admin\controller\User.php

查看代码
php
<?php
namespace app\admin\controller;

use support\Request;
use support\Response;
use app\common\logic\UserLogic;

/**
 * 用户 控制器
 * */
class User
{

    // 此控制器是否需要登录
    protected $onLogin = true;
    
    // 不需要登录的方法
    protected $noNeedLogin = [];


    /**
     * 列表
     * @method get
     * @param Request $request 
     * @return Response
     */
    public function getList(Request $request): Response
    {
        $list = UserLogic::getList($request->get());
        return success($list);
    }

    /**
     * @log 新增用户
     * @method post
     * @param Request $request 
     * @return Response
     */
    public function create(Request $request): Response
    {
        UserLogic::create($request->post());
        return success([], '添加成功');
    }

    /**
     * 获取数据
     * @method get
     * @param int $id 
     * @return Response
     */
    public function findData(int $id): Response
    {
        $data = UserLogic::findData($id);
        return success($data);
    }

    /**
     * @log 修改用户
     * @method post
     * @param Request $request 
     * @return Response
     */
    public function update(Request $request): Response
    {
        UserLogic::update($request->post());
        return success([], '修改成功');
    }

    /**
     * @log 删除用户
     * @method post
     * @param Request $request 
     * @return Response
     */
    public function delete(Request $request ): Response
    {
        UserLogic::delete($request->post('id'));
        return success([], '删除成功');
    }
}

前端操作

1、新建后台菜单、权限节点等

新建后台的菜单、按钮权限节点等,登录后台访问:系统管理》权限节点》新建,具体如何新建参考权限节点

2、新建前端api文件

文件目录:public\admin_react\src\api\user.js

查看代码
js
import { http } from '@/common/axios.js'

/**
 * 用户 API
 * */
export const userApi = {
    //列表
    getList: (params = {}) => {
        return http.get('/admin/User/getList',params);
    },
    //新增
    create: (params = {}) => {
        return http.post('/admin/User/create',params);
    },
    //获取数据
    findData: (params = {}) => {
        return http.get('/admin/User/findData',params);
    },
    //更新
    update: (params = {}) => {
        return http.post('/admin/User/update',params);
    },
    //删除
    delete: (params = {}) => {
        return http.post('/admin/User/delete',params);
    }, 
}

3、新建前端列表页面

文件目录:public\admin_react\src\pages\user\index.jsx

查看代码
js
import { useRef, lazy, useState } from 'react';
import { PageContainer } from '@ant-design/pro-components';
import { userApi } from '@/api/user';
import { ProTable } from '@ant-design/pro-components';
import { App, Button, Popconfirm, Space, Tooltip } from 'antd';
import { config } from '@/common/config';
import { NavLink } from 'react-router-dom';
import { authCheck} from '@/common/function';
import Lazyload from '@/component/lazyLoad/index';

const Create = lazy(() => import('./create'));
const Update = lazy(() => import('./update'));

/**
 * 用户 
 * */
export default () => {
    const { message } = App.useApp();
    const tableRef = useRef();
    const formRef = useRef();

    //刷新表格数据
    const tableReload = () => {
        tableRef.current.reload();
        tableRef.current.clearSelected();
    }

    //要修改的数据
    const [updateId, setUpdateId] = useState(0);    

    /////////////////删除//////////////
    const del = (id) => {
        userApi.delete({
            id
        }).then(res => {
            if (res.code === 1) {
                message.success(res.message)
                tableReload();
            } else {
                message.error(res.message)
            }
        })
    }

    //表格列
    const columns = [
        {
            title: '姓名',
            dataIndex: 'name',
            search: true,
            valueType : 'text',
            render: (_, record) => _,
        },
        {
            title: '手机号',
            dataIndex: 'tel',
            search: true,
            valueType : 'text',
            render: (_, record) => _,
        },
        {
            title: '年龄',
            dataIndex: 'age',
            search: false,
            render: (_, record) => _,
        },
        {
            title: '性别',
            dataIndex: 'age',
            search: true,
            valueType : 'select',
            fieldProps: {
                showSearch: true,
                options: [
                    {
                        value: 1,
                        label: '男',
                    },
                    {
                        value: 2,
                        label: '女',
                    },
                ]
            },
            render: (_, record) => record?.sex == 1 ? '男' : '女',
        },
        {
            title: 'create_time',
            dataIndex: 'create_time',
            search: true,
            valueType : 'dateRange',
            render: (_, record) => record.create_time,
        },

        {
            title: '操作',
            dataIndex: 'action',
            search: false,
            render: (_, record) => {
                return <>
                    <Button
                        type="link"
                        size="small"
                        onClick={() => { 
                            setUpdateId(record.id) 
                        }}
                        disabled={authCheck('userUpdate')}
                    >修改</Button>
                    <Popconfirm
                        title="确认要删除吗?"
                        onConfirm={() => { 
                            del(record.id);
                        }}
                        disabled={authCheck('userDelete')}
                    >
                        <Button
                            type="link"
                            size="small"
                            danger
                            disabled={authCheck('userDelete')}
                        >删除</Button>
                    </Popconfirm>
                </>
            },
        },        
    ];
    return (
        <>
            {/* 修改表单 */}
            <Lazyload block={false}>
                <Update
                    tableReload={tableReload}
                    updateId={updateId}
                    setUpdateId={setUpdateId}
                />
            </Lazyload>
            <PageContainer
                className="sa-page-container"
                ghost
                header={{
                    title: '用户管理',
                    style: { padding: '0px 24px 12px' },
                }}
            >
                <ProTable
                    actionRef={tableRef}
                    formRef={formRef}
                    rowKey="id"
                    columns={columns}
                    scroll={{
                        x: 1000
                    }}
                    options={{
                        fullScreen: true
                    }}
                    columnsState={{
                        //此table列设置后存储本地的唯一key
                        persistenceKey: 'table_column_' + 'User', 
                        persistenceType: 'localStorage'
                    }}
                    headerTitle={
                        <Space>
                            <Lazyload block={false}>
                                <Create tableReload={tableReload} />
                            </Lazyload>
                        </Space>
                    }
                    pagination={{
                        defaultPageSize: 10,
                        size: 'default',
                        //支持跳到多少页
                        showQuickJumper: true,
                        showSizeChanger: true,
                        responsive: true,
                    }}
                    request={async (params = {}, sort, filter) => {
                        //排序的时候
                        let orderBy = '';
                        for (let key in sort) {
                            orderBy = key + ' ' + (sort[key] === 'descend' ? 'desc' : 'asc');
                        }
                        const result = await userApi.getList({
                            ...params,//包含了翻页参数跟搜索参数
                            orderBy, //排序
                            page: params.current,
                        });
                        return {
                            data: result.data.data,
                            success: true,
                            total: result.data.total,
                        };
                    }}
                />
            </PageContainer>
        </>
    )
}

4、新建前端新增、修改弹窗

添加页面:文件目录:public\admin_react\src\pages\user\create\index.jsx

查看代码
js
import { useRef, lazy } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import {
    ModalForm,
} from '@ant-design/pro-components';
import { userApi } from '@/api/user';
import { Button, App } from 'antd';
import { authCheck } from '@/common/function';
import Lazyload from '@/component/lazyLoad/index';

const Form1 = lazy(() => import('./../component/form1'));

/**
 * 用户 新增
 * */
export default ({ tableReload, ...props }) => {
    const formRef = useRef();
    const { message } = App.useApp();
    return (
        <ModalForm
            name="createUser"
            formRef={formRef}
            title="添加用户"
            trigger={
                <Button 
                    type="primary" 
                    disabled={authCheck('userCreate')} 
                    icon={<PlusOutlined />}
                >添加用户</Button>
            }
            width={400}
            //第一个输入框获取焦点
            autoFocusFirstInput={true}
            //可以回车提交
            isKeyPressSubmit={true}
            omitNil={false}
            onFinish={async (values) => {
                const result = await userApi.create(values);
                if (result.code === 1) {
                    tableReload?.();
                    message.success(result.message)
                    formRef.current?.resetFields?.()
                    return true;
                } else {
                    message.error(result.message)
                }
            }}
        >
            <Lazyload height={50}>
                <Form1 typeAction="create" />
            </Lazyload>
        </ModalForm>
    );
};

修改页面:文件目录:public\admin_react\src\pages\user\update\index.jsx

查看代码
js
import { useRef, useState, lazy } from 'react';
import {
    ModalForm,
} from '@ant-design/pro-components';
import { userApi } from '@/api/user';
import { App } from 'antd';
import { useUpdateEffect } from 'ahooks';
import Lazyload from '@/component/lazyLoad/index';

const Form1 = lazy(() => import('./../component/form1'));

/**
 * 用户 修改
 * */
export default ({ tableReload, updateId, setUpdateId, ...props }) => {
    const formRef = useRef();
    const { message } = App.useApp();
    const [open, setOpen] = useState(false);

    useUpdateEffect(() => {
        if (updateId > 0) {
            setOpen(true);
        }
    }, [updateId])

    return (
        <ModalForm
            name="updateUser"
            formRef={formRef}
            open={open}
            onOpenChange={(_boolean) => {
                setOpen(_boolean);
                //关闭的时候干掉updateId,不然无法重复修改同一条数据
                if (_boolean === false) {
                    setUpdateId(0);
                }
            }}
            title="修改用户"
            width={400}
            //第一个输入框获取焦点
            autoFocusFirstInput={true}
            //可以回车提交
            isKeyPressSubmit={true}
            omitNil={false}
            modalProps={{
                destroyOnClose: true,
            }}
            params={{
                id: updateId
            }}
            request={async (params) => {
                const result = await userApi.findData(params);
                if (result.code === 1) {
                    return result.data;
                } else {
                    message.error(result.message);
                    setOpen(false);
                }
            }}
            onFinish={async (values) => {
                const result = await userApi.update({
                    id: updateId,
                    ...values
                });
                if (result.code === 1) {
                    tableReload?.();
                    message.success(result.message)
                    formRef.current?.resetFields?.()
                    return true;
                } else {
                    message.error(result.message)
                }
            }}
        >
            <Lazyload height={50}>
                <Form1 typeAction='update' />
            </Lazyload>
        </ModalForm>
    );
};

添加修改共用的form里面的字段组件:文件目录:public\admin_react\src\pages\user\component\form1.jsx

查看代码
js
import { lazy } from 'react';
import { ProForm, ProFormText, ProFormDigit, ProFormRadio, } from '@ant-design/pro-components';
import {Row, Col} from 'antd';

/**
 * 用户 添加修改的form字段
 * 
 * @param {string} typeAction create》添加,update》修改
 * */
export default ({typeAction, ...props}) => {

    return <>
        <Row gutter={[24, 0]}>
            <Col xs={24} sm={24} md={24} lg={24} xl={24} xxl={24}>
                <ProFormText
                    name="name"
                    label="姓名"
                    placeholder="请输入"
                    rules={[
                        { required: true, message: '请输入' },
                    ]}
                />
            </Col>    
            <Col xs={24} sm={24} md={24} lg={24} xl={24} xxl={24}>
                <ProFormDigit
                    name="tel"
                    label="手机号"
                    placeholder="请输入"
                    fieldProps={{
                        precision: 0,
                        style: {width: '100%'},
                    }}
                    rules={[
                        { required: true, message: '请输入' },
                        { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号' },
                    ]}
                />
            </Col>    
            <Col xs={24} sm={24} md={24} lg={24} xl={24} xxl={24}>
                <ProFormDigit
                    name="age"
                    label="年龄"
                    placeholder="请输入"
                    fieldProps={{
                        precision: 0,
                        style: {width: '100%'},
                    }}
                    min={0}
                    rules={[
                        { required: true, message: '请输入' },
                        { type: 'number', min: 1, message: '最小为:1' },
                        { type: 'number', max: 100, message: '最大为:100' },
                    ]}
                />
            </Col>    
            <Col xs={24} sm={24} md={24} lg={24} xl={24} xxl={24}>
                <ProFormRadio.Group  
                    name="age"
                    label="性别"
                    placeholder="请选择"
                    options={[
                        { label: '男', value: 1},
                        { label: '女', value: 2},
                    ]}
                    extra=""
                    rules={[
                        { required: true, message: '请选择' },
                    ]}
                />
            </Col>
        </Row>
    </>
}

感觉很麻烦?

去试下代码生成,可以生成所有的文件并自动生成到目录里面:代码生成器