初始化项目
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\api\service\passport;
|
||||
|
||||
use app\common\service\BaseService;
|
||||
use yiovo\captcha\facade\CaptchaApi;
|
||||
|
||||
class Captcha extends BaseService
|
||||
{
|
||||
/**
|
||||
* 图形验证码
|
||||
* @return array
|
||||
*/
|
||||
public function create(): array
|
||||
{
|
||||
$data = CaptchaApi::create();
|
||||
return [
|
||||
'base64' => str_replace("\r\n", '', $data['base64']),
|
||||
'key' => $data['key'],
|
||||
'md5' => $data['md5']
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\api\service\passport;
|
||||
|
||||
use think\facade\Cache;
|
||||
use yiovo\captcha\facade\CaptchaApi;
|
||||
use app\api\model\{User as UserModel, Setting as SettingModel};
|
||||
use app\api\service\{user\Oauth as OauthService, user\Avatar as AvatarService, passport\Party as PartyService};
|
||||
use app\api\validate\passport\Login as ValidateLogin;
|
||||
use app\common\service\BaseService;
|
||||
use app\common\enum\Setting as SettingEnum;
|
||||
use cores\exception\BaseException;
|
||||
|
||||
/**
|
||||
* 服务类:用户登录
|
||||
* Class Login
|
||||
* @package app\api\service\passport
|
||||
*/
|
||||
class Login extends BaseService
|
||||
{
|
||||
/**
|
||||
* 用户信息 (登录成功后才记录)
|
||||
* @var UserModel|null $userInfo
|
||||
*/
|
||||
private $userInfo;
|
||||
|
||||
// 用于生成token的自定义盐
|
||||
const TOKEN_SALT = 'user_salt';
|
||||
|
||||
/**
|
||||
* 执行用户登录
|
||||
* @param array $data
|
||||
* @return bool
|
||||
* @throws BaseException
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function login(array $data): bool
|
||||
{
|
||||
// 数据验证
|
||||
$this->validate($data);
|
||||
// 自动登录注册
|
||||
$this->register($data);
|
||||
// 保存第三方用户信息
|
||||
$this->createUserOauth($this->getUserId(), $data['isParty'], $data['partyData']);
|
||||
// 记录登录态
|
||||
return $this->setSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快捷登录:微信小程序用户
|
||||
* @param array $form
|
||||
* @return bool
|
||||
* @throws BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function loginMpWx(array $form): bool
|
||||
{
|
||||
// 获取微信小程序登录态(session)
|
||||
$wxSession = PartyService::getMpWxSession($form['partyData']['code']);
|
||||
|
||||
// 判断openid是否存在
|
||||
$userId = OauthService::getUserIdByOauthId($wxSession['openid'], 'MP-WEIXIN');
|
||||
// 获取用户信息
|
||||
$userInfo = !empty($userId) ? UserModel::detail($userId) : null;
|
||||
|
||||
// 用户信息存在, 更新登录信息
|
||||
if (!empty($userInfo)) {
|
||||
// 更新用户登录信息
|
||||
$this->updateUser($userInfo, true, $form['partyData']);
|
||||
// 记录登录态
|
||||
return $this->setSession();
|
||||
}
|
||||
|
||||
// 用户信息不存在 => 注册新用户 或者 跳转到绑定手机号页
|
||||
$setting = SettingModel::getItem(SettingEnum::REGISTER);
|
||||
// 后台设置了需强制绑定手机号, 返回前端isBindMobile, 跳转到手机号验证页
|
||||
if ($setting['isForceBindMpweixin']) {
|
||||
throwError('当前用户未绑定手机号', null, ['isBindMobile' => true]);
|
||||
}
|
||||
// 后台未开启强制绑定手机号, 直接保存新用户
|
||||
if (!$setting['isForceBindMpweixin']) {
|
||||
// 用户不存在: 创建一个新用户
|
||||
$this->createUser('', true, $form['partyData']);
|
||||
// 保存第三方用户信息
|
||||
$this->createUserOauth($this->getUserId(), true, $form['partyData']);
|
||||
}
|
||||
// 记录登录态
|
||||
return $this->setSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* 快捷登录:微信小程序用户
|
||||
* @param array $form
|
||||
* @return bool
|
||||
* @throws BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public function loginMpWxMobile(array $form): bool
|
||||
{
|
||||
// 获取微信小程序登录态(session)
|
||||
$wxSession = PartyService::getMpWxSession($form['code']);
|
||||
// 解密encryptedData -> 拿到手机号
|
||||
$wxData = OauthService::wxDecryptData($wxSession['session_key'], $form['encryptedData'], $form['iv']);
|
||||
// 整理登录注册数据
|
||||
$loginData = [
|
||||
'mobile' => $wxData['purePhoneNumber'],
|
||||
'isParty' => $form['isParty'],
|
||||
'partyData' => $form['partyData'],
|
||||
];
|
||||
// 自动登录注册
|
||||
$this->register($loginData);
|
||||
// 保存第三方用户信息
|
||||
$this->createUserOauth($this->getUserId(), $loginData['isParty'], $loginData['partyData']);
|
||||
// 记录登录态
|
||||
return $this->setSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存oauth信息(第三方用户信息)
|
||||
* @param int $userId 用户ID
|
||||
* @param bool $isParty 是否为第三方用户
|
||||
* @param array $partyData 第三方用户数据
|
||||
* @return void
|
||||
* @throws BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function createUserOauth(int $userId, bool $isParty, array $partyData = []): void
|
||||
{
|
||||
if ($isParty) {
|
||||
$Oauth = new PartyService;
|
||||
$Oauth->createUserOauth($userId, $partyData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前登录的用户信息
|
||||
*/
|
||||
public function getUserInfo(): ?UserModel
|
||||
{
|
||||
return $this->userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前登录的用户ID
|
||||
* @return int
|
||||
*/
|
||||
private function getUserId(): int
|
||||
{
|
||||
return (int)$this->getUserInfo()['user_id'];
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动登录注册
|
||||
* @param array $data
|
||||
* @return void
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function register(array $data): void
|
||||
{
|
||||
// 查询用户是否已存在
|
||||
// 用户存在: 更新用户登录信息
|
||||
$userInfo = UserModel::detail(['mobile' => $data['mobile']]);
|
||||
if ($userInfo) {
|
||||
$this->updateUser($userInfo, $data['isParty'], $data['partyData']);
|
||||
return;
|
||||
}
|
||||
// 用户不存在: 创建一个新用户
|
||||
$this->createUser($data['mobile'], $data['isParty'], $data['partyData']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
* @param string $mobile 手机号
|
||||
* @param bool $isParty 是否存在第三方用户信息
|
||||
* @param array $partyData 用户信息(第三方)
|
||||
* @return void
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function createUser(string $mobile, bool $isParty, array $partyData = []): void
|
||||
{
|
||||
// 用户信息
|
||||
$data = [
|
||||
'mobile' => $mobile,
|
||||
'nick_name' => !empty($mobile) ? hide_mobile($mobile) : '',
|
||||
'platform' => getPlatform(),
|
||||
'last_login_time' => time(),
|
||||
'store_id' => $this->storeId
|
||||
];
|
||||
// 写入用户信息(第三方)
|
||||
if ($isParty === true && !empty($partyData)) {
|
||||
$partyUserInfo = PartyService::partyUserInfo($partyData, true);
|
||||
$data = array_merge($data, $partyUserInfo);
|
||||
}
|
||||
// 新增用户记录
|
||||
$model = new UserModel;
|
||||
$model->save($data);
|
||||
// 将微信用户昵称添加编号便于后台管理, 例如:微信用户_10001
|
||||
if ($data['nick_name'] === '微信用户') {
|
||||
$model->save(['nick_name' => "微信用户_{$model['user_id']}"]);
|
||||
}
|
||||
// 记录用户信息
|
||||
$this->userInfo = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户登录信息
|
||||
* @param UserModel $userInfo
|
||||
* @param bool $isParty 是否存在第三方用户信息
|
||||
* @param array $partyData 用户信息(第三方)
|
||||
* @return void
|
||||
*/
|
||||
private function updateUser(UserModel $userInfo, bool $isParty, array $partyData = []): void
|
||||
{
|
||||
// 用户信息
|
||||
$data = [
|
||||
'last_login_time' => time(),
|
||||
'store_id' => $this->storeId
|
||||
];
|
||||
// 写入用户信息(第三方)
|
||||
// 如果不需要每次登录都更新微信用户头像昵称, 下面4行代码可以屏蔽掉
|
||||
// if ($isParty === true && !empty($partyData)) {
|
||||
// $partyUserInfo = PartyService::partyUserInfo($partyData, true);
|
||||
// $data = array_merge($data, $partyUserInfo);
|
||||
// }
|
||||
// 更新用户记录
|
||||
$status = $userInfo->save($data) !== false;
|
||||
// 记录用户信息
|
||||
$this->userInfo = $userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录登录态
|
||||
* @return bool
|
||||
* @throws BaseException
|
||||
*/
|
||||
private function setSession(): bool
|
||||
{
|
||||
empty($this->userInfo) && throwError('未找到用户信息');
|
||||
// 登录的token
|
||||
$token = $this->getToken($this->getUserId());
|
||||
// 记录缓存, 30天
|
||||
Cache::set($token, [
|
||||
'user' => $this->userInfo,
|
||||
'store_id' => $this->storeId,
|
||||
'is_login' => true,
|
||||
], 86400 * 30);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据验证
|
||||
* @param array $data
|
||||
* @return void
|
||||
* @throws BaseException
|
||||
*/
|
||||
private function validate(array $data): void
|
||||
{
|
||||
// 数据验证
|
||||
$validate = new ValidateLogin;
|
||||
if (!$validate->check($data)) {
|
||||
throwError($validate->getError());
|
||||
}
|
||||
// 验证短信验证码是否匹配
|
||||
if (!CaptchaApi::checkSms($data['smsCode'], $data['mobile'])) {
|
||||
throwError('短信验证码不正确');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录的token
|
||||
* @param int $userId
|
||||
* @return string
|
||||
*/
|
||||
public function getToken(int $userId): string
|
||||
{
|
||||
static $token = '';
|
||||
if (empty($token)) {
|
||||
$token = $this->makeToken($userId);
|
||||
}
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成用户认证的token
|
||||
* @param int $userId
|
||||
* @return string
|
||||
*/
|
||||
private function makeToken(int $userId): string
|
||||
{
|
||||
$storeId = $this->storeId;
|
||||
// 生成一个不会重复的随机字符串
|
||||
$guid = get_guid_v4();
|
||||
// 当前时间戳 (精确到毫秒)
|
||||
$timeStamp = microtime(true);
|
||||
// 自定义一个盐
|
||||
$salt = self::TOKEN_SALT;
|
||||
return md5("{$storeId}_{$timeStamp}_{$userId}_{$guid}_{$salt}");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\api\service\passport;
|
||||
|
||||
use app\api\model\UserOauth as UserOauthModel;
|
||||
use app\api\service\user\Oauth as OauthService;
|
||||
use app\api\service\user\Avatar as AvatarService;
|
||||
use app\common\service\BaseService;
|
||||
use cores\exception\BaseException;
|
||||
|
||||
/**
|
||||
* 第三方用户注册登录服务
|
||||
* Class Party
|
||||
* @package app\api\service\passport
|
||||
*/
|
||||
class Party extends BaseService
|
||||
{
|
||||
/**
|
||||
* 保存用户的第三方认证信息
|
||||
* @param int $userId 用户ID
|
||||
* @param array $partyData 第三方登录信息
|
||||
* @return bool
|
||||
* @throws BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public function createUserOauth(int $userId, array $partyData = []): bool
|
||||
{
|
||||
try {
|
||||
// 获取oauthId和unionId
|
||||
$oauthInfo = $this->getOauthInfo($partyData);
|
||||
} catch (BaseException $e) {
|
||||
// isBack参数代表需重新获取code, 前端拿到该参数进行页面返回
|
||||
throwError($e->getMessage(), null, ['isBack' => true]);
|
||||
}
|
||||
// 是否存在第三方用户
|
||||
$oauthId = UserOauthModel::getOauthIdByUserId($userId, $partyData['oauth']);
|
||||
// 如果不存在oauth则写入
|
||||
if (empty($oauthId)) {
|
||||
return (new UserOauthModel)->add([
|
||||
'user_id' => $userId,
|
||||
'oauth_type' => $partyData['oauth'],
|
||||
'oauth_id' => $oauthInfo['oauth_id'],
|
||||
'unionid' => $oauthInfo['unionid'] ?? '', // unionid可以不存在
|
||||
'store_id' => $this->storeId
|
||||
]);
|
||||
}
|
||||
// 如果存在第三方用户, 需判断oauthId是否相同
|
||||
if ($oauthId != $oauthInfo['oauth_id']) {
|
||||
// isBack参数代表需重新获取code, 前端拿到该参数进行页面返回
|
||||
throwError('很抱歉,当前手机号已绑定其他微信号', null, ['isBack' => true]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信小程序登录态(session)
|
||||
* 这里支持静态变量缓存, 用于实现第二次调用该方法时直接返回已获得的session
|
||||
* @param string $code
|
||||
* @return array|false
|
||||
* @throws BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
public static function getMpWxSession(string $code)
|
||||
{
|
||||
static $session;
|
||||
if (empty($session)) {
|
||||
try {
|
||||
// 微信小程序通过code获取session
|
||||
$session = OauthService::wxCode2Session($code);
|
||||
} catch (BaseException $e) {
|
||||
// showError参数表示让前端显示错误
|
||||
throwError($e->getMessage());
|
||||
}
|
||||
}
|
||||
return $session;
|
||||
}
|
||||
|
||||
/**
|
||||
* 第三方用户信息
|
||||
* @param array $partyData 第三方用户信息
|
||||
* @param bool $isGetAvatarUrl 是否下载头像
|
||||
* @return array
|
||||
* @throws BaseException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
public static function partyUserInfo(array $partyData, bool $isGetAvatarUrl = true): array
|
||||
{
|
||||
$partyUserInfo = $partyData['userInfo'];
|
||||
$data = [
|
||||
'nick_name' => $partyUserInfo['nickName'],
|
||||
'gender' => $partyUserInfo['gender']
|
||||
];
|
||||
// 下载用户头像
|
||||
if ($isGetAvatarUrl) {
|
||||
$data['avatar_id'] = static::partyAvatar($partyUserInfo['avatarUrl']);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载第三方头像并写入文件库
|
||||
* @param string $avatarUrl
|
||||
* @return int
|
||||
* @throws BaseException
|
||||
* @throws \think\Exception
|
||||
*/
|
||||
private static function partyAvatar(string $avatarUrl): int
|
||||
{
|
||||
$Avatar = new AvatarService;
|
||||
$fileId = $Avatar->party($avatarUrl);
|
||||
return $fileId ? $fileId : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取第三方用户session信息 (openid、unionid、session_key等)
|
||||
* @param array $partyData
|
||||
* @return array|null
|
||||
* @throws BaseException
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\DbException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
*/
|
||||
private function getOauthInfo(array $partyData): ?array
|
||||
{
|
||||
if ($partyData['oauth'] === 'MP-WEIXIN') {
|
||||
$wxSession = static::getMpWxSession($partyData['code']);
|
||||
return ['oauth_id' => $wxSession['openid'], 'unionid' => $wxSession['unionid'] ?? null];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 萤火科技 <admin@yiovo.com>
|
||||
// +----------------------------------------------------------------------
|
||||
declare (strict_types=1);
|
||||
|
||||
namespace app\api\service\passport;
|
||||
|
||||
use yiovo\cache\facade\Cache;
|
||||
use yiovo\captcha\facade\CaptchaApi;
|
||||
use app\api\validate\passport\SmsCaptcha as ValidateSmsCaptcha;
|
||||
use app\common\service\BaseService;
|
||||
use app\common\service\Message as MessageService;
|
||||
use cores\exception\BaseException;
|
||||
|
||||
/**
|
||||
* 服务类:发送短信验证码
|
||||
* Class SmsCaptcha
|
||||
* @package app\api\service\passport
|
||||
*/
|
||||
class SmsCaptcha extends BaseService
|
||||
{
|
||||
// 最大发送次数,默认10次
|
||||
protected $sendTimes = 10;
|
||||
|
||||
// 发送限制间隔时间,默认24小时
|
||||
protected $safeTime = 86400;
|
||||
|
||||
/**
|
||||
* 发送短信验证码
|
||||
* @param array $data
|
||||
* @return bool
|
||||
* @throws BaseException
|
||||
*/
|
||||
public function handle(array $data): bool
|
||||
{
|
||||
// 数据验证
|
||||
$this->validate($data);
|
||||
// 执行发送短信
|
||||
if (!$this->sendCaptcha($data['mobile'])) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行发送短信
|
||||
* @param string $mobile
|
||||
* @return bool
|
||||
*/
|
||||
private function sendCaptcha(string $mobile): bool
|
||||
{
|
||||
// 缓存发送记录并判断次数
|
||||
if (!$this->record($mobile)) {
|
||||
return false;
|
||||
}
|
||||
// 生成验证码
|
||||
$smsCaptcha = CaptchaApi::createSMS($mobile);
|
||||
// 发送短信
|
||||
MessageService::send('passport.captcha', [
|
||||
'code' => $smsCaptcha['code'],
|
||||
'mobile' => $smsCaptcha['key']
|
||||
], $this->storeId);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录短信验证码发送记录并判断是否超出发送限制
|
||||
* @param string $mobile
|
||||
* @return bool
|
||||
*/
|
||||
private function record(string $mobile): bool
|
||||
{
|
||||
// 获取发送记录缓存
|
||||
$record = Cache::get("sendCaptchaSMS.$mobile");
|
||||
// 写入缓存:记录剩余发送次数
|
||||
if (empty($record)) {
|
||||
Cache::set("sendCaptchaSMS.$mobile", ['times' => $this->sendTimes - 1], $this->safeTime);
|
||||
return true;
|
||||
}
|
||||
// 判断发送次数是否合法
|
||||
if ($record['times'] <= 0) {
|
||||
$this->error = '很抱歉,已超出今日最大发送次数限制';
|
||||
return false;
|
||||
}
|
||||
// 发送次数递减
|
||||
Cache::update("sendCaptchaSMS.$mobile", ['times' => $record['times'] - 1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据验证
|
||||
* @param array $data
|
||||
* @throws BaseException
|
||||
*/
|
||||
private function validate(array $data)
|
||||
{
|
||||
// 数据验证
|
||||
$validate = new ValidateSmsCaptcha;
|
||||
if (!$validate->check($data)) {
|
||||
throwError($validate->getError());
|
||||
}
|
||||
// 验证图形验证码
|
||||
if (!CaptchaApi::check($data['captchaCode'], $data['captchaKey'])) {
|
||||
throwError('很抱歉,图形验证码不正确');
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user