|
|
|
@ -1,9 +1,13 @@
|
|
|
|
|
package hw.tagApi.service.service.impl;
|
|
|
|
|
|
|
|
|
|
import hw.tagApi.common.utils.uuid.IdGenerator;
|
|
|
|
|
import hw.tagApi.service.service.IHwTagRecordService;
|
|
|
|
|
import hw.tagApi.service.service.IKDocsService;
|
|
|
|
|
import hw.tagApi.service.utils.httpClientUtils;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
|
import org.springframework.http.*;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import org.springframework.web.client.RestTemplate;
|
|
|
|
|
import org.springframework.web.util.UriComponentsBuilder;
|
|
|
|
|
|
|
|
|
@ -15,6 +19,7 @@ import java.util.ArrayList;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.concurrent.*;
|
|
|
|
|
|
|
|
|
|
import hw.tagApi.service.constant.ApiConstants;
|
|
|
|
|
import hw.tagApi.service.mapper.HwTagRecordMapper;
|
|
|
|
@ -22,11 +27,9 @@ import hw.tagApi.service.domain.HwTagRecord;
|
|
|
|
|
import hw.tagApi.common.utils.poi.TagExcelUtil;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
import org.apache.http.HttpEntity;
|
|
|
|
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
|
|
|
|
import org.apache.http.client.methods.HttpGet;
|
|
|
|
|
import org.apache.http.impl.client.CloseableHttpClient;
|
|
|
|
|
import org.apache.http.util.EntityUtils;
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
import hw.tagApi.service.domain.ApiResponse;
|
|
|
|
|
import hw.tagApi.service.domain.ApiContent;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 云文档服务实现类
|
|
|
|
@ -35,137 +38,187 @@ import org.apache.http.util.EntityUtils;
|
|
|
|
|
* @date 2025-04-15
|
|
|
|
|
*/
|
|
|
|
|
@Service
|
|
|
|
|
public class KDocsServiceImpl implements IKDocsService
|
|
|
|
|
{
|
|
|
|
|
public class KDocsServiceImpl implements IKDocsService {
|
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(KDocsServiceImpl.class);
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private HwTagRecordMapper hwTagRecordMapper;
|
|
|
|
|
private IHwTagRecordService tagRecordService;
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
private CloseableHttpClient httpClient;
|
|
|
|
|
private static final int BATCH_SIZE = 100;
|
|
|
|
|
|
|
|
|
|
private static final int BATCH_SIZE = 10;
|
|
|
|
|
private List<HwTagRecord> batchList = new ArrayList<>();
|
|
|
|
|
// 创建线程池
|
|
|
|
|
private static final ExecutorService executorService = new ThreadPoolExecutor(
|
|
|
|
|
5, // 核心线程数
|
|
|
|
|
10, // 最大线程数
|
|
|
|
|
60L, // 空闲线程存活时间
|
|
|
|
|
TimeUnit.SECONDS, // 时间单位
|
|
|
|
|
new LinkedBlockingQueue<>(100), // 任务队列
|
|
|
|
|
new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略:由调用线程处理
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 导入数据列表
|
|
|
|
|
*
|
|
|
|
|
* @param contentList 包含导入数据的ApiContent对象列表
|
|
|
|
|
* @return 初始响应的ApiContent对象列表
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public String importData(String url) {
|
|
|
|
|
public List<ApiContent> importDataList(List<ApiContent> contentList) {
|
|
|
|
|
List<ApiContent> resApiContentList = getApiContents(contentList);
|
|
|
|
|
|
|
|
|
|
// 异步执行导入任务
|
|
|
|
|
executorService.execute(() -> {
|
|
|
|
|
List<ApiContent> resList = new ArrayList<>();
|
|
|
|
|
for (ApiContent apiContent : contentList) {
|
|
|
|
|
ApiContent resContent = new ApiContent();
|
|
|
|
|
resContent.setId(apiContent.getId());
|
|
|
|
|
try {
|
|
|
|
|
ApiContent result = this.importData(apiContent);
|
|
|
|
|
// 更新响应内容
|
|
|
|
|
resContent.setFields(result.getFields());
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("导入任务执行失败: {}", e.getMessage(), e);
|
|
|
|
|
Map<String, String> errorFields = new HashMap<>();
|
|
|
|
|
errorFields.put(ApiConstants.IMPORT_STATUS, "系统错误");
|
|
|
|
|
errorFields.put(ApiConstants.DESCRIPTION, "导入任务执行失败: " + e.getMessage());
|
|
|
|
|
resContent.setFields(errorFields);
|
|
|
|
|
}
|
|
|
|
|
resList.add(resContent);
|
|
|
|
|
}
|
|
|
|
|
// 发送处理结果到回调接口
|
|
|
|
|
httpClientUtils.sendResultToCallback(resList);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return resApiContentList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建初始响应的ApiContent对象列表
|
|
|
|
|
*
|
|
|
|
|
* @param contentList 包含导入数据的ApiContent对象列表
|
|
|
|
|
* @return 初始响应的ApiContent对象列表
|
|
|
|
|
*/
|
|
|
|
|
private static List<ApiContent> getApiContents(List<ApiContent> contentList) {
|
|
|
|
|
List<ApiContent> resApiContentList = new ArrayList<>();
|
|
|
|
|
for (ApiContent apiContent : contentList) {
|
|
|
|
|
// 创建初始响应
|
|
|
|
|
Map<String, String> resFields = new HashMap<>();
|
|
|
|
|
resFields.put(ApiConstants.IMPORT_STATUS, "导入中");
|
|
|
|
|
resFields.put(ApiConstants.DESCRIPTION, "后台处理中");
|
|
|
|
|
ApiContent responseContent = new ApiContent();
|
|
|
|
|
responseContent.setId(apiContent.getId());
|
|
|
|
|
responseContent.setFields(resFields);
|
|
|
|
|
resApiContentList.add(responseContent);
|
|
|
|
|
}
|
|
|
|
|
return resApiContentList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 导入数据
|
|
|
|
|
*
|
|
|
|
|
* @param apiContent 包含导入数据的ApiContent对象
|
|
|
|
|
* @return 处理后的ApiContent对象
|
|
|
|
|
*/
|
|
|
|
|
public ApiContent importData(ApiContent apiContent) {
|
|
|
|
|
Map<String, String> fields = apiContent.getFields();
|
|
|
|
|
String importMode = fields.get("导入模式");
|
|
|
|
|
String model = fields.getOrDefault("型号", "");
|
|
|
|
|
String fileUrl = fields.get("文件链接");
|
|
|
|
|
List<HwTagRecord> batchList = new ArrayList<>();
|
|
|
|
|
Map<String, String> resFields = new HashMap<>();
|
|
|
|
|
apiContent.setFields(resFields);
|
|
|
|
|
try {
|
|
|
|
|
log.info("开始从金山文档下载Excel文件: {}", url);
|
|
|
|
|
|
|
|
|
|
// 创建HttpGet请求
|
|
|
|
|
HttpGet httpGet = new HttpGet(url);
|
|
|
|
|
httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
|
|
|
|
|
httpGet.setHeader("Accept", "*/*");
|
|
|
|
|
httpGet.setHeader("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8");
|
|
|
|
|
httpGet.setHeader("Connection", "keep-alive");
|
|
|
|
|
|
|
|
|
|
// 执行请求
|
|
|
|
|
try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
|
|
|
|
|
// 获取响应状态码
|
|
|
|
|
int statusCode = response.getStatusLine().getStatusCode();
|
|
|
|
|
if (statusCode != 200) {
|
|
|
|
|
log.error("从金山文档获取文件失败,响应码: {}", statusCode);
|
|
|
|
|
return ApiConstants.SYSTEM_ERROR;
|
|
|
|
|
log.info("开始处理文件,URL: {}", fileUrl);
|
|
|
|
|
|
|
|
|
|
// 获取文件字节数组
|
|
|
|
|
byte[] fileData = httpClientUtils.getByteArrayFromUrl(fileUrl);
|
|
|
|
|
if (fileData == null) {
|
|
|
|
|
log.error("获取文件失败");
|
|
|
|
|
resFields.put(ApiConstants.IMPORT_STATUS, "系统错误");
|
|
|
|
|
resFields.put(ApiConstants.DESCRIPTION, "获取文件失败");
|
|
|
|
|
return apiContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 解析Excel数据
|
|
|
|
|
try (ByteArrayInputStream bis = new ByteArrayInputStream(fileData)) {
|
|
|
|
|
Map<String, Object> excelResult = TagExcelUtil.parseTagExcel(bis);
|
|
|
|
|
if (!excelResult.containsKey("tagList")) {
|
|
|
|
|
log.error("解析Excel文件失败,未找到标签数据");
|
|
|
|
|
resFields.put(ApiConstants.IMPORT_STATUS, "导入失败");
|
|
|
|
|
resFields.put(ApiConstants.DESCRIPTION, "解析Excel文件失败,未找到标签数据");
|
|
|
|
|
return apiContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取响应实体
|
|
|
|
|
HttpEntity entity = response.getEntity();
|
|
|
|
|
if (entity == null) {
|
|
|
|
|
log.error("无法从金山文档获取文件或文件为空");
|
|
|
|
|
return ApiConstants.SYSTEM_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将响应实体转换为字节数组
|
|
|
|
|
byte[] fileData = EntityUtils.toByteArray(entity);
|
|
|
|
|
|
|
|
|
|
if (fileData.length == 0) {
|
|
|
|
|
log.error("无法从金山文档获取文件或文件为空");
|
|
|
|
|
return ApiConstants.SYSTEM_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 直接使用字节流处理Excel数据
|
|
|
|
|
Map<String, Object> excelResult;
|
|
|
|
|
try (ByteArrayInputStream bis = new ByteArrayInputStream(fileData)) {
|
|
|
|
|
excelResult = TagExcelUtil.parseTagExcel(bis);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 获取订单信息
|
|
|
|
|
Map<String, String> orderInfo = (Map<String, String>) excelResult.get("orderInfo");
|
|
|
|
|
String orderNo = orderInfo.get("orderNo");
|
|
|
|
|
String batchNo = orderInfo.get("batchNo");
|
|
|
|
|
String operatorId = orderInfo.get("operatorId");
|
|
|
|
|
String processTime = orderInfo.get("processTime");
|
|
|
|
|
|
|
|
|
|
log.info("解析订单信息 - 订单号: {}, 批次号: {}, 操作员: {}", orderNo, batchNo, operatorId);
|
|
|
|
|
|
|
|
|
|
// 获取标签数据列表
|
|
|
|
|
List<Map<String, String>> tagList = (List<Map<String, String>>) excelResult.get("tagList");
|
|
|
|
|
|
|
|
|
|
// 批量处理标签数据
|
|
|
|
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
for (Map<String, String> tagData : tagList) {
|
|
|
|
|
HwTagRecord record = new HwTagRecord();
|
|
|
|
|
record.setOrderCode(orderNo);
|
|
|
|
|
record.setBatchNumber(batchNo);
|
|
|
|
|
record.setOperatorId(operatorId);
|
|
|
|
|
record.setProcessingTime(sdf.parse(processTime));
|
|
|
|
|
|
|
|
|
|
record.setOrderCode(orderInfo.get("orderNo"));
|
|
|
|
|
record.setBatchNumber(orderInfo.get("batchNo"));
|
|
|
|
|
record.setOperatorId(orderInfo.get("operatorId"));
|
|
|
|
|
record.setProcessingTime(sdf.parse(orderInfo.get("processTime")));
|
|
|
|
|
// 设置标签数据
|
|
|
|
|
record.setEpc(tagData.get("EPC"));
|
|
|
|
|
record.settId(tagData.get("TID"));
|
|
|
|
|
record.setModelCode(model);
|
|
|
|
|
record.setTagSequence(tagData.get("序号"));
|
|
|
|
|
|
|
|
|
|
// 添加到批处理列表
|
|
|
|
|
batchList.add(record);
|
|
|
|
|
|
|
|
|
|
record.settId(tagData.get("TID"));
|
|
|
|
|
record.setEpc(tagData.get("EPC"));
|
|
|
|
|
record.setPassword(tagData.get("密码"));
|
|
|
|
|
record.setFields1(tagData.get("测试结果"));
|
|
|
|
|
record.setFields2(tagData.get("测试值"));
|
|
|
|
|
record.setFields3(tagData.get("参考值"));
|
|
|
|
|
record.setRemark(tagData.get("测试时间"));
|
|
|
|
|
|
|
|
|
|
// 达到批量大小时执行插入
|
|
|
|
|
if ("更新".equals(importMode)) {
|
|
|
|
|
tagRecordService.updateHwTagRecordByTID(record);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 添加到批处理列表
|
|
|
|
|
record.setrId(IdGenerator.nextId());
|
|
|
|
|
batchList.add(record);
|
|
|
|
|
if (batchList.size() >= BATCH_SIZE) {
|
|
|
|
|
hwTagRecordMapper.batchInsertHwTagRecord(batchList);
|
|
|
|
|
tagRecordService.batchInsertHwTagRecord(batchList);
|
|
|
|
|
log.info("批量插入{}条数据成功", batchList.size());
|
|
|
|
|
batchList.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 处理剩余的数据
|
|
|
|
|
if (!batchList.isEmpty()) {
|
|
|
|
|
hwTagRecordMapper.batchInsertHwTagRecord(batchList);
|
|
|
|
|
tagRecordService.batchInsertHwTagRecord(batchList);
|
|
|
|
|
log.info("批量插入剩余{}条数据成功", batchList.size());
|
|
|
|
|
batchList.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return getSystemStatus();
|
|
|
|
|
resFields.put(ApiConstants.IMPORT_STATUS, "导入完成");
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("导入数据失败: {}", e.getMessage(), e);
|
|
|
|
|
return ApiConstants.SYSTEM_ERROR;
|
|
|
|
|
log.error("处理文件失败: {}", e.getMessage(), e);
|
|
|
|
|
resFields.put(ApiConstants.IMPORT_STATUS, "系统错误");
|
|
|
|
|
resFields.put(ApiConstants.DESCRIPTION, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return apiContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getSystemStatus() {
|
|
|
|
|
Map<String, Object> response = new HashMap<>();
|
|
|
|
|
response.put("CASE", ApiConstants.DATA_IMPORT);
|
|
|
|
|
|
|
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
Map<String, Object> statusItem = new HashMap<>();
|
|
|
|
|
Map<String, String> statusFields = new HashMap<>();
|
|
|
|
|
statusFields.put("导入状态", ApiConstants.IMPORTING);
|
|
|
|
|
statusItem.put("fields", statusFields);
|
|
|
|
|
statusItem.put("id", "16");
|
|
|
|
|
result.add(statusItem);
|
|
|
|
|
|
|
|
|
|
Map<String, Object> errorItem = new HashMap<>();
|
|
|
|
|
Map<String, String> errorFields = new HashMap<>();
|
|
|
|
|
errorFields.put("导入模式", ApiConstants.SYSTEM_ERROR);
|
|
|
|
|
errorFields.put("情况说明", "");
|
|
|
|
|
errorItem.put("fields", errorFields);
|
|
|
|
|
errorItem.put("id", "s5");
|
|
|
|
|
result.add(errorItem);
|
|
|
|
|
|
|
|
|
|
response.put("RESULT", result);
|
|
|
|
|
return null;
|
|
|
|
|
try {
|
|
|
|
|
ApiResponse response = new ApiResponse();
|
|
|
|
|
response.setCaseCode("10");
|
|
|
|
|
// 添加导入模式信息
|
|
|
|
|
ApiContent modeContent = new ApiContent();
|
|
|
|
|
Map<String, String> modeFields = new HashMap<>();
|
|
|
|
|
modeFields.put(ApiConstants.DESCRIPTION, "");
|
|
|
|
|
// 使用ObjectMapper将对象转换为JSON字符串
|
|
|
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
|
|
|
return mapper.writeValueAsString(response);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
log.error("生成系统状态响应失败", e);
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|