SpringBoot项目前端Vue访问后端(图片静态资源) 配置

静态资源配置

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    @Value("${file.save-path}")
    private String fileSavePath;


    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {

        //映射本地文件夹
        registry.addResourceHandler("/images/**").addResourceLocations("file:" + fileSavePath);
        super.addResourceHandlers(registry);
    }
}

 application.yml

file:
   save-path: D:\qr_code_duct\qr_code_back\images\

详细说明 

由于要展示的图片可能比较大,从后端数据库中获取base64编码明显不可能(base64大部分适用于KB级别的),数据库正常来说也只存放图片的地址,而不是图片的内容。

CREATE TABLE `card_record_image` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `card_record_id` int(11) DEFAULT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `operator_id` int(11) DEFAULT NULL,
  `image_url` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `card_record_id` (`card_record_id`),
  CONSTRAINT `card_record_image_ibfk_1` FOREIGN KEY (`card_record_id`) REFERENCES `card_record` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8mb4;
    public RespondDto saveCardRecord(RequestData requestData) {
        // 解析前端传递的数据, 创建CardRecord对象并保存到数据库
        CardRecord cardRecord = new CardRecord();
        cardRecord.setProductId(requestData.getProductId());
        cardRecord.setCurrentLocation(requestData.getCurrentLocation());
        cardRecord.setDescription(requestData.getDesc());
        cardRecord.setCreateTime(new Date());
        cardRecordMapper.insert(cardRecord);

        // 保存卡记录图片
        List<String> imageList = requestData.getImageList();
        List<String> imageUrlList = new ArrayList<>();

        for (String base64Image : imageList) {
            // 移除可能的前缀信息(如"data:image/jpeg;base64,"),只保留base64编码部分
            String base64Data = base64Image.replaceAll("data:image/.*;base64,", "");
            // 从 base64 解码成二进制数据
            byte[] imageBytes = Base64.getDecoder().decode(base64Data);
            // 生成文件名,这里可以根据需要生成唯一的文件名
            String fileName = "image_" + UUID.randomUUID() + ".png";

            // 构建文件保存路径
//            String fileSavePath = "D:" + File.separator + "qr_code_duct" + File.separator + "qr_code_back" + File.separator +"images" +File.separator +fileName;

            String fileSavePath = fileProperties.getSavePath() + fileName;

            try (FileOutputStream fos = new FileOutputStream(fileSavePath)) {
                fos.write(imageBytes);
                // 替换为实际的域名和路径
                imageUrlList.add("/images/" + fileName);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            // 保存图片信息到数据库
            CardRecordImage cardRecordImage = new CardRecordImage();
            cardRecordImage.setCardRecordId(Math.toIntExact(cardRecord.getId()));
            // 替换为实际的域名和路径
            cardRecordImage.setImageUrl("/images/" + fileName);
            cardRecordImage.setCreateTime(new Date());
            cardRecordImageMapper.insert(cardRecordImage);
        }
        return new RespondDto(ResultCode.OK, "保存成功!!");
    }
<template>
  <div>
    <div class="return-button-container">
      <el-button size="small"  @click="goBack">返回</el-button>
    </div>
    <el-table :data="cardRecords" style="width: 100%">
      <el-table-column prop="productId" label="板卡编号"></el-table-column>
      <el-table-column prop="currentLocation" label="记录人"></el-table-column>
      <el-table-column label="图片">
        <template slot-scope="scope">
          <div v-if="Array.isArray(scope.row.images)">
            <div v-for="(image, index) in scope.row.images" :key="index">
              <img :src="getImageUrl(image.imageUrl)" style="max-width: 100px; max-height: 100px">
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="description" label="说明备注"></el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      cardRecords: []
    };
  },
  created() {
    this.getAllCardRecordsWithImages();
  },
  methods: {
    goBack() {
      window.location.href = 'http://localhost:8889/login'
    },
    getImageUrl(imageUrl) {
      return 'http://192.168.**.**:9999' + imageUrl;
    },
    getAllCardRecordsWithImages() {
      this.$request.get('/cardRecord/allWithImages')
          .then(res => {
            console.log('Response data:', res.data);
            if (Array.isArray(res.data) && res.data.length > 0) {
              this.cardRecords = res.data.map(item => this.parseData(item));
            } else {
              console.error('Error fetching card records: Data is empty');
            }
          })
          .catch(error => {
            console.error('Error fetching card records:', error);
          });
    },
    parseData(data) {
      return {
        productId: data.productId,
        currentLocation: data.currentLocation,
        images: Array.isArray(data.images) ? data.images.map(image => ({
          id: image.id,
          imageUrl: image.imageUrl
        })) : [],
        description: data.description
      };
    }
  }
};
</script>
<style scoped>
.return-button-container {
  position: absolute;
  top: 16px;
  right: 16px;
}
</style>

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

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

