Files
YwxAppThink/docs/tpl/table.html
T
ywxapp 1d49e6f5ee feat: 公共表更名 common/member 前缀 + 插件命令自动加载 + 版本 1.1.1
- 18 张公共表更名(addon/attachment/configure/links/spider_log/spider_stat/sms/notice/ad/task/prop/medal/help/card -> common_*,member_wallets->member_wallet,score_rule/score_log -> member_*,addon_config->common_addonconf),模型全部对齐新表名,Db 直引用清零
- Attachment 模型补  表名绑定,修复富文本上传查 wxapp_attachment 1146 隐患
- install.sql + 迁移 SQL:backend_admin/backend_role delete_at 默认 0,修复软删除(NULL != 0)误过滤导致后台菜单为空
- AppService::boot() 支持插件 info.php 声明 commands 自动注册插件命令(psr-4 自动加载,坏类名自动跳过)
- 各插件(haonav/mqttbroker/wxchat/articles/blog/forum 等)字段与配置同步调整
- 框架版本 1.1.0 -> 1.1.1
2026-08-20 20:19:15 +08:00

434 lines
18 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header"></div>
<div class="layui-card-body">
<table class="layui-hide" id="dataTable" lay-filter="dataTable"></table>
</div>
</div>
</div>
<!-- 表格顶部工具条 -->
<script type="text/html" id="tableBarTpl">
<div class="layui-btn-group">
<a
class="layui-btn layui-btn-sm layui-btn-primary"
title="新建数据"
lay-event="dataCreate"
data-perm="role:add">
<i class="layui-icon layui-icon-add-1"></i>
</a>
<a
class="layui-btn layui-btn-sm layui-btn-primary"
title="删除资源"
lay-event="dataDelete"
data-perm="role:delete"
><i class="layui-icon layui-icon-delete"></i>
</a>
<a
class="layui-btn layui-btn-sm layui-btn-primary"
title="资源回收站"
lay-event="dataRecybin"
data-perm="role:recyclebin"
><i class="layui-icon layui-icon-home"></i>
</a>
</div>
</script>
<!-- 表格数据工具条 -->
<script type="text/html" id="dataBarTpl">
<div class="layui-btn-group">
<a
class="layui-btn layui-btn-sm layui-btn-primary"
title="编辑数据"
lay-event="update"
data-perm="role:edit"
><i class="layui-icon layui-icon-edit"></i>
</a>
<a
class="layui-btn layui-btn-sm layui-btn-primary"
title="权限分配"
lay-event="permission"
data-perm="role:*"
><i class="layui-icon layui-icon-auz"></i>
</a>
{{# if(d.id > 1) { }}
<a
class="layui-btn layui-btn-sm layui-btn-primary"
title="删除数据"
lay-event="delete"
data-perm="role:delete"
><i class="layui-icon layui-icon-delete"></i>
</a>
{{# } }}
</div>
</script>
<!-- 表格回收站 -->
<script type="text/html" id="dataRecybinTpl">
<div class="layui-card">
<div class="layui-card-header"></div>
<div class="layui-card-body">
<table
class="layui-hide"
id="dataRecybinTable"
lay-filter="dataRecybinTable"></table>
</div>
</div>
</script>
<!-- 角色状态 -->
<script type="text/html" id="statusTpl">
{{# if(d.status == 1) { }}
<span class="layui-badge layui-bg-green">正常</span>
{{# } else { }}
<span class="layui-badge layui-bg-orange">禁用</span>
{{# } }}
</script>
<!-- 添加/编辑角色表单 -->
<script type="text/html" id="dataFormTpl">
<form class="layui-form layui-form-pane" lay-filter="wxapp-form" id="wxapp-form">
<input type="hidden" name="id" value="{{d.id||''}}">
<div class="layui-form-item">
<label class="layui-form-label">角色名称</label>
<div class="layui-input-block">
<input type="text" name="title" required lay-verify="required" placeholder="请输入角色名称" autocomplete="off" class="layui-input" value="{{d.title||''}}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">编码</label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" placeholder="请输入分组编码" autocomplete="off" class="layui-input" value="{{d.name||''}}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">角色描述</label>
<div class="layui-input-block">
<textarea name="description" placeholder="请输入角色描述" class="layui-textarea">{{d.description||''}}</textarea>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">状态</label>
<div class="layui-input-block">
<input type="radio" name="status" value="1" title="启用" {{ d.status==undefined || d.status==1 ? 'checked' : '' }}>
<input type="radio" name="status" value="0" title="禁用" {{ d.status==0 ? 'checked' : '' }}>
</div>
</div>
<div class="layui-form-item layui-hide">
<button class="layui-btn" lay-submit="" lay-filter="wxapp-form-submit" id="wxapp-form-submit">提交</button>
</div>
</form>
</script>
<!-- 权限分配弹窗 -->
<script type="text/html" id="permissionFormTpl">
<div class="layui-card">
<div class="layui-card-header">
角色{{d.name}}
<span style="color:#999;font-weight:normal;">(ID: {{d.id}})</span>
</div>
<div class="layui-card-body">
<div id="permissionTree"></div>
</div>
</div>
</script>
<script>
layui.use(['http', 'auth'], function () {
var $ = layui.$, table = layui.table, form = layui.form, layer = layui.layer
, laydate = layui.laydate, laytpl = layui.laytpl, tree = layui.tree, http = layui.http
, auth = layui.auth;
var _savedPerms = (layui.data('backend').permission) || [];
auth.init(_savedPerms);
auth.setController('group');
var dataTable = table.render({
elem: '#dataTable'
, url: 'index' // 后端数据接口
, page: true
, limit: 15
, toolbar: '#tableBarTpl'
, cols: [[
{ type: 'checkbox', fixed: 'left' }
, { field: 'id', title: 'ID', width: 60, align: 'center', sort: true, fixed: 'left' }
, { field: 'title', title: '名称', width: 150, align: 'center', fixed: 'left' }
, { field: 'name', title: '代码', width: 150, align: 'center', fixed: 'left' }
, { field: 'description', title: '描述', minWidth: 200, align: 'left' }
, { field: 'status', title: '状态', width: 120, align: 'center', templet: '#statusTpl' }
, { field: 'create_time', title: '创建时间', width: 160, align: 'center', sort: true }
, { title: '操作', width: 160, align: 'left', toolbar: '#dataBarTpl', fixed: 'right', unresize: true }
]]
, done: function (res, curr, count) {
var view = $('#dataTable').next('.layui-table-view');
view.find('[data-perm]').each(function () {
var perm = $(this).attr('data-perm');
if (perm && !auth.has(perm)) { $(this).remove(); }
});
$('.layui-btn[data-perm]').each(function () {
var perm = $(this).attr('data-perm');
if (perm && !auth.has(perm)) { $(this).remove(); }
});
}
});
table.on('toolbar(dataTable)', function (elem) {
switch (elem.event) {
case 'dataCreate':
active.dataCreate({ pid: 0, type: 1 });
break;
case 'dataDelete':
var checkStatus = table.checkStatus('dataTable'), checkData = checkStatus.data;
let ids = checkData.map((item, index, array) => { return item.id; });
active.dataDelete(ids);
break;
case 'dataRecybin':
active.dataRecybin();
break;
};
});
table.on('tool(dataTable)', function (elem) {
var data = elem.data;
switch (elem.event) {
case 'update':
active.dataEdit(data);
break;
case 'permission':
openPermissionForm(data);
break;
case 'delete':
active.dataDelete([data.id]);
break;
}
});
var dataFromFun = function (data, callback, done) {
var title = data ? '编辑数据[' + data.account + ']' : '添加数据';
var formHtml = laytpl($('#dataFormTpl').html()).render(data || {});
layer.open({
title: data.id ? '编辑菜单' : (data.pid ? '添加子菜单' : '添加根菜单'),
content: formHtml,
anim: "slideLeft",
offset: "r",
btnAlign: "l",
area: ['50% ', '99%'],
shade: 0.1,
shadeClose: true,
btn: ['确定', '取消'],
success: function (layero, index) {
callback(layero, index);
form.render();
},
yes: function (index, layero) {
window.layui.form.on('submit(wxapp-form-submit)', function (elem) {
done(layero, index, elem);
layui.off('submit(wxapp-form)', 'from');
return false;
});
layero.contents().find("#wxapp-form-submit").trigger('click');
}
});
};
//事件
var active = {
dataDelete: function (ids, force = 0) {
if (ids.length === 0) {
return layer.msg('请选择数据');
}
layer.prompt({
formType: 1
, title: '敏感操作,请验证口令'
}, function (value, index) {
layer.close(index);
layer.confirm('确定删除吗?', function (index) {
http.delete("delete", { ids: ids.join(','), force: force })
.then((res) => {
if (res.code === 0) {
layer.close(index);
table.reload('dataTable', {}, true);
} else {
layer.msg(res.msg || '操作失败');
}
});
});
});
},
dataCreate: function (data = {}) {
dataFromFun(data,
function (layero, index) { },
function (layero, index, elem) {
var field = elem.field;
http.post('save', field)
.then((res) => {
if (res.code === 0) {
layer.close(index);
table.reload('dataTable', {}, true);
} else {
layer.msg(res.msg || '操作失败');
}
});
}
);
},
dataEdit: function (data = {}) {
dataFromFun(data,
function (layero, index) { },
function (layero, index, elem) {
var field = elem.field;
http.put('update', field)
.then((res) => {
if (res.code === 0) {
layer.close(index);
table.reload('dataTable', {}, true);
} else {
layer.msg(res.msg || '操作失败');
}
});
}
);
},
dataRecybin: function (data = {}) {
var formHtml = laytpl($('#dataRecybinTpl').html()).render(data || {});
layer.open({
title: '资源回收站',
content: formHtml,
anim: "slideLeft",
offset: "r",
area: ['50%', '99%'],
shade: 0.1,
shadeClose: true,
success: function (layero, index) {
table.render({
elem: '#dataRecybinTable',
url: "recyclebin",
defaultToolbar: [{
title: '批量删除数据',
layEvent: 'dataDelete',
icon: 'layui-icon-delete',
onClick: function (obj) {
var checkStatus = table.checkStatus('dataRecybinTable'), checkData = checkStatus.data;
let ids = checkData.map((item, index, array) => { return item.id; });
console.log(ids);
}
}, 'filter', 'exports', 'print'],
cols: [[
{ type: 'checkbox', fixed: 'left' },
{ field: 'id', title: 'ID', width: 80, sort: true, fixed: 'left' },
{ field: 'title', title: '名称', width: 180, fixed: 'left' },
{ field: 'name', title: '代码', width: 180, fixed: 'left' },
{ field: 'description', title: '描述', minWidth: 200, sort: true },
{
fixed: "right", title: "操作", width: 120, align: "center", templet: function (d) {
return `<div class="layui-btn-group">
<a class="layui-btn layui-btn-sm" title="恢复数据" lay-event="restore" > <i class="layui-icon layui-icon-edit"></i> </a >
<a class="layui-btn layui-btn-sm" title="删除数据" lay-event="delete"><i class="layui-icon layui-icon-delete"></i> </a>
</div >`;
}
}
]],
page: true,
done: function () {
table.on('tool(dataRecybinTable)', function (elem) {
var data = elem.data;
switch (elem.event) {
case 'restore':
active.dataRestore([data.id]);
break;
case 'delete':
active.dataDelete([data.id], 1);
break;
}
});
table.on('toolbar(dataRecybinTable)', function (elem) {
switch (elem.event) {
case 'dataDelete':
var checkStatus = table.checkStatus('dataRecybinTable'), checkData = checkStatus.data;
let idss = checkData.map((item, index, array) => { return item.id; });
active.dataDelete(idss, 1);
break;
case 'dataRestore':
var checkStatus = table.checkStatus('dataRecybinTable'), checkData = checkStatus.data;
let ids = checkData.map((item, index, array) => { return item.id; });
active.dataRestore(ids);
break;
};
});
}
});
}
});
},
dataRestore: function (ids) {
if (ids.length === 0) {
return layer.msg('请选择数据');
}
http.put("restore", { ids: ids.join(',') })
.then((res) => {
if (res.code === 0) {
layer.msg('恢复成功');
table.reload('dataTable', {}, true);
} else {
layer.msg(res.msg || '恢复失败');
}
});
}
};
// 打开权限分配表单
function openPermissionForm(data) {
var title = '分配权限 [' + data.name + ']';
var formHtml = laytpl($('#permissionFormTpl').html()).render(data);
var index = layer.open({
anim: "slideLeft",
offset: "r",
btnAlign: "l",
area: ['50% ', '99%'],
shade: 0.1,
shadeClose: true,
content: formHtml,
success: function (layero, index) {
http.get("permission", { id: data.id })
.then((res) => {
if (res.code === 0) {
tree.render({
elem: '#permissionTree',
data: res.data,
showCheckbox: true,
id: 'permissionTree'
});
} else {
layer.msg(res.msg || '获取权限失败', { icon: 2 });
}
});
},
btn: ['保存', '取消'],
yes: function (index, layero) {
var checkedData = layui.tree.getChecked('permissionTree');
var permissionIds = [];
function getIds(data) {
data.forEach(function (item) {
permissionIds.push(item.id);
if (item.children && item.children.length > 0) {
getIds(item.children);
}
});
}
getIds(checkedData);
http.put("permission", {
id: data.id,
permissions: permissionIds
}).then((res) => {
if (res.code === 0) {
layer.msg(res.msg || '保存成功', { icon: 1, time: 1000 }, function () {
layer.close(index);
});
} else {
layer.msg(res.msg || '保存失败', { icon: 2 });
}
});
}
});
}
});
</script>