DataEase-V1.18版本源码通过Docker镜像部署与静态资源通过阿里云OSS存储实现看这一篇就够了

news2025/2/23 12:14:44

修改DataEase实现静态资源阿里云OSS存储

后端源码文件读取配置类配置

1.阿里云OSS配置类
/**
 * ClassName AliyunConfig.java
 * author shuyixiao
 * version 1.0.0
 * Description 阿里云OSS配置
 * createTime 2024年04月03日 10:03:00
 */
@Data
@Configuration
public class AliyunConfig {

    // 地域节点
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;

    @Value("${aliyun.oss.bucketName}")
    private String bucketName;
    @Value("${aliyun.oss.urlPrefix}")
    private String urlPrefix;

}
2.图片文件上传base64转MultipartFile工具类
public class Base64DecodedMultipartFile implements MultipartFile {
    private final byte[] imgContent;
    private final String header;

    public Base64DecodedMultipartFile(byte[] imgContent, String header) {
        this.imgContent = imgContent;
        this.header = header;
    }
    @Override
    public String getName() {
        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1].split(";")[0];
    }

    @Override
    public String getOriginalFilename() {
        return getName();
    }

    @Override
    public String getContentType() {
        return header.split(":")[1].split(";")[0];
    }

    @Override
    public boolean isEmpty() {
        return imgContent == null || imgContent.length == 0;
    }

    @Override
    public long getSize() {
        return imgContent.length;
    }

    @Override
    public byte[] getBytes() {
        return imgContent;
    }

    @Override
    public InputStream getInputStream() {
        return new ByteArrayInputStream(imgContent);
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        try (FileOutputStream fos = new FileOutputStream(dest)) {
            fos.write(imgContent);
        }
    }

}
3.图片静态文件解析工具类
public class Base64DecodedStaticFile implements MultipartFile {
    private byte[] imgContent;

    public Base64DecodedStaticFile(byte[] imgContent) {
        this.imgContent = imgContent;
    }

    @Override
    public String getName() {
        return "filename";
    }

    @Override
    public String getOriginalFilename() {
        return "originalFilename.jpg";
    }

    @Override
    public String getContentType() {
        return "image/jpeg";
    }

    @Override
    public boolean isEmpty() {
        return imgContent == null || imgContent.length == 0;
    }

    @Override
    public long getSize() {
        return imgContent.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return imgContent;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(imgContent);
    }

    @Override
    public void transferTo(java.io.File dest) throws IOException, IllegalStateException {
        // 这里根据你的需求实现文件传输的逻辑
    }

}
4.阿里云oos响应配置类
@Getter
@Setter
public class PicUploadResult {
    private String uid;

    private String name;

    private String status;

    private String response;

    private String linkProps;

}
5.文件上传工具类
@Component
public class FileUtil {
    @Autowired
    private AliyunConfig aliyunConfig;


    // 允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg", ".jpeg", ".gif", ".png"};
    public PicUploadResult upload(MultipartFile multipartFile) {
        // 1. 对上传的图片进行校验: 这里简单校验后缀名
        // 另外可通过ImageIO读取图片的长宽来判断是否是图片,校验图片的大小等。
        // TODO 图片校验
        boolean isLegal = false;
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(multipartFile.getOriginalFilename(), type)) {
                isLegal = true;
                break;  // 只要与允许上传格式其中一个匹配就可以
            }
        }
        PicUploadResult picUploadResult = new PicUploadResult();
        // 格式错误, 返回与前端约定的error
        if (!isLegal) {
            picUploadResult.setStatus("error");
            return picUploadResult;
        }

        // 生成唯一的文件名
        String originalFileName = multipartFile.getOriginalFilename();
        String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
        String uniqueFileName = UUID.randomUUID().toString() + fileExtension; // 包含UUID的文件名


        // 3. 上传至阿里OSS
        try {
            // 初始化OSSClient
            OSS ossClient = new OSSClientBuilder().build(aliyunConfig.getEndpoint(), aliyunConfig.getAccessKeyId(), aliyunConfig.getAccessKeySecret());

            ossClient.putObject(aliyunConfig.getBucketName(), uniqueFileName, new ByteArrayInputStream(multipartFile.getBytes()));
        } catch (IOException e) {
            e.printStackTrace();
            // 上传失败
            picUploadResult.setStatus("error");
            return picUploadResult;
        }

        // 上传成功
        picUploadResult.setStatus("done");
        // 文件名(即直接访问的完整路径)
        picUploadResult.setName(aliyunConfig.getUrlPrefix() + uniqueFileName);
        // uid
        picUploadResult.setUid(String.valueOf(System.currentTimeMillis()));
        return picUploadResult;
    }

}
6.DataEase源码部分适配OSS修改
1.修改应用管理功能逻辑(PanelAppTemplateService类)
  • 注入文件上传工具类
