Browse Source

G4-1 对焦标定清理任务(C6):scene=1 按天数物删 / scene=0 永留

- C# 下发链补 cleanAutofocusData(中央 tl_setting.clean_autofocus_data 原始列
  + Java 链原已就绪,仅缺 C# 消费者):tlSettingDTO / TLSettingDB / TLSetting
  / ConvertHelper 3 路径,镜像 focusLayerCount。
- DBService.CleanAutofocusData(keepDays):物删 house_autofocus_calibration
  scene=1 且 calibTime<now-keepDays;scene=0 出厂基准永不删(12 §2.7 约束①);
  keepDays<=0 安全阀不删;全 try 兜底返回删除条数。
- AppData.CleanAutofocusCalibration():挂每日维护窗口(autoFocusTime,与 DeleteLog
  同源同守卫),keepDays 读内存 TLSetting.cleanAutofocusData 缺省30(零 SQLite 读)。
- dotnet build operate 0 error(仅预存警告)。清理真入库待运行抽查;
  本地 SQLite 旧库列迁移归 G4-3/V-046 真机门控。
- 同步文档:当前开发计划/工作计划表/进度状态.yaml/交接卡/进度数据.js/需求文档12。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
huangjie 5 days ago
parent
commit
968f9ae

+ 21 - 0
ivf_tl_operate_2.0/control/ivf_tl_Control/AppData.cs

@@ -575,6 +575,7 @@ namespace ivf_tl_Control
                         }
                         if (isSetZiDong) continue;
                         Task.Run(() => DeleteLog());
+                        Task.Run(() => CleanAutofocusCalibration()); // G4-1:每日维护窗口同步清理对焦标定 scene=1 过期记录
                         isSetZiDong = true;
                         if (HouseBin1 != null)
                         {
@@ -1656,6 +1657,26 @@ namespace ivf_tl_Control
             }
         }
 
+        /// <summary>
+        /// G4-1 / 需求文档12 §2.7:对焦标定数据清理(每日维护窗口触发,与 DeleteLog 同源)。
+        /// 保留天数取服务器下发的 TLSetting.cleanAutofocusData(缺省/非正回退 30);
+        /// 只删 scene=1 日常对焦记录、scene=0 出厂基准永久保留(由 DBService.CleanAutofocusData 保证)。
+        /// 全 try 兜底,异常吞掉记日志,绝不向上抛(不影响采集/对焦)。
+        /// </summary>
+        public void CleanAutofocusCalibration()
+        {
+            try
+            {
+                int keepDays = TLSetting?.cleanAutofocusData ?? 30;
+                if (keepDays <= 0) keepDays = 30;
+                int n = DBService.CleanAutofocusData(keepDays);
+                LogService.TLLog($"对焦标定清理(G4-1):保留 {keepDays} 天,删除 scene=1 共 {n} 条", LogEnum.RunRecord);
+            }
+            catch (Exception ex)
+            {
+                LogService.ExceptionLog(ex, "CleanAutofocusCalibration", null, LogEnum.RunException);
+            }
+        }
         private void DeleteLogFile(string newPath)
         {
             var newDir = Directory.GetFiles(newPath, "*.htm", SearchOption.TopDirectoryOnly);

+ 7 - 0
ivf_tl_operate_2.0/control/ivf_tl_Entity/DBEntitys/TLSettingDB.cs

@@ -383,6 +383,13 @@ namespace IvfTl.Control.Entity.DBEntitys
         [SugarColumn(IsNullable = true)]
         public int? focusLayerCount { get; set; }
 
+        /// <summary>
+        /// Desc:对焦标定数据保留天数(清理任务用,默认30) clean_autofocus_data —— G4-1
+        /// Nullable:True
+        /// </summary>
+        [SugarColumn(IsNullable = true)]
+        public int? cleanAutofocusData { get; set; }
+
         /// <summary>
         /// Desc:对焦起点下移层数 focus_layer_down
         /// Nullable:True

+ 5 - 0
ivf_tl_operate_2.0/control/ivf_tl_Entity/DTO/ApiResultDTO/tlSettingDTO.cs

@@ -265,6 +265,11 @@ namespace IvfTl.Control.Entity.DTO.ApiResultDTO
         /// </summary>
         public int? focusLayerCount { get; set; }
 
+        /// <summary>
+        /// 对焦标定数据保留天数(清理任务用,默认30) clean_autofocus_data —— G4-1
+        /// </summary>
+        public int? cleanAutofocusData { get; set; }
+
         /// <summary>
         /// 对焦起点下移层数(默认2) focus_layer_down
         /// </summary>

+ 7 - 0
ivf_tl_operate_2.0/control/ivf_tl_Entity/GlobalEntitys/TLSetting.cs

@@ -361,6 +361,13 @@ namespace IvfTl.Control.Entity.GlobalEntitys
         /// </summary>
         public int? focusLayerCount { get; set; }
 
+        /// <summary>
+        /// Desc:对焦标定数据保留天数(清理任务用) clean_autofocus_data —— G4-1
+        /// Default: 30
+        /// Nullable:True
+        /// </summary>
+        public int? cleanAutofocusData { get; set; }
+
         /// <summary>
         /// Desc:对焦起点下移层数(清晰层在第几层之上) focus_layer_down
         /// Default: 2

+ 27 - 0
ivf_tl_operate_2.0/control/ivf_tl_Services/DBService.cs

@@ -864,6 +864,33 @@ namespace IvfTl.Control.Services
                 return null;
             }
         }
