Batch Update Jx Data Job.md 15 KB

批量更新Jx数据作业

本文引用的文件

  • BatchUpdateJXDataJob.cs
  • SystemDataController.cs
  • Program.cs
  • QuartzUtil.cs
  • IPEasyUtility.cs
  • PerformanceItem.cs
  • UpdateJXDataFromIPEasyJob.cs
  • appsettings.json

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件围绕“批量更新Jx数据作业(BatchUpdateJXDataJob)”进行系统化技术文档梳理,覆盖其职责、执行流程、数据来源、关键算法、错误处理、性能特征与运维建议。该作业负责从IPEasy批量报表与网页抓取两种渠道获取绩效数据,对当月未结算且非特定前缀的绩效事项进行批量匹配与更新,并在字段变更时触发点数重算或仅保存更新。

项目结构

  • 作业实现位于 wispro.sp.api/Job/BatchUpdateJXDataJob.cs,实现 Quartz 的 IJob 接口。
  • 通过控制器接口触发执行,控制器位于 wispro.sp.api/Controllers/SystemDataController.cs。
  • 作业调度由 wispro.sp.api/Program.cs 中的 QuartzUtil 配置 Cron 触发器,按配置定时运行。
  • 数据抓取工具位于 wispro.sp.utility/IPEasyUtility.cs,提供报表下载与网页抓取能力。
  • 实体模型位于 wospro.sp.entity/PerformanceItem.cs,描述绩效事项的核心字段。
  • 补充作业 UpdateJXDataFromIPEasyJob.cs 提供单条抓取与批量抓取能力,作为补充手段。
graph TB
subgraph "API服务"
C["SystemDataController<br/>触发作业"]
P["Program<br/>Quartz调度"]
Q["QuartzUtil<br/>作业注册/触发器"]
end
subgraph "作业"
J["BatchUpdateJXDataJob<br/>批量更新Jx数据"]
UJ["UpdateJXDataFromIPEasyJob<br/>单条/批量抓取"]
end
subgraph "数据源"
IP["IPEasyUtility<br/>报表下载/网页抓取"]
DB["数据库<br/>PerformanceItem等"]
end
C --> J
P --> Q
Q --> J
J --> IP
J --> DB
UJ --> IP
UJ --> DB

图表来源

  • SystemDataController.cs
  • Program.cs
  • QuartzUtil.cs
  • BatchUpdateJXDataJob.cs
  • UpdateJXDataFromIPEasyJob.cs
  • IPEasyUtility.cs
  • PerformanceItem.cs

章节来源

  • SystemDataController.cs
  • Program.cs
  • QuartzUtil.cs

核心组件

  • BatchUpdateJXDataJob:实现 IJob,负责筛选当月待更新绩效事项、批量下载IPEasy报表、合并索引、逐条匹配与更新、统计与日志输出。
  • IPEasyUtility:封装浏览器自动化下载报表与网页抓取逻辑,支持等待文件下载完成、登录、报表导出、文件解析等。
  • PerformanceItem:绩效事项实体,包含案号、处理事项、阶段、系数、字数、核稿人、外部处理人、申请类型、案件类型、状态等字段。
  • UpdateJXDataFromIPEasyJob:补充的单条/批量抓取作业,可直接调用以更新个别或批量记录。
  • Quartz 调度:Program.cs 中通过 QuartzUtil 注册 Cron 触发器,按配置周期运行 BatchUpdateJXDataJob。

章节来源

  • BatchUpdateJXDataJob.cs
  • IPEasyUtility.cs
  • PerformanceItem.cs
  • UpdateJXDataFromIPEasyJob.cs
  • Program.cs

架构总览

作业执行链路:

  • 控制器 SystemDataController 提供 UpdateJXData 接口,异步启动 BatchUpdateJXDataJob。
  • Program.cs 使用 QuartzUtil 注册 BatchUpdateJXDataJob,按 appsettings.json 中 UpdateScheduleSetting 配置的 Cron 表达式定时触发。
  • BatchUpdateJXDataJob 从数据库筛选当月待更新记录,调用 IPEasyUtility 下载两个报表,构建“案号+处理事项”字典索引,逐条匹配更新;若匹配失败则单条抓取。
  • 更新完成后,如字段发生变更且非“特殊点数申诉”,则调用控制器刷新点数;否则仅保存更新。
