DCatAdmin的文件上传组件,如何能展示原名并下载?

问题描述

文件上传以(多文件同理),使用了->uniqueName()来避免重名和文件名乱码,同时我另存了文件的原名;
在展示的时候,我想展示原名,翻了文档可以用->customFormat()方法,但是问题来了,我使用->downloadable()下载文件,只有展示成文件的真正名字,才能正确下载下来,用了customFormat()方法,下载就404,折腾好久了,求个大佬指点迷津 T-T

$form->hidden(‘file_name’);
$form->file(‘file_url’, ‘起诉状文件’)
->customFormat(function ()
{
//如果展示了原名,下载的文件就不对
return $this->file_name;
})
->accept(‘pdf’)
->uniqueName()
->downloadable()
->on(‘uploadSuccess’, <<<JS
function (file,res) { if(res.status){
$(‘input[name=file_name]’).val(file.name);
} }
JS );

期望结果

能展示原名,能成功下载,下载后的文件名还得是原名

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
Dcatplus-杨光
最佳答案

给出单个文件上传的解决方法:
只能修改dcat-admin扩展包实现。

1.vendor/dcat/laravel-admin/src/Form/Field.php

注释掉原来的函数

/**
     * @param  string  $key
     * @param  Fluent|null  $dataremoveField
     */
    protected function callCustomFormatter($key = 'value', Fluent $data = null)
    {
        /*if ($this->customFormat) {
            $this->{$key} = $this->customFormat
                ->call(
                    $data ?: $this->data(),
                    $this->{$key},
                    $this->column,
                    $this
                );
        }*/
    }

2. vendor/dcat/laravel-admin/src/Form/Field/File.php

添加新的函数,获了自义定的标题。然后把值传给js文件。

/**
     * @desc 新增 获取自定义格式的值
     * @return array|mixed|string
     * author eRic
     * dateTime 2025-04-12 16:16
     */
    protected function getCustomFormatValue(){
        $key = 'value';
        $titleArr = '';
        if($this->customFormat){
            $titleArr = $this->customFormat
                ->call(
                    $this->data(),
                    $this->{$key},
                    $this->column,
                    $this
                );
            if(\Illuminate\Support\Str::isJson($titleArr)){
                $titleArr = json_decode($titleArr);
            }

            if(!empty($titleArr) && !is_array($titleArr)){
                $titleArr = Helper::array($titleArr);
            }
        }

        return  $titleArr;
    }

修改函数

/**
     * @return array
     */
    protected function initialPreviewConfig()
    {
        $previews = [];
        $titleArr = $this->getCustomFormatValue();
        foreach (Helper::array($this->value()) as $key => $value) {
            $title = $this->objectUrl($value);
            if(!empty($titleArr[$key])){
                $title = $titleArr[$key];
            }
            $previews[] = [
                'id'   => $value,
                'path' => Helper::basename($value),
                'url'  => $this->objectUrl($value),
                'title' => $title, // 追加一个值
            ];
        }
        return $previews;
    }

3 修改js文件

文件位置:public/vendor/dcat-admin/dcat/extra/upload.js

  1. 拿这个serverUrl:t.preview[e].url 去查找,找到如图中的代码:找到后,添加一项新的值:serverTitle:t.preview[e].title
    file
    serverTitle:t.preview[e].title
  2. 拿这个feather icon-check text-white icon-success text-white 去查找,找到如图中的代码。把它改成serverTitle.

file

最终效果截图

file

优化说明

如果不使用 customFormat(),也不会报错,会使用原始值。做到兼容。如果是多个文件上传,有追加,有删除。优化起来就比较复杂了。
有任何疑问可以加我微信(Q3664839),可以给予指导如何修改

4天前 评论
Proton (楼主) 4天前
讨论数量: 7
Mutoulee

$grid中的话还好说一点,$form中好像还真没办法 :flushed:

5天前 评论
Proton (楼主) 4天前
Dcatplus-杨光

dcat-admin 暂时没有支持的。也不好解决。像你说的,单文件还有可能解决,多文件就现在的数据结构不好解决。 每一个上传的文件,要有标题,真实下载地址。像这种数据结构,最好是使用一个单独的媒体数据表去存放。

我给你一个思路:

1.新建一个媒体数据表。

