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,109 @@
<?php
namespace Modules\User\Facades;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Modules\User\Models\User;
class Calendar
{
/**
* Notes : 获取日历展示图,设置每周开始为周日
*
* @Date : 2022/1/21 10:23
* @Author : Mr.wang
* @param string $date
* @return array
*/
public static function show(string $date = ''): array
{
$start = Carbon::parse($date)->startOfMonth()->startOfWeek(0)->toDateString();
$end = Carbon::parse($date)->endOfMonth()->endOfWeek(6)->toDateString();
$data = self::getBetweenDate($start, $end);
$calendar = Carbon::parse($date);
$days = $data->map(function ($today) use ($calendar) {
return [
'today' => $today->toDateString(),
'day' => (int) $today->format('j'),
'isPast' => $today->isPast(),//是否为之前的日期
'isMonth' => $today->isSameMonth($calendar),//当前月
];
});
return [
'start' => $start,
'end' => $end,
'calendar' => $days
];
}
/**
* Notes: 返回日期区间
*
* @Author: 玄尘
* @Date: 2022/2/8 16:52
* @param string $start_at 开始日期
* @param string $end_at 结束日期
*/
public static function getBetweenDate(string $start_at, string $end_at)
{
return collect(CarbonPeriod::create($start_at, $end_at));
}
/**
* Notes: 获取日期 某一天的前一天后一天
*
* @Author: 玄尘
* @Date: 2022/1/21 11:03
* @param string $today
* @param string $type
* @return string
*/
public static function day(string $today = '', string $type = ''): string
{
$variate = ['before' => -1, 'after' => 1, '' => 0][$type];
return Carbon::parse($today)->addDays($variate)->toDateString();
}
/**
* Notes: 获取日期 某一天的前一天后一天
*
* @Author: 玄尘
* @Date: 2022/1/21 11:03
* @param string $month
* @param string $type
* @return string
*/
public static function getFirstDayByMonth(string $month = '', string $type = ''): string
{
$month = Carbon::parse($month);
if ($type == 'before') {
$month = $month->subMonth();
}
if ($type == 'after') {
$month = $month->addMonth();
}
return $month->startOfMonth()->toDateString();
}
/**
* Notes: 获取年份
*
* @Author: 玄尘
* @Date: 2022/8/10 9:30
* @param $start
*/
public static function getYears($startYear)
{
$years = CarbonPeriod::years($startYear);
return $years;
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace Modules\User\Facades;
use Illuminate\Support\Arr;
use Modules\User\Models\Sms as SmsModel;
use Modules\User\Models\SmsConfig;
use Modules\User\Services\VerificationCode;
use Overtrue\EasySms\Exceptions\InvalidArgumentException;
use Overtrue\EasySms\Exceptions\NoGatewayAvailableException;
use Overtrue\EasySms\Strategies\OrderStrategy;
class Sms
{
/**
* Notes : 获取短信配置
*
* @Date : 2021/5/27 4:01 下午
* @Author : <Jason.C>
* @param string|null $key 配置的主键
* @return mixed
*/
public static function getConfig(string $key = null)
{
$model = SmsConfig::orderByDesc('in_use')->first();
$config = [
'debug' => $model->debug ?? true,
'debug_code' => $model->debug_code ?? '0000',
'length' => $model->length ?? 4,
'template' => $model->template ?? [],
'default' => [
'strategy' => OrderStrategy::class,
'gateways' => [
$model->default_gateway ?? 'aliyun',
],
],
'gateways' => [
$model->default_gateway => $model->getGateway(),
],
];
// dd($config);
if (isset($config['gateways']['aliyun'])) {
$config['gateways']['aliyun']['access_key_id'] = $config['gateways']['aliyun']['APP_ID'];
$config['gateways']['aliyun']['access_key_secret'] = $config['gateways']['aliyun']['APP_SECRET'];
$config['gateways']['aliyun']['sign_name'] = $config['gateways']['aliyun']['SIGN_NAME'];
}
return Arr::get($config, $key) ?? $config;
}
/**
* Notes : 发送验证码短信
*
* @Date : 2021/5/26 4:17 下午
* @Author : <Jason.C>
* @param string $mobile 手机号码
* @param string $channel 验证通道
* @throws InvalidArgumentException
* @throws NoGatewayAvailableException
*/
public static function sendVerificationCode(string $mobile, string $channel = 'DEFAULT')
{
$message = new VerificationCode(self::getConfig(), $channel);
if (! self::getConfig('debug')) {
app('sms')->send($mobile, $message);
}
SmsModel::create([
'mobile' => $mobile,
'channel' => $channel,
'gateway' => self::getConfig('debug') ? 'debug' : self::getConfig('default.gateways.0'),
'content' => $message->code,
]);
}
/**
* 验证短信
*
* @Author:<C.Jason>
* @Date :2018-11-07T14:26:38+0800
* @param string $mobile 手机号码
* @param string $code 验证码
* @param string $channel 验证通道
* @return bool
*/
public static function checkCode(string $mobile, string $code, string $channel = 'DEFAULT'): bool
{
$Sms = SmsModel::where('mobile', $mobile)->where('channel', $channel)->first();
if ($Sms && $Sms->content == $code) {
if ($Sms->used && ! self::getConfig('debug')) {
return false;
}
# todo 有效期判定
$Sms->used = 1;
$Sms->save();
return true;
} else {
return false;
}
}
/**
* Notes : 发送通知短信
*
* @Date : 2021/5/26 5:08 下午
* @Author : <Jason.C>
* @param string|array $mobile 接受短信的手机号
* @param string $content 短信内容
*/
public static function sendNotification($mobile, string $content)
{
# todo. 这里要实现批量发送,短信通道等操作,待测试
}
}

View File

@@ -0,0 +1,308 @@
<?php
namespace Modules\User\Facades;
use Carbon\Carbon;
use DateTime;
use Exception;
use Illuminate\Support\HigherOrderCollectionProxy;
use Modules\Gout\Models\GoutCase;
use Modules\User\Models\SignConfig;
use Modules\User\Models\SignLog;
use Modules\User\Models\User;
/**
* 用户签到
* Class UserSign
*
* @package Modules\User\Facades
*/
class UserSign
{
/**
* @param User $user
* @return array
*/
public static function signIn(User $user, $date = ''): array
{
try {
$date = Carbon::parse($date);//签到日期
$params = SignConfig::getParams();
if (! $params['open']) {
throw new Exception('签到功能未开启');
}
if (! self::canSign($user, $date)) {
throw new Exception(self::getNotSignText($user, $date));
}
$continue_days = $user->sign->continue_days;
$counts = $user->sign->counts;
if (SignLog::where('user_id', $user->id)
->whereDate('date', (clone $date)->subDay()->toDateString())
->exists()) {
$continue_days++;
} else {
$continue_days = 1;
}
$crystals = self::getSignCrystal($continue_days);
$rule_name = $params['rule_name'];
$str = "{$continue_days}天签到";
if ($crystals > 0) {
$user->account->rule($rule_name, 0, false, [
'frozen_at' => now()->toDateTimeString(),
'settle_at' => now()->toDateTimeString(),
'remark' => '第'.$continue_days.'天签到',
]);
$str .= ",获得{$crystals}水滴"."\n";
// $str .= '第'.$continue_days.'天签到';
}
$task_crystals = self::getTaskCrystal($continue_days);
if ($task_crystals > 0) {
// $user->account->rule($rule_name, $task_crystals, true, [
// 'frozen_at' => now()->toDateTimeString(),
// 'settle_at' => now()->toDateTimeString(),
// 'remark' => '连续签到'.$continue_days.'天',
// ]);
// $str .= '连续签到'.$continue_days.'天,获得水晶'.$task_crystals;
$str .= '连续签到'.$continue_days.'天';
}
$user->sign->update([
'continue_days' => $continue_days,
'counts' => ++$counts,
'last_sign_at' => $date,
]);
SignLog::create([
'user_id' => $user->id,
'date' => $date,
'type' => 0,
]);
return [true, $str];
} catch (Exception $e) {
return [false, $e->getMessage()];
}
}
/**
* 返回连续签到额外任务
*
* @param int $continue_days
* @return int
*/
public static function getTaskCrystal(int $continue_days = 1): int
{
$tasks = SignConfig::getTasks();
$task = $tasks->firstWhere('day', $continue_days);
return $task['number'] ?? 0;
}
public static function getNextTaskCrystal($continue_days = 1)
{
$tasks = SignConfig::getTasks();
return $tasks->where('day', ' > ', $continue_days)
->sortBy('day')
->first();
}
/**
* 返回签到奖励
*
* @param int $continue_days
* @return HigherOrderCollectionProxy|int|mixed
*/
public static function getSignCrystal(int &$continue_days = 1)
{
$params = SignConfig::getParams();
$crystals = 0;
switch ($params['type']) {
case 'single':
$crystals = $params['single_number'];
break;
case 'continuous':
$crystals = (int) $params['continuous_base'] + (int) bcmul($continue_days - 1,
$params['continuous_incremental'],
0);
break;
case 'cycle':
if ($continue_days > $params['cycle_day']) {
$continue_days -= $params['cycle_day'];
}
$crystals = (int) $params['cycle_base'] + (int) bcmul($continue_days - 1, $params['cycle_incremental'],
0);
break;
}
return $crystals;
}
/**
* Notes : 某一天是否可签到
*
* @Date : 2021/5/28 3:25 下午
* @Author : <Jason.C>
* @param User $user
* @param Carbon $date
* @return bool
*/
public static function canSign(User $user, DateTime $date): bool
{
$identityMiddle = $user->identityMiddle()->first();
$start_at = $identityMiddle->started_at;
if (! $start_at) {
$start_at = $identityMiddle->created_at;
}
return $identityMiddle->identity->order > 1 &&
Carbon::parse($date)->endOfDay()->gt($start_at) &&
! $user->IsSign($date) &&
$date->isToday();
}
/**
* Notes: 是否可以补签
*
* @Author: 玄尘
* @Date: 2022/8/12 8:51
* @param User $user
* @param DateTime $date
* @return bool
*/
public static function canReSign(User $user, DateTime $date): bool
{
$identityMiddle = $user->identityMiddle()->first();
$start_at = $identityMiddle->started_at;
if (! $start_at) {
$start_at = $identityMiddle->created_at;
}
return ! $user->IsSign($date) &&
now()->endOfDay()->gt($date) &&
! $date->isToday() &&
Carbon::parse($date)->endOfDay()->gt($start_at);
}
/**
* Notes: 获取不可打卡的信息
*
* @Author: 玄尘
* @Date: 2022/8/10 13:18
*/
public static function getNotSignText(User $user, DateTime $date)
{
$identityMiddle = $user->identityMiddle()->first();
if (SignLog::where('user_id', $user->id)->whereDate('date', $date)->exists()) {
return '今日已打卡';
}
if ($identityMiddle->identity->order < 2) {
return '未开通会员';
}
$started_at = $identityMiddle->started_at;
if (! $started_at) {
$started_at = $identityMiddle->created_at;
}
if ($started_at->gt(Carbon::parse($date)->startOfDay())) {
return '当前时间还未开通会员';
}
}
/**
* Notes : 补签
*
* @Date : 2021/5/28 3:15 下午
* @Author : <Jason.C>
* @param User $user
* @param DateTime $date
* @return bool
* @throws Exception
*/
public static function replenish(User $user, DateTime $date): array
{
if (! self::canReSign($user, $date)) {
throw new Exception(self::getNotSignText($user, $date));
}
$params = SignConfig::getParams();
$continue_days = $user->sign->continue_days;
$crystals = self::getSignCrystal($continue_days);
$rule_name = $params['rule_name'];
$str = $date->format('Y-m-d')."号补签";
if ($crystals > 0) {
$user->account->rule($rule_name, 0, false, [
'frozen_at' => now()->toDateTimeString(),
'settle_at' => now()->toDateTimeString(),
'remark' => now()->toDateTimeString().'天补签到',
]);
$str .= ",获得{$crystals}水滴"."\n";
}
$counts = $user->sign->counts;
$user->sign->update([
'counts' => ++$counts,
]);
$log = SignLog::create([
'user_id' => $user->id,
'date' => $date,
'type' => 1,
]);
self::recalculateContinueDays($user);
return [true, $str];
}
/**
* Notes: 重新计算连续签到日期
*
* @Author: 玄尘
* @Date: 2022/8/4 9:34
*/
public static function recalculateContinueDays(User $user)
{
$reset_at = $user->sign->reset_at;
$days = SignLog::query()
->byUser($user)
->when($reset_at, function ($q) use ($reset_at) {
$q->where('date', '>=', $reset_at);
})
->latest('date')
->pluck('date');
$continue_days = 1;
foreach ($days as $key => $day) {
if (isset($days[$key + 1])) {
if ($day->subDay()->isSameDay($days[$key + 1])) {
$continue_days++;
} else {
break;
}
}
}
$user->sign->update([
'continue_days' => max($continue_days, 1),
'counts' => $user->signLogs()->count()
]);
return true;
}
}