一、技术栈

1、前端 Vue3 + Element Plus + TypeSprict

2、后端 Spring Boot 3.2.12 + Mybatis Plus

3、模型特点

3.1、表格展示列表数据

3.2、行点击,弹出对话框

3.3、前端使用 FormData 提交混合表单数据,包含普通字段和文件字段

3.4、文件对应数据库结构类型为 image

3.5、Spring MVC 注解 @RequestPart、@ModelAttribute

2、应用效果

3、Vue3 前端

对话框表单 QualityFileInfoDialog.vue

<script setup lang="ts" name="QualityFileInfoDialog">
......
// 上传,防抖
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 表单数据的内容// FormData对象不能直接通过 console.log(formData)输出完整内容(控制台仅显示 FormData {}的抽象表示)// console.log("formData = ", formData);// 使用 Object.fromEntries()将 FormData 转为普通对象,再通过 console.log 打印完整内容// const data = Object.fromEntries(formData.entries());// console.log(data);// 清空 FormData 表单数据的内容:遍历删除所有字段// formData.keys() 返回的迭代器会实时跟踪 FormData的当前状态。当调用 delete(key) 后,迭代器的内部指针可能因数据变化而跳过后续键。// 先将将迭代器转为静态数组,避免动态变化的影响// 使用 Array.from() 将迭代器转为静态数组// const keys = Array.from(formData.keys());// 使用 扩展运算符 将迭代器转为静态数组// const keys = [...formData.keys()];// for (let key of keys) {//   formData.delete(key);// }// 清空 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 (props.isNew) {if (upperCase(extension.value) === upperCase("pdf")) {// 将文件对象 file 添加到 formData 对象中,uploadFile 需要与后端接口中接收文件的参数名一致,如果不一致,则后端需要指定参数名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);} else if (upperCase(extension.value) === upperCase("xls") || upperCase(extension.value) === upperCase("xlsx")) {// 将文件对象 file 添加到 formData 对象中,uploadFile 需要与后端接口中接收文件的参数名一致,如果不一致,则后端需要指定参数名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 将普通对象 qualityFileObj 的属性添加到 formData 对象中formData.append("fileNo", qualityFileObj.value.fileNo);formData.append("fileName", qualityFileObj.value.fileName);formData.append("edition", qualityFileObj.value.edition as string);formData.append("orderNo", qualityFileObj.value.orderNo as string);formData.append("issueDept", qualityFileObj.value.issueDept as string);formData.append("issueDate", qualityFileObj.value.issueDate as string);formData.append("smallCategory", qualityFileObj.value.smallCategory as string);formData.append("detailCategory", qualityFileObj.value.detailCategory as string);formData.append("modifyRecord", qualityFileObj.value.modifyRecord as string);formData.append("remark", qualityFileObj.value.remark as string);} else {// 将文件对象 file 添加到 formData 对象中,uploadFile 需要与后端接口中接收文件的参数名一致,如果不一致,则后端需要指定参数名,如 @RequestPart("uploadFile") MultipartFile fileformData.append("uploadFile", file);// 将普通对象 qualityFileObj 转换为 json 字符串 添加到 formData 对象中formData.append("qualityFile", JSON.stringify(qualityFileObj.value));}}// 查改模式else {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;}
};// 确定
const onConfirmClick = async () => {// 检查if (!check()) {return;}// 新增模式if (props.isNew) {if (upperCase(extension.value) === upperCase("pdf")) {// 发送请求,使用 put 发送请求,发送的数据有:请求体数据(文件数据 file),请求参数数据(普通对象数据 qualityFile)await qualityFileAddAttachUploadFileWithPutService(qualityFileObj.value, formData);} else if (upperCase(extension.value) === upperCase("xls") || upperCase(extension.value) === upperCase("xlsx")) {// 发送请求,使用 patch 发送请求,通过请求体发送表单数据 formData,表单数据,包含的数据有:文件数据(uploadFile)和// 普通对象的属性数据(fileNo、fileName、edition、orderNo、issueDept、issueDate、smallCategory、detailCategory、modifyRecord、remark)await qualityFileAddAttachUploadFileWithPatchService(formData);} else {// 发送请求,使用 post 发送请求,通过请求体发送表单数据 formData,表单数据,包含的数据有:文件数据(uploadFile)和 普通对象的json字符串数据(qualityFile)await qualityFileAddAttachUploadFileService(formData);}}// 查改模式else {// 两个对象不相同,需要更新数据;如果两个对象相同(所有属性值都相同),不需要更新数据if (!isEqual(props.qualityFileInfo, qualityFileObj.value)) {// 点击【确定】,确定质量体系文件信息,通知父组件执行相应的操作emit("confirm-quality-file", qualityFileObj.value);}}dialogVisible.value = false;
};
......
</script><template><el-dialogclass="quality-file-dialog"title="基础信息"width="640px"top="0vh"centerstyle="border-radius: 10px"v-model="dialogVisible":close-on-press-escape="true":close-on-click-modal="false":show-close="true"@close="onCancelClick"><template #default><el-form :model="qualityFileObj" label-width="auto" style="margin: 8px 16px"><el-row :gutter="10"><el-col :span="12"><el-form-item label="序号" label-position="right"><el-input v-model="qualityFileObj.orderNo" clearable /></el-form-item></el-col><el-col :span="12"><el-form-item label="文件编号" label-position="right"><el-input v-model="qualityFileObj.fileNo" clearable :disabled="!props.isNew" /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="24"><el-form-item label="文件名称" label-position="right"><el-input v-model="qualityFileObj.fileName" clearable /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="12"><el-form-item label="版本号" label-position="right"><el-input v-model="qualityFileObj.edition" clearable /></el-form-item></el-col><el-col :span="12"><el-form-item label="修改记录" label-position="right"><el-input v-model="qualityFileObj.modifyRecord" clearable /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="12"><el-form-item label="所属小类" label-position="right"><el-selectv-model="qualityFileObj.smallCategory"placeholder="请选择"clearable@clear="handleSmallCategoryClear"><el-option v-for="item in fileSmallCategoryList" :label="item.label" :value="item.value" /></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="所属类别" label-position="right"><el-selectv-model="qualityFileObj.detailCategory"placeholder="请选择"clearablefilterabledefault-first-option><el-option v-for="item in fileDetailCategoryList" :label="item.label" :value="item.label" /></el-select></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="12"><el-form-item label="发布部门" label-position="right"><el-selectv-model="qualityFileObj.issueDept"placeholder="请选择"clearablefilterableallow-createdefault-first-option:value-on-clear="``"><el-option v-for="item in departmentList" :label="item.deptName" :value="item.deptName" /></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="发布日期" label-position="right"><el-date-pickerv-model="qualityFileObj.issueDate"type="date"format="YYYY-MM-DD"value-format="YYYY-MM-DD"clearablestyle="width: 100%" /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="24"><el-form-item label="备注" label-position="right"><el-input v-model="qualityFileObj.remark" clearable /></el-form-item></el-col></el-row><el-row :gutter="10"><el-col :span="15"><el-form-item label="附件" label-position="right"><el-input class="input-readonly" v-model="qualityFileObj.filePathname" readonly /></el-form-item></el-col><el-col :span="9"><el-form-item label="" label-position="right"><BasePreventReClickButton type="primary" plain :loading="false" @click="onUploadClick">{{qualityFileObj.isNullContent ? "上传" : "重传"}}</BasePreventReClickButton><BasePreventReClickButton:loading="false":disabled="qualityFileObj.isNullContent"@click="onDownloadClick">下载</BasePreventReClickButton><BasePreventReClickButtontype="danger"plain:loading="false":disabled="qualityFileObj.isNullContent"@click="onClearClick">清除</BasePreventReClickButton><!-- 文件输入元素,不显示,通过点击按钮【上传/重传】执行 onUploadClick,模拟点击该元素,从而触发 handleUpload 事件 --><input ref="fileInputRef" type="file" style="display: none" @change="handleUpload" /></el-form-item></el-col></el-row></el-form></template><!-- 模态框底部插槽,就算没有内容,也要写一个空的插槽,否则会影响布局 --><template #footer><div class="footer-div"><BasePreventReClickButton class="btn" type="primary" @click="onConfirmClick">确定</BasePreventReClickButton><el-button class="btn" @click="onCancelClick">取消</el-button></div></template></el-dialog>
</template><style scoped lang="scss">
.el-form {margin: 0 15px;
}// 设置等同于disabled的样式效果,背景色 #f5f7fa,字体颜色 #c0c4cc
// 设置类名为 input-readonly 的元素的背景颜色
.input-readonly :deep(.el-input__wrapper) {background-color: #f5f7fa;
}
// 设置只读的input的字体颜色,不使用类名,使用类属性选择器(.类名[属性名])
:deep(.el-input__inner[readonly]) {color: #c0c4cc;
}
</style>

