Commit e5d5c98e0a60cbafce30f2fa08753d915e6dbb45

Authored by zichun
1 parent 047d358b

docs: en wiki — document the KPI Work Center (FROUNT home dashboard)

Investigated the FROUNT home-page card titled `KPI监控` to determine
whether it's Activiti-driven (it isn't).

Findings:
- Endpoint: POST /xlyEntry/modelCenter/getModelCenter →
  BusinessModelCenterController.getModelCenter (xlyEntry,
  web/businessweb/) → BusinessModelCenterServiceImpl.getKPIModelList
  (thin wrapper) → BusinessModelKpiServiceImpl.getKPIModelList
  (xlyBusinessService).
- Internal name: "KPI Work Center" (Javadoc 初次获取KPI工作中心).
- Data source: gdsmodule rows where bUnTask=1, partitioned by sUnType
  ∈ {Pending, PendingCheck, MyWarning}. No KPI math; just open-task
  aggregation.
- Categorisation in UI: by role (sftlogininfojurisdictiongroup ⋈
  sisjurisdictionclassify) and by business flow (gdsmodule parent-
  child tree; "01/04, 02/04…" is the iOrder within a flow parent).
- Cache: @Cacheable(value="getKpiModelByUser") evicted by
  getModelCenterCalculation and gdsmodule-changing paths.
- Empirical proof of independence from Activiti: in this dev DB,
  biz_todo_item and biz_flow are both 0 rows, yet the KPI Work
  Center still shows non-zero counts. Activiti's task surface
  flows through CheckFlowController instead.

Updates:
- runtime.md: add BusinessModelCenterController row to the load-
  bearing-controllers table; new "The KPI Work Center" subsection
  with full architecture, data source, cache behaviour, and the
  why-not-Activiti contrast.
