新增:开发文档

This commit is contained in:
ivan 2026-02-14 18:59:36 +08:00
parent 25455e1a81
commit a7bbc509da
32 changed files with 1193 additions and 0 deletions

View File

@ -0,0 +1,37 @@
---
description: 修改或新增 src/ 代码时同步更新 docs/ 技术文档
globs: src/**/*
alwaysApply: false
---
# 文档同步规则
当你在 `src/` 下**新增或修改**任何文件时,必须同步更新 `docs/` 中对应的技术文档。
## 文件映射关系
| 源文件 | 文档路径 |
|--------|----------|
| `src/api/*.ts` | `docs/api/*.md` |
| `src/stores/*.ts` | `docs/stores/*.md` |
| `src/composables/*.ts` | `docs/composables/*.md` |
| `src/views/*.vue` | `docs/views/*.md` |
| `src/components/*.vue` | `docs/components/*.md` |
| `src/main.ts` | `docs/core/main.md` |
| `src/App.vue` | `docs/core/App.md` |
| `src/router/index.ts` | `docs/core/router.md` |
| `src/plugins/*.ts` | `docs/core/*.md`(如 vuetify.md |
## 文档结构要求
每个文档需包含以下三部分:
1. **功能用途**:该文件/模块的职责与核心能力
2. **使用方式**调用示例、Props/Events、API 用法
3. **扩展方式**:如何修改、新增功能
API 与组件文档需补充类型说明、Props、Events 等。
## 示例
修改 `src/api/event.ts` 后,需更新 `docs/api/event.md`;新增 `src/api/order.ts` 时,需新建 `docs/api/order.md`。

143
docs/FEATURES.md Normal file
View File

@ -0,0 +1,143 @@
# 功能实现状态
本文档列出项目中**已实现**与**未实现**的功能,便于开发与迭代时参考。
---
## 已实现功能
### 认证与用户
| 功能 | 说明 |
|------|------|
| 钱包登录 (SIWE) | 通过 MetaMask 等钱包签名,调用 `/base/walletLogin` 获取 token存入 userStore |
| 用户信息 | `getUserInfo` 获取头像、昵称等,登录后自动拉取 |
| USDC 余额 | `getUsdcBalance` 获取余额,除以 1_000_000 后展示 |
| 登出 | 清空 token、user移除 localStorage |
### 首页 (Home)
| 功能 | 说明 |
|------|------|
| 分类 Tab | 调用 `getPmTagMain` 获取分类树,支持三层;接口失败时回退 `MOCK_CATEGORY_TREE` |
| 事件列表 | `getPmEventPublic` 分页获取,支持 keyword、tagSlug、tagId 等筛选 |
| 搜索 | 关键词搜索、搜索历史localStorage最多 10 条) |
| 下拉刷新 | VPullToRefresh 组件 |
| 无限滚动 | 滚动到底部加载更多 |
| 列表缓存 | 切换页面时复用 `eventListCache`,下拉刷新时清空 |
| 单一/多选项卡片 | MarketCard 支持 singleYes/No与 multi轮播多选项 |
### 交易详情 (TradeDetail)
| 功能 | 说明 |
|------|------|
| 事件详情 | `findPmEvent` 按 id/slug 获取,需鉴权 |
| 分时图 | ECharts 渲染,时间粒度 1H/6H/1D/1W/1M/ALL**当前为本地生成 mock 数据** |
| 交易组件 | Buy/Sell、Market 模式、Merge、Split |
| 下单 | `pmOrderPlace` 调用 CLOB 下单接口 |
| Split | `pmMarketSplit` 用 USDC 兑换 Yes+No |
| Merge | `pmMarketMerge` 合并 Yes+No 得 USDC |
| 移动端适配 | 底部 Yes/No 栏 + 弹窗交易组件 |
| 多市场切换 | 支持 query.marketId 指定当前 market |
### 钱包 (Wallet)
| 功能 | 说明 |
|------|------|
| Portfolio 卡片 | 展示 userStore.balance |
| Deposit/Withdraw 弹窗 | UI 完整Deposit 展示固定地址与二维码Withdraw 支持金额、网络、目标地址选择 |
| 取消订单 | `pmCancelOrder` 调用真实接口,**但 Positions/Open orders/History 数据为 mock** |
| Profit/Loss 图表 | ECharts 展示,**数据为 mock** |
| Positions/Orders/History Tab | 表格与移动端列表,**数据为 mock** |
| 搜索、分页 | 对 mock 数据生效 |
### 事件市场列表 (EventMarkets)
| 功能 | 说明 |
|------|------|
| 事件详情 | `findPmEvent` 获取,失败时用 `getMockEventById` 兜底 |
| 市场列表 | 展示该 Event 下多个 Market可点击跳转交易详情 |
### API 层
| 模块 | 已实现 |
|------|--------|
| request | get、post支持 BASE_URL、自定义 headers |
| event | getPmEventPublic、findPmEvent、mapEventItemToCard、缓存 |
| category | getPmTagMain、enrichWithIcons、MOCK_CATEGORY_TREE |
| categoryIcons | resolveCategoryIcon、resolveCategoryIconColor |
| market | pmOrderPlace、pmCancelOrder、pmMarketSplit、pmMarketMerge |
| user | getUserInfo、getUsdcBalance、formatUsdcBalance |
| constants | OrderType、Side |
### 其他
| 功能 | 说明 |
|------|------|
| 路由 | 6 个页面createWebHistory |
| Keep-alive | Home 页面缓存 |
| 多语言 | 当前中英混用,无 i18n |
---
## 未实现 / Mock 功能
### 认证
| 功能 | 状态 |
|------|------|
| 邮箱密码登录 | 仅前端校验,无真实 API 调用,直接跳转首页 |
### 首页
| 功能 | 状态 |
|------|------|
| 分类接口失败兜底 | 使用 MOCK_CATEGORY_TREE非真实数据 |
### 交易详情
| 功能 | 状态 |
|------|------|
| 分时图数据 | 本地 `generateData()` 生成随机曲线,未对接 WebSocket 或历史接口 |
| Comments | 占位文案 "No comments yet." |
| Top Holders | 占位文案 "Top holders will appear here." |
| Activity | 使用硬编码 mock 数据,未对接交易活动接口 |
### 订单簿 (OrderBook)
| 功能 | 状态 |
|------|------|
| Asks/Bids | 硬编码 mock 数据,定时随机变化模拟 |
| Last/Spread | mock |
| 真实订单簿 | 需对接 CLOB 或 WebSocket |
### 钱包
| 功能 | 状态 |
|------|------|
| Positions | mock 数据 |
| Open orders | mock 数据,取消订单调用真实 API 但列表为 mock |
| History | mock 数据 |
| Profit/Loss 图表 | mock 数据 |
| Portfolio 余额 | 来自 userStore真实非 mock |
| Deposit 实际充值 | 仅展示地址与二维码,未对接链上或托管充值 |
| Withdraw 实际提现 | 仅 UI 流程,未对接提现接口 |
| Close Losses | TODO未实现 |
| Export | TODO未实现 |
| 筛选/排序 | 部分按钮为占位,未实现逻辑 |
### 其他
| 功能 | 状态 |
|------|------|
| 注册页 | 路由未配置Login 中链接指向 `/register` |
| Limit 单 | TradeComponent 有 Limit 选项,下单逻辑以 Market 为主 |
| 订单簿点击下单 | 点击某行价格填入 TradeComponent 未实现 |
---
## 实现优先级建议
1. **高**订单簿真实数据、分时图真实数据、Positions/Orders/History 真实接口
2. **中**Comments、Top Holders、Activity 接口Deposit/Withdraw 实际流程
3. **低**邮箱密码登录、注册页、Limit 单完善

