Scriptables/Scripts/「源码」京东白条数据.js

244 lines
6.7 KiB
JavaScript
Raw Normal View History

2022-06-02 17:00:01 +08:00
// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: red; icon-glyph: hand-holding-usd;
//
// iOS 桌面组件脚本 @「小件件」
// 开发说明:请从 Widget 类开始编写,注释请勿修改
// https://x.im3x.cn
//
// 添加require是为了vscode中可以正确引入包以获得自动补全等功能
if (typeof require === 'undefined') require = importModule
const { Base } = require("./「小件件」开发环境")
// @组件代码开始
class Widget extends Base {
/**
* 传递给组件的参数可以是桌面 Parameter 数据也可以是外部如 URLScheme 等传递的数据
* @param {string} arg 自定义参数
*/
constructor (arg) {
super(arg)
this.name = '京东白条'
this.desc = '显示京东白条账号额度和还款数据'
this.logo = 'https://m.jr.jd.com/statics/logo.jpg'
this.registerAction("登录京东", this.actionLogin)
}
/**
* 渲染函数函数名固定
* 可以根据 this.widgetFamily 来判断小组件尺寸以返回不同大小的内容
*/
async render () {
const data = await this.getData()
try {
if (data.resultCode !== 0) {
return this.renderFail(data['resultMsg'], true);
}
if (!data.resultData.data['quota'] || !data.resultData.data['bill']) {
return this.renderFail("数据获取失败,请联系反馈更新")
}
} catch (e) {
return this.renderFail("数据解析失败")
}
switch (this.widgetFamily) {
case 'large':
return await this.renderLarge(data['resultData']['data'])
case 'medium':
return await this.renderMedium(data['resultData']['data'])
default:
return await this.renderSmall(data['resultData']['data'])
}
}
async renderFail (msg, login = false) {
const w = new ListWidget()
w.addText("⚠️")
w.addSpacer(10)
const t = w.addText(msg)
t.textColor = Color.red()
t.font = Font.boldSystemFont(14)
w.url = login ? this.actionUrl('login') : this.actionUrl()
return w
}
/**
* 渲染小尺寸组件
*/
async renderSmall (data) {
let w = new ListWidget()
w.url = this.actionUrl('open-url')
await this.renderHeader(w, this.logo, this.name)
const bg = new LinearGradient()
bg.locations = [0, 1]
bg.colors = [
new Color('#f35942', 1),
new Color('#e92d1d', 1)
]
w.backgroundGradient = bg
// 判断参数如果传递1则显示待还否则显示额度
let info = {}
if (this.arg === "1") {
info = {
title: data['bill']['title'],
data: data['bill']['amount'],
desc: data['bill']['buttonName']
}
} else {
info = {
title: '可用额度',
data: data['quota']['quotaLeft'],
desc: '总额度:' + data['quota']['quotaAll']
}
}
const box = w.addStack()
const body = box.addStack()
body.layoutVertically()
const title = body.addText(info.title)
title.font = Font.boldSystemFont(16)
body.addSpacer(10)
const num = body.addText(info.data)
num.font = Font.systemFont(24)
body.addSpacer()
const desc = body.addText(info.desc)
desc.font = Font.lightSystemFont(12)
desc.textOpacity = 0.8
desc.lineLimit = 1
box.addSpacer()
return w
}
/**
* 渲染中尺寸组件
*/
async renderMedium (data) {
let w = new ListWidget()
w.url = this.actionUrl('open-url')
// const bg = new LinearGradient()
// bg.locations = [0, 1]
// bg.colors = [
// new Color('#f35942', 1),
// new Color('#e92d1d', 1)
// ]
// w.backgroundGradient = bg
w.backgroundImage = await this.getImageByUrl('https://txc.gtimg.com/data/287371/2020/1124/30e1524a9288442bec9243c9afa40e90.png')
await this.renderHeader(w, this.logo, this.name, Color.white())
const VIEW_TOP = w.addStack()
VIEW_TOP.addSpacer(24)
const TOP_LEFT = VIEW_TOP.addStack()
TOP_LEFT.layoutVertically()
const t11 = TOP_LEFT.addText("可用额度")
t11.font = Font.boldSystemFont(16)
TOP_LEFT.addSpacer(10)
const t12 = TOP_LEFT.addText(data['quota']['quotaLeft'])
t12.font = Font.systemFont(24)
TOP_LEFT.addSpacer()
const t13 = TOP_LEFT.addText("总额度:" + data['quota']['quotaAll'])
t13.font = Font.lightSystemFont(12)
t13.textOpacity = 0.8
VIEW_TOP.addSpacer()
const TOP_RIGHT = VIEW_TOP.addStack()
TOP_RIGHT.layoutVertically()
const t21 = TOP_RIGHT.addText(data['bill']['title'])
t21.font = Font.boldSystemFont(16)
TOP_RIGHT.addSpacer(10)
const t22 = TOP_RIGHT.addText(data['bill']['amount'])
t22.font = Font.systemFont(24)
TOP_RIGHT.addSpacer()
const t23 = TOP_RIGHT.addText(data['bill']['buttonName'])
t23.font = Font.lightSystemFont(12)
t23.textOpacity = 0.8
;[t11, t12, t13, t21, t22, t23].map(t => t.textColor = Color.white())
VIEW_TOP.addSpacer(20)
return w
}
/**
* 渲染大尺寸组件
*/
async renderLarge (data) {
return await this.renderFail("暂只支持中尺寸小组件")
}
async getData () {
const pt_key = this.settings['pt_key']
const req = new Request("https://ms.jr.jd.com/gw/generic/bt/h5/m/firstScreenNew")
req.method = "POST"
req.body = 'reqData={"clientType":"ios","clientVersion":"13.2.3","deviceId":"","environment":"3"}'
req.headers = {
Cookie: 'pt_key=' + pt_key
}
const res = await req.loadJSON()
return res
}
async actionLogin () {
const webView = new WebView()
webView.loadURL('https://mcr.jd.com/credit_home/pages/index.html?btPageType=BT&channelName=024')
// 循环获取cookie
const tm = new Timer()
tm.timeInterval = 1000
tm.repeats = true
tm.schedule(async () => {
const req = new Request("https://ms.jr.jd.com/gw/generic/bt/h5/m/firstScreenNew")
req.method = "POST"
req.body = 'reqData={"clientType":"ios","clientVersion":"13.2.3","deviceId":"","environment":"3"}'
const res = await req.loadJSON()
const cookies = req.response.cookies
cookies.map(cookie => {
if (cookie['name'] === 'pt_key') {
// 存储,并通知成功
this.notify("登录成功", "登录凭证已保存!可以关闭当前登录页面了!")
tm.invalidate()
this.settings['pt_key'] = cookie['value']
this.saveSettings(false)
return
}
})
})
await webView.present(true)
tm.invalidate()
}
async actionOpenUrl () {
Safari.openInApp('https://mcr.jd.com/credit_home/pages/index.html?btPageType=BT', false)
}
}
// @组件代码结束
const { Testing } = require("./「小件件」开发环境")
await Testing(Widget)