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

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

运行sql,创建数据库表

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来区分不同的模块。

java 复制代码
    @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 补充以下代码。

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

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

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、将原来的批量删除、和删除方法调整如下,实现先删除文件,再删除数据信息

java 复制代码
/**
 * 批量删除系统通用文件库
 * 
 * @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、组件引入

java 复制代码
<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

java 复制代码
import { getToken } from "@/utils/auth";

3、引入api

java 复制代码
import { listFileInfo,delFileInfo} from "@/api/system/fileInfo";

4、data中添加属性

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

5、添加对应事件

java 复制代码
   //文件提交处理
	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

java 复制代码
  /** 提交按钮 */ 			
  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会自增:

java 复制代码
@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赋值请求到的文件列表信息就行

java 复制代码
//查看
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、注意接口是否对应得上

相关推荐
疯狂的沙粒4 分钟前
Vue 前端大屏做多端屏幕适配时,如何让其自动适配多种不同尺寸的屏幕?
前端·javascript·vue.js
范小多7 分钟前
24小时学会Python Visual code +Python Playwright通过谷歌浏览器取控件元素(连载、十一)
服务器·前端·python
ooolmf8 分钟前
matlab2024读取温度01
java·前端·javascript
打工人小夏9 分钟前
前端vue3项目使用nprogress动画组件,实现页面加载动画
前端
一颗宁檬不酸11 分钟前
前端农业商城中产品产地溯源功能的实现
前端
李少兄18 分钟前
深入理解前端中的透视(Perspective)
前端·css
席之郎小果冻20 分钟前
【03】【创建型】【聊一聊,单例模式】
开发语言·javascript·单例模式
江公望28 分钟前
HTML5 History 模式 5分钟讲清楚
前端·html·html5
云和数据.ChenGuang35 分钟前
Zabbix Web 界面安装时**无法自动创建配置文件 `zabbix.conf.php`** 的问题
前端·zabbix·运维技术·数据库运维工程师·运维教程
码界奇点37 分钟前
Java Web学习 第15篇jQuery万字长文详解从入门到实战解锁前端交互新境界
java·前端·学习·jquery