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

三. 测试样例


相关推荐
计算机毕设定制辅导-无忧学长9 小时前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
JWASX14 小时前
【Go】map 源码解析 - group
后端·golang·map·源码分析
小郎君65815 小时前
注解式脱敏:用 Jackson 的 ContextualSerializer 做字段级策略(一)
spring boot·spring cloud
jktantan17 小时前
注解式脱敏:用 Jackson 的 ContextualSerializer 做字段级策略(一)
spring boot·后端·算法·spring cloud·系统架构
露天赏雪1 天前
第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案
java·开发语言·人工智能·spring boot·spring·servlet·sentinel
联犀1 天前
纯 Go 的 CAD 开源库 go-cad:直接解析 DWG/DXF,现在也能导出 PDF
开发语言·golang·pdf
FungLeo2 天前
成为全栈·Go 后端篇·三轮代码审阅之后:把可读性和证据做成工程规则
golang·go·ast·静态检查·成为全栈·代码审阅
蜗牛8752 天前
为 Spring Boot 团队做一个 Elasticsearch 查询工作台:六种模式、语义补全与浏览器直连
spring boot
联犀2 天前
联犀 Go SIMD 实战:视频转码从 16.5ms 到 5.46ms
开发语言·golang·音视频
养军博客2 天前
Spring Boot 3.x + Spring Security 6.x 整合 JWT 实战:jjwt 与 java-jwt 两种工具库详解
java·spring boot·springsecurity