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)
}

三. 测试样例


相关推荐
阿维的博客日记6 小时前
Hippo4j 线程池监控平台部署手册
java·spring boot·后端
pixcarp8 小时前
知识库系统的内容资产闭环怎么设计
服务器·数据库·后端·golang
张忠琳11 小时前
【Go 1.26.4】Golang Select 深度解析
开发语言·后端·golang
提笔了无痕13 小时前
如何用Go实现整套RAG流程
开发语言·后端·golang
wlsh1513 小时前
Go 错误处理
golang
geovindu14 小时前
go: Generators Pattern
开发语言·后端·设计模式·golang·生成器模式
鹅城剑仙18 小时前
Spring Boot 微服务架构设计与最佳实践
spring boot·后端·微服务
心之伊始19 小时前
Spring Boot Actuator + Micrometer 实战:自定义业务指标并接入 Prometheus 观测接口耗时
java·spring boot·prometheus·actuator·micrometer
青春喂了后端19 小时前
Go Sidecar Status 性能优化
开发语言·性能优化·golang
我登哥MVP19 小时前
走进 Gang of Four 设计模式:装饰器模式
java·spring boot·设计模式·装饰器模式