v-md-editor插入本地图片

本地图片上传

  v-md-editor并没有给我们实现在editor中插入本地图片,这需要我们自己手动实现,最近两天考虑多种情况,还是决定采取很经典的解决方案:在数据库存储图片的从属关系以及其保存路径和图片名称,然后通过访问后端服务器来获取图片,这两天都在折腾其他事情,今天才来得及解决,下面是具体实施:
  首先我们结合官方文档说明来思考方案

官方文档

  插入本地图片

  下面是文档关于此处的核心代码,官方只给出了提示并没有给出方案,这需要我们自我发挥了 methods: { handleUploadImage(event, insertImage, files) { // 拿到 files 之后上传到文件服务器,然后向编辑框中插入对应的内容 console.log(files);

  // 此处只做示例
  insertImage({
    url:
      'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1269952892,3525182336&fm=26&gp=0.jpg',
    desc: '七龙珠',
    // width: 'auto',
    // height: 'auto',
  });
},

后端方面

  很容易想到的是先从数据库下手,我们只需要保存图片的获取方法和从属与哪一篇文章即可,下面就是表结构:

    create table images
(
id            int auto_increment
    primary key,
image         varchar(200) not null,
dependence_id int          null,
address       varchar(200) not null
);

实体类

  注意dependence_id是可以为空的,因为我们在编写文章时会保存草稿,此时文章并未上传数据库,但是图片一旦插入就会保存在数据库,当文章发布时才会更新dependence_id,下面是对应的实体类:

@TableName("images")
@Data
public class Image {

    @TableId(type = IdType.AUTO)
    private Integer id;
    private String image;
    private Integer dependenceId;
    private String address;

}

Controller

  请注意id的策略为AUTO,接下来照着模板把ImageService、ImageServiceImpl、ImageMapper、ImageController等整理一下即可,这里先列出ImageController:

@RestController
@RequestMapping("/upload/image")
public class imageController {

    @Autowired
    private ImageService imageService;
    @Value("${MyBlog.path}")//千万别用path,这是已有的配置,不是自定义的
    private String basePath;
    @Value("${Service.address}")
    private String baseService;

    @PostMapping("/{id}")
    public R<String> uploadImageOfArticle(@PathVariable("id") Integer id,@RequestBody Integer []ids){

        Image image = new Image();
        image.setDependenceId(id);

        for(Integer idImage : ids){
            image.setId(idImage);
            imageService.updateById(image);
        }

        return R.success("图片从属关系已更新!");

    }

    @PostMapping
    public R<String[]> uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
        //原始文件名
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;//断定不为空
        //后缀
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));

        //判断是否存在目录basePath
        File dir=new File(basePath);

        //如果不存在就创建目录
        if(!dir.exists()){
            dir.mkdirs();
        }

        //UUID重命名文件,防止文件名称重复造成文件覆盖
        String fileName= UUID.randomUUID().toString() + suffix;

        System.out.println(basePath + fileName);

        file.transferTo(new File(basePath + fileName));
//        file.transferTo(new File("D:\\test\\test.jpg"));

        Image image = new Image();
        image.setImage(fileName);
        image.setAddress(basePath+fileName);

        imageService.save(image);

        String []s={baseService+"upload/image/"+fileName, String.valueOf(image.getId())};

        return R.success(s);
//        return R.success("D:\\test\\test.jpg");
    }

    @GetMapping("/{name}")
    public R<String> getById(@PathVariable("name") String name, HttpServletResponse response) throws IOException {

        FileInputStream inputStream=new FileInputStream(new File(basePath + name));

        ServletOutputStream outputStream = response.getOutputStream();

        response.setContentType("image/jpeg");

        int len;
        byte[] bytes = new byte[1024];

        while ((len=inputStream.read(bytes))!=-1){
            outputStream.write(bytes, 0, len);
            outputStream.flush();
        }

        outputStream.close();
        inputStream.close();

        return R.success("载入成功!");
    }
}

分析Controller

  从头到尾解释一遍此controller:@Value中的属性是对应application.yml里的值,配置如下,大家可以灵活更改:

Service:
  address: http://127.0.0.1:${server.port}/
#图片保存路径
MyBlog:
  path: D:\myBlogImages\

  uploadImageOfArticle接口对应的是当文章提交时,更新图片的从属关系,我们要获取文章的id以及文章所包含的上传图片的数组ids,然后遍历更新一遍数组ids对应图片的从属关系
  uploadImage接口对应的是图片插入时直接上传到数据库,我们只需要获取文件即可,这里采用了伪form表单提交,前端会伪造一个form表单提交,然后我们重命名图片保证其name不重复,将其保存在yml中设置的图片文件夹路径下,随后将图片的数据提交到数据库,并返回图片的获取路径和id
  getById接口顾名思义,就是通过id获取图片,此处又是经典的java文件流读取,HttpServletResponse将会把图片返回;

前端方面

  插入本地图片时,在官方文档提供的methods的基础上,我们将file放入FormData中,模拟表单提交即可: handleUploadImage(event, insertImage, files){ let file=new FormData(); file.append('file',files[0]);

  imageLoad(file).then(res=>{
    let data = res.data;

    if(data.code==="100"){
      this.$notify.success(this.notifyMsgSuc("图片插入成功!"));
      insertImage({
        url:data.data[0],
        desc:files.name
      });
      let ids=this.localGetObject(this.articleSaveImageIds);
      if(!ids) {
        ids=[data.data[1]];
      }else ids.push(data.data[1]);

      this.localSetObject(this.articleSaveImageIds,ids);
    }
  }).catch(err=>this.$notify.error(this.notifyMsgErr(err.message)));
}

分析handleUploadImage

  files是一个数组,而我们一次只插入一张图片,因此只需要获取files[0]即可,将其放入FormData,注意'file'要与后端接口的file保持一致,否则后端会报空指针,下面的imageLoad是我封装的ajax请求,其代码如下:

const src="/api/upload";

export function imageLoad(Data){
    return axios.post(src+"/image",Data, {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    });
}

  以后src将直接替代接口的根路径,就不再次呈现了,axios的第三参数为config,务必不要忘记这个配置,在请求返回成功后,执行insertImage,这是官方提供的api,随后我们将返回的图片id保存在本地存储的ids数组中,等待提交命令下达

提交操作

  当点击保存时,文章模板会背保存到本地;当点击提交时会执行如下操作:

submit(){
  this.Article.author=this.localGetObject(this.userObjectName).username;
  articlePost(this.Article).then(res=>{
    let d=res.data;
    this.$notify.success(this.notifyMsgSuc(d.data));
    if(d.code==="100"){

      imageUploadArticle(d.data,this.localGetObject(this.articleSaveImageIds)).then(resp=>{
        let im=resp.data;
        if(im.code==="100"){
          localStorage.removeItem(this.articleSaveImageIds);
          this.$notify.success(this.notifyMsgSuc("图片从属关系已更新!"));
        }else this.$notify.error(this.notifyMsgErr(im.msg))
      }).catch(err=>this.$notify.error(err.message))

      localStorage.removeItem(this.articleEditTemplate);//清空本地文章编辑存储
    }else this.$notify.error(this.notifyMsgErr(d.msg))
  }).catch(err=>this.$notify.error(this.notifyMsgErr(err.message)));
}

分析submit

  提交流程为:先为Article补充信息,然后发出提交请求,提交成功后则立即为ids数组对应图片更新从属关系,然后删除本地有关的存储即可

效果展示

  图片插入效果如下:

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱飞的男孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值