vant图片上传服务器踩坑传

vant图片上传服务器踩坑传

需求

使用vant的图片上传组件上传图片,后台接收图片并存储到服务器,并且返回图片地址和存储id

前端

HTML:

<van-field  :readonly=detailFlag  autosize   name="code" label="上传图片"   placeholder="请输入">
  <template #input>
    <van-uploader v-model="uploader"
                  multiple
                  accept="image/*"
                  :before-read="beforeRead"
                  :max-count="5"
                  :max-size="3 * 1024 * 1024"
                  @oversize="onOversize"
                  :after-read="afterRead"
                  @delete="deleteFile"
    />
  </template>
</van-field>

js:

  	  import  {uploadMultipleFile} from "../../api/target/file";
   	  import Toast from "vant/es/toast";
	  //校验文件大小是否超出限制
      onOversize(file){
        Toast.fail('文件太大');
      },
      //校验图片格式
      beforeRead(file){
        let fileType='';
        if(file instanceof Array && file.length){
          for (let i = 0; i < file.length; i++) {
              fileType=file[i].type.substr(0,file[i].type.indexOf('/'));
              if (fileType !== 'image') {
                Toast('格式错误');
                return false;
              }
          }
        }else{
          fileType=file.type.substr(0,file.type.indexOf('/'));
          if (fileType!== 'image') {
            Toast('格式错误');
            return false;
          }
        }
        return true;
      },
      //上传图片
      afterRead(file){
         console.log("上传文件"+file);
          file.status = 'uploading';
          file.message = '上传中...';

         let formData = new FormData();
         //区分单文件上传还是多文件
         if(file instanceof Array && file.length){
           for (let i = 0; i < file.length; i++) {
               formData.append("files", file[i].file);
           }
         }else{
           formData.append("files", file.file);
         }
           uploadMultipleFile(formData).then(res => {
            console.log("上传图片结果报文", res);
            if (res.data.code =='200' ){
               if(file instanceof Array && file.length){
                 for (let i = 0; i < file.length; i++) {
                     this.storeId.push(res.data.data.storeIds[i]);
                 }
               }else{
                 this.storeId.push(res.data.data.storeIds[0]);
               }
                console.log("storeIds");
                console.log(this.storeId);
              // Toast.success('上传图片成功');
            } else{
              file.status = 'failed';
              file.message = '上传失败';
              Toast.fail('上传图片失败');
            }
          }).catch(err => {
            file.status = 'failed';
            file.message = '上传失败';
              console.log(err);
          });
      },
      //删除图片
      deleteFile(file,detail){
            console.log("删除");
            this.storeId.splice(detail.index,1);
            console.log("storeIds");
            console.log(this.storeId);
       }

此处是使用form-data格式传值,请求方式使用的是axios
使用form-data格式传值和使用普通的body传值方法(raw)是一样的,无非是form-data要把数据提前处理好而已,需要注意的是在请求的时候不用设置Content-Type,因为发送请求时会自动识别

注意:这里不能直接将方法获取到的file当做参数传过去,因为这个file是被包装过的,我们要的是里面的那个精华,像是这样:

formData.append("files", file.file);

file.file
本人便是在这里卡了四五个小时。。。
api:
index.js:

import axios from 'axios'
import setRequestHeader from "../../utils/setHeaderData"

const service = axios.create({
  baseURL:"http://ip:port/",
  responseType: 'json',
  timeout: 10000,
  ...setRequestHeader
});
export default service

file.js:

import {createSerialNumber} from "../../utils/random.js"
import axios from "./index.js"

/**
 * 图片上传
 * @param {Object} obj
 */
export function uploadMultipleFile(obj) {
  obj.seqno = createSerialNumber;
  return axios({
    url: 'store/uploadMultipleFile',
    method: 'post',
    data: obj
  });
}

后端

controler:

    public Response uploadImg(@RequestParam("files")MultipartFile[] files,HttpServletRequest request){
        if (files.length==0){
            return new Response("fail","无文件");
        }
        try {
            return  new Response("success",storeService.uploadImg(files, request));
        } catch (IOException e) {
            e.printStackTrace();
            return new Response("fail",e.getMessage());
        }
    }

service:

HashMap uploadImg(MultipartFile[] files, HttpServletRequest request) throws IOException;

serviceImpl:

	@Override
    public HashMap uploadImg(MultipartFile[] files, HttpServletRequest request) throws IOException {
        HashMap map=new HashMap();
        List<String> images = new ArrayList<>();
        List<String> storeIds = new ArrayList<>();
        for (MultipartFile file : files) {
            //获取绝对路径
            String realPath = uploadFileConfig.getFilePath();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
            String format = sdf.format(new Date());
            //文件存放的目录
            File folder = new File(realPath + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String oldName = file.getOriginalFilename();
            //文件后缀
            String suffix = oldName.substring(oldName.lastIndexOf("."));
            //文件新名字
            String newName = UUID.randomUUID().toString() + suffix;
            File targetFile = new File(folder+"/"+newName);

            if (!targetFile.exists()) {
                targetFile.mkdirs();
            } else {
                targetFile.delete();
            }
            file.transferTo(targetFile);
            String filePath =  "uploadFile/" + format + newName;
            String storeId = editStore(filePath, "");
            images.add(filePath );
            storeIds.add(storeId);
        }
        map.put("images",images);
        map.put("storeIds",storeIds);
        return map;
    }

application.yml:

upload:
  filepath: D:/upload/test/uploadFile/

configuration:

@Component
@ConfigurationProperties(prefix = "upload")
@Data
public class UploadFileConfig {
    private  String filePath;
}

效果

效果图
效果图2

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值