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' => '已重置密码为:' . e($new) . '(请尽快通知对方修改)', ]); } 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; } }