相关文章

NineData推出SQL开发专业版:10数据源永久免费,助力企业数据库研发提效!

在数据库开发领域&#xff0c;选择合适的工具和服务至关重要。而NineData作为新一代的云原生智能数据管理平台&#xff0c;提供了数据复制、SQL 开发、数据备份以及数据对比等多种功能&#xff0c;帮助用户轻松实现混合云、多云数据源的统一管理。采用SaaS模式&#xff0c;无需…

QML入门

First Step with QML 每个QML文件都包含两部分&#xff1a;一个import部分和一个对象声明部分。对用户界面来说&#xff0c;最常用的类型和函数都定义在QtQuick 这个模块里。 编写HelloWorld 先从编程世界起点HelloWorld开始&#xff0c;这里&#xff0c;我们先不建立Qt Pro…

linux单机部署hadoop

1.下载安装包 https://archive.apache.org/dist/hadoop/common/ 2.上传压缩 3.修改配置文件 1)设置JDK的路径 cd /usr/local/software/hadoop-3.1.3/etc/hadoop vi hadoop-env.sh export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.402.b06-1.el7_9.x86_64/ 查看…

Zynq ultrascale+ 中断方式整理

摘要&#xff1a;目前一共整理三种中断&#xff0c;主要整理三种中断&#xff08;AXI_GPIO、EMIO、PL-PS_irq&#xff09;在PL和PS侧的使用 一、AXI_GPIO 这个IP可以用作单bit的输入和输出&#xff1b;也可以单独作为中断或者复位等使用&#xff1b; 使用AXI GPIO IP&#xff…

CSS案例-3.背景练习

效果1 用背景加入图标 效果2 将图片设为页面背景,图片主体在中间 效果3 鼠标放到导航栏上会变颜色 知识点 CSS背景 属性 描述 取值 background 复合属性 看独立属性 background-color 背景颜色 <color> background-image 背景图像 none | url background-repeat 背景…

分享几个适合大学生的副业兼职,大家可以根据自己的情况选择

有很多大学生想找一份兼职&#xff0c;既能打发时间&#xff0c;还能赚一些零花钱。一方面提升自己的生活质量&#xff0c;另一方面为家里减轻一些负担。同时也可以通过兼职来锻炼自己的能力&#xff0c;增加社会经验。今天跟大家分享几个适合大学生的副业兼职&#xff0c;大家…

fastjson反序列化-1.2.24漏洞利用与分析

0x01 利用条件 通过对fastjson基础知识的学习和反序列化流程的分析&#xff0c;发现它与我们之前学的常规的反序列化又不太一样。fastjson自己定义了一套反序列化规则&#xff0c;它不需要反序列化的类去继承Serializable接口&#xff0c;也不需要找readObject函数作为入口。相…

视觉SLAM理论到实践系列:补充——泊松公式证明

视觉SLAM理论到实践系列文章 下面是《视觉SLAM十四讲》学习笔记的系列记录的总链接&#xff0c;本人发表这个系列的文章链接均收录于此 视觉SLAM理论到实践系列文章链接 下面是专栏地址&#xff1a; 视觉SLAM理论到实践专栏 文章目录 视觉SLAM理论到实践系列文章视觉SLAM理论…

png格式怎么转成gif?一个小窍门快速转换

如何将png转换成gif动画&#xff1f;作为新媒体工作者&#xff0c;在日常办公中少不了使用到gif格式图片。那么&#xff0c;当我们遇到需要将png格式转换成gif格式的时候要怎么操作呢&#xff1f;很简单&#xff0c;使用gif动画图片&#xff08;https://www.gif.cn/&#xff09…

