mirror of
https://github.com/lkddi/Xboard.git
synced 2026-04-23 19:37:35 +08:00
feat: enhance plan validation, traffic system and email verification
- feat: add plan price validation - feat: make traffic packages stackable - feat: add commission and invite info to admin order details - feat: apply email whitelist to verification code API - fix: subscription link copy compatibility for non-HTTPS - fix: resolve route editing 500 error in certain cases - refactor: restructure traffic reset logic
This commit is contained in:
@@ -2,56 +2,154 @@
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\Plan;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Contracts\Validation\Validator;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
|
||||
class PlanSave extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function rules()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required',
|
||||
'content' => '',
|
||||
'group_id' => 'required',
|
||||
'transfer_enable' => 'required',
|
||||
'month_price' => 'nullable|integer',
|
||||
'quarter_price' => 'nullable|integer',
|
||||
'half_year_price' => 'nullable|integer',
|
||||
'year_price' => 'nullable|integer',
|
||||
'two_year_price' => 'nullable|integer',
|
||||
'three_year_price' => 'nullable|integer',
|
||||
'onetime_price' => 'nullable|integer',
|
||||
'reset_price' => 'nullable|integer',
|
||||
'reset_traffic_method' => 'nullable|integer|in:0,1,2,3,4',
|
||||
'capacity_limit' => 'nullable|integer',
|
||||
'speed_limit' => 'nullable|integer'
|
||||
'id' => 'nullable|integer',
|
||||
'name' => 'required|string|max:255',
|
||||
'content' => 'nullable|string',
|
||||
'reset_traffic_method' => 'integer|nullable',
|
||||
'transfer_enable' => 'integer|required|min:1',
|
||||
'prices' => 'nullable|array',
|
||||
'prices.*' => 'nullable|numeric|min:0',
|
||||
'group_id' => 'integer|nullable',
|
||||
'speed_limit' => 'integer|nullable|min:0',
|
||||
'device_limit' => 'integer|nullable|min:0',
|
||||
'capacity_limit' => 'integer|nullable|min:0',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages()
|
||||
/**
|
||||
* Configure the validator instance.
|
||||
*/
|
||||
public function withValidator(Validator $validator): void
|
||||
{
|
||||
$validator->after(function (Validator $validator) {
|
||||
$this->validatePrices($validator);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证价格配置
|
||||
*/
|
||||
protected function validatePrices(Validator $validator): void
|
||||
{
|
||||
$prices = $this->input('prices', []);
|
||||
|
||||
if (empty($prices)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取所有有效的周期
|
||||
$validPeriods = array_keys(Plan::getAvailablePeriods());
|
||||
|
||||
foreach ($prices as $period => $price) {
|
||||
// 验证周期是否有效
|
||||
if (!in_array($period, $validPeriods)) {
|
||||
$validator->errors()->add(
|
||||
"prices.{$period}",
|
||||
"不支持的订阅周期: {$period}"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 价格可以为 null、空字符串或大于 0 的数字
|
||||
if ($price !== null && $price !== '') {
|
||||
// 转换为数字进行验证
|
||||
$numericPrice = is_numeric($price) ? (float) $price : null;
|
||||
|
||||
if ($numericPrice === null) {
|
||||
$validator->errors()->add(
|
||||
"prices.{$period}",
|
||||
"价格必须是数字格式"
|
||||
);
|
||||
} elseif ($numericPrice <= 0) {
|
||||
$validator->errors()->add(
|
||||
"prices.{$period}",
|
||||
"价格必须大于 0(如不需要此周期请留空或设为 null)"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理验证后的数据
|
||||
*/
|
||||
protected function passedValidation(): void
|
||||
{
|
||||
// 清理和格式化价格数据
|
||||
$prices = $this->input('prices', []);
|
||||
$cleanedPrices = [];
|
||||
|
||||
foreach ($prices as $period => $price) {
|
||||
// 只保留有效的正数价格
|
||||
if ($price !== null && $price !== '' && is_numeric($price)) {
|
||||
$numericPrice = (float) $price;
|
||||
if ($numericPrice > 0) {
|
||||
// 转换为浮点数并保留两位小数
|
||||
$cleanedPrices[$period] = round($numericPrice, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新请求中的价格数据
|
||||
$this->merge(['prices' => $cleanedPrices]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom error messages for validator errors.
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => '套餐名称不能为空',
|
||||
'type.required' => '套餐类型不能为空',
|
||||
'type.in' => '套餐类型格式有误',
|
||||
'group_id.required' => '权限组不能为空',
|
||||
'transfer_enable.required' => '流量不能为空',
|
||||
'month_price.integer' => '月付金额格式有误',
|
||||
'quarter_price.integer' => '季付金额格式有误',
|
||||
'half_year_price.integer' => '半年付金额格式有误',
|
||||
'year_price.integer' => '年付金额格式有误',
|
||||
'two_year_price.integer' => '两年付金额格式有误',
|
||||
'three_year_price.integer' => '三年付金额格式有误',
|
||||
'onetime_price.integer' => '一次性金额有误',
|
||||
'reset_price.integer' => '流量重置包金额有误',
|
||||
'reset_traffic_method.integer' => '流量重置方式格式有误',
|
||||
'reset_traffic_method.in' => '流量重置方式格式有误',
|
||||
'capacity_limit.integer' => '容纳用户量限制格式有误',
|
||||
'speed_limit.integer' => '限速格式有误'
|
||||
'name.max' => '套餐名称不能超过 255 个字符',
|
||||
'transfer_enable.required' => '流量配额不能为空',
|
||||
'transfer_enable.integer' => '流量配额必须是整数',
|
||||
'transfer_enable.min' => '流量配额必须大于 0',
|
||||
'prices.array' => '价格配置格式错误',
|
||||
'prices.*.numeric' => '价格必须是数字',
|
||||
'prices.*.min' => '价格不能为负数',
|
||||
'group_id.integer' => '权限组ID必须是整数',
|
||||
'speed_limit.integer' => '速度限制必须是整数',
|
||||
'speed_limit.min' => '速度限制不能为负数',
|
||||
'device_limit.integer' => '设备限制必须是整数',
|
||||
'device_limit.min' => '设备限制不能为负数',
|
||||
'capacity_limit.integer' => '容量限制必须是整数',
|
||||
'capacity_limit.min' => '容量限制不能为负数',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a failed validation attempt.
|
||||
*/
|
||||
protected function failedValidation(Validator $validator): void
|
||||
{
|
||||
throw new HttpResponseException(
|
||||
response()->json([
|
||||
'data' => false,
|
||||
'message' => $validator->errors()->first(),
|
||||
'errors' => $validator->errors()->toArray()
|
||||
], 422)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user