Skip to content

集合:用户(users)

字数
1790 字
阅读时间
8 分钟

1. 目的与使用场景

  • 存储微信登录用户的基础资料、账号状态与守护配置。主要由“我的”页、账号与资料管理、隐私授权中心等模块读取;由登录云函数、资料编辑接口写入。

2. Schema 定义

字段类型必填默认值约束/校验说明索引权限
_idstring-TCB 自动生成主键PKP1
_openidstring-TCB 自动生成微信 OpenIDUKP2
nicknamestring-长度 1-32昵称IDXP1
avatar_urlstring-URL 校验头像-P1
genderstringsecret枚举值性别-P2
birthdaydate-ISO 字符串生日-P2
campus_affiliationstring-长度 ≤ 64校区/院系标签IDXP1
phone_maskedstring-^\+?\d{3,} 脱敏存储紧急联系掩码-P2
emailstring-Email 格式校验邮箱地址-P2
statusstringactive枚举账号状态IDXP1
rolestringuser枚举用户角色IDXP1
onboarding_stagestringintro_completed枚举引导阶段IDXP1
guardian_idsarray[]元素为指针id绑定守护者-P2
counselor_idstring-指向 users._id绑定辅导员FKP2
emergency_contactsarray[]对象数组紧急联系人-P3
last_login_atdate-ISO 字符串最近登录时间IDXP1
risk_tierstringlow枚举风险画像等级IDXP3
risk_factorsarray[]字符串数组风险因素-P3
preference_profileobject-偏好设置对象-P1
consent_versionstring-semver隐私协议版本IDXP1
is_deletedbooleanfalse-软删标记IDXP1
deleted_atdate--删除时间-P2
last_activity_atdate--最后活动时间IDXP1
badge_idsarray[]徽章ID数组-P1
statisticsobject-统计对象-P2
createdAtdate-服务端时间创建时间IDXP1
updatedAtdate-服务端时间更新时间IDXP1
createdBystringsystem-创建来源-P1
updatedBystringsystem-更新来源-P1

枚举值

  • status: active(活跃), inactive(未激活), restricted(受限), suspended(暂停)
  • role: user(用户), counselor(辅导员), guardian(守护者), ops(运营)
  • onboarding_stage: intro_pending(介绍待完成), intro_completed(介绍已完成), feature_unlocked(功能已解锁)
  • risk_tier: low(低), mid(中), high(高), critical(紧急)
  • gender: male(男), female(女), secret(隐藏)

3. 索引设计

索引策略

  • _openid_1: 唯一索引,支持微信登录和用户识别
  • status_1: 状态索引,支持用户状态筛选
  • role_1_status_1: 复合索引,支持角色权限管理
  • campus_affiliation_1_status_1: 复合索引,支持校区用户管理
  • risk_tier_1_last_activity_at_-1: 复合索引,支持风险用户监控
  • counselor_id_1_status_1: 复合索引,支持辅导员学生管理
  • nickname: 全文索引,支持用户搜索

设计理由

  • 登录鉴权依赖 _openid 精准匹配
  • 运营筛选校区活跃用户需要校区+状态组合
  • 风险画像用于预警看板和及时干预
  • 辅导员需要快速查找所负责学生状态

4. 访问控制(TCB 权限)

json
{
  "read": "_openid == auth.openid || auth.role in ['ops','counselor','guardian'] || (auth.role == 'counselor' && counselor_id == auth.uid)",
  "write": "_openid == auth.openid || auth.role in ['ops']"
}

角色与场景说明:普通用户可访问自身记录;运营(ops)可协助修改资料;心理辅导员(counselor)可查看所负责学生;守护者(guardian)有授权查看权限。

  1. 关系与级联

引用到的集合与外键字段:

  • guardian_ids 指向同集合 _id(守护者)。
  • 多数集合通过 user_id 指针引用用户。

删除策略:

  • 用户注销时将 is_deleted=true,保留审计字段;相关集合遵循软删与匿名化策略。

反范式字段:

  • risk_tier 与画像服务同步,变更时需触发任务推荐回调。
  1. 数据生命周期与合规
  • 留存时长:账号注销后 30 天保留备份,其后硬删或脱敏。
  • 匿名化策略:清除昵称、头像,保留统计字段。
  • 导出/删除流程:用户发起注销 → 工单审核 → 云函数 userCleanup 执行软删及相关集合脱敏。
  • 审计字段:createdAtupdatedAtcreatedByupdatedBylast_login_at
  1. API/云函数契约映射 | 接口/函数 | 读/写 | 使用字段 | 过滤条件 | 排序/分页 | 备注 | | /api/user/profile | 读 | nickname, avatar_url, gender, birthday, campus_affiliation, onboarding_stage, risk_tier, role, statistics | _openid = auth.openid | - | 我的页展示 | | /api/user/profile | 写 | nickname, avatar_url, gender, birthday, campus_affiliation, emergency_contacts | _openid = auth.openid | - | 资料编辑 | | /api/privacy/consents | 读/写 | consent_version, guardian_ids, counselor_id | _openid = auth.openid | - | 授权中心 | | 登录云函数 authLogin | 读/写 | _openid, status, last_login_at, role | _openid = auth.openid | - | 登录态同步 | | 风险监测服务 riskMonitor | 读 | risk_tier, risk_factors, last_activity_at | risk_tier in ['high','critical'] | - | 风险预警 | | 徽章服务 badgeService | 写 | badge_ids, statistics | user_id 匹配 | - | 徽章解锁 |

  2. 示例文档(≥3条)

