wp车辆信息

This commit is contained in:
2026-03-09 17:46:17 +08:00
parent 9a0fec3410
commit 25795a4f66
13 changed files with 1277 additions and 268 deletions
@@ -0,0 +1,305 @@
<?php
namespace app\common\controller;
use app\common\controller\BaseController;
use app\common\traits\crud\CrudControllerTrait;
use app\common\service\UsedCarDetailService;
use app\common\service\OssService;
use support\Request;
use support\exception\BusinessException;
class UsedCarDetailController extends BaseController
{
use CrudControllerTrait;
protected $service;
public function __construct()
{
$this->service = new UsedCarDetailService();
}
/**
* 列表页数据格式化
*
* @param array $data
* @return array
*/
protected function indexFormat($data)
{
if (isset($data['created_at'])) {
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
}
if (isset($data['updated_at'])) {
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
}
// 处理图片
if (!empty($data['images'])) {
$images = is_array($data['images']) ? $data['images'] : json_decode($data['images'], true);
if ($images) {
$ossService = new OssService();
$images_pull = [];
foreach ($images as $image) {
$images_pull[] = $ossService->generatePrivateUrl($image);
}
$data['images_pull'] = $images_pull;
} else {
$data['images_pull'] = [];
}
}
return $data;
}
/**
* 详情页数据格式化
*
* @param array $data
* @return array
*/
protected function showFormat($data)
{
if (isset($data['created_at'])) {
$data['created_at'] = date('Y-m-d H:i:s', $data['created_at']);
}
if (isset($data['updated_at'])) {
$data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']);
}
// 处理主图
if (!empty($data['images'])) {
$images = is_array($data['images']) ? $data['images'] : json_decode($data['images'], true);
if ($images) {
$ossService = new OssService();
$images_pull = [];
$process = 'image/resize,w_800/quality,Q_40/format,webp';
foreach ($images as $image) {
$images_pull[] = $ossService->generatePrivateUrlResize($image, 3600, $process);
}
$data['images_pull'] = $images_pull;
} else {
$data['images_pull'] = [];
}
} else {
$data['images_pull'] = [];
}
// 处理介绍图片
if (!empty($data['intro_images'])) {
$introImages = is_array($data['intro_images']) ? $data['intro_images'] : json_decode($data['intro_images'], true);
if ($introImages) {
$ossService = new OssService();
$intro_images_pull = [];
foreach ($introImages as $image) {
$intro_images_pull[] = $ossService->generatePrivateUrl($image);
}
$data['intro_images_pull'] = $intro_images_pull;
} else {
$data['intro_images_pull'] = [];
}
} else {
$data['intro_images_pull'] = [];
}
// 处理附件
if (!empty($data['attachment'])) {
$attachments = is_array($data['attachment']) ? $data['attachment'] : json_decode($data['attachment'], true);
if ($attachments) {
$ossService = new OssService();
$attachment_pull = [];
foreach ($attachments as $attachment) {
$attachment_pull[] = [
'name' => $attachment['name'] ?? '',
'src' => $attachment['src'] ?? '',
'src_pull' => $ossService->generatePrivateUrl($attachment['src'] ?? ''),
];
}
$data['attachment_pull'] = $attachment_pull;
} else {
$data['attachment_pull'] = [];
}
} else {
$data['attachment_pull'] = [];
}
return $data;
}
/**
* 更新状态
*
* @param Request $request
* @return \support\Response
*/
public function status(Request $request)
{
try {
$data = $request->post();
$res = $this->service->serviceUpdateStatus($request, $data);
return $this->success([], '更新成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 保存FAQ
*
* @param Request $request
* @return \support\Response
*/
public function saveFaqs(Request $request)
{
try {
$carId = $request->post('id');
$faqs = $request->post('faqs', []);
if (empty($carId)) {
throw new BusinessException('车辆ID不能为空');
}
$this->service->saveFaqs($carId, $faqs);
return $this->success([], '保存成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 创建车辆(含FAQ)
*
* @param Request $request
* @return \support\Response
*/
public function storeWithFaqs(Request $request)
{
try {
$data = $request->post();
$faqs = $data['faqs'] ?? [];
// 先创建车辆
$result = $this->service->serviceStore($request);
// 再保存FAQ
if (!empty($faqs) && isset($result['id'])) {
$this->service->saveFaqs($result['id'], $faqs);
}
return $this->success($result, '创建成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 更新车辆(含FAQ)
*
* @param Request $request
* @return \support\Response
*/
public function updateWithFaqs(Request $request)
{
try {
$data = $request->post();
$faqs = $data['faqs'] ?? [];
$carId = $data['id'] ?? null;
// 先更新车辆
$result = $this->service->serviceUpdate($request);
// 再更新FAQ
if (!empty($faqs) && $carId) {
$this->service->saveFaqs($carId, $faqs);
}
return $this->success($result, '更新成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 提交审核
*
* @param Request $request
* @return \support\Response
*/
public function submitAudit(Request $request)
{
try {
$carId = $request->post('id');
if (empty($carId)) {
throw new BusinessException('车辆ID不能为空');
}
$this->service->submitAudit($request, $carId);
return $this->success([], '提交审核成功');
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 审核车辆
*
* @param Request $request
* @return \support\Response
*/
public function audit(Request $request)
{
try {
$data = $request->post();
$this->service->audit($request, $data);
$statusText = $data['audit_status'] == 1 ? '通过' : '拒绝';
return $this->success([], "审核{$statusText}成功");
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 获取审核记录
*
* @param Request $request
* @return \support\Response
*/
public function auditRecords(Request $request)
{
try {
$carId = $request->get('id');
if (empty($carId)) {
throw new BusinessException('车辆ID不能为空');
}
$records = $this->service->getAuditRecords($carId);
return $this->success($records);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
/**
* 获取审核统计
*
* @param Request $request
* @return \support\Response
*/
public function auditStats(Request $request)
{
try {
$stats = $this->service->getAuditStats($request);
return $this->success($stats);
} catch (\Throwable $e) {
return $this->error($e->getMessage());
}
}
}
+17
View File
@@ -0,0 +1,17 @@
<?php
namespace app\common\logic;
use app\common\traits\crud\CrudLogicTrait;
use app\common\model\UsedCarDetail;
class UsedCarDetailLogic
{
use CrudLogicTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = UsedCarDetail::class;
}
+123
View File
@@ -0,0 +1,123 @@
<?php
namespace app\common\model;
use support\Model;
class UsedCarDetail extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'used_car_detail';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = ['id', 'code', 'user_id', 'role_wp', 'product_name', 'vin', 'price', 'source_place', 'plate_place', 'plate_time', 'displacement', 'mileage', 'power', 'body_color', 'images', 'condition_desc', 'attachment', 'pdf_src', 'source_url', 'crawl_title', 'crawl_brand', 'crawl_brand_id', 'crawl_series', 'crawl_series_id', 'crawl_year', 'crawl_msrp', 'crawl_car_id', 'status', 'sort', 'simple_desc', 'intro_images', 'intro_text', 'intro_video', 'official_guide_price', 'manufacturer', 'level', 'energy_type', 'listing_time', 'engine', 'electric_motor', 'nedc_range', 'cltc_range', 'fast_charge_platform', 'charging_time', 'fast_charge_percent', 'max_power_kw', 'max_torque_nm', 'transmission', 'dimensions', 'body_structure', 'max_speed', 'acceleration_100', 'nedc_fuel_consumption', 'power_consumption_100', 'equivalent_fuel_consumption', 'maintenance_cost_60k', 'body_length', 'body_width', 'body_height', 'wheelbase', 'door_count', 'door_open_type', 'seat_count', 'transmission_desc', 'gear_count', 'transmission_type', 'drive_mode', 'front_suspension', 'rear_suspension', 'steering_type', 'has_abs', 'has_ebd', 'has_bra', 'has_tcs', 'has_esp', 'has_active_brake', 'has_lane_assist', 'has_lka', 'has_lane_centering', 'has_fatigue_remind', 'front_brake_type', 'rear_brake_type', 'parking_brake_type', 'front_tire_spec', 'rear_tire_spec', 'created_at', 'updated_at'];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
/**
* JSON 类型字段自动转换
*/
protected $casts = [
'images' => 'array',
'attachment' => 'array',
'intro_images' => 'array',
];
/**
* 关联 FAQ
*/
public function faqs()
{
return $this->hasMany(UsedCarFaq::class, 'car_id', 'id');
}
/**
* 关联用户
*/
public function user()
{
return $this->belongsTo(\app\common\model\User::class, 'user_id', 'id');
}
/**
* 关联审核记录
*/
public function auditRecords()
{
return $this->hasMany(UsedCarDetailAudit::class, 'car_id', 'id')->orderBy('created_at', 'desc');
}
/**
* 最新审核记录
*/
public function latestAudit()
{
return $this->hasOne(UsedCarDetailAudit::class, 'car_id', 'id')->orderBy('created_at', 'desc');
}
/**
* 审核状态文本
*/
public static $auditStatusText = [
0 => '待审核',
1 => '审核通过',
2 => '审核拒绝',
];
/**
* 作用域:待审核
*/
public function scopePending($query)
{
return $query->where('status', 0);
}
/**
* 作用域:已通过
*/
public function scopeApproved($query)
{
return $query->where('status', 1);
}
/**
* 作用域:已拒绝
*/
public function scopeRejected($query)
{
return $query->where('status', 2);
}
}
+108
View File
@@ -0,0 +1,108 @@
<?php
namespace app\common\model;
use support\Model;
class UsedCarDetailAudit extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'used_car_detail_audit';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = [
'id', 'car_id', 'auditor_id', 'audit_status', 'audit_reason',
'before_status', 'after_status', 'created_at', 'updated_at'
];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
/**
* 审核状态文本
*/
public static $statusText = [
0 => '待审核',
1 => '审核通过',
2 => '审核拒绝',
];
/**
* 关联车辆
*/
public function car()
{
return $this->belongsTo(UsedCarDetail::class, 'car_id', 'id');
}
/**
* 关联审核人
*/
public function auditor()
{
return $this->belongsTo(\app\common\model\User::class, 'auditor_id', 'id');
}
/**
* 获取审核状态文本
*/
public function getAuditStatusTextAttribute()
{
return self::$statusText[$this->audit_status] ?? '未知';
}
/**
* 作用域:通过审核
*/
public function scopeApproved($query)
{
return $query->where('audit_status', 1);
}
/**
* 作用域:拒绝审核
*/
public function scopeRejected($query)
{
return $query->where('audit_status', 2);
}
/**
* 作用域:待审核
*/
public function scopePending($query)
{
return $query->where('audit_status', 0);
}
}
+58
View File
@@ -0,0 +1,58 @@
<?php
namespace app\common\model;
use support\Model;
class UsedCarFaq extends Model
{
/**
* The connection name for the model.
*
* @var string|null
*/
protected $connection = 'mysql';
/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'used_car_faq';
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps = true;
protected $dateFormat = 'U';
/**
* 允许自动填充模型字段
*/
protected $fillable = [
'id', 'car_id', 'question', 'answer', 'sort', 'status', 'created_at', 'updated_at'
];
/**
* 不允许自动填充模型字段
*/
protected $guarded = [];
/**
* 关联车辆详情
*/
public function car()
{
return $this->belongsTo(UsedCarDetail::class, 'car_id', 'id');
}
}
+458
View File
@@ -0,0 +1,458 @@
<?php
namespace app\common\service;
use app\common\validate\UsedCarDetailValidate;
use app\common\traits\crud\CrudServiceTrait;
use app\common\model\UsedCarDetail;
use app\common\model\User;
use support\exception\BusinessException;
use support\Log;
use support\Request;
use support\Redis;
class UsedCarDetailService
{
use CrudServiceTrait;
/**
* 指定当前要操作的模型
*/
protected string $modelClass = UsedCarDetail::class;
/**
* 验证器
*/
protected $validator = UsedCarDetailValidate::class;
/**
* 获取验证器
*/
public function getValidator()
{
return new $this->validator;
}
/**
* 构建查询配置
*/
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
{
$p = $request->all();
$config = [];
$config['model'] = $this->modelClass;
switch ($scene) {
case 'default':
$config['where']['status'] = 1;
$config['order']['sort'] = 'desc';
$config['order']['id'] = 'desc';
break;
case 'index':
// 默认只显示审核通过的数据
$config['where']['status'] = 1;
// 审核状态筛选
if (isset($p['status'])) {
$config['where']['status'] = $p['status'];
}
// 我的车辆
if (isset($p['scene']) && $p['scene'] == 'self') {
$config['where']['user_id'] = $request->user['id'];
unset($config['where']['status']);
}
// 关键字搜索
if (isset($p['keyword']) && $p['keyword']) {
$k = '%' . $p['keyword'] . '%';
foreach (['product_name', 'code', 'vin', 'manufacturer'] as $col) {
$config['orWhere'][] = [$col, 'like', $k];
}
}
// 品牌筛选
if (isset($p['crawl_brand_id']) && $p['crawl_brand_id']) {
$config['where']['crawl_brand_id'] = $p['crawl_brand_id'];
}
// 车系筛选
if (isset($p['crawl_series_id']) && $p['crawl_series_id']) {
$config['where']['crawl_series_id'] = $p['crawl_series_id'];
}
// 价格区间
if (isset($p['min_price']) && $p['min_price']) {
$config['where'][] = ['price', '>=', $p['min_price']];
}
if (isset($p['max_price']) && $p['max_price']) {
$config['where'][] = ['price', '<=', $p['max_price']];
}
$config['order']['sort'] = 'desc';
$config['order']['id'] = 'desc';
break;
case 'show':
$config['where']['id'] = $p['id'];
// 关联FAQ
$config['with'] = ['faqs'];
break;
case 'store':
break;
case 'update':
$config['where']['id'] = $p['id'];
break;
case 'destroy':
$config['where']['id'] = $p['id'];
break;
}
return $config;
}
/**
* 创建前数据处理
*/
public function beforeServiceStore($data, Request $request): array
{
if (empty($data['product_name'])) {
throw new BusinessException('产品名称不能为空');
}
// 设置用户信息
$data['user_id'] = $request->user['id'];
$user = User::where('id', $request->user['id'])->first();
$data['role_wp'] = $user['role_wp'] ?? 1;
// 默认待审核状态
if (!isset($data['status'])) {
$data['status'] = 0;
}
// 生成车辆编号
$data['code'] = $this->getCode($request->user['id']);
// 处理图片数据
if (!empty($data['images'])) {
if (is_array($data['images'])) {
$data['images'] = json_encode($data['images']);
}
} else {
$data['images'] = '';
}
// 处理附件数据
if (!empty($data['attachment'])) {
if (is_array($data['attachment'])) {
$data['attachment'] = json_encode($data['attachment']);
}
} else {
$data['attachment'] = '';
}
// 处理介绍图片
if (!empty($data['intro_images'])) {
if (is_array($data['intro_images'])) {
$data['intro_images'] = json_encode($data['intro_images']);
}
} else {
$data['intro_images'] = '';
}
// 检查来源URL是否重复
if (!empty($data['source_url'])) {
$exists = UsedCarDetail::where('source_url', $data['source_url']);
$exists = $exists->where('user_id', $data['user_id']);
if ($exists->exists()) {
throw new BusinessException('该车源已收录');
}
}
return $data;
}
/**
* 更新前数据处理
*/
public function beforeServiceUpdate($data, Request $request): array
{
if (empty($data['product_name'])) {
throw new BusinessException('产品名称不能为空');
}
// 获取车辆信息
$carId = $data['id'] ?? null;
if ($carId) {
$car = UsedCarDetail::find($carId);
if (!$car) {
throw new BusinessException('车辆不存在');
}
// 审核通过的车辆禁止修改
if ($car->status == 1) {
throw new BusinessException('审核通过的车辆禁止修改');
}
// 审核拒绝的车辆修改后状态改为待审核
if ($car->status == 2) {
$data['status'] = 0;
}
}
// 处理图片数据
if (isset($data['images'])) {
if (is_array($data['images'])) {
$data['images'] = json_encode($data['images']);
}
}
// 处理附件数据
if (isset($data['attachment'])) {
if (is_array($data['attachment'])) {
$data['attachment'] = json_encode($data['attachment']);
}
}
// 处理介绍图片
if (isset($data['intro_images'])) {
if (is_array($data['intro_images'])) {
$data['intro_images'] = json_encode($data['intro_images']);
}
}
return $data;
}
/**
* 更新状态
*/
public function serviceUpdateStatus(Request $request, array $data)
{
if (empty($data['id'])) {
throw new BusinessException('id不能为空');
}
if (!isset($data['status'])) {
throw new BusinessException('status错误');
}
return UsedCarDetail::where('id', $data['id'])->update(['status' => $data['status']]);
}
/**
* 保存FAQ
*/
public function saveFaqs(int $carId, array $faqs)
{
// 删除旧的FAQ
\app\common\model\UsedCarFaq::where('car_id', $carId)->delete();
// 创建新的FAQ
if (!empty($faqs)) {
foreach ($faqs as $faq) {
\app\common\model\UsedCarFaq::create([
'car_id' => $carId,
'question' => $faq['question'] ?? '',
'answer' => $faq['answer'] ?? '',
'sort' => $faq['sort'] ?? 0,
'status' => $faq['status'] ?? 1,
]);
}
}
}
/**
* 生成车辆编号
*/
public function getCode(int $userId): string
{
$userCount = Redis::get('used_car_detail_count_' . $userId, 0);
$todayStart = strtotime('today');
$count = UsedCarDetail::where('user_id', $userId)
->where('created_at', '>=', $todayStart)
->count();
$count = $count < $userCount ? $userCount + 1 : $count + 1;
$countCode = str_pad($count, 3, '0', STR_PAD_LEFT);
$userCode = str_pad($userId, 3, '0', STR_PAD_LEFT);
Redis::set('used_car_detail_count_' . $userId, $count, 86400);
$user = User::where('id', $userId)->first();
$nameInitials = $this->getNameInitials($user['name'] ?? '');
return 'UCD' . $nameInitials . $userCode . date('Ymd') . $countCode;
}
/**
* 获取中文名拼音首字母
*/
private function getNameInitials(string $name): string
{
$initials = '';
$len = mb_strlen($name);
for ($i = 0; $i < $len; $i++) {
$char = mb_substr($name, $i, 1);
$initials .= $this->getFirstChar($char);
}
return strtoupper($initials);
}
/**
* 获取单个字符的首字母
*/
private function getFirstChar(string $char): string
{
$s = iconv('UTF-8', 'GB2312//IGNORE', $char);
$asc = ord($s[0]);
if ($asc >= 65 && $asc <= 90) {
return $char;
}
if ($s === false || strlen($s) < 2) {
return '';
}
$code = ord($s[0]) * 256 + ord($s[1]) - 65536;
$map = [
[-20319, -20284, 'A'],
[-20283, -19776, 'B'],
[-19775, -19219, 'C'],
[-19218, -18711, 'D'],
[-18710, -18527, 'E'],
[-18526, -18240, 'F'],
[-18239, -17923, 'G'],
[-17922, -17418, 'H'],
[-17417, -16475, 'J'],
[-16474, -16213, 'K'],
[-16212, -15641, 'L'],
[-15640, -15166, 'M'],
[-15165, -14923, 'N'],
[-14922, -14915, 'O'],
[-14914, -14631, 'P'],
[-14630, -14150, 'Q'],
[-14149, -14091, 'R'],
[-14090, -13319, 'S'],
[-13318, -12839, 'T'],
[-12838, -12557, 'W'],
[-12556, -11848, 'X'],
[-11847, -11056, 'Y'],
[-11055, -10247, 'Z']
];
foreach ($map as [$start, $end, $letter]) {
if ($code >= $start && $code <= $end) {
return $letter;
}
}
return '';
}
/**
* 提交审核
*/
public function submitAudit(Request $request, int $carId)
{
$car = UsedCarDetail::find($carId);
if (!$car) {
throw new BusinessException('车辆不存在');
}
// 检查权限:只能提交自己创建的车辆
if ($car->user_id != $request->user['id']) {
throw new BusinessException('无权操作');
}
// 只有待审核状态才能提交
if ($car->status != 0) {
throw new BusinessException('当前状态不允许提交审核');
}
return UsedCarDetail::where('id', $carId)->update(['status' => 0]);
}
/**
* 审核车辆
*/
public function audit(Request $request, array $data)
{
$carId = $data['car_id'] ?? null;
$auditStatus = $data['audit_status'] ?? null;
$auditReason = $data['audit_reason'] ?? '';
if (empty($carId)) {
throw new BusinessException('车辆ID不能为空');
}
if (!isset($auditStatus) || !in_array($auditStatus, [1, 2])) {
throw new BusinessException('审核状态错误');
}
$car = UsedCarDetail::find($carId);
if (!$car) {
throw new BusinessException('车辆不存在');
}
$beforeStatus = $car->status;
// 创建审核记录
\app\common\model\UsedCarDetailAudit::create([
'car_id' => $carId,
'auditor_id' => $request->user['id'],
'audit_status' => $auditStatus,
'audit_reason' => $auditReason,
'before_status' => $beforeStatus,
'after_status' => $auditStatus,
]);
// 更新车辆状态
return UsedCarDetail::where('id', $carId)->update(['status' => $auditStatus]);
}
/**
* 获取审核记录列表
*/
public function getAuditRecords(int $carId)
{
return \app\common\model\UsedCarDetailAudit::where('car_id', $carId)
->with(['auditor:id,name'])
->orderBy('created_at', 'desc')
->get()
->map(function ($item) {
return [
'id' => $item->id,
'audit_status' => $item->audit_status,
'audit_status_text' => $item->audit_status_text,
'audit_reason' => $item->audit_reason,
'before_status' => $item->before_status,
'after_status' => $item->after_status,
'auditor_name' => $item->auditor->name ?? '',
'created_at' => date('Y-m-d H:i:s', $item->created_at),
];
});
}
/**
* 获取审核统计数据
*/
public function getAuditStats(Request $request)
{
$query = UsedCarDetail::query();
// 如果不是管理员,只能看到自己的数据
if ($request->user['role_wp'] != 3) {
$query->where('user_id', $request->user['id']);
}
return [
'pending' => (clone $query)->where('status', 0)->count(),
'approved' => (clone $query)->where('status', 1)->count(),
'rejected' => (clone $query)->where('status', 2)->count(),
'total' => $query->count(),
];
}
}
@@ -0,0 +1,33 @@
<?php
namespace app\common\validate;
use think\Validate;
class UsedCarDetailValidate extends Validate
{
// 规则
protected $rule = [
'id' => 'requireWith:id',
'product_name' => 'require|max:255',
'price' => 'require|float|>=:0',
'user_id' => 'require|integer',
'role' => 'integer|in:1,2,3,4',
];
// 提示
protected $message = [
'product_name.require' => '产品名称不能为空',
'product_name.max' => '产品名称最多255个字符',
'price.require' => '车辆价格不能为空',
'price.float' => '车辆价格格式不正确',
'price.>=' => '车辆价格不能为负数',
'role.in' => '角色值不正确',
];
// 场景
protected $scene = [
'store' => ['product_name', 'price', 'user_id', 'role'],
'update' => ['id', 'product_name', 'price'],
];
}