u
This commit is contained in:
1 parent
ce466130c0
commit
9c026f00ad
36 files changed
+2230
-1036
No files matched your search
@@ -83,6 +83,17 @@
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>6.10.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@@ -7,12 +7,14 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication(exclude = {
|
||||
DataSourceAutoConfiguration.class,
|
||||
DruidDataSourceAutoConfigure.class ,
|
||||
})
|
||||
@EnableAsync
|
||||
@EnableAsync // 异步
|
||||
@EnableScheduling // 定时任务
|
||||
public class ApiApplication {
|
||||
public static void main(String[] args){
|
||||
// 初始化雪花id
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package cn.g3soft.config;
|
||||
|
||||
|
||||
import cn.g3soft.utils.PathUtils;
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "file")
|
||||
public class FileConfig {
|
||||
private String baseDir;
|
||||
private String tempDir;
|
||||
private String containerDir;
|
||||
|
||||
private String staticPath;
|
||||
private String serverUrl;
|
||||
|
||||
public String getTempPath() {
|
||||
return PathUtils.joinFilePath(baseDir, tempDir);
|
||||
}
|
||||
|
||||
public String getContainerPath(){
|
||||
return PathUtils.joinFilePath(baseDir,containerDir);
|
||||
}
|
||||
|
||||
public String buildTempFilePath(String fileName) {
|
||||
return PathUtils.joinFilePath(baseDir, tempDir, fileName);
|
||||
}
|
||||
|
||||
public String getStaticUrlPrefix() {
|
||||
return PathUtils.joinUrl(serverUrl, staticPath);
|
||||
}
|
||||
|
||||
public String buildTempUrl(String fileName) {
|
||||
return PathUtils.joinUrl(serverUrl, staticPath, tempDir, fileName);
|
||||
}
|
||||
|
||||
public String buildFileUrl(String relativePath) {
|
||||
return PathUtils.joinUrl(serverUrl, staticPath, relativePath);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -3,28 +3,38 @@ package cn.g3soft.config;
|
||||
import cn.g3soft.interceptor.AuthInterceptor;
|
||||
import cn.g3soft.interceptor.DataSourceInterceptor;
|
||||
import cn.g3soft.interceptor.RequestWrapperFilter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Resource
|
||||
private FileConfig fileConfig;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new AuthInterceptor())
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns(
|
||||
"/auth/login",
|
||||
"/error"
|
||||
"/error",
|
||||
"/static/**"
|
||||
);
|
||||
|
||||
registry.addInterceptor(new DataSourceInterceptor())
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns(
|
||||
"/auth/login",
|
||||
"/error"
|
||||
"/error",
|
||||
"/static/**"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,7 +43,13 @@ public class WebMvcConfig implements WebMvcConfigurer {
|
||||
FilterRegistrationBean<RequestWrapperFilter> registration = new FilterRegistrationBean<>();
|
||||
registration.setFilter(new RequestWrapperFilter());
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setOrder(1); // 一定要靠前
|
||||
registration.setOrder(1);
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler(fileConfig.getStaticPath() + "/**")
|
||||
.addResourceLocations("file:" + fileConfig.getUploadDir() + "/");
|
||||
}
|
||||
}
|
||||
+20
-115
@@ -7,8 +7,10 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -18,123 +20,26 @@ import java.util.Map;
|
||||
public class FileController {
|
||||
@Resource
|
||||
private DbUtils dbUtils;
|
||||
@Resource
|
||||
private FileUploadUtils fileUploadUtils;
|
||||
|
||||
@PostMapping("/getAliyunKey")
|
||||
public Result<Map<String,Object>> getAliyunKey(@RequestBody Map<String, Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "bucketName");
|
||||
|
||||
String bucketName = (String) params.get("bucketName");
|
||||
|
||||
String orgId = UserContext.get().getOrgId();
|
||||
|
||||
String requestUrl = "http://g3oss.g3soft.cn:8082/upload?orgid=" + orgId + "&bucket=" + bucketName;
|
||||
String reqResult = HttpUtils.sendGet(requestUrl);
|
||||
|
||||
Map<String, Object> objectMap = JsonUtils.toMap(reqResult);
|
||||
|
||||
return Result.ok(objectMap);
|
||||
}
|
||||
|
||||
@PostMapping("/insert")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Long> insertFile(@RequestBody Map<String,Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "father", "mx_xh", "mx_filename", "mx_filesize", "mx_mapfilename", "mx_moduleid");
|
||||
|
||||
String userId = UserContext.get().getUserId();
|
||||
|
||||
long nextId = UniqueId.nextId();
|
||||
|
||||
params.put("subid", nextId);
|
||||
params.put("mx_inputuser_id",userId);
|
||||
params.put("mx_inputdatetime", TimeUtils.getDateTime());
|
||||
|
||||
dbUtils.insert("bf_file","subid",params);
|
||||
|
||||
return Result.ok(nextId);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> deleteFile(@RequestBody Map<String, Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "subid", "tableName", "bucketName");
|
||||
|
||||
String tableName = params.get("tableName").toString();
|
||||
String bucketName = params.get("bucketName").toString();
|
||||
String id = params.get("subid").toString();
|
||||
|
||||
// 查询数据
|
||||
List<Map<String, Object>> maps = dbUtils.loadData("SELECT * FROM " + tableName + " WHERE subid = ?", id);
|
||||
|
||||
// 如果没有数据,直接返回删除成功
|
||||
if (ObjectUtils.isEmpty(maps)) {
|
||||
return Result.ok("删除成功");
|
||||
}
|
||||
|
||||
String mxMapfilename = maps.get(0).get("mx_mapfilename").toString();
|
||||
String orgId = UserContext.get().getOrgId();
|
||||
int index = mxMapfilename.indexOf(orgId + "/");
|
||||
|
||||
// 如果没找到,就转换orgId为大写
|
||||
if (index < 0) {
|
||||
orgId = orgId.toUpperCase();
|
||||
index = mxMapfilename.indexOf(orgId + "/");
|
||||
}
|
||||
|
||||
String objectName = mxMapfilename.substring(index);
|
||||
|
||||
// 删除记录
|
||||
Map<String, Object> deleteParams = new HashMap<>();
|
||||
deleteParams.put("subid", id);
|
||||
int deleteCount = dbUtils.delete(tableName, deleteParams);
|
||||
|
||||
// 如果删除成功,发送删除请求
|
||||
if (deleteCount > 0) {
|
||||
if(StringUtils.isBlank(objectName)){
|
||||
return Result.fail("删除失败,文件格式有误");
|
||||
}
|
||||
String requestUrl = String.format("http://g3oss.g3soft.cn:8082/delete?bucketName=%s&objectName=%s", bucketName, objectName);
|
||||
try {
|
||||
HttpUtils.sendGet(requestUrl);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("删除文件失败",e);
|
||||
}
|
||||
}
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/deleteAliyunFile")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> deleteAliyunFile(@RequestBody Map<String, Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "bucketName", "mx_mapfilename");
|
||||
|
||||
String bucketName = params.get("bucketName").toString();
|
||||
String mxMapfilename = params.get("mx_mapfilename").toString();
|
||||
String orgId = UserContext.get().getOrgId();
|
||||
|
||||
int index = mxMapfilename.indexOf(orgId + "/");
|
||||
// 如果没找到,就转换orgId为大写
|
||||
if (index < 0) {
|
||||
orgId = orgId.toUpperCase();
|
||||
index = mxMapfilename.indexOf(orgId + "/");
|
||||
}
|
||||
|
||||
String objectName = mxMapfilename.substring(index);
|
||||
if(StringUtils.isBlank(objectName)){
|
||||
return Result.fail("删除失败,文件格式有误");
|
||||
}
|
||||
|
||||
// 发送删除请求
|
||||
String requestUrl = String.format("http://g3oss.g3soft.cn:8082/delete?bucketName=%s&objectName=%s", bucketName, objectName);
|
||||
|
||||
System.out.println(requestUrl);
|
||||
|
||||
/**
|
||||
* 上传临时文件接口
|
||||
*/
|
||||
@PostMapping("/uploadTemp")
|
||||
public Result<Map<String, String>> uploadTemp(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(value = "fileName") String fileName) {
|
||||
Map<String, String> response = new HashMap<>();
|
||||
try {
|
||||
HttpUtils.sendGet(requestUrl);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("删除文件失败",e);
|
||||
}
|
||||
// 调用工具类上传临时文件,返回临时 URL
|
||||
String tempUrl = fileUploadUtils.uploadTemp(file,fileName);
|
||||
|
||||
return Result.ok();
|
||||
// 返回临时文件 URL
|
||||
response.put("tempUrl", tempUrl);
|
||||
return Result.ok(response);
|
||||
} catch (IOException e) {
|
||||
return Result.fail("文件上传失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -33,7 +33,7 @@ public class OcrController {
|
||||
reqPayload.put("visualize", false);
|
||||
|
||||
try {
|
||||
String response = HttpUtils.sendPostJson(requestUrl, reqPayload);
|
||||
String response = HttpUtils.postJson(requestUrl, reqPayload);
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode root = mapper.readTree(response);
|
||||
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
package cn.g3soft.controller;
|
||||
|
||||
import cn.g3soft.context.UserContext;
|
||||
import cn.g3soft.utils.*;
|
||||
import cn.g3soft.utils.uniqueId.idgen.UniqueId;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/file")
|
||||
public class OssController {
|
||||
@Resource
|
||||
private DbUtils dbUtils;
|
||||
|
||||
@PostMapping("/getAliyunKey")
|
||||
public Result<Map<String,Object>> getAliyunKey(@RequestBody Map<String, Object> params) throws Exception {
|
||||
ValidationUtils.checkRequiredFields(params, "bucketName");
|
||||
|
||||
String bucketName = (String) params.get("bucketName");
|
||||
|
||||
String orgId = UserContext.get().getOrgId();
|
||||
|
||||
String requestUrl = "http://g3oss.g3soft.cn:8082/upload?orgid=" + orgId + "&bucket=" + bucketName;
|
||||
String reqResult = HttpUtils.get(requestUrl);
|
||||
|
||||
Map<String, Object> objectMap = JsonUtils.toMap(reqResult);
|
||||
|
||||
return Result.ok(objectMap);
|
||||
}
|
||||
|
||||
@PostMapping("/insert")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Long> insertFile(@RequestBody Map<String,Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "father", "mx_xh", "mx_filename", "mx_filesize", "mx_mapfilename", "mx_moduleid");
|
||||
|
||||
String userId = UserContext.get().getUserId();
|
||||
|
||||
long nextId = UniqueId.nextId();
|
||||
|
||||
params.put("subid", nextId);
|
||||
params.put("mx_inputuser_id",userId);
|
||||
params.put("mx_inputdatetime", TimeUtils.getDateTime());
|
||||
|
||||
dbUtils.insert("bf_file","subid",params);
|
||||
|
||||
return Result.ok(nextId);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> deleteFile(@RequestBody Map<String, Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "subid", "tableName", "bucketName");
|
||||
|
||||
String tableName = params.get("tableName").toString();
|
||||
String bucketName = params.get("bucketName").toString();
|
||||
String id = params.get("subid").toString();
|
||||
|
||||
// 查询数据
|
||||
List<Map<String, Object>> maps = dbUtils.loadData("SELECT * FROM " + tableName + " WHERE subid = ?", id);
|
||||
|
||||
// 如果没有数据,直接返回删除成功
|
||||
if (ObjectUtils.isEmpty(maps)) {
|
||||
return Result.ok("删除成功");
|
||||
}
|
||||
|
||||
String mxMapfilename = maps.get(0).get("mx_mapfilename").toString();
|
||||
String orgId = UserContext.get().getOrgId();
|
||||
int index = mxMapfilename.indexOf(orgId + "/");
|
||||
|
||||
// 如果没找到,就转换orgId为大写
|
||||
if (index < 0) {
|
||||
orgId = orgId.toUpperCase();
|
||||
index = mxMapfilename.indexOf(orgId + "/");
|
||||
}
|
||||
|
||||
String objectName = mxMapfilename.substring(index);
|
||||
|
||||
// 删除记录
|
||||
Map<String, Object> deleteParams = new HashMap<>();
|
||||
deleteParams.put("subid", id);
|
||||
int deleteCount = dbUtils.delete(tableName, deleteParams);
|
||||
|
||||
// 如果删除成功,发送删除请求
|
||||
if (deleteCount > 0) {
|
||||
if(StringUtils.isBlank(objectName)){
|
||||
return Result.fail("删除失败,文件格式有误");
|
||||
}
|
||||
String requestUrl = String.format("http://g3oss.g3soft.cn:8082/delete?bucketName=%s&objectName=%s", bucketName, objectName);
|
||||
try {
|
||||
HttpUtils.get(requestUrl);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("删除文件失败",e);
|
||||
}
|
||||
}
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
|
||||
@PostMapping("/deleteAliyunFile")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Void> deleteAliyunFile(@RequestBody Map<String, Object> params) {
|
||||
ValidationUtils.checkRequiredFields(params, "bucketName", "mx_mapfilename");
|
||||
|
||||
String bucketName = params.get("bucketName").toString();
|
||||
String mxMapfilename = params.get("mx_mapfilename").toString();
|
||||
String orgId = UserContext.get().getOrgId();
|
||||
|
||||
int index = mxMapfilename.indexOf(orgId + "/");
|
||||
// 如果没找到,就转换orgId为大写
|
||||
if (index < 0) {
|
||||
orgId = orgId.toUpperCase();
|
||||
index = mxMapfilename.indexOf(orgId + "/");
|
||||
}
|
||||
|
||||
String objectName = mxMapfilename.substring(index);
|
||||
if(StringUtils.isBlank(objectName)){
|
||||
return Result.fail("删除失败,文件格式有误");
|
||||
}
|
||||
|
||||
// 发送删除请求
|
||||
String requestUrl = String.format("http://g3oss.g3soft.cn:8082/delete?bucketName=%s&objectName=%s", bucketName, objectName);
|
||||
|
||||
System.out.println(requestUrl);
|
||||
|
||||
try {
|
||||
HttpUtils.get(requestUrl);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("删除文件失败",e);
|
||||
}
|
||||
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package cn.g3soft.schedule;
|
||||
|
||||
import cn.g3soft.config.FileConfig;
|
||||
import cn.g3soft.utils.PathUtils;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
|
||||
@Component
|
||||
public class TempFIleSchedule {
|
||||
@Resource
|
||||
private FileConfig fileConfig;
|
||||
|
||||
/**
|
||||
* 定时清理临时文件(临时文件超过1天后清理)
|
||||
*/
|
||||
@Scheduled(cron = "0 0 3 * * ?") // 每天3点清理
|
||||
public void cleanTempFiles() {
|
||||
File tempDir = new File(PathUtils.joinFilePath(fileConfig.getTempPath()));
|
||||
if (tempDir.exists()) {
|
||||
File[] files = tempDir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (isFileExpired(file)) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断文件是否过期(假设超过1天的文件删除)
|
||||
* @param file 文件
|
||||
* @return 是否过期
|
||||
*/
|
||||
private boolean isFileExpired(File file) {
|
||||
long lastModified = file.lastModified();
|
||||
long now = System.currentTimeMillis();
|
||||
return now - lastModified > 86400000L; // 1天的毫秒数
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import cn.g3soft.config.FileConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 通用文件上传工具类
|
||||
* 规则:
|
||||
* - 文件名保持原始或指定
|
||||
* - 同一天同箱号重复 -> 自动生成 _1/_2/... 文件夹
|
||||
* - 使用 FileUtils 拼接路径
|
||||
*/
|
||||
@Component
|
||||
public class FileContainerUtils {
|
||||
|
||||
@Resource
|
||||
private FileConfig fileConfig;
|
||||
|
||||
/**
|
||||
* 单文件上传
|
||||
*/
|
||||
public String upload(MultipartFile file, String containerNo, String fileName) throws IOException {
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new RuntimeException("文件不能为空");
|
||||
}
|
||||
|
||||
// 1. 日期路径 yyyy/MM/dd
|
||||
String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
|
||||
|
||||
// 2. 基础目录:上传目录 + 日期
|
||||
String basePath = PathUtils.joinFilePath(fileConfig.getContainerPath(), datePath);
|
||||
|
||||
// 3. 计算最终目录(箱号 + 重复批次)
|
||||
File finalDir = resolveContainerDir(basePath, containerNo);
|
||||
|
||||
if (!finalDir.exists()) {
|
||||
finalDir.mkdirs();
|
||||
}
|
||||
|
||||
// 4. 最终文件
|
||||
File dest = new File(finalDir, fileName);
|
||||
file.transferTo(dest);
|
||||
|
||||
// 5. 相对路径,用于生成URL
|
||||
String relativePath = PathUtils.joinFilePath(
|
||||
datePath,
|
||||
finalDir.getName(),
|
||||
fileName
|
||||
);
|
||||
|
||||
return fileConfig.buildFileUrl(relativePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 多文件上传
|
||||
*/
|
||||
public List<String> uploadBatch(MultipartFile[] files, String containerNo, String[] fileNames) throws IOException {
|
||||
if (files == null || files.length == 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> urls = new ArrayList<>();
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
String name = (fileNames != null && i < fileNames.length) ? fileNames[i] : files[i].getOriginalFilename();
|
||||
urls.add(upload(files[i], containerNo, name));
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析容器目录
|
||||
* - 如果同一天已存在该箱号目录 -> 自动加 _1/_2/... 避免覆盖
|
||||
*/
|
||||
private File resolveContainerDir(String basePath, String containerNo) {
|
||||
File containerDir = new File(PathUtils.joinFilePath(basePath, containerNo));
|
||||
|
||||
if (!containerDir.exists()) {
|
||||
return containerDir;
|
||||
}
|
||||
|
||||
// 已存在 -> 找下一个可用序号
|
||||
int i = 1;
|
||||
while (true) {
|
||||
File dir = new File(PathUtils.joinFilePath(basePath, containerNo + "_" + i));
|
||||
if (!dir.exists()) {
|
||||
return dir;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import cn.g3soft.config.FileConfig;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.UUID;
|
||||
|
||||
@Component
|
||||
public class FileUploadUtils {
|
||||
|
||||
@Resource
|
||||
private FileConfig fileConfig;
|
||||
|
||||
/**
|
||||
* 上传文件到临时路径
|
||||
* @param file 上传的文件
|
||||
* @param fileName 如果前端传递了文件名,使用传递的文件名
|
||||
* @return 临时文件的URL
|
||||
*/
|
||||
public String uploadTemp(MultipartFile file, String fileName) throws IOException {
|
||||
// 1. 生成最终文件名
|
||||
String finalFileName = generateTempFileName(file, fileName);
|
||||
|
||||
// 2. 临时目录路径
|
||||
File tempDir = new File(fileConfig.getTempPath());
|
||||
|
||||
// 如果临时目录不存在,创建目录
|
||||
if (!tempDir.exists()) {
|
||||
tempDir.mkdirs();
|
||||
}
|
||||
|
||||
// 3. 保存文件到临时目录
|
||||
File tempFile = new File(tempDir, finalFileName);
|
||||
file.transferTo(tempFile);
|
||||
|
||||
// 4. 返回临时文件的 URL(供 OCR 使用)
|
||||
return fileConfig.buildTempUrl(finalFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件名生成临时文件名(带时间戳 + UUID + 文件后缀)
|
||||
* @param file 上传的文件
|
||||
* @param fileName 传递的文件名(可选)
|
||||
* @return 生成的最终文件名
|
||||
*/
|
||||
private String generateTempFileName(MultipartFile file, String fileName) {
|
||||
// 优先使用前端传递的 fileName
|
||||
String originalFilename = (fileName != null && !fileName.isEmpty())
|
||||
? fileName
|
||||
: file.getOriginalFilename();
|
||||
|
||||
// 如果没有获取到文件名,设置一个默认文件名
|
||||
if (originalFilename == null) {
|
||||
originalFilename = "file";
|
||||
}
|
||||
|
||||
// 获取文件后缀
|
||||
String extension = "";
|
||||
if (originalFilename.contains(".")) {
|
||||
extension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
}
|
||||
|
||||
// 生成带时间戳和 UUID 的文件名
|
||||
return LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + "_"
|
||||
+ UUID.randomUUID().toString().replace("-", "") + extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除临时文件(成功识别后删除)
|
||||
* @param tempFileName 临时文件的文件名
|
||||
*/
|
||||
public void deleteTempFile(String tempFileName) {
|
||||
String filePath = PathUtils.joinFilePath(fileConfig.getBaseDir(), fileConfig.getTempDir(), tempFileName);
|
||||
|
||||
File tempFile = new File(tempFileName);
|
||||
if (tempFile.exists()) {
|
||||
tempFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class FileUtils {
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 最简调用:自动生成文件名 + 不覆盖
|
||||
* =========================
|
||||
*/
|
||||
public static String upload(MultipartFile file, String uploadPath) throws IOException {
|
||||
return upload(file, uploadPath, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 指定文件名 + 不覆盖
|
||||
* =========================
|
||||
*/
|
||||
public static String upload(MultipartFile file,
|
||||
String uploadPath,
|
||||
String fileName) throws IOException {
|
||||
return upload(file, uploadPath, fileName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 控制是否覆盖 + 自动生成文件名
|
||||
* =========================
|
||||
*/
|
||||
public static String upload(MultipartFile file,
|
||||
String uploadPath,
|
||||
boolean overwrite) throws IOException {
|
||||
return upload(file, uploadPath, null, overwrite);
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 核心方法(唯一执行逻辑)
|
||||
* =========================
|
||||
*/
|
||||
public static String upload(MultipartFile file,
|
||||
String uploadPath,
|
||||
String fileName,
|
||||
boolean overwrite) throws IOException {
|
||||
|
||||
// 1. 校验文件
|
||||
if (file == null || file.isEmpty()) {
|
||||
throw new RuntimeException("上传文件不能为空");
|
||||
}
|
||||
|
||||
// 2. 创建目录
|
||||
File dir = new File(uploadPath);
|
||||
if (!dir.exists()) {
|
||||
boolean created = dir.mkdirs();
|
||||
if (!created) {
|
||||
throw new RuntimeException("目录创建失败: " + uploadPath);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 获取原始文件名
|
||||
String originalName = file.getOriginalFilename();
|
||||
|
||||
// 4. 处理文件名
|
||||
if (fileName == null || fileName.trim().isEmpty()) {
|
||||
fileName = generateFileName(originalName);
|
||||
} else {
|
||||
// 如果用户传了文件名,但没有后缀,则补上
|
||||
if (!fileName.contains(".") && originalName != null && originalName.contains(".")) {
|
||||
fileName = fileName + getSuffix(originalName);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 目标文件
|
||||
File dest = new File(dir, fileName);
|
||||
|
||||
// 6. 处理覆盖逻辑
|
||||
if (dest.exists() && !overwrite) {
|
||||
String newName = generateFileName(fileName);
|
||||
dest = new File(dir, newName);
|
||||
fileName = newName;
|
||||
}
|
||||
|
||||
// 7. 保存文件
|
||||
file.transferTo(dest);
|
||||
|
||||
// 8. 返回文件路径(你也可以改成返回 URL)
|
||||
return dest.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 生成唯一文件名
|
||||
* =========================
|
||||
*/
|
||||
private static String generateFileName(String originalName) {
|
||||
return UUID.randomUUID().toString().replace("-", "")
|
||||
+ getSuffix(originalName);
|
||||
}
|
||||
|
||||
/**
|
||||
* =========================
|
||||
* 获取文件后缀
|
||||
* =========================
|
||||
*/
|
||||
private static String getSuffix(String fileName) {
|
||||
if (fileName == null || !fileName.contains(".")) {
|
||||
return "";
|
||||
}
|
||||
return fileName.substring(fileName.lastIndexOf("."));
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,12 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.MediaType;
|
||||
import okhttp3.*;
|
||||
|
||||
/**
|
||||
* 通用http发送方法
|
||||
@@ -32,287 +15,92 @@ import org.springframework.http.MediaType;
|
||||
*/
|
||||
public class HttpUtils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送GET方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendGet(String url)
|
||||
{
|
||||
return sendGet(url, StringUtils.EMPTY);
|
||||
private static final OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(5, TimeUnit.SECONDS)
|
||||
.readTimeout(10, TimeUnit.SECONDS)
|
||||
.writeTimeout(10, TimeUnit.SECONDS)
|
||||
.connectionPool(new ConnectionPool(50, 5, TimeUnit.MINUTES))
|
||||
.build();
|
||||
|
||||
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
||||
|
||||
// ==================== GET ====================
|
||||
public static String get(String url) throws Exception {
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.get()
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
return response.body() != null ? response.body().string() : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送GET方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendGet(String url, String param)
|
||||
{
|
||||
return sendGet(url, param, "UTF-8");
|
||||
}
|
||||
public static String get(String url, Map<String, Object> params, String contentType) throws Exception {
|
||||
HttpUrl.Builder urlBuilder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送GET方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @param contentType 编码类型
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendGet(String url, String param, String contentType)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
BufferedReader in = null;
|
||||
try
|
||||
{
|
||||
String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url;
|
||||
log.info("sendGet - {}", urlNameString);
|
||||
URL realUrl = new URL(urlNameString);
|
||||
URLConnection connection = realUrl.openConnection();
|
||||
connection.setRequestProperty("accept", "*/*");
|
||||
connection.setRequestProperty("connection", "Keep-Alive");
|
||||
connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||
connection.connect();
|
||||
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null)
|
||||
{
|
||||
result.append(line);
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (in != null)
|
||||
{
|
||||
in.close();
|
||||
if (params != null) {
|
||||
for (Map.Entry<String, Object> entry : params.entrySet()) {
|
||||
if (entry.getValue() != null) {
|
||||
urlBuilder.addQueryParameter(
|
||||
entry.getKey(),
|
||||
String.valueOf(entry.getValue())
|
||||
);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送POST方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendPost(String url, String param)
|
||||
{
|
||||
return sendPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送POST方法的请求
|
||||
*
|
||||
* @param url 发送请求的 URL
|
||||
* @param param 请求参数
|
||||
* @param contentType 内容类型
|
||||
* @return 所代表远程资源的响应结果
|
||||
*/
|
||||
public static String sendPost(String url, String param, String contentType)
|
||||
{
|
||||
PrintWriter out = null;
|
||||
BufferedReader in = null;
|
||||
StringBuilder result = new StringBuilder();
|
||||
try
|
||||
{
|
||||
log.info("sendPost - {}", url);
|
||||
URL realUrl = new URL(url);
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
out = new PrintWriter(conn.getOutputStream());
|
||||
out.print(param);
|
||||
out.flush();
|
||||
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null)
|
||||
{
|
||||
result.append(line);
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if (out != null)
|
||||
{
|
||||
out.close();
|
||||
}
|
||||
if (in != null)
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向指定 URL 发送 POST 请求,内容类型为 JSON
|
||||
*
|
||||
* @param url 请求的 URL
|
||||
* @param reqPayload 请求参数,Map 类型
|
||||
* @return 响应结果
|
||||
*/
|
||||
public static String sendPostJson(String url, Map<String, Object> reqPayload) {
|
||||
// 创建一个 ObjectMapper 实例,用于将 Map 转换为 JSON 字符串
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
String jsonParam = null;
|
||||
try {
|
||||
// 将 Map 转换为 JSON 字符串
|
||||
jsonParam = objectMapper.writeValueAsString(reqPayload);
|
||||
} catch (Exception e) {
|
||||
log.error("请求参数转换为 JSON 失败,url=" + url, e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 调用 sendPost 方法,发送请求并返回响应
|
||||
return sendPost(url, jsonParam, "application/json");
|
||||
}
|
||||
Request.Builder builder = new Request.Builder()
|
||||
.url(urlBuilder.build())
|
||||
.get();
|
||||
|
||||
public static String sendSSLPost(String url, String param)
|
||||
{
|
||||
return sendSSLPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
}
|
||||
|
||||
public static String sendSSLPost(String url, String param, String contentType)
|
||||
{
|
||||
StringBuilder result = new StringBuilder();
|
||||
String urlNameString = url + "?" + param;
|
||||
try
|
||||
{
|
||||
log.info("sendSSLPost - {}", urlNameString);
|
||||
SSLContext sc = SSLContext.getInstance("SSL");
|
||||
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
|
||||
URL console = new URL(urlNameString);
|
||||
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
|
||||
conn.setRequestProperty("accept", "*/*");
|
||||
conn.setRequestProperty("connection", "Keep-Alive");
|
||||
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
|
||||
conn.setRequestProperty("Accept-Charset", "utf-8");
|
||||
conn.setRequestProperty("Content-Type", contentType);
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
|
||||
conn.setSSLSocketFactory(sc.getSocketFactory());
|
||||
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
|
||||
conn.connect();
|
||||
InputStream is = conn.getInputStream();
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
String ret = "";
|
||||
while ((ret = br.readLine()) != null)
|
||||
{
|
||||
if (ret != null && !"".equals(ret.trim()))
|
||||
{
|
||||
result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
log.info("recv - {}", result);
|
||||
conn.disconnect();
|
||||
br.close();
|
||||
}
|
||||
catch (ConnectException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (SocketTimeoutException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static class TrustAnyTrustManager implements X509TrustManager
|
||||
{
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType)
|
||||
{
|
||||
if (contentType != null && !contentType.isEmpty()) {
|
||||
builder.addHeader("Content-Type", contentType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers()
|
||||
{
|
||||
return new X509Certificate[] {};
|
||||
try (Response response = client.newCall(builder.build()).execute()) {
|
||||
return response.body() != null ? response.body().string() : null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TrustAnyHostnameVerifier implements HostnameVerifier
|
||||
{
|
||||
@Override
|
||||
public boolean verify(String hostname, SSLSession session)
|
||||
{
|
||||
return true;
|
||||
// ==================== POST FORM ====================
|
||||
public static String postForm(String url, Map<String, String> params) throws Exception {
|
||||
FormBody.Builder builder = new FormBody.Builder();
|
||||
|
||||
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||
builder.add(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.post(builder.build())
|
||||
.build();
|
||||
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
return response.body() != null ? response.body().string() : null;
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== POST JSON ====================
|
||||
// ==================== POST JSON(Map版本)====================
|
||||
public static String postJson(String url, Map<String, Object> params) throws Exception {
|
||||
|
||||
// 1. Map 转 JSON 字符串
|
||||
String json = MAPPER.writeValueAsString(params);
|
||||
|
||||
// 2. 构建请求体
|
||||
RequestBody body = RequestBody.create(json, JSON);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.post(body)
|
||||
.build();
|
||||
|
||||
// 3. 执行请求
|
||||
try (Response response = client.newCall(request).execute()) {
|
||||
return response.body() != null ? response.body().string() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package cn.g3soft.utils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class PathUtils {
|
||||
public static String joinUrl(String... parts) {
|
||||
if (parts == null || parts.length == 0) return "";
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (String part : parts) {
|
||||
if (part == null || part.trim().isEmpty()) continue;
|
||||
|
||||
part = part.trim();
|
||||
|
||||
if (sb.length() == 0) {
|
||||
// 第一段:保留协议(http://)
|
||||
sb.append(part.replaceAll("/+$", ""));
|
||||
} else {
|
||||
sb.append("/");
|
||||
sb.append(part.replaceAll("^/+", "").replaceAll("/+$", ""));
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String joinFilePath(String... paths) {
|
||||
if (paths == null || paths.length == 0) return "";
|
||||
Path result = null;
|
||||
for (String p : paths) {
|
||||
if (p == null || p.trim().isEmpty()) continue;
|
||||
if (result == null) {
|
||||
result = Paths.get(p.trim());
|
||||
} else {
|
||||
result = result.resolve(p.trim());
|
||||
}
|
||||
}
|
||||
return (result == null) ? "" : result.normalize().toString();
|
||||
}
|
||||
}
|
||||
+9
-1
@@ -7,6 +7,9 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class AddressUtils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
|
||||
@@ -28,7 +31,12 @@ public class AddressUtils
|
||||
|
||||
try
|
||||
{
|
||||
String rspStr = HttpUtils.sendGet(IP_URL, "ip=" + ip + "&json=true", "GBK");
|
||||
|
||||
Map<String,Object> params = new HashMap<>();
|
||||
params.put("ip",ip);
|
||||
params.put("json",true);
|
||||
|
||||
String rspStr = HttpUtils.get(IP_URL, params, "GBK");
|
||||
if (StringUtils.isEmpty(rspStr))
|
||||
{
|
||||
log.error("获取地理位置异常 {}", ip);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
server:
|
||||
servlet:
|
||||
context-path: /api # 应用的访问路径
|
||||
context-path: /api # 应用的访问路径
|
||||
tomcat:
|
||||
uri-encoding: UTF-8 # URI编码
|
||||
accept-count: 1000 # 连接数满后的排队数
|
||||
@@ -16,4 +16,12 @@ spring:
|
||||
max-request-size: -1
|
||||
jackson:
|
||||
time-zone: "Asia/Shanghai"
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
|
||||
file:
|
||||
static-path: /static/file
|
||||
server-url: http://192.168.1.137:80/api
|
||||
|
||||
base-dir: D:/data
|
||||
container-dir: container
|
||||
temp-dir: temp
|
||||
@@ -3,8 +3,8 @@ username=sa
|
||||
password=zhang520..
|
||||
driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
|
||||
# url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3BoxOCR
|
||||
# username=sa
|
||||
# password=123456@aaa
|
||||
# driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
|
||||
#url=jdbc:sqlserver://127.0.0.1:1433;databaseName=G3BoxOCR
|
||||
#username=sa
|
||||
#password=123456@aaa
|
||||
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
@@ -0,0 +1,84 @@
|
||||
package cn.g3soft;
|
||||
|
||||
|
||||
import cn.g3soft.utils.HttpUtils;
|
||||
import cn.g3soft.utils.Result;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@SpringBootTest
|
||||
public class DEMO {
|
||||
@Test
|
||||
public void testHello() throws Exception {
|
||||
long startTime = System.nanoTime(); // 开始时间
|
||||
|
||||
String filePath = "D:\\100全关门-3\\20241005082220A664.jpg"; // 你的图片路径
|
||||
|
||||
byte[] fileBytes = Files.readAllBytes(Paths.get(filePath));
|
||||
|
||||
// String fileUrl = Base64.getEncoder().encodeToString(fileBytes);
|
||||
|
||||
String fileUrl = "http://g3hd.oss-cn-hangzhou.aliyuncs.com/g3hd/2026/03/28/1774665878210_960.jpg";
|
||||
|
||||
String requestUrl = "http://127.0.0.1:8867/ocr";
|
||||
|
||||
Map<String, Object> reqPayload = new HashMap<>();
|
||||
reqPayload.put("file", fileUrl);
|
||||
reqPayload.put("fileType", 1);
|
||||
reqPayload.put("visualize", false);
|
||||
|
||||
try {
|
||||
String response = HttpUtils.postJson(requestUrl, reqPayload);
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode root = mapper.readTree(response);
|
||||
|
||||
JsonNode ocrResults = root.path("result").path("ocrResults");
|
||||
if (!ocrResults.isArray() || ocrResults.isEmpty()) {
|
||||
System.out.println("空");
|
||||
}
|
||||
|
||||
String number = "";
|
||||
double maxScore = -1.0;
|
||||
|
||||
for (JsonNode item : ocrResults) {
|
||||
JsonNode pruned = item.path("prunedResult");
|
||||
JsonNode recTexts = pruned.path("rec_texts");
|
||||
JsonNode recScores = pruned.path("rec_scores");
|
||||
|
||||
for (int i = 0; i < recTexts.size(); i++) {
|
||||
double score = recScores.get(i).asDouble();
|
||||
if (score > maxScore) {
|
||||
maxScore = score;
|
||||
number = recTexts.get(i).asText();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("boxNumber", number);
|
||||
result.put("score", maxScore);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
long endTime = System.nanoTime(); // 结束时间
|
||||
long durationMs = (endTime - startTime) / 1_000_000;
|
||||
|
||||
System.out.println("耗时: " + durationMs + " ms");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user