2.每上传一个文件,把记录存在媒体数据表中,有标题,文件大小,文件类型,真实下载地址等。

3.在其它地方使用时去关联这个表,然后去展示信息,提供功能,如下载,预览等。

4天前 评论
Dcatplus-杨光

给出单个文件上传的解决方法:
只能修改dcat-admin扩展包实现。

1.vendor/dcat/laravel-admin/src/Form/Field.php

注释掉原来的函数

/**
     * @param  string  $key
     * @param  Fluent|null  $dataremoveField
     */
    protected function callCustomFormatter($key = 'value', Fluent $data = null)
    {
        /*if ($this->customFormat) {
            $this->{$key} = $this->customFormat
                ->call(
                    $data ?: $this->data(),
                    $this->{$key},
                    $this->column,
                    $this
                );
        }*/
    }

2. vendor/dcat/laravel-admin/src/Form/Field/File.php

添加新的函数,获了自义定的标题。然后把值传给js文件。

/**
     * @desc 新增 获取自定义格式的值
     * @return array|mixed|string
     * author eRic
     * dateTime 2025-04-12 16:16
     */
    protected function getCustomFormatValue(){
        $key = 'value';
        $titleArr = '';
        if($this->customFormat){
            $titleArr = $this->customFormat
                ->call(
                    $this->data(),
                    $this->{$key},
                    $this->column,
                    $this
                );
            if(\Illuminate\Support\Str::isJson($titleArr)){
                $titleArr = json_decode($titleArr);
            }

            if(!empty($titleArr) && !is_array($titleArr)){
                $titleArr = Helper::array($titleArr);
            }
        }

        return  $titleArr;
    }

修改函数

/**
     * @return array
     */
    protected function initialPreviewConfig()
    {
        $previews = [];
        $titleArr = $this->getCustomFormatValue();
        foreach (Helper::array($this->value()) as $key => $value) {
            $title = $this->objectUrl($value);
            if(!empty($titleArr[$key])){
                $title = $titleArr[$key];
            }
            $previews[] = [
                'id'   => $value,
                'path' => Helper::basename($value),
                'url'  => $this->objectUrl($value),
                'title' => $title, // 追加一个值
            ];
        }
        return $previews;
    }

3 修改js文件

文件位置:public/vendor/dcat-admin/dcat/extra/upload.js

  1. 拿这个serverUrl:t.preview[e].url 去查找,找到如图中的代码:找到后,添加一项新的值:serverTitle:t.preview[e].title
    file
    serverTitle:t.preview[e].title
  2. 拿这个feather icon-check text-white icon-success text-white 去查找,找到如图中的代码。把它改成serverTitle.

file

最终效果截图

file

优化说明

如果不使用 customFormat(),也不会报错,会使用原始值。做到兼容。如果是多个文件上传,有追加,有删除。优化起来就比较复杂了。
有任何疑问可以加我微信(Q3664839),可以给予指导如何修改

4天前 评论
Proton (楼主) 4天前
Dcatplus-杨光

在原来的基础上,要兼容多文件上传。

如下代码:

$form->hidden('file_name');
            $form->multipleFile('file_url', '起诉状文件')
                ->customFormat(function (){
                    // 如果展示了原名,下载的文件就不对
                    return $this->file_name;
                })
                ->disk('public')
                ->autoUpload()
                ->uniqueName()
                ->downloadable()
                ->on('uploadSuccess', <<<JS
        function (file,res) {
// 获取当前的 file_name 值
var file_name_value = $('input[name=file_name]').val();
// 初始化一个空数组
var fileNamesArray = [];
// 检查 file_name_value 是否为空
if (file_name_value) {
    try {
        // 尝试将 JSON 字符串解析为数组
        fileNamesArray = JSON.parse(file_name_value);
    } catch (e) {
        console.error("解析 JSON 时出错:", e);
        // 如果解析失败,可以选择清空数组或处理错误
        fileNamesArray = [];
    }
}
// 将 file.name 添加到数组中
fileNamesArray.push(file.name);

// 将更新后的数组转换回 JSON 字符串
var updatedFileNames = JSON.stringify(fileNamesArray);

// 将更新后的值填充回输入框
$('input[name=file_name]').val(updatedFileNames);
        }
JS
                );

在删除某个文件后,要自己去更新file_name 字段。

4天前 评论
Proton (楼主) 3天前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!