前后端聯合實現文件上傳,實現 SQL Server image 類型文件上傳

?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…