30 changed files with 659 additions and 21 deletions
-
4app/Constants/v3/ActivityType.php
-
47app/Constants/v3/ErrorCode.php
-
5app/Constants/v3/OrderState.php
-
5app/Constants/v3/OrderType.php
-
5app/Constants/v3/Payment.php
-
17app/Constants/v3/SmsTemplateCode.php
-
17app/Constants/v3/SsdbKeys.php
-
9app/Constants/v3/Tabs.php
-
7app/Controller/BaseController.php
-
41app/Controller/v3/SmsController.php
-
44app/Controller/v3/UserController.php
-
29app/Exception/ErrorCodeException.php
-
48app/Exception/Handler/ErrorCodeExceptionHandler.php
-
27app/Middleware/Auth/UserMiddleware.php
-
10app/Model/v3/User.php
-
2app/Request/UserRequest.php
-
44app/Request/v3/UserBindTelRequest.php
-
41app/Request/v3/VerifyCodeRequest.php
-
20app/Service/v3/Implementations/HelperService.php
-
78app/Service/v3/Implementations/SmsAliService.php
-
38app/Service/v3/Implementations/UserBindService.php
-
89app/Service/v3/Implementations/VerifyCodeService.php
-
8app/Service/v3/Interfaces/HelperServiceInterface.php
-
11app/Service/v3/Interfaces/SmsServiceInterface.php
-
10app/Service/v3/Interfaces/UserBindServiceInterface.php
-
10app/Service/v3/Interfaces/VerifyCodeServiceInterface.php
-
5config/autoload/dependencies.php
-
5config/autoload/exceptions.php
-
1config/config.php
-
3config/routes.php
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Constants\v3; |
||||
|
|
||||
|
use Hyperf\Constants\AbstractConstants; |
||||
|
use Hyperf\Constants\Annotation\Constants; |
||||
|
|
||||
|
/** |
||||
|
* @Constants |
||||
|
*/ |
||||
|
class SmsTemplateCode extends AbstractConstants |
||||
|
{ |
||||
|
/** |
||||
|
* @Message("短信验证码") |
||||
|
*/ |
||||
|
const ALI_VERIFY_CODE = 'SMS_200690862'; |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Constants\v3; |
||||
|
|
||||
|
use Hyperf\Constants\AbstractConstants; |
||||
|
use Hyperf\Constants\Annotation\Constants; |
||||
|
|
||||
|
/** |
||||
|
* @Constants |
||||
|
*/ |
||||
|
class SsdbKeys extends AbstractConstants |
||||
|
{ |
||||
|
/** |
||||
|
* @Message("短信验证码") |
||||
|
*/ |
||||
|
const VERIFY_CODE = 'verify_code_'; |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Controller\v3; |
||||
|
|
||||
|
use App\Controller\BaseController; |
||||
|
use App\Request\v3\VerifyCodeRequest; |
||||
|
use App\Service\v3\Interfaces\VerifyCodeServiceInterface; |
||||
|
use Psr\Http\Message\ResponseInterface; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
|
||||
|
/** |
||||
|
* 短信相关 |
||||
|
* Class SmsController |
||||
|
* @package App\Controller\v3 |
||||
|
*/ |
||||
|
class SmsController extends BaseController |
||||
|
{ |
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var VerifyCodeServiceInterface |
||||
|
*/ |
||||
|
protected $verifyCodeService; |
||||
|
|
||||
|
/** |
||||
|
* 获取手机验证码,发送验证码短信 |
||||
|
* 1、获取手机号并验证 |
||||
|
* 2、发送短信 |
||||
|
* 3、存储验证码,保留用于校验,有失效时间 |
||||
|
* @param VerifyCodeRequest $request |
||||
|
* @return ResponseInterface |
||||
|
*/ |
||||
|
public function getVerifyCode(VerifyCodeRequest $request) |
||||
|
{ |
||||
|
// 获取参数
|
||||
|
$params = $request->validated(); |
||||
|
// 获取并发送验证码
|
||||
|
$this->verifyCodeService->make($params['user_id'], $params['tel']); |
||||
|
|
||||
|
return $this->success([]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Controller\v3; |
||||
|
|
||||
|
use App\Constants\v3\ErrorCode; |
||||
|
use App\Controller\BaseController; |
||||
|
use App\Request\v3\UserBindTelRequest; |
||||
|
use App\Service\v3\Interfaces\UserBindServiceInterface; |
||||
|
use App\Service\v3\Interfaces\VerifyCodeServiceInterface; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
|
||||
|
/** |
||||
|
* 用户相关 |
||||
|
* Class UserController |
||||
|
* @package App\Controller\v3 |
||||
|
*/ |
||||
|
class UserController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var VerifyCodeServiceInterface |
||||
|
*/ |
||||
|
protected $verifyCodeService; |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var UserBindServiceInterface |
||||
|
*/ |
||||
|
protected $userBindService; |
||||
|
|
||||
|
public function bindTel(UserBindTelRequest $request) |
||||
|
{ |
||||
|
|
||||
|
// 获取参数
|
||||
|
$params = $request->validated(); |
||||
|
// 校验验证码
|
||||
|
$this->verifyCodeService->check($params['user_id'], $params['tel'], $params['verify_code']); |
||||
|
// 绑定
|
||||
|
$this->userBindService->makeTel($params['user_id'], $params['tel']); |
||||
|
|
||||
|
return $this->success([]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
/** |
||||
|
* This file is part of Hyperf. |
||||
|
* |
||||
|
* @link https://www.hyperf.io |
||||
|
* @document https://doc.hyperf.io |
||||
|
* @contact group@hyperf.io |
||||
|
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE |
||||
|
*/ |
||||
|
namespace App\Exception; |
||||
|
|
||||
|
use App\Constants\v3\ErrorCode; |
||||
|
use Hyperf\Server\Exception\ServerException; |
||||
|
use Throwable; |
||||
|
|
||||
|
class ErrorCodeException extends ServerException |
||||
|
{ |
||||
|
public function __construct(int $code = 0, string $message = null, Throwable $previous = null) |
||||
|
{ |
||||
|
|
||||
|
if (is_null($message)) { |
||||
|
$message = ErrorCode::getMessage($code); |
||||
|
} |
||||
|
|
||||
|
parent::__construct($message, $code, $previous); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,48 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Exception\Handler; |
||||
|
|
||||
|
use App\Exception\ErrorCodeException; |
||||
|
use Hyperf\Contract\StdoutLoggerInterface; |
||||
|
use Hyperf\ExceptionHandler\ExceptionHandler; |
||||
|
use Hyperf\HttpMessage\Stream\SwooleStream; |
||||
|
use Psr\Http\Message\ResponseInterface; |
||||
|
use Throwable; |
||||
|
|
||||
|
class ErrorCodeExceptionHandler extends ExceptionHandler |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @var StdoutLoggerInterface |
||||
|
*/ |
||||
|
protected $logger; |
||||
|
|
||||
|
public function __construct(StdoutLoggerInterface $logger) |
||||
|
{ |
||||
|
$this->logger = $logger; |
||||
|
} |
||||
|
|
||||
|
public function handle(Throwable $throwable, ResponseInterface $response) |
||||
|
{ |
||||
|
$this->logger->error(sprintf('%s[%s] in %s', $throwable->getMessage(), $throwable->getLine(), $throwable->getFile())); |
||||
|
$this->logger->error($throwable->getTraceAsString()); |
||||
|
|
||||
|
$this->stopPropagation(); |
||||
|
|
||||
|
$content = json_encode([ |
||||
|
"status" => 'error', |
||||
|
"code" => $throwable->getCode(), |
||||
|
"result" => [], |
||||
|
"message" => $throwable->getMessage() |
||||
|
]); |
||||
|
|
||||
|
return $response->withHeader('Content-Type', 'application/json') |
||||
|
->withStatus(200) |
||||
|
->withBody(new SwooleStream($content)); |
||||
|
} |
||||
|
|
||||
|
public function isValid(Throwable $throwable): bool |
||||
|
{ |
||||
|
return $throwable instanceof ErrorCodeException; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Model\v3; |
||||
|
|
||||
|
use App\Model\Model; |
||||
|
|
||||
|
class User extends Model |
||||
|
{ |
||||
|
protected $table = 'lanzu_user'; |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
namespace App\Request\v3; |
||||
|
|
||||
|
use App\Request\BaseFormRequest; |
||||
|
|
||||
|
class UserBindTelRequest extends BaseFormRequest |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* Get the validation rules that apply to the request. |
||||
|
*/ |
||||
|
public function rules(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'user_id' => 'required|nonempty|exists_enable:ims_cjdc_user,id', |
||||
|
'tel' => 'required|nonempty|tel', |
||||
|
'verify_code' => 'required|nonempty|numeric|strlen:6,6', |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function messages(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'user_id.*' => ':attribute未登录或无效', |
||||
|
'tel.*' => ':attribute无效', |
||||
|
'verify_code.*' => ':attribute格式有误', |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
public function attributes(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'user_id' => '用户', |
||||
|
'tel' => '手机号码', |
||||
|
'verify_code' => '验证码', |
||||
|
]; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
<?php |
||||
|
|
||||
|
declare(strict_types=1); |
||||
|
|
||||
|
namespace App\Request\v3; |
||||
|
|
||||
|
use App\Request\BaseFormRequest; |
||||
|
|
||||
|
class VerifyCodeRequest extends BaseFormRequest |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* Get the validation rules that apply to the request. |
||||
|
*/ |
||||
|
public function rules(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'user_id' => 'required|nonempty|exists_enable:ims_cjdc_user,id', |
||||
|
'tel' => 'required|nonempty|tel', |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return array |
||||
|
*/ |
||||
|
public function messages(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'user_id.*' => ':attribute未登录或无效', |
||||
|
'tel.*' => ':attribute无效', |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
public function attributes(): array |
||||
|
{ |
||||
|
return [ |
||||
|
'user_id' => '用户', |
||||
|
'tel' => '手机号码', |
||||
|
]; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Implementations; |
||||
|
|
||||
|
use App\Service\v3\Interfaces\HelperServiceInterface; |
||||
|
|
||||
|
class HelperService implements HelperServiceInterface |
||||
|
{ |
||||
|
|
||||
|
public function makeNumCode($length) |
||||
|
{ |
||||
|
// 获取验证码
|
||||
|
$codeArr = array_map(function ($item) { |
||||
|
return mt_rand(0,9); |
||||
|
}, array_pad([], $length, 0)); |
||||
|
|
||||
|
// 返回验证码
|
||||
|
return implode('', $codeArr); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Implementations; |
||||
|
|
||||
|
use AlibabaCloud\Client\AlibabaCloud; |
||||
|
use AlibabaCloud\Client\Exception\ClientException; |
||||
|
use AlibabaCloud\Client\Exception\ServerException; |
||||
|
use App\Constants\v3\ErrorCode; |
||||
|
use App\Exception\ErrorCodeException; |
||||
|
use Exception; |
||||
|
use App\Commons\Log; |
||||
|
use App\Constants\v3\SmsTemplateCode; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
use App\Service\v3\Interfaces\SmsServiceInterface; |
||||
|
|
||||
|
class SmsAliService implements SmsServiceInterface |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var Log |
||||
|
*/ |
||||
|
protected $log; |
||||
|
|
||||
|
public function send($tel, $template, $templateParams) |
||||
|
{ |
||||
|
|
||||
|
try { |
||||
|
$aliSms = config('alisms'); |
||||
|
AlibabaCloud::accessKeyClient($aliSms['app_key'], $aliSms['app_secret']) |
||||
|
->regionId($aliSms['regionid']) |
||||
|
->asDefaultClient(); |
||||
|
|
||||
|
$result = AlibabaCloud::rpc() |
||||
|
->product($aliSms['product']) |
||||
|
->version('2017-05-25') |
||||
|
->action('SendSms') |
||||
|
->method('POST') |
||||
|
->host($aliSms['host']) |
||||
|
->options([ |
||||
|
'query' => [ |
||||
|
'RegionId' => $aliSms['regionid'], |
||||
|
'PhoneNumbers' => $tel, |
||||
|
'SignName' => $aliSms['sign_name'], |
||||
|
'TemplateCode' => $template, |
||||
|
'TemplateParam' => $templateParams, |
||||
|
], |
||||
|
]) |
||||
|
->request(); |
||||
|
return $result->toArray(); |
||||
|
} catch (ClientException $e) { |
||||
|
$this->log->event('alisms', ['alisms_error_ClientException' => $e->getErrorMessage()]); |
||||
|
throw new ErrorCodeException(ErrorCode::SMS_SEND_FAILURE); |
||||
|
} catch (ServerException $e) { |
||||
|
$this->log->event('alisms', ['alisms_error_ServerException' => $e->getErrorMessage()]); |
||||
|
throw new ErrorCodeException(ErrorCode::SMS_SEND_FAILURE); |
||||
|
} catch (Exception $e) { |
||||
|
$this->log->event('alisms', ['alisms_error_Exception' => $e->getErrorMessage()]); |
||||
|
throw new ErrorCodeException(ErrorCode::SMS_SEND_FAILURE); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function makeVerifyCode($tel, $code) |
||||
|
{ |
||||
|
$params = ['user_name' => '疯狂的水叔叔', 'market_name' => '验证码', 'money' => $code]; |
||||
|
return $this->send($tel, SmsTemplateCode::ALI_VERIFY_CODE, json_encode($params)); |
||||
|
} |
||||
|
|
||||
|
public function checkVerifyCode($tel, $code) |
||||
|
{ |
||||
|
// TODO: Implement checkVerifyCode() method.
|
||||
|
} |
||||
|
|
||||
|
public function removeVerifyCode($tel, $code) |
||||
|
{ |
||||
|
// TODO: Implement removeVerifyCode() method.
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Implementations; |
||||
|
|
||||
|
use App\Constants\v3\ErrorCode; |
||||
|
use App\Exception\ErrorCodeException; |
||||
|
use App\Model\v3\User; |
||||
|
use App\Service\v3\Interfaces\UserBindServiceInterface; |
||||
|
|
||||
|
class UserBindService implements UserBindServiceInterface |
||||
|
{ |
||||
|
|
||||
|
public function makeTel($userId, $tel) |
||||
|
{ |
||||
|
$user = User::find($userId); |
||||
|
$user->tel = $tel; |
||||
|
if (!$user->save()) { |
||||
|
throw new ErrorCodeException(ErrorCode::BIND_TEL_ERROR); |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public function checkTel($userId) |
||||
|
{ |
||||
|
$user = User::find($userId); |
||||
|
return $user->tel ? true : false; |
||||
|
} |
||||
|
|
||||
|
public function removeTel($userId) |
||||
|
{ |
||||
|
$user = User::find($userId); |
||||
|
$user->tel = ''; |
||||
|
if (!$user->save()) { |
||||
|
throw new ErrorCodeException(ErrorCode::UNBIND_TEL_ERROR); |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,89 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Implementations; |
||||
|
|
||||
|
use App\Constants\v3\ErrorCode; |
||||
|
use App\Constants\v3\SsdbKeys; |
||||
|
use App\Exception\BusinessException; |
||||
|
use App\Exception\ErrorCodeException; |
||||
|
use App\Service\v3\Interfaces\HelperServiceInterface; |
||||
|
use App\Service\v3\Interfaces\SmsServiceInterface; |
||||
|
use App\Service\v3\Interfaces\VerifyCodeServiceInterface; |
||||
|
use App\TaskWorker\SSDBTask; |
||||
|
use Hyperf\Utils\ApplicationContext; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
|
||||
|
class VerifyCodeService implements VerifyCodeServiceInterface |
||||
|
{ |
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var SmsServiceInterface |
||||
|
*/ |
||||
|
protected $smsService; |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var HelperServiceInterface |
||||
|
*/ |
||||
|
protected $helperService; |
||||
|
|
||||
|
public function make($userId, $tel) |
||||
|
{ |
||||
|
// 获取验证码
|
||||
|
$verifyCode = $this->helperService->makeNumCode(6); |
||||
|
|
||||
|
// 存到SSDB
|
||||
|
$ssdbClient = ApplicationContext::getContainer()->get(SSDBTask::class); |
||||
|
$setRes = $ssdbClient->exec( |
||||
|
"setnx", |
||||
|
SsdbKeys::VERIFY_CODE.$userId.'_'.$tel, |
||||
|
$verifyCode |
||||
|
); |
||||
|
if (!$setRes) { |
||||
|
throw new ErrorCodeException(ErrorCode::VERIFY_CODE_SENDED); |
||||
|
} |
||||
|
|
||||
|
$expireRes = $ssdbClient->exec( |
||||
|
'expire', |
||||
|
SsdbKeys::VERIFY_CODE.$userId.'_'.$tel, |
||||
|
900 |
||||
|
); |
||||
|
if (!$expireRes) { |
||||
|
throw new ErrorCodeException(ErrorCode::VERIFY_CODE_ERROR); |
||||
|
} |
||||
|
|
||||
|
// 发送短信
|
||||
|
$smsRes = $this->smsService->makeVerifyCode($tel, $verifyCode); |
||||
|
if (!$smsRes) { |
||||
|
throw new ErrorCodeException(ErrorCode::VERIFY_CODE_ERROR); |
||||
|
} |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public function check($userId, $tel, $verifyCode) |
||||
|
{ |
||||
|
// 获取验证码并验证
|
||||
|
$ssdbClient = ApplicationContext::getContainer()->get(SSDBTask::class); |
||||
|
$code = $ssdbClient->exec( |
||||
|
"get", |
||||
|
SsdbKeys::VERIFY_CODE.$userId.'_'.$tel |
||||
|
); |
||||
|
if (empty($code) || $verifyCode!=$code) { |
||||
|
throw new ErrorCodeException(ErrorCode::INVALID_VERIFY_CODE); |
||||
|
} |
||||
|
|
||||
|
$this->remove($userId, $tel); |
||||
|
return true; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public function remove($userId, $tel) |
||||
|
{ |
||||
|
$ssdbClient = ApplicationContext::getContainer()->get(SSDBTask::class); |
||||
|
return $ssdbClient->exec( |
||||
|
'del', |
||||
|
SsdbKeys::VERIFY_CODE.$userId.'_'.$tel |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Interfaces; |
||||
|
|
||||
|
interface HelperServiceInterface |
||||
|
{ |
||||
|
public function makeNumCode($length); |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Interfaces; |
||||
|
|
||||
|
interface SmsServiceInterface |
||||
|
{ |
||||
|
public function send($tel, $template, $templateParams); |
||||
|
public function makeVerifyCode($tel, $code); |
||||
|
public function checkVerifyCode($tel, $code); |
||||
|
public function removeVerifyCode($tel, $code); |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Interfaces; |
||||
|
|
||||
|
interface UserBindServiceInterface |
||||
|
{ |
||||
|
public function makeTel($userId, $tel); |
||||
|
public function checkTel($userId); |
||||
|
public function removeTel($userId); |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Interfaces; |
||||
|
|
||||
|
interface VerifyCodeServiceInterface |
||||
|
{ |
||||
|
public function make($userId, $tel); |
||||
|
public function check($userId, $tel, $verifyCode); |
||||
|
public function remove($userId, $tel); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue