This commit is contained in:
2023-03-08 09:16:04 +08:00
commit e78454540f
1318 changed files with 210569 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
<?php
namespace Modules\User\Http\Controllers\Api\Account;
use App\Api\Controllers\Controller;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\User\Http\Resources\Account\UserAccountLogCollection;
class LogController extends Controller
{
/**
* Notes:水滴
*
* @Author: 玄尘
* @Date: 2022/8/18 13:57
*/
public function score(): \Illuminate\Http\JsonResponse
{
$user = Api::user();
$logs = $user->account->logs()
->where('type', 'score')
->paginate();
$data = [
'score' => $user->account->score,
'logs' => new UserAccountLogCollection($logs)
];
return $this->success($data);
}
/**
* Notes:现金账户
*
* @Author: 玄尘
* @Date: 2022/8/19 8:37
*/
public function balance(): \Illuminate\Http\JsonResponse
{
$user = Api::user();
$logs = $user->account->logs()->where('type', 'balance')->paginate();
$yesterday = $user->account->logs()
->whereDate('created_at', now()->subDay()->toDateTime())
->where('type', 'balance')
->where('amount', '>', 0)
->sum('amount') ?? 0;
$withdraw = $user->withdraws()->sum('amount') ?? 0;
$data = [
'account' => [
'balance' => floatval($user->account->balance),
'yesterday' => floatval($yesterday),
'withdraw' => floatval($withdraw),
],
'logs' => new UserAccountLogCollection($logs)
];
return $this->success($data);
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Modules\User\Http\Controllers\Api\Auth;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Jason\Api\Api;
use Modules\User\Events\UserLoginSuccess;
use Modules\User\Http\Requests\LoginRequest;
use Modules\User\Models\User;
class LoginController extends Controller
{
/**
* Notes : 用户名密码登录
*
* @Date : 2021/3/11 5:03 下午
* @Author : <Jason.C>
* @param LoginRequest $request
* @return JsonResponse
*/
public function index(LoginRequest $request): JsonResponse
{
$credentials = [
'username' => $request->username,
'password' => $request->password,
];
$token = Api::attempt($credentials);
if ($token) {
$user = User::where('username', $request->username)->first();
event(new UserLoginSuccess($user, $request, '账号密码'));
return $this->success([
'access_token' => $token,
'token_type' => 'Bearer',
]);
} else {
return $this->failed('用户名或密码错误');
}
}
/**
* Notes : 退出登录,撤销所有令牌,这个需要配合 api:^5.0 使用
*
* @Date : 2021/9/22 11:07 上午
* @Author : <Jason.C>
* @return JsonResponse
*/
public function logout(): JsonResponse
{
$user = Api::user();
if ($user) {
$user->tokens()->delete();
}
return $this->success('');
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Modules\User\Http\Controllers\Api\Auth;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Jason\Api\Api;
use Modules\User\Events\UserLoginSuccess;
use Modules\User\Http\Requests\RegisterRequest;
use Modules\User\Models\User;
class RegisterController extends Controller
{
/**
* Notes : 注册
*
* @Date : 2021/3/14 1:24 下午
* @Author : <Jason.C>
* @param RegisterRequest $request
* @return JsonResponse
*/
public function index(RegisterRequest $request): JsonResponse
{
$username = $request->username;
$password = $request->password;
$user = User::create([
'username' => $username,
'password' => $password,
]);
$token = Api::login($user);
event(new UserLoginSuccess($user, $request, '用户注册'));
return $this->success([
'access_token' => $token,
'token_type' => 'Bearer',
]);
}
}

View File

@@ -0,0 +1,114 @@
<?php
namespace Modules\User\Http\Controllers\Api\Auth;
use App\Api\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Jason\Api\Api;
use Modules\User\Events\UserLoginSuccess;
use Modules\User\Facades\Sms;
use Modules\User\Http\Requests\LoginSmsRequest;
use Modules\User\Http\Requests\SmsRequest;
use Modules\User\Models\User;
class SmsController extends Controller
{
/**
* Notes : 获取登录短信验证码
*
* @Date : 2021/5/26 4:59 下午
* @Author : <Jason.C>
* @param SmsRequest $request
* @return JsonResponse
*/
public function send(SmsRequest $request): JsonResponse
{
$mobile = $request->mobileNo;
try {
Sms::sendVerificationCode($mobile);
$isExists = User::where('username', $mobile)->exists();
return $this->success([
'new' => ! $isExists,
'message' => '短信发送成功',
]);
} catch (Exception $exception) {
return $this->failed($exception->getException('aliyun')->getMessage());
}
}
/**
* Notes : 短信验证码登录
*
* @Date : 2021/7/20 10:15 上午
* @Author : <Jason.C>
* @param LoginSmsRequest $request
* @return JsonResponse
*/
public function login(LoginSmsRequest $request): JsonResponse
{
$mobileNo = $request->mobileNo;
$code = $request->code;
$invite_code = $request->invite ?? '';
$channel_code = $request->channel ?? '';//渠道
$channel = '';
if ($channel_code) {
$channel = UserChannel::query()
->where('code', $channel_code)
->first();
}
$parent = 0;
if ($invite_code) {
$invite = Hashids::connection('code')->decode($invite_code);
if (empty($invite)) {
return $this->failed('邀请码不正确');
}
$parent = $invite[0];
$parentUser = User::find($parent);
//普通用户无法分享
if ($parentUser && $parentUser->identityFirst()->id == 1) {
$parent = 0;
}
}
$check = Sms::checkCode($mobileNo, $code);
if ($check == false) {
return $this->failed('验证码不正确', 422);
}
$user = User::firstOrCreate([
'username' => $mobileNo,
], [
'parent_id' => $parent,
'password' => 111111,
]);
$is_new = $user->wasRecentlyCreated;
$message = '';
if ($is_new) {
if ($user->parent && $parent && $user->parent->id != $parent) {
$message = "您已与用户{$user->parent->info->nickname}绑定隶属关系,此次邀请码无效";
}
}
$token = Api::login($user);
event(new UserLoginSuccess($user, $request, '手机验证码'));
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
'message' => $message,
'is_new' => $is_new,
]);
}
}

View File

@@ -0,0 +1,154 @@
<?php
namespace Modules\User\Http\Controllers\Api\Auth;
use App\Api\Controllers\Controller;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Exceptions\RuntimeException;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class WechatController extends Controller
{
/**
* Notes: 获取授权的跳转地址
*
* @Author: 玄尘
* @Date : 2021/6/25 13:21
* @param Request $request
* @return mixed
*/
public function getAuthUrl(Request $request)
{
$app = app('wechat.official_account');
$pages = $request->url ?? '';
$scopes = $request->scopes ?? ['snsapi_userinfo'];
$web_url = config('user.web.base');
$redirect = $web_url.$pages;
if (! is_array($scopes)) {
$scopes = [$scopes];
}
$response = $app->oauth->scopes($scopes)->redirect($redirect);
return $this->success($response);
}
/**
* Notes: 获取jssdk
*
* @Author: 玄尘
* @Date : 2021/7/1 11:08
* @param Request $request
* @return JsonResponse
*/
public function getJsSdk(Request $request)
{
$url = $request->url;
$jsApiList = $request->jsApiList ?? [];
$openTagList = $request->openTagList ?? [];
$app = app('wechat.official_account');
if ($url) {
$app->jssdk->setUrl($url);
}
if (! is_array($jsApiList)) {
$jsApiList = [$jsApiList];
}
if (! is_array($openTagList)) {
$openTagList = [$openTagList];
}
return $this->success($app->jssdk->buildConfig($jsApiList, false, false, true, $openTagList));
}
/**
* Notes: 微信分享
*
* @Author: 玄尘
* @Date : 2021/10/26 16:52
* @param Request $request
* @return JsonResponse|mixed
* @throws InvalidArgumentException
* @throws InvalidConfigException
* @throws RuntimeException
* @throws GuzzleException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function officialShare(Request $request)
{
$url = $request->url ?? '';
if (empty($url)) {
return $this->failed('地址必须传');
}
$app = app('wechat.official_account');
$apis = [
'updateAppMessageShareData',
'updateTimelineShareData',
// 'showOptionMenu',
// 'showMenuItems',
'showAllNonBaseMenuItem',
];
$app->jssdk->setUrl($url);
$cog = $app->jssdk->buildConfig($apis);
return $this->success($cog);
}
/**
* Notes: 获取小程序openid
*
* @Author: 玄尘
* @Date: 2022/9/26 14:17
* @return mixed|void
*/
public function getMiniOpenid(Request $request)
{
$validator = \Validator::make($request->all(), [
'code' => 'required',
], [
'code.required' => '缺少参数code',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first());
}
$weChat = app('wechat.mini_program');
$session = $weChat->auth->session($request->code);
if (isset($session->errcode)) {
return $this->failed($session->errmsg);
}
return $this->success($session->openid);
}
/**
* Notes: 获取公众号openid
*
* @Author: 玄尘
* @Date: 2022/9/26 14:21
*/
public function getOfficialOpenid()
{
try {
$weUser = $this->getUserFromCode();
return $weUser->getId();
} catch (\Exception $exception) {
return $this->failed($exception->getMessage());
}
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Modules\User\Http\Controllers\Api\Certification;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Jason\Api\Api;
use Modules\User\Http\Requests\CertificationRequest;
use Modules\User\Http\Resources\UserCertificationResource;
use Modules\User\Models\UserCertification;
use Modules\User\Models\UserCertificationConfig;
class IndexController extends Controller
{
public function index()
{
$user = Api::user();
if (! $user->certification) {
return $this->failed('暂无认证记录');
}
return $this->success(new UserCertificationResource($user->certification));
}
/**
* Notes : 判定认证与秘钥
*
* @Date : 2021/5/17 16:52
* @Author : Mr.wang
* @return JsonResponse
*/
public function certified(): JsonResponse
{
$user = Api::user();
if (! $user) {
return $this->success(false);
}
return $this->success((bool) $user->certification);
}
/**
* Notes : 保存认证信息
*
* @Date : 2021/7/20 10:24 上午
* @Author : <Jason.C>
* @param CertificationRequest $request
* @return mixed
*/
public function store(CertificationRequest $request)
{
$user = Api::user();
if ($user->certification) {
return $this->failed('用户已存在认证信息');
}
$keys = [
'name' => $request->name,
'idcard' => $request->id_card,
'front_card' => $request->front_card ?? '',
'back_card' => $request->back_card ?? '',
];
$config = new UserCertificationConfig();
$data = $config->autoVerified($keys);
if ($data['code'] == 1) {
$verified = 1;
} else {
return $this->failed($data['message']);
}
$result = UserCertification::updateOrCreate([
'user_id' => $user->id,
], [
'name' => $request->name,
'id_card' => $request->id_card,
'front_card' => $request->front_card ?? '',
'back_card' => $request->back_card ?? '',
'verified' => $verified,
]);
if ($result) {
$user->info()->update([
'nickname' => $request->name,
]);
return $this->success('操作成功');
} else {
return $this->failed('操作失败');
}
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace Modules\User\Http\Controllers\Api\Favorite;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\Cms\Http\Resources\CategoryCollection;
use Modules\Cms\Models\Article;
use Modules\Cms\Models\Category;
use Modules\User\Http\Resources\Favorite\FavoriteCollection;
class IndexController extends Controller
{
/**
* Notes: 我的收藏
*
* @Author: 玄尘
* @Date: 2022/10/11 11:12
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$user = Api::user();
$category_id = $request->category_id ?? 0;
$favorteArticles = $user->favorites()
->when($category_id, function ($q) use ($category_id) {
$q->whereHasMorph('favoriteable', [Article::class], function ($query) use ($category_id) {
$query->whereHas('categories', function ($q) use ($category_id) {
$q->where('cms_categories.id', $category_id);
});
});
})
->paginate();
$data = [
'categories' => new CategoryCollection(Category::query()->get()),
'favorites' => new FavoriteCollection($favorteArticles),
];
return $this->success($data);
}
}

View File

@@ -0,0 +1,409 @@
<?php
namespace Modules\User\Http\Controllers\Api\Identity;
use App\Api\Controllers\Controller;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\JsonResponse;
use Jason\Api\Api;
use Modules\User\Http\Resources\IdentityMiddleResource;
use Modules\User\Http\Resources\UserIdentityResource;
use Modules\User\Models\Identity;
use Modules\User\Models\Order;
class IndexController extends Controller
{
public function index(): JsonResponse
{
$type = $request->type ?? '';
$user = Api::user();
$list = Identity::where('order', '>', 1)->where('can_buy', 1)->get();
$data = [
'user' => [
'username' => $user->username,
'nickname' => $user->info->nickname,
'avatar' => $user->info->avatar,
'identity' => $user->identities->count()
? new IdentityMiddleResource($user->identityMiddle()->first())
: '',
],
'identities' => UserIdentityResource::collection($list),
];
return $this->success($data);
}
/**
* Notes: 获取可开通的身份
*
* @Author: 玄尘
* @Date : 2021/6/4 9:37
* @param Identity $identity
* @return JsonResponse
*/
public function create(Identity $identity): JsonResponse
{
$user = Api::user();
$ended_at = '';
//可开通的身份ids
$ids = Identity::where('can_buy', 1)->pluck('id')->toArray();
$identity_middles = $user->identityMiddle;
//是否可以前台开通
if (in_array($identity->id, $ids)) {
//有有效期
if ($identity->years) {
//已经开通的身份ids
$identity_ids = $identity_middles->pluck('identity_id')->toArray();
//是否已经开通了此身份
if (in_array($identity->id, $identity_ids)) {
$ended_at = $identity_middles->where('identity_id', $identity->id)
->first()->ended_at ?? now()->format('Y-m-d H:i:s');
$ended_at = Carbon::parse($ended_at)->addMonths($identity->years)->format('Y/m/d');
} else {
$ended_at = now()->addMonths($identity->years)->format('Y/m/d');
}
} else {
$ended_at = '永久';
}
}
// $price = $identity->getCondition('price', '0');
// if ($identity->job == Identity::JOB_JK) {
// $coupon =
// }
$price = $identity->getCondition('price', '0');
$cost = $identity->getCondition('cost', '0');
if (! $cost) {
$cost = $price;
}
$coupon_price = 0;
if ($identity->job == Identity::JOB_JK) {
$coupons = $this->getCreateOrderCoupon($user, $identity, 0);
if ($coupons->isNotEmpty()) {
$user_coupon = $coupons->first();
$coupon_price = $user_coupon->price;
if ($user_coupon->coupon->type == Coupon::TYPE_REDUCTION) {
$price = $price > $user_coupon->price ? bcsub($price, $coupon_price, 2) : 0;
}
}
}
$data = [
'identity' => [
'identity_id' => $identity->id,
'name' => $identity->name,
'cover' => $identity->cover_url,
'description' => $ended_at ? '有效期至'.$ended_at : $identity->description,
'coupon_price' => $coupon_price,
'cost' => $cost,
'price' => $price,
'can_buy' => (bool) $identity->can_buy,
'ended_at' => $ended_at,
'service' => config('user.experience.service'),
'protocol_url' => (string) $identity->protocol_url,//协议地址
],
];
return $this->success($data);
}
/**
* Notes: 开通会员
*
* @Author: 玄尘
* @Date : 2021/6/4 10:02
* @param Identity $identity
* @param Request $request
* @return JsonResponse
*/
public function store(Identity $identity, Request $request): JsonResponse
{
$user = Api::user();
$price = $request->price ?? 0;
if ($identity->job != Identity::JOB_TY) {
$validator = Validator::make($request->all(), [
'name' => 'required',
// 'card_no' => 'required|numeric',
'cover' => 'required',
'price' => 'required',
], [
'name.required' => '缺少姓名',
'card_no.required' => '缺少银行卡号',
'card_no.numeric' => '银行卡号只能是数字',
'cover.required' => '缺少打款凭证',
'price.required' => '缺少打款金额',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first());
}
// if ($identity->job == Identity::JOB_NK && ! $user->parent) {
// return $this->failed('没有推荐人不可开通年卡会员');
// }
} else {
$total = $identity->users()->count();
if ($total >= 100) {
return $this->failed('体验官最多可开通100人');
}
$end_at = $identity->end_at;
if ($end_at) {
$end_at = Carbon::parse($end_at)->endOfDay();
if (now()->gt($end_at)) {
return $this->failed('体验官活动已过期');
}
}
$tencentMap = app('xuanchen.tencent.map');
$res = $tencentMap->api()->ip(request()->ip())->toArray();
if (! in_array($res['ad_info']['city'], ['深圳', '深圳市'])) {
// return $this->failed('体验官活动只限于深圳用户参加');
}
}
if (! $identity->can_buy) {
return $this->failed('当前身份不可开通,请联系客服开通。');
}
$type = Order::TYPE_OPEN;
$year = $request->year ?? 1;
//是否可以开通多身份 false不可
if (config('identity.can_has_many_identity') == false) {
if ($user->identities->isNotEmpty()) {
$this_identity = $user->identities->first();
if ($this_identity->order > $identity->order) {
return $this->failed('不可降级开通');
}
if ($this_identity->id == $identity->id) {
$type = Order::TYPE_RENEW;
}
}
}
$hasOne = Order::query()
->byUser($user)
->where('identity_id', $identity->id)
->where('state', Order::STATE_INIT)
->exists();
if ($hasOne) {
return $this->failed('您已经提交过了,请等待审核');
}
if (! $price) {
$price = $identity->getCondition('price', '0');
$price = $price * $year;
}
$data = [
'user_id' => $user->id,
'identity_id' => $identity->id,
'year' => $year,
'type' => $type,
'stock' => $identity->stock,
'name' => $request->name,
'card_no' => $request->card_no,
'cover' => $request->cover,
'state' => Order::STATE_INIT,
'price' => $price,
];
$order = Order::create($data);
if ($order) {
if ($coupon_price > 0) {
$order->useCouponLog()->create([
'sourceable_type' => get_class($order),
'sourceable_id' => $order->id,
'coupon_grant_id' => $user_coupon->id,
]);
}
if ($identity->job == Identity::JOB_TY) {
return $this->success([
'order_id' => $order->id,
'openids' => $user->wechat->getOpenids()
]);
} else {
return $this->success('提交成功,请等待后台审核');
}
} else {
return $this->failed('创建订单失败,请稍后再试');
}
}
/**
* Notes: 微信支付
*
* @Author: 玄尘
* @Date : 2021/6/7 14:42
* @param Order $order
* @return JsonResponse
* @throws Exception
*/
public function wechat(Order $order, Request $request): JsonResponse
{
$channel = $request->channel ?? 'mp';
$openid = $request->openid ?? '';
$user = Api::user();
if (! $order->canPay()) {
return $this->failed('支付失败,订单不可支付');
}
if ($order->user()->isNot($user)) {
return $this->failed('支付失败,您没有权限支付');
}
$extends = [
'notify_url' => route('api.payment.notify.wechat'),
];
if (! $openid) {
$openid = $user->wechat->getUserOpenid($channel);
}
$payment = $order->createWechatPayment($user, $order->price, $channel);
if (! $openid) {
return $this->failed('支付失败缺少openid');
}
if (config('payment.version', 2) == 2) {
$extends = array_merge($extends, [
'openid' => $openid,
]);
} else {
$extends = array_merge($extends, [
'payer' => [
'openid' => $openid,
],
]);
}
$notify = $payment->getPaymentParams('商品下单', $extends);
if (config('payment.version', 2) == 2) {
$notify = $notify->getContent();
} else {
$notify = $notify->toJson();
}
$data = [
'wechat' => $notify,
'identity' => [
'identity_id' => $order->identity_id,
'name' => $order->identity->name,
],
];
return $this->success($data);
}
/**
* Notes: 支付宝支付
*
* @Author: 玄尘
* @Date : 2021/6/7 14:42
* @param Order $order
* @return JsonResponse
* @throws Exception
*/
public function alipay(Order $order): JsonResponse
{
$user = Api::user();
if (! $order->canPay()) {
return $this->failed('支付失败,订单不可支付');
}
if ($order->user()->isNot($user)) {
return $this->failed('支付失败,您没有权限支付');
}
$payment = $order->createAlipayPayment($user, $order->price, 'app');
$notify = $payment->getPaymentParams('商品下单', [
'notify_url' => route('api.payment.notify.alipay'),
]);
$data = [
'wechat' => $notify->getContent(),
'identity' => [
'identity_id' => $order->identity_id,
'name' => $order->identity->name,
],
];
return $this->success($data);
}
/**
* Notes: 根据不同身份判定用户折扣
*
* @Author: Mr.wang
* @Date : 2021/6/10 11:00
* @return JsonResponse
*/
public function rule(): JsonResponse
{
$user = Api::user();
$defaultIdentity = Identity::orderBy('order', 'desc')->first();
$defaultDiscount = $defaultIdentity->getRule('buy_discount', 0);
if (! $user) {
return $this->success([
'message' => '开通节点 最高享'.($defaultDiscount / 10).'折优惠',
'not_vip' => true,
'discount' => $defaultDiscount / 100,
]);
}
$identity = $user->identities->first();
$discount = $identity->getRule('buy_discount', 0);
if ($discount >= 100) {
$message = '开通节点 最高享'.($defaultDiscount / 10).'折优惠';
} else {
$message = $identity->name.'尊享'.($discount / 10).'折优惠';
}
return $this->success([
'message' => $message,
'not_vip' => (bool) $identity->default,
'discount' => $discount / 100,
]);
}
/**
* Notes: 获取身份权益
*
* @Author: 玄尘
* @Date : 2021/6/8 8:39
* @param Identity $identity
* @return JsonResponse
*/
public function show(Identity $identity): JsonResponse
{
return $this->success(new UserIdentityResource($identity));
}
}

View File

@@ -0,0 +1,200 @@
<?php
namespace Modules\User\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Jason\Api\Api;
use Modules\User\Http\Resources\UserInfoBaseResource;
use Modules\User\Http\Resources\UserInfoResource;
use Vinkla\Hashids\Facades\Hashids;
use Illuminate\Support\Facades\Config;
class IndexController extends Controller
{
/**
* Notes : 用户主页信息
*
* @Date : 2021/3/11 5:45 下午
* @Author : <Jason.C>
* @return JsonResponse
*/
public function index(): JsonResponse
{
$user = Api::user();
return $this->success(new UserInfoResource($user));
}
/**
* Notes : 用户信息
*
* @Date : 2021/6/16 2:14 下午
* @Author : Mr.wang
* @return JsonResponse
*/
public function info(): JsonResponse
{
$user = Api::user();
return $this->success(new UserInfoBaseResource($user));
}
/**
* Notes : 用户基础信息修改
*
* @Date : 2021/5/27 14:02
* @Author : Mr.wang
* @param Request $request
* @param string $key
* @return JsonResponse
*/
public function update(Request $request, string $key): JsonResponse
{
$user = Api::user();
switch ($key) {
case 'nickname':
$validator = Validator::make($request->all(), [
'value' => 'required',
], [
'value.required' => '用户昵称必须填写',
]);
break;
case 'avatar':
$validator = Validator::make($request->all(), [
'value' => ['required', 'regex:/[^\s]*\.(jpg|jpeg|gif|png)$/i'],
], [
'value.required' => '用户头像必须上传',
'value.regex' => '头像地址格式不正确',
]);
break;
default:
return $this->failed('路径不合法');
}
if ($validator->fails()) {
return $this->failed($validator->errors()->first(), 422);
}
$result = $user->info()->update([$key => $request->value]);
if ($result) {
return $this->success('操作成功');
} else {
return $this->failed('失败');
}
}
/**
* Notes : 用户邀请码接口
*
* @Date : 2021/5/27 14:15
* @Author : Mr.wang
* @return JsonResponse
*/
public function invite(): JsonResponse
{
$user = Api::user();
if ($user->identityFirst()->id > 1) {
$invite = Hashids::connection('code')->encode($user->id);
} else {
$invite = '';
}
$url = Config::get('user.invite_code.url').'?invite='.$invite;
$code = 'data:image/png;base64,'.base64_encode(QrCode::format('png')
->size(100)
->margin(3)
->generate($url));
return $this->success([
'code' => $code,
'invite' => $invite,
'children' => $user->children()->count(),
'user_info' => new UserInfoBaseResource($user),
]);
}
/**
* Notes : 绑定邀请码
*
* @Date : 2021/7/20 10:30 上午
* @Author : wang
* @param Request $request
* @return JsonResponse
*/
public function bind(Request $request): JsonResponse
{
$invite = $request->invite ?? '';
if (empty($invite)) {
return $this->failed('邀请码不能为空');
}
$invite = Hashids::connection('code')->decode($invite);
if (empty($invite)) {
return $this->failed('邀请码不正确');
}
$user = Api::user();
if ($user->parent) {
return $this->failed('用户已有上级,不能重复绑定');
}
if ($user->updateParent($invite[0])) {
return $this->success('绑定成功');
} else {
return $this->failed('绑定失败');
}
}
/**
* Notes: 获取小程序码
*
* @Author: 玄尘
* @Date: 2022/9/28 13:13
*/
public function getMiniCode(Request $request)
{
$user = Api::user();
$size = $request->size ?? '300';
$url = $request->url ?? 'pages/mall/index/index';
$name = "share_user_mini_{$user->id}.png";
$path = "share/".$name;
$file_path = storage_path("app/public/".$path);
$data = [
'username' => $user->username,
'nickname' => $user->info->nickname ?? '',
'avatar' => $user->info->avatar ?? '',
];
$invite = Hashids::connection('code')->encode($user->id);
$parse = parse_url($url);
$arr['invite'] = $invite;
$str = $parse['path'].'?'.http_build_query($arr);
if (! file_exists($file_path)) {
$app = app('wechat.mini_program');
$response = $app->app_code
->get($str, [
'width' => $size,
'is_hyaline' => true,
]);
if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
$response->saveAs(storage_path("app/public/share"), $name);
}
}
$data = array_merge($data, [
'qrcode' => Storage::url($path),
]);
return $this->success($data);
}
}

View File

@@ -0,0 +1,131 @@
<?php
namespace Modules\User\Http\Controllers\Api\Rank;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\User\Models\User;
use Modules\User\Traits\RankDataTrait;
class IndexController extends Controller
{
use RankDataTrait;
/**
* Notes: 总排行
*
* @Author: 玄尘
* @Date: 2022/8/17 15:10
* @param Request $request
* @return JsonResponse
*/
public function total(Request $request): JsonResponse
{
$dateBetween = [
'2022-06-01 00:00:00',
now()->toDateTimeString(),
];
$vipUsers = $this->getRankDataTrait($dateBetween);
$data = [];
$i = 1;
foreach ($vipUsers as $user) {
$data[] = [
'rank' => $i,
'avatar' => $user->info->avatar, //头像
'nickname' => $user->info->nickname,
'rate' => '---',
'number' => $user->countChild,
];
}
return $this->success([
'page_id' => 6,
'rand' => $data
]);
}
/**
* Notes: 推荐用户总排行
*
* @Author: 玄尘
* @Date: 2022/8/17 15:11
* @return JsonResponse
*/
public function totalUser(): JsonResponse
{
$user = Api::user();
$users = User::query()
->withCount('children')
->take(10)
->latest('children_count')
->get()
->map(function ($info) use ($user) {
return [
'user' => [
'user_id' => $info->id,
'username' => $info->username,
'nickname' => $info->info->nickname ?? '',
'avatar' => $info->info->avatar ?? '',
],
'is_my' => $info->id == $user->id,
'total' => $info->children_count,
];
})
->pad(10, [
'user' => [
'user_id' => 0,
'username' => '---',
'nickname' => '---',
'avatar' => '---',
],
'is_my' => false,
'total' => 0,
]);
$users = $users->toArray();
$i = 1;
$top = $other = [];
$myRank = 0;
foreach ($users as &$rank) {
$rank['rank'] = $i;
if ($rank['is_my']) {
$myRank = $i;
}
if ($i < 4) {
$top[] = $rank;
} else {
$other[] = $rank;
}
$i++;
}
$childrenCount = $user->children()->count();
if (! $myRank) {
$myRank = User::query()
->withCount('children')
->latest('children_count')
->where('children_count'.'>', $childrenCount)
->count();
}
$data = [
'user' => [
'username' => $user->username,
'nickname' => $user->info->nickname,
'avatar' => $user->info->avatar,
'total' => $user->sign->counts,
'rank' => $myRank ?: $myRank + 1,
],
'top' => $top,
'other' => $other,
];
return $this->success($data);
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Modules\User\Http\Controllers\Api\Relation;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\User\Http\Resources\RelationResource;
use Modules\User\Models\Relation;
class IndexController extends Controller
{
/**
* Notes: 我的下级
*
* @Author: 玄尘
* @Date : 2021/9/24 15:05
* @param Request $request
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$layer = $request->larer ?? 1;
$user = Api::user();
$layer = bcadd($user->relation->layer, $layer);
$users = Relation::query()
->where('bloodline', 'like', "%,".$user->id.",%")
->when($layer, function ($q) use ($layer) {
$q->where('layer', $layer);
}, function ($q) {
$q->whereIn('layer', [2, 3]);
})
->paginate();
$data = [
'count' => $user->getRelationCount(),
'users' => RelationResource::collection($users),
];
return $this->success($data);
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\User\Http\Controllers\Api\Service;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\User\Http\Resources\UserServiceResource;
use Modules\User\Models\Identity;
class IndexController extends Controller
{
public function index(Request $request): JsonResponse
{
$identityId = $request->identity_id ?? 0;
if ($identityId) {
$identity = Identity::findOrFail($identityId);
$service = $identity->identities()->shown()->inRandomOrder()->first();
} else {
$user = Api::user();
$service = $user->identities->first()->identities()->shown()->inRandomOrder()->first();
}
if (empty($service)) {
return $this->success([]);
}
return $this->success(new UserServiceResource($service));
}
}

View File

@@ -0,0 +1,96 @@
<?php
namespace Modules\User\Http\Controllers\Api\Setting;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Jason\Api\Api;
use Modules\User\Models\UserWechat;
class IndexController extends Controller
{
/**
* Notes : 设置页面展示
*
* @Date : 2021/8/27 14:42
* @Author : Mr.wang
* @return JsonResponse
*/
public function index(): JsonResponse
{
$user = Api::user();
$wechat = UserWechat::where('user_id', $user->id)->first();
if ($wechat) {
if ($wechat->mini) {
$bool = true;
} else {
$bool = false;
}
} else {
$bool = false;
}
return $this->success([
'avatar' => $user->info->avatar ?? '',
'nickname' => $user->info->nickname ?? '',
'is_bind' => $bool,
'certification' => [
'is_true' => (bool) $user->certification,
'message' => $user->certification ? [
'name' => $user->certification->name,
'idcard' => $user->certification->id_card,
] : [],
],
]);
}
/**
* Notes : 用户基础信息修改
*
* @Date : 2021/5/27 14:02
* @Author : Mr.wang
* @param Request $request
* @param string $key
* @return JsonResponse
*/
public function update(Request $request, string $key): JsonResponse
{
$user = Api::user();
switch ($key) {
case 'nickname':
$validator = Validator::make($request->all(), [
'value' => 'required',
], [
'value.required' => '用户昵称必须填写',
]);
break;
case 'avatar':
$validator = Validator::make($request->all(), [
'value' => ['required', 'regex:/[^\s]*\.(jpg|jpeg|gif|png)$/i'],
], [
'value.required' => '用户头像必须上传',
'value.regex' => '头像地址格式不正确',
]);
break;
default:
return $this->failed('路径不合法');
}
if ($validator->fails()) {
return $this->failed($validator->errors()->first(), 422);
}
$result = $user->info()->update([$key => $request->value]);
if ($result) {
return $this->success('操作成功');
} else {
return $this->failed('失败');
}
}
}

View File

@@ -0,0 +1,363 @@
<?php
namespace Modules\User\Http\Controllers\Api\Sign;
use App\Api\Controllers\Controller;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;
use Jason\Api\Api;
use Modules\Coupon\Http\Resources\User\UserBaseResource;
use Modules\User\Facades\Calendar;
use Modules\User\Facades\UserSign;
use Modules\User\Http\Resources\Sign\SignBannerResource;
use Modules\User\Http\Resources\Sign\SignTextResource;
use Modules\User\Http\Resources\UserInfoBaseResource;
use Modules\User\Models\Sign;
use Modules\User\Models\SignBanner;
use Modules\User\Models\SignConfig;
use Modules\User\Models\SignLog;
use Modules\User\Models\SignText;
use Overtrue\ChineseCalendar\Calendar as OvertrueCalendar;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
use Vinkla\Hashids\Facades\Hashids;
class IndexController extends Controller
{
/**
* Notes : 签到的主页,根据配置展示相应内容
*
* @Date : 2021/5/28 4:41 下午
* @Author : <Jason.C>
* @param Request $request
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$type = SignConfig::getParams('show_type');
$user = Api::user();
switch ($type) {
case 'week':
##todo 根据自然周进行展示,等待完善
break;
case 'month':
//获取年
$year = $request->year ?? now()->year;
//获取月份
$month = $request->month ?? now()->month;
$yearMonth = sprintf("%d-%s", $year, $month);
$data = $this->month($yearMonth, $user);
break;
default:
$days = $request->days ?? 7;
$data = $this->sevenDay($days, $user);
break;
}
return $this->success($data);
}
/**
* Notes : 7天签到图
*
* @Date : 2022/1/7 15:07
* @Author : Mr.wang
* @param $days
* @param $user
* @return array
*/
private function sevenDay($days, $user)
{
$continue_days = $user->sign->continue_days;
$modDay = bcmod($continue_days, $days);
$cycle = bcdiv($continue_days, $days, 0);
$data = [
'can_sign' => ! UserSign::canSign($user, now()),
'next_task' => '',
];
$task = UserSign::getNextTaskCrystal($continue_days);
if ($task) {
$data['next_task'] = [
'day' => $task['day'],
'diff' => $task['day'] - $continue_days,
'crystal' => $task['number'] ?? 0,
];
}
for ($i = 1; $i <= $days; $i++) {
$day = $cycle * $days + $i;
$text = '第'.$day.'天';
if ($i == $modDay) {
$text = '今天';
}
$data['lists'][$i] = [
'sign' => ($i <= $modDay),
'crystal' => UserSign::getSignCrystal($day),
'text' => $text,
];
}
if ($user->sign) {
return $data;
} else {
return [];
}
}
/**
* Notes : 一月签到图
*
* @Date : 2022/1/7 15:11
* @Author : Mr.wang
* @param $yearMonth
* @param $user
* @return array[]
*/
private function month($yearMonth, $user)
{
$base = [
'month' => $yearMonth,
'continue' => $user->sign->continue_days,
'total' => $user->sign->counts,
'isSign' => $user->isSign(),
];
$calendar = Calendar::show($yearMonth)['calendar'];
$calendar = $calendar->map(function ($info) use ($user) {
$canSign = UserSign::canSign($user, Carbon::parse($info['today']));
return array_merge($info, [
'isSign' => $user->isSign($info['today']),
'canSign' => $canSign,
'canReSign' => UserSign::canReSign($user, Carbon::parse($info['today']))
]);
});
// //获取月份第一天所在的星期
// $firstDayOfWeek = Carbon::parse("$yearMonth-01")->dayOfWeek;
// //补全
// $day = 0;
// $calendar = [];
// for ($i = 0; $i < 6; $i++) {
// for ($j = 0; $j < 7; $j++) {
// if ($firstDayOfWeek != 0 and $i == 0) {
// //根据月初第一天所在的星期,计算出之前几天的日子
// $day = Carbon::parse("$yearMonth-01")->subDays($firstDayOfWeek - $j)->day;
// $date = Carbon::parse("$yearMonth-01")->subDays($firstDayOfWeek - $j);
// $hidden = $date->lt(Carbon::parse("$yearMonth-01")->startOfMonth());
// } else {
// $day++;
// $date = Carbon::parse("$yearMonth-01")->addDays($day - 1);
// $hidden = $date->gt(Carbon::parse("$yearMonth-01")->endOfMonth());
// }
// $calen = [
// 'date' => $date->format("j"),
// 'isPast' => $date->isPast(),
// 'isHidden' => $hidden,
// 'isSign' => $user->isSign($date->format('Y-m-d')),
// ];
// $calendar[$i][] = $calen;
// }
// }
return [
'base' => $base,
'calendar' => $calendar->splitIn(5),
];
}
/**
* Notes : 签到
*
* @Date : 2021/5/28 3:14 下午
* @Author : <Jason.C>
* @return JsonResponse
*/
public function sign(): JsonResponse
{
$user = Api::user();
try {
[$res, $message] = UserSign::signIn($user);
if ($res) {
// $logs = $user->account->logs()
// ->where('rule_id', 10)
// ->whereDate('created_at', now())
// ->get();
return $this->success($message);
} else {
return $this->failed($message);
}
} catch (Exception $exception) {
return $this->failed($exception->getMessage());
}
}
/**
* Notes : 预留补签功能
*
* @Date : 2021/5/28 3:14 下午
* @Author : <Jason.C>
* @param Request $request
* @return JsonResponse
*/
public function replenish(Request $request): JsonResponse
{
$user = Api::user();
$date = $request->date;
$date = Carbon::parse($date);
try {
[$res, $message] = UserSign::replenish($user, $date);
if ($res) {
return $this->success($message);
} else {
return $this->failed('补签失败');
}
} catch (Exception $exception) {
return $this->failed($exception->getMessage());
}
}
/**
* Notes: 月日历
*
* @Author: 玄尘
* @Date: 2022/8/3 11:44
* @return JsonResponse
*/
public function date()
{
return $this->success(Calendar::show('2022-07'));
}
/**
* Notes: 签到封面
*
* @Author: 玄尘
* @Date: 2022/8/9 8:15
* @return JsonResponse
*/
public function backgrounds(): JsonResponse
{
$user = Api::user();
$signTexts = SignText::shown()->get();
$signBanner = SignBanner::query()->shown()->inRandomOrder()->first();
$calendar = new OvertrueCalendar();
$lunarMonth = $calendar->toChinaMonth(now()->month);
$lunarDay = $calendar->toChinaDay(now()->day);
$invite = Hashids::connection('code')->encode($user->id);
$url = Config::get('user.invite_code.url').'?invite='.$invite;
$code = 'data:image/png;base64,'.base64_encode(QrCode::format('png')
->size(100)
->margin(3)
->generate($url));
//锶源昆仑
return $this->success([
'texts' => SignTextResource::collection($signTexts),
'banner' => new SignBannerResource($signBanner),
'time' => [
'yearMonth' => now()->format('Y-m'),
'time' => now()->format('H:i'),
'day' => now()->format('d'),
'lunar' => '农历'.$lunarMonth.$lunarDay,
],
'user' => [
'username' => $user->username,
'nickname' => $user->info->nickname ?? '',
'avatar' => $user->info->avatar ?? '',
'code' => $code,
],
'sign' => $user->getSignData()
]);
}
/**
* Notes: 签到排行
*
* @Author: 玄尘
* @Date: 2022/8/17 13:43
* @param Request $request
* @return JsonResponse
*/
public function rank(Request $request): JsonResponse
{
$user = Api::user();
$ranks = Sign::query()
->latest('counts')
->take(10)
->get()
->map(function ($info) use ($user) {
return [
'user' => [
'user_id' => $info->user_id,
'username' => $info->user->username,
'nickname' => $info->user->info->nickname ?? '',
'avatar' => $info->user->info->avatar ?? '',
],
'is_my' => $info->user_id == $user->id,
'total' => $info->counts,
];
})
->pad(10, [
'user' => [
'user_id' => 0,
'username' => '---',
'nickname' => '---',
'avatar' => '---',
],
'is_my' => false,
'total' => 0,
]);
$ranks = $ranks->toArray();
$i = 1;
$top = $other = [];
$myRank = 0;
foreach ($ranks as &$rank) {
$rank['rank'] = $i;
if ($rank['user']['user_id'] == $user->id) {
$myRank = $i;
}
if ($i < 4) {
$top[] = $rank;
} else {
$other[] = $rank;
}
$i++;
}
if (! $myRank) {
$myRank = Sign::query()->where('counts', '>', $user->sign->counts)->count();
}
$data = [
'user' => [
'username' => $user->username,
'nickname' => $user->info->nickname,
'avatar' => $user->info->avatar,
'total' => $user->sign->counts,
'rank' => $myRank ?: $myRank + 1,
],
'top' => $top,
'other' => $other,
];
return $this->success($data);
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Modules\User\Http\Controllers\Api\Socialite;
use Illuminate\Http\Request;
abstract class Controller extends \App\Api\Controllers\Controller
{
abstract public function app(Request $request);
abstract public function query(Request $request);
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Modules\User\Http\Controllers\Api\Socialite;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Jason\Api\Api;
use Modules\User\Events\UserLoginSuccess;
use Modules\User\Models\User;
class UniCloudController extends Controller
{
public function app(Request $request)
{
$validator = Validator::make($request->all(), [
'access_token' => 'required',
'openid' => 'required',
], [
'access_token.required' => 'access_token必须填写',
'openid.required' => 'openid必须填写',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first(), 422);
}
$data = [
'access_token' => $request->access_token,
'openid' => $request->openid,
];
$secret = config('user.socialite.unicloud.self_secret', '');
$domain = config('user.socialite.unicloud.domain', '');
$url = config('user.socialite.unicloud.cloud_function_url.one_key', '');
if (! $secret || ! $domain || ! $url) {
return $this->failed('过程参数存在错误');
}
ksort($data);
$signString = urldecode(http_build_query($data));
$sign = hash_hmac('sha256', $signString, $secret);
$params = $signString.'&sign='.$sign;
$url = $domain.$url.'?'.$params;
$res = json_decode(file_get_contents($url));
if ($res->success) {
$user = User::firstOrCreate([
'username' => $res->phoneNumber,
], [
'password' => 111111,
]);
$token = Api::login($user);
event(new UserLoginSuccess($user, $request, '本机一键登录'));
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
'is_new' => $user->wasRecentlyCreated,
]);
} else {
return $this->failed('一键登录失败');
}
}
public function query(Request $request)
{
$validator = Validator::make($request->all(), [
'mobile' => 'required',
], [
'mobile.required' => '请传入手机号',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first(), 422);
}
$user = User::firstOrCreate([
'username' => $request->mobile,
], [
'password' => 111111,
]);
$token = Api::login($user);
event(new UserLoginSuccess($user, $request, '本机一键登录'));
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
'is_new' => $user->wasRecentlyCreated,
]);
}
}

View File

@@ -0,0 +1,368 @@
<?php
namespace Modules\User\Http\Controllers\Api\Socialite;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Jason\Api\Api;
use Modules\User\Events\UserLoginSuccess;
use Modules\User\Facades\Sms;
use Modules\User\Http\Requests\WechatMiniRequest;
use Modules\User\Models\User;
use Modules\User\Models\UserSubscribe;
use Modules\User\Models\UserWechat;
use Modules\User\Traits\WechatTrait;
class WeChatController extends Controller
{
use WechatTrait;
protected array $config = [];
/**
* Notes : APP 登录
*
* @Date : 2021/6/10 3:40 下午
* @Author : Mr.wang
* @param Request $request
* @return JsonResponse
*/
public function app(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'union_id' => 'required',
'mobileNo' => 'required|phone:CN,mobile',
'code' => 'required',
], [
'union_id.required' => 'unionId必须填写',
'mobileNo.required' => '手机号码必须填写',
'mobileNo.phone' => '手机号码格式不正确',
'code.required' => '验证码必须填写',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first(), 422);
}
$unionId = $request->union_id;
$wechat = UserWechat::where('unionid', $unionId)->first();
if (empty($wechat)) {
$mobileNo = $request->mobileNo;
$code = $request->code;
$check = Sms::checkCode($mobileNo, $code);
if ($check == false) {
return $this->failed('验证码不正确', 422);
}
$user = User::firstOrCreate([
'username' => $mobileNo,
], [
'password' => 111111,
]);
$wechat = $user->wechat()->firstOrcreate([
'unionid' => $unionId,
'nickname' => $request->nickname ?? '',
'avatar' => $request->avatar ?? '',
'sex' => $request->gender ?? 0,
'country' => $request->country ?? '',
'province' => $request->province ?? '',
'city' => $request->city ?? '',
]);
$wechat->app()->firstOrcreate([
'openid' => $request->open_id ?? '',
]);
$user->info()->update([
'nickname' => $request->nickname ?? $user->info->nickname,
'avatar' => $request->avatar ?? '',
]);
$token = Api::login($user);
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
'is_new' => $user->wasRecentlyCreated,
]);
} else {
$token = Api::login($wechat->user);
event(new UserLoginSuccess(Api::user(), $request, '微信授权'));
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
'is_new' => false,
]);
}
}
/**
* Notes : 小程序手机号登录
*
* @Date : 2021/7/29 17:21
* @Author : Mr.wang
* @param WechatMiniRequest $request
* @return JsonResponse
* @throws InvalidConfigException
*/
public function mini(WechatMiniRequest $request): JsonResponse
{
$code = $request->code;
$this->getConfig();
$app = Factory::miniProgram($this->config);
$session = $app->auth->session($code);
if ($session->errcode) {
return $this->failed($session->errmsg);
}
try {
$decryptedData = $app->encryptor->decryptData(
$session->session_key,
$request->iv,
$request->encryptedData
);
$mobile = $decryptedData['purePhoneNumber'];
$user = User::where('username', $mobile)->first();
if (! $user) {
$user = User::create([
'username' => $mobile,
'password' => 111111,
]);
$user->info()->create([
'nickname' => $request->nickname ?? '',
'avatar' => $request->avatar ?? '',
]);
}
$token = Api::login($user);
event(new UserLoginSuccess(Api::user(), $request, '微信授权'));
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
'is_new' => $user->wasRecentlyCreated,
]);
} catch (\Exception $exception) {
return $this->failed($exception->getMessage());
}
}
protected function getConfig()
{
$this->config = [
'app_id' => env('WECHAT_MINI_APPID'),
'secret' => env('WECHAT_MINI_SECRET'),
'response_type' => 'collection',
];
}
/**
* Notes : 公众号登录
*
* @Date : 2021/5/26 3:14 下午
* @Author : < Jason.C >
*/
public function official()
{
}
public function query(Request $request): JsonResponse
{
$unionId = $request->union_id ?? '';
if (empty($unionId)) {
return $this->failed('', 404);
}
$wechat = UserWechat::where('unionid', $unionId)->first();
if (empty($wechat)) {
return $this->success([
'union_id' => $unionId,
]);
} else {
$token = Api::login($wechat->user);
event(new UserLoginSuccess(Api::user(), $request, '微信授权'));
return $this->success([
'token_type' => 'Bearer',
'access_token' => $token,
]);
}
}
/**
* Notes: 入库微信信息
*
* @Author: 玄尘
* @Date: 2022/8/2 11:16
*/
public function addWechatUser(): JsonResponse
{
try {
$user = Api::user();
if (! $user) {
throw new \Exception('操作失败请登录。');
}
$wechatUser = $user->wechat;
$weUser = $this->getUserFromCode();
$openid = $weUser->getId();
$baseUser = $this->getWechatUser($openid);
$unionid = '';
$raw = $weUser->getRaw();
if (isset($raw['unionid'])) {
$unionid = $raw['unionid'];
}
if (! $openid) {
if ($raw && $raw['errmsg']) {
throw new \Exception($raw['errmsg']);
}
throw new \Exception('code解密失败');
}
if (! $user->info->avatar) {
//更新头像
$user->info->update([
'avatar' => $weUser->getAvatar(),
]);
}
if (! $wechatUser) {
$wechatUser = $user->wechat()
->firstOrCreate([
'unionid' => $unionid,
'nickname' => $weUser->getNickname(),
'avatar' => $weUser->getAvatar(),
]);
} elseif (empty($wechatUser['unionid']) && ! empty($unionid)) {
$wechatUser->update([
'unionid' => $unionid,
]);
}
if (! $wechatUser->official) {
$wechatUser->official()->firstOrCreate([
'openid' => $weUser->getId(),
'subscribe' => $baseUser->subscribe
]);
} else {
$wechatUser->official()->update([
'subscribe' => $baseUser->subscribe
]);
}
//设置关注状态
if ($unionid) {
$this->setUserSubscribe($unionid, $openid, $baseUser->subscribe);
}
return $this->success([
'openid' => $openid,
'subscribe' => $baseUser->subscribe,
]);
} catch (\Exception $exception) {
return $this->failed($exception->getMessage());
}
}
/**
* Notes: 小程序入库
*
* @Author: 玄尘
* @Date: 2022/9/23 14:46
* @param Request $request
* @return JsonResponse|mixed
*/
public function miniAddWechatUser(Request $request)
{
$user = Api::user();
$validator = \Validator::make($request->all(), [
'code' => 'required',
'iv' => 'required',
'encryptedData' => 'required',
], [
'code.required' => '缺少参数code',
'iv.required' => '缺少参数iv',
'encryptedData.mobile' => '缺少参数encryptedData',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first());
}
try {
$code = $request->code;
$unionid = '';
$weChat = app('wechat.mini_program');
$session = $weChat->auth->session($code);
if (isset($session->unionid)) {
$unionid = $session->unionid;
}
if (isset($session->errcode)) {
return $this->failed($session->errmsg);
}
$openid = $session->openid;
$wechatUser = $user->wechat;
$decryptedData = $weChat->encryptor->decryptData(
$session->session_key,
$request->iv,
$request->encryptedData
);
if (! $wechatUser) {
$wechatUser = $user->wechat()
->firstOrCreate([
'unionid' => $unionid,
'nickname' => $decryptedData['nickName'] ?? '',
'avatar' => $decryptedData['avatarUrl'] ?? '',
]);
} elseif (empty($wechatUser['unionid']) && ! empty($unionid)) {
$wechatUser->update([
'unionid' => $unionid,
]);
}
if (! $wechatUser->mini) {
$wechatUser->mini()->firstOrCreate([
'openid' => $openid,
]);
}
$userSubscribe = UserSubscribe::query()
->where('unionid', $unionid)
->where('subscribe', 1)
->first();
if ($userSubscribe && ! $wechatUser->official) {
if (! $wechatUser->official) {
$wechatUser->official()
->firstOrCreate([
'openid' => $userSubscribe->openid,
'subscribe' => $userSubscribe->subscribe
]);
} else {
$wechatUser->official()->update([
'subscribe' => $userSubscribe->subscribe
]);
}
}
return $this->success([
'openid' => $openid,
'subscribe' => $userSubscribe ? 1 : 0,
]);
} catch (\Exception $e) {
return $this->failed($e->getMessage());
}
}
}

