jxg/jinxiangguo-master/app/Http/Controllers/UserController.php

533 lines
17 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers;
use App\Models\Coin;
use App\Models\CoinClue;
use App\Models\User;
use App\Models\UserCoin;
use App\Models\UserCoinClue;
use App\Models\UserCoinLog;
use App\Models\UserInvite;
use EasyWeChat\Factory;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Lysice\Sms\Facade\SmsFacade;
use Illuminate\Http\Response;
class UserController extends Controller
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function index(Request $request)
{
$user = $request->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();
}
}