194 lines
7.7 KiB
PHP
194 lines
7.7 KiB
PHP
<?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;
|
|
}
|
|
}
|