View File

@@ -0,0 +1,180 @@
<?php
namespace Modules\User\Http\Controllers\Api\Stock;
use App\Api\Controllers\Controller;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Jason\Api\Api;
use Modules\Mall\Facades\Item;
use Modules\Mall\Facades\Order as OrderFacade;
use Modules\Mall\Http\Resources\Api\Address\AddressResource;
use Modules\Mall\Http\Resources\Api\Goods\GoodsBaseResource;
use Modules\Mall\Http\Resources\Api\Order\OrderCollection;
use Modules\Mall\Models\Address;
use Modules\Mall\Models\Goods;
use Modules\Mall\Models\GoodsSku;
use Modules\Mall\Models\Order;
use Modules\Mall\Models\Region;
use Modules\User\Http\Resources\stock\UserStockLogCollection;
use Modules\User\Http\Resources\UserIdentityBaseResource;
use Modules\User\Models\Identity;
use Modules\User\Models\UserStockLog;
class IndexController extends Controller
{
/**
* Notes : 订单列表
*
* @Date : 2021/5/13 5:17 下午
* @Author : <Jason.C>
* @param Request $request
* @return JsonResponse
*/
public function index(Request $request): JsonResponse
{
$state = $request->state ?? '';
$list = Order::byUser(Api::user())
->TypeSample()
->when($state, function ($query) use ($state) {
switch ($state) {
case 'init':
$query->paid()->unPay();
break;
case 'delivered':
$query->delivered();
break;
}
}, function ($query) {
$query->common();
})
->paginate(8);
return $this->success(new OrderCollection($list));
}
/**
* Notes: 提货前置
*
* @Author: 玄尘
* @Date: 2022/8/1 11:32
* @return JsonResponse
*/
public function create(): JsonResponse
{
$user = Api::user();
$addresses = Address::where('user_id', $user->id)->orderBy('is_default', 'desc')->get();
$address = Address::where('user_id', $user->id)->orderBy('is_default', 'desc')->first();
$data = [
'addresses' => AddressResource::collection($addresses),
'address' => $address ? new AddressResource($address) : '',
'stockData' => $user->getStockData(),
'dientity' => new UserIdentityBaseResource($user->identityFirst())
];
return $this->success($data);
}
/**
* Notes: 提货
*
* @Author: 玄尘
* @Date: 2022/8/1 11:33
* @param Request $request
* @return JsonResponse|mixed
* @throws \Exception
*/
public function store(Request $request)
{
$user = Api::user();
$validator = Validator::make($request->all(), [
'address_id' => 'required|integer',
'qty' => 'required|integer',
], [
'qty.required' => '缺少提货数量',
'qty.integer' => '数量必须是数字',
'address_id.required' => '缺少收货地址',
'address_id.integer' => '收货地址必须是数字',
]);
if ($validator->fails()) {
return $this->failed($validator->errors()->first());
}
$remark = $request->remark ?? '';
$address_id = $request->address_id;
$qty = $request->qty;
$address = Address::find($address_id);
$userIdentity = $user->identityFirst();
if ($userIdentity->job == Identity::JOB_TY) {
$shenzhen = Region::query()->where('name', '深圳市')->first();
if ($address->city_id != $shenzhen->id) {
return $this->failed('体验官收货地址只能选择深圳');
}
}
$goods_sku = GoodsSku::query()
->whereHas('goods', function ($q) {
$q->where('channel', Goods::CHANNEL_FREE)->where('status', Goods::STATUS_UP);
})
->first();
if (! $goods_sku) {
return $this->failed('缺少商品');
}
$stockData = $user->getStockData();
if ($qty > $stockData['residue']) {
return $this->failed('用户库存不足');
}
$detail = collect();
$item = new Item($goods_sku, $address, $qty);
$detail->push($item);
$orders = (new OrderFacade)->user($user)
->remark($remark)
->type(Order::TYPE_SAMPLE)
->items($detail)
->address($address)
->create();
//提货自动完成
foreach ($orders as $order) {
if ($order->type == Order::TYPE_SAMPLE) {
$order->pay();
}
}
return $this->success('提货成功');
}
/**
* Notes: 账变记录
*
* @Author: 玄尘
* @Date: 2022/8/3 10:43
*/
public function logs()
{
$user = Api::user();
$logs = UserStockLog::query()
->ByUser($user)
->oldest()
->paginate();
return $this->success(new UserStockLogCollection($logs));
}
}