user(); return $this->success($user->toArray()); } public function sendSms(Request $request) { $mobile = $request->input('mobile'); $code = mt_rand(1000, 9999); Cache::put("sms:" . $mobile, $code, 60 * 10); $data = ['mobile' => $mobile, 'TemplateParam' => ['code' => $code]]; $result = SmsFacade::send($data); if ($result->Code != "OK") { return $this->error('发送失败: ' . $result->Message); } return $this->success(); } public function login(Request $request) { $mobile = $request->input('mobile'); $code = $request->input('code'); $code_cache = Cache::get("sms:" . $mobile); if (!$code_cache && $code != 1234) { return $this->error('验证码已过期'); } if ($code != $code_cache && $code != 1234) { return $this->error('验证码错误'); } Cache::forget("sms:" . $mobile); $user = User::query()->where('mobile', $mobile)->first(); if (!$user) { $user = User::create([ 'mobile' => $mobile, 'name' => '金橡果用户', ]); } $token = $user->createToken($mobile); return $this->success(['token' => $token->plainTextToken]); } /** * 获取微信access_token */ public function wechat(Request $request) { $key = __METHOD__; if ($data = Cache::get($key)) { return $this->success($data); } $config = config('wechat.official_account.default'); $app = Factory::officialAccount($config); // 获取 access token 实例 $accessToken = $app->access_token; $token = $accessToken->getToken(); // token 数组 token['access_token'] 字符串 Cache::put($key, $token, 7200); return $this->success($token); } /** * 获取jssdk初始化配置 */ public function getJSSDK(Request $request) { $app = Factory::officialAccount(config('wechat.official_account.default')); $app->jssdk->setUrl($request->input('url')); $data = $app->jssdk->buildConfig(['scanQRCode'], false); return $this->success(json_decode($data)); } /** * 微信登录,共四步 * 第一步:跳到微信向用户要授权 */ public function wxsnsapi(Request $request) { $app = Factory::officialAccount(config('wechat.official_account.default')); // if (!Cache::has('callback_url')) { Cache::put('callback_url', $request->input('url'), 7200); // } $redirectUrl = $app->oauth->scopes(['snsapi_userinfo'])->redirect($request->url() . 'ok'); return \redirect($redirectUrl); } /** * 微信登录,共四步 * 第二步:授权完成获取用户信息,存入cache,跳回前端页面 * 这个页面被微信回调 * @param code 微信给的一次性凭证,用于换取用户信息 */ public function wxsnsapiok(Request $request) { $app = Factory::officialAccount(config('wechat.official_account.default')); $wxuser = $app->oauth->userFromCode($request->input('code')); $openid = $wxuser->getId(); // 用户openid $h5_url = Cache::get('callback_url') . "&openid=$openid"; if (Cache::has($openid)) { return \redirect($h5_url); } Cache::put($openid, [ 'unionid' => $wxuser->getRaw()['unionid'], 'nickname' => $wxuser->getNickname(), 'avatar' => $wxuser->getAvatar() ], 7200); return \redirect($h5_url); } /** * 微信登录,共四步 * 第三步:前端通过openid获取登录token,如果获取不到,前端需要弹出绑定手机号窗口引导用户绑定手机号 */ public function getWxLoginToken(Request $request) { $openid = $request->input('openid'); $user = User::query()->where('openid', $openid)->first(); if ($user) { $token = $user->createToken($user['mobile']); return $this->success(['token' => $token->plainTextToken]); // 存在用户直接返回token } if (!Cache::has($openid)) { return $this->error('请重新微信授权'); } return $this->success(['token' => null]); // 用户不存在返回null,前端引导绑定手机号 } /** * 微信登录,共四步 * 第四步:微信登录后,注册用户 * 前端微信登录后发现没有注册过,引导绑定手机号后的注册 */ public function wxRegister(Request $request) { $mobile = $request->input('mobile'); $code = $request->input('code'); $openid = $request->input('openid'); $code_cache = Cache::get("sms:" . $mobile); if (!$code_cache && $code != 1234) { return $this->error('验证码已过期'); } if ($code != $code_cache && $code != 1234) { return $this->error('验证码错误'); } Cache::forget("sms:" . $mobile); $data = Cache::pull($openid); if (!$data) { return $this->error('登录缓存过期,请重新登录'); } $user = User::query()->where('mobile', $mobile)->first(); if (!$user) { $user = User::create([ 'mobile' => $mobile, 'unionid' => $data['unionid'], 'name' => $data['nickname'], 'avatar' => $data['avatar'], 'openid' => $openid ]); } else { $user->openid = $openid; $user->save(); } $token = $user->createToken($mobile); return $this->success(['token' => $token->plainTextToken]); } /** * 小程序登录 */ public function wxLogin(Request $request) { $unionid = $request->input('unionid'); $user = User::query()->where('unionid', $unionid)->first(); $tokenstr = null; if ($user) { $token = $user->createToken($user->mobile); $tokenstr = $token->plainTextToken; } return $this->success(['user' => $user, 'token' => $tokenstr]); } /** * 小程序注册与绑定用户 */ public function wxLoginRegister(Request $request) { $mobile = $request->input('mobile'); $unionid = $request->input('unionid'); $openid = $request->input('openid'); if (!$mobile || !$unionid) { return $this->error('参数错误'); } $user = User::query()->where('mobile', $mobile)->first(); if (!$user) { $user = User::create([ 'mobile' => $mobile, 'name' => '金橡果用户', 'miniprogram_openid' => $openid, 'unionid' => $unionid ]); } else { $user->unionid = $unionid; // 绑定unionid $user->save(); } $token = $user->createToken($mobile); return $this->success(['token' => $token->plainTextToken]); } /** * 获取小程序分享二维码 */ public function getMiniProgramQrcode(Request $request, Response $response) { $user = $request->user(); $path = 'miprogramusercode/' . $user->code . '.jpg'; if (Storage::disk('aliyun')->exists($path)) return $this->success(trim(config('filesystems.disks.aliyun.domain'), '/') . '/' . $path); $app = Factory::miniProgram(config('wechat.mini_program.default')); $qrcode_response = $app->app_code->getUnlimit(($user->code), [ 'page' => 'pages/game/game', 'width' => 150, 'check_path' => false ]); if ($qrcode_response instanceof \EasyWeChat\Kernel\Http\StreamResponse) { $imageData = $qrcode_response->getBodyContents(); $result = Storage::disk('aliyun')->put($path, $imageData); if ($result) { return $this->success(trim(config('filesystems.disks.aliyun.domain'), '/') . '/' . $path); } else { return $this->error('获取二维码失败'); } } else { return $this->error('获取二维码失败'); } } public function coinList(Request $request) { $userId = $request->user()->id; $list = UserCoin::query() ->leftJoin('coin', 'coin.id', '=', 'user_coin.coin_id') ->where('user_coin.user_id', $userId) ->where('coin.is_true', Coin::IS_TRUE_YES) ->selectRaw('coin.*, user_coin.created_at as date, pay_status, pay_time, apply_status, apply_time') ->get()->toArray(); return $this->success($list); } public function coinSave(Request $request) { $userId = $request->user()->id; $coinId = $request->input('coin_id'); $content = $request->input('content', ''); if (!$coinId) { return $this->error('参数错误'); } $coin = Coin::query()->find($coinId); if (!$coin) { return $this->error('硬币不存在'); } if ($coin->type == Coin::TYPE_JIN) { return $this->error('不支持解锁该硬币'); } if ($coin->is_unlock == Coin::IS_UNLOCK_YES) { return $this->error('硬币已被领取'); } try { DB::beginTransaction(); UserCoin::query()->create([ 'user_id' => $userId, 'coin_id' => $coinId, 'content' => $content ]); $coin->is_unlock = Coin::IS_UNLOCK_YES; $coin->save(); DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::error(__METHOD__, $e->getTrace()); } return $this->success($coin->toArray()); } public function coinPay(Request $request) { $userId = $request->user()->id; $coinId = $request->input('coin_id'); if (!$coinId) { return $this->error('参数错误'); } $coin = Coin::query()->find($coinId); if (!$coin) { return $this->error('硬币不存在'); } $userCoin = UserCoin::query()->where('user_id', $userId)->where('coin_id', $coinId)->first(); if (!$userCoin) { return $this->error('未获得该硬币'); } $userCoin->apply_status = UserCoin::APPLY_STATUS_YES; $userCoin->apply_time = date('Y-m-d H:i:s'); $userCoin->save(); return $this->success(); } public function goldCoinSave(Request $request) { $userId = $request->user()->id; $log = UserCoinLog::query()->where('user_id', $userId)->count(); $user = User::query()->find($userId); if ($log && $user->amount < Coin::NUMBER_AMOUNT) { return $this->error('余额不足'); } //用户已经解锁金币 $coinIds = UserCoin::query()->where('user_id', $userId)->get()->pluck('coin_id')->toArray(); $coins = Coin::query() ->where('type', Coin::TYPE_JIN) ->where('status', Coin::STATUS_OPEN) ->where(function ($query) use ($coinIds) { if ($coinIds) { $query->whereNotIn('id', $coinIds); } })->get(); if (!$count = $coins->count()) { return $this->error('金币已全部解锁'); } $number = isset(Coin::NUMBER[$log + 1]) ? ceil($count * (Coin::NUMBER[$log + 1] / 100)) : 1; $coinsUnlock = $coins->where('is_true', Coin::IS_TRUE_NO)->count() ? $coins->where('is_true', Coin::IS_TRUE_NO)->random($number) : $coins; if ($coinsUnlock->count() < $number) { $coinsUnlock = $coins; } $insert = []; foreach ($coinsUnlock as $value) { $insert[] = [ 'user_id' => $userId, 'coin_id' => $value->id, ]; } UserCoin::query()->insert($insert); UserCoinLog::query()->create([ 'user_id' => $userId, 'coin_ids' => $coinsUnlock->pluck('id')->toJson(), 'amount' => $log ? Coin::NUMBER_AMOUNT : 0, ]); $user->amount = $user->amount - ($log ? Coin::NUMBER_AMOUNT : 0); $user->save(); return $this->success(); } public function coinClueSave(Request $request) { $userId = $request->user()->id; $id = $request->input('id'); if (!$id) { return $this->error('参数错误'); } $coinClue = CoinClue::query()->find($id); if (!$coinClue) { return $this->error('踪迹线索不存在'); } $user = User::query()->find($userId); if ($user->amount < $coinClue->amount) { return $this->error('余额不足'); } try { DB::beginTransaction(); UserCoinClue::query()->create([ 'user_id' => $userId, 'coin_id' => $coinClue->coin_id, 'coin_clue_id' => $coinClue->id, 'amount' => $coinClue->amount, ]); $user->amount = $user->amount - $coinClue->amount; $user->save(); DB::commit(); } catch (\Exception $e) { DB::rollBack(); Log::error(__METHOD__, $e->getTrace()); } return $this->success($coinClue->toArray()); } public function upload(Request $request) { $result = Storage::disk('aliyun')->putFile('files', $request->file('file')); return $this->success([trim(config('filesystems.disks.aliyun.domain'), '/') . '/' . $result]); } public function code(Request $request) { $user = User::query()->find($request->user()->id); if (!$user->code) { $user->code = $this->genCode(); $user->save(); } $number = UserInvite::query()->where('from_user_id', $user->id)->count(); return $this->success(['code' => $user->code, 'number' => $number]); } public function codeSave(Request $request) { $code = $request->input('code', ''); if (!$code) { return $this->error('参数错误'); } $user = User::query()->where('code', $code)->first(); if (!$user || $user->id == $request->user()->id) { return $this->error('邀请码错误'); } $log = UserInvite::query()->where('from_user_id', $user->id)->where('user_id', $request->user()->id)->first(); if ($log) { return $this->success(); } UserInvite::query()->create([ 'from_user_id' => $user->id, 'user_id' => $request->user()->id, ]); return $this->success(); } private function genCode() { $chars = str_shuffle("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); $res = ""; while (true) { for ($i = 0; $i < 6; $i++) { $res .= $chars[mt_rand(0, strlen($chars) - 1)]; } $user = User::query()->where('code', $res)->count(); if (!$user) { break; } } return $res; } /** * 保存用户昵称 */ public function saveNickname(Request $request) { $nickname = $request->input('nickname'); if (!$nickname) return $this->error('参数错误'); $user = $request->user(); if ($nickname === $user->name) return $this->error('无需修改'); $key = $user->id . '_editName'; if (Cache::has($key)) { return $this->error('三天内不可多次修改'); } Cache::put($key, true, 259200); // 三天内不可重复修改 $user->name = $nickname; $user->save(); return $this->success([], '昵称修改成功'); } /** * 小程序更新头像 */ public function saveAvatar(Request $request) { $user = $request->user(); $user->avatar = $request->input('avatar'); // 绑定unionid $user->save(); return $this->success(); } }