From a36157d40642c9a9474ecab7e158a8f34e5ecb9f Mon Sep 17 00:00:00 2001 From: gcd Date: Fri, 28 Mar 2025 12:46:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Worker.php | 33 -- application/common/controller/WorkerApi.php | 310 ++++++++++++++++++ application/common/model/WorkerVendor.php | 18 + application/services/BaseService.php | 27 ++ application/services/WorkerService.php | 62 ++-- application/services/WorkerVendorService.php | 33 ++ application/worker/config.php | 6 + application/worker/controller/Worker.php | 39 +++ .../worker/controller/WorkerVendor.php | 10 + .../{api => worker}/validate/Worker.php | 7 +- 10 files changed, 490 insertions(+), 55 deletions(-) delete mode 100644 application/api/controller/Worker.php create mode 100644 application/common/controller/WorkerApi.php create mode 100644 application/common/model/WorkerVendor.php create mode 100644 application/services/WorkerVendorService.php create mode 100644 application/worker/config.php create mode 100644 application/worker/controller/Worker.php create mode 100644 application/worker/controller/WorkerVendor.php rename application/{api => worker}/validate/Worker.php (54%) diff --git a/application/api/controller/Worker.php b/application/api/controller/Worker.php deleted file mode 100644 index 5417afa..0000000 --- a/application/api/controller/Worker.php +++ /dev/null @@ -1,33 +0,0 @@ -request->request(); - $validate = $this->validate($params, \app\api\validate\Worker::class . '.login'); - if ($validate !== true) { - $this->error($validate); - } - - $this->success('登录成功', $this->getWorkerService()->login($params['code'])); - } - - function bindPhoneNumber() - { - $params = $this->request->request(); - $validate = $this->validate($params, \app\api\validate\Worker::class . '.bindPhoneNumber'); - if ($validate !== true) { - $this->error($validate); - } - - $this->success('操作成功', $this->getWorkerService()->bindPhoneNumber($params['code'])); - } -} diff --git a/application/common/controller/WorkerApi.php b/application/common/controller/WorkerApi.php new file mode 100644 index 0000000..da77245 --- /dev/null +++ b/application/common/controller/WorkerApi.php @@ -0,0 +1,310 @@ +request = is_null($request) ? Request::instance() : $request; + + // 控制器初始化 + $this->_initialize(); + } + + /** + * 初始化操作 + * @access protected + */ + protected function _initialize() + { + //跨域请求检测 + check_cors_request(); + + // 检测IP是否允许 + check_ip_allowed(); + + //移除HTML标签 + $this->request->filter('trim,strip_tags,htmlspecialchars'); + + // token + $token = $this->request->server('HTTP_TOKEN', $this->request->request('token', \think\Cookie::get('token'))); + if (!$this->match($this->noNeedLogin)) { + $this->init($token); + } else { + if ($token) { + $this->init($token); + } + } + + return true; + } + + /** + * 检测当前控制器和方法是否匹配传递的数组 + * + * @param array $arr 需要验证权限的数组 + * @return boolean + */ + public function match($arr = []) + { + $request = Request::instance(); + $arr = is_array($arr) ? $arr : explode(',', $arr); + if (!$arr) { + return false; + } + $arr = array_map('strtolower', $arr); + // 是否存在 + if (in_array(strtolower($request->action()), $arr) || in_array('*', $arr)) { + return true; + } + + // 没找到匹配 + return false; + } + + /** + * 操作成功返回的数据 + * @param string $msg 提示信息 + * @param mixed $data 要返回的数据 + * @param int $code 错误码,默认为1 + * @param string $type 输出类型 + * @param array $header 发送的 Header 信息 + */ + protected function success($msg = '', $data = null, $code = 1, $type = null, array $header = []) + { + $this->result($msg, $data, $code, $type, $header); + } + + /** + * 操作失败返回的数据 + * @param string $msg 提示信息 + * @param mixed $data 要返回的数据 + * @param int $code 错误码,默认为0 + * @param string $type 输出类型 + * @param array $header 发送的 Header 信息 + */ + protected function error($msg = '', $data = null, $code = 0, $type = null, array $header = []) + { + $this->result($msg, $data, $code, $type, $header); + } + + /** + * 返回封装后的 API 数据到客户端 + * @access protected + * @param mixed $msg 提示信息 + * @param mixed $data 要返回的数据 + * @param int $code 错误码,默认为0 + * @param string $type 输出类型,支持json/xml/jsonp + * @param array $header 发送的 Header 信息 + * @return void + * @throws HttpResponseException + */ + protected function result($msg, $data = null, $code = 0, $type = null, array $header = []) + { + $result = [ + 'code' => $code, + 'msg' => $msg, + 'time' => Request::instance()->server('REQUEST_TIME'), + 'data' => $data, + ]; + // 如果未设置类型则自动判断 + $type = $type ? $type : ($this->request->param(config('var_jsonp_handler')) ? 'jsonp' : $this->responseType); + + if (isset($header['statuscode'])) { + $code = $header['statuscode']; + unset($header['statuscode']); + } else { + //未设置状态码,根据code值判断 + $code = $code >= 1000 || $code < 200 ? 200 : $code; + } + $response = Response::create($result, $type, $code)->header($header); + throw new HttpResponseException($response); + } + + /** + * 师傅登录 + * @param int $id + * @return bool + */ + public function workerLogin(int $id): bool + { + $user = $this->getWorkerModel()->find($id); + $this->tryLogin($user); + + $user = $user->toArray(); + $user['token'] = $this->getTokenByUserId($user['id']); + + $this->user = $user; + + return true; + } + + /** + * 验证数据 + * @access protected + * @param array $data 数据 + * @param string|array $validate 验证器名或者验证规则数组 + * @param array $message 提示信息 + * @param bool $batch 是否批量验证 + * @param mixed $callback 回调方法(闭包) + * @return array|string|true + * @throws ValidateException + */ + public function validate($data, $validate, $messageHeader = '', $message = [], $batch = false, $callback = null) + { + if (is_array($validate)) { + $v = Loader::validate(); + $v->rule($validate); + } else { + // 支持场景 + if (strpos($validate, '.')) { + list($validate, $scene) = explode('.', $validate); + } + $v = Loader::validate($validate); + + !empty($scene) && $v->scene($scene); + } + + // 批量验证 + if ($batch || $this->batchValidate) { + $v->batch(true); + } + // 设置错误信息 + if (is_array($message)) { + $v->message($message); + } + // 使用回调验证 + if ($callback && is_callable($callback)) { + call_user_func_array($callback, [$v, &$data]); + } + + if (!$v->check($data)) { + $errorMessage = $v->getError(); + if ($messageHeader) { + $errorMessage = "$messageHeader$errorMessage"; + } + + if ($this->failException) { + throw new ValidateException($errorMessage); + } + + throw new ApiException($errorMessage); + } + + return true; + } + + private function init($token) + { + if ($this->user) { + return true; + } + + $data = Token::get($token); + if (!$data) { + throw new ApiException('登录已失效', 401); + } + + $this->token = $token; + + $user = $this->getWorkerModel() + ->field($this->allowFields) + ->where('id', $data['user_id']) + ->find(); + + $this->tryLogin($user); + + $this->user = $user->toArray(); + + return true; + } + + private function tryLogin($user) + { + if (!$user) { + throw new ApiException('用户不存在,请联系平台'); + } + + if ($user->status === 0) { + throw new ApiException('当前账号不可用'); + } + + return true; + } + + protected function getTokenByUserId($userId) + { + $token = Random::uuid(); + Token::set($token, $userId, $this->keeptime); + + return $token; + } +} diff --git a/application/common/model/WorkerVendor.php b/application/common/model/WorkerVendor.php new file mode 100644 index 0000000..9c01940 --- /dev/null +++ b/application/common/model/WorkerVendor.php @@ -0,0 +1,18 @@ +getMiniProgramApp()->getPhoneNumber($code); +// $phoneInfo = $this->getMiniProgramApp()->getPhoneNumber($code); +// +// if (empty($phoneInfo)) { +// $this->apiError('获取手机号失败', 0, $phoneInfo); +// } +// +// if ($phoneInfo['errcode'] !== 0) { +// $this->apiError('获取手机号失败', 0, $phoneInfo); +// } +// +// $phone = $phoneInfo['phone_info']['phoneNumber']; - if (empty($phoneInfo)) { - $this->apiError('获取手机号失败', 0, $phoneInfo); + $phone = '18628195903'; + $tokenData = Token::get($vendorToken); + if (!$tokenData) { + $this->apiError('vendor_token 无效'); } - if ($phoneInfo['errcode'] !== 0) { - $this->apiError('获取手机号失败', 0, $phoneInfo); - } - - $phone = $phoneInfo['phone_info']['phoneNumber']; + $workerVendorId = $tokenData['user_id']; dump($phone); } public function login(string $code) { - $app = $this->getMiniProgramApp(); - try { - $info = $app->auth->session($code); - } catch (InvalidConfigException $e) { - $this->apiError('登录失败', $e); +// $app = $this->getMiniProgramApp(); +// try { +// $info = $app->auth->session($code); +// } catch (InvalidConfigException $e) { +// $this->apiError('登录失败', $e); +// } +// +// if (isset($info['errcode']) && $info['errcode'] !== 0) { +// $this->apiError('登录失败', 0, $info); +// } + + $info['openid'] = 'oNgcn42DRwoG_qE6jjvsCSbM4cX8'; + $workerVendor = $this->getWorkerVendorService()->getVendorByOpenid($info['openid']); + + //创建 + if (empty($workerVendor)) { + try { + $this->getWorkerVendorService()->createWechatMpVendor($info['openid']); + } catch (\Exception $e) { + $this->apiError('登录失败', $e, $info); + } + + $workerVendor = $this->getWorkerVendorService()->getVendorByOpenid($info['openid']); } - if (isset($info['errcode']) && $info['errcode'] !== 0) { - $this->apiError('登录失败', 0, $info); - } - - dd($info); + return $workerVendor->toArray(); } /** diff --git a/application/services/WorkerVendorService.php b/application/services/WorkerVendorService.php new file mode 100644 index 0000000..4a7f1ad --- /dev/null +++ b/application/services/WorkerVendorService.php @@ -0,0 +1,33 @@ +getWorkerVendorModel()->where(['openid' => $openid])->find(); + } + + /** + * 创建微信小程序账户 + * @param string $openid + */ + public function createWechatMpVendor(string $openid) + { + $vendor = $this->getWorkerVendorModel(); + $vendor->vendor = 'wechat'; + $vendor->platform = 'WechatMp'; + $vendor->unionid = ''; + $vendor->openid = $openid; + $vendor->worker_id = 0; + $vendor->create_time = datetime(time()); + $vendor->save(); + + return $vendor->id; + } +} diff --git a/application/worker/config.php b/application/worker/config.php new file mode 100644 index 0000000..0844157 --- /dev/null +++ b/application/worker/config.php @@ -0,0 +1,6 @@ + '\\app\\api\\library\\ExceptionHandle', +]; diff --git a/application/worker/controller/Worker.php b/application/worker/controller/Worker.php new file mode 100644 index 0000000..9a9dd13 --- /dev/null +++ b/application/worker/controller/Worker.php @@ -0,0 +1,39 @@ +request->request(); + $validate = $this->validate($params, \app\worker\validate\Worker::class . '.login'); + if ($validate !== true) { + $this->error($validate); + } + + $workerVendor = $this->getWorkerService()->login($params['code']); + + //存在师傅id,直接登录 + if ($workerVendor['worker_id']) { + $this->workerLogin($workerVendor['worker_id']); + $this->success('登录成功', $this->user); + } + + $this->error('请绑定手机号', ['vendor_token' => $this->getTokenByUserId($workerVendor['id'])]); + } + + function bindPhoneNumber() + { + $params = $this->request->request(); + $validate = $this->validate($params, \app\worker\validate\Worker::class . '.bindPhoneNumber'); + if ($validate !== true) { + $this->error($validate); + } + + $this->success('操作成功', $this->getWorkerService()->bindPhoneNumber($params['code'], $params['vendor_token'])); + } +} diff --git a/application/worker/controller/WorkerVendor.php b/application/worker/controller/WorkerVendor.php new file mode 100644 index 0000000..806a0cb --- /dev/null +++ b/application/worker/controller/WorkerVendor.php @@ -0,0 +1,10 @@ + 'require|max:128', + 'vendor_token' => 'require|max:128', ]; protected $message = [ @@ -15,7 +16,7 @@ class Worker extends Validate ]; protected $scene = [ - 'login' => ['code'], - 'bindPhoneNumber' => ['code'], + 'login' => ['code'], + 'bindPhoneNumber' => ['code', 'vendor_token'], ]; }