- 星座运势: 天聚数行API集成,5维进度条+幸运标签+今日概述 - AI资讯: 天聚数行API,图文布局5条展示,文件缓存2小时刷新 - 知识卡片: AI生成,关键字+提示词配置,30分钟刷新 - 桌面设置: 独立WebView2窗口,760x1350,含壁纸/布局/城市/颜色等配置 - 显示控制: 壁纸/时间/天气/星座/知识/AI资讯独立开关,秒显示开关 - 文件缓存: 星座运势+AI资讯缓存到本地,启动即显示上次数据 - initDone防抖: 防止设置窗口初始化触发卡片重载
178 lines
4.0 KiB
Go
178 lines
4.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
const tianapiKey = "da21ff665b09cbdcc29952a105aad97b"
|
|
const tianapiStarURL = "https://apis.tianapi.com/star/index"
|
|
|
|
var zodiacToSign = map[string]string{
|
|
"白羊座": "aries", "金牛座": "taurus", "双子座": "gemini", "巨蟹座": "cancer",
|
|
"狮子座": "leo", "处女座": "virgo", "天秤座": "libra", "天蝎座": "scorpio",
|
|
"射手座": "sagittarius", "摩羯座": "capricorn", "水瓶座": "aquarius", "双鱼座": "pisces",
|
|
}
|
|
|
|
var horoscopeMu sync.Mutex
|
|
|
|
type tianapiStarResp struct {
|
|
Code int `json:"code"`
|
|
Result struct {
|
|
List []struct {
|
|
Type string `json:"type"`
|
|
Content string `json:"content"`
|
|
} `json:"list"`
|
|
} `json:"result"`
|
|
}
|
|
|
|
type horoscopeInfo struct {
|
|
Zodiac string `json:"zodiac"`
|
|
Date string `json:"date"`
|
|
All string `json:"all"`
|
|
Love string `json:"love"`
|
|
Work string `json:"work"`
|
|
Money string `json:"money"`
|
|
Health string `json:"health"`
|
|
LuckyColor string `json:"luckyColor"`
|
|
LuckyNum string `json:"luckyNum"`
|
|
Noble string `json:"noble"`
|
|
Summary string `json:"summary"`
|
|
}
|
|
|
|
func horoscopeCachePath() string {
|
|
return filepath.Join(configDir(), "horoscope_cache.json")
|
|
}
|
|
|
|
func saveHoroscopeCache(info *horoscopeInfo) {
|
|
info.Date = time.Now().Format("2006-01-02")
|
|
data, _ := json.Marshal(info)
|
|
os.WriteFile(horoscopeCachePath(), data, 0644)
|
|
}
|
|
|
|
func loadHoroscopeCache() *horoscopeInfo {
|
|
data, err := os.ReadFile(horoscopeCachePath())
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
var info horoscopeInfo
|
|
if json.Unmarshal(data, &info) != nil {
|
|
return nil
|
|
}
|
|
return &info
|
|
}
|
|
|
|
func isCacheToday(info *horoscopeInfo) bool {
|
|
return info != nil
|
|
}
|
|
|
|
func fetchHoroscope(zodiac string) *horoscopeInfo {
|
|
sign := zodiacToSign[zodiac]
|
|
if sign == "" {
|
|
sign = "sagittarius"
|
|
}
|
|
|
|
url := fmt.Sprintf("%s?key=%s&astro=%s", tianapiStarURL, tianapiKey, sign)
|
|
data, err := httpGet(url)
|
|
if err != nil {
|
|
log.Println("星座运势请求失败:", err)
|
|
return nil
|
|
}
|
|
|
|
var resp tianapiStarResp
|
|
if json.Unmarshal(data, &resp) != nil || resp.Code != 200 {
|
|
log.Println("星座运势解析失败:", string(data))
|
|
return nil
|
|
}
|
|
|
|
info := &horoscopeInfo{Zodiac: zodiac}
|
|
for _, item := range resp.Result.List {
|
|
switch item.Type {
|
|
case "综合指数":
|
|
info.All = strings.TrimSuffix(item.Content, "%")
|
|
case "爱情指数":
|
|
info.Love = strings.TrimSuffix(item.Content, "%")
|
|
case "工作指数":
|
|
info.Work = strings.TrimSuffix(item.Content, "%")
|
|
case "财运指数":
|
|
info.Money = strings.TrimSuffix(item.Content, "%")
|
|
case "健康指数":
|
|
info.Health = strings.TrimSuffix(item.Content, "%")
|
|
case "幸运颜色":
|
|
info.LuckyColor = item.Content
|
|
case "幸运数字":
|
|
info.LuckyNum = item.Content
|
|
case "贵人星座":
|
|
info.Noble = item.Content
|
|
case "今日概述":
|
|
info.Summary = strings.TrimSpace(item.Content)
|
|
}
|
|
}
|
|
|
|
log.Printf("星座运势已获取: %s", zodiac)
|
|
return info
|
|
}
|
|
|
|
func pushHoroscopeInfo(info *horoscopeInfo) {
|
|
jsonData, _ := json.Marshal(info)
|
|
log.Printf("星座运势JS: %s", string(jsonData[:min(len(jsonData), 120)]))
|
|
js := fmt.Sprintf(`if(window.updateHoroscopeFromGo) window.updateHoroscopeFromGo(%s)`, string(jsonData))
|
|
evalJS(js)
|
|
}
|
|
|
|
func pushHoroscope(zodiac string) {
|
|
info := fetchHoroscope(zodiac)
|
|
if info == nil {
|
|
log.Println("星座运势: fetchHoroscope返回nil")
|
|
return
|
|
}
|
|
saveHoroscopeCache(info)
|
|
pushHoroscopeInfo(info)
|
|
}
|
|
|
|
func horoscopeLoop() {
|
|
cfg := loadConfig()
|
|
if cfg.HideZodiac {
|
|
return
|
|
}
|
|
|
|
cached := loadHoroscopeCache()
|
|
if cached != nil {
|
|
pushHoroscopeInfo(cached)
|
|
}
|
|
|
|
time.Sleep(5 * time.Second)
|
|
|
|
cfg = loadConfig()
|
|
if cfg.HideZodiac {
|
|
return
|
|
}
|
|
|
|
today := time.Now().Format("2006-01-02")
|
|
if cached != nil && cached.Date == today && cached.Zodiac == cfg.Zodiac {
|
|
return
|
|
}
|
|
|
|
pushHoroscope(cfg.Zodiac)
|
|
|
|
ticker := time.NewTicker(24 * time.Hour)
|
|
for range ticker.C {
|
|
cfg := loadConfig()
|
|
if !cfg.HideZodiac {
|
|
pushHoroscope(cfg.Zodiac)
|
|
}
|
|
}
|
|
}
|
|
|
|
func triggerHoroscopeRefresh(zodiac string) {
|
|
go func() {
|
|
pushHoroscope(zodiac)
|
|
}()
|
|
}
|