增删改查
基类继承
// 接口基类
app/common/basics/Api.php
// 后端基类
app/common/basics/Backend.php
// 前端基类
app/common/basics/Frontend.php
// 服务基类
app/common/basics/Service.php
Curd类
- 控制器中继承基类 Backend (根据应用继承)
- 服务层中也需要继承基类 Service, 没继承是没办法用搜索器的
- 为什么要继承基类?答: 因为基类实现了拦截 和 大量好用的方法
class ArticleController extends Backend
{
// 列表
public function index() { }
// 新增
public function add() { }
// 编辑
public function edit() { }
// 删除
public function del() { }
}
验证器
- 验证器写在validate目录中并继承
app\common\basics\Validate
- 如果没有继承自定义的基类验证器,则无法使用切面验证写法
// 1、定义验证器, 具体请参考代码 或 查看ThinkPHP6的开发文档
use app\common\basics\Validate;
class ArticleValidate extends Validate
{
protected $rule = [
'id' => 'require|integer',
'title' => 'require'
];
}
// 2、在控制器中使用验证器
class ArticleController extends Backend
{
public function add() {
if ($this->isAjaxPost()) {
(new ArticleValidate())->addCheck(); // 验证器: 验证新增数据
ArticleService::add($this->request->post());
return AjaxUtils::success();
}
return view();
}
}
// 3、以下是场景验证器的使用方式
// 目前提供了4种快捷验证: addCheck / editCheck / idCheck / idsCheck
// 如果以下4种满足不了, 可以指定场景 goCheck('此处填场景')
// 验证新增数据
(new ArticleValidate())->addCheck();
// 验证编辑数据
(new ArticleValidate())->editCheck();
// 验证数字类型ID
(new ArticleValidate())->idCheck();
// 验证数组类型的ID
(new ArticleValidate())->idsCheck();
// 验证分页参数
(new PageValidate())->goCheck();
业务流程
- 1、创建 controller
- 2、创建 service
- 3、创建 validate
- 4、创建 view
- 5、创建 model
controller
调用validate验证参数 调用service处理具体逻辑 view返回HTML页面
service
调用model实现增删改查 使用具体的逻辑需求
视图页面
列表页常用模板
{extend name="common/layout" /}
{block name="body"}
<div class="container">
<!-- 搜索栏 -->
<form class="layui-form layui-search" lay-filter="filter-search-form">
<div class="layui-form-item">
<!-- 多类型搜索 -->
<div class="layui-inline">
<label for="keyword" class="layui-form-label">搜索类型:</label>
<div class="layui-input-inline layui-sm-select">
<input type="hidden" id="search-filter-type" name="type">
<div class="layui-inline">
<label for="keyword_type" class="layui-hide"></label>
<select id="keyword_type" name="keyword_type">
<option value="">请选择</option>
<option value="licence_sn">授权编号</option>
<option value="user_sn">用户编号</option>
<option value="nickname">用户昵称</option>
</select>
</div>
<div class="layui-inline" >
<input type="text" id="keyword" name="keyword" placeholder="请输入关键词" class="layui-input">
</div>
</div>
</div>
<!-- 文本框搜索 -->
<div class="layui-inline">
<label for="title" class="layui-form-label">标题:</label>
<div class="layui-input-inline">
<input type="text" id="title" name="title" class="layui-input" placeholder="请输入标题名称" autocomplete="off">
</div>
</div>
<!-- 下拉式搜索 -->
<div class="layui-inline">
<label for="status" class="layui-form-label">状态:</label>
<div class="layui-input-inline">
<select id="status" name="status">
<option value="" selected>全部</option>
<option value="0">显示</option>
<option value="1">隐藏</option>
</select>
</div>
</div>
<!-- 时间范围搜索 -->
<div class="layui-inline layui-input-datetime">
<label for="datetime" class="layui-form-label">操作时间:</label>
<div class="layui-input-block">
<input type="text" id="datetime" name="datetime" class="layui-input" placeholder="开始时间 - 结束时间" readonly>
</div>
</div>
<!-- 搜索按钮 -->
<div class="layui-inline">
<a class="layui-btn layui-btn-sm layui-btn-default" lay-submit lay-filter="search">查询</a>
<a class="layui-btn layui-btn-sm layui-btn-primary" lay-submit lay-filter="clear-search">重置</a>
</div>
</div>
</form>
<!-- 表格栏 -->
<div class="layui-card">
<div class="layui-card-body">
<!-- 渲染节点 -->
<table id="wait-table-list" lay-filter="wait-table-list"></table>
<!-- 表格头操作 -->
<script type="text/html" id="toolbar">
<div class="layui-btn-container">
<a class="layui-btn layui-btn-sm layui-btn-default" lay-event="add">
<i class="layui-icon icon-add"></i>
<span>新增</span>
</a>
<a class="layui-btn layui-btn-sm layui-btn-danger layui-btn-forbid" lay-event="leave">
<i class="layui-icon icon-del"></i>
<span>删除</span>
</a>
</div>
</script>
<!-- 表格行操作 -->
<script type="text/html" id="table-operate">
<button type="button" class="layui-btn layui-btn-xs layui-btn-default" lay-event="edit">
<i class="layui-icon icon-edit"></i>
</button>
<button type="button" class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">
<i class="layui-icon icon-del"></i>
</button>
</script>
</div>
</div>
</div>
{block name="js"}
<script>
layui.use(['laydate'], function() {
let laydate = layui.laydate;
// 时间选择
laydate.render({elem: '#datetime' ,type: 'datetime' ,trigger: 'click' ,range: true});
// 渲染表格
let table = waitUtil.table({
elem: '#wait-table-list'
,url: '{:route("content.article/index")}'
,cols: [[
{type:'checkbox', width:48},
{field:'id', title:'ID', width:60, align:'center', event:'id'},
{fixed:'right', title:'操作', width:90, align:'center', toolbar:'#table-operate'}
]]
});
// 逻辑事件
waitUtil.event({
add: function () {
waitUtil.popup({
title: '新增',
url: '{:route("content.article/add")}',
area: ['95%', '95%'],
success: function (layero, index) {
layero.layui.form.on('submit(addForm)', function(data) {
waitUtil.locking(this);
data.field['content'] = layero.tinymce.activeEditor.getContent();
waitUtil.ajax({
url: '{:route("content.article/add")}',
type: 'POST',
data: data.field
}).then((res) => {
waitUtil.unlock(this);
if (res.code === 0) {
table.reload({page: {curr: 1}});
layer.close(index);
}
}).catch(() => {
waitUtil.unlock(this);
});
});
}
});
},
edit: function (obj) {
waitUtil.popup({
title: '编辑',
url: '{:route("content.article/edit")}?id='+obj.data.id,
area: ['95%', '95%'],
success: function (layero, index) {
layero.layui.form.on('submit(addForm)', function(data) {
waitUtil.locking(this);
data.field['id'] = obj.data.id;
waitUtil.ajax({
url: '{:route("content.article/edit")}',
type: 'POST',
data: data.field
}).then((res) => {
waitUtil.unlock(this);
if (res.code === 0) {
table.reload();
layer.close(index);
}
}).catch(() => {
waitUtil.unlock(this);
});
});
}
});
},
del: function (obj) {
layer.confirm('确定要删除此项数据吗?', function(index) {
layer.close(index);
waitUtil.ajax({
url: '{:route("content.article/del")}',
type: 'POST',
data: {ids: [obj.data.id]}
}).then((res) => {
if (res.code === 0) {
table.reload();
}
});
});
},
leave: function () {
let ids = waitUtil.checkbox();
if (!ids.length) {
return layer.msg('请至少选择一项!', {icon: 2});
}
layer.confirm(`确定要删除选中的${ids.length}项数据吗?`, function(index) {
layer.close(index);
waitUtil.ajax({
url: '{:route("content.article/del")}',
type: 'POST',
data: {ids: ids}
}).then((res) => {
if (res.code === 0) {
table.reload();
}
});
});
}
});
// 搜索事件
waitUtil.search(table);
}};
</script>
新增页常用模板
{extend name="common/layout" /}
{block name="body"}
<form class="layui-form">
<!-- 主体内容 -->
<div class="wait-body-content">
<!-- 下拉框 -->
<div class="layui-form-item">
<label for="cid" class="layui-form-label"><span class="asterisk">*</span>类目:</label>
<div class="layui-input-block">
<select id="cid" name="cid" lay-verify="required|number">
<option value="">请选择</option>
{volist name="$category" id="vo"}
<option value="{$vo.id}">{$vo.name}</option>
{/volist}
</select>
</div>
</div>
<!-- 文本框 -->
<div class="layui-form-item">
<label for="title" class="layui-form-label"><span class="asterisk">*</span>标题:</label>
<div class="layui-input-block">
<input type="text" id="title" name="title"
autocomplete="off" class="layui-input" lay-verType="tips" lay-verify="required">
</div>
</div>
<!-- 封面图 -->
<div class="layui-form-item">
<label class="layui-form-label">封面:</label>
<div class="layui-input-block">
<div class="thumbnail" data-type="image" data-field="image" data-limit="1">
<div class="musters"></div>
<div class="builder">
<i class="layui-icon layui-icon-camera"></i>
<p>上传封面</p>
<div class="mask">
<div class="item layui-auto">图库选择</div>
<div class="item layui-auto-call">本地上传</div>
</div>
</div>
</div>
</div>
</div>
<!-- 头像图 -->
<div class="thumbnail" data-type="image" data-field="avatar" data-limit="1">
<div class="musters"></div>
<div class="builder layui-auto-call">
<i class="layui-icon layui-icon-camera"></i>
<p>上传头像</p>
</div>
</div>
<!-- 内容框 -->
<div class="layui-form-item">
<label for="intro" class="layui-form-label">简介:</label>
<div class="layui-input-block">
<textarea id="intro" name="intro" class="layui-textarea"></textarea>
</div>
</div>
<!-- 单选框 -->
<div class="layui-form-item">
<label class="layui-form-label"><span class="asterisk">*</span>状态:</label>
<div class="layui-input-block">
<input type="radio" name="is_show" value="1" title="显示" checked>
<input type="radio" name="is_show" value="0" title="隐藏">
</div>
</div>
</div>
<!-- 提交按钮 -->
<div class="wait-body-footer">
<a class="layui-layer-btn0" lay-submit lay-filter="addForm">确定</a>
<a class="layui-layer-btn1" id="closePopupWindow">取消</a>
</div>
</form>
{/block}
编辑页常用模板
{extend name="common/layout" /}
{block name="body"}
<form class="layui-form">
<!-- 主体内容 -->
<div class="wait-body-content">
<!-- 下拉框 -->
<div class="layui-form-item">
<label for="cid" class="layui-form-label"><span class="asterisk">*</span>类目:</label>
<div class="layui-input-block">
<select id="cid" name="cid" lay-verify="required|number">
<option value="">请选择</option>
{volist name="$category" id="vo"}
<option value="{$vo.id}" {if $detail.cid==$vo.id}selected{/if}>{$vo.name}</option>
{/volist}
</select>
</div>
</div>
<!-- 文本框 -->
<div class="layui-form-item">
<label for="title" class="layui-form-label"><span class="asterisk">*</span>标题:</label>
<div class="layui-input-block">
<input type="text" id="title" name="title" value="{$detail.title}"
autocomplete="off" class="layui-input" lay-verType="tips" lay-verify="required">
</div>
</div>
<!-- 封面图 -->
<div class="layui-form-item">
<label for="image" class="layui-form-label">封面:</label>
<div class="layui-input-block">
<div class="thumbnail" data-type="image" data-limit="1">
<div class="musters">
{if $detail.image}
<div class="preview">
<input type="hidden" id="image" name="image" value="{$detail.image}">
<i class="layui-icon layui-icon-close"></i>
<img src="{$detail.image}" alt="img">
</div>
{/if}
</div>
<div class="builder {if $detail.image}layui-hide{/if}">
<i class="layui-icon layui-icon-camera"></i>
<p>上传封面</p>
<div class="mask">
<div class="item layui-auto">图库选择</div>
<div class="item layui-auto-call">本地上传</div>
</div>
</div>
</div>
</div>
</div>
<!-- 头像图 -->
<div class="thumbnail" data-type="image" data-field="avatar" data-limit="1">
<div class="musters">
{if $detail.avatar}
<div class="preview">
<input type="hidden" name="avatar" value="{$detail.avatar}">
<i class="layui-icon layui-icon-close"></i>
<img src="{$detail.avatar}" alt="img">
</div>
{/if}
</div>
<div class="builder layui-auto-call {if $detail.avatar}layui-hide{/if}">
<i class="layui-icon layui-icon-camera"></i>
<p>上传头像</p>
</div>
</div>
<!-- 内容框 -->
<div class="layui-form-item">
<label for="intro" class="layui-form-label">简介:</label>
<div class="layui-input-block">
<textarea id="intro" name="intro" class="layui-textarea">{$detail.intro}</textarea>
</div>
</div>
<!-- 单选框 -->
<div class="layui-form-item">
<label class="layui-form-label"><span class="asterisk">*</span>状态:</label>
<div class="layui-input-block">
<input type="radio" name="is_show" value="1" title="显示" {if $detail.is_show==1}checked{/if}>
<input type="radio" name="is_show" value="0" title="隐藏" {if $detail.is_show==0}checked{/if}>
</div>
</div>
</div>
<!-- 提交按钮 -->
<div class="wait-body-footer">
<a class="layui-layer-btn0" lay-submit lay-filter="addForm">确定</a>
<a class="layui-layer-btn1" id="closePopupWindow">取消</a>
</div>
</form>
{/block}
Layui常用标签
<!-- 输入框 -->
<div class="layui-form-item">
<label for="username" class="layui-form-label">输入框</label>
<div class="layui-input-block">
<input type="text" id="username" name="username" placeholder="请输入"
autocomplete="off" class="layui-input" lay-verType="tips" lay-verify="required" />
</div>
</div>
<!-- 普通文本域 -->
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">普通文本域</label>
<div class="layui-input-block">
<textarea placeholder="请输入内容" class="layui-textarea"></textarea>
</div>
</div>
<!-- 单行选择框 -->
<div class="layui-form-item">
<label for="interest" class="layui-form-label">单行选择框</label>
<div class="layui-input-block">
<select id="interest" name="interest" lay-filter="interest">
<option value=""></option>
<option value="0">写作</option>
<option value="1" selected>阅读</option>
<option value="2">游戏</option>
</select>
</div>
</div>
<!-- 开关 -->
<div class="layui-form-item">
<label for="open" class="layui-form-label">开关-默认开</label>
<div class="layui-input-block">
<input type="checkbox" id="open" name="open" lay-skin="switch" lay-filter="switchTest" title="开关" checked>
</div>
</div>
<!-- 复选框 -->
<div class="layui-form-item">
<label class="layui-form-label">复选框</label>
<div class="layui-input-block">
<input type="checkbox" name="arr1[0]" lay-skin="tag" title="选项1" checked>
<input type="checkbox" name="arr1[1]" lay-skin="tag" title="选项2">
<input type="checkbox" name="arr1[2]" lay-skin="tag" title="选项3" disabled>
</div>
</div>
<!-- 单选框 -->
<div class="layui-form-item">
<label class="layui-form-label">单选框</label>
<div class="layui-input-block">
<input type="radio" name="sex" value="男" title="男" checked>
<input type="radio" name="sex" value="女" title="女">
<input type="radio" name="sex" value="禁" title="禁用" disabled>
</div>
</div>
Layui常用事件
layui.use(['form', 'laydate', 'util'], function() {
let form = layui.form;
let layer = layui.layer;
let laydate = layui.laydate;
let util = layui.util;
// 指向所有 select 组件的选择事件
form.on('select', function(data){
console.log(data);
});
// 指向元素为 `<select lay-filter="test"></select>` 的选择事件
form.on('select(test)', function(data){
console.log(data);
});
// 监听复选框事件
form.on('checkbox(test)', function(data){
console.log(data);
});
// 监听单选框事件
form.on('radio(test)', function(data){
console.log(data);
});
// 监听开关事件
form.on('switch(switchTest)', function(data) {
layer.msg('开关 checked:'+ (this.checked ? 'true' : 'false'), {
offset: '6px'
});
layer.tips('温馨提示:请注意开关状态的文字可以随意定义,而不仅仅是 ON|OFF', data.othis)
});
// 监听提交事件
form.on('submit(demo1)', function(data) {
let field = data.field; // 获取表单字段值
// 显示填写结果仅作演示用
layer.alert(JSON.stringify(field), {
title: '当前填写的字段值'
});
// 此处可执行 Ajax 等操作
// …
return false; // 阻止默认 form 跳转
});
// 日期事件
laydate.render({
elem: '#date'
});
// 自定义验证规则
form.verify({
pass: [
/^[\S]{6,12}$/,
'密码必须6到12位,且不能出现空格'
]
});
// 普通事件
util.on('lay-on', {
// 获取验证码
"get-vercode": function(othis){
var isvalid = form.validate('.demo-phone'); // 主动触发验证,v2.7.0 新增
// 验证通过
if(isvalid){
layer.msg('手机号规则验证通过');
// 此处可继续书写「发送验证码」等后续逻辑
// …
}
}
});
});