前言

适用于自己使用php+uniapp全栈开发项目的码农


一、使用crud创建数据库

在这里插入图片描述
创建数据表的时候勾选公共模型,放到common目录

二、封装前台crud基类

新建 app/api/controller/FrontendCrudBase.php

<?php
namespace app\api\controller;

use Throwable;
use think\Model;
use app\common\controller\Frontend;
use think\Validate;

abstract class FrontendCrudBase extends Frontend
{
    // 列表和详情默认公开;如需登录可在子类重写 
    protected array $noNeedLogin = ['index', 'read'];
    // uniapp 常用场景:只校验登录,不走 user_rule 节点权限 
    protected array $noNeedPermission = ['*'];
    // 子类必须赋值 
    protected Model $model;
    // 子类可重写 
    protected array $systemFields = ['id', 'create_time', 'update_time', 'delete_time'];
    protected string $defaultOrder = 'id desc';
    // 子类可返回验证器实例;不需要验证可返回 null 
    protected function getValidator(): ?Validate
    {
        return null;
    }
    public function index(): void
    {
        $limit = $this->request->get('limit/d', 10);
        $page = $this->request->get('page/d', 1);
        $keyword = trim($this->request->get('keyword/s', ''));
        $order = $this->request->get('order/s', $this->defaultOrder);
        $fields = $this->getTableFields();
        $query = $this->model->order($order);
        if ($keyword !== '') {
            $searchFields = array_values(array_filter($fields, function ($field) {
                return !in_array($field, ['id', 'create_time', 'update_time', 'delete_time'], true);
            }));
            if ($searchFields) {
                $query->where(function ($subQuery) use ($searchFields, $keyword) {
                    foreach ($searchFields as $field) {
                        $subQuery->whereOr($field, 'like', '%' . $keyword . '%');
                    }
                });
            }
        }
        $result = $query->paginate(['list_rows' => $limit, 'page' => $page,]);
        $this->success('', ['list' => $result->items(), 'total' => $result->total(), 'page' => $page, 'limit' => $limit, 'editableFields' => $this->getEditableFields(),]);
    }
    public function read(): void
    {
        $id = $this->request->get('id/d', 0);
        $row = $this->model->find($id);
        if (!$row) {
            $this->error(__('Record not found'));
        }
        $this->success('', ['row' => $row, 'editableFields' => $this->getEditableFields(),]);
    }
    public function add(): void
    {
        if (!$this->request->isPost()) {
            $this->error(__('Parameter error'));
        }
        $data = $this->getWriteData();
        if (!$data) {
            $this->error(__('Parameter %s can not be empty', ['']));
        }
        $this->model->startTrans();
        try {
            $validate = $this->getValidator();
            if ($validate) {
                $validate->scene('add')->check($data);
            }
            $this->beforeAdd($data);
            $this->model->save($data);
            $this->afterAdd($this->model);
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            $this->error($e->getMessage());
        }
        $this->success(__('Added successfully'), ['id' => $this->model->id,]);
    }
    public function edit(): void
    {
        if (!$this->request->isPost()) {
            $this->error(__('Parameter error'));
        }
        $id = $this->request->post('id/d', 0);
        $row = $this->model->find($id);
        if (!$row) {
            $this->error(__('Record not found'));
        }
        $data = $this->getWriteData();
        if (!$data) {
            $this->error(__('No rows updated'));
        }
        $this->model->startTrans();
        try {
            $validate = $this->getValidator();
            if ($validate) {
                $validate->scene('edit')->check(array_merge($data, ['id' => $id]));
            }
            $this->beforeEdit($row, $data);
            $row->save($data);
            $this->afterEdit($row);
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            $this->error($e->getMessage());
        }
        $this->success(__('Update successful'));
    }
    public function del(): void
    {
        if (!$this->request->isPost()) {
            $this->error(__('Parameter error'));
        }
        $ids = $this->request->post('ids/a', []);
        if (!$ids) {
            $id = $this->request->post('id/d', 0);
            if ($id) {
                $ids = [$id];
            }
        }
        if (!$ids) {
            $this->error(__('Parameter error'));
        }
        $rows = $this->model->whereIn($this->model->getPk(), $ids)->select();
        if ($rows->isEmpty()) {
            $this->error(__('Record not found'));
        }
        $count = 0;
        $this->model->startTrans();
        try {
            foreach ($rows as $row) {
                $this->beforeDelete($row);
                $count += $row->delete();
                $this->afterDelete($row);
            }
            $this->model->commit();
        } catch (Throwable $e) {
            $this->model->rollback();
            $this->error($e->getMessage());
        }
        if (!$count) {
            $this->error(__('No rows were deleted'));
        }
        $this->success(__('Deleted successfully'));
    }
    protected function getTableFields(): array
    {
        return $this->model->db()->getTableFields();
    }
    protected function getEditableFields(): array
    {
        return array_values(array_diff($this->getTableFields(), $this->systemFields));
    }
    protected function getWriteData(): array
    {
        $params = $this->request->post();
        $data = [];
        foreach ($this->getEditableFields() as $field) {
            if (array_key_exists($field, $params)) {
                $data[$field] = $params[$field];
            }
        }
        return $data;
    }
    // 扩展钩子:子类按需重写 
    protected function beforeAdd(array &$data): void {}
    protected function afterAdd(Model $row): void {}
    protected function beforeEdit(Model $row, array &$data): void {}
    protected function afterEdit(Model $row): void {}
    protected function beforeDelete(Model $row): void {}
    protected function afterDelete(Model $row): void {}
}

三、控制器使用

<?php 
namespace app\api\controller; 
class Test extends FrontendCrudBase
{
    // 无需登录的方法,同时也可以在表中设置哪些方法需要登录
    protected array $noNeedLogin = ['index', 'read'];
    // 或者 [] 全部要求登录 
    public function initialize(): void
    {
        parent::initialize();
        $this->model = new \app\common\model\Test();
    }
    protected function getValidator(): ?\think\Validate
    {
        return new \app\common\validate\Test();
    }
}

例如test表,创建一个test的控制器,继承刚才封装的基类,然后在uniapp中就可以使用接口:

  1. GET /api/test/index
  2. GET /api/test/read?id=1
  3. POST /api/test/add
  4. POST /api/test/edit
  5. POST /api/test/del

记住

不要忘了前端接口调用时需要在header中添加server和ba-user-token,ba-user-token是api应用调用的(前台),ba-token是admin应用调用的(后台)


Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