Procházet zdrojové kódy

feat(zhaozhaonews): 新增基础服务和Feign接口模块 - basic(MinIO文件存储starter) - feign-api(文章/文件/用户/自媒体Feign客户端接口)

WanJL před 3 týdny
rodič
revize
253aa0194f

+ 22 - 0
zhaozhaonews/zhaozhaonews-basic/pom.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>zhaozhaonews</artifactId>
+        <groupId>com.zhaozhaonews</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modules>
+        <module>zhaozhaonews-file-starter</module>
+    </modules>
+
+    <artifactId>zhaozhaonews-basic</artifactId>
+    <packaging>pom</packaging>
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+</project>

+ 42 - 0
zhaozhaonews/zhaozhaonews-basic/zhaozhaonews-file-starter/pom.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>zhaozhaonews-basic</artifactId>
+        <groupId>com.zhaozhaonews</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>zhaozhaonews-file-starter</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>7.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 36 - 0
zhaozhaonews/zhaozhaonews-basic/zhaozhaonews-file-starter/src/main/java/com/zhaozhaonews/file/config/MinIOConfig.java

@@ -0,0 +1,36 @@
+package com.zhaozhaonews.file.config;
+
+import com.zhaozhaonews.file.service.FileStorageService;
+import io.minio.MinioClient;
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title MinIOConfig
+ * @description
+ */
+@Data
+@Configuration
+@EnableConfigurationProperties({MinIOConfigProperties.class})
+//当引入FileStorageService接口时
+@ConditionalOnClass(FileStorageService.class)
+public class MinIOConfig {
+
+    @Autowired
+    private MinIOConfigProperties minIOConfigProperties;
+
+    @Bean
+    public MinioClient buildMinioClient(){
+        return MinioClient
+                .builder()
+                .credentials(minIOConfigProperties.getAccessKey(), minIOConfigProperties.getSecretKey())
+                .endpoint(minIOConfigProperties.getEndpoint())
+                .build();
+    }
+}

+ 23 - 0
zhaozhaonews/zhaozhaonews-basic/zhaozhaonews-file-starter/src/main/java/com/zhaozhaonews/file/config/MinIOConfigProperties.java

@@ -0,0 +1,23 @@
+package com.zhaozhaonews.file.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.io.Serializable;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title MinIOConfigProperties
+ * @description
+ */
+@Data
+@ConfigurationProperties(prefix = "minio")  // 文件上传 配置前缀file.oss
+public class MinIOConfigProperties implements Serializable {
+
+    private String accessKey;   //用户名
+    private String secretKey;   //密码
+    private String bucket;      //存储的桶,zhaozhaonews
+    private String endpoint;    //上传路径
+    private String readPath;    //读取的路径
+}

+ 46 - 0
zhaozhaonews/zhaozhaonews-basic/zhaozhaonews-file-starter/src/main/java/com/zhaozhaonews/file/service/FileStorageService.java

@@ -0,0 +1,46 @@
+package com.zhaozhaonews.file.service;
+
+import java.io.InputStream;
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title FileStorageService
+ * @description
+ */
+
+public interface FileStorageService {
+
+
+    /**
+     *  上传图片文件
+     * @param prefix  文件前缀
+     * @param filename  文件名
+     * @param inputStream 文件流
+     * @return  文件全路径
+     */
+    public String uploadImgFile(String prefix, String filename,InputStream inputStream);
+
+    /**
+     *  上传html文件
+     * @param prefix  文件前缀
+     * @param filename   文件名
+     * @param inputStream  文件流
+     * @return  文件全路径
+     */
+    public String uploadHtmlFile(String prefix, String filename,InputStream inputStream);
+
+    /**
+     * 删除文件
+     * @param pathUrl  文件全路径
+     */
+    public void delete(String pathUrl);
+
+    /**
+     * 下载文件
+     * @param pathUrl  文件全路径
+     * @return
+     *
+     */
+    public byte[]  downLoadFile(String pathUrl);
+
+}

+ 166 - 0
zhaozhaonews/zhaozhaonews-basic/zhaozhaonews-file-starter/src/main/java/com/zhaozhaonews/file/service/MinIOFileStorageService.java