+
+        /// <summary>
+        /// G4-1 / 需求文档12 §2.7:对焦标定数据清理任务。
+        /// 物理删除 house_autofocus_calibration 中 scene=1(日常对焦) 且 calibTime 早于 (now - keepDays) 的记录;
+        /// scene=0(出厂基准) 永不删除——否则日常对焦失去参照基准(12 §2.7 约束①)。
+        /// keepDays&lt;=0 视为不清理(安全阀:避免 cutoff 异常误删全部)。
+        /// 全 try 兜底,异常吞掉记日志,绝不向上抛(不崩采集/对焦线程)。返回删除条数。
+        /// </summary>
+        /// <param name="keepDays">保留天数(来自 tl_setting.clean_autofocus_data 下发值,默认30)</param>
+        public int CleanAutofocusData(int keepDays)
+        {
+            try
+            {
+                if (keepDays <= 0) return 0;
+                DateTime cutoff = DateTime.Now.AddDays(-keepDays);
+                // Deleteable 物理删除(本表无逻辑删除全局过滤):retention 需真正缩表,故物理删而非置 deleted。
+                int n = Db.Deleteable<HouseAutofocusCalibrationDB>()
+                    .Where(x => x.scene == 1 && x.calibTime < cutoff)
+                    .ExecuteCommand();
+                return n;
+            }
+            catch (Exception ex)
+            {
+                ExceptionLogEvent?.Invoke(ex, "DBServiceImpl.CleanAutofocusData", null, LogEnum.DbException);
+                return 0;
+            }
+        }
         #endregion
     }
 }

+ 3 - 0
ivf_tl_operate_2.0/control/ivf_tl_UtilHelper/ConvertHelper.cs

@@ -81,6 +81,7 @@ namespace ivf_tl_UtilHelper
             TLSetting.localAutofocusEnabled = tlSetting.localAutofocusEnabled ?? 0;
             TLSetting.focusLayerSpacingPulse = tlSetting.focusLayerSpacingPulse;
             TLSetting.focusLayerCount = tlSetting.focusLayerCount;
+            TLSetting.cleanAutofocusData = tlSetting.cleanAutofocusData; // G4-1:对焦标定保留天数下发
             TLSetting.focusLayerDown = tlSetting.focusLayerDown;
             TLSetting.focusPeakRatioThreshold = tlSetting.focusPeakRatioThreshold;
 
@@ -151,6 +152,7 @@ namespace ivf_tl_UtilHelper
             // V-047 取数链:设备级拍照层配置 本地缓存 → 运行时(喂 PhotoLayerCalculator)。
             TLSetting.focusLayerSpacingPulse = tLSettingDB.focusLayerSpacingPulse;
             TLSetting.focusLayerCount = tLSettingDB.focusLayerCount;
