Files
whale-town-front/docs/auth/form_validation.md
moyin 370cffbdd8 config:更新项目配置和文档
- 更新Godot项目配置,添加自动加载脚本
- 完善.gitignore文件,排除不必要的文件
- 更新README文档,添加项目介绍和使用说明
- 更新主场景配置,集成认证系统
- 添加开发规范文档和项目结构说明
2025-12-24 20:39:33 +08:00

324 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 表单验证规范文档
## 概述
本文档详细说明了登录和注册表单的验证规则、UI交互规范和错误处理机制。
## 验证规则
### 1. 用户名验证
#### 规则
- **必填项**: 是
- **长度**: 1-50字符
- **格式**: 只能包含字母、数字和下划线
- **正则表达式**: `^[a-zA-Z0-9_]+$`
#### 错误提示
- 空值: "用户名不能为空"
- 长度不符: "用户名长度应为1-50字符"
- 格式错误: "用户名只能包含字母、数字和下划线"
### 2. 邮箱验证
#### 规则
- **必填项**: 是(注册时)
- **格式**: 标准邮箱格式
- **正则表达式**: `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`
#### 错误提示
- 空值: "邮箱不能为空"
- 格式错误: "请输入有效的邮箱地址"
### 3. 密码验证
#### 规则
- **必填项**: 是
- **长度**: 8-128字符
- **复杂度**: 必须包含字母和数字
- **安全性**: 不允许纯数字或纯字母
#### 错误提示
- 空值: "密码不能为空"
- 长度不足: "密码长度至少8位"
- 长度超限: "密码长度不能超过128位"
- 复杂度不够: "密码必须包含字母和数字"
### 4. 确认密码验证
#### 规则
- **必填项**: 是(注册时)
- **一致性**: 必须与密码字段完全一致
#### 错误提示
- 空值: "确认密码不能为空"
- 不一致: "两次输入的密码不一致"
### 5. 验证码验证
#### 规则
- **必填项**: 是(注册时)
- **长度**: 6位数字
- **格式**: 纯数字
- **有效性**: 必须先获取验证码
#### 错误提示
- 空值: "验证码不能为空"
- 长度错误: "验证码必须是6位数字"
- 格式错误: "验证码必须是6位数字"
- 未获取: "请先获取邮箱验证码"
## UI交互规范
### 1. 必填项标识
所有必填字段都使用水平布局来显示标签、红色星号和右对齐的错误提示:
#### 结构设计
```
VBoxContainer (字段容器)
├── HBoxContainer (标签和错误提示容器)
│ ├── Label (字段名称)
│ ├── Label (红色星号 " *")
│ ├── Control (弹性空间) [size_flags_horizontal = 3]
│ └── Label (红色错误提示) [右对齐,默认隐藏]
└── LineEdit (输入框)
```
#### 视觉效果
- **标签**: 黑色文本,如 "用户名"、"邮箱"、"密码"
- **星号**: 红色文本 `Color(1, 0.2, 0.2, 1)`,内容为 " *"
- **弹性空间**: Control节点`size_flags_horizontal = 3`,占据剩余空间
- **错误提示**: 红色文本12px字体右对齐显示 (`horizontal_alignment = 2`)
- **布局**: 标签和星号左对齐,错误提示右对齐
#### 交互行为
- **正常状态**: 显示 `用户名 * `
- **错误状态**: 显示 `用户名 * 用户名不能为空`
- **输入时**: 错误提示自动隐藏,回到正常状态
#### 优势
- 错误提示右对齐,与输入框右边缘对齐,视觉更整齐
- 利用弹性空间实现左右分布,布局更美观
- 不占用额外的垂直空间
- 避免UI布局被拉长导致溢出
- 保持界面紧凑美观
- 红色星号和错误提示颜色一致,视觉统一
- 错误提示位置固定,不会因为文本长度变化而影响布局
### 2. 实时验证
#### 失焦验证
- 当用户离开输入框时(`focus_exited`)触发验证
- 立即显示相应的错误提示
- 错误提示显示在输入框下方
#### 输入时验证
- 当用户开始输入时(`text_changed`)隐藏错误提示
- 提供即时的视觉反馈
- 避免在用户输入过程中显示错误
### 3. 错误提示样式
#### 视觉设计
- **颜色**: 红色 `Color(1, 0.2, 0.2, 1)`
- **字体大小**: 12px
- **位置**: 输入框正下方
- **显示状态**: 默认隐藏,验证失败时显示
#### 错误信息特点
- 简洁明了,直接指出问题
- 提供解决建议
- 使用友好的语言
### 4. 按钮状态管理
#### 发送验证码按钮
- **正常状态**: "发送验证码"
- **冷却状态**: "重新发送(60)" (倒计时)
- **禁用状态**: 请求进行中时禁用
#### 提交按钮
- **正常状态**: 可点击
- **禁用状态**: 表单验证失败或请求进行中时禁用
- **加载状态**: 显示"正在注册..."等提示
## 验证流程
### 1. 登录表单验证流程
```
用户输入 → 失焦验证 → 显示错误(如有) → 点击登录 → 整体验证 → 提交请求
```
#### 验证步骤
1. 检查用户名是否为空
2. 检查密码是否为空
3. 所有验证通过后提交登录请求
### 2. 注册表单验证流程
```
用户输入 → 失焦验证 → 显示错误(如有) → 获取验证码 → 输入验证码 → 点击注册 → 整体验证 → 邮箱验证 → 用户注册
```
#### 验证步骤
1. 验证用户名格式和长度
2. 验证邮箱格式
3. 验证密码强度
4. 验证确认密码一致性
5. 验证验证码格式和有效性
6. 发送邮箱验证请求
7. 验证成功后发送注册请求
### 3. 验证码获取流程
```
输入邮箱 → 验证邮箱格式 → 检查冷却时间 → 发送验证码 → 开始冷却计时
```
#### 冷却机制
- **冷却时间**: 60秒
- **按钮状态**: 显示倒计时
- **重复发送**: 冷却结束后可重新发送
## 错误处理机制
### 1. 客户端验证
#### 即时验证
- 在用户输入过程中提供即时反馈
- 防止用户提交无效数据
- 提升用户体验
#### 提交前验证
- 在发送请求前进行完整验证
- 确保所有必填项都已正确填写
- 避免无效的网络请求
### 2. 服务器验证
#### 后端验证
- 服务器端进行二次验证
- 处理服务器返回的错误信息
- 显示相应的错误提示
#### 网络错误处理
- 连接失败提示
- 超时处理
- 服务器错误提示
### 3. 用户引导
#### 错误恢复
- 清晰的错误提示
- 提供解决方案
- 引导用户正确操作
#### 成功反馈
- 注册成功提示
- 自动跳转到登录界面
- 自动填充用户名
## 代码实现
### 1. 验证函数
每个字段都有对应的验证函数:
- `validate_username(username: String) -> Dictionary`
- `validate_email(email: String) -> Dictionary`
- `validate_password(password: String) -> Dictionary`
- `validate_confirm_password(password: String, confirm: String) -> Dictionary`
- `validate_verification_code(code: String) -> Dictionary`
### 2. 事件处理
#### 失焦事件
- `_on_register_username_focus_exited()`
- `_on_register_email_focus_exited()`
- `_on_register_password_focus_exited()`
- `_on_register_confirm_focus_exited()`
- `_on_verification_focus_exited()`
#### 输入事件
- `_on_register_username_text_changed(new_text: String)`
- `_on_register_email_text_changed(new_text: String)`
- `_on_register_password_text_changed(new_text: String)`
- `_on_register_confirm_text_changed(new_text: String)`
- `_on_verification_text_changed(new_text: String)`
### 3. 整体验证
- `validate_login_form() -> bool`
- `validate_register_form() -> bool`
## 测试用例
### 1. 用户名测试
| 输入 | 预期结果 | 错误信息 |
|------|----------|----------|
| "" | 失败 | "用户名不能为空" |
| "a" | 成功 | - |
| "test_user123" | 成功 | - |
| "test@user" | 失败 | "用户名只能包含字母、数字和下划线" |
| "a".repeat(51) | 失败 | "用户名长度应为1-50字符" |
### 2. 邮箱测试
| 输入 | 预期结果 | 错误信息 |
|------|----------|----------|
| "" | 失败 | "邮箱不能为空" |
| "test@example.com" | 成功 | - |
| "invalid-email" | 失败 | "请输入有效的邮箱地址" |
| "test@" | 失败 | "请输入有效的邮箱地址" |
### 3. 密码测试
| 输入 | 预期结果 | 错误信息 |
|------|----------|----------|
| "" | 失败 | "密码不能为空" |
| "1234567" | 失败 | "密码长度至少8位" |
| "12345678" | 失败 | "密码必须包含字母和数字" |
| "abcdefgh" | 失败 | "密码必须包含字母和数字" |
| "abc12345" | 成功 | - |
### 4. 验证码测试
| 输入 | 预期结果 | 错误信息 |
|------|----------|----------|
| "" | 失败 | "验证码不能为空" |
| "12345" | 失败 | "验证码必须是6位数字" |
| "1234567" | 失败 | "验证码必须是6位数字" |
| "12345a" | 失败 | "验证码必须是6位数字" |
| "123456" | 成功 | - |
## 最佳实践
### 1. 用户体验
- **即时反馈**: 在用户输入时提供即时的视觉反馈
- **清晰提示**: 错误信息要简洁明了,易于理解
- **引导操作**: 通过UI引导用户完成正确的操作流程
### 2. 性能优化
- **避免过度验证**: 不在每次字符输入时都进行复杂验证
- **合理的验证时机**: 在失焦和提交时进行验证
- **缓存验证结果**: 避免重复验证相同的内容
### 3. 安全考虑
- **客户端+服务端**: 双重验证确保数据安全
- **敏感信息**: 密码等敏感信息不在客户端明文存储
- **防止暴力破解**: 验证码冷却机制防止频繁请求
### 4. 可维护性
- **模块化设计**: 每个验证规则独立成函数
- **统一的错误处理**: 使用统一的错误显示机制
- **可配置的规则**: 验证规则可以根据需求调整
## 更新日志
- **v1.0.0** (2025-12-24): 初始版本,包含完整的表单验证规范