diff --git a/.env.example b/.env.example index c6f11e1a..bcef85c1 100644 --- a/.env.example +++ b/.env.example @@ -43,7 +43,7 @@ MAIL_ENCRYPTION=ssl MAIL_FROM_ADDRESS=admin@proxypanel.demo MAIL_FROM_NAME=ProxyPanel -SESSION_SECURE_COOKIE=true +SESSION_SECURE_COOKIE= #IP查询相关 BAIDU_APP_AK= IPINFO_ACCESS_TOKEN= diff --git a/app/Casts/data_rate.php b/app/Casts/data_rate.php new file mode 100644 index 00000000..6ba04eb4 --- /dev/null +++ b/app/Casts/data_rate.php @@ -0,0 +1,29 @@ + $attributes + */ + public function get(Model $model, string $key, mixed $value, array $attributes): int|float + { + return $value / Mbps; + } + + /** + * Prepare the given value for storage. + * + * @param array $attributes + */ + public function set(Model $model, string $key, mixed $value, array $attributes): int + { + return $value * Mbps; + } +} diff --git a/app/Casts/datestamp.php b/app/Casts/datestamp.php new file mode 100644 index 00000000..47125618 --- /dev/null +++ b/app/Casts/datestamp.php @@ -0,0 +1,29 @@ + $attributes + */ + public function get(Model $model, string $key, mixed $value, array $attributes): string + { + return date('Y-m-d', $value); + } + + /** + * Prepare the given value for storage. + * + * @param array $attributes + */ + public function set(Model $model, string $key, mixed $value, array $attributes): int + { + return strtotime($value); + } +} diff --git a/app/Casts/money.php b/app/Casts/money.php new file mode 100644 index 00000000..fd4e196d --- /dev/null +++ b/app/Casts/money.php @@ -0,0 +1,29 @@ + $attributes + */ + public function get(Model $model, string $key, mixed $value, array $attributes): int|float + { + return $value / 100; + } + + /** + * Prepare the given value for storage. + * + * @param array $attributes + */ + public function set(Model $model, string $key, mixed $value, array $attributes): int + { + return $value * 100; + } +} diff --git a/app/Console/Commands/PanelUpdate.php b/app/Console/Commands/PanelUpdate.php index fb0ccdfc..da528d27 100644 --- a/app/Console/Commands/PanelUpdate.php +++ b/app/Console/Commands/PanelUpdate.php @@ -23,7 +23,7 @@ class PanelUpdate extends Command Artisan::call('migrate --force'); if (config('app.demo') && $this->confirm('检测到您在DEMO模式, 是否重置数据库?')) { - Artisan::call('migrate:fresh --seed'); + Artisan::call('migrate:fresh --seed --force'); } $bar->advance(); diff --git a/app/Console/Commands/TaskDaily.php b/app/Console/Commands/TaskDaily.php index 02a79eb0..aebc9211 100644 --- a/app/Console/Commands/TaskDaily.php +++ b/app/Console/Commands/TaskDaily.php @@ -70,11 +70,10 @@ class TaskDaily extends Command private function closeTickets(): void { // 关闭用户超时未处理的工单 - Ticket::whereStatus(1) + Ticket::whereStatus(1)->with('reply') ->whereHas('reply', function ($q) { $q->where('admin_id', '<>', null); }) - ->has('reply') ->where('updated_at', '<=', date('Y-m-d', strtotime('-'.config('tasks.close.tickets').' hours'))) ->chunk(config('tasks.chunk'), function ($tickets) { foreach ($tickets as $ticket) { @@ -92,7 +91,7 @@ class TaskDaily extends Command User::where('status', '<>', -1) ->where('expired_at', '>', date('Y-m-d')) ->where('reset_time', '<=', date('Y-m-d')) - ->with('orders')->whereHas('orders') + ->with('orders')->has('orders') ->chunk(config('tasks.chunk'), function ($users) { foreach ($users as $user) { $order = $user->orders()->activePlan()->first(); // 取出用户正在使用的套餐 diff --git a/app/Models/Article.php b/app/Models/Article.php index 192e18da..7364a90c 100644 --- a/app/Models/Article.php +++ b/app/Models/Article.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -19,12 +20,12 @@ class Article extends Model protected $guarded = []; // 筛选类型 - public function scopeType($query, $type) + public function scopeType(Builder $query, int $type): Builder { return $query->whereType($type); } - public function scopeLang($query, $language = null) + public function scopeLang(Builder $query, ?string $language = null): Builder { return $query->whereLanguage($language ?? app()->getLocale()); } diff --git a/app/Models/Coupon.php b/app/Models/Coupon.php index a79f084c..0fffb960 100644 --- a/app/Models/Coupon.php +++ b/app/Models/Coupon.php @@ -2,6 +2,8 @@ namespace App\Models; +use App\Casts\datestamp; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -14,26 +16,16 @@ class Coupon extends Model protected $table = 'coupon'; - protected $casts = ['limit' => 'array', 'start_time' => 'date:Y-m-d', 'end_time' => 'date:Y-m-d', 'deleted_at' => 'datetime']; + protected $casts = ['limit' => 'array', 'start_time' => datestamp::class, 'end_time' => datestamp::class, 'deleted_at' => 'datetime']; protected $guarded = []; // 筛选类型 - public function scopeType($query, $type) + public function scopeType(Builder $query, int $type): Builder { return $query->whereType($type); } - public function setStartTimeAttribute($value) - { - return $this->attributes['start_time'] = strtotime($value); - } - - public function setEndTimeAttribute($value) - { - return $this->attributes['end_time'] = strtotime($value); - } - public function used(): bool { $this->attributes['status'] = 1; diff --git a/app/Models/CouponLog.php b/app/Models/CouponLog.php index 025ee930..01cd49e1 100644 --- a/app/Models/CouponLog.php +++ b/app/Models/CouponLog.php @@ -3,6 +3,7 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; /** * 优惠券使用日志. @@ -12,4 +13,19 @@ class CouponLog extends Model public const UPDATED_AT = null; protected $table = 'coupon_log'; + + public function coupon(): BelongsTo + { + return $this->belongsTo(User::class); + } + + public function goods(): BelongsTo + { + return $this->belongsTo(Goods::class); + } + + public function order(): BelongsTo + { + return $this->belongsTo(Order::class); + } } diff --git a/app/Models/Goods.php b/app/Models/Goods.php index b4f3f031..b97fa3a4 100644 --- a/app/Models/Goods.php +++ b/app/Models/Goods.php @@ -2,7 +2,10 @@ namespace App\Models; +use App\Casts\data_rate; +use App\Casts\money; use App\Utils\Helpers; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; @@ -16,7 +19,7 @@ class Goods extends Model protected $table = 'goods'; - protected $casts = ['deleted_at' => 'datetime']; + protected $casts = ['price' => money::class, 'renew' => money::class, 'speed_limit' => data_rate::class, 'deleted_at' => 'datetime']; protected $guarded = []; @@ -25,36 +28,16 @@ class Goods extends Model return $this->hasMany(Order::class); } - public function scopeType($query, $type) + public function scopeType(Builder $query, int $type): Builder { return $query->whereType($type)->whereStatus(1)->orderByDesc('sort'); } - public function getPriceAttribute($value) - { - return $value / 100; - } - - public function setPriceAttribute($value): void - { - $this->attributes['price'] = $value * 100; - } - public function getPriceTagAttribute(): string { return Helpers::getPriceTag($this->price); } - public function getRenewAttribute($value) - { - return $value / 100; - } - - public function setRenewAttribute($value): void - { - $this->attributes['renew'] = $value * 100; - } - public function getRenewTagAttribute(): string { return Helpers::getPriceTag($this->renew); @@ -64,14 +47,4 @@ class Goods extends Model { return formatBytes($this->attributes['traffic'] * MB); } - - public function setSpeedLimitAttribute($value) - { - return $this->attributes['speed_limit'] = $value * Mbps; - } - - public function getSpeedLimitAttribute($value) - { - return $value / Mbps; - } } diff --git a/app/Models/Invite.php b/app/Models/Invite.php index f25043ce..11443e80 100644 --- a/app/Models/Invite.php +++ b/app/Models/Invite.php @@ -3,6 +3,7 @@ namespace App\Models; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; @@ -20,7 +21,7 @@ class Invite extends Model protected $guarded = []; - public function scopeUid($query) + public function scopeUid(Builder $query): Builder { return $query->whereInviterId(Auth::id()); } diff --git a/app/Models/Marketing.php b/app/Models/Marketing.php index a72dff96..83543f2f 100644 --- a/app/Models/Marketing.php +++ b/app/Models/Marketing.php @@ -15,10 +15,11 @@ class Marketing extends Model public function getStatusLabelAttribute(): string { - return [ + return match ($this->attributes['status']) { -1 => '失败', 0 => '待推送', 1 => '成功', - ][$this->attributes['status']] ?? ''; + default => '', + }; } } diff --git a/app/Models/Node.php b/app/Models/Node.php index 0c4d9cf5..9f069fbc 100644 --- a/app/Models/Node.php +++ b/app/Models/Node.php @@ -2,7 +2,9 @@ namespace App\Models; +use App\Casts\data_rate; use App\Utils\IP; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; @@ -19,7 +21,7 @@ class Node extends Model protected $guarded = []; - protected $casts = ['profile' => 'array']; + protected $casts = ['speed_limit' => data_rate::class, 'profile' => 'array']; public function labels(): BelongsToMany { @@ -96,7 +98,7 @@ class Node extends Model return $this->hasOne(Level::class, 'level', 'level'); } - public function users() + public function users(): Collection { return User::activeUser() ->where('level', '>=', $this->attributes['level']) @@ -140,25 +142,16 @@ class Node extends Model return array_map('trim', explode(',', $ip)); } - public function getSpeedLimitAttribute($value) - { - return $value / Mbps; - } - - public function setSpeedLimitAttribute($value) - { - return $this->attributes['speed_limit'] = $value * Mbps; - } - public function getTypeLabelAttribute(): string { - return [ + return match ($this->attributes['type']) { 0 => 'Shadowsocks', 1 => 'ShadowsocksR', 2 => 'V2Ray', 3 => 'Trojan', 4 => 'VNet', - ][$this->attributes['type']] ?? 'UnKnown'; + default => 'UnKnown', + }; } public function getHostAttribute(): string diff --git a/app/Models/NodeHeartbeat.php b/app/Models/NodeHeartbeat.php index 7dcee9d3..50585289 100644 --- a/app/Models/NodeHeartbeat.php +++ b/app/Models/NodeHeartbeat.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; /** @@ -15,7 +16,7 @@ class NodeHeartbeat extends Model protected $guarded = []; - public function scopeRecently($query) + public function scopeRecently(Builder $query): Builder { return $query->where('log_time', '>=', strtotime(config('tasks.recently_heartbeat')))->latest('log_time'); } diff --git a/app/Models/Order.php b/app/Models/Order.php index dacda2e0..28d54d3c 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -2,8 +2,10 @@ namespace App\Models; +use App\Casts\money; use App\Utils\Helpers; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasOne; @@ -16,13 +18,13 @@ class Order extends Model { use Sortable; - public $sortable = ['id', 'sn', 'expired_at', 'created_at']; + public array $sortable = ['id', 'sn', 'expired_at', 'created_at']; protected $table = 'order'; protected $guarded = []; - protected $casts = ['expired_at' => 'datetime']; + protected $casts = ['origin_amount' => money::class, 'amount' => money::class, 'expired_at' => 'datetime']; public function user(): BelongsTo { @@ -44,50 +46,55 @@ class Order extends Model return $this->hasOne(Payment::class); } - public function scopeUid($query, $uid = null) + public function scopeUid(Builder $query, int $uid = 0): Builder { return $query->whereUserId($uid ?: Auth::id()); } - public function scopeRecentUnPay($query, int $minutes = 0) + public function scopeRecentUnPay(Builder $query, int $minutes = 0): Builder { if (! $minutes) { - $minutes = config('tasks.close.orders'); + $minutes = (int) config('tasks.close.orders'); } - return $query->whereStatus(0)->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-'.$minutes.' minutes'))); + return $query->whereStatus(0)->where('created_at', '<=', date('Y-m-d H:i:s', strtotime("-$minutes minutes"))); } - public function scopeUserPrepay($query, $uid = null) + public function scopeUserPrepay(Builder $query, int $uid = 0): Builder { return $query->uid($uid)->whereStatus(3)->oldest(); } - public function scopeActive($query) + public function scopeActive(Builder $query): Builder { return $query->whereIsExpire(0)->whereStatus(2); } - public function scopeActivePlan($query) + public function scopeActivePlan(Builder $query): Builder { - return $query->active()->with('goods')->whereHas('goods', static function ($query) { + return $query->active()->isPlan(); + } + + public function scopeIsPlan(Builder $query): Builder + { + return $query->with('goods')->whereHas('goods', function ($query) { $query->whereType(2); }); } - public function scopeActivePackage($query) + public function scopeActivePackage(Builder $query): Builder { return $query->active()->with('goods')->whereHas('goods', static function ($query) { $query->whereType(1); }); } - public function scopeUserActivePlan($query, $uid = null) + public function scopeUserActivePlan(Builder $query, int $uid = 0): Builder { return $query->uid($uid)->activePlan(); } - public function scopeUserActivePackage($query, $uid = null) + public function scopeUserActivePackage(Builder $query, int $uid = 0): Builder { return $query->uid($uid)->activePackage(); } @@ -122,7 +129,7 @@ class Order extends Model return $this->statusTags($this->attributes['status'], $this->attributes['is_expire']); } - public function statusTags($status, $expire, $isHtml = true): string + public function statusTags(int $status, bool $expire, bool $isHtml = true): string { switch ($status) { case -1: @@ -162,31 +169,11 @@ class Order extends Model return $label; } - public function getOriginAmountAttribute($value) - { - return $value / 100; - } - - public function setOriginAmountAttribute($value) - { - return $this->attributes['origin_amount'] = $value * 100; - } - public function getOriginAmountTagAttribute(): string { return Helpers::getPriceTag($this->origin_amount); } - public function getAmountAttribute($value) - { - return $value / 100; - } - - public function setAmountAttribute($value) - { - return $this->attributes['amount'] = $value * 100; - } - public function getAmountTagAttribute(): string { return Helpers::getPriceTag($this->amount); @@ -195,7 +182,7 @@ class Order extends Model // 支付渠道 public function getPayTypeLabelAttribute(): string { - return [ + return match ($this->attributes['pay_type']) { 0 => trans('common.payment.credit'), 1 => trans('common.payment.alipay'), 2 => trans('common.payment.qq'), @@ -204,7 +191,8 @@ class Order extends Model 5 => 'PayPal', 6 => 'Stripe', 7 => trans('common.payment.manual'), - ][$this->attributes['pay_type']] ?? ''; + default => '', + }; } // 支付图标 diff --git a/app/Models/Payment.php b/app/Models/Payment.php index 27a1c03c..cdaf5efe 100644 --- a/app/Models/Payment.php +++ b/app/Models/Payment.php @@ -2,8 +2,10 @@ namespace App\Models; +use App\Casts\money; use App\Utils\Helpers; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -16,7 +18,9 @@ class Payment extends Model protected $guarded = []; - public function scopeUid($query) + protected $casts = ['amount' => money::class]; + + public function scopeUid(Builder $query): Builder { return $query->whereUserId(Auth::id()); } @@ -46,16 +50,6 @@ class Payment extends Model return $this->update(['status' => 1]); } - public function getAmountAttribute($value) - { - return $value / 100; - } - - public function setAmountAttribute($value) - { - return $this->attributes['amount'] = $value * 100; - } - public function getAmountTagAttribute(): string { return Helpers::getPriceTag($this->amount); diff --git a/app/Models/PaymentCallback.php b/app/Models/PaymentCallback.php index dc216550..fcb69978 100644 --- a/app/Models/PaymentCallback.php +++ b/app/Models/PaymentCallback.php @@ -15,11 +15,12 @@ class PaymentCallback extends Model public function getStatusLabelAttribute(): string { - return [ + return match ($this->attributes['status']) { 'WAIT_BUYER_PAY' => '等待买家付款', 'WAIT_SELLER_SEND_GOODS' => '等待卖家发货', 'TRADE_SUCCESS' => '交易成功', 'PAID' => '支付完成', - ][$this->attributes['status']] ?? ''; + default => '', + }; } } diff --git a/app/Models/ReferralApply.php b/app/Models/ReferralApply.php index e00bc813..6990719b 100644 --- a/app/Models/ReferralApply.php +++ b/app/Models/ReferralApply.php @@ -2,8 +2,10 @@ namespace App\Models; +use App\Casts\money; use App\Utils\Helpers; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -14,11 +16,11 @@ class ReferralApply extends Model { protected $table = 'referral_apply'; - protected $casts = ['link_logs' => 'array']; + protected $casts = ['before' => money::class, 'after' => money::class, 'amount' => money::class, 'link_logs' => 'array']; protected $guarded = []; - public function scopeUid($query) + public function scopeUid(Builder $query): Builder { return $query->whereUserId(Auth::id()); } @@ -28,41 +30,11 @@ class ReferralApply extends Model return $this->belongsTo(User::class); } - public function referral_logs() + public function referral_logs(): ReferralLog|\Illuminate\Database\Query\Builder { return ReferralLog::whereIn('id', $this->link_logs); } - public function getBeforeAttribute($value) - { - return $value / 100; - } - - public function setBeforeAttribute($value): void - { - $this->attributes['before'] = $value * 100; - } - - public function getAfterAttribute($value) - { - return $value / 100; - } - - public function setAfterAttribute($value): void - { - $this->attributes['after'] = $value * 100; - } - - public function getAmountAttribute($value) - { - return $value / 100; - } - - public function setAmountAttribute($value): void - { - $this->attributes['amount'] = $value * 100; - } - public function getAmountTagAttribute(): string { return Helpers::getPriceTag($this->amount); diff --git a/app/Models/ReferralLog.php b/app/Models/ReferralLog.php index c8916aaa..0ce681ed 100644 --- a/app/Models/ReferralLog.php +++ b/app/Models/ReferralLog.php @@ -2,8 +2,10 @@ namespace App\Models; +use App\Casts\money; use App\Utils\Helpers; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -14,9 +16,11 @@ class ReferralLog extends Model { protected $table = 'referral_log'; + protected $casts = ['amount' => money::class, 'commission' => money::class]; + protected $guarded = []; - public function scopeUid($query) + public function scopeUid(Builder $query): Builder { return $query->whereInviterId(Auth::id()); } @@ -36,26 +40,6 @@ class ReferralLog extends Model return $this->belongsTo(Order::class); } - public function getAmountAttribute($value) - { - return $value / 100; - } - - public function getCommissionAttribute($value) - { - return $value / 100; - } - - public function setAmountAttribute($value): void - { - $this->attributes['amount'] = $value * 100; - } - - public function setCommissionAttribute($value): void - { - $this->attributes['commission'] = $value * 100; - } - public function getAmountTagAttribute(): string { return Helpers::getPriceTag($this->amount); diff --git a/app/Models/Rule.php b/app/Models/Rule.php index 0dc6918c..ef57eceb 100644 --- a/app/Models/Rule.php +++ b/app/Models/Rule.php @@ -16,28 +16,30 @@ class Rule extends Model protected $guarded = []; - public function getTypeLabelAttribute(): string - { - return [ - 1 => trans('admin.rule.type.reg'), - 2 => trans('admin.rule.type.domain'), - 3 => trans('admin.rule.type.ip'), - 4 => trans('admin.rule.type.protocol'), - ][$this->attributes['type']] ?? trans('common.status.unknown'); - } - - public function getTypeApiLabelAttribute(): string - { - return [ - 1 => 'reg', - 2 => 'domain', - 3 => 'ip', - 4 => 'protocol', - ][$this->attributes['type']] ?? 'unknown'; - } - public function rule_groups(): BelongsToMany { return $this->belongsToMany(RuleGroup::class); } + + public function getTypeLabelAttribute(): string + { + return match ($this->attributes['type']) { + 1 => trans('admin.rule.type.reg'), + 2 => trans('admin.rule.type.domain'), + 3 => trans('admin.rule.type.ip'), + 4 => trans('admin.rule.type.protocol'), + default => trans('common.status.unknown'), + }; + } + + public function getTypeApiLabelAttribute(): string + { + return match ($this->attributes['type']) { + 1 => 'reg', + 2 => 'domain', + 3 => 'ip', + 4 => 'protocol', + default => 'unknown', + }; + } } diff --git a/app/Models/RuleGroup.php b/app/Models/RuleGroup.php index 4af89c72..63463750 100644 --- a/app/Models/RuleGroup.php +++ b/app/Models/RuleGroup.php @@ -14,19 +14,16 @@ class RuleGroup extends Model protected $guarded = []; - public function getTypeLabelAttribute(): string - { - if ($this->attributes['type']) { - $type_label = ''.trans('admin.rule.group.type.off').''; - } else { - $type_label = ''.trans('admin.rule.group.type.on').''; - } - - return $type_label; - } - public function rules(): BelongsToMany { return $this->belongsToMany(Rule::class); } + + public function getTypeLabelAttribute(): string + { + return match ($this->attributes['type']) { + 0 => ''.trans('admin.rule.group.type.on').'', + 1 => ''.trans('admin.rule.group.type.off').'', + }; + } } diff --git a/app/Models/SsConfig.php b/app/Models/SsConfig.php index 4fe923c8..3a277973 100644 --- a/app/Models/SsConfig.php +++ b/app/Models/SsConfig.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; /** @@ -15,14 +16,14 @@ class SsConfig extends Model protected $guarded = []; - public function scopeDefault($query): void + public function scopeDefault(Builder $query): Builder { // 筛选默认 - $query->whereIsDefault(1); + return $query->whereIsDefault(1); } - public function scopeType($query, int $type): void + public function scopeType(Builder $query, int $type): Builder { // 筛选类型 - $query->whereType($type); + return $query->whereType($type); } public function setDefault(): bool diff --git a/app/Models/Ticket.php b/app/Models/Ticket.php index ad9085f0..c42cea1c 100644 --- a/app/Models/Ticket.php +++ b/app/Models/Ticket.php @@ -3,6 +3,7 @@ namespace App\Models; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -16,7 +17,7 @@ class Ticket extends Model protected $guarded = []; - public function scopeUid($query) + public function scopeUid(Builder $query): Builder { return $query->whereUserId(Auth::id()); } diff --git a/app/Models/User.php b/app/Models/User.php index 4c95a178..558f940a 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,9 +2,12 @@ namespace App\Models; +use App\Casts\data_rate; +use App\Casts\money; use App\Utils\Helpers; use App\Utils\QQInfo; use Hash; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -23,11 +26,11 @@ class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable, HasRoles, Sortable; - public $sortable = ['id', 'credit', 'port', 't', 'expired_at']; + public array $sortable = ['id', 'credit', 'port', 't', 'expired_at']; protected $table = 'user'; - protected $casts = ['expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d']; + protected $casts = ['credit' => money::class, 'speed_limit' => data_rate::class, 'expired_at' => 'date:Y-m-d', 'reset_time' => 'date:Y-m-d', 'ban_time' => 'date:Y-m-d']; protected $guarded = []; @@ -178,16 +181,6 @@ class User extends Authenticatable return Level::whereLevel($this->attributes['level'])->first()->name; } - public function getCreditAttribute() - { - return $this->attributes['credit'] / 100; - } - - public function setCreditAttribute($value) - { - return $this->attributes['credit'] = $value * 100; - } - public function getCreditTagAttribute(): string { return Helpers::getPriceTag($this->credit); @@ -198,21 +191,11 @@ class User extends Authenticatable return formatBytes($this->attributes['transfer_enable']); } - public function getSpeedLimitAttribute() - { - return $this->attributes['speed_limit'] / Mbps; - } - - public function setPasswordAttribute($password): string + public function setPasswordAttribute(string $password): string { return $this->attributes['password'] = Hash::make($password); } - public function setSpeedLimitAttribute($value) - { - return $this->attributes['speed_limit'] = $value * Mbps; - } - public function getAvatarAttribute(): string { if ($this->qq) { @@ -229,27 +212,27 @@ class User extends Authenticatable return $url; } - public function scopeActiveUser($query) + public function scopeActiveUser(Builder $query): Builder { return $query->where('status', '<>', -1)->whereEnable(1); } - public function scopeBannedUser($query) + public function scopeBannedUser(Builder $query): Builder { return $query->where('status', '<>', -1)->whereEnable(0); } - public function nodes($userLevel = -1, $userGroupId = -1) + public function nodes(?int $userLevel = null, int $userGroupId = 0): Node|Builder { - if ($userGroupId === -1 && $this->attributes['user_group_id']) { + if ($userGroupId === 0 && $this->attributes['user_group_id']) { // 使用默认的用户分组 $query = $this->userGroup->nodes(); - } elseif ($userGroupId !== -1 && $userGroupId) { + } elseif ($userGroupId) { // 使用给的用户分组 $query = UserGroup::findOrFail($userGroupId)->nodes(); - } else { + } else { // 无用户分组 $query = Node::query(); } - return $query->whereStatus(1)->where('level', '<=', $userLevel !== -1 && $userLevel !== null ? $userLevel : $this->attributes['level'] ?? 0); + return $query->whereStatus(1)->where('level', '<=', $userLevel ?? $this->attributes['level'] ?? 0); } public function userGroup(): BelongsTo @@ -277,7 +260,7 @@ class User extends Authenticatable } public function isNotCompleteOrderByUserId(int $userId): bool - { // 添加用户余额 + { return Order::uid($userId)->whereIn('status', [0, 1])->exists(); } diff --git a/app/Models/UserCreditLog.php b/app/Models/UserCreditLog.php index e1c41820..a82da7b1 100644 --- a/app/Models/UserCreditLog.php +++ b/app/Models/UserCreditLog.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Casts\money; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -14,6 +15,8 @@ class UserCreditLog extends Model protected $table = 'user_credit_log'; + protected $casts = ['before' => money::class, 'after' => money::class, 'amount' => money::class]; + protected $guarded = []; public function user(): BelongsTo @@ -25,34 +28,4 @@ class UserCreditLog extends Model { return $this->belongsTo(Order::class); } - - public function getBeforeAttribute($value) - { - return $value / 100; - } - - public function setBeforeAttribute($value) - { - return $this->attributes['before'] = $value * 100; - } - - public function getAfterAttribute($value) - { - return $value / 100; - } - - public function setAfterAttribute($value) - { - return $this->attributes['after'] = $value * 100; - } - - public function getAmountAttribute($value) - { - return $value / 100; - } - - public function setAmountAttribute($value) - { - return $this->attributes['amount'] = $value * 100; - } } diff --git a/app/Models/UserDailyDataFlow.php b/app/Models/UserDailyDataFlow.php index 25bb3149..e08b0252 100644 --- a/app/Models/UserDailyDataFlow.php +++ b/app/Models/UserDailyDataFlow.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -26,9 +27,8 @@ class UserDailyDataFlow extends Model return $this->belongsTo(Node::class); } - // 用户每天使用总流量 - public function scopeUserDaily($query, $uid) - { + public function scopeUserDaily(Builder $query, int $uid): Builder + { // 用户每天使用总流量 return $query->whereUserId($uid)->whereNodeId(null); } } diff --git a/app/Models/UserHourlyDataFlow.php b/app/Models/UserHourlyDataFlow.php index df5e85bf..64046ed9 100644 --- a/app/Models/UserHourlyDataFlow.php +++ b/app/Models/UserHourlyDataFlow.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -27,12 +28,12 @@ class UserHourlyDataFlow extends Model } // 用户每时使用总流量 - public function scopeUserHourly($query, $uid) + public function scopeUserHourly(Builder $query, int $uid): Builder { return $query->whereUserId($uid)->whereNodeId(null); } - public function scopeUserRecentUsed($query, $uid) + public function scopeUserRecentUsed(Builder $query, int $uid): Builder { return $query->userHourly($uid)->where('created_at', '>=', date('Y-m-d H:i:s', time() - 3900)); } diff --git a/app/Models/UserSubscribe.php b/app/Models/UserSubscribe.php index 87c1b8ba..59eb7146 100644 --- a/app/Models/UserSubscribe.php +++ b/app/Models/UserSubscribe.php @@ -3,6 +3,7 @@ namespace App\Models; use Auth; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -15,13 +16,13 @@ class UserSubscribe extends Model { use Sortable; - public $sortable = ['id', 'times']; + public array $sortable = ['id', 'times']; protected $table = 'user_subscribe'; protected $guarded = []; - public function scopeUid($query) + public function scopeUid(Builder $query): Builder { return $query->whereUserId(Auth::id()); } diff --git a/app/Models/Verify.php b/app/Models/Verify.php index d720c131..9bcbcd4c 100644 --- a/app/Models/Verify.php +++ b/app/Models/Verify.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -15,7 +16,7 @@ class Verify extends Model protected $guarded = []; // 筛选类型 - public function scopeType($query, $type) + public function scopeType(Builder $query, int $type): Builder { return $query->whereType($type); } diff --git a/app/Models/VerifyCode.php b/app/Models/VerifyCode.php index 6b520001..e958d49e 100644 --- a/app/Models/VerifyCode.php +++ b/app/Models/VerifyCode.php @@ -2,6 +2,7 @@ namespace App\Models; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; /** @@ -13,7 +14,7 @@ class VerifyCode extends Model protected $guarded = []; - public function scopeRecentUnused($query) + public function scopeRecentUnused(Builder $query): Builder { return $query->whereStatus(0)->where('created_at', '<=', date('Y-m-d H:i:s', strtotime('-'.config('tasks.close.verify').' minutes'))); } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 3da5e785..61e2bfd2 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -44,7 +44,7 @@ class AppServiceProvider extends ServiceProvider Paginator::useBootstrap(); // 检测是否强制跳转https - if (env('SESSION_SECURE_COOKIE', false)) { // todo + if (config('session.secure')) { URL::forceScheme('https'); } diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index 40ec7ea0..1069fdee 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -79,14 +79,22 @@ class OrderService private function setPrepaidPlan(): bool { // 设置预支付套餐, 刷新账号有效时间用于流量重置判断 - Order::whereId($this->order->id)->first()->prepay(); // 直接编辑$this->order->prepay() [手动修改]会加不上 + $this->order->prepay(); - return self::$user->update(['expired_at' => date('Y-m-d', strtotime(self::$user->expired_at.' +'.self::$goods->days.' days'))]); + return self::$user->update(['expired_at' => $this->getFinallyExpiredTime()]); + } + + public function getFinallyExpiredTime(): string + { // 推算最新的到期时间 + $orders = self::$user->orders()->whereIn('status', [2, 3])->whereIsExpire(0)->isPlan()->get(); + $current = $orders->where('status', '==', 2)->first(); + + return ($current->expired_at ?? now())->addDays($orders->except($current->id ?? 0)->sum('goods.days'))->format('Y-m-d'); } public function activatePlan(): bool { // 激活套餐 - Order::whereId($this->order->id)->first()->update(['expired_at' => date('Y-m-d H:i:s', strtotime(self::$goods->days.' days'))]); + $this->order->update(['expired_at' => date('Y-m-d H:i:s', strtotime(self::$goods->days.' days'))]); $oldData = self::$user->transfer_enable; $updateData = [ 'invite_num' => self::$user->invite_num + (self::$goods->invite_num ?: 0), @@ -109,27 +117,23 @@ class OrderService public function resetTimeAndData(string|null $expired_at = null): array { // 计算下次重置与账号过期时间 - $data = ['u' => 0, 'd' => 0]; - // 账号有效期 - if (! $expired_at) { - $expired_at = date('Y-m-d', strtotime(self::$goods->days.' days')); - foreach (Order::userPrepay($this->order->user_id)->with('goods')->get() as $paidOrder) {//拿出可能存在的其余套餐, 推算最新的到期时间 - //取出对应套餐信息 - $expired_at = date('Y-m-d', strtotime("$expired_at +".$paidOrder->goods->days.' days')); - } - $data['expired_at'] = $expired_at; + if (! $expired_at) { // 账号有效期 + $expired_at = $this->getFinallyExpiredTime(); } //账号流量重置日期 - $nextResetTime = date('Y-m-d', strtotime(self::$goods->period.' days')); + $nextResetTime = now()->addDays(self::$goods->period)->format('Y-m-d'); if ($nextResetTime >= $expired_at) { $nextResetTime = null; } - return array_merge($data, [ + return [ + 'u' => 0, + 'd' => 0, 'transfer_enable' => self::$goods->traffic * MB, + 'expired_at' => $expired_at, 'reset_time' => $nextResetTime, - ]); + ]; } private function setCommissionExpense(User $user) diff --git a/resources/views/admin/config/system.blade.php b/resources/views/admin/config/system.blade.php index 35775476..03420224 100644 --- a/resources/views/admin/config/system.blade.php +++ b/resources/views/admin/config/system.blade.php @@ -125,7 +125,7 @@ - + @@ -473,8 +473,7 @@ function disablePayment(op) { for (let i = 1; i < op.length; i++) { - @json($payments). - includes(op[i].value) + @json($payments).includes(op[i].value) ? op[i].disabled = false : op[i].disabled = true; }