+            TLSetting.cleanAutofocusData = tLSettingDB.cleanAutofocusData; // G4-1:本地缓存回读保留天数
             TLSetting.focusLayerDown = tLSettingDB.focusLayerDown;
             TLSetting.focusPeakRatioThreshold = tLSettingDB.focusPeakRatioThreshold;
 
@@ -230,6 +232,7 @@ namespace ivf_tl_UtilHelper
             // V-047 取数链:设备级拍照层配置 运行时 → 本地缓存,跨重启保留。
             tLSettingDB.focusLayerSpacingPulse = tLSetting.focusLayerSpacingPulse;
             tLSettingDB.focusLayerCount = tLSetting.focusLayerCount;
+            tLSettingDB.cleanAutofocusData = tLSetting.cleanAutofocusData; // G4-1:保留天数写入本地缓存
             tLSettingDB.focusLayerDown = tLSetting.focusLayerDown;
             tLSettingDB.focusPeakRatioThreshold = tLSetting.focusPeakRatioThreshold;
 

+ 1 - 1
项目文档/开发计划/2026-06-20-当前开发计划.md

@@ -79,7 +79,7 @@
 
 **涉及文件**:operate 对焦清理任务、两个 migration + base 建库脚本 + 幂等 runner、`清单.md`、本地 SQLite(`tl_setting`/`house_well_setting`)列迁移。
 
-- [ ] **G4-1** `[纯代码][P2]` 对焦标定清理任务(C6):按天数,scene=1 删 / scene=0 保留;可跑。
+- [x] **G4-1** `[纯代码][P2]` 对焦标定清理任务(C6):按天数,scene=1 删 / scene=0 保留;可跑。 ✅2026-06-20 完成:用户拍板配置走 tl_setting.clean_autofocus_data 中央下发列(非 App.config)。发现该列+Java 下发链(TlSetting/TlSettingVO cleanAutofocusData 默认30)中央端原已就绪,**仅缺 C# 消费者**;本次补全:① C# 下发链 4 文件(tlSettingDTO/TLSettingDB/TLSetting/ConvertHelper 3 路径 DTO↔TLSetting↔DB)加 cleanAutofocusData,镜像 focusLayerCount;② DBService.CleanAutofocusData(keepDays):物删 house_autofocus_calibration scene=1 且 calibTime<now-keepDays、scene=0 永留、keepDays<=0 安全阀不删、全 try 兜底返回条数;③ AppData 每日维护窗口(StartPushMessageThread autoFocusTime 时刻,与 DeleteLog 同源)调 CleanAutofocusCalibration,keepDays 读 TLSetting.cleanAutofocusData 缺省30。`dotnet build operate` 0 error。★清理真入库待运行抽查;本地 SQLite 旧库 cleanAutofocusData 列迁移归 G4-3(V-046 真机门控)★。
 - [x] **G4-2** `[纯代码][P1]` 建库脚本与 migration 合并 + 幂等 runner(C2):两 migration 并入 base 或部署清单强制登记;`清单.md` 补 operation_log/对焦表;全新部署一次跑完不缺表/列。 ✅2026-06-20 完成:对焦表/列并入 `aivfo_tl_setting.sql`、operation_log 并入 `log.sql`、新增幂等 `sql/init-database.sh`、`清单.md` 补全;临时 MySQL 容器全量跑通+二次幂等零报错验证(18 表/7+2 列/operation_log 齐)。
 - [ ] **G4-3** `[真机][P1]` 本地 SQLite 列迁移(V-046):对 tl_setting/house_well_setting 加 AddColumn(IF NOT EXISTS 语义)或重发预置 db;旧 db 升级后写缓存不报 no such column。
 

+ 12 - 0
项目文档/进度/交接卡.md