70
docs/README.md Normal file
View File

@ -0,0 +1,70 @@
# PolyClientVuetify 开发文档
本目录包含项目各模块的详细开发文档,每个文件对应一份文档,说明其功能用途、使用方式及扩展方法。
## 功能实现状态
**[FEATURES.md](./FEATURES.md)**:已实现功能与未实现/Mock 功能清单,含实现优先级建议。
## 文档结构
```
docs/
├── README.md # 本索引文件
├── api/ # API 层
│ ├── request.md
│ ├── event.md
│ ├── category.md
│ ├── categoryIcons.md
│ ├── market.md
│ ├── user.md
│ ├── constants.md
│ └── mockEventList.md
├── stores/ # Pinia 状态
│ ├── user.md
│ └── counter.md
├── composables/ # 组合式函数
│ └── useSearchHistory.md
├── views/ # 页面视图
│ ├── Home.md
│ ├── Trade.md
│ ├── TradeDetail.md
│ ├── EventMarkets.md
│ ├── Login.md
│ └── Wallet.md
├── components/ # 可复用组件
│ ├── MarketCard.md
│ ├── TradeComponent.md
│ ├── OrderBook.md
│ ├── HorizontalProgressBar.md
│ ├── DepositDialog.md
│ └── WithdrawDialog.md
├── core/ # 核心入口与配置
│ ├── main.md
│ ├── App.md
│ ├── router.md
│ └── vuetify.md
└── config/ # 构建与工具配置
├── vite.md
└── package.md
```
## 技术栈概览
- **框架**Vue 3Composition API+ TypeScript
- **构建**Vite 7路径别名 `@/*``./src/*`
- **UI**Vuetify 4
- **状态**Pinia
- **路由**Vue Router 5
## 快速导航
| 模块 | 说明 |
|------|------|
| [API 层](./api/) | 请求封装、接口函数、类型定义 |
| [Stores](./stores/) | 全局状态管理 |
| [Composables](./composables/) | 组合式函数 |
| [Views](./views/) | 页面级视图,对应路由 |
| [Components](./components/) | 可复用 UI 组件 |
| [Core](./core/) | 入口、路由、插件 |
| [Config](./config/) | 构建与工具配置 |

39
docs/api/category.md Normal file
View File

