laravel-admin动态表单添加删除
laravel-admin动态表单添加删除,系统会自动渲染
// ==================== 核心:动态增减组(产品+天数+预警次数) ====================
$form->hasMany('yujings', '产品预警配置', function (Form\NestedForm $form) {
// 产品下拉选择(从 Product 模型读取,最稳定)
$form->select('product_id', '产品')
->options(\App\Models\Chanpin\ChanpinList::all()->pluck('name', 'id')) // 直接从模型拿
->attribute('data-live-search', 'true') // 开启搜索
->attribute('data-actions-box', 'true')
->required();
// 天数
$form->number('days', '天数')->required();
// 预警次数
$form->number('warning_count', '预警次数')->required()->help('设置日期内未到达该次数启动预警');;
});
模型
<?php
namespace App\Models\Shanghu;
use Illuminate\Support\Facades\Auth; //这个是给判断登录用的
use Illuminate\Database\Eloquent\Model; //这个模型文件必带的
use Illuminate\Database\Eloquent\SoftDeletes; //是软删除用的
use DateTimeInterface;
use App\Models\Chanpin\ChanpinList;
class Yujing extends Model {
//use SoftDeletes; //是软删除用的 就是数据再。日期字段多了一个日期
protected $table = 'lmai_yujing';
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
// 关联产品模型(用于下拉框显示产品名称)
public function product()
{
return $this->belongsTo(ChanpinList::class, 'product_id');
}
// 关键:必须把这4个字段都加进来 ✅
protected $fillable = [
'shanghu_list_id',
'product_id', // 这个必须写!
'days',
'warning_count',
];
}
?
模型二
<?php
namespace App\Models\Shanghu;
use Illuminate\Support\Facades\Auth; //这个是给判断登录用的
use Illuminate\Database\Eloquent\Model; //这个模型文件必带的
use Illuminate\Database\Eloquent\SoftDeletes; //是软删除用的
use DateTimeInterface;
class ShanghuList extends Model {
//use SoftDeletes; //是软删除用的 就是数据再。日期字段多了一个日期
protected $table = 'lmai_shanghu_list';
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
// 一对多关联预警配置
public function yujings()
{
// 关键:指定外键 shanghu_list_id,彻底解决报错!
return $this->hasMany(Yujing::class, 'shanghu_list_id');
}
// public function yujings()
// {
// return $this->hasMany(
// \App\Models\Shanghu\Yujing::class,
// 'shanghu_list_id', // 子表外键
// 'id' // 主表主键
// );
// }
}
?>
完整的列表页面+回显
<?php
namespace App\Admin\Controllers\Shanghu;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Encore\Admin\Show;
use App\Models\Shanghu\ShanghuList;
use SimpleSoftwareIOQrCodeFacadesQrCode;
use DB;
use App\Models\Jianguan\JianguanUser;
use App\Models\Chanpin\ChanpinList;
use Carbon\Carbon;
class ListController extends AdminController
{
/**
* Title for current resource.
*
* @var string
*/
protected $title = '商户信息';
/**
* Make a grid builder.
*
* @return Grid
*/
protected function grid()
{
$grid = new Grid(new ShanghuList);
//筛选
$grid->filter(function(Grid\Filter $filter){
// 范围过滤器,调用模型的`onlyTrashed`方法,查询出被软删除的数据。
// $filter->like('shopname', __('店铺名称'));
// $filter->like('shequ', __('所属社区'));
// $filter->like('xqaddress', __('地址'));
$filter->distpicker('province_id', 'city_id', 'district_id', '地域选择');
$filter->like('created_at', __('创建日期'))->date();
});
//筛选结束
$grid->column('id', __('ID'))->sortable();
$grid->column('shopname', __('店铺名称'));
//省名
$grid->column('province_id', __('省份'))
->display(function($code) {
$name = DB::table('china_area')->where('code', $code)->value('name');
return $name;
});
//市名
$grid->column('city_id', __('市'))
->display(function($code) {
$name = DB::table('china_area')->where('code', $code)->value('name');
return $name;
});
//区名
$grid->column('district_id', __('区'))
->display(function($code) {
$name = DB::table('china_area')->where('code', $code)->value('name');
return $name;
});
$grid->address('街道')->display(function ($title) {
return mb_strlen($title, 'utf-8') > 10
? mb_substr($title, 0, 15, 'utf-8').'...'
: $title;
});
$grid->column('lianxiren', __('联系人'));
// $grid->column('benyue', __('总上报数'))->display(function(){
// $q= \DB::table('lmai_code_log')
// ->where('shanghu_id', $this->id)
// // ->where('age', '>=', 18)
// ->where('created_at', '>=', Carbon::now()->subDays(36000))
// ->count();
// $count = $q; // 实际应该是 $this->benyue
// $color = $count > 50 ? '#67C23A' : ($count > 20 ? '#E6A23C' : '#F56C6C');
// return "<a href=' /saomalog?shanghu_id={$this->id}'><span style='font-weight:bold;color:{$color};padding:4px 8px;border-radius:4px;background:#f0f0f0;'>
// {$count}
// </span></a>";
// });
$grid->column('yyzz', __('营业执照'))->lightbox(['width' => 50, 'height' => 50]);
$grid->column('status', __('状态'))->display(function(){
if ($this->status == null) {
return '正常';
}
return '异常';
});
$grid->column('created_at', __('创建时间'));
// ========== 核心:最近10天扫码次数 + 异常判断 ==========
$grid->column('benyue1', __('最近上报'))->display(function () {
// 获取预加载的计数,若不存在则默认为0
$scanCount = \DB::table('lmai_code_log')
->where('shanghu_id', $this->id)
// ->where('age', '>=', 18)
->where('created_at', '>=', Carbon::now()->subDays($this->day))
->count();
// 从模型字段获取阈值和天数(支持默认值)
$threshold = $this->ciyujing ?? 20; // 阈值(次)
$days = $this->day ?? 10; // 统计天数
// 异常判断与样式
$isAbnormal = $scanCount < $threshold;
$color = $isAbnormal ? '#F56C6C' : '#67C23A'; // 文字颜色
$labelClass = $isAbnormal ? 'label-danger' : 'label-success'; // 标签样式
$statusText = $isAbnormal ? "异常(不足{$threshold}次)" : "正常(≥{$threshold}次)";
// 生成安全链接(使用 admin_url 辅助函数)
$url = '/saomalog?shanghu_id='.e($this->id);
// 返回 HTML(所有变量均已提前计算,避免 HEREDOC 中写表达式)
return <<<HTML
<div style="display: flex; align-items: center; gap: 8px; flex-wrap: wrap;">
<a href="{$url}" style="font-weight:bold;color:{$color};padding:4px 8px;border-radius:4px;background:#f0f0f0;">
{$scanCount}次
</a>
<span class="label {$labelClass}">{$statusText}</span>
<small style="color:#999;">(需达到预警阈值{$days}天{$threshold}次)</small>
</div>
HTML;
});
//导出结束
return $grid;
}
/**
* Make a show builder.
*
* @param mixed $id
* @return Show
*/
protected function detail($id)
{
$show = new Show(ShanghuList::findOrFail($id));
$show->field('id', __('ID'));
$show->field('shbh', __('商铺编号'));
$show->field('shopname', __('商铺名称'));
$show->field('lianxiren', __('联系人'));
$show->field('tel', __('联系电话'));
// ==================== 安全展示动态数据(无任何链式报错) ====================
// ChanpinList
$show->field('__warning_config', '产品预警配置')
->unescape()
->as(function () use ($id) {
$yujings = \App\Models\Shanghu\Yujing::where('shanghu_list_id', $id)->get();
$products = ChanpinList::pluck('name', 'id');
// ✅ Laravel-Admin 原生现代化表格样式
$html = '<div class="box-body" style="padding:0;">';
$html .= '<table class="table table-striped table-bordered table-hover">';
// 表头
$html .= '
<thead>
<tr style="background-color: #fafbfc; font-weight: 600;">
<td>产品名称</td>
<td>预警天数</td>
<td>预警次数</td>
</tr>
</thead>
<tbody>';
// 数据行
foreach ($yujings as $item) {
$productName = $products[$item->product_id] ?? '未知产品';
$html .= "
<tr>
<td>{$productName}</td>
<td>{$item->days}</td>
<td>{$item->warning_count}</td>
</tr>";
}
// 空数据提示
if($yujings->isEmpty()){
$html .= '<tr><td colspan="3" align="center" style="color:#999;">暂无配置数据</td></tr>';
}
$html .= '</tbody></table></div>';
return $html;
});
// ==========================================================================
$show->field('created_at', __('创建时间'));
$show->field('updated_at', __('更新时间'));
return $show;
}
/**
* Make a form builder.
*
* @return Form
*/
protected function form()
{
$form = new Form(new ShanghuList);
$form->display('id', __('ID'));
$form->text('shbh', __('商户编号'))->default('SH'.time().rand(1111,9999))->readonly()->help('系统生成不可修改');
$form->text('shopname',__('店铺名称'))->required();
$form->distpicker([
'province_id' => '省份',
'city_id' => '市',
'district_id' => '区'
], '地域选择')->default([
'province' => 460000,
'city' => '',
'district' => '',
])->required();
$form->text('address',__('街道地址'));
$form->date('jiarutime',__('加入时间'))->required();
$form->text('lianxiren',__('联系人'))->required();
$form->mobile('tel',__('联系电话'))->required();
$form->image('yyzz', __('营业执照'))->move(function () {
return 'images/chanpin/' . date('Y/m/d');
})->uniqueName()->required();
// $form->number('day',__('天数'))->required();
// $form->number('ciyujing',__('次数'))->required()->help('设置日期内未到达该次数启动预警');
$form->select('jgname_id', __('监管负责人'))->options(JianguanUser::orderBy('id', 'desc')->pluck('name', 'id'));
$states = [
'on' => ['value' => null, 'text' => '正常', 'color' => 'success'],
'off' => ['value' => 1, 'text' => '异常', 'color' => 'danger'],
];
$form->switch( 'status', __('当前状态') )->states($states);
$form->display('created_at', __('创建日期'));
$form->display('updated_at', __('更新日期'));
// ==================== 核心:动态增减组(产品+天数+预警次数) ====================
$form->hasMany('yujings', '产品预警配置', function (Form\NestedForm $form) {
// 产品下拉选择(从 Product 模型读取,最稳定)
$form->select('product_id', '产品')
->options(\App\Models\Chanpin\ChanpinList::all()->pluck('name', 'id')) // 直接从模型拿
->attribute('data-live-search', 'true') // 开启搜索
->attribute('data-actions-box', 'true')
->required();
// 天数
$form->number('days', '天数')->required();
// 预警次数
$form->number('warning_count', '预警次数')->required()->help('设置日期内未到达该次数启动预警');;
});
// $form->hasMany('yujings', '预警配置', function (Form\NestedForm $form) {
// // 1. 产品下拉框(支持搜索选择 ✅ 你的核心需求)
// $form->selectResource('product_id', '产品')
// ->options(\App\Models\Chanpin\ChanpinList::pluck('name', 'id')) // 产品名称+ID
// ->searchable() // 开启搜索功能
// ->required();
// // 2. 天数输入框
// $form->number('days', '天数')
// ->default(0)
// ->required()
// ->help('输入预警天数');
// // 3. 预警次数输入框
// $form->number('warning_count', '预警次数')
// ->default(0)
// ->required()
// ->help('输入预警触发次数');
// });
return $form;
}
}
最近访问时间:2026-05-11 13:02:53