@@ -539,3 +539,15 @@
 - 真机/运行待验:★真入库 + Kafka 宕→恢复补送 + 配置文件改→热生效,三条均待起 Kafka+oplog 端到端抽查(运行期,非真机门控)★。
 - 本次未 git commit(按惯例主会话统一,与累计未提交改动一并)。累计未提交:本次 Aivfo.OperationLog 5 文件 + 此前各会话累计(见前卡)。
 - 下一步:M8 可写代码全清。挑剩余纯代码——G2 UI(首页舱室弹框/13子页自适应/TabTip/well三态,视觉真机为准)或 G4-1(C6 对焦标定清理任务)。真机门控 G1-1(T1.4)/G4-3/G5 待用户在场。
+
+## 2026-06-20 · ★G4-1 对焦标定清理任务(C6)完成★
+- 用户拍板:保留天数配置走 tl_setting.clean_autofocus_data 中央下发列(而非本地 App.config)。
+- ★关键发现省一半工作★:clean_autofocus_data 是 tl_setting **原始遗留列**(与 clean_source/control/pc/surface/video_data 同族"清理时间"列),base sql(aivfo_tl_setting.sql:688 默认30)已含、老库本就有→中央 MySQL 无需改;Java 下发链原已就绪(TlSetting.java:235 cleanAutofocusData 默认30、TlSettingVO:224、TlSystemSettingVO/UpdateDTO)。审计 C6 原话"clean_autofocus_data 仅配置列无消费者"——G4-1 = 补 C# 消费者。
+- 改动(C# 端,全镜像 focusLayerCount):
+  · 下发链 4 文件:tlSettingDTO / TLSettingDB([SugarColumn(IsNullable=true)] int?) / TLSetting / ConvertHelper 3 路径(DTO→TLSetting、TLSettingDB→TLSetting、TLSetting→TLSettingDB)各加 cleanAutofocusData。
+  · DBService.CleanAutofocusData(int keepDays):Db.Deleteable<HouseAutofocusCalibrationDB>().Where(scene==1 && calibTime<now-keepDays) 物理删除;scene=0 永不动(12 §2.7 约束①);keepDays<=0 安全阀返回0不删;全 try 兜底记 DbException 返回删除条数。物删非置 deleted——retention 需真正缩表(12 §2.7 数据量评估按清理维持万级)。
+  · AppData.CleanAutofocusCalibration():读 TLSetting.cleanAutofocusData(缺省/非正→30)调 DBService.CleanAutofocusData,记 RunRecord 日志;挂到 StartPushMessageThread 每日维护窗口(autoFocusTime 时刻、isSetZiDong 守卫,与既有 DeleteLog 同源同守卫,日清一次)。
+- 读路径不碰 SQLite:keepDays 取自内存 TLSetting(server init 下发值,AppData.cs:197/1321),**零 V-046 读风险**。TLSettingDB 加列是为离线缓存一致,与既有 focus 列同受 V-046/G4-3 预置库重建门控。
+- ★编译核实:dotnet build operate = 0 error(仅预存警告,含已知 BufferDebug MVVMTK0034)。codegraph sync done。
+- 真机/运行待验:清理真执行删库 = 起运行后到 autoFocusTime 触发查 house_autofocus_calibration scene=1 过期行被删、scene=0 在(运行期非真机门控);本地旧 SQLite 加 cleanAutofocusData 列 = G4-3/V-046 真机门控。
+- 本次未 git commit(待与文档一并)。下一步:G2 UI 或 G1-2(ComBin 去重,需专门一轮+真机)。

+ 4 - 4
项目文档/进度/工作计划表.md

@@ -19,7 +19,7 @@
 
 **续接三件套(无缝接续,不依赖对话记忆)**:① 本表(里程碑状态)② 《2026-06-20-当前开发计划.md》(剩余工作)③ 进度状态.yaml(当前断点)。
 
-**剩余工作总览**(详见《当前开发计划》):G1 串口收尾(T1.4 真机/ComBin 枚举迁移去重/写EEPROM V-010)|G2 UI(首页舱室弹框位置大小/13 子页自适应/TabTip/well 三态)|G3 日志铺开(**operate 逐方法 ✅2026-06-20**/**Java 埋点 ✅2026-06-20**/**C4 配置下发+补送 ✅2026-06-20 G3 全清**)|G4 对焦·数据(C6 清理任务/**C2 建库 runner ✅2026-06-20 完成**/V-046 列迁移)|G5 业务回归(M6/M7)。多数受真机 GUI 门控。
+**剩余工作总览**(详见《当前开发计划》):G1 串口收尾(T1.4 真机/ComBin 枚举迁移去重/写EEPROM V-010)|G2 UI(首页舱室弹框位置大小/13 子页自适应/TabTip/well 三态)|G3 日志铺开(**operate 逐方法 ✅2026-06-20**/**Java 埋点 ✅2026-06-20**/**C4 配置下发+补送 ✅2026-06-20 G3 全清**)|G4 对焦·数据(**C6 清理任务 ✅2026-06-20**/**C2 建库 runner ✅2026-06-20 完成**/V-046 列迁移待 G4-3 真机)|G5 业务回归(M6/M7)。多数受真机 GUI 门控。
 
 ---
 
@@ -76,9 +76,9 @@
 | M2-05 | 场景A 工程师调试页一键标定 | 🟢 | M2-03 | 16 well 逐个跑 | HouseDebugPageVM | ✔ |
 | M2-06 | 场景B 放皿后自动对焦接入触发 | 🟢 | M2-05 | 放皿自动出图 | HouseBin;安全门 | ✔ |
 | M2-07 | 对焦后界面手调拍摄层(well 级持久化) | 🟢 | M2-03 | 手调值写 house_well_setting | HouseDebugPageView;V-064 上行链 Java 编译 SUCCESS | ✔ |
-| M2-清理 | 对焦标定清理任务(scene=1 定期清理) | ❌ | M2-04 | 按天数清理、scene=0 保留 | 审计 C6:clean_autofocus_data 仅配置列无消费者 | ✔ |
+| M2-清理 | 对焦标定清理任务(scene=1 定期清理) | 🟢 | M2-04 | 按天数清理、scene=0 保留 | 审计 C6 / **G4-1✅2026-06-20**:DBService.CleanAutofocusData 物删 scene=1 过期(scene=0 永留)+AppData 每日维护窗口调度+读 tl_setting.clean_autofocus_data 下发值(C# 下发链 4 文件+ConvertHelper 3 路径补全;中央列+Java 链原已就绪);dotnet build operate 0 error;清理真入库待运行验 | ✔ |
 
-**M2 总评**:🟢 算法/公式/手调/单测可信,scene=0 致命 bug 本会话已修;标定实拍真机待验、清理任务(C6)未做
+**M2 总评**:🟢 算法/公式/手调/单测可信,scene=0 致命 bug 本会话已修;清理任务(C6/G4-1)本会话补齐(0 error);标定实拍真机、清理运行抽查待验
 
 ## M3 · 微服务改造(依据 04;审计 U4)
 
@@ -162,7 +162,7 @@
 - **G1 串口收尾**:T1.4 真机验证(借用→暂停→调试复用句柄→归还恢复,不报端口占用,需 GUI);ComBin 枚举阶段迁移去重(B 栈枚举阶段未迁移、未全删,迁移后真机验);写 EEPROM 调试动作补全(待 V-010 真机)。
 - **G2 UI**:首页舱室弹框位置/大小修复;M4 13 子页自适应(去写死像素 + Viewbox);TabTip 程序级屏蔽;well 三态色彩。
 - **G3 日志铺开**:~~operate 逐方法埋点(G3-1✅2026-06-20)~~;~~Java(tl-control/business)埋点(G3-2✅)~~;~~M8 §10 配置集中下发 / §11 本地兜底补送(C4,G3-3✅2026-06-20)~~。**G3 全清,真入库/补送/热生效待运行抽查。**
-- **G4 对焦/数据**:对焦标定清理任务(C6);建库脚本与 migration 合并 + 幂等 runner(C2);本地 SQLite 列迁移(V-046)。
+- **G4 对焦/数据**:~~对焦标定清理任务(C6,G4-1✅2026-06-20~~~~建库脚本与 migration 合并 + 幂等 runner(C2~~;本地 SQLite 列迁移(V-046,G4-3 真机门控)。
 - **G5 业务回归 / 真机验收**:M6 业务回归;M7 真机验收(按待验证清单逐条,含 operate 完整 GUI 业务流程、对焦实拍、首页舱室弹框、M4 子页自适应视觉)。
 
 > **真机门控**:G1 的 T1.4、G2 全部、G4 的对焦实拍、G5 全部需连下位机 + GUI 才能验收(见待验证清单 V-129~V-134)。

+ 6 - 5
项目文档/进度/进度数据.js

@@ -1,10 +1,10 @@
 // 进度数据(监控面板.html 读取)。每完成一步由助手回写,generatedAt 用于停滞检测。
 window.PROGRESS_DATA = {
   project: "时差培养箱合并改造",
-  generatedAt: "2026-06-20T23:05:00",
-  currentTask: "★G3-3 完成 → M8 全量操作日志 C# 端可写代码全清(G3 三任务收官)★:①§10 配置热生效——OperationLogOptions 加 ConfigFilePath/ApplyConfigJson + 新增 OperationLogConfigWatcher(后台轮询配置文件热应用,运维下发覆盖即生效不重编);②§11 兜底补送——KafkaOplogTransport 加 onDeliveryFailed(投递失败/队列满落兜底)、LocalFileWriter 加补送原语(原子认领 .resending)、Pipeline 加 TryResend 定时器(认领→重投→删,重入+限流);③门面 OperationLogger 接线 transport 传 onDeliveryFailed:WriteFallback/InitCore 起 Watcher/Shutdown 释放。dotnet build Aivfo.OperationLog 0 error 0 警告,消费端门面签名未变零改动,修了 WIP 遗留 2 处 JToken.Value<bool>() 编译错。真入库/补送/热生效待 Kafka+oplog 运行抽查。",
-  currentStep: "G3-3 配置集中下发+本地兜底补送完成(M8 G3 全清)",
-  nextStep: "剩余纯代码:G2 UI(首页弹框/13子页自适应/TabTip/well三态,视觉真机为准)或 G4-1(C6 对焦标定清理任务)。真机门控 G1-1(T1.4)/G4-3/G5 待用户在场。",
+  generatedAt: "2026-06-20T23:55:00",
+  currentTask: "★G4-1 对焦标定清理任务(C6)完成★:用户拍板配置走 tl_setting.clean_autofocus_data 中央下发列。该列+Java下发链(cleanAutofocusData默认30)中央原已就绪,仅缺C#消费者;补全①C#下发链4文件(tlSettingDTO/TLSettingDB/TLSetting/ConvertHelper 3路径)加cleanAutofocusData镜像focusLayerCount;②DBService.CleanAutofocusData(keepDays)物删house_autofocus_calibration scene=1过期、scene=0永留、keepDays<=0安全阀、全try兜底;③AppData每日维护窗口(autoFocusTime,与DeleteLog同源)调CleanAutofocusCalibration读TLSetting.cleanAutofocusData缺省30。dotnet build operate 0 error。清理真入库待运行验;本地SQLite旧库列迁移归G4-3(V-046真机门控)。",
+  currentStep: "G4-1 对焦标定清理任务(C6)完成",
+  nextStep: "剩余纯代码:G2 UI(首页弹框/13子页自适应/TabTip/well三态,视觉真机为准)或 G1-2(ComBin枚举迁移去重,交接卡注明需专门一轮+真机)。真机门控 G1-1(T1.4)/G3真入库抽查/G4-3(V-046)/G5 待用户在场。",
   phase: "★★三项目合并物理收尾完成 + 串口占用代码层已修(T1.1~T1.3,T1.4待GUI验) + Phase0功能bug已修(scene=0不拍照/kfka重复键/front去imageScore) + 真机硬件+API+服务起全闭环★★ 文档重组进行中,真机GUI全流程验收待续",
   note: "2026-06-20:在2026-06-19灾后恢复基础上,本会话完成三项目合并最后一公里——control物理并入operate/control/(顶层ivf_tl_control_2.0消失,operate自包含)、autofocustool删除、编译operate/front/单测三关0错误。真机验证:硬件层(7舱握手+三路温度+压力+舱门+电机偏差0+相机出图2592×1944+CCDSN映射)+业务API(登录/tl-control/business/surface getButtons/对焦下发V-047上行V-064)全闭环;data-transmission补建aivfo-tl库后Started(nacos 6服务)。串口占用代码层修复T1.1~T1.3(T1.4真机待GUI);功能bug修复T0.1~T0.3。M2-02单测重建23断言全通过。审计报告与会话续接文档内容已三层归位后删除。详见交接卡。",
   planTasks: [
@@ -16,6 +16,7 @@ window.PROGRESS_DATA = {
     { id: "M2-02test", name: "★M2-02单测重建23断言全通过+对焦公式逻辑验证★", status: "☑" },
     { id: "Phase4", name: "★容错读取接崩点(B6)+HTTP失联标记(C3)+down<count校验下沉+front接日志(C5)★", status: "☑" },
     { id: "G4-2", name: "★建库脚本与migration合并+幂等runner(C2):对焦表列/operation_log并入base+init-database.sh,临时容器全量+幂等验证★", status: "☑" },
+    { id: "G4-1", name: "★对焦标定清理任务(C6):DBService.CleanAutofocusData 物删 house_autofocus_calibration scene=1 过期(scene=0永留)+AppData 每日维护窗口调度+读 tl_setting.clean_autofocus_data 中央下发(C# 下发链4文件+ConvertHelper 3路径补全),operate 0 error;清理真入库待运行验★", status: "☑" },
     { id: "G3-3", name: "★配置集中下发+本地兜底补送(C4):§10 ConfigFilePath+OperationLogConfigWatcher 热加载 + §11 onDeliveryFailed 落兜底+TryResend 定时补送,dotnet build 0 error;真入库/补送待运行验★", status: "☑" },
     { id: "G3-2", name: "★Java操作日志埋点(tl-control 15C/90法+business 24C/121法贴@OperateLog)+两服务装M8三件套,编译BUILD SUCCESS;真入库待Kafka+oplog运行验★", status: "☑" },
     { id: "G3-1", name: "★operate逐方法埋点(VM层HouseDebug/Buffer/Main/UnifiedConfig+View code-behind加皿/胚胎/舱室设置/对焦设置命令入口,Begin scope+失败显式Fail),dotnet build 0 error;真入库待运行验★", status: "☑" },
@@ -58,7 +59,7 @@ window.PROGRESS_DATA = {
       { id: "M2-05", name: "场景A调试页一键标定", status: "🟢", env: true },
       { id: "M2-06", name: "场景B放皿后自动对焦", status: "🟢", env: true },
       { id: "M2-07", name: "对焦后界面手调拍摄层", status: "🟢", env: true },
-      { id: "M2-清理", name: "对焦标定清理任务(C6欠账)", status: "❌", env: true }
+      { id: "M2-清理", name: "对焦标定清理任务(C6/G4-1✅:DBService.CleanAutofocusData 物删scene=1过期+AppData每日调度+读tl_setting.clean_autofocus_data下发,0 error;真入库清理待运行验)", status: "🟢", env: false }
     ]},
     { id: "M3", name: "微服务改造(审计U4·质量最好)", tasks: [
       { id: "M3-DB", name: "自动对焦数据层SQL迁移(V-001☑)", status: "☑", env: true },

+ 6 - 7
项目文档/进度/进度状态.yaml

@@ -1,14 +1,13 @@
 # 续接断点状态(机器可解析)。换会话/换电脑后首先读它定位。
 # 状态取值: 未开始 / 进行中 / 完成 / 代码完成待验证
 # 纪律:本字段只存【当前断点】,历史细节进 交接卡.md(见 CLAUDE.md 第三节)。
-更新时间: 2026-06-20 G3-3 完成(M8 §10 配置集中下发热生效 + §11 本地兜底补送,G3 全清
+更新时间: 2026-06-20 G4-1 完成(对焦标定清理任务 C6,scene=1 物删/scene=0 永留
 当前任务: >
-  【★G3-3 完成 → M8 全量操作日志 C# 端可写代码全清(G3 三任务收官)★】
-  · §10 配置热生效:OperationLogOptions 加 ConfigFilePath/ApplyConfigJson + 新增 OperationLogConfigWatcher(后台轮询配置文件热应用,运维下发覆盖即生效不重编)。
-  · §11 兜底补送:KafkaOplogTransport 加 onDeliveryFailed(投递失败/队列满落兜底)、LocalFileWriter 加补送原语(原子认领 .resending)、Pipeline 加 TryResend 定时器(认领→重投→删,重入+限流)。
-  · 门面 OperationLogger 接线:transport 传 onDeliveryFailed:WriteFallback、InitCore 起 Watcher、Shutdown 释放。dotnet build Aivfo.OperationLog 0 error 0 警告;消费端门面签名未变零改动。修了 WIP 遗留 2 处 JToken.Value<bool>() 编译错。
-  · ★真入库/补送/热生效待起 Kafka+oplog 端到端抽查(运行期,非真机门控)★。本次未提交,待与 G3-3 牵动文档一并 git。
-  下一步:挑剩余纯代码任务——G2 UI(首页舱室弹框/13子页自适应/TabTip/well三态,最终视觉真机为准)或 G4-1(C6 对焦标定清理任务)。真机门控 G1-1(T1.4)/G4-3/G5 待用户在场。
+  【★G4-1 对焦标定清理任务(C6)完成★】用户拍板配置走 tl_setting.clean_autofocus_data 中央下发列。
+  · 发现该列(原始遗留,base 已含)+ Java 下发链(TlSetting/TlSettingVO cleanAutofocusData 默认30)中央端原已就绪,仅缺 C# 消费者。
+  · 补全:① C# 下发链 4 文件(tlSettingDTO/TLSettingDB/TLSetting/ConvertHelper 3 路径)加 cleanAutofocusData 镜像 focusLayerCount;② DBService.CleanAutofocusData(keepDays):物删 house_autofocus_calibration scene=1 且 calibTime<now-keepDays、scene=0 永留、keepDays<=0 安全阀不删、全 try 兜底返回条数;③ AppData 每日维护窗口(StartPushMessageThread autoFocusTime,与 DeleteLog 同源)调 CleanAutofocusCalibration,读 TLSetting.cleanAutofocusData 缺省30。
+  · dotnet build operate 0 error。★清理真入库待运行抽查;本地 SQLite 旧库 cleanAutofocusData 列迁移归 G4-3(V-046 真机门控)。本次未提交,待一并 git。
+  下一步:剩余纯代码 G2 UI(首页弹框/13子页自适应/TabTip/well三态,视觉真机为准);或 G1-2(ComBin 枚举迁移去重,交接卡注明需专门一轮+真机)。真机门控 G1-1(T1.4)/G3真入库/G4-3/G5 待用户在场。
   续接读:《工作计划表》+《当前开发计划》+ 本文件 + 交接卡末尾。
 说明: >
   M0-M5 全部【可写源码】已完成,C#合并端 0 error + M2-02 单测 15/15。工具链就位(JDK11.0.25 + Maven3.9.9

+ 2 - 0
项目文档/需求文档/12-工作计划表与自动对焦数据设计.md

@@ -264,6 +264,8 @@ house_autofocus_calibration (
 
 > 数据量评估:约 10 舱 × ≤16 well × 每天数次 × 30 天清理 ≈ 万级,单表足够,无需分表。
 
+> **实现状态(G4-1 ✅2026-06-20)**:`tl_setting.clean_autofocus_data`(默认30,原始遗留列)+ Java 下发链原已就绪;本次补 C# 消费者——下发链 4 文件(tlSettingDTO/TLSettingDB/TLSetting/ConvertHelper 3 路径)载 `cleanAutofocusData`;`DBService.CleanAutofocusData(keepDays)` 物理删 `scene=1` 且 `calibTime<now-keepDays`、`scene=0` 永留;`AppData.CleanAutofocusCalibration()` 挂每日维护窗口(autoFocusTime,与 DeleteLog 同源),keepDays 取内存 `TLSetting.cleanAutofocusData` 缺省 30。物删而非置 `deleted`(retention 需真正缩表)。本地 SQLite 旧库新列迁移见 G4-3/V-046。
+
 ### 2.8 数据库改动汇总
 
 | 改动 | 对象 | 说明 |