vue3 带图片的提交按钮
一、界面元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | < el-form v-loading="isLoading" :model="editForm" ref="ruleFormRef" :rules="rules" label-width="120px"> < el-row > < el-col :span="12"> < el-form-item label="1" prop="deptId"> < EscortOrgTree class="tree" @getNode="getNodeData" ref="deptTree" :checkNode="editForm.deptId"/> </ el-form-item > </ el-col > < el-col :span="12"> < el-form-item label="2" prop="maintType"> < el-radio-group v-model="editForm.maintType" class="ml-4"> < el-radio v-for="item in maintTypeOption" :key="item.id" :label="String(item.optionCode)">{{item.optionName}}</ el-radio > </ el-radio-group > </ el-form-item > </ el-col > </ el-row > < el-row > < el-col :span="12"> < el-form-item label="3" prop="vehicleId"> < el-select v-model="editForm.vehicleId" placeholder="请选择" filterable clearable style="width: 100%;" @change="changeVehicle"> < el-option v-for="item in vehicleOption" :key="item.id" :label="item.plateNumber" :value="item.id" :disabled="item.disabled"> </ el-option > </ el-select > </ el-form-item > </ el-col > < el-col :span="12"> < el-form-item label="4" prop="maintMode"> < el-select v-model="editForm.maintMode" filterable placeholder="请选择" clearable style="width: 100%;"> < el-option v-for="item in maintModeOption" :key="item.optionCode" :label="item.optionName" :value="item.optionCode" /> </ el-select > </ el-form-item > </ el-col > </ el-row > < el-row > < el-col :span="12"> < el-form-item label="5" prop="reporterName"> < el-input v-model="editForm.reporterName" readonly/> </ el-form-item > </ el-col > < el-col :span="12"> < el-form-item label="6" prop="maintApplyTime"> < el-date-picker type="datetime" v-model="editForm.maintApplyTime" value-format="YYYY-MM-DD HH:mm:ss" style="width: 100%;" /> </ el-form-item > </ el-col > </ el-row > < el-row > < el-col :span="12"> < el-form-item label="7:" prop="repairDepotId"> < el-cascader ref="cascader" v-model="editForm.repairDepotId" :options="repairDepotOption" :props="propsOption" :show-all-levels="false" clearable style="width: 100%;" @change="handleChangeRepair"> </ el-cascader > </ el-form-item > </ el-col > < el-col :span="12"> < el-form-item label="8" prop="mileageNow"> < el-input v-model="editForm.mileageNow" minlength="1" style="width: 100%;"> < template #append>公里</ template > </ el-input > < span class="fontColor">提示信息:行驶里程是取自加油信息的最后一次里程信息。</ span > </ el-form-item > </ el-col > </ el-row > < el-row > < el-col :span="12"> < el-form-item label="9" prop="costLevel" v-if="processSpreadingMode == 2"> < el-select v-model="editForm.costLevel" filterable clearable placeholder="请选择" style="width: 100%;" > < el-option v-for="item in costLeveOption" :key="item.optionCode" :label="item.optionName" :value="item.costLevel"> </ el-option > </ el-select > </ el-form-item > < el-form-item label="10" type="number" prop="totalPrice" v-if="processSpreadingMode==1"> < el-input placeholder="请输入" v-model="editForm.totalPrice" style="width: 100%;"> < template #append>元</ template > </ el-input > </ el-form-item > </ el-col > < el-col :span="12"> < el-form-item label="11" prop="driverId"> < el-select v-model="editForm.driverId" filterable clearable placeholder="请选择" style="width: 100%;" @focus="focusVehicleId" @change="changeDriverName"> < el-option v-for="item in driverOption" :key="item.id" :label="item.personName" :value="item.id"> </ el-option > </ el-select > </ el-form-item > </ el-col > </ el-row > < el-row > < el-col :span="12"> < el-form-item label="12" prop="applyRemark"> < el-input placeholder="请输入" type="textarea" :rows="6" :maxlength="800" v-model="editForm.applyRemark" show-word-limit /> </ el-form-item > </ el-col > < el-col :span="12"> < el-form-item label="13" prop="remark"> < el-input placeholder="请输入" type="textarea" :rows="5" :maxlength="500" v-model="editForm.remark" show-word-limit /> </ el-form-item > </ el-col > </ el-row > <!--上传图片组件--> < upload-pic :fileList="fileList" @getFileList="getFileList"></ upload-pic > </ el-form > |
</div>
<div class="button-show">
<el-button type="primary" icon="Plus" @click="submitForm(0,ruleFormRef)" size="large" :loading="fullscreenLoading"> 保存</el-button>
<el-button type="primary" icon="DocumentAdd" @click="submitForm(1,ruleFormRef)" size="large" :loading="loadingSave">保存且提交审批</el-button>
</div>
二、逻辑方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | < script setup lang="ts"> import { onActivated, reactive, ref, toRefs, watch } from "vue"; // 审批接口 import { getProcessConfByMainCode } from "@/api/vehicle/system"; import { ElMessage, FormInstance, FormRules,ElMessageBox,UploadProps } from "element-plus"; import useTagsViewStore from "@/store/modules/tagsView"; // 返回 const tagsView = useTagsViewStore(); const ruleFormRef = ref< FormInstance >(); } // 参数定义 const state = reactive({ repair:'', loadingSave:false, processSpreadingMode:common.vehicleConfig.processSpreadingMode }) const{ repair,loadingSave,processSpreadingMode }=toRefs(state) // 保存 const submitForm = (number,formEl: FormInstance | undefined) => { if (!formEl) return; formEl.validate((valid: boolean) => { if (valid) { // 自主选择 if(state.processSpreadingMode ===1){ let totalPrice =editForm.value.totalPrice if(totalPrice === ""){ ElMessage.error("请填写预计费用!") return; } } if(number === 1){ state.loadingSave = true }else{ state.fullscreenLoading = true } const par= new FormData(); //form中的值整理到formData中 Object.keys(editForm.value).forEach(item => { let value =editForm.value[item] if(value !=='' && value !== null && value !== undefined){ par.append(item, value) } }) //图片放到formData中 state.fileList.forEach((item,index)=>{ if(state.fileList[index].raw){ par.append("fileList", item.raw); } }) let formData = reactive({ processMaintApply:par, isSubmit:number, userCode:useCommon.userInfo.accountName, orgId:editForm.value.deptId, userFullName:useCommon.userPersonInfo.personName }) //num是否提交申请单,0:不提交只保存,1:提交申请单 addApplyOutSide(formData).then(res =>{ ElMessage.success("申请单申请成功!") tagsView.delCurrentView() router.go(-1) }).finally(()=>{ state.fullscreenLoading= false state.loadingSave = false }); } }) } </ script > export function addApplyOutSide(data) { return request({ url: `api/process-maint-apply-outside/add?isSubmit=` + data.isSubmit + `&userCode=` + data.userCode + `&userFullName=` + data.userFullName + `&orgId=` + data.orgId, method: `post`, data: data.processMaintApply, type: 'picture' }) } |
三、后端实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Operation(summary = "新增") @PostMapping(value = "/add") @Parameters({ @Parameter(name = "userCode", description = "登录账号"), @Parameter(name = "orgId", description = "所属部门"), @Parameter(name = "userFullName", description = "用户姓名"), @Parameter(name = "isSubmit", description = "提交申请单标识(0:保存申请单,1:提交申请单"), @Parameter(name = "processMaintApply", description = "申请单信息") }) public ResponseData add(@RequestHeader(value = "app-flag" ,required = false) String headerValue, @RequestParam(value = "userCode",required = true) String userCode, @RequestParam(value = "userFullName", required = false) String userFullName, @RequestParam(value = "isSubmit", required = true) Integer isSubmit, @RequestParam(value = "orgId", required = true) Long orgId, ProcessMaintApplyOutside processMaintApplyOutside,@RequestParam(value = "fileList" ,required = false) MultipartFile[] fileList){ // 通过headerValue判断是不是小程序新增的数据 if (StringUtils.isNotBlank(headerValue) && headerValue.equals("wx")) { processMaintApplyOutside.setIsWx(true); } return ResponseUtil.success(processMaintApplyOutsideService.add(userCode,orgId,userFullName,isSubmit,processMaintApplyOutside,fileList)); } |
四、图片上传
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | public class FileUpload { public static String fileUpload(MultipartFile[] files, Long id, String path) { String thumn = ""; try { if (files != null && files.length > 0) { //获取当前年月 String ym = "vehicle/"+DateUtil.getYearMonth(new Date()) + "/"; path = path + ym; File filePath = new File(path); //判断filePath是否存在 if (!filePath.exists() && !filePath.isDirectory()) { //filePath目录不存在,需要创建 filePath.mkdirs(); } int len = files.length; for (int i = 0; i < len ; i++) { //获取文件原始名称(带扩展名) String originalFilename = files[i].getOriginalFilename(); //获取文件类型 String type = originalFilename.substring(originalFilename.lastIndexOf(".")); //生成新文件名称 String filename = id + "_" + SnowIdUtil.getId() + type; byte[] bytes = files[i].getBytes(); File file1 = new File(path + filename); if (file1.exists() && !file1.delete()) { throw new Exception((path + filename) + "文件删除错误"); } Path newpath = Paths.get(path + filename); Files.write(newpath, bytes); if (i < len - 1) { thumn += (ym + filename) + ","; } else { thumn += ym + filename; } } } } catch (Exception e) { e.printStackTrace(); } return thumn; }<br>< br >public void addFileList(MultipartFile[] files, Long id, String tableName) {< br > //存储图片的路径< br > String path = customConfig.getFilePath();< br > if (files != null && files.length > 0) {< br > String filepaths = FileUpload.fileUpload(files, id, path); //上传图片< br > String[] filepath = filepaths.split(",");< br > for (int i = 0; i < filepath.length ; i++) {<br> SysAttachFilepathInfo attachFilepathInfo = new SysAttachFilepathInfo();< br > attachFilepathInfo.setFilePath(filepath[i]);< br > attachFilepathInfo.setRelationId(id);< br > attachFilepathInfo.setRelationTable(tableName);< br > attachFilepathInfo.setId(SnowIdUtil.getId());< br > sysAttachFilepathInfoMapper.insert(attachFilepathInfo);< br > }< br > } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!