yeg
2026-09-17 e3f412c5474311a471345ea508db4875c9ec648e
talent-card-server/src/main/java/com/talentcard/server/business/payment/PaymentIssueRecorder.java
@@ -1,5 +1,7 @@
package com.talentcard.server.business.payment;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
@@ -30,7 +32,23 @@
                """, type, PROVIDER, businessNo, emptyToNull(orderNo), emptyToNull(expected), emptyToNull(actual), amount, truncate(message));
    }
    /**
     * 把一笔业务仍未结的问题记为已解决。
     *
     * <p>唯一键是 {@code (issue_type, provider, business_no, status)},而同一笔业务会被「解掉、又出现、
     * 再解掉」(对账每一轮都可能把同一条问题关掉再开出来)。直接把 open 行改成 resolved 会撞上已经存在
     * 的那条 resolved 行,所以先把上一条结论行清掉再落新结论。删除是有条件的:只有当确实存在一条 open 行
     * (也就是真的要有新结论)时才动它,人工写下的结论不会因为一次无关的对账轮次被抹掉。
     */
    public void resolve(String type, String businessNo, String by) {
        List<Long> superseded = jdbc.queryForList("""
                select r.id from payment_reconciliation_issue r
                where r.issue_type = ? and r.provider = ? and r.business_no = ? and r.status = 'resolved'
                  and exists (select 1 from payment_reconciliation_issue open_issue
                              where open_issue.issue_type = r.issue_type and open_issue.provider = r.provider
                                and open_issue.business_no = r.business_no and open_issue.status = 'open')
                """, Long.class, type, PROVIDER, businessNo);
        for (Long id : superseded) jdbc.update("delete from payment_reconciliation_issue where id = ?", id);
        jdbc.update("update payment_reconciliation_issue set status = 'resolved', resolved_at = now(), resolved_by = ? where issue_type = ? and provider = ? and business_no = ? and status = 'open'", by, type, PROVIDER, businessNo);
    }