在我们很多模块里面,都需要使用到一些诸如图片、Excel文件、PDF文件等附件的管理,一般我们倾向于把它独立为一个公用的附件管理模块,这样可以有效的统一管理附件的信息。本篇随笔介绍附件内容的管理,包括可以对图片进行预览,对其他文件实现信息的查看和下载等操作,以及后端提供对应的附件上传等处理。

1、附件管理的界面

和其他模块一样,我们可以对附件记录表里面的信息进行管理,一般情况下,我们管理的附件都是诸如图片、Excel文件、PDF文件等附件的管理。

附件表是一个综合管理这些文件的记录表,虽然附件一般是独立上传到服务器端的文件系统里面,不过也需要记录这些文件的名称、类别名称、大小、后缀名、创建时间、创建人等信息。

数据库设计表如下所示。

记录明细大概如下所示。

为了管理好这些文件信息,我们在界面提供一些条件供查询,如下是管理界面。

为了快速的进行检索,我们提供了两个树形列表进行查询,可以按照文件类型,以及按照类别名称查询,类别是我们在上传的时候指定的一个附件的类别名称。

按文件类型分类如下所示

按类别名称分类如下所示。

而树形列表的信息展示,我们使用了自定义的树列表控件,非常方便,并极大减少了界面代码,界面代码如下所示。

<el-tabs value="treeType" type="border-card">
<el-tab-pane name="treeType" label="按文件类型">
<myTree :data="treeType" icon-class="el-icon-price-tag" @nodeClick="nodeTypeClick" />
</el-tab-pane>
<el-tab-pane name="treeCategory" label="按类别名称">
<myTree :data="treeCategory" icon-class="el-icon-price-tag" @nodeClick="nodeCategoryClick" />
</el-tab-pane>
</el-tabs>

而树形列表的类别名称,我们是从数据库中动态获取的,因此需要特殊的API封装调用。

在ABP框架的后端,应用服务类FileUploadAppService中定义一个获取类别的列表接口

        /// <summary>
/// 获取所有类别(Distinct)
/// </summary>
/// <returns></returns>
public virtual async Task<List<string>> GetAllCategory()
{
var query = Repository.GetAll().Where(s=> s.Category != null).OrderBy(s => s.Category);
var list = query.Select(s => s.Category).Distinct().ToList();
return await Task.FromResult(list);
}

在客户端的API调用类中同时增加一个API处理接口,如下所示。

而Element的前端调用后端的ABP接口,前面很多博客也介绍的很多了,如下是它们的处理过程图示。

前端根据ABP后端的接口进行前端JS端的类的封装处理,引入了ES6类的概念实现业务基类接口的统一封装,简化代码。

大多数模块我们涉及到常规增删改查等业务接口,那么这些类继承BaseApi,就会具有相关的接口了,如下所示继承关系。

其中JS类的BaseApi具有常规的增删改查接口,如下所示。

在整合ABP后端接口的时候,我们为了方便,一般使用ES6的方式定义一个客户端的Api调用类,基础接口封装在BaseApi类里面,扩展自定义接口放在子类定义,因此前端API封装类fileupload.js的类关系如下所示。

我们再次回到管理界面,在列表中展示附件信息外,如果是图片提供预览,如果是文件则提供下载链接,方便处理。

或者

预览查看图片文件的时候,我们也需要在明细中列出附件的一些信息,如下界面所示。

以上就是附件管理的设计表,以及管理界面,其中前端主要使用了Vue + Element进行开发,后端还是用ABP的框架提供相关的API接口。

2、附件上传的处理

在之前随笔《循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理》中已经比较详细的介绍了对附件的上传处理,我们ABP后端提供了一些API接口给前端界面控件进行调用即可上传对应的附件

在附件上传处理的时候,我们就可以通过这样获得请求的文件对象了,如下代码所示。

我们上传到后端ABP应用服务器的文件,一般情况是不能访问目录的,如果需要特别放行,那么需要在ABP服务的Host应用里面,设置静态文件,允许前端访问我们的文件路径。

一般在Host项目的启动入口设置即可。

        public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
............ app.UseStaticFiles();
//指定特定的目录作为静态文件目录,如UploadFiles
//是否可以访问静态文件
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "UploadFiles")),
RequestPath = "/UploadFiles"
}); .........

这样上传的文件,在对应目录里面,就可以通过URL地址访问了。

另外,前面我们看到的数据记录里面,没有绝对的URL地址,一般是为了适应性方便,不需要绝对的地址。

但是前端为了方便,服务器后端返回的接口中,我们一般增加一个绝对的地址信息供查看或者下载文件,那么我们可以在后端对应附件记录的转义函数里面增加一个对相对地址转换为绝对访问的URL地址的转换即可。

        /// <summary>
