- 星座运势: 天聚数行API集成,5维进度条+幸运标签+今日概述 - AI资讯: 天聚数行API,图文布局5条展示,文件缓存2小时刷新 - 知识卡片: AI生成,关键字+提示词配置,30分钟刷新 - 桌面设置: 独立WebView2窗口,760x1350,含壁纸/布局/城市/颜色等配置 - 显示控制: 壁纸/时间/天气/星座/知识/AI资讯独立开关,秒显示开关 - 文件缓存: 星座运势+AI资讯缓存到本地,启动即显示上次数据 - initDone防抖: 防止设置窗口初始化触发卡片重载
669 lines
19 KiB
HTML
669 lines
19 KiB
HTML
<!-- v4 -->
|
|
<!DOCTYPE html>
|
|
<html lang="zh">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<style>
|
|
* { margin: 0; padding: 0; }
|
|
html, body {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
background: #000;
|
|
font-family: "Microsoft YaHei", sans-serif;
|
|
color: #fff;
|
|
}
|
|
|
|
/* ===== 公共卡片样式 ===== */
|
|
.card {
|
|
background: rgba(0, 0, 0, 0.25);
|
|
backdrop-filter: blur(24px);
|
|
-webkit-backdrop-filter: blur(24px);
|
|
border-radius: 20px;
|
|
padding: 24px 28px;
|
|
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255,255,255,0.08);
|
|
}
|
|
|
|
.time {
|
|
font-size: 72px;
|
|
font-weight: 200;
|
|
text-shadow: 0 2px 20px rgba(0,0,0,0.5);
|
|
letter-spacing: -2px;
|
|
line-height: 1;
|
|
font-variant-numeric: tabular-nums;
|
|
font-family: "Segoe UI", "Microsoft YaHei", sans-serif;
|
|
}
|
|
@keyframes hourlyGlow {
|
|
0% { text-shadow: 0 0 30px rgba(255,255,255,1), 0 0 80px rgba(180,200,255,0.8), 0 0 120px rgba(100,150,255,0.5); color: #fff; }
|
|
8% { text-shadow: 0 0 50px rgba(255,255,255,1), 0 0 100px rgba(180,200,255,1), 0 0 160px rgba(100,150,255,0.6); }
|
|
18% { text-shadow: 0 0 20px rgba(255,255,255,0.6), 0 0 40px rgba(180,200,255,0.3); }
|
|
28% { text-shadow: 0 0 35px rgba(255,255,255,0.85), 0 0 70px rgba(180,200,255,0.6), 0 0 100px rgba(100,150,255,0.35); }
|
|
38% { text-shadow: 0 0 15px rgba(255,255,255,0.4), 0 0 30px rgba(180,200,255,0.2); }
|
|
48% { text-shadow: 0 0 25px rgba(255,255,255,0.6), 0 0 50px rgba(180,200,255,0.4); }
|
|
60% { text-shadow: 0 0 10px rgba(255,255,255,0.25), 0 0 20px rgba(180,200,255,0.12); }
|
|
75% { text-shadow: 0 0 15px rgba(255,255,255,0.35), 0 0 30px rgba(180,200,255,0.2); }
|
|
100% { text-shadow: 0 2px 20px rgba(0,0,0,0.5); color: #fff; }
|
|
}
|
|
.time.hourly-glow {
|
|
animation: hourlyGlow 6s ease-out forwards;
|
|
}
|
|
.date {
|
|
font-size: 14px;
|
|
color: rgba(255,255,255,0.7);
|
|
margin-bottom: 6px;
|
|
text-shadow: 0 1px 6px rgba(0,0,0,0.5);
|
|
letter-spacing: 0.5px;
|
|
}
|
|
|
|
.current-weather {
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
color: rgba(255,255,255,0.95);
|
|
text-shadow: 0 1px 4px rgba(0,0,0,0.5);
|
|
margin-bottom: 14px;
|
|
}
|
|
.forecast-title {
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
color: rgba(255,255,255,0.45);
|
|
letter-spacing: 1px;
|
|
margin-bottom: 8px;
|
|
}
|
|
.weather-forecast {
|
|
display: flex;
|
|
gap: 6px;
|
|
overflow-x: auto;
|
|
padding-bottom: 6px;
|
|
justify-content: flex-end;
|
|
}
|
|
.forecast-item {
|
|
background: rgba(255,255,255,0.06);
|
|
border-radius: 10px;
|
|
padding: 10px 12px;
|
|
text-align: center;
|
|
min-width: 58px;
|
|
font-size: 12px;
|
|
color: rgba(255,255,255,0.85);
|
|
border: 1px solid rgba(255,255,255,0.04);
|
|
}
|
|
.forecast-icon { font-size: 20px; margin: 4px 0; }
|
|
.forecast-time { opacity: 0.6; font-size: 10px; }
|
|
.forecast-temp { font-weight: 600; margin-top: 2px; font-size: 13px; }
|
|
.daily-forecast {
|
|
display: flex;
|
|
gap: 6px;
|
|
overflow-x: auto;
|
|
padding-bottom: 6px;
|
|
justify-content: flex-end;
|
|
}
|
|
.daily-item {
|
|
background: rgba(255,255,255,0.04);
|
|
border-radius: 8px;
|
|
padding: 8px 10px;
|
|
text-align: center;
|
|
min-width: 54px;
|
|
font-size: 12px;
|
|
color: rgba(255,255,255,0.85);
|
|
border: 1px solid rgba(255,255,255,0.03);
|
|
}
|
|
.daily-icon { font-size: 20px; margin: 3px 0; }
|
|
|
|
.zodiac-text {
|
|
font-size: 14px;
|
|
color: rgba(255,255,255,0.9);
|
|
line-height: 1.6;
|
|
text-shadow: 0 1px 4px rgba(0,0,0,0.5);
|
|
}
|
|
.zodiac-title {
|
|
font-size: 15px;
|
|
font-weight: 500;
|
|
margin-bottom: 2px;
|
|
}
|
|
.zodiac-date {
|
|
font-size: 11px;
|
|
opacity: 0.4;
|
|
margin-bottom: 14px;
|
|
}
|
|
.zodiac-bar {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 7px;
|
|
font-size: 12px;
|
|
}
|
|
.zodiac-bar-label {
|
|
width: 28px;
|
|
opacity: 0.55;
|
|
flex-shrink: 0;
|
|
}
|
|
.zodiac-bar-track {
|
|
flex: 1;
|
|
height: 4px;
|
|
background: rgba(255,255,255,0.08);
|
|
border-radius: 2px;
|
|
overflow: hidden;
|
|
}
|
|
.zodiac-bar-fill {
|
|
height: 100%;
|
|
border-radius: 2px;
|
|
transition: width 0.6s ease;
|
|
}
|
|
.zodiac-bar-val {
|
|
width: 30px;
|
|
text-align: right;
|
|
font-size: 11px;
|
|
opacity: 0.7;
|
|
flex-shrink: 0;
|
|
}
|
|
.zodiac-tags {
|
|
display: flex;
|
|
gap: 6px;
|
|
flex-wrap: wrap;
|
|
margin: 12px 0;
|
|
}
|
|
.zodiac-tag {
|
|
font-size: 10px;
|
|
background: rgba(255,255,255,0.06);
|
|
padding: 2px 8px;
|
|
border-radius: 5px;
|
|
opacity: 0.6;
|
|
}
|
|
.zodiac-summary {
|
|
font-size: 12px;
|
|
opacity: 0.6;
|
|
line-height: 1.7;
|
|
}
|
|
|
|
/* ===== AI 资讯 ===== */
|
|
.ainews-header {
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
color: rgba(255,255,255,0.45);
|
|
letter-spacing: 1px;
|
|
margin-bottom: 10px;
|
|
}
|
|
.ainews-item {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-bottom: 10px;
|
|
padding-bottom: 10px;
|
|
border-bottom: 1px solid rgba(255,255,255,0.06);
|
|
}
|
|
.ainews-item:last-child {
|
|
margin-bottom: 0;
|
|
padding-bottom: 0;
|
|
border-bottom: none;
|
|
}
|
|
.ainews-img {
|
|
width: 80px;
|
|
height: 54px;
|
|
border-radius: 6px;
|
|
object-fit: cover;
|
|
flex-shrink: 0;
|
|
opacity: 0.85;
|
|
}
|
|
.ainews-body {
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
.ainews-title-row {
|
|
display: flex;
|
|
align-items: baseline;
|
|
gap: 6px;
|
|
}
|
|
.ainews-title {
|
|
font-size: 13px;
|
|
color: rgba(255,255,255,0.9);
|
|
line-height: 1.4;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
.ainews-source {
|
|
font-size: 10px;
|
|
opacity: 0.4;
|
|
flex-shrink: 0;
|
|
}
|
|
.ainews-desc {
|
|
font-size: 11px;
|
|
opacity: 0.5;
|
|
line-height: 1.5;
|
|
margin-top: 4px;
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: 2;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* ===== 知识卡片 ===== */
|
|
.knowledge-header {
|
|
font-size: 11px;
|
|
color: rgba(255,255,255,0.45);
|
|
margin-bottom: 8px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
letter-spacing: 0.5px;
|
|
}
|
|
.knowledge-keyword-tag {
|
|
background: rgba(255,255,255,0.08);
|
|
padding: 1px 8px;
|
|
border-radius: 4px;
|
|
font-size: 10px;
|
|
color: rgba(255,255,255,0.6);
|
|
}
|
|
.knowledge-content {
|
|
font-size: 14px;
|
|
color: rgba(255,255,255,0.9);
|
|
line-height: 1.7;
|
|
text-shadow: 0 1px 4px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.divider {
|
|
height: 1px;
|
|
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
|
|
margin: 16px 0;
|
|
}
|
|
|
|
#author {
|
|
position: fixed;
|
|
bottom: 60px;
|
|
right: 30px;
|
|
font-size: 16px;
|
|
color: rgba(255,255,255,0.5);
|
|
letter-spacing: 1px;
|
|
z-index: 10;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.weather-forecast::-webkit-scrollbar,
|
|
.daily-forecast::-webkit-scrollbar { display: none; }
|
|
|
|
/* ===== SINGLE 布局(现有) ===== */
|
|
body.layout-single #layout-single { display: block; }
|
|
body.layout-single #layout-multi { display: none; }
|
|
|
|
body.layout-single #info {
|
|
position: fixed;
|
|
top: 40px;
|
|
right: 40px;
|
|
text-align: left;
|
|
width: calc(50vw - 60px);
|
|
z-index: 10;
|
|
}
|
|
body.layout-single #info .date {
|
|
text-align: left;
|
|
}
|
|
|
|
/* ===== MULTI 布局(独立卡片) ===== */
|
|
body.layout-multi #layout-single { display: none; }
|
|
body.layout-multi #layout-multi { display: block; }
|
|
|
|
body.layout-multi #card-time {
|
|
position: fixed;
|
|
top: 40px;
|
|
right: 40px;
|
|
text-align: left;
|
|
min-width: 280px;
|
|
z-index: 10;
|
|
}
|
|
body.layout-multi #card-bottom {
|
|
position: fixed;
|
|
bottom: 80px;
|
|
right: 40px;
|
|
width: calc(50vw - 60px);
|
|
display: flex;
|
|
gap: 16px;
|
|
align-items: flex-end;
|
|
z-index: 10;
|
|
}
|
|
body.layout-multi #card-right-col {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
body.layout-multi #card-right-col #card-knowledge {
|
|
text-align: left;
|
|
}
|
|
body.layout-multi #card-right-col #card-ainews {
|
|
text-align: left;
|
|
}
|
|
body.layout-multi #card-bottom #card-weather {
|
|
text-align: right;
|
|
}
|
|
body.layout-multi #card-ainews {
|
|
position: fixed;
|
|
bottom: 80px;
|
|
left: 40px;
|
|
width: calc(50vw - 80px);
|
|
z-index: 10;
|
|
}
|
|
body.layout-multi #card-zodiac {
|
|
position: fixed;
|
|
top: 200px;
|
|
right: 40px;
|
|
width: 280px;
|
|
z-index: 10;
|
|
}
|
|
|
|
/* ===== 卡片隐藏 ===== */
|
|
body.hide-time #card-time,
|
|
body.hide-time #info .time,
|
|
body.hide-time #info .date { display: none !important; }
|
|
body.hide-weather #card-weather,
|
|
body.hide-weather #info .weather-section,
|
|
body.hide-weather #info .current-weather,
|
|
body.hide-weather #info .forecast-title,
|
|
body.hide-weather #info .weather-forecast,
|
|
body.hide-weather #info .daily-forecast { display: none !important; }
|
|
body.hide-zodiac #card-zodiac,
|
|
body.hide-zodiac #info .zodiac-text { display: none !important; }
|
|
body.hide-ainews #card-ainews,
|
|
body.hide-ainews #info .ainews-section { display: none !important; }
|
|
body.hide-knowledge #card-knowledge,
|
|
body.hide-knowledge #info .knowledge-section { display: none !important; }
|
|
</style>
|
|
</head>
|
|
<body class="layout-{{LAYOUT}}">
|
|
{{BACKGROUND}}
|
|
|
|
<!-- ===== SINGLE 布局 ===== -->
|
|
<div id="layout-single">
|
|
<div id="info" class="card">
|
|
<div class="date" id="date">1月1日 周一</div>
|
|
<div class="time" id="time">00:00</div>
|
|
<div class="divider"></div>
|
|
<div class="ainews-section">
|
|
<div class="ainews-header">🤖 AI 资讯</div>
|
|
<div id="ainews">加载中...</div>
|
|
</div>
|
|
<div class="divider"></div>
|
|
<div class="knowledge-section">
|
|
<div class="knowledge-header">💡 知识卡片 <span class="knowledge-keyword-tag" id="knowledgeTag"></span></div>
|
|
<div class="knowledge-content" id="knowledge">请设置知识关键字</div>
|
|
</div>
|
|
<div class="divider"></div>
|
|
<div>
|
|
<div class="current-weather" id="currentWeather">加载中...</div>
|
|
<div class="forecast-title">24小时预报</div>
|
|
<div class="weather-forecast" id="hourlyForecast"></div>
|
|
<div class="forecast-title" style="margin-top:12px">7日预报</div>
|
|
<div class="daily-forecast" id="dailyForecast"></div>
|
|
</div>
|
|
<div class="divider"></div>
|
|
<div class="zodiac-text" id="zodiac">加载中...</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ===== MULTI 布局 ===== -->
|
|
<div id="layout-multi">
|
|
<div id="card-time" class="card">
|
|
<div class="date" id="date2">1月1日 周一</div>
|
|
<div class="time" id="time2">00:00</div>
|
|
</div>
|
|
<div id="card-zodiac" class="card">
|
|
<div class="zodiac-text" id="zodiac2">加载中...</div>
|
|
</div>
|
|
<div id="card-ainews" class="card">
|
|
<div class="ainews-header">🤖 AI 资讯</div>
|
|
<div id="ainews2">加载中...</div>
|
|
</div>
|
|
<div id="card-bottom">
|
|
<div id="card-right-col">
|
|
<div id="card-knowledge" class="card">
|
|
<div class="knowledge-header">💡 知识卡片 <span class="knowledge-keyword-tag" id="knowledgeTag2"></span></div>
|
|
<div class="knowledge-content" id="knowledge2">请设置知识关键字</div>
|
|
</div>
|
|
<div id="card-weather" class="card">
|
|
<div class="current-weather" id="currentWeather2">加载中...</div>
|
|
<div class="forecast-title">24小时预报</div>
|
|
<div class="weather-forecast" id="hourlyForecast2"></div>
|
|
<div class="forecast-title" style="margin-top:12px">7日预报</div>
|
|
<div class="daily-forecast" id="dailyForecast2"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="author">绝尘</div>
|
|
|
|
<script>
|
|
var lastTimeStr='', lastDateStr='', lastZodiac='';
|
|
var horoscopeInfo=null;
|
|
|
|
var zodiacData = {
|
|
'白羊座':{icon:'♈',date:'3.21-4.19'},
|
|
'金牛座':{icon:'♉',date:'4.20-5.20'},
|
|
'双子座':{icon:'♊',date:'5.21-6.21'},
|
|
'巨蟹座':{icon:'♋',date:'6.22-7.22'},
|
|
'狮子座':{icon:'♌',date:'7.23-8.22'},
|
|
'处女座':{icon:'♍',date:'8.23-9.22'},
|
|
'天秤座':{icon:'♎',date:'9.23-10.23'},
|
|
'天蝎座':{icon:'♏',date:'10.24-11.22'},
|
|
'射手座':{icon:'♐',date:'11.23-12.21'},
|
|
'摩羯座':{icon:'♑',date:'12.22-1.19'},
|
|
'水瓶座':{icon:'♒',date:'1.20-2.18'},
|
|
'双鱼座':{icon:'♓',date:'2.19-3.20'}
|
|
};
|
|
|
|
var barColors={all:'#e0e0e0',love:'#ff6b9d',work:'#4fc3f7',money:'#ffd54f',health:'#81c784'};
|
|
|
|
function getUserZodiac(){ return window.userZodiac||'射手座'; }
|
|
|
|
function setEl(id,html){
|
|
var e=document.getElementById(id);
|
|
if(e) e.innerHTML=html;
|
|
}
|
|
function setText(id,txt){
|
|
var e=document.getElementById(id);
|
|
if(e) e.textContent=txt;
|
|
}
|
|
|
|
function buildBar(label,val,color){
|
|
var v=parseInt(val)||0;
|
|
return '<div class="zodiac-bar">'+
|
|
'<span class="zodiac-bar-label">'+label+'</span>'+
|
|
'<div class="zodiac-bar-track"><div class="zodiac-bar-fill" style="width:'+v+'%;background:'+color+'"></div></div>'+
|
|
'<span class="zodiac-bar-val">'+val+'%</span></div>';
|
|
}
|
|
|
|
function buildZodiacHTML(name){
|
|
var z=zodiacData[name]||{icon:'✨',date:''};
|
|
var html='<div class="zodiac-title">'+z.icon+' '+name+'运势</div>';
|
|
html+='<div class="zodiac-date">'+z.date+'</div>';
|
|
if(horoscopeInfo&&horoscopeInfo.zodiac===name){
|
|
html+=buildBar('综合',horoscopeInfo.all,barColors.all);
|
|
html+=buildBar('爱情',horoscopeInfo.love,barColors.love);
|
|
html+=buildBar('工作',horoscopeInfo.work,barColors.work);
|
|
html+=buildBar('财运',horoscopeInfo.money,barColors.money);
|
|
html+=buildBar('健康',horoscopeInfo.health,barColors.health);
|
|
html+='<div class="zodiac-tags">';
|
|
if(horoscopeInfo.luckyColor) html+='<span class="zodiac-tag">🎨 '+horoscopeInfo.luckyColor+'</span>';
|
|
if(horoscopeInfo.luckyNum) html+='<span class="zodiac-tag">🔢 '+horoscopeInfo.luckyNum+'</span>';
|
|
if(horoscopeInfo.noble) html+='<span class="zodiac-tag">⭐ '+horoscopeInfo.noble+'</span>';
|
|
html+='</div>';
|
|
if(horoscopeInfo.summary) html+='<div class="zodiac-summary">'+horoscopeInfo.summary+'</div>';
|
|
} else {
|
|
html+='<div style="opacity:0.4;font-size:12px;margin-top:8px">运势加载中...</div>';
|
|
}
|
|
return html;
|
|
}
|
|
|
|
function syncZodiacHeight(){
|
|
var zw=document.getElementById('card-zodiac');
|
|
var ww=document.getElementById('card-weather');
|
|
if(!zw||!ww||!document.body.classList.contains('layout-multi')) return;
|
|
var wh=ww.getBoundingClientRect().height;
|
|
zw.style.minHeight=wh+'px';
|
|
}
|
|
|
|
function updateZodiacDisplay(){
|
|
var name=getUserZodiac();
|
|
if(name===lastZodiac) return;
|
|
lastZodiac=name;
|
|
var html=buildZodiacHTML(name);
|
|
setEl('zodiac',html);
|
|
setEl('zodiac2',html);
|
|
syncZodiacHeight();
|
|
}
|
|
|
|
var holidays=[
|
|
{m:1,d:1,name:'元旦'},
|
|
{m:2,d:14,name:'情人节'},
|
|
{m:3,d:8,name:'妇女节'},
|
|
{m:4,d:5,name:'清明节'},
|
|
{m:5,d:1,name:'劳动节'},
|
|
{m:5,d:4,name:'青年节'},
|
|
{m:6,d:1,name:'儿童节'},
|
|
{m:7,d:1,name:'建党节'},
|
|
{m:8,d:1,name:'建军节'},
|
|
{m:9,d:10,name:'教师节'},
|
|
{m:10,d:1,name:'国庆节'},
|
|
{m:10,d:31,name:'万圣节'},
|
|
{m:12,d:25,name:'圣诞节'}
|
|
];
|
|
|
|
function getNextHoliday(now){
|
|
var y=now.getFullYear(), results=[];
|
|
for(var i=0;i<holidays.length;i++){
|
|
var h=holidays[i];
|
|
var target=new Date(y,h.m-1,h.d);
|
|
var diff=Math.ceil((target-now)/(1000*60*60*24));
|
|
if(diff>0&&diff<=60) results.push({diff:diff,name:h.name});
|
|
if(diff<0){
|
|
target=new Date(y+1,h.m-1,h.d);
|
|
diff=Math.ceil((target-now)/(1000*60*60*24));
|
|
if(diff>0&&diff<=60) results.push({diff:diff,name:h.name});
|
|
}
|
|
}
|
|
results.sort(function(a,b){return a.diff-b.diff;});
|
|
return results.length>0?'距'+results[0].name+'还有'+results[0].diff+'天':'';
|
|
}
|
|
|
|
window.setCardVisible=function(card,visible){
|
|
if(visible){document.body.classList.remove('hide-'+card);}
|
|
else{document.body.classList.add('hide-'+card);}
|
|
};
|
|
|
|
window.setWallpaperVisible=function(visible){
|
|
var bg=document.getElementById('bg-layer');
|
|
if(bg){bg.style.display=visible?'':'none';}
|
|
};
|
|
|
|
window._showSeconds={{SHOW_SECONDS}};
|
|
window.setShowSeconds=function(v){window._showSeconds=v; updateTime();};
|
|
|
|
function updateTime(){
|
|
var now=new Date();
|
|
var hh=String(now.getHours()).padStart(2,'0');
|
|
var mm=String(now.getMinutes()).padStart(2,'0');
|
|
var ss=String(now.getSeconds()).padStart(2,'0');
|
|
var month=now.getMonth()+1;
|
|
var day=now.getDate();
|
|
var week=['周日','周一','周二','周三','周四','周五','周六'][now.getDay()];
|
|
var timeStr=window._showSeconds?(hh+':'+mm+':'+ss):(hh+':'+mm);
|
|
var dateStr=month+'月'+day+'日 '+week;
|
|
if(timeStr!==lastTimeStr){
|
|
setText('time',timeStr); setText('time2',timeStr); lastTimeStr=timeStr;
|
|
if(mm==='00'&&ss==='00'){
|
|
['time','time2'].forEach(function(id){
|
|
var el=document.getElementById(id);
|
|
if(el){
|
|
el.classList.remove('hourly-glow');
|
|
void el.offsetWidth;
|
|
el.classList.add('hourly-glow');
|
|
el.addEventListener('animationend',function(){ el.classList.remove('hourly-glow'); },{once:true});
|
|
}
|
|
});
|
|
}
|
|
}
|
|
if(dateStr!==lastDateStr){
|
|
var holiday=getNextHoliday(now);
|
|
var displayStr=holiday?dateStr+' <span style="opacity:0.5;font-size:12px">「'+holiday+'」</span>':dateStr;
|
|
setEl('date',displayStr); setEl('date2',displayStr); lastDateStr=dateStr;
|
|
}
|
|
updateZodiacDisplay();
|
|
}
|
|
|
|
window.updateHoroscopeFromGo=function(data){
|
|
console.log('[horoscope] received:', typeof data, JSON.stringify(data).substring(0,100));
|
|
if(typeof data==='string') data=JSON.parse(data);
|
|
horoscopeInfo=data;
|
|
lastZodiac='';
|
|
window.userZodiac=data.zodiac;
|
|
updateZodiacDisplay();
|
|
syncZodiacHeight();
|
|
};
|
|
|
|
window.updateAINewsFromGo=function(items){
|
|
if(typeof items==='string') items=JSON.parse(items);
|
|
if(!items||!items.length) return;
|
|
var html='';
|
|
var count=Math.min(items.length,5);
|
|
for(var i=0;i<count;i++){
|
|
var n=items[i];
|
|
var time=n.ctime||'';
|
|
if(time.length>10) time=time.substring(5,10);
|
|
html+='<div class="ainews-item">';
|
|
if(n.picUrl){
|
|
html+='<img class="ainews-img" src="'+n.picUrl+'" loading="lazy" onerror="this.style.display=\'none\'">';
|
|
}
|
|
html+='<div class="ainews-body">';
|
|
html+='<div class="ainews-title-row"><span class="ainews-title">'+n.title+'</span><span class="ainews-source">'+n.source+' · '+time+'</span></div>';
|
|
if(n.description) html+='<div class="ainews-desc">'+n.description+'</div>';
|
|
html+='</div></div>';
|
|
}
|
|
setEl('ainews',html);
|
|
setEl('ainews2',html);
|
|
};
|
|
|
|
window.updateKnowledgeFromGo=function(data){
|
|
if(typeof data==='string') data=JSON.parse(data);
|
|
var ids=['knowledge','knowledge2'];
|
|
var tagIds=['knowledgeTag','knowledgeTag2'];
|
|
ids.forEach(function(id,i){
|
|
var el=document.getElementById(id);
|
|
if(el) el.textContent=data.content||'';
|
|
var tag=document.getElementById(tagIds[i]);
|
|
if(tag) tag.textContent=data.keyword?'#'+data.keyword:'';
|
|
});
|
|
};
|
|
|
|
window.updateWeatherFromGo=function(data){
|
|
if(typeof data==='string') data=JSON.parse(data);
|
|
|
|
function renderWeather(curId,hourlyId,dailyId){
|
|
if(data.current) setText(curId,data.current);
|
|
var fel=document.getElementById(hourlyId);
|
|
if(fel){
|
|
if(data.hourly&&data.hourly.length>0){
|
|
fel.innerHTML=data.hourly.map(function(item){
|
|
return '<div class="forecast-item"><div class="forecast-time">'+item.time+'</div><div class="forecast-icon">'+item.icon+'</div><div class="forecast-temp">'+item.temp+'</div></div>';
|
|
}).join('');
|
|
} else { fel.innerHTML='<div style="font-size:11px;opacity:0.4">暂无数据</div>'; }
|
|
}
|
|
var del=document.getElementById(dailyId);
|
|
if(del){
|
|
if(data.daily&&data.daily.length>0){
|
|
del.innerHTML=data.daily.map(function(item){
|
|
return '<div class="daily-item"><div style="opacity:0.6;font-size:10px">'+item.date+'</div><div class="daily-icon">'+item.icon+'</div><div class="forecast-temp">'+item.tempMin+'°~'+item.tempMax+'°</div></div>';
|
|
}).join('');
|
|
} else { del.innerHTML='<div style="font-size:11px;opacity:0.4">暂无数据</div>'; }
|
|
}
|
|
}
|
|
|
|
renderWeather('currentWeather','hourlyForecast','dailyForecast');
|
|
renderWeather('currentWeather2','hourlyForecast2','dailyForecast2');
|
|
syncZodiacHeight();
|
|
};
|
|
|
|
updateTime();
|
|
setInterval(updateTime,1000);
|
|
</script>
|
|
</body>
|
|
</html>
|