laravel-admin动态表单添加删除
xuexi 2026-05-09 10:32:55 发表在:PHP 查看数:33

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
知识库:456条鸣谢:TAY  备案号:蜀ICP备2024090044号