import java.nio.charset.StandardCharsets;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.sql.Connection;
|
import java.sql.DriverManager;
|
import java.sql.ResultSet;
|
import java.sql.ResultSetMetaData;
|
import java.sql.SQLException;
|
import java.sql.Statement;
|
|
/**
|
* 一次性只读探针:定位 2026-09-24 那笔支付创建 409 的通道原始回执。
|
*
|
* <p>只跑 select,不写库。输出同时打到 stdout 与 UTF-8 文件(Git Bash 控制台编码不可靠)。
|
*/
|
public class Payment409Probe {
|
|
private static final String[] DATABASES = {
|
"talent_card2", "talent_card", "talent_card_verify1", "talent_card_dryrun"
|
};
|
|
public static void main(String[] args) throws Exception {
|
Path out = Path.of(args.length > 0 ? args[0] : ".scratch/payment-409-probe/out.txt");
|
Files.createDirectories(out.getParent());
|
StringBuilder text = new StringBuilder();
|
String base = "jdbc:mysql://127.0.0.1:8134/?useUnicode=true&characterEncoding=utf8"
|
+ "&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&useSSL=false";
|
try (Connection connection = DriverManager.getConnection(base, "root", "123456")) {
|
for (String database : DATABASES) {
|
section(text, "===== " + database + " =====");
|
try (Statement statement = connection.createStatement()) {
|
statement.execute("use `" + database + "`");
|
} catch (SQLException exception) {
|
text.append("数据库不可用:").append(exception.getMessage()).append('\n');
|
continue;
|
}
|
dump(text, connection, "最近的支付流水",
|
"select payment_no, order_no, amount, status, provider_huifu_id, "
|
+ "provider_response_code, provider_response_message, created_at, paid_at "
|
+ "from payment_transaction order by id desc limit 15");
|
dump(text, connection, "今天创建的支付流水(金额/状态/回执)",
|
"select payment_no, order_no, amount, status, provider_response_code, provider_response_message, created_at "
|
+ "from payment_transaction where created_at >= '2026-09-24 00:00:00' order by id desc limit 20");
|
dump(text, connection, "最近的对账问题记录",
|
"select issue_type, business_no, status, expected_value, actual_value, amount, description, created_at "
|
+ "from payment_reconciliation_issue order by id desc limit 15");
|
dump(text, connection, "商户微信阶段快照",
|
"select application_id, sync_owner, last_synced_at, sync_error, stages_json "
|
+ "from merchant_onboarding_progress order by id desc limit 8");
|
}
|
}
|
System.out.println(text);
|
Files.writeString(out, text.toString(), StandardCharsets.UTF_8);
|
System.out.println("\nwritten to " + out.toAbsolutePath());
|
}
|
|
private static void section(StringBuilder text, String title) {
|
text.append('\n').append(title).append('\n');
|
}
|
|
private static void dump(StringBuilder text, Connection connection, String title, String sql) {
|
text.append("\n--- ").append(title).append(" ---\n");
|
try (Statement statement = connection.createStatement(); ResultSet rs = statement.executeQuery(sql)) {
|
ResultSetMetaData meta = rs.getMetaData();
|
int columns = meta.getColumnCount();
|
int rows = 0;
|
while (rs.next()) {
|
rows++;
|
for (int i = 1; i <= columns; i++) {
|
text.append(meta.getColumnLabel(i)).append('=').append(value(rs.getObject(i))).append(" ");
|
}
|
text.append('\n');
|
}
|
if (rows == 0) text.append("(空)\n");
|
} catch (SQLException exception) {
|
text.append("查询失败:").append(exception.getMessage()).append('\n');
|
}
|
}
|
|
private static String value(Object raw) {
|
if (raw == null) return "NULL";
|
String text = String.valueOf(raw).trim();
|
return text.isEmpty() ? "\"\"" : text;
|
}
|
}
|