# 规格 772 / 774 时长检查与修复 SQL 生成 独立 Java 11 程序,只读数据库,不启动 Spring、不执行修复、不修改规格配置。 从真实车票和订单生成 `preview.csv` 与逐条带旧值条件的 `repair.sql`。 数据库表、字段缺失或查询失败时会报错停止,不会忽略失败后生成不完整的修复清单。 ## 为什么不只判断 SQL 等号 `expiry_time = DATE_ADD(start_time, INTERVAL 12 MONTH)` 判断精确的 12 个自然月, 但部分开通入口使用两次当前时间,可能有秒差;正常半年续费累计一年也会满足等号。 程序展示与“开始时间 + 12 个月”的秒差,并读取当前车票用户的关联订单、成功发放车票的记录和补时记录。 订单通过 `order_don.relation_id` 和 `order_don_ticket_record` 两种关联查找并去重。 分类规则: - `candidate`:规格为 772/774,当前有用户且车票状态为 validity/outside,起止完整、精确一年; 普通购买、非 VIP、无冻结/恢复/保留天数、无补偿/手工补时记录,且只有一笔同规格普通订单。 历史多数量叠加时长不进入候选;有成功发放独立车票记录的多数量订单按单张票处理。 - `review`:时间在一年附近(误差不超过 60 秒或到期自然日期相同),或存在续费、多笔订单、补时、 冻结等需要核对的情况。**不生成更新 SQL,也不自动接受任何秒差。** - `skipped`:未设置完整起止时间或时长不属于一年附近,例如已经是半年。 候选只是筛查结果,不是误设的绝对证明。历史换票、未记录的手工改期等仍需核对业务记录。 扣减按**原到期时间减 6 个自然月**,不按 180 天/183 天,也不重算为开始时间加半年。 例如 `2024-02-29 → 2025-02-28` 扣减后到期为 `2024-08-28`。 起止时间缺失、冻结保留权益及续费累计时间均不擅自修正。 ## 在 PowerShell 运行 需要 Java 11+、MySQL Connector/J 8 驱动以及目标数据库的查询权限。程序不会自动读取项目生产配置。 数据库应含本项目的 `groups_relation`、`groups_trips`、`order_don`、 `order_don_ticket_record`、`incr_expiry_time_record` 表。使用事务表可以获得一致快照。 在项目根目录执行,将主机、库名和用户名替换成目标环境: ```powershell $env:DURATION_REPAIR_JDBC_URL = 'jdbc:mysql://数据库主机:3306/数据库名?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8' $env:DURATION_REPAIR_DB_USER = '数据库查询用户' $repairDriver = Join-Path $env:USERPROFILE '.m2\repository\mysql\mysql-connector-java\8.0.23\mysql-connector-java-8.0.23.jar' $repairOutput = Join-Path $env:TEMP ('duration-repair-output-' + (Get-Date -Format 'yyyyMMdd-HHmmss')) java '-Dfile.encoding=UTF-8' --class-path $repairDriver tools/duration-repair/RepairSkuDuration.java $repairOutput ``` 终端会隐藏输入数据库密码。非交互运行时通过 `DURATION_REPAIR_DB_PASSWORD` 环境变量提供密码, 不要把密码写进 JDBC URL、源代码或命令行参数。输出目录必须不存在,其父目录必须存在。 先查看 `preview.csv` 中每条候选的订单和新旧到期时间,再在数据库客户端打开 `repair.sql`。 SQL 使用车票 ID、当前用户、所属车队/规格、原开始/到期/更新时间和状态作为条件。 每条更新紧跟 `ROW_COUNT()`,预期为 1;为 0 表示已修复或记录发生变化,需重新检查。 旧到期条件可防止同一清单重复扣减。事务末尾的 `COMMIT` / `ROLLBACK` 均注释, 必须在同一连接内按核对结果执行其中一个,不要执行一半后遗留未结束事务。 程序只生成车票修复 SQL。默认规格仍为 12 个月时,另行在后台改为 6 个月, 并核对 `days`(天数大于 0 时系统优先使用天数),避免新订单继续错误开通。 ## 离线验证 测试不连接数据库,也不加载 JDBC 驱动: ```powershell $repairClasses = Join-Path $env:TEMP ('duration-repair-test-' + [guid]::NewGuid().ToString('N')) New-Item -ItemType Directory -Path $repairClasses | Out-Null javac -encoding UTF-8 -d $repairClasses tools/duration-repair/RepairSkuDuration.java tools/duration-repair/RepairSkuDurationTest.java java '-Dfile.encoding=UTF-8' -cp $repairClasses RepairSkuDurationTest ```