Files
superlink/static/js/system.js
T
nanguaboss 71c6e8d9c1 v1.0.10
2026-08-03 00:07:01 +08:00

417 lines
18 KiB
JavaScript

/**
* system.js - 系统管理逻辑(用户管理 / 角色管理 / 操作日志)
* 页面:user.html / role.html / log.html
*/
$(function () {
var pageFile = location.pathname.split('/').pop();
if (pageFile === 'user.html') initUser();
else if (pageFile === 'role.html') initRole();
else if (pageFile === 'log.html') initLog();
else renderShell('权限管理', '系统管理');
});
/* ================= 用户管理 ================= */
function initUser() {
renderShell('用户管理', '权限管理 / 用户');
renderUserPage();
initPage('system', function (user) {
if (!checkPagePermission('system')) return;
loadUsers(1);
});
var currentPage = 1;
function renderUserPage() {
$('#page-content').html(
'<div class="card">' +
' <div class="toolbar">' +
' <input type="text" data-filter="keyword" placeholder="账号/姓名关键词">' +
' <select data-filter="role_id" id="filter-role"><option value="">全部角色</option></select>' +
' <button class="btn btn-primary" id="btn-search">搜索</button>' +
' <button class="btn" id="btn-reset">重置</button>' +
' <span class="spacer"></span>' +
' <button class="btn btn-success" id="btn-add">+ 新增用户</button>' +
' </div>' +
' <div class="table-wrap"><table class="grid">' +
' <thead><tr><th>ID</th><th>账号</th><th>姓名</th><th>角色</th><th>状态</th><th>最后登录</th><th>登录IP</th><th>创建时间</th><th>操作</th></tr></thead>' +
' <tbody id="user-tbody"></tbody>' +
' </table></div>' +
' <div class="pagination" id="pagination"></div>' +
'</div>'
);
}
function loadUsers(page) {
currentPage = page;
var params = buildFilterParam();
params.page = page;
params.limit = PAGE_SIZE;
httpGet('system/user_list.php', params).then(function (data) {
var rows = data.list || [];
var html = '';
rows.forEach(function (r) {
html += '<tr>' +
'<td>' + r.id + '</td>' +
'<td>' + escHtml(r.username) + '</td>' +
'<td>' + escHtml(r.real_name || '-') + '</td>' +
'<td>' + escHtml(r.role_name || '-') + '</td>' +
'<td>' + (r.is_active ? '<span class="tag tag-green">启用</span>' : '<span class="tag tag-red">禁用</span>') + '</td>' +
'<td>' + fmtDate(r.last_login_time) + '</td>' +
'<td>' + escHtml(r.last_login_ip || '-') + '</td>' +
'<td>' + fmtDate(r.created_at) + '</td>' +
'<td class="ops">' +
' <a onclick="editUser(' + r.id + ')">编辑</a>' +
(r.id != 1 ? ' <a class="danger" onclick="delUser(' + r.id + ')">删除</a>' : '') +
'</td></tr>';
});
if (!rows.length) {
html = '<tr><td colspan="9" class="empty-tip" style="padding:40px 0;">暂无用户</td></tr>';
}
$('#user-tbody').html(html);
// 角色下拉
var roles = data.roles || [];
var optHtml = '<option value="">全部角色</option>';
roles.forEach(function (r) {
optHtml += '<option value="' + r.id + '">' + escHtml(r.role_name) + '</option>';
});
$('#filter-role').html(optHtml);
renderPagination($('#pagination'), data, loadUsers);
});
}
$('#btn-search').on('click', function () { loadUsers(1); });
$('#btn-reset').on('click', function () {
$('.toolbar [data-filter]').val('');
loadUsers(1);
});
$('#btn-add').on('click', function () { openUserForm(null); });
window.editUser = function (id) {
var row = null;
$('#user-tbody tr').each(function () {
var $tds = $(this).find('td');
if ($tds.length && $tds.eq(0).text() == id) {
row = {
id: id,
username: $tds.eq(1).text(),
real_name: $tds.eq(2).text() === '-' ? '' : $tds.eq(2).text(),
role_name: $tds.eq(3).text(),
is_active: $tds.eq(4).find('.tag').hasClass('tag-green') ? 1 : 0
};
}
});
openUserForm(row);
};
function openUserForm(user) {
var isEdit = !!user;
var u = user || {};
var roleOptionsHtml = '';
$('#filter-role option').each(function () {
var $o = $(this);
if (!$o.val()) return;
roleOptionsHtml += '<option value="' + $o.val() + '"' + (u.role_name === $o.text() ? ' selected' : '') + '>' + escHtml($o.text()) + '</option>';
});
var content =
'<form id="user-form" style="padding:18px 22px 4px;">' +
'<div class="form-grid">' +
' <div class="form-item"><label>登录账号' + (isEdit ? '' : '<span class="req">*</span>') + '</label>' +
(isEdit ? '<input type="text" value="' + escHtml(u.username) + '" disabled>' : '<input type="text" name="username" placeholder="3-50位字母/数字/下划线">') + '</div>' +
' <div class="form-item"><label>真实姓名</label><input type="text" name="real_name" value="' + escHtml(u.real_name) + '"></div>' +
' <div class="form-item"><label>登录密码' + (isEdit ? '(留空不修改)' : '<span class="req">*</span>') + '</label><input type="password" name="password" placeholder="至少6位"></div>' +
' <div class="form-item"><label>角色<span class="req">*</span></label><select name="role_id">' + roleOptionsHtml + '</select></div>' +
' <div class="form-item"><label>状态</label><select name="is_active">' +
' <option value="1"' + (u.is_active !== 0 ? ' selected' : '') + '>启用</option>' +
' <option value="0"' + (u.is_active === 0 ? ' selected' : '') + '>禁用</option></select></div>' +
'</div>' +
'<div class="dialog-footer"><button type="button" class="btn" id="form-cancel">取消</button>' +
'<button type="submit" class="btn btn-primary">保存</button></div>' +
'</form>';
var idx = Dialog.open({
title: isEdit ? '编辑用户' : '新增用户',
area: ['560px', 'auto'],
content: content,
btn: false
});
$('#form-cancel').on('click', function () { Dialog.close(idx); });
$('#user-form').on('submit', function (e) {
e.preventDefault();
var data = {};
$(this).find('input, select').each(function () {
var name = $(this).attr('name');
if (!name) return;
data[name] = $(this).val();
});
if (isEdit) data.id = u.id;
httpPost(isEdit ? 'system/user_update.php' : 'system/user_add.php', data).then(function () {
Dialog.success('保存成功', function () {
Dialog.close(idx);
loadUsers(currentPage);
});
});
});
}
window.delUser = function (id) {
Dialog.confirm('确定删除该用户吗?', function () {
httpPost('system/user_delete.php', { id: id }).then(function () {
Dialog.success('删除成功', function () { loadUsers(currentPage); });
});
});
};
}
/* ================= 角色管理 ================= */
function initRole() {
renderShell('角色管理', '权限管理 / 角色');
renderRolePage();
initPage('system', function (user) {
if (!checkPagePermission('system')) return;
loadRoles(1);
});
var currentPage = 1;
function renderRolePage() {
$('#page-content').html(
'<div class="card">' +
' <div class="toolbar">' +
' <input type="text" data-filter="keyword" placeholder="角色名称关键词">' +
' <button class="btn btn-primary" id="btn-search">搜索</button>' +
' <button class="btn" id="btn-reset">重置</button>' +
' <span class="spacer"></span>' +
' <button class="btn btn-success" id="btn-add">+ 新增角色</button>' +
' </div>' +
' <div class="table-wrap"><table class="grid">' +
' <thead><tr><th>ID</th><th>角色名称</th><th>权限</th><th>用户数</th><th>状态</th><th>创建时间</th><th>操作</th></tr></thead>' +
' <tbody id="role-tbody"></tbody>' +
' </table></div>' +
' <div class="pagination" id="pagination"></div>' +
'</div>'
);
}
function loadRoles(page) {
currentPage = page;
var params = buildFilterParam();
params.page = page;
params.limit = PAGE_SIZE;
httpGet('system/role_list.php', params).then(function (data) {
var rows = data.list || [];
var html = '';
rows.forEach(function (r) {
var permTags = (r.permissions || []).map(function (p) {
var m = MENU_MAP[p];
return '<span class="tag" style="margin:2px 4px 2px 0;">' + (m ? escHtml(m.name) : escHtml(p)) + '</span>';
}).join('');
html += '<tr>' +
'<td>' + r.id + '</td>' +
'<td>' + escHtml(r.role_name) + '</td>' +
'<td>' + (permTags || '<span class="tag tag-gray">无权限</span>') + '</td>' +
'<td>' + r.user_count + '</td>' +
'<td>' + (r.is_active ? '<span class="tag tag-green">启用</span>' : '<span class="tag tag-red">禁用</span>') + '</td>' +
'<td>' + fmtDate(r.created_at) + '</td>' +
'<td class="ops">' +
(r.id != 1 ? ' <a onclick="editRole(' + r.id + ')">编辑</a>' : '') +
(r.id != 1 ? ' <a class="danger" onclick="delRole(' + r.id + ')">删除</a>' : '<span style="color:#b6bfcc;">内置</span>') +
'</td></tr>';
});
if (!rows.length) {
html = '<tr><td colspan="7" class="empty-tip" style="padding:40px 0;">暂无角色</td></tr>';
}
$('#role-tbody').html(html);
renderPagination($('#pagination'), data, loadRoles);
});
}
$('#btn-search').on('click', function () { loadRoles(1); });
$('#btn-reset').on('click', function () {
$('.toolbar [data-filter]').val('');
loadRoles(1);
});
$('#btn-add').on('click', function () { openRoleForm(null); });
window.editRole = function (id) {
var row = null;
$('#role-tbody tr').each(function () {
var $tds = $(this).find('td');
if ($tds.length && $tds.eq(0).text() == id) {
var perms = [];
$tds.eq(2).find('.tag').each(function () { perms.push($(this).text()); });
row = {
id: id,
role_name: $tds.eq(1).text(),
permissions: perms,
is_active: $tds.eq(4).find('.tag').hasClass('tag-green') ? 1 : 0
};
}
});
openRoleForm(row);
};
function openRoleForm(role) {
var isEdit = !!role;
var r = role || {};
var permHtml = '';
PERMISSION_OPTIONS.forEach(function (p) {
var checked = (r.permissions || []).indexOf(p.key) >= 0 ? 'checked' : '';
permHtml += '<label style="display:inline-block;min-width:110px;margin:4px 8px 4px 0;font-size:13px;">' +
'<input type="checkbox" name="perm" value="' + p.key + '" ' + checked + '> ' + p.name + '</label>';
});
var content =
'<form id="role-form" style="padding:18px 22px 4px;">' +
'<div class="form-grid">' +
' <div class="form-item"><label>角色名称<span class="req">*</span></label><input type="text" name="role_name" value="' + escHtml(r.role_name) + '"></div>' +
' <div class="form-item"><label>状态</label><select name="is_active">' +
' <option value="1"' + (r.is_active !== 0 ? ' selected' : '') + '>启用</option>' +
' <option value="0"' + (r.is_active === 0 ? ' selected' : '') + '>禁用</option></select></div>' +
' <div class="form-item full"><label>权限分配</label><div style="border:1px solid #eef0f4;border-radius:4px;padding:10px;background:#fafbfd;">' + permHtml + '</div></div>' +
'</div>' +
'<div class="dialog-footer"><button type="button" class="btn" id="form-cancel">取消</button>' +
'<button type="submit" class="btn btn-primary">保存</button></div>' +
'</form>';
var idx = Dialog.open({
title: isEdit ? '编辑角色' : '新增角色',
area: ['620px', 'auto'],
content: content,
btn: false
});
$('#form-cancel').on('click', function () { Dialog.close(idx); });
$('#role-form').on('submit', function (e) {
e.preventDefault();
var perms = [];
$('input[name="perm"]:checked').each(function () { perms.push($(this).val()); });
var data = {
role_name: $('input[name="role_name"]').val(),
is_active: $('select[name="is_active"]').val(),
permissions: JSON.stringify(perms)
};
if (isEdit) data.id = r.id;
httpPost(isEdit ? 'system/role_update.php' : 'system/role_add.php', data).then(function () {
Dialog.success('保存成功', function () {
Dialog.close(idx);
loadRoles(currentPage);
});
});
});
}
window.delRole = function (id) {
Dialog.confirm('确定删除该角色吗?', function () {
httpPost('system/role_delete.php', { id: id }).then(function () {
Dialog.success('删除成功', function () { loadRoles(currentPage); });
});
});
};
}
/* ================= 操作日志 ================= */
function initLog() {
renderShell('操作日志', '权限管理 / 操作日志(仅超级管理员)');
renderLogPage();
initPage('log', function (user) {
var perms = user.permissions || [];
if (perms.indexOf('log') < 0) {
Dialog.alert('仅超级管理员可查看操作日志', function () {
location.href = 'dashboard.html';
});
return;
}
loadLogs(1);
});
var currentPage = 1;
function renderLogPage() {
$('#page-content').html(
'<div class="card">' +
' <div class="toolbar">' +
' <input type="text" data-filter="keyword" placeholder="账号/内容/模块关键词">' +
' <select data-filter="action" id="filter-action"><option value="">全部操作</option></select>' +
' <select data-filter="module" id="filter-module"><option value="">全部模块</option></select>' +
' <input type="text" data-filter="username" placeholder="操作人账号">' +
' <input type="date" data-filter="start_date" title="开始日期">' +
' <input type="date" data-filter="end_date" title="结束日期">' +
' <button class="btn btn-primary" id="btn-search">搜索</button>' +
' <button class="btn" id="btn-reset">重置</button>' +
' </div>' +
' <div class="table-wrap"><table class="grid">' +
' <thead><tr><th>ID</th><th>账号</th><th>操作</th><th>模块</th><th>对象表</th><th>对象ID</th><th>内容</th><th>IP</th><th>时间</th></tr></thead>' +
' <tbody id="log-tbody"></tbody>' +
' </table></div>' +
' <div class="pagination" id="pagination"></div>' +
'</div>'
);
}
function loadLogs(page) {
currentPage = page;
var params = buildFilterParam();
params.page = page;
params.limit = PAGE_SIZE;
httpGet('system/log_list.php', params).then(function (data) {
var rows = data.list || [];
var html = '';
rows.forEach(function (r) {
var content = '';
try {
var obj = JSON.parse(r.content || 'null');
content = obj ? JSON.stringify(obj) : '';
} catch (e) {}
html += '<tr>' +
'<td>' + r.id + '</td>' +
'<td>' + escHtml(r.username) + '</td>' +
'<td><span class="tag">' + escHtml(r.action) + '</span></td>' +
'<td>' + escHtml(r.module) + '</td>' +
'<td>' + escHtml(r.target_table || '-') + '</td>' +
'<td>' + (r.target_id || '-') + '</td>' +
'<td title="' + escHtml(content) + '">' + escHtml((content || '-').substring(0, 30)) + '</td>' +
'<td>' + escHtml(r.ip || '-') + '</td>' +
'<td>' + fmtDate(r.created_at) + '</td></tr>';
});
if (!rows.length) {
html = '<tr><td colspan="9" class="empty-tip" style="padding:40px 0;">近1个月暂无操作日志</td></tr>';
}
$('#log-tbody').html(html);
renderPagination($('#pagination'), data, loadLogs);
// 筛选下拉
var dict = data.dict || {};
if (dict.actions && dict.actions.length) {
var h = '<option value="">全部操作</option>';
dict.actions.forEach(function (a) { h += '<option value="' + escHtml(a) + '">' + escHtml(a) + '</option>'; });
$('#filter-action').html(h);
}
if (dict.modules && dict.modules.length) {
var h2 = '<option value="">全部模块</option>';
dict.modules.forEach(function (m) { h2 += '<option value="' + escHtml(m) + '">' + escHtml(m) + '</option>'; });
$('#filter-module').html(h2);
}
});
}
$('#btn-search').on('click', function () { loadLogs(1); });
$('#btn-reset').on('click', function () {
$('.toolbar [data-filter]').val('');
loadLogs(1);
});
}