buildAdmin 后端控制器的代码分析
buildAdmin的代码生成,很像是 fastadmin 的生成模式,当我们利用数据库生成了一个控制器的时候,我们可以看到, 它的生成代码很简洁
<?phpnamespace app\admin\controller\askanswer;use app\common\controller\Backend;/*** 回答管理*/
class Answer extends Backend //控制器继承了 backend
{/*** Answer模型对象* @var object* @phpstan-var \app\admin\model\Answer*///定义了一个 模型对象,也就是对应数据表的 模型protected object $model;//这里是在添加数据中 排除了一些,自动生成的字段, 在Backend中,有对这些字段的调用protected array|string $preExcludeFields = ['id', 'create_time', 'update_time'];//这里是设置了前端的快速搜索protected string|array $quickSearchField = ['id'];public function initialize(): void{parent::initialize(); //这里用了父类的 初始化方法, 做了一些 用户认证,权限判断,数据库连接检测等$this->model = new \app\admin\model\Answer;$this->request->filter('clean_xss'); //这里对 request 做了一次 xss 攻击的过滤}/*** 若需重写查看、编辑、删除等方法,请复制 @see \app\admin\library\traits\Backend 中对应的方法至此进行重写*/
}
接着我们来到,父类, backend

在追代码的过程中,我没有看到 跨域的操作, 因为fastadmin 在这里面是有跨域操作的一段代码的,后来经过 整块代码搜索, 才想起来, 这是tp8了, 是有中间键的,而fastadmin中是tp5.0,没有中间键的