@Autowired
private FileUtil fileUtil;
  • 修改原有代码逻辑
//Store static resource into the server
            // 缩略图处理
            String snapshotName = "app-template-" + request.getId() + ".jpeg";
            String base64Image = request.getSnapshot().split(",")[1];
            String imageType = request.getSnapshot().split(";")[0].split(":")[1];
            byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);
            MultipartFile multipartFile = new Base64DecodedMultipartFile(imageBytes, imageType);
            // 调用上传方法
            PicUploadResult uploadResult = fileUtil.upload(multipartFile);
            staticResourceService.saveSingleFileToServe(snapshotName, request.getSnapshot().replace("data:image/jpeg;base64,", "").replace("data:image/png;base64,", ""));
            requestTemplate.setSnapshot("/" + UPLOAD_URL_PREFIX + '/' + snapshotName);
//            requestTemplate.setSnapshot("/" + UPLOAD_URL_PREFIX + '/' + snapshotName);
            requestTemplate.setSnapshot(uploadResult.getName());
            // 静态资源小图处理
            Gson gson = new Gson();
            PanelGroupRequest panelGroupRequest = gson.fromJson(request.getPanelInfo(), PanelGroupRequest.class);
//            panelGroupRequest.setPanelData(JSON.toJSONString(jsonArray));
            Map<String, String> resource = gson.fromJson(panelGroupRequest.getStaticResource(), Map.class);
            Map<String, String> imageUrl = new HashMap<>();
            for (String s : resource.keySet()) {
                String imageCode = resource.get(s);
                byte[] bytes = DatatypeConverter.parseBase64Binary(imageCode);
                PicUploadResult picUploadResult = fileUtil.upload(new Base64DecodedStaticFile(bytes));
                imageUrl.put(s, picUploadResult.getName());
            }
            // 数据库缩略图存储处理
            String staticResource = panelGroupRequest.getStaticResource();
            Map<String,String> staticResourceMap= gson.fromJson(staticResource, Map.class);
            for (String s : staticResourceMap.keySet()) {
                String s1 = staticResourceMap.get(s);
                if (s.contains("static-resource")) {
                    // 找到匹配项,修改为阿里云oos存储地址
                    for (String string : imageUrl.keySet()) {
                        if (string.equals(s)){
                            staticResourceMap.remove(s);
                            staticResourceMap.put(imageUrl.get(s), s1);
                        }
                    }
                }
            }
            String panelData = panelGroupRequest.getPanelData();
            JSONArray jsonArray = JSON.parseArray(panelData);
            // 遍历数组,寻找特定的 propValue 值
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject obj = jsonArray.getJSONObject(i);
                if (obj.containsKey("propValue") && obj.getString("propValue").contains("/static-resource/")) {
                    // 找到匹配项,添加前缀
                    obj.put("propValue", imageUrl.get(obj.get("propValue")));
                }
            }
            panelGroupRequest.setPanelData(JSON.toJSONString(jsonArray));
            panelGroupRequest.setStaticResource(gson.toJson(staticResourceMap));
            requestTemplate.setPanelInfo(gson.toJson(panelGroupRequest));
2.修改模板管理功能逻辑(PanelTemplateService类)
  • 注入文件上传工具类
@Autowired
private FileUtil fileUtil;
  • 修改原有逻辑代码