@ -0,0 +1,39 @@
# category.ts
**路径**`src/api/category.ts`
## 功能用途
分类Tag相关接口与数据结构对接 `/PmTag/getPmTagList`,获取首页顶部分类 Tab 数据。支持树形结构、图标自动匹配、按 sort 排序。
## 核心能力
- `getPmTagMain`:获取主分类树,返回 `CategoryTreeNode[]`
- `enrichWithIcons`:递归为节点补充 MDI 图标(无 icon 时自动匹配)
- `MOCK_CATEGORY_TREE`:模拟分类数据,用于开发/测试
## 类型说明
| 类型 | 说明 |
|------|------|
| `PmTagMainItem` | 接口返回的 PmTag 结构,含 children |
| `CategoryTreeNode` | 前端使用的树节点,含 id、label、slug、icon、sectionTitle、children |
## 使用方式
```typescript
import { getPmTagMain, enrichWithIcons, MOCK_CATEGORY_TREE } from '@/api/category'
// 获取分类
const res = await getPmTagMain()
const tree = res.data // 已包含图标、排序
// 开发时使用 mock
const mockTree = enrichWithIcons(MOCK_CATEGORY_TREE)
```
## 扩展方式
1. **新增分类层级**:在 `CategoryTreeNode` 中扩展字段,`getPmTagMain``mapPmTagToTreeNode` 中映射
2. **自定义图标**:在 `categoryIcons.ts` 中扩展 `ICON_MAP``enrichWithIcons` 会自动使用
3. **过滤逻辑**:在 `getPmTagMain` 中根据 `forceShow`/`forceHide` 过滤节点

42
docs/api/categoryIcons.md Normal file
View File

@ -0,0 +1,42 @@
# categoryIcons.ts
**路径**`src/api/categoryIcons.ts`
## 功能用途
根据分类的 label/slug 自动解析 MDI 图标名和颜色,供首页分类 Tab 使用。项目已引入 `@mdi/font`,图标名为 `mdi-xxx` 格式。
## 核心能力
- `resolveCategoryIcon`:根据 label/slug 返回 MDI 图标名,无匹配时返回 `DEFAULT_CATEGORY_ICON`
- `resolveCategoryIconColor`:返回 Vuetify 颜色名或 CSS 颜色
- `DEFAULT_CATEGORY_ICON`:默认图标 `mdi-tag-outline`
## 匹配优先级
1. 节点已有 `icon` 且以 `mdi-` 开头 → 直接使用
2. 精确匹配 slug
3. 精确匹配 label
4. 关键词匹配 label`LABEL_KEYWORDS`
5. 默认图标
## 使用方式
```typescript
import {
resolveCategoryIcon,
resolveCategoryIconColor,
DEFAULT_CATEGORY_ICON,
} from '@/api/categoryIcons'
// 在模板中
<v-icon :color="resolveCategoryIconColor(item) ?? 'grey'">
{{ item.icon || resolveCategoryIcon(item) || DEFAULT_CATEGORY_ICON }}
</v-icon>
```
## 扩展方式
1. **新增分类图标**:在 `ICON_MAP` 中增加 `slug -> mdi-xxx` 映射
2. **新增颜色**:在 `ICON_COLOR_MAP``LABEL_COLOR_KEYWORDS` 中增加
3. **正则匹配**:在 `LABEL_KEYWORDS` 中使用 RegExp`/^\d+[mhd]$/i`

44
docs/api/constants.md Normal file
View File

@ -0,0 +1,44 @@
# constants.ts
**路径**`src/api/constants.ts`
## 功能用途
交易相关常量订单类型OrderType、交易方向Side用于 market 接口入参。
## 常量说明
### OrderType
| 值 | 常量 | 说明 |
|----|------|------|
| 0 | GTC | Good Till Cancelled一直有效直到取消 |
| 1 | GTD | Good Till Date指定时间内有效 |
| 2 | FOK | Fill Or Kill全部成交或立即取消 |
| 3 | FAK | Fill And Kill (IOC),立即成交,剩余取消 |
| 4 | Market | 市价单 |
### Side
| 值 | 常量 | 说明 |
|----|------|------|
| 1 | Buy | 买入 |
| 2 | Sell | 卖出 |
## 使用方式
```typescript
import { OrderType, Side } from '@/api/constants'
// 下单时
await pmOrderPlace({
orderType: OrderType.GTC,
side: Side.Buy,
// ...
})
```
## 扩展方式
1. **新增订单类型**:在 `OrderType` 中增加,并同步后端定义
2. **业务枚举**:可在此文件或新建 `enums.ts` 中集中管理

51
docs/api/event.md Normal file
View File

@ -0,0 +1,51 @@
# event.ts
**路径**`src/api/event.ts`
## 功能用途
Event预测市场事件相关接口与类型定义对接 XTrader API 的 `/PmEvent/*` 接口。提供事件列表、详情查询,以及将接口数据映射为首页卡片所需结构的工具函数。
## 核心能力
- `getPmEventPublic`:分页获取公开事件列表(无需鉴权)
- `findPmEvent`:按 id/slug 查询事件详情(需鉴权)
- `mapEventItemToCard`:将 `PmEventListItem` 转为 `EventCardItem`(供 MarketCard 使用)
- 内存缓存:`getEventListCache``setEventListCache``clearEventListCache`,用于列表切换页面时复用
## 类型说明
| 类型 | 说明 |
|------|------|
| `PmEventListItem` | 接口返回的事件项 |
| `PmEventMarketItem` | 市场项,含 outcomes、outcomePrices、clobTokenIds |
| `EventCardItem` | 首页卡片所需结构,含 displayTypesingle/multi |
| `EventCardOutcome` | 多选项卡片中单个选项 |
| `PageResult<T>` | 分页结果 |
## 使用方式
```typescript
import {
getPmEventPublic,
findPmEvent,
mapEventItemToCard,
clearEventListCache,
} from '@/api/event'
// 获取列表
const res = await getPmEventPublic({ page: 1, pageSize: 10, tagSlug: 'crypto' })
const cards = res.data.list.map(mapEventItemToCard)
// 获取详情(需鉴权)
const detail = await findPmEvent({ id: 123 }, { headers: authHeaders })
// 下拉刷新时清空缓存
clearEventListCache()
```
## 扩展方式
1. **新增筛选参数**:在 `GetPmEventListParams` 中增加字段,并在 `getPmEventPublic` 的 query 中传入
2. **缓存策略**:可改为 sessionStorage 或带 TTL 的缓存
3. **多选项展示**`mapEventItemToCard` 已支持 multi 类型,可扩展 `EventCardOutcome` 字段

