This commit is contained in:
aaron 2025-05-15 15:42:24 +08:00
parent d079bb164e
commit b497f2c7c8
3 changed files with 133 additions and 104 deletions

View File

@ -5,7 +5,7 @@ services:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
image: tradus-web:1.14 image: tradus-web:1.15
container_name: tradus-web container_name: tradus-web
ports: ports:
- '6000:80' - '6000:80'

View File

@ -223,24 +223,34 @@ const copyAnalysis = async () => {
<span class="label">正在分析股票</span> <span class="label">正在分析股票</span>
<span class="value">{{ stockCode }}</span> <span class="value">{{ stockCode }}</span>
</div> </div>
<button class="new-analysis-button" @click="resetView" :disabled="isAnalyzing"> <div class="action-buttons" v-if="!isAnalyzing">
<svg <button class="action-button" @click="resetView">
class="icon" <svg
viewBox="0 0 24 24" class="icon"
fill="none" viewBox="0 0 24 24"
stroke="currentColor" fill="none"
stroke-width="2" stroke="currentColor"
stroke-linecap="round" stroke-width="2"
stroke-linejoin="round" stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="22 12 18 12 15 12"></polyline>
<path d="M11.5 3a17 17 0 0 0-6.5 2.5L2 8"></path>
<path d="M2 3v5h5"></path>
<path d="M13.5 21a17 17 0 0 0 6.5-2.5L22 16"></path>
<path d="M22 21v-5h-5"></path>
</svg>
<span>重新分析</span>
</button>
<button
class="action-button copy"
@click="copyAnalysis"
:class="{ success: copySuccess }"
> >
<polyline points="22 12 18 12 15 12"></polyline> <span v-if="!copySuccess">复制结果</span>
<path d="M11.5 3a17 17 0 0 0-6.5 2.5L2 8"></path> <span v-else>复制成功</span>
<path d="M2 3v5h5"></path> </button>
<path d="M13.5 21a17 17 0 0 0 6.5-2.5L22 16"></path> </div>
<path d="M22 21v-5h-5"></path>
</svg>
<span>新的分析</span>
</button>
</div> </div>
<div v-if="isAnalyzing" class="analysis-status"> <div v-if="isAnalyzing" class="analysis-status">
@ -261,12 +271,6 @@ const copyAnalysis = async () => {
:class="{ 'fade-in': analysisContent }" :class="{ 'fade-in': analysisContent }"
> >
<div class="analysis-content" v-html="analysisContent"></div> <div class="analysis-content" v-html="analysisContent"></div>
<div v-if="analysisContent && !isAnalyzing" class="copy-button-container">
<button class="copy-button" @click="copyAnalysis" :class="{ success: copySuccess }">
<span v-if="!copySuccess">复制分析结果</span>
<span v-else>复制成功</span>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -567,9 +571,17 @@ const copyAnalysis = async () => {
align-items: flex-start; align-items: flex-start;
} }
.new-analysis-button { .action-buttons {
width: 100%; width: 100%;
flex-direction: row;
gap: 0.75rem;
}
.action-button {
flex: 1;
justify-content: center; justify-content: center;
padding: 0.6rem;
font-size: 0.85rem;
} }
.analysis-container { .analysis-container {
@ -580,11 +592,6 @@ const copyAnalysis = async () => {
padding: 1.25rem 1.5rem; padding: 1.25rem 1.5rem;
font-size: 0.9rem; font-size: 0.9rem;
} }
.copy-button-container {
bottom: 1.5rem;
right: 1.5rem;
}
} }
@media (max-width: 480px) { @media (max-width: 480px) {
@ -652,14 +659,13 @@ const copyAnalysis = async () => {
padding: 0.75rem; padding: 0.75rem;
} }
.copy-button-container { .action-buttons {
bottom: 1rem; gap: 0.5rem;
right: 1rem;
} }
.copy-button { .action-button {
padding: 0.6rem 1.2rem; padding: 0.5rem;
font-size: 0.85rem; font-size: 0.8rem;
} }
} }
@ -698,7 +704,13 @@ const copyAnalysis = async () => {
font-size: 0.9rem; font-size: 0.9rem;
} }
.new-analysis-button { .action-buttons {
display: flex;
gap: 1rem;
align-items: center;
}
.action-button {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
@ -709,19 +721,30 @@ const copyAnalysis = async () => {
color: var(--color-accent); color: var(--color-accent);
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
font-size: 0.9rem;
font-weight: 500;
} }
.new-analysis-button:hover:not(:disabled) { .action-button:hover {
background-color: var(--color-accent); background-color: var(--color-accent);
color: white; color: white;
} }
.new-analysis-button:disabled { .action-button.copy {
opacity: 0.6; background-color: var(--color-accent);
cursor: not-allowed; color: white;
} }
.new-analysis-button .icon { .action-button.copy:hover {
opacity: 0.9;
}
.action-button.copy.success {
background-color: #4caf50;
border-color: #4caf50;
}
.action-button .icon {
width: 16px; width: 16px;
height: 16px; height: 16px;
} }
@ -743,36 +766,4 @@ const copyAnalysis = async () => {
:deep(*::-webkit-scrollbar-thumb:hover) { :deep(*::-webkit-scrollbar-thumb:hover) {
background-color: rgba(125, 125, 125, 0.3); background-color: rgba(125, 125, 125, 0.3);
} }
.copy-button-container {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 10;
}
.copy-button {
display: flex;
align-items: center;
justify-content: center;
padding: 0.75rem 1.5rem;
border: none;
border-radius: var(--border-radius);
background-color: var(--color-accent);
color: white;
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.copy-button:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}
.copy-button.success {
background-color: #4caf50;
}
</style> </style>

View File

@ -246,24 +246,34 @@ const copyAnalysis = async () => {
timeframes.find((t) => t.value === selectedTimeframe)?.label timeframes.find((t) => t.value === selectedTimeframe)?.label
}}</span> }}</span>
</div> </div>
<button class="new-analysis-button" @click="resetView" :disabled="isAnalyzing"> <div class="action-buttons" v-if="!isAnalyzing">
<svg <button class="action-button" @click="resetView">
class="icon" <svg
viewBox="0 0 24 24" class="icon"
fill="none" viewBox="0 0 24 24"
stroke="currentColor" fill="none"
stroke-width="2" stroke="currentColor"
stroke-linecap="round" stroke-width="2"
stroke-linejoin="round" stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="22 12 18 12 15 12"></polyline>
<path d="M11.5 3a17 17 0 0 0-6.5 2.5L2 8"></path>
<path d="M2 3v5h5"></path>
<path d="M13.5 21a17 17 0 0 0 6.5-2.5L22 16"></path>
<path d="M22 21v-5h-5"></path>
</svg>
<span>重新分析</span>
</button>
<button
class="action-button copy"
@click="copyAnalysis"
:class="{ success: copySuccess }"
> >
<polyline points="22 12 18 12 15 12"></polyline> <span v-if="!copySuccess">复制结果</span>
<path d="M11.5 3a17 17 0 0 0-6.5 2.5L2 8"></path> <span v-else>复制成功</span>
<path d="M2 3v5h5"></path> </button>
<path d="M13.5 21a17 17 0 0 0 6.5-2.5L22 16"></path> </div>
<path d="M22 21v-5h-5"></path>
</svg>
<span>新的分析</span>
</button>
</div> </div>
<div v-if="isAnalyzing" class="analysis-status"> <div v-if="isAnalyzing" class="analysis-status">
@ -283,12 +293,6 @@ const copyAnalysis = async () => {
:class="{ 'fade-in': analysisContent }" :class="{ 'fade-in': analysisContent }"
> >
<div class="analysis-content" v-html="analysisContent"></div> <div class="analysis-content" v-html="analysisContent"></div>
<div v-if="analysisContent && !isAnalyzing" class="copy-button-container">
<button class="copy-button" @click="copyAnalysis" :class="{ success: copySuccess }">
<span v-if="!copySuccess">复制分析结果</span>
<span v-else>复制成功</span>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -783,9 +787,17 @@ const copyAnalysis = async () => {
align-items: flex-start; align-items: flex-start;
} }
.new-analysis-button { .action-buttons {
width: 100%; width: 100%;
flex-direction: row;
gap: 0.75rem;
}
.action-button {
flex: 1;
justify-content: center; justify-content: center;
padding: 0.6rem;
font-size: 0.85rem;
} }
.analysis-content { .analysis-content {
@ -880,6 +892,15 @@ const copyAnalysis = async () => {
font-size: 0.85rem; font-size: 0.85rem;
padding: 0.6rem; padding: 0.6rem;
} }
.action-buttons {
gap: 0.5rem;
}
.action-button {
padding: 0.5rem;
font-size: 0.8rem;
}
} }
.search-container.is-analyzing { .search-container.is-analyzing {
@ -1186,7 +1207,13 @@ const copyAnalysis = async () => {
border-radius: var(--border-radius); border-radius: var(--border-radius);
} }
.new-analysis-button { .action-buttons {
display: flex;
gap: 1rem;
align-items: center;
}
.action-button {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
@ -1197,19 +1224,30 @@ const copyAnalysis = async () => {
color: var(--color-accent); color: var(--color-accent);
cursor: pointer; cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
font-size: 0.9rem;
font-weight: 500;
} }
.new-analysis-button:hover:not(:disabled) { .action-button:hover {
background-color: var(--color-accent); background-color: var(--color-accent);
color: white; color: white;
} }
.new-analysis-button:disabled { .action-button.copy {
opacity: 0.6; background-color: var(--color-accent);
cursor: not-allowed; color: white;
} }
.new-analysis-button .icon { .action-button.copy:hover {
opacity: 0.9;
}
.action-button.copy.success {
background-color: #4caf50;
border-color: #4caf50;
}
.action-button .icon {
width: 16px; width: 16px;
height: 16px; height: 16px;
} }