sequenceDiagram
participant Client as "客户端/调用方"
participant Ctrl as "SystemDataController"
participant Job as "BatchUpdateJXDataJob"
participant Util as "IPEasyUtility"
participant DB as "数据库"
Client->>Ctrl : 调用 UpdateJXData()
Ctrl->>Job : 异步执行 Execute()
Job->>DB : 查询当月待更新的绩效事项
Job->>Util : 下载报表1上月完成案件
Util-->>Job : 返回DataTable
Job->>Util : 下载报表2中国一次OA授权表
Util-->>Job : 返回DataTable
Job->>Job : 构建“案号|处理事项”字典索引
loop 逐条处理
Job->>DB : 匹配DataRow或单条抓取
Job->>Util : 单条抓取网页抓取
Util-->>Job : 返回动态对象
Job->>DB : 更新字段并判断是否保存/重算
end
Job-->>Client : 日志与统计输出

图表来源

  • SystemDataController.cs
  • BatchUpdateJXDataJob.cs
  • IPEasyUtility.cs

详细组件分析

BatchUpdateJXDataJob 组件分析

  • 职责与入口
    • 实现 IJob.Execute,筛选当月未结算且非特定前缀的绩效事项,加载关联实体。
    • 通过 IPEasyUtility 下载两个报表,合并为统一字典索引。
    • 逐条匹配更新,匹配失败则单条抓取,带重试与异常处理。
    • 字段变更时根据申诉状态决定是否重算点数或仅保存。
  • 关键流程
    • 数据筛选:过滤 AgentFeedbackMemo、CalMonth 状态、CaseNo 前缀。
    • 报表下载:两个报表分别下载,异常捕获并记录。
    • 索引构建:以“案号|处理事项”为键,避免重复与冲突。
    • 匹配更新:优先批量匹配 DataRow,失败则单条抓取,最多重试三次。
    • 变更处理:字段变化时调用控制器刷新点数或直接保存。
  • 错误处理与日志
    • 分层 try/catch 记录异常与统计信息,输出到本地文本文件。
    • 单条抓取失败时最多重试三次,避免偶发网络/页面问题影响整体。
  • 性能与并发
    • 逐条处理并带短暂休眠,降低对目标系统的压力。
    • 字典索引 O(1) 查找,整体复杂度受记录数线性影响。
flowchart TD
Start(["开始 Execute"]) --> LoadItems["筛选当月待更新记录"]
LoadItems --> HasItems{"是否有待更新记录?"}
HasItems --> |否| End(["结束"])
HasItems --> |是| Download1["下载报表1"]
Download1 --> Download2["下载报表2"]
Download2 --> BuildIndex["构建案号|处理事项索引"]
BuildIndex --> Loop["逐条处理"]
Loop --> Match{"批量匹配成功?"}
Match --> |是| UpdateFromRow["从DataRow更新字段"]
Match --> |否| SingleFetch["单条抓取最多重试3次"]
UpdateFromRow --> Changed{"字段是否变更?"}
SingleFetch --> Changed
Changed --> |是| Refresh["刷新点数或保存"]
Changed --> |否| Next["继续下一条"]
Refresh --> Next
Next --> Loop
Loop --> Stats["输出统计与日志"]
Stats --> End

图表来源

  • BatchUpdateJXDataJob.cs

章节来源

  • BatchUpdateJXDataJob.cs

IPEasyUtility 组件分析

  • 报表下载
    • 支持根据报表名称导出并等待下载完成,自动处理文件大小稳定与扩展名清理。
    • 登录、切换框架、调用报表导出脚本、等待导出完成并下载。
  • 网页抓取
    • 提供获取单个案件的处理事项、系数、字数、核稿人、外部处理人、申请类型、案件系数、类型、阶段等信息的动态对象。
    • 内置等待元素、选择器、表格解析与文件下载流程。
  • 配置与环境
    • 读取账户、密码、下载目录、Chrome驱动路径、是否无头模式等配置。
    • 创建 ChromeDriver 并设置下载目录、禁用弹窗、隐式等待等参数。
classDiagram
class IPEasyUtility {
+DownloadReport(reportName, isModifyDate) DataTable
+GetPerformanceRecord(caseNo, doItem, caseStage) dynamic
-CreateChromeDriver(downloadPath) ChromeDriver
-Login(driver, wait) void
-WaitForFileDownload(dir, timeout) string
}

图表来源

  • IPEasyUtility.cs
  • IPEasyUtility.cs

章节来源

  • IPEasyUtility.cs

PerformanceItem 实体分析

  • 关键字段
    • 案号、处理事项、阶段、系数、字数、核稿人、外部处理人、申请类型、案件类型、状态、基础点数、申诉标记等。
  • 与作业的关系
    • BatchUpdateJXDataJob 依据这些字段进行匹配、更新与点数重算。
    • UpdateJXDataFromIPEasyJob 也基于这些字段进行赋值与保存。
erDiagram
PERFORMANCE_ITEM {
int Id PK
string CaseNo
string DoItem
string CaseStage
string CaseCoefficient
string DoItemCoefficient
int? ReviewerId
int? ExternalHandlerId
string ApplicationType
string CaseType
int? WordCount
double? BasePoint
string AgentFeedbackMemo
}