真正的 增,删,改,查的代码 就在traits中
<?phpnamespace app\admin\library\traits;use Throwable;
use think\facade\Config;/*** 后台控制器trait类* 已导入到 @see \app\common\controller\Backend 中* 若需修改此类方法:请复制方法至对应控制器后进行重写*/
trait Backend
{/*** 排除入库字段* @param array $params* @return array*/protected function excludeFields(array $params): array{if (!is_array($this->preExcludeFields)) {$this->preExcludeFields = explode(',', (string)$this->preExcludeFields);}foreach ($this->preExcludeFields as $field) {if (array_key_exists($field, $params)) {unset($params[$field]);}}return $params;}/*** 查看* @throws Throwable*/public function index(): void{if ($this->request->param('select')) {$this->select();}list($where, $alias, $limit, $order) = $this->queryBuilder();$res = $this->model->field($this->indexField)->withJoin($this->withJoinTable, $this->withJoinType)->alias($alias)->where($where)->order($order)->paginate($limit);$this->success('', ['list' => $res->items(),'total' => $res->total(),'remark' => get_route_remark(),]);}/*** 添加*/public function add(): void{if ($this->request->isPost()) {$data = $this->request->post();if (!$data) {$this->error(__('Parameter %s can not be empty', ['']));}$data = $this->excludeFields($data);if ($this->dataLimit && $this->dataLimitFieldAutoFill) {$data[$this->dataLimitField] = $this->auth->id;}$result = false;$this->model->startTrans();try {// 模型验证if ($this->modelValidate) {$validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));if (class_exists($validate)) {$validate = new $validate;if ($this->modelSceneValidate) $validate->scene('add');$validate->check($data);}}$result = $this->model->save($data);$this->model->commit();} catch (Throwable $e) {$this->model->rollback();$this->error($e->getMessage());}if ($result !== false) {$this->success(__('Added successfully'));} else {$this->error(__('No rows were added'));}}$this->error(__('Parameter error'));}/*** 编辑* @throws Throwable*/public function edit(): void{$id = $this->request->param($this->model->getPk());$row = $this->model->find($id);if (!$row) {$this->error(__('Record not found'));}$dataLimitAdminIds = $this->getDataLimitAdminIds();if ($dataLimitAdminIds && !in_array($row[$this->dataLimitField], $dataLimitAdminIds)) {$this->error(__('You have no permission'));}if ($this->request->isPost()) {$data = $this->request->post();if (!$data) {$this->error(__('Parameter %s can not be empty', ['']));}$data = $this->excludeFields($data);$result = false;$this->model->startTrans();try {// 模型验证if ($this->modelValidate) {$validate = str_replace("\\model\\", "\\validate\\", get_class($this->model));if (class_exists($validate)) {$validate = new $validate;if ($this->modelSceneValidate) $validate->scene('edit');$validate->check($data);}}$result = $row->save($data);$this->model->commit();} catch (Throwable $e) {$this->model->rollback();$this->error($e->getMessage());}if ($result !== false) {$this->success(__('Update successful'));} else {$this->error(__('No rows updated'));}}$this->success('', ['row' => $row]);}/*** 删除* @param array $ids* @throws Throwable*/public function del(array $ids = []): void{if (!$this->request->isDelete() || !$ids) {$this->error(__('Parameter error'));}$where = [];$dataLimitAdminIds = $this->getDataLimitAdminIds();if ($dataLimitAdminIds) {$where[] = [$this->dataLimitField, 'in', $dataLimitAdminIds];}$pk = $this->model->getPk();$where[] = [$pk, 'in', $ids];$count = 0;$data = $this->model->where($where)->select();$this->model->startTrans();try {foreach ($data as $v) {$count += $v->delete();}$this->model->commit();} catch (Throwable $e) {$this->model->rollback();$this->error($e->getMessage());}if ($count) {$this->success(__('Deleted successfully'));} else {$this->error(__('No rows were deleted'));}}/*** 排序* @param int $id 排序主键值* @param int $targetId 排序位置主键值* @throws Throwable*/public function sortable(int $id, int $targetId): void{$dataLimitAdminIds = $this->getDataLimitAdminIds();if ($dataLimitAdminIds) {$this->model->where($this->dataLimitField, 'in', $dataLimitAdminIds);}$row = $this->model->find($id);$target = $this->model->find($targetId);if (!$row || !$target) {$this->error(__('Record not found'));}if ($row[$this->weighField] == $target[$this->weighField]) {$autoSortEqWeight = is_null($this->autoSortEqWeight) ? Config::get('buildadmin.auto_sort_eq_weight') : $this->autoSortEqWeight;if (!$autoSortEqWeight) {$this->error(__('Invalid collation because the weights of the two targets are equal'));}// 自动重新整理排序$all = $this->model->select();foreach ($all as $item) {$item[$this->weighField] = $item[$this->model->getPk()];$item->save();}unset($all);// 重新获取$row = $this->model->find($id);$target = $this->model->find($targetId);}$backup = $target[$this->weighField];$target[$this->weighField] = $row[$this->weighField];$row[$this->weighField] = $backup;$row->save();$target->save();$this->success();}/*** 加载为select(远程下拉选择框)数据,默认还是走$this->index()方法* 必要时请在对应控制器类中重写*/public function select(): void{}
}
相关文章:
buildAdmin 后端控制器的代码分析
buildAdmin的代码生成,很像是 fastadmin 的生成模式,当我们利用数据库生成了一个控制器的时候,我们可以看到, 它的生成代码很简洁 <?phpnamespace app\admin\controller\askanswer;use app\common\controller\Backend;/*** 回…...
Python丨让简历脱颖而出的关键,居然是“它”!
进入疫情后时代,各行各业都在力争新的发展!财会行业亦是如此,浏览各大招聘网站,不难发现财会相关岗位的招聘要求越来越“卷”,那求职者如何才能让自己获得面试邀请呢? 答案就是:一份亮眼且具有…...
CMake中常见的预定义变量
文章目录 CMake常见的预定义变量CMake variables官方文档 CMake常见的预定义变量 在 CMake 中,有一些常见的预定义变量,它们提供了有关项目、目录结构和构建环境的信息。这些变量可用于设置路径、传递参数、以及进行其他与构建过程相关的操作。 以下是…...
.netcore 获取appsettings
我的开发环境是abpvnext net6.0 。 因为业务需要,从原来老项目net4.5工程里复制了一个报表导出的业务类到net6项目里面,但是他的获取appsettings的代码其实不用想都知道会报错。因为原来framwork时代获取appsettings的方法常见的是 System.Configura…...
额温枪方案,MS8551,MS8601;MS1112,MS1100
鉴于测温的传感器信号非常微弱,需要用高精度、低噪声的运算放大器和高精度、低功耗的ADC。 运算放大器可供选择:MS8551 or MS8601,具有低失调(1uV)、低噪(22nV√Hz )、封装小等优点,…...
数字图像处理基础-用通俗语言进行超详细的总结
目录 图像感知与获取 韦伯定理 马赫带效应 图像获取 图像的采样和量化 图像内插(重采样) 图像的表示与描述 像素间的关系 exercise:4-邻域连通区域标记 本文章讲解数字图像处理的基础,大部分内容来源于课堂笔记中 图像感…...
3.3.1详解linux内核链表list_head及其接口应用
文章目录 1 list定义2 list接口2.1 list初始化方法1:定义并初始化链表方法2:先定义再初始化链表2.2 list_add2.3 list_del2.4 list_replace2.5 list_move2.6 list_splice3 list遍历3.1 list_entry3.2 list_first_entry3.3 list_last_entry3.4 list_first_entry_or_null3.5 li…...
发挥云计算潜力:Amazon Lightsail 与 Amazon EC2 的综述
文章作者:Libai 欢迎来到云计算世界,这里有无数的机会和无限的应用程序增长。 在当今的数字时代,企业可能会发现管理基础架构和扩展应用程序具有挑战性。 传统的本地解决方案需要大量的硬件、软件和维护前期投资。 要满足不断增长的需求&…...
【深度学习】卷积神经网络(CNN)
一、引子————边界检测 我们来看一个最简单的例子:“边界检测(edge detection)”,假设我们有这样的一张图片,大小88: 图片中的数字代表该位置的像素值,我们知道,像素值越大&#…...
科普:多领域分布式协同仿真
分布式协同仿真是一种在分布式计算环境中进行协同工作的仿真方法。使用该方法进行协同仿真时,仿真任务将被分发到多个计算节点上,并且这些节点可以同时工作以模拟完整的系统行为。分布式协同仿真已被广泛应用于工程、科学和军事领域,以便更好…...
openstack(2)
目录 块存储服务 安装并配置控制节点 安装并配置一个存储节点 验证操作 封装镜像 上传镜像 块存储服务 安装并配置控制节点 创建数据库 [rootcontroller ~]# mysql -u root -pshg12345 MariaDB [(none)]> CREATE DATABASE cinder; MariaDB [(none)]> GRANT ALL PR…...
Jmeter 压测保姆级入门教程
1、Jmeter本地安装 1.1、下载安装 软件下载地址: https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/ 选择一个压缩包下载即可 然后解压缩后进入bin目录直接执行命令jmeter即可启动 1.2 修改语言 默认是英文的,修改中文,点击…...
springboot2.1升级到2.7 actuator丢失部分metrics端点
项目场景: 项目需要升级springboot从2.1升级至2.7 问题描述 发现之前的metrics后面的jvm相关的端口丢了 原因分析: 找到这样一篇博文https://blog.csdn.net/CL_YD/article/details/120309094,这篇博文意思是对的,但是写的不太好…...
梦开始的地方——Adobe Premiere Pro
今天,我们来说说一款老生常谈的相信也是很多人都经常迫切需要的软件。Adobe Premiere Pro,简称Pr,是由Adobe公司开发的一款视频编辑软件。 Premiere Pro是视频编辑爱好者和专业人士必不可少的视频编辑工具。它可以提升您的创作能力和创作自由…...
Nginx同时支持Http和Https的配置详解
当配置Nginx同时支持HTTP和HTTPS时,需要进行以下步骤: 安装和配置SSL证书: 获得SSL证书:从可信任的证书颁发机构(CA)或使用自签名证书创建SSL证书。 将证书和私钥保存到服务器:将SSL证书和私钥…...
3.2 Windows驱动开发:内核CR3切换读写内存
CR3是一种控制寄存器,它是CPU中的一个专用寄存器,用于存储当前进程的页目录表的物理地址。在x86体系结构中,虚拟地址的翻译过程需要借助页表来完成。页表是由页目录表和页表组成的,页目录表存储了页表的物理地址,而页表…...
基于springBoot+Vue的停车管理系统
开发环境 IDEA JDK1.8 MySQL8.0Node 系统简介 本项目为前后端分离项目,前端使用vue,后端使用SpringBoot开发,主要的功能有用户管理,停车场管理,充值收费,用户可以注册登录系统,自主充值和预…...
ES开启安全认证
elasticsearch开启安全认证步骤 1.创建证书 进入到es主目录下执行 ./bin/elasticsearch-certutil ca Elasticsearch开启安全认证详细步骤 第一个证书名称默认,直接回车 第二个输入密码,直接回车 完成后会生成一个文件:elastic-stack-ca.p12…...
CS5511规格书|CS5511方案应用说明|DP转双路LVDS/eDP芯片方案
概述:CS5511是一个将DP/eDP输入转换为LVDS信号的桥接芯片,此外,CS5511可以用作在DP/eDP输入到DP/eDP输出场景中桥接芯片。CS5511的高级接收器支持VEDA DisplayPort(DP)1.3和嵌入式DisplayPort(eDP…...
JAVA小游戏“飞翔的小鸟”
第一步是创建项目 项目名自拟 第二步创建个包名 来规范class 再创建一个包 来存储照片 如下: package game; import java.awt.*; import javax.swing.*; import javax.imageio.ImageIO;public class Bird {Image image;int x,y;int width,height;int size;doubl…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
线程与协程
1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指:像函数调用/返回一样轻量地完成任务切换。 举例说明: 当你在程序中写一个函数调用: funcA() 然后 funcA 执行完后返回&…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
