【VUE_ruoyi-vue】基于ruoyi-vue框架实现简单的系统通用文件模块

news2024/11/14 8:57:26

基于ruoyi-vue框架,新增一个简单的系统通用文件模块,服务与各个模块涉及到文件上传信息的记录和相关展示

运行sql,创建数据库表

DROP TABLE IF EXISTS `sys_file_info`;
CREATE TABLE `sys_file_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `link_obj_id` int(11) DEFAULT NULL COMMENT '关联对象id',
  `name` varchar(255) DEFAULT NULL COMMENT '文件名称',
  `file_type` varchar(255) DEFAULT NULL COMMENT '文件类型',
  `type` char(10) DEFAULT NULL COMMENT '归属类型(预留字段,比如归属某个模块)',
  `file_size` varchar(255) DEFAULT NULL COMMENT '文件大小',
  `file_path` varchar(255) DEFAULT NULL COMMENT '文件路径',
  `create_by` varchar(255) DEFAULT NULL COMMENT '创建人',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `i_pof_type` (`link_obj_id`,`type`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统通用文件库';

生成代码

(按正常的若依分离版生成导入代码流程走)在系统工具生成代码,然后再编辑代码生成的内容,调整一下业务名,看自己的需求吧。
在这里插入图片描述
将生成后的后端代码加入系统模块相关位置,生成的前端代码内容如果不做台账管理则只用生成的api接口文件就行,后续要用到文件删除和请求。如果需要做台账则同样加到前端相应模块下,然后运行生成的sql文件(主要是生成相关路由菜单信息)即可,其他不多赘述。

java部分

1、在文件模块的controller层补充文件上传接口,代码如下:
重点:String linkObjId = map.get(“linkObjId”); String type = map.get(“type”); 获取前端组件额外传的参数,分别对应相关模块的数据id和模块类型,因为现在采用的id是1开始递增,不是全系统唯一uuid,因此可能不同模块会出现相同id,导致文件数据绑定异常,需要加上type来区分不同的模块。

    @PostMapping(value = "/uploadFile")
    @ResponseBody
    public AjaxResult uploadFile(SysFileInfo pdFile, MultipartFile[] file, @RequestParam Map<String,String> map) {
        String linkObjId = map.get("linkObjId");
        String type = map.get("type");
        try {
            System.out.println("文件上传进入方法!");
            List<SysFileInfo> list = new ArrayList<SysFileInfo>();
            for (MultipartFile f : file) {
                // 文件保存路径
                String loadPath = FileUploadUtils.upload(RuoYiConfig.getUploadSysFilePath(), f);
                pdFile.setFilePath(loadPath);
                // 保存文件名
                String f_name = f.getOriginalFilename();
                pdFile.setName(f_name);
                pdFile.setLinkObjId(Long.valueOf(linkObjId));
                pdFile.setType(type);
                pdFile.setFileSize(
                        FileUtils.getFileSize(RuoYiConfig.getProfile() + loadPath.replace(Constants.RESOURCE_PREFIX, ""))
                                + " kb");
                sysFileInfoService.insertSysFileInfo(pdFile);
                list.add(pdFile);
            }
            return AjaxResult.success(list);
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("文件上传失败!" + e.getMessage());
        }
    }

2、RuoYiConfig.getUploadSysFilePath()爆红,为了和原来自带的上传路径(原来的是getUploadPath,按自己的需求调整,用原来的也行)做个区分,需要处理文件上传存储位置,在RuoYiConfig.java 补充以下代码。

/**
 * 系统文件
 * @return
 */
public static String getUploadSysFilePath()
{
    return getProfile() + "/sysFile";
}

3、FileUtils.getFileSize()爆红,在FileUtils.java补充获取文件大小的方法, 没有这个需求就不用处理

/**
 * 计算文件大小
 * @param  filePath
 * @return 单位是byte
 */
public static long getFileSize(String filePath) {
    long size = 0;
    FileInputStream fis= null;
    FileChannel fc= null;
    try {
        File f = new File(filePath);
        if (f.exists() && f.isFile()){
            fis= new FileInputStream(f);
            fc= fis.getChannel();
            size = fc.size();
        }else{
            // Constant.LOGGER.error("{},file doesn't exist or is not a file", filePath);
        }
    } catch (FileNotFoundException e) {
        //Constant.LOGGER.error("文件大小检查发生异常,{}", e.getMessage());
        e.getMessage();
    } catch (IOException e) {
        // Constant.LOGGER.error("文件大小检查发生异常,{}", e.getMessage());
        e.getMessage();
    } finally {
        if (null!=fc){
            try{
                fc.close();
            }catch(IOException e){
                e.getMessage();
            }
        }
        if (null!=fis){
            try{
                fis.close();
            }catch(IOException e){
                // Constant.LOGGER.error("FileInputStream资源关闭发生异常,{}", e.getMessage());
                e.getMessage();
            }
        }
    }
    return size/1024;
}

4、将原来的批量删除、和删除方法调整如下,实现先删除文件,再删除数据信息

/**
 * 批量删除系统通用文件库
 * 
 * @param ids 需要删除的系统通用文件库主键
 * @return 结果
 */
@Override
public int deleteSysFileInfoByIds(Long[] ids)
{
    for(Long id :ids){
        SysFileInfo sysFiles = selectSysFileInfoById(id);
        String path= RuoYiConfig.getProfile() + sysFiles.getFilePath().replace(Constants.RESOURCE_PREFIX, "");
        FileUtils.deleteFile(path);
    }
    return sysFileInfoMapper.deleteSysFileInfoByIds(ids);
}

/**
 * 删除系统通用文件库信息
 * 
 * @param id 系统通用文件库主键
 * @return 结果
 */
@Override
public int deleteSysFileInfoById(Long id)
{
    //删除本地文件
    SysFileInfo sysFiles = selectSysFileInfoById(id);
    String path= RuoYiConfig.getProfile() + sysFiles.getFilePath().replace(Constants.RESOURCE_PREFIX, "");
    FileUtils.deleteFile(path);
    // 删除数据库文件记录
    return sysFileInfoMapper.deleteSysFileInfoById(id);
}

其他爆红导入相关类就行。

前端在需要文件上传的地方处理文件上传

1、组件引入

<el-form-item label="附件">
	<el-upload
	  class="notice_upload"
	  ref="upload"
	  :limit="7"
	  accept=""
	  multiple
	  :data="upload.data"
	  :headers="upload.headers"
	  :action="upload.url"
	  :disabled="upload.isUploading"
	  :on-progress="handleFileUploadProgress"
	  :on-success="handleFileSuccess"
	  :on-preview="handleDownload"
	  :show-file-list="true"
	  :file-list="upload.fileList"
	  :auto-upload="false"
	  :before-remove="beforeRemove"
	  :on-remove="handleRemove"
	>
	  <em v-if="!upload.isUploading">
	    <div
	      :style="{
	        width: '80px',
	        height: '30px',
	        lineHeight: '20px',
	        color: theme,
	      }"
	    >
	      <i class="el-icon-link"></i> 点击上传
	    </div>
	  </em>
	</el-upload>
</el-form-item>

2、引入获取token

import { getToken } from "@/utils/auth";

3、引入api

import { listFileInfo,delFileInfo} from "@/api/system/fileInfo";

4、data中添加属性

upload: {
  // 是否禁用上传
  isUploading: false,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址(接口就是上文的文件上传接口)
  url: process.env.VUE_APP_BASE_API + "/system/fileInfo/uploadFile",
  // 上传的文件列表
  fileList: [],
  //携带参数
  data: {
    linkObjId: null,
    type: 1,
  }
},

5、添加对应事件

   //文件提交处理
	submitUpload() {
	  this.$refs.upload.submit();
	},
	// 文件上传中处理
	handleFileUploadProgress(event, file, fileList) {
	  this.upload.isUploading = true;
	},
	// 文件上传成功处理
	handleFileSuccess(response, file, fileList) {
	  this.upload.isUploading = false;
	},
	// 删除文件之前确认
	beforeRemove(file, fileList) {
	    return this.$confirm(`是否确定永久移除文件 ${file.name}?`);
	},
	//文件删除
	handleRemove(file, fileList) {
	  if (file.id) {
	    delFileInfo(file.id)
	      .then((res) => {
	        this.$message.success(res.msg);
	        console.log("res", res);
	      })
	      .catch((err) => {
	        this.$message.errer(err + "");
	        console.log("err", err);
	      });
	  }
	},
	// 文件下载处理
	handleDownload(file) {
	 var name = file.name;
	 //先打印看文件信息再调整url构建
	 var url = process.env.VUE_APP_BASE_API + file.filePath;
	 const a = document.createElement("a");
	 a.setAttribute("download", name);
	 a.setAttribute("target", "_blank");
	 a.setAttribute("href", url);
	 a.click();
	},

6、在表单提交时,调用文件上传方法,注意id的获取,this.upload.data.linkObjId

  /** 提交按钮 */ 			
  submitForm(e) {
	this.$refs["form"].validate((valid) => {
		if (valid) {
			if (this.form.id != null) {
				updateWorkInfo(this.form).then((response) => {
					console.log("修改:" + response)
					this.$modal.msgSuccess("修改成功");
					this.upload.data.linkObjId=this.form.id;
					this.submitUpload()
					this.open = false;
					this.$emit("cancel")
				});
			} else {
				addWorkInfo(this.form).then((response) => {
					this.$modal.msgSuccess("新增成功");
					this.upload.data.linkObjId=response.id;
					this.submitUpload()
					this.open = false;
					this.$emit("cancel")
				});
			}
		}
	}); 			
},

补充,后端处理新增返回id的方式,需求表单的id会自增:

@PostMapping
public AjaxResult add(@RequestBody WorkInfo workInfo ) {
    workInfoService.insertWorkInfo (workInfo);
    AjaxResult ajaxResult = new AjaxResult();
    ajaxResult.put("id",workInfo.getId());
    return ajaxResult;
}

7、附件回显,再点击修改或者查看事件的方法内给this.upload.fileList赋值请求到的文件列表信息就行

//查看
handleView(row) {
	this.reset();
	const id = row.id || this.ids;
	getWorkInfo(id).then((response) => {
		this.form = response.data;
		//处理文件信息(可以在后端WorkInfo加个返回参数,也可以在这里请求文件信息数据再赋值,注意type和linkObjId的参数传值)
		this.upload.fileList=response.data.sysFileInfoList
		this.seeOpen = true;
		this.title = "查看授权申请单";
	});
},

8、文件列表重置,不然会有缓存问题
在this.reset()方法里加上this.upload.fileList=[]

注意事项

1、会使用若依分离版的代码生成功能
2、注意接口是否对应得上

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2163608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎样才能远程了解在iPhone、iPad上看了什么网站、用了什么APP?

有不少家长在网上吐槽&#xff1a; ——自家小孩每天抱着手机看&#xff0c;一看就两三个小时&#xff0c;到底在看什么&#xff1f; ——没有不允许小孩玩手机&#xff0c;但他一玩就一整天&#xff0c;用什么户外活动、家庭活动都吸引不回来。 ——每次问小孩在手机上看什…

【C++掌中宝】用最少的话让你全方位理解内联函数

文章目录 引言1. 什么是内联函数2. 工作原理3. 内联函数的编程风格4. 使用限制5. 内联函数与宏的比较6. 优缺点7. 何时使用内联函数8. 补充9. 总结结语 引言 在C编程中&#xff0c;函数的调用开销是程序运行效率的一个重要影响因素。为了解决频繁调用函数时的性能问题&#xf…

8080时序

通过RS来区分是命令还是数据 在WR高电平时&#xff0c;将数据放入D[0:15]数据线上 在WR上升沿&#xff0c;读取D[0:15]数据线上的数据 //提前把默认信号设置为对应电平 static inline void LcdSendCmd(uint16_t cmdVal) {LCD_CS_RESET();//cs输出低电平&#xff0c;表示片选…

【Diffusion分割】MedSegDiff-v2:Diffusion模型进行医学图像分割

MedSegDiff-V2: Diffusion-Based Medical Image Segmentation with Transformer 摘要&#xff1a; 最近的研究揭示了 DPM 在医学图像分析领域的实用性&#xff0c;医学图像分割模型在各种任务中表现出的出色性能就证明了这一点。尽管这些模型最初是以 UNet 架构为基础的&…

低代码BPA(业务流程自动化)技术探讨

一、BPA流程设计平台的特点 可视化设计工具 大多数BPA流程设计平台提供直观的拖拽式界面&#xff0c;用户可以通过图形化方式设计、修改及优化业务流程。这种可视化的方式不仅降低了门槛&#xff0c;还便于非技术人员理解和参与流程设计。集成能力 现代BPA平台通常具备与其他系…

My_String完善

#include "my_string_ok.h" My_string_Ok::My_string_Ok():size(20) { len 0; ptr new char[size]; ptr[len] \0; } My_string_Ok::My_string_Ok(int num,char c) { cout<<"有参构造"<<endl; ptr new char [20] ; len 0; for…

K8s安装部署(v1.28)--超详细(cri-docker作为运行时)

1、准备环境 ip角色系统主机名cpumem192.168.40.129mastercentos7.9k8smaster48192.168.40.130node1centos7.9k8snode148192.168.40.131node2centos7.9k8snode248192.168.40.132node3centos7.9k8snode348 2、系统配置&#xff08;所有节点&#xff09; 重要&#xff1a;首先…

怎么更换自己的ip地址?多种方法可实现

在当今的数字化时代&#xff0c;IP地址作为我们在网络世界中的“身份证”&#xff0c;扮演着举足轻重的角色。然而&#xff0c;有时候出于隐私保护、网络安全或是访问特定服务等需求&#xff0c;我们可能需要更换自己的IP地址。那么&#xff0c;如何实现这一目标呢&#xff1f;…

2024年10月2-4日(星期三-星期五)骑行(石林-老圭山)

2024年10月2-4日 (星期六&#xff09;骑行&#xff08;石林-大草坪---长坪---石头寨---海邑镇---老圭山&#xff09;&#xff0c;早8:30到9:00&#xff0c;新螺蛳湾客运站正门&#xff0c;地铁二号线南部客运站站出口集合&#xff0c;9:30装车&#xff0c;10:00出发。偶遇地点:…

网络安全前景大好,转行这些职位成了“香饽饽”

网络安全就业前景 大数据、人工智能、云计算、物联网、5G等新兴技术的高速发展&#xff0c;蒸蒸日上。但是随之也出现了许多问题&#xff0c;比如&#xff1a;政府单位、企业、个人信息泄露&#xff0c;网络安全问题日益严峻&#xff0c;网络空间安全建设刻不容缓。 网络安全…

【unity进阶知识3】封装一个事件管理系统

前言 框架的事件系统主要负责高效的方法调用与数据传递&#xff0c;实现各功能之间的解耦&#xff0c;通常在调用某个实例的方法时&#xff0c;必须先获得这个实例的引用或者新实例化一个对象&#xff0c;低耦合度的框架结构希望程序本身不去关注被调用的方法所依托的实例对象…

亲测好用,吐血整理 ChatGPT 3.5/4.0新手使用手册~

都知道ChatGPT很强大&#xff0c;聊聊天、写论文、搞翻译、写代码、写文案、审合同等等&#xff0c;无所不能~ 那么到底怎么使用呢&#xff1f;其实很简单了&#xff0c;国内AI产品发展也很快&#xff0c;很多都很好用了~ 我一直在用&#xff0c;建议收藏下来~ 有最先进、最…

古代的“契丹人”在今天属于哪个民族

在中国古代&#xff0c;自从我国历史上的夏朝建立以来&#xff0c;一共出现了二十多个朝代。随着朝代的不断更替&#xff0c;社会也在不断前进。如今&#xff0c;封建社会已经成为过去&#xff0c;朝代和政权已不再是同一个概念。例如&#xff0c;在三国时期&#xff0c;魏、蜀…

可视掏耳勺鸡肋吗?高清可视掏耳勺牌子推荐!

很多人习惯在洗漱完顺手拿一根棉签掏耳朵&#xff0c;但是棉签的表面直径大且粗糙&#xff0c;不易将耳朵深处的耳垢挖出&#xff0c;耳垢堆积在耳道深处长时间不清理会导致堵塞耳道&#xff0c;引起耳鸣甚至感染。而可视掏耳勺作为一种新型的挖耳工具&#xff0c;它的安全性也…

羽毛球场馆预约系统,便捷管理预约

全国羽毛球运动的热度不断上升&#xff0c;在健身行业中掀起了一股羽毛球热潮。同时羽毛球运动的风靡&#xff0c;也吸引了不少人入局&#xff0c;各种大大小小的羽毛球馆不断出现&#xff0c;为大众的羽毛球喜好提供了场地。 随着互联网的发展&#xff0c;羽毛球馆也开始向线…

程序员转型攻略:数据分析师、AI大模型工程师、产品经理、云计算工程师,哪个更适合你?

先给结论再说理由&#xff1a;数据分析师、AI大模型工程师、产品经理和云计算工程师。 这些领域不仅因应了当前技术发展的趋势&#xff0c;也为程序员提供了转型的广阔舞台和职业发展的新机遇。 一起来看看吧&#xff01; 数据分析师&#xff1a;数据驱动决策的关键 程序员…

开源大模型技术路线及趋势

1. 三个维度 大模型研发力量 学术机构 大模型创业公司 科技大厂 旗舰开源模型的形态/模态 基础大模型 -> instruct大模型 -> 多模态&#xff08;VL大模型 -> 类gpt-4o大模型&#xff09; 时间线 23年上半年 23年下半年 24年 25年 2. 核心观察 学术机构及…

帮助中心:如何搭建有效解决客户问题的内容

在竞争激烈的市场环境中&#xff0c;优质的客户服务是企业脱颖而出的关键之一。而搭建一个高效、全面的帮助中心&#xff0c;提供有效解决客户问题的内容&#xff0c;则是提升客户满意度和忠诚度的重要途径。本文将探讨如何搭建这样一个帮助中心&#xff0c;以确保客户在遇到问…

机器学习_神经网络_深度学习

【神经网络——最易懂最清晰的一篇文章 - CSDN App】https://blog.csdn.net/illikang/article/details/82019945?type=blog&rId=82019945&refer=APP&source=weixin_45387165 参考以上资料,可对神经网络有初步了解。接下来可参考书籍等投身实际项目中使用。 书…

7大网络安全机构真实测评:零基础转行网安这么选就对了~

最近有不少零基础的朋友想学网络安全&#xff0c;但网络一搜索&#xff0c;各大品牌的课程都跳出来&#xff0c;让人看得眼花缭乱&#xff0c;真不知道怎么选。 今天就比较几家主流的7大网络安全机构课程&#xff0c;综合对了对比测评。不知道怎么选的朋友们&#xff0c;千万别…