//Store static resource into the server
                staticResourceService.saveFilesToServe(request.getStaticResource());
                // 缩略大图处理
                String snapshotName = "template-" + request.getId() + ".jpeg";
                String base64Image = request.getSnapshot().split(",")[1];
                String imageType = request.getSnapshot().split(";")[0].split(":")[1];
                byte[] imageBytes = javax.xml.bind.DatatypeConverter.parseBase64Binary(base64Image);
                MultipartFile multipartFile = new Base64DecodedMultipartFile(imageBytes, imageType);
                // 调用上传方法
                PicUploadResult uploadResult = fileUtil.upload(multipartFile);
                staticResourceService.saveSingleFileToServe(snapshotName, request.getSnapshot().replace("data:image/jpeg;base64,", "").replace("data:image/png;base64,", ""));
                request.setSnapshot("/" + UPLOAD_URL_PREFIX + '/' + snapshotName);
                // 文件中静态资源小图处理
                String staticResource = request.getStaticResource();
                Gson gson = new Gson();
                Map<String, String> resource = gson.fromJson(staticResource, Map.class);
                Map<String, String> imageCode = new HashMap<>();
                for (String s : resource.keySet()) {
                    String base64Picture = resource.get(s);
                    byte[] bytes = DatatypeConverter.parseBase64Binary(base64Picture);
                    PicUploadResult picUploadResult = fileUtil.upload(new Base64DecodedStaticFile(bytes));
                    imageCode.put(s, picUploadResult.getName());
                }
                String templateData = request.getTemplateData();
                JSONArray jsonArray = JSON.parseArray(templateData);
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject obj = jsonArray.getJSONObject(i);
                    if (obj.containsKey("propValue") && obj.getString("propValue").contains("/static-resource/")) {
                        // 找到匹配项,添加前缀
                        obj.put("propValue", imageCode.get(obj.get("propValue")));
                    }
                }
                request.setTemplateData(JSON.toJSONString(jsonArray));
//                request.setSnapshot("/" + UPLOAD_URL_PREFIX + '/' + snapshotName);
                request.setSnapshot(uploadResult.getName());

7.配置文件中添加阿里云OSS配置

阿里云oss配置

# 阿里云oss配置
# Aliyun OSS 配置
# 访问密钥ID,用于标识用户
aliyun.accessKeyId=xxxxxxxxxxxxxx
# 访问密钥密文,用于验证用户的身份
aliyun.accessKeySecret=xxxxxxxxxxxxxx
# OSS服务的访问域名
aliyun.oss.endpoint=xxxxxxxxxxxxxx
# OSS中的存储桶名称
aliyun.oss.bucketName=xxxxxxxxxxxxxx
#访问OSS服务的URL前缀
aliyun.oss.urlPrefix=xxxxxxxxxxxxxx

前端源码样式修改为自己喜欢的即可

前后端不分离单体部署

1.源码获取

GitHub地址
在这里插入图片描述
Gitee地址

在这里插入图片描述

2.配置源码信息
后端代码

注意事项:

注意V1.18代码的配置方式为JDK11版本
需要后端POM文件中有的资源依赖拉取不下来,可以链接:https://pan.baidu.com/s/1UYKk9R96B6dBUEqsRgjJhA 提取码:x8wr 这里获取然后直接替换即可
在这里插入图片描述
配置启动类配置处的配置文件信息,由于是在windows的环境中,下图是Linux中的文件写法,因此偷懒一些可以直接就是在windows的项目的根路径下建立相似的路径文件信息即可,详情见下图
在这里插入图片描述
在这里插入图片描述
配置配置文件中的数据库信息,数据库信息比较私密因此直接打马赛克了~
在这里插入图片描述

前端代码

注意事项:由于使用的是V1.18版本左右的前端代码,因此node版本不宜太高16.0.0左右即可。

查看前端项目的打包配置信息可以得到,运行需要的指令信息
在这里插入图片描述

3.Docker打包部署
首先在项目根文件夹下面添加数据库信息的配置文件

在这里插入图片描述

去除后端POM文件中移动端部分资源

在这里插入图片描述##### 修改前端POM文件中node和npm版本
在这里插入图片描述

分别打包前后端文件资源

在这里插入图片描述

执行Docker打包指令得到镜像文件
 # 这里我需要说明一下就是版本号随着DataEase官方版本给就可以,这里我写的时候使用1.18.15就写这个了
 docker build --build-arg IMAGE_TAG=1.18.15 -t your-image-name:tag .

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

运行镜像文件得到前端展示页面

