优化:增加模拟数据开关
This commit is contained in:
parent
4ab5ffa6af
commit
ddca28e51c
@ -6,6 +6,14 @@
|
||||
# WebSocket 路径前缀(可选)。若 CLOB WS 在 /api/clob/ws 且 API base 无 /api,则设:
|
||||
# VITE_WS_PATH_PREFIX=/api
|
||||
#
|
||||
# 模拟数据开关(方便本地测试):
|
||||
# VITE_USE_MOCK_DATA=true # 总开关:全部启用 mock
|
||||
# VITE_USE_MOCK_DATA=false # 全部关闭 mock
|
||||
# VITE_USE_MOCK_CATEGORY=true # 分类树用 mock
|
||||
# VITE_USE_MOCK_EVENT=true # 事件接口失败时 mock 兜底(默认 true)
|
||||
# VITE_USE_MOCK_ORDER_BOOK=true # 订单簿无 CLOB 时用 mock(默认 true)
|
||||
# VITE_USE_MOCK_WALLET=true # 钱包持仓/订单/历史用 mock(默认 true)
|
||||
#
|
||||
# 生产打包/部署时自动使用 .env.production 中的 https://api.xtrader.vip
|
||||
|
||||
# SSH 部署(npm run deploy),不配置时使用默认值
|
||||
|
||||
41
docs/api/mockData.md
Normal file
41
docs/api/mockData.md
Normal file
@ -0,0 +1,41 @@
|
||||
# mockData.ts
|
||||
|
||||
**路径**:`src/api/mockData.ts`
|
||||
|
||||
## 功能用途
|
||||
|
||||
模拟数据统一封装,集中管理事件、分类、订单簿、钱包等 mock 数据,配合 `src/config/mock.ts` 的开关使用。
|
||||
|
||||
## 导出内容
|
||||
|
||||
| 导出 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `MOCK_EVENT_LIST` | `PmEventListItem[]` | 模拟事件列表(来自 mockEventList) |
|
||||
| `MOCK_CATEGORY_TREE` | `CategoryTreeNode[]` | 模拟分类树(来自 category) |
|
||||
| `MOCK_ORDER_BOOK_ASKS` | `MockOrderBookRow[]` | 订单簿卖单 |
|
||||
| `MOCK_ORDER_BOOK_BIDS` | `MockOrderBookRow[]` | 订单簿买单 |
|
||||
| `MOCK_ORDER_BOOK_LAST_PRICE` | `number` | 最新价 |
|
||||
| `MOCK_ORDER_BOOK_SPREAD` | `number` | 价差 |
|
||||
| `MOCK_TOKEN_ID` | `string` | 测试用 token ID |
|
||||
| `MOCK_WALLET_POSITIONS` | `MockPosition[]` | 钱包持仓 |
|
||||
| `MOCK_WALLET_ORDERS` | `MockOpenOrder[]` | 钱包未成交订单 |
|
||||
| `MOCK_WALLET_HISTORY` | `MockHistoryItem[]` | 钱包历史 |
|
||||
| `getMockEventById(id)` | `(id: number) => PmEventListItem \| null` | 按 ID 获取 mock 事件 |
|
||||
|
||||
## 使用方式
|
||||
|
||||
```typescript
|
||||
import { MOCK_WALLET_POSITIONS, getMockEventById } from '@/api/mockData'
|
||||
import { USE_MOCK_WALLET } from '@/config/mock'
|
||||
|
||||
if (USE_MOCK_WALLET) {
|
||||
positions.value = [...MOCK_WALLET_POSITIONS]
|
||||
}
|
||||
|
||||
const fallback = getMockEventById(9001)
|
||||
```
|
||||
|
||||
## 扩展方式
|
||||
|
||||
1. 新增 mock 数据:在 `mockData.ts` 中定义并导出
|
||||
2. 修改现有数据:直接编辑对应常量
|
||||
@ -24,4 +24,4 @@ const cards = MOCK_EVENT_LIST.map(mapEventItemToCard)
|
||||
## 扩展方式
|
||||
|
||||
1. **新增 mock 项**:在 `MOCK_EVENT_LIST` 中追加符合 `PmEventListItem` 结构的对象
|
||||
2. **环境切换**:在 Home 等视图中根据 `import.meta.env.DEV` 选择使用 mock 或真实接口
|
||||
2. **统一入口**:`MOCK_EVENT_LIST` 已由 `src/api/mockData.ts` 统一导出,配合 `src/config/mock.ts` 的 `USE_MOCK_EVENT` 开关使用
|
||||
|
||||
37
docs/config/mock.md
Normal file
37
docs/config/mock.md
Normal file
@ -0,0 +1,37 @@
|
||||
# mock.ts
|
||||
|
||||
**路径**:`src/config/mock.ts`
|
||||
|
||||
## 功能用途
|
||||
|
||||
模拟数据开关配置,通过环境变量控制各模块是否使用 mock 数据,方便本地测试与联调。
|
||||
|
||||
## 开关说明
|
||||
|
||||
| 变量 | 说明 | 默认值 |
|
||||
|------|------|--------|
|
||||
| `VITE_USE_MOCK_DATA` | 总开关:`true` 全部启用,`false` 全部关闭 | - |
|
||||
| `VITE_USE_MOCK_CATEGORY` | 分类树:Home 使用模拟分类 | false |
|
||||
| `VITE_USE_MOCK_EVENT` | 事件:EventMarkets 接口失败时 mock 兜底 | true |
|
||||
| `VITE_USE_MOCK_ORDER_BOOK` | 订单簿:无 CLOB 数据时用 mock | true |
|
||||
| `VITE_USE_MOCK_WALLET` | 钱包:持仓/订单/历史用 mock | true |
|
||||
|
||||
## 使用方式
|
||||
|
||||
在 `.env` 中配置:
|
||||
|
||||
```bash
|
||||
# 全部启用 mock
|
||||
VITE_USE_MOCK_DATA=true
|
||||
|
||||
# 全部关闭 mock(联调真实接口时)
|
||||
VITE_USE_MOCK_DATA=false
|
||||
|
||||
# 仅分类树用 mock
|
||||
VITE_USE_MOCK_CATEGORY=true
|
||||
```
|
||||
|
||||
## 扩展方式
|
||||
|
||||
1. 新增模块开关:在 `mock.ts` 中增加 `USE_MOCK_XXX` 导出
|
||||
2. 新增 mock 数据:在 `src/api/mockData.ts` 中补充并导出
|
||||
262
src/api/mockData.ts
Normal file
262
src/api/mockData.ts
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* 模拟数据统一封装
|
||||
* 供 Home、EventMarkets、OrderBook、Wallet 等使用
|
||||
* 配合 src/config/mock.ts 的开关控制
|
||||
*/
|
||||
|
||||
import type { PmEventListItem } from './event'
|
||||
|
||||
// --- 事件列表(来自 mockEventList) ---
|
||||
import { MOCK_EVENT_LIST } from './mockEventList'
|
||||
export { MOCK_EVENT_LIST }
|
||||
|
||||
// --- 分类树(来自 category) ---
|
||||
export { MOCK_CATEGORY_TREE } from './category'
|
||||
|
||||
// --- 订单簿 mock ---
|
||||
export interface MockOrderBookRow {
|
||||
price: number
|
||||
shares: number
|
||||
}
|
||||
|
||||
export const MOCK_ORDER_BOOK_ASKS: MockOrderBookRow[] = [
|
||||
{ price: 45, shares: 1000.0 },
|
||||
{ price: 44, shares: 2500.0 },
|
||||
{ price: 43, shares: 1800.0 },
|
||||
{ price: 42, shares: 3200.0 },
|
||||
{ price: 41, shares: 2000.0 },
|
||||
{ price: 40, shares: 1500.0 },
|
||||
{ price: 39, shares: 800.0 },
|
||||
{ price: 38, shares: 500.0 },
|
||||
{ price: 37, shares: 300.0 },
|
||||
]
|
||||
|
||||
export const MOCK_ORDER_BOOK_BIDS: MockOrderBookRow[] = [
|
||||
{ price: 36, shares: 200.0 },
|
||||
{ price: 35, shares: 500.0 },
|
||||
{ price: 34, shares: 1000.0 },
|
||||
{ price: 33, shares: 1500.0 },
|
||||
{ price: 32, shares: 2000.0 },
|
||||
{ price: 31, shares: 2500.0 },
|
||||
{ price: 30, shares: 3000.0 },
|
||||
{ price: 29, shares: 2800.0 },
|
||||
{ price: 28, shares: 2500.0 },
|
||||
{ price: 27, shares: 2000.0 },
|
||||
{ price: 26, shares: 1500.0 },
|
||||
{ price: 25, shares: 1000.0 },
|
||||
]
|
||||
|
||||
export const MOCK_ORDER_BOOK_LAST_PRICE = 37
|
||||
export const MOCK_ORDER_BOOK_SPREAD = 1
|
||||
|
||||
// --- 钱包 mock ---
|
||||
export const MOCK_TOKEN_ID =
|
||||
'59966088656508531737144108943848781534186324373509174641856486864137458635937'
|
||||
|
||||
export interface MockPosition {
|
||||
id: string
|
||||
market: string
|
||||
iconChar?: string
|
||||
iconClass?: string
|
||||
outcomeTag?: string
|
||||
outcomePillClass?: string
|
||||
shares: string
|
||||
avgNow: string
|
||||
bet: string
|
||||
toWin: string
|
||||
value: string
|
||||
valueChange?: string
|
||||
valueChangePct?: string
|
||||
valueChangeLoss?: boolean
|
||||
sellOutcome?: string
|
||||
outcomeWord?: string
|
||||
}
|
||||
|
||||
export interface MockOpenOrder {
|
||||
id: string
|
||||
market: string
|
||||
side: 'Yes' | 'No'
|
||||
outcome: string
|
||||
price: string
|
||||
filled: string
|
||||
total: string
|
||||
expiration: string
|
||||
actionLabel?: string
|
||||
filledDisplay?: string
|
||||
iconChar?: string
|
||||
iconClass?: string
|
||||
orderID?: number
|
||||
tokenID?: string
|
||||
}
|
||||
|
||||
export interface MockHistoryItem {
|
||||
id: string
|
||||
market: string
|
||||
side: 'Yes' | 'No'
|
||||
activity: string
|
||||
value: string
|
||||
activityDetail?: string
|
||||
profitLoss?: string
|
||||
profitLossNegative?: boolean
|
||||
timeAgo?: string
|
||||
avgPrice?: string
|
||||
shares?: string
|
||||
iconChar?: string
|
||||
iconClass?: string
|
||||
}
|
||||
|
||||
export const MOCK_WALLET_POSITIONS: MockPosition[] = [
|
||||
{
|
||||
id: 'p1',
|
||||
market: 'Bitcoin Up or Down - February 9, 2:00AM-2:15AM ET',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
outcomeTag: 'Down 72¢',
|
||||
outcomePillClass: 'pill-down',
|
||||
shares: '6.9 shares',
|
||||
avgNow: '72¢ → 0.5¢',
|
||||
bet: '$4.95',
|
||||
toWin: '$6.87',
|
||||
value: '$0.03',
|
||||
valueChange: '-$4.91',
|
||||
valueChangePct: '99.31%',
|
||||
valueChangeLoss: true,
|
||||
sellOutcome: 'Down',
|
||||
outcomeWord: 'Down',
|
||||
},
|
||||
{
|
||||
id: 'p2',
|
||||
market: 'Bitcoin Up or Down - February 9, 2:15AM-2:30AM ET',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
outcomeTag: 'Up 26¢',
|
||||
outcomePillClass: 'pill-yes',
|
||||
shares: '3.8 shares',
|
||||
avgNow: '28¢ → 26¢',
|
||||
bet: '$0.99',
|
||||
toWin: '$3.54',
|
||||
value: '$0.90',
|
||||
valueChange: '-$0.09',
|
||||
valueChangePct: '8.9%',
|
||||
valueChangeLoss: true,
|
||||
sellOutcome: 'Up',
|
||||
outcomeWord: 'Up',
|
||||
},
|
||||
{
|
||||
id: 'p3',
|
||||
market: 'Will ETH merge complete by Q3?',
|
||||
iconChar: 'Ξ',
|
||||
iconClass: 'position-icon-eth',
|
||||
outcomeTag: 'Yes 48¢',
|
||||
outcomePillClass: 'pill-yes',
|
||||
shares: '30 shares',
|
||||
avgNow: '45¢ → 48¢',
|
||||
bet: '$30',
|
||||
toWin: '$36',
|
||||
value: '$32',
|
||||
valueChange: '+$2',
|
||||
valueChangePct: '6.67%',
|
||||
valueChangeLoss: false,
|
||||
sellOutcome: 'Yes',
|
||||
outcomeWord: 'Yes',
|
||||
},
|
||||
]
|
||||
|
||||
export const MOCK_WALLET_ORDERS: MockOpenOrder[] = [
|
||||
{
|
||||
id: 'o1',
|
||||
market: 'Bitcoin Up or Down - February 9, 2:45AM-3:00AM ET',
|
||||
side: 'Yes',
|
||||
outcome: 'Up',
|
||||
price: '1¢',
|
||||
filled: '0',
|
||||
total: '$0.05',
|
||||
expiration: 'Until Cancelled',
|
||||
actionLabel: 'Buy Up',
|
||||
filledDisplay: '0/5',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
orderID: 5,
|
||||
tokenID: MOCK_TOKEN_ID,
|
||||
},
|
||||
{
|
||||
id: 'o2',
|
||||
market: 'Will Bitcoin hit $100k by end of 2025?',
|
||||
side: 'Yes',
|
||||
outcome: 'Yes',
|
||||
price: '70¢',
|
||||
filled: '0',
|
||||
total: '$70',
|
||||
expiration: 'Dec 31, 2025',
|
||||
orderID: 5,
|
||||
tokenID: MOCK_TOKEN_ID,
|
||||
},
|
||||
{
|
||||
id: 'o3',
|
||||
market: 'Will ETH merge complete by Q3?',
|
||||
side: 'No',
|
||||
outcome: 'No',
|
||||
price: '52¢',
|
||||
filled: '25',
|
||||
total: '$26',
|
||||
expiration: 'Sep 30, 2025',
|
||||
orderID: 5,
|
||||
tokenID: MOCK_TOKEN_ID,
|
||||
},
|
||||
]
|
||||
|
||||
export const MOCK_WALLET_HISTORY: MockHistoryItem[] = [
|
||||
{
|
||||
id: 'h1',
|
||||
market: 'Bitcoin Up or Down - February 9, 3:00AM-3:15AM ET',
|
||||
side: 'No',
|
||||
activity: 'Sell No',
|
||||
activityDetail: 'Sold 1 Down at 50¢',
|
||||
value: '$0.50',
|
||||
profitLoss: '+$0.50',
|
||||
profitLossNegative: false,
|
||||
timeAgo: '3 minutes ago',
|
||||
avgPrice: '50¢',
|
||||
shares: '1',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
},
|
||||
{
|
||||
id: 'h2',
|
||||
market: 'Bitcoin Up or Down - February 9, 3:00AM-3:15AM ET',
|
||||
side: 'Yes',
|
||||
activity: 'Sell Yes',
|
||||
activityDetail: 'Sold 1 Up at 63¢',
|
||||
value: '$0.63',
|
||||
profitLoss: '+$0.63',
|
||||
profitLossNegative: false,
|
||||
timeAgo: '6 minutes ago',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
},
|
||||
{
|
||||
id: 'h3',
|
||||
market: 'Bitcoin Up or Down - February 9, 3:00AM-3:15AM ET',
|
||||
side: 'Yes',
|
||||
activity: 'Split',
|
||||
activityDetail: 'Split',
|
||||
value: '-$1.00',
|
||||
profitLoss: '-$1.00',
|
||||
profitLossNegative: true,
|
||||
timeAgo: '7 minutes ago',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
},
|
||||
{
|
||||
id: 'h4',
|
||||
market: 'Will ETH merge complete by Q3?',
|
||||
side: 'No',
|
||||
activity: 'Sell No',
|
||||
value: '$35.20',
|
||||
},
|
||||
]
|
||||
|
||||
export function getMockEventById(id: number): PmEventListItem | null {
|
||||
const item = MOCK_EVENT_LIST.find((e) => e.ID === id)
|
||||
return item && (item.markets?.length ?? 0) > 1 ? item : null
|
||||
}
|
||||
@ -82,6 +82,13 @@
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import HorizontalProgressBar from './HorizontalProgressBar.vue'
|
||||
import {
|
||||
MOCK_ORDER_BOOK_ASKS,
|
||||
MOCK_ORDER_BOOK_BIDS,
|
||||
MOCK_ORDER_BOOK_LAST_PRICE,
|
||||
MOCK_ORDER_BOOK_SPREAD,
|
||||
} from '../api/mockData'
|
||||
import { USE_MOCK_ORDER_BOOK } from '../config/mock'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@ -118,48 +125,27 @@ const props = withDefaults(
|
||||
// State
|
||||
const activeTrade = ref('up')
|
||||
|
||||
// 使用 props 或回退到 mock 数据
|
||||
const internalAsks = ref<OrderBookRow[]>([
|
||||
{ price: 45, shares: 1000.0 },
|
||||
{ price: 44, shares: 2500.0 },
|
||||
{ price: 43, shares: 1800.0 },
|
||||
{ price: 42, shares: 3200.0 },
|
||||
{ price: 41, shares: 2000.0 },
|
||||
{ price: 40, shares: 1500.0 },
|
||||
{ price: 39, shares: 800.0 },
|
||||
{ price: 38, shares: 500.0 },
|
||||
{ price: 37, shares: 300.0 },
|
||||
])
|
||||
const internalBids = ref<OrderBookRow[]>([
|
||||
{ price: 36, shares: 200.0 },
|
||||
{ price: 35, shares: 500.0 },
|
||||
{ price: 34, shares: 1000.0 },
|
||||
{ price: 33, shares: 1500.0 },
|
||||
{ price: 32, shares: 2000.0 },
|
||||
{ price: 31, shares: 2500.0 },
|
||||
{ price: 30, shares: 3000.0 },
|
||||
{ price: 29, shares: 2800.0 },
|
||||
{ price: 28, shares: 2500.0 },
|
||||
{ price: 27, shares: 2000.0 },
|
||||
{ price: 26, shares: 1500.0 },
|
||||
{ price: 25, shares: 1000.0 },
|
||||
])
|
||||
const internalLastPrice = ref(37)
|
||||
const internalSpread = ref(1)
|
||||
// 使用 props 或回退到 mock 数据(来自 mockData 统一封装)
|
||||
const internalAsks = ref<OrderBookRow[]>([...MOCK_ORDER_BOOK_ASKS])
|
||||
const internalBids = ref<OrderBookRow[]>([...MOCK_ORDER_BOOK_BIDS])
|
||||
const internalLastPrice = ref(MOCK_ORDER_BOOK_LAST_PRICE)
|
||||
const internalSpread = ref(MOCK_ORDER_BOOK_SPREAD)
|
||||
|
||||
// 当有外部数据时使用 props,否则用 mock
|
||||
// 当有外部数据时使用 props,否则在 USE_MOCK_ORDER_BOOK 时用 mock
|
||||
const asks = computed(() =>
|
||||
props.asks?.length ? props.asks : internalAsks.value,
|
||||
props.asks?.length ? props.asks : USE_MOCK_ORDER_BOOK ? internalAsks.value : [],
|
||||
)
|
||||
const bids = computed(() =>
|
||||
props.bids?.length ? props.bids : internalBids.value,
|
||||
props.bids?.length ? props.bids : USE_MOCK_ORDER_BOOK ? internalBids.value : [],
|
||||
)
|
||||
const displayLastPrice = computed(() =>
|
||||
props.lastPrice ?? internalLastPrice.value,
|
||||
props.lastPrice ?? (USE_MOCK_ORDER_BOOK ? internalLastPrice.value : 0),
|
||||
)
|
||||
const displaySpread = computed(() =>
|
||||
props.spread ?? (USE_MOCK_ORDER_BOOK ? internalSpread.value : 0),
|
||||
)
|
||||
const displaySpread = computed(() => props.spread ?? internalSpread.value)
|
||||
|
||||
// 仅在没有外部数据时运行 mock 更新
|
||||
// 仅在没有外部数据且开启 mock 时运行 mock 更新
|
||||
let mockInterval: ReturnType<typeof setInterval> | undefined
|
||||
watch(
|
||||
() => props.connected || (props.asks?.length ?? 0) > 0,
|
||||
@ -167,7 +153,7 @@ watch(
|
||||
if (hasRealData && mockInterval) {
|
||||
clearInterval(mockInterval)
|
||||
mockInterval = undefined
|
||||
} else if (!hasRealData && !mockInterval) {
|
||||
} else if (!hasRealData && USE_MOCK_ORDER_BOOK && !mockInterval) {
|
||||
mockInterval = setInterval(() => {
|
||||
const randomAskIndex = Math.floor(Math.random() * internalAsks.value.length)
|
||||
const askItem = internalAsks.value[randomAskIndex]
|
||||
|
||||
35
src/config/mock.ts
Normal file
35
src/config/mock.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* 模拟数据开关配置
|
||||
* 通过环境变量控制,方便本地测试与联调
|
||||
*
|
||||
* 使用方式:
|
||||
* - .env 中设置 VITE_USE_MOCK_DATA=true 开启总开关
|
||||
* - 或单独设置各模块:VITE_USE_MOCK_CATEGORY、VITE_USE_MOCK_EVENT、VITE_USE_MOCK_ORDER_BOOK、VITE_USE_MOCK_WALLET
|
||||
*/
|
||||
|
||||
const env = typeof import.meta !== 'undefined' ? (import.meta as { env?: Record<string, string> }).env : {}
|
||||
|
||||
function isTruthy(val: string | undefined): boolean {
|
||||
return val === 'true' || val === '1' || val === 'yes'
|
||||
}
|
||||
function isFalsy(val: string | undefined): boolean {
|
||||
return val === 'false' || val === '0' || val === 'no'
|
||||
}
|
||||
|
||||
const master = env?.VITE_USE_MOCK_DATA
|
||||
|
||||
/** 分类树:Home 使用模拟分类(一层二层三层 UI 测试),默认 false */
|
||||
export const USE_MOCK_CATEGORY =
|
||||
isTruthy(master) || (master === undefined && isTruthy(env?.VITE_USE_MOCK_CATEGORY))
|
||||
|
||||
/** 事件/市场:EventMarkets 接口失败时用 mock 兜底,默认 true */
|
||||
export const USE_MOCK_EVENT =
|
||||
isFalsy(master) ? false : isTruthy(master) || isTruthy(env?.VITE_USE_MOCK_EVENT) || env?.VITE_USE_MOCK_EVENT === undefined
|
||||
|
||||
/** 订单簿:OrderBook 无 CLOB 数据时使用 mock,默认 true */
|
||||
export const USE_MOCK_ORDER_BOOK =
|
||||
isFalsy(master) ? false : isTruthy(master) || isTruthy(env?.VITE_USE_MOCK_ORDER_BOOK) || env?.VITE_USE_MOCK_ORDER_BOOK === undefined
|
||||
|
||||
/** 钱包:Wallet 持仓/订单/历史使用 mock,默认 true */
|
||||
export const USE_MOCK_WALLET =
|
||||
isFalsy(master) ? false : isTruthy(master) || isTruthy(env?.VITE_USE_MOCK_WALLET) || env?.VITE_USE_MOCK_WALLET === undefined
|
||||
@ -197,7 +197,8 @@ import {
|
||||
type PmEventListItem,
|
||||
type PmEventMarketItem,
|
||||
} from '../api/event'
|
||||
import { MOCK_EVENT_LIST } from '../api/mockEventList'
|
||||
import { getMockEventById } from '../api/mockData'
|
||||
import { USE_MOCK_EVENT } from '../config/mock'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useUserStore } from '../stores/user'
|
||||
import { useToastStore } from '../stores/toast'
|
||||
@ -643,7 +644,7 @@ async function loadEventDetail() {
|
||||
eventDetail.value = res.data ?? null
|
||||
detailError.value = null
|
||||
} else {
|
||||
const fallback = isNumericId ? getMockEventById(numId) : null
|
||||
const fallback = USE_MOCK_EVENT && isNumericId ? getMockEventById(numId) : null
|
||||
if (fallback) {
|
||||
eventDetail.value = fallback
|
||||
detailError.value = null
|
||||
@ -653,7 +654,7 @@ async function loadEventDetail() {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
const fallback = isNumericId ? getMockEventById(numId) : null
|
||||
const fallback = USE_MOCK_EVENT && isNumericId ? getMockEventById(numId) : null
|
||||
if (fallback) {
|
||||
eventDetail.value = fallback
|
||||
detailError.value = null
|
||||
@ -666,11 +667,6 @@ async function loadEventDetail() {
|
||||
}
|
||||
}
|
||||
|
||||
function getMockEventById(id: number): PmEventListItem | null {
|
||||
const item = MOCK_EVENT_LIST.find((e) => e.ID === id)
|
||||
return item && (item.markets?.length ?? 0) > 1 ? item : null
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadEventDetail()
|
||||
window.addEventListener('resize', handleResize)
|
||||
|
||||
@ -322,6 +322,7 @@ import {
|
||||
resolveCategoryIconColor,
|
||||
type CategoryTreeNode,
|
||||
} from '../api/category'
|
||||
import { USE_MOCK_CATEGORY } from '../config/mock'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useSearchHistory } from '../composables/useSearchHistory'
|
||||
import { useToastStore } from '../stores/toast'
|
||||
@ -651,8 +652,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/** 开发时设为 true 可始终使用模拟数据查看一二三层 UI */
|
||||
const USE_MOCK_CATEGORY = false
|
||||
if (USE_MOCK_CATEGORY) {
|
||||
categoryTree.value = enrichWithIcons(MOCK_CATEGORY_TREE)
|
||||
initCategorySelection()
|
||||
|
||||
@ -573,6 +573,13 @@ import DepositDialog from '../components/DepositDialog.vue'
|
||||
import WithdrawDialog from '../components/WithdrawDialog.vue'
|
||||
import { useUserStore } from '../stores/user'
|
||||
import { pmCancelOrder } from '../api/market'
|
||||
import {
|
||||
MOCK_TOKEN_ID,
|
||||
MOCK_WALLET_POSITIONS,
|
||||
MOCK_WALLET_ORDERS,
|
||||
MOCK_WALLET_HISTORY,
|
||||
} from '../api/mockData'
|
||||
import { USE_MOCK_WALLET } from '../config/mock'
|
||||
|
||||
const { mobile } = useDisplay()
|
||||
const userStore = useUserStore()
|
||||
@ -669,156 +676,15 @@ interface HistoryItem {
|
||||
iconClass?: string
|
||||
}
|
||||
|
||||
const positions = ref<Position[]>([
|
||||
{
|
||||
id: 'p1',
|
||||
market: 'Bitcoin Up or Down - February 9, 2:00AM-2:15AM ET',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
outcomeTag: 'Down 72¢',
|
||||
outcomePillClass: 'pill-down',
|
||||
shares: '6.9 shares',
|
||||
avgNow: '72¢ → 0.5¢',
|
||||
bet: '$4.95',
|
||||
toWin: '$6.87',
|
||||
value: '$0.03',
|
||||
valueChange: '-$4.91',
|
||||
valueChangePct: '99.31%',
|
||||
valueChangeLoss: true,
|
||||
sellOutcome: 'Down',
|
||||
outcomeWord: 'Down',
|
||||
},
|
||||
{
|
||||
id: 'p2',
|
||||
market: 'Bitcoin Up or Down - February 9, 2:15AM-2:30AM ET',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
outcomeTag: 'Up 26¢',
|
||||
outcomePillClass: 'pill-yes',
|
||||
shares: '3.8 shares',
|
||||
avgNow: '28¢ → 26¢',
|
||||
bet: '$0.99',
|
||||
toWin: '$3.54',
|
||||
value: '$0.90',
|
||||
valueChange: '-$0.09',
|
||||
valueChangePct: '8.9%',
|
||||
valueChangeLoss: true,
|
||||
sellOutcome: 'Up',
|
||||
outcomeWord: 'Up',
|
||||
},
|
||||
{
|
||||
id: 'p3',
|
||||
market: 'Will ETH merge complete by Q3?',
|
||||
iconChar: 'Ξ',
|
||||
iconClass: 'position-icon-eth',
|
||||
outcomeTag: 'Yes 48¢',
|
||||
outcomePillClass: 'pill-yes',
|
||||
shares: '30 shares',
|
||||
avgNow: '45¢ → 48¢',
|
||||
bet: '$30',
|
||||
toWin: '$36',
|
||||
value: '$32',
|
||||
valueChange: '+$2',
|
||||
valueChangePct: '6.67%',
|
||||
valueChangeLoss: false,
|
||||
sellOutcome: 'Yes',
|
||||
outcomeWord: 'Yes',
|
||||
},
|
||||
])
|
||||
const MOCK_TOKEN_ID =
|
||||
'59966088656508531737144108943848781534186324373509174641856486864137458635937'
|
||||
const openOrders = ref<OpenOrder[]>([
|
||||
{
|
||||
id: 'o1',
|
||||
market: 'Bitcoin Up or Down - February 9, 2:45AM-3:00AM ET',
|
||||
side: 'Yes',
|
||||
outcome: 'Up',
|
||||
price: '1¢',
|
||||
filled: '0',
|
||||
total: '$0.05',
|
||||
expiration: 'Until Cancelled',
|
||||
actionLabel: 'Buy Up',
|
||||
filledDisplay: '0/5',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
orderID: 5,
|
||||
tokenID: MOCK_TOKEN_ID,
|
||||
},
|
||||
{
|
||||
id: 'o2',
|
||||
market: 'Will Bitcoin hit $100k by end of 2025?',
|
||||
side: 'Yes',
|
||||
outcome: 'Yes',
|
||||
price: '70¢',
|
||||
filled: '0',
|
||||
total: '$70',
|
||||
expiration: 'Dec 31, 2025',
|
||||
orderID: 5,
|
||||
tokenID: MOCK_TOKEN_ID,
|
||||
},
|
||||
{
|
||||
id: 'o3',
|
||||
market: 'Will ETH merge complete by Q3?',
|
||||
side: 'No',
|
||||
outcome: 'No',
|
||||
price: '52¢',
|
||||
filled: '25',
|
||||
total: '$26',
|
||||
expiration: 'Sep 30, 2025',
|
||||
orderID: 5,
|
||||
tokenID: MOCK_TOKEN_ID,
|
||||
},
|
||||
])
|
||||
const history = ref<HistoryItem[]>([
|
||||
{
|
||||
id: 'h1',
|
||||
market: 'Bitcoin Up or Down - February 9, 3:00AM-3:15AM ET',
|
||||
side: 'No',
|
||||
activity: 'Sell No',
|
||||
activityDetail: 'Sold 1 Down at 50¢',
|
||||
value: '$0.50',
|
||||
profitLoss: '+$0.50',
|
||||
profitLossNegative: false,
|
||||
timeAgo: '3 minutes ago',
|
||||
avgPrice: '50¢',
|
||||
shares: '1',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
},
|
||||
{
|
||||
id: 'h2',
|
||||
market: 'Bitcoin Up or Down - February 9, 3:00AM-3:15AM ET',
|
||||
side: 'Yes',
|
||||
activity: 'Sell Yes',
|
||||
activityDetail: 'Sold 1 Up at 63¢',
|
||||
value: '$0.63',
|
||||
profitLoss: '+$0.63',
|
||||
profitLossNegative: false,
|
||||
timeAgo: '6 minutes ago',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
},
|
||||
{
|
||||
id: 'h3',
|
||||
market: 'Bitcoin Up or Down - February 9, 3:00AM-3:15AM ET',
|
||||
side: 'Yes',
|
||||
activity: 'Split',
|
||||
activityDetail: 'Split',
|
||||
value: '-$1.00',
|
||||
profitLoss: '-$1.00',
|
||||
profitLossNegative: true,
|
||||
timeAgo: '7 minutes ago',
|
||||
iconChar: '₿',
|
||||
iconClass: 'position-icon-btc',
|
||||
},
|
||||
{
|
||||
id: 'h4',
|
||||
market: 'Will ETH merge complete by Q3?',
|
||||
side: 'No',
|
||||
activity: 'Sell No',
|
||||
value: '$35.20',
|
||||
},
|
||||
])
|
||||
const positions = ref<Position[]>(
|
||||
USE_MOCK_WALLET ? [...MOCK_WALLET_POSITIONS] : [],
|
||||
)
|
||||
const openOrders = ref<OpenOrder[]>(
|
||||
USE_MOCK_WALLET ? [...MOCK_WALLET_ORDERS] : [],
|
||||
)
|
||||
const history = ref<HistoryItem[]>(
|
||||
USE_MOCK_WALLET ? [...MOCK_WALLET_HISTORY] : [],
|
||||
)
|
||||
|
||||
function matchSearch(text: string): boolean {
|
||||
const q = search.value.trim().toLowerCase()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user