修复中介库

This commit is contained in:
wkc
2026-04-20 11:24:18 +08:00
parent c278d11390
commit 2b321a8621
31 changed files with 1360 additions and 1466 deletions

View File

@@ -39,6 +39,7 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
private static final String STATUS_RUNNING = "RUNNING";
private static final String STATUS_SUCCESS = "SUCCESS";
private static final String STATUS_FAILED = "FAILED";
private static final String TASK_ERROR_MESSAGE_FALLBACK = "任务失败,详细异常请查看后端日志";
private static final String RESULT_TYPE_STATEMENT = "STATEMENT";
private static final String OBJECT_TYPE_STAFF_ID_CARD = "STAFF_ID_CARD";
@@ -147,12 +148,11 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
return task.getId();
} catch (Exception ex) {
task.setStatus(STATUS_FAILED);
task.setErrorMessage(ex.getMessage());
task.setEndTime(new Date());
task.setNeedRerun(null);
task.setUpdateBy(operator);
task.setUpdateTime(new Date());
taskMapper.updateTask(task);
updateFailedTaskSafely(task, ex);
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.PROCESSING, operator);
log.error("【流水标签】任务执行失败: taskId={}, projectId={}, modelCode={}, triggerType={}, error={}",
task.getId(), projectId, modelCode, triggerType, ex.getMessage(), ex);
@@ -359,4 +359,44 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
}
return Integer.parseInt(value);
}
private void updateFailedTaskSafely(CcdiBankTagTask task, Exception ex) {
task.setErrorMessage(buildSafeTaskErrorMessage(ex));
try {
taskMapper.updateTask(task);
} catch (Exception updateEx) {
log.error("【流水标签】写入任务失败状态异常: taskId={}, error={}",
task.getId(), updateEx.getMessage(), updateEx);
task.setErrorMessage(TASK_ERROR_MESSAGE_FALLBACK);
taskMapper.updateTask(task);
}
}
private static String buildSafeTaskErrorMessage(Throwable throwable) {
if (throwable == null) {
return TASK_ERROR_MESSAGE_FALLBACK;
}
StringBuilder builder = new StringBuilder();
if (throwable.getMessage() != null && !throwable.getMessage().isBlank()) {
builder.append(throwable.getMessage().trim());
}
Throwable rootCause = throwable;
while (rootCause.getCause() != null && rootCause.getCause() != rootCause) {
rootCause = rootCause.getCause();
}
if (rootCause != throwable && rootCause.getMessage() != null && !rootCause.getMessage().isBlank()) {
String rootMessage = rootCause.getMessage().trim();
if (!builder.toString().contains(rootMessage)) {
if (!builder.isEmpty()) {
builder.append(" | rootCause=");
}
builder.append(rootMessage);
}
}
return builder.isEmpty() ? TASK_ERROR_MESSAGE_FALLBACK : builder.toString();
}
}

View File