qualityFile.ts

import request from "@/utils/request";
import type { IQualityFile, IQualityFileQueryObj } from "@/views/resources/QualityFile/types";/*** 新增质量体系文件信息,附带上传文件,使用 put 发送请求,发送的数据有:请求体数据(文件数据 uploadFile),请求参数数据(普通对象数据 qualityFile)* @param qualityFile 质量体系文件信息 {@link IQualityFile}* @param formData 表单数据,包含的数据只有:文件数据(uploadFile) {@link FormData}* @returns*/
export const qualityFileAddAttachUploadFileWithPutService = (qualityFile: IQualityFile, formData: FormData) => {// 发送请求,发送的数据有:请求体数据(文件数据 uploadFile),请求参数数据(普通对象数据 qualityFile)return request.put("/resources/qualityFile/addAttachUploadFile", formData, {params: qualityFile,// 上传文件,需设置 headers 信息,将"Content-Type"设置为"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};/*** 新增质量体系文件信息,附带上传文件,使用 patch 发送请求,通过请求体发送表单数据 formData* @param formData 表单数据,包含的数据有:文件数据(uploadFile)和* 普通对象的属性数据(fileNo、fileName、edition、orderNo、issueDept、issueDate、smallCategory、detailCategory、modifyRecord、remark) {@link FormData}* @returns*/
export const qualityFileAddAttachUploadFileWithPatchService = (formData: FormData) => {return request.patch("/resources/qualityFile/addAttachUploadFile", formData, {// 上传文件,需设置 headers 信息,将"Content-Type"设置为"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};/*** 新增质量体系文件信息,附带上传文件,使用 post 发送请求,通过请求体发送表单数据 formData* @param formData 表单数据,包含的数据有:文件数据(uploadFile)和 普通对象的json字符串数据(qualityFile) {@link FormData}* @returns*/
export const qualityFileAddAttachUploadFileService = (formData: FormData) => {return request.post("/resources/qualityFile/addAttachUploadFile", formData, {// 上传文件,需设置 headers 信息,将"Content-Type"设置为"multipart/form-data"headers: {"Content-Type": "multipart/form-data"}});
};

4、Spring Boot 后端

DTO 

QualityFile.java

package com.weiyu.pojo;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDate;/*** 质量体系文件*/
@Schema(description = "质量体系文件实体")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QualityFile {@Schema(description = "文件唯一标识 id", example = "1")private Integer id;@Schema(description = "序号", example = "A00")private String orderNo;@Schema(description = "文件编号", example = "CZCDC/QM-2024-A0")private String fileNo;@Schema(description = "文件名称", example = "质量手册(封面)")private String fileName;@Schema(description = "版本号", example = "第9版")private String edition;@Schema(description = "修改记录", example = "第9版第0次修改")private String modifyRecord;@Schema(description = "所属小类", example = "3003")private String smallCategory;@Schema(description = "所属类别", example = "第九版")private String detailCategory;@Schema(description = "发布部门", example = "质量管理科")private String issueDept;@Schema(description = "发布日期", example = "2025-08-16")@JsonFormat(pattern = "yyyy-MM-dd")private LocalDate issueDate;@Schema(description = "备注", example = " ")private String remark;@Schema(description = "文件路径名称", example = "CZCDC∕QM-2018-B2 4.2 人员vVv+DW=dw.doc")private String filePathname;@Schema(description = "是否空内容", example = "true")private Boolean isNullContent;
}

QualityFileDTO.java

package com.weiyu.pojo;import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDate;/*** 质量体系文件 DTO*/
@Schema(description = "质量体系文件 DTO")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class QualityFileDTO {@Schema(description = "序号", example = "A00")private String orderNo;@Schema(description = "文件编号", example = "CZCDC/QM-2024-A0")private String fileNo;@Schema(description = "文件名称", example = "质量手册(封面)")private String fileName;@Schema(description = "版本号", example = "第9版")private String edition;@Schema(description = "修改记录", example = "第9版第0次修改")private String modifyRecord;@Schema(description = "所属小类", example = "3003")private String smallCategory;@Schema(description = "所属类别", example = "第九版")private String detailCategory;@Schema(description = "发布部门", example = "质量管理科")private String issueDept;@Schema(description = "发布日期", example = "2025-08-16")@JsonFormat(pattern = "yyyy-MM-dd")private LocalDate issueDate;@Schema(description = "备注", example = " ")private String remark;
}

控制层 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;/*** 新增质量体系文件,附带上传文件,使用 @PutMapping 接收请求,@ModelAttribute 接收参数* @ ModelAttribute是 Spring MVC 中处理复杂数据绑定和模型管理的核心注解,尤其适合表单操作和共享数据场景,能显著减少样板代码* 将 HTTP 请求参数(如表单字段、查询参数)自动绑定到 Java 对象的属性上* 示例说明:* 如果查询参数有fileNo为A1,表单字段也有fileNo为B2,那么qualityFile中的fileNo为B2,A1,即先获取表单字段,再获取查询参数,中间使用逗号分隔* MultipartFile参数名称说明:* 因为前端使用 formData.append("uploadFile", file) 用的参数名称是 uploadFile* 后端这里使用 uploadFile 与前端一致,可以不使用 @RequestPart("uploadFile"),也可以使用* @param qualityFile 质量体系文件 {@link QualityFile}* @param uploadFile 上传文件 {@link MultipartFile}*/@PutMapping("/addAttachUploadFile")public Result<?> addAttachUploadFile(@ModelAttribute QualityFile qualityFile,MultipartFile uploadFile) throws IOException {log.info("【质量体系文件】,新增附带上传文件,使用 @PutMapping 接收请求,@ModelAttribute 接收参数," +"/resources/qualityFile/addAttachUploadFile,qualityFile = {},uploadFile = {}", qualityFile, uploadFile);qualityFileService.addAttachUploadFile(qualityFile, uploadFile);return Result.success();}/*** 新增质量体系文件,附带上传文件,使用 @PatchMapping 接收请求,@ModelAttribute 接收参数* @ ModelAttribute是 Spring MVC 中处理复杂数据绑定和模型管理的核心注解,尤其适合表单操作和共享数据场景,能显著减少样板代码* 将 HTTP 请求参数(如表单字段、查询参数)自动绑定到 Java 对象的属性上* 示例说明:* 如果查询参数有fileNo为A1,表单字段也有fileNo为B2,那么qualityFile中的fileNo为B2,A1,即先获取表单字段,再获取查询参数,中间使用逗号分隔* MultipartFile参数名称说明:* 因为前端使用 formData.append("uploadFile", file) 用的参数名称是 uploadFile* 后端这里使用 uploadFile 与前端一致,可以不使用 @RequestPart("uploadFile"),也可以使用* @param qualityFileDTO 质量体系文件 DTO {@link QualityFileDTO}* @param uploadFile 上传文件 {@link MultipartFile}*/@PatchMapping("/addAttachUploadFile")public Result<?> addAttachUploadFile(@ModelAttribute QualityFileDTO qualityFileDTO,MultipartFile uploadFile) throws IOException {log.info("【质量体系文件】,新增附带上传文件,使用 @PatchMapping 接收请求,@ModelAttribute 接收参数," +"/resources/qualityFile/addAttachUploadFile,qualityFileDTO = {},uploadFile = {}", qualityFileDTO, uploadFile);QualityFile qualityFile = new QualityFile();qualityFile.setFileNo(qualityFileDTO.getFileNo());qualityFile.setFileName(qualityFileDTO.getFileName());qualityFile.setEdition(qualityFileDTO.getEdition());qualityFile.setOrderNo(qualityFileDTO.getOrderNo());qualityFile.setIssueDept(qualityFileDTO.getIssueDept());qualityFile.setIssueDate(qualityFileDTO.getIssueDate());qualityFile.setSmallCategory(qualityFileDTO.getSmallCategory());qualityFile.setDetailCategory(qualityFileDTO.getDetailCategory());qualityFile.setModifyRecord(qualityFileDTO.getModifyRecord());qualityFile.setRemark(qualityFileDTO.getRemark());qualityFileService.addAttachUploadFile(qualityFile, uploadFile);return Result.success();}/*** 新增质量体系文件,附带上传文件,使用 @PostMapping 接收请求,@RequestPart 接收参数* @ RequestPart是 Spring MVC 中处理 multipart 请求的灵活工具,尤其适合文件与结构化数据混合提交的场景,简化了数据绑定与异常处理* MultipartFile参数名称说明:* 因为前端使用 formData.append("uploadFile", file) 用的参数名称是 uploadFile* 后端这里使用 uploadFile 与前端一致,可以使用 @RequestPart("uploadFile"),也可以不使用* String参数名称说明:* 因为前端使用 formData.append("qualityFile", JSON.stringify(qualityFileObj.value)) 用的参数名称是 qualityFile* 后端这里使用 qualityFileJsonString 与前端不一致,必须使用 @RequestPart("qualityFile") 映射参数名称* @param qualityFileJsonString 质量体系文件json字符串* @param uploadFile 上传文件 {@link MultipartFile}*/@PostMapping("/addAttachUploadFile")public Result<?> addAttachUploadFile(@RequestPart("qualityFile") String qualityFileJsonString,@RequestPart("uploadFile") MultipartFile uploadFile) throws IOException {log.info("【质量体系文件】,新增附带上传文件,使用 @PostMapping 接收请求,@RequestPart 接收参数," +"/resources/qualityFile/addAttachUploadFile,qualityFileJsonString = {},uploadFile = {}",qualityFileJsonString, uploadFile);// json字符串 转换成 java对象(QualityFile)QualityFile qualityFile = JSON.parseObject(qualityFileJsonString, QualityFile.class);qualityFileService.addAttachUploadFile(qualityFile, uploadFile);return Result.success();}
}

服务层 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 queryDTO 查询 DTO* @return 质量体系文件列表*/@Overridepublic List<QualityFile> query(QualityFileQueryDTO queryDTO) {if (queryDTO == null) return new ArrayList<>();return qualityFileMapper.select(queryDTO);}/*** 新增质量体系文件** @param qualityFile 质量体系文件*/@Overridepublic void add(QualityFile qualityFile) {qualityFileMapper.insert(qualityFile);}/*** 上传质量体系文件** @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);}/*** 新增质量体系文件,附带上传文件** @param qualityFile 质量体系文件* @param uploadFile 上传文件*/@Override@Transactionalpublic void addAttachUploadFile(QualityFile qualityFile, MultipartFile uploadFile) throws IOException {// 新增质量体系文件add(qualityFile);// 上传质量体系文件uploadFile(qualityFile.getFileNo(), uploadFile);}
}

Mapper 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 queryDTO 查询 DTO* @return 质量体系文件列表*/List<QualityFile> select(QualityFileQueryDTO queryDTO);/*** 新增质量体系文件* @param qualityFile 质量体系文件*/void insert(QualityFile qualityFile);/*** 保存质量体系文件数据到数据库* @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--><!-- 查询质量体系文件列表 --><select id="select" resultType="com.weiyu.pojo.QualityFile">selectCfm_OrderID as orderNo, Cfm_ID as fileNo, Cfm_Name as fileName, Cfm_Edition as edition,Cfm_ModifyRecord as modifyRecord, Cfm_SmallType as smallCategory, Cfm_SampleType as detailCategory,Cfm_Dept as issueDept, Cfm_IssueDate as issueDate, Cfm_Memo as remark,cfm_ContentFileName as filePathname, cfm_ContentIsNull as isNullContentfrom ControledFileMain<where>Cfm_BigType = '3'<if test="fileNo != null and fileNo != ''">and Cfm_ID like '%' + #{fileNo} + '%'</if><if test="fileName != null and fileName != ''">and Cfm_Name like '%' + #{fileName} + '%'</if></where>order by Cfm_SmallType, Cfm_ID</select><!-- 新增质量体系文件 --><insert id="insert">insert into ControledFileMain(Cfm_BigType, Cfm_OrderID, Cfm_ID, Cfm_Name, Cfm_Edition,Cfm_ModifyRecord, Cfm_SmallType, Cfm_SampleType,Cfm_Dept, Cfm_IssueDate, Cfm_Memo)values ('3', #{orderNo}, #{fileNo}, #{fileName}, #{edition},#{modifyRecord}, #{smallCategory}, #{detailCategory},#{issueDept}, #{issueDate}, #{remark})</insert><!-- 保存质量体系文件数据到数据库 --><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>

5、数据库表结构(sql server)

CREATE TABLE [dbo].[ControledFileMain]([Cfm_ID] [varchar](30) NOT NULL,[Cfm_Name] [varchar](200) NULL,[Cfm_BigType] [varchar](10) NOT NULL,[Cfm_SmallType] [varchar](10) NULL,[Cfm_Dept] [varchar](50) NULL,[Cfm_Memo] [varchar](100) NULL,[Cfm_ModifyRecord] [varchar](128) NULL,[Cfm_Edition] [varchar](50) NULL,[Cfm_IssueDate] [datetime] NULL,[Cfm_SampleType] [varchar](50) NULL,[Cfm_StandardType] [int] NULL,[Cfm_OrderID] [varchar](10) NULL,[Cfm_Holder] [varchar](50) NULL,[cfm_Content] [image] NULL,[cfm_ContentIsNull] [bit] NULL,[cfm_ContentFileName] [varchar](255) NULL,CONSTRAINT [PK_ControledFileMain] PRIMARY KEY CLUSTERED 
([Cfm_ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GO

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

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

相关文章

【Qt开发】Qt的背景介绍(四)

目录 1 -> Qt Hello World 程序 1.1 -> 使用“按钮”实现 1.1.1 -> 纯代码方式实现 1.1.2 -> 可视化操作实现 1.2 -> 使用“标签”实现 1.2.1 -> 纯代码方式实现 1.2.2 -> 可视化操作实现 2 -> 项目文件解析 2.1 -> .pro文件解析 2.2 -&g…

Linux驱动开发笔记(六)——pinctrl GPIO

开发板&#xff1a;imx6ull mini 虚拟机&#xff1a;VMware17 ubuntu&#xff1a;ubuntu20.04 视频&#xff1a;第8.1讲 pinctrl和gpio子系统试验-pincrl子系统详解_哔哩哔哩_bilibili 文档&#xff1a;《【正点原子】I.MX6U嵌入式Linux驱动开发指南.pdf》四十五章 这一章…

SpringBoot 快速上手:从环境搭建到 HelloWorld 实战

在 Java 开发领域&#xff0c;Spring 框架占据着举足轻重的地位&#xff0c;但它复杂的配置曾让不少开发者望而却步。SpringBoot 的出现&#xff0c;如同为 Spring 框架装上了 “加速器”&#xff0c;以 “约定大于配置” 的理念简化了开发流程。本文将从环境准备、Maven 配置入…

图、最小生成树与最短路径

目录 并查集 并查集实现 图 概念 图的存储结构 邻接矩阵 邻接表 无向图 有向图 图的遍历 广度优先遍历 深度优先遍历 最小生成树 Kruskal算法&#xff08;克鲁斯卡尔算法&#xff09; Prim算法&#xff08;普利姆算法&#xff09; 最短路径 单源最短路径--Dij…

互联网电商新生态:开源AI智能名片、链动2+1模式与S2B2C商城小程序的融合赋能

摘要&#xff1a;本文聚焦互联网电商领域&#xff0c;探讨在当下直播电商蓬勃发展的背景下&#xff0c;开源AI智能名片、链动21模式以及S2B2C商城小程序如何相互融合&#xff0c;为创业者、企业和淘宝主播IP等电商参与者带来新的发展机遇。通过分析各要素的特点与优势&#xff…

企业车辆|基于SprinBoot+vue的企业车辆管理系统(源码+数据库+文档)

企业车辆管理系统 基于SprinBootvue的企业车辆管理系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员模块实现 驾驶员模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博…

自学嵌入式第二十五天:数据结构-队列、树

一、队列队列是只允许一段进行插入&#xff0c;另一端进行删除操作的线性表&#xff1b;允许插入的一端叫队尾&#xff0c;允许删除的一端叫对头&#xff1b;先进先出&#xff1b;用于解决速度不匹配&#xff08;例如一快一慢&#xff09;&#xff0c;做缓冲用&#xff1b;二、…

MySQL索引原理与优化全解析

1、MySQL索引是什么&#xff1f; 在关系数据库中&#xff0c;索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构&#xff0c;它是某个表中一列或若干列值的集合和相应的指向表中物理标志这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录&a…

模型对话状态管理方法详解

模型对话状态管理方法详解 目录 简介手动管理对话状态构建对话历史追加响应内容 API 支持的自动化对话状态管理使用 previous_response_id 链接话轮 Token 及上下文窗口管理上下文窗口定义与限制Token 计数与工具 安全与合规注意事项结语1. 简介 在多轮对话场景中&#xff0c;合…

GPT-5 上线风波深度复盘:从口碑两极到策略调整,OpenAI 的变与不变

摘要&#xff1a; 近日&#xff0c;备受瞩目的 GPT-5 正式上线&#xff0c;却意外地在社区引发了两极化争议。面对技术故障与用户质疑&#xff0c;OpenAI 迅速推出一系列补救措施。本文将深度复盘此次发布风波&#xff0c;解析其背后的技术挑战与应对策略&#xff0c;并探讨这一…

【Android】使用FragmentManager动态添加片段

三三要成为安卓糕手 上一篇文章&#xff0c;我们是在xml中静态添加fragment&#xff0c;但是一些修改或者其他事情是做不了的&#xff1b; 本章我们达成在java代码中灵活添加、删除、替换fragment操作 一&#xff1a;核心代码展示 简单做一个这种页面public class FragmentActi…

MiniOB环境部署开发(使用开源学堂)

整体思路&#xff1a; 1.使用开源学堂在线编程环境开发MiniOB编译环境 2.使用vscode进行代码调试和开发以及上传到仓库 MiniOB源码&#xff1a;https://github.com/oceanbase/miniob MiniOB文档&#xff1a;MiniOB 介绍 - MiniOB 数据库大赛官网&#xff1a;OceanBase 社区…

09_常用内置模块进阶

第9课&#xff1a;常用内置模块进阶 课程目标 深入学习Python常用内置模块掌握collections、itertools、functools等模块学习json、csv、pickle等数据处理模块 1. collections模块 1.1 Counter类 from collections import Counter# 统计元素出现次数 text "hello world p…

⚡ Ranger 基础命令与功能详解

&#x1f4cc; 1. Ranger简介 Ranger&#xff08;游侠&#xff09;是一款 Linux 专用的 指令式文件管理器&#xff0c;其操作风格类似 Vim&#xff0c;通过输入指令即可完成目录跳转、文件编辑、移动、复制等操作。 相比于 mc&#xff08;Midnight Commander&#xff09;&…

CUDA安装教程(包括cuDNN的教程)一个博客带你了解所有问题

前言 windows10 版本安装 CUDA &#xff0c;首先需要下载两个安装包 CUDA toolkit&#xff08;toolkit就是指工具包&#xff09;cuDNN 注&#xff1a;cuDNN 是用于配置深度学习使用 官方教程 CUDA&#xff1a;Installation Guide Windows :: CUDA Toolkit Documentation …

ArkTS 语言全方位解析:鸿蒙生态开发新选择

在鸿蒙生态蓬勃发展的当下&#xff0c;一款高效、健壮的开发语言成为开发者的迫切需求。ArkTS 语言应运而生&#xff0c;作为鸿蒙生态的核心应用开发语言&#xff0c;它在 TypeScript&#xff08;简称 TS&#xff09;基础上进行创新扩展&#xff0c;为开发者打造高性能、易维护…

JavaScript性能优化实战:从瓶颈识别到极致体验

文章目录JavaScript性能优化实战&#xff1a;从瓶颈识别到极致体验1. 引言&#xff1a;为什么JavaScript性能至关重要1.1 性能对用户体验的影响1.2 JavaScript性能瓶颈的多样性2. JavaScript内存管理优化2.1 JavaScript内存模型详解2.2 垃圾回收机制与优化策略2.3 内存分析实战…

批量归一化:不将参数上传到中心服务器,那服务器怎么进行聚合?

联邦批量归一化&#xff08;FedBN&#xff09; 是一种联邦学习客户端本地模型优化算法。它的核心思想是&#xff1a;在联邦学习的客户端本地训练过程中&#xff0c;保留并独立更新批量归一化层&#xff08;Batch Normalization, BN&#xff09;的参数&#xff0c;而不将这些参数…

Qt中使用MySQL数据库

一、MySQL 入门 核心概念 在 QT 中操作数据库,主要使用两个模块: QSqlDatabase:代表一个数据库连接。 QSqlQuery:用于执行 SQL 语句(如 SELECT, INSERT, UPDATE, DELETE)并处理结果。 环境准备 在编写代码之前,你需要确保系统已具备以下条件: 1. 安装 MySQL 从 M…

Android - 统一资源标识符 Uri

一、概念URI&#xff08;Uniform Resource Identifier&#xff09;统一资源标识符&#xff0c;用于标识资源的字符串&#xff08;如图片、网页、文件、应用等&#xff09;。1.1 与 URL 的区别URL&#xff08;统一资源定位符&#xff09;是 URI&#xff08;统一资源标识符&#…