在我们很多模块里面,都需要使用到一些诸如图片、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. Linux入门到放弃之八《任务计划管理》

    任务计划管理 1.每周一下午5:50将/data目录下的所有目录和文件归档并压缩为:backup.tar.gz 放在/home/backup目录下. 先新建/data目录,并在目录中随意生成几个文件 ...

  2. 我天天curd,怎么才能成长?

    起因 "天天在那curd,也没啥技术含量" "你就是一个curd boy" "你就是一个curder啊" "你不写代码,你只是代码 ...

  3. SpringBoot+HikariCP+Dropwizard-Metrics统计连接池使用情况

    SpringBoot+HikariCP+Dropwizard-Metrics统计连接池使用情况 背景,HikariCP是Java目前使用最广的连接池工具类,SpringBoot默认也是用这个,现在想获 ...

  4. Android Studio的第一次经历

    第一个简单APP的制作是从xml开始的,通过在java新建一个empty  activity,并在layout里找到对应的xml文件进行编写.每编写一个xml就要事先新建 一个对应的empty  ac ...

  5. python爬虫scrapy框架

    Scrapy 框架 关注公众号"轻松学编程"了解更多. 一.简介 Scrapy是用纯Python实现一个为了爬取网站数据.提取结构性数据而编写的应用框架,用途非常广泛. 框架的力量 ...

  6. 洛谷P6623——[省选联考 2020 A 卷] 树

    传送门:QAQQAQ 题意:自己看 思路:正解应该是线段树/trie树合并? 但是本蒟蒻啥也不会,就用了树上二次差分 (思路来源于https://www.luogu.com.cn/blog/dengy ...

  7. How to Convert and Import VHD to VMDK (VMWare)

    VHD or Virtual Hard Disk is the disk image format used by Microsoft virtualization software such as ...

  8. 1.使用javax.mail, spring的JavaMailSender,springboot发送邮件

    一.java发邮件 电子邮件服务器:这些邮件服务器就类似于邮局,它主要负责接收用户投递过来的邮件,并把邮件投递到邮件接收者的电子邮箱中,按功能划分有两种类型 SMTP邮件服务器:用户替用户发送邮件和接 ...

  9. JavaSE基础语法学习-方法&数组

    方法 Java方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 设计方法的原则:方法的本意是功能块,就是实现某 ...

  10. LR-demo

    from __future__ import print_function   # 导入相关python库 import os import numpy as np import pandas as ...