Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a2ee69d0f | ||
|
|
d513177c74 | ||
|
|
0705b9a38d | ||
|
|
feb26660e8 | ||
|
|
b8ccf1542b | ||
|
|
74122885f1 |
@@ -355,6 +355,7 @@ class BuildCurd
|
|||||||
if (!empty($bindSelectField) && !in_array($bindSelectField, array_column($columns, 'Field'))) {
|
if (!empty($bindSelectField) && !in_array($bindSelectField, array_column($columns, 'Field'))) {
|
||||||
throw new TableException("关联表{$relationTable}不存在该字段: {$bindSelectField}");
|
throw new TableException("关联表{$relationTable}不存在该字段: {$bindSelectField}");
|
||||||
}
|
}
|
||||||
|
$onlyFields = [];
|
||||||
foreach ($columns as $vo) {
|
foreach ($columns as $vo) {
|
||||||
if (empty($primaryKey) && $vo['Key'] == 'PRI') {
|
if (empty($primaryKey) && $vo['Key'] == 'PRI') {
|
||||||
$primaryKey = $vo['Field'];
|
$primaryKey = $vo['Field'];
|
||||||
@@ -362,6 +363,7 @@ class BuildCurd
|
|||||||
if (!empty($onlyShowFields) && !in_array($vo['Field'], $onlyShowFields)) {
|
if (!empty($onlyShowFields) && !in_array($vo['Field'], $onlyShowFields)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!empty($onlyShowFields)) $onlyFields[] = $vo['Field'];
|
||||||
$colum = [
|
$colum = [
|
||||||
'type' => $vo['Type'],
|
'type' => $vo['Type'],
|
||||||
'comment' => $vo['Comment'],
|
'comment' => $vo['Comment'],
|
||||||
@@ -388,6 +390,7 @@ class BuildCurd
|
|||||||
'bindSelectField' => $bindSelectField,
|
'bindSelectField' => $bindSelectField,
|
||||||
'delete' => $delete,
|
'delete' => $delete,
|
||||||
'tableColumns' => $formatColumns,
|
'tableColumns' => $formatColumns,
|
||||||
|
'onlyFields' => $onlyFields,
|
||||||
];
|
];
|
||||||
if (!empty($bindSelectField)) {
|
if (!empty($bindSelectField)) {
|
||||||
$relationArray = explode('\\', $modelFilename);
|
$relationArray = explode('\\', $modelFilename);
|
||||||
@@ -1038,7 +1041,7 @@ class BuildCurd
|
|||||||
$relationCode = '';
|
$relationCode = '';
|
||||||
foreach ($this->relationArray as $key => $val) {
|
foreach ($this->relationArray as $key => $val) {
|
||||||
$relation = CommonTool::lineToHump($key);
|
$relation = CommonTool::lineToHump($key);
|
||||||
$relationCode = "->withJoin('{$relation}', 'LEFT')\r";
|
$relationCode = "with(['{$relation}'])";
|
||||||
if (!empty($val['bindSelectField']) && !empty($val['primaryKey'])) {
|
if (!empty($val['bindSelectField']) && !empty($val['primaryKey'])) {
|
||||||
$constructRelation = '$notes["' . lcfirst($val['foreignKey']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
|
$constructRelation = '$notes["' . lcfirst($val['foreignKey']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
|
||||||
}
|
}
|
||||||
@@ -1092,16 +1095,17 @@ class BuildCurd
|
|||||||
$relationList = '';
|
$relationList = '';
|
||||||
if (!empty($this->relationArray)) {
|
if (!empty($this->relationArray)) {
|
||||||
foreach ($this->relationArray as $key => $val) {
|
foreach ($this->relationArray as $key => $val) {
|
||||||
$relation = CommonTool::lineToHump($key);
|
$relation = CommonTool::lineToHump($key);
|
||||||
// $relationCode = CommonTool::replaceTemplate(
|
$relationCode = CommonTool::replaceTemplate(
|
||||||
// $this->getTemplate("model{$this->DS}relation"),
|
$this->getTemplate("model{$this->DS}relation"),
|
||||||
// [
|
[
|
||||||
// 'relationMethod' => $relation,
|
'relationMethod' => $relation,
|
||||||
// 'relationModel' => "\app\admin\model\\{$val['modelFilename']}",
|
'relationModel' => "{$val['modelFilename']}::class",
|
||||||
// 'foreignKey' => $val['foreignKey'],
|
'foreignKey' => $val['primaryKey'],
|
||||||
// 'primaryKey' => $val['primaryKey'],
|
'primaryKey' => $val['foreignKey'],
|
||||||
// ]);
|
'relationFields' => empty($val['onlyFields']) ? "" : "->field('{$val['primaryKey']}," . implode(',', $val['onlyFields']) . "')",
|
||||||
// $relationList .= $relationCode;
|
]);
|
||||||
|
$relationList .= $relationCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1343,6 +1347,15 @@ class BuildCurd
|
|||||||
);
|
);
|
||||||
$this->fileList[$viewEditFile] = $viewEditValue;
|
$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;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1363,7 +1376,7 @@ class BuildCurd
|
|||||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
|
||||||
} elseif ($val['formType'] == 'datetime') {
|
} elseif ($val['formType'] == 'datetime') {
|
||||||
$templateValue = "{field: '{$field}', search: 'range', title: '{$val['comment']}'}";
|
$templateValue = "{field: '{$field}', search: 'range', title: '{$val['comment']}'}";
|
||||||
} elseif ($val['formType'] == 'images') {
|
} elseif ($val['formType'] == 'images') {
|
||||||
continue;
|
continue;
|
||||||
} elseif ($val['formType'] == 'file') {
|
} elseif ($val['formType'] == 'file') {
|
||||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
|
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
|
||||||
@@ -1424,13 +1437,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(
|
$jsValue = CommonTool::replaceTemplate(
|
||||||
$this->getTemplate("static{$this->DS}js"),
|
$this->getTemplate("static{$this->DS}js"),
|
||||||
[
|
[
|
||||||
'controllerUrl' => $this->controllerUrl,
|
'controllerUrl' => $this->controllerUrl,
|
||||||
'indexCols' => $indexCols,
|
'indexCols' => $indexCols,
|
||||||
|
'recycleCols' => $recycleCols,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
$this->fileList[$jsFile] = $jsValue;
|
$this->fileList[$jsFile] = $jsValue;
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ class {{controllerName}} extends AdminController
|
|||||||
{
|
{
|
||||||
parent::__construct($app);
|
parent::__construct($app);
|
||||||
self::$model = {{modelFilename}}::class;
|
self::$model = {{modelFilename}}::class;
|
||||||
$this->notes = $notes = self::$model::$notes;
|
$notes = self::$model::$notes;
|
||||||
{{constructRelation}}
|
{{constructRelation}}
|
||||||
|
$this->notes =$notes;
|
||||||
$this->assign(compact('notes'));
|
$this->assign(compact('notes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
#[NodeAnnotation(title: '列表', auth: true)]
|
||||||
|
public function index(\app\Request $request): \think\response\Json|string
|
||||||
|
{
|
||||||
|
if ($request->isAjax()) {
|
||||||
|
if (input('selectFields')) {
|
||||||
|
return $this->selectList();
|
||||||
|
}
|
||||||
|
list($page, $limit, $where) = $this->buildTableParams();
|
||||||
|
$count = self::$model::where($where)->count();
|
||||||
|
$list = self::$model::where($where)->{{relationIndexMethod}}->page($page, $limit)->order($this->sort)->select()->toArray();
|
||||||
|
$data = [
|
||||||
|
'code' => 0,
|
||||||
|
'msg' => '',
|
||||||
|
'count' => $count,
|
||||||
|
'data' => $list,
|
||||||
|
];
|
||||||
|
return json($data);
|
||||||
|
}
|
||||||
|
return $this->fetch();
|
||||||
|
}
|
||||||
@@ -18,4 +18,6 @@ class {{modelName}} extends TimeModel
|
|||||||
|
|
||||||
public static array $notes = {{selectArrays}};
|
public static array $notes = {{selectArrays}};
|
||||||
|
|
||||||
|
{{relationList}}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
public function {{relationMethod}}()
|
public function {{relationMethod}}()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('{{relationModel}}', '{{foreignKey}}', '{{primaryKey}}');
|
return $this->hasOne({{relationModel}}, '{{foreignKey}}', '{{primaryKey}}'){{relationFields}};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
|||||||
delete_url: '{{controllerUrl}}/delete',
|
delete_url: '{{controllerUrl}}/delete',
|
||||||
export_url: '{{controllerUrl}}/export',
|
export_url: '{{controllerUrl}}/export',
|
||||||
modify_url: '{{controllerUrl}}/modify',
|
modify_url: '{{controllerUrl}}/modify',
|
||||||
|
recycle_url: '{{controllerUrl}}/recycle',
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -29,5 +30,62 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
|||||||
edit: function () {
|
edit: function () {
|
||||||
ea.listen();
|
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-add="{:auth('{{controllerUrl}}/add')}"
|
||||||
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
data-auth-edit="{:auth('{{controllerUrl}}/edit')}"
|
||||||
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
data-auth-delete="{:auth('{{controllerUrl}}/delete')}"
|
||||||
|
data-auth-recycle="{:auth('{{controllerUrl}}/recycle')}"
|
||||||
lay-filter="currentTable">
|
lay-filter="currentTable">
|
||||||
<!-- searchTableShow="false" 隐藏搜索框 -->
|
<!-- searchTableShow="false" 隐藏搜索框 -->
|
||||||
</table>
|
</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\annotation\NodeAnnotation;
|
||||||
use app\admin\service\tool\CommonTool;
|
use app\admin\service\tool\CommonTool;
|
||||||
use app\Request;
|
use app\Request;
|
||||||
|
use think\db\exception\PDOException;
|
||||||
use think\facade\Db;
|
use think\facade\Db;
|
||||||
use think\response\Json;
|
use think\response\Json;
|
||||||
|
|
||||||
@@ -154,4 +155,49 @@ trait Curd
|
|||||||
$this->success('保存成功');
|
$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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-col-xs2">
|
<div class="layui-col-xs2">
|
||||||
<button class="layui-btn layui-bg-purple layui-btn-fluid" type="button" lay-on="AiOptimization">AI优化</button>
|
<button class="layui-btn layui-bg-purple" type="button" lay-on="AiOptimization">AI优化</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
data-auth-edit="{:auth('mall.goods/edit')}"
|
data-auth-edit="{:auth('mall.goods/edit')}"
|
||||||
data-auth-delete="{:auth('mall.goods/delete')}"
|
data-auth-delete="{:auth('mall.goods/delete')}"
|
||||||
data-auth-stock="{:auth('mall.goods/stock')}"
|
data-auth-stock="{:auth('mall.goods/stock')}"
|
||||||
|
data-auth-recycle="{:auth('mall.goods/recycle')}"
|
||||||
lay-filter="currentTable">
|
lay-filter="currentTable">
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
11
app/admin/view/mall/goods/recycle.html
Normal file
11
app/admin/view/mall/goods/recycle.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<div class="layuimini-container">
|
||||||
|
<div class="layuimini-main">
|
||||||
|
<table id="currentTable" class="layui-table layui-hide"
|
||||||
|
data-auth-recycle="{:auth('mall.goods/recycle')}"
|
||||||
|
lay-filter="currentTable">
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
let cateSelects = JSON.parse('{$cate|json_encode=256|raw}')
|
||||||
|
</script>
|
||||||
@@ -75,8 +75,8 @@ body {
|
|||||||
|
|
||||||
/**重写layui表格自适应*/
|
/**重写layui表格自适应*/
|
||||||
.layuimini-container .layui-table-cell {
|
.layuimini-container .layui-table-cell {
|
||||||
height: 100%;
|
height: 50px;
|
||||||
max-width: 100%;
|
line-height: 42px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**数据表格-搜索表单样式*/
|
/**数据表格-搜索表单样式*/
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
|||||||
export_url: 'mall.goods/export',
|
export_url: 'mall.goods/export',
|
||||||
modify_url: 'mall.goods/modify',
|
modify_url: 'mall.goods/modify',
|
||||||
stock_url: 'mall.goods/stock',
|
stock_url: 'mall.goods/stock',
|
||||||
|
recycle_url: 'mall.goods/recycle',
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -27,7 +28,7 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
|||||||
icon: 'fa fa-plus ',
|
icon: 'fa fa-plus ',
|
||||||
extend: 'data-width="90%" data-height="95%"',
|
extend: 'data-width="90%" data-height="95%"',
|
||||||
}],
|
}],
|
||||||
'delete', 'export'],
|
'delete', 'export', 'recycle'],
|
||||||
cols: [[
|
cols: [[
|
||||||
{type: "checkbox"},
|
{type: "checkbox"},
|
||||||
{field: 'id', width: 80, title: 'ID', searchOp: '='},
|
{field: 'id', width: 80, title: 'ID', searchOp: '='},
|
||||||
@@ -107,6 +108,78 @@ define(["jquery", "easy-admin"], function ($, ea) {
|
|||||||
stock: function () {
|
stock: function () {
|
||||||
ea.listen();
|
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) {
|
function aiOptimization(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);
|
options.toolbar = admin.table.renderToolbar(options.toolbar, options.elem, options.id, options.init);
|
||||||
|
|
||||||
// 判断是否有操作列表权限
|
// 判断是否有操作列表权限
|
||||||
@@ -312,6 +312,14 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
|||||||
if (admin.checkAuth('export', elem)) {
|
if (admin.checkAuth('export', elem)) {
|
||||||
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';
|
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';
|
||||||
|
}
|
||||||
} else if (typeof v === "object") {
|
} else if (typeof v === "object") {
|
||||||
$.each(v, function (ii, vv) {
|
$.each(v, function (ii, vv) {
|
||||||
vv.class = vv.class || '';
|
vv.class = vv.class || '';
|
||||||
@@ -1785,7 +1793,7 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
|||||||
layer.open({
|
layer.open({
|
||||||
'title': options?.title || 'AI建议',
|
'title': options?.title || 'AI建议',
|
||||||
type: 1,
|
type: 1,
|
||||||
area: options?.area || ['42%', '60%'],
|
area: options?.area || (admin.checkMobile() ? ['95%', '60%'] : ['50%', '60%']),
|
||||||
shade: options?.shade || 0,
|
shade: options?.shade || 0,
|
||||||
shadeClose: options?.shadeClose || false,
|
shadeClose: options?.shadeClose || false,
|
||||||
scrollbar: options?.scrollbar || false,
|
scrollbar: options?.scrollbar || false,
|
||||||
@@ -1795,11 +1803,23 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
|||||||
success: function (layero, index) {
|
success: function (layero, index) {
|
||||||
let elem = document.getElementById(id)
|
let elem = document.getElementById(id)
|
||||||
if (options?.stream) {
|
if (options?.stream) {
|
||||||
clearTimeout(aiStreamTimeout)
|
let index = 0;
|
||||||
aiStreamCurrentIndex = 0
|
let lastTime = performance.now();
|
||||||
setTimeout(() => {
|
const interval = options.interval || 100;
|
||||||
admin.ai.streamOutput(elem, content)
|
|
||||||
}, 300)
|
function typeCharacter(currentTime) {
|
||||||
|
if (index < content.length) {
|
||||||
|
if (currentTime - lastTime >= interval) {
|
||||||
|
elem.innerHTML += content.charAt(index);
|
||||||
|
index++;
|
||||||
|
lastTime = currentTime;
|
||||||
|
elem.scrollIntoView({behavior: "smooth", block: "end"});
|
||||||
|
}
|
||||||
|
requestAnimationFrame(typeCharacter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(typeCharacter);
|
||||||
} else {
|
} else {
|
||||||
content = content.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>')
|
content = content.replace(/\r\n/g, '<br>').replace(/\n/g, '<br>')
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -1812,28 +1832,8 @@ define(["jquery", "tableSelect", "miniTheme", "xmSelect", "lazyload"], function
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
streamOutput: function (dom, htmlContent) {
|
|
||||||
const chunkSize = 1;
|
|
||||||
let length = htmlContent.length;
|
|
||||||
if (aiStreamCurrentIndex < length) {
|
|
||||||
const endIndex = Math.min(aiStreamCurrentIndex + chunkSize, length);
|
|
||||||
const chunk = htmlContent.slice(aiStreamCurrentIndex, endIndex);
|
|
||||||
const tempDiv = document.createElement('div');
|
|
||||||
tempDiv.innerHTML = chunk;
|
|
||||||
while (tempDiv.firstChild) {
|
|
||||||
dom.appendChild(tempDiv.firstChild);
|
|
||||||
}
|
|
||||||
aiStreamCurrentIndex = endIndex;
|
|
||||||
aiStreamTimeout = setTimeout(() => {
|
|
||||||
admin.ai.streamOutput(dom, htmlContent);
|
|
||||||
dom.scrollIntoView({behavior: "smooth", block: "end"});
|
|
||||||
}, 60);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
var aiStreamCurrentIndex = 0;
|
|
||||||
var aiStreamTimeout = null;
|
|
||||||
|
|
||||||
return admin;
|
return admin;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user