新增:文档更新

This commit is contained in:
ivan 2026-03-20 17:05:49 +08:00
parent afdc5edcca
commit f1dfbf7d80
11 changed files with 6652 additions and 16 deletions

6493
design/pencil-new.pen Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
## 功能用途 ## 功能用途
HTTP 请求基础封装,提供 `get``post``buildQuery` 方法,以及 WebSocket URL 生成。所有 API 模块均通过此文件发起请求。 HTTP 请求基础封装,提供 `get``post``put`、`buildQuery` 方法,以及 WebSocket URL 生成。所有 API 模块均通过此文件发起请求。
## 核心能力 ## 核心能力
@ -14,13 +14,14 @@ HTTP 请求基础封装,提供 `get`、`post`、`buildQuery` 方法,以及 W
- User WebSocket URL`getUserWsUrl()` 返回 `ws(s)://host/clob/ws/user`(订单/持仓/余额推送) - User WebSocket URL`getUserWsUrl()` 返回 `ws(s)://host/clob/ws/user`(订单/持仓/余额推送)
- GET 请求:支持 query 参数,自动序列化 - GET 请求:支持 query 参数,自动序列化
- POST 请求:支持 JSON body - POST 请求:支持 JSON body
- PUT 请求:支持 JSON body
- 自定义 headers通过 `RequestConfig.headers` 传入 - 自定义 headers通过 `RequestConfig.headers` 传入
- **Accept-Language**:所有 GET/POST 请求自动附带当前 vue-i18n 的 `locale` - **Accept-Language**:所有 GET/POST/PUT 请求自动附带当前 vue-i18n 的 `locale`
## 使用方式 ## 使用方式
```typescript ```typescript
import { get, post, buildQuery, getClobWsUrl, getUserWsUrl } from '@/api/request' import { get, post, put, buildQuery, getClobWsUrl, getUserWsUrl } from '@/api/request'
// 构建 query自动过滤空值 // 构建 query自动过滤空值
const query = buildQuery({ page: 1, pageSize: 10, keyword, tagIds }) const query = buildQuery({ page: 1, pageSize: 10, keyword, tagIds })
@ -39,11 +40,16 @@ const data = await get<MyResponse>('/path', undefined, {
const res = await post<MyResponse>('/path', { key: 'value' }, { const res = await post<MyResponse>('/path', { key: 'value' }, {
headers: { 'x-token': token }, headers: { 'x-token': token },
}) })
// PUT 请求
const putRes = await put<MyResponse>('/path', { key: 'value' }, {
headers: { 'x-token': token },
})
``` ```
## 扩展方式 ## 扩展方式
1. **添加 PUT/DELETE**:仿照 `get`/`post` 实现 `put``del` 函数 1. **添加 DELETE**:仿照 `get`/`post`/`put` 实现 `del` 函数
2. **统一错误处理**:在 `get`/`post` 内对 `!res.ok` 做统一 toast 或错误上报 2. **统一错误处理**:在 `get`/`post` 内对 `!res.ok` 做统一 toast 或错误上报
3. **请求/响应拦截**:在 fetch 前后加入拦截逻辑(如 loading、日志 3. **请求/响应拦截**:在 fetch 前后加入拦截逻辑(如 loading、日志
4. **超时控制**:使用 `AbortController` 实现超时取消 4. **超时控制**:使用 `AbortController` 实现超时取消

View File

@ -4,12 +4,13 @@
## 功能用途 ## 功能用途
用户相关接口获取用户信息、USDC 余额。对接 `/user/getUserInfo``/user/getUsdcBalance`,均需鉴权。 用户相关接口获取用户信息、USDC 余额、修改自身用户名。对接 `/user/getUserInfo``/user/getUsdcBalance`、`/user/setSelfUsername`,均需鉴权。
## 核心能力 ## 核心能力
- `getUserInfo`:获取当前用户信息(头像、昵称等) - `getUserInfo`:获取当前用户信息(头像、昵称等)
- `getUsdcBalance`:查询 USDC 余额amount、available、locked 需除以 1_000_000 - `getUsdcBalance`:查询 USDC 余额amount、available、locked 需除以 1_000_000
- `setSelfUsername`修改自身用户名PUT `/user/setSelfUsername`
- `formatUsdcBalance`:将原始数值转为显示用字符串(如 "0.00" - `formatUsdcBalance`:将原始数值转为显示用字符串(如 "0.00"
## 类型说明 ## 类型说明
@ -22,7 +23,7 @@
## 使用方式 ## 使用方式
```typescript ```typescript
import { getUserInfo, getUsdcBalance, formatUsdcBalance } from '@/api/user' import { getUserInfo, getUsdcBalance, setSelfUsername, formatUsdcBalance } from '@/api/user'
const headers = { 'x-token': token, 'x-user-id': userId } const headers = { 'x-token': token, 'x-user-id': userId }
@ -32,6 +33,12 @@ const balanceRes = await getUsdcBalance(headers)
if (balanceRes.data) { if (balanceRes.data) {
const display = formatUsdcBalance(balanceRes.data.available) const display = formatUsdcBalance(balanceRes.data.available)
} }
// 修改自身用户名
const setRes = await setSelfUsername(headers, { username: 'new_username' })
if (setRes.code === 0 || setRes.code === 200) {
// 建议:成功后调用 fetchUserInfo() 刷新页面展示
}
``` ```
## 扩展方式 ## 扩展方式

View File

@ -12,6 +12,7 @@
- Asks、Bids 列表,带 `HorizontalProgressBar` 深度条(买卖两边共用同一最大值 `maxOrderBookTotal`,取两边累计总量中的最大值,便于对比深度) - Asks、Bids 列表,带 `HorizontalProgressBar` 深度条(买卖两边共用同一最大值 `maxOrderBookTotal`,取两边累计总量中的最大值,便于对比深度)
- Last price、Spread 展示 - Last price、Spread 展示
- Live / 连接中 状态展示(均通过 i18n 国际化) - Live / 连接中 状态展示(均通过 i18n 国际化)
- Header 右侧已移除折叠箭头图标(`mdi-chevron-up`),仅保留状态文案与成交量文案
## Props ## Props

View File

@ -4,20 +4,27 @@
## 功能用途 ## 功能用途
根组件,包含全局 AppBar、主内容区router-view。AppBar 含返回按钮、标题、登录/余额/头像菜单,主内容区使用 keep-alive 缓存 Home。 根组件,包含全局 AppBar、主内容区router-view。AppBar 含返回按钮、标题、登录/余额/头像入口,主内容区使用 keep-alive 缓存 Home。
## 核心能力 ## 核心能力
- 顶部导航栏返回、TestMarket 标题、Login 或余额+用户名+头像菜单 - 顶部导航栏返回、TestMarket 标题、Login 或余额+头像入口
- 多语言入口:右侧地球图标(`mdi-earth`+ 当前语言文案,点击打开语言选择菜单 - 头像入口:登录态点击头像直接跳转 `/profile`
- 移动端底部导航Home / Search / Mine三个 tab 等分屏宽与路由联动Mine 未登录跳转 Login选中态仅加粗、无底色未选中项图标与文字偏灰底部导航上方有淡投影 - 移动端底部导航Home / Search / Mine三个 tab 等分屏宽与路由联动Mine 点击跳转 `/profile`;选中态仅加粗、无底色;未选中项图标与文字偏灰;底部导航上方有淡投影);仅在 `/``/search``/profile` 三个主页面显示,其他页面隐藏
- 全局滚动稳定:通过 `scrollbar-gutter: stable` 保留滚动条占位,避免页面从搜索态切到结果态时出现顶部/底部导航轻微横向抖动
- 登录态:`userStore.isLoggedIn` 控制展示 - 登录态:`userStore.isLoggedIn` 控制展示
- 用户名:`nickName``userName` 显示在头像左侧(有值时) - 用户名:`nickName``userName` 显示在头像左侧(有值时)
- 挂载时与 `isLoggedIn` 变为 true 时:拉取用户信息与余额(`router.isReady()` + `nextTick` 后执行),确保钱包登录、刷新页面后头像和用户名正确显示 - 挂载时与 `isLoggedIn` 变为 true 时:拉取用户信息与余额(`router.isReady()` + `nextTick` 后执行),确保钱包登录、刷新页面后头像和用户名正确显示
- keep-alive`include="['Home']"` 缓存首页 - keep-alive`include="['Home']"` 缓存首页
## 使用方式
- 启动应用后由 `App.vue` 承载顶栏、主内容与底部导航
- 路由切换时由 `bottomNavValue` 自动同步 Home / Search / Mine 高亮状态
- 页面内容通过 `<router-view>` 渲染Home 页面使用 keep-alive 缓存
## 扩展方式 ## 扩展方式
1. **多级导航**:根据路由深度调整返回逻辑 1. **多级导航**:根据路由深度调整返回逻辑
2. **主题切换**:增加亮/暗模式切换 2. **主题切换**:增加亮/暗模式切换
3. **多语言**:接入 i18n 插件 3. **个人入口扩展**:可在个人中心页继续扩展设置项与账户操作

View File

@ -17,6 +17,8 @@ Vue Router 配置,定义路由表与滚动行为。
| /trade-detail/:id | trade-detail | TradeDetail | | /trade-detail/:id | trade-detail | TradeDetail |
| /event/:id/markets | event-markets | EventMarkets | | /event/:id/markets | event-markets | EventMarkets |
| /wallet | wallet | Wallet | | /wallet | wallet | Wallet |
| /profile | profile | Profile |
| /api-key | api-key | ApiKey |
## 滚动行为 ## 滚动行为

22
docs/views/ApiKey.md Normal file
View File

@ -0,0 +1,22 @@
# ApiKey.vue
**路径**`src/views/ApiKey.vue`
**路由**`/api-key`name: `api-key`
## 功能用途
API Key 管理页面,按 Pencil 设计稿 `WFa0K` 节点 1:1 还原。页面包含标题区(`API Key 管理` + `创建 Key` 按钮)和 API Key 卡片列表Key 名称、Key 值、复制/删除按钮)。
## 使用方式
- 访问路由 `/api-key`
- 页面展示 3 条示例 Key 数据,卡片结构如下:
- 顶部:`Key #n`
- 中部:完整 Key 字符串
- 底部:右对齐操作按钮 `复制``删除`
## 扩展方式
1. **接入真实列表**:将本地 `apiKeys` 常量替换为后端 API 数据。
2. **接入操作事件**:为 `创建 Key``复制``删除` 按钮绑定真实业务逻辑。
3. **安全策略**:可增加 Key 脱敏展示与二次确认删除弹窗。

42
docs/views/Profile.md Normal file
View File

@ -0,0 +1,42 @@
# Profile.vue
**路径**`src/views/Profile.vue`
**路由**`/profile`name: `profile`
## 功能用途
个人中心页面,按照 Pencil 设计稿(`design/pencil-new.pen``UNTdC` 节点)还原移动端 Profile Screen并接入用户态与国际化
- 从 `useUserStore` 读取昵称、UID、头像、余额、钱包地址等数据
- 页面加载后自动触发 `fetchUserInfo()``fetchUsdcBalance()`,刷新展示数据
- 支持语言切换、复制钱包地址、登出等交互逻辑
- 全量文案改为 `vue-i18n``profile.*``common.logout` 等)
## 使用方式
- 访问路由 `/profile`
- 页面会读取 `userStore.user` 作为展示数据源昵称、UID、头像、VIP 标签、钱包地址)
- 点击设置项中的 `钱包管理` 会弹出钱包地址框,显示当前钱包地址(无地址时显示 i18n 兜底文案)
- 点击设置项中的 `API KEY 管理` 会跳转到 `/api-key`
- 点击设置项中的 `语言` 会弹出语言选择框,点选后即时切换并关闭弹窗,右侧显示当前语言名称
- 点击钱包卡片的 `钱包详情` 会跳转到 `/wallet`
- 页面展示的用户名与编辑初始值统一取 `userName`(调用 `PUT /user/setSelfUsername` 后刷新);输入会提示允许格式与校验错误(至少 2 位,且仅允许 `a-z / 0-9 / _`
- 点击 `复制地址` 会写入剪贴板,并通过 toast 提示成功/失败
- 点击底部 `退出登录` 会执行异步登出(带 loading 防重复)并跳转到 `/login`
主要结构:
- Profile 卡片头像、昵称、UID、VIP 标签、编辑按钮
- Wallet 卡片:总览标题、余额、明细文案、充币/提币按钮
- 设置卡片钱包管理、API KEY 管理、语言
- 退出按钮:底部高亮按钮
## 扩展方式
1. **更新用户名错误分层**:当前错误优先展示输入校验与接口返回的 `msg`;后续可按错误码映射到更细粒度的 i18n 文案与字段提示。
2. **余额细分字段接入**:目前可用/冻结余额已支持多字段兜底,后续可统一对接后端标准字段。
3. **头像兜底增强**:当前无头像时展示昵称首字母,可扩展为默认头像资源或主题色方案。
4. **多语言持续补齐**:新增字段时同步更新 `src/locales/*.json``profile` 命名空间。
5. **长昵称适配**`.name-text` 已启用 `ellipsis` 截断,避免与右侧 `编辑` 按钮发生重叠。
6. **底部留白优化**:通过调整 `.profile-page` 的 flex 对齐方式,避免容器被拉伸导致底部空白过多。
7. **高度收缩优化**:移除了 `.profile-screen` 过高的 `min-height`(由固定值改为可收缩),减少页面因内容过少而产生滚动。

33
docs/views/Search.md Normal file
View File

@ -0,0 +1,33 @@
# Search.vue
**路径**`src/views/Search.vue`
**路由**`/search`name: `search`
## 功能用途
搜索页独立实现,按 Pencil 设计稿同文件实现双态页面:
- `p4Kcp`:搜索页(搜索框、搜索记录、推荐标签)
- `mN9t2`:搜索结果页(顶部搜索框 + 结果卡片列表)
- 页面容器改为移动端自适应宽度(`width: 100%`),不再固定 `402px`
## 使用方式
- 访问路由 `/search`
- 在搜索输入框中输入关键词后,手机键盘回车键会显示为“搜索”(`enterkeyhint="search"`
- 点击键盘“搜索”会请求 `GET /PmEvent/getPmEventPublic``keyword` 参数),并将关键词写入搜索记录顶部
- 搜索前展示 `p4Kcp` 结构:
- 顶部标题:`搜索`
- 搜索框:真实输入框,占位文案 `搜索市场、话题、地址`
- 搜索记录卡3 条示例记录,每行右侧带关闭图标
- 推荐标签卡:`ETH``科技股``总统大选`
- 搜索后切换到 `mN9t2` 结构:
- 顶部同样保留标题与搜索框
- 下方展示结果卡片列表(图标、标题、百分比、时间)
- 切换结果态时不会因滚动条变化导致顶部/底部导航轻微位移
## 扩展方式
1. **接入真实搜索记录**:将 `searchRecords` 替换为用户历史接口数据。
2. **接入搜索行为**:将搜索框改为可输入组件并绑定查询 API。
3. **标签联动搜索**:点击标签触发关键词搜索并跳转到结果页。
4. **响应式优化**:可按断点进一步细分字号与间距,但保持 1:1 视觉层级。

View File

@ -11,6 +11,7 @@
- 分时图TradingView Lightweight Charts 渲染,支持 Past、时间粒度切换1H/6H/1D/1W/1M/ALL**Yes/No 模式**数据来自 **GET /pmPriceHistory/getPmPriceHistoryPublic**market 传 clobTokenIds[0]),接口返回 `time`Unix 秒)、`price`01转成 `[timestamp_ms, value_0_100][]` 后缓存在 `rawChartData`**分时**为前端按当前选中范围过滤1H=最近 1 小时、6H=6 小时、1D=1 天、1W=7 天、1M=30 天、ALL=全部,切换时间范围不重复请求;**加密货币事件**可切换 YES/NO 分时图与加密货币价格走势图CoinGecko 实时数据),**加密货币模式默认显示 30S 分时走势图** - 分时图TradingView Lightweight Charts 渲染,支持 Past、时间粒度切换1H/6H/1D/1W/1M/ALL**Yes/No 模式**数据来自 **GET /pmPriceHistory/getPmPriceHistoryPublic**market 传 clobTokenIds[0]),接口返回 `time`Unix 秒)、`price`01转成 `[timestamp_ms, value_0_100][]` 后缓存在 `rawChartData`**分时**为前端按当前选中范围过滤1H=最近 1 小时、6H=6 小时、1D=1 天、1W=7 天、1M=30 天、ALL=全部,切换时间范围不重复请求;**加密货币事件**可切换 YES/NO 分时图与加密货币价格走势图CoinGecko 实时数据),**加密货币模式默认显示 30S 分时走势图**
- 订单簿:`OrderBook` 组件,通过 **ClobSdk** 对接 CLOB WebSocket 实时数据(全量快照、增量更新、成交推送);份额接口按 6 位小数传1_000_000 = 1 share`priceSizeToRows``mergeDelta` 会将 raw 值除以 `ORDER_BOOK_SIZE_SCALE` 转为展示值 - 订单簿:`OrderBook` 组件,通过 **ClobSdk** 对接 CLOB WebSocket 实时数据(全量快照、增量更新、成交推送);份额接口按 6 位小数传1_000_000 = 1 share`priceSizeToRows``mergeDelta` 会将 raw 值除以 `ORDER_BOOK_SIZE_SCALE` 转为展示值
- 订单簿外层容器(`order-book-card`)已去除重复外边框,仅保留 `OrderBook` 组件单层描边,避免视觉上出现双层边线
- 交易:`TradeComponent`,传入 `market``initialOption``positions`(持仓数据) - 交易:`TradeComponent`,传入 `market``initialOption``positions`(持仓数据)
- 持仓列表:通过 `getPositionList` 获取当前市场持仓,传递给 `TradeComponent` 用于计算可合并份额 - 持仓列表:通过 `getPositionList` 获取当前市场持仓,传递给 `TradeComponent` 用于计算可合并份额
- 限价订单:通过 `getOrderList` 获取当前市场未成交限价单,支持撤单 - 限价订单:通过 `getOrderList` 获取当前市场未成交限价单,支持撤单

