1、前端 Vue3

QualityFileInfoDialog.vue

<script setup lang="ts" name="QualityFile">
......
// 上传,防抖
const onUploadClick = debounce(() => {// 模拟点击元素if (fileInputRef.value) {// 重置以允许重复选择相同文件fileInputRef.value.value = "";fileInputRef.value.click();}},1000,{ leading: true, trailing: true, maxWait: 1000 }
);// 点击【上传】触发,实现 SQL Server image 类型文件上传
const handleUpload = async (e: Event) => {// 清空 FormData 表单数据的内容:重新赋值,创建新实例,旧数据被丢弃(完全清空),需要使用 let 声明对象,不能使用 const 声明对象formData = new FormData();// 获取文件对象const input = e.target as HTMLInputElement;if (!input.files?.length) return;const file = input.files[0];// 校验文件大小if (file.size > 1024 * 1024 * 10) {ElMessage.warning("文件大小不能超过10MB");return;}if (file) {// 获取文件名的扩展名(后缀)extension.value = getExtension(file.name);if (upperCase(extension.value) === upperCase("pdf")) {// 将文件对象 file 添加到 formData 对象中,uploadFile 需要与后端接口中接收文件的参数名一致,如果不一致,则后端需要指定参数名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 无需点击确定,直接发送请求,上传文件到数据库,实现 SQL Server image 类型文件上传await qualityFileUploadFileWithPutService(qualityFileObj.value.fileNo, formData);} else {// 将文件对象 file 添加到 formData 对象中,uploadFile 需要与后端接口中接收文件的参数名一致,如果不一致,则后端需要指定参数名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 将普通对象 qualityFileObj 的 fileNo 属性添加到 formData 对象中formData.append("fileNo", qualityFileObj.value.fileNo);// 无需点击确定,直接发送请求,上传文件到数据库,实现 SQL Server image 类型文件上传await qualityFileUploadFileService(formData);}// 点击【上传/重传】选择文件后,上传文件完成,通知父组件更新文件路径名称和是否空内容的操作emit("upload-file-complete", file.name);// 同步更新表单数据qualityFileObj.value.filePathname = file.name;qualityFileObj.value.isNullContent = false;}
};
......
</script><template>
......<el-table-column label="操作" width="150" header-align="center" align="center" fixed="right"><template #default="scope"><BasePreventReClickButton type="primary" plain :loading="false" @click="onUploadClick">{{qualityFileObj.isNullContent ? "上传" : "重传"}}</BasePreventReClickButton>></template></el-table-column>
......
</template>

qualityFile.ts

import request from "@/utils/request";
import type { IQualityFile, IQualityFileQueryObj } from "@/views/resources/QualityFile/types";/*** 上传质量体系文件,实现 SQL Server image 类型文件上传,使用 put 发送请求,发送的数据有:请求体数据(文件数据 uploadFile),请求参数数据(文件编号 fileNo)* @param fileNo 文件编号(可能包含特殊字符如 /)* @param formData 表单数据,包含的数据只有:文件数据(uploadFile)* @returns*/
export const qualityFileUploadFileWithPutService = (fileNo: string, formData: FormData) => {// 发送请求,发送的数据有:请求体数据(文件数据 uploadFile),请求参数数据(文件编号 fileNo)return request.put("/resources/qualityFile/uploadFile", formData, {params: {fileNo: fileNo},// 上传文件,需设置 headers 信息,将"Content-Type"设置为"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};/*** 上传质量体系文件,实现 SQL Server image 类型文件上传,使用 post 发送请求,发送的数据只有:请求体数据(文件数据 uploadFile)* @param formData 表单数据,包含的数据有:文件数据(uploadFile)和 文件编号(fileNo) {@link FormData}* @returns*/
export const qualityFileUploadFileService = (formData: FormData) => {return request.post("/resources/qualityFile/uploadFile", formData, {// 上传文件,需设置 headers 信息,将"Content-Type"设置为"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};

fileUtils.ts

/*** 获取文件名的扩展名(后缀)* @param filename 文件名* @returns 扩展名(后缀)*/
export const getExtension = (filename: string) => {// 方法1:​使用split()和pop(),通过将文件名按点号(.)分割成数组,取最后一个元素作为后缀名。// const parts = filename.split(".");// return parts.length > 1 ? parts.pop() : "";// 方法2:​使用lastIndexOf()和substring(),更健壮的方式是定位最后一个点号的位置后截取字符串,避免多重点号的误判// const lastDotIndex = filename.lastIndexOf(".");// return lastDotIndex !== -1 ? filename.substring(lastDotIndex + 1) : "";// 方法3:使用slice()和lastIndexOf()// const lastDotIndex = filename.lastIndexOf(".");// return lastDotIndex !== -1 ? filename.slice(lastDotIndex + 1) : "";// 方法4:使用正则表达式const match = filename.match(/\.([a-zA-Z0-9]+)$/);return match ? match[1] : "";
};/*** 获取URL中的文件名的扩展名(后缀)* @param url url* @returns 扩展名(后缀)*/
export const getExtensionFromURL = (url: string) => {const pathname = new URL(url).pathname;return getExtension(pathname);
};

2、后端 Spring boot + Mybatis

控制层:QualityFileController.java
package com.weiyu.controller;import com.alibaba.fastjson.JSON;
import com.weiyu.anno.Debounce;
import com.weiyu.pojo.QualityFile;
import com.weiyu.pojo.QualityFileDTO;
import com.weiyu.pojo.QualityFileQueryDTO;
import com.weiyu.pojo.Result;
import com.weiyu.service.QualityFileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.List;/*** 质量体系文件 Controller*/
@RestController
@RequestMapping("/resources/qualityFile")
@Slf4j
public class QualityFileController {@Autowiredprivate QualityFileService qualityFileService;/*** 质量体系文件上传,实现 SQL Server image 类型文件上传,使用 @PutMapping 接收请求* MultipartFile参数名称说明:* 因为前端使用 formData.append("uploadFile", file) 用的参数名称是 uploadFile* 后端这里使用 uploadFile 与前端一致,可以不使用 @RequestPart("uploadFile"),也可以使用* @param fileNo 文件编号(可能包含特殊字符如 /)* @param uploadFile 上传文件 {@link MultipartFile}* @apiNote 本接口使用防抖机制,3s 内重复请求会被忽略*/@PutMapping("/uploadFile")@Debounce(key = "/resources/qualityFile/uploadFile", value = 3000)public Result<?> uploadFile(@RequestParam String fileNo, MultipartFile uploadFile) {try {log.info("【质量体系文件】,上传,实现 SQL Server image 类型文件上传,使用 @PutMapping 接收请求," +"/resources/qualityFile/uploadFile,fileNo = {},uploadFile = {}", fileNo, uploadFile);qualityFileService.uploadFile(fileNo, uploadFile);return Result.success("文件上传成功!");} catch (Exception e) {return Result.success("文件上传失败:" + e.getMessage());}}/*** 质量体系文件上传,实现 SQL Server image 类型文件上传,使用 @PostMapping 接收请求* MultipartFile参数名称说明:* 因为前端使用 formData.append("uploadFile", file) 用的参数名称是 uploadFile* 后端这里使用 uploadFile 与前端一致,可以不使用 @RequestPart("uploadFile"),也可以使用* String参数名称说明:* 因为前端使用 formData.append("fileNo", qualityFileObj.value.fileNo) 用的参数名称是 fileNo* 后端这里使用 fileNo 与前端一致,可以不使用 @RequestPart("fileNo"),也可以使用* @param fileNo 文件编号(可能包含特殊字符如 /)* @param uploadFile 上传文件 {@link MultipartFile}* @apiNote 本接口使用防抖机制,3s 内重复请求会被忽略*/@PostMapping("/uploadFile")@Debounce(key = "/resources/qualityFile/uploadFile", value = 3000)public Result<?> uploadFile(MultipartFile uploadFile, String fileNo) {try {log.info("【质量体系文件】,上传,实现 SQL Server image 类型文件上传,使用 @PostMapping 接收请求," +"/resources/qualityFile/uploadFile,uploadFile = {},fileNo = {}", uploadFile, fileNo);qualityFileService.uploadFile(fileNo, uploadFile);return Result.success("文件上传成功!");} catch (Exception e) {return Result.success("文件上传失败:" + e.getMessage());}}
}
服务层接口实现:QualityFileServiceImpl .java
package com.weiyu.service.impl;import com.weiyu.mapper.QualityFileMapper;
import com.weiyu.pojo.FileData;
import com.weiyu.pojo.QualityFile;
import com.weiyu.pojo.QualityFileQueryDTO;
import com.weiyu.service.QualityFileService;
import com.weiyu.utils.FileDownloadUtil;
import jakarta.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;/*** 质量体系文件 Service 接口实现*/
@Service
public class QualityFileServiceImpl implements QualityFileService {@Autowiredprivate QualityFileMapper qualityFileMapper;/*** 上传质量体系文件** @param fileNo 文件编号* @param uploadFile 上传文件*/@Overridepublic void uploadFile(String fileNo, MultipartFile uploadFile) throws IOException {FileData fileData = new FileData();fileData.setFileName(uploadFile.getOriginalFilename());fileData.setFileContent(uploadFile.getBytes());// todo: 如果是大文件(超过10MB)保存到文件系统,数据库只保存文件路径;否则保存到数据库// 保存文件到数据库qualityFileMapper.saveFile(fileNo, fileData);}
}
数据表结构
数据传输对象 DTO:FileData.java
package com.weiyu.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** 文件数据*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FileData {private String fileName;private byte[] fileContent;
}

持久层:QualityFileMapper.java

package com.weiyu.mapper;import com.weiyu.pojo.FileData;
import com.weiyu.pojo.QualityFile;
import com.weiyu.pojo.QualityFileQueryDTO;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** 质量体系文件 Mapper*/
@Mapper
public interface QualityFileMapper {/*** 保存质量体系文件数据到数据库* @param fileNo 文件编号* @param fileData 上传文件*/void saveFile(String fileNo, FileData fileData);
}

持久层数据库sql更新:QualityFileMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.weiyu.mapper.QualityFileMapper"><!--mssql--><!-- 保存质量体系文件数据到数据库 --><update id="saveFile">update ControledFileMain setcfm_ContentFileName = #{fileData.fileName}, cfm_Content = #{fileData.fileContent}, cfm_ContentIsNull = 0where Cfm_BigType = '3' and Cfm_ID = #{fileNo}</update>
</mapper>

3、应用效果

文件名称支持空格和加号

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用安卓平板,通过USB数据线(而不是Wi-Fi)来控制电脑(版本1)

这是一个对延迟和稳定性要求很高的场景。 核心原理是&#xff1a;利用USB数据线&#xff0c;在手机和电脑之间创建一个高速的“虚拟网络连接”&#xff0c;然后在这个稳定的网络通道上运行远程控制软件。 方案1&#xff1a; 在完全没有无线网络&#xff08;Wi-Fi&#xff09;和…

linux报permission denied问题

linux报permission denied问题 一般是没有可执行权限&#xff0c;需要先添加执行权限 1. 确认文件权限 在你的项目目录下执行&#xff1a; ls -l ./folder你可能会看到类似&#xff1a; -rw-r--r-- 1 user user 1234 Aug 18 12:00 script.sh注意&#xff1a;这里缺少 x&#xf…

Vue深入组件:组件事件详解2

声明触发的事件 为了让组件的用法更清晰(作为文档),同时让 Vue 能区分事件与透传 attribute,推荐显式声明组件要触发的事件。根据组件是否使用 <script setup>,声明方式有所不同。 使用 <script setup> 时:defineEmits() 宏 在 <script setup> 中,…

FLASK项目快速构建

Flask 项目构建 exts.py # flask_sqlalchemy from flask_sqlalchemy import SQLAlchemy from flask_mail import Mail from flask_caching import Cache from flask_wtf import CSRFProtect from flask_avatars import Avatars from flask_jwt_extended import JWTManager from…

数据结构--2:ArrayList与顺序表

1.顺序表的创建 2.常见操作 3.遍历 4.扩容机制 5.例子1.顺序表的创建在集合框架中&#xff0c;ArrayList是⼀个普通的类&#xff0c;实现了List接口&#xff0c;具体框架图如下&#xff1a;2.常见操作代码…

【Kubesphere】K8s容器无法访问内网xx网络问题

问题遇到的现象和发生背景 Kubesphere中运行的一个容器&#xff0c;可以ping通我们公司内网网段172.16.XX.XX&#xff0c;但是在容器内无法ping通192.168.5.XX&#xff0c;但是我在宿主机是可以ping通192.168.5.XX&#xff0c;这个192.168.5.XX是通过xx设备接进来的&#xff0c…

【开发语言】Groovy语言:Java生态中的动态力量

博客目录一、Groovy 的诞生与发展二、核心特性深度解析1. 与 Java 的无缝集成2. 动态类型与可选静态类型3. 强大的集合操作三、Groovy 在实际开发中的应用场景1. 构建自动化&#xff08;Gradle&#xff09;2. 测试开发&#xff08;Spock 框架&#xff09;3. 脚本任务自动化四、…

Obsidian 1.9.10升级

概述 Obsidian发布了更新版本1.9.10&#xff0c;是一次比较大的升级&#xff0c;尤其是增加了一些以前没有的核心插件&#xff0c;尤其是重磅的数据库功能。虽然可能还是比较初期&#xff0c;但是这意味着OB还是往更好的方向进化了。 本文以一些目前的视频教程加自己的实际上手…

内容审计技术

一、 内容审计需求背景1.网络安全法要求明确责任人&#xff1a;制定内部安全管理制度和操作规程&#xff0c;落实安全保护责任。监测、记录并保留日志&#xff1a;采取监测、记录网络运行状态、网络安全事件的技术措施&#xff0c;并按照规定留存相关网络日志不少于六个月。采取…

反序列化漏洞

php反序列化 1.什么是序列化和反序列化 office word是程序 doc/docx是数据 保存word文件&#xff1a;程序--保存(序列化)-->数据文件 打开word文件&#xff1a;程序--加载数据文件-->还原(反序列化) 游戏存档&#xff1a;角色等级&#xff0c;任务&#xff0c;人物坐…

Lecture 4 Mixture of experts课程笔记

什么是MoE?用&#xff08;多个&#xff09;大型前馈网络和一个选择器层取代大型前馈网络。你可以在不影响浮点运算次数的情况下增加专家数量。 MoE受欢迎的原因 相同的浮点运算次数&#xff0c;更多的参数表现更好训练混合专家模型&#xff08;MoEs&#xff09;速度更快训练混…

微服务架构的演进:从 Spring Cloud Netflix 到云原生新生态

过去十年,Spring Cloud 凭借 Netflix 全家桶(Eureka、Ribbon、Hystrix、Zuul 等)几乎成为 Java 微服务的事实标准。但随着这些核心组件逐步停止更新或进入维护模式,微服务架构正经历一场深刻的演进。新的微服务架构更加注重 云原生兼容性、社区活跃度、企业级稳定性和低运维…

网络流量分析——基础知识

文章目录所需技能和知识TCP/IP 堆栈和 OSI 模型基本网络概念常用端口和协议IP 数据包和子层的概念协议传输封装环境与设备常见的流量分析工具BPF 语法执行网络流量分析NTA工作流程NTA工作流程网络 - 第 1-4 层OSI / TCP-IP 模型寻址机制MAC地址IP 寻址IPv4IPv6IPv6 寻址类型IPv…

ansible playbook 实战案例roles | 实现基于 IHS 的 AWStats 访问监控系统

文章目录一、核心功能描述二、roles内容2.1 文件结构2.2 主配置文件2.3 tasks文件内容三、files文件内容四、关键价值免费个人运维知识库&#xff0c;欢迎您的订阅&#xff1a;literator_ray.flowus.cn 一、核心功能描述 这个 Ansible Role 的核心功能是&#xff1a;​实现 ​…

DELL服务器 R系列 IPMI的配置

1、iDRAC功能默认都是关闭&#xff0c;需要在BIOS面启用&#xff0c;首先重启计算机&#xff0c;按F2然后进入BIOS&#xff0c;选择iDRAC Setting进行iDRAC配置 2、重置一下idrac卡-重置才能恢复默认密码 3、进入iDRAC Setting之后&#xff0c;选择设置网络Network 4、启用iDRA…

模式组合应用-桥接模式(一)

写在前面Hello&#xff0c;我是易元&#xff0c;这篇文章是我学习设计模式时的笔记和心得体会。如果其中有错误&#xff0c;欢迎大家留言指正&#xff01;文章为设计模式间的组合使用&#xff0c;涉及代码较多&#xff0c;个人觉得熟能生巧&#xff0c;希望自己能从中学习到新的…

【clion】visual studio的sln转cmakelist并使用clion构建32位

我想在linux上运行,所以先转为cmake工程 例如可以把exe mfc 部分不构建,这样ubuntu就不用移植。 先转cmakelist,而后clion完成win32的构建,与vs构建对比,验证脚本正确性。 Vcxproj2CMake https://github.com/gns333/Vcxproj2CMake cmakeconverter https://github.com/pave…

MySQL之分区功能

序言 随着业务发展&#xff0c;我们维护的项目数据库中的数据可能会越来越大&#xff0c;那么单张表的数据变多后&#xff0c;接口查询效率可能会变慢&#xff0c;那我们就直接照抄大厂常见的分库分表吗&#xff1f;—— 当然不是的&#xff0c;分库分表不是万能的。 分库分表…

java_spring boot 中使用 log4j2 及 自定义layout设置示例

1. log4j2对比 原始Logback 优势 对于 Spring Boot 3.x&#xff0c;Logback 是默认日志框架&#xff0c;但在高并发、异步日志场景下&#xff0c;Log4j2 通常表现更优。当业务百万级用户、微服务、日志量大时&#xff1a; ✅ 1. Logback&#xff08;默认 Spring Boot 集成&am…

记录Webapi Excel 导出

文章目录1、helper2、control3、前端 axios记录webapi excel 导出File示例.NET8.0 NPOI2.731、helper using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Data; using System.IO; /// <summary> /// 导出EXCEL /// </summary> public class Exce…