wesmiler 6 miesięcy temu
rodzic
commit
0bb40ef400

+ 14 - 0
app/Http/Controllers/Api/v1/MemberController.php

@@ -105,4 +105,18 @@ class MemberController extends webApp
         }
     }
 
+    /**
+     * 购买VIP
+     * @return array
+     */
+    public function vipBuy()
+    {
+        $vipId = request()->post('id');
+        if (!MemberService::make()->vipBuy($this->userId, $vipId)) {
+            return showJson(MemberService::make()->getError(), false);
+        } else {
+            return showJson(1013, true);
+        }
+    }
+
 }

+ 3 - 4
app/Http/Controllers/Api/v1/NotifyController.php

@@ -70,18 +70,17 @@ class NotifyController extends webApp
 
     /**
      * 退款回调
-     * @param string $scene 场景,deposit-保证金,depositRefund-保证金退款,withdraw-收入提现
+     * @param string $scene 场景,vip-VIP退款
      * @param int $payType 支付方式:10-微信,20-支付宝
      * @return array|false
      * @throws \Yansongda\Pay\Exception\ContainerException
      * @throws \Yansongda\Pay\Exception\InvalidParamsException
      */
-    public function depositRefund($payType = 10)
+    public function refund($scene='refund', $payType = 10)
     {
-        $scene = 'depositRefund';
         $date = date('Y-m-d H:i:s');
         $result = request()->post();
-        $pay = PaymentService::make()->createPay('depositRefund', $payType);
+        $pay = PaymentService::make()->createPay($scene, $payType);
         $channel = $payType == 10? 'wechat':'alipay';
         if (empty($pay) || empty($scene) || empty($payType)) {
             if (env('APP_DEBUG')) {

+ 222 - 92
app/Services/Api/MemberService.php

@@ -14,9 +14,12 @@ namespace App\Services\Api;
 use App\Helpers\Jwt;
 use App\Models\ActionLogModel;
 use App\Models\MemberModel;
+use App\Models\OrderModel;
 use App\Models\VipModel;
 use App\Services\BaseService;
+use App\Services\ConfigService;
 use App\Services\MpService;
+use App\Services\PaymentService;
 use App\Services\RedisService;
 use App\Services\SmsService;
 use phpQrcode\QRcode;
@@ -96,23 +99,23 @@ class MemberService extends BaseService
         }
 
         // 更新
-        if(!RedisService::get("caches:members:login_{$userId}")){
-            $system = isset($params['system'])? $params['system'] : [];
-            $system = $system && !is_array($system)? json_decode($system,true) : $system;
-            $appSources = isset($system['app_sources']) && $system['app_sources']? $system['app_sources'] : 'ios';
-            $uuid = isset($system['uuid'])? $system['uuid'] : '';
-            $version = isset($system['app_version'])? $system['app_version'] : '';
+        if (!RedisService::get("caches:members:login_{$userId}")) {
+            $system = isset($params['system']) ? $params['system'] : [];
+            $system = $system && !is_array($system) ? json_decode($system, true) : $system;
+            $appSources = isset($system['app_sources']) && $system['app_sources'] ? $system['app_sources'] : 'ios';
+            $uuid = isset($system['uuid']) ? $system['uuid'] : '';
+            $version = isset($system['app_version']) ? $system['app_version'] : '';
             $updateData = [
-                'update_time'=> time(),
-                'login_ip'=> get_client_ip(),
-                'login_time'=> time(),
-                'device_code'=> $uuid,
-                'login_count'=> DB::raw("login_count+1"),
-                'app_version'=> $version,
-                'device'=> $appSources=='ios'? 1 : 2,
+                'update_time' => time(),
+                'login_ip' => get_client_ip(),
+                'login_time' => time(),
+                'device_code' => $uuid,
+                'login_count' => DB::raw("login_count+1"),
+                'app_version' => $version,
+                'device' => $appSources == 'ios' ? 1 : 2,
             ];
-            $this->model->where(['id'=> $userId])->update($updateData);
-            RedisService::set("caches:members:login_{$userId}",$updateData, rand(300,600));
+            $this->model->where(['id' => $userId])->update($updateData);
+            RedisService::set("caches:members:login_{$userId}", $updateData, rand(300, 600));
         }
 
 
@@ -123,7 +126,7 @@ class MemberService extends BaseService
         // 结果返回
         $result = [
             'access_token' => $token,
-            'info' => ['uid' => $userId,'nickname' => $data['nickname']],
+            'info' => ['uid' => $userId, 'nickname' => $data['nickname']],
         ];
 
         // 用户缓存信息
@@ -141,7 +144,7 @@ class MemberService extends BaseService
      * @param array $params
      * @return array|false
      */
-    public function mpAuth($code, $params=[])
+    public function mpAuth($code, $params = [])
     {
         // 账号登录
         if (empty($code)) {
@@ -151,34 +154,34 @@ class MemberService extends BaseService
 
         // 获取授权用户信息
         $phone = '';
-        $pcode = isset($params['pcode'])? $params['pcode'] : '';
-        if($pcode){
+        $pcode = isset($params['pcode']) ? $params['pcode'] : '';
+        if ($pcode) {
             $phoneData = MpService::make()->getPhoneNumber($pcode);
-            $phoneData = isset($phoneData['phone_info'])? $phoneData['phone_info'] : [];
-            $phone = isset($phoneData['phoneNumber'])? $phoneData['phoneNumber'] : '';
+            $phoneData = isset($phoneData['phone_info']) ? $phoneData['phone_info'] : [];
+            $phone = isset($phoneData['phoneNumber']) ? $phoneData['phoneNumber'] : '';
         }
 
-        if(empty($phone)){
+        if (empty($phone)) {
             $this->error = 2014;
             return false;
         }
 
         $userInfo = MpService::make()->getUserInfo($code);
-        $openid = isset($userInfo['openid'])? $userInfo['openid'] : '';
-        if(empty($userInfo)){
+        $openid = isset($userInfo['openid']) ? $userInfo['openid'] : '';
+        if (empty($userInfo)) {
             $this->error = MpService::make()->getError();
             return false;
         }
 
-        if(empty($openid)){
+        if (empty($openid)) {
             $this->error = 1042;
             return false;
         }
 
         // 验证是否注册,没有则注册
-        $where = ['mobile'=>$phone,'mark' => 1];
+        $where = ['mobile' => $phone, 'mark' => 1];
         $data = $this->model->where($where)
-            ->select(['id','openid', 'mobile', 'user_type', 'nickname','entry_type','need_paper', 'code', 'status'])
+            ->select(['id', 'openid', 'mobile', 'user_type', 'nickname', 'entry_type', 'need_paper', 'code', 'status'])
             ->first();
         $data = $data ? $data->toArray() : [];
         $userId = isset($data['id']) ? $data['id'] : 0;
@@ -191,48 +194,47 @@ class MemberService extends BaseService
         }
 
 
-        $system = isset($params['system'])? $params['system'] : [];
-        $system = $system && !is_array($system)? json_decode($system,true) : $system;
-        $appSources = isset($system['app_sources']) && $system['app_sources']? $system['app_sources'] : 'ios';
-        $uuid = isset($system['uuid'])? $system['uuid'] : '';
-        $version = isset($system['app_version'])? $system['app_version'] : '';
-        if(empty($data)){
+        $system = isset($params['system']) ? $params['system'] : [];
+        $system = $system && !is_array($system) ? json_decode($system, true) : $system;
+        $appSources = isset($system['app_sources']) && $system['app_sources'] ? $system['app_sources'] : 'ios';
+        $uuid = isset($system['uuid']) ? $system['uuid'] : '';
+        $version = isset($system['app_version']) ? $system['app_version'] : '';
+        if (empty($data)) {
 
-            $userId = $this->model->max('id')+1;
+            $userId = $this->model->max('id') + 1;
             $data = [
-                'nickname'=> $phone? '微信用户'.substr($phone,-6,6) : '微信用户'.$userId,
-                'openid'=> $openid,
-                'mobile'=> $phone,
-                'password'=> $phone? get_password(substr($phone,-6,6)) : get_password('123456'),
-                'login_ip'=> get_client_ip(),
-                'create_time'=> time(),
-                'login_time'=> time(),
-                'login_count'=> DB::raw("login_count+1"),
-                'app_version'=> $version,
-                'app_uuid'=> $uuid,
-                'device'=> $appSources=='ios'? 1 : 2,
+                'nickname' => $phone ? '微信用户' . substr($phone, -6, 6) : '微信用户' . $userId,
+                'openid' => $openid,
+                'mobile' => $phone,
+                'password' => $phone ? get_password(substr($phone, -6, 6)) : get_password('123456'),
+                'login_ip' => get_client_ip(),
+                'create_time' => time(),
+                'login_time' => time(),
+                'login_count' => DB::raw("login_count+1"),
+                'app_version' => $version,
+                'app_uuid' => $uuid,
+                'device' => $appSources == 'ios' ? 1 : 2,
             ];
-            if($this->model->insertGetId($data)){
+            if ($this->model->insertGetId($data)) {
                 $this->error = 2012;
                 return false;
             }
-        }
-        // 更新登录信息
-        else if(!RedisService::get("caches:members:login_{$userId}")){
+        } // 更新登录信息
+        else if (!RedisService::get("caches:members:login_{$userId}")) {
             $updateData = [
-                'login_ip'=> get_client_ip(),
-                'create_time'=> time(),
-                'login_time'=> time(),
-                'app_uuid'=> $uuid,
-                'login_count'=> DB::raw("login_count+1"),
-                'app_version'=> $version,
-                'device'=> $appSources=='ios'? 1 : 2,
+                'login_ip' => get_client_ip(),
+                'create_time' => time(),
+                'login_time' => time(),
+                'app_uuid' => $uuid,
+                'login_count' => DB::raw("login_count+1"),
+                'app_version' => $version,
+                'device' => $appSources == 'ios' ? 1 : 2,
             ];
-            if($openid){
+            if ($openid) {
                 $updateData['openid'] = $openid;
             }
-            $this->model->where(['id'=> $userId])->update($updateData);
-            RedisService::set("caches:members:login_{$userId}",$updateData, rand(180,300));
+            $this->model->where(['id' => $userId])->update($updateData);
+            RedisService::set("caches:members:login_{$userId}", $updateData, rand(180, 300));
         }
 
         // 获取登录授权token
@@ -240,10 +242,10 @@ class MemberService extends BaseService
         $token = $jwt->getToken($userId);
 
         // 结果返回
-        $setEntry = $entryType && $needPaper? 1 : 0;
+        $setEntry = $entryType && $needPaper ? 1 : 0;
         $result = [
             'access_token' => $token,
-            'info' => ['uid' => $userId,'openid'=>$openid,'set_entry'=>$setEntry,'nickname' => $data['nickname']],
+            'info' => ['uid' => $userId, 'openid' => $openid, 'set_entry' => $setEntry, 'nickname' => $data['nickname']],
         ];
 
         // 用户缓存信息
@@ -282,13 +284,13 @@ class MemberService extends BaseService
             return false;
         }
 
-        if(!$this->model->where(['id'=>$userId])->update(['password'=> get_password($password),'update_time'=>time()])){
+        if (!$this->model->where(['id' => $userId])->update(['password' => get_password($password), 'update_time' => time()])) {
             $this->error = 2030;
             return false;
         }
 
         // 操作日志
-        ActionLogModel::setRecord($userId,['type'=>2,'title'=>'重置密码','content'=>'重置登录密码','module'=>'member']);
+        ActionLogModel::setRecord($userId, ['type' => 2, 'title' => '重置密码', 'content' => '重置登录密码', 'module' => 'member']);
         ActionLogModel::record();
 
         $this->error = 2031;
@@ -300,15 +302,15 @@ class MemberService extends BaseService
      * @param $where
      * @param array $field
      */
-    public function getInfo($where, array $field = [], $refresh=true)
+    public function getInfo($where, array $field = [], $refresh = true)
     {
-        $cacheKey = "caches:members:info_".(!is_array($where)? $where.'_':'').md5(json_encode($where).json_encode($field));
+        $cacheKey = "caches:members:info_" . (!is_array($where) ? $where . '_' : '') . md5(json_encode($where) . json_encode($field));
         $info = RedisService::get($cacheKey);
-        if($info && !$refresh){
+        if ($info && !$refresh) {
             return $info;
         }
 
-        $defaultField = ['id', 'user_type', 'realname', 'mobile', 'nickname','is_zg_vip','zg_vip_expired','is_zsb_vip','is_zsb_vip','zsb_vip_expired','is_video_vip','video_vip_expired','balance', 'code', 'openid', 'status', 'avatar'];
+        $defaultField = ['id', 'user_type', 'realname', 'mobile', 'nickname', 'is_zg_vip', 'zg_vip_expired', 'is_zsb_vip', 'is_zsb_vip', 'zsb_vip_expired', 'is_video_vip', 'video_vip_expired', 'balance', 'code', 'openid', 'status', 'avatar'];
         $field = $field ? $field : $defaultField;
         if (is_array($where)) {
             $info = $this->model->where(['mark' => 1])->where($where)->select($field)->first();
@@ -326,28 +328,28 @@ class MemberService extends BaseService
                 $info['mobile_text'] = $info['mobile'] ? format_mobile($info['mobile']) : '';
             }
 
-            if(isset($info['create_time'])){
+            if (isset($info['create_time'])) {
                 $info['create_at'] = datetime(strtotime($info['create_time']));
             }
 
             $isVip = 0;
             $vipExpired = '';
-            $isZgVip = isset($info['is_zg_vip'])? $info['is_zg_vip'] : 0;
-            $zgVipExpired = isset($info['zg_vip_expired']) && !empty($info['zg_vip_expired'])? $info['zg_vip_expired'] : '';
-            if($isZgVip && $zgVipExpired && $zgVipExpired>date('Y-m-d H:i:s')){
+            $isZgVip = isset($info['is_zg_vip']) ? $info['is_zg_vip'] : 0;
+            $zgVipExpired = isset($info['zg_vip_expired']) && !empty($info['zg_vip_expired']) ? $info['zg_vip_expired'] : '';
+            if ($isZgVip==1 && $zgVipExpired && $zgVipExpired > date('Y-m-d H:i:s')) {
                 $isVip = 1;
                 $isZgVip = 1;
                 $vipExpired = $zgVipExpired;
-            }else{
+            } else {
                 $isZgVip = 0;
             }
 
-            $isZsbVip = isset($info['is_zsb_vip'])? $info['is_zsb_vip'] : 0;
-            $zsbVipExpired = isset($info['zsb_vip_expired']) && !empty($info['zsb_vip_expired'])? $info['zsb_vip_expired'] : '';
-            if($isZsbVip && $zsbVipExpired && $zsbVipExpired>date('Y-m-d H:i:s')){
+            $isZsbVip = isset($info['is_zsb_vip']) ? $info['is_zsb_vip'] : 0;
+            $zsbVipExpired = isset($info['zsb_vip_expired']) && !empty($info['zsb_vip_expired']) ? $info['zsb_vip_expired'] : '';
+            if ($isZsbVip==1 && $zsbVipExpired && $zsbVipExpired > date('Y-m-d H:i:s')) {
                 $isVip = 1;
-                $vipExpired = $zsbVipExpired>$vipExpired? $zsbVipExpired : $vipExpired;
-            }else{
+                $vipExpired = $zsbVipExpired > $vipExpired ? $zsbVipExpired : $vipExpired;
+            } else {
                 $isZsbVip = 0;
             }
 
@@ -357,7 +359,7 @@ class MemberService extends BaseService
             $info['vip_expired'] = $vipExpired;
             $info['zg_vip_expired'] = $zgVipExpired;
             $info['zsb_vip_expired'] = $zsbVipExpired;
-            $info['video_vip_expired'] = isset($info['video_vip_expired']) && !empty($info['video_vip_expired'])? $info['video_vip_expired'] : '';
+            $info['video_vip_expired'] = isset($info['video_vip_expired']) && !empty($info['video_vip_expired']) ? $info['video_vip_expired'] : '';
             RedisService::set($cacheKey, $info, rand(5, 10));
         }
 
@@ -421,13 +423,13 @@ class MemberService extends BaseService
     public function modify($userId, $params)
     {
         $cacheLockKey = "caches:members:modify_{$userId}";
-        if(RedisService::get($cacheLockKey)){
+        if (RedisService::get($cacheLockKey)) {
             $this->error = 1034;
             return false;
         }
 
         // 用户验证
-        RedisService::set($cacheLockKey, ['user_id'=> $userId,'params'=>$params], rand(2,3));
+        RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(2, 3));
         $info = $this->model->where(['id' => $userId, 'mark' => 1])
             ->select(['id', 'password', 'status'])
             ->first();
@@ -460,7 +462,7 @@ class MemberService extends BaseService
                 return false;
             }
 
-            if(empty($newPassword)){
+            if (empty($newPassword)) {
                 $this->error = 1039;
                 RedisService::clear($cacheLockKey);
                 return false;
@@ -499,13 +501,13 @@ class MemberService extends BaseService
     public function setEntry($userId, $params)
     {
         $cacheLockKey = "caches:members:entry_{$userId}";
-        if(RedisService::get($cacheLockKey)){
+        if (RedisService::get($cacheLockKey)) {
             $this->error = 1034;
             return false;
         }
 
         // 用户验证
-        RedisService::set($cacheLockKey, ['user_id'=> $userId,'params'=>$params], rand(2,3));
+        RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(2, 3));
         $info = $this->model->where(['id' => $userId, 'mark' => 1])
             ->select(['id', 'password', 'status'])
             ->first();
@@ -517,8 +519,8 @@ class MemberService extends BaseService
 
         // 密码校验
         $data = [
-            'entry_type'=> isset($params['entry_type'])? intval($params['entry_type']) : 0,
-            'need_paper'=> isset($params['need_paper'])? intval($params['need_paper']) : 0,
+            'entry_type' => isset($params['entry_type']) ? intval($params['entry_type']) : 0,
+            'need_paper' => isset($params['need_paper']) ? intval($params['need_paper']) : 0,
             'update_time' => time()
         ];
 
@@ -538,23 +540,151 @@ class MemberService extends BaseService
      * @param int $type
      * @return array|mixed
      */
-    public function getVipList($type=1)
+    public function getVipList($type = 1)
     {
         $cacheKey = "caches:members:vipList:{$type}";
         $datas = RedisService::get($cacheKey);
-        if($datas){
+        if ($datas) {
             return $datas;
         }
 
-        $datas = VipModel::where(['type'=> $type,'status'=>1,'mark'=>1])
-            ->select(['id','name','type','price','day','remark','status'])
-            ->orderBy('id','asc')
+        $datas = VipModel::where(['type' => $type, 'status' => 1, 'mark' => 1])
+            ->select(['id', 'name', 'type', 'price', 'day', 'remark', 'status'])
+            ->orderBy('id', 'asc')
             ->get();
-        $datas = $datas? $datas->toArray() : [];
-        if($datas){
+        $datas = $datas ? $datas->toArray() : [];
+        if ($datas) {
             RedisService::set($cacheKey, $datas, rand(3600, 7200));
         }
 
         return $datas;
     }
+
+    public function vipBuy($userId, $vipId)
+    {
+        $cacheKey = "caches:members:vipBuy:{$userId}_{$vipId}";
+        if (RedisService::get($cacheKey . '_lock')) {
+            $this->error = '请不要频繁提交~';
+            return false;
+        }
+
+        RedisService::set($cacheKey, ['date' => date('Y-m-d H:i:s')], rand(2, 3));
+        $vipInfo = VipModel::where(['id' => $vipId, 'status' => 1, 'mark' => 1])
+            ->select(['id', 'type', 'price', 'day', 'status'])
+            ->first();
+        $price = isset($vipInfo['price']) ? floatval($vipInfo['price']) : 0;
+        $day = isset($vipInfo['day']) ? intval($vipInfo['day']) : 0;
+        $vipType = isset($vipInfo['type']) && $vipInfo['type']? intval($vipInfo['type']) : 1;
+        $vipName = isset($vipInfo['name'])? $vipInfo['name'] : '';
+        if (empty($vipInfo)) {
+            $this->error = '该VIP已下架';
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        if ($price <= 0 || $day <= 0) {
+            $this->error = '该VIP参数错误';
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        $info = $this->model->where(['id' => $userId, 'mark' => 1])
+            ->select(['id','is_zg_vip', 'zg_vip_expired','is_zsb_vip','zsb_vip_expired','is_video_vip','video_expired', 'status'])
+            ->first();
+        $isZgVip = isset($info['is_zg_vip'])? $info['is_zg_vip'] : '';
+        $isZsbVip = isset($info['is_zsb_vip'])? $info['is_zsb_vip'] : '';
+        $isVideoVip = isset($info['is_video_vip'])? $info['is_video_vip'] : '';
+        $zgVipExpired = isset($info['zg_vip_expired'])? $info['zg_vip_expired'] : '';
+        $zsbVipExpired = isset($info['zsb_vip_expired'])? $info['zsb_vip_expired'] : '';
+        $videoVipExpired = isset($info['zsb_vip_expired'])? $info['zsb_vip_expired'] : '';
+        if (!$info || $info['status'] != 1) {
+            $this->error = 1045;
+            RedisService::clear($cacheKey . '_lock');
+            return false;
+        }
+
+        // 验证是否
+        $expiredTime = time();
+        $vipLimitOpen = ConfigService::make()->getConfigByCode('vip_limit_more', 1);
+        if($vipLimitOpen){
+            // 已开通职高VIP无法再开通
+            if($vipType == 1 && ($isZgVip==1 && $zgVipExpired >= date('Y-m-d H:i:s'))){
+                $this->error = '抱歉,您的职高VIP未到期,到期后再尝试~';
+                return false;
+            }
+
+            // 已开通专升本VIP无法再开通
+            if($vipType == 2 && ($isZsbVip==1 && $zsbVipExpired >= date('Y-m-d H:i:s'))){
+                $this->error = '抱歉,您的专升本VIP未到期,到期后再尝试~';
+                return false;
+            }
+
+            // 已开通全部视频VIP无法再开通
+            if($vipType == 3 && ($isVideoVip && $videoVipExpired >= date('Y-m-d H:i:s'))){
+                $this->error = '抱歉,您的已开通全部视频VIP,请到期后再尝试~';
+                return false;
+            }
+        }else{
+            if($vipType == 1 && $isZgVip==1 && $zgVipExpired >= date('Y-m-d H:i:s')){
+                $expiredTime = strtotime($zgVipExpired);
+            }
+
+            if($vipType == 2 && $isZsbVip==1 && $zsbVipExpired >= date('Y-m-d H:i:s')){
+                $expiredTime = strtotime($zsbVipExpired);
+            }
+
+            if($vipType == 3 && $isVideoVip==1 && $videoVipExpired >= date('Y-m-d H:i:s')){
+                $expiredTime = strtotime($videoVipExpired);
+            }
+        }
+
+        // 创建订单
+        $orderNo = get_order_num('VP');
+        $order = [
+            'order_no'=> $orderNo,
+            'user_id'=> $userId,
+            'goods_id'=> $vipId,
+            'total'=> $price,
+            'expired_at'=> date('Y-m-d H:i:s', $expiredTime + $day * 86400),
+            'create_time'=> time(),
+            'remark'=> "购买{$vipName}VIP",
+            'status'=>1,
+            'mark'=>1
+        ];
+
+        DB::beginTransaction();
+        if(!$orderId = OrderModel::insertGetId($order)){
+            $this->error = '创建购买订单失败';
+            return false;
+        }
+
+        /* TODO 支付处理 */
+        $payOrder = [
+            'type'=> 1,
+            'order_no'=> $orderNo,
+            'pay_money'=> $price,
+            'body'=> "购买{$vipName}VIP",
+        ];
+
+        // 调起支付
+        $payment = PaymentService::make()->wechatPay($info, $payOrder,'vip');
+        if(empty($payment)){
+            DB::rollBack();
+            RedisService::clear($cacheLockKey);
+            $this->error = PaymentService::make()->getError();
+            return false;
+        }
+
+        // 用户操作记录
+        DB::commit();
+        $this->error = 2122;
+        RedisService::clear($cacheLockKey);
+        return [
+            'order_id'=> $orderId,
+            'payment'=> $payment,
+            'total'=> $payOrder['pay_money'],
+            'pay_type'=> $payType,
+        ];
+
+    }
 }

+ 29 - 244
app/Services/PaymentService.php

@@ -16,7 +16,9 @@ use App\Models\BalanceLogModel;
 use App\Models\DepositModel;
 use App\Models\MemberModel;
 use App\Models\MessageModel;
+use App\Models\OrderModel;
 use App\Models\PaymentModel;
+use App\Models\VipModel;
 use App\Services\Api\MessageService;
 use Illuminate\Support\Facades\DB;
 use Yansongda\Pay\Pay;
@@ -135,7 +137,7 @@ class PaymentService extends BaseService
      * @param string $scene
      * @return false|\Yansongda\Supports\Collection
      */
-    public function wechatPay($userInfo, $order, $scene = 'deposit')
+    public function wechatPay($userInfo, $order, $scene = 'pay')
     {
         $amount = isset($order['pay_money']) ? $order['pay_money'] : 0;
         if ($amount < 0) {
@@ -366,9 +368,9 @@ class PaymentService extends BaseService
 
         /* TODO 订单验证和状态处理 */
         // 充值订单
-        if ($scene == 'deposit') {
-            $orderInfo = DepositModel::where(['order_no' => $orderNo, 'type' => 1, 'mark' => 1])
-                ->select(['id as order_id', 'user_id', 'order_no', 'money as pay_money','before_money', 'pay_at as pay_time', 'pay_status', 'status'])
+        if ($scene == 'vip') {
+            $orderInfo = OrderModel::with(['vip'])->where(['order_no' => $orderNo, 'mark' => 1])
+                ->select(['id as order_id', 'user_id','goods_id','expired_at', 'order_no', 'total as pay_money', 'pay_at as pay_time', 'status'])
                 ->first();
             $orderStatus = isset($orderInfo['status']) ? $orderInfo['status'] : 0;
             // 验证订单
@@ -385,17 +387,17 @@ class PaymentService extends BaseService
                 return false;
             }
 
-            $updateData = ['pay_status' => 2, 'pay_at' => $payAt, 'transaction_id' => $transactionId, 'status' => 3, 'update_time' => time()];
-            if (!DepositModel::where(['order_no' => $orderNo, 'type' => 1, 'mark' => 1])->update($updateData)) {
+            $updateData = ['pay_at' => $payAt, 'transaction_id' => $transactionId, 'status' => 2, 'update_time' => time()];
+            if (!OrderModel::where(['order_no' => $orderNo, 'mark' => 1])->update($updateData)) {
                 $this->error = 2633;
                 DB::rollBack();
                 return false;
             }
 
         } // 保证金退款
-        else if ($scene == 'depositRefund') {
-            $orderInfo = DepositModel::where(['refund_no' => $orderNo, 'type' => 1, 'mark' => 1])
-                ->select(['id as order_id', 'user_id', 'refund_no as order_no', 'refund_money as pay_money','before_money', 'pay_at as pay_time', 'refund_status as status'])
+        else if ($scene == 'refund') {
+            $orderInfo = OrderModel::where(['order_no' => $orderNo, 'mark' => 1])
+                ->select(['id as order_id', 'user_id', 'order_no', 'total as pay_money', 'pay_at as pay_time', 'refund_status as status'])
                 ->first();
             $orderStatus = isset($orderInfo['status']) ? $orderInfo['status'] : 0;
             // 验证订单
@@ -419,41 +421,8 @@ class PaymentService extends BaseService
                 return false;
             }
 
-            $updateData = ['refund_pay_at' => $payAt, 'refund_transaction_id' => $transactionId, 'refund_status' => 4, 'update_time' => time()];
-            if (!DepositModel::where(['refund_no' => $orderNo, 'type' => 1, 'mark' => 1])->update($updateData)) {
-                $this->error = 2633;
-                DB::rollBack();
-                return false;
-            }
-        } else if($scene == 'withdraw'){
-            $orderInfo = BalanceLogModel::where(['order_no' => $orderNo, 'type' => 2, 'mark' => 1])
-                ->select(['id as order_id', 'user_id', 'order_no', 'money as pay_money','before_money', 'pay_at as pay_time', 'pay_status', 'status'])
-                ->first();
-            $orderStatus = isset($orderInfo['status']) ? $orderInfo['status'] : 0;
-            $payStatus = isset($orderInfo['pay_status']) ? $orderInfo['pay_status'] : 0;
-            // 验证订单
-            if (empty($orderInfo)) {
-                DB::rollBack();
-                $this->error = 2629;
-                return false;
-            }
-
-            // 订单状态
-            if ($orderStatus != 2) {
-                DB::rollBack();
-                $this->error = 2639;
-                return false;
-            }
-
-            // 订单打款状态
-            if ($payStatus != 1) {
-                DB::rollBack();
-                $this->error = 2630;
-                return false;
-            }
-
-            $updateData = ['pay_status' => 2, 'pay_at' => $payAt, 'transaction_id' => $transactionId, 'update_time' => time()];
-            if (!BalanceLogModel::where(['order_no' => $orderNo, 'type' => 2, 'mark' => 1])->update($updateData)) {
+            $updateData = ['refund_status' => 4, 'update_time' => time()];
+            if (!OrderModel::where(['order_no' => $orderNo,'mark' => 1])->update($updateData)) {
                 $this->error = 2633;
                 DB::rollBack();
                 return false;
@@ -461,111 +430,36 @@ class PaymentService extends BaseService
         }
 
         // TODO 场景业务回调处理
-        $pushData = []; // 推送消息数据
         $orderUserId = isset($orderInfo['user_id']) ? $orderInfo['user_id'] : 0;
         RedisService::set("caches:notify:{$orderNo}_{$scene}:data", ['order' => $orderInfo, 'notify' => $data], 7200);
         switch ($scene) {
-            case 'deposit': // 保证金充值
-                $updateData = ['deposit'=>DB::raw("deposit + {$payTotal}"),'update_time'=>time()];
-                if(!MemberModel::where(['id'=> $orderUserId,'mark'=>1])->update($updateData)){
+            case 'vip': // 购买VIP
+                $vipInfo = isset($orderInfo['vip'])? $orderInfo['vip'] : [];
+                $vipType = isset($vipInfo['type'])? $vipInfo['type'] : 0;
+                $expiredAt = isset($orderInfo['expired_at'])? $vipInfo['expired_at'] : '';
+                if(empty($vipInfo) || $expiredAt <= date('Y-m-d H:i:s') || $vipType<=0){
                     DB::rollBack();
-                    $this->error = 2180;
-                    return false;
+                    $this->error = 'VIP参数错误';
                 }
-
-                // 缴纳保证金消息
-                $message = "用户{$username}充值了{$payTotal}元保证金";
-                $msgData = [
-                    'from_uid' => $orderUserId,
-                    'to_uid' => 0,
-                    'type' => 3,// 保证金消息
-                    'msg_type' => 4,
-                    'title' => '充值保证金消息',
-                    'description' => $message,
-                    'order_no' => $orderNo,
-                    'content' => json_encode([
-                        'title'=> $message.'<span class="ele-text-primary">查看订单</span>',
-                        'order_no'=> $orderNo,
-                        'money'=> $payTotal,
-                        'date'=> date('Y-m-d H:i:s'),
-                        'user_id'=> $orderUserId,
-                        'type'=> 'deposit',
-                        'remark'=> '充值保证金',
-                    ],256),
-                    'chat_key' => getChatKey($orderUserId,0),
-                    'create_time' => time(),
-                    'update_time' => time(),
-                    'is_read' => 2,
-                    'status' => 1
-                ];
-                MessageModel::insertGetId($msgData);
-            case 'depositRefund': // 保证金退款
-                $deposit = isset($orderInfo['before_money'])? $orderInfo['before_money'] : 0;
-                // 明细处理
-                $logId = AccountLogModel::where(['user_id'=>$orderUserId,'source_order_no'=> $orderNo,'mark'=>1])->value('id');
-                $log = [
-                    'user_id' => $orderUserId,
-                    'source_order_no' => isset($orderInfo['order_no']) ? $orderInfo['order_no'] : '',
-                    'type' => $scene=='deposit'? 2 : 3,
-                    'money' => $payTotal,
-                    'before_money' => $scene=='deposit'?$deposit:0,
-                    'date'=> date('Y-m-d'),
-                    'create_time' => time(),
-                    'remark' => $scene == 'deposit'? '充值保证金' :'退保申请',
-                    'status' => 1,
-                    'mark' => 1,
-                ];
-                if($logId){
-                   AccountLogModel::where(['id'=> $logId])->update([
-                        'status'=>1,
-                        'update_time'=>time(),
-                    ]);
-                }else if (!AccountLogModel::insertGetId($log)) {
-                    DB::rollBack();
-                    $this->error = 2180;
-                    return false;
-
+                $field = "zg_vip";
+                if($vipType == 2){
+                    $field = "zsb_vip";
+                }else if($vipType==3){
+                    $field = "video_vip";
                 }
-                break;
-            case 'withdraw': // 收入提现// 明细处理
-                $money = isset($orderInfo['before_money'])? $orderInfo['before_money'] : 0;
-                $logId = AccountLogModel::where(['user_id'=>$orderUserId,'source_order_no'=> $orderNo,'mark'=>1])->value('id');
-                $log = [
-                    'user_id' => $orderUserId,
-                    'source_order_no' => isset($orderInfo['order_no']) ? $orderInfo['order_no'] : '',
-                    'type' => 4,
-                    'money' => $payTotal,
-                    'before_money' => $money,
-                    'date'=> date('Y-m-d'),
-                    'create_time' => time(),
-                    'remark' => '收入提现',
-                    'status' => 1,
-                    'mark' => 1,
-                ];
-                if($logId){
-                    AccountLogModel::where(['id'=> $logId])->update([
-                        'status'=>1,
-                        'update_time'=>time(),
-                    ]);
-                }else if (!AccountLogModel::insertGetId($log)) {
+                $updateData = ["is_{$field}"=> 1,"{$field}_expired"=> $expiredAt,'update_time'=>time()];
+                if(!MemberModel::where(['id'=> $orderUserId,'mark'=>1])->update($updateData)){
                     DB::rollBack();
-                    $this->error = 2180;
+                    $this->error = 2639;
                     return false;
-
                 }
-                break;
             default:
                 DB::rollBack();
                 $this->error = 2631;
                 return false;
         }
 
-        if ($pushData && !MessageService::make()->pushMessage($orderInfo['user_id'], $pushData)) {
-            $this->error = MessageService::make()->getError();
-            return false;
-        }
-
-
+        $this->error = 2638;
         DB::commit();
         return true;
     }
@@ -579,7 +473,7 @@ class PaymentService extends BaseService
      * @throws \Yansongda\Pay\Exception\InvalidParamsException
      * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
      */
-    public function refund($order, $scene='depositRefund')
+    public function refund($order, $scene='vip')
     {
         $money = isset($order['money'])? $order['money'] : 0;
         $payType = isset($order['pay_type'])? $order['pay_type'] : 0;
@@ -647,113 +541,4 @@ class PaymentService extends BaseService
         $this->error = 2176;
         return $refundStatus;
     }
-
-    /**
-     * 企业打款到余额
-     * @param $order 订单参数:order_no-单号,pay_money-打款金额,account-打款账号(微信openid或支付宝账号),body-打款备注
-     * @param string $scene
-     * @param int $payType
-     * @return bool
-     */
-    public function transfer($order, $scene='withdraw', $payType=10)
-    {
-        $outTradeNo = isset($order['order_no']) && $order['order_no'] ? $order['order_no'] : get_order_num('WD');
-        $body = isset($order['body']) ? $order['body'] : '';
-        $amount = isset($order['pay_money']) ? $order['pay_money'] : 0;
-        $account = isset($order['account']) ? $order['account'] : '';  // 微信openid或支付宝账号
-        $realName = isset($order['real_name']) ? $order['real_name'] : '';  // 实名
-        if ($amount < 0) {
-            $this->error = 2037;
-            return false;
-        }
-
-        if(empty($account)){
-            $this->error = $payType == 10? 2044 : 2045;
-            return false;
-        }
-
-        // 创建支付
-        $result = [];
-        try {
-            $config = ConfigService::make()->getConfigOptionByGroup(6);
-            if ($payType == 10) {
-                $appid = isset($config['wxpay_appid']) ? $config['wxpay_appid'] : '';
-                $payData = [
-                    'appid' => $appid, // 微信小程序的app_id
-                    'out_batch_no' => $outTradeNo, // 商家批次单号
-                    'batch_name' => $body? $body : '收入提现',    // 该笔批量转账的名称
-                    'batch_remark' => $body? $body : '收入提现',  // 转账说明
-                    'total_amount' => intval($amount * 100),  // 转账金额,单位:分
-                    'total_num' => 1,   // 转账总笔数
-                    'transfer_detail_list' => [
-                        [
-                            'out_detail_no' => $outTradeNo,  // 商家明细单号
-                            'transfer_amount' => intval($amount * 100),  // 转账金额
-                            'transfer_remark' => $body? $body : '收入提现',  // 单条转账备注(微信用户会收到该备注)
-                            'openid' => $account, //  转账用户的 openid
-                        ],
-                    ],
-                ];
-
-                $pay = $this->createPay($scene, $payType);
-                RedisService::set("caches:payments:wechat:{$scene}_{$outTradeNo}_pay", ['order' => $order, 'config' => $this->config], 7200);
-                if (empty($pay)) {
-                    $this->error = 2616;
-                    return false;
-                }
-
-
-                $result = $pay->transfer($payData);
-                RedisService::set("caches:payments:wechat:{$scene}_{$outTradeNo}_result", ['order' => $order,'result'=> $result, 'config' => $this->config], 7200);
-                $msg = isset($result['message'])? trim($result['message']) : '';
-                $orderId = isset($result['batch_id'])? trim($result['batch_id']) : '';
-                if(empty($orderId)){
-                    $this->error = $msg? $msg : 2046;
-                    return false;
-                }
-
-                $this->error = 2047;
-                return ['order_no'=> $outTradeNo,'order_id'=> $orderId];
-            }else if ($payType == 20){
-                $payData = [
-                    'out_biz_no'   => $outTradeNo,//商户订单号,内部订单号
-                    'trans_amount' => $amount,  //订单总金额,单位为元,精确到小数点后两位,
-                    'biz_scene'    => 'DIRECT_TRANSFER',  //描述特定的业务场景,可传的参数如下:DIRECT_TRANSFER:单笔无密转账到支付宝,B2C现金红包PERSONAL_COLLECTION:C2C现金红包-领红包
-                    'product_code' => 'TRANS_ACCOUNT_NO_PWD',  //业务产品码,单笔无密转账到支付宝账户固定为:TRANS_ACCOUNT_NO_PWD;收发现金红包固定为:STD_RED_PACKET;
-                    'remark'       => $body? $body : '收入提现',//业务备注
-                    'order_title'  => $body? $body : '收入提现',//转账业务的标题,用于在支付宝用户的账单里显示
-                    'payee_info'   => [
-                        'identity'      => $account,//参与方的唯一标识'208823395231'
-                        'name'      => $realName,//参与方的唯一标识'208823395231'
-                        'identity_type' => 'ALIPAY_LOGON_ID',//参与方的标识类型,目前支持如下类型:1、ALIPAY_USER_ID 支付宝的会员ID2、ALIPAY_LOGON_ID:支付宝登录号,支持邮箱和手机号格式3、ALIPAY_OPEN_ID:支付宝openid
-                    ],//收款方信息
-                ];
-                $pay = $this->createPay($scene, $payType);
-                RedisService::set("caches:payments:alipay:{$scene}_{$outTradeNo}_pay", ['order' => $order, 'config' => $this->config], 7200);
-                if (empty($pay)) {
-                    $this->error = 2616;
-                    return false;
-                }
-
-
-                $result = $pay->transfer($payData);
-                RedisService::set("caches:payments:alipay:{$scene}_{$outTradeNo}_result", ['order' => $order,'result'=> $result, 'config' => $this->config], 7200);
-                $code = isset($result['code'])? intval($result['code']) : '';
-                $msg = isset($result['sub_msg'])? trim($result['sub_msg']) : '';
-                if($code != 10000){
-                    $this->error = $msg? $msg : 2046;
-                    return false;
-                }
-                $this->error = 2047;
-                return $result;
-            }
-
-            $this->error = 2046;
-            return false;
-        } catch (\Exception $exception) {
-            RedisService::set("caches:payments:trabsfer:{$scene}_{$outTradeNo}_error", ['order' => $order,'error'=>$exception->getTrace(), 'config' => $this->config], 7200);
-            $this->error = $exception->getMessage();
-            return false;
-        }
-    }
 }

+ 28 - 0
resources/lang/zh-cn/api.php

@@ -39,10 +39,38 @@ return [
     '1041' => '缺少微信授权码',
     '1042' => '授权登录错误',
     '1043' => '操作失败,请返回重试~',
+    '1045' => '操作失败,该账户已被冻结,请联系客服~',
 
     // 账户
     '2011'=>"授权登录失败,用户账号被冻结",
     '2012'=>"授权登录失败",
     '2013'=>"授权登录成功",
     '2014'=>"手机号获取失败",
+
+
+    '2615'=> '支付金额错误',
+    '2616'=> '微信支付参数未配置',
+    '2617'=> '微信支付调用成功',
+    '2618'=> '微信支付调用失败',
+    '2619'=> '支付宝支付参数未配置',
+    '2620'=> '支付宝支付调用成功',
+    '2621'=> '支付宝支付调用失败',
+    '2622'=> '支付回调状态未成功',
+    '2623'=> '支付回调订单参数错误',
+    '2624'=> '支付回调付款金额错误',
+    '2625'=> '支付请求信息错误',
+    '2626'=> '订单已支付',
+    '2627'=> '订单回调支付类型不一致',
+    '2628'=> '订单付款金额错误',
+    '2629'=> '支付订单不存在',
+    '2630'=> '支付订单已处理',
+    '2631'=> '交易场景参数错误',
+    '2632'=> '支付信息处理错误',
+    '2633'=> '支付订单处理错误',
+    '2634'=> '用户账户入账错误',
+    '2635'=> '支付回调处理失败',
+    '2636'=> '订单不存在或参数错误',
+    '2637'=> '订单支付信息错误,请联系客服',
+    '2638'=> '支付回调处理成功',
+    '2639'=> '用户VIP数据更新失败',
 ];

+ 2 - 1
routes/api.php

@@ -56,6 +56,7 @@ Route::prefix('v1')->middleware('web.login')->group(function() {
     Route::get('/user/vipList', [\App\Http\Controllers\Api\v1\MemberController::class, 'vipList']);
     Route::post('/user/setEntry', [\App\Http\Controllers\Api\v1\MemberController::class, 'setEntry']);
     Route::post('/user/modify', [\App\Http\Controllers\Api\v1\MemberController::class, 'modify']);
+    Route::post('/user/vipBuy', [\App\Http\Controllers\Api\v1\MemberController::class, 'vipBuy']);
 
     // 账户
     Route::post('/account/index', [\App\Http\Controllers\Api\v1\AccountController::class, 'index']);
@@ -74,7 +75,7 @@ Route::prefix('v1')->middleware('web.login')->group(function() {
 });
 
 // 回调处理
-Route::match(['get','post'],'/notify/refund/{payType}', [\App\Http\Controllers\Api\v1\NotifyController::class, 'refund']);
+Route::match(['get','post'],'/notify/{scene}/{payType}', [\App\Http\Controllers\Api\v1\NotifyController::class, 'refund']);
 Route::match(['get','post'],'/notify/{scene}/{payType}', [\App\Http\Controllers\Api\v1\NotifyController::class, 'callback']);
 Route::match(['get','post'],'/notify/kf', [\App\Http\Controllers\Api\v1\NotifyController::class, 'kf']);