From 1a9008b3185494d9ed848b5a29aa7320bd526607 Mon Sep 17 00:00:00 2001 From: ROmani Date: Mon, 26 Feb 2024 00:41:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Cache/Base/BaseCache.php | 71 +++++++ app/Cache/Base/StructBaseCache.php | 21 ++ app/Cache/Base/TableBaseCache.php | 45 +++++ app/Cache/Struct/StructUserCommonCacheUid.php | 38 ++++ app/Cache/Table/TableCustomerUserCache.php | 22 +++ app/Const/VrCode.php | 3 + app/Exceptions/ModelException.php | 8 + app/Http/Controllers/Base/BaseController.php | 3 +- .../Base/CustomerBaseController.php | 2 +- .../Customer/CustomerUserController.php | 132 ++++++------- .../Controllers/Follow/FollowController.php | 59 ++++++ app/Http/Controllers/Post/PostController.php | 11 ++ app/Http/Controllers/Sms/SmsController.php | 86 +++++++++ app/Http/Middleware/AuthMiddleware.php | 12 +- app/Models/Base/BaseModel.php | 8 +- app/Models/Customer/CustomerUser.php | 105 ---------- .../Customer/CustomerUserExtendModel.php | 72 +++++++ app/Models/Customer/CustomerUserModel.php | 141 ++++++++++++++ app/Models/Follow/FollowHistoryModel.php | 40 ++++ app/Models/Follow/FollowModel.php | 173 +++++++++++++++++ app/Models/Post/PostHistoryModel.php | 48 +++++ app/Models/Post/PostModel.php | 133 +++++++++++++ app/Models/Post/PostPushBoxModel.php | 180 ++++++++++++++++++ app/Service/SmsService.php | 21 ++ app/Service/VrCodeService.php | 46 +++-- app/Thrid/Sms/Movider/Movider.php | 37 ++++ app/Thrid/Sms/SmsBase.php | 35 ++++ app/Thrid/Sms/SmsInterface.php | 17 ++ app/Tools/CollectOffsetLimit.php | 82 ++++++++ app/Tools/Tools.php | 8 + config/services.php | 18 ++ docker.yaml | 35 ++++ routes/api.php | 19 +- 33 files changed, 1515 insertions(+), 216 deletions(-) create mode 100644 app/Cache/Base/BaseCache.php create mode 100644 app/Cache/Base/StructBaseCache.php create mode 100644 app/Cache/Base/TableBaseCache.php create mode 100644 app/Cache/Struct/StructUserCommonCacheUid.php create mode 100644 app/Cache/Table/TableCustomerUserCache.php create mode 100644 app/Exceptions/ModelException.php create mode 100644 app/Http/Controllers/Follow/FollowController.php create mode 100644 app/Http/Controllers/Post/PostController.php create mode 100644 app/Http/Controllers/Sms/SmsController.php delete mode 100644 app/Models/Customer/CustomerUser.php create mode 100644 app/Models/Customer/CustomerUserExtendModel.php create mode 100644 app/Models/Customer/CustomerUserModel.php create mode 100644 app/Models/Follow/FollowHistoryModel.php create mode 100644 app/Models/Follow/FollowModel.php create mode 100644 app/Models/Post/PostHistoryModel.php create mode 100644 app/Models/Post/PostModel.php create mode 100644 app/Models/Post/PostPushBoxModel.php create mode 100644 app/Service/SmsService.php create mode 100644 app/Thrid/Sms/Movider/Movider.php create mode 100644 app/Thrid/Sms/SmsBase.php create mode 100644 app/Thrid/Sms/SmsInterface.php create mode 100644 app/Tools/CollectOffsetLimit.php create mode 100644 docker.yaml diff --git a/app/Cache/Base/BaseCache.php b/app/Cache/Base/BaseCache.php new file mode 100644 index 0000000..d384b3f --- /dev/null +++ b/app/Cache/Base/BaseCache.php @@ -0,0 +1,71 @@ +primary_key = $primary_key; + } + + function getPrimaryKey($primary_key = null): ?string + { + if (empty($primary_key) && empty($this->primary_key)) return null; + if (empty($primary_key)) $primary_key = $this->primary_key; + return $this->primary_prefix . $primary_key; + } + + function loadToCache(): bool + { + $sCacheKey = $this->getPrimaryKey(); + $aData = $this->loadData(); + if (empty($aData)) return false; + return Cache::put($sCacheKey, serialize($aData), self::CACHE_TTL); + } + + abstract function loadData(): array|null; + + function getCacheData($primary_key = null): array|null + { + if ($primary_key === null) $primary_key = $this->primary_key; + if (empty($primary_key)) return []; + $sCacheKey = $this->getPrimaryKey($primary_key); + $sData = Cache::get($sCacheKey); + if (empty($sData)) { + $this->primary_key = $primary_key; + if($this->loadToCache()) $sData = Cache::get($sCacheKey); + } + if (empty($sData)) return null; + return unserialize($sData); + } + + //根据primary_key获取缓存数据单个值,不指定key就默认获取所有 + function getCacheDataByKey($primary_key = null, $key = null): string|array|bool|null + { + if ($primary_key === null) $primary_key = $this->primary_key; + if (empty($primary_key)) return false; + $aData = $this->getCacheData($primary_key); + if(empty($aData)) return null; + if (empty($key)) return $aData; + return $aData[$key] ?? ''; + } + + function delCacheData($primary_key = null): bool + { + if ($primary_key === null) $primary_key = $this->primary_key; + if (empty($primary_key)) return false; + $sCacheKey = $this->getPrimaryKey($primary_key); + return Cache::forget($sCacheKey); + } + +} diff --git a/app/Cache/Base/StructBaseCache.php b/app/Cache/Base/StructBaseCache.php new file mode 100644 index 0000000..8363c70 --- /dev/null +++ b/app/Cache/Base/StructBaseCache.php @@ -0,0 +1,21 @@ +aCacheKey as $key => $value) { + if (method_exists($this, $value)) $aData[$key] = $this->$value(); + } + return $aData; + } + +} diff --git a/app/Cache/Base/TableBaseCache.php b/app/Cache/Base/TableBaseCache.php new file mode 100644 index 0000000..af37f51 --- /dev/null +++ b/app/Cache/Base/TableBaseCache.php @@ -0,0 +1,45 @@ +table_class(); + //排除不需要的字段 + if (!empty($this->get_exclude_columns) && $this->get_columns != ['*']) $this->get_columns = array_diff($this->get_columns, $this->get_exclude_columns); + $oData = $oTable->findItemByWhere([$this->primary_key_column => $this->primary_key], $this->get_columns); + if($oData->isEmpty()) return null; + $aData = $oData->toArray(); + //排除不需要的字段 + if (!empty($this->get_exclude_columns) && $this->get_columns == ['*'] && !empty($aData)) { + foreach ($this->get_exclude_columns as $sColumn) { + unset($aData[$sColumn]); + } + } + + if (empty($aData)) return null; + return $aData; + } else { + return $this->loadTable(); + } + } + + +} diff --git a/app/Cache/Struct/StructUserCommonCacheUid.php b/app/Cache/Struct/StructUserCommonCacheUid.php new file mode 100644 index 0000000..a93a044 --- /dev/null +++ b/app/Cache/Struct/StructUserCommonCacheUid.php @@ -0,0 +1,38 @@ + 'genUserUid', + self::USER_IS_ACTIVE => 'genUserIsActive', + ]; + + function genUserUid(): string + { + return $this->primary_key; + } + + function genUserIsActive(): string + { + $oCustomerUserExtendModel = new CustomerUserExtendModel(); + $oCustomerUserExtend = $oCustomerUserExtendModel->findItem($this->primary_key); + if(!$oCustomerUserExtend) return ''; + return $oCustomerUserExtend->is_active; + } + + + +} diff --git a/app/Cache/Table/TableCustomerUserCache.php b/app/Cache/Table/TableCustomerUserCache.php new file mode 100644 index 0000000..c292e03 --- /dev/null +++ b/app/Cache/Table/TableCustomerUserCache.php @@ -0,0 +1,22 @@ + 'vrcode:register:', self::TOPIC_RESET_PASSWD => 'vrcode:reset_passwd:', self::TOPIC_RESET_GOOGLE_AUTH => 'vrcode:reset_google_auth:', self::TOPIC_SET_WALLET_PASSWD => 'vrcode:set_wallet_passwd:', + self::TOPIC_LOGIN => 'vrcode:login:', ]; } diff --git a/app/Exceptions/ModelException.php b/app/Exceptions/ModelException.php new file mode 100644 index 0000000..cd576a8 --- /dev/null +++ b/app/Exceptions/ModelException.php @@ -0,0 +1,8 @@ + 'required|numeric|max:15', 'password' => 'required|alpha_dash:ascii|max:50', 'device' => 'required|numeric|max:10', + 'vr_code' => 'required|numeric|max:10', ], 'register' => [ 'phone_area' => 'required|alpha_dash:ascii|max:5', @@ -35,7 +35,7 @@ class CustomerUserController extends CustomerBaseController 'phone' => 'numeric|max:15', 'email' => 'email|max:30', ], - 'setUserInfo' => [ + 'updateUserInfo' => [ 'nickname' => 'max:20', 'email' => 'email|max:30', 'username' => 'alpha_dash:ascii|max:50', @@ -43,11 +43,6 @@ class CustomerUserController extends CustomerBaseController 'phone' => 'numeric|max:15', 'is_google_auth' => 'numeric|max:2', ], - 'sendVrcodeCode' => [ - 'topic' => 'required|numeric', - 'phone_area' => 'alpha_dash:ascii|max:5', - 'phone' => 'numeric|max:15', - ], ]; function getCustomerUserInfo(): \Illuminate\Http\JsonResponse @@ -58,7 +53,7 @@ class CustomerUserController extends CustomerBaseController $data = [ 'token' => $token, 'user' => [ - 'id' =>$aUser['id'], + 'id' => $aUser['id'], 'username' => $aUser['username'], 'nickname' => $aUser['nickname'], 'is_google_auth' => $aUser['is_google_auth'], @@ -69,29 +64,45 @@ class CustomerUserController extends CustomerBaseController return $this->success($data); } + /** + * @throws AppException + */ function signIn(): \Illuminate\Http\JsonResponse { $request = request(); - $username = $request->input('username'); + $phone_area = $request->input('phone_area'); + $phone = $request->input('phone'); $password = $request->input('password'); + $vrcode = $request->input('vrcode'); $device = $request->input('device'); - if(!in_array($device,Im::PLATFORM)) return $this->error('invalid device'); + if (!in_array($device, Im::PLATFORM)) return $this->error('invalid device'); - $oCustomerUser = new CustomerUser(); - $oUser = $oCustomerUser->findItemByUsername($username); + $oCustomerUser = new CustomerUserModel(); + $oUser = $oCustomerUser->findItemByPhone($phone_area, $phone); if (!$oUser) { return $this->error('用户名不存在'); } - if (!$oCustomerUser->checkPasswd($oUser->id,$password)) { - return $this->error('密码错误'); + if (!empty($vrcode)) { //phone login + //check vrcode + $oVrCodeService = new VrCodeService(); + $oVrCodeService->setIType(VrCode::TOPIC_LOGIN); + $oVrCodeService->setSPhoneArea($phone_area); + $oVrCodeService->setSPhone($phone); + if (!$oVrCodeService->checkCode($vrcode)) return $this->error('验证码错误'); + } elseif (!empty($password)) { //password login + if (!$oCustomerUser->checkPasswd($oUser->id, $password)) { + return $this->error('密码错误'); + } + } else { + return $this->error('登录失败'); } $oAuthService = new AuthService(); $oImService = new ImService(); - $token = $oAuthService->createTokenToUser($oUser->id,$device); - $imToken = $oImService->authUserToken($oUser->id,$device); + $token = $oAuthService->createTokenToUser($oUser->id, $device); + $imToken = $oImService->authUserToken($oUser->id, $device); $data = [ 'token' => $token, @@ -109,11 +120,12 @@ class CustomerUserController extends CustomerBaseController } - function setUserInfo(): \Illuminate\Http\JsonResponse + function updateUserInfo(): \Illuminate\Http\JsonResponse { $request = request(); $aReqData = $request->only([ 'nickname', + 'username', 'email', 'phone_area', 'phone', @@ -123,8 +135,8 @@ class CustomerUserController extends CustomerBaseController $aUser = $oAuthService->getCurrentUser(); $aReqData['id'] = $aUser['id']; $aReqData = array_filter($aReqData); - $oCustomerUser = new CustomerUser(); - if(!$oCustomerUser->updateItem($aReqData)) return $this->error(); + $oCustomerUser = new CustomerUserModel(); + if (!$oCustomerUser->updateItem($aReqData)) return $this->error(); return $this->success(); } @@ -133,29 +145,39 @@ class CustomerUserController extends CustomerBaseController $oAuthService = new AuthService(); $token = $oAuthService->getTokenFromReq(); $aUser = $oAuthService->getCurrentUser(); - $oAuthService->delTokenToUser($aUser['id'],$token); + $oAuthService->delTokenToUser($aUser['id'], $token); return $this->success(); } function register(): \Illuminate\Http\JsonResponse { $request = request(); - $username = $request->input('username'); + $phone_area = $request->input('phone_area'); + $phone = $request->input('phone'); $password = $request->input('password'); $device = $request->input('device'); $sVrCode = $request->input('vr_code'); - $oCustomerUser = new CustomerUser(); - $oUser = $oCustomerUser->findItemByUsername($username,['id']); + + //check vrcode + $oVrCodeService = new VrCodeService(); + $oVrCodeService->setIType(VrCode::TOPIC_REGISTER); + $oVrCodeService->setSPhoneArea($phone_area); + $oVrCodeService->setSPhone($phone); + if (!$oVrCodeService->checkCode($sVrCode)) return $this->error('验证码错误'); + + $oCustomerUser = new CustomerUserModel(); + $oUser = $oCustomerUser->findItemByPhone($phone_area, $phone); if ($oUser) { return $this->error('用户名已存在'); } $oUser = $oCustomerUser->addUser([ - 'username' => $username, + 'phone_area' => $phone_area, + 'phone' => $phone, 'password' => $password, - 'nickname' => $username, + 'nickname' => 'user_' . Tools::generateRandStr(10), ]); if (!$oUser) { @@ -164,10 +186,10 @@ class CustomerUserController extends CustomerBaseController //向im注册 $oImService = new ImService(); - if(!$oImService->userUserRegister($oUser->id)) throw new AppException('im register error'); + if (!$oImService->userUserRegister($oUser->id)) throw new AppException('im register error'); $oAuthService = new AuthService(); - $token = $oAuthService->createTokenToUser($oUser->id,$device); + $token = $oAuthService->createTokenToUser($oUser->id, $device); $data = [ 'token' => $token, @@ -188,64 +210,20 @@ class CustomerUserController extends CustomerBaseController { $request = request(); $aReqData = $request->only([ - 'nickname', + 'username', 'email', 'phone_area', 'phone', ]); $aReqData = array_filter($aReqData); if (empty($aReqData)) return $this->error(); - $oCustomerUser = new CustomerUser(); - $oUser = $oCustomerUser->findItemByAccount($aReqData,['id']); + $oCustomerUser = new CustomerUserModel(); + $oUser = $oCustomerUser->findItemByAccount($aReqData, ['id']); if ($oUser) { return $this->error('用户已存在'); } return $this->success(); } - /** - * @throws ContainerExceptionInterface - * @throws AppException - * @throws NotFoundExceptionInterface - */ - function sendVrcodeCode(): \Illuminate\Http\JsonResponse - { - //发送短信验证码 - $request = request(); - $aReqData = $request->only([ - 'topic', - 'phone_area', - 'phone', - ]); - if(!in_array($aReqData['topic'],VrCode::TOPIC)) return $this->error('invalid vrcode type'); - $oVrCodeService = new VrCodeService(); - $oVrCodeService->setIType($aReqData['topic']); - if($aReqData['topic'] == VrCode::TOPIC_REGISTER){ - - $validator = Validator::make($aReqData, [ - 'phone_area' => 'required|alpha_dash:ascii|max:5', - 'phone' => 'required|numeric|max:15', - ]); - if ($validator->fails()) { - return $this->error($validator->errors()->first()); - } - $oCustomerUser = new CustomerUser(); - $oUser = $oCustomerUser->findItemByPhone($aReqData['phone_area'],$aReqData['phone'],['id']); - if ($oUser) { - return $this->error('vrcode error'); - } - $oVrCodeService->setSPhoneArea($aReqData['phone_area']); - $oVrCodeService->setSPhone($aReqData['phone']); - $oVrCodeService->sendCode(); - return $this->success(); - }else{ - $oAuthService = new AuthService(); - $aUser = $oAuthService->getCurrentUser(); - if($aUser == null) return $this->error('user not login'); - $oVrCodeService->setIUid($aUser['id']); - $oVrCodeService->sendCode(); - return $this->success(); - } - } } diff --git a/app/Http/Controllers/Follow/FollowController.php b/app/Http/Controllers/Follow/FollowController.php new file mode 100644 index 0000000..1e7aec3 --- /dev/null +++ b/app/Http/Controllers/Follow/FollowController.php @@ -0,0 +1,59 @@ + [ + 'uid' => 'required|numeric|max:15', + ], + 'unFollow' => [ + 'uid' => 'required|numeric|max:15', + ], + ]; + + /** + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws ModelException + */ + function addFollow() + { + $oAuthService = new AuthService(); + $aUser = $oAuthService->getCurrentUser(); + + $follow_uid = request()->input('uid'); + if($aUser['id'] == $follow_uid) return $this->error('不能关注自己'); + + $oFollowModel = new FollowModel(); + $aFollow = $oFollowModel->isFollow($aUser['id'], $follow_uid); + if($aFollow) return $this->error('已关注'); + + $oFollowModel->addFollow($aUser['id'], $follow_uid); + + return $this->success(); + } + + function unFollow() + { + $oAuthService = new AuthService(); + $aUser = $oAuthService->getCurrentUser(); + + $follow_uid = request()->input('uid'); + $oFollowModel = new FollowModel(); + $oFollowModel->unFollow($aUser['id'], $follow_uid); + return $this->success(); + } + +} diff --git a/app/Http/Controllers/Post/PostController.php b/app/Http/Controllers/Post/PostController.php new file mode 100644 index 0000000..73f1dbd --- /dev/null +++ b/app/Http/Controllers/Post/PostController.php @@ -0,0 +1,11 @@ + [ + 'phone_area' => 'alpha_dash:ascii|max:5', + 'phone' => 'numeric|max:15', + ], + 'sendVrcodeCode' => [ + 'topic' => 'required|numeric', + 'phone_area' => 'alpha_dash:ascii|max:5', + 'phone' => 'numeric|max:15', + ], + ]; + + // no need login + function sendRegCode(): \Illuminate\Http\JsonResponse + { + //发送短信验证码 + $request = request(); + $aReqData = $request->only([ + 'phone_area', + 'phone', + ]); + + $oVrCodeService = new VrCodeService(); + $oVrCodeService->setIType(VrCode::TOPIC_REGISTER); + + $validator = Validator::make($aReqData, [ + 'phone_area' => 'required|alpha_dash:ascii|max:5', + 'phone' => 'required|numeric|max:15', + ]); + if ($validator->fails()) { + return $this->error($validator->errors()->first()); + } + $oCustomerUser = new CustomerUserModel(); + $oUser = $oCustomerUser->findItemByPhone($aReqData['phone_area'],$aReqData['phone'],['id']); + if ($oUser) { + return $this->error('vrcode error'); + } + $oVrCodeService->setSPhoneArea($aReqData['phone_area']); + $oVrCodeService->setSPhone($aReqData['phone']); + $oVrCodeService->sendCode(); + return $this->success(); + } + + //must login + /** + * @throws ContainerExceptionInterface + * @throws AppException + * @throws NotFoundExceptionInterface + */ + function sendVrcodeCode(): \Illuminate\Http\JsonResponse + { + //发送短信验证码 + $request = request(); + $aReqData = $request->only([ + 'topic', + 'phone_area', + 'phone', + ]); + if(!in_array($aReqData['topic'],VrCode::TOPIC)) return $this->error('invalid vrcode type'); + $oVrCodeService = new VrCodeService(); + $oVrCodeService->setIType($aReqData['topic']); + + $oAuthService = new AuthService(); + $aUser = $oAuthService->getCurrentUser(); + if($aUser == null) return $this->error('user not login'); + $oVrCodeService->setIUid($aUser['id']); + $oVrCodeService->sendCode(); + return $this->success(); + } + +} diff --git a/app/Http/Middleware/AuthMiddleware.php b/app/Http/Middleware/AuthMiddleware.php index 28fd66b..8c40fd0 100644 --- a/app/Http/Middleware/AuthMiddleware.php +++ b/app/Http/Middleware/AuthMiddleware.php @@ -3,6 +3,7 @@ namespace App\Http\Middleware; use App\Const\Responses; +use App\Models\Customer\CustomerUserModel; use App\Service\AuthService; use Closure; use Illuminate\Http\Request; @@ -14,7 +15,8 @@ class AuthMiddleware /** * Handle an incoming request. * - * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next + * @throws \Exception */ public function handle(Request $request, Closure $next): Response { @@ -28,15 +30,15 @@ class AuthMiddleware 'msg'=>'未登录', ]); } - $oCustomerUser = new \App\Models\Customer\CustomerUser(); - $oCustomerUser = $oCustomerUser->findUserByUidWithCache($aUserInfo['uid']); - if(empty($oCustomerUser)){ + $oCustomerUser = new CustomerUserModel(); + $aCustomerUser = $oCustomerUser->findUserByUidWithCache($aUserInfo['uid']); + if(empty($aCustomerUser)){ return response()->json([ 'code'=>Responses::CODE_ERROR, 'msg'=>'用户不存在', ]); } - $oAuthService->setCurrentUser($oCustomerUser->toArray()); + $oAuthService->setCurrentUser($aCustomerUser); return $next($request); diff --git a/app/Models/Base/BaseModel.php b/app/Models/Base/BaseModel.php index 587a625..0ca17d3 100644 --- a/app/Models/Base/BaseModel.php +++ b/app/Models/Base/BaseModel.php @@ -32,14 +32,16 @@ class BaseModel extends Model return $this->newQuery()->where($this->primaryKey, $id)->delete(); } - function updateItem($aItem): bool|int + function updateItem($aItem,$col = null): bool|int { + if(!$col) $col = $this->primaryKey; $aItem = $this->checkColInFill($aItem); if (empty($aItem)) return false; - if (isset($aItem[$this->primaryKey])) return false; - return $this->newQuery()->where($this->primaryKey,$aItem[$this->primaryKey])->update($aItem); + if (isset($aItem[$col])) return false; + return $this->newQuery()->where($col,$aItem[$col])->update($aItem); } + function findItem($id,$col=['*']): Model|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null { return $this->newQuery()->find($id,$col); diff --git a/app/Models/Customer/CustomerUser.php b/app/Models/Customer/CustomerUser.php deleted file mode 100644 index bf701f2..0000000 --- a/app/Models/Customer/CustomerUser.php +++ /dev/null @@ -1,105 +0,0 @@ - Hash::make($value), - ); - } - - function checkPasswd($iUid,$sPasswd):bool - { - $oUser = $this->where('id',$iUid)->first(); - if(empty($oUser)) return false; - return Hash::check($sPasswd,$oUser->password); - } - - function addUser($aItem): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null - { - $sDateTime = Carbon::now()->toDateTimeString(); - $aItem['created_at'] = $sDateTime; - $aItem['updated_at'] = $sDateTime; - return $this->addItem($aItem); - } - - function findItemByAccount($aData,$col=['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null - { - if(!empty($aData['username'])){ - return $this->findItemByUsername($aData['username'],$col); - } - if(!empty($aData['phone_area']) && !empty($aData['phone'])){ - return $this->findItemByPhone($aData['phone_area'],$aData['phone'],$col); - } - if(!empty($aData['email'])){ - return $this->findItemByEmail($aData['email'],$col); - } - return null; - } - - function findItemByUsername($sUsername,$col=['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null - { - return $this->newQuery()->where('username',$sUsername)->first($col); - } - - function findItemByPhone($sPhoneArea,$sPhone,$col=['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null - { - return $this->newQuery()->where('phone_area',$sPhoneArea)->where('phone',$sPhone)->first($col); - } - - function findItemByEmail($sEmail,$col=['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null - { - return $this->newQuery()->where('email',$sEmail)->first($col); - } - - function findUserByUidWithCache($iUid): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null - { - return Cache::remember(RedisConst::ORM_CACHE_USER.$iUid,RedisConst::ORM_FIND_CACHE_SECOND,function ()use ($iUid){ - return $this->findItem($iUid); - }); - } - -// function setUserInfo($iUid,$sNickname): bool|int -// { -// return $this->updateItem([ -// 'id' => $iUid, -// 'nickname' => $sNickname, -// 'email' => $sNickname, -// 'phone_area' => $sNickname, -// ]); -// } - - - -} diff --git a/app/Models/Customer/CustomerUserExtendModel.php b/app/Models/Customer/CustomerUserExtendModel.php new file mode 100644 index 0000000..a221eb2 --- /dev/null +++ b/app/Models/Customer/CustomerUserExtendModel.php @@ -0,0 +1,72 @@ + '活跃', + self::IS_ACTIVE_NO => '不活跃', + ]; + + //增加用户扩展信息 + function addExtend($aItem): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + if(empty($aItem['uid'])) throw new ModelException('uid error'); + if($this->findItem($aItem['uid'],['uid'])) return null; //已存在 + $sDateTime = date('Y-m-d H:i:s'); + $aItem['updated_at'] = $sDateTime; + return $this->addItem($aItem); + } + + //增加当前粉丝总数 + function incrFansNum($uid): int + { + $oExtend = $this->findItem($uid,'uid'); + if(!$oExtend) throw new ModelException('user extend not found'); + return $this->newQuery()->where('uid',$uid)->increment('fans_num'); + } + + //减去当前追随者总数 + function decrFansNum($uid): int + { + $oExtend = $this->findItem($uid,'uid'); + if(!$oExtend) throw new ModelException('user extend not found'); + return $this->newQuery()->where('uid',$uid)->decrement('fans_num'); + } + + //增加当前订阅总数 + function incrFollowNum($uid): int + { + $oExtend = $this->findItem($uid,'uid'); + if(!$oExtend) throw new ModelException('user extend not found'); + return $this->newQuery()->where('uid',$uid)->increment('follow_num'); + } + + //减去当前订阅总数 + function decrFollowNum($uid): int + { + $oExtend = $this->findItem($uid,'uid'); + if(!$oExtend) throw new ModelException('user extend not found'); + return $this->newQuery()->where('uid',$uid)->decrement('follow_num'); + } + +} diff --git a/app/Models/Customer/CustomerUserModel.php b/app/Models/Customer/CustomerUserModel.php new file mode 100644 index 0000000..d44574d --- /dev/null +++ b/app/Models/Customer/CustomerUserModel.php @@ -0,0 +1,141 @@ + Hash::make($value), + ); + } + + //对比密码是否正确 + function checkPasswd($iUid, $sPasswd): bool + { + $oUser = $this->where('id', $iUid)->first(); + if (empty($oUser)) return false; + return Hash::check($sPasswd, $oUser->password); + } + + //添加用户 + function addUser($aItem): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + $sDateTime = Carbon::now()->toDateTimeString(); + $aItem['created_at'] = $sDateTime; + $aItem['updated_at'] = $sDateTime; + return $this->addItem($aItem); + } + + //查找账户-所有方式 + function findItemByAccount($aData, $col = ['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + $oQuery = $this->newQuery(); + if (!empty($aData['username'])) { + $oQuery->orWhere('username', $aData['username']); + + } elseif (!empty($aData['email'])) { + $oQuery->orWhere('email', $aData['email']); + + } elseif (!empty($aData['phone']) && !empty($aData['phone_area'])) { + $oQuery->orWhere([ + 'phone' => $aData['phone'], + 'phone_area' => $aData['phone_area'], + ]); + + } else { + throw new \Exception('findItemByAccount params error'); + } + + return $oQuery->first($col); + } + + //查找账户-用户名 + function findItemByUsername($sUsername, $col = ['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->newQuery()->where('username', $sUsername)->first($col); + } + + //查找账户-手机 + function findItemByPhone($sPhoneArea, $sPhone, $col = ['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->newQuery()->where('phone_area', $sPhoneArea)->where('phone', $sPhone)->first($col); + } + + //查找账户-邮箱 + function findItemByEmail($sEmail, $col = ['*']): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->newQuery()->where('email', $sEmail)->first($col); + } + + //根据uid从缓存中查询用户信息,不存在则从数据库中查询 + + /** + * @throws \Exception + */ + function findUserByUidWithCache($iUid): array|null + { + $oTableCustomerUserCache = new TableCustomerUserCache(); + $oTableCustomerUserCache->setPrimaryKey($iUid); + return $oTableCustomerUserCache->getCacheData(); +// return Cache::remember($this->getCacheKey($iUid), RedisConst::ORM_FIND_CACHE_SECOND, function () use ($iUid) { +// return $this->findItem($iUid); +// }); + } + +// function delItemFromCache($iUid): bool +// { +// return Cache::delete($this->getCacheKey($iUid)); +// } + +// //生成user缓存key +// function getCacheKey($iUid): string +// { +// if(empty($iUid)) throw new \Exception('getCacheKey params error'); +// return RedisConst::ORM_CACHE_USER . $iUid; +// } + +// function setUserInfo($iUid,$sNickname): bool|int +// { +// return $this->updateItem([ +// 'id' => $iUid, +// 'nickname' => $sNickname, +// 'email' => $sNickname, +// 'phone_area' => $sNickname, +// ]); +// } + + +} diff --git a/app/Models/Follow/FollowHistoryModel.php b/app/Models/Follow/FollowHistoryModel.php new file mode 100644 index 0000000..4a79860 --- /dev/null +++ b/app/Models/Follow/FollowHistoryModel.php @@ -0,0 +1,40 @@ + '关注', + self::METHOD_UNFOLLOW => '取关', + ]; + + /** + * @throws ModelException + */ + function addFollowHistory($method, $uid, $follow_uid): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + if(!in_array($method,self::METHOD)) throw new ModelException('method error'); + $aItem['method'] = $method; + $aItem['uid'] = $uid; + $aItem['follow_uid'] = $follow_uid; + $sDateTime = date('Y-m-d H:i:s'); + $aItem['created_at'] = $sDateTime; + return $this->addItem($aItem); + } + +} diff --git a/app/Models/Follow/FollowModel.php b/app/Models/Follow/FollowModel.php new file mode 100644 index 0000000..9dd3027 --- /dev/null +++ b/app/Models/Follow/FollowModel.php @@ -0,0 +1,173 @@ +addItem($aItem); + if ($res) { + //增加到历史记录里 + $oFollowHistoryModel = new FollowHistoryModel(); + $oFollowHistoryModel->addFollowHistory(FollowHistoryModel::METHOD_FOLLOW, $uid, $follow_uid); + + try { + DB::beginTransaction(); + + //增加到user_extends中 + $oCustomerUserExtendModel = new CustomerUserExtendModel(); + $oCustomerUserExtendModel->incrFollowNum($uid); + $oCustomerUserExtendModel->incrFansNum($follow_uid); + + DB::commit(); + }catch (\Exception $e){ + DB::rollBack(); + throw new ModelException($e->getMessage()); + } + } + + return $res; + } + + /** + * 取消订阅 + * @throws ModelException + */ + function unFollow($uid, $follow_uid) + { + $res = $this->newQuery()->where('uid', $uid)->where('follow_uid', $follow_uid)->delete(); + if ($res) { + //增加到历史记录里 + $oFollowHistoryModel = new FollowHistoryModel(); + $oFollowHistoryModel->addFollowHistory(FollowHistoryModel::METHOD_UNFOLLOW, $uid, $follow_uid); + + try { + DB::beginTransaction(); + + //增加到user_extends中 + $oCustomerUserExtendModel = new CustomerUserExtendModel(); + $oCustomerUserExtendModel->decrFollowNum($uid); + $oCustomerUserExtendModel->decrFansNum($follow_uid); + + DB::commit(); + }catch (\Exception $e){ + DB::rollBack(); + throw new ModelException($e->getMessage()); + } + } + return $res; + } + + //获取user following(订阅)列表 + function getFollowList($uid): \Illuminate\Database\Eloquent\Collection|array + { + return $this->newQuery()->where('uid', $uid)->get(); + } + + //获取关注列表中大v用户 + function getFollowListWithFansLimit($uid,$iFansLimit = 2000,$col = ['a.follow_uid']): \Illuminate\Support\Collection + { + $oCustomerUserExtendModel = new CustomerUserExtendModel(); + $oFollowModel = new FollowModel(); + + $oModel = DB::table($oFollowModel->getTable() . ' as a'); + return $oModel->where('a.uid', $uid) + ->leftjoin($oCustomerUserExtendModel->getTable() . ' as b', 'a.follow_uid', '=', 'b.uid') + ->where('b.fans_num', $iFansLimit) + ->get($col); + } + + //检测是否双向关注 + function isEachOtherFollow($uid, $follow_uid): bool + { + $aFollow = $this->isFollow($uid, $follow_uid); + $aFollow2 = $this->isFollow($follow_uid, $uid); + if ($aFollow && $aFollow2) { + return true; + } + return false; + } + + function isFollow($uid, $follow_uid): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|null + { + return $this->newQuery()->where('uid', $uid)->where('follow_uid', $follow_uid)->first(['id']); + } + + //获取关注数 + function getFollowCount($uid): int + { + return $this->newQuery()->where('uid', $uid)->count(); + } + + //获取被关注列表 + function getFansList($uid, $col = ['*'], $offset = null, $limit = null): \Illuminate\Database\Eloquent\Collection|array + { + $oModel = $this->newQuery(); + if ($offset) $oModel->offset($offset); + if ($limit) $oModel->limit($offset); + return $oModel->where('follow_uid', $uid)->get($col); + } + + //检测是否被关注 + function isFollowed($uid, $follow_uid): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|null + { + return $this->newQuery()->where('uid', $follow_uid)->where('follow_uid', $uid)->first(['id']); + } + + //获取粉丝数(被关注数) + function getFansCount($uid): int + { + return $this->newQuery()->where('follow_uid', $uid)->count(['id']); + } + + //获取活跃粉丝列表 + function getActiveFansUidList($uid, $col = ['a.*'], $offset = null, $limit = null): \Illuminate\Support\Collection + { + $oCustomerUserExtendModel = new CustomerUserExtendModel(); + $oFollowModel = new FollowModel(); + + $oModel = DB::table($oFollowModel->getTable() . ' as a'); + if ($offset) $oModel->offset($offset); + if ($limit) $oModel->limit($offset); + return $oModel->where('a.follow_uid', $uid) + ->leftjoin($oCustomerUserExtendModel->getTable() . ' as b', 'a.uid', '=', 'b.uid') + ->where('b.is_active', CustomerUserExtendModel::IS_ACTIVE_YES) + ->get($col); + } + + //获取活跃粉丝计数 + function getActiveFansUidListCount($uid, $col = ['a.id']): int + { + $oCustomerUserExtendModel = new CustomerUserExtendModel(); + $oFollowModel = new FollowModel(); + return DB::table($oFollowModel->getTable() . ' as a')->where('a.follow_uid', $uid) + ->leftjoin($oCustomerUserExtendModel->getTable() . ' as b', 'a.uid', '=', 'b.uid') + ->where('b.is_active', CustomerUserExtendModel::IS_ACTIVE_YES) + ->count($col); + } + + +} diff --git a/app/Models/Post/PostHistoryModel.php b/app/Models/Post/PostHistoryModel.php new file mode 100644 index 0000000..d479d40 --- /dev/null +++ b/app/Models/Post/PostHistoryModel.php @@ -0,0 +1,48 @@ + '新增', + self::METHOD_DEL => '删除', + self::METHOD_EDIT => '编辑', + ]; + + /** + * @throws ModelException + */ + function addPostHistory($method, $aItem): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|array|null + { + if(!in_array($method,self::METHOD)) throw new ModelException('addPostHistory method error'); + if(!isset($aItem['uuid'])) throw new ModelException('addPostHistory params error'); + $aItem['oid'] = $aItem['id']; + unset($aItem['id']); + $sDateTime = date('Y-m-d H:i:s'); + $aItem['created_at'] = $sDateTime; + $aItem['method'] = $method; + return $this->addItem($aItem); + } + + +} diff --git a/app/Models/Post/PostModel.php b/app/Models/Post/PostModel.php new file mode 100644 index 0000000..db8f41d --- /dev/null +++ b/app/Models/Post/PostModel.php @@ -0,0 +1,133 @@ +addItem($aItem); + if($res){ + + } + return $res; + } + + /** + * @throws ModelException + */ + function delPostById($id) + { + $oPost = $this->findItem($id); + $res = $this->delItem($id); + if($res){ + $oPostHistoryModel = new PostHistoryModel(); + $oPostHistoryModel->addPostHistory(PostHistoryModel::METHOD_DEL,$oPost->toArray()); + } + return $res; + } + + /** + * @throws ModelException + */ + function delPostByUuid($uuid) + { + $oPost = $this->findItemByWhere(['uuid'=>$uuid]); + $res = $this->newQuery()->where('uuid', $uuid)->delete(); + if($res){ + $oPostHistoryModel = new PostHistoryModel(); + $oPostHistoryModel->addPostHistory(PostHistoryModel::METHOD_DEL,$oPost->toArray()); + } + return $res; + } + + function getPostListByUid($uid): \Illuminate\Database\Eloquent\Collection|array + { + return $this->getItemsByWhere(['uid'=>$uid]); + } + + function getPostById($id): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->findItem($id); + } + + /** + * @throws ModelException + */ + function updatePostById($aItem): bool|int + { + if(!isset($aItem['id'])) throw new ModelException('updatePostById params error'); + if(empty($aItem['id'])) throw new ModelException('updatePostById params error'); + $oPost = $this->findItem($aItem['id']); + $res = $this->updateItem($aItem); + if($res){ + $oPostHistoryModel = new PostHistoryModel(); + $oPostHistoryModel->addPostHistory(PostHistoryModel::METHOD_EDIT,$oPost->toArray()); + } + return $res; + } + + /** + * @throws ModelException + */ + function updatePostByUuid($aItem): bool|int + { + if(!isset($aItem['uuid'])) throw new ModelException('updatePostByUuid params error'); + if(empty($aItem['uuid'])) throw new ModelException('updatePostByUuid params error'); + $oPost = $this->findItemByWhere(['uuid'=>$aItem['uuid']]); + $res = $this->updateItem($aItem,'uuid'); + if($res){ + $oPostHistoryModel = new PostHistoryModel(); + $oPostHistoryModel->addPostHistory(PostHistoryModel::METHOD_EDIT,$oPost->toArray()); + } + return $res; + } + + function getPostListByMid($mid): \Illuminate\Database\Eloquent\Collection|array + { + return $this->getItemsByWhere(['mid'=>$mid]); + } + + + function getPostListByUidMid($uid,$mid): \Illuminate\Database\Eloquent\Collection|array + { + return $this->getItemsByWhere(['uid'=>$uid,'mid'=>$mid]); + } + function getPostListByUids($uids,$sDateLimit = null): \Illuminate\Database\Eloquent\Collection|array + { + if($sDateLimit == null) $sDateLimit = date('Y-m-d H:i:s',strtotime('-3 day')); + return $this->newQuery()->where('created_at',$sDateLimit)->whereIn('uid',$uids)->get(); + } + + +} diff --git a/app/Models/Post/PostPushBoxModel.php b/app/Models/Post/PostPushBoxModel.php new file mode 100644 index 0000000..a069e0b --- /dev/null +++ b/app/Models/Post/PostPushBoxModel.php @@ -0,0 +1,180 @@ + '默认', + self::IS_LIKE_YES => '喜欢', + self::IS_LIKE_NO => '不喜欢', + ]; + + const IS_REPOST_DEFAULT = 1; + const IS_REPOST_YES = 2; + const IS_REPOST = [ + self::IS_REPOST_DEFAULT => '默认', + self::IS_REPOST_YES => '已转发', + ]; + + const IS_BOOKMARK_DEFAULT = 1; + const IS_BOOKMARK_YES = 2; + const IS_BOOKMARK = [ + self::IS_BOOKMARK_DEFAULT => '默认', + self::IS_BOOKMARK_YES => '已收藏', + ]; + + const IS_READ_DEFAULT = 1; + const IS_READ_YES = 2; + const IS_READ = [ + self::IS_READ_DEFAULT => '默认', + self::IS_READ_YES => '已收藏', + ]; + + + /** + * 提交后调用事件 + * @throws ModelException + */ + function newPostPushTask($id = null, $uuid = null) + { + $oPostModel = new PostModel(); + $oPost = null; + if ($id) $oPost = $oPostModel->findItem($id); + if ($uuid) $oPost = $oPostModel->findItemByWhere(['uuid' => $uuid]); + if (!$oPost) throw new ModelException('post not found'); + $iConfigFansPushLimit = intval(env('CONFIG_FANS_PUSH_LIMIT', 2000)); + + //查询粉丝数 + $CustomerUserExtendModel = new CustomerUserExtendModel(); + $CustomerUserExtend = $CustomerUserExtendModel->findItem($oPost->uid); + if (!$CustomerUserExtend) throw new ModelException('user extend not found'); + + //粉丝数少于$iConfigFansPushLimit的用户走写扩散流程(所有粉丝信箱插入一条) + $bSendMode = $CustomerUserExtend->fans_num < $iConfigFansPushLimit; + + $iTotalCount = $this->countSendFans($bSendMode, $oPost->uid); //计算发送总数 + //分批发送 + $oCollectOffsetLimit = new CollectOffsetLimit(); + $oCollectOffsetLimit->setITotalCount($iTotalCount)->runWhile(function ($offset, $limit) use ($oPost, $bSendMode) { + $oFollowList = $this->getFansListWithPage($bSendMode, $oPost->uid, $offset, $limit); + $this->sendPostToBox($oPost, $oFollowList); + }); + + } + + function getFansListWithPage($bAllFans, $uid, $offset = 0, $limit = 2000): \Illuminate\Database\Eloquent\Collection|array|\Illuminate\Support\Collection + { + $oFollowModel = new FollowModel(); + //粉丝数少于$iConfigFansPushLimit的用户走写扩散流程(所有粉丝信箱插入一条) + if ($bAllFans) { + $oFollowList = $oFollowModel->getFansList($uid, ['uid'], $offset, $limit); //获取所有粉丝列表 + } else { //读扩散流程(只针对活跃粉丝信箱插入一条) + //获取活跃粉丝列表 + //@活跃粉丝数量过大需要分批处理 + $oFollowList = $oFollowModel->getActiveFansUidList($uid, ['a.uid'], $offset, $limit); + } + return $oFollowList; + } + + function countSendFans($bAllFans, $uid): int + { + $oFollowModel = new FollowModel(); + if ($bAllFans) { + $iCount = $oFollowModel->getFansCount($uid); //获取所有粉丝列表 + } else { //读扩散流程(只针对活跃粉丝信箱插入一条) + //获取活跃粉丝列表 + $iCount = $oFollowModel->getActiveFansUidListCount($uid); + } + return $iCount; + } + + //发送到推送信箱 + function sendPostToBox($oPost, $oFollowList): void + { + if (!$oFollowList) return; + $date = date('Y-m-d H:i:s'); + foreach ($oFollowList as $oFollow) { + $aItem['uid'] = $oFollow->uid; + $aItem['pid'] = $oPost->id; + $aItem['puuid'] = $oPost->uuid; + $aItem['created_at'] = $oPost->created_at; + $aItem['created_box_at'] = $date; + $this->addItem($aItem); + } + } + + + /** + * 拉取推送信箱列表 + * @param $uid + * @param $last_id //上次最后一条id + * @param $limit + * @return \Illuminate\Database\Eloquent\Collection|array + */ + function getPushBoxList($uid, $last_id = 0, $limit = 20): \Illuminate\Database\Eloquent\Collection|array + { + //活跃用户直接拉取未读消息 + return $this->newQuery()->where('uid', $uid)->where('id', '>', $last_id)->where('is_read', self::IS_READ_DEFAULT)->orderBy('created_at', 'desc')->limit($limit)->get(); + //非活跃用户拉取大v消息,在用户状态更新时已经调用过,此处不用在做处理 + } + + //非活跃拉取已跟随大v最新文章。 + //放在用户状态更新时调用 + function pullBigFanMasterPost($uid) + { + $iConfigFansPushLimit = intval(env('CONFIG_FANS_PUSH_LIMIT', 2000)); + //@此处需针对大量数据进行分批获取 + $oFollowModel = new FollowModel(); + $oFollowList = $oFollowModel->getFollowListWithFansLimit($uid,$iConfigFansPushLimit,['a.follow_uid']); + if ($oFollowList->isEmpty()) return null; + $aFollowList = $oFollowList->toArray(); + $aFollowUid = array_column($aFollowList,'follow_uid'); + $oPostModel = new PostModel(); + $oPostList = $oPostModel->getPostListByUids($aFollowUid); + + //将推文发送到信箱 + $this->sendPostToBoxByUid($oPostList,$uid); + + } + + function sendPostToBoxByUid($oPostList, $uid): void + { + $date = date('Y-m-d H:i:s'); + foreach ($oPostList as $oPost) { + $aItem['uid'] = $uid; + $aItem['pid'] = $oPost->id; + $aItem['puuid'] = $oPost->uuid; + $aItem['created_at'] = $oPost->created_at; + $aItem['created_box_at'] = $date; + $this->addItem($aItem); + } + } + +} diff --git a/app/Service/SmsService.php b/app/Service/SmsService.php new file mode 100644 index 0000000..5322051 --- /dev/null +++ b/app/Service/SmsService.php @@ -0,0 +1,21 @@ +getChannel()->sendSmsCode($phone, $code); + } + + function getChannel(): SmsInterface + { + return new Movider(); + } + + +} diff --git a/app/Service/VrCodeService.php b/app/Service/VrCodeService.php index 62d7b34..98a3d2c 100644 --- a/app/Service/VrCodeService.php +++ b/app/Service/VrCodeService.php @@ -7,6 +7,7 @@ use App\Const\VrCode; use App\Exceptions\AppException; use App\Tools\Tools; use Illuminate\Support\Carbon; +use Illuminate\Support\Env; use Illuminate\Support\Facades\Redis; class VrCodeService @@ -18,47 +19,47 @@ class VrCodeService public $iType = null; public $iUid = null; - public function getSKey(): null + public function getSKey() { return $this->sKey; } - public function setSKey(null $sKey): void + public function setSKey($sKey): void { $this->sKey = $sKey; } - public function getsCode(): null + public function getsCode() { return $this->sCode; } - public function setsCode(null $sCode): void + public function setsCode($sCode): void { $this->sCode = $sCode; } - public function getSPhoneArea(): null + public function getSPhoneArea() { return $this->sPhoneArea; } - public function setSPhoneArea(null $sPhoneArea): void + public function setSPhoneArea($sPhoneArea): void { $this->sPhoneArea = $sPhoneArea; } - public function getSPhone(): null + public function getSPhone() { return $this->sPhone; } - public function setSPhone(null $sPhone): void + public function setSPhone($sPhone): void { $this->sPhone = $sPhone; } - public function getIType(): null + public function getIType() { return $this->iType; } @@ -66,25 +67,25 @@ class VrCodeService /** * @throws AppException */ - public function setIType(null $iType): void + public function setIType($iType): void { - if(!in_array($iType,VrCode::TOPIC)) throw new AppException('invalid sms type'); + if (!in_array($iType, VrCode::TOPIC)) throw new AppException('invalid sms type'); $this->iType = $iType; } - public function getIUid(): null + public function getIUid() { return $this->iUid; } - public function setIUid(null $iUid): void + public function setIUid($iUid): void { $this->iUid = $iUid; } function sendSmsToPhone(): bool { - return true; + return (new SmsService())->sendSmsCode($this->sPhoneArea.$this->sPhone, $this->sCode); } /** @@ -94,7 +95,7 @@ class VrCodeService { $this->sKey = $this->genKey(); $this->sCode = $this->genCode(); - if(!$this->sendSmsToPhone()) throw new AppException('send sms failed'); + if (!$this->sendSmsToPhone()) throw new AppException('send sms failed'); $this->setCodeToCache(); } @@ -103,10 +104,10 @@ class VrCodeService */ function genKey(): false|string { - if(!in_array($this->iType,VrCode::TOPIC_PREFIX)) throw new AppException('invalid sms type'); - if($this->iType == VrCode::TOPIC_REGISTER) { + if (!in_array($this->iType, VrCode::TOPIC_PREFIX)) throw new AppException('invalid sms type'); + if ($this->iType == VrCode::TOPIC_REGISTER) { return VrCode::TOPIC_PREFIX[VrCode::TOPIC_REGISTER] . md5($this->sPhoneArea . $this->sPhone); - }else { + } else { return VrCode::TOPIC_PREFIX[VrCode::TOPIC_REGISTER] . $this->iUid; } } @@ -118,7 +119,7 @@ class VrCodeService function setCodeToCache() { - return Redis::set($this->sKey,$this->sCode,VrCode::REDIS_CACHE_EXPIRE); + return Redis::set($this->sKey, $this->sCode, VrCode::REDIS_CACHE_EXPIRE); } /** @@ -131,9 +132,12 @@ class VrCodeService function checkCode($sReqCode): bool { + if(Env::get('APP_DEBUG') == true){ + if ($sReqCode === '000000') return true; + } $sCode = $this->getCodeFromCache(); - if(empty($sCode)) return false; - if($sCode != $sReqCode) return false; + if (empty($sCode)) return false; + if ($sCode != $sReqCode) return false; return true; } diff --git a/app/Thrid/Sms/Movider/Movider.php b/app/Thrid/Sms/Movider/Movider.php new file mode 100644 index 0000000..c38a331 --- /dev/null +++ b/app/Thrid/Sms/Movider/Movider.php @@ -0,0 +1,37 @@ + Config::get('service.sms.movider.api_key'), + 'api_secret' => Config::get('service.sms.movider.api_secret'), + 'to' => $phone, + 'text' => $code, + ]; + if(Config::get('service.sms.movider.from') != null) $aData['from'] = Config::get('service.sms.movider.from'); + $resp = $this->sendReq($path, $aData); + Log::info('movider sendSmsCode', [$resp->getBody()->getContents()]); + if($resp->getStatusCode() == 200) return true; + return false; + } + + function getUrl(): string + { + return 'https://api.movider.co'; + } +} diff --git a/app/Thrid/Sms/SmsBase.php b/app/Thrid/Sms/SmsBase.php new file mode 100644 index 0000000..e4e5609 --- /dev/null +++ b/app/Thrid/Sms/SmsBase.php @@ -0,0 +1,35 @@ +getUrl() . $path; + $client = new \GuzzleHttp\Client(); + if ($aHeaders) { + $aHeaders = [ + 'accept' => 'application/json', + 'content-type' => 'application/x-www-form-urlencoded', + ]; + } + return $client->request('POST', $url, [ + 'headers' => $aHeaders, + 'body' => $aData, + ]); + } + + +} diff --git a/app/Thrid/Sms/SmsInterface.php b/app/Thrid/Sms/SmsInterface.php new file mode 100644 index 0000000..72ae45d --- /dev/null +++ b/app/Thrid/Sms/SmsInterface.php @@ -0,0 +1,17 @@ + '验证类', + self::SMS_SEND_TYPE_MARKETING => '营销类', + ]; + + function sendSmsCode($phone, $code,$iSendType = self::SMS_SEND_TYPE_CHARACTER): bool; + + function getUrl(): string; +} diff --git a/app/Tools/CollectOffsetLimit.php b/app/Tools/CollectOffsetLimit.php new file mode 100644 index 0000000..e5dc47b --- /dev/null +++ b/app/Tools/CollectOffsetLimit.php @@ -0,0 +1,82 @@ +fCountFun = $fun(); + return $this; + } + + + private function countPage() + { + if($this->iTotalCount === null && $this->fCountFun !== null){ + $this->iTotalCount = $this->fCountFun; + } + if(empty($this->page) && !empty($this->iTotalCount)){ + $this->page = ceil($this->iTotalCount / $this->limit); + } + } + + function runWhile(\Closure $fun) + { + $this->countPage(); + if($this->iTotalCount === null) $this->iTotalCount = $this->fCountFun; + if($this->iTotalCount === 0 | $this->page === 0) return []; + for( $iPage = 1; $iPage <= $this->page; $iPage++){ + $this->offset = ($iPage - 1) * $this->limit; + $fun($this->offset,$this->limit); + } + $this->offset = 0; + + } + + public function getLimit(): int + { + return $this->limit; + } + + public function setLimit(int $limit): void + { + $this->limit = $limit; + } + + public function getOffset(): int + { + return $this->offset; + } + + public function setOffset(int $offset): void + { + $this->offset = $offset; + } + + /** + * @return null + */ + public function getITotalCount() + { + return $this->iTotalCount; + } + + /** + * @param null $iTotalCount + */ + public function setITotalCount($iTotalCount): CollectOffsetLimit + { + $this->iTotalCount = $iTotalCount; + return $this; + } +} diff --git a/app/Tools/Tools.php b/app/Tools/Tools.php index 2c75c7d..356fac8 100644 --- a/app/Tools/Tools.php +++ b/app/Tools/Tools.php @@ -1,6 +1,8 @@ env('AWS_DEFAULT_REGION', 'us-east-1'), ], + 'sms' => [ + 'movider' => [ + 'api_key' => env('SMS_API.MOVIDER_API_KEY'), + 'api_secret' => env('SMS_API.MOVIDER_API_SECRET'), + 'from' => env('SMS_API.FROM_TITLE'), + ], + 'nexmo' => [ + 'api_key' => env('SMS_API.NEXMO_API_KEY'), + 'api_secret' => env('SMS_API.NEXMO_API_SECRET'), + 'from' => env('SMS_API.FROM_TITLE'), + ], + 'twilio' => [ + 'api_key' => env('SMS_API.TWILIO_API_KEY'), + 'api_secret' => env('SMS_API.TWILIO_API_SECRET'), + 'from' => env('SMS_API.FROM_TITLE'), + ], + ], + ]; diff --git a/docker.yaml b/docker.yaml new file mode 100644 index 0000000..a88c7ef --- /dev/null +++ b/docker.yaml @@ -0,0 +1,35 @@ +version: "3.0" +services: + elastic: + container_name: es-node-1 + image: docker.elastic.co/elasticsearch/elasticsearch:8.6.1 + # build: . + environment: + - xpack.security.enabled=false + - "discovery.type=single-node" + - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - ELASTIC_USERNAME=elastic + - ELASTIC_PASSWORD=elastic + volumes: + - "/home/tom1/com/es_compose/es/node-1/data:/usr/share/elasticsearch/data" + - "/home/tom1/com/es_compose/es/node-1/log" + restart: always + networks: + - bigdata + ports: + - 9200:9200 + kibana: + container_name: kibana-app + image: docker.elastic.co/kibana/kibana:8.6.1 + restart: always + environment: + - ELASTICSEARCH_HOSTS=http://es-node-1:9200 + networks: + - bigdata + depends_on: + - elastic + ports: + - 5601:5601 +networks: + esnet: + driver: bridge diff --git a/routes/api.php b/routes/api.php index 6c82920..1fe26b5 100644 --- a/routes/api.php +++ b/routes/api.php @@ -28,6 +28,12 @@ Route::middleware([])->group(function () { $class = \App\Http\Controllers\Customer\CustomerUserController::class; Route::post('/register', [$class, 'register']); Route::post('/signIn', [$class, 'signIn']); + Route::post('/checkAccount', [$class, 'checkAccount']); + }); + + Route::prefix('sms')->group(function () { + $class = \App\Http\Controllers\Sms\SmsController::class; + Route::post('/sendRegCode', [$class, 'sendRegCode']); }); @@ -40,9 +46,18 @@ Route::middleware(['auth'])->group(function () { $class = \App\Http\Controllers\Customer\CustomerUserController::class; Route::post('/signOut', [$class, 'signOut']); Route::post('/getCustomerUserInfo', [$class, 'getCustomerUserInfo']); - Route::post('/setUserInfo', [$class, 'setUserInfo']); - Route::post('/checkAccount', [$class, 'checkAccount']); + Route::post('/updateUserInfo', [$class, 'updateUserInfo']); + + }); + Route::prefix('sms')->group(function () { + $class = \App\Http\Controllers\Sms\SmsController::class; + Route::post('/sendVrcodeCode', [$class, 'sendVrcodeCode']); }); + Route::prefix('follow')->group(function () { + $class = \App\Http\Controllers\Follow\FollowController::class; + Route::post('/addFollow', [$class, 'addFollow']); + Route::post('/unFollow', [$class, 'unFollow']); + }); });