feat: AI 即时分析计费/共识/校准与 Docker 前端构建

- 即时分析:先扣费、防重入(429)、失败退款;记忆库与离线校准 worker
- 多周期共识、客观分与设置项 AI_ANALYSIS_CONSENSUS_TIMEFRAMES
- Docker:前端多阶段构建(QuantDinger-Vue-src)、根目录 .dockerignore、compose 调整
- 同步 frontend/dist 静态资源

Made-with: Cursor
This commit is contained in:
dinger
2026-03-20 21:08:26 +08:00
parent b91cfcc7fa
commit 9473e50d59
27 changed files with 1197 additions and 103 deletions
+26 -6
View File
@@ -1,12 +1,32 @@
# QuantDinger Frontend - Pre-built Static Files
# No build step needed - dist/ is already compiled.
# QuantDinger Frontend — multi-stage build
# Build context: repository root (see docker-compose.yml)
#
# Stage 1: compile Vue app from QuantDinger-Vue-src
# Stage 2: nginx static + API reverse proxy (nginx.conf)
FROM node:18-alpine AS builder
WORKDIR /app
# Layer cache: deps only
COPY QuantDinger-Vue-src/package.json QuantDinger-Vue-src/package-lock.json ./
RUN npm ci
COPY QuantDinger-Vue-src/ ./
# Match local production build (`npm run build` in QuantDinger-Vue-src)
ENV NODE_OPTIONS=--max_old_space_size=4096
RUN npm run build
# --- runtime ---
FROM nginx:1.25-alpine
# Copy pre-built frontend files
COPY dist/ /usr/share/nginx/html/
# curl: docker-compose healthcheck
RUN apk add --no-cache curl
# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/dist /usr/share/nginx/html/
COPY frontend/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -33,31 +33,35 @@ html{--antd-wave-shadow-color:#1890ff}
#nprogress .bar{background:#1890ff}
#nprogress .peg{-webkit-box-shadow:0 0 10px #1890ff,0 0 5px #1890ff;box-shadow:0 0 10px #1890ff,0 0 5px #1890ff}
#nprogress .spinner-icon{border-top-color:#1890ff;border-left-color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .loading-header .loading-icon-pro[data-v-110dde64]{color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .progress-wrapper .progress-text[data-v-110dde64]{color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .current-step[data-v-110dde64]{color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .steps-list .step-item.active[data-v-110dde64]{background:#e6f7ff;color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .steps-list .step-item.active .step-dot[data-v-110dde64]{background:#1890ff;-webkit-box-shadow:0 0 0 3px rgba(24,144,255,.2);box-shadow:0 0 0 3px rgba(24,144,255,.2)}
.fast-analysis-report .result-container .decision-card[data-v-110dde64]{border-left:6px solid #1890ff}
.fast-analysis-report .result-container .price-info-row .price-card.current[data-v-110dde64]{border-top:3px solid #1890ff}
.fast-analysis-report .result-container .scores-row .score-item .score-header .anticon[data-v-110dde64]{color:#1890ff}
.fast-analysis-report .result-container .scores-row .score-item.overall[data-v-110dde64]{background:linear-gradient(135deg,#e6f7ff,#fff);border:1px solid #91d5ff}
.fast-analysis-report .result-container .detailed-analysis .analysis-card[data-v-110dde64]{border-left:4px solid #1890ff}
.fast-analysis-report .result-container .detailed-analysis .analysis-card.technical[data-v-110dde64]{border-left-color:#1890ff}
.fast-analysis-report .result-container .detailed-analysis .analysis-card .analysis-card-header.technical .anticon[data-v-110dde64]{color:#1890ff}
.fast-analysis-report .result-container .analysis-details .detail-section .detail-list li[data-v-110dde64]:before{color:#1890ff}
.fast-analysis-report .result-container .indicators-section .section-title .anticon[data-v-110dde64]{color:#1890ff}
.fast-analysis-report.theme-dark .decision-card[data-v-110dde64]{border-left-color:#1890ff}
.fast-analysis-report.theme-dark .detailed-analysis .analysis-card.technical[data-v-110dde64]{border-left-color:#1890ff}
.fast-analysis-report.theme-dark .score-item.overall[data-v-110dde64]{background:linear-gradient(135deg,rgba(24,144,255,.1),#2a2e39);border-color:#1890ff}
.left-panel .heatmap-box .box-header[data-v-76a3e064] .ant-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{background:var(--primary-color,#1890ff);border-color:var(--primary-color,#1890ff)}
.left-panel .calendar-box .box-header .box-title .anticon[data-v-76a3e064]{color:var(--primary-color,#1890ff)}
.right-panel .analysis-toolbar .analyze-button[data-v-76a3e064]{background:var(--primary-color,#1890ff);border-color:var(--primary-color,#1890ff)}
.right-panel .analysis-main .analysis-placeholder .placeholder-content .placeholder-icon[data-v-76a3e064]{color:var(--primary-color,#1890ff)}
.watchlist-panel .watchlist-list .watchlist-item.active[data-v-76a3e064]{background:#e6f7ff;border:1px solid #91d5ff}
.ai-analysis-container.theme-dark .watchlist-panel .watchlist-list .watchlist-item.active[data-v-76a3e064]{background:rgba(24,144,255,.1);border-color:#1890ff}
.ai-analysis-container.theme-dark .watchlist-bar-legacy .stock-chip.active[data-v-76a3e064],.ai-analysis-container.theme-dark .watchlist-bar-legacy .stock-chip[data-v-76a3e064]:hover{border-color:var(--primary-color,#1890ff);background:rgba(24,144,255,.1)}
.ai-analysis-container.theme-dark .watchlist-bar-compat .stock-chip.active[data-v-76a3e064],.ai-analysis-container.theme-dark .watchlist-bar-compat .stock-chip[data-v-76a3e064]:hover{border-color:var(--primary-color,#1890ff);background:rgba(24,144,255,.1)}
.fast-analysis-report .loading-container .loading-content-pro .loading-header .loading-icon-pro[data-v-693144f6]{color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .progress-wrapper .progress-text[data-v-693144f6]{color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .current-step[data-v-693144f6]{color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .steps-list .step-item.active[data-v-693144f6]{background:#e6f7ff;color:#1890ff}
.fast-analysis-report .loading-container .loading-content-pro .steps-list .step-item.active .step-dot[data-v-693144f6]{background:#1890ff;-webkit-box-shadow:0 0 0 3px rgba(24,144,255,.2);box-shadow:0 0 0 3px rgba(24,144,255,.2)}
.fast-analysis-report .result-container .decision-card[data-v-693144f6]{border-left:6px solid #1890ff}
.fast-analysis-report .result-container .decision-card .consensus-strip[data-v-693144f6]{background:rgba(24,144,255,.06);border:1px solid rgba(24,144,255,.2)}
.fast-analysis-report .result-container .decision-card .consensus-strip .consensus-strip-title[data-v-693144f6]{color:#1890ff}
.fast-analysis-report .result-container .price-info-row .price-card.current[data-v-693144f6]{border-top:3px solid #1890ff}
.fast-analysis-report .result-container .scores-row .score-item .score-header .anticon[data-v-693144f6]{color:#1890ff}
.fast-analysis-report .result-container .scores-row .score-item.overall[data-v-693144f6]{background:linear-gradient(135deg,#e6f7ff,#fff);border:1px solid #91d5ff}
.fast-analysis-report .result-container .detailed-analysis .analysis-card[data-v-693144f6]{border-left:4px solid #1890ff}
.fast-analysis-report .result-container .detailed-analysis .analysis-card.technical[data-v-693144f6]{border-left-color:#1890ff}
.fast-analysis-report .result-container .detailed-analysis .analysis-card .analysis-card-header.technical .anticon[data-v-693144f6]{color:#1890ff}
.fast-analysis-report .result-container .analysis-details .detail-section .detail-list li[data-v-693144f6]:before{color:#1890ff}
.fast-analysis-report .result-container .indicators-section .section-title .anticon[data-v-693144f6]{color:#1890ff}
.fast-analysis-report.theme-dark .decision-card[data-v-693144f6]{border-left-color:#1890ff}
.fast-analysis-report.theme-dark .decision-card .consensus-strip[data-v-693144f6]{background:rgba(24,144,255,.12);border-color:rgba(24,144,255,.35)}
.fast-analysis-report.theme-dark .decision-card .consensus-strip .consensus-strip-title[data-v-693144f6]{color:#69c0ff}
.fast-analysis-report.theme-dark .detailed-analysis .analysis-card.technical[data-v-693144f6]{border-left-color:#1890ff}
.fast-analysis-report.theme-dark .score-item.overall[data-v-693144f6]{background:linear-gradient(135deg,rgba(24,144,255,.1),#2a2e39);border-color:#1890ff}
.left-panel .heatmap-box .box-header[data-v-41eda137] .ant-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{background:var(--primary-color,#1890ff);border-color:var(--primary-color,#1890ff)}
.left-panel .calendar-box .box-header .box-title .anticon[data-v-41eda137]{color:var(--primary-color,#1890ff)}
.right-panel .analysis-toolbar .analyze-button[data-v-41eda137]{background:var(--primary-color,#1890ff);border-color:var(--primary-color,#1890ff)}
.right-panel .analysis-main .analysis-placeholder .placeholder-content .placeholder-icon[data-v-41eda137]{color:var(--primary-color,#1890ff)}
.watchlist-panel .watchlist-list .watchlist-item.active[data-v-41eda137]{background:#e6f7ff;border:1px solid #91d5ff}
.ai-analysis-container.theme-dark .watchlist-panel .watchlist-list .watchlist-item.active[data-v-41eda137]{background:rgba(24,144,255,.1);border-color:#1890ff}
.ai-analysis-container.theme-dark .watchlist-bar-legacy .stock-chip.active[data-v-41eda137],.ai-analysis-container.theme-dark .watchlist-bar-legacy .stock-chip[data-v-41eda137]:hover{border-color:var(--primary-color,#1890ff);background:rgba(24,144,255,.1)}
.ai-analysis-container.theme-dark .watchlist-bar-compat .stock-chip.active[data-v-41eda137],.ai-analysis-container.theme-dark .watchlist-bar-compat .stock-chip[data-v-41eda137]:hover{border-color:var(--primary-color,#1890ff);background:rgba(24,144,255,.1)}
.qt-header .qt-header-left .qt-icon[data-v-0d547552]{color:#1890ff}
.theme-dark[data-v-0d547552] .ant-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{background:#1890ff;border-color:#1890ff}
.theme-dark[data-v-0d547552] .ant-slider-track{background:#1890ff}
+1 -1
View File
@@ -421,4 +421,4 @@
.brand-text {
font-size: 20px;
}
}</style><script defer="defer" src="/js/chunk-vendors.b7f38551.js" type="module"></script><script defer="defer" src="/js/app.d094c0fc.js" type="module"></script><link href="/css/chunk-vendors.b8cb9e53.css" rel="stylesheet"><link href="/css/app.ee3dda40.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors-legacy.2846149e.js" nomodule></script><script defer="defer" src="/js/app-legacy.f346bd4d.js" nomodule></script></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><div class="first-loading-wrp"><h2>Landing</h2><div class="loading-wrp"><div class="pixel-cat-container"><div class="ground"></div><div class="pixel-cat"><div class="cat-head"><div class="cat-ear-left"></div><div class="cat-ear-right"></div><div class="cat-eye-left"></div><div class="cat-eye-right"></div><div class="cat-nose"></div><div class="cat-whiskers"></div></div><div class="cat-body"></div><div class="cat-leg-front-left"></div><div class="cat-leg-front-right"></div><div class="cat-leg-back-left"></div><div class="cat-leg-back-right"></div><div class="cat-tail"></div></div></div></div><div class="brand-text">QuantDinger</div></div></div></body></html>
}</style><script defer="defer" src="/js/chunk-vendors.e3ae0d1f.js" type="module"></script><script defer="defer" src="/js/app.de48b29a.js" type="module"></script><link href="/css/chunk-vendors.b8cb9e53.css" rel="stylesheet"><link href="/css/app.ee3dda40.css" rel="stylesheet"><script defer="defer" src="/js/chunk-vendors-legacy.beabf087.js" nomodule></script><script defer="defer" src="/js/app-legacy.a9e4bd9c.js" nomodule></script></head><body><noscript><strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><div class="first-loading-wrp"><h2>Landing</h2><div class="loading-wrp"><div class="pixel-cat-container"><div class="ground"></div><div class="pixel-cat"><div class="cat-head"><div class="cat-ear-left"></div><div class="cat-ear-right"></div><div class="cat-eye-left"></div><div class="cat-eye-right"></div><div class="cat-nose"></div><div class="cat-whiskers"></div></div><div class="cat-body"></div><div class="cat-leg-front-left"></div><div class="cat-leg-front-right"></div><div class="cat-leg-back-left"></div><div class="cat-leg-back-right"></div><div class="cat-tail"></div></div></div></div><div class="brand-text">QuantDinger</div></div></div></body></html>
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long