v1.0.10
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* 操作日志查询接口 GET/POST /api/system/log_list.php
|
||||
* 仅超级管理员可见,默认查询近1个月
|
||||
* 参数:page / limit / keyword / action / module / username / start_date / end_date
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
|
||||
requireSuperAdmin();
|
||||
|
||||
[$page, $limit] = pageParams();
|
||||
$keyword = trim($_REQUEST['keyword'] ?? '');
|
||||
$action = trim($_REQUEST['action'] ?? '');
|
||||
$module = trim($_REQUEST['module'] ?? '');
|
||||
$username = trim($_REQUEST['username'] ?? '');
|
||||
$startDate = trim($_REQUEST['start_date'] ?? '');
|
||||
$endDate = trim($_REQUEST['end_date'] ?? '');
|
||||
|
||||
$where = ['created_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)'];
|
||||
$params = [];
|
||||
if ($keyword !== '') {
|
||||
$where[] = '(username LIKE ? OR content LIKE ? OR module LIKE ?)';
|
||||
$like = "%$keyword%";
|
||||
array_push($params, $like, $like, $like);
|
||||
}
|
||||
if ($action !== '') { $where[] = 'action = ?'; $params[] = $action; }
|
||||
if ($module !== '') { $where[] = 'module = ?'; $params[] = $module; }
|
||||
if ($username !== '') { $where[] = 'username = ?'; $params[] = $username; }
|
||||
if ($startDate !== '') { $where[] = 'DATE(created_at) >= ?'; $params[] = $startDate; }
|
||||
if ($endDate !== '') { $where[] = 'DATE(created_at) <= ?'; $params[] = $endDate; }
|
||||
$whereSql = implode(' AND ', $where);
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM system_logs WHERE $whereSql");
|
||||
$stmt->execute($params);
|
||||
$total = (int)$stmt->fetchColumn();
|
||||
|
||||
$offset = ($page - 1) * $limit;
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT id, user_id, username, action, module, target_table, target_id, content, ip, created_at
|
||||
FROM system_logs
|
||||
WHERE $whereSql
|
||||
ORDER BY id DESC
|
||||
LIMIT $limit OFFSET $offset"
|
||||
);
|
||||
$stmt->execute($params);
|
||||
$list = $stmt->fetchAll();
|
||||
|
||||
// 筛选下拉字典
|
||||
$dict = [
|
||||
'actions' => $pdo->query("SELECT DISTINCT action FROM system_logs ORDER BY action")->fetchAll(PDO::FETCH_COLUMN),
|
||||
'modules' => $pdo->query("SELECT DISTINCT module FROM system_logs ORDER BY module")->fetchAll(PDO::FETCH_COLUMN),
|
||||
];
|
||||
|
||||
Response::success(['list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit, 'dict' => $dict]);
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* 新增角色接口(含权限分配) POST /api/system/role_add.php
|
||||
* 入参:role_name / permissions(JSON数组,菜单标识)/ is_active
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('system');
|
||||
|
||||
$roleName = trim($_POST['role_name'] ?? '');
|
||||
$perms = json_decode($_POST['permissions'] ?? '[]', true);
|
||||
$isActive = isset($_POST['is_active']) ? ((int)$_POST['is_active'] ? 1 : 0) : 1;
|
||||
|
||||
if ($roleName === '') {
|
||||
Response::error('角色名称不能为空', 400);
|
||||
}
|
||||
if (!is_array($perms)) {
|
||||
Response::error('权限格式错误', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$chk = $pdo->prepare("SELECT COUNT(*) FROM system_roles WHERE role_name = ?");
|
||||
$chk->execute([$roleName]);
|
||||
if ((int)$chk->fetchColumn() > 0) {
|
||||
Response::error('角色名称已存在');
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare("INSERT INTO system_roles (role_name, permissions, is_active) VALUES (?, ?, ?)");
|
||||
$stmt->execute([$roleName, json_encode(array_values($perms), JSON_UNESCAPED_UNICODE), $isActive]);
|
||||
$newId = (int)$pdo->lastInsertId();
|
||||
|
||||
logCurrent('add', 'system', 'system_roles', $newId, ['role_name' => $roleName, 'permissions' => $perms]);
|
||||
Response::success(['id' => $newId], '新增成功');
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* 删除角色接口 POST /api/system/role_delete.php
|
||||
* 入参:id(或 ids 逗号分隔批量)
|
||||
* 保护:不允许删除内置超级管理员角色(id=1)及仍被用户使用的角色
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('system');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$ids = trim($_POST['ids'] ?? '');
|
||||
$idList = [];
|
||||
if ($id > 0) $idList[] = $id;
|
||||
if ($ids !== '') {
|
||||
foreach (explode(',', $ids) as $v) {
|
||||
$v = (int)trim($v);
|
||||
if ($v > 0) $idList[] = $v;
|
||||
}
|
||||
}
|
||||
$idList = array_unique($idList);
|
||||
if (!$idList) {
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
if (in_array(1, $idList, true)) {
|
||||
Response::error('不允许删除内置超级管理员角色', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
// 检查角色是否被使用
|
||||
$in = implode(',', array_fill(0, count($idList), '?'));
|
||||
$stmt = $pdo->prepare("SELECT role_id, COUNT(*) AS cnt FROM system_users WHERE role_id IN ($in) GROUP BY role_id");
|
||||
$stmt->execute($idList);
|
||||
$inUse = $stmt->fetchAll();
|
||||
if ($inUse) {
|
||||
$names = [];
|
||||
foreach ($inUse as $r) {
|
||||
$names[] = "角色ID {$r['role_id']}({$r['cnt']}个用户)";
|
||||
}
|
||||
Response::error('以下角色仍被用户使用,无法删除:' . implode('、', $names), 400);
|
||||
}
|
||||
|
||||
$del = $pdo->prepare("DELETE FROM system_roles WHERE id IN ($in)");
|
||||
$del->execute($idList);
|
||||
$affected = $del->rowCount();
|
||||
|
||||
logCurrent('delete', 'system', 'system_roles', null, ['ids' => $idList]);
|
||||
Response::success(['affected' => $affected], "已删除 $affected 个角色");
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* 角色列表接口 GET/POST /api/system/role_list.php
|
||||
* 参数:page / limit / keyword / is_active
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
|
||||
checkPermission('system');
|
||||
|
||||
[$page, $limit] = pageParams();
|
||||
$keyword = trim($_REQUEST['keyword'] ?? '');
|
||||
$active = isset($_REQUEST['is_active']) && $_REQUEST['is_active'] !== '' ? (int)$_REQUEST['is_active'] : null;
|
||||
|
||||
$where = ['1=1'];
|
||||
$params = [];
|
||||
if ($keyword !== '') {
|
||||
$where[] = 'role_name LIKE ?';
|
||||
$params[] = "%$keyword%";
|
||||
}
|
||||
if ($active !== null) { $where[] = 'is_active = ?'; $params[] = $active; }
|
||||
$whereSql = implode(' AND ', $where);
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM system_roles WHERE $whereSql");
|
||||
$stmt->execute($params);
|
||||
$total = (int)$stmt->fetchColumn();
|
||||
|
||||
$offset = ($page - 1) * $limit;
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT id, role_name, permissions, is_active, created_at,
|
||||
(SELECT COUNT(*) FROM system_users u WHERE u.role_id = system_roles.id) AS user_count
|
||||
FROM system_roles
|
||||
WHERE $whereSql
|
||||
ORDER BY id ASC
|
||||
LIMIT $limit OFFSET $offset"
|
||||
);
|
||||
$stmt->execute($params);
|
||||
$list = $stmt->fetchAll();
|
||||
foreach ($list as &$r) {
|
||||
$r['permissions'] = json_decode($r['permissions'], true) ?: [];
|
||||
}
|
||||
unset($r);
|
||||
|
||||
Response::success(['list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit]);
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* 编辑角色接口(含权限分配) POST /api/system/role_update.php
|
||||
* 入参:id / role_name / permissions(JSON数组)/ is_active
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('system');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$check = $pdo->prepare("SELECT * FROM system_roles WHERE id = ?");
|
||||
$check->execute([$id]);
|
||||
$old = $check->fetch();
|
||||
if (!$old) {
|
||||
Response::error('角色不存在');
|
||||
}
|
||||
|
||||
// 超级管理员角色保护:不允许移除其自身
|
||||
if ($id === 1) {
|
||||
Response::error('内置超级管理员角色不允许修改', 400);
|
||||
}
|
||||
|
||||
$sets = [];
|
||||
$params = [];
|
||||
|
||||
if (isset($_POST['role_name'])) {
|
||||
$roleName = trim($_POST['role_name']);
|
||||
if ($roleName === '') {
|
||||
Response::error('角色名称不能为空', 400);
|
||||
}
|
||||
$chk = $pdo->prepare("SELECT COUNT(*) FROM system_roles WHERE role_name = ? AND id <> ?");
|
||||
$chk->execute([$roleName, $id]);
|
||||
if ((int)$chk->fetchColumn() > 0) {
|
||||
Response::error('角色名称已存在');
|
||||
}
|
||||
$sets[] = 'role_name = ?';
|
||||
$params[] = $roleName;
|
||||
}
|
||||
if (isset($_POST['permissions'])) {
|
||||
$perms = json_decode($_POST['permissions'], true);
|
||||
if (!is_array($perms)) {
|
||||
Response::error('权限格式错误', 400);
|
||||
}
|
||||
$sets[] = 'permissions = ?';
|
||||
$params[] = json_encode(array_values($perms), JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
if (isset($_POST['is_active'])) {
|
||||
$sets[] = 'is_active = ?';
|
||||
$params[] = (int)$_POST['is_active'] ? 1 : 0;
|
||||
}
|
||||
|
||||
if (!$sets) {
|
||||
Response::error('没有需要更新的字段', 400);
|
||||
}
|
||||
|
||||
$params[] = $id;
|
||||
$pdo->prepare("UPDATE system_roles SET " . implode(', ', $sets) . " WHERE id = ?")->execute($params);
|
||||
|
||||
logCurrent('update', 'system', 'system_roles', $id, ['before' => $old, 'after' => $sets]);
|
||||
Response::success(null, '更新成功');
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* 新增用户接口 POST /api/system/user_add.php
|
||||
* 入参:username / password / real_name / role_id / is_active
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('system');
|
||||
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$password = (string)($_POST['password'] ?? '');
|
||||
$realName = trim($_POST['real_name'] ?? '');
|
||||
$roleId = (int)($_POST['role_id'] ?? 0);
|
||||
$isActive = isset($_POST['is_active']) ? ((int)$_POST['is_active'] ? 1 : 0) : 1;
|
||||
|
||||
if ($username === '' || !preg_match('/^[a-zA-Z0-9_]{3,50}$/', $username)) {
|
||||
Response::error('账号需为3-50位字母/数字/下划线', 400);
|
||||
}
|
||||
if (strlen($password) < 6) {
|
||||
Response::error('密码长度不能少于6位', 400);
|
||||
}
|
||||
if ($roleId <= 0) {
|
||||
Response::error('请选择角色', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
$chk = $pdo->prepare("SELECT COUNT(*) FROM system_users WHERE username = ?");
|
||||
$chk->execute([$username]);
|
||||
if ((int)$chk->fetchColumn() > 0) {
|
||||
Response::error('账号已存在');
|
||||
}
|
||||
|
||||
$chkRole = $pdo->prepare("SELECT COUNT(*) FROM system_roles WHERE id = ?");
|
||||
$chkRole->execute([$roleId]);
|
||||
if ((int)$chkRole->fetchColumn() === 0) {
|
||||
Response::error('角色不存在', 400);
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
"INSERT INTO system_users (username, password, real_name, role_id, is_active)
|
||||
VALUES (?, ?, ?, ?, ?)"
|
||||
);
|
||||
$stmt->execute([$username, sha1($password), $realName !== '' ? $realName : null, $roleId, $isActive]);
|
||||
$newId = (int)$pdo->lastInsertId();
|
||||
|
||||
logCurrent('add', 'system', 'system_users', $newId, ['username' => $username, 'role_id' => $roleId, 'is_active' => $isActive]);
|
||||
Response::success(['id' => $newId], '新增成功');
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* 删除用户接口 POST /api/system/user_delete.php
|
||||
* 入参:id(或 ids 逗号分隔批量)
|
||||
* 保护:不允许删除内置管理员(id=1)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('system');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
$ids = trim($_POST['ids'] ?? '');
|
||||
$idList = [];
|
||||
if ($id > 0) $idList[] = $id;
|
||||
if ($ids !== '') {
|
||||
foreach (explode(',', $ids) as $v) {
|
||||
$v = (int)trim($v);
|
||||
if ($v > 0) $idList[] = $v;
|
||||
}
|
||||
}
|
||||
$idList = array_unique($idList);
|
||||
if (!$idList) {
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
if (in_array(1, $idList, true)) {
|
||||
Response::error('不允许删除内置管理员账号', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$in = implode(',', array_fill(0, count($idList), '?'));
|
||||
$stmt = $pdo->prepare("DELETE FROM system_users WHERE id IN ($in)");
|
||||
$stmt->execute($idList);
|
||||
$affected = $stmt->rowCount();
|
||||
|
||||
logCurrent('delete', 'system', 'system_users', null, ['ids' => $idList]);
|
||||
Response::success(['affected' => $affected], "已删除 $affected 个用户");
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* 用户列表接口 GET/POST /api/system/user_list.php
|
||||
* 参数:page / limit / keyword / role_id / is_active
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
|
||||
checkPermission('system');
|
||||
|
||||
[$page, $limit] = pageParams();
|
||||
$keyword = trim($_REQUEST['keyword'] ?? '');
|
||||
$roleId = (int)($_REQUEST['role_id'] ?? 0);
|
||||
$active = isset($_REQUEST['is_active']) && $_REQUEST['is_active'] !== '' ? (int)$_REQUEST['is_active'] : null;
|
||||
|
||||
$where = ['1=1'];
|
||||
$params = [];
|
||||
if ($keyword !== '') {
|
||||
$where[] = '(u.username LIKE ? OR u.real_name LIKE ?)';
|
||||
$like = "%$keyword%";
|
||||
array_push($params, $like, $like);
|
||||
}
|
||||
if ($roleId > 0) { $where[] = 'u.role_id = ?'; $params[] = $roleId; }
|
||||
if ($active !== null) { $where[] = 'u.is_active = ?'; $params[] = $active; }
|
||||
$whereSql = implode(' AND ', $where);
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM system_users u WHERE $whereSql");
|
||||
$stmt->execute($params);
|
||||
$total = (int)$stmt->fetchColumn();
|
||||
|
||||
$offset = ($page - 1) * $limit;
|
||||
$stmt = $pdo->prepare(
|
||||
"SELECT u.id, u.username, u.real_name, u.role_id, r.role_name, u.is_active,
|
||||
u.last_login_time, u.last_login_ip, u.created_at
|
||||
FROM system_users u
|
||||
LEFT JOIN system_roles r ON r.id = u.role_id
|
||||
WHERE $whereSql
|
||||
ORDER BY u.id ASC
|
||||
LIMIT $limit OFFSET $offset"
|
||||
);
|
||||
$stmt->execute($params);
|
||||
$list = $stmt->fetchAll();
|
||||
|
||||
// 角色下拉
|
||||
$roles = $pdo->query("SELECT id, role_name FROM system_roles WHERE is_active = 1 ORDER BY id")->fetchAll();
|
||||
|
||||
Response::success(['list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit, 'roles' => $roles]);
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* 编辑用户接口(含角色分配) POST /api/system/user_update.php
|
||||
* 入参:id / real_name / role_id / is_active / password(可选,留空不改密码)
|
||||
*/
|
||||
require_once __DIR__ . '/../common/db.php';
|
||||
require_once __DIR__ . '/../common/response.php';
|
||||
require_once __DIR__ . '/../common/auth.php';
|
||||
require_once __DIR__ . '/../common/logger.php';
|
||||
|
||||
checkAjax();
|
||||
checkPermission('system');
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
Response::error('参数错误', 400);
|
||||
}
|
||||
|
||||
$pdo = DB::getInstance()->getPdo();
|
||||
$check = $pdo->prepare("SELECT * FROM system_users WHERE id = ?");
|
||||
$check->execute([$id]);
|
||||
$old = $check->fetch();
|
||||
if (!$old) {
|
||||
Response::error('用户不存在');
|
||||
}
|
||||
|
||||
// 内置管理员保护:不允许禁用 id=1(admin)
|
||||
if ($id === 1 && isset($_POST['is_active']) && (int)$_POST['is_active'] === 0) {
|
||||
Response::error('不允许禁用内置管理员账号', 400);
|
||||
}
|
||||
|
||||
$sets = [];
|
||||
$params = [];
|
||||
|
||||
if (isset($_POST['real_name'])) {
|
||||
$sets[] = 'real_name = ?';
|
||||
$params[] = trim($_POST['real_name']) !== '' ? trim($_POST['real_name']) : null;
|
||||
}
|
||||
if (isset($_POST['role_id'])) {
|
||||
$roleId = (int)$_POST['role_id'];
|
||||
$chkRole = $pdo->prepare("SELECT COUNT(*) FROM system_roles WHERE id = ?");
|
||||
$chkRole->execute([$roleId]);
|
||||
if ((int)$chkRole->fetchColumn() === 0) {
|
||||
Response::error('角色不存在', 400);
|
||||
}
|
||||
$sets[] = 'role_id = ?';
|
||||
$params[] = $roleId;
|
||||
}
|
||||
if (isset($_POST['is_active'])) {
|
||||
$sets[] = 'is_active = ?';
|
||||
$params[] = (int)$_POST['is_active'] ? 1 : 0;
|
||||
}
|
||||
$password = (string)($_POST['password'] ?? '');
|
||||
if ($password !== '') {
|
||||
if (strlen($password) < 6) {
|
||||
Response::error('密码长度不能少于6位', 400);
|
||||
}
|
||||
$sets[] = 'password = ?';
|
||||
$params[] = sha1($password);
|
||||
}
|
||||
|
||||
if (!$sets) {
|
||||
Response::error('没有需要更新的字段', 400);
|
||||
}
|
||||
|
||||
$params[] = $id;
|
||||
$pdo->prepare("UPDATE system_users SET " . implode(', ', $sets) . " WHERE id = ?")->execute($params);
|
||||
|
||||
logCurrent('update', 'system', 'system_users', $id, ['before' => ['username' => $old['username'], 'role_id' => $old['role_id'], 'is_active' => $old['is_active']]]);
|
||||
Response::success(null, '更新成功');
|
||||
Reference in New Issue
Block a user