在这里插入图片描述

附录一下打包和启动命令
docker build --build-arg IMAGE_TAG=1.18.15 -t core-backend-image-v1.18.15:1.18.15 .
docker run -d -p 8181:8181 core-backend-image-v1.18.15:1.18.15

前后端分离单体部署

后端代码
1.修改后端代码添加对应上下文

在这里插入图片描述##### 2.修改后端短链共享代码部分
在这里插入图片描述

3.pom文件中去除掉前端资源打包内容

在这里插入图片描述

4.执行Docker打包,步骤和上述前端后不分离单体部署命令一致不赘述了

前端代码修改

前端代码修改下面两处配置信息完成接口路径上下文配置

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

执行前端打包后放置与nginx服务器
# 打包命令:
npm run build

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Docker端口一直占用问题,docker重置(端口无法释放)(彻底重置docker环境)

文章目录 背景解决方法&#xff1a;彻底重置docker环境1. 停止所有Docker容器2. 删除所有容器3. 删除所有Docker镜像4. 删除所有Docker网络5. 删除所有Docker卷6. 清理Dangling资源7. 停止Docker服务8. 删除Docker数据和配置文件9. 重启Docker服务10. 验证 在这里插入图片描述验…

PostgreSQL入门到实战-第十四弹

PostgreSQL入门到实战 PostgreSQL数据过滤(七)官网地址PostgreSQL概述PostgreSQL中BETWEEN 命令理论PostgreSQL中BETWEEN 命令实战更新计划 PostgreSQL数据过滤(七) BETWEEN运算符允许您检查值是否在值的范围内。 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容…

“桃花庵主”是我国哪位古代名人的称号?2024年4月12日蚂蚁庄园今日答案

原文来源&#xff1a;蚂蚁庄园今日答案 - 词令 蚂蚁庄园是一款爱心公益游戏&#xff0c;用户可以通过喂养小鸡&#xff0c;产生鸡蛋&#xff0c;并通过捐赠鸡蛋参与公益项目。用户每日完成答题就可以领取鸡饲料&#xff0c;使用鸡饲料喂鸡之后&#xff0c;会可以获得鸡蛋&…

2024年腾讯云新用户云服务器价格表

腾讯云作为国内领先的云服务提供商&#xff0c;以其稳定可靠、灵活高效的服务赢得了广大用户的信赖。对于新用户而言&#xff0c;腾讯云提供了丰富的云服务器产品&#xff0c;并且制定了具有竞争力的价格策略&#xff0c;以吸引更多的新用户加入。 首先&#xff0c;我们来看一下…

【C++】STL--stackquene

这一节主要学习stack、quene和priority_quene的使用以及模拟实现&#xff0c;最后介绍了容器适配器。 目录 stack的介绍和使用 stack的介绍 stack的使用 stack的模拟实现 queue的介绍和使用 queue的介绍 queue的使用 queue的模拟实现 priority_queue的介绍和使用 pri…

Spring Boot与Vue联手打造智能化学生选课平台

末尾获取源码作者介绍&#xff1a;大厂全栈码农|毕设实战开发&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。 更多项目&#xff1a;CSDN主页YAML墨韵 学如逆水行舟&#xff0c;不进则退。学习如赶路&#xff0c;不能慢一步。 目录 一、项目简介 二、开发技术与…

嵌入式工程师需要掌握哪些技术?

嵌入式系统是当今科技领域中的重要组成部分&#xff0c;它们存在于我们生活的方方面面&#xff0c;从智能手机到汽车控制系统&#xff0c;从家电到医疗设备。因此&#xff0c;对于那些想要进入嵌入式行业的人来说&#xff0c;掌握一些必要的技术能力是至关重要的。在本篇中&…

springboot 反射调用ServiceImpl时报错:java.lang.NullPointerExceptio、,mapper为null【解决方法】

springboot 反射调用ServiceImpl时报错&#xff1a;java.lang.NullPointerException、mapper为null【解决方法】 问题描述问题分析解决方案创建SpringBootBeanUtil编写调用方法 executeMethod调用 总结 问题描述 在使用Spring Boot时&#xff0c;我们希望能够通过反射动态调用…

