Skip to content

Commit 124d122

Browse files
committed
完成编写联通流量话费小部件
1 parent 2762cad commit 124d122

File tree

4 files changed

+1286
-87
lines changed

4 files changed

+1286
-87
lines changed

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
import './scripts/china10010.tsx'
1+
import './scripts/helloWorld.tsx'

src/scripts/china10010.tsx

Lines changed: 130 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* 今日热榜小部件
2+
* 联通话费流量查询小部件
33
*/
44

55
import {
@@ -14,6 +14,7 @@ import {
1414
sleep,
1515
} from '@app/lib/help'
1616
import {FC} from 'react'
17+
import {WtextProps, WstackProps} from '@app/types/widget'
1718

1819
/**手机卡数据列表*/
1920
interface PhoneDatas {
@@ -27,7 +28,7 @@ interface PhoneData {
2728
pointUpdateTimeStamp: string
2829
paperwork4: string
2930
buttonBacImageUrlBig: string
30-
type: string
31+
type: PhoneDataType
3132
remainTitle: string
3233
buttonText7: string
3334
buttonLinkMode: string
@@ -57,25 +58,13 @@ interface PhoneData {
5758
warningPointColor?: string
5859
}
5960

60-
/**页面信息*/
61-
interface PageInfo {
62-
/**页面数据*/
63-
phoneDatas: PhoneDatas
64-
65-
/**cookie*/
66-
cookie: string | null
67-
68-
/**js执行的错误信息*/
69-
err: string
70-
}
71-
7261
/**有用的手机卡数据*/
7362
interface UsefulPhoneData {
7463
/**类型*/
75-
type: string
64+
type: PhoneDataType
7665

7766
/**剩余百分比数字*/
78-
present: number
67+
percent: number
7968

8069
/**单位*/
8170
unit: string
@@ -87,6 +76,39 @@ interface UsefulPhoneData {
8776
label: string
8877
}
8978

79+
/**手机卡数据类型*/
80+
enum PhoneDataType {
81+
/**流量*/
82+
FLOW = 'flow',
83+
84+
/**话费*/
85+
FEE = 'fee',
86+
87+
/**语音*/
88+
VOICE = 'voice',
89+
90+
/**积分*/
91+
POINT = 'point',
92+
93+
/**信用分*/
94+
CREDIT = 'credit',
95+
96+
/**电子券*/
97+
WOPAY = 'woPay',
98+
}
99+
100+
const typeDesc: Record<PhoneDataType, string> = {
101+
[PhoneDataType.FLOW]: '流量',
102+
[PhoneDataType.FEE]: '话费',
103+
[PhoneDataType.VOICE]: '语音',
104+
[PhoneDataType.POINT]: '积分',
105+
[PhoneDataType.CREDIT]: '信用分',
106+
[PhoneDataType.WOPAY]: '电子券',
107+
}
108+
109+
// 格式化数字
110+
const formatNum = (num: number) => parseFloat(Number(num).toFixed(1))
111+
90112
const {setStorage, getStorage} = useStorage('china10010-xiaoming')
91113

92114
/**默认背景颜色*/
@@ -117,7 +139,7 @@ class China10010 {
117139
await showNotification({title: '稍等片刻', body: '小部件渲染中...', sound: 'alert'})
118140
}
119141
// 多久(毫秒)更新一次小部件(默认3分钟)
120-
const updateInterval = 3 * 60 * 1000
142+
const updateInterval = 1 * 60 * 1000
121143

122144
// 渲染尺寸
123145
const size = config.widgetFamily
@@ -142,7 +164,6 @@ class China10010 {
142164
background={typeof boxBg === 'string' && boxBg.match('透明背景') ? transparentBg : boxBg}
143165
>
144166
<wstack flexDirection="column" padding={[0, 16, 0, 16]}>
145-
<wspacer></wspacer>
146167
<wspacer></wspacer>
147168
{/* 标题和logo */}
148169
<wstack verticalAlign="center">
@@ -153,12 +174,11 @@ class China10010 {
153174
borderRadius={4}
154175
></wimage>
155176
<wspacer length={8}></wspacer>
156-
<wtext opacity={0.7} font={Font.boldSystemFont(16)} textColor={textColor}>
177+
<wtext opacity={0.7} font={Font.boldSystemFont(14)} textColor={textColor}>
157178
中国联通
158179
</wtext>
159180
</wstack>
160181
<wspacer></wspacer>
161-
<wspacer></wspacer>
162182
{/* 内容 */}
163183
{size === 'small' && this.renderSmall(usefulPhoneDatas)}
164184
{size === 'medium' && this.renderMedium(usefulPhoneDatas)}
@@ -170,27 +190,103 @@ class China10010 {
170190

171191
// 渲染小尺寸
172192
renderSmall(usefulPhoneDatas: UsefulPhoneData[]) {
193+
// 流量
194+
const flow = usefulPhoneDatas.find(item => item.type === PhoneDataType.FLOW) as UsefulPhoneData
195+
// 话费
196+
const fee = usefulPhoneDatas.find(item => item.type === PhoneDataType.FEE) as UsefulPhoneData
173197
return (
174198
<>
175-
<wtext>hello</wtext>
199+
<wtext textColor={textColor} font={Font.lightSystemFont(14)}>
200+
剩余流量{formatNum(flow.count || 0) + flow.unit}
201+
</wtext>
202+
<wspacer></wspacer>
203+
<wtext textColor={textColor} font={Font.lightSystemFont(14)}>
204+
剩余话费{formatNum(fee.count || 0) + fee.unit}
205+
</wtext>
206+
<wspacer></wspacer>
176207
</>
177208
)
178209
}
179210

180211
// 渲染中尺寸
181212
renderMedium(usefulPhoneDatas: UsefulPhoneData[]) {
182-
return (
183-
<>
184-
<wtext>hello</wtext>
185-
</>
186-
)
213+
const showDataType: PhoneDataType[] = [PhoneDataType.FLOW, PhoneDataType.FEE, PhoneDataType.VOICE]
214+
return this.renderLarge(usefulPhoneDatas.filter(data => showDataType.indexOf(data.type) >= 0))
187215
}
188216

189217
// 渲染大尺寸
190218
renderLarge(usefulPhoneDatas: UsefulPhoneData[]) {
219+
/**进度条*/
220+
const Progress: FC<{
221+
color: WstackProps['background']
222+
bgcolor: WstackProps['background']
223+
progress: number
224+
width: number
225+
height: number
226+
borderRadius?: number
227+
}> = ({...props}) => {
228+
const {color, bgcolor, progress, width, height, borderRadius = 0} = props
229+
return (
230+
<wstack background={bgcolor} width={width} height={height} borderRadius={borderRadius}>
231+
<wstack background={color} height={height} width={width * progress}>
232+
<wtext></wtext>
233+
</wstack>
234+
{progress < 1 && <wspacer></wspacer>}
235+
</wstack>
236+
)
237+
}
238+
239+
/**表格格子*/
240+
const TableGrid: FC<
241+
WtextProps & {text: string | React.ReactNode; width: number; align: 'left' | 'center' | 'right'}
242+
> = ({text, width, align, ...props}) => (
243+
<wstack width={width}>
244+
{(align === 'center' || align === 'right') && <wspacer></wspacer>}
245+
{typeof text === 'string' ? (
246+
<wtext font={14} textColor={textColor} {...props}>
247+
{text}
248+
</wtext>
249+
) : (
250+
text
251+
)}
252+
{(align === 'center' || align === 'left') && <wspacer></wspacer>}
253+
</wstack>
254+
)
255+
256+
/**表格行*/
257+
const TableRow: FC<WtextProps & {texts: (string | React.ReactNode)[]}> = ({texts, ...props}) => (
258+
<wstack verticalAlign="center">
259+
<TableGrid text={texts[0]} {...props} width={60} align="left"></TableGrid>
260+
<wspacer></wspacer>
261+
<TableGrid text={texts[1]} {...props} width={90} align="center"></TableGrid>
262+
<wspacer></wspacer>
263+
<TableGrid text={texts[2]} {...props} width={70} align="right"></TableGrid>
264+
</wstack>
265+
)
191266
return (
192267
<>
193-
<wtext>hello</wtext>
268+
<TableRow texts={['类型', '剩余百分比', '剩余量']}></TableRow>
269+
{usefulPhoneDatas.map(item => (
270+
<>
271+
<wspacer></wspacer>
272+
<TableRow
273+
font={Font.lightSystemFont(14)}
274+
texts={[
275+
typeDesc[item.type],
276+
Progress({
277+
color: '#39b54a',
278+
bgcolor: '#dddddd',
279+
width: 80,
280+
height: 10,
281+
borderRadius: 5,
282+
progress: formatNum(item.percent) / 100,
283+
}),
284+
formatNum(item.count) + item.unit,
285+
]}
286+
></TableRow>
287+
</>
288+
))}
289+
<wspacer></wspacer>
194290
</>
195291
)
196292
}
@@ -199,14 +295,14 @@ class China10010 {
199295
async showMenu() {
200296
const selectIndex = await showActionSheet({
201297
title: '菜单',
202-
itemList: ['登录', '设置手机号和cookie', '设置颜色', '设置透明背景', '预览组件'],
298+
itemList: ['登录获取cookie', '设置手机号和cookie', '设置颜色', '设置透明背景', '预览组件'],
203299
})
204300
switch (selectIndex) {
205301
case 0:
206302
const {cancel: cancelLogin} = await showModal({
207303
title: '为什么要登录',
208304
content:
209-
'获取手机号码信息需要 cookie,而 cookie 不登录获取不到\n\n若 cookie 失效,再次登录即可\n\n登录完成后,关闭网页,网页会再自动打开\n\n此时点击底部按钮复制 cookie ,然后关网页去设置cookie',
305+
'获取手机号码信息需要 cookie,而 cookie 不登录获取不到\n\n登录完成后,关闭网页,网页会再自动打开\n\n此时点击底部按钮复制 cookie ,然后关网页去设置cookie\n\n若 cookie 失效,再次登录复制即可',
210306
confirmText: '去登录',
211307
})
212308
if (cancelLogin) return
@@ -319,9 +415,9 @@ class China10010 {
319415
if (!isLaunchInsideApp() && !getStorage('cookie')) return 'cookie 不存在,请先登录'
320416
const api = `https://wap.10010.com/mobileService/home/queryUserInfoSeven.htm?version=iphone_c@7.0403&desmobiel=${phoneNumber}&showType=3`
321417
// 获取手机卡信息列表
322-
const res = await request<PhoneDatas>({
418+
const res = await request<string>({
323419
url: api,
324-
dataType: 'json',
420+
dataType: 'text',
325421
header: {
326422
'user-agent':
327423
'Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
@@ -331,15 +427,15 @@ class China10010 {
331427
// isLaunchInsideApp() && cookie && setStorage('cookie', cookie)
332428
let usefulPhoneDatas: UsefulPhoneData[] = []
333429
try {
334-
const phoneDatas: PhoneData[] = res.data?.data.dataList || []
430+
const phoneDatas: PhoneData[] = (JSON.parse(res.data || '') as PhoneDatas).data.dataList || []
335431
// 提取有用的信息
336432
usefulPhoneDatas = phoneDatas.map(info => {
337-
const present = info.usedTitle.replace(/(|)([\d\.]+)?\%/, (...args) => {
433+
const percent = info.usedTitle.replace(/(|)([\d\.]+)?\%/, (...args) => {
338434
return args[1] === '剩余' ? args[2] : 100 - args[2]
339435
})
340436
return {
341437
type: info.type,
342-
present: Number(present) > 100 ? 100 : Number(present),
438+
percent: Number(percent) > 100 ? 100 : Number(percent),
343439
unit: info.unit,
344440
count: Number(info.number),
345441
label: info.remainTitle,
@@ -352,58 +448,6 @@ class China10010 {
352448
}
353449
return usefulPhoneDatas
354450
}
355-
// // 获取手机卡数据
356-
// async getPhoneData(phoneNumber: number): Promise<UsefulPhoneData[] | string> {
357-
// const api = `https://wap.10010.com/mobileService/home/queryUserInfoSeven.htm?version=iphone_c@7.0403&desmobiel=${phoneNumber}&showType=3`
358-
// if (isLaunchInsideApp()) {
359-
// const webview = new WebView()
360-
// await webview.loadURL(api)
361-
// await webview.waitForLoad()
362-
// const {cookie} = (await webview.evaluateJavaScript(`
363-
// let cookie = document.cookie
364-
// Object.assign({}, {cookie})
365-
// `)) as PageInfo
366-
// cookie && setStorage('cookie', cookie)
367-
// }
368-
// let usefulPhoneData: UsefulPhoneData[] = []
369-
// try {
370-
// const cookie = getStorage<string>('cookie')
371-
// if (!cookie) {
372-
// await showNotification({title: 'cookie 不存在,请先登录', sound: 'failure'})
373-
// return 'cookie 不存在,请先登录'
374-
// }
375-
// // 获取手机卡信息列表
376-
// const dataList: PhoneData[] =
377-
// (
378-
// await request<PhoneDatas>({
379-
// url: api,
380-
// dataType: 'text',
381-
// header: {
382-
// 'user-agent':
383-
// 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0 Mobile/15E148 Safari/604.1',
384-
// cookie,
385-
// },
386-
// })
387-
// ).data?.data.dataList || []
388-
// // 提取有用的信息
389-
// usefulPhoneData = dataList.map(info => {
390-
// const present = info.usedTitle.replace(/(已用|剩余)([\d\.]+)?\%/, (...args) => {
391-
// return args[1] === '剩余' ? args[2] : 100 - args[2]
392-
// })
393-
// return {
394-
// type: info.type,
395-
// present: Number(present) > 100 ? 100 : Number(present),
396-
// unit: info.unit,
397-
// count: Number(info.number),
398-
// label: info.remainTitle,
399-
// }
400-
// })
401-
// } catch (err) {
402-
// await showNotification({title: '获取联通卡信息失败', body: '检查一下网络,或重新登录', sound: 'failure'})
403-
// return '获取联通卡信息失败\n检查一下网络,或重新登录'
404-
// }
405-
// return usefulPhoneData
406-
// }
407451
}
408452

409453
EndAwait(() => new China10010().init())

打包好的成品/install.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,14 @@
4949
"thumb": "https://p.pstatp.com/origin/fe4400034e131f9e4e45",
5050
"name": "网易云歌单",
5151
"title": "网易云歌单"
52+
},
53+
{
54+
"version": "1.0.0",
55+
"description": "小明出品,必属精品",
56+
"scriptURL": "https://raw.githubusercontent.com/2214962083/ios-scriptable-tsx/master/打包好的成品/联通流量话费小部件.js",
57+
"thumb": "https://p.pstatp.com/origin/fe4400034e131f9e4e45",
58+
"name": "联通流量话费小部件",
59+
"title": "联通流量话费小部件"
5260
}
5361
]
5462
}

0 commit comments

Comments
 (0)