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

文章目录

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


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

以下部分仅贴出关键代码

一. 总体代码流程

1.1 全局Axios部分样例

axios前后端网络交互

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类型
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

    <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>
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("简历投递已取消!")
  })
}

文件校验部分

// 单文件大小校验
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);
}

请求发送部分

export function reqPostResumeForm(formData){
    return uploadFiles(jobs.postResumeUrl,formData)
}

二. 后端部分

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

三. 测试样例

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/112133.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ORANGE室内高尔夫—韩国室内模拟高尔夫原装进口真实体验身临其境

ORANGE室内高尔夫—韩国室内模拟高尔夫 真实体验 身临其境 室内高尔夫的产品优势&#xff1a; 1. 实际高尔夫球场的限制&#xff1a;室内高尔夫可以弥补室外高尔夫球场数量有限的问题&#xff0c;使得更多人能够享受高尔夫运动。 2. 天气和季节的限制&#xff1a;室内高尔夫可…

苹果AirTag平替产品选择,国内外支持苹果Find My芯片功耗全面对比

2021年4月20,苹果在春季产品发布会上推出了全新的产品类型- AirTag,将哆啦A梦的追踪徽章带到了现实。这个小产品当年并没有像其它苹果新品那样一朝爆红。随着年轮缓缓而坚定地前行, AirTag也缓缓而坚定地前行,并被越来越多的人接受和喜欢。 深入思考AirTag背后的产品逻辑和实现…

前端基础之JavaScript

目录 一、JavaScript概述 二、JavaScript引入方式 三、JavaScript语言规范 四、JavaScript语言基础 五、JavaScript数据类型 数值(Number) 字符串(String) 布尔值(Boolean) null和undefined 对象(Object) forEach() map() 六、运算符 七、流程控制 八、函数 函…

10.31日模拟赛总结

文章目录 考试时间及策略考试结果考试反思题解A.进步科学B.吉吉没急C.老杰克哒D.季积晓淆 考试时间及策略 没啥好说的&#xff0c;因为好像都不会。所以全场感觉都在罚坐&#xff0c;很痛苦。 考试结果 30 0 50 5 85 考试反思 T1&#xff1a;T1是个神奇状压&#xff0…

vsCode安装CodeRunner插件输出中文乱码问题

1 vsCode下载 vcCode官网地址&#xff1a;https://code.visualstudio.com/ 2 安装CodeRunner 通过Ctrl Shift P 找到 settings找到code-runner.executorMap&#xff0c;在 settings.json 中加入 "code-runner.executorMap": {....."python": "s…

上班族如何做日程自律清单实现逆袭呢?电脑日程管理软件助力高效办公

越来越多的上班族都表示自己每天的工作任务非常多&#xff0c;经常从早忙到晚也无法按时完成工作&#xff0c;导致工作的拖延完成&#xff0c;这应该怎么办呢&#xff1f;其实对于职场人士来说&#xff0c;想要在工作中提升效率&#xff0c;就需要提前做好每天的工作日程安排&a…

如何在Android设备上检查应用程序使用情况,包括使用时间

你可能不知道自己花了多少时间在手机上。很可能你一天中有一半的时间都在盯着手机屏幕。如果你怀疑这一事实,你会很快核实的。在这篇文章中,我们将向你介绍如何在Android设备上检查应用程序的使用情况。 如何在Android上检查应用程序电池使用情况 你使用时间最长的应用程序…

腾讯云轻量级服务器哪个镜像比较好?

腾讯云轻量应用服务器镜像是什么&#xff1f;镜像就是操作系统&#xff0c;轻量服务器镜像系统怎么选择&#xff1f;如果是用来搭建网站腾讯云百科txybk.com建议选择选择宝塔Linux面板腾讯云专享版&#xff0c;镜像系统根据实际使用来选择&#xff0c;腾讯云百科来详细说下腾讯…

2023年四川省网络与信息安全技能大赛 决赛个人赛Writeup

