mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-24 03:57:27 +08:00
feat: multiple improvements and bug fixes
- Add gift card redemption feature - Resolve custom range selection issue in overview - Allow log page size to be modified - Add subscription path change notification - Improve dynamic node rate feature - Support markdown documentation display for plugins - Reduce power reset service logging - Fix backend version number not updating after update
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* App\Models\GiftCardCode
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $template_id 模板ID
|
||||
* @property GiftCardTemplate $template 关联模板
|
||||
* @property string $code 兑换码
|
||||
* @property string|null $batch_id 批次ID
|
||||
* @property int $status 状态
|
||||
* @property int|null $user_id 使用用户ID
|
||||
* @property int|null $used_at 使用时间
|
||||
* @property int|null $expires_at 过期时间
|
||||
* @property array|null $actual_rewards 实际奖励
|
||||
* @property int $usage_count 使用次数
|
||||
* @property int $max_usage 最大使用次数
|
||||
* @property array|null $metadata 额外数据
|
||||
* @property int $created_at
|
||||
* @property int $updated_at
|
||||
*/
|
||||
class GiftCardCode extends Model
|
||||
{
|
||||
protected $table = 'v2_gift_card_code';
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
// 状态常量
|
||||
const STATUS_UNUSED = 0; // 未使用
|
||||
const STATUS_USED = 1; // 已使用
|
||||
const STATUS_EXPIRED = 2; // 已过期
|
||||
const STATUS_DISABLED = 3; // 已禁用
|
||||
|
||||
protected $fillable = [
|
||||
'template_id',
|
||||
'code',
|
||||
'batch_id',
|
||||
'status',
|
||||
'user_id',
|
||||
'used_at',
|
||||
'expires_at',
|
||||
'actual_rewards',
|
||||
'usage_count',
|
||||
'max_usage',
|
||||
'metadata'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'timestamp',
|
||||
'updated_at' => 'timestamp',
|
||||
'used_at' => 'timestamp',
|
||||
'expires_at' => 'timestamp',
|
||||
'actual_rewards' => 'array',
|
||||
'metadata' => 'array'
|
||||
];
|
||||
|
||||
/**
|
||||
* 获取状态映射
|
||||
*/
|
||||
public static function getStatusMap(): array
|
||||
{
|
||||
return [
|
||||
self::STATUS_UNUSED => '未使用',
|
||||
self::STATUS_USED => '已使用',
|
||||
self::STATUS_EXPIRED => '已过期',
|
||||
self::STATUS_DISABLED => '已禁用',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态名称
|
||||
*/
|
||||
public function getStatusNameAttribute(): string
|
||||
{
|
||||
return self::getStatusMap()[$this->status] ?? '未知状态';
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联礼品卡模板
|
||||
*/
|
||||
public function template(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(GiftCardTemplate::class, 'template_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联使用用户
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联使用记录
|
||||
*/
|
||||
public function usages(): HasMany
|
||||
{
|
||||
return $this->hasMany(GiftCardUsage::class, 'code_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否可用
|
||||
*/
|
||||
public function isAvailable(): bool
|
||||
{
|
||||
// 检查状态
|
||||
if ($this->status !== self::STATUS_UNUSED) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查是否过期
|
||||
if ($this->expires_at && $this->expires_at < time()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查使用次数
|
||||
if ($this->usage_count >= $this->max_usage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否已过期
|
||||
*/
|
||||
public function isExpired(): bool
|
||||
{
|
||||
return $this->expires_at && $this->expires_at < time();
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记为已使用
|
||||
*/
|
||||
public function markAsUsed(User $user): bool
|
||||
{
|
||||
$this->status = self::STATUS_USED;
|
||||
$this->user_id = $user->id;
|
||||
$this->used_at = time();
|
||||
$this->usage_count += 1;
|
||||
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记为已过期
|
||||
*/
|
||||
public function markAsExpired(): bool
|
||||
{
|
||||
$this->status = self::STATUS_EXPIRED;
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记为已禁用
|
||||
*/
|
||||
public function markAsDisabled(): bool
|
||||
{
|
||||
$this->status = self::STATUS_DISABLED;
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成兑换码
|
||||
*/
|
||||
public static function generateCode(string $prefix = 'GC'): string
|
||||
{
|
||||
do {
|
||||
$code = $prefix . strtoupper(substr(md5(uniqid(mt_rand(), true)), 0, 12));
|
||||
} while (self::where('code', $code)->exists());
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量生成兑换码
|
||||
*/
|
||||
public static function batchGenerate(int $templateId, int $count, array $options = []): string
|
||||
{
|
||||
$batchId = uniqid('batch_');
|
||||
$prefix = $options['prefix'] ?? 'GC';
|
||||
$expiresAt = $options['expires_at'] ?? null;
|
||||
$maxUsage = $options['max_usage'] ?? 1;
|
||||
|
||||
$codes = [];
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$codes[] = [
|
||||
'template_id' => $templateId,
|
||||
'code' => self::generateCode($prefix),
|
||||
'batch_id' => $batchId,
|
||||
'status' => self::STATUS_UNUSED,
|
||||
'expires_at' => $expiresAt,
|
||||
'max_usage' => $maxUsage,
|
||||
'created_at' => time(),
|
||||
'updated_at' => time(),
|
||||
];
|
||||
}
|
||||
|
||||
self::insert($codes);
|
||||
|
||||
return $batchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实际奖励(用于盲盒等)
|
||||
*/
|
||||
public function setActualRewards(array $rewards): bool
|
||||
{
|
||||
$this->actual_rewards = $rewards;
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实际奖励
|
||||
*/
|
||||
public function getActualRewards(): array
|
||||
{
|
||||
return $this->actual_rewards ?? $this->template->rewards ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查兑换码格式
|
||||
*/
|
||||
public static function validateCodeFormat(string $code): bool
|
||||
{
|
||||
// 基本格式验证:字母数字组合,长度8-32
|
||||
return preg_match('/^[A-Z0-9]{8,32}$/', $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据批次ID获取兑换码
|
||||
*/
|
||||
public static function getByBatchId(string $batchId)
|
||||
{
|
||||
return self::where('batch_id', $batchId)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理过期兑换码
|
||||
*/
|
||||
public static function cleanupExpired(): int
|
||||
{
|
||||
$count = self::where('status', self::STATUS_UNUSED)
|
||||
->where('expires_at', '<', time())
|
||||
->count();
|
||||
|
||||
self::where('status', self::STATUS_UNUSED)
|
||||
->where('expires_at', '<', time())
|
||||
->update(['status' => self::STATUS_EXPIRED]);
|
||||
|
||||
return $count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
/**
|
||||
* App\Models\GiftCardTemplate
|
||||
*
|
||||
* @property int $id
|
||||
* @property string $name 礼品卡名称
|
||||
* @property string|null $description 礼品卡描述
|
||||
* @property int $type 卡片类型
|
||||
* @property boolean $status 状态
|
||||
* @property array|null $conditions 使用条件配置
|
||||
* @property array $rewards 奖励配置
|
||||
* @property array|null $limits 限制条件
|
||||
* @property array|null $special_config 特殊配置
|
||||
* @property string|null $icon 卡片图标
|
||||
* @property string $theme_color 主题色
|
||||
* @property int $sort 排序
|
||||
* @property int $admin_id 创建管理员ID
|
||||
* @property int $created_at
|
||||
* @property int $updated_at
|
||||
*/
|
||||
class GiftCardTemplate extends Model
|
||||
{
|
||||
protected $table = 'v2_gift_card_template';
|
||||
protected $dateFormat = 'U';
|
||||
|
||||
// 卡片类型常量
|
||||
const TYPE_GENERAL = 1; // 通用礼品卡
|
||||
const TYPE_PLAN = 2; // 套餐礼品卡
|
||||
const TYPE_MYSTERY = 3; // 盲盒礼品卡
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
'type',
|
||||
'status',
|
||||
'conditions',
|
||||
'rewards',
|
||||
'limits',
|
||||
'special_config',
|
||||
'icon',
|
||||
'background_image',
|
||||
'theme_color',
|
||||
'sort',
|
||||
'admin_id'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'timestamp',
|
||||
'updated_at' => 'timestamp',
|
||||
'conditions' => 'array',
|
||||
'rewards' => 'array',
|
||||
'limits' => 'array',
|
||||
'special_config' => 'array',
|
||||
'status' => 'boolean'
|
||||
];
|
||||
|
||||
/**
|
||||
* 获取卡片类型映射
|
||||
*/
|
||||
public static function getTypeMap(): array
|
||||
{
|
||||
return [
|
||||
self::TYPE_GENERAL => '通用礼品卡',
|
||||
self::TYPE_PLAN => '套餐礼品卡',
|
||||
self::TYPE_MYSTERY => '盲盒礼品卡',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型名称
|
||||
*/
|
||||
public function getTypeNameAttribute(): string
|
||||
{
|
||||
return self::getTypeMap()[$this->type] ?? '未知类型';
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联兑换码
|
||||
*/
|
||||
public function codes(): HasMany
|
||||
{
|
||||
return $this->hasMany(GiftCardCode::class, 'template_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联使用记录
|
||||
*/
|
||||
public function usages(): HasMany
|
||||
{
|
||||
return $this->hasMany(GiftCardUsage::class, 'template_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联统计数据
|
||||
*/
|
||||
public function stats(): HasMany
|
||||
{
|
||||
return $this->hasMany(GiftCardUsage::class, 'template_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否可用
|
||||
*/
|
||||
public function isAvailable(): bool
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户是否满足使用条件
|
||||
*/
|
||||
public function checkUserConditions(User $user): bool
|
||||
{
|
||||
switch ($this->type) {
|
||||
case self::TYPE_GENERAL:
|
||||
$rewards = $this->rewards ?? [];
|
||||
if (isset($rewards['transfer_enable']) || isset($rewards['expire_days']) || isset($rewards['reset_package'])) {
|
||||
if (!$user->plan_id) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case self::TYPE_PLAN:
|
||||
if ($user->isActive()) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
$conditions = $this->conditions ?? [];
|
||||
|
||||
// 检查新用户条件
|
||||
if (isset($conditions['new_user_only']) && $conditions['new_user_only']) {
|
||||
$maxDays = $conditions['new_user_max_days'] ?? 7;
|
||||
if ($user->created_at < (time() - ($maxDays * 86400))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查付费用户条件
|
||||
if (isset($conditions['paid_user_only']) && $conditions['paid_user_only']) {
|
||||
$paidOrderExists = $user->orders()->where('status', Order::STATUS_COMPLETED)->exists();
|
||||
if (!$paidOrderExists) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查允许的套餐
|
||||
if (isset($conditions['allowed_plans']) && $user->plan_id) {
|
||||
if (!in_array($user->plan_id, $conditions['allowed_plans'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查是否需要邀请人
|
||||
if (isset($conditions['require_invite']) && $conditions['require_invite']) {
|
||||
if (!$user->invite_user_id) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算实际奖励
|
||||
*/
|
||||
public function calculateActualRewards(User $user): array
|
||||
{
|
||||
$baseRewards = $this->rewards;
|
||||
$actualRewards = $baseRewards;
|
||||
|
||||
// 处理盲盒随机奖励
|
||||
if ($this->type === self::TYPE_MYSTERY && isset($this->rewards['random_rewards'])) {
|
||||
$randomRewards = $this->rewards['random_rewards'];
|
||||
$totalWeight = array_sum(array_column($randomRewards, 'weight'));
|
||||
$random = mt_rand(1, $totalWeight);
|
||||
$currentWeight = 0;
|
||||
|
||||
foreach ($randomRewards as $reward) {
|
||||
$currentWeight += $reward['weight'];
|
||||
if ($random <= $currentWeight) {
|
||||
$actualRewards = array_merge($actualRewards, $reward);
|
||||
unset($actualRewards['weight']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理节日等特殊奖励(通用逻辑)
|
||||
if (isset($this->special_config['festival_bonus'])) {
|
||||
$now = time();
|
||||
$festivalConfig = $this->special_config;
|
||||
|
||||
if (isset($festivalConfig['start_time']) && isset($festivalConfig['end_time'])) {
|
||||
if ($now >= $festivalConfig['start_time'] && $now <= $festivalConfig['end_time']) {
|
||||
$bonus = (float) ($festivalConfig['festival_bonus'] ?? 1.0);
|
||||
if ($bonus > 1.0) {
|
||||
foreach ($actualRewards as $key => &$value) {
|
||||
if (is_numeric($value)) {
|
||||
$value = intval($value * $bonus);
|
||||
}
|
||||
}
|
||||
unset($value); // 解除引用
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $actualRewards;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查使用频率限制
|
||||
*/
|
||||
public function checkUsageLimit(User $user): bool
|
||||
{
|
||||
$conditions = $this->conditions ?? [];
|
||||
|
||||
// 检查每用户最大使用次数
|
||||
if (isset($conditions['max_use_per_user'])) {
|
||||
$usedCount = $this->usages()
|
||||
->where('user_id', $user->id)
|
||||
->count();
|
||||
if ($usedCount >= $conditions['max_use_per_user']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 检查冷却时间
|
||||
if (isset($conditions['cooldown_hours'])) {
|
||||
$lastUsage = $this->usages()
|
||||
->where('user_id', $user->id)
|
||||
->orderBy('created_at', 'desc')
|
||||
->first();
|
||||
|
||||
if ($lastUsage) {
|
||||
$cooldownTime = $lastUsage->created_at + ($conditions['cooldown_hours'] * 3600);
|
||||
if (time() < $cooldownTime) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
/**
|
||||
* App\Models\GiftCardUsage
|
||||
*
|
||||
* @property int $id
|
||||
* @property int $code_id 兑换码ID
|
||||
* @property int $template_id 模板ID
|
||||
* @property int $user_id 使用用户ID
|
||||
* @property int|null $invite_user_id 邀请人ID
|
||||
* @property array $rewards_given 实际发放的奖励
|
||||
* @property array|null $invite_rewards 邀请人获得的奖励
|
||||
* @property int|null $user_level_at_use 使用时用户等级
|
||||
* @property int|null $plan_id_at_use 使用时用户套餐ID
|
||||
* @property float $multiplier_applied 应用的倍率
|
||||
* @property string|null $ip_address 使用IP地址
|
||||
* @property string|null $user_agent 用户代理
|
||||
* @property string|null $notes 备注
|
||||
* @property int $created_at
|
||||
*/
|
||||
class GiftCardUsage extends Model
|
||||
{
|
||||
protected $table = 'v2_gift_card_usage';
|
||||
protected $dateFormat = 'U';
|
||||
public $timestamps = false;
|
||||
|
||||
protected $fillable = [
|
||||
'code_id',
|
||||
'template_id',
|
||||
'user_id',
|
||||
'invite_user_id',
|
||||
'rewards_given',
|
||||
'invite_rewards',
|
||||
'user_level_at_use',
|
||||
'plan_id_at_use',
|
||||
'multiplier_applied',
|
||||
'ip_address',
|
||||
'user_agent',
|
||||
'notes',
|
||||
'created_at'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'created_at' => 'timestamp',
|
||||
'rewards_given' => 'array',
|
||||
'invite_rewards' => 'array',
|
||||
'multiplier_applied' => 'float'
|
||||
];
|
||||
|
||||
/**
|
||||
* 关联兑换码
|
||||
*/
|
||||
public function code(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(GiftCardCode::class, 'code_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联模板
|
||||
*/
|
||||
public function template(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(GiftCardTemplate::class, 'template_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联使用用户
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联邀请人
|
||||
*/
|
||||
public function inviteUser(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class, 'invite_user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建使用记录
|
||||
*/
|
||||
public static function createRecord(
|
||||
GiftCardCode $code,
|
||||
User $user,
|
||||
array $rewards,
|
||||
array $options = []
|
||||
): self {
|
||||
return self::create([
|
||||
'code_id' => $code->id,
|
||||
'template_id' => $code->template_id,
|
||||
'user_id' => $user->id,
|
||||
'invite_user_id' => $user->invite_user_id,
|
||||
'rewards_given' => $rewards,
|
||||
'invite_rewards' => $options['invite_rewards'] ?? null,
|
||||
'user_level_at_use' => $user->plan ? $user->plan->sort : null,
|
||||
'plan_id_at_use' => $user->plan_id,
|
||||
'multiplier_applied' => $options['multiplier'] ?? 1.0,
|
||||
// 'ip_address' => $options['ip_address'] ?? null,
|
||||
'user_agent' => $options['user_agent'] ?? null,
|
||||
'notes' => $options['notes'] ?? null,
|
||||
'created_at' => time(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,11 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
* @property int|null $actual_commission_balance
|
||||
* @property int|null $commission_rate
|
||||
* @property int|null $commission_auto_check
|
||||
*
|
||||
* @property int|null $commission_balance
|
||||
* @property int|null $discount_amount
|
||||
* @property int|null $paid_at
|
||||
* @property string|null $callback_no
|
||||
*
|
||||
* @property-read Plan $plan
|
||||
* @property-read Payment|null $payment
|
||||
* @property-read User $user
|
||||
|
||||
+16
-1
@@ -28,6 +28,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
* @property string|null $network 网络类型
|
||||
* @property int|null $parent_id 父节点ID
|
||||
* @property float|null $rate 倍率
|
||||
* @property array|null $rate_time_ranges 倍率时间范围
|
||||
* @property int|null $sort 排序
|
||||
* @property array|null $protocol_settings 协议设置
|
||||
* @property int $created_at
|
||||
@@ -114,7 +115,9 @@ class Server extends Model
|
||||
'last_push_at' => 'integer',
|
||||
'show' => 'boolean',
|
||||
'created_at' => 'timestamp',
|
||||
'updated_at' => 'timestamp'
|
||||
'updated_at' => 'timestamp',
|
||||
'rate_time_ranges' => 'array',
|
||||
'rate_time_enable' => 'boolean',
|
||||
];
|
||||
|
||||
private const PROTOCOL_CONFIGURATIONS = [
|
||||
@@ -449,4 +452,16 @@ class Server extends Model
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public function getCurrentRate(): float
|
||||
{
|
||||
$now = date('H:i');
|
||||
$ranges = $this->rate_time_ranges ?? [];
|
||||
foreach ($ranges as $range) {
|
||||
if ($now >= $range['start'] && $now <= $range['end']) {
|
||||
return (float) $range['rate'];
|
||||
}
|
||||
}
|
||||
return (float) $this->rate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
class TrafficResetLog extends Model
|
||||
{
|
||||
protected $table = 'v2_traffic_reset_logs';
|
||||
|
||||
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'reset_type',
|
||||
@@ -64,6 +64,8 @@ class TrafficResetLog extends Model
|
||||
public const SOURCE_API = 'api';
|
||||
public const SOURCE_CRON = 'cron';
|
||||
public const SOURCE_USER_ACCESS = 'user_access';
|
||||
public const SOURCE_ORDER = 'order';
|
||||
public const SOURCE_GIFT_CARD = 'gift_card';
|
||||
|
||||
/**
|
||||
* 获取重置类型的多语言名称
|
||||
@@ -139,9 +141,9 @@ class TrafficResetLog extends Model
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
|
||||
$bytes /= (1 << (10 * $pow));
|
||||
|
||||
|
||||
return round($bytes, 2) . ' ' . $units[$pow];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
* @property int|null $balance 余额
|
||||
* @property int|null $commission_balance 佣金余额
|
||||
* @property float $commission_rate 返佣比例
|
||||
* @property int|null $commission_type 返佣类型
|
||||
* @property int|null $device_limit 设备限制数量
|
||||
* @property int|null $discount 折扣
|
||||
* @property int|null $last_login_at 最后登录时间
|
||||
|
||||
Reference in New Issue
Block a user