文件复制(临时使用)

localizer
lzq 2025-10-22 16:56:58 +08:00
parent f3e5f3bba0
commit ca9a965519
5 changed files with 207 additions and 65 deletions

View File

@ -68,10 +68,11 @@ public class BizAuditConfigController {
/**
*
*
*/
@GetMapping("/copy")
public void copy() {
bizAuditConfigService.copy();
public R<Integer> copy(@RequestParam(required = false, defaultValue = "true") Boolean newTask) {
Integer totalSize = bizAuditConfigService.copy(newTask);
return R.success(totalSize);
}
}

View File

@ -9,6 +9,9 @@ import com.njzscloud.supervisory.biz.pojo.result.SearchAuditConfigResult;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
*
*/
@ -20,4 +23,6 @@ public interface BizAuditConfigMapper extends BaseMapper<BizAuditConfigEntity> {
void modify(@Param("id") Long id, @Param("cityRole") String cityRole, @Param("areaRole") String areaRole);
String getAreaName(@Param("area") String area);
List<Map<String, Object>> listPicture();
}

View File

@ -1,16 +1,23 @@
package com.njzscloud.supervisory.biz.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.tuple.Tuple2;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.supervisory.biz.mapper.BizAuditConfigMapper;
@ -22,7 +29,12 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
*
@ -32,6 +44,29 @@ import java.util.List;
@RequiredArgsConstructor
public class BizAuditConfigService extends ServiceImpl<BizAuditConfigMapper, BizAuditConfigEntity> implements IService<BizAuditConfigEntity> {
private final AppProperties appProperties;
// 1. 配置线程池核心线程数100最大线程数100控制并发量
// 队列使用SynchronousQueue避免任务堆积若任务过多可改用有界队列
ThreadPoolExecutor executor = null;
OSS oss1 = null;
OSS oss2 = null;
AtomicInteger t = new AtomicInteger();
AtomicInteger s = new AtomicInteger();
AtomicInteger e = new AtomicInteger();
public static String uploadFile(OSS oss, String objectName, String contentType, InputStream inputStream) {
ObjectMetadata objectMetadata = new ObjectMetadata();
if (StrUtil.isNotBlank(contentType)) objectMetadata.setContentType(contentType);
oss.putObject("czxcsy-cdn", objectName, inputStream, objectMetadata);
return "/" + "czxcsy-cdn" + "/" + objectName;
}
public static Tuple2<InputStream, String> obtainFile(OSS oss, String bucketName, String objectName) {
OSSObject response = oss.getObject(new GetObjectRequest(bucketName, objectName));
ObjectMetadata objectMetadata = response.getObjectMetadata();
String contentType = objectMetadata.getContentType();
InputStream objectContent = response.getObjectContent();
return Tuple2.create(objectContent, contentType);
}
/**
*
@ -109,70 +144,130 @@ public class BizAuditConfigService extends ServiceImpl<BizAuditConfigMapper, Biz
.build();
}
/* public static String uploadFile(OSS oss,String objectName, String contentType, InputStream inputStream) {
public Integer copy(boolean newTask) {
if (executor == null) {
executor = new ThreadPoolExecutor(
100, // 核心线程数
100, // 最大线程数控制同时运行的线程数不超过100
60L, // 空闲线程存活时间
TimeUnit.SECONDS,
new SynchronousQueue<>(), // 无缓冲队列,直接提交任务给线程
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy() // 任务满时,让提交者线程执行(避免任务丢失)
);
}
if (oss1 == null) {
oss1 = oss(
"LTAI5tJJu2WayYchExrT5W1E",
"zllX0ZJ1EwsZXT6dE6swCLgTF4ImGg",
"oss-cn-shanghai.aliyuncs.com",
"cn-shanghai"
);
}
/*
zsy@1088358182388648.onaliyun.com
AccessKey ID LTAI5t96qDgWDzu5rSRHUttZ
AccessKey Secret GS9wh0stna11POzBXG7kzh0lKYvhkg
*/
if (oss2 == null) {
oss2 = oss(
"LTAI5t96qDgWDzu5rSRHUttZ",
"GS9wh0stna11POzBXG7kzh0lKYvhkg",
"oss-cn-shanghai.aliyuncs.com",
"cn-shanghai"
);
}
FileUtil.del("D:/ProJects/IdeaProjects/njzscloud/logs/error.txt");
List<String> dataList = listPicture(newTask);
int totalSize = dataList.size();
log.info("总共有 {} 条数据", totalSize);
int batchSize = 5;
totalSize = Math.min(totalSize, 10);
t.set(totalSize);
CountDownLatch latch = new CountDownLatch(totalSize);
// 3. 分片提交任务
for (int i = 0; i < totalSize; i += batchSize) {
// 计算当前分片的结束索引(避免越界)
int end = Math.min(i + batchSize, totalSize);
// 截取当前分片的子列表注意subList是原列表的视图非新集合
List<String> batch = dataList.subList(i, end);
// 提交任务到线程池
executor.submit(() -> {
// 处理当前分片的所有元素
for (String picture : batch) {
processElement(picture);
latch.countDown();
}
});
}
new Thread(() -> {
try {
latch.await();
log.info("所有任务完成,总共 {} 条,成功 {} 条,失败 {} 条", t.get(), s.get(), e.get());
} catch (InterruptedException e) {
log.error("等待任务完成时被中断", e);
}
}).start();
return totalSize;
}
void processElement(String picture) {
try {
ObjectMetadata objectMetadata = new ObjectMetadata();
if (StrUtil.isNotBlank(contentType)) objectMetadata.setContentType(contentType);
oss.putObject("cdn-zsy", objectName, inputStream, objectMetadata);
return "/" + "cdn-zsy" + "/" + objectName;
} catch (OSSException oe) {
log.error("阿里云上传文件失败,错误信息:{}、错误码:{}、请求标识:{}、主机标识:{}、存储桶:{}、对象名称:{}",
oe.getErrorMessage(),
oe.getErrorCode(),
oe.getRequestId(),
oe.getHostId(),
BUCKET_NAME,
objectName);
throw Exceptions.error("文件服务器错误");
} catch (ClientException ce) {
log.error("阿里云上传文件失败,错误信息:{}、存储桶:{}、对象名称:{}",
ce.getMessage(),
BUCKET_NAME,
objectName);
throw Exceptions.error("文件服务器错误");
if (!picture.startsWith("/cdn-zsy/")) {
e.incrementAndGet();
log.error("文件 {} 不是以 /cdn-zsy/ 开头", picture);
recodeError(picture);
return;
}
String[] split = picture.split("/cdn-zsy/");
Tuple2<InputStream, String> tuple2 = obtainFile(oss1, "cdn-zsy", split[1]);
uploadFile(oss2, split[1], tuple2.get_1(), tuple2.get_0());
s.incrementAndGet();
} catch (Exception ex) {
e.incrementAndGet();
log.error("复制文件失败: {}", picture);
recodeError(picture);
}
}
public static Tuple2<InputStream, String> obtainFile(OSS oss,String bucketName, String objectName) {
try {
OSSObject response = CLIENT.getObject(new GetObjectRequest(bucketName, objectName));
ObjectMetadata objectMetadata = response.getObjectMetadata();
String contentType = objectMetadata.getContentType();
InputStream objectContent = response.getObjectContent();
return Tuple2.create(objectContent, contentType);
} catch (OSSException oe) {
log.error("阿里云下载文件失败,错误信息:{}、错误码:{}、请求标识:{}、主机标识:{}、存储桶:{}、对象名称:{}",
oe.getErrorMessage(),
oe.getErrorCode(),
oe.getRequestId(),
oe.getHostId(),
bucketName,
objectName);
// throw Exceptions.error("文件服务器错误");
} catch (ClientException ce) {
log.error("阿里云下载文件失败,错误信息:{}、存储桶:{}、对象名称:{}",
ce.getMessage(),
bucketName,
objectName);
// throw Exceptions.error("文件服务器错误");
}
return Tuple2.create(new ByteArrayInputStream(new byte[0]), "");
} */
public void copy() {
OSS oss1 = oss(
"LTAI5tJJu2WayYchExrT5W1E",
"zllX0ZJ1EwsZXT6dE6swCLgTF4ImGg",
"oss-cn-shanghai.aliyuncs.com",
"cn-shanghai"
);
OSS oss2 = oss(
"LTAI5tJJu2WayYchExrT5W1E",
"zllX0ZJ1EwsZXT6dE6swCLgTF4ImGg",
"oss-cn-shanghai.aliyuncs.com",
"cn-shanghai"
);
synchronized void recodeError(String picture) {
FileUtil.writeLines(Collections.singletonList(picture), "D:/ProJects/IdeaProjects/njzscloud/logs/error.txt", StandardCharsets.UTF_8, true);
}
List<String> listPicture(boolean newTask) {
if (newTask) {
List<Map<String, Object>> list = baseMapper.listPicture();
Set<String> strings = new HashSet<>();
for (Map<String, Object> map : list) {
if (CollUtil.isEmpty(map)) continue;
String p1 = (String) map.get("p1");
if (StrUtil.isNotBlank(p1)) strings.add(p1);
String p2 = (String) map.get("p2");
if (StrUtil.isNotBlank(p2)) strings.add(p2);
String p3 = (String) map.get("p3");
if (StrUtil.isNotBlank(p3)) strings.add(p3);
String p4 = (String) map.get("p4");
if (StrUtil.isNotBlank(p4)) strings.add(p4);
JSONArray p5 = (JSONArray) map.get("p5");
if (CollUtil.isNotEmpty(p5)) strings.addAll(p5.toJavaList(String.class));
JSONArray p6 = (JSONArray) map.get("p6");
if (CollUtil.isNotEmpty(p6)) strings.addAll(p6.toJavaList(String.class));
JSONArray p7 = (JSONArray) map.get("p7");
if (CollUtil.isNotEmpty(p7)) strings.addAll(p7.toJavaList(String.class));
}
return strings.stream().filter(StrUtil::isNotBlank).collect(Collectors.toList());
} else {
return FileUtil.readLines("D:/ProJects/IdeaProjects/njzscloud/logs/error.txt", StandardCharsets.UTF_8);
}
}
}

View File

@ -26,6 +26,7 @@ spring:
- /payment/wechat/notify
- /payment/wechat/refundNotify
- /district/areaList
- /biz_audit_config/copy
app:
default-place:
province: 320000

View File

@ -26,4 +26,44 @@
FROM sys_district
WHERE id = #{area}
</select>
<select id="listPicture" resultType="java.util.Map">
SELECT business_license p1, NULL p2, NULL p3, NULL p4, NULL p5, NULL p6, NULL p7
FROM biz_company
WHERE deleted = 0
UNION ALL
SELECT driving_licence p1, NULL p2, NULL p3, NULL p4, NULL p5, NULL p6, NULL p7
FROM biz_driver
WHERE deleted = 0
UNION ALL
SELECT picture p1, NULL p2, NULL p3, NULL p4, NULL p5, NULL p6, NULL p7
FROM bulletin
WHERE deleted = 0
UNION ALL
SELECT picture p1, NULL p2, NULL p3, NULL p4, NULL p5, NULL p6, NULL p7
FROM goods_category
WHERE deleted = 0
UNION ALL
SELECT picture p1, NULL p2, NULL p3, NULL p4, NULL p5, NULL p6, NULL p7
FROM goods_info
WHERE deleted = 0
UNION ALL
SELECT cover p1, pdf_url p2, video_url p3, NULL p4, NULL p5, NULL p6, NULL p7
FROM operation_manual
WHERE deleted = 0
UNION ALL
SELECT picture p1, NULL p2, NULL p3, NULL p4, truck_license p5, qualification p6, NULL p7
FROM biz_truck
WHERE deleted = 0
UNION ALL
SELECT b.in_body_photo p1,
b.in_front_photo p2,
b.out_body_photo p3,
b.out_front_photo p4,
a.cargo_photo p5,
a.check_photo p6,
a.site_photos p7
FROM order_info a
INNER JOIN order_car_in_out b ON b.id = a.car_in_out_id
WHERE a.deleted = 0
</select>
</mapper>