健身房私教管理系统 (二):多角色路由分发与实体扩展表设计
目录
- 前言
- 一、 数据库设计:统一主表 + 动态角色扩展表(1 + N 模式)
- 1. 统一用户主表 (`fit_users`)
- 2. 角色扩展表 (N)
- 2.1 教练扩展表 (`fit_trainer_profiles`)
- 2.2 学员扩展表 (`fit_member_profiles`)
- 2.3 员工扩展表 (`fit_staff_profiles`)
- 二、 前端交互:角色选择页与动态路由分发
- 1. 视图层设计
- 2. 控制层逻辑
- 本篇小结
前言
在上一篇中,我们理清了微搭外部用户的底层动态核验流程。当新用户首次进入系统时,我们的欢迎页会精准拦截并引导其点击“用户注册”。
今天这篇,我们聚焦于点击注册后的核心环节:如何设计一个支持“学员、教练、管理员、员工”多角色的动态注册流,以及如何在低代码平台中优雅地解耦底层数据表与全局状态对象。
一、 数据库设计:统一主表 + 动态角色扩展表(1 + N 模式)
在进入前端页面开发前,必须先定下底层的“数据底座”。对于多角色系统,最忌讳的是将所有角色的特有字段(如教练的“特长标签”、学员的“身体数据”、员工的“入职时间”)全部堆在一张表里,这会导致数据表极其臃肿且充满空值。
我们采用经典的“统一主表 + 角色扩展表(1 + N)”架构:
1. 统一用户主表 (fit_users)
所有角色必须在这张表里有一条记录,用来承载通用的、全系统唯一的账户信息。
| 字段名称 | 字段标识 | 数据类型 | 描述 |
|---|---|---|---|
| 用户ID | id | 文本 | 主键,UUID |
| 手机号 | phone | 电话号码 | 唯一索引,与微搭 Auth 绑定 |
| 昵称 | nickname | 文本 | 用户昵称/真实姓名 |
| 头像 | avatar | 图片 | 头像 URL |
| 当前角色 | current_role | 枚举 | 学员 / 教练 / 管理员 / 员工 |
| 状态 | status | 枚举 | 待激活 / 启用 / 冻结 |
| 创建时间 | created_at | 日期时间 | - |
| 更新时间 | updated_at | 日期时间 | - |
2. 角色扩展表 (N)
根据用户在主表中的current_role,动态关联到对应的扩展表。
2.1 教练扩展表 (fit_trainer_profiles)
| 字段名称 | 字段标识 | 数据类型 | 描述 |
|---|---|---|---|
| 记录ID | id | 文本 | 主键,UUID |
| 用户ID | user_id | 关联关系 | 外键 →fit_users.id |
| 教练简介 | bio | 文本 | - |
| 擅长标签 | tags | 数组 | 如["减脂", "增肌", "普拉提"] |
| 资质证书 | certificates | 数组 | 图片列表[{"url": "...", "name": "..."}] |
| 基础提成比例 | base_commission_rate | 数字 | 如 0.30 表示 30% |
| 入职日期 | work_start_date | 日期 | - |
| 创建时间 | created_at | 日期时间 | - |
| 更新时间 | updated_at | 日期时间 | - |
2.2 学员扩展表 (fit_member_profiles)
| 字段名称 | 字段标识 | 数据类型 | 描述 |
|---|---|---|---|
| 记录ID | id | 文本 | 主键,UUID |
| 用户ID | user_id | 关联关系 | 外键 →fit_users.id |
| 健身目标 | fitness_goal | 文本 | 减脂 / 增肌 / 塑形 |
| 初始体重 | initial_weight | 数字 | 单位:kg |
| 当前体重 | current_weight | 数字 | 单位:kg |
| 身高 | height | 数字 | 单位:cm |
| 出生日期 | birth_date | 日期 | - |
| 紧急联系人 | emergency_contact | 电话号码 | - |
| 剩余课时 | remaining_lessons | 数字 | - |
| 会员卡类型 | membership_type | 枚举 | 无 / 月卡 / 季卡 / 年卡 |
| 会员到期时间 | membership_expire_at | 日期时间 | - |
| 创建时间 | created_at | 日期时间 | - |
| 更新时间 | updated_at | 日期时间 | - |
2.3 员工扩展表 (fit_staff_profiles)
| 字段名称 | 字段标识 | 数据类型 | 描述 |
|---|---|---|---|
| 记录ID | id | 文本 | 主键,UUID |
| 用户ID | user_id | 关联关系 | 外键 →fit_users.id |
| 员工工号 | employee_no | 文本 | 唯一索引 |
| 入职日期 | hire_date | 日期 | - |
| 所属门店 | store_id | 关联关系 | 外键 →fit_stores.id |
| 员工状态 | employee_status | 枚举 | 在职 / 离职 / 休假 |
| 创建时间 | created_at | 日期时间 | - |
| 更新时间 | updated_at | 日期时间 | - |
二、 前端交互:角色选择页与动态路由分发
当未注册用户点击“立即注册”后,系统不应该直接展示一个冗长的表单,而是将其引导至一个极简的“角色选择页”。
1. 视图层设计
页面提供四个精美的卡片式按钮:
- 【我是学员】—— 适合消费者,表单侧重于个人健身偏好。
- 【我是教练】—— 适合健身房教练,表单侧重于专业资质、履历。
- 【我是员工 / 我是管理员】—— 适合店内运营人员,可能需要输入特定的“门店邀请码”或提交后由后台管理员审核。
点击创建页面的图标,创建角色选择页面
在页面组件下添加普通容器,设置样式,宽为100%,高为100vh
里边添加四个按钮,修改按钮的内容分别为我是学员、我是教练、我是员工、我是管理员
设置普通容器的布局样式为纵向排列,水平垂直居中
打开按钮的是否通栏配置
给按钮设置圆角
给普通容器设置内边距
给按钮设置外边距
给按钮配置背景色形成一个对比
设置了背景色之后要将边框设置为无边框
2. 控制层逻辑
点击不同角色按钮时,触发同一个页面事件,传入角色参数。我们需要在跳转前做两件事:
- 将用户选择的临时角色写入页面变量。
- 执行页面跳转,并将角色信息传递到下一个页面。
创建一个文本变量用来保存用户的选择
创建一个自定义方法用来执行页面的跳转
// 通用角色选择处理函数:onRoleSelectexportdefaultasyncfunctiononRoleSelect({event,data}){// 从按钮绑定的 data 中获取角色信息constselectedRole=data.target;// 'STUDENT' | 'TRAINER' | 'STAFF' | 'ADMIN'// 1. 在全局应用数据中记录用户当前意向角色$w.page.dataset.state.tempRegisterRole=selectedRole;// 2. 根据角色跳转到对应的注册表单页,并传递角色参数constregisterPages={'STUDENT':'page_register_student','TRAINER':'page_register_trainer','STAFF':'page_register_staff','ADMIN':'page_register_admin'};$w.utils.navigateTo({pageId:registerPages[selectedRole],params:{role:selectedRole// 将角色信息传递到下一个页面}});}按钮配置示例:
在角色选择页中,四个角色按钮分别绑定同一个事件,传入不同的角色值:
| 按钮 | 事件绑定 | 入参 |
|---|---|---|
| 我是学员 | onRoleSelect | STUDENT |
| 我是教练 | onRoleSelect | TRAINER |
| 我是员工 | onRoleSelect | STAFF |
| 我是管理员 | onRoleSelect | ADMIN |
本篇小结
通过本章的学习,我们完成了从“欢迎页拦截”到“多角色选择与底层扩展表设计”的过渡。这种“主表+扩展表”的 1+N 模式,既顺应了微搭低代码平台的数据模型构建规范,又具备极高的商业扩展性(支持未来门店多角色裂变)。
下篇专栏,我们将切入实战代码,带大家手把手用微搭的表单组件,完成【教练注册页】的资质上传、表单校验,以及如何原子化地向fit_users和fit_trainer_profiles两张表同时写入数据。欢迎持续关注!
