文件还在测试中

This commit is contained in:
2026-08-08 15:53:53 +08:00
parent 5f1e7adb64
commit 8101177cb5
241 changed files with 18074 additions and 22 deletions
+193
View File
@@ -0,0 +1,193 @@
<?php
namespace App\Controllers\Admin;
use App\Controllers\Controller;
use App\Models\AdminUser;
/** 用户管理(仅超级管理员可访问,路由层已拦截) */
class UserController extends Controller
{
protected $layout = 'layouts/admin';
public function __construct()
{
admin_required();
role_required('super_admin');
}
private function model(): AdminUser
{
return new AdminUser();
}
public function index()
{
$users = $this->model()->all();
return $this->view('admin/users', ['users' => $users, 'error' => '', 'ok' => '']);
}
public function create()
{
$p = $this->defaultPermsPair();
return $this->view('admin/user_form', [
'user' => null,
'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'],
'error' => '', 'ok' => '',
]);
}
public function store()
{
if (!csrf_check()) {
$p = $this->defaultPermsPair();
return $this->view('admin/user_form', ['user' => null, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => '表单已过期,请重试', 'ok' => '']);
}
$username = trim($this->post('username'));
$name = trim($this->post('name'));
$role = $this->post('role');
$password = $this->post('password');
$status = $this->post('status') ? 1 : 0;
$err = $this->validate($username, $role, $password);
if ($err) { $p = $this->defaultPermsPair(); return $this->view('admin/user_form', ['user' => null, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => $err, 'ok' => '']); }
if ($this->model()->byUsername($username)) {
$p = $this->defaultPermsPair();
return $this->view('admin/user_form', ['user' => null, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => '该账号已存在', 'ok' => '']);
}
$this->model()->insert([
'username' => $username,
'name' => $name ?: $username,
'password' => password_hash($password, PASSWORD_DEFAULT),
'role' => $role,
'crm_role' => $this->post('crm_role') ?: 'none',
'psi_role' => $this->post('psi_role') ?: 'none',
'crm_perms' => json_encode($this->collectPerms('crm', (array)($this->post('crm_pages') ?: [])), JSON_UNESCAPED_UNICODE),
'psi_perms' => json_encode($this->collectPerms('psi', (array)($this->post('psi_pages') ?: [])), JSON_UNESCAPED_UNICODE),
'status' => $status,
'created_at' => date('Y-m-d'),
]);
$this->redirect('admin/users');
}
public function edit($id)
{
$user = $this->model()->find($id);
if (!$user) return $this->redirect('admin/users');
$p = $this->userPerms($user);
return $this->view('admin/user_form', ['user' => $user, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => '', 'ok' => '']);
}
public function update($id)
{
$user = $this->model()->find($id);
if (!$user) return $this->redirect('admin/users');
if (!csrf_check()) {
$p = $this->userPerms($user);
return $this->view('admin/user_form', ['user' => $user, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => '表单已过期,请重试', 'ok' => '']);
}
$username = trim($this->post('username'));
$name = trim($this->post('name'));
$role = $this->post('role');
$password = $this->post('password');
$status = $this->post('status') ? 1 : 0;
$err = $this->validate($username, $role, $password, true);
if ($err) { $p = $this->userPerms($user); return $this->view('admin/user_form', ['user' => $user, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => $err, 'ok' => '']); }
if ($username !== $user['username'] && $this->model()->byUsername($username)) {
$p = $this->userPerms($user);
return $this->view('admin/user_form', ['user' => $user, 'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'], 'error' => '该账号已存在', 'ok' => '']);
}
$data = [
'username' => $username,
'name' => $name ?: $username,
'role' => $role,
'crm_role' => $this->post('crm_role') ?: 'none',
'psi_role' => $this->post('psi_role') ?: 'none',
'crm_perms' => json_encode($this->collectPerms('crm', (array)($this->post('crm_pages') ?: [])), JSON_UNESCAPED_UNICODE),
'psi_perms' => json_encode($this->collectPerms('psi', (array)($this->post('psi_pages') ?: [])), JSON_UNESCAPED_UNICODE),
'status' => $status,
];
if ($password !== '') {
$data['password'] = password_hash($password, PASSWORD_DEFAULT);
}
$this->model()->update($id, $data);
$this->redirect('admin/users');
}
public function destroy($id)
{
if (admin_uid() == $id) return $this->redirect('admin/users'); // 不能删除自己
$this->model()->delete($id);
$this->redirect('admin/users');
}
/** 超级管理员重置他人密码(自己重置走修改密码页) */
public function reset($id)
{
$user = $this->model()->find($id);
if (!$user) return $this->redirect('admin/users');
if (admin_uid() == $id) return $this->redirect('admin/password');
$new = $this->genPassword();
$this->model()->update($id, ['password' => password_hash($new, PASSWORD_DEFAULT)]);
$p = $this->userPerms($user);
return $this->view('admin/user_form', [
'user' => $user,
'crmPerms' => $p['crm'], 'psiPerms' => $p['psi'],
'error' => '',
'ok' => '已重置密码为:<b>' . e($new) . '</b>(请尽快通知对方修改)',
]);
}
private function defaultPermsPair(): array
{
return ['crm' => $this->defaultPerms('crm'), 'psi' => $this->defaultPerms('psi')];
}
/** 从用户记录解码已保存的页面权限(无记录则默认全部可见) */
private function userPerms($user): array
{
$crm = $this->defaultPerms('crm');
$psi = $this->defaultPerms('psi');
if (!empty($user['crm_perms'])) { $d = @json_decode($user['crm_perms'], true); if (is_array($d)) $crm = $d; }
if (!empty($user['psi_perms'])) { $d = @json_decode($user['psi_perms'], true); if (is_array($d)) $psi = $d; }
return ['crm' => $crm, 'psi' => $psi];
}
private function defaultPerms(string $sys): array
{
$out = [];
foreach (\subsys_pages($sys) as $p) { if ($p !== 'dashboard') $out[$p] = true; }
return $out;
}
private function collectPerms(string $sys, array $checked): array
{
$out = [];
foreach (\subsys_pages($sys) as $p) { if ($p === 'dashboard') continue; $out[$p] = in_array($p, $checked, true); }
return $out;
}
private function validate($username, $role, $password, $isEdit = false): string
{
if ($username === '' || !preg_match('/^[a-zA-Z0-9_]{3,30}$/', $username)) {
return '账号须为 3-30 位字母/数字/下划线';
}
if (!in_array($role, ['super_admin', 'admin', 'user', 'none'], true)) {
return '角色不合法';
}
if (!$isEdit && strlen($password) < 6) {
return '密码至少 6 位';
}
return '';
}
private function genPassword(): string
{
$chars = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
$s = '';
for ($i = 0; $i < 10; $i++) {
$s .= $chars[random_int(0, strlen($chars) - 1)];
}
return $s;
}
}