feat(curd):支持CURD自动生成回收站功能 add recycle functionality for soft deleted items
- Add recycle method to Curd trait for restoring or permanently deleting items - Implement recycle view and update index view to include recycle button-Add recycle URL and functionality to JavaScript table initialization - Create new recycle template files for view and JavaScript
This commit is contained in:
@@ -132,35 +132,4 @@ EOF;
|
||||
$this->success('success', compact('choices'));
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '回收站', auth: true)]
|
||||
public function recycle(Request $request): Json|string
|
||||
{
|
||||
if (!$request->isAjax()) {
|
||||
return $this->fetch();
|
||||
}
|
||||
$id = $request->param('id', []);
|
||||
$type = $request->param('type', '');
|
||||
switch ($type) {
|
||||
case 'restore':
|
||||
self::$model::withTrashed()->whereIn('id', $id)->update(['delete_time' => null, 'update_time' => time()]);
|
||||
$this->success('success');
|
||||
break;
|
||||
case 'delete':
|
||||
self::$model::destroy($id, true);
|
||||
$this->success('success');
|
||||
break;
|
||||
default:
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
$count = self::$model::withTrashed()->whereNotNull('delete_time')->count();
|
||||
$list = self::$model::withTrashed()->with(['cate'])->where($where)->page($page, $limit)->order($this->sort)->whereNotNull('delete_time')->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
return json($data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1343,6 +1343,15 @@ class BuildCurd
|
||||
);
|
||||
$this->fileList[$viewEditFile] = $viewEditValue;
|
||||
|
||||
$viewRecycleFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}recycle.html";
|
||||
$viewRecycleValue = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("view{$this->DS}recycle"),
|
||||
[
|
||||
'controllerUrl' => $this->controllerUrl,
|
||||
'notesScript' => $this->formatNotesScript(),
|
||||
]
|
||||
);
|
||||
$this->fileList[$viewRecycleFile] = $viewRecycleValue;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1363,7 +1372,7 @@ class BuildCurd
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
||||
} elseif ($val['formType'] == 'datetime') {
|
||||
$templateValue = "{field: '{$field}', search: 'range', title: '{$val['comment']}'}";
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
} elseif ($val['formType'] == 'images') {
|
||||
continue;
|
||||
} elseif ($val['formType'] == 'file') {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
|
||||
@@ -1424,13 +1433,15 @@ class BuildCurd
|
||||
}
|
||||
}
|
||||
|
||||
$indexCols .= $this->formatColsRow("{width: 250, title: '操作', templet: ea.table.tool},\r");
|
||||
$recycleCols = $indexCols;
|
||||
$indexCols .= $this->formatColsRow("{width: 250, title: '操作', templet: ea.table.tool},\r");
|
||||
|
||||
$jsValue = CommonTool::replaceTemplate(
|
||||
$this->getTemplate("static{$this->DS}js"),
|
||||
[
|
||||
'controllerUrl' => $this->controllerUrl,
|
||||
'indexCols' => $indexCols,
|
||||
'recycleCols' => $recycleCols,
|
||||
]
|
||||
);
|
||||
$this->fileList[$jsFile] = $jsValue;
|
||||
|
||||
@@ -9,6 +9,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
delete_url: '{{controllerUrl}}/delete',
|
||||
export_url: '{{controllerUrl}}/export',
|
||||
modify_url: '{{controllerUrl}}/modify',
|
||||
recycle_url: '{{controllerUrl}}/recycle',
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -29,5 +30,62 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
||||
edit: function () {
|
||||
ea.listen();
|
||||
},
|
||||
recycle: function () {
|
||||
init.index_url = init.recycle_url;
|
||||
ea.table.render({
|
||||
init: init,
|
||||
toolbar: ['refresh',
|
||||
[{
|
||||
class: 'layui-btn layui-btn-sm',
|
||||
method: 'get',
|
||||
field: 'id',
|
||||
icon: 'fa fa-refresh',
|
||||
text: '全部恢复',
|
||||
title: '确定恢复?',
|
||||
auth: 'recycle',
|
||||
url: init.recycle_url + '?type=restore',
|
||||
checkbox: true
|
||||
}, {
|
||||
class: 'layui-btn layui-btn-danger layui-btn-sm',
|
||||
method: 'get',
|
||||
field: 'id',
|
||||
icon: 'fa fa-delete',
|
||||
text: '彻底删除',
|
||||
title: '确定彻底删除?',
|
||||
auth: 'recycle',
|
||||
url: init.recycle_url + '?type=delete',
|
||||
checkbox: true
|
||||
}], 'export',
|
||||
],
|
||||
cols: [[
|
||||
{{recycleCols}}
|
||||
{
|
||||
width: 250,
|
||||
title: '操作',
|
||||
templet: ea.table.tool,
|
||||
operat: [
|
||||
[{
|
||||
title: '确认恢复?',
|
||||
text: '恢复数据',
|
||||
filed: 'id',
|
||||
url: init.recycle_url + '?type=restore',
|
||||
method: 'get',
|
||||
auth: 'recycle',
|
||||
class: 'layui-btn layui-btn-xs layui-btn-success',
|
||||
}, {
|
||||
title: '想好了吗?',
|
||||
text: '彻底删除',
|
||||
filed: 'id',
|
||||
method: 'get',
|
||||
url: init.recycle_url + '?type=delete',
|
||||
auth: 'recycle',
|
||||
class: 'layui-btn layui-btn-xs layui-btn-normal layui-bg-red',
|
||||
}]]
|
||||
}
|
||||
]],
|
||||
});
|
||||
|
||||
ea.listen();
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -4,6 +4,7 @@
|
||||
data-auth-add="{:auth('{{controllerUrl}}/add')}"
|
||||
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
||||
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
||||
data-auth-recycle="{:auth('{{controllerUrl}}/recycle')}"
|
||||
lay-filter="currentTable">
|
||||
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||
</table>
|
||||
|
||||
13
app/admin/service/curd/templates/view/recycle.code
Normal file
13
app/admin/service/curd/templates/view/recycle.code
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main">
|
||||
<table id="currentTable" class="layui-table layui-hide"
|
||||
data-auth-recycle="{:auth('{{controllerUrl}}/recycle')}"
|
||||
lay-filter="currentTable">
|
||||
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{{notesScript}}
|
||||
</script>
|
||||
@@ -5,6 +5,7 @@ namespace app\admin\traits;
|
||||
use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\admin\service\tool\CommonTool;
|
||||
use app\Request;
|
||||
use think\db\exception\PDOException;
|
||||
use think\facade\Db;
|
||||
use think\response\Json;
|
||||
|
||||
@@ -154,4 +155,49 @@ trait Curd
|
||||
$this->success('保存成功');
|
||||
}
|
||||
|
||||
#[NodeAnnotation(title: '回收站', auth: true)]
|
||||
public function recycle(Request $request): Json|string
|
||||
{
|
||||
if (!$request->isAjax()) {
|
||||
return $this->fetch();
|
||||
}
|
||||
$id = $request->param('id', []);
|
||||
$type = $request->param('type', '');
|
||||
$deleteTimeField = (new self::$model)->getOption('deleteTime'); // 获取软删除字段
|
||||
$defaultErrorMsg = 'Model 中未设置软删除 deleteTime 对应字段 或 数据表中不存在该字段';
|
||||
if (!$deleteTimeField) $this->success($defaultErrorMsg);
|
||||
switch ($type) {
|
||||
case 'restore':
|
||||
self::$model::withTrashed()->whereIn('id', $id)->strict(false)->update([$deleteTimeField => null, 'update_time' => time()]);
|
||||
$this->success('success');
|
||||
break;
|
||||
case 'delete':
|
||||
self::$model::destroy($id, true);
|
||||
$this->success('success');
|
||||
break;
|
||||
default:
|
||||
list($page, $limit, $where) = $this->buildTableParams();
|
||||
try {
|
||||
$count = self::$model::withTrashed()->where($where)->whereNotNull($deleteTimeField)->count();
|
||||
$list = self::$model::withTrashed()->where($where)->page($page, $limit)->order($this->sort)->whereNotNull($deleteTimeField)->select()->toArray();
|
||||
$data = [
|
||||
'code' => 0,
|
||||
'msg' => '',
|
||||
'count' => $count,
|
||||
'data' => $list,
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
$error = $e->getMessage();
|
||||
if ($e instanceof PDOException) $error .= '<br>' . $defaultErrorMsg;
|
||||
$data = [
|
||||
'code' => -1,
|
||||
'msg' => $error,
|
||||
'count' => 0,
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
return json($data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +253,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
}
|
||||
|
||||
// 初始化表格左上方工具栏
|
||||
options.toolbar = options.toolbar || ['refresh', 'add', 'delete', 'export'];
|
||||
options.toolbar = options.toolbar || ['refresh', 'add', 'delete', 'export', 'recycle'];
|
||||
options.toolbar = admin.table.renderToolbar(options.toolbar, options.elem, options.id, options.init);
|
||||
|
||||
// 判断是否有操作列表权限
|
||||
@@ -313,6 +313,10 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
||||
toolbarHtml += '<button class="layui-btn layui-btn-sm layui-btn-success easyadmin-export-btn" data-url="' + init.export_url + '" data-table-export="' + tableId + '"><i class="fa fa-file-excel-o"></i> 导出</button>\n';
|
||||
}
|
||||
} else if (v === 'recycle') {
|
||||
if (init.recycle_url === undefined) {
|
||||
console.warn('未定义回收站地址 init.recycle_url')
|
||||
return false
|
||||
}
|
||||
if (admin.checkAuth('recycle', elem)) {
|
||||
toolbarHtml += '<button class="layui-btn layui-btn-sm layui-bg-orange" data-open="' + init.recycle_url + '" data-title="回收站"><i class="fa fa-recycle"></i> 回收站</button>\n';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user