This commit is contained in:
aaron 2025-05-17 20:59:12 +08:00
parent 84597702c8
commit 971e6ed98a
4 changed files with 78 additions and 176 deletions

View File

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

View File

@ -1242,7 +1242,7 @@ body {
.desktop-user-info {
display: flex;
flex-direction: column;
padding: 1.25rem;
padding: 0.75rem;
margin-top: auto;
border-top: 1px solid rgba(0, 0, 0, 0.08);
background-color: var(--color-bg-secondary);
@ -1254,9 +1254,9 @@ body {
.desktop-user-info .user-info-box {
display: flex;
align-items: center;
gap: 1rem;
gap: 0.75rem;
cursor: pointer;
padding: 0.75rem;
padding: 0.5rem;
border-radius: var(--border-radius);
transition: all 0.3s ease;
background-color: rgba(255, 255, 255, 0.05);
@ -1271,14 +1271,14 @@ body {
}
.desktop-user-info .user-avatar {
width: 3rem;
height: 3rem;
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
background: linear-gradient(135deg, var(--color-accent) 0%, rgba(51, 85, 255, 0.8) 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.2rem;
font-size: 1rem;
color: white;
font-weight: bold;
box-shadow: 0 3px 10px rgba(51, 85, 255, 0.25);
@ -1333,14 +1333,14 @@ body {
/* 认证按钮样式 */
.auth-button {
width: 100%;
padding: 0.75rem;
padding: 0.6rem;
border: 1px solid var(--color-accent);
border-radius: var(--border-radius);
font-size: 0.95rem;
font-size: 0.9rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
margin: 0.5rem 0;
margin: 0.25rem 0;
background: none;
color: var(--color-accent);
}
@ -1575,14 +1575,14 @@ body {
display: flex;
flex-direction: column;
flex: 1;
padding: 0.25rem 0;
padding: 0.15rem 0;
}
.desktop-user-info .user-nickname {
font-size: 1.05rem;
font-size: 0.95rem;
font-weight: var(--font-weight-medium);
color: var(--color-text-primary);
margin-bottom: 0.3rem;
margin-bottom: 0.2rem;
transition: all 0.2s ease;
display: block;
text-overflow: ellipsis;
@ -1592,7 +1592,7 @@ body {
}
.desktop-user-info .user-points {
font-size: 0.85rem;
font-size: 0.8rem;
color: var(--color-text-secondary);
display: flex;
align-items: center;

View File

@ -337,7 +337,7 @@ const copyAnalysis = async () => {
/* 搜索区域样式 */
.search-section {
width: 100%;
max-width: 600px;
max-width: 800px;
transition: all 0.5s ease;
}

View File

@ -7,12 +7,6 @@ interface AnalysisRequest {
timeframe?: string
}
interface HistoryItem {
code: string
timeframe: string
timestamp: number
}
const userStore = useUserStore()
const cryptoCode = ref('')
const isAnalyzing = ref(false)
@ -52,9 +46,6 @@ const handleKeydown = (event: KeyboardEvent) => {
const handleAnalysis = async () => {
if (!cryptoCode.value.trim() || isAnalyzing.value) return
//
addToHistory(cryptoCode.value.trim(), selectedTimeframe.value)
showInitialView.value = false
isAnalyzing.value = true
analysisContent.value = ''
@ -186,56 +177,24 @@ const copyAnalysis = async () => {
}
}
const HISTORY_KEY = 'crypto_search_history'
const MAX_HISTORY = 5
const searchHistory = ref<HistoryItem[]>([])
//
const commonAnalysisList = [
{ code: 'BTC', timeframe: '15m', label: 'BTC 15分钟' },
{ code: 'BTC', timeframe: '1h', label: 'BTC 1小时' },
{ code: 'BTC', timeframe: '4h', label: 'BTC 4小时' },
{ code: 'BTC', timeframe: '1d', label: 'BTC 日线' },
{ code: 'ETH', timeframe: '15m', label: 'ETH 15分钟' },
{ code: 'ETH', timeframe: '1h', label: 'ETH 1小时' },
{ code: 'ETH', timeframe: '4h', label: 'ETH 4小时' },
{ code: 'ETH', timeframe: '1d', label: 'ETH 日线' },
]
//
const loadSearchHistory = () => {
const history = localStorage.getItem(HISTORY_KEY)
if (history) {
searchHistory.value = JSON.parse(history)
}
}
//
const addToHistory = (code: string, timeframe: string) => {
const newItem = {
code: code.toUpperCase(),
timeframe,
timestamp: Date.now(),
}
const history = searchHistory.value.filter(
(item) => !(item.code === newItem.code && item.timeframe === newItem.timeframe),
)
history.unshift(newItem)
searchHistory.value = history.slice(0, MAX_HISTORY)
localStorage.setItem(HISTORY_KEY, JSON.stringify(searchHistory.value))
}
//
const selectFromHistory = (item: HistoryItem) => {
//
const handleCommonAnalysis = (item: { code: string; timeframe: string }) => {
cryptoCode.value = item.code
selectedTimeframe.value = item.timeframe
handleAnalysis()
}
//
const removeFromHistory = (item: HistoryItem) => {
searchHistory.value = searchHistory.value.filter(
(h) => !(h.code === item.code && h.timeframe === item.timeframe),
)
localStorage.setItem(HISTORY_KEY, JSON.stringify(searchHistory.value))
}
//
const clearHistory = () => {
searchHistory.value = []
localStorage.removeItem(HISTORY_KEY)
}
//
loadSearchHistory()
</script>
<template>
@ -257,7 +216,7 @@ loadSearchHistory()
v-model="cryptoCode"
type="text"
class="search-input"
placeholder="请输入加密货币代码,如 BTC、ETH、SOL"
placeholder="请输入BTC、ETH仅支持输入一个分析。"
@keydown="handleKeydown"
:disabled="isAnalyzing"
/>
@ -304,40 +263,22 @@ loadSearchHistory()
</div>
</div>
<!-- 搜索历史 -->
<div class="search-history-section">
<div v-if="searchHistory.length > 0 && !isAnalyzing" class="search-history-container">
<div class="history-header">
<span class="history-title">搜索历史</span>
<button class="clear-history" @click="clearHistory">清空</button>
<!-- 快速分析列表 -->
<div class="common-analysis-section">
<div class="common-analysis-container">
<div class="section-header">
<span class="section-title">快速分析</span>
</div>
<div class="history-list">
<div
v-for="item in searchHistory"
:key="`${item.code}-${item.timeframe}`"
class="history-item"
<div class="common-analysis-list">
<button
v-for="item in commonAnalysisList"
:key="item.label"
class="common-analysis-item"
@click="handleCommonAnalysis(item)"
:disabled="isAnalyzing"
>
<button class="history-code" @click="selectFromHistory(item)">
<span class="code">{{ item.code }}</span>
<span class="timeframe">{{
timeframes.find((t) => t.value === item.timeframe)?.label
}}</span>
</button>
<button class="remove-history" @click.stop="removeFromHistory(item)">
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="remove-icon"
>
<line x1="18" y1="6" x2="6" y2="18"></line>
<line x1="6" y1="6" x2="18" y2="18"></line>
</svg>
</button>
</div>
{{ item.label }}
</button>
</div>
</div>
</div>
@ -438,7 +379,7 @@ loadSearchHistory()
flex-direction: column;
align-items: center;
margin-bottom: 15vh;
gap: 2rem;
gap: 1.5rem;
transition: all 0.5s ease;
}
@ -463,7 +404,7 @@ loadSearchHistory()
.search-section {
width: 100%;
max-width: 600px;
max-width: 800px;
transition: all 0.5s ease;
padding: 0 1.5rem;
}
@ -1455,122 +1396,83 @@ loadSearchHistory()
background-color: rgba(125, 125, 125, 0.3);
}
.search-history-section {
/* 快速分析列表样式 */
.common-analysis-section {
width: 100%;
max-width: 600px;
max-width: 800px;
margin: 0 auto;
padding: 0 1.5rem;
/* margin-top: 0.5rem; */
}
.search-history-container {
.common-analysis-container {
width: 100%;
padding: 0 1.5rem;
margin-bottom: 1.5rem;
}
.history-header {
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.75rem;
}
.history-title {
.section-title {
font-size: 0.9rem;
color: var(--color-text-secondary);
}
.clear-history {
font-size: 0.85rem;
color: var(--color-text-secondary);
background: none;
border: none;
cursor: pointer;
padding: 0.25rem 0.5rem;
transition: all 0.2s ease;
}
.clear-history:hover {
color: var(--color-accent);
}
.history-list {
.common-analysis-list {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.history-item {
display: flex;
align-items: center;
gap: 0.25rem;
}
.history-code {
display: flex;
align-items: center;
gap: 0.5rem;
.common-analysis-item {
padding: 0.35rem 0.75rem;
font-size: 0.9rem;
color: var(--color-text-primary);
color: var(--color-accent);
background-color: var(--color-bg-secondary);
border: 1px solid var(--color-border);
border: 1px solid var(--color-accent);
border-radius: var(--border-radius);
cursor: pointer;
transition: all 0.2s ease;
}
.history-code:hover {
background-color: var(--color-bg-secondary);
border-color: var(--color-accent);
opacity: 0.9;
.common-analysis-item:hover:not(:disabled) {
background-color: var(--color-accent);
color: white;
}
.history-code .code {
font-weight: 500;
color: var(--color-accent);
}
.history-code .timeframe {
font-size: 0.85rem;
color: var(--color-text-secondary);
padding: 0.1rem 0.4rem;
background-color: rgba(var(--color-accent-rgb), 0.05);
border-radius: var(--border-radius);
}
.remove-history {
display: flex;
align-items: center;
justify-content: center;
padding: 0.25rem;
background: none;
border: none;
cursor: pointer;
color: var(--color-text-secondary);
.common-analysis-item:disabled {
opacity: 0.6;
transition: all 0.2s ease;
}
.remove-history:hover {
opacity: 1;
color: var(--color-accent);
}
.remove-icon {
width: 14px;
height: 14px;
cursor: not-allowed;
border-color: var(--color-border);
color: var(--color-text-secondary);
}
@media (max-width: 768px) {
.search-history-section {
.common-analysis-section {
padding: 0 1rem;
}
.common-analysis-container {
padding: 0 1rem;
}
}
@media (max-width: 480px) {
.search-history-section {
.common-analysis-section {
padding: 0 0.75rem;
}
.common-analysis-container {
padding: 0 0.75rem;
}
.common-analysis-item {
font-size: 0.85rem;
padding: 0.3rem 0.6rem;
}
}
</style>