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
35 KiB
EchoChat 第一阶段:基础设施与用户体系 - 实施计划
For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
目标: 搭建项目完整骨架(Go 后端、uniapp 前端、Vue3 管理端),实现用户注册登录体系,建立 Docker 开发环境,为后续 IM/会议等功能奠定基础。
架构: Go 单体模块化服务 + uniapp 前台 + Vue3 管理端 + PostgreSQL + Redis,Docker Compose 编排。
技术栈: Go 1.23+ (Gin + GORM + Wire + zap) / uniapp 3.0 (Vue 3.4 + Pinia 2.x) / Vue 3.5+ 管理端 (Pinia 3.x + Element Plus) / PostgreSQL 17 / Redis 7 / Docker Compose
设计文档: docs/plans/2026-02-27-echochat-system-design.md
日志系统设计: docs/architecture/system-architecture.md 第八节
全局规范(贯穿所有 Task)
代码注释规范
以下规范适用于所有 Task 中编写的代码,必须严格遵守:
Go 后端注释规范:
- 包注释:每个 package 必须有注释,以包名开头,说明包的用途
- 公开函数/方法:所有大写字母开头的函数/方法必须有注释,格式:
// FuncName 描述功能 - 结构体注释:每个 struct 需要注释说明用途,关键字段需要行内注释
- 枚举/常量:每个常量值必须有注释说明含义
- 复杂逻辑:非显而易见的逻辑段落需要注释说明意图和设计考虑
- DAO 层:每个数据库操作函数需说明 SQL 查询逻辑和性能考虑
- 中间件:说明中间件的作用、执行顺序依赖和副作用
前端注释规范(Vue/uniapp):
- 组件注释:每个
.vue文件顶部<!-- -->说明组件用途、功能清单、对应 API 和文档引用 - API 函数:每个 API 调用函数说明对应后端接口路径和参数
- Store:state 字段、action 方法需要注释说明
- 工具函数:参数和返回值类型、用途说明
- 复杂模板逻辑:
v-if/v-for等复杂条件需要注释说明 - CSS 注释:
<style>顶部声明设计系统来源和色板引用
前端目录结构与编码规范
目录结构(uni-app 前台):
frontend/src/
├── api/ # API 接口模块,每个后端模块一个文件
│ └── auth.js # 对应 /api/v1/auth/*
├── pages/ # 页面组件(uni-app 页面路由)
│ ├── auth/ # 认证页面(login/register)
│ ├── index/ # 启动页(登录状态判断 + 路由重定向)
│ ├── chat/ # 消息列表(TabBar 页)
│ ├── contact/ # 联系人(TabBar 页)
│ ├── meeting/ # 会议(TabBar 页)
│ └── profile/ # 个人中心(TabBar 页)
├── store/ # Pinia 状态管理
│ └── user.js # 用户认证状态
├── utils/ # 工具函数
│ ├── request.js # HTTP 请求封装(基于 uni.request)
│ └── storage.js # 本地存储封装
├── services/ # 业务服务(WebSocket 等)
│ └── websocket.js # WebSocket 管理(占位)
├── static/ # 静态资源(图片、图标)
├── main.js # 应用入口(Pinia 初始化)
├── App.vue # 根组件
├── pages.json # 页面路由 + TabBar 配置
└── manifest.json # 应用配置
编码规范:
- 模块化导入:使用
@/别名引用src/下的模块(如@/api/auth、@/store/user) - 命名规范:文件名使用 kebab-case 或小写,Vue 组件 name 使用 PascalCase
- 导出方式:统一使用 ES Module(
export/export default)。禁止使用 CommonJSmodule.exports/require,Vite 构建环境不兼容 CJS - 状态管理:所有全局状态通过 Pinia Store 管理,组件内部状态使用
data() - API 调用:页面组件不直接调用
request.js,必须通过api/层或 Store action - 表单校验:使用 label + error feedback 模式(禁止 placeholder-only),参照 ui-ux-pro-max UX 规则
- 设计系统:所有页面 UI 必须基于
design-system/echochat/MASTER.md设计规范实现 - 响应式单位:使用
rpx替代px(750rpx = 屏幕宽度),确保多端适配 - npm 配置:
frontend/.npmrc设置legacy-peer-deps=true(uni-app 生态需要)
日志规范
所有 Task 中的 Go 后端代码必须遵守日志规范(详见架构文档第八节):
- 每个 Service/DAO 函数使用入口/出口日志模式
- 所有日志从 context 提取 trace_id
- 错误必须记录 ERROR 级别日志,包含上下文信息
- 敏感信息必须脱敏
Wire 依赖注入
从初期就使用 Wire 管理依赖注入:
- 每个模块在
provider.go中声明 Provider Set - 根目录
app/provider/下维护全局 Wire 配置 - 新增模块时同步更新 Wire Provider
Task 1: Docker Compose 开发环境搭建
Files:
- Create:
deploy/docker-compose.dev.yml - Create:
deploy/docker/postgres/init.sql - Create:
deploy/docker/redis/redis.conf - Create:
scripts/dev-setup.sh
Step 1: 创建 Docker Compose 开发环境配置
创建 deploy/docker-compose.dev.yml,包含 PostgreSQL 17 和 Redis 7 两个服务:
version: '3.8'
services:
postgres:
image: postgres:17
container_name: echochat-postgres
environment:
POSTGRES_DB: echochat
POSTGRES_USER: echochat
POSTGRES_PASSWORD: echochat_dev_2026
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
- ./docker/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U echochat"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7
container_name: echochat-redis
ports:
- "6379:6379"
volumes:
- redisdata:/data
- ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
volumes:
pgdata:
redisdata:
Step 2: 创建 PostgreSQL 初始化 SQL
创建 deploy/docker/postgres/init.sql,包含 auth 模块相关的所有表:
-- auth_users, auth_roles, auth_user_roles 表
-- 参考设计文档第四节数据库设计
-- 同时插入默认角色: user, admin, super_admin
-- 插入默认超级管理员账号
Step 3: 创建 Redis 配置文件
创建 deploy/docker/redis/redis.conf,基础开发环境配置。
Step 4: 创建开发环境搭建脚本
创建 scripts/dev-setup.sh,一键启动开发环境。
Step 5: 启动并验证开发环境
Run: cd deploy && docker compose -f docker-compose.dev.yml up -d
Expected: PostgreSQL 和 Redis 正常启动,可以连接
Step 6: Commit
git add deploy/ scripts/
git commit -m "infra: Docker Compose 开发环境(PostgreSQL + Redis)"
Task 2: Go 服务骨架搭建
Files:
- Create:
backend/go-service/cmd/server/main.go - Create:
backend/go-service/go.mod - Create:
backend/go-service/config/config.go - Create:
backend/go-service/config/config.dev.yaml - Create:
backend/go-service/pkg/db/postgres.go - Create:
backend/go-service/pkg/db/redis.go - Create:
backend/go-service/pkg/logs/logger.go - Create:
backend/go-service/pkg/logs/trace.go - Create:
backend/go-service/pkg/utils/response.go - Create:
backend/go-service/pkg/middleware/cors.go - Create:
backend/go-service/pkg/middleware/recovery.go - Create:
backend/go-service/pkg/middleware/logger.go - Create:
backend/go-service/pkg/middleware/trace.go - Create:
backend/go-service/app/provider/provider.go - Create:
backend/go-service/app/provider/wire.go
日志系统详细设计见
docs/architecture/system-architecture.md第八节
Step 1: 初始化 Go Module
Run: cd backend/go-service && go mod init github.com/echochat/backend
Step 2: 创建配置管理
创建 config/config.go 使用 viper 读取 YAML 配置 + 环境变量覆盖。
创建 config/config.dev.yaml 包含开发环境默认配置(数据库连接、Redis 连接、JWT 密钥、服务端口、日志级别等)。
// config/config.go
type Config struct {
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
Redis RedisConfig `mapstructure:"redis"`
JWT JWTConfig `mapstructure:"jwt"`
Log LogConfig `mapstructure:"log"`
}
type LogConfig struct {
Level string `mapstructure:"level"` // debug/info/warn/error
Format string `mapstructure:"format"` // text(开发)/json(生产)
OutputPath string `mapstructure:"output_path"` // stdout 或文件路径
File LogFileConfig `mapstructure:"file"` // 日志文件轮转配置
}
type LogFileConfig struct {
Enable bool `mapstructure:"enable"` // 是否启用文件日志
Dir string `mapstructure:"dir"` // 日志文件目录
MaxSize int `mapstructure:"max_size"` // 单文件最大大小(MB)
MaxBackups int `mapstructure:"max_backups"` // 保留旧日志文件数量
MaxAge int `mapstructure:"max_age"` // 旧日志保留天数
Compress bool `mapstructure:"compress"` // 是否压缩归档文件
}
Step 3: 创建日志系统(核心)
创建 pkg/logs/logger.go:
- 基于 zap 的结构化日志封装
- 支持从 context 中提取 trace_id 自动附加到每条日志
- 提供分级日志方法:
Debug(ctx, func, msg, fields...)/Info(...)/Warn(...)/Error(...) - 敏感信息脱敏工具函数(邮箱、手机号、Token)
- 控制台输出(始终启用):开发环境彩色可读文本,生产环境 JSON 结构化
- 文件输出(可配置启用):基于 lumberjack 自动轮转
logs/app.log— 全量日志(JSON 格式),便于接入 ELK/Lokilogs/error.log— 仅 WARN 及以上级别,便于快速定位问题- 支持按文件大小切割、保留数量、过期天数、压缩归档
创建 pkg/logs/trace.go:
GenerateTraceID()— 生成唯一 trace ID(UUID v4 或雪花算法)WithTraceID(ctx, traceID)— 将 trace_id 注入 contextGetTraceID(ctx)— 从 context 提取 trace_id
日志输出格式示例(开发环境):
2026-02-27 10:30:00 INFO [abc-123] auth | service.Login | 用户登录成功 | account=zhangsan | latency=25ms
日志输出格式示例(生产环境 JSON):
{"level":"info","ts":"2026-02-27 10:30:00","trace_id":"abc-123","module":"auth","func":"service.Login","msg":"用户登录成功","account":"zhangsan","latency_ms":25}
Step 4: 创建数据库连接
创建 pkg/db/postgres.go — GORM + PostgreSQL 连接池。GORM 日志适配 zap,SQL 查询日志携带 trace_id。
创建 pkg/db/redis.go — go-redis 客户端。Redis 操作日志携带 trace_id。
Step 5: 创建统一响应工具
创建 pkg/utils/response.go 包含 ResponseOK、ResponseBadRequest、ResponseUnauthorized、ResponseForbidden、ResponseError 等统一响应函数。响应中包含 trace_id 便于前端反馈问题时定位。
type Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
TraceID string `json:"trace_id,omitempty"`
Time string `json:"time"`
}
Step 6: 创建中间件
创建 pkg/middleware/trace.go — 链路追踪中间件:
- 从请求头提取
X-Request-ID,不存在则自动生成 - 注入 context,后续所有日志自动携带 trace_id
- 在响应头中返回
X-Request-ID
创建 pkg/middleware/logger.go — 请求日志中间件(Access Log 层):
- 采用社区标准「分层不重复」策略,只记录 HTTP 请求级元信息
- 记录字段:method / path / handler / status / latency / ip / user_agent / query
- 不记录 Request Body(由 Controller 层在 ShouldBindJSON 后以结构化参数形式记录,caller 可精确指向业务代码行号)
- 错误响应(4xx/5xx)额外记录 Response Body(最大 2KB),便于排查接口返回内容
- handler 字段通过
c.HandlerName()获取,显示实际处理请求的函数名 - 自动携带 trace_id,通过 trace_id 串联同一请求的各层日志
- 状态码分级:5xx→ERROR / 4xx→WARN / 慢请求(>500ms)→WARN / 正常→INFO
创建 pkg/middleware/cors.go — CORS 跨域中间件。
创建 pkg/middleware/recovery.go — Panic 恢复中间件(捕获 panic 后记录 ERROR 日志含堆栈信息)。
Step 7: 初始化 Wire 依赖注入
创建 app/provider/provider.go — 定义基础设施层的 Provider Set:
// provider.go — 基础设施 Provider Set
package provider
import "github.com/google/wire"
// InfraSet 提供所有基础设施组件
var InfraSet = wire.NewSet(
db.NewPostgres,
db.NewRedis,
logs.NewLogger,
)
创建 app/provider/wire.go — Wire 注入入口:
//go:build wireinject
package provider
// InitializeApp 初始化整个应用(Wire 自动生成实现)
func InitializeApp(cfg *config.Config) (*App, error) {
wire.Build(
InfraSet,
// 后续每增加一个模块,在这里添加对应的 ProviderSet
)
return nil, nil
}
安装 Wire 工具:go install github.com/google/wire/cmd/wire@latest
生成注入代码:cd app/provider && wire
Step 8: 创建 main.go 入口
创建 cmd/server/main.go:
- 加载配置
- 初始化日志系统(根据配置设置级别和输出格式)
- 通过 Wire 生成的 InitializeApp 初始化所有组件
- 创建 Gin Engine
- 注册中间件(顺序:Trace → Logger → CORS → Recovery)
- 注册路由(暂时只有健康检查 GET /health)
- 启动 HTTP 服务
Step 9: 安装依赖
Run: cd backend/go-service && go mod tidy
Step 10: 运行验证
Run: cd backend/go-service && go run cmd/server/main.go
Expected: 服务启动在 :8085,访问 /health 返回 200
Step 11: Commit
git add backend/go-service/
git commit -m "feat(backend): Go 服务骨架(配置、日志、数据库、中间件、路由)"
Task 3: Auth 模块 — 用户模型与数据层
Files:
- Create:
backend/go-service/app/auth/model/user.go - Create:
backend/go-service/app/auth/model/role.go - Create:
backend/go-service/app/auth/dao/user_dao.go - Create:
backend/go-service/app/auth/dao/role_dao.go - Create:
backend/go-service/app/auth/provider.go - Create:
backend/go-service/app/constants/user_status.go - Create:
backend/go-service/app/constants/role_code.go
Step 1: 创建用户状态和角色常量
// app/constants/user_status.go — 驼峰命名,符合 Go 社区规范
const (
UserStatusActive = 1 // 正常
UserStatusDisabled = 2 // 禁用
UserStatusDeleted = 3 // 注销
)
// app/constants/role_code.go
const (
RoleUser = "user"
RoleAdmin = "admin"
RoleSuperAdmin = "super_admin"
)
Step 2: 创建用户模型
创建 app/auth/model/user.go,定义 User 结构体,JSON tag 使用下划线命名,GORM tag 指定表名 auth_users。
Step 3: 创建角色模型
创建 app/auth/model/role.go,定义 Role 和 UserRole 结构体。
Step 4: 创建用户 DAO
创建 app/auth/dao/user_dao.go,包含:
Create(ctx, user)— 创建用户FindByEmail(ctx, email)— 按邮箱查询FindByUsername(ctx, username)— 按用户名查询FindByID(ctx, id)— 按 ID 查询Update(ctx, user)— 更新用户UpdateLastLogin(ctx, userID, ip)— 更新最后登录信息
包含标准的日志入口/出口记录。
Step 5: 创建角色 DAO
创建 app/auth/dao/role_dao.go,包含:
FindByCode(ctx, code)— 按角色代码查询AssignRole(ctx, userID, roleID)— 分配角色GetUserRoles(ctx, userID)— 获取用户角色列表HasRole(ctx, userID, roleCode)— 检查用户是否拥有指定角色
Step 6: 创建 Auth 模块 Wire Provider
创建 app/auth/provider.go:
// provider.go — Auth 模块依赖注入 Provider Set
package auth
import "github.com/google/wire"
// AuthSet 提供 Auth 模块的所有组件
var AuthSet = wire.NewSet(
dao.NewUserDAO,
dao.NewRoleDAO,
)
同步更新 app/provider/wire.go,在 wire.Build 中添加 auth.AuthSet。
Step 7: Commit
git add backend/go-service/app/
git commit -m "feat(auth): 用户/角色模型与数据访问层"
Task 4: Auth 模块 — 认证服务层
Files:
- Create:
backend/go-service/app/auth/service/auth_service.go - Create:
backend/go-service/app/auth/service/token_store.go - Create:
backend/go-service/app/dto/auth_dto.go - Create:
backend/go-service/pkg/utils/jwt.go - Create:
backend/go-service/pkg/utils/password.go - Create:
backend/go-service/pkg/middleware/auth.go
Step 1: 创建密码工具
创建 pkg/utils/password.go:
HashPassword(password)— bcrypt 加密(golang.org/x/crypto/bcrypt,复用 go.mod 已有的兼容版本)CheckPassword(password, hash)— 密码校验
Step 2: 创建 JWT 工具
创建 pkg/utils/jwt.go(使用 github.com/golang-jwt/jwt/v5@v5.2.1,兼容 Go 1.23):
GenerateToken(cfg, userID, username, roles)— 生成 Access TokenGenerateRefreshToken(cfg, userID)— 生成 Refresh TokenParseToken(cfg, tokenStr)— 解析验证 Token- Claims 结构体包含 UserID, Username, Roles
依赖版本选择原则: 优先选择兼容当前 Go 版本的包版本,不盲目拉取最新版,避免触发工具链升级。
Step 3: 创建认证 DTO
创建 app/dto/auth_dto.go:
type UserInfo struct {
ID int64 `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Gender int `json:"gender"`
Phone string `json:"phone,omitempty"`
Roles []string `json:"roles"`
CreatedAt string `json:"created_at,omitempty"`
}
Step 4: 创建 Token Redis 存储管理
创建 app/auth/service/token_store.go:
- 遵循设计方案中的 Redis Key 规范:
echo:auth:token:{user_id}/echo:auth:refresh:{user_id} SaveTokens(ctx, userID, accessToken, refreshToken)— 存入 Redis(覆盖旧 Token,实现单设备登录)ValidateAccessToken(ctx, userID, token)— 校验 Access Token 与 Redis 一致ValidateRefreshToken(ctx, userID, token)— 校验 Refresh Token 与 Redis 一致RemoveTokens(ctx, userID)— 登出时删除 Redis 中的 Token
Step 5: 创建认证服务
创建 app/auth/service/auth_service.go:
Register(ctx, req)— 注册逻辑(检查重复、加密密码、创建用户、分配默认角色、生成 Token + 存 Redis)Login(ctx, req, clientIP)— 登录逻辑(查找用户、校验密码、检查状态、更新登录信息、生成 Token + 存 Redis)AdminLogin(ctx, req, clientIP)— 管理员登录(额外检查 admin/super_admin 角色)RefreshToken(ctx, refreshToken)— 刷新 Token(校验 Redis + 生成新 Token + 覆盖 Redis)Logout(ctx, userID)— 登出(从 Redis 删除 Token)ValidateAccessToken(ctx, userID, token)— 供中间件调用,校验 RedisGetProfile(ctx, userID)— 获取用户信息UpdateProfile(ctx, userID, req)— 更新用户信息ChangePassword(ctx, userID, req)— 修改密码
Step 6: 创建认证中间件
创建 pkg/middleware/auth.go:
TokenValidator接口 — 定义 Token 校验契约,由 AuthService 实现(解耦 pkg 与 app 层依赖)JWTAuth(cfg, validator)— 有状态 JWT 验证中间件(解析 Token + 校验 Redis 有效性)RequireRole(roles ...string)— 角色检查中间件- 将 UserID、Username 和 Roles 注入 Gin Context
Step 7: 更新 Wire Provider
更新 app/auth/provider.go:
var AuthSet = wire.NewSet(
dao.NewUserDAO,
dao.NewRoleDAO,
service.NewTokenStore,
service.NewAuthService,
controller.NewAuthController,
controller.NewAdminAuthController,
)
Step 8: Commit
git add backend/go-service/
git commit -m "feat(auth): 认证服务层(注册、登录、有状态JWT、密码加密、中间件)"
Task 5: Auth 模块 — Controller 与路由注册
Files:
- Create:
backend/go-service/app/auth/controller/auth_controller.go - Create:
backend/go-service/app/auth/controller/admin_auth_controller.go - Create:
backend/go-service/app/auth/router.go— auth 模块路由定义(模块自包含) - Create:
backend/go-service/router/router.go— 主路由汇总入口 - Modify:
backend/go-service/cmd/server/main.go— 调用 router.Setup() 注册路由 - Modify:
backend/go-service/app/auth/provider.go— 添加 Controller Provider
路由架构: 采用"模块自包含 + 主路由汇总"模式。每个模块在自己目录内的
router.go定义具体路由,router/router.go主路由文件仅做汇总注册,不含具体路由定义。利于后期微服务拆分——整个模块目录搬走即可。
Step 1: 创建前台认证 Controller
创建 app/auth/controller/auth_controller.go:
Register(c *gin.Context)— POST /api/v1/auth/registerLogin(c *gin.Context)— POST /api/v1/auth/loginLogout(c *gin.Context)— POST /api/v1/auth/logoutRefreshToken(c *gin.Context)— POST /api/v1/auth/refresh-tokenGetProfile(c *gin.Context)— GET /api/v1/auth/profileUpdateProfile(c *gin.Context)— PUT /api/v1/auth/profileChangePassword(c *gin.Context)— PUT /api/v1/auth/password
每个方法:参数绑定 → 调用 Service → 统一响应返回。
Step 2: 创建后台认证 Controller
创建 app/auth/controller/admin_auth_controller.go:
AdminLogin(c *gin.Context)— POST /api/v1/admin/auth/login- 与普通登录的区别:登录后检查用户是否拥有 admin 或 super_admin 角色
Step 3: 创建路由注册函数
创建 app/auth/router.go:
func RegisterRoutes(r *gin.Engine, ctrl *AuthController, adminCtrl *AdminAuthController, authMiddleware gin.HandlerFunc) {
// 前台公开路由
public := r.Group("/api/v1/auth")
{
public.POST("/register", ctrl.Register)
public.POST("/login", ctrl.Login)
public.POST("/refresh-token", ctrl.RefreshToken)
}
// 前台需认证路由
authed := r.Group("/api/v1/auth").Use(authMiddleware)
{
authed.POST("/logout", ctrl.Logout)
authed.GET("/profile", ctrl.GetProfile)
authed.PUT("/profile", ctrl.UpdateProfile)
authed.PUT("/password", ctrl.ChangePassword)
}
// 后台认证路由
admin := r.Group("/api/v1/admin/auth")
{
admin.POST("/login", adminCtrl.AdminLogin)
}
}
Step 4: 创建主路由汇总文件
创建 router/router.go:
Setup(engine, app)函数,负责注册健康检查和调用各模块的 RegisterRoutes- 不含任何具体路由定义,仅做汇总调度
Step 5: 在 main.go 中调用 router.Setup()
修改 cmd/server/main.go,将路由注册逻辑移到 router.Setup() 调用,main.go 不再直接定义路由。
Step 5: 运行验证
Run: cd backend/go-service && go run cmd/server/main.go
Expected: 服务启动在 :8085,可以通过 curl 测试注册和登录接口
# 测试注册
curl -X POST http://localhost:8085/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"testuser","email":"test@example.com","password":"123456","nickname":"测试用户"}'
# 测试登录
curl -X POST http://localhost:8085/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"account":"testuser","password":"123456"}'
# 测试登出后 Token 立即失效
TOKEN=$(curl -s ... | jq -r '.data.token')
curl -X POST http://localhost:8085/api/v1/auth/logout -H "Authorization: Bearer $TOKEN"
curl http://localhost:8085/api/v1/auth/profile -H "Authorization: Bearer $TOKEN"
# 预期返回 401 "认证已失效,请重新登录"
Expected: 注册返回 Token(同时存入 Redis),登录返回 Token + 用户信息,登出后 Token 立即失效
Step 6: Commit
git add backend/go-service/
git commit -m "feat(auth): 用户注册/登录 API(Controller + 路由注册)"
Task 6: uniapp 前端骨架完善
Files:
- Create:
frontend/src/utils/request.js - Create:
frontend/src/utils/storage.js - Create:
frontend/src/api/auth.js - Create:
frontend/src/store/user.js - Create:
frontend/src/services/websocket.js(占位) - Modify:
frontend/src/pages.json - Modify:
frontend/src/main.js - Modify:
frontend/package.json
Step 1: 安装前端依赖
版本策略: uni-app 锁定 Vue 3.4.21,Pinia 3.x 需要 Vue >= 3.5.11,因此前台用户端必须使用 Pinia 2.x。后台管理端(Task 9)为独立 Vue 3 项目,不受此限制,可使用 Pinia 3.x。
npm 兼容性: uni-app 的 peer dependency 链与 npm 7+ 的严格解析存在冲突,需在
frontend/.npmrc中设置legacy-peer-deps=true。
# 创建 .npmrc 固化 npm 解析策略
echo "legacy-peer-deps=true" > frontend/.npmrc
# 安装 Pinia 及持久化插件
cd frontend && npm install pinia@2.1.7 pinia-plugin-persistedstate@3
uniapp 内置了请求 API(uni.request),不需要额外安装 axios。
Step 2: 创建 HTTP 请求封装
创建 src/utils/request.js:
- 封装 uni.request 为 Promise
- 请求拦截器:自动添加 Authorization Header
- 响应拦截器:统一处理错误码(401 跳转登录等)
- 基础 URL 配置
Step 3: 创建存储工具
创建 src/utils/storage.js:
- 封装 uni.setStorageSync / uni.getStorageSync
- Token 存取方法
Step 4: 创建 Pinia Store
修改 src/main.js 集成 Pinia。
创建 src/store/user.js:
- state: userInfo, token, isLoggedIn
- actions: login, register, logout, getProfile, setToken
Step 5: 创建 Auth API
创建 src/api/auth.js:
- register(data)
- login(data)
- logout()
- getProfile()
- updateProfile(data)
- changePassword(data)
Step 6: 更新 pages.json
添加 auth 页面路由、TabBar 配置。
Step 7: Commit
git add frontend/
git commit -m "feat(frontend): uniapp 前端骨架(请求封装、状态管理、Auth API)"
Task 7: uniapp 登录/注册页面
Files:
- Create:
frontend/src/pages/auth/login.vue - Create:
frontend/src/pages/auth/register.vue - Modify:
frontend/src/pages.json
Note: 页面构建使用 ui-ux-pro-max skill 生成设计系统后实现。uniapp 使用
<view><text><input>等组件而非 HTML 标签。
Step 1: 使用 ui-ux-pro-max 生成设计系统
python3 skills/ui-ux-pro-max/scripts/search.py "video conference meeting chat modern professional" --design-system -p "EchoChat" --persist
然后获取 Vue stack 的实现指南:
python3 skills/ui-ux-pro-max/scripts/search.py "login register form" --stack vue
Step 2: 创建登录页面
创建 src/pages/auth/login.vue:
- 输入框:账号(邮箱或用户名)+ 密码
- 登录按钮
- "没有账号?去注册" 链接
- 表单验证
- 调用 userStore.login()
- 登录成功跳转首页
Step 3: 创建注册页面
创建 src/pages/auth/register.vue:
- 输入框:用户名 + 邮箱 + 密码 + 确认密码 + 昵称(选填)
- 注册按钮
- "已有账号?去登录" 链接
- 表单验证
- 调用 userStore.register()
- 注册成功自动登录
Step 4: 更新 pages.json 路由配置
Step 5: 运行验证
Run: cd frontend && npm run dev:h5
Expected: H5 浏览器中可以看到登录/注册页面,输入信息后可以成功注册和登录
Step 6: Commit
git add frontend/
git commit -m "feat(frontend): 登录/注册页面"
Task 8: uniapp 首页框架与 TabBar
Files:
- Create:
frontend/src/pages/chat/index.vue(占位) - Create:
frontend/src/pages/contact/index.vue(占位) - Create:
frontend/src/pages/meeting/index.vue(占位) - Create:
frontend/src/pages/profile/index.vue - Modify:
frontend/src/pages/index/index.vue - Modify:
frontend/src/pages.json
Step 1: 创建 TabBar 页面占位
创建消息、联系人、会议三个 Tab 页面的占位版本(显示模块名称和"开发中"提示)。
Step 2: 创建个人中心页面
创建 src/pages/profile/index.vue:
- 显示用户头像、昵称、用户名
- 编辑资料入口
- 修改密码入口
- 退出登录按钮
- 使用 ui-ux-pro-max 设计系统
Step 3: 配置 TabBar
修改 pages.json,配置底部 TabBar:消息 | 联系人 | 会议 | 我的
Step 4: 配置首页重定向
修改 src/pages/index/index.vue,判断登录状态:
- 已登录 → 跳转消息列表页
- 未登录 → 跳转登录页
Step 5: 运行验证
Run: cd frontend && npm run dev:h5
Expected: 未登录时显示登录页,登录后显示 TabBar 页面,个人中心可以查看信息并退出
Step 6: Commit
git add frontend/
git commit -m "feat(frontend): TabBar 框架与个人中心页面"
Task 9: Vue 3 管理端项目搭建
Files:
- Create:
admin/整个目录(通过 Vite 脚手架创建) - 项目结构参考设计文档第三节
Step 1: 创建 Vue 3 项目
Run: cd /path/to/EchoChat && npm create vite@latest admin -- --template vue
Step 2: 安装核心依赖
版本策略: 管理端为独立 Vue 3 项目(非 uni-app),可使用最新的 Vue 3.5+ 和 Pinia 3.x,不受 uni-app 版本限制。
Run: cd admin && npm install element-plus vue-router@4 pinia axios @element-plus/icons-vue
Step 3: 创建布局框架
创建 src/views/layout/index.vue:
- 左侧边栏导航
- 顶部栏(管理员信息、退出登录)
- 主内容区
- 使用 Element Plus 的 Container/Aside/Header/Main 布局
Step 4: 创建路由配置
创建 src/router/index.js:
- 登录页路由
- 后台布局路由(嵌套子路由)
- 路由守卫(未登录跳转登录页)
Step 5: 创建请求封装
创建 src/api/request.js:
- 基于 axios 的请求封装
- 请求/响应拦截器
- Token 自动附加
Step 6: 创建管理员登录页
创建 src/views/login.vue:
- 管理员账号 + 密码登录表单
- 使用 Element Plus 表单组件
- 使用 ui-ux-pro-max 设计系统
Step 7: 创建仪表盘占位页
创建 src/views/dashboard/index.vue:
- 显示统计卡片占位(总用户数、在线用户、今日会议等)
Step 8: 运行验证
Run: cd admin && npm run dev
Expected: 浏览器访问管理端,未登录跳转登录页,登录后进入仪表盘
Step 9: Commit
git add admin/
git commit -m "feat(admin): Vue 3 管理端项目搭建(布局、路由、登录页)"
Task 10: 管理端用户管理模块
Files:
- Create:
backend/go-service/app/admin/controller/user_manage_controller.go - Create:
backend/go-service/app/admin/service/user_manage_service.go - Create:
backend/go-service/app/admin/dao/user_manage_dao.go - Create:
backend/go-service/app/admin/router.go - Create:
backend/go-service/app/dto/admin_dto.go - Create:
admin/src/api/user.js - Create:
admin/src/views/user/list.vue - Create:
admin/src/views/user/detail.vue - Modify:
backend/go-service/cmd/server/main.go
Step 1: 创建管理端 DTO
创建 app/dto/admin_dto.go:
- UserListRequest(分页、搜索、状态筛选)
- UserListResponse(用户列表 + 总数)
- UserDetailResponse
Step 2: 创建管理端用户 DAO
创建 app/admin/dao/user_manage_dao.go:
ListUsers(ctx, req)— 分页查询用户列表(支持搜索、状态筛选)CountUsers(ctx)— 统计用户总数UpdateUserStatus(ctx, userID, status)— 更新用户状态
Step 3: 创建管理端用户 Service
创建 app/admin/service/user_manage_service.go:
GetUserList(ctx, req)— 获取用户列表GetUserDetail(ctx, userID)— 获取用户详情(含角色信息)UpdateUserStatus(ctx, userID, status)— 启用/禁用用户AssignUserRole(ctx, userID, roleCode)— 分配角色CreateUser(ctx, req)— 管理员手动创建用户
Step 4: 创建管理端 Controller 和路由
创建 Controller 和路由注册函数,所有管理端 API 需要 JWT + admin 角色双重中间件。
Step 5: 创建管理端用户列表页面
创建 admin/src/views/user/list.vue:
- 搜索框(用户名/邮箱搜索)
- 状态筛选下拉
- 用户数据表格(Element Plus Table)
- 分页组件
- 操作按钮(查看详情、启用/禁用)
Step 6: 创建管理端用户详情页面
创建 admin/src/views/user/detail.vue:
- 基本信息 Tab
- 角色管理
- 会议记录 Tab(占位,后续完善)
Step 7: 运行验证
Expected: 管理端可以查看用户列表、搜索筛选、查看详情、启用/禁用用户
Step 8: Commit
git add backend/go-service/app/admin/ admin/src/
git commit -m "feat(admin): 用户管理模块(列表、详情、状态管理、角色分配)"
Task 11: 端到端集成测试与文档
Files:
- Create:
backend/go-service/Dockerfile - Modify:
deploy/docker-compose.dev.yml— 添加 go-service - Create:
README.md— 项目说明文档
Step 1: 创建 Go 服务 Dockerfile
创建 backend/go-service/Dockerfile,多阶段构建:
- 第一阶段:Go 编译
- 第二阶段:alpine 运行镜像
Step 2: 更新 Docker Compose
在 deploy/docker-compose.dev.yml 中添加 go-service 服务。
Step 3: 编写项目 README
更新根目录 README.md:
- 项目简介
- 技术栈
- 项目结构
- 开发环境搭建步骤
- API 文档链接
Step 4: 完整流程验证
- Docker Compose 启动所有服务
- 访问前台 H5 → 注册 → 登录 → 查看个人中心 → 退出
- 访问管理端 → 管理员登录 → 查看用户列表 → 查看用户详情
Step 5: Commit
git add .
git commit -m "feat: 第一阶段完成(基础设施 + 用户体系 + 管理端用户管理)"
阶段完成标准
- Docker Compose 开发环境可一键启动(PostgreSQL + Redis)
- Go 后端服务骨架完整(配置、日志、数据库、中间件)
- 用户注册/登录 API 正常工作(邮箱+密码、用户名+密码)
- JWT Token 认证机制正常(Access Token + Refresh Token)
- RBAC 角色权限体系正常(user / admin / super_admin)
- uniapp 前端骨架完整(请求封装、状态管理、路由)
- 前台登录/注册页面可用
- 前台 TabBar 框架和个人中心可用
- Vue 3 管理端项目搭建完成(布局、路由、登录)
- 管理端用户管理模块可用(列表、详情、状态管理)
- 所有代码已提交 Git