文章目录 Web前端验证PHP_Try MiscHelloWorld密码在这easy_log Cryptobaser 线下“断网”CTF个人赛&#xff0c;题都很简单(新手级难度)&#xff0c;总共10道题目&#xff0c;解了6题。 赛题附件请自取&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1lgNEBO7a1L4KLE2t…

Academic Inquiry|如何阅读英文文献

相关素材&#xff1a; 知云文献阅读器、谷粉学术 相关可借鉴文章&#xff1a; [1]Academic Inquiry|国外文献查找-CSDN博客 [2]Academic accumulation|英文文献速读-CSDN博客 [3]Academic Inquiry|edge、chrome浏览器插件配置及相关问题解答-CSDN博客 一、相关素材准备 &#…

最新Ai智能创作系统源码V3.0,AI绘画系统/支持GPT联网提问/支持Prompt应用+搭建部署教程

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

kubernetes-service微服务

目录 一、service微服务 二、Ipvs模式 三、ClusterIP 1.ClusterIP 2.headless 四、NodePort 1.NodePort 2.默认端口 五、LoadBalancer 1.LoadBalancer 2.metallb 六、ExternalName 一、service微服务 Kubernetes Service微服务是一种基于Kubernetes的微服务架构&…

智慧矿山:AI算法在带式运输机中的异物识别应用

随着现代农业和工业的发展&#xff0c;带式运输机在各种生产作业中发挥着越来越重要的作用。然而&#xff0c;在带式运输机运行过程中&#xff0c;可能会混入各种异物&#xff0c;这些异物的存在可能会对运输过程和设备本身造成损害。为了解决这一问题&#xff0c;本文将介绍一…

一个极好用的浏览器标签页插件

这是我登录后&#xff0c;并且上传了个人壁纸的页面 Br标签页 一 . 我们来看看界面和功能1.注册登录2.首页及右键功能3.添加小组件和app网址4.切换壁纸5. 计划页面 二 . Edge浏览器安装和chrome&#xff08;谷歌&#xff09;浏览器安装1. Edge浏览器安装2. chrome&#xff08;谷…

【java】命令行,包

文件夹情况&#xff1a; HelloWorld.java package com.demo; public class HelloWorld{public static void print(){System.out.println("HelloWorld!");}public static void main(String[] args){print();} } import.java import com.demo.HelloWorld; public cla…

K8S的pod创建过程

创建流程图 用户发起请求创建deployment&#xff1b;apiserver收到创建资源的请求&#xff0c;apiserver对客户端操作进行身份认证&#xff0c;认证完成后接受该请求&#xff0c;并把相关的信息保存到etcd中&#xff0c;然后返回确认信息给客户端&#xff1b;apiserver向etcd…

EDA常用数字器件硬件描述

EDA常用数字器件硬件描述 前言 在使用了一段时间EDA编程之后&#xff0c;来回顾一下基本的知识&#xff0c;看看如何实现基本的EDA常用数字器件对应的硬件描述 一、组合逻辑器件描述 1. 基本的逻辑门电路 与、或、非&#xff08;取反&#xff09;、与非、或非、异或、同或 …

Centos7安装Docker,安装DockerCompose(集群化部署),Docker私服镜像仓库

0.安装Docker Docker 分为 CE 和 EE 两大版本。CE 即社区版&#xff08;免费&#xff0c;支持周期 7 个月&#xff09;&#xff0c;EE 即企业版&#xff0c;强调安全&#xff0c;付费使用&#xff0c;支持周期 24 个月。 Docker CE 分为 stable test 和 nightly 三个更新频道…

数据结构第一课-----------数据结构的介绍

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

VueRouter 源码解析

重要函数思维导图 路由注册 在开始之前&#xff0c;推荐大家 clone 一份源码对照着看。因为篇幅较长&#xff0c;函数间的跳转也很多。 使用路由之前&#xff0c;需要调用 Vue.use(VueRouter)&#xff0c;这是因为让插件可以使用 Vue export function initUse(Vue: GlobalAP…