refactor: CSS残留hex清理+内联样式提取+console.log降级+错误toast补全

- components.css: 10处hex替换为CSS变量(stoploss/watch/signal/alert-change/toast)
- pages.css: 20+处hex替换(ss-dot信号强度/step操作色/summary-tag/trade-type/reason-item)
- auth.css: 2处hex替换(login-error/login-success)
- base.css: 新增30+公共CSS class(cursor-pointer/flex-center/input-mini/icon-sm等)
- index.html: 41处内联style提取为CSS class(93→52)
- app.js: 14处console.log降级为console.debug(减少生产日志噪音)
- app.js: 5处用户可感知catch块补充showToast错误反馈
This commit is contained in:
selfrelease
2026-07-18 09:28:37 +08:00
parent b3c21c6f91
commit 03e095ded0
6 changed files with 140 additions and 93 deletions
+2 -2
View File
@@ -120,14 +120,14 @@
}
.login-error {
color: #ff4444;
color: var(--danger);
font-size: 13px;
margin-bottom: 12px;
text-align: center;
}
.login-success {
color: #00ff88;
color: var(--success);
font-size: 13px;
margin-bottom: 12px;
text-align: center;
+43 -1
View File
@@ -383,7 +383,7 @@
}
.scan-source-select option {
background: #1a1a2e;
background: var(--bg-dark);
color: var(--text-primary);
padding: 10px;
}
@@ -773,4 +773,46 @@
color: var(--text-muted);
line-height: 1.5;
}
/* ===== 内联样式提取的公共 class ===== */
.cursor-pointer { cursor: pointer; }
.margin-top-sm { margin-top: 8px; }
.margin-top-md { margin-top: 15px; }
.margin-bottom-sm { margin-bottom: 8px; }
.margin-bottom-md { margin-bottom: 12px; }
.margin-left-auto { margin-left: auto; }
.margin-right-sm { margin-right: 6px; }
.text-xs { font-size: 11px; }
.text-sm { font-size: 12px; }
.text-md { font-size: 13px; }
.text-muted-2 { color: var(--text-muted); }
.text-secondary-2 { color: var(--text-secondary); }
.text-danger { color: var(--danger); }
.text-success { color: var(--success); }
.text-warning { color: var(--warning); }
.text-info { color: var(--info); }
.font-weight-600 { font-weight: 600; }
.flex-center { display: flex; align-items: center; gap: 4px; }
.flex-wrap-gap { display: flex; flex-wrap: wrap; gap: 6px; }
.grid-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.hidden { display: none; }
.opacity-70 { opacity: 0.7; }
.padding-y-sm { padding: 8px 0; }
.max-height-scroll { max-height: 300px; overflow-y: auto; }
.icon-sm { width: 16px; height: 16px; vertical-align: -2px; margin-right: 4px; }
.icon-xs { width: 14px; height: 14px; vertical-align: -2px; margin-right: 3px; }
.input-mini {
width: 60px; background: var(--bg-dark); border: 1px solid var(--border-color);
color: var(--text-primary); border-radius: 4px; padding: 2px 6px;
}
.input-mini-wide {
width: 80px; background: var(--bg-dark); border: 1px solid var(--border-color);
color: var(--text-primary); border-radius: 4px; padding: 2px 6px;
}
.badge-mini {
background: var(--bg-dark); padding: 1px 6px; border-radius: 8px; font-size: 10px;
}
.border-top-divider {
margin-top: 10px; border-top: 1px solid var(--border-color); padding-top: 10px;
}
+10 -10
View File
@@ -438,7 +438,7 @@
}
.stoploss-sell-btn:hover {
background: #ff6666;
background: var(--danger);
}
/* 基本面弹窗样式 */
@@ -502,7 +502,7 @@
}
.watch-btn.add:hover {
background: #00cc6a;
background: var(--success);
}
.watch-btn.remove {
@@ -592,7 +592,7 @@
}
.signal-chip.triggered {
background: rgba(239,68,68,0.12);
color: #ef4444;
color: var(--danger);
border: 1px solid rgba(239,68,68,0.25);
}
.signal-chip.inactive {
@@ -606,7 +606,7 @@
border-radius: 50%;
display: inline-block;
}
.signal-dot.on { background: #ef4444; }
.signal-dot.on { background: var(--danger); }
.signal-dot.off { background: var(--text-muted); opacity: 0.4; }
.signal-summary {
font-size: 12px;
@@ -614,7 +614,7 @@
border-radius: 6px;
background: var(--bg-secondary);
}
.signal-strong { color: #ef4444; font-weight: 600; }
.signal-strong { color: var(--danger); font-weight: 600; }
.signal-normal { color: var(--text-secondary); }
.signal-none { color: var(--text-muted); }
@@ -1826,7 +1826,7 @@
}
.alert-price {
font-size: 12px;
color: #ffd700;
color: var(--warning);
margin-left: auto;
font-weight: 500;
}
@@ -1839,14 +1839,14 @@
font-weight: 500;
margin-right: 4px;
}
.alert-change.up { color: #ff4444; }
.alert-change.down { color: #00ce9e; }
.alert-change.up { color: var(--up); }
.alert-change.down { color: var(--down); }
.alert-sig-tag {
font-size: 10px;
padding: 1px 6px;
border-radius: 3px;
background: rgba(0, 206, 158, 0.15);
color: #00ce9e;
color: var(--success);
}
.refresh-btn {
@@ -1932,7 +1932,7 @@
.toast-container.info .toast-icon {
background: rgba(100, 150, 255, 0.2);
color: #6496ff;
color: var(--info);
}
.toast-container.success .toast-icon {
+22 -22
View File
@@ -89,8 +89,8 @@
.tech-recommend-reason { font-size: 12px; color: var(--text-secondary); margin-top: 6px; }
.tech-holding-note {
margin-top: 8px; padding: 6px 10px;
background: rgba(255,152,0,0.08); border-radius: 6px;
font-size: 12px; color: #e67e00; line-height: 1.5;
background: rgba(255,170,0,0.08); border-radius: 6px;
font-size: 12px; color: var(--warning); line-height: 1.5;
}
.tech-indicators {
@@ -843,9 +843,9 @@
color: var(--text-secondary);
}
.step-watch .step-action { color: #748ffc; }
.step-buy .step-action { color: #ff6b6b; }
.step-add .step-action { color: #00ce9e; }
.step-hold .step-action { color: #ffd93d; }
.step-buy .step-action { color: var(--danger); }
.step-add .step-action { color: var(--success); }
.step-hold .step-action { color: var(--warning); }
/* 核心信号一句话总结 */
.signal-summary-list {
@@ -869,11 +869,11 @@
}
.summary-tag.core {
background: rgba(255, 107, 107, 0.15);
color: #ff6b6b;
color: var(--danger);
}
.summary-tag.normal {
background: rgba(0, 206, 158, 0.15);
color: #00ce9e;
color: var(--success);
}
.summary-tag.aux {
background: rgba(255,255,255,0.08);
@@ -1287,13 +1287,13 @@
flex-shrink: 0;
}
.ss-dot.s85 { background: #ff4444; }
.ss-dot.s80 { background: #ff6b35; }
.ss-dot.s75 { background: #4CAF50; }
.ss-dot.s70 { background: #2196F3; }
.ss-dot.s65 { background: #9C27B0; }
.ss-dot.s60 { background: #FF9800; }
.ss-dot.s55 { background: #607D8B; }
.ss-dot.s85 { background: var(--sig-85); }
.ss-dot.s80 { background: var(--sig-80); }
.ss-dot.s75 { background: var(--sig-75); }
.ss-dot.s70 { background: var(--sig-70); }
.ss-dot.s65 { background: var(--sig-65); }
.ss-dot.s60 { background: var(--sig-60); }
.ss-dot.s55 { background: var(--sig-55); }
.ss-name {
font-weight: 600;
@@ -1315,7 +1315,7 @@
.ss-badge.active {
background: rgba(0, 200, 83, 0.2);
color: #00c853;
color: var(--down);
border: 1px solid rgba(0, 200, 83, 0.4);
}
@@ -1431,12 +1431,12 @@
.trade-type-tag.buy {
background: rgba(76, 175, 80, 0.2);
color: #4caf50;
color: var(--success);
}
.trade-type-tag.sell, .trade-type-tag.partial_sell {
background: rgba(244, 67, 54, 0.2);
color: #f44336;
color: var(--danger);
}
.trade-stock {
@@ -1451,7 +1451,7 @@
}
.trade-fee {
color: #ff9800;
color: var(--warning);
font-size: 11px;
}
@@ -1474,22 +1474,22 @@
.result-reason-item.reason-limit {
background: rgba(255, 152, 0, 0.1);
border-left: 3px solid #ff9800;
border-left: 3px solid var(--warning);
}
.result-reason-item.reason-cash {
background: rgba(33, 150, 243, 0.1);
border-left: 3px solid #2196f3;
border-left: 3px solid var(--info);
}
.result-reason-item.reason-sell {
background: rgba(244, 67, 54, 0.08);
border-left: 3px solid #f44336;
border-left: 3px solid var(--danger);
}
.result-reason-item.reason-buy {
background: rgba(76, 175, 80, 0.08);
border-left: 3px solid #4caf50;
border-left: 3px solid var(--success);
}
.result-reason-item.reason-info {
+18 -13
View File
@@ -541,10 +541,10 @@
const response = await axios.get('/api/me');
if (response.data.success && response.data.user) {
this.currentUser = response.data.user;
console.log('已登录:', this.currentUser.username);
console.debug('已登录:', this.currentUser.username);
}
} catch (e) {
console.log('未登录');
console.debug('未登录');
} finally {
this.checkingAuth = false;
}
@@ -791,7 +791,7 @@
return response.data.data.stock_name;
}
} catch (e) {
console.log('获取股票名称失败');
console.debug('获取股票名称失败');
}
return null;
},
@@ -1235,19 +1235,19 @@
// 版本不匹配则强制刷新
if (cacheVer < ALERT_CACHE_VERSION) {
console.log(`缓存版本过旧(v${cacheVer} < v${ALERT_CACHE_VERSION}),强制刷新`);
console.debug(`缓存版本过旧(v${cacheVer} < v${ALERT_CACHE_VERSION}),强制刷新`);
} else {
this.stockAlerts = cachedAlerts;
console.log(`加载缓存数据: ${cachedAlerts.length}条, 更新时间: ${lastUpdate}, v${cacheVer}`);
console.debug(`加载缓存数据: ${cachedAlerts.length}条, 更新时间: ${lastUpdate}, v${cacheVer}`);
if (cacheDate === today) {
console.log('缓存是今天的,无需更新');
console.debug('缓存是今天的,无需更新');
this.alertsLoading = false;
this.updateHoldingPricesFromAlerts();
const cachedCodes = new Set(cachedAlerts.map(a => a.code));
const newStocks = allStocks.filter(s => !cachedCodes.has(s.code));
if (newStocks.length > 0) {
console.log(`发现${newStocks.length}只新股票,增量更新`);
console.debug(`发现${newStocks.length}只新股票,增量更新`);
await this.analyzeNewStocks(newStocks, today);
}
return;
@@ -1255,7 +1255,7 @@
}
}
} catch (err) {
console.log('加载缓存失败,将重新分析:', err);
console.debug('加载缓存失败,将重新分析:', err);
}
}
@@ -1264,7 +1264,7 @@
this.alertsProgress = { current: 0, total: allStocks.length };
try {
console.log(`开始信号分析 ${allStocks.length} 只股票...`);
console.debug(`开始信号分析 ${allStocks.length} 只股票...`);
const startTime = Date.now();
const response = await axios.post('/api/signal_alerts', {
@@ -1273,14 +1273,14 @@
});
const elapsed = ((Date.now() - startTime) / 1000).toFixed(1);
console.log(`信号分析完成,耗时 ${elapsed}s`);
console.debug(`信号分析完成,耗时 ${elapsed}s`);
if (response.data.success) {
const results = response.data.results || [];
this.alertsProgress.current = allStocks.length;
this.stockAlerts = [...results];
console.log(`成功: ${response.data.success_count}`);
console.debug(`成功: ${response.data.success_count}`);
// 3. 保存到缓存
this.saveAlertsCache(this.stockAlerts);
@@ -1296,7 +1296,7 @@
} catch (err) {
console.error('批量分析请求失败:', err);
// 回退到逐个分析
console.log('回退到逐个分析模式...');
console.debug('回退到逐个分析模式...');
await this.analyzeStocksOneByOne(allStocks, today, forceRefresh);
}
@@ -1445,7 +1445,7 @@
lastUpdate: new Date().toISOString().replace('T', ' ').split('.')[0],
version: ALERT_CACHE_VERSION
});
console.log('分析结果已保存到缓存');
console.debug('分析结果已保存到缓存');
} catch (err) {
console.error('保存缓存失败:', err);
}
@@ -1562,6 +1562,7 @@
await this.loadAvailableCash();
} catch (err) {
console.error('加载交易记录失败:', err);
this.showToast('加载交易记录失败', 'error');
}
},
@@ -1752,6 +1753,7 @@
}
} catch (error) {
console.error('检查止损失败:', error);
this.showToast('检查止损失败,请稍后重试', 'error');
}
},
@@ -2161,6 +2163,7 @@
}
} catch (err) {
console.error('技术信号检测失败:', err);
this.showToast('技术信号检测失败,请稍后重试', 'error');
} finally {
this.techLoading = false;
}
@@ -2187,6 +2190,7 @@
}
} catch (err) {
console.error('批量技术信号检测失败:', err);
this.showToast('批量检测失败,请稍后重试', 'error');
} finally {
this.techLoading = false;
}
@@ -2241,6 +2245,7 @@
}
} catch (err) {
console.error('获取扫描结果失败:', err);
this.showToast('获取扫描结果失败,请稍后重试', 'error');
} finally {
this.fullScanLoading = false;
}