Browse Source

Merge branch 'dev' into pre-production

pre-production
pref_mail@163.com 9 months ago
parent
commit
ce8d58f494
  1. 3
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  2. 6
      blade-ops/blade-resource/src/main/java/org/springblade/resource/controller/OssController.java
  3. 133
      blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/OssEndpoint.java
  4. 38
      blade-ops/blade-resource/src/main/resources/application-dev.yml
  5. 45
      blade-ops/blade-swagger/src/main/resources/application-dev.yml
  6. 2
      blade-service-api/blade-system-api/src/main/java/org/springblade/system/entity/Tenant.java

3
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@ -22,5 +22,6 @@ package org.springblade.common.utils;
* @author Chill
*/
public class CommonUtil {
public static final String SYSTEMFILEPATH = "D:\\temp\\hwy\\";
// public static final String SYSTEMFILEPATH = "/home/java_works/logpm_temp_file/edu/";
}

6
blade-ops/blade-resource/src/main/java/org/springblade/resource/controller/OssController.java

@ -16,6 +16,7 @@
*/
package org.springblade.resource.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
@ -27,6 +28,7 @@ import org.springblade.core.cache.utils.CacheUtil;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.annotation.PreAuth;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.RoleConstant;
@ -76,7 +78,9 @@ public class OssController extends BladeController {
@ApiOperationSupport(order = 2)
@ApiOperation(value = "分页", notes = "传入oss")
public R<IPage<OssVO>> list(Oss oss, Query query) {
IPage<Oss> pages = ossService.page(Condition.getPage(query), Condition.getQueryWrapper(oss));
QueryWrapper<Oss> queryWrapper = Condition.getQueryWrapper(oss);
queryWrapper.eq("tenant_id", AuthUtil.getTenantId());
IPage<Oss> pages = ossService.page(Condition.getPage(query), queryWrapper);
return R.data(OssWrapper.build().pageVO(pages));
}

133
blade-ops/blade-resource/src/main/java/org/springblade/resource/endpoint/OssEndpoint.java

@ -19,9 +19,12 @@ package org.springblade.resource.endpoint;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.utils.CommonUtil;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.oss.model.OssFile;
import org.springblade.core.secure.annotation.PreAuth;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.constant.RoleConstant;
@ -33,6 +36,17 @@ import org.springblade.resource.service.IAttachService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileAttribute;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
/**
* 对象存储端点
*
@ -41,6 +55,7 @@ import org.springframework.web.multipart.MultipartFile;
@NonDS
@RestController
@AllArgsConstructor
@Slf4j
@RequestMapping("/oss/endpoint")
@Api(value = "对象存储端点", tags = "对象存储端点")
public class OssEndpoint {
@ -55,6 +70,7 @@ public class OssEndpoint {
*/
private final IAttachService attachService;
/**
* 创建存储桶
*
@ -148,6 +164,123 @@ public class OssEndpoint {
return R.data(bladeFile);
}
/**
* 文件分片上传
*
* @param file 切片
* @param chunkNumber 当前的切片位置
* @param totalChunks 总切片数
* @param fileName 文件名称
* @return
*/
@PostMapping("/chunk")
public R putFile(@RequestParam("file") MultipartFile file,
@RequestParam("chunkNumber") int chunkNumber,
@RequestParam("totalChunks") int totalChunks,
@RequestParam("fileName") String fileName) {
String uploadPath = CommonUtil.SYSTEMFILEPATH + AuthUtil.getUser().getUserId();
// 安全性优化:确保文件名是安全的
String safeFileName = sanitizeFileName(fileName);
// 边界条件检查
if (chunkNumber < 0 || totalChunks < 1) {
return R.fail("无效的chunkNumber或totalChunks");
}
// 异常处理优化:添加日志记录
try {
ensureUploadDirectoryExists(uploadPath);
// 优化:使用UUID避免文件覆盖
// String uniqueChunkIdentifier = UUID.randomUUID().toString();
Path chunkFilePath = Paths.get(uploadPath, safeFileName + ".part" + chunkNumber);
// 创建父目录
Files.createDirectories(chunkFilePath.getParent(), new FileAttribute<?>[0]);
file.transferTo(chunkFilePath.toFile());
return R.data(chunkNumber);
} catch (Exception e) {
// 优化:添加错误日志
log.error("文件上传失败", e);
return R.fail("文件上传失败~");
}
}
// 安全性优化:清理文件名
private String sanitizeFileName(String fileName) {
// 实现文件名清理逻辑,例如移除特殊字符,确保文件名安全
// 此处的实现依赖具体项目安全要求,以下为示例
return fileName.replaceAll("[^a-zA-Z0-9\\.\\-_]", "_");
}
// 性能优化:确保上传目录存在
private void ensureUploadDirectoryExists(String uploadPath) {
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
}
/**
* 文件分片上传合并
*
* @param map
* @return
*/
@PostMapping("/mergeFile")
public R mergeChunks(@RequestBody Map map) {
// 提取参数
Integer totalChunks = Objects.requireNonNull((Integer) map.get("totalChunks"), "totalChunks cannot be null");
String fileName = Objects.requireNonNull((String) map.get("fileName"), "fileName cannot be null");
// 文件路径使用File.separator保证跨平台兼容性
String userFilePath = CommonUtil.SYSTEMFILEPATH + File.separator + AuthUtil.getUser().getUserId() + File.separator + fileName;
File mergedFile = new File(userFilePath);
// 使用try-with-resources语句确保文件流正确关闭
try (FileOutputStream fos = new FileOutputStream(mergedFile)) {
for (int i = 0; i < totalChunks; i++) {
String chunkFilePath = userFilePath + ".part" + i;
File chunkFile = new File(chunkFilePath);
if (chunkFile.exists()) {
Files.copy(chunkFile.toPath(), fos);
if (!chunkFile.delete()) {
log.error("Failed to delete chunk file: {}", chunkFilePath);
}
} else {
// 分片缺失的更细致处理
return R.fail("文件合并失败,缺失分片:" + i);
}
}
log.info("文件合并完成: {}", mergedFile.getPath());
// 合并文件上传到OSS
try (FileInputStream inputStream = new FileInputStream(mergedFile)) {
long startTime = System.currentTimeMillis();
BladeFile bladeFile = ossBuilder.template().putFile(fileName, inputStream);
long endTime = System.currentTimeMillis();
log.info("Upload file {} from merge, start-end time: {}, {}", fileName, startTime, endTime);
// bladeFile.setLink(bladeFile.getLink().replaceFirst("(http|https)://.*?/", "/minio/"));
bladeFile.setDomain("http://files.huo5u.com/");
return R.data(bladeFile);
}
} catch (Exception e) {
log.error("Error during file merging and uploading: ", e);
return R.fail("文件上传失败~");
} finally {
// 删除合并后的临时文件,如果存在
if (mergedFile.exists()) {
boolean isDeleted = mergedFile.delete();
log.info("Merge file deleted: {}", isDeleted);
}
}
}
/**
* 上传文件
*

38
blade-ops/blade-resource/src/main/resources/application-dev.yml

@ -5,22 +5,22 @@ spring:
username: ${blade.datasource.dev.username}
password: ${blade.datasource.dev.password}
#oss默认配置
oss:
#开启oss配置
enabled: true
#开启oss类型
#minio、s3、qiniu、alioss、huaweiobs、tencentcos
name: minio
#租户模式
tenant-mode: true
#oss服务地址
endpoint: http://192.168.2.46:9000
#minio转换服务地址,用于内网上传后将返回地址改为转换的外网地址
transform-endpoint: http://192.168.2.46:9000
#访问key
access-key: minio
#密钥key
secret-key: 123123123
#存储桶
bucket-name: logpm
##oss默认配置
#oss:
# #开启oss配置
# enabled: true
# #开启oss类型
# #minio、s3、qiniu、alioss、huaweiobs、tencentcos
# name: minio
# #租户模式
# tenant-mode: true
# #oss服务地址
# endpoint: http://192.168.2.46:9000
# #minio转换服务地址,用于内网上传后将返回地址改为转换的外网地址
# transform-endpoint: http://192.168.2.46:9000
# #访问key
# access-key: minio
# #密钥key
# secret-key: 123123123
# #存储桶
# bucket-name: logpm

45
blade-ops/blade-swagger/src/main/resources/application-dev.yml

@ -1,25 +1,28 @@
knife4j:
cloud:
routes:
- name: 授权模块
uri: 192.168.10.101:8888
location: /blade-auth/v2/api-docs
- name: 工作台模块
uri: 192.168.2.101:8888
location: /blade-desk/v2/api-docs
- name: 系统模块
uri: 192.168.10.101:8888
location: /blade-system/v2/api-docs
- name: 配送模块
uri: 192.168.10.101:8888
location: /logpm-distribution/v2/api-docs
- name: 工厂模块
uri: 192.168.10.101:8888
location: /logpm-factory/v2/api-docs
- name: 仓库模块
uri: 192.168.10.101:8888
location: /logpm-warehouse/v2/api-docs
- name: 基础数据
uri: 192.168.10.101:8888
location: /logpm-basicdata/v2/api-docs
# - name: 授权模块
# uri: 192.168.10.101:8888
# location: /blade-auth/v2/api-docs
# - name: 工作台模块
# uri: 192.168.2.101:8888
# location: /blade-desk/v2/api-docs
# - name: 系统模块
# uri: 192.168.10.101:8888
# location: /blade-system/v2/api-docs
# - name: 配送模块
# uri: 192.168.10.101:8888
# location: /logpm-distribution/v2/api-docs
# - name: 工厂模块
# uri: 192.168.10.101:8888
# location: /logpm-factory/v2/api-docs
# - name: 仓库模块
# uri: 192.168.10.101:8888
# location: /logpm-warehouse/v2/api-docs
# - name: 基础数据
# uri: 192.168.10.101:8888
# location: /logpm-basicdata/v2/api-docs
- name: 基础模块
uri: 192.168.3.2:13000
location: /logpm-basic/v2/api-docs

2
blade-service-api/blade-system-api/src/main/java/org/springblade/system/entity/Tenant.java

@ -108,7 +108,7 @@ public class Tenant extends BaseEntity {
@ApiModelProperty(value = "授权码")
private String licenseKey;
@ApiModelProperty(value = "租户类型 默认 干仓配 2 商场")
@ApiModelProperty(value = "租户类型 默认 1 干仓配 2 商场")
private Integer tenantType;
}

Loading…
Cancel
Save