Browse Source

docs: 更新 agents 与 mall 设计文档

Co-authored-by: Cursor <cursoragent@cursor.com>
master
dark 1 month ago
parent
commit
4f61f0de68
  1. 249
      agents.md
  2. 378
      mall-design.md

249
agents.md

@ -3,6 +3,30 @@
- 涉及到任何代码修改,记得更新此文档和设计文档
- 需求记录文档: [`docs/REQUIREMENTS.md`](docs/REQUIREMENTS.md)
## 前端开发启动
使用统一启动脚本,自动检查端口占用并清理后启动:
```bash
# 同时启动 健康APP(5173) + 商城(5174)
npm run dev # 或 node scripts/dev.js
# 仅启动健康APP
npm run dev:web # 或 node scripts/dev.js web
# 仅启动商城
npm run dev:mall # 或 node scripts/dev.js mall
# 仅关闭占用端口的进程
npm run dev:kill # 或 node scripts/dev.js --kill
```
| 项目 | 目录 | 端口 | 说明 |
|------|------|------|------|
| 健康APP (web) | `web/` | 5173 | 健康AI助手前端 |
| 健康商城 (mall) | `mall/` | 5174 | 独立商城前端 |
| 后端 API | `server/` | 8080 | Go-Zero 后端 |
## 前端自动化测试规范
**重要**: 前端进行功能更新和修改后,必须使用 Playwright 进行自动化测试验证。
@ -17,6 +41,9 @@ tests/
├── constitution.test.js # 体质分析功能测试
├── profile.test.js # "我的"页面功能测试
├── health-profile-complete.test.js # 健康档案完整功能测试(推荐)
├── chat.test.js # 问答页对话管理与流式输出测试
├── mall.test.js # 商城前端测试(53项,含公开浏览+登录守卫,API Mock)
├── mall-real.test.js # 商城前端真实数据测试(52项,需后端)
└── screenshots/ # 测试截图目录
```
@ -408,3 +435,225 @@ const result = {
- 过敏记录: 4 个字段(过敏类型、过敏原、严重程度、过敏反应描述)
- 测试结果: **58/58 通过**
- 测试截图: `tests/screenshots/hp-*.png`
---
### 2026-02-02: AI 问答功能增强
**修改内容**:
1. **等待动画**: 添加 LoadingDots 组件,在等待 AI 回复和思考过程中显示动态加载动画
2. **思考过程显示**: 支持显示 AI 思考过程(需要模型支持 `enable_thinking`
3. **放开思考过程过滤**: 移除之前添加的关键词过滤逻辑,完整显示 AI 思考内容
**修改文件**:
- `app/src/screens/chat/ChatDetailScreen.tsx`:
- 添加 `LoadingDots` 组件,实现三个点的脉冲动画
- 在 AI 回复等待时显示 "AI 正在回复..."
- 在思考过程等待时显示 "💭 思考中..."
- `server/internal/service/ai/aliyun.go`:
- 移除 `thinkingFilterKeywords` 关键词列表
- 移除 `shouldFilterThinking` 过滤函数
- 简化思考过程流式输出,直接转发不过滤
- `server/config.yaml`:
- 注释掉 `app_id` 配置(应用 API 格式与 OpenAI 兼容模式不同,暂不支持)
**LoadingDots 组件示例**:
```tsx
const LoadingDots = ({ text = "思考中", fontSize = 15 }) => {
const [dotCount, setDotCount] = useState(1);
useEffect(() => {
const interval = setInterval(() => {
setDotCount((prev) => (prev >= 3 ? 1 : prev + 1));
}, 400);
return () => clearInterval(interval);
}, []);
return (
<Text style={{ fontSize, color: colors.textSecondary }}>
{text}
{".".repeat(dotCount)}
</Text>
);
};
```
**备注**:
- 阿里云百炼应用 API 需要使用专用的 `/api/v1/apps/{APP_ID}/completion` 端点,与当前 OpenAI 兼容模式实现不同
- 思考过程功能需要使用支持 `enable_thinking` 参数的模型(如 qwen-plus)
---
### 2026-02-03: 商城后端 API 开发
**内容**: 在现有健康AI后端基础上扩展商城功能,共享用户体系和JWT认证
**新增模型**:
- `ProductCategory` - 商品分类
- `ProductSku` - 商品SKU
- `PointsRecord` - 积分变动记录
- `CartItem` - 购物车
- `Address` - 收货地址
- `Order` / `OrderItem` - 订单
**新增API路由** (`/api/mall`):
- 公开路由: 分类列表、商品列表/详情/搜索/推荐
- 认证路由: 会员信息、积分、购物车CRUD、地址CRUD、订单全流程、体质推荐
**API定义**: `backend/healthapi/healthapi.api` (商城部分在文件末尾)
**测试**: `backend/healthapi/tests/mall_api_test.go` - 30个Go集成测试全部通过
---
### 2026-02-07: 商城 Web H5 前端开发 → 独立项目拆分
**内容**: 基于 Vue 3 + TypeScript + Element Plus 开发商城 Web H5 前端,后拆分为独立项目
**项目结构调整**:
商城从 `web/` 项目中拆分为独立的 `mall/` 项目:
- `web/` (端口 5173) - 健康AI助手前端
- `mall/` (端口 5174) - 健康商城前端
- 两个项目共享同一后端(端口 8080)和 JWT Token(通过 localStorage 共享)
- 双向跳转通过 `VITE_MALL_URL` / `VITE_HEALTH_AI_URL` 环境变量配置
**mall/ 项目文件结构**:
```
mall/
├── package.json # 独立依赖管理
├── vite.config.ts # Vite 配置(端口 5174)
├── tsconfig.json # TypeScript 配置
├── .env # 环境变量(API地址、健康AI地址)
├── index.html
└── src/
├── main.ts # 入口文件
├── App.vue
├── router/index.ts # 路由(根路径 / 开头)
├── api/
│ ├── request.ts # Axios 封装(共享Token拦截器)
│ ├── auth.ts # 认证 API
│ └── mall.ts # 商城 API(商品/购物车/订单/地址/会员)
├── stores/
│ ├── auth.ts # 认证状态(从 localStorage 恢复)
│ ├── constitution.ts # 体质数据(从 localStorage 读取)
│ ├── mall.ts # 购物车和分类
│ ├── order.ts # 订单
│ └── member.ts # 会员信息
├── types/index.ts # 商城类型定义 + 体质类型
├── utils/healthAI.ts # 健康AI跳转工具
├── styles/index.scss # 全局样式
└── views/
├── layout/MallLayout.vue # H5布局
└── mall/ # 10个页面
├── MallHomeView.vue # 首页
├── CategoryView.vue # 分类
├── ProductDetailView.vue # 商品详情
├── SearchView.vue # 搜索
├── CartView.vue # 购物车
├── CheckoutView.vue # 结算
├── OrderListView.vue # 订单列表
├── OrderDetailView.vue # 订单详情
├── AddressListView.vue # 地址管理
└── MemberView.vue # 会员中心
```
**web/ 项目变更**:
- 移除所有商城代码(views/mall/、stores/mall|order|member、api/mall、utils/healthAI等)
- `web/src/router/index.ts` - 移除 `/mall` 路由组
- `web/src/views/home/HomeView.vue` - "健康商城"改为外部链接跳转
- `web/src/views/profile/ProfileView.vue` - "健康商城"改为外部链接跳转
- `web/src/types/index.ts` - 移除商城类型定义
- `web/.env` - 新增 `VITE_MALL_URL` 环境变量
**认证策略(按需登录)**:
商城采用"公开浏览 + 按需登录"策略,用户可自由浏览商品,仅在涉及个人数据的操作时要求登录:
| 页面/操作 | 是否需要登录 | 说明 |
|-----------|:----------:|------|
| 首页、分类、商品详情、搜索 | 否 | 自由浏览 |
| 加入购物车、立即购买 | 是 | 弹窗引导登录 |
| 购物车、结算、订单 | 是 | 路由守卫重定向 |
| 地址管理、会员中心 | 是 | 路由守卫重定向 |
- 路由守卫:仅 `meta.requiresAuth` 的路由会重定向到 `/login`
- 操作拦截:`useAuthCheck().requireAuth()` 弹窗引导登录
- 401 处理:API 返回 401 时清除 token 并跳转到本地登录页
**跨项目跳转机制**:
```
健康AI (web/) ←→ 商城 (mall/)
├── 共享: localStorage 中的 token 和 user 信息
├── web → mall: window.open(VITE_MALL_URL)
├── mall → web: jumpToHealthAI() / goToHealthAI()
└── mall 独立登录: /login 页面(不再依赖 web 登录页)
```
**启动方式**:
```bash
# 健康AI前端
cd web && npm run dev # http://localhost:5173
# 商城前端
cd mall && npm run dev # http://localhost:5174
# 后端
cd backend && go run . # http://localhost:8080
```
**设计规范**:
- 主色调: #52C41A (绿色/健康主题)
- 价格色: #FF4D4F
- H5 布局 max-width: 750px
- 面向中老年用户:大字体、大按钮、简洁流程
- 与健康AI双向跳转集成(AI咨询悬浮按钮、体质推荐等)
---
### 2026-02-07: 商城认证策略优化 — 公开浏览 + 按需登录
**需求**: 商城应允许用户自由浏览商品,仅在生成订单或支付时才需要登录
**修改内容**:
1. **路由守卫改造** (`mall/src/router/index.ts`):
- 取消全局登录拦截,改为按路由标记 `meta.requiresAuth`
- 公开页面(首页/分类/商品详情/搜索)无需登录
- 受保护页面(购物车/订单/结算/地址/会员)需要登录
2. **操作级登录引导** (`mall/src/utils/auth.ts`):
- 新增 `useAuthCheck()` composable
- `requireAuth(message)` 方法:未登录时弹 `ElMessageBox.confirm` 引导登录
- 用于商品详情页的"加入购物车"和"立即购买"按钮
3. **商品详情页** (`mall/src/views/mall/ProductDetailView.vue`):
- `handleAddToCart()``handleBuyNow()` 执行前调用 `requireAuth()` 检查
4. **测试更新** (`tests/mall.test.js`):
- 新增 Phase 7A: 未登录公开浏览测试(首页/分类/商品/搜索可正常访问)
- 更新 Phase 7B: 受保护页面重定向测试(5个路由均重定向到 /login)
- 53项测试全部通过
**新增文件**:
- `mall/src/utils/auth.ts` - 认证检查 composable
**修改文件**:
- `mall/src/router/index.ts` - 路由守卫改造
- `mall/src/views/mall/ProductDetailView.vue` - 按钮登录检查
- `tests/mall.test.js` - 测试更新

378
mall-design.md

@ -2,6 +2,43 @@
> 关联项目:健康AI问询助手
> 开发顺序:在健康AI问询助手项目完成后开发
> **实现状态**: 后端API已完成,前端待开发
---
## 实现进度
### 后端开发状态 ✅ 已完成
| 模块 | 状态 | 说明 |
|------|------|------|
| 会员系统 | ✅ 完成 | 会员等级(普通/银卡/金卡/钻石)、积分、折扣 |
| 商品模块 | ✅ 完成 | 分类、商品列表、详情、SKU、搜索 |
| 购物车 | ✅ 完成 | 增删改查、批量操作、库存检查 |
| 收货地址 | ✅ 完成 | 地址管理、默认地址 |
| 订单系统 | ✅ 完成 | 订单创建、支付、取消、确认收货 |
| 体质推荐 | ✅ 完成 | 基于用户体质的商品推荐 |
| 用户共享 | ✅ 完成 | 与健康AI共用用户表和JWT认证 |
### 前端开发状态
| 平台 | 状态 | 说明 |
|------|------|------|
| Web (Vue3) | ✅ 完成 | 独立 `mall/` 项目(10个页面 + 布局 + API层 + 状态管理) |
| React Native | 📋 待开发 | APP端商城界面 |
### 前端项目架构
```
healthApps/
├── web/ → 健康AI助手前端 (端口 5173)
├── mall/ → 健康商城前端 (端口 5174) ← 独立项目
└── backend/ → 共享后端 (端口 8080)
```
- `web/``mall/` 为独立 Vue 3 项目,各自有 `package.json`
- 共享同一后端 API 和 JWT Token(通过 localStorage)
- 通过环境变量配置双向跳转 URL
---
@ -36,11 +73,16 @@
|------|----------|------|
| Web前端 | Vue 3 + TypeScript + Vite | 与健康AI项目保持一致 |
| APP端 | React Native + TypeScript | 与健康AI项目保持一致 |
| 后端服务 | Go + Gin + GORM | 与健康AI项目保持一致 |
| 后端服务 | Go + go-zero + GORM | 与健康AI项目保持一致(已迁移) |
| 数据库 | SQLite / PostgreSQL | 支持切换,与健康AI共享用户表 |
| 支付对接 | 微信支付 / 支付宝 | 预留接口 |
| 对象存储 | 阿里云OSS / 本地存储 | 产品图片存储 |
> **框架说明**: 后端使用 go-zero 微服务框架,保持与健康AI后端一致。
> - API定义: 使用 .api 文件定义接口
> - ORM: 继续使用 GORM 进行数据库操作
> - 认证: 使用 go-zero 内置 JWT 中间件
### 2.2 系统架构图
```
@ -87,6 +129,46 @@
| 体质信息获取 | 商城 ← 健康AI | 商城调用健康AI接口获取用户体质,优化推荐排序 |
| 购买记录同步 | 商城 → 健康AI | 用户购买保健品后,同步到健康AI用于AI问诊参考 |
### 2.4 会员系统设计 (已实现)
#### 会员等级体系
| 等级 | 升级条件 | 折扣 | 积分倍率 | 包邮门槛 |
|------|----------|------|----------|----------|
| 普通用户 | 默认 | 无 | 1.0x | ¥99 |
| 银卡会员 | 累计消费≥¥500 | 98折 | 1.2x | ¥69 |
| 金卡会员 | 累计消费≥¥2000 | 95折 | 1.5x | ¥49 |
| 钻石会员 | 累计消费≥¥5000 | 92折 | 2.0x | 全场包邮 |
#### 积分规则
- **获取**: 订单支付后按实付金额 × 等级倍率获得积分
- **使用**: 100积分 = 1元,单笔订单最多抵扣20%
- **有效期**: 获得后1年过期
#### 数据模型 (已实现)
```go
// User 扩展字段
type User struct {
// ... 基础字段
MemberLevel string // normal/silver/gold/diamond
TotalSpent float64 // 累计消费
Points int // 当前积分
MemberSince *time.Time // 首次消费时间
}
// 积分变动记录
type PointsRecord struct {
UserID uint
Type string // earn/spend/expire/adjust
Points int // 变动积分(正负)
Balance int // 变动后余额
Source string // order/activity/system
ReferenceID uint // 关联订单ID
}
```
---
## 三、功能模块
@ -473,6 +555,132 @@ POST /api/favorites # 添加收藏
DELETE /api/favorites/:product_id # 取消收藏
```
### 5.7 go-zero API 定义示例
```api
// mallapi.api - 商城API定义文件
syntax = "v1"
info(
title: "保健品商城API"
desc: "健康AI配套商城服务"
author: "healthApps"
version: "1.0"
)
// ==================== 类型定义 ====================
type (
// 产品
Product {
ID uint `json:"id"`
Name string `json:"name"`
Category string `json:"category"`
MainImage string `json:"main_image"`
SalePrice float64 `json:"sale_price"`
OriginalPrice float64 `json:"original_price,omitempty"`
SalesCount int `json:"sales_count"`
Stock int `json:"stock"`
}
ProductListReq {
Category string `form:"category,optional"`
Page int `form:"page,default=1"`
PageSize int `form:"page_size,default=20"`
Sort string `form:"sort,optional"` // price_asc, price_desc, sales
}
ProductListResp {
List []Product `json:"list"`
Total int64 `json:"total"`
}
// 购物车
CartItem {
ID uint `json:"id"`
ProductID uint `json:"product_id"`
SkuID uint `json:"sku_id,omitempty"`
Name string `json:"name"`
Image string `json:"image"`
Price float64 `json:"price"`
Quantity int `json:"quantity"`
Selected bool `json:"selected"`
}
AddCartReq {
ProductID uint `json:"product_id"`
SkuID uint `json:"sku_id,omitempty"`
Quantity int `json:"quantity,default=1"`
}
// 订单
CreateOrderReq {
AddressID uint `json:"address_id"`
CartIDs []uint `json:"cart_ids"`
Remark string `json:"remark,optional"`
}
OrderResp {
OrderNo string `json:"order_no"`
Status string `json:"status"`
TotalAmount float64 `json:"total_amount"`
PayAmount float64 `json:"pay_amount"`
}
)
// ==================== 公开接口(无需认证)====================
@server(
prefix: /api/mall
)
service mallapi-api {
@doc "产品列表"
@handler GetProductList
get /products (ProductListReq) returns (ProductListResp)
@doc "产品详情"
@handler GetProduct
get /products/:id returns (Product)
@doc "产品搜索"
@handler SearchProducts
get /products/search returns (ProductListResp)
@doc "分类列表"
@handler GetCategories
get /categories returns ([]Category)
}
// ==================== 需要认证的接口 ====================
@server(
prefix: /api/mall
jwt: Auth
)
service mallapi-api {
@doc "获取购物车"
@handler GetCart
get /cart returns ([]CartItem)
@doc "添加到购物车"
@handler AddToCart
post /cart (AddCartReq) returns (CartItem)
@doc "创建订单"
@handler CreateOrder
post /orders (CreateOrderReq) returns (OrderResp)
@doc "订单列表"
@handler GetOrders
get /orders returns ([]OrderResp)
@doc "体质推荐产品"
@handler GetRecommendProducts
get /recommend returns (ProductListResp)
}
```
---
## 六、项目目录结构
@ -512,39 +720,45 @@ healthMall/
│ │ └── utils/
│ └── package.json
├── server/ # 后端服务
│ ├── cmd/
│ │ └── main.go
│ ├── internal/
│ │ ├── api/
│ │ │ ├── handler/
│ │ │ │ ├── product.go
│ │ │ │ ├── cart.go
│ │ │ │ ├── order.go
│ │ │ │ ├── payment.go
│ │ │ │ └── address.go
│ │ │ ├── middleware/
│ │ │ └── router.go
│ │ ├── model/
│ │ │ ├── product.go
│ │ │ ├── cart.go
│ │ │ ├── order.go
│ │ │ ├── payment.go
│ │ │ └── address.go
│ │ ├── repository/
│ │ ├── service/
│ │ │ ├── product.go
│ │ │ ├── cart.go
│ │ │ ├── order.go
│ │ │ └── payment.go
│ │ ├── database/
│ │ └── config/
│ ├── pkg/
│ │ ├── payment/ # 支付SDK封装
│ │ │ ├── wechat.go
│ │ │ └── alipay.go
│ │ └── logistics/ # 物流查询
│ └── go.mod
├── backend/ # 后端服务 (go-zero)
│ └── mallapi/ # 商城API服务
│ ├── mallapi.go # 主入口
│ ├── mallapi.api # API定义文件
│ ├── etc/
│ │ └── mallapi-api.yaml # 配置文件
│ ├── internal/
│ │ ├── config/
│ │ │ └── config.go # 配置结构
│ │ ├── handler/ # 请求处理器 (goctl生成)
│ │ │ ├── product_handler.go
│ │ │ ├── cart_handler.go
│ │ │ ├── order_handler.go
│ │ │ ├── payment_handler.go
│ │ │ ├── address_handler.go
│ │ │ └── routes.go
│ │ ├── logic/ # 业务逻辑
│ │ │ ├── product_logic.go
│ │ │ ├── cart_logic.go
│ │ │ ├── order_logic.go
│ │ │ ├── payment_logic.go
│ │ │ └── address_logic.go
│ │ ├── model/ # GORM模型
│ │ │ ├── product.go
│ │ │ ├── cart.go
│ │ │ ├── order.go
│ │ │ ├── payment.go
│ │ │ └── address.go
│ │ ├── svc/
│ │ │ └── service_context.go # 服务上下文
│ │ ├── types/
│ │ │ └── types.go # 请求/响应类型 (goctl生成)
│ │ └── database/
│ │ └── database.go # 数据库初始化
│ └── pkg/
│ ├── payment/ # 支付SDK封装
│ │ ├── wechat.go
│ │ └── alipay.go
│ └── logistics/ # 物流查询
├── config.yaml # 配置文件
└── README.md
@ -599,14 +813,28 @@ healthMall/
### 8.2 开发任务清单
**后端开发:**
1. 项目初始化(共用健康AI的基础架构)
**后端开发(go-zero):**
1. 项目初始化
- 使用 goctl 生成项目骨架:`goctl api new mallapi`
- 编写 mallapi.api 定义文件
- 配置与健康AI共享的数据库和JWT密钥
2. 产品模块(详情、SKU、库存)
- GORM 模型定义
- 产品列表、详情、搜索接口
3. 购物车模块
- 添加、修改、删除购物车
4. 地址管理模块
- CRUD 地址接口
5. 订单模块(创建、状态流转)
- 订单创建、列表、详情
- 订单状态机实现
6. 支付模块(微信/支付宝)
7. 健康AI对接(用户认证、体质推荐、订单同步)
- 支付SDK封装
- 回调处理
7. 健康AI对接
- JWT Token 共享认证
- 体质推荐产品接口
- 购买记录同步接口
**Web前端开发:**
1. 项目初始化
@ -630,21 +858,38 @@ healthMall/
### 9.1 用户认证集成
商城与健康AI共享同一套JWT认证,使用相同的 AccessSecret:
```yaml
# mallapi-api.yaml 配置(与健康AI保持一致)
Auth:
AccessSecret: health-ai-secret-key-change-in-production
AccessExpire: 86400
```
```go
// 商城服务验证Token时,调用健康AI的JWT验证
func ValidateToken(token string) (*UserClaims, error) {
// 使用相同的JWT密钥验证
// 或调用健康AI的 /api/auth/validate 接口
// go-zero 内置 JWT 中间件自动验证
// 在 .api 文件中使用 jwt:Auth 标记需要认证的路由
@server(
prefix: /api/mall
jwt: Auth
)
service mallapi-api {
@handler GetCart
get /cart returns (CartResp)
}
```
### 9.2 体质推荐集成
```go
// 商城首页获取用户体质推荐产品
func GetConstitutionRecommend(userID uint) ([]Product, error) {
// 1. 调用健康AI接口获取用户体质
// GET http://health-ai-server/api/constitution/result
// internal/logic/recommend_logic.go
func (l *RecommendLogic) GetConstitutionRecommend() (*types.RecommendResp, error) {
userID, _ := logic.GetUserIDFromCtx(l.ctx)
// 1. 从共享数据库获取用户体质
var assessment model.ConstitutionAssessment
l.svcCtx.DB.Where("user_id = ?", userID).Order("assessed_at DESC").First(&assessment)
// 2. 根据体质查询推荐产品
// SELECT * FROM products p
@ -873,6 +1118,47 @@ storage:
---
> **文档版本**: v1.0
## 附录B:后端API汇总 (已实现)
### 商城公开接口 (/api/mall)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /categories | 获取商品分类 |
| GET | /products | 商品列表 |
| GET | /products/:id | 商品详情 |
| GET | /products/search | 搜索商品 |
| GET | /products/featured | 推荐商品 |
### 商城认证接口 (/api/mall,需JWT)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /member/info | 获取会员信息 |
| GET | /member/points/records | 积分变动记录 |
| GET | /cart | 获取购物车 |
| POST | /cart | 添加到购物车 |
| PUT | /cart/:id | 更新购物车项 |
| DELETE | /cart/:id | 删除购物车项 |
| POST | /cart/batch-select | 批量选中 |
| DELETE | /cart/clear | 清空购物车 |
| GET | /addresses | 地址列表 |
| POST | /addresses | 创建地址 |
| PUT | /addresses/:id | 更新地址 |
| DELETE | /addresses/:id | 删除地址 |
| PUT | /addresses/:id/default | 设为默认 |
| GET | /orders | 订单列表 |
| GET | /orders/:id | 订单详情 |
| POST | /orders/preview | 订单预览 |
| POST | /orders | 创建订单 |
| POST | /orders/:id/pay | 支付订单 |
| POST | /orders/:id/cancel | 取消订单 |
| POST | /orders/:id/receive | 确认收货 |
| GET | /products/constitution-recommend | 体质推荐商品 |
---
> **文档版本**: v1.3
> **更新日期**: 2026-02-07
> **创建日期**: 2026-02-01
> **关联项目**: 健康AI问询助手

Loading…
Cancel
Save