# 月度教学统计 入口:管理中心 → 统计分析。页面为 `packages/app/src/pages/admin/analytics.vue`,接口为 `GET /api/admin/teaching-analytics?month=YYYY-MM`。 ## 统计口径 | 指标 | 定义 | | --- | --- | | 已上课程 | COMPLETED 预约关联的时段数,同一时段只计一次 | | 已完成上课人次 | COMPLETED 预约数 | | 本月上课学员 | 已完成预约的 userId 去重,不按姓名合并 | | 授课小时 | 已完成时段的排课分钟数之和除以 60,同一时段不重复累计 | | 上课天数 | 已完成课程日期去重 | | 人均上课次数 | 上课人次除以上课学员数,无学员时显示横线 | | 上月参考 | 上一个完整自然月的已上课程节数;当月未结束时明确提示,不给误导性环比 | | 待核对 | 已过中国时间课程结束时刻、仍待确认或已确认的预约 | 月份以 TimeSlot.date 的日历日期为准,查询使用月初包含、下月初不包含的区间。预约创建时间、完成时间和取消时间不影响月份归属。取消、未出席、待确认和已确认不计入已上课程。 当前模型没有老师归属、课程名称或课程类别,因此统计范围明确为工作室;不能把 operatorId 当作授课老师。用卡分布代表预约所用会员卡的当前卡种名称,不代表课程类别、实际消课收入或老师课酬。同名卡种合并显示。 系统存在自动完成预约任务,COMPLETED 不等于现场签到,不提供签到率。没有课程日期的历史累计补录不计入本报告。 ## 页面与交互 - 米白底、松绿色总览、宋体标题与衬线数字,延续原有课表风格。 - 月份选择器、前后月切换、回到本月、手动刷新与下拉刷新;支持 2000—2099 年。 - 月历显示每天已完成课程节数,点击日期定位明细,再次点击解除日期条件。 - 学员排行支持姓名搜索,显示上课次数、天数与最近上课日期;点击查看该学员全月已完成明细。 - 明细支持日期、学员、预约状态组合筛选;每个状态显示当前日期/学员条件内的记录数。清除筛选恢复全月全部记录。 - 明细显示课程日期、起止时间、学员、用卡与状态,点击姓名进入会员详情。 - 排行每次增加 10 人、明细每次增加 20 条,避免一次渲染过多节点。接口返回当月完整记录,不以列表显示上限截断统计。 - 切月清空旧数据和筛选,请求序号防止慢响应覆盖新月份。错误提示与空月独立显示,失败不伪装成零数据。 ## 实现边界与验证 接口继承管理中心的 JWT 和 ADMIN 权限保护。一次查询读取当月及上月必要关联字段,无逐学员查询;只向前端返回当月明细与两个月的汇总。未新增数据库表或迁移。 服务测试覆盖课程去重、同名不同学员、状态排除、空月、跨年、闰年、月会员管理 页面中,默认是查看全部用户,这个查看效率太低了,我希望默认看到的是会员用户增加这么一个筛选, 至于新用户,我可以选择筛选无卡用户就行了,这样的体验会更加好一些参数验证、中国时间结束判断以及接口权限元数据。 验证通过:共享包构建、后端构建、前端类型检查、微信小程序构建;新增统计测试 12 项通过。全量测试 231 项通过,原有 scheduler 测试 8 项因缺少 FlashSaleService mock 失败。 使用真实 Vue 页面与 SCSS、模拟数据进行了 390px 手机宽度预览,验证学员钻取、日期筛选、快速切月、空月和错误状态。浏览器预览仅模拟小程序容器;微信真机、原生月份选择器以及线上数据联调仍需发布前验收。 设计参考:[TeamUp 出勤报表](https://support.goteamup.com/en/articles/9327465-reports-class-attendances-all-attendances),借鉴按学员、日期和状态追溯出勤记录的交互,不复制其产品界面。 上线需要部署后端并发布小程序,本次仅实现与本地验证,未执行生产部署。