# P3:用户认证层 — miniapp-auth-system > 优先级:P3(依赖 P1,可与 P2 并行) > 预估工作量:中等 --- ## 需求(Requirements) ### 用户故事 1. 作为球房工作人员,我需要通过微信登录小程序,首次登录时填写申请表单(球房ID、申请身份、手机号、编号、昵称)。 2. 作为租户管理员,我需要审核用户申请,将用户关联到对应的助教/员工,并分配身份权限。 3. 作为系统,我需要通过球房ID+手机号自动建议用户与助教/员工的对应关系(同时匹配 `dwd.dim_assistant` 助教表和 `dwd.dim_staff` + `dwd.dim_staff_ex` 员工信息表)。 4. 作为用户,我需要看到自己的申请状态(审核中/通过/拒绝)。 5. 作为用户,我可以同时属于多个店铺(连锁场景),权限按店铺独立。 ### 验收标准 - AC1:微信 code2Session 登录正常,返回 JWT - AC2:新用户首次登录后进入申请页面,提交后状态为 pending - AC3:管理员审核通过后,用户状态变为 approved,可正常访问小程序 - AC4:球房ID 不存在时,申请仍可提交,管理端显示"未找到关联信息" - AC7:用户申请信息比对时,系统同时在助教表(`dwd.dim_assistant`)和员工信息表(`dwd.dim_staff` / `dwd.dim_staff_ex`)中匹配,返回所有匹配结果供管理员选择 - AC5:权限中间件正确拦截无权请求(如助教不能看财务看板) - AC6:一个用户可关联多个店铺,切换店铺后数据正确隔离 --- ## 设计要点 ### 表结构 ``` auth.users - id, wx_openid, wx_union_id, wx_avatar_url, nickname, phone - status (pending/approved/rejected/disabled) - created_at, updated_at auth.user_applications - id, user_id, site_code (球房ID文本), applied_role_text (自由文本) - employee_number (选填), status, reviewer_id, review_note - created_at, reviewed_at auth.site_code_mapping - id, site_code (2字母+3数字), site_id (ETL bigint), site_name - tenant_id, created_at auth.user_site_roles - id, user_id, site_id, role_id - created_at auth.user_assistant_binding - id, user_id, site_id, assistant_id (ETL dim_assistant) - staff_id (ETL dim_staff,可选,员工绑定时填写) - binding_type (assistant/staff/manager) - created_at ``` ### 人员匹配逻辑(用户申请 → 信息比对) 用户提交申请时填写球房ID + 手机号(或编号),系统自动在以下两张表中匹配: 1. 助教表 `dwd.dim_assistant`(通过 FDW `fdw_etl.v_assistant`):按 `site_id` + `mobile` 或 `alias_name` 匹配 2. 员工信息表 `dwd.dim_staff` + `dwd.dim_staff_ex`(通过 FDW):按 `site_id` + `mobile` 或 `staff_name` / `alias_name` / `job_num` 匹配 匹配结果合并后返回给管理端,管理员从候选列表中选择正确的关联对象。若两张表均无匹配,显示"未找到关联信息",管理员可手动填写。 > 员工信息表数据链路:上游 API → `ods.staff_info_master` → `dwd.dim_staff`(基础维度,SCD2)+ `dwd.dim_staff_ex`(扩展维度,SCD2) ### 权限列表(固定) | 权限 code | 说明 | |-----------|------| | `view_tasks` | 任务板块可见 | | `view_board` | 看板板块可见 | | `view_board_finance` | 财务板块可见 | | `view_board_customer` | 客户板块可见 | | `view_board_coach` | 助教板块可见 | ### 租户层级 ``` 租户 (tenant) └── 店铺 (site) ← site_code 映射 └── 用户 (user) ← 可属于多个 site └── 角色 (role) ← 按 site 独立分配 ``` --- ## 小程序前端开发强制规范 > 以下规范适用于本 SPEC 中所有小程序页面实现,具有强制约束力。 1. **原型图是唯一视觉真相**:`docs/h5_ui/pages/*.html` 中的结构、层次、元素、配色、间距、交互行为是小程序页面实现的唯一参考标准。任何偏离原型图的实现都需要明确的产品确认。 2. **WXML ≠ HTML**:严禁在小程序中使用 HTML 标签(div/span/p/a/img 等),必须使用小程序原生标签(view/text/image/navigator 等)。 3. **WXSS ≠ CSS**:使用 rpx 单位、仅支持有限选择器、无 DOM/BOM API、样式隔离机制不同。Tailwind CSS 类名必须手动转换为 WXSS。 4. **TDesign 优先**:凡 TDesign 组件库能覆盖的 UI 元素,必须使用 TDesign 组件;自定义实现仅限 TDesign 无法覆盖的场景。 5. **Power 文档优先**:实现前必须加载 `wechat-miniprogram` Power 的相关 steering 文件(`view-layer.md`、`tdesign.md`、`builtin-components.md`),确保语法和组件用法正确。 6. **项目踩坑指南必读**:实现前必须阅读 `docs/prd/MIGRATION-PLAYBOOK.md` 第六章,该文档是基于本项目实际转换经验的避坑手册,涵盖 WXML/WXSS 差异、事件系统、TDesign 用法、rpx 换算规则及新页面开发 Checklist。 --- ## 任务清单 - [ ] T1:创建 `auth` Schema 下全部表(users, user_applications, site_code_mapping, user_site_roles, user_assistant_binding) - [ ] T2:迁移现有 RBAC 表到 `auth` Schema(或保留 public 但建立关联) - [ ] T3:实现微信 code2Session 登录 API - [ ] T4:实现用户申请提交 API - [ ] T5:实现 JWT 签发与刷新 - [ ] T6:实现权限中间件(基于 user_site_roles) - [ ] T7:实现用户状态查询 API - [ ] T8:种子数据:预置权限列表和默认角色