From b93fb3ec41f83798bd38dfcd8ac15ab085d7be0d Mon Sep 17 00:00:00 2001 From: leefer Date: Thu, 30 Jul 2026 07:45:55 +0800 Subject: [PATCH] rebuild(stage-12): deliver private review workflows --- next/backend/bootstrap/container.py | 5 + .../database/migrations/m0010_review.py | 112 +++++ next/backend/database/migrations/registry.py | 2 + next/backend/features/review/__init__.py | 3 + next/backend/features/review/prompt.py | 29 ++ next/backend/features/review/repository.py | 306 ++++++++++++++ next/backend/features/review/routes.py | 183 ++++++++ next/backend/features/review/schemas.py | 51 +++ next/backend/features/review/service.py | 368 ++++++++++++++++ next/backend/features/review/views.py | 54 +++ next/backend/http/router.py | 2 + next/docs/evidence/stage-12/acceptance.md | 46 ++ .../stage-12/review-dark-1920x1080.jpg | Bin 0 -> 111371 bytes .../evidence/stage-12/review-dark-390x844.jpg | Bin 0 -> 38455 bytes next/frontend/src/app/shell/TopBar.vue | 11 +- .../src/app/views/EntityDetailView.vue | 2 + next/frontend/src/app/views/WorkspaceView.vue | 2 + next/frontend/src/main.ts | 1 + .../frontend/src/pages/review/AlertsPanel.vue | 44 ++ .../src/pages/review/AssistantPanel.vue | 66 +++ next/frontend/src/pages/review/ReviewPage.vue | 144 +++++++ next/frontend/src/pages/review/StockNotes.vue | 28 ++ .../frontend/src/pages/review/TradeDialog.vue | 57 +++ next/frontend/src/shared/api/review.ts | 92 ++++ .../src/shared/components/DialogHost.vue | 13 +- next/frontend/src/shared/stores/ui.ts | 5 +- next/frontend/src/shared/styles/mobile.css | 14 + next/frontend/src/shared/styles/review.css | 397 ++++++++++++++++++ next/playwright.config.js | 1 + next/tests/e2e/stage12.spec.js | 102 +++++ next/tests/test_migrations.py | 19 +- next/tests/test_review.py | 142 +++++++ 32 files changed, 2292 insertions(+), 9 deletions(-) create mode 100644 next/backend/database/migrations/m0010_review.py create mode 100644 next/backend/features/review/__init__.py create mode 100644 next/backend/features/review/prompt.py create mode 100644 next/backend/features/review/repository.py create mode 100644 next/backend/features/review/routes.py create mode 100644 next/backend/features/review/schemas.py create mode 100644 next/backend/features/review/service.py create mode 100644 next/backend/features/review/views.py create mode 100644 next/docs/evidence/stage-12/acceptance.md create mode 100644 next/docs/evidence/stage-12/review-dark-1920x1080.jpg create mode 100644 next/docs/evidence/stage-12/review-dark-390x844.jpg create mode 100644 next/frontend/src/pages/review/AlertsPanel.vue create mode 100644 next/frontend/src/pages/review/AssistantPanel.vue create mode 100644 next/frontend/src/pages/review/ReviewPage.vue create mode 100644 next/frontend/src/pages/review/StockNotes.vue create mode 100644 next/frontend/src/pages/review/TradeDialog.vue create mode 100644 next/frontend/src/shared/api/review.ts create mode 100644 next/frontend/src/shared/styles/review.css create mode 100644 next/tests/e2e/stage12.spec.js create mode 100644 next/tests/test_review.py diff --git a/next/backend/bootstrap/container.py b/next/backend/bootstrap/container.py index 5e2d1bc..9e769e2 100644 --- a/next/backend/bootstrap/container.py +++ b/next/backend/bootstrap/container.py @@ -25,6 +25,8 @@ from backend.features.mentor.context import MentorContextBuilder from backend.features.mentor.repository import MentorRepository from backend.features.mentor.service import MentorService from backend.features.mentor.skills import MentorSkillRegistry +from backend.features.review import ReviewService +from backend.features.review.repository import ReviewRepository from backend.features.screener.repository import ScreenerRepository from backend.features.screener.service import ScreenerService from backend.llm import LLMGateway @@ -46,6 +48,7 @@ class ApplicationContainer: llm: LLMGateway mentor: MentorService heaven: HeavenService + review: ReviewService def build_container(settings: Settings) -> ApplicationContainer: @@ -100,6 +103,7 @@ def build_container(settings: Settings) -> ApplicationContainer: llm, PROJECT_ROOT / "config" / "heaven" / "iching_zh.json", ) + review = ReviewService(database, ReviewRepository(), gateway, screener, llm) return ApplicationContainer( settings=settings, database=database, @@ -113,4 +117,5 @@ def build_container(settings: Settings) -> ApplicationContainer: llm=llm, mentor=mentor, heaven=heaven, + review=review, ) diff --git a/next/backend/database/migrations/m0010_review.py b/next/backend/database/migrations/m0010_review.py new file mode 100644 index 0000000..cfe0dcb --- /dev/null +++ b/next/backend/database/migrations/m0010_review.py @@ -0,0 +1,112 @@ +from __future__ import annotations + +import sqlite3 + +from backend.database.migrations.runner import Migration + + +def upgrade(connection: sqlite3.Connection) -> None: + connection.execute("ALTER TABLE watchlist_entries ADD COLUMN remark TEXT NOT NULL DEFAULT ''") + statements = ( + """ + CREATE TABLE review_notes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + code TEXT NOT NULL DEFAULT '', + stock_name TEXT NOT NULL DEFAULT '', + trade_date TEXT NOT NULL, + summary TEXT NOT NULL DEFAULT '', + content TEXT NOT NULL DEFAULT '', + plan TEXT NOT NULL DEFAULT '', + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL, + UNIQUE(user_id, code, trade_date) + ) + """, + """ + CREATE TABLE trade_entries ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + trade_date TEXT NOT NULL, + code TEXT NOT NULL, + name TEXT NOT NULL, + action TEXT NOT NULL CHECK (action IN ('buy','sell','add','trim','watch')), + price REAL NOT NULL CHECK (price >= 0), + quantity INTEGER NOT NULL DEFAULT 0 CHECK (quantity >= 0), + position_pct REAL CHECK (position_pct BETWEEN 0 AND 100), + pnl_amount REAL, + pnl_pct REAL, + emotion TEXT NOT NULL CHECK ( + emotion IN ('calm','confident','hesitant','anxious','impulsive') + ), + tags_json TEXT NOT NULL DEFAULT '[]', + thesis TEXT NOT NULL DEFAULT '', + execution TEXT NOT NULL DEFAULT '', + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL + ) + """, + """ + CREATE INDEX trade_entries_user_date_idx + ON trade_entries(user_id, trade_date DESC, id DESC) + """, + """ + CREATE TABLE alerts ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + kind TEXT NOT NULL CHECK (kind IN ('manual','strategy_t1','strategy_t5')), + title TEXT NOT NULL, + content TEXT NOT NULL DEFAULT '', + available_date TEXT NOT NULL, + code TEXT NOT NULL DEFAULT '', + dedupe_key TEXT NOT NULL, + is_read INTEGER NOT NULL DEFAULT 0 CHECK (is_read IN (0,1)), + read_at TEXT, + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL, + UNIQUE(user_id, dedupe_key) + ) + """, + """ + CREATE INDEX alerts_user_due_idx + ON alerts(user_id, available_date, is_read, id DESC) + """, + """ + CREATE TABLE review_assistant_messages ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, + role TEXT NOT NULL CHECK (role IN ('user','assistant')), + content TEXT NOT NULL, + context_date TEXT NOT NULL, + request_id TEXT REFERENCES llm_requests(id) ON DELETE SET NULL, + status TEXT NOT NULL CHECK (status IN ('complete','stopped','error')), + created_at TEXT NOT NULL + ) + """, + """ + CREATE INDEX review_assistant_user_idx + ON review_assistant_messages(user_id, id DESC) + """, + ) + for statement in statements: + connection.execute(statement) + + +def downgrade(connection: sqlite3.Connection) -> None: + for table in ( + "review_assistant_messages", + "alerts", + "trade_entries", + "review_notes", + ): + connection.execute(f"DROP TABLE {table}") + connection.execute("ALTER TABLE watchlist_entries DROP COLUMN remark") + + +MIGRATION = Migration( + version=10, + name="create_private_review_domain", + signature="review:v1:notes-trades-alerts-assistant", + upgrade=upgrade, + downgrade=downgrade, +) diff --git a/next/backend/database/migrations/registry.py b/next/backend/database/migrations/registry.py index 6efee63..23d0c15 100644 --- a/next/backend/database/migrations/registry.py +++ b/next/backend/database/migrations/registry.py @@ -7,6 +7,7 @@ from backend.database.migrations.m0006_watchlists import MIGRATION as WATCHLISTS from backend.database.migrations.m0007_screener import MIGRATION as SCREENER from backend.database.migrations.m0008_mentor_llm import MIGRATION as MENTOR_LLM from backend.database.migrations.m0009_heaven import MIGRATION as HEAVEN +from backend.database.migrations.m0010_review import MIGRATION as REVIEW from backend.database.migrations.runner import Migration MIGRATIONS: tuple[Migration, ...] = ( @@ -19,4 +20,5 @@ MIGRATIONS: tuple[Migration, ...] = ( SCREENER, MENTOR_LLM, HEAVEN, + REVIEW, ) diff --git a/next/backend/features/review/__init__.py b/next/backend/features/review/__init__.py new file mode 100644 index 0000000..6ded6c2 --- /dev/null +++ b/next/backend/features/review/__init__.py @@ -0,0 +1,3 @@ +from backend.features.review.service import ReviewService + +__all__ = ["ReviewService"] diff --git a/next/backend/features/review/prompt.py b/next/backend/features/review/prompt.py new file mode 100644 index 0000000..9dd16f5 --- /dev/null +++ b/next/backend/features/review/prompt.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +import json +from typing import Any + +PROMPT_VERSION = "review-assistant-v1" + + +def messages( + context: dict[str, Any], history: list[dict[str, str]], question: str +) -> list[dict[str, str]]: + return [ + { + "role": "system", + "content": ( + "你是复盘助手,只能基于提供的数据帮助用户复盘,不修改数据、不执行交易。" + "回答依次区分【市场事实】【用户记录】【推断】【条件化计划】;缺失信息明确留空。" + "不得把推断写成事实,不给无条件买卖指令。默认不超过800个中文字符," + "只有用户明确要求展开时才可更长。" + ), + }, + { + "role": "user", + "content": "复盘上下文:" + + json.dumps(context, ensure_ascii=False, separators=(",", ":")), + }, + *history, + {"role": "user", "content": question}, + ] diff --git a/next/backend/features/review/repository.py b/next/backend/features/review/repository.py new file mode 100644 index 0000000..8250dbf --- /dev/null +++ b/next/backend/features/review/repository.py @@ -0,0 +1,306 @@ +from __future__ import annotations + +import json +import sqlite3 + + +class ReviewRepository: + def watchlist(self, connection: sqlite3.Connection, user_id: int) -> tuple[sqlite3.Row, ...]: + return tuple( + connection.execute( + """SELECT identifier, name, sector, remark, created_at FROM watchlist_entries + WHERE user_id = ? ORDER BY created_at, identifier""", + (user_id,), + ).fetchall() + ) + + def save_watch( + self, connection: sqlite3.Connection, user_id: int, item: dict, now: str + ) -> None: + connection.execute( + """INSERT INTO watchlist_entries (user_id, identifier, name, sector, remark, created_at) + VALUES (?, ?, ?, ?, ?, ?) + ON CONFLICT(user_id, identifier) DO UPDATE SET + name=excluded.name, sector=excluded.sector, + remark=CASE + WHEN excluded.remark = '' THEN watchlist_entries.remark + ELSE excluded.remark + END""", + ( + user_id, + item["identifier"], + item["name"], + item.get("sector"), + item.get("remark") or "", + now, + ), + ) + + def delete_watch(self, connection: sqlite3.Connection, user_id: int, identifier: str) -> bool: + cursor = connection.execute( + "DELETE FROM watchlist_entries WHERE user_id = ? AND identifier = ?", + (user_id, identifier), + ) + return cursor.rowcount > 0 + + def save_watch_remark( + self, connection: sqlite3.Connection, user_id: int, identifier: str, remark: str + ) -> bool: + cursor = connection.execute( + "UPDATE watchlist_entries SET remark=? WHERE user_id=? AND identifier=?", + (remark, user_id, identifier), + ) + return cursor.rowcount > 0 + + def latest_factors(self, connection: sqlite3.Connection, through: str) -> dict[str, dict]: + snapshot = connection.execute( + """SELECT id, trade_date FROM screener_factor_snapshots + WHERE trade_date <= ? ORDER BY trade_date DESC, id DESC LIMIT 1""", + (through,), + ).fetchone() + if snapshot is None: + return {} + return { + str(row["identifier"]): json.loads(str(row["payload_json"])) + for row in connection.execute( + "SELECT identifier, payload_json FROM screener_factor_values WHERE snapshot_id = ?", + (int(snapshot["id"]),), + ).fetchall() + } + + def latest_auction_scores( + self, connection: sqlite3.Connection, through: str + ) -> dict[str, float]: + row = connection.execute( + """SELECT payload_json FROM market_insight_snapshots + WHERE kind = 'auction' AND trade_date <= ? AND entity_key = '' + ORDER BY trade_date DESC LIMIT 1""", + (through,), + ).fetchone() + if row is None: + return {} + payload = json.loads(str(row["payload_json"])) + scores = {} + for key in ("_market_rows", "rows", "one_price_rows"): + for item in payload.get(key) or []: + identifier = str(item.get("identifier") or item.get("ts_code") or "") + score = item.get("attention_score") + if identifier and isinstance(score, (int, float)): + scores[identifier] = float(score) + return scores + + def note( + self, connection: sqlite3.Connection, user_id: int, code: str, trade_date: str + ) -> sqlite3.Row | None: + return connection.execute( + "SELECT * FROM review_notes WHERE user_id = ? AND code = ? AND trade_date = ?", + (user_id, code, trade_date), + ).fetchone() + + def notes( + self, connection: sqlite3.Connection, user_id: int, code: str = "", limit: int = 60 + ) -> tuple[sqlite3.Row, ...]: + return tuple( + connection.execute( + """SELECT * FROM review_notes WHERE user_id = ? AND code = ? + ORDER BY trade_date DESC, id DESC LIMIT ?""", + (user_id, code, limit), + ).fetchall() + ) + + def save_note(self, connection: sqlite3.Connection, user_id: int, data: dict, now: str) -> int: + connection.execute( + """INSERT INTO review_notes ( + user_id, code, stock_name, trade_date, summary, content, plan, + created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(user_id, code, trade_date) DO UPDATE SET + stock_name=excluded.stock_name, summary=excluded.summary, + content=excluded.content, plan=excluded.plan, updated_at=excluded.updated_at""", + ( + user_id, + data["code"], + data["stock_name"], + data["trade_date"], + data["summary"], + data["content"], + data["plan"], + now, + now, + ), + ) + row = self.note(connection, user_id, data["code"], data["trade_date"]) + if row is None: + raise RuntimeError("复盘记录写入失败") + return int(row["id"]) + + def delete_note(self, connection: sqlite3.Connection, user_id: int, note_id: int) -> bool: + cursor = connection.execute( + "DELETE FROM review_notes WHERE user_id = ? AND id = ?", (user_id, note_id) + ) + return cursor.rowcount > 0 + + def trades( + self, connection: sqlite3.Connection, user_id: int, limit: int = 300 + ) -> tuple[sqlite3.Row, ...]: + return tuple( + connection.execute( + """SELECT * FROM trade_entries WHERE user_id = ? + ORDER BY trade_date DESC, id DESC LIMIT ?""", + (user_id, limit), + ).fetchall() + ) + + def trade( + self, connection: sqlite3.Connection, user_id: int, trade_id: int + ) -> sqlite3.Row | None: + return connection.execute( + "SELECT * FROM trade_entries WHERE user_id = ? AND id = ?", (user_id, trade_id) + ).fetchone() + + def save_trade(self, connection: sqlite3.Connection, user_id: int, data: dict, now: str) -> int: + values = ( + data["trade_date"], + data["code"], + data["name"], + data["action"], + data["price"], + data["quantity"], + data["position_pct"], + data["pnl_amount"], + data["pnl_pct"], + data["emotion"], + json.dumps(data["tags"], ensure_ascii=False), + data["thesis"], + data["execution"], + now, + ) + if data.get("id"): + cursor = connection.execute( + """UPDATE trade_entries SET trade_date=?, code=?, name=?, action=?, price=?, + quantity=?, position_pct=?, pnl_amount=?, pnl_pct=?, emotion=?, tags_json=?, + thesis=?, execution=?, updated_at=? WHERE user_id=? AND id=?""", + (*values, user_id, int(data["id"])), + ) + if cursor.rowcount == 0: + raise ValueError("交易记录不存在或无权修改。") + return int(data["id"]) + cursor = connection.execute( + """INSERT INTO trade_entries ( + trade_date, code, name, action, price, quantity, position_pct, pnl_amount, + pnl_pct, emotion, tags_json, thesis, execution, created_at, updated_at, user_id + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", + (*values, now, user_id), + ) + return int(cursor.lastrowid) + + def delete_trade(self, connection: sqlite3.Connection, user_id: int, trade_id: int) -> bool: + cursor = connection.execute( + "DELETE FROM trade_entries WHERE user_id = ? AND id = ?", (user_id, trade_id) + ) + return cursor.rowcount > 0 + + def save_alert(self, connection: sqlite3.Connection, user_id: int, data: dict, now: str) -> int: + connection.execute( + """INSERT INTO alerts ( + user_id, kind, title, content, available_date, code, dedupe_key, + created_at, updated_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT(user_id, dedupe_key) DO NOTHING""", + ( + user_id, + data["kind"], + data["title"], + data["content"], + data["available_date"], + data["code"], + data["dedupe_key"], + now, + now, + ), + ) + row = connection.execute( + "SELECT id FROM alerts WHERE user_id = ? AND dedupe_key = ?", + (user_id, data["dedupe_key"]), + ).fetchone() + return int(row["id"]) + + def alerts( + self, connection: sqlite3.Connection, user_id: int, unread: bool + ) -> tuple[sqlite3.Row, ...]: + clause = "AND is_read = 0" if unread else "" + return tuple( + connection.execute( + f"""SELECT * FROM alerts WHERE user_id = ? {clause} + ORDER BY available_date > date('now'), is_read, + available_date DESC, id DESC LIMIT 100""", + (user_id,), + ).fetchall() + ) + + def unread_count(self, connection: sqlite3.Connection, user_id: int, today: str) -> int: + row = connection.execute( + """SELECT COUNT(*) total FROM alerts + WHERE user_id = ? AND available_date <= ? AND is_read = 0""", + (user_id, today), + ).fetchone() + return int(row["total"]) + + def mark_alert( + self, connection: sqlite3.Connection, user_id: int, alert_id: int, now: str + ) -> bool: + cursor = connection.execute( + "UPDATE alerts SET is_read=1, read_at=?, updated_at=? WHERE user_id=? AND id=?", + (now, now, user_id, alert_id), + ) + return cursor.rowcount > 0 + + def mark_all_alerts( + self, connection: sqlite3.Connection, user_id: int, today: str, now: str + ) -> int: + cursor = connection.execute( + """UPDATE alerts SET is_read=1, read_at=?, updated_at=? + WHERE user_id=? AND available_date <= ? AND is_read=0""", + (now, now, user_id, today), + ) + return int(cursor.rowcount) + + def delete_alert(self, connection: sqlite3.Connection, user_id: int, alert_id: int) -> bool: + cursor = connection.execute( + "DELETE FROM alerts WHERE user_id=? AND id=?", (user_id, alert_id) + ) + return cursor.rowcount > 0 + + def messages( + self, connection: sqlite3.Connection, user_id: int, limit: int = 100 + ) -> tuple[sqlite3.Row, ...]: + rows = connection.execute( + """SELECT * FROM review_assistant_messages WHERE user_id=? + ORDER BY id DESC LIMIT ?""", + (user_id, limit), + ).fetchall() + return tuple(reversed(rows)) + + def add_message( + self, connection: sqlite3.Connection, user_id: int, data: dict, now: str + ) -> None: + connection.execute( + """INSERT INTO review_assistant_messages + (user_id, role, content, context_date, request_id, status, created_at) + VALUES (?, ?, ?, ?, ?, ?, ?)""", + ( + user_id, + data["role"], + data["content"], + data["context_date"], + data.get("request_id"), + data["status"], + now, + ), + ) + + def clear_messages(self, connection: sqlite3.Connection, user_id: int) -> int: + cursor = connection.execute( + "DELETE FROM review_assistant_messages WHERE user_id=?", (user_id,) + ) + return int(cursor.rowcount) diff --git a/next/backend/features/review/routes.py b/next/backend/features/review/routes.py new file mode 100644 index 0000000..334c1ca --- /dev/null +++ b/next/backend/features/review/routes.py @@ -0,0 +1,183 @@ +from __future__ import annotations + +import json +from collections.abc import Iterator +from typing import Annotated + +from fastapi import APIRouter, Path, Query, Request +from fastapi.responses import StreamingResponse + +from backend.features.accounts.auth import ( + AuthenticatedPrincipal, + CsrfPrincipal, + SmartAccessPrincipal, + SmartWritePrincipal, +) +from backend.features.review.schemas import ( + AlertInput, + AssistantInput, + NoteInput, + TradeInput, + WatchInput, + WatchRemarkInput, +) +from backend.features.review.service import ReviewError +from backend.http.errors import AppError +from backend.llm.gateway import LLMGatewayError + +router = APIRouter(prefix="/review", tags=["review"]) + + +@router.get("", response_model=dict) +def workspace( + request: Request, + principal: AuthenticatedPrincipal, + trade_date: Annotated[str, Query(alias="date")], +) -> dict: + return _call(request, "workspace", principal, trade_date) + + +@router.post("/watchlist", response_model=dict) +def add_watch(payload: WatchInput, request: Request, principal: CsrfPrincipal) -> dict: + return _call(request, "add_watch", principal, payload.identifier) + + +@router.patch("/watchlist/{identifier}/remark", response_model=dict) +def save_watch_remark( + payload: WatchRemarkInput, + request: Request, + principal: CsrfPrincipal, + identifier: Annotated[str, Path(min_length=1, max_length=40)], +) -> dict: + _call(request, "save_watch_remark", principal, identifier, payload.remark) + return {"message": "跟踪备注已保存。"} + + +@router.delete("/watchlist/{identifier}", response_model=dict) +def delete_watch( + request: Request, + principal: CsrfPrincipal, + identifier: Annotated[str, Path(min_length=1, max_length=40)], +) -> dict: + _call(request, "delete_watch", principal, identifier) + return {"message": "已移出自选。"} + + +@router.put("/notes", response_model=dict) +def save_note(payload: NoteInput, request: Request, principal: CsrfPrincipal) -> dict: + identifier = _call(request, "save_note", principal, payload.model_dump()) + return {"id": identifier} + + +@router.get("/stock-notes/{code}", response_model=list[dict]) +def stock_notes( + request: Request, + principal: AuthenticatedPrincipal, + code: Annotated[str, Path(min_length=1, max_length=12)], +) -> list[dict]: + return _call(request, "stock_notes", principal, code) + + +@router.delete("/notes/{note_id}", response_model=dict) +def delete_note( + request: Request, + principal: CsrfPrincipal, + note_id: Annotated[int, Path(gt=0)], +) -> dict: + _call(request, "delete_note", principal, note_id) + return {"message": "复盘记录已删除。"} + + +@router.put("/trades", response_model=dict) +def save_trade(payload: TradeInput, request: Request, principal: CsrfPrincipal) -> dict: + identifier = _call(request, "save_trade", principal, payload.model_dump()) + return {"id": identifier} + + +@router.delete("/trades/{trade_id}", response_model=dict) +def delete_trade( + request: Request, + principal: CsrfPrincipal, + trade_id: Annotated[int, Path(gt=0)], +) -> dict: + _call(request, "delete_trade", principal, trade_id) + return {"message": "交易记录已删除。"} + + +@router.get("/alerts", response_model=dict) +def alerts( + request: Request, + principal: AuthenticatedPrincipal, + unread: Annotated[bool, Query()] = False, +) -> dict: + return _call(request, "alert_center", principal, unread) + + +@router.post("/alerts", response_model=dict) +def create_alert(payload: AlertInput, request: Request, principal: CsrfPrincipal) -> dict: + identifier = _call(request, "create_alert", principal, payload.model_dump()) + return {"id": identifier} + + +@router.patch("/alerts/read-all", response_model=dict) +def mark_all_alerts(request: Request, principal: CsrfPrincipal) -> dict: + return {"updated": _call(request, "mark_all_alerts", principal)} + + +@router.patch("/alerts/{alert_id}/read", response_model=dict) +def mark_alert( + request: Request, + principal: CsrfPrincipal, + alert_id: Annotated[int, Path(gt=0)], +) -> dict: + _call(request, "mark_alert", principal, alert_id) + return {"message": "提醒已读。"} + + +@router.delete("/alerts/{alert_id}", response_model=dict) +def delete_alert( + request: Request, + principal: CsrfPrincipal, + alert_id: Annotated[int, Path(gt=0)], +) -> dict: + _call(request, "delete_alert", principal, alert_id) + return {"message": "提醒已删除。"} + + +@router.get("/assistant/messages", response_model=list[dict]) +def assistant_messages(request: Request, principal: SmartAccessPrincipal) -> list[dict]: + return _call(request, "messages", principal) + + +@router.delete("/assistant/messages", response_model=dict) +def clear_assistant_messages(request: Request, principal: SmartWritePrincipal) -> dict: + return {"deleted": _call(request, "clear_messages", principal)} + + +@router.post("/assistant/chat") +def assistant_chat( + payload: AssistantInput, + request: Request, + principal: SmartWritePrincipal, +) -> StreamingResponse: + prepared = _call(request, "prepare_assistant", principal, payload.trade_date, payload.question) + + def body() -> Iterator[bytes]: + for event in request.app.state.container.review.stream_assistant(prepared): + yield (json.dumps(event, ensure_ascii=False, separators=(",", ":")) + "\n").encode() + + return StreamingResponse( + body(), + media_type="application/x-ndjson", + headers={"Cache-Control": "no-cache, no-transform", "X-Accel-Buffering": "no"}, + ) + + +def _call(request: Request, method: str, *args): + try: + return getattr(request.app.state.container.review, method)(*args) + except ReviewError as exc: + raise AppError("review_unavailable", str(exc), 409) from exc + except LLMGatewayError as exc: + status = 403 if exc.code in {"membership_required", "quota_exhausted"} else 503 + raise AppError(exc.code, str(exc), status) from exc diff --git a/next/backend/features/review/schemas.py b/next/backend/features/review/schemas.py new file mode 100644 index 0000000..2149663 --- /dev/null +++ b/next/backend/features/review/schemas.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +from typing import Literal + +from pydantic import BaseModel, Field + + +class WatchInput(BaseModel): + identifier: str = Field(min_length=1, max_length=40) + + +class WatchRemarkInput(BaseModel): + remark: str = Field(max_length=500) + + +class NoteInput(BaseModel): + trade_date: str + code: str = Field(default="", max_length=12) + stock_name: str = Field(default="", max_length=40) + summary: str = Field(default="", max_length=500) + content: str = Field(default="", max_length=5000) + plan: str = Field(default="", max_length=2000) + + +class TradeInput(BaseModel): + id: int | None = Field(default=None, gt=0) + trade_date: str + code: str = Field(min_length=6, max_length=12) + name: str = Field(min_length=1, max_length=40) + action: Literal["buy", "sell", "add", "trim", "watch"] + price: float = Field(ge=0, le=1_000_000) + quantity: int = Field(default=0, ge=0, le=100_000_000) + position_pct: float | None = Field(default=None, ge=0, le=100) + pnl_amount: float | None = Field(default=None, ge=-1e12, le=1e12) + pnl_pct: float | None = Field(default=None, ge=-1000, le=10000) + emotion: Literal["calm", "confident", "hesitant", "anxious", "impulsive"] + tags: list[str] = Field(default_factory=list, max_length=8) + thesis: str = Field(default="", max_length=2000) + execution: str = Field(default="", max_length=2000) + + +class AlertInput(BaseModel): + title: str = Field(min_length=1, max_length=80) + remind_date: str + code: str = Field(default="", max_length=12) + content: str = Field(default="", max_length=500) + + +class AssistantInput(BaseModel): + trade_date: str + question: str = Field(min_length=1, max_length=2000) diff --git a/next/backend/features/review/service.py b/next/backend/features/review/service.py new file mode 100644 index 0000000..af34752 --- /dev/null +++ b/next/backend/features/review/service.py @@ -0,0 +1,368 @@ +from __future__ import annotations + +import secrets +from collections.abc import Iterator +from dataclasses import dataclass +from datetime import date, datetime +from typing import Any +from zoneinfo import ZoneInfo + +from backend.data.gateway import DataGateway +from backend.database.connection import Database +from backend.features.accounts.models import Principal +from backend.features.review.prompt import PROMPT_VERSION, messages +from backend.features.review.repository import ReviewRepository +from backend.features.review.views import alert as alert_view +from backend.features.review.views import note as note_view +from backend.features.review.views import trade_summary, trades +from backend.features.screener.service import ScreenerService +from backend.llm.gateway import LLMCall, LLMGateway, LLMGatewayError + +SHANGHAI = ZoneInfo("Asia/Shanghai") + + +class ReviewError(RuntimeError): + pass + + +@dataclass(frozen=True, slots=True) +class PreparedAssistant: + call: LLMCall + prompt: list[dict[str, str]] + context_date: str + + +class ReviewService: + def __init__( + self, + database: Database, + repository: ReviewRepository, + gateway: DataGateway, + screener: ScreenerService, + llm: LLMGateway, + ) -> None: + self._database = database + self._repository = repository + self._gateway = gateway + self._screener = screener + self._llm = llm + + def workspace(self, principal: Principal, requested_date: str) -> dict[str, Any]: + trade_date = self._trade_date(requested_date) + with self._database.read() as connection: + watches = self._watch_rows(connection, principal.user.id, trade_date) + daily = self._repository.note(connection, principal.user.id, "", trade_date) + history = self._repository.notes(connection, principal.user.id, "", 60) + trade_rows = trades(self._repository.trades(connection, principal.user.id)) + return { + "trade_date": trade_date, + "watchlist": watches, + "daily": note_view(daily), + "history": [note_view(row) for row in history], + "trades": trade_rows, + "trade_summary": trade_summary(trade_rows), + } + + def add_watch(self, principal: Principal, identifier: str) -> dict[str, Any]: + normalized = identifier.strip().upper() + candidates = self._gateway.search(normalized) + item = next( + ( + candidate + for candidate in candidates + if candidate.entity_type == "stock" and candidate.identifier == normalized + ), + None, + ) + if item is None: + raise ReviewError("未找到可加入自选的股票。") + with self._database.transaction() as connection: + self._repository.save_watch( + connection, + principal.user.id, + {"identifier": item.identifier, "name": item.name, "sector": item.sector}, + _now(), + ) + return {"identifier": item.identifier, "name": item.name} + + def save_watch_remark(self, principal: Principal, identifier: str, remark: str) -> None: + normalized = _text(remark, 500) + with self._database.transaction() as connection: + if not self._repository.save_watch_remark( + connection, principal.user.id, identifier, normalized + ): + raise ReviewError("自选记录不存在。") + + def delete_watch(self, principal: Principal, identifier: str) -> None: + with self._database.transaction() as connection: + if not self._repository.delete_watch(connection, principal.user.id, identifier): + raise ReviewError("自选记录不存在。") + + def save_note(self, principal: Principal, payload: dict[str, Any]) -> int: + data = { + "trade_date": _date(payload["trade_date"]), + "code": payload.get("code", "").strip().upper(), + "stock_name": _text(payload.get("stock_name", ""), 40), + "summary": _text(payload.get("summary", ""), 500), + "content": _text(payload.get("content", ""), 5000), + "plan": _text(payload.get("plan", ""), 2000), + } + if data["code"] and not data["stock_name"]: + raise ReviewError("个股名称不能为空。") + with self._database.transaction() as connection: + return self._repository.save_note(connection, principal.user.id, data, _now()) + + def stock_notes(self, principal: Principal, code: str) -> list[dict[str, Any]]: + with self._database.read() as connection: + return [ + note_view(row) + for row in self._repository.notes( + connection, principal.user.id, code.strip().upper() + ) + ] + + def delete_note(self, principal: Principal, note_id: int) -> None: + with self._database.transaction() as connection: + if not self._repository.delete_note(connection, principal.user.id, note_id): + raise ReviewError("复盘记录不存在。") + + def save_trade(self, principal: Principal, payload: dict[str, Any]) -> int: + data = dict(payload) + data["trade_date"] = _date(str(data["trade_date"])) + data["code"] = str(data["code"]).strip().upper() + data["name"] = _text(data["name"], 40, True) + data["thesis"] = _text(data.get("thesis", ""), 2000) + data["execution"] = _text(data.get("execution", ""), 2000) + data["tags"] = [_text(item, 20, True) for item in data.get("tags", [])][:8] + with self._database.transaction() as connection: + return self._repository.save_trade(connection, principal.user.id, data, _now()) + + def delete_trade(self, principal: Principal, trade_id: int) -> None: + with self._database.transaction() as connection: + if not self._repository.delete_trade(connection, principal.user.id, trade_id): + raise ReviewError("交易记录不存在。") + + def alert_center(self, principal: Principal, unread: bool = False) -> dict[str, Any]: + self._sync_tracking_alerts(principal.user.id) + today = date.today().isoformat() + with self._database.read() as connection: + rows = self._repository.alerts(connection, principal.user.id, unread) + items = [alert_view(row, today) for row in rows] + if unread: + items = [item for item in items if item["due"]] + count = self._repository.unread_count(connection, principal.user.id, today) + return {"items": items, "unread_count": count, "as_of": today} + + def create_alert(self, principal: Principal, payload: dict[str, Any]) -> int: + data = { + "kind": "manual", + "title": _text(payload["title"], 80, True), + "content": _text(payload.get("content", ""), 500), + "available_date": _date(payload["remind_date"]), + "code": _text(payload.get("code", ""), 12), + "dedupe_key": f"manual:{secrets.token_hex(12)}", + } + with self._database.transaction() as connection: + return self._repository.save_alert(connection, principal.user.id, data, _now()) + + def mark_alert(self, principal: Principal, alert_id: int) -> None: + with self._database.transaction() as connection: + if not self._repository.mark_alert(connection, principal.user.id, alert_id, _now()): + raise ReviewError("提醒不存在。") + + def mark_all_alerts(self, principal: Principal) -> int: + with self._database.transaction() as connection: + return self._repository.mark_all_alerts( + connection, principal.user.id, date.today().isoformat(), _now() + ) + + def delete_alert(self, principal: Principal, alert_id: int) -> None: + with self._database.transaction() as connection: + if not self._repository.delete_alert(connection, principal.user.id, alert_id): + raise ReviewError("提醒不存在。") + + def messages(self, principal: Principal) -> list[dict[str, Any]]: + with self._database.read() as connection: + return [dict(row) for row in self._repository.messages(connection, principal.user.id)] + + def clear_messages(self, principal: Principal) -> int: + with self._database.transaction() as connection: + return self._repository.clear_messages(connection, principal.user.id) + + def prepare_assistant( + self, principal: Principal, requested_date: str, question: str + ) -> PreparedAssistant: + context_date = self._trade_date(requested_date) + normalized = _text(question, 2000, True) + context = self._assistant_context(principal, context_date) + history = self._history(principal.user.id) + prompt = messages(context, history, normalized) + call = self._llm.prepare( + principal, + feature="review_assistant", + prompt_version=PROMPT_VERSION, + business_id=context_date, + input_chars=sum(len(item["content"]) for item in prompt), + ) + with self._database.transaction() as connection: + self._repository.add_message( + connection, + principal.user.id, + { + "role": "user", + "content": normalized, + "context_date": context_date, + "request_id": call.request_id, + "status": "complete", + }, + _now(), + ) + return PreparedAssistant(call, prompt, context_date) + + def stream_assistant(self, prepared: PreparedAssistant) -> Iterator[dict[str, Any]]: + answer = "" + stream = self._llm.stream(prepared.call, prepared.prompt) + try: + for event in stream: + if event.type == "delta": + answer += event.content + yield { + "type": "delta", + "content": event.content, + "request_id": event.request_id, + } + elif event.type == "done": + self._save_assistant(prepared, answer, "complete") + yield {"type": "done", "request_id": event.request_id} + except GeneratorExit: + stream.close() + if answer: + self._save_assistant(prepared, answer, "stopped") + raise + except LLMGatewayError as exc: + if answer: + self._save_assistant(prepared, answer, "error") + yield {"type": "error", "code": exc.code, "message": str(exc), "partial": exc.partial} + + def _watch_rows(self, connection, user_id: int, trade_date: str) -> list[dict[str, Any]]: + factors = self._repository.latest_factors(connection, trade_date) + auction_scores = self._repository.latest_auction_scores(connection, trade_date) + rows = [] + for watch in self._repository.watchlist(connection, user_id): + factor = factors.get(str(watch["identifier"]), {}) + rows.append( + { + **dict(watch), + "code": str(watch["identifier"]).split(".")[0], + "pct_chg": factor.get("pct_chg"), + "return_5d": factor.get("return_5d"), + "attention_score": auction_scores.get(str(watch["identifier"])), + "remark": str(watch["remark"]), + } + ) + return rows + + def _sync_tracking_alerts(self, user_id: int) -> None: + tracks = self._screener.tracks(user_id) + batches: dict[int, list[dict]] = {} + for item in tracks: + batches.setdefault(int(item["run_id"]), []).append(item) + with self._database.transaction() as connection: + for run_id, items in batches.items(): + name = str(items[0]["strategy_name"]) + if any(item.get("t1_return") is not None for item in items): + self._repository.save_alert( + connection, + user_id, + { + "kind": "strategy_t1", + "title": f"{name} 已有 T+1 反馈", + "content": ( + f"{sum(item.get('t1_return') is not None for item in items)}" + f"/{len(items)} 只标的已有首日表现。" + ), + "available_date": date.today().isoformat(), + "code": "", + "dedupe_key": f"strategy:{run_id}:t1", + }, + _now(), + ) + if items and all(item.get("t5_return") is not None for item in items): + self._repository.save_alert( + connection, + user_id, + { + "kind": "strategy_t5", + "title": f"{name} 五日跟踪完成", + "content": f"本批 {len(items)} 只标的已完成 T+5 跟踪。", + "available_date": date.today().isoformat(), + "code": "", + "dedupe_key": f"strategy:{run_id}:t5", + }, + _now(), + ) + + def _assistant_context(self, principal: Principal, trade_date: str) -> dict[str, Any]: + summary = self._gateway.summary(trade_date) + workspace = self.workspace(principal, trade_date) + alerts = self.alert_center(principal)["items"][:20] + return { + "data_date": trade_date, + "market_facts": summary["values"], + "user_records": { + "watchlist": workspace["watchlist"][:30], + "daily_reviews": workspace["history"][:10], + "strategy_tracking": self._screener.tracks(principal.user.id)[:30], + "alerts": alerts, + "trade_summary": workspace["trade_summary"], + "trade_entries": workspace["trades"][:30], + }, + } + + def _history(self, user_id: int) -> list[dict[str, str]]: + with self._database.read() as connection: + rows = self._repository.messages(connection, user_id, 20) + return [ + {"role": str(row["role"]), "content": str(row["content"])[:4000]} for row in rows[-12:] + ] + + def _save_assistant(self, prepared: PreparedAssistant, answer: str, status: str) -> None: + if not answer: + return + with self._database.transaction() as connection: + self._repository.add_message( + connection, + prepared.call.user_id, + { + "role": "assistant", + "content": answer, + "context_date": prepared.context_date, + "request_id": prepared.call.request_id, + "status": status, + }, + _now(), + ) + + def _trade_date(self, value: str) -> str: + requested = _date(value) + return self._gateway.trade_context(requested).actual_date or requested + + +def _date(value: str) -> str: + try: + return date.fromisoformat(value).isoformat() + except ValueError as exc: + raise ReviewError("日期格式无效。") from exc + + +def _text(value: Any, limit: int, required: bool = False) -> str: + normalized = " ".join(str(value or "").split()) + if required and not normalized: + raise ReviewError("必填内容不能为空。") + if len(normalized) > limit: + raise ReviewError(f"内容不能超过{limit}个字符。") + return normalized + + +def _now() -> str: + return datetime.now(SHANGHAI).isoformat(timespec="seconds") diff --git a/next/backend/features/review/views.py b/next/backend/features/review/views.py new file mode 100644 index 0000000..d9e4e0b --- /dev/null +++ b/next/backend/features/review/views.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import json +from typing import Any + +ACTIONS = {"buy": "买入", "sell": "卖出", "add": "加仓", "trim": "减仓", "watch": "观察"} +EMOTIONS = { + "calm": "平静", + "confident": "笃定", + "hesitant": "犹豫", + "anxious": "焦虑", + "impulsive": "冲动", +} + + +def note(row) -> dict[str, Any] | None: + return dict(row) if row is not None else None + + +def trades(rows) -> list[dict[str, Any]]: + result = [] + for row in rows: + item = dict(row) + item["tags"] = json.loads(str(item.pop("tags_json"))) + item["action_label"] = ACTIONS[str(item["action"])] + item["emotion_label"] = EMOTIONS[str(item["emotion"])] + result.append(item) + return result + + +def trade_summary(items: list[dict[str, Any]]) -> dict[str, Any]: + realized = [ + item for item in items if item["pnl_amount"] is not None or item["pnl_pct"] is not None + ] + wins = sum( + float(item["pnl_pct"] if item["pnl_pct"] is not None else item["pnl_amount"]) > 0 + for item in realized + ) + amounts = [float(item["pnl_amount"]) for item in items if item["pnl_amount"] is not None] + positions = [float(item["position_pct"]) for item in items if item["position_pct"] is not None] + return { + "total": len(items), + "realized": len(realized), + "win_rate": round(wins / len(realized) * 100, 1) if realized else None, + "pnl_amount": round(sum(amounts), 2) if amounts else None, + "average_position": round(sum(positions) / len(positions), 1) if positions else None, + } + + +def alert(row, today: str) -> dict[str, Any]: + item = dict(row) + item["is_read"] = bool(item["is_read"]) + item["due"] = str(item["available_date"]) <= today + return item diff --git a/next/backend/http/router.py b/next/backend/http/router.py index c44d1cf..73fb435 100644 --- a/next/backend/http/router.py +++ b/next/backend/http/router.py @@ -4,6 +4,7 @@ from backend.features.accounts.routes import router as accounts_router from backend.features.heaven.routes import router as heaven_router from backend.features.market.routes import router as market_router from backend.features.mentor.routes import router as mentor_router +from backend.features.review.routes import router as review_router from backend.features.screener.routes import router as screener_router from backend.http.routes.health import router as health_router @@ -14,3 +15,4 @@ api_router.include_router(market_router) api_router.include_router(screener_router) api_router.include_router(mentor_router) api_router.include_router(heaven_router) +api_router.include_router(review_router) diff --git a/next/docs/evidence/stage-12/acceptance.md b/next/docs/evidence/stage-12/acceptance.md new file mode 100644 index 0000000..2d72cde --- /dev/null +++ b/next/docs/evidence/stage-12/acceptance.md @@ -0,0 +1,46 @@ +# 阶段12验收记录 + +## 完成范围 + +- 我的复盘:账户独立的自选追踪、交易日志、每日复盘、历史记录和个股复盘笔记。 +- 提醒中心:手动提醒、策略T+1/T+5提醒、未读状态、批量已读和持久化去重。 +- 复盘助手:统一LLM网关、结构化复盘上下文、流式回答、历史与清空。 +- 权限:复盘私有数据严格按账号隔离;非会员保留完整助手界面并灰化锁定。 +- 前端:PC与移动端、日间与夜间、顶栏提醒入口和个股详情笔记入口。 + +## 关键行为 + +- 每日复盘按账号和交易日唯一更新,三个输入区分别保存盘面摘要、得失和明日计划。 +- 交易日志只统计已填写盈亏字段的已实现记录;零收益进入胜率分母但不计为盈利。 +- 重复加入已有自选不会清空跟踪备注;自选、笔记、交易、提醒和助手历史均不可跨账号读取或修改。 +- 策略跟踪提醒以运行批次和T+1/T+5阶段生成稳定去重键,重复读取提醒中心不会重复创建。 +- 复盘助手只读取本地市场快照和当前账号记录,不执行交易,不建立第二套模型、配额或流式实现。 + +## 自动验收 + +- Ruff:通过。 +- Pytest:92项通过。 +- Vue TypeScript:通过。 +- Vitest:3个文件、7项通过。 +- Vite生产构建:通过。 +- Playwright:阶段4至12共14项通过,固定单工作进程避免共享验收账号并发互相撤销会话。 +- 数据库:版本10前进、回退、账户隔离和每日复盘唯一更新测试通过。 +- Git差异检查:通过。 +- 密钥扫描:已提供的账号密码和Token值无匹配。 + +## 视觉证据 + +- `review-dark-1920x1080.jpg` +- `review-dark-390x844.jpg` + +## 减法审计 + +- 未导入旧复盘页面、旧自选存储、旧助手脚本或旧弹窗覆盖层。 +- 复盘领域只有一组Repository、Service和Routes;响应转换拆入54行的`views.py`,业务Service保持368行。 +- 复盘助手继续复用阶段10唯一LLM网关,顶栏提醒和助手继续复用全局弹窗Host。 +- 页面按复盘、交易弹窗、提醒、助手和个股笔记拆分;页面样式397行,没有新增令牌外色值或间距字面值。 + +## 残余边界 + +- 策略提醒依赖盘后跟踪指标已写入;缺少T+1/T+5结果时不会伪造提醒。 +- NAS生产容器保持不变,最终切换仍需人工确认。 diff --git a/next/docs/evidence/stage-12/review-dark-1920x1080.jpg b/next/docs/evidence/stage-12/review-dark-1920x1080.jpg new file mode 100644 index 0000000000000000000000000000000000000000..dc311631815c23a0d1e8972bbe9bce246bb54c2d GIT binary patch literal 111371 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

y&6#4Sa&6x%6pb#ZJ>;B&4HNCFx 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 BX?*|y literal 0 HcmV?d00001 diff --git a/next/frontend/src/app/shell/TopBar.vue b/next/frontend/src/app/shell/TopBar.vue index 83fdaae..80a9d28 100644 --- a/next/frontend/src/app/shell/TopBar.vue +++ b/next/frontend/src/app/shell/TopBar.vue @@ -3,6 +3,7 @@ import { computed, onBeforeUnmount, onMounted, ref } from "vue"; import { useRoute, useRouter } from "vue-router"; import { marketApi } from "../../shared/api/market"; +import { reviewApi } from "../../shared/api/review"; import { useMarketStore } from "../../shared/stores/market"; import { useSessionStore } from "../../shared/stores/session"; import { useUiStore } from "../../shared/stores/ui"; @@ -70,7 +71,12 @@ async function refreshMarket(): Promise { } } -onMounted(() => document.addEventListener("mousedown", closeOnOutside)); +async function refreshAlerts(): Promise { + try { ui.alertUnread = (await reviewApi.alerts()).unread_count; } + catch { ui.alertUnread = 0; } +} + +onMounted(() => { document.addEventListener("mousedown", closeOnOutside); void refreshAlerts(); }); onBeforeUnmount(() => document.removeEventListener("mousedown", closeOnOutside)); @@ -84,7 +90,8 @@ onBeforeUnmount(() => document.removeEventListener("mousedown", closeOnOutside)) - + + diff --git a/next/frontend/src/app/views/EntityDetailView.vue b/next/frontend/src/app/views/EntityDetailView.vue index bf0d5f9..714b5cd 100644 --- a/next/frontend/src/app/views/EntityDetailView.vue +++ b/next/frontend/src/app/views/EntityDetailView.vue @@ -4,6 +4,7 @@ import { useRoute } from "vue-router"; import type { MarketEntity } from "../../shared/api/market"; import MarketPreviewPanel from "../../shared/market/MarketPreviewPanel.vue"; +import StockNotes from "../../pages/review/StockNotes.vue"; const route = useRoute(); const entity = computed(() => ({ @@ -22,5 +23,6 @@ const entity = computed(() => ({ 最新真实行情 + diff --git a/next/frontend/src/app/views/WorkspaceView.vue b/next/frontend/src/app/views/WorkspaceView.vue index 784110f..585f261 100644 --- a/next/frontend/src/app/views/WorkspaceView.vue +++ b/next/frontend/src/app/views/WorkspaceView.vue @@ -7,6 +7,7 @@ import MarketWorkspaceView from "../../pages/market/MarketWorkspaceView.vue"; import ScreenerPage from "../../pages/screener/ScreenerPage.vue"; import MentorPage from "../../pages/mentor/MentorPage.vue"; import HeavenPage from "../../pages/heaven/HeavenPage.vue"; +import ReviewPage from "../../pages/review/ReviewPage.vue"; import { useMarketStore } from "../../shared/stores/market"; import { useSessionStore } from "../../shared/stores/session"; import { useUiStore } from "../../shared/stores/ui"; @@ -35,6 +36,7 @@ const implementedMarket = computed(() => +