ai_trade_assistance/docs/superpowers/plans/2026-07-21-ai-trade-assistant-ui.md

260 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AI 交易辅助系统 Phase1 UI 框架 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 搭建 Vue3 + Vite7 + Element Plus 单页交易辅助 UI(浅色),含行情/新闻/持仓/AI 抽屉/设置,数据全部 mock。
**Architecture:** `AppLayout` 滚动主区 + 固定底栏 AI 抽屉;业务拆为 header/quote/news/position/ai 组件;composable 读 `src/mocks/*`,对外 `{ data, loading, error, refresh }`;设置用 Pinia + localStorage。
**Tech Stack:** Vue 3、Vite 7、Element Plus、Pinia、ECharts、vue-echarts
**Spec:** `docs/superpowers/specs/2026-07-21-ai-trade-assistant-design.md`
---
## File Structure
```
package.json, vite.config.js, index.html
src/main.js, src/App.vue
src/styles/variables.css, src/styles/global.css
src/layout/AppLayout.vue
src/components/header/AppHeader.vue, SettingsDialog.vue
src/components/quote/QuoteStats.vue, ChartPanel.vue, OrderBook.vue, TradeTape.vue
src/components/news/NewsList.vue, NewsItem.vue
src/components/position/PositionPanel.vue, PositionDonut.vue, PositionTable.vue
src/components/ai/AiAdviceDrawer.vue
src/composables/useQuote.js, useNews.js, usePositions.js, useAiAdvice.js
src/stores/settings.js
src/mocks/quote.js, news.js, positions.js, aiAdvice.js
README.md
```
---
### Task 1: Scaffold Vite Vue 项目并安装依赖
**Files:**
- Create: `package.json`, `vite.config.js`, `index.html`, `src/main.js`(由 create-vite 生成后改)
- Modify: `README.md`
- [ ] **Step 1: 在仓库根目录用 create-vite 初始化 Vue 模板**
在 PowerShell、仓库根目录(已有 README,允许非空):
```powershell
cd e:\Gitea\ai_trade_assistance
npm create vite@latest . -- --template vue
```
若提示目录非空,确认继续。期望生成 `package.json`、`vite.config.js`、`src/` 等。
- [ ] **Step 2: 安装运行时依赖**
```powershell
npm install
npm install element-plus @element-plus/icons-vue pinia echarts vue-echarts
```
确认 `package.json` 中 `vite` 主版本为 7.x(若为 6.x,执行 `npm install vite@7`)。
- [ ] **Step 3: 配置 main.js 接入 Element Plus + Pinia**
`src/main.js`:
```js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import ElementPlus from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import 'element-plus/dist/index.css'
import './styles/variables.css'
import './styles/global.css'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.use(ElementPlus, { locale: zhCn })
app.mount('#app')
```
- [ ] **Step 4: 验证能启动**
```powershell
npm run dev
```
期望:终端出现本地 URL,浏览器可打开默认 Vite 页。
- [ ] **Step 5: Commit(仅当用户明确要求时执行;本仓库默认跳过)**
---
### Task 2: 全局样式与 AppLayout 壳
**Files:**
- Create: `src/styles/variables.css`, `src/styles/global.css`, `src/layout/AppLayout.vue`
- Modify: `src/App.vue`
- [ ] **Step 1: 写入主题变量(浅色、红涨绿跌)**
`src/styles/variables.css`:
```css
:root {
--bg-page: #f5f6f8;
--bg-card: #ffffff;
--border: #e6e8eb;
--text-primary: #1f2329;
--text-secondary: #8a9199;
--up: #e54545;
--down: #12b37b;
--accent: #1677ff;
--header-height: 56px;
--ai-bar-height: 48px;
}
```
`src/styles/global.css`: 重置 body 背景 `--bg-page`、字体、链接色;`.price-up { color: var(--up) }` / `.price-down { color: var(--down) }`。
- [ ] **Step 2: AppLayout — 滚动主区 + 底栏插槽**
`src/layout/AppLayout.vue`:顶部 `#header` 插槽,中间 `.main-scroll` 放默认插槽,底部固定 `.ai-footer` 放 `#ai` 插槽;主区 `padding-bottom` 预留 AI 栏高度。
- [ ] **Step 3: App.vue 挂载壳(占位组件可先用空 section)**
```vue
<template>
<AppLayout>
<template #header><AppHeader /></template>
<!-- quote / news / position sections -->
<template #ai><AiAdviceDrawer /></template>
</AppLayout>
</template>
```
---
### Task 3: Mock 数据与 Settings Store
**Files:**
- Create: `src/mocks/quote.js`, `src/mocks/news.js`, `src/mocks/positions.js`, `src/mocks/aiAdvice.js`, `src/stores/settings.js`
- Create: `src/composables/useQuote.js`, `useNews.js`, `usePositions.js`, `useAiAdvice.js`
- [ ] **Step 1: quote mock** — 合约 `玻璃2609`/`FG609`,最新价 936、涨跌 -13/-1.37%,开高低结算持仓量内外盘;`intraday` 点数数组;`orderBook` 卖5–买1;`trades` 若干条。
- [ ] **Step 2: news / positions / aiAdvice mock** — 新闻 5 条(source/time/title/summary/url);持仓多空各 20 名含 qty/change/percent;AI 建议含 action/confidence/reasons/updatedAt。
- [ ] **Step 3: settings store**
```js
// src/stores/settings.js
import { defineStore } from 'pinia'
import { ref, watch } from 'vue'
const KEY = 'ai-trade-settings'
export const useSettingsStore = defineStore('settings', () => {
const saved = JSON.parse(localStorage.getItem(KEY) || '{}')
const apiKey = ref(saved.apiKey || '')
const keywords = ref(saved.keywords || '')
watch([apiKey, keywords], () => {
localStorage.setItem(KEY, JSON.stringify({ apiKey: apiKey.value, keywords: keywords.value }))
})
return { apiKey, keywords }
})
```
- [ ] **Step 4: composables** — 各 `useX` 返回 `data`(ref mock)、`loading`、`error`、`refresh`(模拟 300ms delay 后重置 mock)。
---
### Task 4: Header + SettingsDialog
**Files:**
- Create: `src/components/header/AppHeader.vue`, `src/components/header/SettingsDialog.vue`
- [ ] **Step 1: AppHeader** — 左:名称+代码;中:现价与涨跌(红绿 class);右:设置按钮打开 dialog。
- [ ] **Step 2: SettingsDialog** — `el-dialog`;`el-input` type=password 绑定 apiKey;`el-input` type=textarea 绑定 keywords;保存即关(store 已 watch 持久化)。
---
### Task 5: 行情区(统计、图表、盘口、成交)
**Files:**
- Create: `src/components/quote/QuoteStats.vue`, `ChartPanel.vue`, `OrderBook.vue`, `TradeTape.vue`
- Modify: `src/App.vue` 组装行情两栏
- [ ] **Step 1: QuoteStats** — 多列网格展示开/高/低/昨结/持仓/量/内外盘等。
- [ ] **Step 2: ChartPanel** — `el-tabs`:分时/五日/日K/周K/月K;分时用 ECharts line+area + 成交量 bar;K 线 tab 用 candle + volume(可用简化 mock OHLC)。注册 `CanvasRenderer`、`LineChart`、`BarChart`、`CandlestickChart`。
- [ ] **Step 3: OrderBook** — 买卖力度条(红绿 flex 比例);卖5→卖1、买1→买5。
- [ ] **Step 4: TradeTape** — 时间/价/量+方向(B/S 着色)。
- [ ] **Step 5: 在 App 中布局** — 左 70% 统计+图,右 30% 盘口+成交;卡片白底圆角边框。
---
### Task 6: 新闻区
**Files:**
- Create: `src/components/news/NewsList.vue`, `NewsItem.vue`
- [ ] **Step 1: NewsItem** — 上行 source+time 与「查看原文」;标题;摘要(多行省略)。
- [ ] **Step 2: NewsList** — 标题「相关新闻」+ `v-for` 渲染列表。
---
### Task 7: 机构持仓区(浅色)
**Files:**
- Create: `src/components/position/PositionPanel.vue`, `PositionDonut.vue`, `PositionTable.vue`
- [ ] **Step 1: PositionDonut** — vue-echarts pie(roseType 或标准 doughnut),legend 右侧。
- [ ] **Step 2: PositionTable** — 名次/会员简称/数量/增减(正红负青)。
- [ ] **Step 3: PositionPanel** — `el-tabs` 总持仓/成交量/净持仓;双列「多单前20」「空单前20」;非总持仓 Tab 复用同结构 mock 并在角标提示「占位数据」。
---
### Task 8: AI 抽屉 + README 收尾
**Files:**
- Create: `src/components/ai/AiAdviceDrawer.vue`
- Modify: `README.md`, `src/App.vue`
- [ ] **Step 1: AiAdviceDrawer** — 收起:一行摘要 + 展开/刷新;展开:方向、置信度、理由列表、时间;无 apiKey 时刷新用 `ElMessage.warning` 提示打开设置,仍可展示 mock。
- [ ] **Step 2: 更新 README** — 启动命令、技术栈、Phase1 范围说明。
- [ ] **Step 3: 全量验收**
```powershell
npm run build
npm run dev
```
对照 spec §8 验收清单逐项点检。
---
## Spec coverage (self-review)
| Spec 项 | Task |
|---|---|
| 浅色单页滚动 | 2, 5–7 |
| 行情+盘口+成交 | 3, 5 |
| 新闻 | 6 |
| 持仓双列浅色 | 7 |
| AI 底栏抽屉 | 8 |
| DeepSeek Key + 关键词 | 3, 4 |
| Mock composable | 3 |
| Vite7 + Vue3 + Element Plus | 1 |
无 TBD 占位;提交步骤遵循用户「未要求不 commit」规则。