Laravel-Admin 新增和编辑差异化显示

在使用 Laravel-admin 开发后台管理系统时,新增编辑 页面需要展示不同表单字段是高频需求。以附件管理模块为例:

  • 新增页面:仅展示文件上传框,必填上传
  • 编辑页面:展示文件详情、预览图,提供可选重新上传功能

本文将完整讲解 Laravel-admin 新增 / 编辑区分显示的实现方法,包含表结构、核心代码、关键逻辑与效果说明,可直接用于项目开发。

目录

需求与场景

附件数据表结构

[核心实现:新增 / 编辑区分表单](#核心实现:新增 / 编辑区分表单)

关键核心要点

[1. 操作判断用官方方法](#1. 操作判断用官方方法)

[2. 必须忽略虚拟字段](#2. 必须忽略虚拟字段)

[3. 编辑文件替换逻辑](#3. 编辑文件替换逻辑)

[4. 页面展示效果](#4. 页面展示效果)

页面效果说明

新增页面

编辑页面

可复用场景

总结


需求与场景

  1. 新增页面:只显示文件上传组件,用户必须上传文件
  2. 编辑页面:展示文件完整信息(ID、名称、大小、尺寸)+ 文件预览 + 可选重新上传
  3. 编辑时不上传新文件则保留原文件,上传则自动替换旧文件
  4. 避免表单虚拟字段 file 入库导致 SQL 报错

附件数据表结构

创建 attachments 表存储文件信息,字段覆盖文件基础属性、图片属性、上传信息:

sql 复制代码
CREATE TABLE `attachments` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件名称',
  `filename` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件名',
  `path` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件路径',
  `extension` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '文件扩展名',
  `mime_type` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'MIME 类型',
  `size` int(11) NOT NULL DEFAULT '0' COMMENT '文件大小 (字节)',
  `type` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'file' COMMENT '文件类型:file-文件,image-图片',
  `width` int(11) DEFAULT NULL COMMENT '图片宽度',
  `height` int(11) DEFAULT NULL COMMENT '图片高度',
  `uploaded_by` int(11) DEFAULT NULL COMMENT '上传人 ID',
  `hash` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文件 hash 值',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `attachments_type_extension_index` (`type`,`extension`),
  KEY `attachments_uploaded_by_index` (`uploaded_by`),
  KEY `attachments_hash_index` (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

核心实现:新增 / 编辑区分表单

Laravel-admin 提供内置官方方法判断操作类型,稳定且兼容所有版本:

  • $form->isCreating():判断是否为新增页面
  • $form->isEditing():判断是否为编辑页面

完整表单代码

php 复制代码
/**
     * Make a form builder.
     *
     * @return Form
     */
    protected function form()
    {
        $form = new Form(new Attachment());

        // 正确判断:用 laravel-admin 内置方法,100% 生效
        $isEditing = $form->isEditing();
        $isCreating = $form->isCreating();

        if ($isEditing) {
            // 编辑模式:显示详情 + 可选重新上传
            $form->display('id', 'ID');
            $form->display('name', '原文件名称');
            $form->display('filename', '存储文件名');
            $form->display('extension', '扩展名');
            $form->display('size', '文件大小')->with(function ($size) {
                return Attachment::formatFileSize($size);
            });

            // 图片尺寸
            $form->html(function () {
                $ext = strtolower($this->extension ?? '');
                $isImg = in_array($ext, ['jpg','jpeg','png','gif','bmp','webp']);
                if ($isImg && $this->width && $this->height) {
                    return "<div style='margin:10px 0'><strong>尺寸:</strong>{$this->width}×{$this->height}</div>";
                }
                return '';
            }, '图片信息');

            // 预览图
            $form->html(function () {
                $ext = strtolower($this->extension ?? '');
                $isImg = in_array($ext, ['jpg','jpeg','png','gif','bmp','webp']);
                if ($isImg) {
                    return "<img src='{$this->url}' style='max-width:200px;border-radius:8px;box-shadow:0 2px 4px rgba(0,0,0,0.1);' />";
                }
                return "<i class='fa {$this->file_icon}' style='font-size:4rem;color:#1890ff;'></i>";
            }, '文件预览');

            // 编辑时:可选重新上传
            $form->file('file', '重新上传文件(留空则不修改)')
                ->required(false)
                ->help('支持:'.implode(', ', config('upload.allowed_extensions'))
                    .',最大:'.Attachment::formatFileSize(config('upload.max_size')));
        }

        if ($isCreating) {
            // 新增模式:只显示上传框
            $form->file('file', '选择文件')
                ->required()
                ->help('支持:'.implode(', ', config('upload.allowed_extensions'))
                    .',最大:'.Attachment::formatFileSize(config('upload.max_size')));
        }

        $form->disableReset();
        $form->ignore('file'); //必须忽略 file 字段,避免 SQL 报错

        // 保存前处理
        $form->saving(function (Form $form) {
            $file = request()->file('file');
            if (!$file) return;

            $fileInfo = UploadService::upload($file);
            if (!$fileInfo) throw new \Exception('文件上传失败');

            // 编辑模式:删除旧文件
            if ($form->isEditing()) {
                Log::info('编辑附件:'.$form->model()->id);
                Log::info('旧文件:'.$form->model()->filename);
                $old = Attachment::findOrFail($form->model()->id);
                $old->deleteFile();
            }

            $form->model()->fill($fileInfo);
            $form->model()->uploaded_by = Admin::user()->id;
        });

        // 保存成功提示
        $form->saved(function () use ($isCreating) {
            $msg = $isCreating ? '上传成功' : '更新成功';
            admin_toastr($msg, 'success');
        });

        return $form;
    }

关键核心要点

1. 操作判断用官方方法

禁止 使用 request()->has('id') 等自定义判断,$form->isEditing()/isCreating() 是 Laravel-admin 官方方案,稳定无兼容问题。

2. 必须忽略虚拟字段

file 是表单上传字段,数据表不存在,必须用 $form->ignore('file') 忽略,否则会报 SQL 字段不存在 错误。

3. 编辑文件替换逻辑

  • 不上传新文件:不修改原数据
  • 上传新文件:自动删除旧物理文件 → 写入新文件信息
  • 需在 Attachment 模型中实现 deleteFile() 方法删除服务器文件

4. 页面展示效果

  • 新增页面:仅显示文件上传框,简洁必填
  • 编辑页面:展示文件详情、图片尺寸、预览图,支持重新上传

页面效果说明

新增页面

仅展示「选择文件」上传组件,标注支持格式与大小限制,用户只需上传文件即可提交。

编辑页面

展示文件 ID、原名称、存储名、扩展名、大小、图片尺寸;

支持图片 / 文件图标预览;

底部提供「重新上传文件」输入框,留空则不修改原文件。

可复用场景

本方案不局限于附件管理,可直接迁移到以下场景:

  • 商品管理:新增填全字段,编辑只改部分字段
  • 用户资料:新增填账号密码,编辑改资料不上传密码
  • 文章管理:新增传封面,编辑可替换封面

总结

本文完整实现了 Laravel-admin 新增与编辑页面差异化显示 的附件管理功能,核心总结如下:

  1. 场景明确:解决后台表单新增、编辑需要展示不同字段的通用问题
  2. 方案标准:使用 Laravel-admin 官方判断方法,无兼容风险、代码规范
  3. 功能完整:包含文件上传、详情展示、预览、编辑替换、旧文件删除
  4. 关键处理:忽略虚拟字段避免 SQL 错误,编辑模式智能处理文件替换
  5. 通用性强:代码可直接复用,适配商品、用户、文章等多种后台模块
相关推荐
niucloud-admin3 小时前
PHP V6 单商户常见问题——卸载应用插件编译报错问题处理
php
学网安的肆伍17 小时前
【043-WEB攻防篇】PHP应用&SQL注入&符号拼接&请求方法&HTTP头&JSON&编码类
sql·安全·php
研究点啥好呢19 小时前
字节跳动Go后端开发工程师面试题精选:10道高频考题+答案解析
面试·golang·php·求职招聘
kybs199120 小时前
springboot租车系统--附源码68701
java·hadoop·spring boot·python·django·asp.net·php
wxin_VXbishe20 小时前
springboot新能源车充电站管理系统小程序-计算机毕业设计源码29213
java·c++·spring boot·python·spring·django·php
嵌入式×边缘AI:打怪升级日志21 小时前
Linux 驱动与应用开发核心自测题库(面试官问答完整版)
linux·运维·php
fengci.1 天前
CTF+随机困难题目
android·开发语言·前端·学习·php
xxjj998a1 天前
PHP vs C#:两大编程语言终极对比
开发语言·c#·php
AIGC设计所1 天前
网络安全8大就业领域和待遇对比!
运维·开发语言·网络·安全·web安全·php