/// 对记录进行转义
/// </summary>
/// <param name="item">dto数据对象</param>
/// <returns></returns>
protected override void ConvertDto(FileUploadDto item)
{
//转义相对地址为绝对地址
item.FileUrl = GetFileUrl(item.BasePath, item.SavePath);
}
        /// <summary>
/// 根据记录的basePath和savePath,以及HttpContext上下文确定绝对路径
/// </summary>
/// <param name="basePath">附件的基础路径</param>
/// <param name="savePath">附件的保存路径</param>
/// <returns></returns>
private string GetFileUrl(string basePath, string savePath)
{
var httpContext = _httpContext.HttpContext;
string serverRealPath = basePath.UriCombine(savePath);
if (!Path.IsPathRooted(basePath) &&
!basePath.StartsWith("http://") &&
!basePath.StartsWith("https://"))
{
//如果是相对目录,加上当前程序的目录才能定位文件地址
var url = string.Format("{0}://{1}", httpContext.Request.Scheme, httpContext.Request.Host.Value);
serverRealPath = url.UriCombine(serverRealPath).Replace('\\', '/');
}
return serverRealPath;
}

而前端界面中,一般的图片和附件上传界面如下所示。

编辑界面下,附件上传界面,可以加载已有的记录展示,如下所示。

用图片列表控件的方式展示图片信息,如下所示。

如果我们用Element的上传组件,大概的界面代码如下所示,主要设置好上传的API地址,以及给它提供好对应的授权头部信息即可。

前端界面的代码如下所示。

    <el-form-item label="封面图片">
<el-upload
ref="upload"
action="/abp/services/app/FileUpload/PostUpload"
list-type="picture-card"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:on-success="onSuccess"
:on-error="onError"
accept="image/jpeg,image/gif,image/png,image/bmp"
:headers="myHeaders"
:file-list="editForm.fileList"
>
<i class="el-icon-plus" />
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</el-form-item>

其中授权头部信息,是ABP约定的授权请求头部信息,如下属性设置

  myHeaders: { Authorization: 'Bearer ' + getToken() }, // 用于上传文件的身份认证

这样就可以整合文件上传的管理操作了,而前端就只需要针对附件信息,做统一的管理即可。

如下是统一的附件管理界面入口。

为了方便读者理解,我列出一下前面几篇随笔的连接,供参考:

循序渐进VUE+Element 前端应用开发(1)--- 开发环境的准备工作

循序渐进VUE+Element 前端应用开发(2)--- Vuex中的API、Store和View的使用

循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理

循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理

循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

循序渐进VUE+Element 前端应用开发(7)--- 介绍一些常规的JS处理函数

循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用

循序渐进VUE+Element 前端应用开发(9)--- 界面语言国际化的处理

循序渐进VUE+Element 前端应用开发(10)--- 基于vue-echarts处理各种图表展示

循序渐进VUE+Element 前端应用开发(11)--- 图标的维护和使用

循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理

循序渐进VUE+Element 前端应用开发(13)--- 前端API接口的封装处理

循序渐进VUE+Element 前端应用开发(14)--- 根据ABP后端接口实现前端界面展示

循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理

循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理

循序渐进VUE+Element 前端应用开发(17)--- 菜单管理

循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

循序渐进VUE+Element 前端应用开发(21)--- 省市区县联动处理的组件使用

循序渐进VUE+Element 前端应用开发(22)--- 简化main.js处理代码,抽取过滤器、全局界面函数、组件注册等处理逻辑到不同的文件中

循序渐进VUE+Element 前端应用开发(23)--- 基于ABP实现前后端的附件上传,图片或者附件展示管理

循序渐进VUE+Element 前端应用开发(24)--- 修改密码的前端界面和ABP后端设置处理

循序渐进VUE+Element 前端应用开发(25)--- 各种界面组件的使用(1)

循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

ABP框架中一对多,多对多关系的处理以及功能界面的处理(1)

电商商品数据库的设计和功能界面的处理

ABP框架中一对多,多对多关系的处理以及功能界面的处理(2)

循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

