|
@ -0,0 +1,587 @@ |
|
|
|
|
|
package com.ruoyi.business.controller; |
|
|
|
|
|
|
|
|
|
|
|
import cn.cttic.crypto.bean.DecryptCodeBean; |
|
|
|
|
|
import cn.cttic.crypto.bean.EncryptCodeBean; |
|
|
|
|
|
import cn.cttic.crypto.bean.EncryptCrcBean; |
|
|
|
|
|
import cn.cttic.crypto.service.SMCryptoService; |
|
|
|
|
|
import cn.cttic.crypto.service.impl.SMCryptoServiceImpl; |
|
|
|
|
|
import cn.hutool.core.date.StopWatch; |
|
|
|
|
|
import com.google.gson.Gson; |
|
|
|
|
|
import com.fasterxml.jackson.core.type.TypeReference; |
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper; |
|
|
|
|
|
import com.ruoyi.business.constant.BusinessServiceEnum; |
|
|
|
|
|
import com.ruoyi.business.domain.*; |
|
|
|
|
|
import com.ruoyi.business.domain.vo.*; |
|
|
|
|
|
import com.ruoyi.business.service.IAdapterService; |
|
|
|
|
|
import com.ruoyi.business.service.IServiceBusinessService; |
|
|
|
|
|
import com.ruoyi.common.core.domain.vo.TransportHeader; |
|
|
|
|
|
import com.ruoyi.common.core.domain.vo.TransportRequest; |
|
|
|
|
|
import com.ruoyi.common.core.domain.vo.TransportRequestInfo; |
|
|
|
|
|
import com.ruoyi.common.core.domain.vo.TransportResponse; |
|
|
|
|
|
import com.ruoyi.common.core.exception.BusinessException; |
|
|
|
|
|
import com.ruoyi.common.core.exception.TransportException; |
|
|
|
|
|
import com.ruoyi.common.core.utils.ServletUtils; |
|
|
|
|
|
import com.ruoyi.common.core.web.domain.AjaxResult; |
|
|
|
|
|
import com.ruoyi.system.service.ISysDictDataService; |
|
|
|
|
|
import lombok.RequiredArgsConstructor; |
|
|
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
|
|
import okhttp3.OkHttpClient; |
|
|
|
|
|
import okhttp3.Request; |
|
|
|
|
|
import okhttp3.RequestBody; |
|
|
|
|
|
import okhttp3.Response; |
|
|
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
import org.springframework.http.*; |
|
|
|
|
|
import org.springframework.validation.annotation.Validated; |
|
|
|
|
|
import org.springframework.web.bind.annotation.GetMapping; |
|
|
|
|
|
import org.springframework.web.bind.annotation.RequestMapping; |
|
|
|
|
|
import org.springframework.web.bind.annotation.RequestParam; |
|
|
|
|
|
import org.springframework.web.bind.annotation.RestController; |
|
|
|
|
|
|
|
|
|
|
|
import javax.sql.DataSource; |
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
|
import java.sql.Connection; |
|
|
|
|
|
import java.sql.PreparedStatement; |
|
|
|
|
|
import java.sql.ResultSet; |
|
|
|
|
|
import java.sql.SQLException; |
|
|
|
|
|
import java.time.LocalDateTime; |
|
|
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
|
|
import java.util.*; |
|
|
|
|
|
import java.util.concurrent.ExecutorService; |
|
|
|
|
|
import java.util.concurrent.Executors; |
|
|
|
|
|
import java.util.concurrent.Future; |
|
|
|
|
|
import java.util.concurrent.atomic.AtomicLong; |
|
|
|
|
|
import com.alibaba.fastjson.*; |
|
|
|
|
|
|
|
|
|
|
|
import static com.ruoyi.common.core.constant.Constants.DELETE_NO; |
|
|
|
|
|
import static com.ruoyi.common.core.constant.HttpStatus.UNAUTHORIZED; |
|
|
|
|
|
import static com.ruoyi.common.core.web.domain.AjaxResult.success; |
|
|
|
|
|
|
|
|
|
|
|
@Slf4j |
|
|
|
|
|
@Validated |
|
|
|
|
|
@RestController |
|
|
|
|
|
@RequestMapping("/inBusiness") |
|
|
|
|
|
@RequiredArgsConstructor |
|
|
|
|
|
public class InBusinessController { |
|
|
|
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(InBusinessController.class); |
|
|
|
|
|
|
|
|
|
|
|
// 配置参数 |
|
|
|
|
|
private static final String API_ENDPOINT = "https://xcx.12328.cn:8086/min12328"; |
|
|
|
|
|
private static final String PROVINCE_AREA_CODE = "500000"; // 行政区划代码 |
|
|
|
|
|
private static final String BASE_AREA_CODE = "999999"; // 基础系统标识 |
|
|
|
|
|
private static final DateTimeFormatter DATE_FORMATTER = |
|
|
|
|
|
DateTimeFormatter.ofPattern("yyyyMMddHHmmss"); |
|
|
|
|
|
private static final String encrypt_key = "8iot1blDJgNK36Do"; // 行政区划代码 |
|
|
|
|
|
private static final String decrypt_key = "QLdQIASYMlT9SUUg"; |
|
|
|
|
|
private final OkHttpClient httpClient = new OkHttpClient(); |
|
|
|
|
|
private final Gson gson = new Gson(); |
|
|
|
|
|
private final AtomicLong sequence = new AtomicLong(1); |
|
|
|
|
|
// 新增字段 |
|
|
|
|
|
private long tokenExpirationTime; |
|
|
|
|
|
private static final long TOKEN_TTL = 24 * 60 * 60 * 1000; // 24小时毫秒数 |
|
|
|
|
|
// 新增加密服务实例(在类顶部) |
|
|
|
|
|
private final SMCryptoService smCryptoService = new SMCryptoServiceImpl(); |
|
|
|
|
|
|
|
|
|
|
|
private final DataSource dataSource; |
|
|
|
|
|
private final ISysDictDataService sysDictDataService; |
|
|
|
|
|
private final IAdapterService adapterService; |
|
|
|
|
|
private final IServiceBusinessService serviceBusinessService; |
|
|
|
|
|
|
|
|
|
|
|
// @InnerAuth |
|
|
|
|
|
@GetMapping |
|
|
|
|
|
public AjaxResult inBusiness(@RequestParam("exchangeResolveId") Long id) throws Exception { |
|
|
|
|
|
StopWatch sw = StopWatch.create("sw"); |
|
|
|
|
|
sw.start(); |
|
|
|
|
|
|
|
|
|
|
|
// 获取请求头中的currentToken字段 |
|
|
|
|
|
HttpHeaders reqHeaders = new HttpHeaders(); |
|
|
|
|
|
reqHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); |
|
|
|
|
|
String auth = ServletUtils.getHeader(HttpHeaders.AUTHORIZATION); |
|
|
|
|
|
String currentToken = ""; |
|
|
|
|
|
if (auth == null) { |
|
|
|
|
|
throw new BusinessException("认证失败", UNAUTHORIZED); |
|
|
|
|
|
} else { |
|
|
|
|
|
String prefix = "data_exchange_feign_"; |
|
|
|
|
|
currentToken = StringUtils.substringAfter(auth, prefix); |
|
|
|
|
|
} |
|
|
|
|
|
// 新增final副本用于lambda |
|
|
|
|
|
final String finalToken = currentToken; |
|
|
|
|
|
// 校验业务配置 |
|
|
|
|
|
ServiceBusiness serviceBusiness = serviceBusinessService.selectServiceBusinessById(id); |
|
|
|
|
|
if (serviceBusiness == null) { |
|
|
|
|
|
return AjaxResult.error("未找到对应的业务配置"); |
|
|
|
|
|
} |
|
|
|
|
|
// 调用数据库查询 |
|
|
|
|
|
AjaxResult ajaxResult = this.outQuery(id, serviceBusiness); |
|
|
|
|
|
if (!ajaxResult.isSuccess()) { |
|
|
|
|
|
return ajaxResult; |
|
|
|
|
|
} |
|
|
|
|
|
Object bodyData = ajaxResult.get("data"); |
|
|
|
|
|
if (bodyData == null) { |
|
|
|
|
|
return ajaxResult; |
|
|
|
|
|
} |
|
|
|
|
|
if (!(bodyData instanceof Map)) { |
|
|
|
|
|
return AjaxResult.error("响应数据格式异常"); |
|
|
|
|
|
} |
|
|
|
|
|
Map<String, Object> dataMap = (Map<String, Object>) bodyData; |
|
|
|
|
|
Object rows = dataMap.get("rows"); |
|
|
|
|
|
if (!(rows instanceof List)) { |
|
|
|
|
|
return AjaxResult.error("缺少有效的业务数据"); |
|
|
|
|
|
} |
|
|
|
|
|
List<?> rowsList = (List<?>) rows; |
|
|
|
|
|
|
|
|
|
|
|
// 获取remark信息 |
|
|
|
|
|
String urlSuffix = ""; |
|
|
|
|
|
JSONObject remarkJson = null; |
|
|
|
|
|
if (serviceBusiness.getRemark() != null) { |
|
|
|
|
|
try { |
|
|
|
|
|
// 解析 JSON 字符串 |
|
|
|
|
|
remarkJson = JSONObject.parseObject(serviceBusiness.getRemark()); |
|
|
|
|
|
// 提取 url 字段 |
|
|
|
|
|
urlSuffix = remarkJson.getString("url"); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
logger.error("解析 remark 字段失败", e); |
|
|
|
|
|
return AjaxResult.error("解析 remark 字段失败"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 新增final副本用于lambda |
|
|
|
|
|
final String finalUrlSuffix = urlSuffix; |
|
|
|
|
|
// 分批处理逻辑 |
|
|
|
|
|
int batchSize = 50; |
|
|
|
|
|
List<List<?>> batches = new ArrayList<>(); |
|
|
|
|
|
for (int i = 0; i < rowsList.size(); i += batchSize) { |
|
|
|
|
|
int end = Math.min(i + batchSize, rowsList.size()); |
|
|
|
|
|
batches.add(rowsList.subList(i, end)); |
|
|
|
|
|
} |
|
|
|
|
|
String[] tableParts = serviceBusiness.getTableName().split("_"); |
|
|
|
|
|
if (tableParts.length < 3) { |
|
|
|
|
|
return AjaxResult.error("表名格式不符合规范: " + serviceBusiness.getTableName()); |
|
|
|
|
|
} |
|
|
|
|
|
String ipcType = tableParts[1].toUpperCase(); // 提取中间部分并转为大写 |
|
|
|
|
|
// 替换为固定线程池(根据CPU核心数配置) |
|
|
|
|
|
int coreCount = Runtime.getRuntime().availableProcessors(); |
|
|
|
|
|
ExecutorService executor = Executors.newFixedThreadPool(coreCount * 2); |
|
|
|
|
|
|
|
|
|
|
|
List<Future<?>> futures = new ArrayList<>(); |
|
|
|
|
|
|
|
|
|
|
|
for (List<?> batch : batches) { |
|
|
|
|
|
futures.add(executor.submit(() -> { |
|
|
|
|
|
try { |
|
|
|
|
|
Map<String, Object> reqMap = new HashMap<>(); |
|
|
|
|
|
reqMap.put("recordInfo", batch); |
|
|
|
|
|
|
|
|
|
|
|
TransportRequest request = buildRequest(ipcType, reqMap, finalToken); |
|
|
|
|
|
logger.info("线程[{}] 请求报文:\n{}", Thread.currentThread().getId(), gson.toJson(request)); |
|
|
|
|
|
|
|
|
|
|
|
String responseJson = postRequest(request, finalUrlSuffix); |
|
|
|
|
|
TransportResponse response = parseResponse(responseJson); |
|
|
|
|
|
handleResponse(response, finalUrlSuffix); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
logger.error("线程处理异常", e); |
|
|
|
|
|
} |
|
|
|
|
|
})); |
|
|
|
|
|
} |
|
|
|
|
|
// 等待所有任务完成 |
|
|
|
|
|
for (Future<?> future : futures) { |
|
|
|
|
|
future.get(); |
|
|
|
|
|
} |
|
|
|
|
|
executor.shutdown(); |
|
|
|
|
|
return success(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 发送HTTP请求 |
|
|
|
|
|
private String postRequest(TransportRequest request, String urlSuffix) throws Exception { |
|
|
|
|
|
String json = gson.toJson(request); |
|
|
|
|
|
|
|
|
|
|
|
RequestBody body = RequestBody.create(json, okhttp3.MediaType.get("application/json")); |
|
|
|
|
|
Request httpRequest = new Request.Builder() |
|
|
|
|
|
.url(API_ENDPOINT + urlSuffix) |
|
|
|
|
|
.post(body) |
|
|
|
|
|
.build(); |
|
|
|
|
|
|
|
|
|
|
|
try (Response response = httpClient.newCall(httpRequest).execute()) { |
|
|
|
|
|
if (!response.isSuccessful()) { |
|
|
|
|
|
throw new TransportException("HTTP错误: " + response.code()); |
|
|
|
|
|
} |
|
|
|
|
|
return response.body().string(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 解析响应 |
|
|
|
|
|
private TransportResponse parseResponse(String json) { |
|
|
|
|
|
return gson.fromJson(json, TransportResponse.class); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理业务响应 |
|
|
|
|
|
private void handleResponse(TransportResponse response, String urlSuffix) throws TransportException { |
|
|
|
|
|
TransportHeader header = response.getHeader(); |
|
|
|
|
|
if (!"0000".equals(header.getCode())) { |
|
|
|
|
|
throw new TransportException("业务错误[" + header.getCode() + "]: " |
|
|
|
|
|
+ header.getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
// 更新Token |
|
|
|
|
|
if (response.getBody() != null && response.getBody() != "") { |
|
|
|
|
|
try { |
|
|
|
|
|
logger.info("返回的Body: {}", response.getBody()); |
|
|
|
|
|
logger.info("返回的Code: {}", header.getCode()); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
throw new RuntimeException(e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public AjaxResult outQuery(Long id, ServiceBusiness serviceBusiness) throws SQLException, IOException { |
|
|
|
|
|
|
|
|
|
|
|
JSONObject jsonObject = null; |
|
|
|
|
|
Map<String, Object> res = new HashMap<>(); |
|
|
|
|
|
List<Map<String, Object>> list; |
|
|
|
|
|
if (BusinessServiceEnum.custom.getCode().equals(serviceBusiness.getType())) { |
|
|
|
|
|
String queryField = serviceBusiness.getResultSql(); |
|
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
|
|
sb.append(queryField); |
|
|
|
|
|
|
|
|
|
|
|
String tableName = serviceBusiness.getTableName(); |
|
|
|
|
|
String lowerCaseQueryField = queryField.toLowerCase(); |
|
|
|
|
|
String lowerCaseTableName = tableName.toLowerCase(); |
|
|
|
|
|
|
|
|
|
|
|
String conditions = ""; |
|
|
|
|
|
int tableNameIndex = lowerCaseQueryField.indexOf(lowerCaseTableName); |
|
|
|
|
|
if (tableNameIndex != -1) { |
|
|
|
|
|
// Extract the part after the table name |
|
|
|
|
|
int startIndex = tableNameIndex + lowerCaseTableName.length(); |
|
|
|
|
|
conditions = queryField.substring(startIndex).trim(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
String sbCount = "select count(1) from " + tableName + " " + conditions; |
|
|
|
|
|
// String sbCount = "select count(1) from" + serviceBusiness.getTableName()+" "+queryField.toLowerCase().split(serviceBusiness.getTableName())[1]; |
|
|
|
|
|
//默认排序 |
|
|
|
|
|
// if (!queryField.toLowerCase().contains("order by")) { |
|
|
|
|
|
// sb.append(" order by id desc"); |
|
|
|
|
|
// } |
|
|
|
|
|
//分页 |
|
|
|
|
|
// sb.append(" limit ?,?"); |
|
|
|
|
|
log.debug("sb=" + sb); |
|
|
|
|
|
// ps:目前写死从mybatis-plus多数据源master取,后续匹配对应数据源 |
|
|
|
|
|
// Connection conn = databaseService.getConnection(serviceBusiness.getDatabaseId(), null); |
|
|
|
|
|
Connection conn = dataSource.getConnection(); |
|
|
|
|
|
PreparedStatement ps = conn.prepareStatement(sb.toString()); |
|
|
|
|
|
PreparedStatement psCount = conn.prepareStatement(sbCount); |
|
|
|
|
|
list = queryData(ps, 1, serviceBusiness, jsonObject); |
|
|
|
|
|
res.put("rows", list); |
|
|
|
|
|
int total = queryCount(psCount); |
|
|
|
|
|
res.put("total", total); |
|
|
|
|
|
ps.close(); |
|
|
|
|
|
conn.close(); |
|
|
|
|
|
} else if (BusinessServiceEnum.select.getCode().equals(serviceBusiness.getType())) { |
|
|
|
|
|
String queryField = serviceBusiness.getQueryField(); |
|
|
|
|
|
if (!StringUtils.isEmpty(queryField)) { |
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper(); |
|
|
|
|
|
List<OutQueryType> queryFieldList = objectMapper.readValue(queryField, new TypeReference<List<OutQueryType>>() { |
|
|
|
|
|
}); |
|
|
|
|
|
Map<String, OutQueryType> queryFieldMap = new HashMap<>(); |
|
|
|
|
|
for (OutQueryType queryType : queryFieldList) { |
|
|
|
|
|
queryFieldMap.put(queryType.getField(), queryType); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
|
|
StringBuilder sbCount = new StringBuilder(); |
|
|
|
|
|
sb.append("select "); |
|
|
|
|
|
sbCount.append("select count(1) from "); |
|
|
|
|
|
String resultField = serviceBusiness.getResultField(); |
|
|
|
|
|
if (!StringUtils.isEmpty(resultField)) { |
|
|
|
|
|
String[] split = resultField.split(","); |
|
|
|
|
|
Set<String> resFieldSet = new HashSet<>(Arrays.asList(split)); |
|
|
|
|
|
for (String resField : resFieldSet) { |
|
|
|
|
|
sb.append(resField); |
|
|
|
|
|
sb.append(","); |
|
|
|
|
|
} |
|
|
|
|
|
sb.deleteCharAt(sb.length() - 1); |
|
|
|
|
|
} else { |
|
|
|
|
|
sb.append("*"); |
|
|
|
|
|
} |
|
|
|
|
|
sb.append(" from "); |
|
|
|
|
|
sb.append(serviceBusiness.getTableName()); |
|
|
|
|
|
sbCount.append(serviceBusiness.getTableName()); |
|
|
|
|
|
// boolean hasWhere = false; |
|
|
|
|
|
// for (Map.Entry<String, OutQueryType> entry : queryFieldMap.entrySet()) { |
|
|
|
|
|
// if(jsonObject != null && StringUtils.isNotEmpty(jsonObject.getString(entry.getKey()))) { |
|
|
|
|
|
// if(hasWhere) { |
|
|
|
|
|
// sb.append(" and "); |
|
|
|
|
|
// sbCount.append(" and "); |
|
|
|
|
|
// } else { |
|
|
|
|
|
// sb.append(" where "); |
|
|
|
|
|
// sbCount.append(" where "); |
|
|
|
|
|
// hasWhere = true; |
|
|
|
|
|
// } |
|
|
|
|
|
// sb.append(entry.getKey()); |
|
|
|
|
|
// sbCount.append(entry.getKey()); |
|
|
|
|
|
// if(FieldTypeEnum.eq.getCode().equals(entry.getValue().getType())) { |
|
|
|
|
|
// sb.append(" = ?"); |
|
|
|
|
|
// sbCount.append(" = ?"); |
|
|
|
|
|
// } else if(FieldTypeEnum.like.getCode().equals(entry.getValue().getType())) { |
|
|
|
|
|
// sb.append(" like ?"); |
|
|
|
|
|
// sbCount.append(" like ?"); |
|
|
|
|
|
// } else if(FieldTypeEnum.dataRange.getCode().equals(entry.getValue().getType())) { |
|
|
|
|
|
// sb.append(" between ? and ?"); |
|
|
|
|
|
// sbCount.append(" between ? and ?"); |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
// sb.append(" order by id desc limit ?,?"); |
|
|
|
|
|
log.debug("sb=" + sb); |
|
|
|
|
|
// ps:目前写死从mybatis-plus多数据源master取,后续匹配对应数据源 |
|
|
|
|
|
// Connection conn = databaseService.getConnection(serviceBusiness.getDatabaseId(), null); |
|
|
|
|
|
Connection conn = dataSource.getConnection(); |
|
|
|
|
|
PreparedStatement ps = conn.prepareStatement(sb.toString()); |
|
|
|
|
|
PreparedStatement psCount = conn.prepareStatement(sbCount.toString()); |
|
|
|
|
|
int index = 1; |
|
|
|
|
|
// for (Map.Entry<String, OutQueryType> entry : queryFieldMap.entrySet()) { |
|
|
|
|
|
// if(jsonObject != null && StringUtils.isNotEmpty(jsonObject.getString(entry.getKey()))) { |
|
|
|
|
|
// if(FieldTypeEnum.eq.getCode().equals(entry.getValue().getType())) { |
|
|
|
|
|
// ps.setObject(index, jsonObject.get(entry.getKey())); |
|
|
|
|
|
// psCount.setObject(index, jsonObject.get(entry.getKey())); |
|
|
|
|
|
// index++; |
|
|
|
|
|
// } else if(FieldTypeEnum.like.getCode().equals(entry.getValue().getType())) { |
|
|
|
|
|
// ps.setObject(index, "%" + jsonObject.get(entry.getKey()) + "%"); |
|
|
|
|
|
// psCount.setObject(index, "%" + jsonObject.get(entry.getKey()) + "%"); |
|
|
|
|
|
// index++; |
|
|
|
|
|
// } else if(FieldTypeEnum.dataRange.getCode().equals(entry.getValue().getType())) { |
|
|
|
|
|
// String[] dateRangeSplit = jsonObject.getString(entry.getKey()).split(","); |
|
|
|
|
|
// ps.setObject(index, dateRangeSplit[0] + " 00:00:00"); |
|
|
|
|
|
// psCount.setObject(index, dateRangeSplit[0] + " 00:00:00"); |
|
|
|
|
|
// index++; |
|
|
|
|
|
// ps.setObject(index, dateRangeSplit[1] + " 23:59:59"); |
|
|
|
|
|
// psCount.setObject(index, dateRangeSplit[1] + " 23:59:59"); |
|
|
|
|
|
// index++; |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
// } |
|
|
|
|
|
list = queryData(ps, index, serviceBusiness, jsonObject); |
|
|
|
|
|
res.put("rows", list); |
|
|
|
|
|
int total = queryCount(psCount); |
|
|
|
|
|
res.put("total", total); |
|
|
|
|
|
ps.close(); |
|
|
|
|
|
conn.close(); |
|
|
|
|
|
} |
|
|
|
|
|
return success(res); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 调用查询,返回数据 |
|
|
|
|
|
* |
|
|
|
|
|
* @param ps PreparedStatement |
|
|
|
|
|
* @param index ps顺序 |
|
|
|
|
|
* @param serviceBusiness 业务服务 |
|
|
|
|
|
* @return List |
|
|
|
|
|
*/ |
|
|
|
|
|
private List<Map<String, Object>> queryData(PreparedStatement ps, int index, ServiceBusiness serviceBusiness, JSONObject jsonObject) throws SQLException { |
|
|
|
|
|
List<Map<String, Object>> list = new ArrayList<>(); |
|
|
|
|
|
DateTimeFormatter dfClock = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); |
|
|
|
|
|
// |
|
|
|
|
|
// convertSqlToPage(ps, index, jsonObject); |
|
|
|
|
|
// System.out.println("ps=" + transSql(ps)); |
|
|
|
|
|
// 处理JSONArray和JSONObject |
|
|
|
|
|
JSONObject remarkJson = null; |
|
|
|
|
|
// List<String> jsonArrayColumnList = new ArrayList<>(); |
|
|
|
|
|
List<String> jsonObjectColumnList = new ArrayList<>(); |
|
|
|
|
|
Map<String, String> jsonArrayColumnMap = new HashMap<>(); |
|
|
|
|
|
if (serviceBusiness.getRemark() != null) { |
|
|
|
|
|
try { |
|
|
|
|
|
// 解析 JSON 字符串 |
|
|
|
|
|
remarkJson = JSONObject.parseObject(serviceBusiness.getRemark()); |
|
|
|
|
|
// 提取 url 字段 |
|
|
|
|
|
// 提取 JSONArray 字段 |
|
|
|
|
|
String jsonArrayColumnStr = remarkJson.getString("JSONArray"); |
|
|
|
|
|
if (jsonArrayColumnStr != null && !jsonArrayColumnStr.isEmpty()) { |
|
|
|
|
|
String[] items = jsonArrayColumnStr.split(","); |
|
|
|
|
|
for (String item : items) { |
|
|
|
|
|
if (item.contains(":")) { |
|
|
|
|
|
String[] parts = item.split(":"); |
|
|
|
|
|
if (parts.length == 2) { |
|
|
|
|
|
jsonArrayColumnMap.put(parts[0], parts[1]); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
// 没有冒号时,使用默认字段名 value |
|
|
|
|
|
jsonArrayColumnMap.put(item, "value"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 提取 JSONObject 字段 |
|
|
|
|
|
String jsonObjectColumnStr = remarkJson.getString("JSONObject"); |
|
|
|
|
|
if (jsonObjectColumnStr != null && !jsonObjectColumnStr.isEmpty()) { |
|
|
|
|
|
jsonObjectColumnList = Arrays.asList(jsonObjectColumnStr.split(",")); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
logger.error("解析 remark 字段失败", e); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ResultSet rs = ps.executeQuery(); |
|
|
|
|
|
Adapter queryAdapter = new Adapter(); |
|
|
|
|
|
queryAdapter.setServiceBusinessId(serviceBusiness.getId()); |
|
|
|
|
|
queryAdapter.setStatus(DELETE_NO); |
|
|
|
|
|
List<Adapter> adapters = adapterService.selectAdapterList(queryAdapter); |
|
|
|
|
|
while (rs.next()) { |
|
|
|
|
|
int columnCount = rs.getMetaData().getColumnCount(); |
|
|
|
|
|
Map<String, Object> rowData = new HashMap<>(); |
|
|
|
|
|
for (int i = 1; i <= columnCount; i++) { |
|
|
|
|
|
String columnName = rs.getMetaData().getColumnLabel(i); |
|
|
|
|
|
if (columnName != null && !columnName.isEmpty()) { |
|
|
|
|
|
String camelCaseName = com.ruoyi.common.core.utils.StringUtils.toCamelCase(columnName); |
|
|
|
|
|
Object value = rs.getObject(i); |
|
|
|
|
|
if (value instanceof LocalDateTime) { |
|
|
|
|
|
LocalDateTime timeTmp = (LocalDateTime) value; |
|
|
|
|
|
value = timeTmp.format(dfClock); |
|
|
|
|
|
} |
|
|
|
|
|
value = dealAdapter(adapters, camelCaseName, value); // 使用转换后的字段名 |
|
|
|
|
|
|
|
|
|
|
|
// 处理 JSONArray 和 JSONObject 列 |
|
|
|
|
|
// 处理 JSONArray 列 |
|
|
|
|
|
if (jsonArrayColumnMap.containsKey(camelCaseName) && value instanceof String) { |
|
|
|
|
|
if (!StringUtils.isEmpty((String) value)) { |
|
|
|
|
|
String fieldName = jsonArrayColumnMap.get(camelCaseName); |
|
|
|
|
|
JSONArray originalArray = JSONArray.parseArray((String.valueOf(value))); |
|
|
|
|
|
JSONArray newArray = new JSONArray(); |
|
|
|
|
|
for (int j = 0; j < originalArray.size(); j++) { |
|
|
|
|
|
if ("value".equals(fieldName)) { |
|
|
|
|
|
// 若 fieldName 为 value,直接添加元素 |
|
|
|
|
|
newArray.add(originalArray.get(j)); |
|
|
|
|
|
} else { |
|
|
|
|
|
String item = originalArray.getString(j); |
|
|
|
|
|
JSONObject obj = new JSONObject(); |
|
|
|
|
|
obj.put(fieldName, item); |
|
|
|
|
|
newArray.add(obj); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
value = newArray; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 处理 JSONObject 列 |
|
|
|
|
|
else if (jsonObjectColumnList.contains(camelCaseName) && value instanceof String) { |
|
|
|
|
|
if (!StringUtils.isEmpty((String) value)) { |
|
|
|
|
|
value = JSONObject.parseObject((String.valueOf(value))); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
rowData.put(camelCaseName, value); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
list.add(rowData); |
|
|
|
|
|
} |
|
|
|
|
|
return list; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 处理适配器 |
|
|
|
|
|
* |
|
|
|
|
|
* @param adapters 适配器 |
|
|
|
|
|
* @param columnName 字段名 |
|
|
|
|
|
* @param o 字段值 |
|
|
|
|
|
* @return 结果 |
|
|
|
|
|
*/ |
|
|
|
|
|
private Object dealAdapter(List<Adapter> adapters, String columnName, Object o) { |
|
|
|
|
|
if (!adapters.isEmpty()) { |
|
|
|
|
|
for (Adapter a : adapters) { |
|
|
|
|
|
if (columnName.equals(a.getServiceBusinessField())) { |
|
|
|
|
|
if (a.getType().equals("1")) { |
|
|
|
|
|
//系统字典 |
|
|
|
|
|
o = sysDictDataService.selectDictLabel(a.getContent(), (String) o); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return o; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 调用查询,返回数据 |
|
|
|
|
|
* |
|
|
|
|
|
* @param ps PreparedStatement |
|
|
|
|
|
* @return List |
|
|
|
|
|
*/ |
|
|
|
|
|
private int queryCount(PreparedStatement ps) throws SQLException { |
|
|
|
|
|
// System.out.println("ps=" + transSql(ps)); |
|
|
|
|
|
int total = 0; |
|
|
|
|
|
ResultSet rs = ps.executeQuery(); |
|
|
|
|
|
while (rs.next()) { |
|
|
|
|
|
total = rs.getInt(1); |
|
|
|
|
|
} |
|
|
|
|
|
return total; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 构建请求报文结构 |
|
|
|
|
|
private TransportRequest buildRequest(String ipcType, Object bodyData, String currentToken) throws Exception { |
|
|
|
|
|
|
|
|
|
|
|
// 类型检查和转换 |
|
|
|
|
|
if (!(bodyData instanceof Map)) { |
|
|
|
|
|
throw new IllegalArgumentException("请求体数据必须是Map类型"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 包装为符合接口要求的格式 |
|
|
|
|
|
TransportRequestInfo requestInfo = new TransportRequestInfo(bodyData); |
|
|
|
|
|
|
|
|
|
|
|
String plainBody = gson.toJson(requestInfo); |
|
|
|
|
|
|
|
|
|
|
|
logger.info("完整请求体(未加密):\n{}", plainBody); |
|
|
|
|
|
return new TransportRequest( |
|
|
|
|
|
new TransportHeader( |
|
|
|
|
|
generateSerialNumber(), |
|
|
|
|
|
PROVINCE_AREA_CODE, // 省级标识 |
|
|
|
|
|
PROVINCE_AREA_CODE, // 部级标识+省级标识 |
|
|
|
|
|
BASE_AREA_CODE, // 部级标识 |
|
|
|
|
|
"V1", |
|
|
|
|
|
ipcType, |
|
|
|
|
|
LocalDateTime.now().format(DATE_FORMATTER), |
|
|
|
|
|
calculateSM3(plainBody), |
|
|
|
|
|
"0", |
|
|
|
|
|
currentToken, |
|
|
|
|
|
null, |
|
|
|
|
|
null |
|
|
|
|
|
), |
|
|
|
|
|
encryptBody(plainBody) |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 生成流水号(符合文档规范) |
|
|
|
|
|
private String generateSerialNumber() { |
|
|
|
|
|
|
|
|
|
|
|
// 2. 当前日期(必须8位) |
|
|
|
|
|
String datePart = LocalDateTime.now() |
|
|
|
|
|
.format(DateTimeFormatter.BASIC_ISO_DATE); |
|
|
|
|
|
|
|
|
|
|
|
// 3. 12位序列号(使用原子计数器示例) |
|
|
|
|
|
AtomicLong counter = new AtomicLong(1); // 实际应从数据库获取 |
|
|
|
|
|
String sequence = String.format("%012d", counter.getAndIncrement() % 1000000000000L); |
|
|
|
|
|
|
|
|
|
|
|
return PROVINCE_AREA_CODE + datePart + sequence; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SM3哈希计算 |
|
|
|
|
|
private String calculateSM3(String data) { |
|
|
|
|
|
EncryptCrcBean encryptCrcBean = new EncryptCrcBean(); |
|
|
|
|
|
encryptCrcBean.setPass(data); |
|
|
|
|
|
String cipherText_crc = smCryptoService.encryptCrc(encryptCrcBean); |
|
|
|
|
|
return cipherText_crc; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SM4加密(ECB模式) |
|
|
|
|
|
private String encryptBody(String plainText) throws Exception { |
|
|
|
|
|
EncryptCodeBean encryptCodeBean = new EncryptCodeBean(); |
|
|
|
|
|
encryptCodeBean.setSecretKey(encrypt_key); |
|
|
|
|
|
encryptCodeBean.setPass(plainText); |
|
|
|
|
|
String cipherText = smCryptoService.encrypt_Body(encryptCodeBean); |
|
|
|
|
|
return cipherText; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SM4解密(ECB模式) |
|
|
|
|
|
private String decryptBody(String plainText) throws Exception { |
|
|
|
|
|
DecryptCodeBean encrypt2 = new DecryptCodeBean(); |
|
|
|
|
|
encrypt2.setSecretKey(decrypt_key); |
|
|
|
|
|
encrypt2.setPass(plainText); |
|
|
|
|
|
String cipherText = smCryptoService.decrypt_Body(encrypt2); |
|
|
|
|
|
return cipherText; |
|
|
|
|
|
} |
|
|
|
|
|
} |