问题修改
This commit is contained in:
parent
93747055f2
commit
f58368f3c8
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?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.bonus</groupId>
|
||||||
|
<artifactId>bonus-modules</artifactId>
|
||||||
|
<version>24.12.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.bonus.czl</groupId>
|
||||||
|
<artifactId>bonus-czl</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!--加密依赖包-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ulisesbocchio</groupId>
|
||||||
|
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||||
|
<version>${jasypt-spring-boot-starter.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>-->
|
||||||
|
|
||||||
|
<!-- Mysql Connector -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version> <!-- 建议使用最新稳定版 -->
|
||||||
|
<scope>runtime</scope> <!-- 通常只需运行时依赖 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common DataSource -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-datasource</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common DataScope -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-datascope</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common Log -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-log</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>30.0-jre</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
<version>2.1.1.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<!-- <version>6.0.18</version>-->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.bonus.czl;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 承载力模块
|
||||||
|
*
|
||||||
|
* @author bonus
|
||||||
|
*/
|
||||||
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class})
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
public class BonusCzlApplication
|
||||||
|
{
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
SpringApplication.run(BonusCzlApplication.class, args);
|
||||||
|
System.out.println("(♥◠‿◠)ノ゙ 承载力模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||||
|
" .-------. ____ __ \n" +
|
||||||
|
" | _ _ \\ \\ \\ / / \n" +
|
||||||
|
" | ( ' ) | \\ _. / ' \n" +
|
||||||
|
" |(_ o _) / _( )_ .' \n" +
|
||||||
|
" | (_,_).' __ ___(_ o _)' \n" +
|
||||||
|
" | |\\ \\ | || |(_,_)' \n" +
|
||||||
|
" | | \\ `' /| `-' / \n" +
|
||||||
|
" | | \\ / \\ / \n" +
|
||||||
|
" ''-' `'-' `-..-' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Spring Boot Version: ${spring-boot.version}
|
||||||
|
Spring Application Name: ${spring.application.name}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 18086
|
||||||
|
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 192.168.87.190:8848
|
||||||
|
namespace: e9abf140-675a-4d55-af3f-1f28a6186904
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 192.168.87.190:8848
|
||||||
|
namespace: e9abf140-675a-4d55-af3f-1f28a6186904
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: bonus-czl
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
|
||||||
|
#加密组件
|
||||||
|
jasypt:
|
||||||
|
encryptor:
|
||||||
|
password: Encrypt
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
<!-- 日志存放路径 -->
|
||||||
|
<property name="log.path" value="logs/bonus-czl" />
|
||||||
|
<!-- 日志输出格式 -->
|
||||||
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.bonus" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
|
|
@ -57,12 +57,6 @@
|
||||||
<artifactId>bonus-api-system</artifactId>
|
<artifactId>bonus-api-system</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- bonus Common Swagger -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.bonus</groupId>
|
|
||||||
<artifactId>bonus-common-swagger</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-net</groupId>
|
<groupId>commons-net</groupId>
|
||||||
<artifactId>commons-net</artifactId>
|
<artifactId>commons-net</artifactId>
|
||||||
|
|
@ -109,6 +103,10 @@
|
||||||
<artifactId>jasypt-spring-boot-starter</artifactId>
|
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||||
<version>${jasypt-spring-boot-starter.version}</version>
|
<version>${jasypt-spring-boot-starter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@ package com.bonus.file;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件服务
|
* 文件服务
|
||||||
*
|
*
|
||||||
* @author bonus
|
* @author bonus
|
||||||
*/
|
*/
|
||||||
@EnableCustomSwagger2
|
|
||||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
|
||||||
|
@EnableDiscoveryClient
|
||||||
public class BonusFileApplication
|
public class BonusFileApplication
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import com.bonus.file.service.ISysFileService;
|
||||||
import com.bonus.system.api.domain.SysFile;
|
import com.bonus.system.api.domain.SysFile;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
@ -29,142 +30,8 @@ import java.net.URLDecoder;
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@Api("服务文件存储")
|
@Api("服务文件存储")
|
||||||
|
@Slf4j
|
||||||
public class SysFileController
|
public class SysFileController
|
||||||
{
|
{
|
||||||
private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
|
|
||||||
|
|
||||||
private final ISysFileService sysFileService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public SysFileController(ISysFileService fileService) {
|
|
||||||
this.sysFileService = fileService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 单文件上传
|
|
||||||
* @param file 单个文件
|
|
||||||
* @return 文件信息,包括文件名和文件路径
|
|
||||||
*/
|
|
||||||
@PostMapping("upload")
|
|
||||||
@ApiOperation("上传本地文件到服务器")
|
|
||||||
public AjaxResult upload(MultipartFile file)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// 上传并返回访问地址
|
|
||||||
if (ObjectUtil.isEmpty(file)) { return AjaxResult.error("上传文件不能为空");}
|
|
||||||
SysFile sysFile = sysFileService.uploadFile(file);
|
|
||||||
return AjaxResult.success(sysFile);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
log.error("上传文件失败", e);
|
|
||||||
return AjaxResult.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多文件上传
|
|
||||||
* @param files 多个文件流
|
|
||||||
* @return 文件信息
|
|
||||||
*/
|
|
||||||
@PostMapping("/uploadFiles")
|
|
||||||
public AjaxResult uploadFile(MultipartFile[] files) {
|
|
||||||
try {
|
|
||||||
if (ObjectUtil.isEmpty(files)) { return AjaxResult.error("上传文件不能为空");}
|
|
||||||
return AjaxResult.success(sysFileService.uploadFiles(files));
|
|
||||||
} catch (Exception e)
|
|
||||||
{
|
|
||||||
return AjaxResult.error(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件下载
|
|
||||||
* @param response 请求响应
|
|
||||||
* @param objectKey,除mongodb 存fileid之外,其他均存上传文件的网络路径
|
|
||||||
*/
|
|
||||||
@GetMapping("/download")
|
|
||||||
public void downloadFile(HttpServletResponse response, @RequestParam String objectKey) throws IOException {
|
|
||||||
try {
|
|
||||||
String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
|
|
||||||
sysFileService.downloadFile(response, fileUrl);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("downloadFile error:{}", e.getMessage());
|
|
||||||
response.setStatus(HttpStatus.ERROR);
|
|
||||||
// 设置响应的 Content-Type 为文本
|
|
||||||
response.setContentType("application/json;charset=UTF-8");
|
|
||||||
// 将错误信息写入响应体
|
|
||||||
PrintWriter writer = response.getWriter();
|
|
||||||
writer.write("{\"error\": \"File download failed: " + e.getMessage() + "\"}");
|
|
||||||
writer.flush();
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件删除
|
|
||||||
* 从各个存储平台删除文件
|
|
||||||
* @param objectKey * @param objectKey,除mongodb 存fileid之外,其他均存上传文件的网络路径
|
|
||||||
*/
|
|
||||||
@PostMapping("/deleteFile")
|
|
||||||
public AjaxResult deleteFile(@RequestParam("objectKey") String objectKey) {
|
|
||||||
try {
|
|
||||||
String fileUrl = Base64Utils.decodeUrl(URLDecoder.decode(objectKey));
|
|
||||||
sysFileService.deleteFile(fileUrl);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return AjaxResult.error(e.getMessage());
|
|
||||||
}
|
|
||||||
return AjaxResult.success("删除文件成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 单文件上传到指定文件夹
|
|
||||||
* @param file 单个文件
|
|
||||||
* @return 文件信息,包括文件名和文件路径
|
|
||||||
*/
|
|
||||||
@PostMapping("uploadToFolder")
|
|
||||||
@ApiOperation("上传本地文件到服务器")
|
|
||||||
public AjaxResult upload(MultipartFile file, String folderName)
|
|
||||||
{
|
|
||||||
return AjaxResult.success("单文件上传成功");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建文件夹
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
* @return 文件夹网络路径
|
|
||||||
*/
|
|
||||||
@PostMapping("/createFolder")
|
|
||||||
@ApiOperation("创建文件夹")
|
|
||||||
public AjaxResult createFolder(@RequestParam("folderName") String folderPath)
|
|
||||||
{
|
|
||||||
sysFileService.createFolder(folderPath);
|
|
||||||
return AjaxResult.success("创建文件夹");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* list 指定目录下所有文件信息(文件名,文件大小,上传时间,是否目录),包括子文件夹
|
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
|
||||||
* @return 文件夹网络路径
|
|
||||||
*/
|
|
||||||
@GetMapping("/listFiles")
|
|
||||||
public AjaxResult listFiles(@RequestParam("folderName") String folderPath) {
|
|
||||||
return AjaxResult.success(sysFileService.getFilesAndSubfolders(folderPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件夹删除
|
|
||||||
* 从各个存储平台删除文件
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
* @return 文件夹网络路径
|
|
||||||
*/
|
|
||||||
@PostMapping("/deleteFolder")
|
|
||||||
public AjaxResult deleteFolder(@RequestParam("folderName") String folderPath) {
|
|
||||||
sysFileService.deleteFolder(folderPath);
|
|
||||||
return AjaxResult.success("文件夹删除成功");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,181 +0,0 @@
|
||||||
package com.bonus.file.service.impl;
|
|
||||||
|
|
||||||
import com.bonus.common.core.utils.file.FileTypeUtils;
|
|
||||||
import com.bonus.common.core.utils.file.MimeTypeUtils;
|
|
||||||
import com.bonus.file.entity.FileDetails;
|
|
||||||
import com.bonus.file.service.ISysFileService;
|
|
||||||
import com.bonus.file.utils.FileUploadUtils;
|
|
||||||
import com.bonus.system.api.domain.SysFile;
|
|
||||||
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
|
|
||||||
import com.github.tobato.fastdfs.service.FastFileStorageClient;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FastDFS 文件存储
|
|
||||||
*
|
|
||||||
* @author bonus
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@ConditionalOnProperty(name = "storage.type", havingValue = "fdfs")
|
|
||||||
public class FastDfsSysFileServiceImpl implements ISysFileService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 域名或本机访问地址
|
|
||||||
*/
|
|
||||||
@Value("${fdfs.domain}")
|
|
||||||
public String domain;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FastFileStorageClient storageClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FastDfs文件上传接口
|
|
||||||
*
|
|
||||||
* @param file 上传的文件
|
|
||||||
* @return 访问地址
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public SysFile uploadFile(MultipartFile file) throws Exception
|
|
||||||
{
|
|
||||||
//验证文件扩展名是否合法
|
|
||||||
FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
|
||||||
|
|
||||||
String fileName = FileUploadUtils.extractFilename(file);
|
|
||||||
InputStream inputStream = file.getInputStream();
|
|
||||||
StorePath storePath = storageClient.uploadFile(inputStream, file.getSize(),
|
|
||||||
FileTypeUtils.getExtension(file), null);
|
|
||||||
IoUtils.closeQuietly(inputStream);
|
|
||||||
return SysFile.builder().url(domain + "/" + storePath.getFullPath()).name(fileName).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SysFile> uploadFiles(MultipartFile[] files) throws Exception {
|
|
||||||
List<SysFile> sysFiles = new ArrayList<>();
|
|
||||||
for (MultipartFile file : files) {
|
|
||||||
SysFile sysFile = uploadFile(file);
|
|
||||||
sysFiles.add(sysFile);
|
|
||||||
}
|
|
||||||
return sysFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FastDfs文件下载接口,待测试
|
|
||||||
*
|
|
||||||
* @param response 响应对象
|
|
||||||
* @param urlStr 文件URL地址
|
|
||||||
* @return 是否下载成功
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFile(HttpServletResponse response, String urlStr) throws Exception
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
String path = urlStr.replace(domain + "/", "");
|
|
||||||
StorePath storePath = StorePath.parseFromUrl(path);
|
|
||||||
|
|
||||||
// 下载文件并返回输入流
|
|
||||||
byte[] fileData = storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), IOUtils::toByteArray);
|
|
||||||
|
|
||||||
// 设置响应头
|
|
||||||
String encodedFileName = URLEncoder.encode(storePath.getPath(), StandardCharsets.UTF_8.toString());
|
|
||||||
response.setContentType("application/octet-stream");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + storePath.getPath() + "\"");
|
|
||||||
|
|
||||||
// 将文件内容写入响应
|
|
||||||
IOUtils.write(fileData, response.getOutputStream());
|
|
||||||
response.flushBuffer();
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Error occurred while downloading file from FastDfs" + urlStr, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从给定的URL下载文件并将其保存到指定的目标位置。
|
|
||||||
*
|
|
||||||
* @param response 请求响应。
|
|
||||||
* @param urlStr 要下载文件的URL地址。
|
|
||||||
* @throws Exception 如果在下载过程中遇到任何异常,例如网络问题、文件写入问题等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFilesAsZip(HttpServletResponse response, List<String> urlStr) throws Exception {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FastDfs文件删除接口,待测试
|
|
||||||
*
|
|
||||||
* @param urlStr 文件URL地址
|
|
||||||
* @return 是否删除成功
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String urlStr) throws Exception
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
// 从 URL 中提取文件路径
|
|
||||||
String path = urlStr.replace(domain + "/", "");
|
|
||||||
StorePath storePath = StorePath.parseFromUrl(path);
|
|
||||||
|
|
||||||
// 删除文件
|
|
||||||
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("Error occurred while deleting file from FastDfs" + urlStr, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定URL所指向的文件。
|
|
||||||
*
|
|
||||||
* @param urlStr 要删除文件的URL地址。
|
|
||||||
* @return 布尔值,指示文件删除是否成功。如果文件被成功删除,则返回true;否则返回false。
|
|
||||||
* @throws Exception 如果在删除文件的过程中遇到错误,例如网络问题、文件不存在或没有删除权限等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFiles(List<String> urlStr) throws Exception {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定文件夹下的所有文件夹和文件。
|
|
||||||
*
|
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
|
||||||
* @return 返回一个包含所有文件夹和文件路径的集合
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<FileDetails> getFilesAndSubfolders(String folderPath) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建文件夹(通过上传带有路径的文件)
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void createFolder(String folderPath) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定路径的所有对象,从而删除“文件夹”。
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFolder(String folderPath) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
package com.bonus.file.service.impl;
|
|
||||||
|
|
||||||
import com.bonus.file.entity.FileDetails;
|
|
||||||
import com.bonus.file.service.ISysFileService;
|
|
||||||
import com.bonus.file.utils.FileDownloadUtils;
|
|
||||||
import com.bonus.file.utils.FileUploadUtils;
|
|
||||||
import com.bonus.system.api.domain.SysFile;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地文件存储
|
|
||||||
*
|
|
||||||
* @author bonus
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@ConditionalOnProperty(name = "storage.type", havingValue = "file", matchIfMissing = true)
|
|
||||||
public class LocalSysFileServiceImpl implements ISysFileService
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* 资源映射路径 前缀
|
|
||||||
*/
|
|
||||||
@Value("${file.prefix}")
|
|
||||||
public String localFilePrefix;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 域名或本机访问地址
|
|
||||||
*/
|
|
||||||
@Value("${file.domain}")
|
|
||||||
public String domain;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件存储在本地的根路径
|
|
||||||
*/
|
|
||||||
@Value("${file.path}")
|
|
||||||
private String localFilePath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地文件上传接口
|
|
||||||
*
|
|
||||||
* @param file 上传的文件
|
|
||||||
* @return 访问地址
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public SysFile uploadFile(MultipartFile file) throws Exception
|
|
||||||
{
|
|
||||||
String name = FileUploadUtils.upload(localFilePath, file);
|
|
||||||
String url = domain + localFilePrefix + name;
|
|
||||||
return SysFile.builder().url(url).name(name).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SysFile> uploadFiles(MultipartFile[] files) throws Exception {
|
|
||||||
List<SysFile> sysFiles = new ArrayList<>();
|
|
||||||
for (MultipartFile file : files) {
|
|
||||||
SysFile sysFile = uploadFile(file);
|
|
||||||
sysFiles.add(sysFile);
|
|
||||||
}
|
|
||||||
return sysFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void downloadFile(HttpServletResponse response, String urlStr) throws Exception
|
|
||||||
{
|
|
||||||
FileDownloadUtils.downloadFile(response, urlStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从给定的URL下载文件并将其保存到指定的目标位置。
|
|
||||||
*
|
|
||||||
* @param response 请求响应。
|
|
||||||
* @param urlStr 要下载文件的URL地址。
|
|
||||||
* @throws Exception 如果在下载过程中遇到任何异常,例如网络问题、文件写入问题等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFilesAsZip(HttpServletResponse response, List<String> urlStr) throws Exception {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String urlStr) throws Exception
|
|
||||||
{
|
|
||||||
String regex = String.format("^(.*?%s)", localFilePrefix);
|
|
||||||
String updatePath = urlStr.replaceFirst(regex, localFilePath);
|
|
||||||
Path path = Paths.get(updatePath);
|
|
||||||
if (Files.exists(path)){
|
|
||||||
try {
|
|
||||||
Files.deleteIfExists(path);
|
|
||||||
}catch (IOException e){
|
|
||||||
throw new Exception(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
throw new Exception("删除文件时文件不存在");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定URL所指向的文件。
|
|
||||||
*
|
|
||||||
* @param urlStr 要删除文件的URL地址。
|
|
||||||
* @return 布尔值,指示文件删除是否成功。如果文件被成功删除,则返回true;否则返回false。
|
|
||||||
* @throws Exception 如果在删除文件的过程中遇到错误,例如网络问题、文件不存在或没有删除权限等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFiles(List<String> urlStr) throws Exception {
|
|
||||||
for (String url : urlStr) {
|
|
||||||
deleteFile(url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定文件夹下的所有文件夹和文件。
|
|
||||||
*
|
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
|
||||||
* @return 返回一个包含所有文件夹和文件路径的集合
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<FileDetails> getFilesAndSubfolders(String folderPath) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建文件夹(通过上传带有路径的文件)
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void createFolder(String folderPath) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定路径的所有对象,从而删除“文件夹”。
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFolder(String folderPath) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,222 +0,0 @@
|
||||||
package com.bonus.file.service.impl;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
|
||||||
import com.bonus.common.core.utils.file.FileUtils;
|
|
||||||
import com.bonus.common.core.utils.file.MimeTypeUtils;
|
|
||||||
import com.bonus.file.entity.FileDetails;
|
|
||||||
import com.bonus.file.service.ISysFileService;
|
|
||||||
import com.bonus.file.utils.FileUploadUtils;
|
|
||||||
import com.bonus.file.utils.MinioUtil;
|
|
||||||
import com.bonus.system.api.domain.SysFile;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minio 文件存储
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@ConditionalOnProperty(name = "storage.type", havingValue = "minio")
|
|
||||||
public class MinioServiceImpl implements ISysFileService {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MinioServiceImpl.class);
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private MinioUtil minioUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minio 文件上传接口
|
|
||||||
*
|
|
||||||
* @param file 上传的文件
|
|
||||||
* @return SysFile对象或null
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public SysFile uploadFile(MultipartFile file) {
|
|
||||||
try {
|
|
||||||
FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
|
||||||
String originalFilename = Objects.requireNonNull(file.getOriginalFilename(), "文件名不能为空").replace(" ", "");
|
|
||||||
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
|
|
||||||
String objectKey = FileUtils.generateObjectName(UuidUtils.generateUuid() + extension);
|
|
||||||
return minioUtil.uploadFile(file, objectKey);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("文件上传失败: {}", file.getOriginalFilename(), e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minio 多文件上传接口
|
|
||||||
*
|
|
||||||
* @param files 上传的文件数组
|
|
||||||
* @return 上传成功的 SysFile 列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<SysFile> uploadFiles(MultipartFile[] files) throws Exception {
|
|
||||||
// 将每个文件的上传操作作为一个 CompletableFuture 任务
|
|
||||||
List<CompletableFuture<SysFile>> futures = new ArrayList<>();
|
|
||||||
for (MultipartFile file : files) {
|
|
||||||
CompletableFuture<SysFile> future = CompletableFuture.supplyAsync(() -> {
|
|
||||||
try {
|
|
||||||
return uploadFile(file);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("文件上传失败: " + file.getOriginalFilename(), e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
futures.add(future);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用 allOf 等待所有任务完成,并收集结果
|
|
||||||
CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
|
|
||||||
|
|
||||||
// 在所有上传任务完成后,获取每个文件的上传结果
|
|
||||||
return allOf.thenApply(v -> futures.stream()
|
|
||||||
.map(CompletableFuture::join) // 获取每个 CompletableFuture 的结果
|
|
||||||
.collect(Collectors.toList())
|
|
||||||
).get(); // .get() 会阻塞直到所有任务完成
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从 MinIO 下载文件
|
|
||||||
*
|
|
||||||
* @param response 响应对象
|
|
||||||
* @param urlStr 文件 URL 地址
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFile(HttpServletResponse response, String urlStr) throws Exception {
|
|
||||||
try (InputStream inputStream = minioUtil.downloadFile(urlStr)) {
|
|
||||||
com.bonus.file.utils.FileUtils.setResponseHeaderByUrl(response, urlStr);
|
|
||||||
try (OutputStream outputStream = response.getOutputStream()) {
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
||||||
outputStream.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
outputStream.flush();
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
||||||
logger.error("下载文件失败: {}", urlStr, e);
|
|
||||||
throw new Exception("下载失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从给定的URL下载文件并将其保存到指定的目标位置。
|
|
||||||
*
|
|
||||||
* @param response 请求响应。
|
|
||||||
* @param urlStr 要下载文件的URL地址。
|
|
||||||
* @throws Exception 如果在下载过程中遇到任何异常,例如网络问题、文件写入问题等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFilesAsZip(HttpServletResponse response, List<String> urlStr) throws Exception {
|
|
||||||
String zipFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".zip";
|
|
||||||
// 设置响应头
|
|
||||||
response.setContentType("application/zip");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
|
|
||||||
|
|
||||||
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
|
||||||
// 遍历文件列表并压缩
|
|
||||||
for (String objectName : urlStr) {
|
|
||||||
try (InputStream inputStream = minioUtil.downloadFile(objectName)) {
|
|
||||||
|
|
||||||
// 添加 ZipEntry
|
|
||||||
zos.putNextEntry(new ZipEntry(objectName));
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int len;
|
|
||||||
while ((len = inputStream.read(buffer)) > 0) {
|
|
||||||
zos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
zos.closeEntry();
|
|
||||||
} catch (Exception e) {
|
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
||||||
throw new Exception("文件压缩或写入失败: " + objectName, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zos.finish();
|
|
||||||
} catch (Exception e) {
|
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
||||||
throw new Exception("压缩文件下载失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除文件
|
|
||||||
*
|
|
||||||
* @param urlStr 文件 URL 地址
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String urlStr) throws Exception {
|
|
||||||
try {
|
|
||||||
minioUtil.deleteObject(urlStr);
|
|
||||||
logger.info("文件删除成功: {}", urlStr);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("文件删除失败: {}", urlStr, e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定URL所指向的文件。
|
|
||||||
*
|
|
||||||
* @param urlStr 要删除文件的URL地址。
|
|
||||||
* @return 布尔值,指示文件删除是否成功。如果文件被成功删除,则返回true;否则返回false。
|
|
||||||
* @throws Exception 如果在删除文件的过程中遇到错误,例如网络问题、文件不存在或没有删除权限等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFiles(List<String> urlStr){
|
|
||||||
for (String objectName : urlStr) {
|
|
||||||
try {
|
|
||||||
deleteFile(objectName);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("文件删除失败: {} 错误: {}", objectName, e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定文件夹下的所有文件夹和文件。
|
|
||||||
*
|
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
|
||||||
* @return 返回一个包含所有文件夹和文件路径的集合
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<FileDetails> getFilesAndSubfolders(String folderPath) {
|
|
||||||
return minioUtil.getFilesAndSubfolders(folderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建文件夹(通过上传带有路径的文件)
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void createFolder(String folderPath) {
|
|
||||||
minioUtil.createFolder(folderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定路径的所有对象,从而删除“文件夹”。
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFolder(String folderPath) {
|
|
||||||
minioUtil.deleteFolder(folderPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,248 +0,0 @@
|
||||||
package com.bonus.file.service.impl;
|
|
||||||
|
|
||||||
import com.bonus.common.core.utils.file.MimeTypeUtils;
|
|
||||||
import com.bonus.file.entity.FileDetails;
|
|
||||||
import com.bonus.file.service.ISysFileService;
|
|
||||||
import com.bonus.file.utils.FileUploadUtils;
|
|
||||||
import com.bonus.system.api.domain.SysFile;
|
|
||||||
import com.mongodb.client.gridfs.model.GridFSFile;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
|
||||||
import org.bson.Document;
|
|
||||||
import org.bson.types.Binary;
|
|
||||||
import org.bson.types.ObjectId;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
|
||||||
import org.springframework.data.mongodb.gridfs.GridFsTemplate;
|
|
||||||
import org.springframework.http.HttpHeaders;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author wangvivi
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@ConditionalOnProperty(name = "storage.type", havingValue = "mongodb")
|
|
||||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
|
||||||
public class MongodbServiceImpl implements ISysFileService {
|
|
||||||
|
|
||||||
@Value("${spring.data.mongodb.gridfs-size-threshold}")
|
|
||||||
private long gridFsSizeThreshold;
|
|
||||||
|
|
||||||
final static String COLLECTION_NAME = "smallFiles";
|
|
||||||
/**
|
|
||||||
* GridFsTemplate 用于大文件存储
|
|
||||||
*/
|
|
||||||
private final GridFsTemplate gridFsTemplate;
|
|
||||||
/**
|
|
||||||
* MongoTemplate 用于小文件存储
|
|
||||||
*/
|
|
||||||
private final MongoTemplate mongoTemplate;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SysFile uploadFile(MultipartFile file) throws Exception {
|
|
||||||
//验证文件扩展名和大小
|
|
||||||
FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
|
||||||
String fileName = Objects.requireNonNull(file.getOriginalFilename(), "文件名不能为空");
|
|
||||||
fileName = fileName.replace(" ", "");
|
|
||||||
long fileSize = file.getSize();
|
|
||||||
// 判断是否使用 GridFS 存储
|
|
||||||
if (fileSize >= gridFsSizeThreshold) {
|
|
||||||
// 使用 GridFS 存储大文件
|
|
||||||
ObjectId fileId = gridFsTemplate.store(file.getInputStream(), fileName, file.getContentType());
|
|
||||||
return SysFile.builder().name(fileName).url(fileId.toHexString()).build();
|
|
||||||
} else {
|
|
||||||
// 小文件直接存储为二进制数据
|
|
||||||
// 创建一个Map存储文件信息
|
|
||||||
Map<String, Object> fileData = new HashMap<>();
|
|
||||||
fileData.put("fileName", fileName);
|
|
||||||
fileData.put("fileSize", file.getSize());
|
|
||||||
fileData.put("contentType", file.getContentType());
|
|
||||||
// 将文件内容以byte[]存储
|
|
||||||
fileData.put("fileData", file.getBytes());
|
|
||||||
|
|
||||||
// 插入文件信息到MongoDB的集合中(可以使用指定的集合名)
|
|
||||||
Document insertedFile = mongoTemplate.insert(new Document(fileData), COLLECTION_NAME);
|
|
||||||
// 返回文件的唯一标识符(MongoDB的ObjectId)
|
|
||||||
return SysFile.builder().name(fileName).url(insertedFile.getObjectId("_id").toString()).build();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SysFile> uploadFiles(MultipartFile[] files) throws Exception {
|
|
||||||
List<SysFile> uploadedFiles = new ArrayList<>();
|
|
||||||
for (MultipartFile file : files) {
|
|
||||||
uploadedFiles.add(uploadFile(file));
|
|
||||||
}
|
|
||||||
return uploadedFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void downloadFile(HttpServletResponse response, String fileId) throws Exception {
|
|
||||||
// 先尝试从 GridFS 中读取
|
|
||||||
GridFSFile gridFSFile = gridFsTemplate.findOne(new org.springframework.data.mongodb.core.query.Query()
|
|
||||||
.addCriteria(org.springframework.data.mongodb.core.query.Criteria.where("_id").is(new ObjectId(fileId))));
|
|
||||||
|
|
||||||
if (gridFSFile != null) {
|
|
||||||
// 设置响应头,告知客户端文件下载信息
|
|
||||||
String encodedFileName = URLEncoder.encode(gridFSFile.getFilename(), StandardCharsets.UTF_8.toString());
|
|
||||||
response.setContentType(gridFSFile.getMetadata().getString("_contentType"));
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedFileName + "\"");
|
|
||||||
// GridFS 文件下载
|
|
||||||
InputStream inputStream = gridFsTemplate.getResource(gridFSFile).getInputStream();
|
|
||||||
IOUtils.copy(inputStream, response.getOutputStream());
|
|
||||||
response.flushBuffer();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
downloadFromCollection(response, fileId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从给定的URL下载文件并将其保存到指定的目标位置。
|
|
||||||
*
|
|
||||||
* @param response 请求响应。
|
|
||||||
* @param fileIds 要下载文件的URL地址。
|
|
||||||
* @throws Exception 如果在下载过程中遇到任何异常,例如网络问题、文件写入问题等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFilesAsZip(HttpServletResponse response, List<String> fileIds) throws Exception {
|
|
||||||
String zipFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".zip";
|
|
||||||
response.setContentType("application/zip");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
|
|
||||||
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
|
|
||||||
for (String fileId : fileIds) {
|
|
||||||
// 先尝试从 GridFS 中读取
|
|
||||||
GridFSFile gridFSFile = gridFsTemplate.findOne(new org.springframework.data.mongodb.core.query.Query()
|
|
||||||
.addCriteria(org.springframework.data.mongodb.core.query.Criteria.where("_id").is(new ObjectId(fileId))));
|
|
||||||
if (gridFSFile != null) {
|
|
||||||
try (InputStream inputStream = gridFsTemplate.getResource(gridFSFile).getInputStream()) {
|
|
||||||
// 创建一个新的 ZipEntry,并使用文件名称
|
|
||||||
zos.putNextEntry(new ZipEntry(gridFSFile.getFilename()));
|
|
||||||
int len;
|
|
||||||
while ((len = inputStream.read(buffer)) > 0) {
|
|
||||||
zos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
zos.closeEntry();
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("无法压缩文件: " + fileId + " 错误: " + e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
System.err.println("文件不存在,文件 ID: " + fileId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zos.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String fileId) throws Exception {
|
|
||||||
try {
|
|
||||||
// 尝试从 GridFS 中删除
|
|
||||||
gridFsTemplate.delete(new org.springframework.data.mongodb.core.query.Query()
|
|
||||||
.addCriteria(org.springframework.data.mongodb.core.query.Criteria.where("_id").is(new ObjectId(fileId))));
|
|
||||||
|
|
||||||
// 尝试删除普通集合中的文件
|
|
||||||
mongoTemplate.findAllAndRemove(new org.springframework.data.mongodb.core.query.Query().addCriteria(org.springframework.data.mongodb.core.query.Criteria.where("_id").is(fileId)), Document.class, COLLECTION_NAME);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception("删除文件失败" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定URL所指向的文件。
|
|
||||||
*
|
|
||||||
* @param fileId 要删除文件的URL地址。
|
|
||||||
* @return 布尔值,指示文件删除是否成功。如果文件被成功删除,则返回true;否则返回false。
|
|
||||||
* @throws Exception 如果在删除文件的过程中遇到错误,例如网络问题、文件不存在或没有删除权限等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFiles(List<String> fileId) throws Exception {
|
|
||||||
for (String url : fileId) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定文件夹下的所有文件夹和文件。
|
|
||||||
*
|
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
|
||||||
* @return 返回一个包含所有文件夹和文件路径的集合
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<FileDetails> getFilesAndSubfolders(String folderPath) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建文件夹(通过上传带有路径的文件)
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void createFolder(String folderPath) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定路径的所有对象,从而删除“文件夹”。
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFolder(String folderPath) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void downloadFromCollection(HttpServletResponse response, String fileId) throws IOException {
|
|
||||||
// 尝试从普通集合中获取二进制文件
|
|
||||||
Document fileDocument = mongoTemplate.findById(fileId, Document.class, COLLECTION_NAME);
|
|
||||||
if (fileDocument == null) {
|
|
||||||
// 如果文件不存在,返回错误信息
|
|
||||||
throw new IOException("文件不存在");
|
|
||||||
}
|
|
||||||
// 获取 Binary 对象并转换为 byte[]
|
|
||||||
Binary binaryData = fileDocument.get("fileData", Binary.class);
|
|
||||||
// 从 Binary 中提取 byte[]
|
|
||||||
byte[] fileData = binaryData.getData();
|
|
||||||
// 假设文件名保存在 fileName 字段
|
|
||||||
String fileName = fileDocument.getString("fileName");
|
|
||||||
// 假设文件类型保存在 contentType 字段
|
|
||||||
String contentType = fileDocument.getString("contentType");
|
|
||||||
|
|
||||||
// 如果 contentType 为空,默认设置为 application/octet-stream
|
|
||||||
if (contentType == null || contentType.isEmpty()) {
|
|
||||||
contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
|
|
||||||
}
|
|
||||||
// 设置响应头,包含文件名和内容类型
|
|
||||||
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
|
|
||||||
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName);
|
|
||||||
response.setContentType(contentType);
|
|
||||||
response.setContentLength(fileData.length);
|
|
||||||
// 将文件的二进制数据写入到响应输出流中
|
|
||||||
try (OutputStream os = response.getOutputStream()) {
|
|
||||||
os.write(fileData);
|
|
||||||
os.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
// 如果写入过程出现异常,返回错误信息
|
|
||||||
throw new IOException("Failed to download file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
package com.bonus.file.service.impl;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
|
||||||
import com.bonus.common.core.domain.R;
|
|
||||||
import com.bonus.common.core.utils.file.FileUtils;
|
|
||||||
import com.bonus.common.core.utils.file.MimeTypeUtils;
|
|
||||||
import com.bonus.file.entity.FileDetails;
|
|
||||||
import com.bonus.file.service.ISysFileService;
|
|
||||||
import com.bonus.file.utils.FileUploadUtils;
|
|
||||||
import com.bonus.file.utils.ObsUtils;
|
|
||||||
import com.bonus.system.api.domain.SysFile;
|
|
||||||
import com.obs.services.model.ObsObject;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.zip.ZipEntry;
|
|
||||||
import java.util.zip.ZipOutputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minio 文件存储
|
|
||||||
*
|
|
||||||
* @author bonus
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@ConditionalOnProperty(name = "storage.type", havingValue = "obs")
|
|
||||||
public class ObsServiceImpl implements ISysFileService {
|
|
||||||
@Resource
|
|
||||||
private ObsUtils obsUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件上传
|
|
||||||
*
|
|
||||||
* @param file 文件流
|
|
||||||
* @return 文件信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public SysFile uploadFile(MultipartFile file) throws Exception {
|
|
||||||
try {
|
|
||||||
//验证文件扩展名和大小
|
|
||||||
FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
|
|
||||||
String originalFilename = Objects.requireNonNull(file.getOriginalFilename(), "文件名不能为空");
|
|
||||||
originalFilename = originalFilename.replace(" ", "");
|
|
||||||
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
|
|
||||||
String objectKey = UuidUtils.generateUuid() + extension;
|
|
||||||
objectKey = FileUtils.generateObjectName(objectKey);
|
|
||||||
SysFile sysFile = obsUtils.uploadFile(objectKey, Objects.requireNonNull(FileUtils.multipartFileToFile(file)));
|
|
||||||
sysFile.setName(originalFilename);
|
|
||||||
return sysFile;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<SysFile> uploadFiles(MultipartFile[] files) throws Exception {
|
|
||||||
try {
|
|
||||||
List<SysFile> sysFiles = new ArrayList<>();
|
|
||||||
for (MultipartFile file : files) {
|
|
||||||
SysFile sysFile = uploadFile(file);
|
|
||||||
sysFiles.add(sysFile);
|
|
||||||
}
|
|
||||||
return sysFiles;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new Exception(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void downloadFile(HttpServletResponse response, String urlStr) throws Exception {
|
|
||||||
R<ObsObject> obsObjectR = obsUtils.downloadFile(urlStr);
|
|
||||||
if (R.isError(obsObjectR)) {
|
|
||||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
|
||||||
throw new Exception("文件不存在");
|
|
||||||
}
|
|
||||||
if (obsObjectR.getData() == null) {
|
|
||||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
|
||||||
throw new Exception("文件不存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream inputStream = obsObjectR.getData().getObjectContent();
|
|
||||||
com.bonus.file.utils.FileUtils.setResponseHeaderByUrl(response, urlStr);
|
|
||||||
try (OutputStream outputStream = response.getOutputStream()) {
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
||||||
outputStream.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
outputStream.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
|
||||||
throw new Exception("下载失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从给定的URL下载文件并将其保存到指定的目标位置。
|
|
||||||
*
|
|
||||||
* @param response 请求响应。
|
|
||||||
* @param urlStr 要下载文件的URL地址。
|
|
||||||
* @throws Exception 如果在下载过程中遇到任何异常,例如网络问题、文件写入问题等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void downloadFilesAsZip(HttpServletResponse response, List<String> urlStr) throws Exception {
|
|
||||||
String zipFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + ".zip";
|
|
||||||
response.setContentType("application/zip");
|
|
||||||
response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
|
|
||||||
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
|
||||||
byte[] buffer = new byte[8192];
|
|
||||||
for (String objectName : urlStr) {
|
|
||||||
R<ObsObject> obsObjectR = obsUtils.downloadFile(objectName);
|
|
||||||
if (R.isError(obsObjectR)) {
|
|
||||||
response.setStatus(HttpStatus.BAD_REQUEST.value());
|
|
||||||
throw new Exception("文件不存在");
|
|
||||||
}
|
|
||||||
if (obsObjectR.getData() == null) {
|
|
||||||
response.setStatus(HttpStatus.NOT_FOUND.value());
|
|
||||||
throw new Exception("文件不存在");
|
|
||||||
}
|
|
||||||
try (InputStream inputStream = obsObjectR.getData().getObjectContent()) {
|
|
||||||
zos.putNextEntry(new ZipEntry(objectName));
|
|
||||||
int len;
|
|
||||||
while ((len = inputStream.read(buffer)) > 0) {
|
|
||||||
zos.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
zos.closeEntry();
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("无法压缩文件: " + objectName + " 错误: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
zos.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteFile(String urlStr) throws Exception {
|
|
||||||
obsUtils.deleteFile(urlStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定URL所指向的文件。
|
|
||||||
*
|
|
||||||
* @param urlStr 要删除文件的URL地址。
|
|
||||||
* @return 布尔值,指示文件删除是否成功。如果文件被成功删除,则返回true;否则返回false。
|
|
||||||
* @throws Exception 如果在删除文件的过程中遇到错误,例如网络问题、文件不存在或没有删除权限等。
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFiles(List<String> urlStr) throws Exception {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取指定文件夹下的所有文件夹和文件。
|
|
||||||
*
|
|
||||||
* @param folderPath 要获取文件夹和文件的父文件夹路径(例如 "folder1/")
|
|
||||||
* @return 返回一个包含所有文件夹和文件路径的集合
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Set<FileDetails> getFilesAndSubfolders(String folderPath) {
|
|
||||||
return obsUtils.getFilesAndFolders(folderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建文件夹(通过上传带有路径的文件)
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void createFolder(String folderPath) {
|
|
||||||
obsUtils.createFolder(folderPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除指定路径的所有对象,从而删除“文件夹”。
|
|
||||||
*
|
|
||||||
* @param folderPath 文件夹路径(例如 "folder1/subfolder/")
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void deleteFolder(String folderPath) {
|
|
||||||
obsUtils.deleteFolderAndContents(folderPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package com.bonus.file.service.impl;
|
package com.bonus.file.service.impl;
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.UuidUtils;
|
import com.alibaba.nacos.common.util.UuidUtils;
|
||||||
import com.aliyun.oss.model.OSSObject;
|
import com.aliyun.oss.model.OSSObject;
|
||||||
import com.bonus.common.core.domain.R;
|
import com.bonus.common.core.domain.R;
|
||||||
import com.bonus.common.core.utils.file.FileUtils;
|
import com.bonus.common.core.utils.file.FileUtils;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Tomcat
|
# Tomcat
|
||||||
server:
|
server:
|
||||||
port: 9300
|
port: 18088
|
||||||
|
|
||||||
# Spring
|
# Spring
|
||||||
spring:
|
spring:
|
||||||
|
|
@ -21,3 +21,6 @@ spring:
|
||||||
# 共享配置
|
# 共享配置
|
||||||
shared-configs:
|
shared-configs:
|
||||||
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
<?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.bonus</groupId>
|
||||||
|
<artifactId>bonus-modules</artifactId>
|
||||||
|
<version>24.12.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.bonus.ldlz</groupId>
|
||||||
|
<artifactId>bonus-ldlz</artifactId>
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!--加密依赖包-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ulisesbocchio</groupId>
|
||||||
|
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||||
|
<version>${jasypt-spring-boot-starter.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>-->
|
||||||
|
|
||||||
|
<!-- Mysql Connector -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version> <!-- 建议使用最新稳定版 -->
|
||||||
|
<scope>runtime</scope> <!-- 通常只需运行时依赖 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common DataSource -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-datasource</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common DataScope -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-datascope</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common Log -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-log</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>30.0-jre</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
<version>2.1.1.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<!-- <version>6.0.18</version>-->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
package com.bonus.ldlz;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 领导履职模块
|
||||||
|
*
|
||||||
|
* @author bonus
|
||||||
|
*/
|
||||||
|
/*@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class },scanBasePackages = {
|
||||||
|
"com.bonus.system",
|
||||||
|
"com.bonus.common.redis", // 必须包含RedisService所在包
|
||||||
|
"com.bonus.system.api",
|
||||||
|
"com.bonus.common.datasource.annotation",
|
||||||
|
"com.bonus.common.datascope",
|
||||||
|
})*/
|
||||||
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class})
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
public class BonusLdlzApplication
|
||||||
|
{
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
SpringApplication.run(BonusLdlzApplication.class, args);
|
||||||
|
System.out.println("(♥◠‿◠)ノ゙ 领导履职模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||||
|
" .-------. ____ __ \n" +
|
||||||
|
" | _ _ \\ \\ \\ / / \n" +
|
||||||
|
" | ( ' ) | \\ _. / ' \n" +
|
||||||
|
" |(_ o _) / _( )_ .' \n" +
|
||||||
|
" | (_,_).' __ ___(_ o _)' \n" +
|
||||||
|
" | |\\ \\ | || |(_,_)' \n" +
|
||||||
|
" | | \\ `' /| `-' / \n" +
|
||||||
|
" | | \\ / \\ / \n" +
|
||||||
|
" ''-' `'-' `-..-' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Spring Boot Version: ${spring-boot.version}
|
||||||
|
Spring Application Name: ${spring.application.name}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 18085
|
||||||
|
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 192.168.87.190:8848
|
||||||
|
namespace: e9abf140-675a-4d55-af3f-1f28a6186904
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 192.168.87.190:8848
|
||||||
|
namespace: e9abf140-675a-4d55-af3f-1f28a6186904
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: bonus-ldlz
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
|
||||||
|
#加密组件
|
||||||
|
jasypt:
|
||||||
|
encryptor:
|
||||||
|
password: Encrypt
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
<!-- 日志存放路径 -->
|
||||||
|
<property name="log.path" value="logs/bonus-ldlz" />
|
||||||
|
<!-- 日志输出格式 -->
|
||||||
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.bonus" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?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.bonus</groupId>
|
||||||
|
<artifactId>bonus-modules</artifactId>
|
||||||
|
<version>24.12.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>com.bonus.realname</groupId>
|
||||||
|
<artifactId>bonus-realname</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
<!--加密依赖包-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.ulisesbocchio</groupId>
|
||||||
|
<artifactId>jasypt-spring-boot-starter</artifactId>
|
||||||
|
<version>${jasypt-spring-boot-starter.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- SpringCloud Alibaba Nacos -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Nacos Config -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringCloud Alibaba Sentinel -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.cloud</groupId>
|
||||||
|
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- SpringBoot Actuator -->
|
||||||
|
<!-- <dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>-->
|
||||||
|
|
||||||
|
<!-- Mysql Connector -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version> <!-- 建议使用最新稳定版 -->
|
||||||
|
<scope>runtime</scope> <!-- 通常只需运行时依赖 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common DataSource -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-datasource</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common DataScope -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-datascope</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- bonus Common Log -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.bonus</groupId>
|
||||||
|
<artifactId>bonus-common-log</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>30.0-jre</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
<version>2.1.1.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<!-- <version>6.0.18</version>-->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>repackage</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package com.bonus.realname;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实名制模块
|
||||||
|
*
|
||||||
|
* @author bonus
|
||||||
|
*/
|
||||||
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class})
|
||||||
|
@EnableDiscoveryClient
|
||||||
|
public class BonusRealNameApplication
|
||||||
|
{
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
SpringApplication.run(BonusRealNameApplication.class, args);
|
||||||
|
System.out.println("(♥◠‿◠)ノ゙ 实名制模块启动成功 ლ(´ڡ`ლ)゙ \n" +
|
||||||
|
" .-------. ____ __ \n" +
|
||||||
|
" | _ _ \\ \\ \\ / / \n" +
|
||||||
|
" | ( ' ) | \\ _. / ' \n" +
|
||||||
|
" |(_ o _) / _( )_ .' \n" +
|
||||||
|
" | (_,_).' __ ___(_ o _)' \n" +
|
||||||
|
" | |\\ \\ | || |(_,_)' \n" +
|
||||||
|
" | | \\ `' /| `-' / \n" +
|
||||||
|
" | | \\ / \\ / \n" +
|
||||||
|
" ''-' `'-' `-..-' ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Spring Boot Version: ${spring-boot.version}
|
||||||
|
Spring Application Name: ${spring.application.name}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Tomcat
|
||||||
|
server:
|
||||||
|
port: 18087
|
||||||
|
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
cloud:
|
||||||
|
nacos:
|
||||||
|
discovery:
|
||||||
|
# 服务注册地址
|
||||||
|
server-addr: 192.168.87.190:8848
|
||||||
|
namespace: e9abf140-675a-4d55-af3f-1f28a6186904
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
config:
|
||||||
|
# 配置中心地址
|
||||||
|
server-addr: 192.168.87.190:8848
|
||||||
|
namespace: e9abf140-675a-4d55-af3f-1f28a6186904
|
||||||
|
username: nacos
|
||||||
|
password: nacos
|
||||||
|
# 配置文件格式
|
||||||
|
file-extension: yml
|
||||||
|
# 共享配置
|
||||||
|
shared-configs:
|
||||||
|
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Spring
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
# 应用名称
|
||||||
|
name: bonus-realname
|
||||||
|
profiles:
|
||||||
|
# 环境配置
|
||||||
|
active: dev
|
||||||
|
|
||||||
|
#加密组件
|
||||||
|
jasypt:
|
||||||
|
encryptor:
|
||||||
|
password: Encrypt
|
||||||
|
feign:
|
||||||
|
hystrix:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration scan="true" scanPeriod="60 seconds" debug="false">
|
||||||
|
<!-- 日志存放路径 -->
|
||||||
|
<property name="log.path" value="logs/bonus-realname" />
|
||||||
|
<!-- 日志输出格式 -->
|
||||||
|
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
|
||||||
|
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统日志输出 -->
|
||||||
|
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/info.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>INFO</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>${log.path}/error.log</file>
|
||||||
|
<!-- 循环政策:基于时间创建日志文件 -->
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- 日志文件名格式 -->
|
||||||
|
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
|
||||||
|
<!-- 日志最大的历史 60天 -->
|
||||||
|
<maxHistory>60</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>${log.pattern}</pattern>
|
||||||
|
</encoder>
|
||||||
|
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||||
|
<!-- 过滤的级别 -->
|
||||||
|
<level>ERROR</level>
|
||||||
|
<!-- 匹配时的操作:接收(记录) -->
|
||||||
|
<onMatch>ACCEPT</onMatch>
|
||||||
|
<!-- 不匹配时的操作:拒绝(不记录) -->
|
||||||
|
<onMismatch>DENY</onMismatch>
|
||||||
|
</filter>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- 系统模块日志级别控制 -->
|
||||||
|
<logger name="com.bonus" level="info" />
|
||||||
|
<!-- Spring日志级别控制 -->
|
||||||
|
<logger name="org.springframework" level="warn" />
|
||||||
|
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="console" />
|
||||||
|
</root>
|
||||||
|
|
||||||
|
<!--系统操作日志-->
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="file_info" />
|
||||||
|
<appender-ref ref="file_error" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
||||||
|
|
@ -47,13 +47,6 @@
|
||||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
</dependency>-->
|
</dependency>-->
|
||||||
|
|
||||||
<!-- Swagger UI -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.springfox</groupId>
|
|
||||||
<artifactId>springfox-swagger-ui</artifactId>
|
|
||||||
<version>${swagger.fox.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Mysql Connector -->
|
<!-- Mysql Connector -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>mysql</groupId>
|
||||||
|
|
@ -81,12 +74,6 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
<!-- bonus Common Swagger -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.bonus</groupId>
|
|
||||||
<artifactId>bonus-common-swagger</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import com.bonus.common.security.annotation.EnableCustomConfig;
|
import com.bonus.common.security.annotation.EnableCustomConfig;
|
||||||
import com.bonus.common.security.annotation.EnableRyFeignClients;
|
import com.bonus.common.security.annotation.EnableRyFeignClients;
|
||||||
import com.bonus.common.swagger.annotation.EnableCustomSwagger2;
|
|
||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
|
|
@ -14,9 +13,14 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
* @author bonus
|
* @author bonus
|
||||||
*/
|
*/
|
||||||
@EnableCustomConfig
|
@EnableCustomConfig
|
||||||
@EnableCustomSwagger2
|
|
||||||
@EnableRyFeignClients
|
@EnableRyFeignClients
|
||||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class },scanBasePackages = {
|
||||||
|
"com.bonus.system",
|
||||||
|
"com.bonus.common.redis", // 必须包含RedisService所在包
|
||||||
|
"com.bonus.system.api",
|
||||||
|
"com.bonus.common.datasource.annotation",
|
||||||
|
"com.bonus.common.datascope",
|
||||||
|
})
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
public class BonusSystemApplication
|
public class BonusSystemApplication
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import com.bonus.system.service.ISysConfigService;
|
||||||
@Service
|
@Service
|
||||||
public class SysConfigServiceImpl implements ISysConfigService
|
public class SysConfigServiceImpl implements ISysConfigService
|
||||||
{
|
{
|
||||||
@Autowired
|
@Resource
|
||||||
private SysConfigMapper configMapper;
|
private SysConfigMapper configMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
|
@ -96,7 +96,8 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||||
String str = config.getConfigKey().replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_");
|
String str = config.getConfigKey().replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_");
|
||||||
config.setConfigKey(str);
|
config.setConfigKey(str);
|
||||||
}
|
}
|
||||||
return configMapper.selectConfigList(config);
|
return null;
|
||||||
|
// return configMapper.selectConfigList(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -165,11 +166,11 @@ public class SysConfigServiceImpl implements ISysConfigService
|
||||||
@Override
|
@Override
|
||||||
public void loadingConfigCache()
|
public void loadingConfigCache()
|
||||||
{
|
{
|
||||||
List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
|
/*List<SysConfig> configsList = configMapper.selectConfigList(new SysConfig());
|
||||||
for (SysConfig config : configsList)
|
for (SysConfig config : configsList)
|
||||||
{
|
{
|
||||||
redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
|
redisService.setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@
|
||||||
<modules>
|
<modules>
|
||||||
<module>bonus-system</module>
|
<module>bonus-system</module>
|
||||||
<module>bonus-file</module>
|
<module>bonus-file</module>
|
||||||
|
<module>bonus-ldlz</module>
|
||||||
|
<module>bonus-czl</module>
|
||||||
|
<module>bonus-realname</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<artifactId>bonus-modules</artifactId>
|
<artifactId>bonus-modules</artifactId>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue