Commit Graph

73 Commits

Author SHA1 Message Date
bujinyuan
2c59500e27 fix(phase2a): 代码审查修复 - 8项关键/重要问题
安全修复:
- WebSocket Token 增加 Redis 有效性校验(已登出用户无法建立 WS)

功能修复:
- GetRecommendFriends 改为批量查询,正确返回用户名/昵称/头像
- 上下线通知:OnlineService 通过接口注入获取好友列表推送状态变更
- 管理端在线用户 API 补充用户名信息

代码质量:
- 所有 json.Marshal/Redis 错误增加检查与日志
- ContactController 13 个 endpoint 统一走 handleError 业务错误映射
- 管理端 Controller 补全包注释、函数注释和结构化日志
- 前端 5 个联系人页面 avatar 工具函数抽取到 utils/avatar.js

Made-with: Cursor
2026-03-02 18:48:28 +08:00
bujinyuan
a77669ee99 feat(admin): 管理端在线监控 + 好友关系管理后端
- admin/service/online_service.go: 在线用户列表/计数
- admin/controller/online_controller.go: GET /admin/online/users|count
- admin/service/contact_manage_service.go: 好友关系分页查询/管理员删除
- admin/controller/contact_manage_controller.go: GET|DELETE /admin/contacts
- 更新 admin router/provider/wire 集成新控制器

Made-with: Cursor
2026-03-02 17:13:06 +08:00
bujinyuan
1c87a466a1 feat(ws): 在线状态管理(Redis SET + TTL 心跳续期)
- app/ws/online_service.go: 上线/下线/心跳续期/批量查询在线状态
- 集成到 WebSocket handler: 连接时写入 Redis, 断线时清除
- client.go: 添加 DisconnectHandler 回调
- Redis 键: echo:user:online (SET) + echo:user:status:{uid} (TTL 60s)

Made-with: Cursor
2026-03-02 17:10:13 +08:00
bujinyuan
632e3b9a28 feat(contact): Controller、Router 与 Wire 集成
- controller/contact_controller.go: 全部 17 个 REST API 端点处理器
- router.go: Contact 模块路由注册(JWT 中间件保护)
- provider.go: Wire Provider Set(DAO + Service + Controller)
- 更新全局 provider、wire.go、router.go 集成 Contact 模块

Made-with: Cursor
2026-03-02 17:07:41 +08:00
bujinyuan
978037f085 feat(contact): Contact Service 业务逻辑
- 好友申请:发送/接受/拒绝 + 前置校验(自加/已好友/重复申请/黑名单)
- 好友管理:删除好友/更新备注
- 黑名单:拉黑(同时解除好友)/取消拉黑/黑名单列表
- 搜索:用户搜索(含好友标识)/好友推荐(基于共同好友)
- 分组:CRUD + 移动好友到分组
- 实时通知:好友申请/接受通过 Redis Pub/Sub 推送

Made-with: Cursor
2026-03-02 17:04:30 +08:00
bujinyuan
d4ab5af34e feat(contact): Contact 模型、DAO、常量与 DTO
- model/friendship.go: 好友关系模型(双向存储,4 种状态)
- model/friend_group.go: 好友分组模型
- constants/contact.go: 好友关系状态常量
- dto/contact_dto.go: 联系人请求/响应 DTO
- dao/friendship_dao.go: 好友关系 CRUD + 搜索 + 共同好友
- dao/friend_group_dao.go: 好友分组 CRUD + 移动好友

Made-with: Cursor
2026-03-02 17:03:13 +08:00
bujinyuan
bfb4fb0ccb feat(ws): WebSocket 核心模块(Hub + Client + PubSub + Handler)
- pkg/ws/message.go: 统一消息协议(Message/Response/PushMessage)
- pkg/ws/hub.go: Hub 连接管理(注册/注销/按 userID 查找/在线计数)
- pkg/ws/client.go: 客户端连接封装(readPump/writePump/心跳 30s)
- pkg/ws/pubsub.go: Redis Pub/Sub 消息路由(按用户频道发布/订阅)
- app/ws/handler.go: WebSocket 升级处理(JWT 认证 + 消息分发)
- app/ws/router.go: GET /ws 路由注册
- app/ws/provider.go: Wire Provider Set
- 更新 provider/router 集成 WebSocket 模块

