前言在企业应用快速发展的过程中,我们需要尽快完成一些功能可能的。如果你使用过AntDesignVue,那么在开发表单的文件上传相关功能的时候,一定急于找到一篇包治百病的文章。文字解决你的后顾之忧。方案设计前端方案设计重写a-upload的文件上传方法,使用axios上传,选择文件后立即上传,上传成功后前端记录name和uid,并构建一个File实例对于a-upload组件,在提交上传文件列表的echo之前,先让文件列表转换成uid列表给后端处理。后端方案设计提供了统一上传单个文件的接口。每个文件选中后,会自动上传到该界面。并将其写入数据库的文件数据表中。新建表单数据后,将上传的文件列表与当前实体记录绑定。表单数据更新后,查看实体记录的所有文件列表。如果列表中没有文件删除列表中的uid文件列表,然后将列表中的所有uid文件记录绑定到当前实体记录。newcreation和update的一致性处理方案是因为updateform读取旧数据后需要和新选择的文件进行比较。同样的格式化过程,这里的处理流程是一样的,要回显的数据是一样的,提交表单也是提交到文件表中已经存在的uid列表,所以这里的数据结构是一致的,并且处理将更有效率。简洁的。让代码说话为了让评委们更容易理解,我直接上传了代码,希望把整个事情解释清楚。构建表单相关下载编写js代码请求后端接口的token、header和baseUrl。我已经默认你已经在axios的统一设置里面配置好了。为了简化axios相关操作,我们对axios进行如下封装(也可以直接使用axios提交数据):constdibootApi={get(url,params){returnaxios.get(url,{params})},upload(url,formData){returnservice({url,method:'POST',data:formData})}}导出默认值tdibootApi我们默认为demo实体中需要上传的一些文件列表exportdefault{name:'demoForm',data(){title:'New',//表单的函数标题form:this.$form.createForm(this),//表单数据初始化,没啥好说的model:{},//如果是更新表单,把之前的数据放在这里进行数据初始化并显示downloadFiles:[]//上传的列表files},methods:{//表单初始打开时的处理(如果表单有更新,需要先读取相关数据)asyncopen(id){if(id===undefined){//如果有没有id数据,会被认为是新建this.model={}this.afterOpen()}else{//否则,会被当作更新处理constres=awaitdibootApi.get(`/${this.name}/${id}`)if(res.code===0){this.model=res.datathis.title='Edit'this.afterOpen(id)}else{this.$notification.error({message:'获取数据失败',descriptionion:res.msg})}}},//读取数据后更新表单的操作afterOpen(id){//获取到记录信息后,回显文件列表的相关操作dibootApi.post(`/demo/getFiles/${id}`).then(res=>{if(res.code===0){if(res.data.downloadFile!==undefined){res.data.downloadFile.forEach(数据=>{this.downloadFiles.push(this.fileFormatter(data))})}}})},//重写a-upload的文件上传处理方法downloadFilesCustomRequest(data){this.saveFile(data)},//上传并保存文件saveFile(data){constformData=newFormData()formData.append('file',data.file)dibootApi.upload('/demo/upload',formData).then((res)=>{如果(res.code===0){letfile=this.fileFormatter(res.data)//上传单个文件后,该文件会先放入a-upload组件的上传文件列表中。this.downloadFiles.push(file)}else{this.$message.error(res.msg)}})},//格式化上传成功返回的数据,将a-upload格式化成可以显示的格式在上传的列表中(官方文档给出了这种格式)fileFormatter(data){letfile={uid:data.uuid,//文件的唯一标识,建议设置为负数防止与内部生成的id冲突n??ame:data.name,//文件名status:'done',//状态为:上传完成errorremovedresponse:'{"status":"success"}',//服务器响应content}returnfile},//是的,删除上传的文件时,这里调用handleDownloadFileRemove(file){constindex=this.downloadFiles.indexOf(file)constnewFileList=this.downloadFiles.slice()newFileList.splice(索引,1)this.downloadFiles=newFileList},//表单验证由他决定,但是还有一些数据需要提交validate(){returnnewPromise((resolve,reject)=>{this.form.validateFields((err,fieldsValue)=>{if(!err){//设置上传文件列表constdownloadFiles=this.downloadFiles.map(o=>{returno.uid})constvalues={...fieldsValue,'downloadFiles':downloadFiles}resolve(values)}else{reject(err)}})})},//表单提交的相关操作asynconSubmit(){constvalues=awaitthis.validate()try{letresult={}如果这.model.id===undefined){//添加这条记录result=awaitthis.add(values)}else{//更新这条记录values['id']=this.model.idresult=awaitthis.update(values)}//提交成功执行后续一系列操作this.submitSuccess(result)}catch(e){//提交失败执行后续一系列操作this.submitFailed(e)}},//添加数据操作asyncadd(values){....},//更新数据操作asyncupdate(values){...}}}编写SpringBoot相关接口代码DemoController/****获取文件信息列表*@paramid*@return*@throwsException*/@PostMapping("/getFiles/{id}")publicJsonResultgetFilesMap(@PathVariable("id")Serializableid)throwsException{Listfiles=fileService.getEntityList(包装器。<文件>lambdaQuery().eq(文件::getRelObjType,Demo.class.getSimpleName()).eq(文件::getRelObjId,id));返回新的JsonResult(Status.OK,文件);}/****上传文件*@paramfile*@paramrequest*@return*@throwsException*/@PostMapping("/upload")publicJsonResultupload(@RequestParam("file")MultipartFilefile)throwsException{文件fileEntity=demoService.uploadFile(文件);returnnewJsonResult(Status.OK,fileEntity,"上传文件成功");}/****创建成功后的相关处理*@paramentity*@return*/@OverrideprotectedStringafterCreated(BaseEntityentity)throwsException{DemoDTOdemoDTO=(DemoDTO)entity;//更新文件关联信息demoService.updateFiles(newArrayList(){{addAll(demoDTO.getDownloadFiles());}},demoDTO.getId(),true);returnnull;}/****更新成功后的相关处理*@paramentity*@return*/@OverrideprotectedStringafterUpdated(BaseEntityentity)throwsException{DemoDTOdemoDTO=(DemoDTO)实体;//更新文件关联信息demoService.updateFiles(newArrayList(){{addAll(demoDTO.getDownloadFiles());}},demoDTO.getId(),false);返回空值;}DemoService@OverridepublicFileuploadFile(MultipartFilefile){if(V.isEmpty(file)){thrownewBusinessException(Status.FAIL_OPERATION,"请上传图片");}StringfileName=file.getOriginalFilename();字符串ext=fileName.substring(fileName.lastIndexOf(".")+1);StringnewFileName=S.newUuid()+"."+分机;//TODO:需要验证合法的文件类型if(FileHelper.isImage(ext)){thrownewBusinessException(Status.FAIL_OPERATION,"请上传合法的文件类型");};//注意:这是我们的处理流程,评委需要根据自己的需要对文件进行保存和处理(我们的File组件开源后也可以按照这里的处理)StringfilePath=FileHelper.saveFile(file,新文件名);if(V.isEmpty(filePath)){thrownewBusinessException(Status.FAIL_OPERATION,"图片上传失败");}文件fileEntity=new文件();fileEntity.setRelObjType(Demo.class.getSimpleName());fileEntity.setFileType(分机);fileEntity.setName(文件名);fileEntity.setPath(文件路径);Stringlink="/file/download/"+D.getYearMonth()+"_"+newFileName;fileEntity.setLink(链接);布尔成功=fileService.createEntity(fileEntity);if(!success){thrownewBusinessException(Status.FAIL_OPERATION,"上传文件失败");}返回文件实体;}@OverridepublicvoidupdateFiles(Listuuids,LongcurrentId,booleanisCreate){//如果没有创建,需要删除不在列表中的文件记录if(!isCreate){fileService.deleteEntities(Wrappers.lambdaQuery().notIn(File::getUuid,uuids));}//执行相关更新booleansuccess=fileService.updateEntity(Wrappers.lambdaUpdate().in(File::getUuid,uuids).set(File::getRelObjType,Demo.class.getSimpleName()).set(文件::getRelObjId,currentId));if(!success){thrownewBusinessException(Status.FAIL_OPERATION,"更新文件信息失败");}}提示本文所有代码均为程序示例,部分删减,不保证能直接运行,如有好的想法,欢迎讨论diboot简单高效的轻代码开发框架(求星)