Files
water-back/modules/User/Http/Controllers/Api/Sign/IndexController.php
2023-01-12 14:47:38 +08:00

364 lines
11 KiB
PHP

<?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);
}
}