# 物料校验功能重构实现总结 ## 实现概述 本文档总结了物料校验功能的重构实现,包括新增的 DAO、扩展的校验逻辑和重构的 UI 界面。 ## 实现的文件 ### 1. 新建文件 #### `db/materials_to_be_deleted_records_dao.py` 新增的 DAO 类,用于操作 `MaterialsToBeDeleted` 表(按 MaterialCode 精确匹配)。 **主要功能:** - `upsert_material()` - 使用 MERGE 语句插入或更新单条记录 - `upsert_batch()` - 批量插入或更新记录 - `get_all_material_codes()` - 获取所有 MaterialCode(返回 Set 用于快速查找) - `get_all_records()` - 获取所有记录 - `get_record_by_material_code()` - 按 MaterialCode 查询单条记录 - `get_materials_by_manager()` - 按负责人查询 - `delete_by_material_code()` - 删除指定记录 - `delete_by_manager()` - 删除指定负责人的所有记录 - `delete_by_material_codes()` - 批量删除 - `material_exists()` - 检查 MaterialCode 是否存在 - `count_all()` - 统计记录数 - `count_by_manager()` - 统计指定负责人的记录数 - `get_statistics()` - 获取综合统计信息 **关键特性:** - 使用 SQL Server MERGE 语句实现原子性的 upsert 操作 - 自动记录 CreateTime 和 UpdateTime - 参数验证和错误处理 - 批量操作支持 ### 2. 修改文件 #### `utils/material_status_validator.py` 扩展了物料校验器,新增完整记录模式的支持。 **新增内容:** 1. **数据结构 `MaterialValidationResult`** ```python @dataclass class MaterialValidationResult: material_name: str material_code: str specification: Optional[str] = None model: Optional[str] = None manager_name: Optional[str] = None is_marked_for_deletion: bool = False matched_type_keyword: Optional[str] = None ``` 2. **新增方法 `match_materials_detailed()`** - 从 `DiscreteMaterialPlanData` 完整记录进行匹配 - 同时匹配 `MaterialsTypeToBeDeleted`(按 MaterialName)和 `MaterialsToBeDeleted`(按 MaterialCode) - 返回 `MaterialValidationResult` 对象列表 3. **新增方法 `validate_from_database_enhanced()`** - 支持全表模式和过滤模式 - 返回完整的物料记录信息 - 导出的 Excel 包含:材料名称、材料代码、规格、型号、负责人、已标记删除、匹配的关键词 #### `gui/material_validation_tab.py` 完全重构的 UI 界面,支持新的数据结构和交互方式。 **主要变更:** 1. **新增 `CheckboxTreeview` 组件** - 自定义 Treeview,支持 checkbox 列 - 使用 Unicode 字符 `☐`(未选中)和 `☑`(选中) - 支持点击切换、全选/取消全选 - 自动同步 checkbox 状态 2. **修改表格结构** - 旧列:材料名称、匹配的MaterialName、负责人、匹配状态 - 新列:选择、材料名称、材料代码、规格、型号、负责人 3. **可编辑单元格** - 双击"负责人"单元格弹出编辑对话框 - 使用 `simpledialog.askstring` 进行编辑 - 实时更新 UI 和日志 4. **新增按钮** - 全选按钮:选中所有记录 - 取消全选按钮:取消选中所有记录 - 确认删除按钮:将选中记录写入数据库 5. **确认删除流程** ``` 1. 验证是否有选中记录 2. 收集 MaterialCode 和 ManagerName 3. 验证 ManagerName 不为空 4. 显示确认对话框 5. 后台线程执行数据库操作 6. 完成后更新 UI 状态 ``` 6. **加载结果时设置 checkbox 状态** - 从 `MaterialsToBeDeleted` 表获取已标记的 MaterialCode - 自动设置对应记录的 checkbox 为选中状态 ## 表关系说明 ### 两个易混淆的表 | 表名 | 用途 | 匹配规则 | 字段 | DAO 类 | |------|------|----------|------|--------| | `MaterialsTypeToBeDeleted` | 物料类型表(已有) | MaterialName 包含匹配 | MaterialName, ManagerName | `MaterialsTypeToBeDeletedDAO` | | `MaterialsToBeDeleted` | 物料记录表(新建) | MaterialCode 精确匹配 | ID, MaterialCode, ManagerName | `MaterialsToBeDeletedDAO` | ### 数据流程 ``` ProductionID (总排号) ↓ [productionContractData].[26年压力表合同数据].[生产订单号] (SourceNumber) ↓ [dbo].[DiscreteMaterialPlanData].[SourceNumber] ↓ MaterialName, MaterialCode, Specification, Model ↓ 匹配 [dbo].[MaterialsTypeToBeDeleted] (MaterialName 包含匹配) → 负责人 匹配 [dbo].[MaterialsToBeDeleted] (MaterialCode 精确匹配) → 已标记删除 ``` ## 使用说明 ### 1. 数据库全表校验 1. 选择"数据库 - 全表校验"模式 2. 点击"开始校验" 3. 等待校验完成,结果会显示在表格中 4. 已标记删除的记录会自动勾选 checkbox ### 2. ProductionID 过滤校验 1. 选择"数据库 - ProductionID 过滤"模式 2. 选择 ProductionID.txt 文件 3. 点击"开始校验" 4. 等待校验完成 ### 3. 编辑负责人 1. 双击表格中的"负责人"单元格 2. 在弹出对话框中输入新的负责人姓名 3. 点击确定保存 ### 4. 确认删除 1. 勾选要删除的记录(使用 checkbox) 2. 可以使用"全选"或"取消全选"按钮 3. 点击"确认删除"按钮 4. 确认对话框中查看要删除的记录数 5. 点击"是"执行删除 6. 等待后台操作完成 ## 错误处理 ### 数据库错误 - 所有 DAO 方法都包含 try-except 错误处理 - 错误信息会打印到控制台 - UI 会显示错误消息框 ### 输入验证 - MaterialCode 不能为空 - ManagerName 不能为空(确认删除前验证) - 负责人姓名长度限制(最大 50 字符) ### 事务处理 - 使用 SQL Server MERGE 语句的原子性 - 要么全部成功,要么全部失败 - 批量操作时逐条处理,记录成功和失败数量 ## 测试建议 ### 功能测试 1. **全表校验**: 验证所有记录正确显示 2. **过滤校验**: 使用 ProductionID 文件,验证过滤逻辑 3. **Checkbox 操作**: 测试全选、取消全选、单独选择 4. **编辑负责人**: 双击单元格编辑,验证数据更新 5. **确认删除**: 选中记录点击确认删除,验证数据库写入 6. **重新加载**: 刷新数据,验证 checkbox 状态保持 ### 边界测试 1. **空结果集**: 数据库无记录时的处理 2. **ManagerName 为空**: 确认删除时的验证 3. **MaterialCode 为空**: 是否正确过滤 4. **大数据集**: 1000+ 条记录的性能 5. **网络中断**: 数据库连接失败的处理 ## 注意事项 1. **表名混淆** - `MaterialsTypeToBeDeleted` - 按材料名称模糊匹配 - `MaterialsToBeDeleted` - 按材料代码精确匹配 2. **Unicode Checkbox** - 使用 `☐` 和 `☑` 字符模拟 checkbox - 不同操作系统/字体可能显示不一致 3. **线程安全** - 数据库操作在后台线程执行 - UI 更新必须使用 `after()` 回调到主线程 4. **SQL Server 限制** - MERGE 语法兼容性 - 参数数量限制(批量操作时分批处理) 5. **向后兼容** - 保留原有的校验方法(`validate_from_database`) - 新增增强方法(`validate_from_database_enhanced`) - 不破坏现有功能