Made-with: Cursor
2026-03-02 16:46:17 +08:00
bujinyuan
fa6f1e5c58 feat: 角色等级体系与权限管控实施
- 数据库:auth_roles 表新增 level 字段(1=超管, 10=管理员, 100=普通用户)
- 后端:新增 GetAllRoles/GetUserMaxLevel/SetUserRoles/FindByCodeList DAO 方法
- 后端:SetRolesRequest 替换 AssignRoleRequest,AdminUserInfo.Roles 改为 []RoleInfo
- 后端:所有管理操作(禁用/启用/角色分配/创建用户)强制层级权限校验
- 后端:PUT /users/:id/roles(批量设置角色)+ GET /roles(角色列表)
- 前端:角色管理改为 Checkbox Group 多选,高等级角色禁用
- 前端:禁用/启用按钮受角色层级约束,列表页操作按钮权限管控
- 前端:创建用户对话框角色选项根据操作者等级动态过滤
- 文档:API 文档、设计方案、集成规范、进度文档同步更新

Made-with: Cursor
2026-03-02 15:40:02 +08:00
bujinyuan
13c6b44352 fix: 管理端所有认证接口统一使用 /api/v1/admin/auth/* 路由
后端:
- 新增管理端认证路由组 /api/v1/admin/auth/(JWT + admin 角色双重检查)
- 管理端登出:POST /api/v1/admin/auth/logout
- 管理端获取个人信息:GET /api/v1/admin/auth/profile
- 管理端更新个人信息:PUT /api/v1/admin/auth/profile
- 管理端修改密码:PUT /api/v1/admin/auth/password

前端:
- admin/src/api/auth.js 所有接口全部改为 /api/v1/admin/auth/*
- 登出和获取个人信息不再使用前台的 /api/v1/auth/ 路由

Made-with: Cursor
2026-03-02 14:33:18 +08:00
bujinyuan
c3e8600b24 fix: 前后台 Token Redis 存储隔离,修复同账号互相覆盖问题
核心变更:
- Redis key 加入 clientType 前缀:echo:auth:token:{frontend|admin}:{user_id}
- JWT Claims 新增 client_type 字段区分前台/管理端
- 新增 constants/client_type.go 定义 ClientTypeFrontend / ClientTypeAdmin
- 全链路传递 clientType:Controller → Service → TokenStore → Redis
- 中间件从 JWT Claims 提取 clientType 做 Redis 校验
- 登出只删除当前端 Token,不影响另一端

前端变更:
- 管理端 login API 改为调用 POST /api/v1/admin/auth/login(之前错误调用了前台接口)

文档更新:
- 系统设计文档、实施计划、API文档、开发规范、项目进度全部同步

Made-with: Cursor
2026-03-02 14:28:45 +08:00
bujinyuan
e1348f57f2 fix: 统一前后端错误提示处理,修复3个问题
1. 管理端 request.js: 所有401均优先显示后端实际message,
   非登录页才清除Token并跳转
2. 前台用户端 request.js: 区分登录/注册请求与已认证请求,
   登录失败时只显示后端message,不清Token不跳转
3. 后端 auth_service: 登录时用户不存在统一返回"账号或密码错误"
   (防止用户枚举攻击,不再返回404"用户不存在")

Made-with: Cursor
2026-03-02 14:05:03 +08:00
bujinyuan
4d03215fe4 feat: Phase 1 完成 — 基础设施 + 用户认证 + 管理端 + 端到端验证
Phase 1 (基础设施与用户认证) 全部 11 个 Task 开发完成:

后端 (Go):
- Auth 模块: 注册/登录/JWT(有状态)/Profile/密码修改
- Admin 模块: 用户列表/详情/禁用/启用/角色分配/创建用户
- 中间件: JWT认证 + RBAC角色权限 + 请求日志 + CORS + Panic恢复
- Dockerfile 多阶段构建 + Docker Compose 全栈部署

前台 (uni-app):
- 登录/注册页面 + 自定义 TabBar + 个人中心
- 请求封装 + 状态管理 (Pinia)

管理端 (Vue 3 + Element Plus):
- 登录/仪表盘/用户列表/用户详情
- Axios 封装 + 路由守卫 + Pinia 状态管理

验证:
- 全流程 API 端到端测试通过
- Playwright 页面自动化验证通过
- code-reviewer 代码审查通过

Made-with: Cursor
2026-03-02 11:31:24 +08:00
bujinyuan
e9bd4dd204 fix: 时间精度精确到秒 + 同步全部文档到最新状态
时间字段修正:
- init.sql: 所有 TIMESTAMP 改为 TIMESTAMP(0),精确到秒
- GORM 模型: 所有时间字段添加 type:timestamp(0) tag
- 已有数据库表通过 ALTER TABLE 修正列类型

文档同步(架构设计 + 实施步骤):
- system-architecture.md:
  - auth 模块描述更新为"有状态 JWT Token 管理(Redis 存储)"
  - 开发环境端口 8080 → 8085
- phase1-foundation-and-auth.md:
  - Go 版本 1.22+ → 1.23+
  - 常量命名更新为驼峰风格(UserStatusActive / RoleUser 等)
  - Task 4 完整重写:增加 token_store.go、TokenValidator 接口、有状态 JWT
  - Task 5 端口号 8080 → 8085,测试命令增加登出失效验证
  - 依赖版本选择原则说明

Made-with: Cursor
2026-02-28 17:04:47 +08:00
bujinyuan
b607434c57 fix(auth): 有状态 JWT + 统一响应格式,严格遵循设计方案
1. 有状态 JWT(Token 存 Redis):
   - 新增 token_store.go: Token 的 Redis 存取管理
     - echo:auth:token:{user_id} → Access Token (TTL = access_expire_min)
     - echo:auth:refresh:{user_id} → Refresh Token (TTL = refresh_expire_day)
   - 登录/注册时自动将 Token 存入 Redis(覆盖旧 Token,实现单设备登录)
   - JWT 中间件增加 Redis 有效性校验(TokenValidator 接口解耦)
   - 登出时从 Redis 删除 Token,使其立即失效
   - 刷新 Token 时校验 Redis 中的 Refresh Token

2. 统一成功响应为 "success" + 200:
   - 注册接口改用 ResponseOK(原 ResponseCreated/201)
   - 所有成功响应统一为 {"code": 0, "message": "success"}

3. API 文档同步更新:
   - frontend/auth.md: 登出说明改为 Redis 方案、注册响应统一
   - README.md: 移除 "created" 示例

已验证:登出后 Token 立即失效 ✓ 重新登录后新 Token 有效 ✓

Made-with: Cursor
2026-02-28 16:57:46 +08:00
bujinyuan
5a65716d10 docs(api): 同步 API 文档与实际实现一致
README.md:
- 开发环境端口 8080 → 8085
- 统一响应格式添加 trace_id 字段
- 成功消息 "ok" → "success",创建 "created"

frontend/auth.md(全面更新):
- 注册响应:201 状态码 + message="created" + expires_in=7200
- 所有响应示例:添加 trace_id 和 time 字段
- user 对象:添加 gender 字段
- 退出登录:更新为无状态 JWT 说明(非 Redis)
- 刷新 Token:添加 user 字段到响应
- profile:添加 phone + created_at 字段
- 错误码:统一使用 HTTP 状态码说明表

代码同步:
- dto.UserInfo: 添加 Phone + CreatedAt 字段
- auth_service.buildUserInfo: 填充新字段

Made-with: Cursor
2026-02-28 16:48:17 +08:00
bujinyuan
d975adaf2a feat(auth): 完整认证系统 — 注册/登录/JWT/路由(Task 4 + Task 5)
Task 4 — 认证服务层:
- pkg/utils/password.go: bcrypt 密码加密与校验
- pkg/utils/jwt.go: Access/Refresh Token 生成与解析(jwt/v5@v5.2.1,兼容 Go 1.23)
- app/dto/auth_dto.go: 认证相关请求/响应 DTO(含参数校验 binding tag)
- app/auth/service/auth_service.go: 核心业务逻辑(注册、登录、管理员登录、Token 刷新、个人信息、改密码)
- pkg/middleware/auth.go: JWT 认证中间件 + 角色权限检查中间件

Task 5 — Controller 与路由注册:
- app/auth/controller/auth_controller.go: 前台认证接口(7 个 API)
- app/auth/controller/admin_auth_controller.go: 后台管理认证接口
- app/auth/router.go: auth 模块路由定义(模块自包含)
- router/router.go: 主路由汇总入口(仅做调度,不含具体路由定义)
- cmd/server/main.go: 路由注册迁移到 router.Setup()

已验证全部接口:注册 ✓ 登录 ✓ 获取 profile ✓ 错误密码 ✓ 未认证拒绝 ✓ 非管理员拒绝 ✓

Made-with: Cursor
2026-02-28 16:42:28 +08:00
bujinyuan
4d3d486902 refactor(middleware): 精简请求日志 — 采用社区标准分层策略
- 移除 Request Body 记录(交由 Controller 层以结构化参数形式记录)
- 移除正常响应 Body 的 DEBUG 记录(减少日志量)
- 保留 HTTP 元信息:method/path/handler/status/latency/ip/query
- 保留错误响应(4xx/5xx)的 Response Body 记录
- 导出 IsSensitivePath 供 Controller 层调用
- 重写架构文档 8.6 节:分层日志架构表、字段说明、分级策略
- 更新 phase1 实施计划中间件描述

Made-with: Cursor
2026-02-28 16:10:07 +08:00
bujinyuan
a6ef49a3e0 feat(middleware): 请求日志新增 handler 字段定位实际处理函数
- 通过 c.HandlerName() 获取处理请求的 handler 函数名
- 解决 caller 始终指向中间件文件无法定位业务代码的问题
- 同步更新架构文档日志示例,补充 caller/handler 说明

Made-with: Cursor
2026-02-28 15:56:32 +08:00
bujinyuan
8a023dfd87 feat(middleware): 请求日志增强 — 记录请求参数 + 响应数据
- Query 参数:INFO 级别始终记录(所有环境生效)
- Request Body:INFO 级别始终记录(所有请求方式)
  - 文件上传自动跳过,仅标记 [file upload]
  - 敏感路径(登录/注册/改密码)自动脱敏 password 字段
  - Body 超过 4KB 自动截断
- Response Body:DEBUG 级别记录正常响应,4xx/5xx 错误在 INFO 也记录
  - 响应 Body 最大记录 2KB
- 状态码分级:5xx→ERROR / 4xx→WARN / 慢请求→WARN / 正常→INFO

Made-with: Cursor
2026-02-28 15:49:19 +08:00
bujinyuan
028cca8695 docs(config): 配置文件添加完整中文注释
Made-with: Cursor
2026-02-28 15:23:52 +08:00
bujinyuan
63c6079667 feat(logs): 日志系统升级 — 文件轮转 + 分级存储
- 引入 lumberjack 实现日志文件自动轮转(按大小切割、保留数量、过期清理)
- app.log: 全量日志(JSON 格式),便于后期接入 ELK/Loki
- error.log: 仅 WARN 及以上级别,便于快速定位问题
- 控制台输出保持不变(彩色可读文本)
- 配置新增 log.file 节,支持 enable/dir/max_size/max_backups/max_age/compress

Made-with: Cursor
2026-02-28 15:15:00 +08:00
bujinyuan
8a6576a2f7 feat(auth): 用户/角色模型与数据访问层
- constants: 用户状态、性别、角色代码常量定义
- model: User/Role/UserRole GORM 模型
- dao: UserDAO (CRUD + 账号查询) + RoleDAO (角色分配/查询/检查)
- provider: Auth 模块 Wire Provider Set

Made-with: Cursor
2026-02-28 10:42:34 +08:00
bujinyuan
c8ffbedf75 feat(backend): Go 服务骨架(配置、日志、数据库、中间件、Wire)
- config: Viper YAML 配置 + 环境变量覆盖
- logs: zap 结构化日志 + trace_id 链路追踪 + 敏感信息脱敏
- db: PostgreSQL (GORM) + Redis (go-redis) 连接管理
- middleware: Trace/Logger/CORS/Recovery 四层中间件
- provider: Wire 编译时依赖注入
- main.go: 优雅启动/关闭 HTTP 服务

Made-with: Cursor
2026-02-28 10:41:20 +08:00