Files
xin-procurement/app/Http/Requests/Product/ProductFormRequest.php
T
2026-08-06 14:52:56 +08:00

87 lines
3.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Requests\Product;
use App\Models\ProductCategoryModel;
use App\Models\ProductPriceModel;
use App\Models\SupplierModel;
use Closure;
use Illuminate\Validation\Rules\Exists;
use Illuminate\Validation\Validator;
use Modules\Common\Http\Requests\BaseFormRequest;
use Modules\SystemTool\Models\SysFileModel;
/**
* 商品档案 创建/编辑 验证(含多等级价格 prices 数组)
*/
class ProductFormRequest extends BaseFormRequest
{
protected $stopOnFirstFailure = true;
public function rules(): array
{
return [
'category_id' => ['required','integer', new Exists(ProductCategoryModel::class,'id')],
'supplier_id' => ['nullable','integer', 'exclude_if:supplier_id,0', new Exists(SupplierModel::class,'id')],
'name' => 'required|string|max:100',
'spec' => 'nullable|string|max:100',
'unit' => 'nullable|string|max:20',
'image_ids' => 'nullable|array|max:255',
'image_ids.*' => ['integer', new Exists(SysFileModel::class, 'id')],
'content' => 'nullable|string',
'sort' => 'nullable|integer',
'shelf_life' => 'nullable|integer|min:0',
'stock' => 'nullable|integer|min:0',
'status' => 'nullable|integer|in:0,1',
'cost_price' => 'nullable|numeric|min:0|max:99999999',
'remark' => 'nullable|string|max:255',
'prices' => 'nullable|array',
'prices.*.level_id' => 'required|integer|exists:customer_level,id',
'prices.*.price_type' => 'nullable|integer|in:0,1',
'prices.*.price' => 'required|numeric|min:0|max:99999999',
'prices.*.percent' => 'nullable|numeric|min:0|max:999.99',
];
}
/**
* 交叉校验:按成本百分比计价(price_type=1)时上浮百分点必填
* Laravel 12 FormRequest 的 after() 需返回单个 Closure,由容器 call 后注册到 Validator
*/
public function after(): Closure
{
return function (Validator $validator): void {
$data = (array) $validator->getData();
foreach ((array) ($data['prices'] ?? []) as $index => $row) {
$priceType = (int) ($row['price_type'] ?? ProductPriceModel::PRICE_TYPE_FIXED);
if ($priceType === ProductPriceModel::PRICE_TYPE_PERCENT
&& (! array_key_exists('percent', (array) $row) || $row['percent'] === null || $row['percent'] === '')) {
$validator->errors()->add("prices.{$index}.percent", '按成本百分比计价时必须填写上浮百分点');
}
}
};
}
public function messages(): array
{
return [
'name.required' => '商品名称不能为空',
'name.max' => '商品名称最长 100 个字符',
'category_id.required' => '请选择商品分类',
'category_id.exists' => '商品分类不存在',
'supplier_id.exists' => '供应商不存在',
'status.in' => '状态值不正确',
'prices.*.level_id.required' => '价格行缺少客户等级',
'prices.*.level_id.exists' => '客户等级不存在',
'prices.*.price.required' => '价格行缺少单价',
'prices.*.price.numeric' => '单价必须为数字',
'prices.*.price.min' => '单价不能小于 0',
'cost_price.numeric' => '成本价必须为数字',
'cost_price.min' => '成本价不能小于 0',
'prices.*.price_type.in' => '计价类型不正确',
'prices.*.percent.numeric' => '上浮百分点必须为数字',
'prices.*.percent.min' => '上浮百分点不能小于 0',
'prices.*.percent.max' => '上浮百分点不能超过 999.99',
];
}
}