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

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

数据库设计表如下所示。

记录明细大概如下所示。

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

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

按文件类型分类如下所示

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

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

复制代码

<myTree :data=“treeType” icon-class=“el-icon-price-tag” @nodeClick=“nodeTypeClick” />


 <myTree :data=“treeCategory” icon-class=“el-icon-price-tag” @nodeClick=“nodeCategoryClick” />


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

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

复制代码
 /// 
 /// 获取所有类别(Distinct)
 /// 
 /// 
 public virtual async Task<List> 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地址的转换即可。

复制代码

/// 
 /// 对记录进行转义
 /// 
 /// dto数据对象
 /// 
 protected override void ConvertDto(FileUploadDto item)
 {
 //转义相对地址为绝对地址
 item.FileUrl = GetFileUrl(item.BasePath, item.SavePath);
 }
 复制代码
 复制代码
 /// 
 /// 根据记录的basePath和savePath,以及HttpContext上下文确定绝对路径
 /// 
 /// 附件的基础路径
 /// 附件的保存路径
 /// 
 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地址,以及给它提供好对应的授权头部信息即可。

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

复制代码



myHeaders: { Authorization: 'Bearer ’ + getToken() }, // 用于上传文件的身份认证
这样就可以整合文件上传的管理操作了,而前端就只需要针对附件信息,做统一的管理即可。



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