1+ # -*- coding: utf-8 -*-
2+ """
3+ 电费剩余金额桌面小组件
4+ 使用方法:运行脚本生成小组件配置
5+ """
6+
7+ from widget import Widget , family ,SMALL , MEDIUM , LARGE
8+ import datetime
9+ import requests
10+
11+ # ═══════════════════════════════════════════════════════════
12+ # 可修改的配置变量
13+
14+ YHDABH = "自行填入" #抓包修改这里,yhdabh=2MqPtcetcUPDScD==类似这样的
15+ # ═══════════════════════════════════════════════════════════
16+ API_URL = "https://mdej.impc.com.cn/hlwyy/business-jffw/znjf/queryDfInfoNew_new"
17+
18+ PARAMS = {
19+ "get" : "" ,
20+ "yhdabh" : YHDABH
21+ }
22+ REQUEST_TIMEOUT = 10 # 请求超时时间(秒)
23+
24+ # ═══════════════════════════════════════════════════════════
25+ # 网络请求获取数据
26+ # ═══════════════════════════════════════════════════════════
27+ def fetch_electricity_data ():
28+ """
29+ 从网络获取电费数据
30+ 返回: dict 或 None(请求失败时返回None)
31+ """
32+ try :
33+ response = requests .get (
34+ API_URL ,
35+ params = PARAMS ,
36+ timeout = REQUEST_TIMEOUT ,
37+ headers = {
38+ "User-Agent" : "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15" ,
39+ "Accept" : "application/json"
40+ }
41+ )
42+ response .raise_for_status ()
43+ json_data = response .json ()
44+
45+ if json_data .get ("code" ) == 0 and json_data .get ("data" ):
46+ return json_data ["data" ]
47+ else :
48+ print (f"API返回异常: code={ json_data .get ('code' )} , msg={ json_data .get ('msg' , '无' )} " )
49+ return None
50+
51+ except requests .exceptions .Timeout :
52+ print ("请求超时,请检查网络连接" )
53+ return None
54+ except requests .exceptions .ConnectionError :
55+ print ("网络连接失败,请检查网络" )
56+ return None
57+ except requests .exceptions .HTTPError as e :
58+ print (f"HTTP错误: { e } " )
59+ return None
60+ except ValueError :
61+ print ("JSON解析失败" )
62+ return None
63+ except Exception as e :
64+ print (f"未知错误: { e } " )
65+ return None
66+
67+ # 获取数据
68+ api_data = fetch_electricity_data ()
69+
70+ # 如果网络请求失败,使用默认数据
71+ if api_data is None :
72+ api_data = {
73+ "gsbh" : "--" ,
74+ "limitFlag" : "--" ,
75+ "qjwyj" : "0.0" ,
76+ "syje" : "0.0" ,
77+ "name" : "网络异常" ,
78+ "addr" : "--" ,
79+ "khxzmc" : "--" ,
80+ "sfyxjf" : "--"
81+ }
82+
83+ # 提取数据
84+ syje = float (api_data .get ("syje" , "0" ))
85+ name = api_data .get ("name" , "--" )
86+ khxzmc = api_data .get ("khxzmc" , "--" )
87+ now = datetime .datetime .now ()
88+
89+ # 判断余额状态
90+ if syje < 10 :
91+ status_color = ("#EF4444" , "#F87171" ) # 红色 - 余额不足
92+ status_text = "余额不足"
93+ status_icon = "exclamationmark.triangle.fill"
94+ elif syje < 50 :
95+ status_color = ("#F59E0B" , "#FBBF24" ) # 橙色 - 偏低
96+ status_text = "余额偏低"
97+ status_icon = "exclamationmark.circle.fill"
98+ else :
99+ status_color = ("#10B981" , "#34D399" ) # 绿色 - 正常
100+ status_text = "余额充足"
101+ status_icon = "checkmark.circle.fill"
102+
103+ # 创建小组件
104+ w = Widget (background = ("#F8FAFC" , "#0F172A" ), padding = 14 )
105+
106+ if family == SMALL :
107+ # 小尺寸:居中显示核心金额
108+ with w .vstack (spacing = 0 , align = "center" ):
109+ w .spacer ()
110+ w .icon (status_icon , size = 16 , color = status_color )
111+ w .spacer (4 )
112+ w .text (f"¥{ syje :.1f} " , size = 26 , weight = "bold" , design = "rounded" ,
113+ color = ("#0F172A" , "#F8FAFC" ))
114+ w .spacer (2 )
115+ w .text ("电费余额" , size = 11 , color = ("#94A3B8" , "#64748B" ))
116+ w .spacer ()
117+
118+ elif family == MEDIUM :
119+ # 中尺寸:左侧金额 + 右侧状态信息
120+ with w .hstack (spacing = 0 ):
121+ # 左侧:金额显示
122+ with w .vstack (spacing = 4 , align = "leading" ):
123+ w .icon ("bolt.fill" , size = 14 , color = "#3B82F6" )
124+ w .text ("电费余额" , size = 12 , color = ("#94A3B8" , "#64748B" ))
125+ w .text (f"¥{ syje :.1f} " , size = 28 , weight = "bold" , design = "rounded" ,
126+ color = ("#0F172A" , "#F8FAFC" ))
127+ w .spacer ()
128+ # 右侧:状态卡片
129+ with w .card (background = ("#F1F5F9" , "#1E293B" ),
130+ corner_radius = 10 , padding = 10 , spacing = 4 ):
131+ w .icon (status_icon , size = 16 , color = status_color )
132+ w .text (status_text , size = 12 , weight = "medium" ,
133+ color = ("#334155" , "#E2E8F0" ))
134+ w .text (f"更新 { now .strftime ('%H:%M' )} " , size = 10 ,
135+ color = ("#94A3B8" , "#64748B" ))
136+
137+ else :
138+ # 大尺寸:完整信息展示
139+ # 头部
140+ with w .hstack (spacing = 6 ):
141+ w .icon ("bolt.fill" , size = 16 , color = "#3B82F6" )
142+ w .text ("电费余额查询" , size = 16 , weight = "semibold" ,
143+ color = ("#334155" , "#E2E8F0" ))
144+ w .spacer ()
145+ w .text (f"{ now .month } 月{ now .day } 日 { now .strftime ('%H:%M' )} " , size = 11 ,
146+ color = ("#94A3B8" , "#64748B" ))
147+
148+ w .spacer (10 )
149+
150+ # 核心金额卡片
151+ with w .card (background = {"gradient" : ["#3B82F6" , "#8B5CF6" ], "direction" : "diagonal" },
152+ corner_radius = 14 , padding = 16 , spacing = 4 ):
153+ with w .vstack (spacing = 4 , align = "center" ):
154+ w .text ("账户余额" , size = 13 , color = ("#FFFFFF" , "#E0E7FF" ), opacity = 0.9 )
155+ w .text (f"¥{ syje :.1f} " , size = 36 , weight = "bold" , design = "rounded" ,
156+ color = ("#FFFFFF" , "#FFFFFF" ))
157+ with w .hstack (spacing = 4 ):
158+ w .icon (status_icon , size = 12 , color = ("#FFFFFF" , "#E0E7FF" ))
159+ w .text (status_text , size = 12 , weight = "medium" ,
160+ color = ("#FFFFFF" , "#E0E7FF" ))
161+
162+ w .spacer (10 )
163+
164+ # 底部信息卡片
165+ with w .card (background = ("#F1F5F9" , "#1E293B" ),
166+ corner_radius = 10 , padding = 12 , spacing = 0 ):
167+ with w .hstack (spacing = 0 ):
168+ with w .vstack (spacing = 2 , align = "leading" ):
169+ w .text ("户主" , size = 11 , color = ("#94A3B8" , "#64748B" ))
170+ w .text (name , size = 13 , weight = "medium" ,
171+ color = ("#334155" , "#E2E8F0" ))
172+ w .spacer ()
173+ with w .vstack (spacing = 2 , align = "leading" ):
174+ w .text ("用电类型" , size = 11 , color = ("#94A3B8" , "#64748B" ))
175+ w .text (khxzmc , size = 13 , weight = "medium" ,
176+ color = ("#334155" , "#E2E8F0" ))
177+
178+ w .render ()
0 commit comments