android studio的布局没有提示之SDK不匹配

我新建了一个项目&#xff0c;然后突然发现布局没有提示了&#xff1a; 我看了下我的build.gradle 我直接修改compileSdkVersion为30就能正常使用了

在微信小程序中或UniApp中自定义tabbar实现毛玻璃高斯模糊效果

backdrop-filter: blur(10px); 这一行代码表示将背景进行模糊处理&#xff0c;模糊程度为10像素。这会导致背景内容在这个元素后面呈现模糊效果。 background-color: rgb(255 255 255 / .32); 这一行代码表示设置元素的背景颜色为白色&#xff08;RGB值为0, 0, 0&#xff09;&a…

linux 基础总结

1、简述Raid0、raid1、aid5、Raid10的区别 RAID:redundant array of independent disks, 独立冗余磁盘阵列 磁盘阵列是由很多块独立的磁盘&#xff0c;组合成一个容量巨大的磁盘组&#xff0c;利用个别磁盘提供数据所产生加成效 果提升整个磁盘系统效能。利用这项技术&#x…

Scala--03--变量和数据类型

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 变量和数据类型1.注释2 变量和常量&#xff08;重点&#xff09;3 标识符的命名规范4 字符串输出5.IO 输入 输出键盘输入读写文件 IO 6.数据类型&#xff08;重点&a…

Alma Linux - Primavera P6 EPPM 安装及分享

引言 继上一期发布的Rocky Linux版环境发布之后&#xff0c;近日我又制作了基于Alma Enterprise Linux 的P6虚拟机环境&#xff0c;同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机&#xff0c;请先与Oracle Primaver…

选择电能表时电流规格是否越大越好

选择电能表时&#xff0c;电流规格是否越大越好是一个值得深入探讨的问题。实际上&#xff0c;这个问题的答案并不是绝对的&#xff0c;而是需要根据具体的使用场景和需求来进行权衡。下面&#xff0c;我将从多个方面对这一问题进行详细的分析和探讨。 一、电流规格与电能表的基…

达索的有限元分析软件Abaqus 2024版本下载与安装配置

目录 前言一、安装前准备二、Abaqus 安装总结 前言 Abaqus软件是一款广泛使用的有限元分析软件&#xff0c;可用于模拟各种工程应用程序&#xff0c;包括结构、流体力学、热传递、电磁和声学等。该软件提供了广泛的建模功能和多种求解器&#xff0c;可以帮助工程师预测材料和结…

面试笔记——Redis(缓存击穿、缓存雪崩)

缓存击穿 缓存击穿&#xff08;Cache Breakdown&#xff09;&#xff1a; 当某个缓存键的缓存失效时&#xff08;如&#xff0c;过期时间&#xff09;&#xff0c;同时有大量的请求到达&#xff0c;并且这些请求都需要获取相同的数据&#xff0c;这些请求会同时绕过缓存系统&a…

数据集笔记:METR-la 原始数据转input/ground truth

0 问题介绍 在交通预测/时间序列预测的论文中&#xff08;如论文笔记&#xff1a;Dual Dynamic Spatial-Temporal Graph ConvolutionNetwork for Traffic Prediction_dual dynamic spatial-temporal graph convolution ne-CSDN博客&#xff09; 模型输入的是过去12个时间片的…

掌握关键技巧!音频转换精灵如何使用?

在数字媒体时代&#xff0c;音频格式的转换已成为日常工作中不可或缺的一部分。为了满足这一需求&#xff0c;市场上涌现出众多音频转换工具。其中&#xff0c;音频转换精灵以其强大的功能和简便的操作赢得了广泛好评。本文将为你详细介绍如何使用该软件&#xff0c;让你轻松完…

Compose UI 之 Segmented buttons 分段按钮

Segmented buttons SegmentedButton 是一种分段式按钮组件,它允许用户在一组相关的选项中选择一个或几个。 上图中:① 单选的分段式按钮。② 多选的分段式按钮。 分段式按钮的几个特点: 分段式按钮是带有状态的按钮,又有单选和多选之分。 从设计上将,不论是单选或是多选…