rebuild(stage-12): deliver private review workflows

This commit is contained in:
leefer
2026-07-30 07:45:55 +08:00
parent 0a055867a4
commit b93fb3ec41
32 changed files with 2292 additions and 9 deletions
+9 -2
View File
@@ -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<void> {
}
}
onMounted(() => document.addEventListener("mousedown", closeOnOutside));
async function refreshAlerts(): Promise<void> {
try { ui.alertUnread = (await reviewApi.alerts()).unread_count; }
catch { ui.alertUnread = 0; }
}
onMounted(() => { document.addEventListener("mousedown", closeOnOutside); void refreshAlerts(); });
onBeforeUnmount(() => document.removeEventListener("mousedown", closeOnOutside));
</script>
@@ -84,7 +90,8 @@ onBeforeUnmount(() => document.removeEventListener("mousedown", closeOnOutside))
<button class="icon-button" type="button" aria-label="后一日" title="后一日" @click="market.moveDate(1)"></button>
</div>
<button class="icon-button" type="button" aria-label="全局搜索" title="全局搜索(Ctrl+K" @click="ui.openDialog('search')"></button>
<button class="icon-button desktop-only" type="button" aria-label="提醒中心" title="提醒中心" @click="ui.showToast('暂无新提醒')">!</button>
<button class="icon-button topbar-alert desktop-only" type="button" aria-label="提醒中心" title="提醒中心" @click="ui.openDialog('alerts')">!<span v-if="ui.alertUnread" class="alert-badge">{{ ui.alertUnread > 99 ? '99+' : ui.alertUnread }}</span></button>
<button class="icon-button desktop-only" type="button" aria-label="复盘助手" title="复盘助手" @click="ui.openDialog('assistant')"></button>
<button class="btn btn-small" type="button" :title="ui.theme === 'light' ? '切换夜间模式' : '切换日间模式'" @click="ui.toggleTheme">
{{ ui.theme === "light" ? "夜间" : "日间" }}
</button>
@@ -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<MarketEntity>(() => ({
@@ -22,5 +23,6 @@ const entity = computed<MarketEntity>(() => ({
<span class="tag">最新真实行情</span>
</header>
<MarketPreviewPanel :entity="entity" class="card entity-chart" />
<StockNotes v-if="entity.entity_type === 'stock'" :code="entity.code" :name="entity.name" />
</main>
</template>
@@ -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(() =>
<ScreenerPage v-else-if="workspace.key === 'screener'" />
<MentorPage v-else-if="workspace.key === 'mentor'" />
<HeavenPage v-else-if="workspace.key === 'heaven'" />
<ReviewPage v-else-if="workspace.key === 'review'" />
<main v-else class="page-frame">
<header class="page-header">
<h1>{{ workspace.title }}</h1>