// +---------------------------------------------------------------------- namespace App\Services\Api; use App\Helpers\Jwt; use App\Models\ActionLogModel; use App\Models\MemberModel; use App\Models\OrderModel; use App\Models\VideoCoursesModel; use App\Models\VideoOrderModel; 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; use Illuminate\Support\Facades\DB; /** * 会员管理-服务类 * @author laravel开发员 * @since 2020/11/11 * Class MemberService * @package App\Services\Api */ class MemberService extends BaseService { // 静态对象 protected static $instance = null; /** * 构造函数 * @author laravel开发员 * @since 2020/11/11 * MemberService constructor. */ public function __construct() { $this->model = new MemberModel(); } /** * 静态入口 * @return MemberService|static|null */ public static function make() { if (!self::$instance) { self::$instance = new static(); } return self::$instance; } /** * 账号登录 * @param $params * @return array|false */ public function login($params) { // 账号登录 $mobile = isset($params['mobile']) ? $params['mobile'] : ''; $password = isset($params['password']) ? $params['password'] : ''; if (empty($params) || empty($mobile) || empty($password)) { $this->error = 1041; return false; } // 验证是否注册,没有则注册 $data = $this->model->where(['mobile' => $mobile, 'mark' => 1])->select(['id', 'mobile', 'user_type', 'password', 'nickname', 'code', 'status'])->first(); $data = $data ? $data->toArray() : []; $userId = isset($data['id']) ? $data['id'] : 0; $status = isset($data['status']) ? $data['status'] : 0; $userPassword = isset($data['password']) ? $data['password'] : ''; if (empty($data) || $userId <= 0) { $this->error = 2014; return false; } if ($status != 1) { $this->error = 2015; return false; } // 验证登录密码 if (empty($userPassword) || $userPassword != get_password($password)) { $this->error = 2017; return false; } // 更新 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, ]; $this->model->where(['id' => $userId])->update($updateData); RedisService::set("caches:members:login_{$userId}", $updateData, rand(300, 600)); } // 获取登录授权token $jwt = new Jwt('jwt_jd_app'); $token = $jwt->getToken($userId); // 结果返回 $result = [ 'access_token' => $token, 'info' => ['uid' => $userId, 'nickname' => $data['nickname']], ]; // 用户缓存信息 $this->error = 2019; $data['token'] = $token; unset($data['password']); unset($data['mobile']); RedisService::set("auths:info:{$userId}", $data, 24 * 3600); return $result; } /** * 授权登录 * @param $code * @param array $params * @return array|false */ public function mpAuth($code, $params = []) { // 账号登录 if (empty($code)) { $this->error = 1041; return false; } // 获取授权用户信息 $phone = ''; $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'] : ''; } if (empty($phone)) { $this->error = 2014; return false; } $userInfo = MpService::make()->getUserInfo($code); $openid = isset($userInfo['openid']) ? $userInfo['openid'] : ''; if (empty($userInfo)) { $this->error = MpService::make()->getError(); return false; } if (empty($openid)) { $this->error = 1042; return false; } // 验证是否注册,没有则注册 $where = ['mobile' => $phone]; $data = $this->model->where($where) ->select(['id', 'openid', 'mobile', 'user_type', 'nickname', 'entry_type', 'province', 'city', 'district', 'need_paper', 'code', 'status','mark']) ->first(); $data = $data ? $data->toArray() : []; $userId = isset($data['id']) ? $data['id'] : 0; $status = isset($data['status']) ? $data['status'] : 0; $mark = isset($data['mark']) ? $data['mark'] : 0; $entryType = isset($data['entry_type']) ? $data['entry_type'] : 0; $needPaper = isset($data['need_paper']) ? $data['need_paper'] : 0; $city = isset($data['city']) ? $data['city'] : ''; $district = isset($data['district']) ? $data['district'] : ''; if ($data && $userId && $status != 1 && $mark==1) { $this->error = 2011; return false; } $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; $data = [ 'nickname' => $phone ? '用户' . substr($phone, -6, 6) : '用户' . $userId, 'openid' => $openid, 'mobile' => $phone, 'code' => get_random_code(9, 'S', $userId), '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 (!$userId = $this->model->insertGetId($data)) { $this->error = 2012; return false; } } // 更新登录信息 else if ($mark==0 || !RedisService::get("caches:members:login_{$userId}")) { $updateData = [ 'login_ip' => get_client_ip(), 'login_time' => time(), 'app_uuid' => $uuid, 'login_count' => DB::raw("login_count+1"), 'app_version' => $version, 'device' => $appSources == 'ios' ? 1 : 2, 'mark' => 1, ]; if ($openid) { $updateData['openid'] = $openid; } if($mark==0){ $data['mobile'] = $phone; $data['create_time'] = time(); $data['openid'] = $openid; $data['prvoince'] = ''; $data['city'] = ''; $data['district'] = ''; $city = ''; $district = ''; } $this->model->where(['id' => $userId])->update($updateData); RedisService::set("caches:members:login_{$userId}", $updateData, rand(180, 300)); } // 获取登录授权token $jwt = new Jwt('jwt_jd_app'); $token = $jwt->getToken($userId); // 结果返回 $setEntry = $entryType && $needPaper ? 1 : 0; $result = [ 'access_token' => $token, 'info' => ['uid' => $userId, 'openid' => $openid, 'set_entry' => $setEntry, 'has_area' => $city && $district ? 1 : 0, 'nickname' => $data['nickname']], ]; // 用户缓存信息 $this->error = 2013; $data['token'] = $token; unset($data['mobile']); RedisService::set("auths:info:{$userId}", $data, 24 * 3600); return $result; } /** * 重置密码 * @param $params * @return array|false */ public function forget($params) { // 账号登录 $mobile = isset($params['mobile']) ? trim($params['mobile']) : ''; $password = isset($params['password']) ? trim($params['password']) : ''; if (empty($params) || empty($mobile) || empty($password)) { $this->error = 1041; return false; } // 验证码验证 $smsCode = isset($params['sms_code']) ? trim($params['sms_code']) : ''; if (!SmsService::make()->check($mobile, $smsCode, 'reset_password')) { $this->error = SmsService::make()->getError(); return false; } // 验证是否注册 if (!$userId = $this->model->where(['mobile' => $mobile, 'mark' => 1])->value('id')) { $this->error = 1038; return false; } 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::record(); $this->error = 2031; return true; } /** * 获取资料详情 * @param $where * @param array $field */ public function getInfo($where, array $field = [], $refresh = true) { $cacheKey = "caches:members:info_" . (!is_array($where) ? $where . '_' : '') . md5(json_encode($where) . json_encode($field)); $info = RedisService::get($cacheKey); 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', 'city', 'district', 'balance', 'code', 'openid', 'status', 'avatar']; $field = $field ? $field : $defaultField; if (is_array($where)) { $info = $this->model->where(['mark' => 1])->where($where)->select($field)->first(); } else { $info = $this->model->where(['mark' => 1])->where(['id' => (int)$where])->select($field)->first(); } $info = $info ? $info->toArray() : []; if ($info) { if (isset($info['avatar'])) { $info['avatar'] = $info['avatar'] ? get_image_url($info['avatar']) : ''; } if (isset($info['mobile'])) { $info['mobile_text'] = $info['mobile'] ? format_mobile($info['mobile']) : ''; } 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 == 1 && $zgVipExpired && $zgVipExpired > date('Y-m-d H:i:s')) { $isVip = 1; $isZgVip = 1; $vipExpired = $zgVipExpired; } 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 == 1 && $zsbVipExpired && $zsbVipExpired > date('Y-m-d H:i:s')) { $isVip = 1; $vipExpired = $zsbVipExpired > $vipExpired ? $zsbVipExpired : $vipExpired; } else { $isZsbVip = 0; } $isVideoVip = isset($info['is_video_vip']) ? $info['is_video_vip'] : 0; $videoVipExpired = isset($info['video_vip_expired']) && !empty($info['video_vip_expired']) ? $info['video_vip_expired'] : ''; if ($isVideoVip == 1 && $videoVipExpired && $videoVipExpired > date('Y-m-d H:i:s')) { $isVideoVip = 1; } else { $isVideoVip = 0; } $info['is_vip'] = $isVip; $info['is_zg_vip'] = $isZgVip; $info['is_zsb_vip'] = $isZsbVip; $info['vip_expired'] = $vipExpired; $info['zg_vip_expired'] = $zgVipExpired; $info['zg_vip_day'] = max(0, intval((strtotime($zgVipExpired) - time()) / 86400)); $info['zsb_vip_expired'] = $zsbVipExpired; $info['zsb_vip_day'] = max(0, intval((strtotime($zsbVipExpired) - time()) / 86400)); $info['is_video_vip'] = $isVideoVip; $info['video_vip_expired'] = $videoVipExpired; $info['video_vip_day'] = max(0, intval((strtotime($videoVipExpired) - time()) / 86400)); RedisService::set($cacheKey, $info, rand(5, 10)); } return $info; } /** * 生成普通参数二维码 * @param $str 参数 * @param bool $refresh 是否重新生成 * @return bool */ public function makeQrcode($str, $refresh = false, $size = 4, $margin = 2, $level = 2) { $basePath = base_path() . '/public'; $qrFile = '/images/qrcode/'; if (!is_dir($basePath . '/uploads' . $qrFile)) { @mkdir($basePath . '/uploads' . $qrFile, 0755, true); } $key = date('Ymd') . strtoupper(md5($str . '_' . $size . $margin . $level)); $qrFile = $qrFile . "C_{$key}.png"; $cacheKey = "caches:qrcodes:member_" . $key; if (RedisService::get($cacheKey) && is_file($basePath . '/uploads' . $qrFile) && !$refresh) { return $qrFile; } QRcode::png($str, $basePath . '/uploads' . $qrFile, $level, $size, $margin); if (!file_exists($basePath . '/uploads' . $qrFile)) { return false; } RedisService::set($cacheKey, ['str' => $str, 'qrcode' => $qrFile, 'date' => date('Y-m-d H:i:s')], 7 * 24 * 3600); return $qrFile; } /** * 修改头像 * @param $userId * @param $avatar * @return mixed */ public function saveAvatar($userId, $avatar) { $oldAvatar = $this->model->where(['id' => $userId])->value('avatar'); if ($this->model->where(['id' => $userId])->update(['avatar' => $avatar, 'update_time' => time()])) { if ($oldAvatar && file_exists(ATTACHMENT_PATH . $oldAvatar)) { @unlink(ATTACHMENT_PATH . $oldAvatar); } return true; } return false; } /** * 修改账号信息 * @param $userId * @param $params * @return bool */ public function modify($userId, $params) { $cacheLockKey = "caches:members:modify_{$userId}"; if (RedisService::get($cacheLockKey)) { $this->error = 1034; return false; } // 用户验证 RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(2, 3)); $info = $this->model->where(['id' => $userId, 'mark' => 1]) ->select(['id', 'password', 'status']) ->first(); $userPassword = isset($info['password']) ? $info['password'] : ''; if (!$info || $info['status'] != 1) { $this->error = 1029; RedisService::clear($cacheLockKey); return false; } // 密码校验 $data = ['update_time' => time()]; // 修改数据 $nickname = isset($params['nickname']) ? $params['nickname'] : ''; if (isset($params['nickname']) && $nickname) { $data['nickname'] = $nickname; } $mobile = isset($params['mobile']) ? $params['mobile'] : ''; if (isset($params['mobile']) && $mobile) { $data['mobile'] = $mobile; } $password = isset($params['password']) ? $params['password'] : ''; $newPassword = isset($params['new_password']) ? $params['new_password'] : ''; if (isset($params['password']) && $password) { if ($userPassword != get_password($password)) { $this->error = 1038; RedisService::clear($cacheLockKey); return false; } if (empty($newPassword)) { $this->error = 1039; RedisService::clear($cacheLockKey); return false; } $data['password'] = get_password($newPassword); } // 头像 $avatar = isset($params['avatar']) ? $params['avatar'] : ''; if (isset($params['avatar']) && $avatar) { $data['avatar'] = get_image_path($avatar); } if (!$this->model->where(['id' => $userId])->update($data)) { $this->error = 1014; RedisService::clear($cacheLockKey); return false; } $oldAvatar = isset($info['avatar']) ? $info['avatar'] : ''; if ($avatar && $oldAvatar && ($avatar != $oldAvatar) && file_exists(ATTACHMENT_PATH . $oldAvatar)) { @unlink(ATTACHMENT_PATH . $oldAvatar); } $this->error = 1013; RedisService::clear($cacheLockKey); return true; } /** * 设置入口类型 * @param $userId * @param $params * @return bool */ public function setEntry($userId, $params) { $cacheLockKey = "caches:members:entry_{$userId}"; if (RedisService::get($cacheLockKey)) { $this->error = 1034; return false; } $realname = isset($params['realname']) ? trim($params['realname']) : ''; $university = isset($params['university']) ? trim($params['university']) : ''; $entryType = isset($params['entry_type']) ? intval($params['entry_type']) : 0; // if(empty($realname)){ // $this->error = '请输入姓名'; // return false; // } // // if(empty($realname)){ // $this->error = '请输入毕业院校'; // return false; // } // // if($entryType<=0){ // $this->error = '请选择报考类型'; // return false; // } // 用户验证 RedisService::set($cacheLockKey.'_temp', ['user_id' => $userId, 'params' => $params], 3600); RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(2, 3)); $info = $this->model->where(['id' => $userId, 'mark' => 1]) ->select(['id', 'password', 'status']) ->first(); if (!$info || $info['status'] != 1) { $this->error = 1043; RedisService::clear($cacheLockKey); return false; } // 密码校验 $data = [ 'entry_type' => $entryType, 'need_paper' => isset($params['need_paper']) ? intval($params['need_paper']) : 0, 'realname' => $realname, 'university' => $university, 'update_time' => time() ]; if ($params['province'] && $params['city']) { $data['province'] = isset($params['province']) ? trim($params['province']) : ''; $data['city'] = isset($params['city']) ? trim($params['city']) : ''; $data['district'] = isset($params['district']) ? trim($params['district']) : ''; } if (!$this->model->where(['id' => $userId])->update($data)) { $this->error = 1020; RedisService::clear($cacheLockKey); return false; } $this->error = 1019; RedisService::clear($cacheLockKey); return true; } /** * 设置地址信息 * @param $userId * @param $params * @return bool */ public function setArea($userId, $params) { $cacheLockKey = "caches:members:area_{$userId}"; if (RedisService::get($cacheLockKey)) { $this->error = 1034; return false; } // 用户验证 RedisService::set($cacheLockKey.'_temp', ['user_id' => $userId, 'params' => $params], 3600); RedisService::set($cacheLockKey, ['user_id' => $userId, 'params' => $params], rand(2, 3)); $info = $this->model->where(['id' => $userId, 'mark' => 1]) ->select(['id', 'password', 'status']) ->first(); if (!$info || $info['status'] != 1) { $this->error = 1043; RedisService::clear($cacheLockKey); return false; } // 密码校验 $data = [ 'province' => isset($params['province']) ? trim($params['province']) : '', 'city' => isset($params['city']) ? trim($params['city']) : '', 'district' => isset($params['district']) ? trim($params['district']) : '', 'update_time' => time() ]; $this->model->where(['id' => $userId])->update($data); $this->error = 1019; RedisService::clear($cacheLockKey); return true; } /** * 获取VIP类别 * @param int $type * @return array|mixed */ public function getVipList($type = 1) { $cacheKey = "caches:members:vipList:{$type}"; $datas = RedisService::get($cacheKey); if ($datas) { return $datas; } $datas = VipModel::where(['type' => $type, 'status' => 1, 'mark' => 1]) ->select(['id', 'name', 'type', 'price', 'original_price', 'day', 'remark', 'status']) ->orderBy('id', 'asc') ->get(); $datas = $datas ? $datas->toArray() : []; if ($datas) { RedisService::set($cacheKey, $datas, rand(3600, 7200)); } return $datas; } /** * 购买VIP * @param $userId * @param $vipId * @return array|false */ public function vipBuy($userId, $params) { $vipId = isset($params['id']) ? $params['id'] : 0; // VIP $cId = isset($params['cid']) ? $params['cid'] : 0; // 课程ID $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', 'name', 'type', 'price', 'day', 'status']) ->first(); $price = isset($vipInfo['price']) ? moneyFormat($vipInfo['price'],1) : 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($vipId== 4){ // $this->error = '套餐价格:'.$price; // RedisService::clear($cacheKey . '_lock'); // return false; // } if ($price <= 0 || $day <= 0) { $this->error = '该VIP参数错误'; RedisService::clear($cacheKey . '_lock'); return false; } $showZsb = ConfigService::make()->getConfigByCode('show_zsb_entry', 0); if($vipType == 2 && !$showZsb){ $this->error = '该VIP套餐暂未开放~'; RedisService::clear($cacheKey . '_lock'); return false; } $info = $this->model->where(['id' => $userId, 'mark' => 1]) ->select(['id', 'openid', 'mobile', 'is_zg_vip', 'zg_vip_expired', 'is_zsb_vip', 'zsb_vip_expired', 'is_video_vip', 'video_vip_expired', 'status']) ->first(); $isZgVip = isset($info['is_zg_vip']) ? $info['is_zg_vip'] : 0; $isZsbVip = isset($info['is_zsb_vip']) ? $info['is_zsb_vip'] : 0; $isVideoVip = isset($info['is_video_vip']) ? $info['is_video_vip'] : 0; $zgVipExpired = isset($info['zg_vip_expired']) ? $info['zg_vip_expired'] : ''; $zsbVipExpired = isset($info['zsb_vip_expired']) ? $info['zsb_vip_expired'] : ''; $videoVipExpired = isset($info['video_vip_expired']) ? $info['video_vip_expired'] : ''; $openid = isset($info['openid']) ? $info['openid'] : ''; if (!$info || $info['status'] != 1) { $this->error = 1045; RedisService::clear($cacheKey . '_lock'); return false; } if (empty($openid)) { $this->error = '用户参数错误,请重新授权登录后尝试~'; RedisService::clear($cacheKey . '_lock'); return false; } // 验证是否 $goodsId = 0; $scene = 'vip'; $expiredTime = time(); if ($vipId == 5) { // 单节视频验证是否已付费过 if (VideoOrderModel::where(['goods_id' => $vipId, 'status' => 2, 'mark' => 1])->where('expired_at', '>', date('Y-m-d H:i:s'))->value('id')) { $this->error = '抱歉,您已购买过该节视频课,请刷新后尝试观看~'; return false; } // 视频数据 $goodsId = $cId; $scene = 'course'; $courseInfo = VideoCoursesModel::where(['id' => $goodsId, 'status' => 1, 'mark' => 1])->select(['id', 'fee', 'course_name', 'status'])->first(); $fee = isset($courseInfo['fee']) ? $courseInfo['fee'] : 0; if (empty($courseInfo)) { $this->error = '抱歉,您购买的课程已下架,请刷新后重试~'; return false; } if ($fee <= 0) { $this->error = '抱歉,您购买的课程为免费课程,请刷新后直接观看~'; return false; } } else { // VIP 验证 $goodsId = $vipId; $vipLimitOpen = ConfigService::make()->getConfigByCode('vip_limit_more', 0); 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'); $remark = $vipType == 3 ? "购买{$vipName}" : "购买{$vipName}VIP"; $order = [ 'order_no' => $orderNo, 'user_id' => $userId, 'goods_id' => $goodsId, 'total' => $price, 'expired_at' => date('Y-m-d H:i:s', $expiredTime + $day * 86400), 'create_time' => time(), 'remark' => $remark, 'status' => 1, 'mark' => 1 ]; DB::beginTransaction(); $model = $vipId == 5 ? new VideoOrderModel : new OrderModel; if (!$orderId = $model::insertGetId($order)) { $this->error = '创建VIP订单失败'; return false; } /* TODO 支付处理 */ $payOrder = [ 'type' => 1, 'order_no' => $orderNo, 'pay_money' => $price, 'body' => $remark, 'openid' => $openid ]; // 调起支付 $payment = PaymentService::make()->minPay($info, $payOrder, $scene); if (empty($payment)) { DB::rollBack(); RedisService::clear($cacheKey . '_lock'); $this->error = PaymentService::make()->getError(); return false; } // 用户操作记录 DB::commit(); $this->error = '创建VIP订单成功,请前往支付~'; RedisService::clear($cacheKey . '_lock'); RedisService::keyDel("caches:videos:list_by_group*"); RedisService::clear("caches:videos:info_{$userId}_{$cId}"); return [ 'order_id' => $orderId, 'payment' => $payment, 'total' => $payOrder['pay_money'], 'pay_type' => 10, ]; } }