import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/**
* 只读排查探针:一笔订单的「资金边界」——钱收没收到、核销没核销、退没退款——以及挂在它上面的通道记录。
*
*
这三列是同一行上的三个判断({@code benefit_order}),核销、退款、资金确认都靠锁定这一行来串行化,
* 所以任何一笔钱的问题都要先把这三列读出来。
*/
public class OrderFundBoundaryProbe {
/** 公网 IP 只留主机段前两段:地址本身(端口+路径)就是攻击面。 */
private static final Pattern AUTHORITY_IPV4 = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.\\d{1,3}\\.\\d{1,3}(:\\d+)?$");
/**
* 回答什么问题:给定订单号,本地 {@code benefit_order} 的资金边界三列
* ({@code order_status} / {@code verify_status} / {@code refund_status})、创建时固定的收款方
* ({@code collect_onboarding_id} / {@code collect_store_id} / {@code collect_huifu_id})、
* 关联的支付流水与退款记录、核销记录,以及 {@code payment_reconciliation_issue} 里相关的未结问题。
*
*
什么时候用它:用户说「付了钱订单没变」「核销了商户没拿到钱」「退款了钱没退回来」。它把一条订单
* 上所有与钱有关的事实一次摆齐,再决定去哪条链路(对账、资金确认、悬账退款)继续查。
*
*
它不改任何状态:整个探针只有 SELECT,连通道都不问(因此不需要汇付配置)。
*
*
参数格式(全部从命令行传,缺参数直接打用法退出,不用任何默认值瞎猜):
*
* --db-url=<JDBC URL> --db-user=<用户> --db-password=<口令>
* --order-no=<订单号>
* [--config=<汇付配置文件路径>] 只为读 environment 打生产警告,本探针不做通道查询
* [--huifu-environment=test|prod] 同上,效果等价且在只给这一项时更方便
*
*/
public static void main(String[] args) {
String dbUrl = required(args, "db-url");
String dbUser = required(args, "db-user");
String dbPassword = required(args, "db-password");
String orderNo = required(args, "order-no");
environmentBanner(arg(args, "config"), arg(args, "huifu-environment"));
System.out.println("只读探针:整个探针只有 SELECT,连通道都不问。不发起支付、不关单、不退款、不交易确认、"
+ "不下发业务开通、不改任何数据库行。");
System.out.println("数据库目标:" + maskHost(dbUrl));
JdbcTemplate jdbc = new JdbcTemplate(new DriverManagerDataSource(dbUrl, dbUser, dbPassword));
List