fix: resolve known issues and improve code standards

- Fix known bugs in user, plan, and server modules
- Standardize code formatting and structure
- Optimize database queries and model relationships
- Improve request validation and error handling
- Update admin controllers for better consistency
This commit is contained in:
xboard
2025-06-22 17:38:17 +08:00
parent 733cc7e9a5
commit 44d92ac1c6
20 changed files with 56 additions and 51 deletions
+10 -9
View File
@@ -4,32 +4,33 @@ namespace App\Console\Commands;
use App\Services\TrafficResetService;
use App\Utils\Helper;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
class ResetTraffic extends Command
{
/**
/**
* The name and signature of the console command.
*/
*/
protected $signature = 'reset:traffic {--batch-size=100 : 分批处理的批次大小} {--dry-run : 预演模式,不实际执行重置} {--max-time=300 : 最大执行时间(秒)}';
/**
/**
* The console command description.
*/
*/
protected $description = '流量重置 - 分批处理所有需要重置的用户';
/**
/**
* 流量重置服务
*/
*/
private TrafficResetService $trafficResetService;
/**
* Create a new command instance.
*/
public function __construct(TrafficResetService $trafficResetService)
{
parent::__construct();
{
parent::__construct();
$this->trafficResetService = $trafficResetService;
}
@@ -177,7 +178,7 @@ class ResetTraffic extends Command
'ID' => $user->id,
'邮箱' => substr($user->email, 0, 20) . (strlen($user->email) > 20 ? '...' : ''),
'套餐' => $user->plan->name ?? 'N/A',
'下次重置' => $user->next_reset_at->format('m-d H:i'),
'下次重置' => Carbon::createFromTimestamp($user->next_reset_at)->format('Y-m-d H:i:s'),
'当前流量' => Helper::trafficConvert(($user->u ?? 0) + ($user->d ?? 0)),
'重置次数' => $user->reset_count,
];
+1 -1
View File
@@ -52,7 +52,7 @@ class SendRemindMail extends Command
}
$startTime = microtime(true);
$progressBar = $this->output->createProgressBar(ceil($totalUsers / $chunkSize));
$progressBar = $this->output->createProgressBar((int) ceil($totalUsers / $chunkSize));
$progressBar->start();
$statistics = $mailService->processUsersInChunks($chunkSize, function () use ($progressBar) {
@@ -13,6 +13,7 @@ use Laravel\Horizon\Contracts\MetricsRepository;
use Laravel\Horizon\Contracts\SupervisorRepository;
use Laravel\Horizon\Contracts\WorkloadRepository;
use Laravel\Horizon\WaitTimeCalculator;
use App\Helpers\ResponseEnum;
class SystemController extends Controller
{
@@ -257,7 +258,7 @@ class SystemController extends Controller
]);
} catch (\Exception $e) {
return $this->error('清除日志失败:' . $e->getMessage());
return $this->fail(ResponseEnum::HTTP_ERROR, null, '清除日志失败:' . $e->getMessage());
}
}
@@ -293,7 +294,7 @@ class SystemController extends Controller
return $this->success($stats);
} catch (\Exception $e) {
return $this->error('获取统计信息失败:' . $e->getMessage());
return $this->fail(ResponseEnum::HTTP_ERROR, null, '获取统计信息失败:' . $e->getMessage());
}
}
}
@@ -71,7 +71,7 @@ class TrafficResetController extends Controller
$logs = $query->paginate($perPage);
// 格式化数据
$logs->getCollection()->transform(function ($log) {
$formattedLogs = $logs->getCollection()->map(function (TrafficResetLog $log) {
return [
'id' => $log->id,
'user_id' => $log->user_id,
@@ -99,7 +99,7 @@ class TrafficResetController extends Controller
});
return response()->json([
'data' => $logs->items(),
'data' => $formattedLogs->toArray(),
'pagination' => [
'current_page' => $logs->currentPage(),
'last_page' => $logs->lastPage(),
@@ -198,7 +198,8 @@ class TrafficResetController extends Controller
$history = $this->trafficResetService->getUserResetHistory($user, $limit);
$data = $history->map(function ($log) {
/** @var \Illuminate\Database\Eloquent\Collection<int, \App\Models\TrafficResetLog> $history */
$data = $history->map(function (TrafficResetLog $log) {
return [
'id' => $log->id,
'reset_type' => $log->reset_type,
+3 -3
View File
@@ -18,12 +18,12 @@ class UserUpdate extends FormRequest
'password' => 'nullable|min:8',
'transfer_enable' => 'numeric',
'expired_at' => 'nullable|integer',
'banned' => 'in:0,1',
'banned' => 'bool',
'plan_id' => 'nullable|integer',
'commission_rate' => 'nullable|integer|min:0|max:100',
'discount' => 'nullable|integer|min:0|max:100',
'is_admin' => 'required|in:0,1',
'is_staff' => 'required|in:0,1',
'is_admin' => 'boolean',
'is_staff' => 'boolean',
'u' => 'integer',
'd' => 'integer',
'balance' => 'numeric',
+2 -1
View File
@@ -14,7 +14,8 @@ class Coupon extends Model
'created_at' => 'timestamp',
'updated_at' => 'timestamp',
'limit_plan_ids' => 'array',
'limit_period' => 'array'
'limit_period' => 'array',
'show' => 'boolean',
];
public function getLimitPeriodAttribute($value)
+2 -1
View File
@@ -10,6 +10,7 @@ class InviteCode extends Model
protected $dateFormat = 'U';
protected $casts = [
'created_at' => 'timestamp',
'updated_at' => 'timestamp'
'updated_at' => 'timestamp',
'status' => 'boolean',
];
}
+1 -1
View File
@@ -23,7 +23,7 @@ use Illuminate\Database\Eloquent\Relations\HasOne;
* @property array|null $prices 价格配置
* @property int $sort 排序
* @property string|null $content 套餐描述
* @property int $reset_traffic_method 流量重置方式
* @property int|null $reset_traffic_method 流量重置方式
* @property int|null $capacity_limit 订阅人数限制
* @property int|null $device_limit 设备数量限制
* @property int $created_at
+5 -1
View File
@@ -11,6 +11,10 @@ class Plugin extends Model
protected $guarded = [
'id',
'created_at',
'updated_at'
'updated_at',
];
protected $casts = [
'is_enabled' => 'boolean'
];
}
+2 -1
View File
@@ -23,7 +23,7 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
* @property array|null $group_ids 分组IDs
* @property array|null $route_ids 路由IDs
* @property array|null $tags 标签
* @property string|null $show 是否显示
* @property boolean $show 是否显示
* @property string|null $allow_insecure 是否允许不安全
* @property string|null $network 网络类型
* @property int|null $parent_id 父节点ID
@@ -112,6 +112,7 @@ class Server extends Model
'protocol_settings' => 'array',
'last_check_at' => 'integer',
'last_push_at' => 'integer',
'show' => 'boolean',
'created_at' => 'timestamp',
'updated_at' => 'timestamp'
];
+5 -3
View File
@@ -37,8 +37,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
* @property int|null $last_login_at 最后登录时间
* @property int|null $parent_id 父账户ID
* @property int|null $is_admin 是否管理员
* @property \Carbon\Carbon|null $next_reset_at 下次流量重置时间
* @property \Carbon\Carbon|null $last_reset_at 上次流量重置时间
* @property int|null $next_reset_at 下次流量重置时间
* @property int|null $last_reset_at 上次流量重置时间
* @property int $reset_count 流量重置次数
* @property int $created_at
* @property int $updated_at
@@ -64,7 +64,9 @@ class User extends Authenticatable
protected $casts = [
'created_at' => 'timestamp',
'updated_at' => 'timestamp',
'banned' => 'integer',
'banned' => 'boolean',
'is_admin' => 'boolean',
'is_staff' => 'boolean',
'remind_expire' => 'boolean',
'remind_traffic' => 'boolean',
'commission_auto_check' => 'boolean',
+2 -2
View File
@@ -53,10 +53,10 @@ class UserObserver
$nextResetTime = $this->trafficResetService->calculateNextResetTime($user);
if ($nextResetTime) {
$user->next_reset_at = $nextResetTime->timestamp;
$user->setAttribute('next_reset_at', $nextResetTime->timestamp);
} else {
// 如果计算结果为空,清除重置时间
$user->next_reset_at = null;
$user->setAttribute('next_reset_at', null);
}
} catch (\Exception $e) {
+1 -1
View File
@@ -16,7 +16,7 @@ class SettingServiceProvider extends ServiceProvider
public function register()
{
$this->app->scoped(Setting::class, function (Application $app) {
return new Setting();
return Setting::getInstance();
});
}
-7
View File
@@ -87,13 +87,6 @@ class ServerService
public static function getRoutes(array $routeIds)
{
$routes = ServerRoute::select(['id', 'match', 'action', 'action_value'])->whereIn('id', $routeIds)->get();
// TODO: remove on 1.8.0
foreach ($routes as $k => $route) {
$array = json_decode($route->match, true);
if (is_array($array))
$routes[$k]['match'] = $array;
}
// TODO: remove on 1.8.0
return $routes;
}
+1 -1
View File
@@ -109,7 +109,6 @@ class TrafficResetService
Plan::RESET_TRAFFIC_MONTHLY => $this->getNextMonthlyReset($user, $now),
Plan::RESET_TRAFFIC_FIRST_DAY_YEAR => $this->getNextYearFirstDay($now),
Plan::RESET_TRAFFIC_YEARLY => $this->getNextYearlyReset($user, $now),
Plan::RESET_TRAFFIC_NEVER => null,
default => null,
};
}
@@ -251,6 +250,7 @@ class TrafficResetService
Plan::RESET_TRAFFIC_MONTHLY => TrafficResetLog::TYPE_MONTHLY,
Plan::RESET_TRAFFIC_FIRST_DAY_YEAR => TrafficResetLog::TYPE_FIRST_DAY_YEAR,
Plan::RESET_TRAFFIC_YEARLY => TrafficResetLog::TYPE_YEARLY,
Plan::RESET_TRAFFIC_NEVER => TrafficResetLog::TYPE_MANUAL,
default => TrafficResetLog::TYPE_MANUAL,
};
}
+2 -2
View File
@@ -145,8 +145,8 @@ class UserService
'total_available' => $user->transfer_enable ?? 0,
'remaining' => $user->getRemainingTraffic(),
'usage_percentage' => $user->getTrafficUsagePercentage(),
'next_reset_at' => $user->next_reset_at?->timestamp,
'last_reset_at' => $user->last_reset_at?->timestamp,
'next_reset_at' => $user->next_reset_at,
'last_reset_at' => $user->last_reset_at,
'reset_count' => $user->reset_count,
];
}
+2 -2
View File
@@ -135,9 +135,9 @@ class Setting
// 处理JSON格式的值
foreach ($settings as $key => $value) {
if (is_string($value) && $value !== null) {
if (is_string($value)) {
$decoded = json_decode($value, true);
if (json_last_error() === JSON_ERROR_NONE) {
if (json_last_error() === JSON_ERROR_NONE && $decoded !== null) {
$settings[$key] = $decoded;
}
}
@@ -122,7 +122,7 @@ return new class extends Migration {
$table->integer('group_id')->change();
$table->integer('transfer_enable')->change();
$table->integer('speed_limit')->nullable()->change();
$table->boolean('reset_traffic_method')->nullable()->change();
$table->integer('reset_traffic_method')->nullable()->change();
$table->integer('capacity_limit')->nullable()->change();
});
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long