循序渐进VUE+Element 前端应用开发(28)--- 附件内容的管理的更多相关文章

  1. 循序渐进VUE+Element 前端应用开发(18)--- 功能点管理及权限控制

    在一个业务管理系统中,如果我们需要实现权限控制功能,我们需要定义好对应的权限功能点,然后在界面中对界面元素的功能点进行绑定,这样就可以在后台动态分配权限进行动态控制了,一般来说,权限功能点是针对角色进 ...

  2. 循序渐进VUE+Element 前端应用开发(26)--- 各种界面组件的使用(2)

    在我们使用Vue+Element开发前端的时候,往往涉及到很多界面组件的使用,其中很多直接采用Element官方的案例即可,有些则是在这个基础上封装更好利用.更少代码的组件:另外有些则是直接采用第三方 ...

  3. 循序渐进VUE+Element 前端应用开发(27)--- 数据表的动态表单设计和数据存储

    在我们一些系统里面,有时候会需要一些让用户自定义的数据信息,一般这些可以使用扩展JSON进行存储,不过每个业务表的显示项目可能不一样,因此需要根据不同的表单进行设计,然后进行对应的数据存储.本篇随笔结 ...

  4. 循序渐进VUE+Element 前端应用开发(19)--- 后端查询接口和Vue前端的整合

    循序渐进VUE+Element 前端应用开发的系列文章中,前面介绍了系统各个功能的处理实现,本篇随笔从一个主线上介绍前后端开发的整合,让我们从ABP框架后端的查询接口的处理,前端API接口调用的封装, ...

  5. 循序渐进VUE+Element 前端应用开发(20)--- 使用组件封装简化界面代码

    VUE+Element 前端应用,比较不错的一点就是界面组件化,我们可以根据重用的指导方针,把界面内容拆分为各个不同的组合,每一个模块可以是一个组件,也可以是多个组件的综合体,而且这一个过程非常方便. ...

  6. 循序渐进VUE+Element 前端应用开发(4)--- 获取后端数据及产品信息页面的处理

    在前面随笔<循序渐进VUE+Element 前端应用开发(3)--- 动态菜单和路由的关联处理>中介绍了在Vue + Element整合框架中,实现了动态菜单和动态路由的处理,从而可以根据 ...

  7. 循序渐进VUE+Element 前端应用开发(5)--- 表格列表页面的查询,列表展示和字段转义处理

    在我们一般开发的系统界面里面,列表页面是一个非常重要的综合展示界面,包括有条件查询.列表展示和分页处理,以及对每项列表内容可能进行的转义处理,本篇随笔介绍基于Vue +Element基础上实现表格列表 ...

  8. 循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用

    在我们开发BS页面的时候,往往需要了解常规界面组件的使用,小到最普通的单文本输入框.多文本框.下拉列表,以及按钮.图片展示.弹出对话框.表单处理.条码二维码等等,本篇随笔基于普通表格业务的展示录入的场 ...

  9. 循序渐进VUE+Element 前端应用开发(8)--- 树列表组件的使用

    在我前面随笔<循序渐进VUE+Element 前端应用开发(6)--- 常规Element 界面组件的使用>里面曾经介绍过一些常规的界面组件的处理,主要介绍到单文本输入框.多文本框.下拉列 ...

随机推荐

  1. 一个例子"入坑"布谷鸟算法(附完整py代码)

    布谷鸟是比较新的启发式最优化算法,但其与传统的遗传算法,退火算法等相比,被证明收敛速度更快,计算效率更高! 文章目录 本文诞生的缘由 布谷鸟算法思想简介 更新位置的方式 莱维飞行 局部随机行走 抛出个 ...

  2. .net core 3.1 vs2019报HTTP Error 500.30 - ANCM In-Process Start Failure

    vs启动报此错误的话查看自己的程序是3.1.1还是3.1.2.解决防范安装高版本的重启

  3. 如何利用go-zero在Go中快速实现JWT认证

    关于JWT是什么,大家可以看看官网,一句话介绍下:是可以实现服务器无状态的鉴权认证方案,也是目前最流行的跨域认证解决方案. 要实现JWT认证,我们需要分成如下两个步骤 客户端获取JWT token. ...

  4. 使用Node.js原生API写一个web服务器

    Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...

  5. pyqy5 程序实例1

    import sys from PyQt5.QtWidgets import QMainWindow,QApplication from PyQt5.QtGui import QIcon class ...

  6. SQL Server 列存储索引 第二篇:设计

    列存储索引可以是聚集的,也可以是非聚集的,用户可以在表上创建聚集的列存储索引(Clustered Columnstore Index)或非聚集的列存储索引(Nonclustered Columnsto ...

  7. Java学习的第三十四天

    1.今天复习完了第十二章 2.有很多的方法不知道什么意思,也记不清该用什么方法. 3.明天写例题.

  8. DevOps 视角的前后端分离与实战

    本文作者:CODING - 廖红坤 前言 随着微前端.微服务等技术理念和架构的蓬勃发展,我们已经没必要去讨论为什么要前后端分离这种话题,前后端分离已成为互联网项目开发的标准模式.前后端在各自的领域发展 ...

  9. python面向对象(类与对象)

    面向对象思想 关注公众号"轻松学编程"了解更多. 1.面向对象的设计思想 面向对象是基于万物皆对象这个哲学观点. 2.面向对象和面向过程的区别 面向过程 在生活中: 它是一种看待问 ...

  10. KVM简介,安装及常见使用详解

    KVM简介 KVM(名称来自英语:Kernel-basedVirtual Machine的缩写,即基于内核的虚拟机),是一种用于Linux内核中的虚拟化基础设施,可以将Linux内核转化为一个hype ...