图表来源

  • PerformanceItem.cs

章节来源

  • PerformanceItem.cs

UpdateJXDataFromIPEasyJob 补充分析

  • 单条抓取与批量抓取
    • 提供 UpdateFromIPEasy 与 RefreshFromIPEasy_BatchThread,支持按条件筛选并批量更新。
    • 带重试机制与进度文件,避免重启后从头开始导致耗时过长。
  • 与 BatchUpdateJXDataJob 的关系
    • 两者互补:前者侧重单条/批量抓取,后者侧重批量报表匹配+单条兜底。
    • 均在字段变更时触发点数刷新或保存。

章节来源

  • UpdateJXDataFromIPEasyJob.cs
  • UpdateJXDataFromIPEasyJob.cs

依赖关系分析

  • BatchUpdateJXDataJob 依赖
    • Quartz IJob 接口(由 Program.cs 与 QuartzUtil 注册)
    • IPEasyUtility(报表下载与网页抓取)
    • 数据库上下文(EF Core)与实体 PerformanceItem
    • 控制器 PerformanceItemController(刷新点数)
  • Quartz 调度
    • Program.cs 通过 QuartzUtil.Add 注册 BatchUpdateJXDataJob,使用 appsettings.json 中 UpdateScheduleSetting 的 Cron 表达式。
  • 配置
    • IPEasy 登录凭据、下载目录、Chrome 驱动路径、无头模式等。
    • 邮件、附件存储等其他配置项。
graph LR
J["BatchUpdateJXDataJob"] --> Q["QuartzUtil"]
J --> U["IPEasyUtility"]
J --> E["EF Core/DbContext"]
E --> P["PerformanceItem"]
J --> C["PerformanceItemController"]
Q --> S["Program"]
S --> A["appsettings.json"]

图表来源

  • BatchUpdateJXDataJob.cs
  • QuartzUtil.cs
  • Program.cs
  • appsettings.json

章节来源

  • Program.cs
  • QuartzUtil.cs
  • appsettings.json

性能考量

  • 批量匹配效率
    • 使用字典索引 O(1) 查找,整体复杂度近似 O(N)。
  • 网络与IO
    • 报表下载与网页抓取均涉及浏览器自动化与文件IO,建议合理设置等待与重试策略。
  • 并发与节流
    • 逐条处理并带短暂休眠,避免对IPEasy造成过大压力。
  • 点数重算成本
    • 字段变更触发刷新点数,需注意数据库写入与计算开销。

[本节为通用性能讨论,无需列出具体文件来源]

故障排查指南

  • 常见问题
    • 报表下载失败或无数据:检查 IPEasy 登录凭据、报表名称、下载目录权限与网络连通性。
    • 网页抓取异常:检查 Chrome 驱动路径、无头模式配置、页面元素定位是否变化。
    • 字段未更新:确认申诉状态是否为“特殊点数申诉”,该状态下不会重算点数。
    • 重试仍失败:查看日志文件与异常堆栈,确认是否为偶发性网络波动。
  • 定位方法
    • 查看本地日志文件(批处理日志与抓取日志),关注统计信息与失败条目。
    • 在控制器中调用 UpdateJXData 接口进行手动触发,便于快速验证。
    • 检查 appsettings.json 中 IPEasySetting 与 UpdateScheduleSetting 配置是否正确。

章节来源

  • BatchUpdateJXDataJob.cs
  • IPEasyUtility.cs
  • appsettings.json

结论

BatchUpdateJXDataJob 通过“批量报表匹配+单条网页抓取”的双通道策略,高效地对当月绩效事项进行数据更新,并在字段变更时智能决定是否重算点数。结合 Quartz 的定时调度与完善的日志统计,该作业具备良好的稳定性与可观测性。建议在生产环境中持续监控日志与报表可用性,确保更新质量与系统健康。

[本节为总结性内容,无需列出具体文件来源]

附录

  • 触发方式
    • 控制器接口:SystemDataController.UpdateJXData
    • 定时调度:Program.cs + QuartzUtil + appsettings.json
  • 关键配置
    • UpdateScheduleSetting:Cron 表达式,控制作业执行频率
    • IPEasySetting:下载目录、账户、密码、Chrome 驱动路径、无头模式等
  • 相关作业
    • UpdateJXDataFromIPEasyJob:单条/批量抓取补充
    • CalJXJob:每日基础点数计算(与本作业配合)

章节来源

  • SystemDataController.cs
  • Program.cs
  • QuartzUtil.cs
  • appsettings.json
  • UpdateJXDataFromIPEasyJob.cs