MIT License Code // +---------------------------------------------------------------------- namespace app\index\controller; use app\common\exception\OperateException; use app\common\exception\user\UserException; use app\common\library\ResultCode; use app\common\model\system\UserLog; use app\common\model\system\UserNotice; use app\common\service\user\UserService; use app\HomeController; use app\common\library\Upload; use app\common\model\system\User as UserModel; use PHPMailer\PHPMailer\Exception; use Psr\SimpleCache\InvalidArgumentException; use support\Request; use support\Response; use system\Random; use think\db\exception\DataNotFoundException; use think\db\exception\DbException; use think\db\exception\ModelNotFoundException; use Webman\Event\Event; use app\common\validate\system\User as UserValidate; class User extends HomeController { /** * 鉴权控制器 */ public bool $needLogin = true; /** * 超时时间 */ public int $expire = 604800; /** * 非登录鉴权方法 */ public array $noNeedLogin = ['login', 'register', 'forgot', 'ajaxLogin', 'mobileLogin', 'scanLogin', 'scanTicket']; public function __construct() { parent::__construct(); $this->model = new UserModel(); } /** * 用户中心 * @return mixed * @throws DbException */ public function index(Request $request): Response { // 未读短消息 $unread = UserNotice::where('user_id', $request->userId)->where('status', 0)->count(); return view('/user/index', [ 'unread' => $unread, ]); } /** * 用户资料 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function center(Request $request): Response { return view('/user/center', [ 'newsHtml' => $result ?? '服务器错误', 'userList' => $this->model->order('login_count', 'desc')->limit(12)->select()->toArray(), 'invite_count' => $this->model->where('invite_id', $request->userId)->count(), ]); } /** * 用户资料 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException * @throws OperateException */ public function profile(Request $request): Response { if (request()->isPost()) { $post = request()->post(); validate(UserValidate::class)->scene('nickname')->check($post); UserService::editProfile($post, $request->userId); return $this->success('更新资料成功'); } return view('/user/profile'); } /** * 用户注册 * @return Response * @throws DbException * @throws InvalidArgumentException * @throws OperateException */ public function register(): Response { if (request()->isPost()) { $post = request()->post(); validate(UserValidate::class)->scene('register')->check($post); $response = UserService::register($post); return $response['response']->withBody(json_encode(ResultCode::REGISTERSUCCESS)); } return view('/user/register', [ 'style' => saenv('user_register'), ]); } /** * 用户登录 * @return Response * @throws InvalidArgumentException|OperateException */ public function login(): Response { if (request()->isPost()) { $nickname = input('nickname'); $password = input('pwd'); validate(UserValidate::class)->scene('login')->check([ 'nickname' => $nickname, 'pwd' => $password ]); $result = UserService::accountLogin($nickname, $password); return $result['response']->withBody(json_encode(ResultCode::LOGINSUCCESS)); } return view('/user/login', [ 'referer' => $this->referer, ]); } /** * 手机登录 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws InvalidArgumentException * @throws ModelNotFoundException * @throws OperateException */ public function mobileLogin(Request $request): Response { if (request()->isPost()) { $mobile = input('mobile'); $captcha = input('captcha'); validate(UserValidate::class)->scene('mobile')->check([ 'mobile' => $mobile, 'captcha' => $captcha ]); $result = UserService::mobileLogin($mobile, $captcha); return $result['response']->withBody(json_encode(ResultCode::LOGINSUCCESS)); } return $this->error('非法请求'); } /** * ajax登录 * @return Response */ public function ajaxLogin(): Response { return view('/user/ajax_login', ['referer' => $this->referer]); } /** * 用户扫码登录 * @param Request $request * @return Response */ public function scanLogin(Request $request): Response { if (request()->isAjax()) { if (!Event::hasListener('scanLoginBefore')) { return $this->error('请安装扫码登录插件'); } try { $result = Event::emit('scanLoginBefore', input(), true) ?? []; $ticket = $result['ticket'] ?? time(); $qrcode = $result['qrcode'] ?? '/static/images/qrcode-qun.png'; } catch (\Throwable $e) { return $this->error($e->getMessage()); } return $this->success('获取成功', '/', ['ticket' => $ticket, 'qrcode' => $qrcode]); } return $this->error('非法请求'); } /** * 扫码登录 * @param Request $request * @return Response */ public function scanTicket(Request $request): Response { if (request()->isPost()) { $data = request()->post(); try { $result = Event::emit('scanLoginAfter', $data, true) ?? []; if (!isset($result['code']) || $result['code'] != 200) { throw new \Exception($result['msg'] ?? '登录异常'); } $response = $result['response']; } catch (\Throwable $e) { return $this->error($e->getMessage()); } return $response->withBody(json_encode(ResultCode::LOGINSUCCESS)); } return $this->error('缺少参数'); } /** * 修改密码 * @param Request $request * @return Response * @throws OperateException */ public function changePwd(Request $request): Response { if (request()->isPost()) { $post = request()->post(); UserService::changePwd($post, $request->userId); return $this->success('修改密码成功!'); } return view('/user/change_pwd'); } /** * 找回密码 * @param Request $request * @return Response * @throws DbException|OperateException */ public function forgot(Request $request): Response { if (request()->isPost()) { $post = request()->post(); UserService::forgotPwd($post); return $this->success('修改密码成功!'); } return view('/user/forgot'); } /** * 消息列表 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function message(Request $request): Response { if (request()->isAjax()) { $page = input('page', 1); $limit = input('limit', 1); $status = input('status', 'all'); $where[] = ['user_id', '=', $request->userId]; if ($status !== 'all') { $where[] = ['status', '=', $status]; } list($list, $count) = UserService::listMessage($limit, $page, $where); return $this->success('查询成功', "/", $list, $count); } return view('/user/message'); } /** * 查看消息 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException * @throws OperateException */ public function viewMessage(Request $request): Response { $id = input('id', 0); $result = UserService::viewMessage($id, $request->userId); return view('/user/message_view', [ 'msgInfo' => $result['msgInfo'], 'unread' => $result['unread'], ]); } /** * 批量操作消息 * @param Request $request * @return Response */ public function batchMessage(Request $request): Response { if (\request()->isPost()) { $ids = input('id'); $type = input('type', 'del'); try { UserService::batchMessage($ids, $type, $request->userId); } catch (UserException $e) { return $this->error($e->getMessage()); } return $this->success('操作成功'); } return $this->error('非法操作'); } /** * 我的邀请 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws InvalidArgumentException * @throws ModelNotFoundException */ public function invite(Request $request): Response { $inviteList = $this->model->where('invite_id', $request->userId) ->limit(9)->field('id,nickname,url,avatar') ->order('id desc') ->select() ->toArray(); return $this->view('', ['inviteList' => $inviteList]); } /** * 申请appKey * @return Response|void */ public function appid(Request $request) { if (request()->isPost()) { $data = array(); $data['id'] = $request->userId; $data['app_id'] = 10000 + $request->userId; $data['app_secret'] = Random::alpha(22); if ($this->model->update($data)) { return $this->success(); } return $this->error(); } } /** * 修改邮箱 * @param Request $request * @return Response * @throws Exception|OperateException|UserException */ public function changeEmail(Request $request): Response { if (request()->isPost()) { $email = input('email'); $captcha = input('captcha'); $event = input('event'); UserService::changeEmail($email, $captcha, $event, $request->userId); return $this->success('修改邮箱成功!'); } return view('/user/change_email'); } /** * 修改手机号 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException * @throws OperateException * @throws UserException */ public function changeMobile(Request $request): Response { if (request()->isPost()) { $mobile = input('mobile'); $captcha = input('captcha'); $event = input('event'); UserService::changeMobile($mobile, $captcha, $event, $request->userId); return $this->success('修改手机号成功!'); } return view('/user/change_mobile'); } /** * 用户登录日志 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public function loginLog(Request $request): Response { if (request()->isAjax()) { $page = input('page', 1); $limit = input('limit', 1); $where[] = ['login_id', '=', $request->userId]; $count = UserLog::where($where)->count(); $page = ($count <= $limit) ? 1 : $page; $list = UserLog::where($where)->order('id', 'desc')->limit((int)$limit)->page((int)$page)->select()->toArray(); return $this->success('查询成功', "", $list, $count); } return view('/user/login_log'); } /** * 实名认证 * @param Request $request * @return Response */ public function certification(Request $request): Response { if (request()->isPost()) { $name = input('name'); $mobile = input('mobile'); $idCard = input('idCard'); $captcha = input('captcha'); if (!empty($request->userInfo['prove'])) { return $this->error('您已经实名认证过了!'); } // 判断是否安装实名认证插件 if (!Event::hasListener('certification')) { return $this->error('实名认证插件未安装'); } // 判断验证码 if (!$captcha || !$this->captchaCheck($captcha)) { return $this->error('验证码错误'); } try { $result = Event::emit('certification', [ 'name' => $name, 'mobile' => $mobile, 'idCard' => $idCard, ]); if ($result['code'] != 1) { throw new \Exception($result['msg']); } // 更新系统认证信息 $this->model->where('id', $request->userId)->update([ 'prove' => 1, 'name' => $name, 'idCard' => $idCard, 'mobile' => $mobile, 'prove_time' => date('Y-m-d H:i:s', time()) ]); } catch (\Exception $e) { return $this->error('实名认证失败,请联系管理员'); } return $this->success('实名认证成功!'); } return view('/user/certification', ['prove' => $request->userInfo['prove']]); } /** * 设置密保 * @param Request $request * @return Response */ public function protection(Request $request): Response { $validate = [ '你家的宠物叫啥?', '你的幸运数字是?', '你不想上班的理由是?', ]; if (request()->isPost()) { $question = input('question'); $answer = input('answer'); if (!$question || !$answer) { return $this->error('设置失败'); } if (!in_array($question, $validate)) { $question = current($validate); } try { $this->model->update([ 'question' => $question, 'answer' => $answer ], ['id' => $request->userId]); } catch (\Throwable $th) { return $this->error(); } return $this->success(); } return view('/user/protection', [ 'validate' => $validate ]); } /** * 安全配置中心 * @param Request $request * @return Response */ public function security(Request $request): Response { $thisProgress = 1; if ($request->userInfo['email']) { $thisProgress++; } if ($request->userInfo['mobile']) { $thisProgress++; } if ($request->userInfo['prove']) { $thisProgress++; } if ($request->userInfo['wechat']) { $thisProgress++; } // 计算比例 $progress = (($thisProgress / 5) * 100); return view('/user/security', [ 'progress' => $progress, ]); } /** * 用户头像上传 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws InvalidArgumentException * @throws ModelNotFoundException */ public function avatar(Request $request): Response { if (request()->isPost()) { $response = Upload::instance()->upload(); if (!$response) { return $this->error(Upload::instance()->getError()); } $avatar = $response['url'] . '?' . Random::alpha(12); $result = $this->model->where('id', $request->userId)->update(['avatar' => $avatar]); if (!empty($result)) { return json($response); } } return json(ResultCode::SUCCESS); } /** * 文件上传函数 */ public function upload(): Response { if (request()->isPost()) { $response = Upload::instance()->upload(); if (empty($response)) { return $this->error(Upload::instance()->getError()); } return json($response); } return json(ResultCode::SUCCESS); } /** * 远程下载图片 * @throws DataNotFoundException * @throws DbException * @throws InvalidArgumentException * @throws ModelNotFoundException */ public function getImage(): Response { $url = input('url', ''); $response = Upload::instance()->download($url); if (empty($response)) { return $this->error(Upload::instance()->getError()); } return json($response); } }