- internal.md: add /modelCenter/* row to the runtime endpoints
  table with cross-link.
en/docs/api-reference/internal.md
@@ -54,6 +54,7 @@ virtual tables) there is a parallel surface in @@ -54,6 +54,7 @@ virtual tables) there is a parallel surface in
54 | `/procedureCall/*` | `GenericProcedureCallController` | Generic stored-procedure invocation by name + parameters — see [generic procedure dispatch](../reference/maintainer/proc-dispatch.md). | 54 | `/procedureCall/*` | `GenericProcedureCallController` | Generic stored-procedure invocation by name + parameters — see [generic procedure dispatch](../reference/maintainer/proc-dispatch.md). |
55 | `/panel/*` | `ConfigformPanelController` | Panel-layout persistence in `gdsconfigformpanel`. | 55 | `/panel/*` | `ConfigformPanelController` | Panel-layout persistence in `gdsconfigformpanel`. |
56 | `/checkflow/*` | `CheckFlowController` | Activiti workflow surface (approve / reject / view) — only meaningful in deployments that run a flow. The class file is `CheckFlowController.java` (camelCase) but the `@RequestMapping` value is all-lowercase `/checkflow`. | 56 | `/checkflow/*` | `CheckFlowController` | Activiti workflow surface (approve / reject / view) — only meaningful in deployments that run a flow. The class file is `CheckFlowController.java` (camelCase) but the `@RequestMapping` value is all-lowercase `/checkflow`. |
  57 +| `/modelCenter/getModelCenter`, `/modelCenter/getModelCenterCalculation` | `BusinessModelCenterController` | The FROUNT home-page **KPI Work Center** card (titled `KPI监控`). Aggregates open tasks across modules tagged `gdsmodule.bUnTask=1`, partitioned by role and business flow. **Not Activiti-driven.** See [The KPI Work Center](../reference/maintainer/runtime.md#the-kpi-work-center-front-end-home-dashboard). |
57 58
58 ## Reporting and printing 59 ## Reporting and printing
59 60
en/docs/reference/maintainer/runtime.md
@@ -17,12 +17,93 @@ controllers and services that carry most of the generic form runtime. @@ -17,12 +17,93 @@ controllers and services that carry most of the generic form runtime.
17 | `GenericProcedureCallController` | `web/businessweb/` | Generic stored-procedure invocation by name + parameters. | `/procedureCall/doGenericProcedureCall` | 17 | `GenericProcedureCallController` | `web/businessweb/` | Generic stored-procedure invocation by name + parameters. | `/procedureCall/doGenericProcedureCall` |
18 | `ConfigformPanelController` | `web/businessweb/` | Panel-layout persistence in `gdsconfigformpanel`. | `/panel/get/{sFormId}`, `/panel/save/{sFormId}` | 18 | `ConfigformPanelController` | `web/businessweb/` | Panel-layout persistence in `gdsconfigformpanel`. | `/panel/get/{sFormId}`, `/panel/save/{sFormId}` |
19 | `CheckFlowController` | `web/businessweb/` | Activiti workflow surface (approve / reject / view) — only meaningful when workflow is deployed. | endpoints under `/checkflow/*` (the class file is `CheckFlowController.java` in camelCase but the `@RequestMapping` value is all-lowercase) | 19 | `CheckFlowController` | `web/businessweb/` | Activiti workflow surface (approve / reject / view) — only meaningful when workflow is deployed. | endpoints under `/checkflow/*` (the class file is `CheckFlowController.java` in camelCase but the `@RequestMapping` value is all-lowercase) |
  20 +| `BusinessModelCenterController` | `web/businessweb/` | The "KPI Work Center" home dashboard on FROUNT — open-task aggregation across modules tagged with `gdsmodule.bUnTask=1`. **Not Activiti-driven** despite the workflow-flavoured UI; reads from `gdsmodule` rows partitioned by `sUnType` ∈ {`Pending`, `PendingCheck`, `MyWarning`}. Cached per user. See [The KPI Work Center](#the-kpi-work-center-front-end-home-dashboard) below. | `/modelCenter/getModelCenter`, `/modelCenter/getModelCenterCalculation` |
20 21
21 Note that the controllers split across **two packages**: `businessweb/` 22 Note that the controllers split across **two packages**: `businessweb/`
22 hosts the runtime-facing endpoints, while `systemweb/` hosts the 23 hosts the runtime-facing endpoints, while `systemweb/` hosts the
23 metadata-CRUD endpoints used by the builder side. Both compile into the 24 metadata-CRUD endpoints used by the builder side. Both compile into the
24 same `xlyEntry` WAR. 25 same `xlyEntry` WAR.
25 26
  27 +## The KPI Work Center (front-end home dashboard)
  28 +
  29 +When a user lands on FROUNT (`http://<host>:8598/indexPage`), the home
  30 +page shows a card titled **`KPI监控`** ("KPI Monitor"). Despite the
  31 +name, this is *not* a KPI dashboard in the analytics sense — there
  32 +are no targets, no charts, no measurements. It's an **open-task
  33 +aggregator**: a unified inbox of "things you owe action on", grouped
  34 +by role and by business flow.
  35 +
  36 +The handler:
  37 +
  38 +- `POST /xlyEntry/modelCenter/getModelCenter` →
  39 + `BusinessModelCenterController.java:44-48` →
  40 + `BusinessModelCenterServiceImpl.getKPIModelList` (a thin wrapper) →
  41 + `BusinessModelKpiServiceImpl.getKPIModelList` in `xlyBusinessService`.
  42 +- `POST /xlyEntry/modelCenter/getModelCenterCalculation` recomputes
  43 + the counts and evicts the cache region `getKpiModelByUser`.
  44 +
  45 +The Javadoc on `getModelCenter` calls it **"初次获取KPI工作中心"**
  46 +("initial fetch of KPI Work Center") — that's the framework's
  47 +internal name for this surface.
  48 +
  49 +### Data source — `gdsmodule` open-task tagging
  50 +
  51 +The KPI Work Center reads from `gdsmodule`, not from
  52 +Activiti's `act_*` tables. Every module that participates in the
  53 +dashboard sets four columns on its `gdsmodule` row:
  54 +
  55 +| Column | Comment | Meaning |
  56 +|---|---|---|
  57 +| `bUnTask` | `是否增加到未清` ("add to open list?") | `1` = include in the dashboard, `0` = ignore |
  58 +| `sUnType` | `未清类型` ("open type") | Bucket: one of `Pending`, `PendingCheck`, `MyWarning` |
  59 +| `sChineseUnMemo`, `sEnglishUnMemo`, `sBig5UnMemo` | `未清描述` ("open description") | Display label per language |
  60 +
  61 +In the live dev DB, `bUnTask = 1` is set on **92** module rows, split:
  62 +
  63 +| `sUnType` | Count | Frontend bucket label |
  64 +|---|---:|---|
  65 +| `Pending` | 79 | 待处理事务 (pending tasks) |
  66 +| `PendingCheck` | 1 | 发起新事务 (initiate new) |
  67 +| `MyWarning` | 3 | 我的预警报表 (my warnings) |
  68 +| (NULL) | 9 | (untagged — excluded) |
  69 +
  70 +For each tagged module, `BusinessModelKpiServiceImpl` runs the
  71 +module's per-user count query and aggregates results by:
  72 +
  73 +- **Role** (按角色 in the UI): joins `sftlogininfojurisdictiongroup`
  74 + ⋈ `sisjurisdictionclassify` to map the calling user to roles, then
  75 + partitions counts by role.
  76 +- **Flow** (按流程 in the UI): the labels like `估价管理流程` /
  77 + `订单生产流程` come from the module's parent in the `gdsmodule`
  78 + tree — each business flow is a parent module containing 1-N
  79 + ordered child modules. The "01/04, 02/04…" step numbering in the
  80 + UI is the child module's `iOrder` within its parent flow.
  81 +
  82 +### Cache
  83 +
  84 +`@Cacheable(value="getKpiModelByUser", key=…)` caches the per-user
  85 +result; `getModelCenterCalculation` and any
  86 +`gdsmodule`-changing path invalidate this region via
  87 +[`CleanRedisServiceImpl`](cache-invalidation.md). With `bUnTask` /
  88 +`sUnType` editable through BACK's 系统模块配置 screen, a maintainer
  89 +adding a new "open task" to the dashboard does so by editing
  90 +metadata, not Java.
  91 +
  92 +### Why not Activiti?
  93 +
  94 +Activiti's job is **approval workflow** — when a row needs sign-off
  95 +through an N-step `act_re_procdef` graph, the `act_ru_task` /
  96 +`biz_todo_item` tables hold pending tasks per assignee. That is a
  97 +*different* surface from the KPI Work Center, even though both
  98 +present "things to do" to the user.
  99 +
  100 +In this dev DB, `biz_todo_item` and `biz_flow` are both empty
  101 +(0 rows) — yet the KPI Work Center still shows non-zero counts.
  102 +That's the empirical proof that the two systems are independent.
  103 +A deployment with active Activiti flows would surface those tasks
  104 +through `CheckFlowController` (`/checkflow/*`) and a separate flow
  105 +panel — not through the KPI Work Center.
  106 +
26 ## The five-key read 107 ## The five-key read
27 108
28 For any metadata-driven module, the request lifecycle (see 109 For any metadata-driven module, the request lifecycle (see