63
docs/api/market.md Normal file
View File

@ -0,0 +1,63 @@
# market.ts
**路径**`src/api/market.ts`
## 功能用途
交易与市场相关接口下单、取消订单、SplitUSDC 换 Yes+No、MergeYes+No 换 USDC。对接 CLOB Gateway 与 PmMarket 接口。
## 核心能力
- `pmOrderPlace`:下单(买入/卖出 Yes 或 No
- `pmCancelOrder`:取消订单
- `pmMarketSplit`:用 USDC 兑换 Yes+No 份额
- `pmMarketMerge`:合并 Yes+No 份额得到 USDC
## 类型说明
| 类型 | 说明 |
|------|------|
| `ClobSubmitOrderRequest` | 下单请求体,含 tokenID、price、size、side 等 |
| `ClobCancelOrderRequest` | 取消订单请求体 |
| `PmMarketSplitRequest` | Split 请求体marketID、usdcAmount |
| `PmMarketMergeRequest` | Merge 请求体marketID、amount |
## 使用方式
```typescript
import {
pmOrderPlace,
pmCancelOrder,
pmMarketSplit,
pmMarketMerge,
} from '@/api/market'
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
const headers = userStore.getAuthHeaders()
if (!headers) return
// 下单
await pmOrderPlace(
{
tokenID: clobTokenId,
price: 3700, // 37¢ = 3700
size: 100,
side: Side.Buy,
// ... 其他字段
},
{ headers }
)
// Split
await pmMarketSplit({ marketID: '123', usdcAmount: '10' }, { headers })
// Merge
await pmMarketMerge({ marketID: '123', amount: '5' }, { headers })
```
## 扩展方式
1. **批量下单**:封装 `pmOrderPlace` 循环或对接批量接口
2. **订单状态查询**:新增 `getOpenOrders``getOrderHistory` 等接口
3. **价格/数量校验**:在调用前增加业务校验逻辑

27
docs/api/mockEventList.md Normal file
View File

@ -0,0 +1,27 @@
# mockEventList.ts
**路径**`src/api/mockEventList.ts`
## 功能用途
模拟事件列表数据 `MOCK_EVENT_LIST`,用于本地开发、测试,覆盖单一 marketUp/Down、Yes/No、多 markets 轮播等场景。
## 核心能力
- 提供 `PmEventListItem[]` 格式的 mock 数据
- 包含单一 market、多 market 等多种结构
- 可与 `mapEventItemToCard` 配合使用
## 使用方式
```typescript
import { MOCK_EVENT_LIST } from '@/api/mockEventList'
import { mapEventItemToCard } from '@/api/event'
const cards = MOCK_EVENT_LIST.map(mapEventItemToCard)
```
## 扩展方式
1. **新增 mock 项**:在 `MOCK_EVENT_LIST` 中追加符合 `PmEventListItem` 结构的对象
2. **环境切换**:在 Home 等视图中根据 `import.meta.env.DEV` 选择使用 mock 或真实接口

40
docs/api/request.md Normal file
View File

@ -0,0 +1,40 @@
# request.ts
**路径**`src/api/request.ts`
## 功能用途
HTTP 请求基础封装,提供 `get``post` 方法,支持自定义请求头(如鉴权 `x-token``x-user-id`)。所有 API 模块均通过此文件发起请求。
## 核心能力
- 统一 BASE_URL默认 `https://api.xtrader.vip`,可通过环境变量 `VITE_API_BASE_URL` 覆盖
- GET 请求:支持 query 参数,自动序列化
- POST 请求:支持 JSON body
- 自定义 headers通过 `RequestConfig.headers` 传入
## 使用方式
```typescript
import { get, post } from '@/api/request'
// GET 请求
const data = await get<MyResponse>('/path', { page: 1, keyword: 'x' })
// 带鉴权
const data = await get<MyResponse>('/path', undefined, {
headers: { 'x-token': token, 'x-user-id': userId },
})
// POST 请求
const res = await post<MyResponse>('/path', { key: 'value' }, {
headers: { 'x-token': token },
})
```
## 扩展方式
1. **添加 PUT/DELETE**:仿照 `get`/`post` 实现 `put``del` 函数
2. **统一错误处理**:在 `get`/`post` 内对 `!res.ok` 做统一 toast 或错误上报
3. **请求/响应拦截**:在 fetch 前后加入拦截逻辑(如 loading、日志
4. **超时控制**:使用 `AbortController` 实现超时取消

41
docs/api/user.md Normal file
View File

@ -0,0 +1,41 @@
# user.ts
**路径**`src/api/user.ts`
## 功能用途
用户相关接口获取用户信息、USDC 余额。对接 `/user/getUserInfo``/user/getUsdcBalance`,均需鉴权。
## 核心能力
- `getUserInfo`:获取当前用户信息(头像、昵称等)
- `getUsdcBalance`:查询 USDC 余额amount、available、locked 需除以 1_000_000
- `formatUsdcBalance`:将原始数值转为显示用字符串(如 "0.00"
## 类型说明
| 类型 | 说明 |
|------|------|
| `UserInfoData` | 用户信息结构 |
| `UsdcBalanceData` | 余额结构amount/available/locked 为原始值 |
## 使用方式
```typescript
import { getUserInfo, getUsdcBalance, formatUsdcBalance } from '@/api/user'
const headers = { 'x-token': token, 'x-user-id': userId }
const userRes = await getUserInfo(headers)
const balanceRes = await getUsdcBalance(headers)
if (balanceRes.data) {
const display = formatUsdcBalance(balanceRes.data.available)
}
```
## 扩展方式
1. **更新个人信息**:新增 `updateUserInfo` 接口
2. **交易记录**:新增 `getUserTrades` 等接口
3. **多币种**:扩展 `UsdcBalanceData` 支持其他资产

View File

@ -0,0 +1,30 @@
# DepositDialog.vue
**路径**`src/components/DepositDialog.vue`
## 功能用途
充值弹窗,支持 Transfer Crypto、Connect Exchange 等方式。展示充值地址、网络选择、二维码等。
## Props
| 属性 | 类型 | 说明 |
|------|------|------|
| modelValue | boolean | v-model 控制显隐 |
| balance | string | 当前余额展示 |
## 事件
- `update:modelValue`:关闭时更新
## 使用方式
```vue
<DepositDialog v-model="depositDialogOpen" :balance="portfolioBalance" />
```
## 扩展方式
1. **真实充值**:对接链上或托管充值接口
2. **多链**:扩展 networks 列表,支持更多网络
3. **历史记录**:展示最近充值记录

View File

@ -0,0 +1,34 @@
# HorizontalProgressBar.vue
**路径**`src/components/HorizontalProgressBar.vue`
## 功能用途
横向进度条,用于订单簿深度展示等场景。根据 `value`/`max` 计算百分比宽度,支持自定义轨道与填充样式。
## Props
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| max | number | 100 | 最大值 |
| value | number | 0 | 当前值 |
| className | string | '' | 自定义类名 |
| trackStyle | object | {} | 轨道样式 |
| fillStyle | object | {} | 填充样式 |
## 使用方式
```vue
<HorizontalProgressBar
:max="maxAsksTotal"
:value="ask.total"
:fill-style="{ backgroundColor: '#e89595' }"
:track-style="{ backgroundColor: 'transparent' }"
/>
```
## 扩展方式
1. **动画**:增加 `transition``animation` 配置
2. **渐变**`fillStyle` 支持 `background: linear-gradient(...)`
3. **垂直模式**:增加 `vertical` prop切换为纵向进度条

View File

@ -0,0 +1,59 @@
# MarketCard.vue
**路径**`src/components/MarketCard.vue`
## 功能用途
首页事件卡片组件展示市场标题、概率、Yes/No 或 Up/Down 按钮、多选项轮播。支持单一single与多选项multi两种展示类型点击可跳转交易详情或直接发起交易。
## Props
| 属性 | 类型 | 说明 |
|------|------|------|
| id | string | 事件 ID |
| marketTitle | string | 市场标题 |
| chanceValue | number | 概率值0100 |
| marketInfo | string | 如 "$1.2k Vol." |
| imageUrl | string | 图片 URL |
| category | string | 分类 |
| expiresAt | string | 到期日 |
| displayType | 'single' \| 'multi' | 展示类型 |
| outcomes | EventCardOutcome[] | 多选项时每项数据 |
| yesLabel / noLabel | string | 按钮文案 |
| isNew | boolean | 是否显示 NEW 角标 |
| marketId | string | 市场 ID |
| clobTokenIds | string[] | 下单用 token ID |
## 事件
- `navigate`:点击卡片跳转
- `trade`:点击 Yes/No 发起交易,携带 market 信息
## 使用方式
```vue
<MarketCard
:id="item.id"
:market-title="item.marketTitle"
:chance-value="item.chanceValue"
:market-info="item.marketInfo"
:image-url="item.imageUrl"
:category="item.category"
:expires-at="item.expiresAt"
:display-type="item.displayType"
:outcomes="item.outcomes"
:yes-label="item.yesLabel"
:no-label="item.noLabel"
:is-new="item.isNew"
:market-id="item.marketId"
:clob-token-ids="item.clobTokenIds"
@navigate="goToDetail"
@trade="openTrade"
/>
```
## 扩展方式
1. **新展示类型**:扩展 `displayType`,如 `compact``featured`
2. **收藏/分享**:增加图标按钮与对应事件
3. **骨架屏**:增加 loading 态 props

View File

@ -0,0 +1,27 @@
# OrderBook.vue
**路径**`src/components/OrderBook.vue`
## 功能用途
订单簿组件,展示 Asks卖单与 Bids买单列表含价格、份额、累计总量以及横向进度条表示深度。当前使用 mock 数据。
## 核心能力
- Trade Up / Trade Down Tab
- Asks、Bids 列表,带 `HorizontalProgressBar` 深度条
- Last price、Spread 展示
## 使用方式
```vue
<OrderBook />
```
当前为展示组件,无 props。后续可扩展为接收 `marketId` 等,从接口或 WebSocket 获取真实数据。
## 扩展方式
1. **真实数据**:接收 `asks``bids` props或内部根据路由/context 拉取
2. **WebSocket**:订阅订单簿推送,实时更新
3. **点击下单**:点击某行价格时,将价格传入 TradeComponent

View File

@ -0,0 +1,39 @@
# TradeComponent.vue
**路径**`src/components/TradeComponent.vue`
## 功能用途
交易核心组件,支持 Buy/Sell、Market/Limit、Merge/Split。根据 `market``initialOption` 展示 Yes/No 或 Up/Down 价格,计算 Total、To win、You'll receive 等,并调用 `pmOrderPlace``pmMarketSplit``pmMarketMerge`
## Props
| 属性 | 类型 | 说明 |
|------|------|------|
| market | object | 市场信息,含 marketId、clobTokenIds、outcomes、outcomePrices 等 |
| initialOption | 'yes' \| 'no' | 初始选中的选项 |
| embeddedInSheet | boolean | 是否嵌入底部弹窗(移动端) |
## 核心能力
- Buy/Sell Tab 切换
- Market/Limit 类型、Merge/Split 菜单
- 余额不足时 Buy 显示 Deposit 按钮
- 25%/50%/Max 快捷份额
- 调用 market API 下单、Split、Merge
## 使用方式
```vue
<TradeComponent
:market="tradeMarketPayload"
:initial-option="tradeInitialOption"
embedded-in-sheet
/>
```
## 扩展方式
1. **Limit 单**:完善 Limit 模式下的价格输入与下单逻辑
2. **订单确认**:增加确认弹窗
3. **滑点设置**:增加滑点配置

View File

@ -0,0 +1,30 @@
# WithdrawDialog.vue
**路径**`src/components/WithdrawDialog.vue`
## 功能用途
提现弹窗支持输入金额、选择网络、选择提现目标Connected wallet / Custom address
## Props
| 属性 | 类型 | 说明 |
|------|------|------|
| modelValue | boolean | v-model 控制显隐 |
| balance | string | 当前余额展示 |
## 事件
- `update:modelValue`:关闭时更新
## 使用方式
```vue
<WithdrawDialog v-model="withdrawDialogOpen" :balance="portfolioBalance" />
```
## 扩展方式
1. **真实提现**:对接提现接口,校验余额与地址
2. **手续费**:展示网络手续费与到账金额
3. **限额**:增加单笔/每日限额校验

View File

@ -0,0 +1,37 @@
# useSearchHistory.ts
**路径**`src/composables/useSearchHistory.ts`
## 功能用途
搜索历史组合式函数,将关键词持久化到 localStorage`polyclient_search_history`),最多保留 10 条,去重且新词置顶。
## 核心能力
- `list`:只读的搜索历史数组
- `add(keyword)`:添加关键词,去重并限制数量
- `remove(index)`:删除指定索引
- `clearAll`:清空全部
## 使用方式
```typescript
import { useSearchHistory } from '@/composables/useSearchHistory'
const searchHistory = useSearchHistory()
// 提交搜索时
searchHistory.add(searchKeyword)
// 展示历史
const searchHistoryList = searchHistory.list.value
// 清空
searchHistory.clearAll()
```
## 扩展方式
1. **分类历史**:扩展为 `useSearchHistory(category)`,按分类存储
2. **同步服务端**:在 `add` 时调用接口同步到后端
3. **最大条数**:修改 `MAX_HISTORY` 常量

31
docs/config/package.md Normal file
View File

@ -0,0 +1,31 @@
# package.json
**路径**`package.json`
## 功能用途
项目依赖与脚本定义。
## 主要脚本
| 命令 | 说明 |
|------|------|
| npm run dev | 启动开发服务器 |
| npm run build | 类型检查 + 构建 |
| npm run deploy | 打包并通过 SSH 部署 |
| npm run preview | 预览构建产物 |
| npm run test:unit | Vitest 单测 |
| npm run test:e2e | Playwright E2E |
| npm run format | Prettier 格式化 |
## 核心依赖
- Vue 3、Vue Router 5、Pinia、Vuetify 4
- ethers、siwe钱包登录
- echarts图表
- @mdi/font(图标)
## 扩展方式
- 新增脚本:在 `scripts` 中增加
- 新增依赖:`npm install xxx` 或手动编辑后 `npm install`

19
docs/config/vite.md Normal file
View File

@ -0,0 +1,19 @@
# vite.config.ts
**路径**`vite.config.ts`
## 功能用途
Vite 7 构建配置包含路径别名、Vue 插件、Node polyfills用于 ethers、SIWE 等)、开发服务器 host。
## 关键配置
- `resolve.alias``@``./src`
- `vite-plugin-node-polyfills`:解决 SIWE 等库的 Node 兼容
- `server.host: true`:监听 0.0.0.0,支持局域网访问
## 扩展方式
1. **环境变量**:在 `define` 中注入 `import.meta.env.XXX`
2. **代理**`server.proxy` 解决跨域
3. **构建优化**`build.rollupOptions` 分包、压缩

20
docs/core/App.md Normal file
View File

@ -0,0 +1,20 @@
# App.vue
**路径**`src/App.vue`
## 功能用途
根组件,包含全局 AppBar、主内容区router-view。AppBar 含返回按钮、标题、登录/余额/头像菜单,主内容区使用 keep-alive 缓存 Home。
## 核心能力
- 顶部导航栏返回、PolyMarket 标题、Login 或余额+头像菜单
- 登录态:`userStore.isLoggedIn` 控制展示
- 挂载时:若已登录,拉取用户信息与余额
- keep-alive`include="['Home']"` 缓存首页
## 扩展方式
1. **多级导航**:根据路由深度调整返回逻辑
2. **主题切换**:增加亮/暗模式切换
3. **多语言**:接入 i18n 插件

17
docs/core/main.md Normal file
View File

@ -0,0 +1,17 @@
# main.ts
**路径**`src/main.ts`
## 功能用途
应用入口,创建 Vue 实例并挂载 Pinia、Router、Vuetify 插件。
## 使用方式
`index.html` 中的脚本加载,无需手动调用。
## 扩展方式
1. **全局错误处理**`app.config.errorHandler`
2. **全局属性**`app.config.globalProperties`
3. **新插件**`app.use(plugin)` 注册

30
docs/core/router.md Normal file
View File

@ -0,0 +1,30 @@
# router/index.ts
**路径**`src/router/index.ts`
## 功能用途
Vue Router 配置,定义路由表与滚动行为。
## 路由表
| path | name | component |
|------|------|-----------|
| / | home | Home |
| /trade | trade | Trade |
| /login | login | Login |
| /trade-detail/:id | trade-detail | TradeDetail |
| /event/:id/markets | event-markets | EventMarkets |
| /wallet | wallet | Wallet |
## 滚动行为
- 有 `savedPosition` 且来自已命名路由:恢复位置
- 有 `to.hash`:滚动到锚点
- 否则:滚动到顶部
## 扩展方式
1. **路由守卫**`beforeEach` 做鉴权、重定向
2. **懒加载**`component: () => import('./views/Home.vue')`
3. **meta**:为路由增加 `meta.requiresAuth`

18
docs/core/vuetify.md Normal file
View File

@ -0,0 +1,18 @@
# plugins/vuetify.ts
**路径**`src/plugins/vuetify.ts`
## 功能用途
Vuetify 4 插件配置,注册组件、指令、主题。引入 VPullToRefresh下拉刷新与 MDI 图标。
## 主题
- `light`:默认主题,含 primary、secondary、accent 等
- `dark`:暗色主题
## 扩展方式
1. **自定义主题**:在 `themes` 中增加新主题,或修改现有颜色
2. **新组件**:从 `vuetify/labs` 引入并注册
3. **RTL**:配置 `rtl: true` 支持从右到左布局

21
docs/stores/counter.md Normal file
View File

@ -0,0 +1,21 @@
# counter.ts (Store)
**路径**`src/stores/counter.ts`
## 功能用途
示例 Pinia Store用于演示 setup 写法:`count``doubleCount``increment`。项目中可能仅用于测试或示例,业务可忽略。
## 使用方式
```typescript
import { useCounterStore } from '@/stores/counter'
const counter = useCounterStore()
counter.increment()
console.log(counter.doubleCount)
```
## 扩展方式
可删除或改为业务相关 demo如示例数据 store

43
docs/stores/user.md Normal file
View File

@ -0,0 +1,43 @@
# user.ts (Store)
**路径**`src/stores/user.ts`
## 功能用途
用户登录态与基础信息的 Pinia Store管理 token、user、余额并提供鉴权请求头。登录数据持久化到 localStorage`poly-user`)。
## 核心能力
- `token``user`:登录凭证与用户信息
- `isLoggedIn``avatarUrl`:派生状态
- `balance`USDC 余额显示(如 "0.00"
- `setUser`:设置登录数据并持久化
- `logout`:清空并清除持久化
- `getAuthHeaders`:返回 `{ 'x-token', 'x-user-id' }`,未登录时返回 `undefined`
- `fetchUserInfo``fetchUsdcBalance`:拉取并更新用户信息与余额
## 使用方式
```typescript
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
// 登录后设置
userStore.setUser({ token: 'xxx', user: { id: 1, nickName: 'User' } })
// 鉴权请求
const headers = userStore.getAuthHeaders()
if (headers) {
await someApiCall(undefined, { headers })
}
// 刷新余额
await userStore.fetchUsdcBalance()
```
## 扩展方式
1. **多端登录**:扩展 `setUser` 支持多设备 token 管理
2. **Token 刷新**:在 `getAuthHeaders` 或请求拦截器中加入 refresh 逻辑
3. **登出回调**:在 `logout` 中增加清理逻辑(如取消订阅、重置其他 store

View File

@ -0,0 +1,18 @@
# EventMarkets.vue
**路径**`src/views/EventMarkets.vue`
**路由**`/event/:id/markets`name: `event-markets`
## 功能用途
事件下的市场列表页,展示某个 Event 的多个 Market如 NFL 多支队伍),支持选择并跳转交易详情。
## 使用方式
- 从首页或详情进入,路由 `/event/123/markets`
- 路由参数 `id` 为 Event ID
## 扩展方式
- 增加市场筛选、排序
- 与 TradeDetail 联动,支持从市场列表直接进入指定 market 的交易

27
docs/views/Home.md Normal file
View File

@ -0,0 +1,27 @@
# Home.vue
**路径**`src/views/Home.vue`
**路由**`/`name: `home`
## 功能用途
首页,展示分类 Tab、搜索、事件卡片列表。支持三层分类、下拉刷新、无限滚动、搜索历史卡片支持单一/多选项展示。
## 核心能力
- 分类:第一层 Tab、第二层图标、第三层 Tab`getPmTagMain` 获取
- 搜索:展开浮层、历史记录、`useSearchHistory`
- 列表:`getPmEventPublic` 分页、`mapEventItemToCard` 映射、`MarketCard` 渲染
- 缓存:`eventListCache` 切换页面时复用,下拉刷新时清空
- Keep-alive`Home` 被 include切换回来时保留状态
## 使用方式
- 访问 `/` 即可进入
- 分类切换、搜索、下拉刷新、滚动加载均自动工作
## 扩展方式
1. **新增筛选**:在搜索浮层旁增加筛选按钮,修改 `getPmEventPublic` 的 params
2. **骨架屏**:在 loading 时展示 `v-skeleton-loader`
3. **空状态**:列表为空时展示空状态插画与文案

25
docs/views/Login.md Normal file
View File

@ -0,0 +1,25 @@
# Login.vue
**路径**`src/views/Login.vue`
**路由**`/login`name: `login`
## 功能用途
登录页,支持邮箱+密码登录与钱包连接SIWE。登录成功后调用 `userStore.setUser` 并跳转首页。
## 核心能力
- 邮箱密码:表单校验,调用登录接口
- 钱包连接ethers + SIWE签名后换取 token
- 错误提示:`errorMessage` 展示
## 使用方式
- 未登录时点击 AppBar 的 Login 进入
- 登录成功后自动跳转 `/`
## 扩展方式
1. **注册**:增加注册表单或跳转注册页(路由 `/register` 需在 router 中配置)
2. **忘记密码**:增加找回密码流程
3. **社交登录**:接入 OAuth 等

17
docs/views/Trade.md Normal file
View File

@ -0,0 +1,17 @@
# Trade.vue
**路径**`src/views/Trade.vue`
**路由**`/trade`name: `trade`
## 功能用途
交易入口页,展示可交易市场列表或快捷入口,通常作为交易功能的聚合入口。
## 使用方式
访问 `/trade` 进入。
## 扩展方式
- 可增加市场筛选、推荐市场、最近交易等模块
- 可与 TradeDetail 联动,支持从列表直接跳转详情并预选市场

28
docs/views/TradeDetail.md Normal file
View File

@ -0,0 +1,28 @@
# TradeDetail.vue
**路径**`src/views/TradeDetail.vue`
**路由**`/trade-detail/:id`name: `trade-detail`
## 功能用途
交易详情页展示单个市场的分时图、订单簿、Comments/Top Holders/Activity 标签页以及右侧交易组件Buy/Sell、Merge/Split。支持桌面端与移动端布局移动端使用底部 Yes/No 栏 + 弹窗。
## 核心能力
- 分时图ECharts 渲染,支持 Past、时间粒度切换
- 订单簿:`OrderBook` 组件
- 交易:`TradeComponent`,传入 `market``initialOption`
- 移动端:底部栏 + `v-bottom-sheet` 嵌入 `TradeComponent`
- Merge/Split通过 `TradeComponent` 或底部菜单触发
## 使用方式
- 从首页卡片点击进入,或直接访问 `/trade-detail/123`
- 路由参数 `id` 为 Event ID用于 `findPmEvent`
## 扩展方式
1. **实时数据**:订单簿、分时图接入 WebSocket
2. **Comments**:对接评论接口,替换 placeholder
3. **Top Holders**:对接持仓接口
4. **Activity**:对接交易活动接口,替换 mock 数据

26
docs/views/Wallet.md Normal file
View File

@ -0,0 +1,26 @@
# Wallet.vue
**路径**`src/views/Wallet.vue`
**路由**`/wallet`name: `wallet`
## 功能用途
钱包页,展示 Portfolio、Profit/Loss、Positions、Open orders、History。支持 Deposit/Withdraw 弹窗、搜索、筛选(如 Close Losses
## 核心能力
- Portfolio 卡片余额、Deposit/Withdraw 按钮
- Profit/Loss 卡片时间范围切换、ECharts 图表
- TabPositions、Open orders、History
- DepositDialog、WithdrawDialog 组件
## 使用方式
- 登录后点击 AppBar 余额或头像菜单进入
- 路由 `/wallet`
## 扩展方式
1. **真实数据**Positions、Orders、History 对接接口
2. **导出**History 支持导出 CSV
3. **筛选**:按市场、时间、盈亏等筛选