View File

@ -5,15 +5,37 @@
## 功能用途 ## 功能用途
钱包页,展示 Portfolio、Profit/Loss、Positions、Open orders、History。支持 Deposit/Withdraw 弹窗、搜索、筛选(如 Close Losses 钱包页,展示 Portfolio、Profit/Loss 与四类交易数据Positions / Open orders / History / Withdrawals。当前已按 `design/pencil-new.pen``tuLlv``KRKZv``aRC6m``tZDYO` 节点同步为卡片化移动端布局不展示搜索栏和筛选工具栏tab 选中后直接显示列表内容。
其中 `tuLlv`Wallet - Positions已按设计稿做 1:1 样式对齐:
- 页面容器使用移动端自适应宽度(`width: 100%`),统一 `16px` 间距与内边距
- 顶部为「钱包」标题
- Portfolio 卡片使用主色背景(`$--primary`)与白色文本
- 快捷操作区为两个等宽按钮(`t('wallet.deposit')` / `t('wallet.withdraw')`
- Settlement 卡片为紧凑样式,右侧胶囊 Claim 按钮
- Wallet Section 为圆角描边卡片 + 胶囊 tabs + Positions 卡片列表
- Positions 标题区采用“右侧价格优先”的自适应布局:价格变长时标题区域自动收缩,标题单行并使用跑马灯展示超出内容,避免与价格重叠
## 核心能力 ## 核心能力
- Portfolio 卡片余额、Deposit/Withdraw 按钮 - Portfolio 卡片余额、Deposit/Withdraw 按钮
- Profit/Loss 卡片时间范围切换1D/1W/1M/ALL、Lightweight Charts 资产变化面积图;数据格式为 `[timestamp_ms, pnl][]`**暂无接口时全部显示为 0**(真实时间轴 + 数值 0有接口后在此处对接 - Profit/Loss 卡片时间范围切换1D/1W/1M/ALL、Lightweight Charts 资产变化面积图;数据格式为 `[timestamp_ms, pnl][]`**暂无接口时全部显示为 0**(真实时间轴 + 数值 0有接口后在此处对接
- TabPositions、Open orders、**History**(历史记录来自 **GET /hr/getHistoryRecordListClient**`src/api/historyRecord.ts`需鉴权、按当前用户分页、Withdrawals提现记录 - TabPositions、Open orders、**History**(历史记录来自 **GET /hr/getHistoryRecordListClient**`src/api/historyRecord.ts`需鉴权、按当前用户分页、Withdrawals提现记录
- Positions卡片展示市场图标、标题、YES/NO outcome、价值、盈亏、`t('wallet.sharesLabel')``t('wallet.avgPriceLabel')``t('wallet.currentPriceLabel')`
- Open orders卡片展示图标、标题、BUY/SELL 标签、YES/NO 标签、`t('wallet.openOrderPriceLabel')``t('wallet.filledTotalLabel')``t('wallet.orderValueLabel')`、取消按钮
- Open orders 标题区与 Positions 一致采用单行跑马灯;标题容器可自适应收缩,优先保证右侧取消按钮与数值不重叠
- Open orders 样式参数已按设计值收敛:图标 `44x44`、取消按钮 `32x32` 圆形描边、BUY/SELL 为描边矩形标签(`22px` 高、`6px` 圆角、YES/NO 为胶囊标签(`20px` 高、`999px` 圆角)
- Open orders 顶部结构按设计对齐:左侧图标置于左上,图标右侧为垂直两行(标题 + BUY/YES/NO 同行标签),右侧关闭按钮与图标处于同一顶行;下半部分独立展示价格相关三列信息
- 当接口返回的 `order.market` 为空时,标题会自动回退为 `Market · <outcome>`,避免顶部标题为空导致布局塌陷
- Open orders 卡片主容器使用纵向布局(上半结构 + 下半价格区),避免价格区被挤到右侧并出现竖排换行
- History支持两种卡片形态交易卡 + 充值/提现卡)
- History`ny6M5`)已按设计做 1:1 对齐:交易卡为“图标+标题日期+右侧金额”上行、下行“BUY/SELL 标签 + `t('wallet.priceLabel')`/`t('wallet.sharesLabel')`”;资金卡为“左侧图标与标题日期 + 右侧金额”的单行结构
- History 标题采用与 Positions/Open orders 一致的单行跑马灯方案,超出宽度时自动循环滚动展示
- Withdrawals紧凑提现卡日期、链路标签、状态标签、金额/手续费、地址)
- Withdrawals`UjOKn`)按 1:1 结构实现:顶部日期 + 链路/状态标签、中部金额与手续费双列、底部地址;并在无真实记录时提供 3 条预览数据用于视觉验收
- Withdrawals 头部布局已调整为“日期在上、chain 在日期下方、状态标签在右侧”,并收紧卡片内边距与列表间距以贴合设计稿密度
- **可结算/领取**未结算项unsettledItems由持仓中有 `marketID``tokenID`**所属 market.closed=true** 的项组成,用于「领取结算」按钮;不再使用 needClaim 判断 - **可结算/领取**未结算项unsettledItems由持仓中有 `marketID``tokenID`**所属 market.closed=true** 的项组成,用于「领取结算」按钮;不再使用 needClaim 判断
- Withdrawals分页列表状态筛选全部/审核中/提现成功/审核不通过/提现失败),对接 GET /pmset/getPmSettlementRequestsListClient - Withdrawals对接 GET /pmset/getPmSettlementRequestsListClient,保留状态映射展示
- DepositDialog、WithdrawDialog 组件 - DepositDialog、WithdrawDialog 组件
- **401 权限错误**:取消订单等接口失败时,通过 `useAuthError().formatAuthError` 统一提示「请先登录」或「权限不足」 - **401 权限错误**:取消订单等接口失败时,通过 `useAuthError().formatAuthError` 统一提示「请先登录」或「权限不足」
@ -24,6 +46,6 @@
## 扩展方式 ## 扩展方式
1. **真实数据**Positions、Orders、History 对接接口 1. **真实字段补全**:若后端补充订单价值、手续费等字段,可替换当前前端组合文案(如 `price × total`)。
2. **导出**History 支持导出 CSV 2. **卡片交互增强**:可在不改变结构前提下添加点击展开、跳转详情、快捷撤单等行为。
3. **筛选**:按市场、时间、盈亏等筛选 3. **视觉主题扩展**:保持当前卡片信息架构,按主题变量调整色彩与密度以适配暗色模式。