json
{
  "_id": "usr_001",
  "_openid": "oAbcd123",
  "nickname": "星河",
  "avatar_url": "https://cdn.example.com/avatar/u1.png",
  "gender": "secret",
  "birthday": "2000-05-15",
  "campus_affiliation": "北苑-心理学",
  "email": "student@example.com",
  "status": "active",
  "role": "user",
  "onboarding_stage": "feature_unlocked",
  "risk_tier": "low",
  "risk_factors": [],
  "preference_profile": {"theme": "light", "language": "zh-CN", "notification_settings": {"enabled": true, "quiet_hours": ["22:00", "07:00"]}},
  "statistics": {"total_checkins": 15, "completed_tasks": 8, "journal_count": 12, "community_helps": 3},
  "badge_ids": ["badge_001", "badge_003"],
  "consent_version": "1.2.0",
  "last_activity_at": "2024-04-06T09:30:00Z",
  "createdAt": "2024-03-01T08:00:00Z",
  "updatedAt": "2024-04-06T09:30:00Z"
}
{
  "_id": "usr_002",
  "_openid": "oAbcd456",
  "nickname": "Aria",
  "gender": "female",
  "birthday": "1999-12-03",
  "phone_masked": "+86-138****2233",
  "email": "aria@example.com",
  "status": "restricted",
  "role": "user",
  "risk_tier": "mid",
  "risk_factors": ["学业压力", "社交焦虑"],
  "campus_affiliation": "南苑-计算机",
  "counselor_id": "counselor_001",
  "guardian_ids": ["usr_guard_01"],
  "emergency_contacts": [{"name": "母亲", "relationship": "家人", "masked_phone": "+86-139****8888"}],
  "consent_version": "1.2.0",
  "last_activity_at": "2024-04-05T07:20:00Z",
  "createdAt": "2024-03-05T12:10:00Z",
  "updatedAt": "2024-04-05T07:20:00Z"
}
{
  "_id": "counselor_001",
  "_openid": "oAbcd789",
  "nickname": "辅导员赵老师",
  "email": "counselor@university.edu.cn",
  "status": "active",
  "role": "counselor",
  "risk_tier": "low",
  "campus_affiliation": "南苑-计算机",
  "createdBy": "ops",
  "last_activity_at": "2024-04-06T10:45:00Z",
  "createdAt": "2024-02-20T03:20:00Z",
  "updatedAt": "2024-03-18T10:45:00Z"
}
  1. 常用查询样例(≥3条)
javascript
// 获取当前用户资料
const me = await db.collection('users').where({ _openid: wxContext.OPENID }).get();

// 查询需要辅导员关注的高风险用户
const highRisk = await db.collection('users').where({ risk_tier: 'high', status: 'active' }).orderBy('updatedAt', 'desc').limit(50).get();

// 运营筛选北苑校区受限账号
const restricted = await db.collection('users').where({ campus_affiliation: '北苑-心理学', status: 'restricted' }).get();
  1. 边界与错误码
  • 重复提交:authLogin 若检测 _openid 已存在则返回 E_USER_EXISTS,前端刷新 token。
  • 角色权限不足:尝试访问超出角色权限的功能返回 E_ROLE_PERMISSION_DENIED
  • 风险用户限制:restricted 状态用户尝试发帖等受限操作返回 E_USER_RESTRICTED
  • 并发冲突:资料编辑采用 updatedAt 乐观锁,不一致时返回 E_VERSION_MISMATCH
  • 越权访问:非本人读取被拒绝,返回 E_FORBIDDEN,记录审计日志。
  1. 变更影响评估
  • 新增字段需更新 /api/user/profile DTO 与“我的”页渲染。
  • 索引调整影响用户画像批处理与埋点 risk_signal_escalate 的用户关联。
  1. 假设与待确认
  • 假设守护者也是用户集合中的账号,通过 guardian_ids 互联;待确认是否需要独立集合存储外部联系人。
  • 待确认 risk_tier 更新由谁负责(AI 服务或人工审核)。

贡献者

The avatar of contributor named as Cai Hongyu Cai Hongyu

文件历史

撰写