初始化提交
This commit is contained in:
451
app/manager/view/package_auth/auth_detail.html
Normal file
451
app/manager/view/package_auth/auth_detail.html
Normal file
@@ -0,0 +1,451 @@
|
||||
<!-- 权限详情弹窗模板 -->
|
||||
<div class="detail-container" style="padding: 20px;" data-user-id="{{d.userId}}">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<!-- 左侧已授权包名列表 -->
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
授权的包名列表
|
||||
<div class="layui-inline" style="width: 200px; margin-left: 10px;">
|
||||
<input type="text" id="searchAuthorized" placeholder="输入包名或应用名称搜索" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card-body auth-table-container">
|
||||
<table id="authorizedTable" lay-filter="authorizedTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧可授权包名列表 -->
|
||||
<div class="layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
可授权的包名列表
|
||||
<span class="layui-badge layui-bg-blue">仅显示启用状态的包名</span>
|
||||
<div class="layui-inline" style="width: 200px; margin-left: 10px;">
|
||||
<input type="text" id="searchPackage" placeholder="输入包名或应用名称搜索" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card-body auth-table-container">
|
||||
<table id="unauthorizedTable" lay-filter="unauthorizedTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<div class="layui-form-item text-center" style="margin-top:15px;">
|
||||
<button class="layui-btn layui-btn-primary" onclick="closeAndRefresh()">关闭窗口</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已授权表格工具栏 -->
|
||||
<script type="text/html" id="authDetailAuthorizedToolbar">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="batchRemove" lay-tips="移除选中的包名权限">
|
||||
<i class="layui-icon"></i> 批量移除
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="removeAll" lay-tips="移除该管理员的所有包名权限">
|
||||
<i class="layui-icon"></i> 一键全部移除
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- 未授权表格工具栏 -->
|
||||
<script type="text/html" id="authDetailUnauthorizedToolbar">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm layui-btn-normal" lay-event="batchAuth" lay-tips="授权选中的包名">
|
||||
<i class="layui-icon"></i> 批量授权
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-sm layui-btn-warm" lay-event="authAll" lay-tips="授权所有未授权的包名">
|
||||
<i class="layui-icon"></i> 一键全部授权
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- 表格行工具条 -->
|
||||
<script type="text/html" id="authDetailTableBar">
|
||||
<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="remove">移除</a>
|
||||
</script>
|
||||
|
||||
<script type="text/html" id="authDetailUnAuthTableBar">
|
||||
<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="auth">授权</a>
|
||||
</script>
|
||||
|
||||
<!-- 表格初始化脚本 -->
|
||||
<script>
|
||||
window.initAuthDetailTables = function(userId) {
|
||||
layui.use(['table', 'form'], function() {
|
||||
let table = layui.table;
|
||||
|
||||
// 初始化已授权表格
|
||||
table.render({
|
||||
elem: '#authorizedTable',
|
||||
url: '{:url("getAuthDetailData")}',
|
||||
where: {
|
||||
user_id: userId,
|
||||
type: 'authorized'
|
||||
},
|
||||
toolbar: '#authDetailAuthorizedToolbar',
|
||||
defaultToolbar: ['filter'],
|
||||
page: true,
|
||||
limit: 10,
|
||||
limits: [10, 20, 50, 100],
|
||||
cols: [[
|
||||
{type: 'checkbox', width: 50},
|
||||
{field: 'package_name', title: '包名', minWidth: 250},
|
||||
{field: 'name', title: '名称', minWidth: 200},
|
||||
{field: 'create_at', title: '授权时间', width: 160},
|
||||
{title: '操作', toolbar: '#authDetailTableBar', width: 80, align: 'center', fixed: 'right'}
|
||||
]]
|
||||
});
|
||||
|
||||
// 初始化未授权表格
|
||||
table.render({
|
||||
elem: '#unauthorizedTable',
|
||||
url: '{:url("getAuthDetailData")}',
|
||||
where: {
|
||||
user_id: userId,
|
||||
type: 'unauthorized'
|
||||
},
|
||||
toolbar: '#authDetailUnauthorizedToolbar',
|
||||
defaultToolbar: ['filter'],
|
||||
page: true,
|
||||
limit: 10,
|
||||
limits: [10, 20, 50, 100],
|
||||
cols: [[
|
||||
{type: 'checkbox', width: 50},
|
||||
{field: 'package_name', title: '包名', minWidth: 250},
|
||||
{field: 'name', title: '名称', minWidth: 200},
|
||||
{title: '操作', toolbar: '#authDetailUnAuthTableBar', width: 80, align: 'center', fixed: 'right'}
|
||||
]]
|
||||
});
|
||||
|
||||
// 绑定搜索事件
|
||||
bindSearchEvents(table, userId);
|
||||
// 绑定工具条事件
|
||||
bindTableEvents(table, userId);
|
||||
});
|
||||
};
|
||||
|
||||
// 绑定搜索事件
|
||||
function bindSearchEvents(table, userId) {
|
||||
let searchTimeout;
|
||||
$('#searchAuthorized').on('input', function() {
|
||||
clearTimeout(searchTimeout);
|
||||
let value = this.value;
|
||||
searchTimeout = setTimeout(function() {
|
||||
table.reload('authorizedTable', {
|
||||
where: {
|
||||
user_id: userId,
|
||||
type: 'authorized',
|
||||
keyword: value
|
||||
},
|
||||
page: {curr: 1}
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
|
||||
$('#searchPackage').on('input', function() {
|
||||
clearTimeout(searchTimeout);
|
||||
let value = this.value;
|
||||
searchTimeout = setTimeout(function() {
|
||||
table.reload('unauthorizedTable', {
|
||||
where: {
|
||||
user_id: userId,
|
||||
type: 'unauthorized',
|
||||
keyword: value
|
||||
},
|
||||
page: {curr: 1}
|
||||
});
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
// 绑定工具条事件
|
||||
function bindTableEvents(table, userId) {
|
||||
// 已授权表格工具条事件
|
||||
table.on('toolbar(authorizedTable)', function(obj) {
|
||||
if (obj.event === 'batchRemove') {
|
||||
let checkStatus = table.checkStatus('authorizedTable');
|
||||
if (checkStatus.data.length === 0) {
|
||||
layer.msg('请选择要移除的包名', {icon: 2});
|
||||
return;
|
||||
}
|
||||
|
||||
layer.confirm('确定要移除选中的 ' + checkStatus.data.length + ' 个包名权限吗?', {
|
||||
title: '批量移除确认',
|
||||
btn: ['确定移除', '取消操作'],
|
||||
skin: 'layer-danger'
|
||||
}, function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
let packageIds = checkStatus.data.map(item => item.id);
|
||||
$.post('{:url("batchRemoveAuth")}', {
|
||||
user_id: userId,
|
||||
package_ids: packageIds
|
||||
}, function(res) {
|
||||
layer.close(loadIndex);
|
||||
layer.msg(res.info);
|
||||
if (res.code === 1) {
|
||||
// 刷新两个表格
|
||||
table.reload('authorizedTable');
|
||||
table.reload('unauthorizedTable');
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
} else if (obj.event === 'removeAll') {
|
||||
layer.confirm('确定要移除该管理员的所有包名权限吗?<br>此操作不可恢复!', {
|
||||
title: '危险操作',
|
||||
btn: ['确定移除', '取消操作'],
|
||||
icon: 2,
|
||||
skin: 'layer-danger'
|
||||
}, function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
$.post('{:url("clearAuth")}', {
|
||||
user_ids: [userId]
|
||||
}, function(res) {
|
||||
layer.close(loadIndex);
|
||||
layer.msg(res.info);
|
||||
if (res.code === 1) {
|
||||
// 刷新两个表格
|
||||
table.reload('authorizedTable');
|
||||
table.reload('unauthorizedTable');
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 未授权表格工具条事件
|
||||
table.on('toolbar(unauthorizedTable)', function(obj) {
|
||||
if (obj.event === 'batchAuth') {
|
||||
let checkStatus = table.checkStatus('unauthorizedTable');
|
||||
if (checkStatus.data.length === 0) {
|
||||
layer.msg('请选择要授权的包名', {icon: 2});
|
||||
return;
|
||||
}
|
||||
|
||||
layer.confirm('确定要授权选中的 ' + checkStatus.data.length + ' 个包名吗?', {
|
||||
title: '批量授权确认',
|
||||
btn: ['确定授权', '取消操作']
|
||||
}, function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
let packageIds = checkStatus.data.map(item => item.id);
|
||||
$.post('{:url("addAuth")}', {
|
||||
user_id: userId,
|
||||
package_ids: packageIds
|
||||
}, function(res) {
|
||||
layer.close(loadIndex);
|
||||
layer.msg(res.info);
|
||||
if (res.code === 1) {
|
||||
// 刷新两个表格
|
||||
table.reload('authorizedTable');
|
||||
table.reload('unauthorizedTable');
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
} else if (obj.event === 'authAll') {
|
||||
layer.confirm('确定要授权所有可用的包名吗?', {
|
||||
title: '一键全部授权',
|
||||
btn: ['确定授权', '取消操作'],
|
||||
icon: 3
|
||||
}, function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
$.post('{:url("addAuth")}', {
|
||||
user_id: userId,
|
||||
is_all: 1
|
||||
}, function(res) {
|
||||
layer.close(loadIndex);
|
||||
layer.msg(res.info);
|
||||
if (res.code === 1) {
|
||||
// 刷新两个表格
|
||||
table.reload('authorizedTable');
|
||||
table.reload('unauthorizedTable');
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 单个移除事件
|
||||
table.on('tool(authorizedTable)', function(obj) {
|
||||
if (obj.event === 'remove') {
|
||||
layer.confirm('确定要移除此包名权限吗?', function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
$.post('{:url("removeAuth")}', {
|
||||
user_id: userId,
|
||||
package_id: obj.data.id
|
||||
}, function(res) {
|
||||
layer.close(loadIndex);
|
||||
layer.msg(res.info);
|
||||
if (res.code === 1) {
|
||||
obj.del();
|
||||
// 刷新未授权表格
|
||||
table.reload('unauthorizedTable');
|
||||
}
|
||||
});
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 单个授权事件
|
||||
table.on('tool(unauthorizedTable)', function(obj) {
|
||||
if (obj.event === 'auth') {
|
||||
let loadIndex = layer.load(2);
|
||||
$.post('{:url("addAuth")}', {
|
||||
user_id: userId,
|
||||
package_ids: [obj.data.id]
|
||||
}, function(res) {
|
||||
layer.close(loadIndex);
|
||||
layer.msg(res.info);
|
||||
if (res.code === 1) {
|
||||
// 刷新两个表格
|
||||
table.reload('authorizedTable');
|
||||
table.reload('unauthorizedTable');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 添加关闭并刷新的函数
|
||||
function closeAndRefresh() {
|
||||
// 关闭当前弹窗
|
||||
layer.closeAll();
|
||||
// 刷新父页面
|
||||
parent.location.reload();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- 弹窗专用样式 -->
|
||||
<style>
|
||||
.detail-container {
|
||||
min-height: 600px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.detail-container .layui-row {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.detail-container .layui-card {
|
||||
margin-bottom: 0;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.detail-container .layui-card-body {
|
||||
flex: 1;
|
||||
padding: 15px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.auth-table-container {
|
||||
min-height: 550px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 搜索框样式 */
|
||||
.detail-container .layui-inline {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.detail-container .layui-input {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
/* 底部按钮样式 */
|
||||
.detail-container .layui-form-item.text-center {
|
||||
padding: 10px 0 0;
|
||||
margin: 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
/* 表格美化样式 */
|
||||
.auth-table-container .layui-table-tool {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
/* 表格头部样式 */
|
||||
.auth-table-container .layui-table-header {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
/* 表格内容区域样式 */
|
||||
.auth-table-container .layui-table-body {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 工具栏按钮样式优化 */
|
||||
.auth-table-container .layui-table-tool {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
padding: 0 15px;
|
||||
font-size: 12px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn .layui-icon {
|
||||
font-size: 14px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
/* 危险操作按钮样式 */
|
||||
.auth-table-container .layui-table-tool .layui-btn-danger {
|
||||
background-color: #FF5722;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn-danger:hover {
|
||||
background-color: #ff4208;
|
||||
}
|
||||
|
||||
/* 一键全部授权按钮样式 */
|
||||
.auth-table-container .layui-table-tool .layui-btn-warm {
|
||||
background-color: #FFB800;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn-warm:hover {
|
||||
background-color: #ff9900;
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.layer-danger .layui-layer-title {
|
||||
background-color: #FF5722 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.layer-danger .layui-layer-btn0 {
|
||||
background-color: #FF5722 !important;
|
||||
border-color: #FF5722 !important;
|
||||
}
|
||||
|
||||
/* 确保弹窗控制按钮在正确位置 */
|
||||
.layui-layer-page .layui-layer-setwin {
|
||||
position: absolute !important;
|
||||
right: 15px !important;
|
||||
top: 16px !important;
|
||||
}
|
||||
</style>
|
||||
786
app/manager/view/package_auth/index.html
Normal file
786
app/manager/view/package_auth/index.html
Normal file
@@ -0,0 +1,786 @@
|
||||
{extend name="../../admin/view/main"}
|
||||
|
||||
{block name='content'}
|
||||
<style>
|
||||
/* 基础样式 */
|
||||
.layui-card-body {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.layui-table-tool {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.layui-table-page {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.layui-table-box {
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 2px rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
/* 时间选择器样式 */
|
||||
#dateRange {
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.layui-inline .layui-input {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.layui-inline .layui-btn {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 在主容器前添加操作指南 -->
|
||||
<div class="think-box-shadow" style="margin-bottom: 15px; padding: 15px;">
|
||||
<h3 class="layui-inline" style="margin-right: 15px;">操作指南</h3>
|
||||
<button class="layui-btn layui-btn-sm" id="showGuide">展开/收起</button>
|
||||
<div class="guide-content layui-hide" style="margin-top: 10px;">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-elem-quote" style="border-left: 5px solid #009688;">
|
||||
<h4>基本说明:</h4>
|
||||
<p>本页面用于管理不同管理员的包名权限,可以进行查看、添加、移除等操作。</p>
|
||||
</div>
|
||||
|
||||
<div class="layui-elem-quote" style="border-left: 5px solid #FFB800;">
|
||||
<h4>操作步骤:</h4>
|
||||
<ol>
|
||||
<li>左侧列表显示所有可配置权限的管理员</li>
|
||||
<li>绿色标签表示已授权包名数量,灰色表示未授权</li>
|
||||
<li>点击【查看权限】可以查看和修改该管理员的包名权限</li>
|
||||
<li>击【批量授权】可以同时给多个管理员授权相同的包名</li>
|
||||
<li>点击【清空权限】可以清除选中管理员的所有包名权限</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="layui-elem-quote" style="border-left: 5px solid #FF5722;">
|
||||
<h4>权限配置窗口说明:</h4>
|
||||
<ol>
|
||||
<li>左侧显示已授权的包名列表,可以搜索和移除</li>
|
||||
<li>右侧显示可授权的包名列表,仅显示启用状态的包名</li>
|
||||
<li>在右侧勾选包名后点击【保存配置】即可添加授权</li>
|
||||
<li>两侧都支持搜索功能,可以快速查找包名</li>
|
||||
<li>所有操作都会实时更新显示结果</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="layui-elem-quote" style="border-left: 5px solid #01AAED;">
|
||||
<h4>注意事项:</h4>
|
||||
<ol>
|
||||
<li>批量授权会覆盖已有的权限配置,请谨慎操作</li>
|
||||
<li>清空权限操作不可恢复,请确认后再操作</li>
|
||||
<li>建议先使用搜索功能查找包名,再进行授权作</li>
|
||||
<li>可以使用全选功能快速选择多个管理员或包名</li>
|
||||
<li>如有疑问请联系技术支持</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="think-box-shadow main-container">
|
||||
<div class="layui-row layui-col-space15">
|
||||
<!-- 左侧管理员列表 -->
|
||||
<div class="layui-col-md3">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
管理员列表
|
||||
<div class="layui-layout-right" style="margin:5px;">
|
||||
<span class="layui-badge layui-bg-blue" style="padding: 5px 10px;">共 {$users|count} 人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card-body user-list-container">
|
||||
<form class="layui-form" lay-filter="userForm">
|
||||
<!-- 添加搜索框 -->
|
||||
<div class="search-box">
|
||||
<div class="layui-form-item" style="margin-bottom: 10px;">
|
||||
<div class="layui-input-block" style="margin-left: 0;">
|
||||
<input type="text" id="searchUsers" placeholder="输入管理员名称搜索" class="layui-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 全选复选框 -->
|
||||
<div class="layui-form-item" style="padding: 10px;">
|
||||
<input type="checkbox" lay-filter="checkAllUsers" title="全选" lay-skin="primary" lay-tips="选中/取消选中所有管理员">
|
||||
</div>
|
||||
|
||||
<!-- 管理员列表 -->
|
||||
<div class="user-list">
|
||||
{foreach $users as $user}
|
||||
<div class="layui-form-item">
|
||||
<input type="checkbox" name="user_ids[]" value="{$user.id}" title="{$user.username}" lay-skin="primary">
|
||||
{if isset($authMap[$user.id])}
|
||||
<span class="layui-badge layui-bg-green" style="margin-left:10px; padding: 4px 8px;">已授权 {$authMap[$user.id]|count} 个包名</span>
|
||||
<a class="layui-btn layui-btn-normal layui-btn-sm" data-user="{$user.id}" lay-event="showAuth" style="margin-left:5px;" lay-tips="点击查看和修改该管理员的包名权限配置">
|
||||
<i class="layui-icon layui-icon-edit"></i> 查看权限
|
||||
</a>
|
||||
{else}
|
||||
<span class="layui-badge layui-bg-gray" style="margin-left:10px; padding: 4px 8px;">未授权</span>
|
||||
<a class="layui-btn layui-btn-warm layui-btn-sm" data-user="{$user.id}" lay-event="showAuth" style="margin-left:5px;" lay-tips="点击为该管理员添加包名权限">
|
||||
<i class="layui-icon layui-icon-add-1"></i> 添加权限
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
{/foreach}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧包名列表 -->
|
||||
<div class="layui-col-md9">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header">
|
||||
包名权限配置
|
||||
<div class="layui-layout-right header-btns">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit lay-filter="batchAuth" lay-tips="选中管理员和包名后,点击此处进行批量授权操作">
|
||||
<i class="layui-icon layui-icon-add-circle"></i> 批量授权
|
||||
</button>
|
||||
<button class="layui-btn layui-btn-danger" id="clearAuth" lay-tips="清空选中管理员的所有包名权限,请谨慎操作">
|
||||
<i class="layui-icon layui-icon-delete"></i> 清空权限
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<!-- 搜索框 -->
|
||||
<div class="layui-form-item" style="margin-bottom: 10px;">
|
||||
<div class="layui-inline" style="width: 250px;">
|
||||
<input type="text" id="searchPackages" placeholder="输入包名或应用名称搜索" class="layui-input">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<input type="text" id="dateRange" placeholder="选择时间范围" class="layui-input" readonly lay-tips="选择时间范围进行筛选">
|
||||
</div>
|
||||
<div class="layui-inline">
|
||||
<button class="layui-btn layui-btn-primary" id="resetFilter" lay-tips="清空所有筛选条件">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 表格 -->
|
||||
<table id="packageTable" lay-filter="packageTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 修改权限详情模板引用 -->
|
||||
<script type="text/html" id="authDetailTpl">
|
||||
{include file="package_auth/auth_detail"}
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<!-- JavaScript 部分 -->
|
||||
<script>
|
||||
// 全局配置
|
||||
var CONFIG = {
|
||||
pageSize: 10,
|
||||
loadingTime: 1000,
|
||||
debounceDelay: 300
|
||||
};
|
||||
|
||||
// 消息提示
|
||||
var MSG = {
|
||||
networkError: '网络错误,请稍后重试!',
|
||||
selectAdmin: '请选择管理员',
|
||||
selectPackage: '请选择包名',
|
||||
confirmClear: '确定要清空权限吗?此操作不可恢复!',
|
||||
confirmBatchAuth: '确定要批量授权吗?<br>此操作将覆盖已有权限!',
|
||||
getUserFailed: '获取用户信息失败',
|
||||
authSuccess: '授权成功!',
|
||||
clearSuccess: '清空成功!'
|
||||
};
|
||||
|
||||
// 防抖函数
|
||||
function debounce(fn, delay) {
|
||||
let timer = null;
|
||||
return function() {
|
||||
let context = this, args = arguments;
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(function() {
|
||||
fn.apply(context, args);
|
||||
}, delay);
|
||||
};
|
||||
}
|
||||
|
||||
// 成功提示
|
||||
function showSuccess(msg, callback) {
|
||||
layer.msg(msg, {
|
||||
icon: 1,
|
||||
time: CONFIG.loadingTime,
|
||||
shade: 0.3
|
||||
}, callback);
|
||||
}
|
||||
|
||||
// 错误提示
|
||||
function showError(msg) {
|
||||
layer.msg(msg, {
|
||||
icon: 2,
|
||||
time: 2000,
|
||||
shade: 0.3
|
||||
});
|
||||
}
|
||||
|
||||
// 表格事件处理对象
|
||||
var TableEventHandler = {
|
||||
// 工具条事件
|
||||
tool: function(obj, callback) {
|
||||
var event = obj.event;
|
||||
var handlers = {
|
||||
remove: function() {
|
||||
layer.confirm('确定要移除此包名权限吗?', {
|
||||
title: '操作确认',
|
||||
btn: ['确定', '取消']
|
||||
}, function(index) {
|
||||
callback && callback(obj, index);
|
||||
});
|
||||
}
|
||||
};
|
||||
handlers[event] && handlers[event]();
|
||||
},
|
||||
|
||||
// 表头工具栏事件
|
||||
toolbar: function(obj, callback) {
|
||||
var event = obj.event;
|
||||
var handlers = {
|
||||
batchRemove: function() {
|
||||
var checkStatus = table.checkStatus(obj.config.id);
|
||||
if (!checkStatus.data.length) {
|
||||
layer.msg('请选择要移除的包名', {icon: 2});
|
||||
return;
|
||||
}
|
||||
layer.confirm('确定要移除选中的 ' + checkStatus.data.length + ' 个包名权限吗?', {
|
||||
title: '批量移除确认',
|
||||
btn: ['确定', '取消']
|
||||
}, function(index) {
|
||||
callback && callback(checkStatus.data, index);
|
||||
});
|
||||
}
|
||||
};
|
||||
handlers[event] && handlers[event]();
|
||||
}
|
||||
};
|
||||
|
||||
// 表格缓存对象
|
||||
var TableCache = {
|
||||
data: {},
|
||||
set: function(key, value) {
|
||||
this.data[key] = value;
|
||||
// 最多缓存100条数据
|
||||
var keys = Object.keys(this.data);
|
||||
if (keys.length > 100) {
|
||||
delete this.data[keys[0]];
|
||||
}
|
||||
},
|
||||
get: function(key) {
|
||||
return this.data[key];
|
||||
},
|
||||
clear: function() {
|
||||
this.data = {};
|
||||
}
|
||||
};
|
||||
|
||||
// 基础表格配置
|
||||
var baseTableConfig = {
|
||||
page: true,
|
||||
limit: 15,
|
||||
loading: true,
|
||||
text: {
|
||||
none: '暂无数据'
|
||||
},
|
||||
size: 'sm'
|
||||
};
|
||||
|
||||
layui.use(['table', 'form', 'laydate'], function() {
|
||||
let table = layui.table,
|
||||
form = layui.form,
|
||||
laydate = layui.laydate;
|
||||
|
||||
// 将 table 绑定到全局,以便其他函数使用
|
||||
window.packageAuthTable = table;
|
||||
|
||||
// 初始化时间选择器
|
||||
laydate.render({
|
||||
elem: '#dateRange',
|
||||
type: 'datetime',
|
||||
range: true,
|
||||
trigger: 'click',
|
||||
done: function(value, date){
|
||||
if(value) {
|
||||
var dates = value.split(' - ');
|
||||
table.reload('packageTable', {
|
||||
where: {
|
||||
start_time: dates[0],
|
||||
end_time: dates[1]
|
||||
},
|
||||
page: {curr: 1}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 重置筛选
|
||||
$('#resetFilter').on('click', function(){
|
||||
$('#searchPackages').val('');
|
||||
$('#dateRange').val('');
|
||||
table.reload('packageTable', {
|
||||
where: {
|
||||
keyword: '',
|
||||
start_time: '',
|
||||
end_time: ''
|
||||
},
|
||||
page: {curr: 1}
|
||||
});
|
||||
});
|
||||
|
||||
// 优化搜索功能
|
||||
$('#searchPackages').on('input', debounce(function(){
|
||||
var value = this.value;
|
||||
var dateRange = $('#dateRange').val();
|
||||
var dates = dateRange ? dateRange.split(' - ') : ['', ''];
|
||||
|
||||
table.reload('packageTable', {
|
||||
where: {
|
||||
keyword: value,
|
||||
start_time: dates[0],
|
||||
end_time: dates[1]
|
||||
},
|
||||
page: {curr: 1}
|
||||
});
|
||||
}, 300));
|
||||
|
||||
// 初始化包名权限配置表格
|
||||
table.render({
|
||||
elem: '#packageTable',
|
||||
url: '{:url("getPackageList")}',
|
||||
method: 'post',
|
||||
toolbar: true,
|
||||
defaultToolbar: ['filter', 'exports'],
|
||||
cols: [[
|
||||
{type: 'checkbox', width: 50},
|
||||
{field: 'package_name', title: '包名', sort: true},
|
||||
{field: 'name', title: '应用名称'}
|
||||
]],
|
||||
page: true,
|
||||
limit: 20,
|
||||
limits: [10, 20, 50, 100],
|
||||
height: 'full-120',
|
||||
text: {
|
||||
none: '暂无包名数据'
|
||||
},
|
||||
size: 'sm'
|
||||
});
|
||||
|
||||
// 管理员全选
|
||||
form.on('checkbox(checkAllUsers)', function(data){
|
||||
var checked = data.elem.checked;
|
||||
$('input[name="user_ids[]"]').prop('checked', checked);
|
||||
form.render('checkbox');
|
||||
});
|
||||
|
||||
// 启用包名全选
|
||||
form.on('checkbox(checkAllEnabled)', function(data){
|
||||
var checked = data.elem.checked;
|
||||
$(data.elem).closest('.layui-form-item').nextUntil('.layui-form-item:has(label:contains("禁用包名"))')
|
||||
.find('input[type="checkbox"]').prop('checked', checked);
|
||||
form.render('checkbox');
|
||||
});
|
||||
|
||||
// 禁用包全选
|
||||
form.on('checkbox(checkAllDisabled)', function(data){
|
||||
var checked = data.elem.checked;
|
||||
$(data.elem).closest('.layui-form-item').nextAll()
|
||||
.find('input[type="checkbox"]').prop('checked', checked);
|
||||
form.render('checkbox');
|
||||
});
|
||||
|
||||
// 批量授权按钮事件
|
||||
form.on('submit(batchAuth)', function(data) {
|
||||
let userIds = [];
|
||||
$('input[name="user_ids[]"]:checked').each(function() {
|
||||
userIds.push($(this).val());
|
||||
});
|
||||
|
||||
if(userIds.length === 0) {
|
||||
layer.msg('请选择要授权的管理员', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
|
||||
// 使用全局的 table 变量
|
||||
let checkStatus = window.packageAuthTable.checkStatus('packageTable');
|
||||
let packageIds = checkStatus.data.map(item => item.id);
|
||||
|
||||
if(packageIds.length === 0) {
|
||||
layer.msg('请选择要授权的包名', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
|
||||
layer.confirm('确定要批量授权吗?<br>此操作将覆盖已有权限!', {
|
||||
title: '操作确认',
|
||||
btn: ['确定', '取消'],
|
||||
icon: 3
|
||||
}, function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
$.ajax({
|
||||
url: '{:url("batchAuth")}',
|
||||
type: 'post',
|
||||
data: {
|
||||
user_ids: userIds,
|
||||
package_ids: packageIds
|
||||
},
|
||||
success: function(res) {
|
||||
layer.close(loadIndex);
|
||||
if(res.code === 1) {
|
||||
layer.msg(res.info, {icon: 1, time: 1000}, function() {
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.info, {icon: 2, time: 2000});
|
||||
}
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
// 清空权限按钮事件
|
||||
$('#clearAuth').click(function() {
|
||||
let userIds = [];
|
||||
$('input[name="user_ids[]"]:checked').each(function() {
|
||||
userIds.push($(this).val());
|
||||
});
|
||||
|
||||
if(userIds.length === 0) {
|
||||
layer.msg('请选择要清空权限的管理员', {icon: 2});
|
||||
return false;
|
||||
}
|
||||
|
||||
layer.confirm('确定要清空所选管理员的权限吗?<br>此操作不可恢复!', {
|
||||
title: '危险操作',
|
||||
btn: ['确定清空', '取消'],
|
||||
icon: 2
|
||||
}, function(index) {
|
||||
let loadIndex = layer.load(2);
|
||||
$.ajax({
|
||||
url: '{:url("clearAuth")}',
|
||||
type: 'post',
|
||||
data: {
|
||||
user_ids: userIds
|
||||
},
|
||||
success: function(res) {
|
||||
layer.close(loadIndex);
|
||||
if(res.code === 1) {
|
||||
layer.msg(res.info, {icon: 1, time: 1000}, function() {
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.info, {icon: 2, time: 2000});
|
||||
}
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 操作指南展开/收起
|
||||
$('#showGuide').click(function(){
|
||||
var $content = $('.guide-content');
|
||||
if ($content.hasClass('layui-hide')) {
|
||||
$content.removeClass('layui-hide').hide().slideDown();
|
||||
// 存储状态到 localStorage
|
||||
localStorage.setItem('packageAuthGuideShow', '1');
|
||||
} else {
|
||||
$content.slideUp(function(){
|
||||
$(this).addClass('layui-hide');
|
||||
});
|
||||
// 存储状态到 localStorage
|
||||
localStorage.setItem('packageAuthGuideShow', '0');
|
||||
}
|
||||
});
|
||||
|
||||
// 页面加载时检查是否需要显示操作指南
|
||||
if (localStorage.getItem('packageAuthGuideShow') === '1') {
|
||||
$('.guide-content').removeClass('layui-hide');
|
||||
}
|
||||
|
||||
// 初始化按钮提示
|
||||
$('[lay-tips]').each(function(){
|
||||
var tips = $(this).attr('lay-tips');
|
||||
if(tips) {
|
||||
layui.use('layer', function(){
|
||||
var layer = layui.layer;
|
||||
$(this).on('mouseenter', function(){
|
||||
this.index = layer.tips(tips, this, {
|
||||
tips: [1, '#3595CC'],
|
||||
time: 0
|
||||
});
|
||||
}).on('mouseleave', function(){
|
||||
layer.close(this.index);
|
||||
});
|
||||
}.bind(this));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 辅助函数
|
||||
function viewAuth(userId, username){
|
||||
$('[data-user="' + userId + '"][lay-event="showAuth"]').click();
|
||||
}
|
||||
|
||||
function clearSingleAuth(userId){
|
||||
layer.confirm('确定要清空此管理员的权限吗?', {
|
||||
title: '操作确认',
|
||||
btn: ['确定', '取消'],
|
||||
icon: 3,
|
||||
skin: 'layui-layer-molv'
|
||||
}, function(index){
|
||||
var loadIndex = layer.load(2);
|
||||
$.ajax({
|
||||
url: '{:url("clearAuth")}',
|
||||
type: 'post',
|
||||
data: {
|
||||
user_ids: [userId]
|
||||
},
|
||||
success: function(res){
|
||||
layer.close(loadIndex);
|
||||
if(res.code === 1){
|
||||
layer.msg(res.info, {icon: 1, time: 1000}, function(){
|
||||
location.reload();
|
||||
});
|
||||
} else {
|
||||
layer.msg(res.info, {icon: 2, time: 2000});
|
||||
}
|
||||
layer.close(index);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 将权限详情相关的函数抽取出来
|
||||
function showAuthDetail(userId, username) {
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: username + ' 的权限配置',
|
||||
area: ['1200px', '80%'],
|
||||
offset: '50px',
|
||||
moveType: 1,
|
||||
content: $('#authDetailTpl').html(),
|
||||
success: function(layero) {
|
||||
window.initAuthDetailTables(userId);
|
||||
// 隐藏默认的关闭按钮
|
||||
$(layero).find('.layui-layer-setwin').css({
|
||||
'display': 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 绑定查看权限按钮事件
|
||||
$(document).on('click', '[lay-event="showAuth"]', function() {
|
||||
let userId = $(this).data('user');
|
||||
let username = $(this).closest('.layui-form-item').find('input[type="checkbox"]').attr('title');
|
||||
showAuthDetail(userId, username);
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- 添加一些样式 -->
|
||||
<style>
|
||||
.guide-content ol {
|
||||
padding-left: 20px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
.guide-content ol li {
|
||||
line-height: 28px;
|
||||
color: #666;
|
||||
}
|
||||
.guide-content h4 {
|
||||
margin: 5px 0;
|
||||
color: #333;
|
||||
}
|
||||
.layui-elem-quote {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.context-menu-layer {
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,.1);
|
||||
background: none;
|
||||
}
|
||||
.context-menu {
|
||||
background: #fff;
|
||||
border-radius: 2px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
.context-menu .menu-item {
|
||||
padding: 8px 15px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
transition: all .2s;
|
||||
}
|
||||
.context-menu .menu-item:hover {
|
||||
background: #f2f2f2;
|
||||
color: #009688;
|
||||
}
|
||||
.context-menu .menu-item .layui-icon {
|
||||
margin-right: 5px;
|
||||
font-size: 14px;
|
||||
}
|
||||
.context-menu .menu-item[onclick*="clearSingleAuth"] {
|
||||
color: #FF5722;
|
||||
}
|
||||
.context-menu .menu-item[onclick*="clearSingleAuth"]:hover {
|
||||
background: #fff1f0;
|
||||
}
|
||||
|
||||
/* 管理员列表样式优化 */
|
||||
.user-list .layui-form-item {
|
||||
padding: 8px 0;
|
||||
margin-bottom: 5px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.user-list .layui-form-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.user-list .layui-btn-sm {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.user-list .layui-badge {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.user-list .layui-btn-normal {
|
||||
background-color: #1E9FFF;
|
||||
}
|
||||
|
||||
.user-list .layui-btn-warm {
|
||||
background-color: #FFB800;
|
||||
}
|
||||
|
||||
.user-list .layui-icon {
|
||||
font-size: 14px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
/* 美化搜索框 */
|
||||
.search-box .layui-input {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
/* 美化全选框 */
|
||||
.layui-form-item .layui-form-checkbox[lay-skin=primary] {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* 右侧顶部按钮样式优化 */
|
||||
.header-btns {
|
||||
margin: 3px 0;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.header-btns .layui-btn {
|
||||
height: 34px;
|
||||
line-height: 34px;
|
||||
padding: 0 15px;
|
||||
font-size: 13px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.header-btns .layui-btn .layui-icon {
|
||||
font-size: 14px;
|
||||
margin-right: 3px;
|
||||
}
|
||||
|
||||
.header-btns .layui-btn-normal {
|
||||
background-color: #1E9FFF;
|
||||
}
|
||||
|
||||
.header-btns .layui-btn-normal:hover {
|
||||
background-color: #0d8aff;
|
||||
}
|
||||
|
||||
.header-btns .layui-btn-danger {
|
||||
background-color: #FF5722;
|
||||
}
|
||||
|
||||
.header-btns .layui-btn-danger:hover {
|
||||
background-color: #ff4208;
|
||||
}
|
||||
|
||||
/* 提示框样式优化 */
|
||||
.layui-layer-tips {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
|
||||
.layui-layer-tips .layui-layer-content {
|
||||
padding: 8px 12px !important;
|
||||
line-height: 1.5 !important;
|
||||
border-radius: 2px !important;
|
||||
}
|
||||
|
||||
.layui-layer-tips i.layui-layer-TipsT {
|
||||
border-right-color: #3595CC !important;
|
||||
}
|
||||
|
||||
/* 危险操作弹窗样式 */
|
||||
.layer-danger .layui-layer-title {
|
||||
background-color: #FF5722 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.layer-danger .layui-layer-btn0 {
|
||||
background-color: #FF5722 !important;
|
||||
border-color: #FF5722 !important;
|
||||
}
|
||||
|
||||
/* 工具栏按钮样式 */
|
||||
.auth-table-container .layui-table-tool .layui-btn {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn-danger:hover {
|
||||
background-color: #ff4208;
|
||||
}
|
||||
|
||||
/* 正常操作弹窗样式 */
|
||||
.layer-normal .layui-layer-title {
|
||||
background-color: #1E9FFF !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.layer-normal .layui-layer-btn0 {
|
||||
background-color: #1E9FFF !important;
|
||||
border-color: #1E9FFF !important;
|
||||
}
|
||||
|
||||
/* 工具栏按钮样式补充 */
|
||||
.auth-table-container .layui-table-tool .layui-btn-normal {
|
||||
background-color: #1E9FFF;
|
||||
}
|
||||
|
||||
.auth-table-container .layui-table-tool .layui-btn-normal:hover {
|
||||
background-color: #0d8aff;
|
||||
}
|
||||
</style>
|
||||
{/block}
|
||||
Reference in New Issue
Block a user