docs/:系统梳理、架构优化方案、CR-02 三端功能设计修订(含 §15 三端一致性同步与平台统计分析)、公寓端/应用端/平台端分册、公寓统计分析与排名报表、公寓端小步迭代开发计划(IT-0~IT-8) dev/:RuoYi-Vue-master(后端)与 RuoYi-Vue2-master(前端)官方上游基线,未改动
36 KiB
10 公寓统计分析与排名报表
文档编号:
docs/平台端/10。性质:设计稿(Design Only),不是接口契约冻结稿;阶段二契约冻结评审通过后才落 DDL。 落地权威表述:本文件是「以公寓为单位的分类统计、周期报表与公寓排名」的唯一权威表述(PS-0110-22、图 10-1PS-05、表 10-110-3);口径裁决、三端状态映射、变更点与影响范围、施工单及验收登记见17 + 23~25)、契约CR-02 §15。 上位依据:docs/平台端/01表 1-4 / 表 1-5、docs/平台端/03表 3-6 / 3-8 / 3-10 / 3-16、docs/平台端/04表 4-10 与 §12 三条接口纪律、docs/平台端/06§7(F6 跨公寓报表汇总)与 §8、docs/平台端/08§1(worker 单活)、docs/平台端/09PR-10 / P-07、docs/设计变更/03(CR-02 表 3-12bizType、表 3-21 枚举、§14 账务扩展)。 硬约束:跨端仍为 **20 个接口编号(1v2-draft、平台不回调公寓;本节全部能力落在平台管理端**/platform/v1/admin/stat/**,不新增跨端编号、不新增bizType;公寓本地库业务表仍 59 张(新增统计表属平台库,另计);平台只聚合已上报数据,不重算公寓明细(表 4-10 边界、F6 要点 1、PR-10);所有跨公寓聚合在 SQL 层带gyIds[]范围(F6 要点 4、docs/平台端/03§5 四级隔离)。金额一律decimal(12,2)/ 字符串两位小数、比率decimal(6,4)、禁止浮点。
表 10-1 文档信息
| 项 | 内容 |
|---|---|
| 范围 | PS-01 指标口径、PS-02 周期汇总、PS-03 公寓排名、PS-04 报表生成与导出、PS-05 权限 / 异常 / 一致性;覆盖业务规则、交互流程、权限控制、异常处理、数据同步与状态映射 |
| 本端职责 | platform-report 为唯一生成方;platform-worker 为唯一调度方;platform.iam 管数据范围;其余模块零写入口 |
| 协同端 | 公寓端(经既有 #9 / #10 / #11 / #12 / #13 / #24 上行归集,不再新增上报义务)、应用端(只读报表入口,不产出统计) |
| 编号规则 | 功能项 PS-01PS-05;表 表 10-y、图 图 10-y 篇内连续;管理端接口 S-01S-07;决策点 Q-46Q-50;裁决 CR-C36CR-C42、流程 F-O / F-P / F-Q(见 CR-02 §15) |
| 术语 | 表名小写为设计命名(pl_apt_stat_*),存量平台表沿用 PL_* / GY_* 大写;gyid 只从会话解析;周期键 periodKey 格式固定 |
表 10-2 修订记录
| 版本 | 日期 | 修订内容 |
|---|---|---|
| v1.0 | 2026-11-10 | 首次形成:五类指标口径与数据源、月 / 季 / 年周期汇总、公寓分类排名、报表生成与导出、权限与异常、三端状态映射、Q-46~Q-50 与验收 8 项;明确"评价情况 / 房间周转"依赖 #13 摘要扩展、现金充值计为收入、PL_REPORT_DAILY 冻结后次日重算 + 修订标记 |
1. 定位与边界
1.1 五类统计与落点
表 10-3 统计分类、指标与权威数据源
| 分类 | 功能项 | 指标 | 权威数据源(平台库) | 上行来源 | 本期 |
|---|---|---|---|---|---|
| 公寓接待能力 | PS-01 |
入住人数 STAY_COUNT、叫乘人数 CALL_COUNT、评价情况 SATISFACTION_*、报警情况 ALARM_* |
PL_REPORT_DAILY(补列)、PL_RECEIVE_LOG(按 biz_type 计数)、pl_staff_performance_daily |
#9 CHECKIN / TABLET_RESULT、#8 TASK_ACK、#12 DEVICE_ALARM、#13 ARCHIVE 摘要 |
是 |
| 补贴发放情况 | PS-01 |
ALLOWANCE_ISSUE_AMOUNT / ALLOWANCE_ISSUE_COUNT |
PL_LEDGER_FLOW(type=ALLOWANCE)、PL_ALLOWANCE_RULE |
#10 LEDGER_OFFLINE |
是 |
| 补贴消费情况 | PS-01 |
ALLOWANCE_CONSUME_AMOUNT / ALLOWANCE_CONSUME_COUNT |
PL_LEDGER_FLOW(type=CONSUME 的 allowance_amount 补列) |
#10 LEDGER_OFFLINE(§14 allowanceAmount / cashAmount) |
是 |
| 现金充值情况(计为收入) | PS-01 |
CASH_RECHARGE_INCOME / CASH_RECHARGE_COUNT |
PL_LEDGER_FLOW(type=RECHARGE) |
#10 LEDGER_OFFLINE(rechargeChannel=OFFLINE_CASH) |
是 |
| 房间利用周转情况 | PS-01 |
ROOM_NIGHTS / ROOM_TURNOVER_RATE / ROOM_AVAILABLE |
PL_REPORT_DAILY(补列) |
#13 ARCHIVE 摘要 roomOccupancy |
是 |
1.2 与既有报表能力的关系
- 不重建、只扩展:
platform.report已有GET /summary/daily、GET /summary/quality、GET /compare、POST /exports(表 4-10)与PL_REPORT_DAILY/V_CALL_QUALITY底座(表 3-8)。本文件在其上补「分类周期指标 + 排名 + 报表周期」,不替换日报口径,也不改PL_REPORT_DAILY既有字段语义。 - 不重算明细:日报由 #11 / #12 / #24 小时增量 + 每日全量生成(F6),本节月 / 季 / 年汇总只从
PL_REPORT_DAILY+PL_LEDGER_FLOW+PL_RECEIVE_LOGrollup,禁止回查公寓库、禁止按apt_local_task/gy_jcxx明细重算(PR-10、表 4-10 边界)。 - 报表冻结纪律沿用:
PL_REPORT_DAILY一旦生成不可改;修正走次日重算 + 修订标记(F6 要点 6),本节的revision_no是该纪律在周期层的落地。 - 调度归属:
platform-worker单活(docs/平台端/08§1),platform-api不持有定时任务;任务进度复用既有PL_JOB_*,不引入消息中间件(docs/平台端/02§2)。
1.3 不变式
- 跨端 20 个编号、方向、路径不变;统计能力全部落在平台管理端
/platform/v1/admin/stat/**,不产生跨端副作用(表 4-10 §12 纪律①)。 - 新增数据一律走既有
payload/bizType扩展;#13 ARCHIVE摘要补satisfaction与roomOccupancy分组计数,不新增bizType、不新增接口编号、不要求公寓端上报明细。 - 平台零回调;公寓端仍"主动拉 + 主动推",统计结果不反向下发公寓。
- 所有平台表 UK 以
gyid为第一列;跨公寓查询必须在 SQL 层带gyIds[],不允许先查全量再应用层过滤(F6 要点 4)。 platform-report是pl_apt_stat_period/pl_apt_stat_rank的唯一写入方;platform-ledger仍是余额主账唯一写者;统计模块对账务表只读。- 归日以平台
serverReceivedAt为准;occurredAt只作业务时间轴,不参与日切(CR-02 表 3-11 / 表 3-14)。 amount一律字符串两位小数 /decimal(12,2),比率decimal(6,4);缺报不推断、不补零(F6 表 6-7 语音缺报口径推广到全部指标)。- 公寓本地库业务表仍 59 张;本节新增 2 张
pl_apt_stat_*属平台库,按docs/平台端/03§0 表 C-1 / C-2「平台库新增表另计」执行,不纳入 59 张校验。 PL_REPORT_DAILY冻结不可原地改;周期修正只能新revision_no+state=REVISED,历史版本保留可追溯。- 统计不成为业务准入门槛:排名与报表结果不回写
gy_jcxx/apt_local_task/GY_YKT_REMAINDER等任何业务表。
2. 状态流转总览
图 10-1 数据流与生成链路
flowchart LR
subgraph AP["公寓服务系统"]
DEV["平板 / 签到终端 / 消费终端"]
OUT["apt-report / outbox"]
end
subgraph PL["平台端"]
ING["platform-ingest<br/>#9/#10/#12/#13 去重"]
JOB["platform-worker(单活)<br/>PL_JOB_* 协调锁"]
DAILY["PL_REPORT_DAILY<br/>日报底座(冻结不可改)"]
FLOW["PL_LEDGER_FLOW<br/>账务归集流水"]
LOG["PL_RECEIVE_LOG<br/>bizType 计数"]
PER["pl_apt_stat_period<br/>周期指标(revision_no)"]
RANK["pl_apt_stat_rank<br/>分类排名快照"]
REP["platform-report<br/>/admin/stat/**"]
EXP["report-export 桶"]
end
subgraph DUTY["应用端 / 管理端"]
UI["值班台 / 管理端报表页(只读)"]
end
DEV -->|上行| OUT
OUT -->|20 个既有编号| ING
ING --> LOG
ING -->|#11/#12/#24 小时增量 + 日全量| DAILY
ING -->|#10 归日| FLOW
JOB -->|日切后触发| DAILY
DAILY -->|rollup 月/季/年| PER
FLOW -->|rollup 账务三类| PER
LOG -->|缺报判定 / 计数| PER
PER -->|RANK() 跳号| RANK
PER --> REP
RANK --> REP
REP --> UI
REP --> EXP
表 10-4 三条状态链(互不替代)
| 链 | 字段 / 载体 | 取值 | 唯一写入口 | 说明 |
|---|---|---|---|---|
| 日报生成态 | PL_REPORT_DAILY + PL_JOB_*.state |
PENDING / RUNNING / DONE / FAILED(任务态);日报行一旦生成即冻结 |
platform-worker → platform-report |
沿用表 3-10 / 表 6-7;PF-7001 不输出半成品 |
| 周期指标态 | pl_apt_stat_period.state + revision_no |
DRAFT / FINAL / REVISED;revision_no 从 1 单调 |
platform-report |
FINAL 后不可改;修正走新 revision_no 且旧行标 REVISED |
| 排名快照态 | pl_apt_stat_rank.revision_no + generated_at |
与周期指标同版;无独立业务状态字段 | platform-report |
排名不随查询实时重算,只按 revision_no 读快照 |
表 10-5 全流程状态流转
| 序 | 流程 | 状态 | 触发 | 写入口与落表 | 后继 / 异常回退 |
|---|---|---|---|---|---|
| 1 | 上行归集 | RECEIVED |
#9 / #10 / #12 / #13 到达 | platform-ingest → PL_RECEIVE_LOG |
idempotencyKey 重复 → PL-IDEMPOTENT-REPLAY;版本落后 → PL-VERSION-STALE |
| 2 | 日报 | RUNNING → DONE |
每日日切后 platform-worker 全量 |
PL_REPORT_DAILY、PL_JOB_* |
缺报指标 NO_DATA,不推断、不补零;超时 > 10 min 拆批 |
| 3 | 账务日对账 | RECONCILED / DIFF |
platform-ledger 三维比对 |
PL_RECONCILE_BATCH、PL_LEDGER_FLOW.reconcile_state |
DIFF → PF-5003 阻断调账,该 gyid 当期账务类指标不封账、不参与排名 |
| 4 | 周期汇总 | DRAFT |
月 / 季 / 年周期到达或手工 S-03 生成 |
pl_apt_stat_period |
源日报未 DONE → PF-7003 周期未封账,任务 FAILED |
| 5 | 周期汇总 | FINAL |
源数据齐备 + 对账无 DIFF |
pl_apt_stat_period.state=FINAL |
生成后不可原地改 |
| 6 | 修正 | REVISED + 新 revision_no |
次日重算 / 人工发起修订 | 新行 + 旧行标 REVISED |
同 (gyid, periodType, periodKey, revisionNo) 幂等,重复返回原结果 |
| 7 | 排名 | 快照生成 | 周期指标 FINAL 后 |
pl_apt_stat_rank |
同分同名次(RANK() 跳号);gyIds[] 越权 → PF-7004 |
| 8 | 导出 | PENDING → DONE / FAILED |
S-06 异步导出 |
report-export 桶、PL_JOB_* |
失败 PF-7002,短期签名默认 7 天 |
图 10-2 周期汇总与排名判定
flowchart TD
A["周期到达 / S-03 生成请求"] --> B{"gyIds[] 在会话数据范围内?"}
B -->|否| Z1["PF-7004 拒绝"]
B -->|是| C{"PL_JOB_* 已有同 key 运行中?"}
C -->|是| Z2["返回原 jobId(幂等)"]
C -->|否| D["建 job(RUNNING)+ 协调锁"]
D --> E{"源日报 DONE 且当日对账无 DIFF?"}
E -->|否| Z3["FAILED / PF-7003<br/>账务类指标不封账"]
E -->|是| F["rollup 五类指标 → DRAFT"]
F --> G{"全部指标源齐备?"}
G -->|否| H["缺报项标 NO_DATA<br/>不推断不补零"]
G -->|是| I["FINAL + revision_no=1"]
H --> I
I --> J["RANK() 生成分类排名快照"]
J --> K["S-01 / S-02 可查;S-06 可导出"]
3. 数据模型
仅新增 2 张平台库表(另计,不纳入公寓本地库 59 张);任务进度复用
PL_JOB_*,导出复用report-export桶,日报沿用PL_REPORT_DAILY。所有补列均为设计定义,DDL 待阶段二契约冻结评审(Q-48)。
表 10-6 复用表与新增表清单
| 表 | 库 | 唯一写入模块 | 本流程用途 | 本模块权限 |
|---|---|---|---|---|
PL_REPORT_DAILY |
platform | platform-report |
日报底座;入住 / 叫乘 / 报警 / 房间周转 / 评价的分类日值 | 只读(补列由日报生成时写入) |
PL_RECEIVE_LOG |
platform | platform-ingest |
按 biz_type 计数、缺报判定、幂等去重核对 |
只读 |
PL_LEDGER_FLOW |
platform | platform-ledger |
补贴发放 / 补贴消费 / 现金充值三类金额与笔数 | 只读 |
PL_RECONCILE_BATCH / PL_RECONCILE_DIFF |
platform | platform-ledger |
封账前置判据(DIFF 阻断) |
只读 |
pl_staff_performance_daily |
platform | platform-report |
评价情况的辅助交叉校验(不替代评价计数) | 只读 |
PL_TASK / PL_TASK_ACK |
platform | platform.plan / platform-ingest |
叫乘人数交叉校验 | 只读 |
PL_JOB_* |
platform | platform-worker |
生成 / 导出任务状态与协调锁 | 只读 |
pl_apt_stat_period |
platform | platform-report |
新增:按公寓 × 周期 × 指标的分类汇总(含修订版本) | 读写 |
pl_apt_stat_rank |
platform | platform-report |
新增:分类排名快照 | 读写 |
表 10-7 pl_apt_stat_period 列级结构(新增)
| 列 | 类型 | 约束 | 说明 |
|---|---|---|---|
id |
id_ulid | PK | 代理主键 |
gyid |
string(32) | NOT NULL,UK 第一列 | 公寓隔离;只从会话 / 归集数据解析 |
period_type |
enum_s | MONTH / QUARTER / YEAR |
周期类型 |
period_key |
string(16) | YYYY-MM / YYYY-Qn / YYYY |
周期键,格式固定,服务端生成 |
metric_class |
enum_s | RECEPTION / ALLOWANCE_ISSUE / ALLOWANCE_CONSUME / CASH_RECHARGE_INCOME / ROOM_TURNOVER |
五类统计 |
metric_code |
enum_s | 见表 10-9 | 指标编码 |
metric_value |
decimal(18,2) | 可空 | 金额 / 人数 / 笔数;NULL 表示 NO_DATA(不写 0) |
metric_unit |
enum_s | PERSON / COUNT / AMOUNT / RATIO / ROOM_NIGHT |
单位;比率另以 decimal(6,4) 精度约束 |
data_status |
enum_s | OK / NO_DATA / BLOCKED |
NO_DATA 缺报、BLOCKED 对账 DIFF 未封账 |
source_version |
bigint | 默认 1 |
源日报 / 流水版本水位,用于对账追溯 |
state |
enum_s | DRAFT / FINAL / REVISED |
表 10-4 周期指标态;FINAL 不可原地改 |
revision_no |
bigint | 默认 1,单调 |
修正走 +1,旧行标 REVISED |
generated_at / created_at |
datetime(3) ×2 | NOT NULL | 生成 / 落库时间 |
UK (gyid, period_type, period_key, metric_code, revision_no);IDX (gyid, period_type, period_key, metric_class, state) |
幂等与周期查询 |
表 10-8 pl_apt_stat_rank 列级结构(新增)
| 列 | 类型 | 约束 | 说明 |
|---|---|---|---|
id |
id_ulid | PK | 代理主键 |
gyid |
string(32) | NOT NULL,UK 第一列 | 公寓隔离 |
period_type / period_key |
enum_s / string(16) | 同表 10-7 | 周期 |
rank_type |
enum_s | RECEPTION / ALLOWANCE_ISSUE / ALLOWANCE_CONSUME / CASH_RECHARGE_INCOME / ROOM_TURNOVER / COMPOSITE |
分类排名 + 综合排名 |
rank_no |
int | NOT NULL | RANK() 跳号;同分同名次 |
score |
decimal(18,4) | 可空 | 排名依据分值;综合排名权重见 Q-49 |
tie_count |
int | 默认 1 |
并列公寓数 |
revision_no / generated_at |
bigint / datetime(3) | 与周期指标同版 | 快照版本一致,不实时重算 |
UK (gyid, period_type, period_key, rank_type, revision_no);IDX (period_type, period_key, rank_type, rank_no) |
榜单查询 |
表 10-9 指标字典(五类)
| 分类 | 指标编码 | 单位 | 口径公式 | 数据源 | 缺报处理 |
|---|---|---|---|---|---|
RECEPTION 接待能力 |
STAY_COUNT |
PERSON | sum(PL_REPORT_DAILY.stay_count) |
日报 #9 CHECKIN |
NO_DATA |
CALL_COUNT |
PERSON | sum(PL_REPORT_DAILY.call_count) |
日报 #8 / #9 TABLET_RESULT、#24 |
NO_DATA |
|
SATISFACTION_GOOD / SATISFACTION_NEUTRAL / SATISFACTION_BAD / SATISFACTION_TOTAL |
COUNT | sum(PL_REPORT_DAILY.satisfaction_* 补列) |
#13 ARCHIVE 摘要 satisfaction{} 扩展 |
NO_DATA;参评数为 0 时不计算好评率 |
|
SATISFACTION_RATE |
RATIO | GOOD / TOTAL,decimal(6,4) |
同上 | TOTAL=0 → NO_DATA,不记 0 |
|
ALARM_COUNT / ALARM_CALL / ALARM_LEAVE / ALARM_DEVICE |
COUNT | #12 按 alarmSource 分组计数 |
日报补列 + PL_RECEIVE_LOG |
NO_DATA |
|
ALLOWANCE_ISSUE 补贴发放 |
ALLOWANCE_ISSUE_AMOUNT |
AMOUNT | sum(amount) where type=ALLOWANCE,正数 |
PL_LEDGER_FLOW |
对账 DIFF → BLOCKED |
ALLOWANCE_ISSUE_COUNT |
COUNT | count(flow_id) 按 biz_id 去重(R-C3) |
同上 | BLOCKED |
|
ALLOWANCE_CONSUME 补贴消费 |
ALLOWANCE_CONSUME_AMOUNT |
AMOUNT | sum(allowance_amount) where type=CONSUME |
PL_LEDGER_FLOW.allowance_amount(补列,CR-02 §14) |
BLOCKED |
ALLOWANCE_CONSUME_COUNT |
COUNT | 同上笔数 | 同上 | BLOCKED |
|
CASH_RECHARGE_INCOME 现金充值(收入) |
CASH_RECHARGE_INCOME |
AMOUNT | sum(amount) where type=RECHARGE,正数 |
PL_LEDGER_FLOW |
BLOCKED |
CASH_RECHARGE_COUNT |
COUNT | 同上笔数 | 同上 | BLOCKED |
|
ROOM_TURNOVER 房间利用周转 |
ROOM_AVAILABLE / ROOM_NIGHTS |
ROOM_NIGHT | sum(PL_REPORT_DAILY.room_available / room_nights 补列) |
#13 ARCHIVE 摘要 roomOccupancy{} 扩展 |
NO_DATA |
ROOM_TURNOVER_RATE |
RATIO | ROOM_NIGHTS / ROOM_AVAILABLE,decimal(6,4) |
同上 | 分母 0 → NO_DATA |
现金充值计为收入(CR-C37):
CASH_RECHARGE_INCOME是期间流入额,按sum(amount)正数统计,不与消费净额抵销、不冲减补贴发放、不记入余额负债;与GY_YKT_REMAINDER的余额快照是两个口径,禁止互相校验。 补贴消费拆分(CR-C38):一笔消费只一条flow_id(CR-C31),补贴部分取allowance_amount、现金部分取cash_amount;ALLOWANCE_CONSUME_AMOUNT只取前者,避免与sum(amount)混用导致双计。 评价与房间周转的数据来源(CR-C39):两项均由公寓端在既有 #13ARCHIVE日归档摘要中按payload扩展分组计数上报(satisfaction{}/roomOccupancy{},摘要类按批覆盖、无版本语义,表 3-13),平台只接计数不接明细、不新增bizType;若公寓端本期未上报,指标标NO_DATA并在报表注明"数据未接入",不推断、不补零、不以pl_staff_performance_daily代填(Q-46)。
表 10-10 既有表补列(设计定义,DDL 待阶段二冻结)
| 表 | 补列 | 用途 |
|---|---|---|
PL_REPORT_DAILY |
satisfaction_good / satisfaction_neutral / satisfaction_bad / satisfaction_total |
#13 摘要评价分组计数 |
alarm_call / alarm_leave / alarm_device |
#12 按 alarmSource 分组计数 |
|
room_available / room_nights |
#13 摘要房间可用夜 / 占用夜 | |
source_version / revision_no |
日报水位与修订标记(F6 要点 6 落地) | |
PL_LEDGER_FLOW |
allowance_amount / cash_amount / recharge_channel |
承接 CR-02 §14 #10 payload 拆分字段,供分类统计 |
表 10-11 枚举字典
| 枚举 | 取值 | 来源 / 说明 |
|---|---|---|
periodType |
MONTH / QUARTER / YEAR |
本流程定义;periodKey = YYYY-MM / YYYY-Qn / YYYY |
metricClass |
RECEPTION / ALLOWANCE_ISSUE / ALLOWANCE_CONSUME / CASH_RECHARGE_INCOME / ROOM_TURNOVER |
五类统计 |
dataStatus |
OK / NO_DATA / BLOCKED |
缺报与对账阻断,不写 0 |
statState |
DRAFT / FINAL / REVISED |
周期指标态 |
rankType |
五类 + COMPOSITE |
分类排名 + 综合排名(Q-49) |
jobState |
PENDING / RUNNING / DONE / FAILED |
沿用 PL_JOB_* / PL_REPLAY_JOB.state(表 3-10) |
reconcileState |
RECEIVED / RECONCILED / DIFF |
沿用 PL_LEDGER_FLOW.reconcile_state,不新造 |
4. PS-01~PS-03 指标、周期与排名
4.1 业务规则
表 10-12 周期口径(CR-C36)
| 项 | 口径 |
|---|---|
| 日切 | 以平台 serverReceivedAt 归日;公寓 occurredAt 不参与日切(CR-02 表 3-11) |
| 月 | periodType=MONTH、periodKey=YYYY-MM;自然月 1 日 00:00 至月末 24:00(平台时区) |
| 季 | periodType=QUARTER、periodKey=YYYY-Qn(Q1=1 |
| 年 | periodType=YEAR、periodKey=YYYY;自然年 |
| 生成方式 | 月 / 季 / 年一律由日报 rollup,不直接扫明细表;周期边界以日报 stat_date 归属 |
| 封账前置 | 期内所有日报 DONE 且账务日对账无 DIFF;否则 PF-7003,账务类指标 BLOCKED、不参与排名 |
| 修正 | PL_REPORT_DAILY 冻结不可改 → 次日重算生成新 revision_no,旧行标 REVISED,历史版本可追溯 |
表 10-13 排名规则(CR-C40)
| 项 | 口径 |
|---|---|
| 维度 | 以 gyid(公寓)为单位,对五类指标与 COMPOSITE 分别排名 |
| 名次序 | RANK() 跳号、同分同名次,tie_count 记并列数;不使用 ROW_NUMBER() 人为拆开并列 |
| 范围 | gyIds[] 必须由会话数据范围解析,SQL 层带范围(F6 要点 4);空 / 越权 → PF-7004 |
| 参与条件 | 仅 state=FINAL、data_status=OK/BLOCKED 之外的有效指标;NO_DATA 公寓不参与该指标排名并在榜单标注 |
| 快照 | 排名按 revision_no 存快照,查询不实时重算;周期修正后生成新版本快照 |
| 综合排名 | COMPOSITE 权重默认五类等权(Q-49 待决),缺类时按剩余类归一化,须在报表注明权重版本 |
| 方向 | 报警数、投诉类指标为逆向指标(越小越优),默认按"越小越靠前",Q-49 拍板前按此执行 |
4.2 接口
表 10-14 管理端接口 S-01~S-07(/platform/v1/admin/stat/**,不计入跨端 20 编号)
| 编号 | 方法 + 路径 | 权限点 | 幂等 | 请求字段 | 响应字段 |
|---|---|---|---|---|---|
| S-01 | GET /stat/periods |
platform:stat:list |
L0 | gyIds[](会话范围)、periodType、periodKey、metricClass、revisionNo(可选) |
items[]{gyid, gyName, periodType, periodKey, metricClass, metricCode, metricValue, metricUnit, dataStatus, state, revisionNo}、revisionNo、serverTime |
| S-02 | GET /stat/ranks |
platform:stat:rank |
L0 | gyIds[]、periodType、periodKey、rankType、revisionNo |
items[]{rankNo, gyid, gyName, score, tieCount, dataStatus}、weightVersion、revisionNo |
| S-03 | POST /stat/generate |
platform:stat:generate |
L2 Idempotency-Key |
periodType、periodKey、gyIds[]、reason(修订时必填)、Idempotency-Key |
jobId、state=PENDING、periodType / periodKey、idempotentReplay |
| S-04 | GET /stat/jobs/{jobId} |
platform:stat:list |
L0 | jobId |
jobId、state、progress、startedAt / finishedAt、errorCode、revisionNo |
| S-05 | GET /stat/metrics |
platform:stat:list |
L0 | 无 | metrics[]{metricClass, metricCode, metricUnit, formula, dataSource, direction}、weightVersion |
| S-06 | POST /stat/exports |
platform:stat:export |
L2 Idempotency-Key |
periodType、periodKey、gyIds[]、rankTypes[]、format(XLSX / PDF)、Idempotency-Key |
exportId、state=PENDING |
| S-07 | GET /stat/exports/{exportId} |
platform:stat:export |
L0 | exportId |
exportId、state、fileRef、signUrl(短期签名)、expiresAt |
接口纪律(表 4-10 §12):① 管理接口不产生跨端副作用,只落
pl_apt_stat_*/PL_JOB_*/report-export;② 写接口 S-03 / S-06 必须带Idempotency-Key;③ 每个接口在docs/平台端/03都能找到落表(表 10-6)。导出复用既有/exports通道与report-export桶,不新增桶。
表 10-15 生成状态机(条件更新带 state 期望值)
| 当前态 | 事件 | 目标态 | 落表 | 失败 / 补偿 |
|---|---|---|---|---|
| — | S-03 提交且 gyIds[] 合法 |
PENDING → RUNNING |
PL_JOB_* |
同 key 运行中 → 返回原 jobId;越权 PF-7004 |
RUNNING |
源日报 DONE + 对账无 DIFF |
DRAFT |
pl_apt_stat_period |
未封账 PF-7003 → FAILED;DIFF → 账务类 BLOCKED |
DRAFT |
指标齐备校验通过 | FINAL |
pl_apt_stat_period |
缺报项标 NO_DATA,不推断不补零 |
FINAL |
排名生成 | 排名快照 | pl_apt_stat_rank |
并列按 RANK() 跳号;NO_DATA 公寓不参与 |
FINAL / REVISED |
次日重算 / 人工修订 | 新 revision_no + 旧行 REVISED |
两张 pl_apt_stat_* |
版本冲突 PF-7005;不原地改 FINAL 行 |
| 任意 | worker 双跑 / 超时 | FAILED |
PL_JOB_* |
库级协调锁防双跑;> 10 min 拆批(docs/平台端/08 §4) |
图 10-3 生成与导出时序
sequenceDiagram
autonumber
participant W as platform-worker(单活)
participant R as platform-report
participant D as PL_REPORT_DAILY / PL_LEDGER_FLOW
participant S as pl_apt_stat_period / rank
participant U as 管理端 / 应用端(只读)
participant E as report-export
W->>R: 周期到达(月/季/年)或 S-03 触发
R->>D: 只读日报与账务流水(SQL 层带 gyIds[])
D-->>R: 日值与三类金额
R->>R: 校验封账(日报 DONE + 对账无 DIFF)
R->>S: rollup 五类指标 → FINAL(revision_no=1)
R->>S: RANK() 生成分类 / 综合排名快照
U->>R: S-01 查周期指标 / S-02 查排名
R-->>U: 按 revision_no 读快照(不实时重算)
U->>R: S-06 导出(Idempotency-Key)
R->>E: 异步生成 XLSX / PDF,短期签名 7 天
E-->>U: S-07 取 fileRef / signUrl
Note over W,E: 全程不回查公寓库、不重算明细、不产生跨端副作用
5. PS-04 报表输出与 PS-05 权限、异常、一致性
5.1 报表输出
表 10-16 报表清单与内容
| 报表 | 周期 | 内容 | 出口 |
|---|---|---|---|
| 公寓分类统计表 | 月 / 季 / 年 | 按 gyid × 五类指标展开;含 data_status / revision_no / 权重版本 |
S-01、S-06 |
| 公寓接待能力报表 | 月 / 季 / 年 | 入住人数、叫乘人数、评价(好 / 中 / 差 / 参评 / 好评率)、报警(总 / 叫乘 / 离寓 / 设备) | S-01、S-06 |
| 补贴发放与消费报表 | 月 / 季 / 年 | 发放额 / 笔数、补贴消费额 / 笔数、补贴使用率(ALLOWANCE_CONSUME / ALLOWANCE_ISSUE) |
S-01、S-06 |
| 现金充值收入报表 | 月 / 季 / 年 | 充值额(计收入)/ 笔数、与消费额分列不抵销 | S-01、S-06 |
| 房间利用周转报表 | 月 / 季 / 年 | 可用房间夜、占用房间夜、周转率 | S-01、S-06 |
| 公寓排名榜 | 月 / 季 / 年 | 五类分类排名 + 综合排名,含并列标记与 NO_DATA 标注 |
S-02、S-06 |
所有报表在页脚注明:数据来源(
PL_REPORT_DAILY/PL_LEDGER_FLOW/ #13 摘要)、periodKey、revisionNo、weightVersion、生成时间与gyIds[]范围;不展示未封账周期(PF-7003)。
5.2 权限与审计
表 10-17 权限与审计
| # | 要求 |
|---|---|
| 1 | 数据范围前置:gyIds[] 从会话数据范围解析,不接受"不传即全量";SQL 层带范围,空 / 越权 PF-7004 并记审计(docs/平台端/03 §5、F6 要点 4) |
| 2 | 权限点:platform:stat:list / rank / generate / export 四级;生成与导出需二次确认,导出仅返回短期签名地址 |
| 3 | 职责分离:platform-worker 只调度、platform-report 只生成、platform.iam 只管范围;统计模块对 PL_LEDGER_FLOW / GY_YKT_REMAINDER 只读,永不写余额(docs/平台端/03 表 3-6) |
| 4 | 只读消费端:应用端值班台与管理端报表页只读 S-01 / S-02 / S-05 / S-07;不得经 /duty/** 触发 S-03 / S-06,也不得写 pl_apt_stat_* |
| 5 | 审计:生成、修订、导出、排名查询四类动作记 PL_JOB_* / 平台操作日志(操作人、gyIds[]、periodKey、revisionNo、Idempotency-Key、结果) |
| 6 | 最小必要:报表不含人员姓名、工号、人脸引用、业务抓拍;评价与房间周转只收分组计数,不收明细 |
| 7 | 金额安全:decimal(12,2) / 字符串两位小数、比率 decimal(6,4),禁止浮点;CASH_RECHARGE_INCOME 与余额快照禁止互相校验 |
5.3 异常
表 10-18 异常与错误码
| 场景 | 处理 | 不做什么 |
|---|---|---|
日报未 DONE / 周期未封账 |
PF-7003、任务 FAILED |
不输出半成品(PF-7001)、不用 DRAFT 数据出报表 |
日对账 DIFF |
账务三类 BLOCKED、PF-5003 阻断调账,该 gyid 不参与账务类排名 |
不直改余额表、不按未对账金额排名 |
| 指标缺报(评价 / 房间周转 / 语音等) | data_status=NO_DATA,报表注明"数据未接入" |
不推断、不补零、不以其他表代填(F6 表 6-7) |
gyIds[] 为空 / 越权 / 含跨租户 |
PF-7004 拒收并记审计 |
不先查全量再应用层过滤 |
| 生成任务双跑 / 重复提交 | 库级协调锁 + Idempotency-Key,重复返回原 jobId |
不产生两份周期指标 |
| 生成超时 > 10 min | 按 gyid 拆批(docs/平台端/08 §4) |
不放宽"单活"约束、不引入消息中间件 |
| 修订版本冲突 | PF-7005,返回当前 revisionNo |
不原地改 FINAL 行、不删历史版本 |
| 导出失败 / 签名过期 | PF-7002,重新导出复用原 Idempotency-Key |
不返回内网绝对路径、不放长签名 |
| 公寓端断网 / 上行积压 | 按 serverReceivedAt 归日、水位收敛;缺日报则该期 NO_DATA |
不回调公寓、不反向补数、不改 PL_REPORT_DAILY 冻结行 |
PL_RECEIVE_LOG 幂等重放 |
PL-IDEMPOTENT-REPLAY 视为成功 |
不与 PF-5002 业务重复混用 |
| 公寓端业务表直连请求 | 拒绝(PR-10:旧 xxtj / excel 直连公寓库阶段五下线) |
不重算公寓明细、不跨库 JOIN |
6. 三端一致性与数据同步
权威映射表见
CR-02 §15表 3-65(公寓端 → 上行 / 下行编号 → 平台端 → 应用端全量对照)。本节只给统计链路的本端落点。
表 10-19 统计数据源与跨端编号映射
| 统计分类 | 公寓端业务事实 | 上行编号 + bizType |
平台端归集落表 | 应用端可见性 |
|---|---|---|---|---|
| 入住人数 | gygl_ly_event(CHECKIN)、#9 CHECKIN 提报 |
#9 / CHECKIN |
PL_RECEIVE_LOG → PL_REPORT_DAILY.stay_count |
值班台只读入住台账,不产出统计 |
| 叫乘人数 | 平板 N-04 TABLET_RESULT / SIP AMI 结论 |
#9 TABLET_RESULT、#8 TASK_ACK、#24 VOICE_SUMMARY(仅 SIP) |
PL_TASK_ACK → PL_REPORT_DAILY.call_count |
/ws/duty tablet.result / state.changed 只读 |
| 评价情况 | 公寓端评价分组计数(#13 摘要扩展) | #13 ARCHIVE payload satisfaction{} |
PL_REPORT_DAILY.satisfaction_*(补列) |
只读报表,不采集、不写回 |
| 报警情况 | apt_device_alarm、gy_bjxx |
#12 DEVICE_ALARM(按 alarmSource 分组)、#11 摘要 |
PL_REPORT_DAILY.alarm_* |
值班台处置入口(只提交命令) |
| 补贴发放 / 补贴消费 / 现金充值 | apt_ledger_offline 一条流水 + 拆分字段 |
#10 LEDGER_OFFLINE |
PL_LEDGER_FLOW(reconcile_state) |
值班台只读额度 / 流水,充值核对只提交命令 |
| 房间利用周转 | 房态与入住夜数(#13 摘要扩展) | #13 ARCHIVE payload roomOccupancy{} |
PL_REPORT_DAILY.room_available / room_nights(补列) |
值班台只读房态,不产出统计 |
表 10-20 同步机制与状态映射(统计侧)
| 环节 | 公寓端状态 | 同步载体 | 平台端状态 | 应用端状态 | 回退 |
|---|---|---|---|---|---|
| 上行受理 | outbox PENDING → SENT |
#9 / #10 / #12 / #13,idempotencyKey |
PL_RECEIVE_LOG RECEIVED |
待办 / 只读视图 | 断网续报复用原幂等键,不产生新业务事实 |
| 归日 | occurredAt / syncedAt |
以 serverReceivedAt 归日 |
日报 stat_date |
— | 跨日迟到不回改已冻结日报 |
| 对账 | offline_scope=LOCAL_ONLY → SYNCED → RECONCILED |
#16 日对账(公寓主动调用,P-02) | PL_LEDGER_FLOW.reconcile_state RECEIVED → RECONCILED / DIFF;PL_RECONCILE_BATCH.state |
只读对账状态 | DIFF + PF-5003 阻断,账务类指标 BLOCKED |
| 周期汇总 | 无(不感知统计) | 无跨端交互 | pl_apt_stat_period.state DRAFT → FINAL → REVISED |
只读 FINAL / REVISED 快照 |
次日重算 + revision_no+1 |
| 排名 | 无(不感知排名) | 无跨端交互 | pl_apt_stat_rank 快照 |
只读榜单 | 修正后新版本快照,旧版可追溯 |
关键一致性约束:统计结果的任何变化都不反向改变公寓端业务状态(
ledger_state/reg_state/match_state/ryzt等一律不变);三端状态映射的完整枚举与终态规则以CR-02 §15表 3-65 为准。
7. 决策点与验收
表 10-21 待决口径(Q-46~Q-50,承接 docs/公寓端/12 Q-45)
| 编号 | 事项 | 默认口径(未决前执行) | 拍板时点 |
|---|---|---|---|
| Q-46 | 评价与房间周转的数据接入方式 | 公寓端在 #13 ARCHIVE 摘要按 payload 扩展分组计数;未上报则 NO_DATA,不推断不补零、不以 pl_staff_performance_daily 代填 |
阶段二契约冻结前 |
| Q-47 | 报表周期时区与季度划分 | 平台统一时区;季按自然季度 YYYY-Qn;跨时区公寓按 gyid 配置,未决前统一平台时区 |
阶段二契约冻结前 |
| Q-48 | pl_apt_stat_* 两张新表与 PL_REPORT_DAILY / PL_LEDGER_FLOW 补列 DDL 冻结时点 |
设计定义,DDL 待阶段二契约冻结评审通过后执行;冻结前可用 PL_JOB_* JSON 兜底留痕 |
阶段二契约冻结前 |
| Q-49 | 综合排名权重与逆向指标处理 | 五类等权、缺类归一化;报警 / 投诉类为逆向指标(越小越优);RANK() 跳号 |
阶段三试点前 |
| Q-50 | 统计报表是否向应用端值班台开放、开放到什么粒度 | 默认只读开放到公寓级分类统计与排名,不开放跨公寓明细下钻、不开放人员级数据 | 阶段三试点前 |
表 10-22 验收要点
| # | 验收项 | 判据 |
|---|---|---|
| 1 | 五类指标齐备 | 入住 / 叫乘 / 评价 / 报警、补贴发放、补贴消费、现金充值(计收入)、房间周转五类均有明确公式、数据源、单位与缺报处理;CASH_RECHARGE_INCOME 不与消费抵销 |
| 2 | 周期报表 | 月 / 季 / 年三种 periodType 均可生成,日切以 serverReceivedAt,周期一律由日报 rollup,不重算公寓明细 |
| 3 | 公寓排名 | 按 gyid 对五类 + 综合分别排名,RANK() 跳号、并列同名次、NO_DATA 不参与;gyIds[] 在 SQL 层生效 |
| 4 | 封账与修订 | 未封账 PF-7003、DIFF 阻断排名;PL_REPORT_DAILY 冻结不可改,修正走次日重算 + revision_no+1,历史版本可追溯 |
| 5 | 权限与审计 | 四类权限点前后端同码;gyIds[] 越权 PF-7004;生成 / 修订 / 导出 / 排名查询全部留痕;统计模块对账务表只读 |
| 6 | 异常完整性 | 缺报 NO_DATA 不补零、双跑幂等、超时拆批、版本冲突 PF-7005、导出失败 PF-7002、断网按水位收敛均有明确处理与"不做什么" |
| 7 | 边界不破 | 跨端 20 编号、v2-draft、平台零回调、公寓 59 张表、不新增 bizType、平台库新增 2 张另计;管理接口不产生跨端副作用 |
| 8 | 三端一致性 | 表 10-19 / 10-20 与 CR-02 §15 表 3-65 逐项对应;统计结果不回写公寓端 / 应用端任何业务状态;金额 decimal(12,2)、比率 decimal(6,4)、禁止浮点 |