Win11又来「重大」更新!

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站ai人工智能工具 更多资源欢迎关注 Windows 11预览通道的22635.3420版本迎来了几个比较大的改进&#xff0c;主要有三个方面&#xff1a; …

Springboot 大事务问题的常用优化方案

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 1.前言 2.什么是大事务 3.解决办法 3.1.少用Transactional注解 3.2..将查询…

医疗图像分割 | 基于Pyramid-Vision-Transformer算法实现医疗息肉分割

项目应用场景 面向医疗图像息肉分割场景&#xff0c;项目采用 Pytorch Pyramid-Vision-Transformer 深度学习算法来实现。 项目效果 项目细节 > 具体参见项目 README.md (1) 模型架构 (2) 项目依赖&#xff0c;包括 python 3.8、pytorch 1.7.1、torchvision 0.8.2(3) 下载…

【实战】ZLMediaKit问题解决

项目中遇到的问题 1.不带音频的rtsp转rtmp后,出现了音频 1.1判断元素rtsp是否有音频的方法 使用vlc进行访问rtsp流,看如图位置: 音频 -> 音轨 ,是否为灰色,为灰色就是不带音频 1.2 解决方法 在zlmediakit的web页面进行全局配置修改如图, 1.将3和4处修改为 否,再保存, …

网络协议——RSTP(快速生成树)与MSTP(多实例生成树)

一. RSTP 1. STP的不足 1、依靠计时器超时的方式进行收敛导致它的收敛时间需要30到50秒 2、端口状态和端口角色没有细致区分&#xff0c;指导数据转发依靠的不是端口状态而是端口所扮演角色。 3、如果拓扑频繁变化导致用户通信质量差&#xff0c;甚至通信中断&#xf…

MyBatis中的动态SQL的用法

前言&#xff1a;我们要想在Spring Boot环境下使用动态SQL&#xff0c;必须先在application.yml中添加配置 mybatis:mapper-locations: classpath:mapper/**Mapper.xml 并且新建一个xml文件&#xff0c;路径及写法按照配置好的形式写 在新建好的xml文件中复制进去以下代码&a…

Golang——方法

一. 方法定义 Golang方法总是绑定对象的实例&#xff0c;并隐式将实例作为第一实参。 只能为当前包内命名类型定义方法参数receiver可以任意命名。如方法中未曾使用&#xff0c;可省略参数名参数receiver类型可以是T或*T。基类型T不能是接口或指针类型(即多级指针)不支持方法重…

【JAVASE】抽象类和接口及其抽象类和接口的区别

✅作者简介&#xff1a;大家好&#xff0c;我是橘橙黄又青&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;再无B&#xff5e;U&#xff5e;G-CSDN博客 目标&#xff1a; 1. 抽象类 2. 接口 3. Object 类 1. &am…

性能测试--数据库慢 SQL 语句分析

一 慢 SQL 语句的几种常见诱因 1. 无索引或索引失效 ​ 当查询基于一个没有索引的列进行过滤、排序或连接时&#xff0c;数据库可能被迫进行全表扫描&#xff0c;即逐行检查所有数据&#xff0c;导致性能显著下降。 ​ 虽然我们很多时候建立了索引&#xff0c;但在一些特定的…

第3章 存储系统(2)

3.3 主存储器与CPU连接 3.3.1 连接原理 现代计算机的MAR和MDR都在CPU内部。 (1)主存储器通过数据总线,地址总线,控制总线与CPU连接。 (2)数据传输率数据总线宽度*总线频率。 (4)控制总线(读写线)控制读写操作。 3.3.2 主存的扩展 数据总线宽度等于存储字长 1.位扩展法【增加…

【软件测试】个人博客系统测试

个人博客系统测试 一、项目背景1.1 技术背景1.2 功能背景 二、自动化测试2.1 什么是自动化测试2.2 通过使用selenium进行自动化测试的编写&#xff08;Java实现&#xff09;2.3 编写测试用例&#xff0c;执行自动化测试2.3.1 输入用户名:test,密码:123&#xff0c;登录成功2.3.…

Java | Leetcode Java题解之第20题有效的括号

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isValid(String s) {int n s.length();if (n % 2 1) {return false;}Map<Character, Character> pairs new HashMap<Character, Character>() {{put(), ();put(], [);put(}, {);}};Deque<…