go-gin-vue3-elementPlus带参手动上传文件

文章目录

    • [一. 总体代码流程](#一. 总体代码流程)
      • [1.1 全局Axios部分样例](#1.1 全局Axios部分样例)
      • [1.2 上传业务](#1.2 上传业务)
    • [二. 后端部分](#二. 后端部分)
    • [三. 测试样例](#三. 测试样例)

go的mvc层使用gin框架. 总的来说gin的formFile封装的不如springboot的好.获取值有很多的坑. 当然使用axios的formData也有不少坑.现给出较好的解决办法

以下部分仅贴出关键代码

一. 总体代码流程

1.1 全局Axios部分样例

axios前后端网络交互

java 复制代码
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
    // axios中请求配置有baseURL选项,表示请求URL公共部分
    baseURL: 'http://127.0.0.1:20139',
    // 超时
    timeout: 5000
})

export default service;

// 不使用service实例.重新创建axios封装上传
export function uploadFiles(url,data={}){
    return axios({
        method: "POST",
        url: 'http://127.0.0.1:20139'+url,
        transformRequest: [function(data, headers) {
            // 去除post请求默认的Content-Type
            delete headers['Content-Type']
            return data
        }],
        data: data,
    })
}

1.2 上传业务

关键代码一览.需要留意的是,我使用手动上传,element中before-upload,before-remove失效. 为避免更多问题使用了on-change监听.其中uploadFile参数是element封装的普通对象. file对象被封装在其中的raw属性. 这一点要尤为注意 gin框架不同于springboot. formfile只能读取file类型

html 复制代码
    <el-form :inline="true"
             :model="resumeForm"
             class="demo-form-inline"
             label-position="right"
             label-width="100px">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="姓名">
            <el-input v-model="resumeForm.name" placeholder="请输入姓名" clearable/>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="电话">
            <el-input v-model="resumeForm.phone" placeholder="请输入电话" clearable/>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="邮箱">
            <el-input v-model="resumeForm.email" placeholder="请输入邮箱" clearable/>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="6">
          <el-form-item label="工作经验">
            <el-input v-model="resumeForm.experience" placeholder="请输入工作经验" clearable/>
          </el-form-item>
        </el-col>
        <el-col :span="6">
          <el-form-item label="学历">
            <el-select
                v-model="resumeForm.education"
                placeholder="请选择学历水平"
                clearable
            >
              <el-option label="专科" value="0"/>
              <el-option label="本科" value="1"/>
              <el-option label="研究生" value="2"/>
              <el-option label="博士" value="3"/>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row>
        <el-col :span="24">
          <el-form-item label="上传简历">
            <el-upload
                ref="recruitRef"
                class="upload-demo"
                drag
                action="#"
                :auto-upload="false"
                :on-change="handleChange"
                limit="1"
            >
              <el-icon class="el-icon--upload">
                <upload-filled/>
              </el-icon>
              <div class="el-upload__text">
                拖拽 或 <em>点击上传</em>
              </div>
              <template #tip>
                <div class="el-upload__tip">
                  .pdf 文件大小 ≤ 500kb
                </div>
              </template>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item>
        <el-button type="primary" @click="postResumeForm()">投递</el-button>
      </el-form-item>
    </el-form>
javascript 复制代码
const router = useRouter()
const resumeForm = reactive({
  name: '',
  phone: '',
  email: '',
  experience: '',
  education: '',
  position: router.currentRoute.value.params.position
})

const recruitRef = ref()
let formData = new FormData()
// 文件改变触发
function handleChange(uploadFile, uploadFiles) {
	// 文件校验
  if (!verifyBeforeUpload(uploadFile)) {
    removeFile()
    return
  }
  console.log(uploadFile)
  formData.append("file", uploadFile.raw)
}

function removeFile() {
  if (recruitRef.value) {
    formData = new FormData()
    recruitRef.value.clearFiles()
  }
}
// 提交表单
function postResumeForm() {
  ElMessageBox.confirm('确认提交?提交后仅能修改一次', '提示', {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  }).then(async () => {
    if (formData === null || formData === undefined) {
      ElMessage.info("必须递交简历信息!")
      return
    }
    for (let key in resumeForm) {
      formData.append(key,resumeForm[key])
    }
    let res = await reqPostResumeForm(formData)
    if (res.code !== 200) {
      ElMessage.error("简历投递失败")
      return
    }
    await ElMessageBox.alert("简历投递成功! 3-7个工作日内,您将收到回复", '提示', {
      confirmButtonText: "确认"
    })
    removeFile()
  }).catch((err) => {
    removeFile()
    console.log(err)
    ElMessage.info("简历投递已取消!")
  })
}

文件校验部分

javascript 复制代码
// 单文件大小校验
function verifyFileSize(file) {
    if (file) {
        let fileSize = file.size;
        let fileMaxSize = 1024 * 500;//500kb
        if (fileSize > fileMaxSize) {
            ElMessage.error("文件不能大于500kb!");
            file.value = "";
            return false;
        } else if (fileSize <= 0) {
            ElMessage.error("文件不能为0kb!");
            file.value = "";
            return false;
        }
        return true
    }
    ElMessage.error("必须传递文件!")
    return false;

}

// 校验文件格式和大小
export function verifyBeforeUpload(file) {
    // 格式
    const extension = file.name.split('.').pop().toLowerCase();
    console.log(extension)
    if (!ACCEPTED_EXTENSIONS.includes(extension)) {
        ElMessage.error('仅支持 pdf 格式的文件');
        return false;
    }
    // 大小
    return verifyFileSize(file);
}

请求发送部分

javascript 复制代码
export function reqPostResumeForm(formData){
    return uploadFiles(jobs.postResumeUrl,formData)
}

二. 后端部分

java 复制代码
func PostResume(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		panic(fmt.Sprintf("file参数不能为空"))
	}
	var resume model.Resume
	err = c.ShouldBind(&resume)
	if err != nil {
		panic(fmt.Sprintf("resume获取错误,原因是: %v", err))
	}
	log.Printf("%v", file)
}

三. 测试样例


相关推荐
2601_962055972 小时前
跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
spring boot·后端·tomcat
EXI-小洲2 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
2601_961901704 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
QQ_21696290965 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
2601_962128417 小时前
SpringBoot篇(缓存层)
java·spring boot·缓存
2601_962069779 小时前
SpringBoot开发——初步了解SpringBoot
java·spring boot·后端
jay神9 小时前
【计算机毕业设计】基于Spring Boot的宠物领养管理系统
java·spring boot·后端·vue·毕业设计·宠物
2601_962056609 小时前
可造成敏感信息泄露!Spring Boot之Actuator信息泄露漏洞三种利用方式总结
java·spring boot·后端
码视野9 小时前
基于 Spring Boot + Vue3 的【城市道路地下空洞塌陷微动传感监测与路面脱空沉降预警中台】设计与实现(含PRD/三端高保真源码/大屏)
vue.js·spring boot·后端
蓝宝石的傻话10 小时前
因为MiBeeNVR,决定接 onvif-go 自己管理并重构
数码相机·重构·golang