@@ -924,7 +924,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ccdi_purchase_transaction pt
inner join (
<include refid="projectScopedDirectStaffSql"/>
) project_staff on project_staff.staffId = pt.applicant_id
) project_staff on project_staff.staffId COLLATE utf8mb4_general_ci = pt.applicant_id COLLATE utf8mb4_general_ci
where IFNULL(pt.actual_amount, 0) > 100000
union
select distinct
@@ -935,7 +935,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ccdi_purchase_transaction pt
inner join (
<include refid="projectScopedDirectStaffSql"/>
) project_staff on project_staff.staffId = pt.purchase_leader_id
) project_staff on project_staff.staffId COLLATE utf8mb4_general_ci = pt.purchase_leader_id COLLATE utf8mb4_general_ci
where pt.purchase_leader_id is not null
and IFNULL(pt.actual_amount, 0) > 100000
) t
@@ -975,7 +975,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ccdi_purchase_transaction pt
inner join (
<include refid="projectScopedDirectStaffSql"/>
) project_staff on project_staff.staffId = pt.applicant_id
) project_staff on project_staff.staffId COLLATE utf8mb4_general_ci = pt.applicant_id COLLATE utf8mb4_general_ci
where IFNULL(pt.actual_amount, 0) > 0
and IFNULL(pt.supplier_name, '') &lt;&gt; ''
@@ -989,7 +989,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ccdi_purchase_transaction pt
inner join (
<include refid="projectScopedDirectStaffSql"/>
) project_staff on project_staff.staffId = pt.purchase_leader_id
) project_staff on project_staff.staffId COLLATE utf8mb4_general_ci = pt.purchase_leader_id COLLATE utf8mb4_general_ci
where pt.purchase_leader_id is not null
and IFNULL(pt.actual_amount, 0) > 0
and IFNULL(pt.supplier_name, '') &lt;&gt; ''
@@ -1006,7 +1006,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ccdi_purchase_transaction pt
inner join (
<include refid="projectScopedDirectStaffSql"/>
) project_staff on project_staff.staffId = pt.applicant_id
) project_staff on project_staff.staffId COLLATE utf8mb4_general_ci = pt.applicant_id COLLATE utf8mb4_general_ci
where IFNULL(pt.actual_amount, 0) > 0
union
@@ -1018,7 +1018,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
from ccdi_purchase_transaction pt
inner join (
<include refid="projectScopedDirectStaffSql"/>
) project_staff on project_staff.staffId = pt.purchase_leader_id
) project_staff on project_staff.staffId COLLATE utf8mb4_general_ci = pt.purchase_leader_id COLLATE utf8mb4_general_ci
where pt.purchase_leader_id is not null
and IFNULL(pt.actual_amount, 0) > 0
) source_total

View File

@@ -148,6 +148,34 @@ class CcdiBankTagAnalysisMapperXmlTest {
);
}
@Test
void largePurchaseTransactionRule_shouldAlignCollationForJoinFields() throws Exception {
String xml = readXml(RESOURCE);
String purchaseSelectSql = extractSelectSql(xml, "selectLargePurchaseTransactionStatements");
String supplierSelectSql = extractSelectSql(xml, "selectSupplierConcentrationObjects");
assertTrue(
purchaseSelectSql.contains("project_staff.staffId COLLATE utf8mb4_general_ci = pt.applicant_id COLLATE utf8mb4_general_ci")
);
assertTrue(
purchaseSelectSql.contains("project_staff.staffId COLLATE utf8mb4_general_ci = pt.purchase_leader_id COLLATE utf8mb4_general_ci")
);
assertTrue(
supplierSelectSql.contains("project_staff.staffId COLLATE utf8mb4_general_ci = pt.applicant_id COLLATE utf8mb4_general_ci")
);
assertTrue(
supplierSelectSql.contains("project_staff.staffId COLLATE utf8mb4_general_ci = pt.purchase_leader_id COLLATE utf8mb4_general_ci")
);
assertTrue(
!xml.contains("project_staff.staffId = pt.applicant_id"),
"采购交易相关 join 不应再使用未声明 COLLATE 的 applicant_id 比较"
);
assertTrue(
!xml.contains("project_staff.staffId = pt.purchase_leader_id"),
"采购交易相关 join 不应再使用未声明 COLLATE 的 purchase_leader_id 比较"
);
}
@Test
void assetRegistrationMismatchRules_shouldUseRealSqlAndAssetTable() throws Exception {
String xml = readXml(RESOURCE);

View File

@@ -28,9 +28,11 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.math.BigDecimal;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -494,6 +496,23 @@ class CcdiBankTagServiceImplTest {
)));
}
@Test
void buildSafeTaskErrorMessage_shouldKeepLongMessageForLongTextColumn() throws Exception {
Method method = CcdiBankTagServiceImpl.class.getDeclaredMethod(
"buildSafeTaskErrorMessage", Throwable.class
);
method.setAccessible(true);
String longMessage = "X".repeat(5000);
RuntimeException throwable = new RuntimeException("root-cause:" + longMessage);
String result = (String) method.invoke(null, throwable);
assertNotNull(result);
assertTrue(result.length() > 2000, "LONGTEXT 方案下不应继续把错误信息截断到 2000");
assertTrue(result.contains("root-cause"), "错误信息应保留根因关键字");
}
@Test
void abnormalAccountMapperXml_shouldDeclareObjectSelects() throws Exception {
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml"));