From 74122885f17756e2522b46bff05ba872703ce003 Mon Sep 17 00:00:00 2001
From: wolfcode <37436228+wolf-leo@users.noreply.github.com>
Date: Mon, 7 Apr 2025 13:44:12 +0800
Subject: [PATCH] =?UTF-8?q?feat(mall):=20=E6=96=B0=E5=A2=9E=E5=9B=9E?=
=?UTF-8?q?=E6=94=B6=E7=AB=99=E5=8A=9F=E8=83=BD=20add=20recycle=20function?=
=?UTF-8?q?ality=20for=20goods?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Add recycle feature to goods management
- Implement recycle button in toolbar
- Create recycle page for deleted goods
- Add functionality to restore or permanently delete goods
---
app/admin/controller/mall/Goods.php | 31 ++++++++
app/admin/view/mall/goods/index.html | 1 +
app/admin/view/mall/goods/recycle.html | 11 +++
public/static/admin/js/mall/goods.js | 75 +++++++++++++++++++-
public/static/plugs/easy-admin/easy-admin.js | 4 ++
5 files changed, 121 insertions(+), 1 deletion(-)
create mode 100644 app/admin/view/mall/goods/recycle.html
diff --git a/app/admin/controller/mall/Goods.php b/app/admin/controller/mall/Goods.php
index e17de04..8d20823 100644
--- a/app/admin/controller/mall/Goods.php
+++ b/app/admin/controller/mall/Goods.php
@@ -132,4 +132,35 @@ 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);
+ }
+
+ }
}
\ No newline at end of file
diff --git a/app/admin/view/mall/goods/index.html b/app/admin/view/mall/goods/index.html
index 5016922..fe02941 100644
--- a/app/admin/view/mall/goods/index.html
+++ b/app/admin/view/mall/goods/index.html
@@ -5,6 +5,7 @@
data-auth-edit="{:auth('mall.goods/edit')}"
data-auth-delete="{:auth('mall.goods/delete')}"
data-auth-stock="{:auth('mall.goods/stock')}"
+ data-auth-recycle="{:auth('mall.goods/recycle')}"
lay-filter="currentTable">
diff --git a/app/admin/view/mall/goods/recycle.html b/app/admin/view/mall/goods/recycle.html
new file mode 100644
index 0000000..29b8573
--- /dev/null
+++ b/app/admin/view/mall/goods/recycle.html
@@ -0,0 +1,11 @@
+
+
\ No newline at end of file
diff --git a/public/static/admin/js/mall/goods.js b/public/static/admin/js/mall/goods.js
index 433752f..eb41ef0 100644
--- a/public/static/admin/js/mall/goods.js
+++ b/public/static/admin/js/mall/goods.js
@@ -10,6 +10,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
export_url: 'mall.goods/export',
modify_url: 'mall.goods/modify',
stock_url: 'mall.goods/stock',
+ recycle_url: 'mall.goods/recycle',
};
return {
@@ -27,7 +28,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
icon: 'fa fa-plus ',
extend: 'data-width="90%" data-height="95%"',
}],
- 'delete', 'export'],
+ 'delete', 'export', 'recycle'],
cols: [[
{type: "checkbox"},
{field: 'id', width: 80, title: 'ID', searchOp: '='},
@@ -107,6 +108,78 @@ define(["jquery", "easy-admin"], function ($, ea) {
stock: 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: [[
+ {type: "checkbox"},
+ {field: 'id', width: 80, title: 'ID', searchOp: '='},
+ {field: 'sort', width: 80, title: '排序', edit: 'text'},
+ {field: 'cate_id', minWidth: 80, title: '商品分类', search: 'select', selectList: cateSelects, laySearch: true},
+ {field: 'title', minWidth: 80, title: '商品名称'},
+ {field: 'logo', minWidth: 80, title: '分类图片', search: false, templet: ea.table.image},
+ {field: 'status', title: '状态', width: 85, selectList: {0: '禁用', 1: '启用'}},
+ // 演示多选,实际数据库并无 status2 字段,搜索后会报错
+ {
+ field: 'status2', title: '演示多选', width: 105, search: 'xmSelect', selectList: {1: '模拟选项1', 2: '模拟选项2', 3: '模拟选项3', 4: '模拟选项4', 5: '模拟选项5'},
+ searchOp: 'in', templet: function (res) {
+ // 根据自己实际项目进行输出
+ return res?.status2 || '模拟数据'
+ }
+ },
+ {field: 'create_time', minWidth: 80, title: '创建时间', search: 'range'},
+ {field: 'delete_time', minWidth: 80, title: '删除时间', search: 'range'},
+ {
+ 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();
+ },
};
function aiOptimization(data) {
diff --git a/public/static/plugs/easy-admin/easy-admin.js b/public/static/plugs/easy-admin/easy-admin.js
index 91cfbf5..567df8a 100644
--- a/public/static/plugs/easy-admin/easy-admin.js
+++ b/public/static/plugs/easy-admin/easy-admin.js
@@ -312,6 +312,10 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
if (admin.checkAuth('export', elem)) {
toolbarHtml += '\n';
}
+ } else if (v === 'recycle') {
+ if (admin.checkAuth('recycle', elem)) {
+ toolbarHtml += '\n';
+ }
} else if (typeof v === "object") {
$.each(v, function (ii, vv) {
vv.class = vv.class || '';