在使用laravel-admin的模型表单的时候,有个字段是json格式,新增的时候总是不能成功,经过排查源代码,发现他在校验有效column的时候,会根据form提交的字段进行null判断,源码位置如下:
D:\WWW\xxx\vendor\encore\laravel-admin\src\Form.php line :900
protected function prepareInsert($inserts): array
{
if ($this->isHasOneRelation($inserts)) {
$inserts = Arr::dot($inserts);
}
foreach ($inserts as $column => $value) {
if (($field = $this->getFieldByColumn($column)) === null) {// 就是这里
unset($inserts[$column]);
continue;
}
$inserts[$column] = $field->prepare($value);
}
$prepared = [];
foreach ($inserts as $key => $value) {
Arr::set($prepared, $key, $value);
}
return $prepared;
}
可以把提交的form数据打印出来,就能看得很清楚了.
dd($this->fields(),$inserts,$column);
改正方法如下,把json_content设置成hidden,这样的话laravel-admin就会判断出是存在这个字段,json.然后设置对应模型cast即可.但是好像还有另外一种官方的用法,用embed标识,在最后.
我之所以没有使用官方的,是因为我的数据给是变化比较大,不是规整的一维或者二维数据.
protected $casts = [
'json_content' => 'json',
'xxx' => 'json',
];
// key被覆盖,重新生成key
public function getProductsAttribute($products)
{
return array_values(json_decode($products, true) ?: []);
}
public function form()
{
$form = new Form(new XXX());
$form->text('name', '活动名称')->required();
$form->text('slug', '活动Slug')->required();
$$xxx = [];
if ($form->isEditing()) {
// 获取路由参数
$form->datetime('created_at', '创建时间')->readonly();
}
$form->table('products', '活动产品', function ($table) {
$table->select('product_id', '产品')->options(function ($id) {
$product = Product::find($id);
return $product ? $product->pluck('pro_name', 'id') : [];
})->ajax('/admin/api/xxx');
$table->select('type', '权益类型')->options(self::TYPES);
$table->number('value', '数值');
});
$form->multipleSelect('language', '语言')->options(array_combine(Launch::LANGUAGES, Launch::LANGUAGES));
$form->hidden('json_content');// 必须要有这个,json_否则会报错content字段不存在\vendor\encore\laravel-admin\src\Form.php Line:900
$form->url('json_content.first_image', '首图')->required();
$form->text('json_content.description', '权益{X}')->required();
$form->textarea('json_content.right_detail', '权益详情{Y}');
$form->url('json_content.rights_and_images.0.image', '权益图{1}');
$form->url('json_content.rights_and_images.1.image', '权益图{2}');
$form->url('json_content.rights_and_images.2.image', '权益图{3}');
$form->text('json_content.rights_and_images.0.right', '权益描述{a}');
$form->text('json_content.rights_and_images.1.right', '权益描述{b}');
$form->text('json_content.rights_and_images.2.right', '权益描述{c}');
$form->datetimeRange('start_time', 'end_time', '活动时间')->required();
$form->select('status', '活动状态')->options(VipActivity::STATUS)->default(VipActivity::STATUS_VALID);
$form->select('style', '按钮样式')->options(VipActivity::STYLES)->default(VipActivity::STYLE_MORE);
$form->url('redirect', '跳转链接')->required();
if ($form->isEditing()) {
$form->url('link', '活动链接');
}
// hook 保存后拿到活动id然后再次保存,没有观察者好用,但是不知道观察者为啥不可用
$form->saved(function (Form $form) {
$$xxx = $form->model();
$$xxx->link = vsprintf(config('app.url') . '/share/%s?xxx=%d', [$$xxx->slug, $$xxx->id]);
$$xxx->save();
});
$form->footer(function ($footer) {
// 去掉`查看`checkbox
$footer->disableViewCheck();
});
// $form->confirm('确定创建吗?', 'create');
// $form->confirm('确定更新吗?', 'edit');
return $form;
}
$form->embeds('column_name', function ($form) {
$form->text('key1')->rules('required');
$form->email('key2')->rules('required');
$form->datetime('key3');
$form->dateRange('key4', 'key5', '范围')->rules('required');
});
// 自定义标题
$form->embeds('column_name', '字段标题', function ($form) {
...
});
参考:官方链接