@@ -0,0 +1,166 @@
+package com.zhaozhaonews.file.service;
+
+import com.zhaozhaonews.file.config.MinIOConfig;
+import com.zhaozhaonews.file.config.MinIOConfigProperties;
+import io.minio.GetObjectArgs;
+import io.minio.MinioClient;
+import io.minio.PutObjectArgs;
+import io.minio.RemoveObjectArgs;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Import;
+import org.springframework.util.StringUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 这个服务类是专门用来将文件上传到MinIO的
+ * 对MinIO的文件进行管理
+ */
+@Slf4j
+@EnableConfigurationProperties(MinIOConfigProperties.class)
+@Import(MinIOConfig.class)
+public class MinIOFileStorageService implements FileStorageService {
+
+    @Autowired
+    private MinioClient minioClient;
+
+    @Autowired
+    private MinIOConfigProperties minIOConfigProperties;
+
+    private final static String separator = "/";
+
+    /**
+     * @param dirPath
+     * @param filename  yyyy/mm/dd/file.jpg
+     * @return
+     */
+    public String builderFilePath(String dirPath,String filename) {
+        StringBuilder stringBuilder = new StringBuilder(50);
+        if(!StringUtils.isEmpty(dirPath)){
+            stringBuilder.append(dirPath).append(separator);
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
+        String todayStr = sdf.format(new Date());
+        stringBuilder.append(todayStr).append(separator);
+        stringBuilder.append(filename);
+        return stringBuilder.toString();
+    }
+
+    /**
+     *  上传图片文件
+     * @param prefix  文件前缀
+     * @param filename  文件名
+     * @param inputStream 文件流
+     * @return  文件全路径
+     */
+    @Override
+    public String uploadImgFile(String prefix, String filename, InputStream inputStream) {
+        String filePath = builderFilePath(prefix, filename);
+        try {
+            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
+                    .object(filePath)
+                    .contentType("image/jpg")
+                    .bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1)
+                    .build();
+            minioClient.putObject(putObjectArgs);
+            StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
+            urlPath.append(separator+minIOConfigProperties.getBucket());
+            urlPath.append(separator);
+            urlPath.append(filePath);
+            return urlPath.toString();
+        }catch (Exception ex){
+            log.error("minio put file error.",ex);
+            throw new RuntimeException("上传文件失败");
+        }
+    }
+
+    /**
+     *  上传html文件
+     * @param prefix  文件前缀
+     * @param filename   文件名
+     * @param inputStream  文件流
+     * @return  文件全路径
+     */
+    @Override
+    public String uploadHtmlFile(String prefix, String filename,InputStream inputStream) {
+        String filePath = builderFilePath(prefix, filename);
+        try {
+            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
+                    .object(filePath)
+                    .contentType("text/html")
+                    .bucket(minIOConfigProperties.getBucket()).stream(inputStream,inputStream.available(),-1)
+                    .build();
+            minioClient.putObject(putObjectArgs);
+            StringBuilder urlPath = new StringBuilder(minIOConfigProperties.getReadPath());
+            urlPath.append(separator+minIOConfigProperties.getBucket());
+            urlPath.append(separator);
+            urlPath.append(filePath);
+            return urlPath.toString();
+        }catch (Exception ex){
+            log.error("minio put file error.",ex);
+            ex.printStackTrace();
+            throw new RuntimeException("上传文件失败");
+        }
+    }
+
+    /**
+     * 删除文件
+     * @param pathUrl  文件全路径
+     */
+    @Override
+    public void delete(String pathUrl) {
+        String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/","");
+        int index = key.indexOf(separator);
+        String bucket = key.substring(0,index);
+        String filePath = key.substring(index+1);
+        // 删除Objects
+        RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
+        try {
+            minioClient.removeObject(removeObjectArgs);
+        } catch (Exception e) {
+            log.error("minio remove file error.  pathUrl:{}",pathUrl);
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * 下载文件
+     * @param pathUrl  文件全路径
+     * @return  文件流
+     *
+     */
+    @Override
+    public byte[] downLoadFile(String pathUrl)  {
+        String key = pathUrl.replace(minIOConfigProperties.getEndpoint()+"/","");
+        int index = key.indexOf(separator);
+        String bucket = key.substring(0,index);
+        String filePath = key.substring(index+1);
+        InputStream inputStream = null;
+        try {
+            inputStream = minioClient.getObject(GetObjectArgs.builder().bucket(minIOConfigProperties.getBucket()).object(filePath).build());
+        } catch (Exception e) {
+            log.error("minio down file error.  pathUrl:{}",pathUrl);
+            e.printStackTrace();
+        }
+
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        byte[] buff = new byte[100];
+        int rc = 0;
+        while (true) {
+            try {
+                if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            byteArrayOutputStream.write(buff, 0, rc);
+        }
+        return byteArrayOutputStream.toByteArray();
+    }
+}

+ 2 - 0
zhaozhaonews/zhaozhaonews-basic/zhaozhaonews-file-starter/src/main/resources/META-INF/spring.factories

@@ -0,0 +1,2 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+  com.zhaozhaonews.file.service.MinIOFileStorageService

+ 33 - 0
zhaozhaonews/zhaozhaonews-feign-api/pom.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.zhaozhaonews</groupId>
+        <artifactId>zhaozhaonews</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>zhaozhaonews-feign-api</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.zhaozhaonews</groupId>
+            <artifactId>zhaozhaonews-model</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.zhaozhaonews</groupId>
+            <artifactId>zhaozhaonews-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+    </dependencies>
+</project>

+ 33 - 0
zhaozhaonews/zhaozhaonews-feign-api/src/main/java/com/zhaozhaonews/apis/article/IArticleClient.java

@@ -0,0 +1,33 @@
+package com.zhaozhaonews.apis.article;
+
+import com.zhaozhaonews.model.article.dtos.ArticleDto;
+import com.zhaozhaonews.model.common.dto.ResponseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+/**
+ * 文章服务Feign远程调用接口(Article Service Feign Client)
+ *
+ * 本接口定义了与文章微服务(zhaozhaonews-article)进行远程通信的Feign客户端。
+ * 通过Spring Cloud OpenFeign实现声明式HTTP调用,用于在微服务之间同步文章数据。
+ *
+ * @author WanJl
+ * @version 1.0
+ * @title IArticleClient
+ * @description 文章服务远程调用接口
+ */
+@FeignClient("zhaozhaonews-article")  // 指定目标服务名称(注册中心的服务ID)
+public interface IArticleClient {
+
+    /**
+     * 保存文章信息
+     *
+     * 将文章数据(包括标题、内容、封面等)远程调用到文章微服务进行持久化保存。
+     *
+     * @param dto 文章数据传输对象,包含文章的标题、内容、分类、封面图等信息
+     * @return ResponseResult 响应结果,包含操作状态码、提示信息和数据
+     */
+    @PostMapping("/api/v1/article/save")
+    ResponseResult saveArticle(@RequestBody ArticleDto dto);
+}

+ 33 - 0
zhaozhaonews/zhaozhaonews-feign-api/src/main/java/com/zhaozhaonews/apis/file/IFileClient.java

@@ -0,0 +1,33 @@
+package com.zhaozhaonews.apis.file;
+
+import com.zhaozhaonews.model.common.dto.ResponseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件上传Feign远程调用接口(File Upload Feign Client)
+ *
+ * 本接口定义了文件上传的Feign客户端。
+ * 文件上传功能由自媒体微服务(zhaozhaonews-wemedia)提供。
+ *
+ * @author WanJl
+ * @version 1.0
+ * @title IFileClient
+ * @description 文件上传远程调用接口
+ */
+@FeignClient("zhaozhaonews-wemedia")  // 文件上传由自媒体服务提供
+public interface IFileClient {
+
+    /**
+     * 上传图片文件
+     *
+     * 将图片以multipart/form-data格式上传,返回文件的访问路径。
+     *
+     * @param file 待上传的图片文件
+     * @return ResponseResult 响应结果,包含文件访问路径
+     */
+    @PostMapping(value = "/api/v1/material/upload_picture", consumes = "multipart/form-data")
+    ResponseResult upload(@RequestParam("multipartFile") MultipartFile multipartFile);
+}

+ 32 - 0
zhaozhaonews/zhaozhaonews-feign-api/src/main/java/com/zhaozhaonews/apis/user/IUserClient.java

@@ -0,0 +1,32 @@
+package com.zhaozhaonews.apis.user;
+
+import com.zhaozhaonews.model.common.dto.ResponseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+
+/**
+ * 用户服务Feign远程调用接口(User Service Feign Client)
+ *
+ * 本接口定义了与用户微服务(zhaozhaonews-user)进行远程通信的Feign客户端。
+ * 用于在微服务之间查询用户信息,支持根据用户ID获取用户详情。
+ *
+ * @author WanJl
+ * @version 1.0
+ * @title IUserClient
+ * @description 用户服务远程调用接口
+ */
+@FeignClient("zhaozhaonews-user")  // 指定目标服务名称(注册中心的服务ID)
+public interface IUserClient {
+
+    /**
+     * 根据用户ID获取用户信息
+     *
+     * 远程调用用户微服务,根据传入的用户ID查询用户的详细信息。
+     *
+     * @param id 用户唯一标识
+     * @return ResponseResult 响应结果,包含用户详细信息数据
+     */
+    @GetMapping("/api/v1/user/{id}")
+    ResponseResult getUserById(@PathVariable("id") Long id);
+}

+ 30 - 0
zhaozhaonews/zhaozhaonews-feign-api/src/main/java/com/zhaozhaonews/apis/wemedia/IWemediaClient.java

@@ -0,0 +1,30 @@
+package com.zhaozhaonews.apis.wemedia;
+
+import com.zhaozhaonews.model.common.dto.ResponseResult;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * 自媒体服务Feign远程调用接口(Wemedia Service Feign Client)
+ *
+ * 本接口定义了与自媒体微服务(zhaozhaonews-wemedia)进行远程通信的Feign客户端。
+ * 用于在微服务之间获取自媒体相关的配置信息,如文章频道列表等。
+ *
+ * @author WanJl
+ * @version 1.0
+ * @title IWemediaClient
+ * @description 自媒体服务远程调用接口
+ */
+@FeignClient("zhaozhaonews-wemedia")  // 指定目标服务名称(注册中心的服务ID)
+public interface IWemediaClient {
+
+    /**
+     * 获取频道列表
+     *
+     * 远程调用自媒体微服务,获取所有可用的文章频道/分类列表。
+     *
+     * @return ResponseResult 响应结果,包含频道列表数据
+     */
+    @GetMapping("/api/v1/channel/channels")
+    ResponseResult getChannels();
+}