From 57600598ac83f43fce1c596d9bfda4b55ba41e9a Mon Sep 17 00:00:00 2001 From: Shen Wei Date: Thu, 30 Apr 2026 18:40:55 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=A8=A1=E5=9D=97=E5=AE=A1?= =?UTF-8?q?=E6=A0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md | 102 +-- .../DATA_MODEL/DATA_MODEL_PERMISSION.md | 154 ++--- .../fonrey/DATA_MODEL/DATA_MODEL_PUBLIC.md | 11 +- .../fonrey/DATA_MODEL/DATA_MODEL_SETTING.md | 32 +- Project/fonrey/DATA_MODEL/SCHEMA_CHANGES.md | 111 ++++ Project/fonrey/PRD/PERSONA_定义.md | 177 +++++ Project/fonrey/PRD/PRD_MVP.md | 8 +- Project/fonrey/PRD/TASK.md | 16 +- Project/fonrey/PRD/TASK_AGENT_READY.md | 16 +- .../PRD/发布管理/客户端发布管理模块PRD.md | 18 +- .../fonrey/PRD/客源管理/客源管理模块PRD.md | 52 +- .../fonrey/PRD/房源管理/房源管理模块PRD.md | 24 +- .../fonrey/PRD/房源管理/楼盘管理模块PRD.md | 8 +- Project/fonrey/PRD/权限管理/小区.md | 2 +- .../fonrey/PRD/权限管理/权限管理模块PRD.md | 26 +- Project/fonrey/PRD/登录管理/找回密码流程.png | Bin 290601 -> 0 bytes .../fonrey/PRD/登录管理/找回用户名流程.png | Bin 184135 -> 0 bytes .../PRD/登录管理/用户登录管理模块PRD.md | 464 ++++++------- .../fonrey/PRD/系统管理/系统管理模块PRD.md | 22 +- .../fonrey/PRD/系统配置/系统配置参数数据.md | 2 +- .../fonrey/PRD/系统配置/系统配置模块PRD.md | 12 +- .../PRD/组织人事管理/组织人事管理模块PRD.md | 28 +- Project/fonrey/TECH_STACK/测试规范.md | 72 ++- Project/fonrey/TECH_STACK/登录管理技术方案.md | 342 +++++----- .../TEST_CASES/TEST_CASES_LOGIN_MODULE.md | 390 +++++++++++ .../fonrey/TEST_CASES/TEST_CASE_ID_SPEC.md | 56 ++ .../fonrey/TEST_CASES/TEST_CASE_REGISTRY.md | 77 +++ Project/fonrey/UI_DESIGN/登录_UI.html | 437 +++---------- .../fonrey/UI_DESIGN/登录_账号密码_UI.html | 612 ++++++++++++++---- .../fonrey/UI_DESIGN/登录_重置密码_UI.html | 247 +++++++ Project/fonrey/UI_DESIGN/登录管理/登录_UI.md | 374 +++++------ .../项目进度交接报告_Phase4.0_收尾.md | 250 ------- .../实施报告/项目骨架搭建实施报告_v1.md | 435 ------------- .../实施报告/项目骨架搭建实施报告_v2.md | 398 ------------ 34 files changed, 2544 insertions(+), 2431 deletions(-) create mode 100644 Project/fonrey/DATA_MODEL/SCHEMA_CHANGES.md create mode 100644 Project/fonrey/PRD/PERSONA_定义.md delete mode 100644 Project/fonrey/PRD/登录管理/找回密码流程.png delete mode 100644 Project/fonrey/PRD/登录管理/找回用户名流程.png create mode 100644 Project/fonrey/TEST_CASES/TEST_CASES_LOGIN_MODULE.md create mode 100644 Project/fonrey/TEST_CASES/TEST_CASE_ID_SPEC.md create mode 100644 Project/fonrey/TEST_CASES/TEST_CASE_REGISTRY.md create mode 100644 Project/fonrey/UI_DESIGN/登录_重置密码_UI.html delete mode 100644 Project/fonrey/实施报告/项目进度交接报告_Phase4.0_收尾.md delete mode 100644 Project/fonrey/实施报告/项目骨架搭建实施报告_v1.md delete mode 100644 Project/fonrey/实施报告/项目骨架搭建实施报告_v2.md diff --git a/Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md b/Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md index 4b63f700..9c70171d 100644 --- a/Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md +++ b/Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md @@ -4,7 +4,7 @@ > **版本**: v1.0 > **日期**: 2026-04-24 > **关联模块**: `apps/accounts/` — 账号认证、登录安全、密码管理 -> **关联 PRD**: `Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md` (v1.3) +> **关联 PRD**: `Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md` (v2.0) > **关联技术方案**: `Project/fonrey/TECH_STACK/登录管理技术方案.md` --- @@ -13,17 +13,18 @@ ### 核心概念 -- **UserAccount(用户账号)**:系统登录主体,必须与员工档案(`org.Staff`)1:1 绑定。分为 Tenant Admin(超级管理账号,每租户唯一)和普通员工账号(username 固定为手机号)。 +- **UserAccount(用户账号)**:系统登录主体,必须与员工档案(`org.Staff`)1:1 绑定。分为 Tenant Admin(超级管理账号,每租户唯一,username 固定为联系人手机号)和普通员工账号(username 固定为员工手机号)。 - **LoginAttempt(登录尝试记录)**:记录每次登录行为(成功/失败),用于安全审计和账号锁定判断,保留 ≥ 90 天。 -- **PasswordResetToken(密码重置令牌)**:通过邮件找回密码时生成的一次性令牌,有效期 30 分钟,使用后立即失效。 +- **PasswordResetToken(密码重置令牌)**:~~通过邮件找回密码时生成的一次性令牌~~ 已废弃,详见 `SmsOtpRecord`。 +- **SmsOtpRecord(短信验证码记录)**:找回密码和手机验证码登录时向用户手机号发送的 6 位一次性验证码。用 `scene` 字段区分场景(`password_reset` / `login`),有效期按场景不同(找回密码 10 分钟,验证码登录 5 分钟);找回密码验证通过后颁发 `sms_reset_token`(有效期 15 分钟),验证码登录验证通过后直接颁发 Session Token;使用后立即作废。 - **PasswordHistory(历史密码记录)**:保存最近 3 次密码哈希,用于防止重复使用历史密码。 ### 关键业务规则 1. **账号与员工强绑定**:每个登录账号 **必须** 与 `org.Staff` 中的员工档案 1:1 绑定(Tenant Admin 例外,可不绑定)。 -2. **用户名规则差异化**: - - Tenant Admin:由平台运营自定义(字母开头,6~30 位,含字母/数字/下划线) - - 普通员工:**固定为员工手机号**(11 位数字),创建后不可变更 +2. **用户名规则统一为手机号**: + - Tenant Admin:**固定为该租户联系人的手机号**(11 位数字),来源于 `public.tenants.contact_phone`,全局唯一,创建后不可更改 + - 普通员工:**固定为员工手机号**(11 位数字),同租户内唯一,创建后不可变更 3. **初始密码强制修改**:新账号及密码重置后,`is_initial_password = True`,首次登录必须修改密码,不可跳过。 4. **账号锁定机制**:同一账号连续密码错误 ≥ 5 次,状态置为 `locked`,30 分钟后自动恢复;Tenant Admin 可提前手动解锁。 5. **员工离职联动**:员工离职时,对应账号的 `status` 自动置为 `disabled`,不可登录,历史操作记录保留。 @@ -38,7 +39,7 @@ UserAccount │ ├── 1:1 ── org.Staff (实名绑定,普通员工必须) ├── 1:N ── LoginAttempt (登录审计记录) - ├── 1:N ── PasswordResetToken (密码重置令牌) + ├── 1:N ── SmsOtpRecord (短信验证码记录,找回密码用) ├── 1:N ── PasswordHistory (历史密码记录) └── M:1 ── UserAccount.created_by (创建人自引用) ``` @@ -49,10 +50,10 @@ UserAccount |----|------------|------| | `user_accounts` | 租户 Schema | 账号数据按租户隔离,username 唯一性在 Schema 维度生效 | | `login_attempts` | 租户 Schema | 审计记录属于租户,跨租户不可见 | -| `password_reset_tokens` | 租户 Schema | 令牌与租户账号绑定 | +| `sms_otp_records` | 租户 Schema | 短信验证码记录,找回密码用 | | `password_histories` | 租户 Schema | 历史密码与账号绑定 | -> **注意**:Tenant ID 验证相关逻辑在 **Public Schema**(`shared_apps`),使用 `django-tenants` 的 `TenantModel`,不在本文档范围内,详见 `DATA_MODEL.md` §四(公共 Schema)。 +> **注意**:Tenant Code 验证相关逻辑在 **Public Schema**(`shared_apps`),使用 `django-tenants` 的 `TenantModel`,不在本文档范围内,详见 `DATA_MODEL.md` §四(公共 Schema)。 --- @@ -69,7 +70,7 @@ UserAccount | `id` | `BIGSERIAL` | `PRIMARY KEY` | — | 自增主键(审计场景下 BigInt 更直观;跨环境引用使用 UUID 扩展字段见下) | | `username` | `VARCHAR(30)` | `NOT NULL` | — | 登录名;普通员工为手机号(11 位数字);Tenant Admin 为自定义字符串;创建后不可更改 | | `password` | `VARCHAR(128)` | `NOT NULL` | — | PBKDF2+SHA256 哈希存储,使用 Django `make_password` | -| `email` | `VARCHAR(254)` | `NULL` | `NULL` | 绑定邮箱;用于找回密码/用户名;为空则无法自助找回;同租户唯一 | +| `email` | `VARCHAR(254)` | `NULL` | `NULL` | 绑定邮箱;完全可选,在本系统无任何必须业务用途;若填写则在同租户内唯一 | | `phone_enc` | `TEXT` | `NULL` | `NULL` | 手机号 AES-256-GCM 加密密文(`core.encryption`);普通员工必填 | | `phone_hash` | `VARCHAR(64)` | `NULL` | `NULL` | 手机号 SHA-256 哈希;用于唯一性校验和查询;不可反推原文 | | `staff_id` | `BIGINT` | `FK → org_staff.id`, `NULL`, `UNIQUE` | `NULL` | 员工档案绑定(1:1);普通员工必须有值;Tenant Admin 可为空 | @@ -122,8 +123,8 @@ class UserAccountManager(BaseUserManager): class UserAccount(AbstractBaseUser): """ 租户级用户账号。 - - 普通员工:username 固定为手机号(11 位数字) - - Tenant Admin:username 由平台运营自定义(字母开头,6~30 位) + - 普通员工:username 固定为员工手机号(11 位数字) + - Tenant Admin:username 固定为该租户联系人手机号(来源于 public.tenants.contact_phone) 注意:此表位于租户 Schema,username 唯一性约束在 Schema 维度生效。 """ username = models.CharField(max_length=30) @@ -212,7 +213,8 @@ CREATE TABLE login_attempts ( failure_reason VARCHAR(30) CHECK (failure_reason IS NULL OR failure_reason IN ( 'wrong_password','wrong_captcha','account_locked', - 'account_disabled','tenant_not_found' + 'account_disabled','tenant_not_found', + 'wrong_otp','otp_expired' )), PRIMARY KEY (id, attempted_at) -- 分区表主键必须包含分区键 ) PARTITION BY RANGE (attempted_at); @@ -233,6 +235,8 @@ CREATE TABLE login_attempts_default PARTITION OF login_attempts DEFAULT; | `account_locked` | 账号已锁定 | | `account_disabled` | 账号已停用 | | `tenant_not_found` | 租户不存在(理论上不应出现,防御性记录) | +| `wrong_otp` | 短信验证码错误 | +| `otp_expired` | 短信验证码已过期 | #### 索引 @@ -259,6 +263,8 @@ class LoginAttempt(models.Model): ('account_locked', '账号已锁定'), ('account_disabled', '账号已停用'), ('tenant_not_found', '租户不存在'), + ('wrong_otp', '短信验证码错误'), + ('otp_expired', '短信验证码已过期'), ] username = models.CharField(max_length=30) @@ -284,9 +290,9 @@ class LoginAttempt(models.Model): --- -### 3.3 `password_reset_tokens` — 密码重置令牌表(租户 Schema) +### 3.3 `sms_otp_records` — 短信验证码记录表(租户 Schema) -**表说明**:用于通过邮件找回密码的一次性令牌。单次有效,30 分钟过期。 +**表说明**:记录找回密码和手机验证码登录两个场景中,向用户手机号发送的短信验证码及其状态。用 `scene` 字段区分场景(`password_reset` / `login`),有效期和发送频率上限按场景独立控制。原 `password_reset_tokens`(邮件令牌)已废弃,由本表替代。 #### 字段定义 @@ -294,45 +300,61 @@ class LoginAttempt(models.Model): |--------|------|------|--------|------| | `id` | `BIGSERIAL` | `PRIMARY KEY` | — | 自增主键 | | `user_id` | `BIGINT` | `FK → user_accounts.id`, `NOT NULL` | — | 关联账号 | -| `token` | `VARCHAR(86)` | `NOT NULL`, `UNIQUE` | — | `secrets.token_urlsafe(64)` 生成(86 字符),全局唯一 | -| `expires_at` | `TIMESTAMPTZ` | `NOT NULL` | — | 过期时间(`created_at + 30 分钟`) | -| `is_used` | `BOOLEAN` | `NOT NULL` | `FALSE` | 是否已使用;使用后立即置 True,防止重放攻击 | +| `phone_hash` | `VARCHAR(64)` | `NOT NULL` | — | 收码手机号 SHA-256 哈希(与账号的 `phone_hash` 一致,冗余存储便于限频查询) | +| `scene` | `VARCHAR(20)` | `NOT NULL` | — | 使用场景:`password_reset`(找回密码)或 `login`(验证码登录) | +| `otp_hash` | `VARCHAR(128)` | `NOT NULL` | — | 验证码 PBKDF2 哈希(禁止明文存储,服务端校验时重新哈希比对) | +| `expires_at` | `TIMESTAMPTZ` | `NOT NULL` | — | 过期时间(`password_reset`:`created_at + 10 分钟`;`login`:`created_at + 5 分钟`) | +| `is_used` | `BOOLEAN` | `NOT NULL` | `FALSE` | 是否已验证通过;通过后立即置 True,防止重放攻击 | +| `verify_attempts` | `SMALLINT` | `NOT NULL` | `0` | 已尝试验证次数;≥ 5 次后本条记录强制作废(`is_used = TRUE`) | | `created_at` | `TIMESTAMPTZ` | `NOT NULL` | `NOW()` | 创建时间 | #### 索引 ```sql -CREATE UNIQUE INDEX uq_password_reset_tokens_token ON password_reset_tokens (token); -CREATE INDEX idx_password_reset_tokens_user ON password_reset_tokens (user_id); -CREATE INDEX idx_password_reset_tokens_expiry ON password_reset_tokens (expires_at) WHERE is_used = FALSE; +CREATE INDEX idx_sms_otp_user ON sms_otp_records (user_id, created_at DESC); +CREATE INDEX idx_sms_otp_phone ON sms_otp_records (phone_hash, created_at DESC); +CREATE INDEX idx_sms_otp_active ON sms_otp_records (user_id, expires_at) WHERE is_used = FALSE; ``` #### Django Model 定义 ```python -class PasswordResetToken(models.Model): +class SmsOtpRecord(models.Model): """ - 密码重置令牌。 + 短信验证码记录(找回密码 + 验证码登录共用)。 安全约束: - - Token 单次有效(is_used=True 后立即失效) - - 有效期 30 分钟 - - 同一账号 1 小时内最多生成 3 个(服务层限频,Redis 计数) + - OTP 明文仅在发送短信时生成,不持久化;仅存 PBKDF2 哈希 + - 单条记录验证次数 ≥ 5 次后强制作废(is_used=True) + - 同一手机号 1 小时内按 scene 独立限频(password_reset ≤ 5 次,login ≤ 10 次) """ - user = models.ForeignKey(UserAccount, on_delete=models.CASCADE, related_name='reset_tokens') - token = models.CharField(max_length=86, unique=True) # secrets.token_urlsafe(64) - expires_at = models.DateTimeField() - is_used = models.BooleanField(default=False) - created_at = models.DateTimeField(auto_now_add=True) + SCENE_CHOICES = [ + ('password_reset', '找回密码'), + ('login', '验证码登录'), + ] + + user = models.ForeignKey(UserAccount, on_delete=models.CASCADE, related_name='sms_otp_records') + phone_hash = models.CharField(max_length=64) # SHA-256 哈希,不暴露手机号原文 + scene = models.CharField(max_length=20, choices=SCENE_CHOICES) # 区分场景 + otp_hash = models.CharField(max_length=128) # PBKDF2 哈希,禁止明文存储 + expires_at = models.DateTimeField() # password_reset: +10min; login: +5min + is_used = models.BooleanField(default=False) + verify_attempts = models.SmallIntegerField(default=0) + created_at = models.DateTimeField(auto_now_add=True) class Meta: - db_table = 'password_reset_tokens' + db_table = 'sms_otp_records' indexes = [ - models.Index(fields=['user_id']), + models.Index(fields=['user', '-created_at']), + models.Index(fields=['phone_hash', '-created_at']), ] def is_valid(self) -> bool: from django.utils import timezone - return not self.is_used and timezone.now() < self.expires_at + return not self.is_used and self.verify_attempts < 5 and timezone.now() < self.expires_at + + def mark_used(self): + self.is_used = True + self.save(update_fields=['is_used']) ``` --- @@ -387,8 +409,9 @@ class PasswordHistory(models.Model): | `captcha_token:{uuid}` | STRING | 3 分钟 | 滑块验证会话 Token;验证通过后生成 `captcha_pass_token` | | `captcha_pass:{uuid}` | STRING | 3 分钟 | 一次性通过凭证;登录提交时校验后立即删除 | | `login_fail:{tenant_id}:{username}` | STRING(计数) | 30 分钟 | 连续密码错误次数;≥ 5 触发锁定;TTL 30 分钟自动清零 | -| `recover_email:{email}` | STRING(计数) | 1 小时 | 找回邮件发送次数;上限 3 次/小时 | -| `recover_reset:{account_id}` | STRING(计数) | 1 小时 | 同一账号密码重置 Token 生成次数;上限 3 次/小时 | +| `sms_limit:password_reset:{phone}` | STRING(计数) | 1 小时 | 找回密码场景:同一手机号短信发送次数;上限 **5 次**/小时 | +| `sms_limit:login:{phone}` | STRING(计数) | 1 小时 | 验证码登录场景:同一手机号短信发送次数;上限 **10 次**/小时 | +| `sms_reset_token:{token}` | STRING(user_id) | 15 分钟 | 验证码通过后颁发的一次性重置凭证;用于步骤三提交新密码;使用后立即删除 | | `tenant_verify_ip:{ip}` | STRING(计数) | 1 分钟 | Tenant 验证接口 IP 限流;≥ 10 次拒绝请求 | > **一致性说明**:账号锁定状态由 `user_accounts.status` 持久化,Redis 仅做计数触发器。当 Redis 数据丢失(如 Redis 重启),应用层通过 `locked_until` 字段恢复锁定状态判断。 @@ -435,8 +458,8 @@ class PasswordHistory(models.Model): ### 5.2 账号创建触发时机 | 账号类型 | 触发时机 | 创建者 | username 规则 | 初始密码 | -|----------|----------|--------|--------------|---------| -| Tenant Admin | 平台运营在系统后台开通租户时 | 平台运营 | 自定义(字母开头,6~30 位) | 平台运营自定义 | +|----------|----------|--------|--------------|---------| +| Tenant Admin | 平台运营在系统后台开通租户时 | 平台运营 | **固定为该租户联系人手机号**(11 位数字,来源于 `public.tenants.contact_phone`) | **系统统一固定初始密码**(如 `Fonrey@2025`,由平台部署配置设定) | | 普通员工 | Tenant Admin 在「新增员工」时系统自动生成 | 系统(Tenant Admin 触发) | 固定为员工手机号(11 位) | 系统统一初始密码(部署配置) | --- @@ -472,7 +495,7 @@ org ──► accounts (反向触发,通过 Service 层调用,不通过 FK ``` 0001_initial_user_accounts.py # UserAccount 表(依赖 org.Staff 表已存在) 0002_login_attempts.py # LoginAttempt 表 -0003_password_reset_tokens.py # PasswordResetToken 表 +0003_sms_otp_records.py # SmsOtpRecord 表(替代原 password_reset_tokens) 0004_password_histories.py # PasswordHistory 表 ``` @@ -492,5 +515,6 @@ org ──► accounts (反向触发,通过 Service 层调用,不通过 FK | `phone` 字段拆分为 `phone_enc` + `phone_hash` | 是 | 与 `org.Staff` 保持一致;`phone_enc` 保存原文用于展示,`phone_hash` 用于唯一性校验和快速查询,避免加密字段全表扫描 | | 不扩展 Django `User` | 使用 `AbstractBaseUser` | 避免 `django.contrib.auth.User` 的全局唯一性限制(多租户下同一 username 在不同租户是允许的) | | `LoginAttempt` 不设外键到 `UserAccount` | 是(冗余存储 username) | 即使账号被删除(停用),审计记录仍需保留;使用 username 字符串字段保证审计完整性 | +| 找回密码机制 | 短信验证码(`SmsOtpRecord`) | 经纪人普遍无邮箱;手机号是本系统唯一已知联系方式,短信核验更直接;废弃邮件找回路径,减少外部依赖(SMTP) | | 历史密码单独建表 | `PasswordHistory` 独立表 | 而非在 `UserAccount` 中存 JSON 数组,便于查询和维护,支持未来扩展保留次数 | | 锁定到期时间持久化 | `locked_until` 字段 | Redis 可能重启丢失数据,持久化 `locked_until` 保证 Redis 故障时锁定状态不丢失 | diff --git a/Project/fonrey/DATA_MODEL/DATA_MODEL_PERMISSION.md b/Project/fonrey/DATA_MODEL/DATA_MODEL_PERMISSION.md index 03362e37..61b16395 100644 --- a/Project/fonrey/DATA_MODEL/DATA_MODEL_PERMISSION.md +++ b/Project/fonrey/DATA_MODEL/DATA_MODEL_PERMISSION.md @@ -877,25 +877,25 @@ _本文档版本 v1.1 | 作者: Backend Architect | 更新时间 2026-04-24_ ```sql -- permission_defs CREATE TABLE permission_defs ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - code VARCHAR(150) NOT NULL UNIQUE, - module VARCHAR(50) NOT NULL, - sub_module VARCHAR(50) NOT NULL DEFAULT '', - group_name VARCHAR(100) NOT NULL, - name VARCHAR(200) NOT NULL, - description TEXT NOT NULL DEFAULT '', - value_type VARCHAR(20) NOT NULL CHECK (value_type IN ('BOOLEAN','SCOPE','INTEGER')), - scope_choices JSONB NOT NULL DEFAULT '[]'::jsonb, - integer_min INTEGER, - integer_max INTEGER, - default_value JSONB NOT NULL DEFAULT '{"v":false}'::jsonb, - max_allowed_categories VARCHAR(50)[] NOT NULL DEFAULT ARRAY[]::VARCHAR[], - sort_order INTEGER NOT NULL DEFAULT 0, - is_active BOOLEAN NOT NULL DEFAULT TRUE, - is_deprecated BOOLEAN NOT NULL DEFAULT FALSE, - version INTEGER NOT NULL DEFAULT 1, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + code VARCHAR(150) NOT NULL UNIQUE, -- 权限码,格式 {module}.{sub_module}.{action}[.{qualifier}],全局唯一,创建后不可修改 + module VARCHAR(50) NOT NULL, -- 一级模块标识,如 property / client / org + sub_module VARCHAR(50) NOT NULL DEFAULT '', -- 二级子模块标识;无子模块时为空字符串 + group_name VARCHAR(100) NOT NULL, -- 权限分组显示名称(管理界面分组展示用) + name VARCHAR(200) NOT NULL, -- 权限项中文名称(管理界面展示) + description TEXT NOT NULL DEFAULT '', -- 权限项说明(管理界面 tooltip 文案) + value_type VARCHAR(20) NOT NULL CHECK (value_type IN ('BOOLEAN','SCOPE','INTEGER')), -- 权限值类型:BOOLEAN=开关 / SCOPE=数据范围 / INTEGER=数量上限 + scope_choices JSONB NOT NULL DEFAULT '[]'::jsonb, -- SCOPE 类型可选范围列表(JSON 数组);非 SCOPE 类型为空数组 + integer_min INTEGER, -- INTEGER 类型最小允许值;其他类型为 NULL + integer_max INTEGER, -- INTEGER 类型最大允许值;其他类型为 NULL + default_value JSONB NOT NULL DEFAULT '{"v":false}'::jsonb, -- 权限默认值,格式 {"v": false/scope_str/int} + max_allowed_categories VARCHAR(50)[] NOT NULL DEFAULT ARRAY[]::VARCHAR[], -- 可配置此权限的角色分类白名单;空数组=无限制 + sort_order INTEGER NOT NULL DEFAULT 0, -- 同分组内排序权重(数值越小越靠前) + is_active BOOLEAN NOT NULL DEFAULT TRUE, -- 是否启用;FALSE=已下线,前端配置页隐藏 + is_deprecated BOOLEAN NOT NULL DEFAULT FALSE, -- 是否已废弃;废弃后不可被新角色引用 + version INTEGER NOT NULL DEFAULT 1, -- 乐观锁版本号(每次更新+1) + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录创建时间(系统自动) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) CONSTRAINT chk_code_format CHECK (code ~ '^[a-z_]+\.[a-z_]+(\.[a-z_]+){1,2}$') ); CREATE INDEX idx_permission_defs_module ON permission_defs(module, sub_module, sort_order) WHERE is_active = TRUE; @@ -903,18 +903,18 @@ CREATE INDEX idx_permission_defs_active ON permission_defs(is_active) WHERE is_a -- roles CREATE TABLE roles ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - name VARCHAR(100) NOT NULL, - category VARCHAR(30) NOT NULL CHECK (category IN ('agent','store_manager','director','operator','custom')), - description TEXT NOT NULL DEFAULT '', - template_role_id UUID REFERENCES roles(id) ON DELETE SET NULL, - is_system_builtin BOOLEAN NOT NULL DEFAULT FALSE, - is_active BOOLEAN NOT NULL DEFAULT TRUE, - created_by UUID REFERENCES staff(id) ON DELETE SET NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_by UUID REFERENCES staff(id) ON DELETE SET NULL, - deleted_at TIMESTAMPTZ + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + name VARCHAR(100) NOT NULL, -- 角色显示名称(同租户内唯一,软删除后不参与唯一性校验) + category VARCHAR(30) NOT NULL CHECK (category IN ('agent','store_manager','director','operator','custom')), -- 角色分类:agent=经纪人 / store_manager=门店管理 / director=区域管理 / operator=运营职能 / custom=自定义 + description TEXT NOT NULL DEFAULT '', -- 角色说明文案 + template_role_id UUID REFERENCES roles(id) ON DELETE SET NULL, -- 模板来源(自引用);从某内置角色克隆时记录;NULL=无模板 + is_system_builtin BOOLEAN NOT NULL DEFAULT FALSE, -- 是否系统内置角色;TRUE=不可删除、不可改名 + is_active BOOLEAN NOT NULL DEFAULT TRUE, -- 是否启用;FALSE=角色已停用,员工不可再分配此角色 + created_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 创建人(关联 staff 表);系统内置角色为 NULL + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录创建时间(系统自动) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) + updated_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 最后修改人(关联 staff 表) + deleted_at TIMESTAMPTZ -- 软删除时间戳,NULL=未删除,非NULL=已软删除 ); CREATE UNIQUE INDEX idx_roles_name_active ON roles(name) WHERE deleted_at IS NULL; CREATE INDEX idx_roles_category ON roles(category) WHERE deleted_at IS NULL; @@ -922,13 +922,13 @@ CREATE INDEX idx_roles_template ON roles(template_role_id); -- role_permissions CREATE TABLE role_permissions ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE, - permission_def_id UUID NOT NULL REFERENCES permission_defs(id) ON DELETE RESTRICT, - value JSONB NOT NULL, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_by UUID REFERENCES staff(id) ON DELETE SET NULL + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + role_id UUID NOT NULL REFERENCES roles(id) ON DELETE CASCADE, -- 关联角色(角色删除则权限配置同步级联清除) + permission_def_id UUID NOT NULL REFERENCES permission_defs(id) ON DELETE RESTRICT, -- 关联权限定义(有角色引用时权限项不可删除) + value JSONB NOT NULL, -- 权限配置值,格式 {"v": false/scope_str/int},与 permission_defs.value_type 对应 + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录创建时间(系统自动) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) + updated_by UUID REFERENCES staff(id) ON DELETE SET NULL -- 最后修改人(关联 staff 表) ); CREATE UNIQUE INDEX idx_role_permissions_uniq ON role_permissions(role_id, permission_def_id); CREATE INDEX idx_role_permissions_role ON role_permissions(role_id); @@ -936,14 +936,14 @@ CREATE INDEX idx_role_permissions_def ON role_permissions(permission_def_id); -- staff_roles CREATE TABLE staff_roles ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE CASCADE, - role_id UUID NOT NULL REFERENCES roles(id) ON DELETE RESTRICT, - is_primary BOOLEAN NOT NULL DEFAULT FALSE, - assigned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - assigned_by UUID REFERENCES staff(id) ON DELETE SET NULL, - valid_from DATE, - valid_until DATE + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE CASCADE, -- 员工 ID(员工删除则角色分配同步级联删除) + role_id UUID NOT NULL REFERENCES roles(id) ON DELETE RESTRICT, -- 角色 ID(有员工使用的角色不可删除) + is_primary BOOLEAN NOT NULL DEFAULT FALSE, -- 是否主角色;每员工同时仅可有 1 个主角色(唯一索引保障) + assigned_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 角色分配时间(系统自动) + assigned_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 分配操作人(关联 staff 表);NULL=系统自动分配 + valid_from DATE, -- 角色有效期开始日期;NULL=立即生效 + valid_until DATE -- 角色有效期结束日期;NULL=永久有效 ); CREATE UNIQUE INDEX idx_staff_roles_uniq ON staff_roles(staff_id, role_id); CREATE UNIQUE INDEX idx_staff_roles_primary ON staff_roles(staff_id) WHERE is_primary = TRUE; @@ -951,32 +951,32 @@ CREATE INDEX idx_staff_roles_role ON staff_roles(role_id); -- staff_permission_overrides CREATE TABLE staff_permission_overrides ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE CASCADE, - permission_def_id UUID NOT NULL REFERENCES permission_defs(id) ON DELETE RESTRICT, - value JSONB NOT NULL, + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE CASCADE, -- 员工 ID(员工删除则个人覆盖配置同步级联删除) + permission_def_id UUID NOT NULL REFERENCES permission_defs(id) ON DELETE RESTRICT, -- 关联权限定义 + value JSONB NOT NULL, -- 覆盖配置值,格式与 role_permissions.value 一致 override_mode VARCHAR(10) NOT NULL DEFAULT 'REPLACE' - CHECK (override_mode IN ('REPLACE','RESTRICT','GRANT')), - reason TEXT NOT NULL DEFAULT '', - modified_by UUID REFERENCES staff(id) ON DELETE SET NULL, - modified_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + CHECK (override_mode IN ('REPLACE','RESTRICT','GRANT')), -- 覆盖模式:REPLACE=完全替换角色权限 / RESTRICT=向下收紧 / GRANT=向上提升 + reason TEXT NOT NULL DEFAULT '', -- 覆盖理由(操作审计留存) + modified_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 修改操作人(关联 staff 表) + modified_at TIMESTAMPTZ NOT NULL DEFAULT NOW() -- 修改时间(系统自动) ); CREATE UNIQUE INDEX idx_staff_overrides_uniq ON staff_permission_overrides(staff_id, permission_def_id); CREATE INDEX idx_staff_overrides_staff ON staff_permission_overrides(staff_id); -- staff_data_scopes CREATE TABLE staff_data_scopes ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE CASCADE, - scope_type VARCHAR(20) NOT NULL + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + staff_id UUID NOT NULL REFERENCES staff(id) ON DELETE CASCADE, -- 员工 ID + scope_type VARCHAR(20) NOT NULL -- 数据范围类型:self=本人 / group=小组 / store=门店 / area=大区 / region=区域 / company=全公司 / custom_unit=自定义单元 CHECK (scope_type IN ('self','group','store','area','region','company','custom_unit')), - org_unit_id UUID REFERENCES org_units(id) ON DELETE RESTRICT, - is_readable BOOLEAN NOT NULL DEFAULT TRUE, - is_writable BOOLEAN NOT NULL DEFAULT FALSE, - granted_by UUID REFERENCES staff(id) ON DELETE SET NULL, - granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - expires_at TIMESTAMPTZ, - reason TEXT NOT NULL DEFAULT '', + org_unit_id UUID REFERENCES org_units(id) ON DELETE RESTRICT, -- 自定义组织单元;scope_type=custom_unit 时必填,其他为 NULL + is_readable BOOLEAN NOT NULL DEFAULT TRUE, -- 是否有读权限 + is_writable BOOLEAN NOT NULL DEFAULT FALSE, -- 是否有写权限 + granted_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 授权操作人(关联 staff 表) + granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 授权时间(系统自动) + expires_at TIMESTAMPTZ, -- 到期时间;NULL=永久有效 + reason TEXT NOT NULL DEFAULT '', -- 数据范围授权理由(操作审计留存) CONSTRAINT chk_custom_unit_has_org CHECK ( (scope_type = 'custom_unit' AND org_unit_id IS NOT NULL) OR (scope_type <> 'custom_unit') @@ -988,22 +988,22 @@ CREATE INDEX idx_data_scopes_expires ON staff_data_scopes(expires_at) WHERE expi -- permission_change_logs (append-only, no deleted_at) CREATE TABLE permission_change_logs ( - id UUID NOT NULL DEFAULT gen_random_uuid(), + id UUID NOT NULL DEFAULT gen_random_uuid(), -- 主键(与 operated_at 组成复合主键,分区表要求) operated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 分区键(原 operated_at 前置) - target_type VARCHAR(30) NOT NULL + target_type VARCHAR(30) NOT NULL -- 操作对象类型:role / role_permission / staff_role / staff_override / staff_scope CHECK (target_type IN ('role','role_permission','staff_role','staff_override','staff_scope')), - target_id UUID NOT NULL, - staff_id UUID REFERENCES staff(id) ON DELETE SET NULL, - role_id UUID REFERENCES roles(id) ON DELETE SET NULL, - permission_code VARCHAR(150), - action VARCHAR(20) NOT NULL + target_id UUID NOT NULL, -- 操作对象 ID + staff_id UUID REFERENCES staff(id) ON DELETE SET NULL, -- 被操作员工 ID(如分配/撤销角色时的目标员工) + role_id UUID REFERENCES roles(id) ON DELETE SET NULL, -- 被操作角色 ID + permission_code VARCHAR(150), -- 操作涉及的权限码(冗余存储,避免关联查询) + action VARCHAR(20) NOT NULL -- 操作类型:create=新建 / update=修改 / delete=删除 / assign=分配 / revoke=撤销 CHECK (action IN ('create','update','delete','assign','revoke')), - old_value JSONB, - new_value JSONB, - operator_id UUID NOT NULL REFERENCES staff(id) ON DELETE RESTRICT, - operator_ip INET, - user_agent TEXT, - reason TEXT NOT NULL DEFAULT '', + old_value JSONB, -- 变更前值;create 时为 NULL + new_value JSONB, -- 变更后值;delete 时为 NULL + operator_id UUID NOT NULL REFERENCES staff(id) ON DELETE RESTRICT, -- 操作人员工 ID(RESTRICT:操作记录保留,操作人不可删除) + operator_ip INET, -- 操作人来源 IP + user_agent TEXT, -- 操作人客户端 UA + reason TEXT NOT NULL DEFAULT '', -- 操作理由(可选,审计留存) PRIMARY KEY (id, operated_at) -- 分区表主键必须包含分区键 ) PARTITION BY RANGE (operated_at); diff --git a/Project/fonrey/DATA_MODEL/DATA_MODEL_PUBLIC.md b/Project/fonrey/DATA_MODEL/DATA_MODEL_PUBLIC.md index d1c248a8..8eece44b 100644 --- a/Project/fonrey/DATA_MODEL/DATA_MODEL_PUBLIC.md +++ b/Project/fonrey/DATA_MODEL/DATA_MODEL_PUBLIC.md @@ -2,8 +2,8 @@ # Fonrey — Public Schema 数据模型 > **作者**: Backend Architect -> **版本**: v1.2 -> **日期**: 2026-04-26 +> **版本**: v1.3 +> **日期**: 2026-04-30 > **权威源**: 本文件是 `public` schema 所有表的唯一权威定义 > **设计依据**: 系统管理模块 PRD(`PRD/系统管理/系统管理模块PRD.md`);客户端发布管理模块 PRD(`PRD/发布管理/客户端发布管理模块PRD.md`) > **索引文档**: [`DATA_MODEL.md §三`](./DATA_MODEL.md)(仅保留摘要索引,开发以本文件为准) @@ -87,11 +87,13 @@ PostgreSQL Instance -- 租户主表(每家房产经纪公司一条记录) CREATE TABLE public.tenants ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - schema_name VARCHAR(63) UNIQUE NOT NULL, -- PG schema 名,最长 63 字符,创建后不可修改 + schema_name VARCHAR(63) UNIQUE NOT NULL, -- PG schema 名,最长 63 字符,创建后不可修改;命名规则:t_{uuid前8位},如 t_3f2a1b4c + tenant_code CHAR(12) UNIQUE NOT NULL, -- 对外暴露的 12 位纯数字识别码,如 202500010001;用户登录时输入,由平台运营在注册时生成;创建后不可修改 name VARCHAR(255) NOT NULL, -- 公司名称 short_name VARCHAR(100), -- 简称/品牌名 contact_name VARCHAR(100) NOT NULL, -- 主联系人姓名 - contact_email VARCHAR(254) NOT NULL, -- 联系邮箱(接收通知/欢迎邮件) + contact_phone CHAR(11) NOT NULL, -- 联系人手机号(11位纯数字);系统开通租户时自动以此手机号创建 Tenant Admin 登录账号;必填 + contact_email VARCHAR(254), -- 联系邮箱(接收通知/欢迎邮件;选填,为空时 Tenant Admin 无法自助找回密码) region VARCHAR(100), -- 所在地区(省市,如「上海市」) plan VARCHAR(20) NOT NULL DEFAULT 'basic' CHECK (plan IN ('basic','professional','enterprise')), @@ -857,6 +859,7 @@ ORDER BY created_at DESC; | `UPDATE public.tenant_status_logs` | append-only 审计表 | | `DELETE FROM public.platform_audit_logs` | append-only 审计表 | | `UPDATE public.tenants SET schema_name = ...` | schema 名绑定 PG 物理 schema | +| `UPDATE public.tenants SET tenant_code = ...` | 12 位识别码一旦发放给用户不可更改,避免经纪人无法登录 | | `UPDATE public.domains SET domain = ...` | 域名路由不可变 | | `UPDATE public.client_releases SET version = ...` | 版本号创建后不可修改,变更须新建记录 | | 在租户 schema 中创建 `client_releases` 副本 | 本表属于 public schema,多租户共享,禁止下沉到租户层 | diff --git a/Project/fonrey/DATA_MODEL/DATA_MODEL_SETTING.md b/Project/fonrey/DATA_MODEL/DATA_MODEL_SETTING.md index 669173f0..cfa63f6e 100644 --- a/Project/fonrey/DATA_MODEL/DATA_MODEL_SETTING.md +++ b/Project/fonrey/DATA_MODEL/DATA_MODEL_SETTING.md @@ -50,14 +50,14 @@ apps/setting/ -- 研发预置,租户不可修改分组本身 -- ============================================================ CREATE TABLE lookup_groups ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) module VARCHAR(50) NOT NULL, -- 'client' | 'property' key VARCHAR(100) NOT NULL, -- 'source' | 'follow_purpose' label_zh VARCHAR(50) NOT NULL, -- 界面显示名称,如「客源来源」 description TEXT, -- 说明文案(前端 tooltip 使用) - sort_order SMALLINT NOT NULL DEFAULT 0, - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + sort_order SMALLINT NOT NULL DEFAULT 0, -- 排序权重(数值越小越靠前) + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录创建时间(系统自动) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) UNIQUE (module, key) ); ``` @@ -80,16 +80,16 @@ CREATE TABLE lookup_groups ( -- 租户管理员可增删排序;is_system=True 的预制项不可物理删除 -- ============================================================ CREATE TABLE lookup_items ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - group_id UUID NOT NULL REFERENCES lookup_groups(id) ON DELETE CASCADE, + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) + group_id UUID NOT NULL REFERENCES lookup_groups(id) ON DELETE CASCADE, -- 所属枚举分组(关联 lookup_groups) value VARCHAR(100) NOT NULL, -- 存储值,英文 snake_case(如 'door_to_door') label_zh VARCHAR(50) NOT NULL, -- 显示文本(如「上门」) is_system BOOLEAN NOT NULL DEFAULT FALSE, -- True=系统预制,不可删除,仅可停用 - is_active BOOLEAN NOT NULL DEFAULT TRUE, - sort_order SMALLINT NOT NULL DEFAULT 0, + is_active BOOLEAN NOT NULL DEFAULT TRUE, -- 是否启用;FALSE 后前端下拉不展示,历史数据保留并追加「(已停用)」后缀 + sort_order SMALLINT NOT NULL DEFAULT 0, -- 排序权重(数值越小越靠前) created_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 系统预制时为 NULL - created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录创建时间(系统自动) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) UNIQUE (group_id, value) ); @@ -153,14 +153,14 @@ CREATE INDEX idx_lookup_items_group_active -- 租户标量配置(键值对)(Tenant Schema) -- ============================================================ CREATE TABLE tenant_settings ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) category VARCHAR(50) NOT NULL, -- 配置分类:'client' | 'property' | 'showroom' key VARCHAR(100) NOT NULL, -- 配置 key,如 'duplicate_check_scope' value JSONB NOT NULL, -- 存储任意类型(bool/int/str),如 {"v": "self"} value_type VARCHAR(20) NOT NULL -- 'bool' | 'int' | 'string' | 'enum'(用于前端渲染控件) CHECK (value_type IN ('bool', 'int', 'string', 'enum')), - updated_by UUID REFERENCES staff(id) ON DELETE SET NULL, - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 最后修改人(关联 staff 表) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) UNIQUE (category, key) ); @@ -193,7 +193,7 @@ CREATE INDEX idx_tenant_settings_category ON tenant_settings(category); -- MVP 仅支持 module='property' -- ============================================================ CREATE TABLE field_requirement_rules ( - id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 主键(系统生成,业务无关) module VARCHAR(20) NOT NULL, -- 'property' | 'client'(MVP 只用 'property') entity_type VARCHAR(50) NOT NULL, -- 与 property.property_type CHECK 约束值对齐 -- 'residential'|'villa'|'commercial_residential'|'shop'|'office'|'other' @@ -202,8 +202,8 @@ CREATE TABLE field_requirement_rules ( field_key VARCHAR(50) NOT NULL, -- 字段 key,如 'orientation'|'decoration'|'floor' requirement VARCHAR(10) NOT NULL -- 规则值 CHECK (requirement IN ('required', 'optional', 'hidden')), - updated_by UUID REFERENCES staff(id) ON DELETE SET NULL, - updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_by UUID REFERENCES staff(id) ON DELETE SET NULL, -- 最后修改人(关联 staff 表) + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- 记录最后更新时间(系统自动) UNIQUE (module, entity_type, trade_status, field_key) ); diff --git a/Project/fonrey/DATA_MODEL/SCHEMA_CHANGES.md b/Project/fonrey/DATA_MODEL/SCHEMA_CHANGES.md new file mode 100644 index 00000000..ef9cd550 --- /dev/null +++ b/Project/fonrey/DATA_MODEL/SCHEMA_CHANGES.md @@ -0,0 +1,111 @@ +# Schema 变更记录 + +> **用途**:记录在初始 Model 创建之后新增/修改的字段,供架构师逐一更新 Migration 脚本。 +> **格式**:每条变更含目标表、变更类型、字段定义、变更原因、来源 PRD 依据。 +> **状态流转**:`待迁移` → `已迁移`(架构师完成 migration 后更新状态) + +--- + +## 变更清单 + +| # | 状态 | 目标表 | 变更类型 | 字段名 | 提出日期 | +|---|------|--------|----------|--------|----------| +| 1 | 待迁移 | `public.tenants` | 新增字段 | `tenant_code` | 2026-04-30 | +| 2 | 待迁移 | `public.tenants` | 新增字段 | `contact_phone` | 2026-04-30 | +| 3 | 待迁移 | `public.tenants` | 字段修改 | `contact_email`(NOT NULL → 可 NULL) | 2026-04-30 | + +--- + +## 变更详情 + +### #1 — `public.tenants` 新增 `tenant_code` + +**状态**:待迁移 +**提出日期**:2026-04-30 +**目标表**:`public.tenants`(Public Schema,django-tenants 主租户表) + +**字段定义**: +```sql +tenant_code CHAR(12) UNIQUE NOT NULL +``` + +**注释**:对外暴露的 12 位纯数字识别码,如 `202500010001`;用户首次登录客户端时输入;由平台运营在注册租户时生成;创建后不可修改。 + +**推荐加在**:`schema_name` 字段之后,`name` 字段之前。 + +**约束要求**: +- `CHAR(12)`:固定 12 位 +- `UNIQUE`:全局唯一 +- `NOT NULL`:注册时必填 +- 禁止 `UPDATE`(应用层 + DB 层双重约束,与 `schema_name` 同等级别) + +**建议索引**: +```sql +CREATE UNIQUE INDEX idx_tenants_tenant_code ON public.tenants(tenant_code); +``` + +**变更原因**: +登录 PRD §5.1.3 明确用户输入 12 位 Tenant Code 完成租户识别,服务端需通过该码查找对应 `schema_name`,原始 `public.tenants` 表中缺少此字段。 + +**PRD 依据**: +`PRD/登录管理/用户登录管理模块PRD.md` §5.1.3 — Tenant Code 格式规范: +> 格式:固定 12 位纯数字,如 `202500010001` + +**登录查询示例**: +```sql +SELECT schema_name, name +FROM public.tenants +WHERE tenant_code = '202500010001' + AND status = 'active'; +``` + +--- + +### #2 — `public.tenants` 新增 `contact_phone` + +**状态**:待迁移 +**提出日期**:2026-04-30 +**目标表**:`public.tenants`(Public Schema) + +**字段定义**: +```sql +contact_phone CHAR(11) NOT NULL +``` + +**注释**:联系人手机号(11位纯数字);系统开通租户时自动以此手机号创建 Tenant Admin 登录账号;必填字段,平台运营在创建租户时录入。 + +**推荐加在**:`contact_name` 字段之后,`contact_email` 字段之前。 + +**约束要求**: +- `CHAR(11)`:固定 11 位手机号 +- `NOT NULL`:开通租户时必填 + +**变更原因**: +登录 PRD v1.5 决策:Tenant Admin 账号统一以联系人手机号作为用户名,与普通员工账号规则对齐。需在 tenants 表增加手机号字段作为 Tenant Admin 账号创建的数据来源。 + +**PRD 依据**: +`PRD/登录管理/用户登录管理模块PRD.md` §5.3.2 Tenant Admin 账号规格表 + +--- + +### #3 — `public.tenants.contact_email` 改为可 NULL + +**状态**:待迁移 +**提出日期**:2026-04-30 +**目标表**:`public.tenants`(Public Schema) + +**变更 SQL**: +```sql +ALTER TABLE public.tenants + ALTER COLUMN contact_email DROP NOT NULL; +``` + +**变更原因**: +`contact_email` 原为 `NOT NULL`。由于 Tenant Admin 账号创建数据来源改为 `contact_phone`(手机号,必填),邮箱降级为选填,仅用于找回密码功能。为空时 Tenant Admin 无法自助找回密码,需联系平台运营处理。 + +**PRD 依据**: +`PRD/登录管理/用户登录管理模块PRD.md` §5.3.2 + +--- + +*后续如有新增字段,按同样格式追加到本文件。* diff --git a/Project/fonrey/PRD/PERSONA_定义.md b/Project/fonrey/PRD/PERSONA_定义.md new file mode 100644 index 00000000..b0e7418a --- /dev/null +++ b/Project/fonrey/PRD/PERSONA_定义.md @@ -0,0 +1,177 @@ +# Fonrey 系统角色 Persona 定义 + +**版本**:v1.0 +**状态**:已定稿 +**作者**:产品团队 +**最后更新**:2026-04-30 + +> 本文档是 Fonrey 所有 PRD、DATA_MODEL、PERMISSION_SEED 等文档的角色命名**唯一权威来源**。 +> 所有其他文档中的角色称谓**必须**以本文档为准,禁止自造名称或混用。 + +--- + +## 一、角色层级概览 + +``` +┌─────────────────────────────────────────────────────────┐ +│ Fonrey SaaS 平台 │ +│ │ +│ ① Platform Admin(平台超级管理员) │ +│ └── 管理所有租户:开通、暂停、配置、版本升级 │ +│ │ +│ ─ ─ ─ ─ ─ ─ ─ 租 户 边 界 ─ ─ ─ ─ ─ ─ ─ ─ ─ │ +│ │ +│ ② Tenant Admin(租户管理员) │ +│ └── 管理本租户:组织架构、账号、权限、系统配置 │ +│ │ +│ ③ Agent(经纪人) │ +│ └── 日常业务操作:录入房源、跟进客源、查看数据 │ +│ │ +└─────────────────────────────────────────────────────────┘ +``` + +--- + +## 二、Persona 详细定义 + +### P1 — Platform Admin(平台超级管理员) + +| 属性 | 值 | +| ---------------- | --------------------- | +| **Persona 名称** | Platform Admin | +| **中文称谓** | 平台超级管理员 | +| **Persona Code** | `PLATFORM_ADMIN` | +| **所属层** | 平台层(Platform) | +| **账号归属** | 平台运营团队(Fonrey 公司内部人员) | +| **账号数量** | 极少,手动创建,不通过租户系统管理 | +| **认证入口** | 独立管理后台(非租户客户端) | +| **Schema 归属** | `public`(跨所有租户) | + +**职责范围:** +- 创建、暂停、注销租户(Tenant) +- 为租户初始化 Tenant Admin 账号 +- 管理平台版本、发布客户端安装包 +- 监控系统健康状态、查看平台级日志 +- 配置平台级参数(短信网关、OSS、第三方集成等) + +**不涉及:** +- 不进入任何租户的业务数据 +- 不参与租户内部的权限分配、组织管理 + +**关键约束:** +- Platform Admin 走**独立认证体系**,不纳入租户 RBAC 权限模型 +- 无需在 `permission_definitions` 中注册权限项 + +--- + +### P2 — Tenant Admin(租户管理员) + +| 属性 | 值 | +| ---------------- | ---------------------------------- | +| **Persona 名称** | Tenant Admin | +| **中文称谓** | 租户管理员 | +| **Persona Code** | `TENANT_ADMIN` | +| **所属层** | 租户层(Tenant) | +| **账号归属** | 各租户(房产经纪公司)的系统管理员 | +| **账号数量** | 每个租户 1~3 个,由 Platform Admin 创建初始账号 | +| **认证入口** | 与经纪人相同的租户客户端(Electron App) | +| **登录账号** | 平台运营分配的自定义字符串(不限于手机号格式) | +| **初始密码** | 平台统一固定初始密码,首次登录强制修改 | +| **Schema 归属** | 租户 Schema(`tenant_{id}`) | +| | | + +**职责范围:** +- 维护组织架构(部门/门店树) +- 办理员工入职、离职、调动 +- 创建和管理员工系统账号 +- 配置角色与权限(角色创建、权限分配、个人权限调整) +- 配置系统枚举值(Lookup Items)、房源录入规则、客源规则 +- 查看全租户范围的业务数据(受数据权限规则约束) + +**不涉及:** +- 不能跨租户操作 +- 不能修改平台级配置(版本、短信网关等) + +**与「经纪人」的区别:** +- Tenant Admin 是**管理身份**,不从事日常房源/客源业务操作 +- 在系统内显示为「管理员」身份,拥有全模块管理权限 +- 可以同时持有某个业务角色(如总经),但账号性质以 Tenant Admin 为主 + +**在 PRD 中的出现场景:** +- 组织人事管理模块的主操作者 +- 权限管理模块的主操作者 +- 系统配置模块的主操作者 +- 在楼盘管理、发布管理中执行管理操作的用户 + +--- + +### P3 — Agent(经纪人) + +| 属性 | 值 | +| ---------------- | ----------------------------- | +| **Persona 名称** | Agent | +| **中文称谓** | 经纪人 | +| **Persona Code** | `AGENT` | +| **所属层** | 租户层(Tenant) | +| **账号归属** | 各租户的在职员工 | +| **账号数量** | 每个租户 N 个,由 Tenant Admin 创建 | +| **认证入口** | 租户客户端(Electron App) | +| **登录账号** | 手机号(由 Tenant Admin 录入员工时自动创建) | +| **初始密码** | 系统统一固定初始密码,首次登录强制修改 | +| **Schema 归属** | 租户 Schema(`tenant_{id}`) | + +**内部岗位子类型(Agent Sub-roles):** + +Agent 是统称,内部通过「角色」区分岗位权限层级。系统内置以下角色(不可删除): + +| 角色名称 | Role Code | 典型岗位 | 数据权限范围 | +| ---- | ---------------- | -------- | --------- | +| 置业顾问 | `ROLE_AGENT` | 一线经纪人 | 仅自己的数据 | +| 店管 | `ROLE_STORE_MGR` | 门店店长 | 本门店数据 | +| 区管 | `ROLE_AREA_MGR` | 区域经理 | 本区域数据 | +| 区总 | `ROLE_AREA_DIR` | 区域总监 | 本区域+下属区数据 | +| 副总 | `ROLE_VP` | 副总经理 | 全公司数据(部分) | +| 总经 | `ROLE_GM` | 总经理 | 全公司数据 | +| 其他职能 | `ROLE_OTHER` | 行政/财务/HR | 按需配置 | + +**在 PRD 中的出现场景:** +- 房源管理模块的主操作者 +- 客源管理模块的主操作者 +- 楼盘管理模块的查看用户 +- 登录模块的主要使用者 + +--- + +## 三、命名规范与替换对照表 + +以下为历史文档中出现的混乱称谓,与标准称谓的对照关系: + +| 历史称谓(禁止继续使用) | 应替换为 | 说明 | +| ------------ | ----------------------- | ---------------- | +| 超级管理员 | Platform Admin(平台超级管理员) | 仅指平台层 | +| 平台管理员 | Platform Admin(平台超级管理员) | 同上 | +| 系统管理员 | Tenant Admin(租户管理员) | 租户层管理员 | +| 管理员(泛称) | Tenant Admin(租户管理员) | 明确指向租户层 | +| HR 管理员 | Tenant Admin(租户管理员) | 同一人,不区分子角色 | +| HR 行政 | Tenant Admin(租户管理员) | 同上 | +| 一线经纪人 | Agent(经纪人) | 统称,角色层面才区分岗位 | +| 置业顾问(作为用户称谓) | Agent(经纪人) | 置业顾问仅作为「内置角色名」使用 | + +**规则说明:** +1. PRD User Story 的 **As a** 部分:使用中文称谓(`Tenant Admin(租户管理员)`、`Agent(经纪人)`) +2. 权限矩阵、DATA_MODEL 注释:使用 Persona Code(`TENANT_ADMIN`、`AGENT`) +3. 角色名称(置业顾问、店管、总经等)**仅在角色管理相关语境中**出现,不作为用户身份称谓 +4. `Platform Admin` 在各 PRD 中尽量少出现,其功能属于「系统管理模块」,不在各子模块 PRD 内展开 + +--- + +## 四、快速索引 + +| 场景 | 使用 | +|------|------| +| PRD User Story 主语 | `Tenant Admin(租户管理员)` / `Agent(经纪人)` | +| 错误提示文案(面向用户) | 「请联系您的租户管理员」 | +| DATA_MODEL 注释 | `created_by: 创建该记录的 Agent(经纪人)用户 ID` | +| 权限矩阵行标题 | 使用角色名(置业顾问 / 店管 / 总经 ...) | +| 代码注释 / 枚举值 | `PLATFORM_ADMIN` / `TENANT_ADMIN` / `AGENT` | +| 日志、审计记录 | `operator_type: PLATFORM_ADMIN / TENANT_ADMIN / AGENT` | diff --git a/Project/fonrey/PRD/PRD_MVP.md b/Project/fonrey/PRD/PRD_MVP.md index a8bde2e5..a1b859ee 100644 --- a/Project/fonrey/PRD/PRD_MVP.md +++ b/Project/fonrey/PRD/PRD_MVP.md @@ -180,7 +180,7 @@ ## 4. 用户故事(MVP 核心路径) ### Story 1 — 经纪人录入房源 -> As a **一线经纪人**, +> As a **Agent(经纪人)**, > I want to **快速录入一套二手住宅并上传图片和业主联系方式**, > So that **这套房源的信息能被团队所有成员找到和跟进**. @@ -192,7 +192,7 @@ --- ### Story 2 — 经纪人跟进房源 -> As a **一线经纪人**, +> As a **Agent(经纪人)**, > I want to **对我负责的房源记录每次跟进(面访/电话/钥匙/实勘)**, > So that **我的跟进历史有据可查,团队不会重复联系同一业主**. @@ -204,7 +204,7 @@ --- ### Story 3 — 经纪人录入客源 -> As a **一线经纪人**, +> As a **Agent(经纪人)**, > I want to **录入意向购房/租房客户并跟进其需求变化**, > So that **我能在合适时机将客户与合适房源匹配**. @@ -216,7 +216,7 @@ --- ### Story 4 — 转成交 -> As a **一线经纪人**, +> As a **Agent(经纪人)**, > I want to **将已达成交易的客源标记为"成交"并关联成交房源**, > So that **成交数据进入系统留存,房源状态自动更新**. diff --git a/Project/fonrey/PRD/TASK.md b/Project/fonrey/PRD/TASK.md index feea5b4e..e8cdd21e 100644 --- a/Project/fonrey/PRD/TASK.md +++ b/Project/fonrey/PRD/TASK.md @@ -88,8 +88,8 @@ | [US-SETTING-010](#US-SETTING-010-管理员配置首页展示内容) | 系统配置 | 管理员配置首页展示内容 | [ ] | | [US-SETTING-011](#US-SETTING-011-管理员配置相关方规则) | 系统配置 | 管理员配置相关方规则 | [ ] | | [US-SETTING-012](#US-SETTING-012-管理员配置客源相关参数) | 系统配置 | 管理员配置客源相关参数 | [ ] | -| [US-SYSTEM-010](#US-SYSTEM-010-平台管理员管理租户开通暂停配置) | 系统管理 | 平台管理员管理租户(开通/暂停/配置) | [ ] | -| [US-SYSTEM-011](#US-SYSTEM-011-平台管理员监控系统健康状态) | 系统管理 | 平台管理员监控系统健康状态 | [ ] | +| [US-SYSTEM-010](#US-SYSTEM-010-Platform Admin(平台超级管理员)管理租户开通暂停配置) | 系统管理 | Platform Admin(平台超级管理员)管理租户(开通/暂停/配置) | [ ] | +| [US-SYSTEM-011](#US-SYSTEM-011-Platform Admin(平台超级管理员)监控系统健康状态) | 系统管理 | Platform Admin(平台超级管理员)监控系统健康状态 | [ ] | | [US-RELEASE-010](#US-RELEASE-010-系统发布Windows桌面客户端安装包) | 客户端发布 | 系统发布Windows桌面客户端安装包 | [ ] | | [US-RELEASE-011](#US-RELEASE-011-客户端自动检测并更新至最新版本) | 客户端发布 | 客户端自动检测并更新至最新版本 | [ ] | @@ -110,8 +110,8 @@ | [US-SETTING-021](#US-SETTING-021-管理员配置交易规则) | 系统配置 | 管理员配置交易规则 | [ ] | | ~~US-SETTING-022~~ | ~~系统配置~~ | ~~管理员配置财务规则~~ — **已移出,财务模块 Out of Scope** | ~~[ ]~~ | | ~~US-SETTING-023~~ | ~~系统配置~~ | ~~管理员配置合同模板~~ — **已移出,合同模块 Out of Scope** | ~~[ ]~~ | -| [US-SYSTEM-020](#US-SYSTEM-020-平台管理员查看操作审计日志) | 系统管理 | 平台管理员查看操作审计日志 | [ ] | -| [US-SYSTEM-021](#US-SYSTEM-021-平台管理员管理灰度发布滚动升级) | 系统管理 | 平台管理员管理灰度发布/滚动升级 | [ ] | +| [US-SYSTEM-020](#US-SYSTEM-020-Platform Admin(平台超级管理员)查看操作审计日志) | 系统管理 | Platform Admin(平台超级管理员)查看操作审计日志 | [ ] | +| [US-SYSTEM-021](#US-SYSTEM-021-Platform Admin(平台超级管理员)管理灰度发布滚动升级) | 系统管理 | Platform Admin(平台超级管理员)管理灰度发布/滚动升级 | [ ] | --- @@ -682,13 +682,13 @@ ### 系统管理(运营后台) -##### US-SYSTEM-010 平台管理员管理租户开通暂停配置 +##### US-SYSTEM-010 Platform Admin(平台超级管理员)管理租户开通暂停配置 - 参考PRD文档:`Project/fonrey/PRD/系统管理/系统管理模块PRD.md` - 租户管理(开通/暂停/配置) - 状态:[ ] - 验收标准:可在运营后台新开通租户(自动创建独立PostgreSQL Schema);可暂停租户(暂停后租户用户无法登录);可为租户配置域名/子域名;租户操作记录写入平台操作日志 -##### US-SYSTEM-011 平台管理员监控系统健康状态 +##### US-SYSTEM-011 Platform Admin(平台超级管理员)监控系统健康状态 - 参考PRD文档:`Project/fonrey/PRD/系统管理/系统管理模块PRD.md` - 系统健康监控 - 状态:[ ] @@ -818,13 +818,13 @@ ### 系统管理(运营后台) -##### US-SYSTEM-020 平台管理员查看操作审计日志 +##### US-SYSTEM-020 Platform Admin(平台超级管理员)查看操作审计日志 - 参考PRD文档:`Project/fonrey/PRD/系统管理/系统管理模块PRD.md` - 操作审计日志 - 状态:[ ] - 验收标准:(规划中,详细验收标准待PRD细化后补充) -##### US-SYSTEM-021 平台管理员管理灰度发布滚动升级 +##### US-SYSTEM-021 Platform Admin(平台超级管理员)管理灰度发布滚动升级 - 参考PRD文档:`Project/fonrey/PRD/系统管理/系统管理模块PRD.md` - 灰度发布/滚动升级 - 状态:[ ] diff --git a/Project/fonrey/PRD/TASK_AGENT_READY.md b/Project/fonrey/PRD/TASK_AGENT_READY.md index 1523d140..bd6e64b9 100644 --- a/Project/fonrey/PRD/TASK_AGENT_READY.md +++ b/Project/fonrey/PRD/TASK_AGENT_READY.md @@ -5489,7 +5489,7 @@ Celery Beat 定时任务每日凌晨执行;超过运营配置天数(如30天 - 未完成项/阻塞项 ``` -### US-SYSTEM-010 平台管理员管理租户开通暂停配置 +### US-SYSTEM-010 Platform Admin(平台超级管理员)管理租户开通暂停配置 - 阶段:**P1** - 模块:**系统管理(运营后台)** @@ -5508,7 +5508,7 @@ Celery Beat 定时任务每日凌晨执行;超过运营配置天数(如30天 你是 OpenCode 编程代理。请在当前仓库根目录完成下面任务。 【任务ID】US-SYSTEM-010 -【任务标题】平台管理员管理租户开通暂停配置 +【任务标题】Platform Admin(平台超级管理员)管理租户开通暂停配置 【阶段】P1 【模块】系统管理(运营后台) @@ -5563,7 +5563,7 @@ Celery Beat 定时任务每日凌晨执行;超过运营配置天数(如30天 - 未完成项/阻塞项 ``` -### US-SYSTEM-011 平台管理员监控系统健康状态 +### US-SYSTEM-011 Platform Admin(平台超级管理员)监控系统健康状态 - 阶段:**P1** - 模块:**系统管理(运营后台)** @@ -5582,7 +5582,7 @@ Celery Beat 定时任务每日凌晨执行;超过运营配置天数(如30天 你是 OpenCode 编程代理。请在当前仓库根目录完成下面任务。 【任务ID】US-SYSTEM-011 -【任务标题】平台管理员监控系统健康状态 +【任务标题】Platform Admin(平台超级管理员)监控系统健康状态 【阶段】P1 【模块】系统管理(运营后台) @@ -6651,7 +6651,7 @@ electron-builder 输出 NSIS .exe 安装包和便携版 .zip;安装包经EV证 - 未完成项/阻塞项 ``` -### US-SYSTEM-020 平台管理员查看操作审计日志 +### US-SYSTEM-020 Platform Admin(平台超级管理员)查看操作审计日志 - 阶段:**P2** - 模块:**系统管理(运营后台)** @@ -6671,7 +6671,7 @@ electron-builder 输出 NSIS .exe 安装包和便携版 .zip;安装包经EV证 你是 OpenCode 编程代理。请在当前仓库根目录完成下面任务。 【任务ID】US-SYSTEM-020 -【任务标题】平台管理员查看操作审计日志 +【任务标题】Platform Admin(平台超级管理员)查看操作审计日志 【阶段】P2 【模块】系统管理(运营后台) @@ -6725,7 +6725,7 @@ electron-builder 输出 NSIS .exe 安装包和便携版 .zip;安装包经EV证 - 未完成项/阻塞项 ``` -### US-SYSTEM-021 平台管理员管理灰度发布滚动升级 +### US-SYSTEM-021 Platform Admin(平台超级管理员)管理灰度发布滚动升级 - 阶段:**P2** - 模块:**系统管理(运营后台)** @@ -6745,7 +6745,7 @@ electron-builder 输出 NSIS .exe 安装包和便携版 .zip;安装包经EV证 你是 OpenCode 编程代理。请在当前仓库根目录完成下面任务。 【任务ID】US-SYSTEM-021 -【任务标题】平台管理员管理灰度发布滚动升级 +【任务标题】Platform Admin(平台超级管理员)管理灰度发布滚动升级 【阶段】P2 【模块】系统管理(运营后台) diff --git a/Project/fonrey/PRD/发布管理/客户端发布管理模块PRD.md b/Project/fonrey/PRD/发布管理/客户端发布管理模块PRD.md index 5418db37..29ba0dbb 100644 --- a/Project/fonrey/PRD/发布管理/客户端发布管理模块PRD.md +++ b/Project/fonrey/PRD/发布管理/客户端发布管理模块PRD.md @@ -5,7 +5,7 @@ **版本**: 1.0 **所属系统**: Fonrey 房产经纪管理系统 **关联模块**: 系统管理、权限管理 -**干系人**: 工程负责人、运维负责人、系统管理员 +**干系人**: 工程负责人、运维负责人、Tenant Admin(租户管理员) --- @@ -24,9 +24,9 @@ Fonrey 房产经纪管理系统当前为纯 Web 应用,依赖用户自行通 | 角色 | 使用场景 | 使用频率 | |------|---------|----------| -| 一线经纪人 | 下载安装客户端、日常登录使用系统、接受自动更新 | 每日 | +| Agent(经纪人) | 下载安装客户端、日常登录使用系统、接受自动更新 | 每日 | | 店长/经理 | 同上 | 每日 | -| 系统管理员 | 发布新版本、管理安装包下载地址、监控客户端版本分布 | 按需 | +| Tenant Admin(租户管理员) | 发布新版本、管理安装包下载地址、监控客户端版本分布 | 按需 | | IT 运维人员 | 维护更新服务器、签名证书、构建发布流水线 | 按发布周期 | ### 核心痛点 @@ -65,7 +65,7 @@ Fonrey 房产经纪管理系统当前为纯 Web 应用,依赖用户自行通 ### Story 1:经纪人下载并安装客户端 -**As** 一线经纪人,**I want** 通过公司提供的网址下载一个安装程序并完成安装,**So that** 我可以立即打开登录界面使用 Fonrey 系统,无需手动配置浏览器。 +**As** Agent(经纪人),**I want** 通过公司提供的网址下载一个安装程序并完成安装,**So that** 我可以立即打开登录界面使用 Fonrey 系统,无需手动配置浏览器。 **验收标准**: - [ ] 官方下载页面可通过指定 URL 访问,页面展示最新版本号、发布日期及下载按钮 @@ -80,7 +80,7 @@ Fonrey 房产经纪管理系统当前为纯 Web 应用,依赖用户自行通 ### Story 2:经纪人使用客户端正常登录并使用系统 -**As** 一线经纪人,**I want** 打开客户端后直接访问 Fonrey 系统的完整功能,**So that** 我的日常使用体验与使用 Chrome 浏览器无差异,且不受本机安装的浏览器版本影响。 +**As** Agent(经纪人),**I want** 打开客户端后直接访问 Fonrey 系统的完整功能,**So that** 我的日常使用体验与使用 Chrome 浏览器无差异,且不受本机安装的浏览器版本影响。 **验收标准**: - [ ] 客户端内嵌现代 Chromium 内核(如基于 Electron 或 WebView2),版本不低于 Chromium 100,支持现代 Web 标准(ES2020、CSS Grid、Fetch API 等) @@ -95,7 +95,7 @@ Fonrey 房产经纪管理系统当前为纯 Web 应用,依赖用户自行通 ### Story 3:客户端感知新版本并自动升级 -**As** 一线经纪人,**I want** 客户端在有新版本时自动提示并完成升级,**So that** 我无需手动下载安装,始终使用最新版本,不会因版本落后导致功能异常。 +**As** Agent(经纪人),**I want** 客户端在有新版本时自动提示并完成升级,**So that** 我无需手动下载安装,始终使用最新版本,不会因版本落后导致功能异常。 **验收标准**: - [ ] 客户端启动时及运行期间(每隔 4 小时)自动向更新服务器检查最新版本 @@ -108,9 +108,9 @@ Fonrey 房产经纪管理系统当前为纯 Web 应用,依赖用户自行通 --- -### Story 4:系统管理员发布新版本 +### Story 4:Tenant Admin(租户管理员)发布新版本 -**As** 系统管理员,**I want** 通过管理后台上传新版客户端安装包并配置版本信息,**So that** 客户端能感知到更新并引导用户升级。 +**As** Tenant Admin(租户管理员),**I want** 通过管理后台上传新版客户端安装包并配置版本信息,**So that** 客户端能感知到更新并引导用户升级。 **验收标准**: - [ ] 系统管理后台提供"客户端版本管理"页面(位于系统管理模块下) @@ -125,7 +125,7 @@ Fonrey 房产经纪管理系统当前为纯 Web 应用,依赖用户自行通 ### Story 5:管理员监控客户端版本分布 -**As** 系统管理员,**I want** 查看当前所有在线客户端的版本分布情况,**So that** 了解升级覆盖率,对仍在使用旧版本的客户端发出提醒或强制升级。 +**As** Tenant Admin(租户管理员),**I want** 查看当前所有在线客户端的版本分布情况,**So that** 了解升级覆盖率,对仍在使用旧版本的客户端发出提醒或强制升级。 **验收标准**: - [ ] 客户端版本管理页面展示版本分布统计:各版本在线客户端数量及占比(饼图或条形图) diff --git a/Project/fonrey/PRD/客源管理/客源管理模块PRD.md b/Project/fonrey/PRD/客源管理/客源管理模块PRD.md index fe7523c2..07d80fdf 100644 --- a/Project/fonrey/PRD/客源管理/客源管理模块PRD.md +++ b/Project/fonrey/PRD/客源管理/客源管理模块PRD.md @@ -26,7 +26,7 @@ | 角色 | 描述 | 使用频率 | |------|------|----------| -| 一线经纪人 | 负责录入、维护、跟进自己名下的客源,并与客户进行带看匹配 | 每日高频 | +| Agent(经纪人) | 负责录入、维护、跟进自己名下的客源,并与客户进行带看匹配 | 每日高频 | | 店长/经理 | 查看全店/全区客源概况,监控跟进完成度及带看活跃度 | 每日 | | 行政人员 | 审核客源信息,处理重复客户合并、来源修改审批等 | 每日 | @@ -62,7 +62,7 @@ ### Story 1:经纪人录入新私客 -**As** 一线经纪人,**I want** 快速录入一位新客户的基本信息和购房/租房需求,**So that** 客源进入系统统一管理并支持后续的智能配房和跟进管理。 +**As** Agent(经纪人),**I want** 快速录入一位新客户的基本信息和购房/租房需求,**So that** 客源进入系统统一管理并支持后续的智能配房和跟进管理。 **验收标准**: - [ ] 录入页面标题为"录入私客",通过顶部导航「客源」→「+ 新增私客」或右侧浮动快捷入口「增客」触达 @@ -81,7 +81,7 @@ ### Story 2:经纪人查看与筛选私客列表 -**As** 一线经纪人,**I want** 在客源列表中快速定位目标客户并了解其跟进状态,**So that** 提升客户管理效率,优先跟进高意向客户。 +**As** Agent(经纪人),**I want** 在客源列表中快速定位目标客户并了解其跟进状态,**So that** 提升客户管理效率,优先跟进高意向客户。 **验收标准**: - [ ] 顶部 Tab 导航按需求类型分组:**求购 / 求租 / 暂缓 / 全部私客**,Tab 间可自由切换 @@ -100,7 +100,7 @@ ### Story 3:经纪人查看求购私客列表 -**As** 一线经纪人,**I want** 在求购 Tab 下查看所有有购房意向的私客,并通过多维度筛选快速定位目标客户,**So that** 优先匹配合适房源,提升成交效率。 +**As** Agent(经纪人),**I want** 在求购 Tab 下查看所有有购房意向的私客,并通过多维度筛选快速定位目标客户,**So that** 优先匹配合适房源,提升成交效率。 **验收标准**: - [ ] 求购 Tab 下,状态筛选项为:不限 / 求购 / 租购 @@ -116,7 +116,7 @@ ### Story 4:经纪人查看求租私客列表 -**As** 一线经纪人,**I want** 在求租 Tab 下查看所有有租房意向的私客,**So that** 快速为其匹配合适的出租房源。 +**As** Agent(经纪人),**I want** 在求租 Tab 下查看所有有租房意向的私客,**So that** 快速为其匹配合适的出租房源。 **验收标准**: - [ ] 求租 Tab 下,状态筛选项为:不限 / 求租 / 租购 @@ -129,7 +129,7 @@ ### Story 5:经纪人管理暂缓私客 -**As** 一线经纪人,**I want** 将暂时没有购房/租房需求的客户标记为"暂缓"状态,**So that** 保持活跃客源列表的精准性,同时不丢失潜在客户资源。 +**As** Agent(经纪人),**I want** 将暂时没有购房/租房需求的客户标记为"暂缓"状态,**So that** 保持活跃客源列表的精准性,同时不丢失潜在客户资源。 **验收标准**: - [ ] 暂缓 Tab 下仅展示状态为"暂缓"的客源 @@ -140,7 +140,7 @@ ### Story 6:经纪人查看私客详情页 -**As** 一线经纪人,**I want** 点击客源姓名后进入详情页,查看该客户的完整信息和快捷操作入口,**So that** 在一个页面内完成客户的跟进、带看、配房等核心操作。 +**As** Agent(经纪人),**I want** 点击客源姓名后进入详情页,查看该客户的完整信息和快捷操作入口,**So that** 在一个页面内完成客户的跟进、带看、配房等核心操作。 **验收标准**: - [ ] 详情页顶部展示客源标题(需求标题+联系人姓名),旁边显示带看进度标签(如"一看") @@ -158,7 +158,7 @@ ### Story 7:经纪人查看与编辑需求信息 -**As** 一线经纪人,**I want** 在需求信息 Tab 中查看客户的完整购房/租房需求字段,并支持编辑,**So that** 确保需求信息准确以提升智能配房的匹配精度。 +**As** Agent(经纪人),**I want** 在需求信息 Tab 中查看客户的完整购房/租房需求字段,并支持编辑,**So that** 确保需求信息准确以提升智能配房的匹配精度。 **验收标准**: - [ ] 需求信息 Tab 下展示以下字段(三栏布局):总价(范围区间,万元)、面积(范围区间,㎡)、居室(X居格式)、装修(下拉枚举)、朝向(多选枚举)、楼层(多选:中楼层/低楼层等)、楼龄(范围区间)、意向商圈(多选)、意向小区(多选)、交通情况(文本)、备注(文本) @@ -170,7 +170,7 @@ ### Story 8:经纪人写入与查看跟进记录 -**As** 一线经纪人,**I want** 在跟进记录 Tab 中记录每一次与客户的沟通内容,并按类型筛选查看,**So that** 保留完整的跟进轨迹,便于持续维护客户关系。 +**As** Agent(经纪人),**I want** 在跟进记录 Tab 中记录每一次与客户的沟通内容,并按类型筛选查看,**So that** 保留完整的跟进轨迹,便于持续维护客户关系。 **验收标准**: - [ ] 跟进记录区块顶部为 5 个子 Tab:全部 / 写入跟进 / 敏感信息跟进 / 修改跟进 / 其他跟进 @@ -189,7 +189,7 @@ ### Story 9:经纪人管理带看记录 -**As** 一线经纪人,**I want** 在带看 Tab 中记录与该客户的预约带看和实际带看情况,**So that** 系统化追踪带看进度,提升成交转化效率。 +**As** Agent(经纪人),**I want** 在带看 Tab 中记录与该客户的预约带看和实际带看情况,**So that** 系统化追踪带看进度,提升成交转化效率。 **验收标准**: - [ ] 带看区块顶部提供两个子 Tab:**预约** / **带看** @@ -217,7 +217,7 @@ ### Story 10:经纪人查看客源解读(AI行为分析) -**As** 一线经纪人,**I want** 在客源解读 Tab 中查看系统根据该客户的找房行为自动生成的偏好分析,**So that** 更准确地判断客户真实需求和购房意向,提升推房精准度。 +**As** Agent(经纪人),**I want** 在客源解读 Tab 中查看系统根据该客户的找房行为自动生成的偏好分析,**So that** 更准确地判断客户真实需求和购房意向,提升推房精准度。 **验收标准**: - [ ] 客源解读 Tab 展示说明文字:"以下数据通过客户找房行为分析生成,百分比越高代表浏览次数多",右上角提供「使用指南」链接 @@ -235,7 +235,7 @@ ### Story 11:经纪人使用二手配房功能推荐房源 -**As** 一线经纪人,**I want** 在智能配房(二手配房)Tab 中查看系统为该客户匹配的房源列表,并将合适房源分享给客户,**So that** 提升推房效率,加快成交进度。 +**As** Agent(经纪人),**I want** 在智能配房(二手配房)Tab 中查看系统为该客户匹配的房源列表,并将合适房源分享给客户,**So that** 提升推房效率,加快成交进度。 **验收标准**: - [ ] 二手配房区块标题右侧显示最后更新时间(如"2026-04-22 17:38 更新")及刷新说明 ⓘ 图标 @@ -262,7 +262,7 @@ ### Story 12:经纪人查看与筛选公客列表 -**As** 一线经纪人,**I want** 在公客 Tab 中查看全公司公共客源池中的客户,并通过多维度筛选快速找到我有能力跟进的公客,**So that** 利用公客资源开拓新成交机会。 +**As** Agent(经纪人),**I want** 在公客 Tab 中查看全公司公共客源池中的客户,并通过多维度筛选快速找到我有能力跟进的公客,**So that** 利用公客资源开拓新成交机会。 **验收标准**: - [ ] 顶部一级 Tab 切换至「公客」后激活该视图,Tab 标题高亮橙色下划线 @@ -312,7 +312,7 @@ ### Story 13:经纪人查看成交客列表 -**As** 一线经纪人,**I want** 在成交客 Tab 中查看已完成成交的客户列表,并通过筛选快速回顾历史成交记录,**So that** 为复购/转介绍跟进和业绩复盘提供数据支撑。 +**As** Agent(经纪人),**I want** 在成交客 Tab 中查看已完成成交的客户列表,并通过筛选快速回顾历史成交记录,**So that** 为复购/转介绍跟进和业绩复盘提供数据支撑。 **验收标准**: - [ ] 顶部一级 Tab 切换至「成交客」后激活该视图(面包屑:客源 / 客源管理 / 成交客) @@ -353,7 +353,7 @@ ### Story 14:经纪人编辑客源信息 -**As** 一线经纪人,**I want** 对已录入的客源进行编辑,修改联系方式、基础信息或购房需求,**So that** 保持客源数据的准确性,提升智能配房匹配精度。 +**As** Agent(经纪人),**I want** 对已录入的客源进行编辑,修改联系方式、基础信息或购房需求,**So that** 保持客源数据的准确性,提升智能配房匹配精度。 **验收标准**: - [ ] 编辑客源页面标题为「编辑客源」,通过私客详情页右侧「编辑」按钮或需求信息 Tab「编辑」链接触达 @@ -404,7 +404,7 @@ ### Story 15:经纪人查看客源信息概览面板 -**As** 一线经纪人,**I want** 在客源详情页右侧快速概览该客源的核心信息和常用操作,**So that** 无需切换 Tab 即可掌握客户关键状态并快速执行高频操作。 +**As** Agent(经纪人),**I want** 在客源详情页右侧快速概览该客源的核心信息和常用操作,**So that** 无需切换 Tab 即可掌握客户关键状态并快速执行高频操作。 **验收标准**: - [ ] 客源详情页右侧固定展示"信息概览"面板,不随页面滚动消失 @@ -422,7 +422,7 @@ ### Story 16:经纪人收藏客源至私客收藏夹 -**As** 一线经纪人,**I want** 将重点客户收藏至私客收藏夹,**So that** 在私客列表中可按收藏夹快速筛选出重点跟进客户。 +**As** Agent(经纪人),**I want** 将重点客户收藏至私客收藏夹,**So that** 在私客列表中可按收藏夹快速筛选出重点跟进客户。 **验收标准**: - [ ] 点击信息概览面板中的「☆ 收藏」触发"选择私客收藏夹"浮层 @@ -440,7 +440,7 @@ ### Story 17:经纪人修改客源等级 -**As** 一线经纪人,**I want** 快速修改客源的购买意向等级,**So that** 确保客源等级与客户当前实际意向相符,辅助工作优先级排序。 +**As** Agent(经纪人),**I want** 快速修改客源的购买意向等级,**So that** 确保客源等级与客户当前实际意向相符,辅助工作优先级排序。 **验收标准**: - [ ] 点击信息概览面板中的「改等级」触发"改等级"弹窗 @@ -456,7 +456,7 @@ ### Story 18:经纪人修改客源状态 -**As** 一线经纪人,**I want** 修改客源的需求状态(求购/求租/租购),**So that** 准确反映客户当前的业务需求方向,保证配房匹配精准。 +**As** Agent(经纪人),**I want** 修改客源的需求状态(求购/求租/租购),**So that** 准确反映客户当前的业务需求方向,保证配房匹配精准。 **验收标准**: - [ ] 点击信息概览面板中的「改状态」触发"改状态"弹窗 @@ -473,7 +473,7 @@ ### Story 19:经纪人手动将私客转为公客 -**As** 一线经纪人或店长,**I want** 主动将某私客转入公共客源池,**So that** 让其他经纪人也能跟进该客户,提升客源利用率和成交机会。 +**As** Agent(经纪人)或店长,**I want** 主动将某私客转入公共客源池,**So that** 让其他经纪人也能跟进该客户,提升客源利用率和成交机会。 **验收标准**: - [ ] 点击信息概览面板中的「转公客」触发"把此私客转为公客"弹窗 @@ -492,7 +492,7 @@ ### Story 20:经纪人将私客转为成交客 -**As** 一线经纪人,**I want** 在客户完成购房/租房成交后将其标记为成交客,并录入成交信息,**So that** 完整记录成交数据,同步到成交客列表及业绩统计。 +**As** Agent(经纪人),**I want** 在客户完成购房/租房成交后将其标记为成交客,并录入成交信息,**So that** 完整记录成交数据,同步到成交客列表及业绩统计。 **验收标准**: - [ ] 点击信息概览面板中的「转成交」触发"客户成交"弹窗 @@ -526,7 +526,7 @@ ### Story 21:经纪人将客源标记为无效 -**As** 一线经纪人,**I want** 将无效客户(如空号/骚扰/无意向等)标记为无效,**So that** 避免对无效客户持续无效跟进,提升客源列表质量。 +**As** Agent(经纪人),**I want** 将无效客户(如空号/骚扰/无意向等)标记为无效,**So that** 避免对无效客户持续无效跟进,提升客源列表质量。 **验收标准**: - [ ] 点击信息概览面板中的「转无效」触发"请选择无效原因"弹窗 @@ -549,7 +549,7 @@ ### Story 22:经纪人编辑客源基础信息(快捷入口) -**As** 一线经纪人,**I want** 通过信息概览面板的快捷入口直接编辑客源基础信息,**So that** 无需进入完整编辑页即可快速更新常用字段。 +**As** Agent(经纪人),**I want** 通过信息概览面板的快捷入口直接编辑客源基础信息,**So that** 无需进入完整编辑页即可快速更新常用字段。 **验收标准**: - [ ] 点击信息概览面板中的「编辑客源」入口,触发"编辑基础信息"弹窗(抽屉浮层) @@ -577,7 +577,7 @@ ### Story 23:经纪人管理客源联系人 -**As** 一线经纪人,**I want** 在客源详情页查看、新增或编辑该客源的联系人信息,**So that** 确保联系方式信息完整,随时可以联系到客户。 +**As** Agent(经纪人),**I want** 在客源详情页查看、新增或编辑该客源的联系人信息,**So that** 确保联系方式信息完整,随时可以联系到客户。 **验收标准**: @@ -620,7 +620,7 @@ ### Story 24:经纪人管理客源相关员工 -**As** 一线经纪人或店长,**I want** 查看和修改客源的首录人与归属人,**So that** 确保客源归属关系正确,保证客源跟进责任到人。 +**As** Agent(经纪人)或店长,**I want** 查看和修改客源的首录人与归属人,**So that** 确保客源归属关系正确,保证客源跟进责任到人。 **验收标准**: @@ -649,7 +649,7 @@ ### Story 25:经纪人查看客源操作日志 -**As** 一线经纪人或店长,**I want** 查看某一客源的完整操作历史记录,**So that** 了解客源的全生命周期操作轨迹,追溯变更原因,辅助审计和管理。 +**As** Agent(经纪人)或店长,**I want** 查看某一客源的完整操作历史记录,**So that** 了解客源的全生命周期操作轨迹,追溯变更原因,辅助审计和管理。 **验收标准**: diff --git a/Project/fonrey/PRD/房源管理/房源管理模块PRD.md b/Project/fonrey/PRD/房源管理/房源管理模块PRD.md index c7eedc29..0be3108e 100644 --- a/Project/fonrey/PRD/房源管理/房源管理模块PRD.md +++ b/Project/fonrey/PRD/房源管理/房源管理模块PRD.md @@ -26,7 +26,7 @@ | 角色 | 描述 | 使用频率 | |------|------|----------| -| 一线经纪人 | 负责录入、维护、跟进自己名下的房源 | 每日高频 | +| Agent(经纪人) | 负责录入、维护、跟进自己名下的房源 | 每日高频 | | 店长/经理 | 查看全店/全区房源概况,分配任务,监控跟进完成度 | 每日 | | 行政人员 | 审核房源信息,维护数据质量 | 每日 | @@ -61,7 +61,7 @@ ### Story 1:经纪人录入新房源 -**As** 一线经纪人,**I want** 快速录入一套新房源的完整信息,**So that** 房源能进入公盘流通并留存完整的基础数据。 +**As** Agent(经纪人),**I want** 快速录入一套新房源的完整信息,**So that** 房源能进入公盘流通并留存完整的基础数据。 **验收标准**: - [ ] 支持选择 6 种房源类型(住宅、别墅、商铺、商住、写字楼、其他),本期 P0 实现住宅,P1 实现别墅,商业类型低优先级 @@ -79,7 +79,7 @@ ### Story 2:经纪人筛选查找目标房源 -**As** 一线经纪人,**I want** 在数万条房源中快速定位符合客户需求的房源,**So that** 提升匹配推荐效率、减少无效沟通。 +**As** Agent(经纪人),**I want** 在数万条房源中快速定位符合客户需求的房源,**So that** 提升匹配推荐效率、减少无效沟通。 **验收标准**: - [ ] 支持关键词搜索:小区名称、地址、业主姓名、电话、钥匙编号等 @@ -100,7 +100,7 @@ ### Story 3:经纪人变更房源状态 -**As** 一线经纪人,**I want** 在房源详情页快速变更房源的交易状态并说明原因,**So that** 保持房源状态与实际情况同步,团队成员能及时感知。 +**As** Agent(经纪人),**I want** 在房源详情页快速变更房源的交易状态并说明原因,**So that** 保持房源状态与实际情况同步,团队成员能及时感知。 **验收标准**: - [ ] 状态变更入口位于详情页顶部操作区"改状态"按钮 @@ -113,7 +113,7 @@ ### Story 4:经纪人在详情页快捷编辑房源核心字段 -**As** 一线经纪人,**I want** 不离开房源详情页就能直接修改价格、等级、属性、现状、用途等高频字段,**So that** 减少页面跳转,快速响应业主意向变化。 +**As** Agent(经纪人),**I want** 不离开房源详情页就能直接修改价格、等级、属性、现状、用途等高频字段,**So that** 减少页面跳转,快速响应业主意向变化。 **验收标准**: - [ ] 详情页顶部支持快捷编辑栋座单元房号(含更改理由,最多 200 字) @@ -131,7 +131,7 @@ ### Story 5:经纪人记录房源跟进 -**As** 一线经纪人,**I want** 随时记录与业主的沟通内容,**So that** 保留完整的跟进轨迹,团队协作时不会重复打扰业主。 +**As** Agent(经纪人),**I want** 随时记录与业主的沟通内容,**So that** 保留完整的跟进轨迹,团队协作时不会重复打扰业主。 **验收标准**: - [ ] 在房源详情页顶部可直接唤起"写跟进"浮层,无需离开当前页面 @@ -151,7 +151,7 @@ ### Story 6:经纪人管理钥匙与委托 -**As** 一线经纪人,**I want** 在系统中登记钥匙持有情况和委托协议信息,**So that** 提升房源维护完成度评分,并让团队知悉钥匙状态,避免带看时出现无法入场的情况。 +**As** Agent(经纪人),**I want** 在系统中登记钥匙持有情况和委托协议信息,**So that** 提升房源维护完成度评分,并让团队知悉钥匙状态,避免带看时出现无法入场的情况。 **验收标准**: @@ -172,7 +172,7 @@ ### Story 7:经纪人提交实勘记录 -**As** 一线经纪人,**I want** 完成实地勘察后在系统中提交实勘报告和分类照片,**So that** 提升房源维护完成度、保障房源信息真实性,给客户提供更可信的参考依据。 +**As** Agent(经纪人),**I want** 完成实地勘察后在系统中提交实勘报告和分类照片,**So that** 提升房源维护完成度、保障房源信息真实性,给客户提供更可信的参考依据。 **验收标准**: - [ ] 实勘为独立页面,包含:实勘定位(GPS)、实勘说明(最多 200 字) @@ -186,7 +186,7 @@ ### Story 8:经纪人管理房源业主与联系人 -**As** 一线经纪人,**I want** 在房源详情页随时新增、编辑业主/联系人信息,并查看该业主名下的其他房源,**So that** 保持联系人资料准确完整,了解业主资产全貌,避免重复打扰、提升沟通效率。 +**As** Agent(经纪人),**I want** 在房源详情页随时新增、编辑业主/联系人信息,并查看该业主名下的其他房源,**So that** 保持联系人资料准确完整,了解业主资产全貌,避免重复打扰、提升沟通效率。 #### 验收标准 8.1:新增业主/联系人 @@ -222,7 +222,7 @@ ### Story 9:经纪人管理房源图片 -**As** 一线经纪人,**I want** 为房源上传并分类管理照片、设置封面图,**So that** 提升房源展示质量,吸引更多买家/租客关注。 +**As** Agent(经纪人),**I want** 为房源上传并分类管理照片、设置封面图,**So that** 提升房源展示质量,吸引更多买家/租客关注。 **验收标准**: - [ ] 支持图片分类:封面(限 1 张)、玄关、客厅、餐厅、卧室、卫生间、厨房、阳台、书房、室内其他、室外、全景 @@ -235,7 +235,7 @@ ### Story 10:经纪人管理房源附件 -**As** 一线经纪人,**I want** 为房源上传并分类管理证件/协议等附件文件,**So that** 将核心证明材料与房源绑定留存,方便后续合规审查和团队共享查阅。 +**As** Agent(经纪人),**I want** 为房源上传并分类管理证件/协议等附件文件,**So that** 将核心证明材料与房源绑定留存,方便后续合规审查和团队共享查阅。 **验收标准**: - [ ] 附件分类 Tab 包含:全部 / 身份证 / 房产证 / 委托书 / 其他,每个 Tab 实时显示该分类文件数量 @@ -248,7 +248,7 @@ ### Story 11:经纪人补全房源详细信息 -**As** 一线经纪人,**I want** 不离开房源详情页补充或修改基本信息、产证信息、房屋介绍和楼盘信息,**So that** 提升房源维护完成度评分,增强房源对买家/租客的吸引力。 +**As** Agent(经纪人),**I want** 不离开房源详情页补充或修改基本信息、产证信息、房屋介绍和楼盘信息,**So that** 提升房源维护完成度评分,增强房源对买家/租客的吸引力。 **验收标准**: - [ ] 「房源信息」Tab 下,以下区块均支持点击"编辑"触发浮窗编辑,无需跳转页面: diff --git a/Project/fonrey/PRD/房源管理/楼盘管理模块PRD.md b/Project/fonrey/PRD/房源管理/楼盘管理模块PRD.md index 7aa3bea5..d8981bc2 100644 --- a/Project/fonrey/PRD/房源管理/楼盘管理模块PRD.md +++ b/Project/fonrey/PRD/房源管理/楼盘管理模块PRD.md @@ -27,9 +27,9 @@ | 角色 | 描述 | 使用频率 | |------|------|----------| | 运营/数据管理员 | 维护楼盘信息、楼栋结构、区域体系、学校信息的标准化数据 | 每日 | -| 一线经纪人 | 查询楼盘详情、参考价格走势、了解周边配套辅助成交 | 每日 | +| Agent(经纪人) | 查询楼盘详情、参考价格走势、了解周边配套辅助成交 | 每日 | | 店长/经理 | 监控楼盘数据完整度,分析区域市场行情 | 每周 | -| 系统管理员 | 配置区域关联关系,管理数据标准 | 不定期 | +| Tenant Admin(租户管理员) | 配置区域关联关系,管理数据标准 | 不定期 | --- @@ -227,7 +227,7 @@ ### Story 7:经纪人查看楼盘价格走势 -**As** 一线经纪人,**I want** 在楼盘详情页查看该楼盘的挂牌价走势和历史成交数据,**So that** 在带看时能为客户提供客观的市场行情参考,增强议价信心。 +**As** Agent(经纪人),**I want** 在楼盘详情页查看该楼盘的挂牌价走势和历史成交数据,**So that** 在带看时能为客户提供客观的市场行情参考,增强议价信心。 **验收标准**: @@ -263,7 +263,7 @@ ### Story 8:经纪人查看楼盘周边配套 -**As** 一线经纪人,**I want** 在楼盘详情页查看该楼盘周边的交通/教育/医疗/购物/生活/娱乐配套,**So that** 在带客时快速回答客户关于生活便利性的问题,增强成交转化。 +**As** Agent(经纪人),**I want** 在楼盘详情页查看该楼盘周边的交通/教育/医疗/购物/生活/娱乐配套,**So that** 在带客时快速回答客户关于生活便利性的问题,增强成交转化。 **验收标准**: - [ ] 周边配套 Tab 以地图为主体,楼盘位置以橙色标记点展示在地图上 diff --git a/Project/fonrey/PRD/权限管理/小区.md b/Project/fonrey/PRD/权限管理/小区.md index 2d679dbc..80b0c987 100644 --- a/Project/fonrey/PRD/权限管理/小区.md +++ b/Project/fonrey/PRD/权限管理/小区.md @@ -20,7 +20,7 @@ | 司内成交明细及套数 | true/false | 开启后,显示公司成交的房源明细信息及成交套数 | | 区域管理 | true/false | 若启用,则可对区域商圈进行新增、合并、关联操作 | | 查看销控盘 | true/false | 开启后,可在楼盘管理系统-楼盘里,查看销控盘。请注意:员工查看销控盘时房源地址是直接可见的,建议只给管理层开启!!! | -| 查看销控盘时,只可查看本部门作业范围内的楼盘 | true/false | 开启后,只可查看本部门作业范围内的楼盘的销控盘;关闭后,则跟作业范围无关,「查看销控盘」权限开启即可见所有楼盘的销控盘;系统管理员不受限制 | +| 查看销控盘时,只可查看本部门作业范围内的楼盘 | true/false | 开启后,只可查看本部门作业范围内的楼盘的销控盘;关闭后,则跟作业范围无关,「查看销控盘」权限开启即可见所有楼盘的销控盘;Tenant Admin(租户管理员)不受限制 | --- diff --git a/Project/fonrey/PRD/权限管理/权限管理模块PRD.md b/Project/fonrey/PRD/权限管理/权限管理模块PRD.md index 8dadd164..8ee24824 100644 --- a/Project/fonrey/PRD/权限管理/权限管理模块PRD.md +++ b/Project/fonrey/PRD/权限管理/权限管理模块PRD.md @@ -24,9 +24,9 @@ | 角色 | 描述 | 使用频率 | |------|------|----------| -| 系统管理员 | 负责角色创建、权限配置、人员权限分配及批量操作,是本模块的核心使用者 | 每日 | +| Tenant Admin(租户管理员) | 负责角色创建、权限配置、人员权限分配及批量操作,是本模块的核心使用者 | 每日 | | 店长 / 区域经理 | 查看下属员工当前权限,按需发起权限变更申请 | 按需 | -| 一线经纪人 | 受权限约束的数据访问者,感知到功能入口的显示/隐藏变化 | 被动感知 | +| Agent(经纪人) | 受权限约束的数据访问者,感知到功能入口的显示/隐藏变化 | 被动感知 | --- @@ -60,7 +60,7 @@ ### Story 1:管理员查看人员权限列表 -**As** 系统管理员,**I want** 在人员列表中查看全公司所有员工的当前角色与权限状态,**So that** 能快速定位权限异常人员并执行调整。 +**As** Tenant Admin(租户管理员),**I want** 在人员列表中查看全公司所有员工的当前角色与权限状态,**So that** 能快速定位权限异常人员并执行调整。 **验收标准**: - [ ] 页面入口路径:顶部导航「人事」→「组织人事」→「权限管理」,面包屑显示「人事OA / 组织人事 / 权限管理」 @@ -81,7 +81,7 @@ ### Story 2:管理员为员工批量设置角色 -**As** 系统管理员,**I want** 同时为多名员工批量设置同一角色,**So that** 在员工入职或组织架构调整时能高效完成权限初始化,无需逐一操作。 +**As** Tenant Admin(租户管理员),**I want** 同时为多名员工批量设置同一角色,**So that** 在员工入职或组织架构调整时能高效完成权限初始化,无需逐一操作。 **验收标准**: - [ ] 在人员列表中勾选至少一名员工后,「批量设置角色」按钮从禁用变为可点击 @@ -95,7 +95,7 @@ ### Story 3:管理员修改个人权限 -**As** 系统管理员,**I want** 为特定员工在角色权限基础上进行个性化权限调整,**So that** 满足因岗位特殊性而需要区别于通用角色权限配置的场景。 +**As** Tenant Admin(租户管理员),**I want** 为特定员工在角色权限基础上进行个性化权限调整,**So that** 满足因岗位特殊性而需要区别于通用角色权限配置的场景。 **验收标准**: - [ ] 点击人员列表中某员工操作列的「修改权限」后,进入该员工的权限编辑页 @@ -132,7 +132,7 @@ ### Story 4:管理员查看并编辑特定权限项(侧边抽屉) -**As** 系统管理员,**I want** 在编辑单个权限项时,同时看到该权限当前应用该角色的所有人员名单,**So that** 能了解本次修改的影响范围,再决定是否确认变更。 +**As** Tenant Admin(租户管理员),**I want** 在编辑单个权限项时,同时看到该权限当前应用该角色的所有人员名单,**So that** 能了解本次修改的影响范围,再决定是否确认变更。 **验收标准**: - [ ] 点击权限项的「编辑」按钮后,页面右侧滑出 Drawer(不覆盖左侧导航) @@ -147,7 +147,7 @@ ### Story 5:管理员查看角色列表 -**As** 系统管理员,**I want** 在角色管理页查看所有已创建的角色及其基本信息,**So that** 快速了解当前系统的角色体系,并按需编辑或删除。 +**As** Tenant Admin(租户管理员),**I want** 在角色管理页查看所有已创建的角色及其基本信息,**So that** 快速了解当前系统的角色体系,并按需编辑或删除。 **验收标准**: - [ ] 点击顶部「角色管理」Tab 切换至角色列表页 @@ -165,7 +165,7 @@ ### Story 6:管理员新增角色 -**As** 系统管理员,**I want** 新建一个角色并配置其权限,**So that** 为新增岗位或特殊职能定义标准权限模板,便于批量分配给对应员工。 +**As** Tenant Admin(租户管理员),**I want** 新建一个角色并配置其权限,**So that** 为新增岗位或特殊职能定义标准权限模板,便于批量分配给对应员工。 **验收标准**: - [ ] 点击「+ 新增角色」按钮弹出 Modal,标题为「添加角色」 @@ -182,7 +182,7 @@ ### Story 7:管理员配置角色权限 -**As** 系统管理员,**I want** 在角色权限编辑页为角色精细配置各模块的权限开关和数据范围,**So that** 该角色下所有人员自动继承统一的权限配置,减少重复操作。 +**As** Tenant Admin(租户管理员),**I want** 在角色权限编辑页为角色精细配置各模块的权限开关和数据范围,**So that** 该角色下所有人员自动继承统一的权限配置,减少重复操作。 **验收标准**: - [ ] 角色权限编辑页顶部展示:角色名称、角色类别、「编辑」按钮(支持在线修改角色基本信息) @@ -199,7 +199,7 @@ ### Story 8:管理员修改角色(切换员工角色) -**As** 系统管理员,**I want** 在员工权限编辑页直接切换员工所属角色,**So that** 快速完成角色变更而不需要退出到人员列表再操作。 +**As** Tenant Admin(租户管理员),**I want** 在员工权限编辑页直接切换员工所属角色,**So that** 快速完成角色变更而不需要退出到人员列表再操作。 **验收标准**: - [ ] 在员工权限编辑页顶部,角色名称旁有下拉箭头,点击展开角色选择器 @@ -427,7 +427,7 @@ Fonrey 采用 **RBAC(基于角色的访问控制)+ 个人权限叠加** 的 | 司内成交明细及套数 | 开关型 | 开启后,显示公司成交的房源明细信息及成交套数 | | 区域管理 | 开关型 | 若启用,则可对区域商圈进行新增、合并、关联操作 | | 查看销控盘 | 开关型 | 开启后,可在楼盘管理系统-楼盘里,查看销控盘;注意:员工查看销控盘时房源地址是直接可见的,建议只给管理层开启!!!| -| 查看销控盘时,只可查看本部门作业范围内的楼盘 | 开关型 | 开启后,只可查看本部门作业范围内的楼盘的销控盘;关闭,则跟作业范围无关,「查看销控盘」权限开启即可查看所有楼盘的销控盘;系统管理员不受限制 | +| 查看销控盘时,只可查看本部门作业范围内的楼盘 | 开关型 | 开启后,只可查看本部门作业范围内的楼盘的销控盘;关闭,则跟作业范围无关,「查看销控盘」权限开启即可查看所有楼盘的销控盘;Tenant Admin(租户管理员)不受限制 | **楼盘资料管理** @@ -537,8 +537,8 @@ Fonrey 采用 **RBAC(基于角色的访问控制)+ 个人权限叠加** 的 | 阶段 | 时间 | 受众 | 通过标准 | |------|------|------|---------| | 内部 Alpha | TBD | 研发 + 产品团队 | 角色 CRUD 流程通畅,权限编辑保存无误 | -| 封闭 Beta | TBD | 1-2 家试点门店系统管理员 | 批量设置角色 / 个人权限修改功能可用,无 P0 Bug | -| 正式上线 | TBD | 全部租户系统管理员 | 权限变更实时生效,错误率 < 0.5%,系统管理员 CSAT ≥ 4/5 | +| 封闭 Beta | TBD | 1-2 家试点门店Tenant Admin(租户管理员) | 批量设置角色 / 个人权限修改功能可用,无 P0 Bug | +| 正式上线 | TBD | 全部租户Tenant Admin(租户管理员) | 权限变更实时生效,错误率 < 0.5%,Tenant Admin(租户管理员) CSAT ≥ 4/5 | **回滚标准**:若权限写入后错误率 > 2%,或出现跨租户数据泄漏问题,立即回滚并通知所有租户管理员。 diff --git a/Project/fonrey/PRD/登录管理/找回密码流程.png b/Project/fonrey/PRD/登录管理/找回密码流程.png deleted file mode 100644 index 63df3f2467d92809b5d100afc2bb4185b62c3737..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 290601 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 z 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�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 Di+Caf+MCzJ-EeD-bh7JX^1 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⪙s)k|WiDkn@-792IQ;ottp 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 diff --git a/Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md b/Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md index eda83556..530d3148 100644 --- a/Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md +++ b/Project/fonrey/PRD/登录管理/用户登录管理模块PRD.md @@ -2,8 +2,8 @@ **状态**: Draft **作者**: 产品经理 -**最后更新**: 2026-04-25(v1.4 §5.5 后端数据模型迁移至独立文档 `DATA_MODEL/DATA_MODEL_LOGIN.md`) -**版本**: 1.4 +**最后更新**: 2026-04-30(v2.0 根据 review 后的 §4 用户故事全面同步 §5 功能详细说明:删除找回用户名流程及邮件模板;找回密码改为纯短信流程;新增 §5.5 手机验证码登录详细说明;§6 技术注意事项更新短信依赖/风险/开放问题;§8.2 接口清单同步正式功能状态) +**版本**: 2.0 **所属系统**: Fonrey 房产经纪管理系统 **关联模块**: 组织人事管理、权限管理、系统管理 @@ -28,17 +28,17 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用多租户架 |------|--------|---------| | 多租户环境下,客户端不知道应该连接哪个租户的服务端 | 新用户首次安装后无法正常使用 | 系统无法启动,用户体验极差 | | 账号密码裸露登录,缺乏验证码保护 | 所有用户 | 存在暴力破解、自动化恶意登录风险 | -| 用户忘记账号或密码无自助找回通道 | 一线经纪人 | 依赖管理员手动重置,效率低 | -| 账号未与实名经纪人档案绑定 | 系统管理员、合规审计 | 操作行为无法追溯至自然人 | +| 用户忘记账号或密码无自助找回通道 | Agent(经纪人) | 依赖管理员手动重置,效率低 | +| 账号未与实名经纪人档案绑定 | Tenant Admin(租户管理员)、合规审计 | 操作行为无法追溯至自然人 | | 无多因素认证,安全系数低 | 管理层、数据合规 | 存在账号冒用、数据泄露风险 | ### 1.3 目标用户 | 角色 | 描述 | 使用频率 | |------|------|----------| -| 一线经纪人 | 每日登录系统使用房源/客源功能 | 每日高频 | +| Agent(经纪人) | 每日登录系统使用房源/客源功能 | 每日高频 | | 店长 / 经理 | 登录后查看全店数据、管理任务 | 每日 | -| 系统管理员 | 管理账号创建、密码重置、租户初始化 | 按需 | +| Tenant Admin(租户管理员) | 管理账号创建、密码重置、租户初始化 | 按需 | | 新安装用户 | 首次安装客户端后需完成 Tenant 识别 | 一次性 | --- @@ -49,7 +49,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用多租户架 |------|------|----------|--------|----------| | 降低登录失败率 | 账号密码正确情况下的登录成功率 | 待统计 | ≥ 99% | 上线后 30 天 | | 防止恶意登录 | 每日验证码拦截异常登录请求数 | 0(无保护) | 建立基线,同IP异常次数 > 5次/分钟触发封锁 | 上线后持续监控 | -| 提升找回账号效率 | 用户自助找回密码耗时 | 依赖管理员(约1工作日) | < 3 分钟(邮件/短信自助) | 上线后 30 天 | +| 提升找回账号效率 | 用户自助找回密码耗时 | 依赖管理员(约1工作日) | < 3 分钟(短信验证码自助) | 上线后 30 天 | | 确保账号实名绑定率 | 拥有系统账号且未与员工档案绑定的账号比例 | 待统计 | 0%(强制绑定) | 上线即达标 | | Tenant 识别成功率 | 首次安装后成功完成 Tenant 识别的用户比例 | 待统计 | ≥ 98% | 上线后 30 天 | @@ -58,11 +58,12 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用多租户架 ## 3. 非目标(本期不做) - **手机验证码登录**:移动端小程序上线后实现,本期**接口预留**,UI 入口以「即将开放」禁用态展示 + > **注意**:本条已更新。手机验证码登录已升级为 **MVP 正式功能**(见 Story 5),与密码登录并列提供。此非目标条目保留仅作版本记录,已失效。 - **微信扫码登录**:移动端小程序上线后实现,本期**接口预留**,UI 入口以「即将开放」禁用态展示 - **单点登录(SSO)/ 企业微信集成**:后续版本规划 - **多设备并发登录的强制踢出策略**:本期允许同账号多端登录,后续安全策略模块规划 - **登录时段限制 / IP 白名单**:安全策略模块另行规划 -- **管理后台(Platform Admin)登录**:系统管理员登录管理后台的流程属于系统管理模块,本 PRD 专注租户内用户登录 +- **管理后台(Platform Admin)登录**:Tenant Admin(租户管理员)登录管理后台的流程属于系统管理模块,本 PRD 专注租户内用户登录 --- @@ -72,31 +73,33 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用多租户架 ### Story 1:新用户首次启动客户端——Tenant 识别 -**As** 新安装 Fonrey 客户端的经纪人,**I want** 在首次启动时输入所属公司的 Tenant ID 完成租户识别,**So that** 客户端能连接到正确的服务端,后续显示对应公司的登录界面和数据。 +**As** 新安装 Fonrey 客户端的经纪人,**I want** 在首次启动时输入所属公司的 12位 Tenant Code 完成租户识别,**So that** 客户端能连接到正确的服务端,后续显示对应公司的登录界面和数据。 **验收标准**: -- [ ] 客户端首次启动时(本地无 Tenant ID 缓存),自动呈现「Tenant 识别」界面,而非直接显示登录界面 -- [ ] 界面包含:产品 Logo、产品名称「Fonrey 房睿」、说明文案「请输入您公司的专属识别码」、Tenant ID 输入框、「确认」按钮 -- [ ] Tenant ID 输入框支持粘贴操作,自动去除前后空格 +- [ ] 客户端首次启动时(本地无 Tenant Code 缓存),自动呈现「Tenant 识别」界面,而非直接显示登录界面 +- [ ] 界面包含:产品 Logo、产品名称「Fonrey 房睿」、说明文案「请输入您公司的专属识别码」、Tenant Code 输入框、「确认」按钮 +- [ ] Tenant Code 输入框支持粘贴操作,自动去除前后空格 - [ ] 点击「确认」后,客户端向服务端发起 Tenant 验证请求(`POST /api/auth/tenant/verify/`),展示加载状态(spinner) -- [ ] **验证成功**:服务端返回租户名称及品牌信息(如公司名称、Logo URL);客户端将 Tenant ID 写入本地持久化存储,自动跳转至该租户的登录界面;界面顶部展示「正在登录:XX 房产」 -- [ ] **验证失败(Tenant ID 无效)**:输入框下方显示红色错误提示「识别码无效,请联系您的系统管理员获取正确的识别码」;Tenant ID 不写入本地缓存;用户可重新输入 +- [ ] **验证成功**:服务端返回租户名称及品牌信息(如公司名称、Logo URL);客户端将 Tenant Code 写入本地持久化存储,自动跳转至该租户的登录界面;界面顶部展示「正在登录:XX 房产」 +- [ ] **验证失败(Tenant Code 无效)**:输入框下方显示红色错误提示「识别码无效,请联系您的Tenant Admin(租户管理员)获取正确的识别码」;Tenant Code 不写入本地缓存;用户可重新输入 - [ ] **网络异常**:显示「网络连接失败,请检查网络后重试」,提供「重试」按钮 -- [ ] 非首次启动(本地已有合法 Tenant ID 缓存):直接跳过识别界面,进入登录界面 -- [ ] 登录界面提供「切换公司」入口(链接文字,非主要 CTA),点击后清除本地 Tenant ID 缓存并重新显示 Tenant 识别界面;确认前弹出二次确认「切换公司将退出当前账号,是否继续?」 +- [ ] 非首次启动(本地已有合法 Tenant Code 缓存):直接跳过识别界面,进入登录界面 +- [ ] 登录界面提供「切换公司」入口(链接文字,非主要 CTA),点击后清除本地 Tenant Code 缓存并重新显示 Tenant 识别界面;确认前弹出二次确认「切换公司将退出当前账号,是否继续?」 - [ ] Tenant 验证接口属于公开接口,无需鉴权;但需对单 IP 请求频率限制(每分钟 ≤ 10 次)以防止枚举攻击 --- -### Story 2:经纪人通过账号密码登录 +### Story 2:经纪人通过手机号和密码登录 -**As** 已识别租户的经纪人,**I want** 通过用户名和密码完成登录,**So that** 进入系统开始工作。 +**As** 已识别租户的经纪人,**I want** 通过手机号和密码完成登录,**So that** 进入系统开始工作。 + +> **说明**:普通员工的登录账号即为其手机号(由Tenant Admin(租户管理员)在新增员工时自动创建),无需记忆额外用户名。Tenant Admin 账号的登录名为平台运营自定义字符串,不受此约束。 **验收标准**: -- [ ] 登录界面展示:租户品牌标识(公司 Logo + 公司名称)、用户名输入框、密码输入框、滑块拼图验证区域、「登录」按钮 -- [ ] 用户名输入框 Placeholder:「请输入用户名」;支持英文字母、数字、下划线,最大长度 50 字符 +- [ ] 登录界面展示:租户品牌标识(公司 Logo + 公司名称)、手机号输入框、密码输入框、滑块拼图验证区域、「登录」按钮 +- [ ] 手机号输入框 Placeholder:「请输入您的手机号」;仅接受数字字符(非数字自动过滤),固定 11 位 - [ ] 密码输入框默认密文显示,右侧提供「显示/隐藏」图标切换明密文 - [ ] **行为验证码(滑块拼图)**:展示一张带缺口的背景图和一块可拖动的拼图碎片,用户通过拖动滑块将碎片移动至缺口位置完成验证;无需输入任何字符,操作直观快速 - [ ] 验证逻辑:前端记录滑动轨迹(坐标序列 + 耗时),与背景图缺口位置一同发送至服务端;服务端综合校验**位置偏差**(允许 ±5px 容差)和**轨迹特征**(是否存在人类滑动的加速/减速规律)以区分机器行为 @@ -104,92 +107,121 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用多租户架 - [ ] 验证成功后,拼图区域显示绿色对勾 + 「验证通过」文案,状态持续至本次登录提交完成 - [ ] 提供「刷新」图标按钮,允许用户主动刷新背景图(针对图片模糊或缺口不清晰的情况) - [ ] 背景图从预置图库中随机抽取,缺口位置每次随机生成,防止固定模式被预测 -- [ ] 三项(用户名、密码、验证码)均有填写后,「登录」按钮才可点击(否则置灰) +- [ ] 三项(手机号、密码、验证码)均有填写后,「登录」按钮才可点击(否则置灰) - [ ] 点击「登录」触发前端格式校验: - - 用户名为空 → 输入框下方红色提示「请输入用户名」 + - 手机号为空 → 输入框下方红色提示「请输入手机号」 + - 手机号不满 11 位 → 提示「请输入完整的 11 位手机号」 - 密码为空 → 提示「请输入密码」 - - 验证码为空 → 提示「请输入验证码」 + - 验证码为空 → 提示「请完成滑块验证」 - [ ] 格式校验通过后,向服务端发起登录请求,按钮进入 loading 状态防止重复提交 -- [ ] **登录成功**:服务端返回 Session Token;客户端存储 Token;跳转至系统首页;顶部显示欢迎信息「欢迎回来,{姓名}」 -- [ ] **登录失败(用户名或密码错误)**:显示「用户名或密码错误,请重新输入」(不区分是用户名错误还是密码错误,防止枚举攻击);验证码自动刷新;密码输入框清空;用户名保留 +- [ ] **登录成功(常规)**:服务端返回 Session Token 及 `is_initial_password` 标记;客户端存储 Token; + - 若 `is_initial_password = False`:直接跳转系统首页,顶部显示欢迎信息「欢迎回来,{姓名}」 + - 若 `is_initial_password = True`:**立即跳转「修改初始密码」强制页面**,不可关闭、不可跳过、不可访问任何其他功能页面(详见 §5.3.4) +- [ ] **登录失败(手机号或密码错误)**:显示「手机号或密码错误,请重新输入」(不区分具体原因,防止枚举攻击);验证码自动刷新;密码输入框清空;手机号保留 - [ ] **登录失败(验证码错误)**:显示「验证码有误,请重新输入」;验证码自动刷新;验证码输入框清空 - [ ] **账号被锁定**(同一账号密码连续错误 ≥ 5 次):显示「账号已被临时锁定,请 30 分钟后重试,或联系管理员解锁」;锁定状态下「登录」按钮置灰 - [ ] **账号已停用**:显示「账号已停用,请联系您的管理员」 - [ ] **Session 过期**:用户在系统内操作时 Session 过期,自动跳转至登录界面,并提示「登录已过期,请重新登录」 -- [ ] 登录界面底部提供:「忘记用户名」链接、「忘记密码」链接(详见 Story 3、Story 4) +- [ ] 登录界面底部提供:「忘记密码」链接(详见 Story 3);移除「忘记用户名」入口(普通员工用户名即手机号,无需找回;Tenant Admin 如忘记用户名请联系平台运营) --- -### Story 3:经纪人找回用户名 +### Story 3:经纪人找回密码 -**As** 忘记用户名的经纪人,**I want** 通过绑定的邮箱或手机号找回用户名,**So that** 不依赖管理员也能自助恢复登录。 +**As** 忘记密码的经纪人,**I want** 通过手机号 + 短信验证码完成身份核验,重新设定密码,**So that** 无需邮箱、无需联系管理员,独立完成密码重置。 + +> **说明**:考虑到大多数Agent(经纪人)没有常用邮箱,本期找回密码统一通过短信验证码实现,废弃邮箱找回方式。账号中 `email` 字段在本系统无任何必须业务用途,完全可选。 **验收标准**: -- [ ] 点击登录界面「忘记用户名」链接,跳转至「找回用户名」页面(或弹窗) -- [ ] 找回方式(本期以邮箱为主,手机号为预留字段): - - 邮箱找回:输入注册邮箱,系统校验邮箱是否与已知账号匹配,匹配成功则发送包含用户名的邮件至该邮箱 - - 手机号找回(预留,UI 入口以「即将开放」禁用态展示) -- [ ] 邮箱输入框:格式校验(包含「@」和域名),错误时提示「请输入有效的邮箱地址」 -- [ ] 点击「发送」后: - - 邮箱存在且已绑定账号 → 显示「用户名已发送至您的邮箱,请查收」;发送按钮进入 60 秒倒计时不可重复点击 - - 邮箱不存在 → **不提示「邮箱未注册」**(防止用户信息枚举),统一显示「如该邮箱已绑定账号,您将收到一封包含用户名的邮件」 -- [ ] 邮件内容:纯文本邮件,包含用户名、发送时间,及「如非本人操作请联系管理员」说明 -- [ ] 发送频率限制:同一邮箱 1 小时内最多发送 3 次 -- [ ] 提供「返回登录」链接 +- [ ] 点击登录界面「忘记密码」链接,跳转至「找回密码」流程(Stepper 分步页面,共三步) + +**步骤一:输入手机号** + +- [ ] 页面显示:手机号输入框(11 位数字,自动过滤非数字)、「获取验证码」按钮、「返回登录」链接 +- [ ] 手机号为空或不足 11 位 → 点击「获取验证码」时在输入框下方提示「请输入完整的 11 位手机号」 +- [ ] 手机号格式合法后,点击「获取验证码」,按钮进入 60 秒倒计时冷却态(「重新获取(59s)」),倒计时结束后按钮恢复可点击 +- [ ] 服务端收到请求后: + - 若该手机号**存在**且账号状态为 `active`:向该号码发送 6 位数字短信验证码,有效期 **10 分钟** + - 若手机号**不存在**或账号已停用:页面统一提示「如该手机号已注册,验证码将在 1 分钟内发送」(**不泄露账号是否存在**) +- [ ] 同一手机号 1 小时内最多发送 **5 次**短信验证码,超限后提示「发送次数过多,请 1 小时后再试」 +- [ ] 短信内容模板:「【Fonrey 房睿】您的密码重置验证码为 {code},10 分钟内有效,请勿泄露。」 + +**步骤二:输入短信验证码** + +- [ ] 页面显示:6 位验证码输入框(支持分格输入)、「重新发送」倒计时链接、「下一步」按钮 +- [ ] 「下一步」按钮:6 位验证码全部输入后方可点击 +- [ ] 服务端校验验证码: + - 正确且未过期 → 进入步骤三,颁发一次性 `sms_reset_token`(有效期 15 分钟,一次性,服务端存储) + - 错误 → 提示「验证码有误,请重新输入」,错误次数 ≥ 5 次则本次验证码作废,需重新获取 + - 已过期 → 提示「验证码已过期,请重新获取」 + +**步骤三:重置密码** + +- [ ] 步骤三依赖步骤二颁发的 `sms_reset_token`(通过 URL 参数或会话状态传递),Token 无效或过期 → 显示「操作已超时,请重新发起找回密码」,跳回步骤一 +- [ ] **本页面复用「设置新密码」公共组件**(与首次登录强制修改密码页面为同一组件,详见 §5.3.4),保持 UI 与交互逻辑完全一致;入口上下文不同时,仅页面标题和提示文案有所差异: + +| 元素 | 首次登录强制修改(§5.3.4) | 找回密码步骤三(本 Story) | +|------|--------------------------|--------------------------| +| 页面标题 | 「欢迎使用 Fonrey,请先设置您的登录密码」 | 「重置您的登录密码」 | +| 提示文案 | 「您当前使用的是初始密码,为保障账号安全,请立即设置新密码后开始使用」 | 「请输入您的新密码,设置完成后请使用新密码重新登录」 | +| 提交按钮文案 | 「确认并进入系统」 | 「确认重置密码」 | +| 提交后跳转 | `is_initial_password = False`,Session 保持,直接进入首页 | 所有 Session 立即失效,跳转登录界面并提示「密码已重置,请使用新密码登录」 | + +- [ ] 提交成功后:`is_initial_password` 置为 **`False`**(找回密码属于用户主动操作,已完成身份核验,无需再触发强制修改流程) + > **注意**:与首次登录流程不同,找回密码时用户已通过短信验证码完成了身份核验,本次密码设置即视为"用户本人主动设置",不应再触发 `is_initial_password = True` 的二次强制修改。 --- -### Story 4:经纪人找回密码 +### Story 4:经纪人找回用户名(已废弃) -**As** 忘记密码的经纪人,**I want** 通过已知用户名 + 绑定邮箱(或手机号)自助重置密码,**So that** 不依赖管理员也能快速恢复登录。 +> **状态**:已废弃。普通员工用户名固定为手机号,无需找回;Tenant Admin 如忘记用户名,请联系平台运营线下处理。本 Story 保留占位以维持版本记录,实现时跳过此 Story。 + +--- + +### Story 5:手机验证码登录(MVP 实现) + +**As** 已有账号的经纪人,**I want** 通过手机号 + 短信验证码直接登录,**So that** 在忘记密码或不想输入密码时,仍能快速进入系统。 + +> **说明**:短信基础设施(`sms_otp_records` 表、OTP 发送/校验逻辑)已在 Story 3 找回密码中建设完成,本 Story 直接复用,实现成本极低。登录界面提供「密码登录」和「验证码登录」两个并列入口,用户自由切换,两种方式均为 MVP 正式功能。 **验收标准**: -- [ ] 点击登录界面「忘记密码」链接,跳转至「找回密码」流程(分步骤页面或 Stepper 组件) +- [ ] 登录界面提供两种登录方式的切换 Tab:**「密码登录」**(默认选中)和 **「验证码登录」** +- [ ] 切换 Tab 时,输入区域平滑切换,已填内容清空,滑块验证状态重置 -**步骤一:身份验证** +**「验证码登录」界面元素**: +- [ ] 手机号输入框(规格同 Story 2,11 位数字,自动过滤非数字) +- [ ] 验证码输入框(6 位数字分格输入)+ 「获取验证码」按钮(60 秒倒计时冷却态) +- [ ] 滑块拼图验证区域(规格同 Story 2,**先通过滑块验证,再允许点击「获取验证码」**) +- [ ] 「登录」按钮(手机号 + 验证码均填写后方可点击) -- [ ] 用户输入:用户名 + 邮箱(本期);手机号找回为预留入口(禁用态) -- [ ] 服务端校验用户名与邮箱是否匹配,不泄露具体原因(统一提示「如信息匹配,重置链接将发送至您的邮箱」) -- [ ] 校验通过后,向绑定邮箱发送含一次性重置链接的邮件;链接有效期 **30 分钟**,使用后立即失效 -- [ ] 同一账号 1 小时内最多发送 3 次重置邮件 +**获取验证码逻辑**: +- [ ] 用户须先完成滑块验证,「获取验证码」按钮方可点击;未完成滑块时点击 → 提示「请先完成滑块验证」 +- [ ] 点击「获取验证码」后,服务端: + - 手机号格式不合法 → 前端拦截,提示「请输入完整的 11 位手机号」 + - 手机号存在且状态 `active` → 发送 6 位 OTP,有效期 **5 分钟**,存入 `sms_otp_records`(`scene = 'login'`) + - 手机号不存在或已停用 → 统一响应「如该手机号已注册,验证码将在 1 分钟内发送」(防止枚举攻击) +- [ ] 同一手机号 1 小时内最多发送 **10 次**登录验证码(找回密码为独立计数,两者不共享限额);超限后提示「发送次数过多,请 1 小时后再试」 +- [ ] 短信内容模板:「【Fonrey 房睿】您的登录验证码为 {code},5 分钟内有效,请勿泄露。」 -**步骤二:重置密码** +**登录校验逻辑**: +- [ ] 点击「登录」,服务端校验 OTP: + - 正确且未过期 → 登录成功,后续行为与 Story 2 密码登录完全一致(含 `is_initial_password` 判断) + - 错误 → 提示「验证码有误,请重新输入」;连续错误 ≥ 5 次 → 本次 OTP 作废,提示「验证码已失效,请重新获取」 + - 已过期 → 提示「验证码已过期,请重新获取」 +- [ ] **账号被锁定**(密码登录失败次数触发):验证码登录仍受账号锁定限制,锁定期间无法通过任何方式登录,提示「账号已被临时锁定,请 30 分钟后重试,或联系管理员解锁」 + > **设计说明**:账号锁定是账号维度的安全策略,不区分登录方式;否则锁定形同虚设。 +- [ ] **账号已停用**:提示「账号已停用,请联系您的管理员」 -- [ ] 用户点击邮件中的链接,跳转至「重置密码」页面(链接含加密 Token,服务端校验 Token 有效性) -- [ ] Token 无效或已过期 → 显示「链接已过期或已使用,请重新申请」,提供「重新申请」按钮 -- [ ] 页面包含:新密码输入框、确认新密码输入框 -- [ ] **密码复杂度规则**(符合安全基线): - - 长度 8 ~ 32 位 - - 必须包含字母(区分大小写)和数字 - - 建议包含特殊符号(非强制,但页面提示推荐) - - 不得与最近 3 次历史密码相同 -- [ ] 两次密码输入不一致 → 提示「两次密码输入不一致」 -- [ ] 不符合复杂度 → 实时提示具体不满足的规则(逐条校验,红色 × / 绿色 ✓ 视觉指引) -- [ ] 提交成功 → 显示「密码已重置,请使用新密码登录」,自动跳转至登录界面;原所有 Session 立即失效(强制重新登录) - ---- - -### Story 5:预留——手机验证码登录(接口预留,v2 实现) - -**As** 绑定了手机号的经纪人,**I want** 通过手机号 + 短信验证码快速登录,**So that** 在忘记密码时仍能正常登录系统。 - -**当前状态**:本期 UI 入口以「即将开放」禁用态展示于登录界面,接口定义预留,不开放实际功能。 - -**预留接口设计**(供后端提前规划): +**接口规范**: ``` POST /api/auth/login/phone/ -Request: { phone: string, sms_code: string, tenant_id: string } -Response: { token: string, user: {...} } | { error: string } +Request: { phone: string, sms_code: string } +Response: { token: string, is_initial_password: bool, user: {...} } | { error_code: string, message: string } ``` -**绑定条件**(v2 实现时的前置要求): -- 手机号必须先在「个人设置」中与用户名账号完成绑定并通过验证 -- 一个手机号只能绑定一个用户名账号(同一租户内) -- 绑定手机号后,可通过手机号 + 短信验证码联合登录 - --- ### Story 6:预留——微信扫码登录(接口预留,v2 实现) @@ -221,9 +253,9 @@ POST /api/auth/wechat/callback/ # 微信扫码确认后回调,换取系 ``` 客户端启动 │ - ├─ 本地有 Tenant ID 缓存? + ├─ 本地有 Tenant Code 缓存? │ │ - │ YES ──→ 校验缓存 Tenant ID 是否仍有效(服务端 validate) + │ YES ──→ 校验缓存 Tenant Code 是否仍有效(服务端 validate) │ │ │ 有效 ──→ 直接进入登录界面 │ │ @@ -231,33 +263,33 @@ POST /api/auth/wechat/callback/ # 微信扫码确认后回调,换取系 │ └─ NO ──→ 显示 Tenant 识别界面 │ - 用户输入 Tenant ID → 发起验证 + 用户输入 Tenant Code → 发起验证 │ - 验证成功 ──→ 缓存 Tenant ID → 进入登录界面 + 验证成功 ──→ 缓存 Tenant Code → 进入登录界面 │ 验证失败 ──→ 显示错误信息,保持识别界面 ``` #### 5.1.2 Tenant 识别界面规范 -| 元素 | 规格 | -|------|------| -| 页面背景 | 品牌色渐变(与登录界面保持一致的视觉风格) | -| Logo | Fonrey 产品 Logo,居中显示 | -| 标题 | 「欢迎使用 Fonrey 房睿」 | -| 副标题 | 「请输入您公司的专属识别码以继续」 | -| Tenant ID 输入框 | 单行数字输入,固定 12 位,支持粘贴;非数字字符自动过滤,超出 12 位截断 | -| 输入框 Label | 「公司识别码(Tenant ID)」 | -| 确认按钮 | 主色调按钮,文字「确认」 | -| 错误提示 | 输入框下方红色文字,固定区域占位(不影响布局抖动) | -| 帮助文案 | 「不知道识别码?请联系您公司的系统管理员」 | +| 元素 | 规格 | +| ------------- | --------------------------------------- | +| 页面背景 | 品牌色渐变(与登录界面保持一致的视觉风格) | +| Logo | Fonrey 产品 Logo,居中显示 | +| 标题 | 「欢迎使用 Fonrey 房睿」 | +| 副标题 | 「请输入您公司的专属识别码以继续」 | +| Tenant Code 输入框 | 单行数字输入,固定 12 位,支持粘贴;非数字字符自动过滤,超出 12 位截断 | +| 输入框 Label | 「公司识别码(Tenant Code)」 | +| 确认按钮 | 主色调按钮,文字「确认」 | +| 错误提示 | 输入框下方红色文字,固定区域占位(不影响布局抖动) | +| 帮助文案 | 「不知道识别码?请联系您公司的Tenant Admin(租户管理员)」 | -#### 5.1.3 Tenant ID 格式规范 +#### 5.1.3 Tenant Code 格式规范 - **格式**:固定 **12 位纯数字**,如 `202500010001` - **生成规则**(建议):由平台运营在系统管理后台开通租户时自动生成,不允许手动指定,确保全局唯一性;可采用时间戳前缀 + 随机后缀的方式生成(如 `YYYYMM` + 6 位随机数) - **前端校验**:输入框仅接受数字字符(非数字自动过滤),输入满 12 位后自动触发格式完成状态;少于 12 位时点击「确认」弹出提示「识别码须为 12 位数字」 -- **唯一性**:全局唯一(公共 Schema 层面),同一 Tenant ID 不可分配给多个租户 +- **唯一性**:全局唯一(公共 Schema 层面),同一 Tenant Code 不可分配给多个租户 - **客户端存储**:Electron `app.getPath('userData')` 目录下的配置文件(加密存储,防止明文读取) #### 5.1.4 服务端 Tenant 验证接口规范 @@ -267,7 +299,7 @@ POST /api/auth/tenant/verify/ Request Body: { - "tenant_id": "202500010001" + "tenant_code": "202500010001" } Response 200 (成功): @@ -294,31 +326,48 @@ Response 200 (失败): #### 5.2.1 界面布局 +登录界面顶部以 **Tab 切换**区分两种登录方式(「密码登录」默认选中),Tab 下方的表单区随当前选中 Tab 动态切换,微信扫码作为独立的「其他登录」保持禁用。 + ``` ┌─────────────────────────────────────────┐ │ [租户 Logo] [租户公司名称] │ ← 顶部品牌区(Tenant 识别后回填) │ │ +│ ┌──────────────┬──────────────────┐ │ +│ │ 密码登录 ✓ │ 验证码登录 │ │ ← 登录方式 Tab,默认选中「密码登录」 +│ └──────────────┴──────────────────┘ │ +│ │ +│ ── 密码登录 Tab(默认展示)─────────── │ │ ┌───────────────────────┐ │ -│ │ 用户名 │ │ +│ │ 手机号 │ │ │ └───────────────────────┘ │ │ ┌───────────────────────┐ │ │ │ 密码 👁 │ │ │ └───────────────────────┘ │ │ ┌─────────────────────────────────┐ │ │ │ [背景图 + 拼图缺口] 🔄 │ │ ← 右上角刷新图标 -│ │ │ │ -│ │ [拼图碎片] │ │ -│ │ ├────────────────────────────── │ │ -│ │ ◀ 拖动滑块完成拼图 ▶ │ │ +│ │ [拼图碎片] ◀ 拖动滑块完成拼图 ▶│ │ │ └─────────────────────────────────┘ │ │ ┌───────────────────────┐ │ │ │ 登 录 │ │ ← 主 CTA,橙色 │ └───────────────────────┘ │ +│ 忘记密码 │ ← 文字链接(忘记用户名入口已废弃) │ │ -│ 忘记用户名 忘记密码 │ ← 次级入口,文字链接 +│ ── 验证码登录 Tab(切换后展示)──────── │ +│ ┌───────────────────────┐ │ +│ │ 手机号 │ │ +│ └───────────────────────┘ │ +│ ┌─────────────────────────────────┐ │ +│ │ [拼图验证] ← 先完成验证,再获取 │ │ ← 验证码登录下滑块前置 +│ └─────────────────────────────────┘ │ +│ ┌──────────────────┐ ┌─────────────┐ │ +│ │ 验证码(6 位) │ │ 获取验证码 │ │ ← 通过滑块后按钮可点击;60s 冷却 +│ └──────────────────┘ └─────────────┘ │ +│ ┌───────────────────────┐ │ +│ │ 登 录 │ │ +│ └───────────────────────┘ │ +│ 忘记密码 │ │ │ │ ─────────────── 其他登录 ──────────────│ -│ [手机验证码登录 - 即将开放] │ ← 禁用态,灰色 │ [微信扫码登录 - 即将开放] │ ← 禁用态,灰色 │ │ │ 切换公司 │ ← 底部,小字链接 @@ -335,7 +384,7 @@ Response 200 (失败): | 验证码有效期 | 单次验证会话有效,提交登录后服务端 Token 立即失效;超过 3 分钟未操作需重新加载 | | 验证失败处理 | 拼图区域抖动动画提示,自动刷新新背景图;**不计入账号密码错误次数**(行为验证失败属独立事件) | | 密码错误锁定 | 同一账号连续密码错误 ≥ 5 次,锁定 30 分钟;解锁方式:等待超时自动解锁 或 管理员手动解锁 | -| 密码错误计数 | 计数存于 Redis,Key 格式:`login_fail:tenant_id:username`,TTL 30 分钟 | +| 密码错误计数 | 计数存于 Redis,Key 格式:`login_fail:tenant_id:phone`(phone 即用户名/手机号),TTL 30 分钟 | | 验证码刷新 | 登录失败(用户名/密码错误)后自动刷新拼图;用户亦可主动点击「刷新」图标重新加载背景图 | | HTTPS | 所有登录相关请求强制 HTTPS,不允许 HTTP 降级 | | 密码传输 | 前端不做密码加密,HTTPS 层保证传输安全;后端存储使用 `django.contrib.auth` 默认的 `PBKDF2+SHA256` 哈希 | @@ -355,18 +404,19 @@ Response 200 (失败): 系统内共有两类账号创建场景,权限和规则各不相同: -**① Tenant Admin 账号(每个租户唯一的超级管理账号)** +**② Tenant Admin 账号(每个租户的超级管理账号)** -| 项目 | 规格 | -|------|------| -| 创建时机 | 平台运营在系统管理后台开通租户时,同步创建第一个 Tenant Admin 账号 | -| 用户名 | **由平台运营自定义设置**,格式:英文字母开头,仅含字母/数字/下划线,6~30 字符,同租户内唯一 | -| 初始密码 | **由平台运营自定义设置**,须符合密码复杂度规则(8~32 位,含字母+数字) | -| 首次登录 | 强制修改初始密码,不可跳过 | -| 权限范围 | 拥有该租户内最高权限,可管理员工账号、角色、系统设置等 | -| 数量限制 | 每个租户仅限 1 个 Tenant Admin 账号(后续可扩展为多管理员,v2 规划) | +| 项目 | 规格 | +| ---- | ------------------------------------------------------------ | +| 创建时机 | 平台运营在系统管理后台开通租户时,系统**自动**以该租户联系人手机号创建 Tenant Admin 账号,无需手动设置 | +| 用户名 | **固定为该租户联系人的手机号**(11 位数字),全局唯一,创建后不可更改 | +| 初始密码 | **系统统一固定初始密码**(与普通员工相同,由平台在部署配置中设定,如 `Fonrey@2025`) | +| 首次登录 | 强制修改初始密码,不可跳过 | +| 权限范围 | 拥有该租户内最高权限,可管理员工账号、角色、系统设置等 | +| 数量限制 | 每个租户仅限 1 个 Tenant Admin 账号(后续可扩展为多管理员,v2 规划) | +| 数据来源 | 联系人手机号来自 `public.tenants.contact_phone` 字段,开通租户时由平台运营录入,必填 | -**② 普通员工账号(经纪人、店长、行政等)** +**① 普通员工账号(经纪人、店长、行政等)** | 项目 | 规格 | |------|------| @@ -381,10 +431,10 @@ Response 200 (失败): | 字段 | 类型 | Tenant Admin | 普通员工账号 | 说明 | |------|------|-------------|-------------|------| -| 用户名(username) | CharField(30) | 平台运营自定义,字母开头,含字母/数字/下划线,6~30 字符 | **固定为员工手机号**(11 位数字) | 登录 ID,创建后不可更改 | -| 密码(password) | CharField | 平台运营自定义初始密码 | **系统统一固定初始密码** | PBKDF2+SHA256 哈希存储 | -| 手机号(phone) | CharField(11) | 选填,加密存储 | **必填,同时作为用户名**,加密存储,同租户内唯一 | 当前阶段为登录 ID;v2 启用手机验证码登录后复用此字段 | -| 邮箱(email) | EmailField | 选填,同租户唯一 | 选填,同租户唯一 | 用于找回密码;若为空则无法自助找回 | +| 用户名(username) | CharField(30) | **固定为联系人手机号**(11 位数字) | **固定为员工手机号**(11 位数字) | 登录 ID,创建后不可更改;两类账号规则统一 | +| 密码(password) | CharField | **系统统一固定初始密码** | **系统统一固定初始密码** | PBKDF2+SHA256 哈希存储;首次登录强制修改 | +| 手机号(phone) | CharField(11) | **必填,同时作为用户名**,来源于 `public.tenants.contact_phone` | **必填,同时作为用户名**,加密存储,同租户内唯一 | 两类账号均用手机号登录,v2 启用手机验证码后复用此字段 | +| 邮箱(email) | EmailField | 选填,同租户唯一 | 选填,同租户唯一 | 在本系统无必须业务用途,完全可选;普通员工忘记密码通过手机短信验证码自助找回,**与邮箱无关** | | 员工档案关联(staff_id) | OneToOneField → `org.Staff` | 可选关联(平台运营账号) | 必须关联 | 实名绑定 | | 账号状态(status) | CharField | `active` / `disabled` / `locked` | `active` / `disabled` / `locked` | locked 为密码错误锁定,30 分钟自动恢复 | | 初始密码标记(is_initial_password) | BooleanField | True(首次登录前) | True(首次登录前) | True 时登录成功后强制跳转修改密码页 | @@ -411,109 +461,84 @@ Response 200 (失败): --- -### 5.4 找回流程详细说明 +### 5.4 找回密码详细说明 -#### 5.4.1 找回用户名流程 +> **说明**:Story 4「找回用户名」已废弃。普通员工用户名固定为手机号,无需找回;Tenant Admin 如忘记用户名请联系平台运营线下处理。 -> **说明**:由于普通员工的用户名即为其**手机号**,通常无需「找回用户名」功能。登录界面的「忘记用户名」入口保留,但仅对 Tenant Admin 账号有意义(其用户名为自定义字符串)。 - -``` -用户点击「忘记用户名」 - │ - ├─ 普通员工:提示「您的登录账号为您的手机号,请直接使用手机号登录」 - │ 提供「返回登录」按钮 - │ - └─ Tenant Admin(用户名非手机号格式): - │ - ├─ 输入绑定邮箱 - │ │ - │ 服务端查询(不向前端返回查询结果,防止枚举) - │ │ - │ 统一响应「如该邮箱已绑定账号,您将收到邮件」 - │ │ - │ 后台:邮箱存在 → 发送邮件(包含用户名) - │ 邮箱不存在 → 静默处理 - │ - └─ 用户查收邮件,获取用户名 → 返回登录 -``` -![[找回用户名流程.png]] -> **前端识别逻辑**:用户在「忘记用户名」页面输入邮箱提交后,服务端根据是否匹配到 Tenant Admin 账号决定处理路径,前端无需区分,统一展示「如该邮箱已绑定账号,您将收到邮件」。 - -**邮件模板(找回用户名)**: - -``` -主题:您的 Fonrey 房睿用户名 - -您好, - -您请求找回在 [公司名称] 的 Fonrey 账号用户名。 - -您的用户名为:{username} - -如果这不是您的操作,请忽略此邮件。如有疑问,请联系您的系统管理员。 - -此邮件由系统自动发送,请勿回复。 -发送时间:{datetime} -``` - -#### 5.4.2 找回密码流程 +#### 5.4.1 找回密码流程 ``` 用户点击「忘记密码」 │ -步骤1:身份验证 +步骤1:输入手机号 │ - ├─ 输入手机号(即用户名)+ 绑定邮箱 - │ (Tenant Admin 则输入自定义用户名 + 绑定邮箱) + ├─ 输入 11 位手机号,点击「获取验证码」 │ │ - │ 服务端校验用户名与邮箱是否匹配 + │ 服务端校验手机号是否存在且状态为 active │ │ - │ 统一响应「如信息匹配,重置链接将发送至您的邮箱」(防止枚举) + │ 统一响应「如该手机号已注册,验证码将在 1 分钟内发送」(防止枚举) │ │ - │ 后台:匹配成功 → 生成加密 Token(有效期 30min)→ 异步发送邮件 - │ 不匹配 → 静默处理 + │ 后台:存在且 active → 生成 6 位 OTP,有效期 10 分钟,存入 sms_otp_records → 发送短信 + │ 不存在或已停用 → 静默处理 │ -步骤2:用户点击邮件中的重置链接 +步骤2:输入短信验证码 │ - ├─ 服务端校验 Token 有效性 + ├─ 输入 6 位验证码,点击「下一步」 │ │ - │ 有效 → 展示「重置密码」表单 + │ 服务端校验 OTP: │ │ - │ 无效/过期 → 提示「链接已过期,请重新申请」,提供「重新申请」按钮 + │ 正确且未过期 → 颁发一次性 sms_reset_token(有效期 15 分钟)→ 进入步骤3 + │ │ + │ 错误(累计 < 5 次)→ 提示「验证码有误,请重新输入」 + │ 错误(累计 ≥ 5 次)→ 提示「验证已失败,请重新获取验证码」,本次 OTP 作废 + │ 已过期 → 提示「验证码已过期,请重新获取」 │ -步骤3:用户输入并提交新密码 +步骤3:重置密码 │ - ├─ 密码复杂度校验(≥ 8 位,含字母+数字) - ├─ 与历史密码对比校验(最近 3 次,含固定初始密码) + ├─ 页面携带 sms_reset_token,服务端校验有效性 + │ │ + │ 无效/过期 → 提示「操作已超时,请重新发起找回密码」,跳回步骤1 + │ │ + ├─ 用户输入新密码 + 确认新密码,实时逐条校验复杂度规则(✓/✗) │ - └─ 校验通过 → 更新密码,is_initial_password = False - → 清除该账号所有有效 Session(强制重新登录) - → 跳转登录界面,提示「密码已重置,请重新登录」 -``` -![[找回密码流程.png]] -> **注意**:找回密码流程依赖员工账号绑定了邮箱。若员工未绑定邮箱,无法自助找回,需联系 Tenant Admin 在管理界面执行「重置密码」操作,将密码恢复为固定初始密码。 - -**邮件模板(重置密码)**: - -``` -主题:重置您的 Fonrey 房睿密码 - -您好, - -我们收到了重置您在 [公司名称] 的 Fonrey 账号密码的请求。 - -请点击以下链接重置密码(链接 30 分钟内有效): -{reset_link} - -如果您未发起此请求,请忽略此邮件,您的密码不会被更改。 - -此邮件由系统自动发送,请勿回复。 -发送时间:{datetime} + └─ 提交成功 + → 更新密码,is_initial_password = False + → 清除该账号所有有效 Session(强制重新登录) + → 跳转登录界面,提示「密码已重置,请使用新密码登录」 ``` --- -### 5.5 后端数据模型设计 +### 5.5 手机验证码登录详细说明 + +> 本节为 Story 5 的实现规范补充。短信基础设施(`sms_otp_records` 表、OTP 发送/校验逻辑)在 Story 3 找回密码中已建设完成,本节描述在**登录场景**下复用该基础设施时的关键差异点。 + +**与找回密码短信逻辑的差异对比**: + +| 维度 | 找回密码(Story 3) | 验证码登录(Story 5) | +|------|-------------------|---------------------| +| `scene` 字段 | `password_reset` | `login` | +| OTP 有效期 | 10 分钟 | 5 分钟 | +| 每小时发送上限 | 5 次 | 10 次 | +| 验证成功后动作 | 颁发 `sms_reset_token` → 步骤三重置密码 | 直接颁发 Session Token,登录成功 | +| 短信文案 | 「密码重置验证码」 | 「登录验证码」 | +| 账号锁定影响 | 不受密码错误锁定限制(非密码登录路径) | **受账号锁定限制**(账号维度安全策略,不区分方式)| + +**滑块验证前置规则**(验证码登录特有): + +- 用户须先完成滑块拼图验证,「获取验证码」按钮方可点击 +- 滑块验证通过后,拼图区域保持「验证通过」状态,不需要在点击「登录」前再次验证 +- 切换 Tab 时,滑块验证状态重置(须重新完成验证后方可获取验证码) + +**`sms_otp_records` 表复用说明**: + +- 不新建表,复用 `DATA_MODEL_LOGIN.md` 中定义的 `sms_otp_records` +- `scene` 字段区分场景:`login` / `password_reset`,各自独立限流计数 +- 同一手机号同一 scene 同一时间只有一条有效 OTP;新发送时将旧记录标记为 `used` + +--- + +### 5.6 后端数据模型设计 > **数据模型已迁移至独立文档**,请参阅: > **`Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md`** @@ -521,7 +546,7 @@ Response 200 (失败): 该文档包含: - `user_accounts` 账号主表(完整字段定义、约束、索引、Django Model 代码) - `login_attempts` 登录审计表 -- `password_reset_tokens` 密码重置令牌表 +- `sms_otp_records` 短信验证码记录表(找回密码 + 验证码登录共用) - `password_histories` 历史密码记录表 - Redis 缓存结构说明 - 账号状态机与创建流程 @@ -531,13 +556,13 @@ Response 200 (失败): --- -### 5.6 Electron 客户端登录相关约定 +### 5.7 Electron 客户端登录相关约定 | 约定项 | 规格 | |--------|------| -| Tenant ID 存储 | `electron-store` 或 `app.getPath('userData')` + AES 加密,不存储明文 | +| Tenant Code 存储 | `electron-store` 或 `app.getPath('userData')` + AES 加密,不存储明文 | | Session Token 存储 | 内存(`global` 变量)+ `session` Cookie(Chromium 管理),不写入磁盘明文文件 | -| 登录页加载 | 客户端主进程根据 Tenant ID 构建目标 URL(`https://{tenant_slug}.fonrey.com/auth/login/`),通过 `BrowserWindow.loadURL()` 加载 | +| 登录页加载 | 客户端主进程根据 Tenant Code 构建目标 URL(`https://{tenant_slug}.fonrey.com/auth/login/`),通过 `BrowserWindow.loadURL()` 加载 | | 多标签页处理 | 同一 `BrowserWindow` 内,所有页面共享同一 Session Cookie | | 客户端登出 | 调用服务端 `POST /api/auth/logout/` 使服务端 Session 失效 + 清除 Chromium Session Cookie | | 窗口关闭时 | Session 保留(不自动登出),下次打开客户端时若 Session 未过期,直接进入系统 | @@ -553,8 +578,9 @@ Response 200 (失败): |--------|------|------| | `django.contrib.auth` | 用户认证基础框架 | 扩展 `AbstractBaseUser` 而非直接使用 `User` 模型,以支持 `username` 唯一性约束在租户维度而非全局 | | `django-tenants` | 多租户隔离 | `UserAccount` 属于租户级 Schema,Tenant 验证接口属于 `shared_apps` | -| `Redis` | 滑块验证 Token 存储、登录失败计数、密码重置 Token 缓存 | 验证 Key:`captcha_token:{uuid}`(TTL 3min);登录失败 Key:`login_fail:{tenant_id}:{username}` | -| `Celery` | 发送找回邮件 | 邮件发送异步处理,防止接口响应超时 | +| `Redis` | 滑块验证 Token 存储、登录失败计数、短信 OTP 限流计数 | 验证 Key:`captcha_token:{uuid}`(TTL 3min);登录失败 Key:`login_fail:{tenant_id}:{username}`;OTP 限流 Key:`sms_limit:{scene}:{phone}`(TTL 1h)| +| 短信服务(待选型) | 发送登录验证码 / 找回密码验证码 | 国内需选用具备短信资质的服务商(如阿里云短信、腾讯云短信);需申请短信签名和模板审核 | +| `Celery` | 异步任务处理 | 短信发送异步处理,防止接口响应超时;原邮件发送需求已废弃,短信为主要通知方式 | | `django-ratelimit` 或自定义中间件 | 接口限流 | Tenant 验证接口、登录接口、找回密码接口均需限流 | | `Pillow` | 滑块拼图图片处理 | 生成拼图背景图(抠出缺口区域)及对应的拼图碎片图片,输出为 Base64,分别通过两个字段返回给前端 | @@ -569,17 +595,17 @@ Response 200 (失败): | 风险 | 可能性 | 影响 | 缓解措施 | |------|--------|------|---------| | 滑块验证被机器模拟轨迹绕过 | 低 | 高 | 服务端同时校验位置偏差 + 轨迹曲线特征(非线性运动特征),拒绝匀速/程序化轨迹;后续可引入设备指纹加固 | -| Tenant ID 枚举攻击(暴力试探) | 低 | 中 | Tenant 验证接口限流(每IP每分钟≤10次),返回结果不区分「未找到」与「已禁用」| -| 密码重置 Token 泄露 | 低 | 高 | Token 单次有效、30分钟过期、HTTPS 传输 | -| 邮件发送失败导致用户无法找回密码 | 中 | 中 | 邮件发送失败写入告警日志,管理员可通过后台查看 Token 手动告知用户 | +| Tenant Code 枚举攻击(暴力试探) | 低 | 中 | Tenant 验证接口限流(每IP每分钟≤10次),返回结果不区分「未找到」与「已禁用」| +| 密码重置 Token 泄露 | 低 | 高 | `sms_reset_token` 单次有效、15 分钟过期、HTTPS 传输 | +| 短信服务故障导致用户无法找回密码或验证码登录 | 中 | 高 | 短信发送失败写入告警日志;密码登录作为保底方式(非单一入口);建议配置备用短信服务商通道 | | 多端同时登录同一账号 | 高(日常场景) | 低 | 本期允许,后续如需踢出,可在 Token 机制中引入版本号 | ### 6.4 开放问题(开发前需确认) -- [ ] **邮件服务商选型**:使用 SendGrid / 阿里云邮件推送 / SMTP 自建?需运维确认 — 负责人:后端负责人 — 截止:开发启动前 +- [ ] **短信服务商选型**:使用阿里云短信 / 腾讯云短信 / 其他服务商?需运维确认并提前申请短信签名和模板审核(国内审核周期 1–3 个工作日)— 负责人:后端负责人 — 截止:开发启动前 - [ ] **Session 有效期默认值**:8 小时是否满足各租户需求?是否允许租户管理员自行配置?— 负责人:产品经理 — 截止:开发启动前 - [ ] **滑块拼图实现方案**:自研(Pillow 生成图片 + 前端拖拽组件)还是集成第三方行为验证服务(如极验 GeeTest / 网易易盾)?自研可控但需维护图库;第三方开箱即用但引入外部依赖,需评估数据合规要求 — 负责人:后端负责人 + 安全 — 截止:开发启动前 -- [ ] **账号锁定通知**:账号被锁定后,是否自动发邮件通知用户和/或管理员?— 负责人:产品经理 — 截止:开发启动前 +- [ ] **账号锁定通知**:账号被锁定后,是否自动发短信通知用户和/或通知管理员(站内消息)?— 负责人:产品经理 — 截止:开发启动前 - [ ] **历史密码校验范围**:最近 3 次是否足够?是否需要额外规则(如不能与用户名相同)?— 负责人:产品经理 — 截止:开发启动前 --- @@ -602,7 +628,7 @@ Response 200 (失败): ``` [未识别 Tenant] - │ 输入有效 Tenant ID + │ 输入有效 Tenant Code ↓ [未登录] │ 账密登录成功 @@ -625,24 +651,20 @@ Response 200 (失败): | 接口 | 方法 | Schema 位置 | 是否需要鉴权 | 说明 | |------|------|------------|------------|------| -| `/api/auth/tenant/verify/` | POST | Public(shared) | 否 | Tenant ID 验证 | +| `/api/auth/tenant/verify/` | POST | Public(shared) | 否 | Tenant Code 验证 | | `/api/auth/captcha/` | GET | Tenant | 否 | 获取滑块拼图验证码(返回背景图 Base64 + 碎片图 Base64 + 验证 Token) | | `/api/auth/captcha/verify/` | POST | Tenant | 否 | 提交滑动轨迹 + 位置,服务端校验并返回一次性通过凭证(供登录接口使用) | -| `/api/auth/login/` | POST | Tenant | 否 | 账号密码登录 | +| `/api/auth/login/` | POST | Tenant | 否 | 手机号 + 密码登录 | +| `/api/auth/login/phone/` | POST | Tenant | 否 | 手机号 + 短信验证码登录(MVP 正式功能) | | `/api/auth/logout/` | POST | Tenant | 是 | 登出,使 Session 失效 | -| `/api/auth/recover/username/` | POST | Tenant | 否 | 发起找回用户名 | -| `/api/auth/recover/password/request/` | POST | Tenant | 否 | 发起找回密码(发送邮件) | +| `/api/auth/recover/password/request/` | POST | Tenant | 否 | 发起找回密码(发送短信验证码) | +| `/api/auth/recover/password/verify/` | POST | Tenant | 否 | 校验短信验证码,颁发一次性 `sms_reset_token` | | `/api/auth/recover/password/reset/` | POST | Tenant | 否(Token 鉴权) | 提交新密码 | -| `/api/auth/login/phone/` | POST | Tenant | 否 | **预留**,手机验证码登录 | -| `/api/auth/wechat/qrcode/` | GET | Tenant | 否 | **预留**,获取微信二维码 | -| `/api/auth/wechat/callback/` | POST | Tenant | 否 | **预留**,微信扫码回调 | +| `/api/auth/wechat/qrcode/` | GET | Tenant | 否 | **预留 v2**,获取微信二维码 | +| `/api/auth/wechat/callback/` | POST | Tenant | 否 | **预留 v2**,微信扫码回调 | ### 8.3 相关文档参考 -- 客户端发布管理模块 PRD:`Project/fonrey/PRD/发布管理/客户端发布管理模块PRD.md` -- 组织人事管理模块 PRD:`Project/fonrey/PRD/组织人事管理/组织人事管理模块PRD.md` -- 权限管理模块 PRD:`Project/fonrey/PRD/权限管理/权限管理模块PRD.md` -- 系统管理模块 PRD:`Project/fonrey/PRD/系统管理/系统管理模块PRD.md` - 技术栈文档:`Project/fonrey/TECH_STACK/TECH_STACK.md` - **登录管理数据模型**:`Project/fonrey/DATA_MODEL/DATA_MODEL_LOGIN.md` - **登录管理技术方案**:`Project/fonrey/TECH_STACK/登录管理技术方案.md` diff --git a/Project/fonrey/PRD/系统管理/系统管理模块PRD.md b/Project/fonrey/PRD/系统管理/系统管理模块PRD.md index 233086d6..29c46fd4 100644 --- a/Project/fonrey/PRD/系统管理/系统管理模块PRD.md +++ b/Project/fonrey/PRD/系统管理/系统管理模块PRD.md @@ -33,7 +33,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten | 角色 | 使用场景 | 频率 | | --------------------------- | ----------- | ------ | -| 超级管理员(Platform Super Admin) | 全局配置、高危操作授权 | 低频(每周) | +| Platform Admin(平台超级管理员)(Platform Super Admin) | 全局配置、高危操作授权 | 低频(每周) | | 运维人员(Ops Operator) | 日常租户管理、监控巡检 | 高频(每日) | | 只读审计员(Read-only Auditor) | 日志查询、合规报告导出 | 中频(每周) | @@ -97,13 +97,13 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten --- -### Persona B:超级管理员 David(系统升级与回滚) +### Persona B:Platform Admin(平台超级管理员) David(系统升级与回滚) > 负责平台技术运维,周期性执行版本升级,关注升级稳定性与租户影响面,有权执行所有高危操作。 **Story 4**:灰度系统升级 -> 作为超级管理员,我希望先对内测租户升级新版本,验证稳定后再全量推送,避免一次性影响所有客户。 +> 作为Platform Admin(平台超级管理员),我希望先对内测租户升级新版本,验证稳定后再全量推送,避免一次性影响所有客户。 **验收标准**: - [ ] 升级前自动执行健康检查,存在异常服务时阻断升级并提示 @@ -113,7 +113,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten **Story 5**:升级失败回滚 -> 作为超级管理员,我希望在升级出现问题时能立即回滚至上一稳定版本,并生成事件报告。 +> 作为Platform Admin(平台超级管理员),我希望在升级出现问题时能立即回滚至上一稳定版本,并生成事件报告。 **验收标准**: - [ ] 回滚操作触发前自动保存当前状态快照 @@ -177,7 +177,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten | 模式 | 说明 | |------|------| | 软删除(Soft Delete) | 标记删除状态,数据保留 30 天(默认,可配置)后由 Celery 定时任务清除 | -| 硬删除(Hard Delete) | 立即清除所有数据、Schema、存储资源及子域名授权;仅超级管理员可操作 | +| 硬删除(Hard Delete) | 立即清除所有数据、Schema、存储资源及子域名授权;仅Platform Admin(平台超级管理员)可操作 | 删除前置条件: 1. 操作人必须确认数据导出已完成(勾选确认框) @@ -264,7 +264,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten **Tenant Admin 管理** - 每个租户可设置 1 至多名 Tenant Admin(超级用户) -- 平台管理员可直接在后台创建新用户并赋予 Tenant Admin 角色,或从租户现有用户中指定 +- Platform Admin(平台超级管理员)可直接在后台创建新用户并赋予 Tenant Admin 角色,或从租户现有用户中指定 - 支持查看当前 Tenant Admin 列表,执行:新增 / 替换 / 撤销权限 **Tenant Admin 权限配置(RBAC)** @@ -282,7 +282,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten **密码重置** -- 平台管理员可为任意租户的任意用户发起密码重置 +- Platform Admin(平台超级管理员)可为任意租户的任意用户发起密码重置 - 方式一:发送重置链接至注册邮箱(用户自助重置) - 方式二:管理员直接设置临时密码(用户首次登录后强制修改) - 所有重置操作记录于操作审计日志 @@ -331,7 +331,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten **灰度升级策略**: -- 维护"内测租户组"列表,由超级管理员配置 +- 维护"内测租户组"列表,由Platform Admin(平台超级管理员)配置 - 灰度阶段仅对内测租户执行升级,其余租户保持原版本 - 内测租户验证通过(手动确认)后,触发全量升级 @@ -423,7 +423,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten **管理员设置** - 管理员账号管理(创建、编辑、停用) -- 角色配置(超级管理员 / 运营人员 / 只读审计员) +- 角色配置(Platform Admin(平台超级管理员) / 运营人员 / 只读审计员) - MFA 设置(强制启用,支持 TOTP) - IP 白名单配置 - 登录会话管理(查看活跃会话、强制登出) @@ -438,7 +438,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten | IP 白名单 | 仅允许指定 IP 范围访问管理控制台 URL(Nginx 层或应用层限制) | | 高危操作二次验证 | 删除租户、数据恢复、系统回滚操作触发 MFA 二次确认弹窗 | | 会话超时 | 无操作 30 分钟后自动登出,Token 失效 | -| 强制登出 | 超级管理员可在"管理员设置"中强制终止指定管理员的所有会话 | +| 强制登出 | Platform Admin(平台超级管理员)可在"管理员设置"中强制终止指定管理员的所有会话 | **与租户应用隔离**: @@ -546,7 +546,7 @@ Fonrey 是一套面向房产经纪公司的 B2B SaaS 平台,采用 `django-ten ### 9.2 管理员角色权限矩阵 -| 操作 | 超级管理员 | 运营人员 | 只读审计员 | +| 操作 | Platform Admin(平台超级管理员) | 运营人员 | 只读审计员 | |------|-----------|---------|-----------| | 创建租户 | ✅ | ✅ | ❌ | | 挂起 / 恢复租户 | ✅ | ✅ | ❌ | diff --git a/Project/fonrey/PRD/系统配置/系统配置参数数据.md b/Project/fonrey/PRD/系统配置/系统配置参数数据.md index ca387168..df12dc5d 100644 --- a/Project/fonrey/PRD/系统配置/系统配置参数数据.md +++ b/Project/fonrey/PRD/系统配置/系统配置参数数据.md @@ -277,7 +277,7 @@ | 相关方 | 相关方说明 | 状态 | 启动权限 | 操作 | | ------ | ------------------------------ | --- | ------------------------ | -------------- | -| 平台摄影师 | 开启平台实勘功能后,在房源预约拍摄完成后统一处理为系统管理员 | 停用 | | 权限配置 | +| 平台摄影师 | 开启平台实勘功能后,在房源预约拍摄完成后统一处理为Tenant Admin(租户管理员) | 停用 | | 权限配置 | | 维护人 | 出租或出售房源的维护人 | 停用 | | 权限配置 | | 售维护人 | 出售房源的维护人(租、售维护人分开时自动启用) | 停用 | | 权限配置 | | 租维护人 | 出租房源的维护人(租、售维护人分开时自动启用) | 停用 | | 权限配置 | diff --git a/Project/fonrey/PRD/系统配置/系统配置模块PRD.md b/Project/fonrey/PRD/系统配置/系统配置模块PRD.md index 6a743b25..37b5900d 100644 --- a/Project/fonrey/PRD/系统配置/系统配置模块PRD.md +++ b/Project/fonrey/PRD/系统配置/系统配置模块PRD.md @@ -50,12 +50,12 @@ ## 4. 目标用户 -**主要角色**:系统管理员(租户侧,每租户 1~3 人) +**主要角色**:Tenant Admin(租户管理员)(租户侧,每租户 1~3 人) > 典型画像:门店运营负责人或行政主管,熟悉业务流程,无技术背景,通过系统后台进行日常运营配置。使用频率:初始开通时高频(完成初始化配置),此后低频(按需调整)。 **间接受益角色**: -- 一线经纪人 — 看到的下拉选项和必填规则由管理员配置决定 +- Agent(经纪人) — 看到的下拉选项和必填规则由管理员配置决定 - 店长/经理 — 配置直接影响客源来源分析报表的数据质量 --- @@ -66,7 +66,7 @@ ### US-SETTING-001-A:管理员配置可选枚举值(Lookup Items) -> **As** 系统管理员, +> **As** Tenant Admin(租户管理员), > **I want** 在「系统设置 → 参数配置」页面维护各业务模块的下拉选项(如客源来源、跟进目的), > **So that** 经纪人录入时看到的选项符合公司实际业务,不再依赖研发修改代码。 @@ -117,7 +117,7 @@ ### US-SETTING-001-B:管理员配置房源字段必填规则 -> **As** 系统管理员, +> **As** Tenant Admin(租户管理员), > **I want** 按「房源用途 × 交易状态」的组合,控制哪些字段在录入时为必填/选填/隐藏, > **So that** 系统能在录入时强制采集公司要求的关键信息,提升房源数据完整度。 @@ -165,7 +165,7 @@ ### US-SETTING-001-C:管理员配置客源录入规则 -> **As** 系统管理员, +> **As** Tenant Admin(租户管理员), > **I want** 配置新增私客时的查重范围,以及必填字段控制, > **So that** 减少客源重复录入风险,并确保客源数据质量满足公司管理要求。 @@ -222,7 +222,7 @@ **核心设计决策**: -1. **Lookup Items 与 enum_labels 分离**:固定系统枚举(装修/朝向/状态/等级)存放在 Public Schema 的 `enum_labels` 表,由平台管理员通过 migration 维护,租户无权修改。可配置枚举(来源/跟进目的)存放在 Tenant Schema 的 `lookup_items` 表,由租户管理员自主维护。详见数据模型说明文档。 +1. **Lookup Items 与 enum_labels 分离**:固定系统枚举(装修/朝向/状态/等级)存放在 Public Schema 的 `enum_labels` 表,由Platform Admin(平台超级管理员)通过 migration 维护,租户无权修改。可配置枚举(来源/跟进目的)存放在 Tenant Schema 的 `lookup_items` 表,由租户管理员自主维护。详见数据模型说明文档。 2. **字段规则不新增字段**:`field_requirement_rules` 只控制「必填/选填/隐藏」状态,字段本身的存在性由数据模型决定。避免配置层与数据模型层职责混淆。 diff --git a/Project/fonrey/PRD/组织人事管理/组织人事管理模块PRD.md b/Project/fonrey/PRD/组织人事管理/组织人事管理模块PRD.md index 011533e2..c3e475da 100644 --- a/Project/fonrey/PRD/组织人事管理/组织人事管理模块PRD.md +++ b/Project/fonrey/PRD/组织人事管理/组织人事管理模块PRD.md @@ -25,9 +25,9 @@ | 角色 | 描述 | 使用频率 | |------|------|----------| -| 系统管理员 / HR 行政 | 负责新增/编辑部门、办理员工入职/离职/调岗,维护账号状态与证件信息 | 每日 | +| Tenant Admin(租户管理员) / Tenant Admin(租户管理员) | 负责新增/编辑部门、办理员工入职/离职/调岗,维护账号状态与证件信息 | 每日 | | 店长 / 区域经理 | 查看本部门组织架构、员工列表,发起入职邀请 | 每日 | -| 一线经纪人 | 查看同事联系方式(通讯录),查看自己的档案信息 | 按需 | +| Agent(经纪人) | 查看同事联系方式(通讯录),查看自己的档案信息 | 按需 | | 公司管理层 | 通过架构图了解全公司组织结构,监控人员异动动态 | 按需 | --- @@ -63,7 +63,7 @@ ### Story 1:管理员查看组织人员列表 -**As** 系统管理员/店长,**I want** 在组织结构页面查看公司所有部门及其员工信息,**So that** 能快速掌握当前人员分布并进行管理操作。 +**As** Tenant Admin(租户管理员)/店长,**I want** 在组织结构页面查看公司所有部门及其员工信息,**So that** 能快速掌握当前人员分布并进行管理操作。 **验收标准**: - [ ] 页面入口路径:顶部导航「人事」→「组织人事」→「组织结构」,面包屑显示「人事OA / 组织人事 / 组织结构」 @@ -72,7 +72,7 @@ - [ ] 点击部门节点后,右侧展示该部门及其下级部门员工列表(可通过「显示下属部门员工」下拉切换) - [ ] 右上角显示全局系统提示(账号数量上限、实名认证不匹配人数等),提示可点击「立即筛选数据」跳转至对应筛选结果 - [ ] 页面右上角有「员工入黑名单」快捷操作入口 -- [ ] 员工列表支持多条件筛选:姓名/工号/电话(文本搜索)、职务(下拉选择)、职务类别(全选/单选)、员工状态(下拉,含已选 N 个计数)、审批状态(下拉)、冻结状态(全选)、登录账号(全选)、系统管理员(请选择)、入职时间(日期范围)、离职时间(日期范围)、显示下属部门员工(显示/隐藏)、部门级别(全选)、证件状态(不限)、证件号搜索 +- [ ] 员工列表支持多条件筛选:姓名/工号/电话(文本搜索)、职务(下拉选择)、职务类别(全选/单选)、员工状态(下拉,含已选 N 个计数)、审批状态(下拉)、冻结状态(全选)、登录账号(全选)、Tenant Admin(租户管理员)(请选择)、入职时间(日期范围)、离职时间(日期范围)、显示下属部门员工(显示/隐藏)、部门级别(全选)、证件状态(不限)、证件号搜索 - [ ] 点击「查询」按钮执行筛选,点击「清空条件」重置所有筛选项 - [ ] 员工列表支持批量操作:勾选复选框后,可执行「批量调动员工」「批量设置员工上级」,通过「更多」下拉展开更多批量操作 - [ ] 列表操作区包含:「新增员工」(主按钮,带下拉箭头)、「导出员工」、「批量调动员工」、「批量设置员工上级」、「更多」、「员工异动记录」(链接) @@ -86,7 +86,7 @@ ### Story 2:管理员新增部门 -**As** 系统管理员,**I want** 新增一个业务部门并配置其基本信息,**So that** 新部门能纳入组织架构并支持员工归属。 +**As** Tenant Admin(租户管理员),**I want** 新增一个业务部门并配置其基本信息,**So that** 新部门能纳入组织架构并支持员工归属。 **验收标准**: - [ ] 点击左侧「+ 新增部门」按钮,跳转至「部门新增」页面,面包屑显示「人事OA / 组织人事 / 组织结构 / 部门新增」 @@ -113,7 +113,7 @@ ### Story 3:管理员编辑部门信息 -**As** 系统管理员,**I want** 编辑已有部门的基本信息,**So that** 组织信息保持最新准确状态。 +**As** Tenant Admin(租户管理员),**I want** 编辑已有部门的基本信息,**So that** 组织信息保持最新准确状态。 **验收标准**: - [ ] 通过部门详情页右上角「编辑」按钮进入「部门编辑」页面,面包屑显示「人事OA / 组织人事 / 组织结构 / 部门编辑」 @@ -163,7 +163,7 @@ ### Story 6:查看员工详情 - 员工基本信息 -**As** HR 管理员,**I want** 查看某员工的完整档案信息,**So that** 能全面了解员工的任职、个人、来源等情况。 +**As** Tenant Admin(租户管理员),**I want** 查看某员工的完整档案信息,**So that** 能全面了解员工的任职、个人、来源等情况。 **验收标准**: - [ ] 点击员工列表的「查看」操作进入员工详情页,页面标题显示「[部门名称] [员工姓名]」,面包屑显示「人事OA / 组织人事 / 组织结构 / 员工详情」 @@ -218,7 +218,7 @@ ### Story 7:查看员工详情 - 异动记录 -**As** HR 管理员,**I want** 在员工详情页查看该员工的所有人事异动历史,**So that** 能追溯员工入职、调岗、上级变动等完整轨迹。 +**As** Tenant Admin(租户管理员),**I want** 在员工详情页查看该员工的所有人事异动历史,**So that** 能追溯员工入职、调岗、上级变动等完整轨迹。 **验收标准**: - [ ] 在员工详情页左侧导航点击「异动记录」切换至异动记录 Tab @@ -233,7 +233,7 @@ ### Story 8:查看员工详情 - 账号信息 -**As** HR 管理员/系统管理员,**I want** 在员工详情页查看和管理该员工的系统账号及第三方平台账号,**So that** 能统一管理员工的登录凭证和外部账号绑定状态。 +**As** Tenant Admin(租户管理员)/Tenant Admin(租户管理员),**I want** 在员工详情页查看和管理该员工的系统账号及第三方平台账号,**So that** 能统一管理员工的登录凭证和外部账号绑定状态。 **验收标准**: - [ ] 在员工详情页左侧导航点击「账号信息」切换至账号信息 Tab @@ -280,7 +280,7 @@ ### Story 10:查看组织员工异动记录(全局视图) -**As** HR 管理员,**I want** 在组织结构模块查看全公司所有员工的异动记录汇总,**So that** 能统一审计和追踪所有人事变动。 +**As** Tenant Admin(租户管理员),**I want** 在组织结构模块查看全公司所有员工的异动记录汇总,**So that** 能统一审计和追踪所有人事变动。 **验收标准**: - [ ] 异动记录入口:组织结构员工列表页右上角「员工异动记录」链接,跳转至异动记录汇总页,面包屑显示「人事OA / 组织人事 / 组织结构 / 异动记录」 @@ -299,7 +299,7 @@ ### Story 11:员工离职操作 -**As** HR 管理员/店长,**I want** 在组织结构员工列表中对在职员工发起离职操作,**So that** 员工状态及时变更为「离职」,并触发业务数据的归属处理流程。 +**As** Tenant Admin(租户管理员)/店长,**I want** 在组织结构员工列表中对在职员工发起离职操作,**So that** 员工状态及时变更为「离职」,并触发业务数据的归属处理流程。 **验收标准**: - [ ] 离职操作入口:员工列表行右侧「异动」下拉菜单中点击「离职」,弹出「员工离职」对话框(Modal 形式,背景遮罩,不跳转页面) @@ -328,7 +328,7 @@ ### Story 12:员工调动操作 -**As** HR 管理员,**I want** 通过右侧抽屉面板对员工发起调动操作并修改其部门、上级、职务等信息,**So that** 员工的组织归属变更即时生效并留下完整的调动记录。 +**As** Tenant Admin(租户管理员),**I want** 通过右侧抽屉面板对员工发起调动操作并修改其部门、上级、职务等信息,**So that** 员工的组织归属变更即时生效并留下完整的调动记录。 **验收标准**: - [ ] 调动操作入口:员工列表行右侧「异动」下拉菜单中点击「调动」,从页面右侧滑出「员工调动」抽屉面板(不跳转页面,背景列表可见但交互禁用) @@ -367,7 +367,7 @@ ### Story 13:查看员工奖惩记录 -**As** HR 管理员/店长,**I want** 在员工详情页查看该员工的所有奖惩记录,**So that** 能了解员工的奖励与处罚历史,作为绩效管理和晋升的参考依据。 +**As** Tenant Admin(租户管理员)/店长,**I want** 在员工详情页查看该员工的所有奖惩记录,**So that** 能了解员工的奖励与处罚历史,作为绩效管理和晋升的参考依据。 **验收标准**: - [ ] 在员工详情页左侧导航点击「奖惩记录」切换至奖惩记录 Tab,当前选中项高亮(橙色文字 + 左侧橙色指示条) @@ -381,7 +381,7 @@ ### Story 14:新增员工奖惩记录 -**As** HR 管理员,**I want** 在员工奖惩记录页面新增一条奖惩记录,**So that** 员工的奖励或处罚情况被系统留档,可追溯查询。 +**As** Tenant Admin(租户管理员),**I want** 在员工奖惩记录页面新增一条奖惩记录,**So that** 员工的奖励或处罚情况被系统留档,可追溯查询。 **验收标准**: - [ ] 点击奖惩记录页面右上角「新增」按钮,弹出「新增奖惩记录」对话框(Modal 形式,标题「新增奖惩记录」,右上角有「×」关闭按钮) diff --git a/Project/fonrey/TECH_STACK/测试规范.md b/Project/fonrey/TECH_STACK/测试规范.md index 855fef91..8cf46455 100644 --- a/Project/fonrey/TECH_STACK/测试规范.md +++ b/Project/fonrey/TECH_STACK/测试规范.md @@ -2,11 +2,11 @@ # Fonrey 测试规范(TEST_SPEC) -**版本**: 1.1 +**版本**: 1.2 **项目**: Fonrey 房产经纪管理系统 **技术栈**: Django 4.x + django-tenants + PostgreSQL 16 + Redis + Celery + HTMX + Playwright -**关联文档**: `TECH_STACK/TECH_STACK.md`、`PRD/TASK.md`、各模块技术方案(登录/权限/房源/客源/楼盘/组织人事/系统管理) -**最后更新**: 2026-04-27 +**关联文档**: `TECH_STACK/TECH_STACK.md`、`PRD/TASK.md`、`TEST_CASES/TEST_CASE_ID_SPEC.md`、`TEST_CASES/TEST_CASE_REGISTRY.md`、各模块技术方案(登录/权限/房源/客源/楼盘/组织人事/系统管理) +**最后更新**: 2026-04-30 --- @@ -36,13 +36,13 @@ Fonrey 采用 AI 驱动迭代,测试是质量兜底。所有 P0 User Story 必 | `apps/*/services/` 业务逻辑层 | ≥ 80% | | `apps/*/views*` 接口与视图层 | ≥ 70% | | `apps/*/tasks.py` 异步任务 | ≥ 70% | -| E2E 核心旅程 | 5 条全部通过 | +| E2E 核心测试用例 | 覆盖指定核心用例并全部通过 | ### 2.2 质量门禁 - 每个 P0 US 对应至少一个集成测试场景集。 - PR 合并前:单元 + 集成必须全绿。 -- `main/develop`:每日自动跑全量(含 E2E 核心旅程)。 +- `main/develop`:每日自动跑全量(含 E2E 核心测试用例)。 --- @@ -50,7 +50,7 @@ Fonrey 采用 AI 驱动迭代,测试是质量兜底。所有 P0 User Story 必 ``` ┌─────────────────────────────────────────┐ -│ E2E 测试(用户旅程) │ ← Playwright +│ E2E 测试(测试用例) │ ← Playwright ├─────────────────────────────────────────┤ │ 集成测试(HTTP / View / Service / DB) │ ← pytest-django + TenantClient ├─────────────────────────────────────────┤ @@ -71,7 +71,7 @@ Fonrey 采用 AI 驱动迭代,测试是质量兜底。所有 P0 User Story 必 ### 3.3 E2E 测试 - 目标:验证真实用户关键路径。 -- 约束:只覆盖核心旅程,避免把所有细节都堆到 E2E。 +- 约束:只覆盖核心测试用例,避免把所有细节都堆到 E2E。 --- @@ -236,15 +236,12 @@ result = some_task.apply(args=[...]) ## 九、E2E 测试规范 -### 9.1 核心旅程(必须) +### 9.1 核心测试用例(必须) -| 编号 | 旅程 | 对应模块 | -|---|---|---| -| J-01 | 登录 → 进入首页 | 登录 | -| J-02 | 录入房源 → 上传图片 → 查看列表 | 房源 | -| J-03 | 录入客源 → 添加跟进 | 客源 | -| J-04 | 无权限访问受限页面 | 权限 | -| J-05 | 创建员工 → 分配角色 → 新员工登录 | 组织人事 + 权限 | +- E2E 覆盖对象采用“测试用例”定义,不使用“旅程编号(J-xx)”。 +- 每条 E2E 用例必须绑定全局唯一测试用例ID:`TC-FON-XXXXXX`。 +- 当前登录模块核心用例以 `TEST_CASES/TEST_CASES_LOGIN_MODULE.md` 为准(`TC-FON-000001` ~ `TC-FON-000048`)。 +- 其他模块(房源/客源/组织/权限等)按 `TEST_CASES/TEST_CASE_REGISTRY.md` 分配编号后补充。 ### 9.2 Playwright 约束 @@ -264,9 +261,31 @@ page.wait_for_load_state('networkidle') --- -## 十、测试配置基线 +## 十、测试用例编号与注册规范(强制) -### 10.1 `pytest.ini` +### 10.1 编号规范 + +- 测试用例ID:`TC-FON-XXXXXX`(全局唯一) +- 步骤ID:`TC-FON-XXXXXX-SYY` +- 详见:`TEST_CASES/TEST_CASE_ID_SPEC.md` + +### 10.2 注册流程 + +1. 新增用例前,先在 `TEST_CASES/TEST_CASE_REGISTRY.md` 查看下一个可用编号。 +2. 先登记编号段(可先 `reserved`),再编写文档和代码。 +3. 合并前状态改为 `active`,并更新“当前编号水位”。 + +### 10.3 强约束 + +- 不允许按模块重置编号。 +- 不允许复用已废弃编号。 +- 不允许未登记编号直接入库测试代码。 + +--- + +## 十一、测试配置基线 + +### 11.1 `pytest.ini` ```ini [pytest] @@ -280,7 +299,7 @@ markers = slow ``` -### 10.2 `tests/settings_test.py` 关键项 +### 11.2 `tests/settings_test.py` 关键项 - Celery eager 模式开启 - Cache 使用测试后端(locmem/fakeredis) @@ -290,26 +309,27 @@ markers = --- -## 十一、CI 自动化运行 +## 十二、CI 自动化运行 -### 11.1 触发策略 +### 12.1 触发策略 - 每日定时全量测试 - `main/develop` 每次 push 触发 -### 11.2 流水线拆分 +### 12.2 流水线拆分 1. `unit-and-integration` 2. `e2e`(依赖前者成功后执行) -### 11.3 最低产物 +### 12.3 最低产物 - 覆盖率报告(终端 + 平台上传) - E2E 失败截图 artifact +- 测试结果明细(至少含 `run_id`、`test_case_id`、`step_id`、`status`、`error_message`、`expected_result`、`actual_result`) --- -## 十二、AI 协作测试要求 +## 十三、AI 协作测试要求 每个 User Story 实现后,必须同时补齐: @@ -326,7 +346,7 @@ markers = --- -## 十三、禁止项(Do NOT) +## 十四、禁止项(Do NOT) - 禁止 Django 原生 `Client()` 进行租户集成测试 - 禁止固定等待(`sleep` / `wait_for_timeout`) @@ -334,12 +354,14 @@ markers = - 禁止测试之间共享可变数据 - 禁止无权限/未登录场景缺失 - 禁止空测试占位后不补全 +- 禁止未分配 `TC-FON-XXXXXX` 的匿名测试入库 --- -## 十四、文档同步规则 +## 十五、文档同步规则 - 新增/调整 User Story:同步 `PRD/TASK.md` 与集成测试映射 - 模块 API 变更:同步对应模块技术方案 - 测试目录变更:同步本文件目录结构与 CI 脚本 - 新增测试基建(fixture/工具):同步 `AGENTS.md` 与本文件 +- 新增测试用例:同步 `TEST_CASES/TEST_CASE_REGISTRY.md`(编号段、水位、状态) diff --git a/Project/fonrey/TECH_STACK/登录管理技术方案.md b/Project/fonrey/TECH_STACK/登录管理技术方案.md index c038d72d..1f14f342 100644 --- a/Project/fonrey/TECH_STACK/登录管理技术方案.md +++ b/Project/fonrey/TECH_STACK/登录管理技术方案.md @@ -2,281 +2,269 @@ # Fonrey 登录管理技术方案 -**版本**: 3.1 +**版本**: 4.0 **项目**: Fonrey 房产经纪管理系统 **技术栈**: Django 4.x + HTMX + Alpine.js + PostgreSQL 16 + Redis + Celery -**关联 PRD**: `PRD/登录管理/用户登录管理模块PRD.md` +**关联 PRD**: `PRD/登录管理/用户登录管理模块PRD.md`(v2.0) **关联数据模型**: `DATA_MODEL/DATA_MODEL_LOGIN.md`(本方案不重复 DDL) **关联契约规范**: `TECH_STACK/API_CONTRACT.md`(全局 API 契约权威) -**最后更新**: 2026-04-27 +**关联测试规范**: `TECH_STACK/测试规范.md`、`TEST_CASES/TEST_CASES_LOGIN_MODULE.md` +**最后更新**: 2026-04-30 --- ## 一、文档定位与边界 -本文件仅定义登录模块的: +本文件定义登录模块的实现口径: -1. 模块边界与服务职责 -2. API 端点设计(页面 / HTMX / JSON) -3. 登录安全策略(验证码、锁定、会话、找回) -4. 缓存与异步任务策略 +1. 模块范围与职责边界 +2. API 端点(页面 / HTMX / JSON) +3. 安全策略(滑块验证、登录锁定、短信 OTP、会话) +4. Redis/Celery 运行策略 5. 错误码与测试映射 -> 不在本文件展开表字段、索引、DDL。数据结构以 `DATA_MODEL_LOGIN.md` 为唯一权威。 +> 本文件不展开数据表字段与索引。数据结构以 `DATA_MODEL_LOGIN.md` 为唯一权威。 --- -## 二、范围定义(以 P0 为准) +## 二、范围定义(以 PRD v2.0 为准) ### 2.1 P0 必须覆盖 -- Tenant ID 校验(Public Schema) -- 用户名 + 密码登录(Tenant Schema) -- 验证码挑战与一次性 pass token -- 连续失败锁定与解锁机制 -- 找回用户名 / 重置密码 -- 首次登录强制改密 -- 安全登出与会话销毁 +- Tenant Code 识别(首次启动 + 切换公司) +- 密码登录(手机号/密码 + 滑块) +- 首次登录强制修改密码 +- 找回密码(纯短信三步流程) +- 手机验证码登录(MVP 正式功能) +- 登录失败锁定 / 自动解锁 / 管理员解锁 +- 安全登出与会话失效 -### 2.2 预留(非本期强制) +### 2.2 非目标 / 预留 -- MFA(OTP / 短信) +- 微信扫码登录(仅保留禁用入口与接口占位,不开放功能) - 企业 SSO(OAuth2 / SAML) -- 设备指纹与风险评分 +- 风险评分/设备指纹 + +### 2.3 已废弃(不得实现) + +- 找回用户名流程(Story 4 已废弃) --- ## 三、模块架构边界 -## 3.1 模块职责(`apps/account`) +### 3.1 模块职责(`apps/account`) -- 登录认证入口与 Session 建立 -- 密码策略、锁定策略、登录防刷策略执行 -- 找回流程与一次性重置令牌管理 -- 登录/登出/失败审计事件写入 +- 租户识别与租户上下文建立前置校验 +- 登录鉴权、会话签发、登出销毁 +- 首登改密门禁(`is_initial_password`) +- 短信 OTP 发送/校验(找回密码 + 验证码登录) +- 登录与安全审计事件写入 -## 3.2 多租户分层职责 +### 3.2 多租户分层职责 | 层级 | Schema | 职责 | |---|---|---| -| Tenant ID 校验 | Public | 校验租户标识、域名映射、租户状态 | -| 登录认证 | Tenant | 账号鉴权、失败计数、会话建立 | -| 密码找回 | Tenant | 身份确认、令牌签发与核销 | +| Tenant Code 校验 | Public | 校验 `tenant_code`、租户状态、品牌信息返回 | +| 登录认证 | Tenant | 账号鉴权、失败计数、锁定状态、会话签发 | +| 短信 OTP | Tenant | OTP 记录、场景区分、过期与尝试次数控制 | -## 3.3 外部依赖 +### 3.3 外部依赖 | 依赖模块 | 用途 | |---|---| -| `apps/org` | 员工状态联动(离职/冻结禁止登录) | -| `core/encryption.py` | 手机号等敏感信息加密与脱敏 | -| `core/cache.py` | 验证码票据、失败计数、频控缓存 | -| `Celery` | 找回消息异步发送、安全日报任务 | +| `apps/org` | 员工状态联动(离职/停用不可登录) | +| `core/encryption.py` | 手机号加密/哈希能力 | +| `core/cache.py` | 滑块票据、频控、锁定计数、重置 token | +| `Celery` | 短信发送异步化(可选,建议) | --- ## 四、API 设计原则 -1. 登录链路固定三段:Tenant 校验 → 验证码 → 账号认证。 -2. 最小暴露原则:账号不存在与密码错误统一返回。 -3. 认证状态以数据库为准,Redis 仅做加速与频控。 -4. 安全相关写操作后立即失效缓存,不依赖 TTL。 -5. HTMX 返回片段,JSON 返回结构化错误体。 +1. 登录安全链路:**Tenant 校验 → 滑块验证 → 登录提交**。 +2. 防枚举:账号不存在/停用等敏感状态采用统一外显文案。 +3. 账号锁定是账号维度策略,不区分密码登录或验证码登录。 +4. Redis 仅作运行态与频控,最终状态以数据库持久化字段为准。 +5. 所有登录相关接口遵循 `TECH_STACK/API_CONTRACT.md` 的统一错误响应格式。 --- -## 五、端点清单(核心) +## 五、端点清单(对齐 PRD) -## 5.1 页面路由(SSR) +### 5.1 页面路由(SSR) | 路径 | 方法 | 鉴权 | 说明 | |---|---|---|---| -| `/account/tenant/verify/` | GET | 否 | 首次租户识别页 | -| `/account/login/` | GET | 否 | 登录页 | -| `/account/change-password/` | GET | 是 | 首登强制改密页 | -| `/account/recover-username/` | GET | 否 | 找回用户名页 | -| `/account/recover-password/` | GET | 否 | 找回密码页 | +| `/auth/tenant/identify/` | GET | 否 | Tenant 识别页 | +| `/auth/login/` | GET | 否 | 登录页(密码登录/验证码登录 Tab) | +| `/auth/password/forgot/` | GET | 否 | 找回密码三步页 | +| `/auth/password/change-initial/` | GET | 是 | 首次登录强制改密页 | -## 5.2 HTMX 片段端点 +> 说明:`/auth/wechat/*` 仅预留,不在 MVP 开放。 + +### 5.2 HTMX 片段端点 | 路径 | 方法 | 用途 | 返回 | |---|---|---|---| -| `/account/fragments/login-form/` | GET | 登录表单局刷 | HTML 片段 | -| `/account/fragments/captcha/` | GET | 验证码区块刷新 | HTML 片段 | -| `/account/fragments/recover-step/` | GET | 找回步骤局刷 | HTML 片段 | +| `/auth/fragments/captcha/` | GET | 刷新滑块区块 | HTML 片段 | +| `/auth/fragments/login-form/` | GET | 登录 Tab 内容局刷 | HTML 片段 | +| `/auth/fragments/forgot-step/` | GET | 找回密码步骤局刷 | HTML 片段 | -## 5.3 JSON API(P0) +### 5.3 JSON API(MVP) | 端点 | 方法 | 说明 | |---|---|---| -| `/api/account/tenant/verify/` | POST | 校验 tenant_id 与可用性 | -| `/api/account/captcha/generate/` | POST | 生成验证码 challenge | -| `/api/account/captcha/verify/` | POST | 校验 challenge 并签发 pass token | -| `/api/account/login/` | POST | 登录并建立 session | -| `/api/account/logout/` | POST | 登出并销毁 session | -| `/api/account/password/change/` | POST | 登录态改密 | -| `/api/account/username/recover/` | POST | 找回用户名 | -| `/api/account/password/recover/request/` | POST | 申请重置密码令牌 | -| `/api/account/password/recover/reset/` | POST | 使用令牌重置密码 | +| `/api/auth/tenant/verify/` | POST | Tenant Code 校验(公开接口) | +| `/api/auth/captcha/` | GET | 获取滑块拼图验证码(返回背景图 Base64 + 碎片图 Base64 + 验证 Token) | +| `/api/auth/captcha/verify/` | POST | 校验滑块并签发 `captcha_pass_token` | +| `/api/auth/login/` | POST | 密码登录 | +| `/api/auth/login/phone/` | POST | 手机验证码登录 | +| `/api/auth/recover/password/request/` | POST | 找回密码步骤一:发 OTP | +| `/api/auth/recover/password/verify/` | POST | 找回密码步骤二:校验 OTP,颁发 `sms_reset_token` | +| `/api/auth/recover/password/reset/` | POST | 找回密码步骤三:提交新密码 | +| `/api/auth/password/change-initial/` | POST | 首次登录强制改密提交 | +| `/api/auth/logout/` | POST | 登出销毁会话 | --- -## 六、关键 API 规范(请求/响应) +## 六、关键流程约束 -## 6.1 登录 +### 6.1 Tenant 识别 -`POST /api/account/login/` +- `tenant_code` 固定 12 位数字,前后空格自动 trim +- 成功返回:租户名称、Logo URL、登录地址 +- 失败返回:`valid=false` + 统一错误信息 +- 接口公开但必须限流:单 IP 每分钟 ≤ 10 次 + +### 6.2 密码登录 + +请求体(示例): ```json { - "tenant_id": "fonrey-sh", - "username": "agent_001", - "password": "******", + "phone": "13800138000", + "password": "***", "captcha_pass_token": "token" } ``` -成功 `200`: +关键规则: +- 滑块通过后方可提交登录 +- 密码连续错误 ≥ 5 次,锁定 30 分钟 +- `is_initial_password = true` 时强制跳转改密页 +- 错误文案统一,不泄露账号存在性细节 + +### 6.3 找回密码(纯短信三步) + +#### 步骤一:发送 OTP +- `scene = password_reset` +- OTP 有效期:10 分钟 +- 同手机号频控:5 次/小时 +- 手机号不存在/停用:统一提示“如该手机号已注册,验证码将在 1 分钟内发送” + +#### 步骤二:校验 OTP +- 正确且未过期:签发 `sms_reset_token`(15 分钟,一次性) +- 错误:累计尝试,≥5 次作废该 OTP +- 过期:提示重新获取 + +#### 步骤三:重置密码 +- 必须携带有效 `sms_reset_token` +- 成功后:`is_initial_password = false` +- 该用户所有会话立即失效,跳回登录页 + +### 6.4 手机验证码登录(MVP 正式) + +请求体(示例): ```json { - "message": "登录成功", - "redirect_url": "/home/" + "phone": "13800138000", + "sms_code": "123456" } ``` -失败码:`ACCOUNT_LOGIN_INVALID_CREDENTIAL` / `ACCOUNT_LOCKED` / `ACCOUNT_CAPTCHA_INVALID` - -## 6.2 申请重置密码 - -`POST /api/account/password/recover/request/` - -```json -{ - "tenant_id": "fonrey-sh", - "username": "agent_001", - "contact": "138****0000" -} -``` - -规则: -- 频率限制(建议 5 次/小时) -- 统一返回文案,避免枚举账号存在性 +关键规则: +- 获取登录验证码前必须先通过滑块 +- `scene = login` +- OTP 有效期:5 分钟 +- 同手机号频控:10 次/小时(与 `password_reset` 独立计数) +- OTP 错误 ≥5 次作废 +- 账号 `locked` 或 `disabled` 时,验证码登录同样拒绝 --- -## 七、HTMX 交互约定 - -## 7.1 Header 约定 - -- 请求头:`HX-Request: true` -- 成功触发:`HX-Trigger: {"toast":{"level":"success","message":"操作成功"}}` -- 失败触发:`HX-Trigger: {"toast":{"level":"error","message":"操作失败"}}` -- 登录成功:`HX-Redirect: /home/` - -## 7.2 模板分片命名 - -- `templates/account/fragments/login_form.html` -- `templates/account/fragments/captcha_panel.html` -- `templates/account/fragments/recover_step.html` - ---- - -## 八、权限与数据范围 - -## 8.1 访问控制 - -- 匿名可访问:租户校验、登录、找回相关端点 -- 登录后访问:改密、登出 -- 首登未改密用户仅允许访问改密页面 - -## 8.2 审计字段要求 - -登录与找回相关操作至少记录: -- tenant_schema -- username(或脱敏标识) -- ip / user_agent -- result_code -- created_at - ---- - -## 九、异步任务与缓存策略 - -## 9.1 Celery 任务 - -| 任务 | 触发时机 | 说明 | -|---|---|---| -| `account_send_recover_message_task` | 找回请求成功后 | 异步发送邮件/短信 | -| `account_security_digest_task` | 定时任务 | 汇总锁定、失败、异常登录统计 | - -## 9.2 Redis Key 规范 +## 七、Redis Key 规范(对齐 PRD) | Key | TTL | 说明 | |---|---|---| -| `{schema}:account:captcha:{challenge_id}` | 180s | 验证码挑战态 | -| `{schema}:account:captcha:pass:{token}` | 180s | 验证通过一次性票据 | -| `{schema}:account:login_fail:{username}` | 1800s | 登录失败计数 | -| `{schema}:account:recover:rate:{username}` | 3600s | 找回频控 | +| `captcha_token:{uuid}` | 3 分钟 | 滑块验证会话 | +| `captcha_pass:{uuid}` | 3 分钟 | 一次性通过凭证 | +| `login_fail:{tenant_id}:{username}` | 30 分钟 | 登录失败计数 | +| `sms_limit:password_reset:{phone}` | 1 小时 | 找回密码 OTP 发送频控(≤5次) | +| `sms_limit:login:{phone}` | 1 小时 | 登录 OTP 发送频控(≤10次) | +| `sms_reset_token:{token}` | 15 分钟 | 找回密码步骤三凭证 | +| `tenant_verify_ip:{ip}` | 1 分钟 | Tenant 校验接口 IP 限流(≤10次) | --- -## 十、性能与可靠性约束 +## 八、安全与合规 -- 登录链路接口目标:`p95 < 300ms`(不含外部消息发送) -- 找回请求接口目标:`p95 < 400ms`(消息发送异步化) -- 缓存故障时系统应降级到 DB 校验,但保留频控硬兜底 -- 验证码组件不可用时,应返回明确错误并禁止跳过登录防护 +1. 密码仅允许 Django 安全哈希(PBKDF2/Argon2)。 +2. OTP 明文不得入库,仅存哈希。 +3. 敏感字段日志脱敏(手机号、token、验证码)。 +4. 会话过期或登出后,受保护页面必须重定向登录。 +5. HTTPS 强制,不允许明文传输降级。 --- -## 十一、安全与合规 +## 九、错误码建议(登录模块) -1. 密码仅允许 Django 安全哈希(PBKDF2 / Argon2)。 -2. 连续失败 N 次锁定(建议 5 次,30 分钟)。 -3. 重置令牌一次性使用,过期失效,不可复用。 -4. 登出必须销毁会话,旧页面刷新需重定向登录。 -5. 敏感字段仅脱敏返回,禁止明文日志输出。 - ---- - -## 十二、错误码建议 - -| code | HTTP | 场景 | +| code | HTTP | 中文含义 | |---|---|---| -| `ACCOUNT_TENANT_INVALID` | 400 | tenant 无效或停用 | -| `ACCOUNT_CAPTCHA_INVALID` | 400 | 验证码失败/过期 | -| `ACCOUNT_LOGIN_INVALID_CREDENTIAL` | 401 | 账号或密码错误 | -| `ACCOUNT_LOCKED` | 423 | 账号锁定中 | -| `ACCOUNT_PASSWORD_WEAK` | 400 | 新密码不满足复杂度 | -| `ACCOUNT_RESET_TOKEN_INVALID` | 400 | 重置令牌无效/已使用 | +| `AUTH_TENANT_NOT_FOUND` | 400 | 租户识别码无效 | +| `AUTH_TENANT_RATE_LIMITED` | 429 | Tenant 校验请求过于频繁 | +| `AUTH_CAPTCHA_INVALID` | 400 | 滑块验证失败 | +| `AUTH_INVALID_CREDENTIAL` | 401 | 手机号或密码错误 | +| `AUTH_ACCOUNT_LOCKED` | 423 | 账号已锁定 | +| `AUTH_ACCOUNT_DISABLED` | 403 | 账号已停用 | +| `AUTH_SMS_OTP_INVALID` | 400 | 短信验证码错误 | +| `AUTH_SMS_OTP_EXPIRED` | 400 | 短信验证码过期 | +| `AUTH_SMS_OTP_RATE_LIMITED` | 429 | OTP 发送超限 | +| `AUTH_SMS_RESET_TOKEN_INVALID` | 400 | 重置凭证无效或过期 | +| `AUTH_PASSWORD_WEAK` | 400 | 新密码不满足强度规则 | --- -## 十三、测试映射(P0) +## 十、测试映射(与全局编号对齐) -| 场景 | 最低覆盖 | -|---|---| -| Tenant 校验 | 有效/无效/停用租户 | -| 登录链路 | 验证码通过、失败锁定、解锁后登录 | -| 找回流程 | 频控、令牌一次性、过期处理 | -| 首登改密 | 未改密不可进入业务页 | -| 登出 | 会话销毁、回退重定向 | +- 测试编号规范:`TEST_CASES/TEST_CASE_ID_SPEC.md` +- 注册表:`TEST_CASES/TEST_CASE_REGISTRY.md` +- 登录模块用例:`TEST_CASES/TEST_CASES_LOGIN_MODULE.md` -测试文件:`tests/integration/account/test_us_account.py` +建议最小执行集: +- Tenant 识别:`TC-FON-000001` ~ `000010` +- 密码登录与锁定:`TC-FON-000011` ~ `000028` +- 首登改密:`TC-FON-000029` ~ `000033` +- 找回密码:`TC-FON-000034` ~ `000044` +- 验证码登录:`TC-FON-000045` ~ `000048` --- -## 十四、落地顺序建议 +## 十一、落地顺序建议 -1. 先实现 tenant 校验 + 登录主链路 -2. 再接验证码 + 失败锁定 -3. 再实现找回用户名/密码 -4. 最后补安全摘要任务与审计报表 +1. Tenant 识别 + 密码登录主链路 +2. 滑块与失败锁定 +3. 首登改密门禁 +4. 找回密码三步(短信) +5. 手机验证码登录(scene=login) +6. 报表与监控补齐 --- -## 十五、文档同步规则 +## 十二、文档同步规则 -- 登录数据结构调整:同步 `DATA_MODEL_LOGIN.md` -- 安全策略或门禁调整:同步 `权限管理系统技术方案.md` -- API 变更:同步本文件与登录 PRD 验收条目 +- PRD 登录模块变更:同步本文件 +- 数据结构调整:同步 `DATA_MODEL_LOGIN.md` +- 测试用例新增/变更:同步 `TEST_CASES/TEST_CASE_REGISTRY.md` 与登录用例文档 +- API 契约调整:同步 `TECH_STACK/API_CONTRACT.md` diff --git a/Project/fonrey/TEST_CASES/TEST_CASES_LOGIN_MODULE.md b/Project/fonrey/TEST_CASES/TEST_CASES_LOGIN_MODULE.md new file mode 100644 index 00000000..228eccd7 --- /dev/null +++ b/Project/fonrey/TEST_CASES/TEST_CASES_LOGIN_MODULE.md @@ -0,0 +1,390 @@ +# Fonrey 登录模块测试用例文档(可自动化) + +> 文档版本:v1.0 +> 适用范围:`PRD/登录管理/用户登录管理模块PRD.md` v2.0 +> 用例编号范围:`TC-FON-000001` ~ `TC-FON-000048`(全局唯一) +> 编号规范:`TEST_CASES/TEST_CASE_ID_SPEC.md` + +--- + +## 1. 目标与原则 + +1. 本文档用于让工程师直接生成自动化测试代码(API 集成测试 + Web E2E)。 +2. 每个测试用例均包含**唯一ID**和**步骤ID**,可直接用于失败定位与测试报告。 +3. 用例覆盖登录模块 MVP 正式范围: + - Story 1:Tenant 识别 + - Story 2:手机号+密码登录 + - Story 3:短信找回密码 + - Story 5:短信验证码登录 +4. Story 4(找回用户名)已废弃,不实现。 +5. Story 6(微信扫码)为预留,不实现,仅验证禁用态。 + +--- + +## 2. 自动化执行与报告要求(工程实现必须遵循) + +- 执行层: + - API 集成:`pytest + pytest-django + TenantClient` + - Web E2E:`playwright` +- 每步必须输出:`run_id / test_case_id / step_id / status / expected_result / actual_result / error_message` +- 失败时必须附带: + - Web:截图路径 + - API:请求响应快照 + 关键日志路径 + +--- + +## 3. 全量测试用例清单(48条) + +### 3.0 登录模块 API 端点口径(以 PRD 为准) + +- `POST /api/auth/tenant/verify/` +- `GET /api/auth/captcha/` +- `POST /api/auth/captcha/verify/` +- `POST /api/auth/login/` +- `POST /api/auth/login/phone/` +- `POST /api/auth/recover/password/request/` +- `POST /api/auth/recover/password/verify/` +- `POST /api/auth/recover/password/reset/` +- `POST /api/auth/logout/` + +> 注:测试代码生成与接口调用必须使用以上路径。 + +## A. Tenant 识别(Story 1) + +### TC-FON-000001 Tenant Code 页面首启展示 +- 级别:E2E +- 前置:本地无 Tenant Code 缓存 +- 步骤: + - `TC-FON-000001-S01` 启动应用/打开登录入口页 + - `TC-FON-000001-S02` 检查是否进入 Tenant 识别页 + - `TC-FON-000001-S03` 校验页面元素(Logo、文案、输入框、确认按钮) +- 预期:显示 Tenant 识别页且元素完整 + +### TC-FON-000002 Tenant Code 输入去空格与粘贴 +- 级别:E2E +- 前置:在 Tenant 识别页 +- 步骤: + - `TC-FON-000002-S01` 粘贴 ` 202500010001 ` + - `TC-FON-000002-S02` 点击确认 + - `TC-FON-000002-S03` 观察发送请求参数 +- 预期:请求中的 tenant_code 为 `202500010001` + +### TC-FON-000003 Tenant Code 非12位拦截 +- 级别:E2E +- 前置:Tenant 识别页 +- 步骤: + - `TC-FON-000003-S01` 输入 `20250001` + - `TC-FON-000003-S02` 点击确认 + - `TC-FON-000003-S03` 检查错误提示 +- 预期:提示“识别码须为12位数字”,不发请求 + +### TC-FON-000004 Tenant 验证成功流程 +- 级别:API+E2E +- 前置:合法 tenant_code 存在 +- 步骤: + - `TC-FON-000004-S01` 调用 `POST /api/auth/tenant/verify/` + - `TC-FON-000004-S02` 校验 `valid=true` 且返回租户品牌信息 + - `TC-FON-000004-S03` 前端跳转登录页并展示“正在登录:XX房产” +- 预期:成功跳转并写入本地缓存 + +### TC-FON-000005 Tenant 验证失败(无效识别码) +- 级别:API+E2E +- 前置:tenant_code 不存在 +- 步骤: + - `TC-FON-000005-S01` 调用 `POST /api/auth/tenant/verify/` + - `TC-FON-000005-S02` 校验 `valid=false` 与错误码 + - `TC-FON-000005-S03` 校验前端错误提示与不落缓存 +- 预期:提示“识别码无效...”,允许重试 + +### TC-FON-000006 Tenant 验证网络异常重试 +- 级别:E2E +- 前置:模拟网络失败 +- 步骤: + - `TC-FON-000006-S01` 点击确认触发请求失败 + - `TC-FON-000006-S02` 检查“网络连接失败”提示 + - `TC-FON-000006-S03` 点击重试并恢复 +- 预期:重试可再次发起请求 + +### TC-FON-000007 非首启跳过识别页 +- 级别:E2E +- 前置:本地已有合法 Tenant Code +- 步骤: + - `TC-FON-000007-S01` 打开应用 + - `TC-FON-000007-S02` 检查是否直接进入登录页 + - `TC-FON-000007-S03` 检查租户品牌信息回填 +- 预期:跳过识别页 + +### TC-FON-000008 切换公司入口流程 +- 级别:E2E +- 前置:已在登录页 +- 步骤: + - `TC-FON-000008-S01` 点击“切换公司” + - `TC-FON-000008-S02` 校验二次确认文案 + - `TC-FON-000008-S03` 确认后检查缓存清除并回到识别页 +- 预期:缓存清除成功并跳回识别页 + +### TC-FON-000009 Tenant 验证接口无需鉴权 +- 级别:API +- 前置:未登录 +- 步骤: + - `TC-FON-000009-S01` 不带 token 调用验证接口 + - `TC-FON-000009-S02` 校验响应状态 + - `TC-FON-000009-S03` 校验业务结构 +- 预期:接口可访问(非401/403) + +### TC-FON-000010 Tenant 验证接口IP限流 +- 级别:API +- 前置:同IP连续请求 +- 步骤: + - `TC-FON-000010-S01` 1分钟内发起11次请求 + - `TC-FON-000010-S02` 校验前10次正常 + - `TC-FON-000010-S03` 校验第11次被限流 +- 预期:触发每分钟≤10次限制 + +--- + +## B. 密码登录(Story 2) + +### TC-FON-000011 密码登录页元素完整 +- 级别:E2E +- 步骤:`S01` 打开密码登录页;`S02` 检查手机号/密码/滑块/登录按钮;`S03` 检查忘记密码入口 +- 预期:元素齐全 + +### TC-FON-000012 手机号输入仅数字11位 +- 级别:E2E +- 步骤:`S01` 输入含字母字符;`S02` 观察自动过滤;`S03` 检查长度限制 +- 预期:仅数字,最长11位 + +### TC-FON-000013 密码明文/密文切换 +- 级别:E2E +- 步骤:`S01` 输入密码;`S02` 点击眼睛图标显示明文;`S03` 再次点击恢复密文 +- 预期:切换正常 + +### TC-FON-000014 三项未完成时登录按钮置灰 +- 级别:E2E +- 步骤:`S01` 只填手机号;`S02` 再填密码;`S03` 未完成滑块时检查按钮状态 +- 预期:按钮不可点击 + +### TC-FON-000015 滑块验证失败不计入密码错误次数 +- 级别:API+E2E +- 步骤: + - `TC-FON-000015-S01` 调用 `GET /api/auth/captcha/` 获取 challenge + - `TC-FON-000015-S02` 调用 `POST /api/auth/captcha/verify/` 提交错误轨迹 + - `TC-FON-000015-S03` 检查滑块失败提示与刷新,且登录失败计数未增加 +- 预期:不计入账号锁定计数 + +### TC-FON-000016 滑块验证成功状态保持至提交 +- 级别:E2E +- 步骤:`S01` 完成滑块;`S02` 检查“验证通过”状态;`S03` 立即点登录 +- 预期:状态有效并允许提交 + +### TC-FON-000017 登录前端校验-手机号为空 +- 级别:E2E +- 步骤:`S01` 留空手机号;`S02` 点登录;`S03` 检查提示 +- 预期:提示“请输入手机号” + +### TC-FON-000018 登录前端校验-手机号不足11位 +- 级别:E2E +- 步骤:`S01` 输入10位;`S02` 点登录;`S03` 检查提示 +- 预期:提示“请输入完整的11位手机号” + +### TC-FON-000019 登录前端校验-密码为空 +- 级别:E2E +- 步骤:`S01` 填手机号与滑块通过;`S02` 密码留空;`S03` 点登录 +- 预期:提示“请输入密码” + +### TC-FON-000020 登录前端校验-未完成滑块 +- 级别:E2E +- 步骤:`S01` 填手机号密码;`S02` 不做滑块;`S03` 点登录 +- 预期:提示“请完成滑块验证” + +### TC-FON-000021 密码登录成功(is_initial_password=False) +- 级别:API+E2E +- 步骤: + - `TC-FON-000021-S01` 调用 `POST /api/auth/login/` 提交正确手机号/密码与 `captcha_pass_token` + - `TC-FON-000021-S02` 校验返回 token 与 `is_initial_password=false` + - `TC-FON-000021-S03` 校验跳首页欢迎语 +- 预期:登录成功进入首页 + +### TC-FON-000022 密码登录成功(is_initial_password=True) +- 级别:API+E2E +- 步骤:`S01` 使用初始密码登录;`S02` 校验返回标志true;`S03` 校验跳转强制改密页 +- 预期:不可访问其他页面 + +### TC-FON-000023 密码错误提示统一 +- 级别:API+E2E +- 步骤:`S01` 提交错误密码;`S02` 校验错误文案;`S03` 校验密码框清空+手机号保留+滑块刷新 +- 预期:提示“手机号或密码错误,请重新输入” + +### TC-FON-000024 连续错误5次触发账号锁定 +- 级别:API +- 步骤:`S01` 连续5次密码错误;`S02` 校验第5次后状态locked;`S03` 校验locked_until=now+30min +- 预期:账号锁定成功 + +### TC-FON-000025 锁定期间登录被拒绝 +- 级别:API+E2E +- 步骤:`S01` 对locked账号发起登录;`S02` 校验提示文案;`S03` 校验登录按钮置灰 +- 预期:拒绝登录 + +### TC-FON-000026 30分钟后自动解锁 +- 级别:API +- 步骤:`S01` 构造锁定到期账号;`S02` 时间推进30分钟后重试;`S03` 校验恢复登录能力 +- 预期:自动解锁 + +### TC-FON-000027 账号停用登录拦截 +- 级别:API+E2E +- 步骤:`S01` 停用账号发起登录;`S02` 校验错误码;`S03` 校验前端提示 +- 预期:提示“账号已停用,请联系您的管理员” + +### TC-FON-000028 Session过期跳转登录 +- 级别:E2E +- 步骤:`S01` 进入受保护页面;`S02` 使session过期;`S03` 执行动作触发跳转 +- 预期:跳回登录并提示“登录已过期,请重新登录” + +--- + +## C. 首次登录强制改密(Story 2/3 公共密码组件) + +### TC-FON-000029 首次登录强制改密页不可跳过 +- 级别:E2E +- 步骤:`S01` 初始密码登录;`S02` 尝试访问其他功能路由;`S03` 检查仍停留改密流程 +- 预期:不可绕过 + +### TC-FON-000030 新密码强度校验 +- 级别:API+E2E +- 步骤:`S01` 输入弱密码;`S02` 提交;`S03` 检查强度错误提示 +- 预期:拒绝弱密码 + +### TC-FON-000031 新密码不得与最近3次重复 +- 级别:API +- 步骤:`S01` 构造历史密码3条;`S02` 提交重复密码;`S03` 校验错误码 +- 预期:拒绝历史重复 + +### TC-FON-000032 首次改密成功后状态更新 +- 级别:API +- 步骤:`S01` 提交合法新密码;`S02` 校验is_initial_password=false;`S03` 校验password_histories新增 +- 预期:状态正确更新 + +### TC-FON-000033 首次改密成功后直接进入系统 +- 级别:E2E +- 步骤:`S01` 完成改密提交;`S02` 检查成功反馈;`S03` 校验跳首页 +- 预期:进入首页 + +--- + +## D. 找回密码(Story 3) + +### TC-FON-000034 忘记密码入口可达 +- 级别:E2E +- 步骤:`S01` 登录页点击忘记密码;`S02` 校验进入Stepper;`S03` 校验步骤一元素 +- 预期:进入找回密码流程 + +### TC-FON-000035 步骤一手机号格式校验 +- 级别:E2E +- 步骤:`S01` 输入不足11位手机号;`S02` 点获取验证码;`S03` 检查提示 +- 预期:提示“请输入完整的11位手机号” + +### TC-FON-000036 步骤一发送验证码成功(active账号) +- 级别:API+E2E +- 步骤: + - `TC-FON-000036-S01` 调用 `POST /api/auth/recover/password/request/` 提交 active 手机号 + - `TC-FON-000036-S02` 校验进入 60 秒倒计时 + - `TC-FON-000036-S03` 校验 `sms_otp_records` 写入 `scene=password_reset` 且有效期 10 分钟 +- 预期:发送成功并记录正确 + +### TC-FON-000037 步骤一防枚举响应(不存在/停用账号) +- 级别:API +- 步骤:`S01` 分别提交不存在和停用手机号;`S02` 校验响应文案一致;`S03` 校验不泄露账号状态 +- 预期:统一提示“如该手机号已注册...” + +### TC-FON-000038 找回密码短信发送频控(5次/小时) +- 级别:API +- 步骤:`S01` 同手机号发送6次;`S02` 校验前5次可用;`S03` 校验第6次超限 +- 预期:提示“发送次数过多,请1小时后再试” + +### TC-FON-000039 步骤二验证码正确进入步骤三 +- 级别:API+E2E +- 步骤: + - `TC-FON-000039-S01` 调用 `POST /api/auth/recover/password/verify/` 提交正确 6 位验证码 + - `TC-FON-000039-S02` 校验颁发 `sms_reset_token`(15 分钟) + - `TC-FON-000039-S03` 页面进入步骤三 +- 预期:通过校验并进入重置页 + +### TC-FON-000040 步骤二验证码错误与5次作废 +- 级别:API +- 步骤:`S01` 连续输入错误验证码5次;`S02` 检查前4次提示错误;`S03` 第5次后验证码作废 +- 预期:提示“验证码已失效,请重新获取” + +### TC-FON-000041 步骤二验证码过期 +- 级别:API +- 步骤:`S01` 使用超时验证码提交;`S02` 校验错误码;`S03` 校验提示文案 +- 预期:提示“验证码已过期,请重新获取” + +### TC-FON-000042 步骤三token无效或过期 +- 级别:API+E2E +- 步骤:`S01` 使用无效sms_reset_token访问步骤三;`S02` 校验错误提示;`S03` 跳回步骤一 +- 预期:提示“操作已超时,请重新发起找回密码” + +### TC-FON-000043 步骤三重置成功后会话失效 +- 级别:API +- 步骤: + - `TC-FON-000043-S01` 调用 `POST /api/auth/recover/password/reset/`(携带有效 `sms_reset_token`)重置密码 + - `TC-FON-000043-S02` 校验 `is_initial_password=false` + - `TC-FON-000043-S03` 校验该用户历史 session 失效 +- 预期:需重新登录 + +### TC-FON-000044 重置成功后用新密码登录 +- 级别:E2E +- 步骤:`S01` 完成找回密码全流程;`S02` 跳回登录页;`S03` 用新密码登录成功 +- 预期:登录成功,提示“密码已重置,请使用新密码登录” + +--- + +## E. 验证码登录(Story 5) + +### TC-FON-000045 登录方式Tab切换与状态重置 +- 级别:E2E +- 步骤:`S01` 从密码登录切换到验证码登录;`S02` 检查表单区切换;`S03` 校验原输入与滑块状态清空 +- 预期:状态重置正确 + +### TC-FON-000046 未完成滑块禁止获取登录验证码 +- 级别:E2E +- 步骤:`S01` 进入验证码登录Tab;`S02` 直接点获取验证码;`S03` 检查提示 +- 预期:提示“请先完成滑块验证” + +### TC-FON-000047 登录验证码发送与频控(10次/小时,独立于找回密码) +- 级别:API +- 步骤:`S01` 发送登录验证码11次(scene=login);`S02` 校验第11次超限;`S03` 校验找回密码scene不受影响 +- 预期:login场景10次/小时,scene隔离计数 + +### TC-FON-000048 验证码登录成功/失败/锁定限制 +- 级别:API+E2E +- 步骤: + - `TC-FON-000048-S01` 调用 `POST /api/auth/login/phone/`,正确 OTP 登录成功,返回 token 与 `is_initial_password` + - `TC-FON-000048-S02` 调用 `POST /api/auth/login/phone/`,错误 OTP 提示“验证码有误”,5 次后作废 + - `TC-FON-000048-S03` 账号 locked 时调用 `POST /api/auth/login/phone/` 同样被拒绝 +- 预期:三类行为均符合 PRD + +--- + +## 4. 工程实现指引(给测试开发工程师) + +1. **目录建议** + - `tests/integration/login/test_tc_fon_000001_000048.py` + - `tests/e2e/login/test_tc_fon_000001_000048.spec.ts` +2. **命名规范** + - 函数名必须带用例ID,例如:`def test_tc_fon_000024_account_lock_after_5_failures():` +3. **步骤日志** + - 每步执行前后打印 step_id;断言失败时把 step_id 写入异常消息 +4. **报告聚合** + - 生成 `reports/login_run_.json` + `reports/login_run_.html` +5. **CI 门禁** + - `TC-FON-000001` ~ `TC-FON-000048` 全量通过才允许合并 + +--- + +## 5. 变更规则 + +- 新增登录用例:从 `TC-FON-000049` 开始递增 +- 后续房源/客源模块:继续用同一全局序列,不得重号 +- 禁止删除历史用例ID;可标记 `deprecated` 但保留编号与历史报告可追溯性 diff --git a/Project/fonrey/TEST_CASES/TEST_CASE_ID_SPEC.md b/Project/fonrey/TEST_CASES/TEST_CASE_ID_SPEC.md new file mode 100644 index 00000000..bf2f33db --- /dev/null +++ b/Project/fonrey/TEST_CASES/TEST_CASE_ID_SPEC.md @@ -0,0 +1,56 @@ +# 测试用例全局编号规范(Fonrey) + +## 1. 目标 +确保所有模块(登录、房源、客源等)测试用例编号**全局唯一**,便于自动化执行、失败定位、统计报表。 + +## 2. 编号规则 + +- **测试用例ID**:`TC-FON-XXXXXX` + - `TC`:Test Case + - `FON`:Fonrey + - `XXXXXX`:6位递增数字,左侧补0(如 `000001`) +- **步骤ID**:`TC-FON-XXXXXX-SYY` + - `SYY`:步骤序号(`S01`、`S02`...) + +### 示例 +- 用例:`TC-FON-000018` +- 第3步:`TC-FON-000018-S03` + +## 3. 分配原则 + +1. 全项目共用一个递增序列,不按模块重置。 +2. 新增用例必须取“当前最大ID + 1”。 +3. 废弃用例保留ID,不复用。 +4. 若拆分用例,新增子用例使用新ID,不改旧ID。 + +## 4. 自动化报告字段(必须) + +每次自动化执行输出以下字段: + +- `run_id`:本次执行唯一ID(如时间戳) +- `test_case_id`:`TC-FON-XXXXXX` +- `step_id`:`TC-FON-XXXXXX-SYY` +- `status`:`passed` / `failed` / `blocked` / `skipped` +- `error_message`:失败信息 +- `actual_result`:实际结果 +- `expected_result`:预期结果 +- `screenshot_path`:失败截图(Web/E2E) +- `log_path`:后端日志/请求响应日志 +- `started_at` / `ended_at` + +## 5. 报告粒度要求 + +1. 报告必须能定位到**具体失败步骤**(step_id)。 +2. 汇总页至少包含: + - 总用例数、通过数、失败数、跳过数 + - 按模块统计(登录/房源/客源) + - Top失败步骤排行(按 step_id) +3. 详情页展示: + - 失败步骤前后 1~2 步执行上下文 + - 请求/响应(脱敏后) + - 关键断言差异(Expected vs Actual) + +## 6. 当前序列占用(本次) + +- 登录模块使用:`TC-FON-000001` ~ `TC-FON-000048` +- 下一可用ID:`TC-FON-000049` diff --git a/Project/fonrey/TEST_CASES/TEST_CASE_REGISTRY.md b/Project/fonrey/TEST_CASES/TEST_CASE_REGISTRY.md new file mode 100644 index 00000000..8639f1c2 --- /dev/null +++ b/Project/fonrey/TEST_CASES/TEST_CASE_REGISTRY.md @@ -0,0 +1,77 @@ +# Fonrey 测试用例编号注册表(全局唯一) + +> 用途:统一管理全项目测试用例编号,避免撞号,支持自动化报告追踪。 +> 适用范围:登录、房源、客源、组织人事、权限、系统设置等全部模块。 +> 编号规范:见 `TEST_CASES/TEST_CASE_ID_SPEC.md` + +--- + +## 1) 全局规则(强制) + +1. 全项目共用一个递增序列:`TC-FON-XXXXXX`。 +2. 不按模块重置编号。 +3. 新增用例必须先在本注册表登记后再写代码。 +4. 废弃用例保留编号,不得复用。 +5. 拆分/重构用例时,新用例使用新编号,旧编号可标记为 `deprecated`。 + +--- + +## 2) 当前编号水位 + +- **已分配到**:`TC-FON-000048` +- **下一个可用编号**:`TC-FON-000049` +- **最后更新人**:Atlas +- **最后更新时间**:2026-04-30 + +> 说明:下一个新增用例(不论哪个模块)都应从 `TC-FON-000049` 开始。 + +--- + +## 3) 编号段注册总览(按批次) + +| 批次ID | 模块 | 编号范围 | 数量 | 状态 | 文档 | +|---|---|---:|---:|---|---| +| BATCH-LOGIN-001 | 登录模块 | TC-FON-000001 ~ TC-FON-000048 | 48 | active | `TEST_CASES/TEST_CASES_LOGIN_MODULE.md` | + +**状态枚举**: +- `active`:有效且执行中 +- `deprecated`:已废弃但保留追溯 +- `reserved`:已预留待落地 + +--- + +## 4) 逐号注册明细(可选,按需扩展) + +> 当前先采用“编号段注册”。若后续需要逐号追踪,可在本节追加明细表。 + +| test_case_id | 模块 | 标题 | 状态 | 首次版本 | 备注 | +|---|---|---|---|---|---| +| TC-FON-000001 | 登录 | Tenant Code 页面首启展示 | active | v1.0 | 见登录用例文档 | +| TC-FON-000048 | 登录 | 验证码登录成功/失败/锁定限制 | active | v1.0 | 见登录用例文档 | + +--- + +## 5) 新增编号操作流程(团队统一) + +1. 打开本文件,查看“下一个可用编号”。 +2. 按需申请连续编号段(建议每次 5/10/20 条)。 +3. 在“编号段注册总览”新增一行,状态先标 `reserved`。 +4. 完成测试用例文档与代码后,改为 `active`。 +5. 同步更新“当前编号水位”。 + +--- + +## 6) 合并门禁建议(CI) + +建议在 CI 中增加校验: +- 检查是否存在重复 `TC-FON-XXXXXX` +- 检查编号是否小于等于当前水位且未登记 +- 检查新增用例是否已在本注册表存在对应编号段 + +--- + +## 7) 变更记录 + +| 日期 | 变更人 | 变更内容 | +|---|---|---| +| 2026-04-30 | Atlas | 初始化注册表;登记登录模块 000001~000048;下一号设为 000049 | diff --git a/Project/fonrey/UI_DESIGN/登录_UI.html b/Project/fonrey/UI_DESIGN/登录_UI.html index 86c3003f..c3992de7 100644 --- a/Project/fonrey/UI_DESIGN/登录_UI.html +++ b/Project/fonrey/UI_DESIGN/登录_UI.html @@ -3,7 +3,7 @@ - Fonrey 登录管理 · 静态原型 + Fonrey 登录管理 · Tenant 识别(Story 1) - +
@@ -69,369 +47,126 @@ Fonrey 房睿
-

面向经纪业务的
高密度工作台

+

欢迎使用 Fonrey 房睿

- 多租户隔离、角色权限控制、房客源高频操作一致体验。 - 本页面原型覆盖 Tenant 识别、账号密码登录、验证码验证、锁定与会话过期等 P0 场景。 + 首次启动客户端时,请先输入 12 位公司识别码完成租户识别。 + 识别成功后将自动进入该租户的登录页面。

-
多租户识别
-
12位 Tenant ID
+
识别码格式
+
12 位纯数字
安全策略
-
5次失败锁定30分钟
+
公共接口限流保护
+

Tenant 识别

+

请输入您公司的专属识别码以继续

-