From c3ddc92f2f723a6515f0f18af06d11a7d5351395 Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Wed, 15 Sep 2021 10:05:30 +0800 Subject: [PATCH 001/152] =?UTF-8?q?=E4=BE=9D=E8=B5=96=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=2015=20=E7=B3=BB=E7=BB=9F=EF=BC=8C=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=E5=9B=BE=E6=A0=87=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 202 ++++++++++++++++++++++++------------------------ 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 86e9595..d4f6123 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -28,7 +28,7 @@ class DmYY { }; // 发起请求 - http = async (options = {headers: {}, url: ''}, type = 'JSON') => { + http = async (options = { headers: {}, url: '' }, type = 'JSON') => { try { let request; if (type !== 'IMG') { @@ -36,7 +36,7 @@ class DmYY { Object.keys(options).forEach((key) => { request[key] = options[key]; }); - request.headers = {...this.defaultHeaders, ...options.headers}; + request.headers = { ...this.defaultHeaders, ...options.headers }; } else { request = this.getRequest(options.url); return (await request.loadImage()) || SFSymbol.named('photo').image; @@ -57,9 +57,9 @@ class DmYY { //request 接口请求 $request = { get: async (url = '', options = {}, type = 'JSON') => { - let params = {...options, method: 'GET'}; + let params = { ...options, method: 'GET' }; if (typeof url === 'object') { - params = {...params, ...url}; + params = { ...params, ...url }; } else { params.url = url; } @@ -68,9 +68,9 @@ class DmYY { return await this.http(params, _type); }, post: async (url = '', options = {}, type = 'JSON') => { - let params = {...options, method: 'POST'}; + let params = { ...options, method: 'POST' }; if (typeof url === 'object') { - params = {...params, ...url}; + params = { ...params, ...url }; } else { params.url = url; } @@ -140,7 +140,7 @@ class DmYY { */ verifyImage = async (img) => { try { - const {width, height} = img.size; + const { width, height } = img.size; const direct = true; if (width > 1000) { const options = ['取消', '打开图像处理']; @@ -187,7 +187,7 @@ class DmYY { function phoneSizes() { return { // 12 Pro Max - '2778': { + 2778: { small: 510, medium: 1092, large: 1146, @@ -199,7 +199,7 @@ class DmYY { }, // 12 and 12 Pro - '2532': { + 2532: { small: 474, medium: 1014, large: 1062, @@ -211,7 +211,7 @@ class DmYY { }, // 11 Pro Max, XS Max - '2688': { + 2688: { small: 507, medium: 1080, large: 1137, @@ -223,7 +223,7 @@ class DmYY { }, // 11, XR - '1792': { + 1792: { small: 338, medium: 720, large: 758, @@ -235,8 +235,7 @@ class DmYY { }, // 11 Pro, XS, X, 12 mini - '2436': { - + 2436: { x: { small: 465, medium: 987, @@ -258,11 +257,10 @@ class DmYY { middle: 801, bottom: 1371, }, - }, // Plus phones - '2208': { + 2208: { small: 471, medium: 1044, large: 1071, @@ -274,7 +272,7 @@ class DmYY { }, // SE2 and 6/6S/7/8 - '1334': { + 1334: { small: 296, medium: 642, large: 648, @@ -286,7 +284,7 @@ class DmYY { }, // SE1 - '1136': { + 1136: { small: 282, medium: 584, large: 622, @@ -298,7 +296,7 @@ class DmYY { }, // 11 and XR in Display Zoom mode - '1624': { + 1624: { small: 310, medium: 658, large: 690, @@ -310,7 +308,7 @@ class DmYY { }, // Plus in Display Zoom mode - '2001': { + 2001: { small: 444, medium: 963, large: 972, @@ -354,7 +352,7 @@ class DmYY { message = '您的📱型号是?'; let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X']; let typeIndex = await this.generateAlert(message, types); - let type = (typeIndex === 0) ? 'mini' : 'x'; + let type = typeIndex === 0 ? 'mini' : 'x'; phone = phone[type]; files.writeString(cachePath, type); } @@ -373,7 +371,7 @@ class DmYY { : ''; // Determine image crop based on phone size. - let crop = {w: '', h: '', x: '', y: ''}; + let crop = { w: '', h: '', x: '', y: '' }; if (widgetSize === '小尺寸') { crop.w = phone.small; crop.h = phone.small; @@ -466,7 +464,7 @@ class DmYY { }); // 保存到本地 if (isSave) { - this.settings = {...this.settings, ...data}; + this.settings = { ...this.settings, ...data }; return this.saveSettings(); } return data; @@ -523,14 +521,16 @@ class DmYY { const rowIcon = row.addImageAtURL(item.url); rowIcon.widthWeight = 100; } else { - const icon = item.icon || {}; - const image = await this.drawTableIcon( - icon.name, - icon.color, - item.cornerWidth, - ); - const imageCell = row.addImage(image); - imageCell.widthWeight = 100; + if (parseInt(Device.systemVersion()) < 15) { + const icon = item.icon || {}; + const image = await this.drawTableIcon( + icon.name, + icon.color, + item.cornerWidth, + ); + const imageCell = row.addImage(image); + imageCell.widthWeight = 100; + } } let rowTitle = row.addText(item['title']); rowTitle.widthWeight = 400; @@ -555,42 +555,42 @@ class DmYY { row.onSelect = item.onClick ? async () => { - try { - await item.onClick(item, table); - } catch (e) { - console.log(e); + try { + await item.onClick(item, table); + } catch (e) { + console.log(e); + } } - } : async () => { - if (item.type == 'input') { - await this.setLightAndDark( - item['title'], - item['desc'], - item['val'], - ); - } else if (item.type == 'setBackground') { - const backImage = await this.getWidgetScreenShot(); - if (backImage) { - await this.setBackgroundImage(backImage, true); - await this.setBackgroundNightImage(backImage, true); + if (item.type == 'input') { + await this.setLightAndDark( + item['title'], + item['desc'], + item['val'], + ); + } else if (item.type == 'setBackground') { + const backImage = await this.getWidgetScreenShot(); + if (backImage) { + await this.setBackgroundImage(backImage, true); + await this.setBackgroundNightImage(backImage, true); + } + } else if (item.type == 'removeBackground') { + const options = ['取消', '清空']; + const message = '该操作不可逆,会清空所有背景图片!'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + await this.setBackgroundImage(false, true); + await this.setBackgroundNightImage(false, true); + } else { + const backImage = await this.chooseImg(); + if (!backImage || !(await this.verifyImage(backImage))) return; + if (item.type == 'setDayBackground') + await this.setBackgroundImage(backImage, true); + if (item.type == 'setNightBackground') + await this.setBackgroundNightImage(backImage, true); } - } else if (item.type == 'removeBackground') { - const options = ['取消', '清空']; - const message = '该操作不可逆,会清空所有背景图片!'; - const index = await this.generateAlert(message, options); - if (index === 0) return; - await this.setBackgroundImage(false, true); - await this.setBackgroundNightImage(false, true); - } else { - const backImage = await this.chooseImg(); - if (!backImage || !(await this.verifyImage(backImage))) return; - if (item.type == 'setDayBackground') - await this.setBackgroundImage(backImage, true); - if (item.type == 'setNightBackground') - await this.setBackgroundNightImage(backImage, true); - } - await this.renderDmYYTables(table); - }; + await this.renderDmYYTables(table); + }; table.addRow(row); } table.reload(); @@ -663,37 +663,35 @@ class DmYY { async renderDmYYTables(table) { const basic = [ { - icon: {name: 'arrow.clockwise', color: '#1890ff'}, + icon: { name: 'arrow.clockwise', color: '#1890ff' }, type: 'input', title: '刷新时间', desc: '刷新时间仅供参考,具体刷新时间由系统判断,单位:分钟', val: 'refreshAfterDate', }, { - icon: {name: 'photo', color: '#13c2c2'}, + icon: { name: 'photo', color: '#13c2c2' }, type: 'input', title: '白天背景颜色', - desc: - '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', + desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', val: 'lightBgColor', }, { - icon: {name: 'photo.fill', color: '#52c41a'}, + icon: { name: 'photo.fill', color: '#52c41a' }, type: 'input', title: '晚上背景颜色', - desc: - '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', + desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', val: 'darkBgColor', }, { - icon: {name: 'sun.max.fill', color: '#d48806'}, + icon: { name: 'sun.max.fill', color: '#d48806' }, type: 'input', title: '白天字体颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'lightColor', }, { - icon: {name: 'moon.stars.fill', color: '#d4b106'}, + icon: { name: 'moon.stars.fill', color: '#d4b106' }, type: 'input', title: '晚上字体颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)', @@ -702,42 +700,42 @@ class DmYY { ]; const background = [ { - icon: {name: 'text.below.photo', color: '#faad14'}, + icon: { name: 'text.below.photo', color: '#faad14' }, type: 'setBackground', title: '透明背景设置', }, { - icon: {name: 'photo.on.rectangle', color: '#fa8c16'}, + icon: { name: 'photo.on.rectangle', color: '#fa8c16' }, type: 'setDayBackground', title: '白天背景图片', }, { - icon: {name: 'photo.fill.on.rectangle.fill', color: '#fa541c'}, + icon: { name: 'photo.fill.on.rectangle.fill', color: '#fa541c' }, type: 'setNightBackground', title: '晚上背景图片', }, { - icon: {name: 'record.circle', color: '#722ed1'}, + icon: { name: 'record.circle', color: '#722ed1' }, type: 'input', title: '白天蒙层透明', desc: '完全透明请设置为0', val: 'lightOpacity', }, { - icon: {name: 'record.circle.fill', color: '#eb2f96'}, + icon: { name: 'record.circle.fill', color: '#eb2f96' }, type: 'input', title: '晚上蒙层透明', desc: '完全透明请设置为0', val: 'darkOpacity', }, { - icon: {name: 'clear', color: '#f5222d'}, + icon: { name: 'clear', color: '#f5222d' }, type: 'removeBackground', title: '清空背景图片', }, ]; const boxjs = { - icon: {name: 'shippingbox', color: '#f7bb10'}, + icon: { name: 'shippingbox', color: '#f7bb10' }, type: 'input', title: 'BoxJS 域名', desc: '', @@ -786,8 +784,9 @@ class DmYY { // 文件管理器 // 提示:缓存数据不要用这个操作,这个是操作源码目录的,缓存建议存放在local temp目录中 - this.FILE_MGR = FileManager[ - module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' + this.FILE_MGR = + FileManager[ + module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' ](); // 本地,用于存储图片等 this.FILE_MGR_LOCAL = FileManager.local(); @@ -851,7 +850,7 @@ class DmYY { * @param {string} name 操作函数名 * @param {func} func 点击后执行的函数 */ - registerAction(name, func, icon = {name: 'gear', color: '#096dd9'}) { + registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }) { this._actions[name] = func.bind(this); this._actionsIcon[name] = icon; } @@ -1041,7 +1040,7 @@ class DmYY { } function u(n, t) { - return (function(n, t) { + return (function (n, t) { var r, e, o = h(n), @@ -1049,7 +1048,7 @@ class DmYY { c = []; for ( u[15] = c[15] = void 0, - 16 < o.length && (o = i(o, 8 * n.length)), + 16 < o.length && (o = i(o, 8 * n.length)), r = 0; r < 16; r += 1 @@ -1256,39 +1255,39 @@ class DmYY { } textFormat = { - defaultText: {size: 14, font: 'regular', color: this.widgetColor}, - battery: {size: 10, font: 'bold', color: this.widgetColor}, - title: {size: 16, font: 'semibold', color: this.widgetColor}, - SFMono: {size: 12, font: 'SF Mono', color: this.widgetColor}, + defaultText: { size: 14, font: 'regular', color: this.widgetColor }, + battery: { size: 10, font: 'bold', color: this.widgetColor }, + title: { size: 16, font: 'semibold', color: this.widgetColor }, + SFMono: { size: 12, font: 'SF Mono', color: this.widgetColor }, }; provideFont = (fontName, fontSize) => { const fontGenerator = { - ultralight: function() { + ultralight: function () { return Font.ultraLightSystemFont(fontSize); }, - light: function() { + light: function () { return Font.lightSystemFont(fontSize); }, - regular: function() { + regular: function () { return Font.regularSystemFont(fontSize); }, - medium: function() { + medium: function () { return Font.mediumSystemFont(fontSize); }, - semibold: function() { + semibold: function () { return Font.semiboldSystemFont(fontSize); }, - bold: function() { + bold: function () { return Font.boldSystemFont(fontSize); }, - heavy: function() { + heavy: function () { return Font.heavySystemFont(fontSize); }, - black: function() { + black: function () { return Font.blackSystemFont(fontSize); }, - italic: function() { + italic: function () { return Font.italicSystemFont(fontSize); }, }; @@ -1339,7 +1338,7 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { Script.complete(); } } else { - let {act, __arg, __size} = args.queryParameters; + let { act, __arg, __size } = args.queryParameters; M = new Widget(__arg || default_args || ''); if (extra) { Object.keys(extra).forEach((key) => { @@ -1354,8 +1353,9 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { const onClick = async (item) => { M.widgetFamily = item.val; w = await M.render(); - const fnc = item.val.toLowerCase().replace( - /( |^)[a-z]/g, (L) => L.toUpperCase()); + const fnc = item.val + .toLowerCase() + .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()); if (w) { return w[`present${fnc}`](); } @@ -1406,4 +1406,4 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { }; // await new DmYY().setWidgetConfig(); -module.exports = {DmYY, Runing}; +module.exports = { DmYY, Runing }; From 01c9ceb50da63a172c2b109183193d97891fc57d Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Wed, 15 Sep 2021 10:06:47 +0800 Subject: [PATCH 002/152] =?UTF-8?q?fix:15=E5=9B=BE=E6=A0=87=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install.json b/install.json index bda27c1..d1004bc 100644 --- a/install.json +++ b/install.json @@ -5,7 +5,7 @@ "repo": "https://github.com/dompling/Scriptable", "apps": [ { - "version": "1.0.7", + "version": "1.0.8", "description": "DmYY组件库", "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js", "thumb": "https://img.icons8.com/clouds/344/settings.png", @@ -13,6 +13,8 @@ "title": "DmYY", "html": [ "

更新说明

", + "v1.0.8", + "
  • 兼容 ios15 系统,图标引起脚本一直转圈问题
  • ", "v1.0.7", "
  • 处理背景图在 12mini 下错位的情况
  • ", "v1.0.6", From 6ce243e05ff721798667099d87a71b8b2adf5d99 Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Wed, 15 Sep 2021 10:37:17 +0800 Subject: [PATCH 003/152] =?UTF-8?q?=E5=8E=BB=E6=8E=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/install.json b/install.json index d1004bc..b32cb85 100644 --- a/install.json +++ b/install.json @@ -424,17 +424,6 @@ "
  • 调整大尺寸排列效果
  • ", "
  • 调整下班倒计时默认不开启
  • " ] - }, - { - "version": "1.0.0", - "description": "低端影视的桌面小组件", - "scriptURL": "https://raw.githubusercontent.com/dompling/scriptableTsx/master/scripts/DdVideo.js", - "thumb": "https://ddrk.me/favicon-32x32.png", - "name": "DdVideo", - "title": "低端影视组件", - "html": [ - "
  • 感谢 @Gideon_Senku 提供接口帮助
  • " - ] } ] } From e2114b8fb07ea1b8f36be031b67d8f20376ff34b Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Wed, 15 Sep 2021 10:42:01 +0800 Subject: [PATCH 004/152] 1 --- Scripts/DmYY.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index d4f6123..7d732fc 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -10,7 +10,11 @@ class DmYY { constructor(arg) { this.arg = arg; - this.init(); + try { + this.init(); + } catch (error) { + console.log(error); + } this.isNight = Device.isUsingDarkAppearance(); } From a1efbbe8cdd08817dc446bc76dc139e1893930c3 Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Sat, 18 Sep 2021 15:26:30 +0800 Subject: [PATCH 005/152] =?UTF-8?q?=E5=81=A5=E5=BA=B7=E6=AD=A5=E6=95=B0?= =?UTF-8?q?=EF=BC=9A=E7=A7=BB=E9=99=A4=E6=8D=B7=E5=BE=84=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Health.js | 734 ++++++++++++++++++++++++---------------------- 1 file changed, 383 insertions(+), 351 deletions(-) diff --git a/Scripts/Health.js b/Scripts/Health.js index 894e4d5..b6efbc4 100644 --- a/Scripts/Health.js +++ b/Scripts/Health.js @@ -9,367 +9,399 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === "undefined") require = importModule; -const { DmYY, Runing } = require("./DmYY"); +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { - constructor(arg) { - super(arg); - this.name = "健康行走步数"; - this.en = "healthCenter"; - this.maxMonthDist = parseInt(this.settings.maxMonthDist) || 5; // 柱状图比例高度,值越大,柱状范围越广 - this.Run(); - } - - widgetFamily = "medium"; - maxYearDist = 1500; - - color1 = Color.orange(); - lineColor = new Color("#48484b"); - useBoxJS = false; - - running = {}; - stepsCount = 0; - stepsToday = 0; - - init = async () => { - try { - await this.getData(); - } catch (e) { - console.log(e); - } - }; - - numberFormat(value) { - try { - const param = {}; - let k = 10000; - const size = ["", '万', "亿", "万亿"]; - let i; - if (value < k) { - param.value = value; - param.unit = ""; - } else { - i = Math.floor(Math.log(value) / Math.log(k)); - param.value = ((value / Math.pow(k, i))).toFixed(2); - param.unit = size[i]; - } - return param; - } catch (e) { - console.log(e); - } - } - - - getData = async () => { - try { - const fileICloud = FileManager.iCloud(); - const dir = fileICloud.documentsDirectory(); - const path = fileICloud.joinPath(dir, "health.txt"); - const response = fileICloud.readString(path); - let data = JSON.parse(response); - const dateToday = new Date(); - const year = dateToday.getFullYear(); - let month = dateToday.getMonth() + 1; - let day = dateToday.getDate(); - month = month >= 10 ? month : `0${month}`; - day = day >= 10 ? day : `0${day}`; - const today = `${year}-${month}-${day}`; - - data.forEach((item) => { - if (item.health_type === "Walking + Running Distance") { - item.samples.forEach((run, index) => { - if (item.samples.length - 1 === index) return; - const date = run.date; - if (!this.running[date]) this.running[date] = 0; - this.running[date] += parseFloat(run.value); - }); - } - if (item.health_type === "Steps") { - item.samples.forEach((step) => { - if (step.date === today) this.stepsToday = step.value; - this.stepsCount += parseInt(step.value); - }); - } - }); - Object.keys(this.running).forEach((key) => { - this.running[key] = Math.floor(this.running[key] * 100) / 100; - }); - } catch (e) { - this.notify( - this.name, - "健康数据读取失败,请点击使用健康数据快捷指令更新步数", - "https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf", - ); - return false; - } - }; - - /*------------------------------------------------------------------------------ + constructor(arg) { + super(arg); + this.name = '健康行走步数'; + this.en = 'healthCenter'; + this.maxMonthDist = parseInt(this.settings.maxMonthDist) || 5; // 柱状图比例高度,值越大,柱状范围越广 + this.Run(); + } + + widgetFamily = 'medium'; + maxYearDist = 1500; + + color1 = Color.orange(); + lineColor = new Color('#48484b'); + useBoxJS = false; + + running = {}; + stepsCount = 0; + stepsToday = 0; + + init = async () => { + try { + await this.getData(); + } catch (e) { + console.log(e); + } + }; + + numberFormat(value) { + try { + const param = {}; + let k = 10000; + const size = ['', '万', '亿', '万亿']; + let i; + if (value < k) { + param.value = value; + param.unit = ''; + } else { + i = Math.floor(Math.log(value) / Math.log(k)); + param.value = (value / Math.pow(k, i)).toFixed(2); + param.unit = size[i]; + } + return param; + } catch (e) { + console.log(e); + } + } + + getData = async () => { + try { + const fileICloud = FileManager.iCloud(); + const dir = fileICloud.documentsDirectory(); + const path = fileICloud.joinPath(dir, 'health.txt'); + const response = fileICloud.readString(path); + let data = JSON.parse(response); + const dateToday = new Date(); + const year = dateToday.getFullYear(); + let month = dateToday.getMonth() + 1; + let day = dateToday.getDate(); + month = month >= 10 ? month : `0${month}`; + day = day >= 10 ? day : `0${day}`; + const today = `${year}-${month}-${day}`; + + data.forEach((item) => { + if (item.health_type === 'Walking + Running Distance') { + item.samples.forEach((run, index) => { + if (item.samples.length - 1 === index) return; + const date = run.date; + if (!this.running[date]) this.running[date] = 0; + this.running[date] += parseFloat(run.value); + }); + } + if (item.health_type === 'Steps') { + item.samples.forEach((step) => { + if (step.date === today) this.stepsToday = step.value; + this.stepsCount += parseInt(step.value); + }); + } + }); + Object.keys(this.running).forEach((key) => { + this.running[key] = Math.floor(this.running[key] * 100) / 100; + }); + } catch (e) { + this.notify( + this.name, + '健康数据读取失败,请点击使用健康数据快捷指令更新步数', + 'https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf', + ); + return false; + } + }; + + /*------------------------------------------------------------------------------ 50 km Linien ------------------------------------------------------------------------------*/ - createLines(stack) { - let canvas, path; - // 50km Linien - canvas = new DrawContext(); - canvas.size = new Size(292, 82); - canvas.opaque = false; - canvas.respectScreenScale = true; - canvas.setFillColor(this.lineColor); - path = new Path(); - path.addRect(new Rect(0, 0, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - path = new Path(); - path.addRect(new Rect(0, 15, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - path = new Path(); - path.addRect(new Rect(0, 30, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - path = new Path(); - path.addRect(new Rect(0, 45, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - stack.backgroundImage = canvas.getImage(); - } - - async buildWidget(widget) { - // // Stacks definieren - let stackYear = widget.addStack(); - widget.addSpacer(); - let stackMonth = widget.addStack(); - // Stacks für Symbol und Jahresauswertung aufbereiten - let stackYear1 = stackYear.addStack(); - stackYear.addSpacer(10); - let stackYear2 = stackYear.addStack(); - let sym = SFSymbol.named("figure.walk"); - let img = stackYear1.addImage(sym.image); - img.tintColor = this.color1; - img.imageSize = new Size(25, 25); - stackYear2.layoutVertically(); - let stackYearCurr = stackYear2.addStack(); - let stackThemItem = stackYear2.addStack(); - let stackToday = stackYear2.addStack(); - - let data = 0; - const runningData = Object.keys(this.running); - if (runningData.length > 12) runningData.splice(0, runningData.length - 12); - runningData.forEach((date) => { - const [_, month, day] = date.split("-"); - const stackDay = stackMonth.addStack(); - const value = this.running[date]; - this.createProgressMonth(stackDay, `${month}.${day}`, value); - stackMonth.addSpacer(2); - data += value; - }); - this.createProgressYear(stackYearCurr, "运动", data, this.color1); - - const count = (18 * this.stepsCount) / (20000 * this.maxMonthDist / 4); - this.createProgressSteps(stackThemItem, "步数", this.stepsCount, this.color1, count); - const today = (18 * this.stepsToday) / (2000 * this.maxMonthDist / 4); - this.createProgressSteps(stackToday, "今日", this.stepsToday, this.color1, today); - - // 50km Linie - this.createLines(stackMonth); - return widget; - } - - createProgressYear(stack, year, dist, color) { - let stackDesc, stackPBar, stackDist, canvas, path, txt, img; - - // Initialisierung - stack.centerAlignContent(); - - // Stacks definieren - stackDesc = stack.addStack(); - stackPBar = stack.addStack(); - stackDist = stack.addStack(); - - // Beschreibung - stackDesc.size = new Size(30, 0); - txt = stackDesc.addText(year); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - stackDesc.addSpacer(); - - // Progress-Bar - canvas = new DrawContext(); - canvas.size = new Size(180, 7); - canvas.opaque = false; - canvas.respectScreenScale = true; - canvas.setFillColor(new Color("#48484b")); - path = new Path(); - path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - canvas.setFillColor(color); - path = new Path(); - path.addRoundedRect(new Rect(0, 0, (180 * dist) / (200 * this.maxMonthDist / 4), 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - img = stackPBar.addImage(canvas.getImage()); - img.imageSize = new Size(180, 7); - - // Distanz - stackDist.addSpacer(10); - txt = stackDist.addText(Math.round(dist).toString() + " km"); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - } - - createProgressSteps(stack, year, dist, color, rectScale) { - let stackDesc, stackPBar, stackDist, canvas, path, txt, img; - - // Initialisierung - stack.centerAlignContent(); - - // Stacks definieren - stackDesc = stack.addStack(); - stackPBar = stack.addStack(); - stackDist = stack.addStack(); - - // Beschreibung - stackDesc.size = new Size(30, 0); - txt = stackDesc.addText(year); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - stackDesc.addSpacer(); - - // Progress-Bar - canvas = new DrawContext(); - canvas.size = new Size(180, 7); - canvas.opaque = false; - canvas.respectScreenScale = true; - canvas.setFillColor(new Color("#48484b")); - path = new Path(); - path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - canvas.setFillColor(color); - path = new Path(); - const numberText = this.numberFormat(dist); - - path.addRoundedRect(new Rect(0, 0, rectScale, 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - img = stackPBar.addImage(canvas.getImage()); - img.imageSize = new Size(180, 7); - - // Distanz - stackDist.addSpacer(10); - - txt = stackDist.addText(numberText.value + ` ${numberText.unit}步`); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - } - - createTemplateItem(stack, desc) { - // Stacks - const txt = stack.addText(desc); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - } - - /*------------------------------------------------------------------------------ + createLines(stack) { + let canvas, path; + // 50km Linien + canvas = new DrawContext(); + canvas.size = new Size(292, 82); + canvas.opaque = false; + canvas.respectScreenScale = true; + canvas.setFillColor(this.lineColor); + path = new Path(); + path.addRect(new Rect(0, 0, 292, 1)); + canvas.addPath(path); + canvas.fillPath(); + path = new Path(); + path.addRect(new Rect(0, 15, 292, 1)); + canvas.addPath(path); + canvas.fillPath(); + path = new Path(); + path.addRect(new Rect(0, 30, 292, 1)); + canvas.addPath(path); + canvas.fillPath(); + path = new Path(); + path.addRect(new Rect(0, 45, 292, 1)); + canvas.addPath(path); + canvas.fillPath(); + stack.backgroundImage = canvas.getImage(); + } + + async buildWidget(widget) { + // // Stacks definieren + let stackYear = widget.addStack(); + widget.addSpacer(); + let stackMonth = widget.addStack(); + // Stacks für Symbol und Jahresauswertung aufbereiten + let stackYear1 = stackYear.addStack(); + stackYear.addSpacer(10); + let stackYear2 = stackYear.addStack(); + let sym = SFSymbol.named('figure.walk'); + let img = stackYear1.addImage(sym.image); + img.tintColor = this.color1; + img.imageSize = new Size(25, 25); + stackYear2.layoutVertically(); + let stackYearCurr = stackYear2.addStack(); + let stackThemItem = stackYear2.addStack(); + let stackToday = stackYear2.addStack(); + + let data = 0; + const runningData = Object.keys(this.running); + if (runningData.length > 12) runningData.splice(0, runningData.length - 12); + runningData.forEach((date) => { + const [_, month, day] = date.split('-'); + const stackDay = stackMonth.addStack(); + const value = this.running[date]; + this.createProgressMonth(stackDay, `${month}.${day}`, value); + stackMonth.addSpacer(2); + data += value; + }); + this.createProgressYear(stackYearCurr, '运动', data, this.color1); + + const count = (18 * this.stepsCount) / ((20000 * this.maxMonthDist) / 4); + this.createProgressSteps( + stackThemItem, + '步数', + this.stepsCount, + this.color1, + count, + ); + const today = (18 * this.stepsToday) / ((2000 * this.maxMonthDist) / 4); + this.createProgressSteps( + stackToday, + '今日', + this.stepsToday, + this.color1, + today, + ); + + // 50km Linie + this.createLines(stackMonth); + return widget; + } + + createProgressYear(stack, year, dist, color) { + let stackDesc, stackPBar, stackDist, canvas, path, txt, img; + + // Initialisierung + stack.centerAlignContent(); + + // Stacks definieren + stackDesc = stack.addStack(); + stackPBar = stack.addStack(); + stackDist = stack.addStack(); + + // Beschreibung + stackDesc.size = new Size(30, 0); + txt = stackDesc.addText(year); + txt.font = Font.systemFont(7); + txt.textColor = this.widgetColor; + stackDesc.addSpacer(); + + // Progress-Bar + canvas = new DrawContext(); + canvas.size = new Size(180, 7); + canvas.opaque = false; + canvas.respectScreenScale = true; + canvas.setFillColor(new Color('#48484b')); + path = new Path(); + path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2); + canvas.addPath(path); + canvas.fillPath(); + canvas.setFillColor(color); + path = new Path(); + path.addRoundedRect( + new Rect(0, 0, (180 * dist) / ((200 * this.maxMonthDist) / 4), 5), + 3, + 2, + ); + canvas.addPath(path); + canvas.fillPath(); + img = stackPBar.addImage(canvas.getImage()); + img.imageSize = new Size(180, 7); + + // Distanz + stackDist.addSpacer(10); + txt = stackDist.addText(Math.round(dist).toString() + ' km'); + txt.font = Font.systemFont(7); + txt.textColor = this.widgetColor; + } + + createProgressSteps(stack, year, dist, color, rectScale) { + let stackDesc, stackPBar, stackDist, canvas, path, txt, img; + + // Initialisierung + stack.centerAlignContent(); + + // Stacks definieren + stackDesc = stack.addStack(); + stackPBar = stack.addStack(); + stackDist = stack.addStack(); + + // Beschreibung + stackDesc.size = new Size(30, 0); + txt = stackDesc.addText(year); + txt.font = Font.systemFont(7); + txt.textColor = this.widgetColor; + stackDesc.addSpacer(); + + // Progress-Bar + canvas = new DrawContext(); + canvas.size = new Size(180, 7); + canvas.opaque = false; + canvas.respectScreenScale = true; + canvas.setFillColor(new Color('#48484b')); + path = new Path(); + path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2); + canvas.addPath(path); + canvas.fillPath(); + canvas.setFillColor(color); + path = new Path(); + const numberText = this.numberFormat(dist); + + path.addRoundedRect(new Rect(0, 0, rectScale, 5), 3, 2); + canvas.addPath(path); + canvas.fillPath(); + img = stackPBar.addImage(canvas.getImage()); + img.imageSize = new Size(180, 7); + + // Distanz + stackDist.addSpacer(10); + + txt = stackDist.addText(numberText.value + ` ${numberText.unit}步`); + txt.font = Font.systemFont(7); + txt.textColor = this.widgetColor; + } + + createTemplateItem(stack, desc) { + // Stacks + const txt = stack.addText(desc); + txt.font = Font.systemFont(7); + txt.textColor = this.widgetColor; + } + + /*------------------------------------------------------------------------------ Balkenanzeige für Monatsauswertung aufbereiten ------------------------------------------------------------------------------*/ - createProgressMonth(stack, month, dist3) { - let stackDist, stackPBar, stackDesc, canvas, path, s, img, txt; - - // Stacks definieren - stack.layoutVertically(); - stackPBar = stack.addStack(); - stack.addSpacer(5); - stackDesc = stack.addStack(); - stackDist = stack.addStack(); - - // Progress-Bar - canvas = new DrawContext(); - canvas.size = new Size(17, 60); - canvas.opaque = false; - canvas.respectScreenScale = true; - - canvas.setFillColor(this.color1); - path = new Path(); - s = (50 * dist3) / this.maxMonthDist; - path.addRect(new Rect(6, 60 - s, 8, s)); - canvas.addPath(path); - canvas.fillPath(); - img = stackPBar.addImage(canvas.getImage()); - img.imageSize = new Size(17, 60); - - // Monat - stackDesc.size = new Size(23, 10); - txt = stackDesc.addText(month); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - txt.centerAlignText(); - - // Distanz aktuelle Jahr - stackDist.size = new Size(20, 8); - txt = stackDist.addText(Math.round(dist3).toString()); - txt.font = Font.systemFont(6); - txt.textColor = this.widgetColor; - txt.centerAlignText(); - } - - - /** - * 渲染函数,函数名固定 - * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 - */ - async render() { - await this.init(); - const widget = new ListWidget(); - await this.getWidgetBackgroundImage(widget); - await this.buildWidget(widget); - await widget.presentMedium(); - if (config.runsFromHomeScreen) return widget; - } - - Run = () => { - if (config.runsInApp) { - this.registerAction("捷径安装", async () => { - await this.notify(this.name, "点击安装捷径", "https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf"); - }); - this.registerAction("柱状比例", async () => { - await this.setAlertInput("设置柱状比例", " 柱状图比例高度,值越大,柱状范围越广", { maxMonthDist: "比例默认值,5" }); - }); - this.registerAction("皮肤颜色", this.setWidgetSkin); - this.registerAction("刻度颜色", this.setWidgetScale); - this.registerAction("基础设置", this.setWidgetConfig); - } - const skinColor = !this.isNight ? this.settings.lightSkinColor : this.settings.darkSkinColor; - this.color1 = skinColor ? new Color(skinColor) : this.color1; - const scaleColor = !this.isNight ? this.settings.lightScaleColor : this.settings.darkScaleColor; - this.lineColor = scaleColor ? new Color(scaleColor) : this.lineColor; - }; - - setWidgetSkin = async () => { - await this.setLightAndDark("柱状颜色", false, "lightSkinColor", "darkSkinColor"); - }; - - setWidgetScale = async () => { - await this.setLightAndDark("刻度颜色", false, "lightScaleColor", "darkScaleColor"); - }; + createProgressMonth(stack, month, dist3) { + let stackDist, stackPBar, stackDesc, canvas, path, s, img, txt; + + // Stacks definieren + stack.layoutVertically(); + stackPBar = stack.addStack(); + stack.addSpacer(5); + stackDesc = stack.addStack(); + stackDist = stack.addStack(); + + // Progress-Bar + canvas = new DrawContext(); + canvas.size = new Size(17, 60); + canvas.opaque = false; + canvas.respectScreenScale = true; + + canvas.setFillColor(this.color1); + path = new Path(); + s = (50 * dist3) / this.maxMonthDist; + path.addRect(new Rect(6, 60 - s, 8, s)); + canvas.addPath(path); + canvas.fillPath(); + img = stackPBar.addImage(canvas.getImage()); + img.imageSize = new Size(17, 60); + + // Monat + stackDesc.size = new Size(23, 10); + txt = stackDesc.addText(month); + txt.font = Font.systemFont(7); + txt.textColor = this.widgetColor; + txt.centerAlignText(); + + // Distanz aktuelle Jahr + stackDist.size = new Size(20, 8); + txt = stackDist.addText(Math.round(dist3).toString()); + txt.font = Font.systemFont(6); + txt.textColor = this.widgetColor; + txt.centerAlignText(); + } + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + await this.getWidgetBackgroundImage(widget); + await this.buildWidget(widget); + await widget.presentMedium(); + if (config.runsFromHomeScreen) return widget; + } + + Run = () => { + if (config.runsInApp) { + this.registerAction('捷径安装', async () => { + await this.notify( + this.name, + '点击安装捷径', + 'https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf', + ); + }); + this.registerAction('柱状比例', async () => { + await this.setAlertInput( + '设置柱状比例', + ' 柱状图比例高度,值越大,柱状范围越广', + { maxMonthDist: '比例默认值,5' }, + ); + }); + this.registerAction('皮肤颜色', this.setWidgetSkin); + this.registerAction('刻度颜色', this.setWidgetScale); + this.registerAction('基础设置', this.setWidgetConfig); + } + const skinColor = !this.isNight + ? this.settings.lightSkinColor + : this.settings.darkSkinColor; + this.color1 = skinColor ? new Color(skinColor) : this.color1; + const scaleColor = !this.isNight + ? this.settings.lightScaleColor + : this.settings.darkScaleColor; + this.lineColor = scaleColor ? new Color(scaleColor) : this.lineColor; + }; + + setWidgetSkin = async () => { + await this.setLightAndDark( + '柱状颜色', + false, + 'lightSkinColor', + 'darkSkinColor', + ); + }; + + setWidgetScale = async () => { + await this.setLightAndDark( + '刻度颜色', + false, + 'lightScaleColor', + 'darkScaleColor', + ); + }; } // @组件代码结束 if (config.runsFromHomeScreen || config.runsInApp) { - Runing(Widget, "", false); + Runing(Widget, '', false); } else { - let params = args.shortcutParameter; - if (params) { - const fileICloud = FileManager.iCloud(); - const path = fileICloud.documentsDirectory(); - fileICloud.writeString(path + "/health.txt", JSON.stringify(params)); - } - (async () => { - const M = new Widget(); - await M.render(); - Script.complete(); - })(); + let params = args.shortcutParameter; + if (params) { + const fileICloud = FileManager.iCloud(); + const path = fileICloud.documentsDirectory(); + fileICloud.writeString(path + '/health.txt', JSON.stringify(params)); + Script.complete(); + } } From e17b7e11037162724e1e00cf0b523e50e2add6b2 Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Fri, 24 Sep 2021 09:46:29 +0800 Subject: [PATCH 006/152] =?UTF-8?q?=E5=A4=B4=E5=83=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/JD-all-one-v2.js | 2261 ++++++++++++++++++++++++++++++++++++++ Scripts/JD-all-one.js | 918 ---------------- 2 files changed, 2261 insertions(+), 918 deletions(-) create mode 100644 Scripts/JD-all-one-v2.js delete mode 100644 Scripts/JD-all-one.js diff --git a/Scripts/JD-all-one-v2.js b/Scripts/JD-all-one-v2.js new file mode 100644 index 0000000..2ff89d7 --- /dev/null +++ b/Scripts/JD-all-one-v2.js @@ -0,0 +1,2261 @@ +// Author: 脑瓜 +// 电报群: https://t.me/Scriptable_JS @anker1209 +// 采用了2Ya美女的京豆收支脚本及DmYY依赖 https://github.com/dompling/Scriptable/tree/master/Scripts +// version:2.2.2 +// update:2021/04/01 + +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); + +class Widget extends DmYY { + constructor(arg) { + super(arg); + this.name = '京东多合一'; + this.en = 'jd_in_one'; + this.run(module.filename, args); + } + fm = FileManager.local(); + iCloudInUse = this.fm.isFileStoredIniCloud(module.filename); + fm = this.iCloudInUse ? FileManager.iCloud() : this.fm; + CACHE_FOLDER = 'JD_in_one'; + cachePath = this.fm.joinPath(this.fm.documentsDirectory(), this.CACHE_FOLDER); + + logo = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/f09e7977-b161-4361-ac78-e64729192ee6.png'; + JDImg = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/43300bf7-61a2-4bd1-94a1-bf2faa2ed9e8.png'; + beanImg = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/7ea91cf8-6dea-477c-ae72-cb4d3f646c34.png'; + plusFG = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/cd0d2b80-0857-4202-8d12-af4eb7d241d6.png'; + plusBG = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/24fc5a14-edea-4b1b-8e30-bdcc1a27a037.png'; + baitiaoImg = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/30c40f5b-7428-46c3-a2c0-d81b2b95ec41.png'; + plusIcon = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/06f78540-a5a4-462e-b8c5-98cb8059efc1.png'; + walletImg = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/cd89ceec-7895-41ee-a1a3-3d3e7223035f.png'; + jingtieImg = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/16a7038e-6082-4ad8-b17f-fdd08266fb22.png'; + gangbengImg = + 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/9704e332-9e7f-47e8-b09a-1f1991d4aa84.png'; + userImage = + 'https://img11.360buyimg.com/jdphoto/s120x120_jfs/t21160/90/706848746/2813/d1060df5/5b163ef9N4a3d7aa6.png'; + + // 请勿在此修改参数值 + + version = '2.2.2'; + basicSetting = { + scale: 1.0, + logo: 30, + userImage: 69, + userStack: 103, + division: 25, + interval: 10, + customizeName: '', + customizeAvatar: '', + smallShowType: '京豆、钱包数据', + walletShowType: '红包', + }; + chartSetting = { + height: 130, + daySize: 9, + dayText: '', + textSize: 18, + textDayColor: '999999', + textNightColor: '999999', + lineColor: '#FA6859', + linePadding: 15, + barPadding: 5, + smallShowType: '双日视图', + showType: '双日视图', + countBean: '收入-支出', + colorful: '关闭', + }; + funcSetting = { + showBaitiao: '打开', + showPackage: '关闭', + logable: '关闭', + alwaysRefreshChart: '打开', + }; + package = { + number: 0, + title: '', + desc: '', + time: '', + status: '', + }; + baitiao = { + title: '', + number: 0, + desc: '', + }; + redPackage = { + title: '通用红包', + number: 0, + desc: '今日无过期', + }; + expireBean = { + title: '过期京豆', + number: 0, + desc: '', + }; + extra = { + jingtie: 0, + gangbeng: 0, + }; + bean = { + todayIncome: 0, + todayExpense: 0, + ydayIncome: 0, + ydayExpense: 0, + }; + + nickName = '未知用户'; + jValue = '0'; + isPlus = false; + + cookie = ''; + userName = ''; + CookiesData = []; + cacheChart = false; + beanCount = 0; + maxDays = 6; + rangeTimer = {}; + timerKeys = []; + + doubleDate = this.getDay(1); + doubleDay = Object.keys(this.doubleDate); + yestoday = this.doubleDay[0]; + today = this.doubleDay[1]; + CACHES = []; + + lineChart(labels = [], datas = [], chartTextSize, topPadding) { + let chartTextColor = Color.dynamic( + new Color(this.chartSetting.textDayColor), + new Color(this.chartSetting.textNightColor), + ); + let lineColor = this.chartSetting.lineColor.split(','); + log(lineColor); + const chartStr = ` + { + type: 'bar', + data: { + labels: ${JSON.stringify(labels)}, + datasets: [ + { + type: 'line', + backgroundColor: '#FFFFFF', + borderColor: getGradientFillHelper('horizontal', ${JSON.stringify( + lineColor, + )}), + borderWidth: ${this.isSmall(true) ? 4 : 3}, + pointRadius: ${this.isSmall(true) ? 8 : 6}, + fill: false, + showLine: true, + data: ${JSON.stringify(datas)}, + }, + ], + }, + options: { + plugins: { + datalabels: { + display: true, + align: 'top', + color: '#${chartTextColor.hex}', + font: { + family: 'ArialMT', + size: ${chartTextSize} + } + }, + }, + layout: { + padding: { + left: -20, + right: 0, + top: ${topPadding}, + bottom: 0 + } + }, + responsive: true, + maintainAspectRatio: true, + legend: { + display: false, + }, + scales: { + xAxes: [ + { + gridLines: { + display: false, + }, + ticks: { + display: false, + }, + }, + ], + yAxes: [ + { + ticks: { + display: false, + beginAtZero: false, + }, + gridLines: { + display: false, + }, + }, + ], + }, + }, + }`; + return chartStr; + } + + barChart(labels = [], datas = [], chartTextSize, topPadding, showType) { + let chartTextColor = Color.dynamic( + new Color(this.chartSetting.textDayColor), + new Color(this.chartSetting.textNightColor), + ); + let backgroundColor = []; + if (this.chartSetting.colorful === '打开') + backgroundColor = JSON.stringify(this.colorfulBar()); + else + backgroundColor = `getGradientFillHelper('vertical', ${JSON.stringify( + this.chartColors(), + )})`; + const chartStr = ` + { + type: 'bar', + data: { + labels: ${JSON.stringify(labels)}, + datasets: [ + { + type: '${showType}', + borderWidth: 0, + pointRadius: 0, + barPercentage: 0.5, + backgroundColor: ${backgroundColor}, + borderColor: false, + data: ${JSON.stringify(datas)}, + }, + ], + }, + options: { + plugins: { + datalabels: { + display: true, + align: 'top', + offset: -4, + anchor:'end', + color: '#${chartTextColor.hex}', + font: { + family: 'ArialMT', + size: ${chartTextSize} + } + }, + }, + layout: { + padding: { + left: -20, + right: 0, + top: ${topPadding}, + bottom: 0 + } + }, + responsive: true, + maintainAspectRatio: true, + legend: { + display: false, + }, + title: { + display: false, + }, + scales: { + xAxes: [ + { + gridLines: { + offsetGridLines: true, + display: false, + }, + ticks: { + display: false, + }, + }, + ], + yAxes: [ + { + ticks: { + display: false, + beginAtZero: true, + }, + gridLines: { + offsetGridLines: true, + display: false, + }, + }, + ], + }, + }, + }`; + return chartStr; + } + + chartColors() { + let colorArr = [ + ['#FFF000', '#E62490'], + ['#FDEB71', '#F8D800'], + ['#ABDCFF', '#0396FF'], + ['#FEB692', '#EA5455'], + ['#FEB692', '#EA5455'], + ['#CE9FFC', '#7367F0'], + ['#90F7EC', '#32CCBC'], + ['#FFF6B7', '#F6416C'], + ['#E2B0FF', '#9F44D3'], + ['#F97794', '#F072B6'], + ['#FCCF31', '#F55555'], + ['#5EFCE8', '#736EFE'], + ['#FAD7A1', '#E96D71'], + ['#FFFF1C', '#00C3FF'], + ['#FEC163', '#DE4313'], + ['#F6CEEC', '#D939CD'], + ['#FDD819', '#E80505'], + ['#FFF3B0', '#CA26FF'], + ['#2AFADF', '#4C83FF'], + ['#EECDA3', '#EF629F'], + ['#C2E59C', '#64B3F4'], + ['#FFF886', '#F072B6'], + ['#F5CBFF', '#C346C2'], + ['#FFF720', '#3CD500'], + ['#EE9AE5', '#5961F9'], + ['#FFC371', '#FF5F6D'], + ['#FFD3A5', '#FD6585'], + ['#C2FFD8', '#465EFB'], + ['#FFC600', '#FD6E6A'], + ['#FFC600', '#FD6E6A'], + ['#92FE9D', '#00C9FF'], + ['#FFDDE1', '#EE9CA7'], + ['#F0FF00', '#58CFFB'], + ['#FFE985', '#FA742B'], + ['#72EDF2', '#5151E5'], + ['#F6D242', '#FF52E5'], + ['#F9D423', '#FF4E50'], + ['#3C8CE7', '#00EAFF'], + ['#FCFF00', '#FFA8A8'], + ['#FF96F9', '#C32BAC'], + ['#D0E6A5', '#FFDD94'], + ['#FFDD94', '#FA897B'], + ['#FFCC4B', '#FF7D58'], + ['#D0E6A5', '#86E3CE'], + ['#F0D5B6', '#F16238'], + ['#F8EC70', '#F9C708'], + ['#C4E86B', '#00BCB4'], + ['#F5CEC7', '#E79796'], + ['#FFC446', '#FA0874'], + ['#E1EE32', '#FFB547'], + ['#FFD804', '#2ACCC8'], + ['#E9A6D2', '#E9037B'], + ['#F8EC70', '#49E2F6'], + ['#A2F8CD', '#A2F852'], + ['#49E2F6', '#A2F8CD'], + ['#FDEFE2', '#FE214F'], + ['#F8EC70', '#A2F8CD'], + ['#F8EC70', '#49E2F6'], + ['#D1FFB7', '#FFB7D1'], + ['#B7FFE4', '#E4B7FF'], + ['#FFB7D1', '#E4B7FF'], + ['#D0E6A5', '#86E3CE'], + ['#E8E965', '#64C5C7'], + ]; + let chartColors = colorArr[Math.floor(Math.random() * colorArr.length)]; + //chartColors = ['#DB36A4', '#F7FF00']; // 固定京豆图表填充颜色 + return chartColors; + } + + colorfulBar() { + let colorArr = [ + ['#1B9E77', '#D95F02', '#7570B3', '#E7298A', '#66A61E', '#E6AB02'], + ['#D53E4F', '#FC8D59', '#FEE08B', '#E6F598', '#99D594', '#3288BD'], + ['#A6CEE3', '#1F78B4', '#B2DF8A', '#33A02C', '#FB9A99', '#E31A1C'], + ['#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#FFFF33'], + ['#F81B02', '#FC7715', '#AFBF41', '#50C49F', '#3B95C4', '#B560D4'], + ['#FFC000', '#A5D028', '#08CC78', '#F24099', '#5AA6C0', '#F56617'], + ['#F09415', '#C1B56B', '#4BAF73', '#5AA6C0', '#D17DF9', '#FA7E5C'], + ['#0F6FC6', '#009DD9', '#0BD0D9', '#10CF9B', '#7CCA62', '#A5C249'], + ['#2C7C9F', '#244A58', '#E2751D', '#FFB400', '#7EB606', '#C00000'], + ['#AC3EC1', '#477BD1', '#46B298', '#90BA4C', '#DD9D31', '#E25247'], + ['#9ACD4C', '#FAA93A', '#D35940', '#B258D3', '#63A0CC', '#8AC4A7'], + ['#A7EA52', '#EFAB16', '#78AC35', '#35ACA2', '#4083CF', '#FF8021'], + ['#2DA2BF', '#DA1F28', '#EB641B', '#39639D', '#474B78', '#7D3C4A'], + ['#9EC544', '#50BEA3', '#4A9CCC', '#9A66CA', '#C54F71', '#DE9C3C'], + ['#41AEBD', '#97E9D5', '#A2CF49', '#608F3D', '#F4DE3A', '#FCB11C'], + ['#2FA3EE', '#4BCAAD', '#86C157', '#D99C3F', '#CE6633', '#A35DD1'], + ['#3399FF', '#69FFFF', '#CCFF33', '#3333FF', '#9933FF', '#FF33FF'], + ['#FBC01E', '#EFE1A2', '#FA8716', '#BE0204', '#A5D848', '#7E13E3'], + ['#90C226', '#54A021', '#E6B91E', '#E76618', '#C42F1A', '#918655'], + ['#0F6FC6', '#009DD9', '#0BD0D9', '#10CF9B', '#7CCA62', '#A5C249'], + ['#FFB91D', '#F97817', '#6DE304', '#FF0000', '#732BEA', '#C913AD'], + ['#C70F0C', '#DD6B0D', '#FAA700', '#93E50D', '#17C7BA', '#0A96E4'], + ['#40BAD2', '#FAB900', '#90BB23', '#EE7008', '#1AB39F', '#D5393D'], + ['#B71E42', '#DE478E', '#BC72F0', '#795FAF', '#586EA6', '#6892A0'], + ['#80B606', '#E29F1D', '#2397E2', '#35ACA2', '#5430BB', '#8D34E0'], + ['#549E39', '#8AB833', '#C0CF3A', '#029676', '#4AB5C4', '#0989B1'], + ['#99CB38', '#63A537', '#37A76F', '#44C1A3', '#4EB3CF', '#51C3F9'], + ['#8C73D0', '#C2E8C4', '#C5A6E8', '#B45EC7', '#9FDAFB', '#95C5B0'], + ['#749805', '#BACC82', '#6E9EC2', '#2046A5', '#5039C6', '#7411D0'], + ['#1CADE4', '#2683C6', '#27CED7', '#42BA97', '#3E8853', '#62A39F'], + ['#B01513', '#EA6312', '#E6B729', '#6AAC90', '#5F9C9D', '#9E5E9B'], + ['#B31166', '#E33D6F', '#E45F3C', '#E9943A', '#9B6BF2', '#D53DD0'], + ['#76C5EF', '#FEA022', '#FF6700', '#70A525', '#A5D848', '#20768C'], + ['#A1D68B', '#5EC795', '#4DADCF', '#CDB756', '#E29C36', '#8EC0C1'], + ['#418AB3', '#A6B727', '#F69200', '#80C34F', '#FEC306', '#DF5327'], + ['#7FD13B', '#EA157A', '#FEB80A', '#00ADDC', '#738AC8', '#1AB39F'], + ['#F0AD00', '#60B5CC', '#E66C7D', '#6BB76D', '#E88651', '#C64847'], + ['#5B9BD5', '#ED7D31', '#A5D848', '#FFC000', '#4472C4', '#70AD47'], + ['#4F81BD', '#C0504D', '#9BBB59', '#8064A2', '#4BACC6', '#F79646'], + ['#B83D68', '#AC66BB', '#DE6C36', '#F9B639', '#CF6DA4', '#FA8D3D'], + ['#F2D908', '#9DE61E', '#0D8BE6', '#C61B1B', '#E26F08', '#8D35D1'], + ['#A5B592', '#F3A447', '#E7BC29', '#D092A7', '#9C85C0', '#809EC2'], + ['#30ACEC', '#80C34F', '#E29D3E', '#D64A3B', '#D64787', '#A666E1'], + ['#A2C816', '#E07602', '#E4C402', '#7DC1EF', '#21449B', '#A2B170'], + ['#FF7F01', '#F1B015', '#FBEC85', '#D2C2F1', '#DA5AF4', '#9D09D1'], + ['#FDA023', '#A7EA52', '#5ECCF3', '#64A73B', '#EB5605', '#B9CA1A'], + ['#00C6BB', '#6FEBA0', '#B6DF5E', '#EFB251', '#EF755F', '#ED515C'], + ['#E84C22', '#FFBD47', '#B64926', '#FF8427', '#CC9900', '#B22600'], + ['#E32D91', '#C830CC', '#4EA6DC', '#4775E7', '#8971E1', '#D54773'], + ['#1CADE4', '#2683C6', '#27CED7', '#42BA97', '#3E8853', '#62A39F'], + ['#A63212', '#E68230', '#9BB05E', '#6B9BC7', '#4E66B2', '#8976AC'], + ['#073779', '#8FD9FB', '#FFCC00', '#EB6615', '#C76402', '#B523B4'], + ['#4E67C8', '#5ECCF3', '#A7EA52', '#5DCEAF', '#FF8021', '#F14124'], + ['#3891A7', '#FEB80A', '#C32D2E', '#84AA33', '#964305', '#475A8D'], + ['#990000', '#FF6600', '#FFBA00', '#99CC00', '#528A02', '#9C007F'], + ['#F7901E', '#FEC60B', '#9FE62F', '#4EA5D1', '#1C4596', '#542D90'], + ['#51A6C2', '#51C2A9', '#7EC251', '#E1DC53', '#B54721', '#A16BB1'], + ['#E8BC4A', '#83C1C6', '#E78D35', '#909CE1', '#839C41', '#CC5439'], + ['#86CE24', '#00A2E6', '#FAC810', '#7D8F8C', '#D06B20', '#FF8021'], + ['#DF2E28', '#FE801A', '#E9BF35', '#81BB42', '#32C7A9', '#4A9BDC'], + ['#92278F', '#9B57D3', '#755DD9', '#665EB8', '#45A5ED', '#5982DB'], + ['#31B6FD', '#4584D3', '#5BD078', '#A5D028', '#F5C040', '#05E0DB'], + ['#A53010', '#DE7E18', '#9F8351', '#728653', '#92AA4C', '#6AAC91'], + ['#FFCA08', '#F8931D', '#CE8D3E', '#EC7016', '#E64823', '#9C6A6A'], + ['#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F', '#EDC948'], + ['#4E79A7', '#A0CBE8', '#F28E2B', '#FFBE7D', '#59A14F', '#8CD17D'], + ['#E03531', '#F0BD27', '#51B364', '#FF684C', '#FFDA66', '#8ACE7E'], + ['#4E9F50', '#87D180', '#EF8A0C', '#FCC66D', '#3CA8BC', '#98D9E4'], + ['#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', '#9467BD', '#E377C2'], + ['#32A251', '#ACD98D', '#FF7F0F', '#FFB977', '#3CB7CC', '#98D9E4'], + ['#2C69B0', '#F02720', '#AC613C', '#6BA3D6', '#EA6B73', '#E9C39B'], + ]; + let chartColors = colorArr[Math.floor(Math.random() * colorArr.length)]; + //chartColors = ['#1B9E77', '#D95F02', '#7570B3', '#E7298A', '#66A61E', '#E6AB02']; // 固定京豆图表填充颜色 + return chartColors; + } + + isSmall(a = false) { + if (a) return config.widgetFamily == 'small' ? true : false; + else return config.widgetFamily == 'small' ? '_small' : ''; + } + + // #####################小组件################### + renderSmall = async (w) => { + const bodyStack = w.addStack(); + bodyStack.layoutVertically(); + if (this.basicSetting.smallShowType === '个人信息') { + await this.setUserShow(bodyStack); + } else { + await this.setHeaderShow(bodyStack); + bodyStack.addSpacer(); + switch (this.chartSetting.smallShowType) { + case '折线图表': + await this.setChartShow(bodyStack, 1); + break; + case '柱状图表': + await this.setChartShow(bodyStack, 2); + break; + case '曲线面积图': + await this.setChartShow(bodyStack, 3); + break; + default: + await this.setBeanShow( + bodyStack, + 22 * this.basicSetting.scale, + 40 * this.basicSetting.scale, + ); + } + bodyStack.addSpacer(5 * this.basicSetting.scale); + if (this.expireBean.number > 0) { + await this.setExpireBeanShow(bodyStack, true); + } else if ( + this.funcSetting.showBaitiao === '打开' && + this.baitiao.number > 0 + ) { + await this.setBaitiaoShow(bodyStack, true); + } else if (this.basicSetting.walletShowType === '红包') { + await this.setRedPackageShow(bodyStack, true); + } else { + await this.setCoinShow(bodyStack, true); + } + } + return w; + }; + + // #####################中组件################### + renderMedium = async (w) => { + const bodyStack = w.addStack(); + await this.setUserShow(bodyStack); + bodyStack.addSpacer(this.basicSetting.division * this.basicSetting.scale); + const mainStack = bodyStack.addStack(); + mainStack.layoutVertically(); + await this.setHeaderShow(mainStack, this.JDImg); + mainStack.addSpacer(); + if (this.funcSetting.showPackage === '打开' && this.package.number > 0) { + await this.setPackageShow(mainStack); + mainStack.addSpacer(); + } else { + switch (this.chartSetting.showType) { + case '折线图表': + await this.setChartShow(mainStack, 1); + mainStack.addSpacer(5 * this.basicSetting.scale); + break; + case '柱状图表': + await this.setChartShow(mainStack, 2); + mainStack.addSpacer(5 * this.basicSetting.scale); + break; + case '曲线面积图': + await this.setChartShow(mainStack, 3); + mainStack.addSpacer(5 * this.basicSetting.scale); + break; + default: + await this.setBeanShow( + mainStack, + 30 * this.basicSetting.scale, + 50 * this.basicSetting.scale, + ); + mainStack.addSpacer(); + } + } + if (this.expireBean.number > 0) { + await this.setExpireBeanShow(mainStack); + } else if ( + this.funcSetting.showBaitiao === '打开' && + this.baitiao.number > 0 + ) { + await this.setBaitiaoShow(mainStack); + } else if (this.basicSetting.walletShowType === '红包') { + await this.setRedPackageShow(mainStack); + } else { + await this.setCoinShow(mainStack); + } + return w; + }; + + // #####################大组件################### + renderLarge = async (w) => { + const bodyStack = w.addStack(); + bodyStack.size = new Size(0, 150); + bodyStack.addSpacer(); + await this.setUserShow(bodyStack); + bodyStack.addSpacer(); + w.addSpacer(20); + const text = w.addText('\u6211\u600e\u4e48\u8fd9\u4e48\u597d\u770b'); + w.addSpacer(20); + text.font = Font.thinSystemFont(30); + text.centerAlignText(); + const emoji = w.addText('🤣🥰🤪'); + emoji.centerAlignText(); + w.addSpacer(); + return w; + }; + + // #####################用户信息################### + async setUserShow(stack) { + const userStack = stack.addStack(); + userStack.size = new Size( + this.basicSetting.userStack * this.basicSetting.scale, + 0, + ); + userStack.layoutVertically(); + // 头像 + const userImgStack = userStack.addStack(); + userImgStack.addSpacer(); + const imgStack = userImgStack.addStack(); + if (this.isPlus) { + imgStack.size = new Size( + this.basicSetting.userImage * this.basicSetting.scale, + this.basicSetting.userImage * this.basicSetting.scale * 1.039, + ); + imgStack.backgroundImage = await this.getImageByUrl( + this.plusBG, + 'plusBGImage.png', + ); + } + const subStack = imgStack.addStack(); + subStack.url = 'openapp.jdmobile://'; + subStack.size = new Size( + this.basicSetting.userImage * this.basicSetting.scale, + this.basicSetting.userImage * this.basicSetting.scale, + ); + subStack.cornerRadius = + (this.basicSetting.userImage / 2) * this.basicSetting.scale; + subStack.backgroundImage = await this.getImageByUrl( + this.basicSetting.customizeAvatar || this.userImage, + `userImage_${this.userName}.png`, + ); + if (this.isPlus) { + const userImg = subStack.addImage( + await this.getImageByUrl(this.plusFG, 'plusFGImage.png'), + ); + } + userImgStack.addSpacer(); + userStack.addSpacer(); + // 物流提示 + const tipStack = userStack.addStack(); + tipStack.addSpacer(); + let signIcon = SFSymbol.named('checkmark.circle.fill'); + const signItem = tipStack.addImage(signIcon.image); + signItem.tintColor = new Color('007aff'); // 签到提示图标颜色 + signItem.imageSize = new Size( + 14 * this.basicSetting.scale, + 14 * this.basicSetting.scale, + ); + if (this.package.number > 0) { + tipStack.addSpacer(3 * this.basicSetting.scale); + const packageIcon = SFSymbol.named(this.package.number + '.circle.fill'); + const packageItem = tipStack.addImage(packageIcon.image); + packageItem.imageSize = new Size( + 14 * this.basicSetting.scale, + 14 * this.basicSetting.scale, + ); + packageItem.tintColor = new Color('FC8600'); // 物流提示图标颜色 + } + tipStack.addSpacer(); + userStack.addSpacer(); + // 用户名 + const nameStack = userStack.addStack(); + nameStack.centerAlignContent(); + if (this.isPlus) { + const nameImg = nameStack.addImage( + await this.getImageByUrl(this.plusIcon, 'plusIcon.png'), + ); + nameImg.imageSize = new Size( + 15 * this.basicSetting.scale, + 15 * this.basicSetting.scale, + ); + } else { + const person = SFSymbol.named('person.circle.fill'); + const nameIcon = nameStack.addImage(person.image); + nameIcon.imageSize = new Size( + 15 * this.basicSetting.scale, + 15 * this.basicSetting.scale, + ); + nameIcon.tintColor = new Color('007aff'); // 昵称前图标颜色,Plus用户改不了 + } + nameStack.addSpacer(5 * this.basicSetting.scale); + const name = nameStack.addText( + this.basicSetting.customizeName || this.nickName, + ); + name.lineLimit = 1; + name.font = Font.regularSystemFont(14 * this.basicSetting.scale); + userStack.addSpacer(5 * this.basicSetting.scale); + // 京享值 + const valueStack = userStack.addStack(); + valueStack.centerAlignContent(); + const tagIcon = SFSymbol.named('tag.circle.fill'); + const lableIcon = valueStack.addImage(tagIcon.image); + lableIcon.imageSize = new Size( + 15 * this.basicSetting.scale, + 15 * this.basicSetting.scale, + ); + lableIcon.tintColor = new Color('fa2d19'); // 京享值前图标颜色 + valueStack.addSpacer(5 * this.basicSetting.scale); + const value = valueStack.addText(this.jValue.toString()); + value.font = Font.mediumSystemFont(14 * this.basicSetting.scale); + + valueStack.addSpacer(5 * this.basicSetting.scale); + const jStack = valueStack.addStack(); + jStack.backgroundColor = new Color('fa2d19'); // “京享”二字背景颜色 + jStack.cornerRadius = 5; + jStack.setPadding( + 1 * this.basicSetting.scale, + 4 * this.basicSetting.scale, + 1 * this.basicSetting.scale, + 4 * this.basicSetting.scale, + ); + const jLable = jStack.addText('京享'); + jLable.font = Font.systemFont(8 * this.basicSetting.scale); + jLable.textColor = new Color('FFFFFF'); // “京享”二字字体颜色 + [name, value].map((t) => (t.textColor = this.widgetColor)); + } + + // #####################顶部内容################### + async setHeaderShow(stack, image) { + const topStack = stack.addStack(); + topStack.centerAlignContent(); + if (this.widgetFamily === 'small') { + const avatarStack = topStack.addStack(); + avatarStack.size = new Size( + this.basicSetting.logo * this.basicSetting.scale, + this.basicSetting.logo * this.basicSetting.scale, + ); + avatarStack.cornerRadius = + (avatarStack.size.width / 2) * this.basicSetting.scale; + avatarStack.backgroundImage = await this.getImageByUrl( + this.basicSetting.customizeAvatar || this.userImage, + `userImage_${this.userName}.png`, + ); + if (this.isPlus) { + avatarStack.addImage( + await this.getImageByUrl(this.plusFG, 'plusFGImage.png'), + ); + } + } else { + const JDLogo = topStack.addImage( + await this.getImageByUrl(this.logo, 'logoImage.png'), + ); + JDLogo.imageSize = new Size( + this.basicSetting.logo * this.basicSetting.scale, + this.basicSetting.logo * this.basicSetting.scale, + ); + if (image) { + topStack.addSpacer(10 * this.basicSetting.scale); + const JD = topStack.addImage( + await this.getImageByUrl(image, 'jingdongImage.png'), + ); + JD.imageSize = new Size( + 194 * 0.2 * this.basicSetting.scale, + 78 * 0.2 * this.basicSetting.scale, + ); + } + } + topStack.addSpacer(); + const jdBean = topStack.addText(this.beanCount.toString()); + jdBean.font = Font.mediumSystemFont(20 * this.basicSetting.scale); + jdBean.textColor = new Color('fa2d19'); // 右上角京豆数颜色 + jdBean.url = + 'openapp.jdmobile://virtual?params=%7B%22category%22%3A%22jump%22%2C%22des%22%3A%22m%22%2C%22url%22%3A%22https%3A%2F%2Fbean.m.jd.com%2FbeanDetail%2Findex.action%3FresourceValue%3Dbean%22%7D'; + const desStack = topStack.addStack(); + desStack.layoutVertically(); + desStack.addSpacer(5.5 * this.basicSetting.scale); + const desText = desStack.addText(' 京豆'); + desText.font = Font.mediumSystemFont(10 * this.basicSetting.scale); + desText.textColor = new Color('fa2d19', 0.7); + } + + // #####################京豆收支################### + async setBeanShow(stack, textSize, imageSize) { + const beanStack = stack.addStack(); + // 今日收支 + const yestodayStack = beanStack.addStack(); + yestodayStack.layoutVertically(); + try { + this.bean.ydayIncome = + this.rangeTimer[this.yestoday][0] - this.rangeTimer[this.yestoday][1]; + this.bean.ydayExpense = this.rangeTimer[this.yestoday][1]; + this.bean.todayIncome = + this.rangeTimer[this.today][0] - this.rangeTimer[this.today][1]; + this.bean.todayExpense = this.rangeTimer[this.today][1]; + } catch (e) { + this.notify( + this.name, + '\u597d\u50cf\u4f60\u6628\u5929\u6ca1\u6709\u4f7f\u7528\u8be5\u5c0f\u7ec4\u4ef6\uff0c\u8bf7\u91cd\u7f6e\u4eac\u8c46\u6570\u636e', + ); + } + this.rowBeanCell( + yestodayStack, + this.bean.ydayExpense.toString(), + this.bean.ydayIncome.toString(), + textSize, + '昨日', + ); + beanStack.addSpacer(); + // 京豆图片 + const ddStack = beanStack.addStack(); + ddStack.layoutVertically(); + const ddImg = ddStack.addImage( + await this.getImageByUrl(this.beanImg, 'beanImage.png'), + ); + ddImg.imageSize = new Size(imageSize, imageSize); + beanStack.addSpacer(); + // 昨日收支 + const todayStack = beanStack.addStack(); + todayStack.layoutVertically(); + this.rowBeanCell( + todayStack, + this.bean.todayExpense.toString(), + this.bean.todayIncome.toString(), + textSize, + '今日', + ); + } + + // #####################京豆图表################### + async setChartShow(stack, type) { + let labels = [], + data = []; + Object.keys(this.rangeTimer).forEach((day) => { + const value = this.rangeTimer[day]; + const arrDay = day.split('-'); + labels.push(arrDay[2]); + if (this.chartSetting.countBean === '收入-支出') data.push(value[0]); + else data.push(value[0] - value[1]); + }); + let cacheKey = `chart${type}Image${this.isSmall()}_${this.userName}.png`; + let textSize = this.chartSetting.textSize; + let linePadding = this.chartSetting.linePadding; + let barPadding = this.chartSetting.barPadding; + if (config.widgetFamily === 'small') { + data.splice(0, 2); + labels.splice(0, 2); + textSize = this.chartSetting.textSize + 7; + linePadding = this.chartSetting.linePadding + 10; + barPadding = this.chartSetting.barPadding + 5; + } + let chartStr; + switch (type) { + case 2: + chartStr = this.barChart(labels, data, textSize, barPadding, 'bar'); + break; + case 3: + chartStr = this.barChart(labels, data, textSize, barPadding, 'line'); + break; + default: + chartStr = this.lineChart(labels, data, textSize, linePadding); + } + const url = `https://quickchart.io/chart?w=${400}&h=${ + this.chartSetting.height + }&f=png&c=${encodeURIComponent(chartStr)}`; + const chart = await this.getImageByUrl(url, cacheKey, this.cacheChart); + + const chartStack = stack.addStack(); + const chartImage = chartStack.addImage(chart); + const beanDateStack = stack.addStack(); + let showDays = data.length; + for (let i = 0; i < showDays; i++) { + beanDateStack.addSpacer(); + let subStack = beanDateStack.addStack(); + let beanDay = beanDateStack.addText( + `${labels[i]}${this.chartSetting.dayText}`, + ); + beanDay.textColor = this.widgetColor; + beanDay.font = new Font( + 'ArialMT', + this.chartSetting.daySize * this.basicSetting.scale, + ); + beanDay.textOpacity = 0.8; + beanDateStack.addSpacer(); + } + } + + // #####################物流信息################### + setPackageShow(stack) { + const packageStack = stack.addStack(); + const detailStack = packageStack.addStack(); + detailStack.layoutVertically(); + const titleStack = detailStack.addStack(); + titleStack.centerAlignContent(); + const title = titleStack.addText(this.package.title); + title.lineLimit = 1; + title.font = Font.mediumSystemFont(12 * this.basicSetting.scale); + detailStack.addSpacer(2 * this.basicSetting.scale); + const desc = detailStack.addText(this.package.desc); + desc.lineLimit = 3; + desc.font = Font.regularSystemFont(12 * this.basicSetting.scale); + detailStack.addSpacer(2 * this.basicSetting.scale); + const statusStack = detailStack.addStack(); + const time = statusStack.addText(this.package.time); + statusStack.addSpacer(); + const status = statusStack.addText(this.package.status); + [title, desc, time, status].map((t) => (t.textColor = this.widgetColor)); + [time, status].map( + (t) => (t.font = Font.regularSystemFont(9 * this.basicSetting.scale)), + ); + [time, status].map((t) => (t.textOpacity = 0.7)); + } + + // #####################金贴&钢镚################## + async setCoinShow(stack, vertical = false) { + await this.getExtraData(); + const extraDataStack = stack.addStack(); + const jtImage = await this.getImageByUrl(this.jingtieImg, 'jtImage.png'); + const gbImage = await this.getImageByUrl(this.gangbengImg, 'gbImage.png'); + const dataStack = extraDataStack.addStack(); + if (vertical) dataStack.layoutVertically(); + this.rowCell(dataStack, jtImage, this.extra.jingtie.toString(), '金贴'); + if (vertical) extraDataStack.addSpacer(5 * this.basicSetting.scale); + if (!vertical) dataStack.addSpacer(20 * this.basicSetting.scale); + this.rowCell(dataStack, gbImage, this.extra.gangbeng.toString(), '钢镚'); + } + + // #####################京东红包################## + async setRedPackageShow(stack, small = false) { + await this.getRedPackageData(); + const walletImage = await this.getImageByUrl( + this.walletImg, + 'walletImage.png', + ); + small + ? this.rowSmallWalletCell(stack, walletImage, this.redPackage) + : this.rowWalletCell(stack, walletImage, this.redPackage); + } + + // #####################京东白条################## + async setBaitiaoShow(stack, small = false) { + const baitiaoImage = await this.getImageByUrl( + this.baitiaoImg, + 'baitiaoImage.png', + ); + small + ? this.rowSmallWalletCell(stack, baitiaoImage, this.baitiao) + : this.rowWalletCell(stack, baitiaoImage, this.baitiao); + } + + // #####################过期京豆################## + async setExpireBeanShow(stack, small = false) { + const walletImage = await this.getImageByUrl( + this.walletImg, + 'walletImage.png', + ); + small + ? this.rowSmallWalletCell(stack, walletImage, this.expireBean) + : this.rowWalletCell(stack, walletImage, this.expireBean); + } + + rowCell(stack, image, value, title) { + const rowStack = stack.addStack(); + rowStack.centerAlignContent(); + const rowImage = rowStack.addImage(image); + rowImage.imageSize = new Size( + 13 * this.basicSetting.scale, + 13 * this.basicSetting.scale, + ); + rowStack.addSpacer(); + const rowValue = rowStack.addText(value); + rowValue.font = Font.mediumSystemFont(15 * this.basicSetting.scale); + rowStack.addSpacer(); + const rowTitle = rowStack.addText(title); + rowTitle.font = Font.regularSystemFont(13 * this.basicSetting.scale); + [rowValue, rowTitle].map((t) => (t.textColor = this.widgetColor)); + } + + rowBeanCell(stack, min, add, textSize, label) { + const rowOne = stack.addStack(); + const labelText = rowOne.addText(label); + labelText.font = Font.regularSystemFont(10 * this.basicSetting.scale); + labelText.textOpacity = 0.7; + const rowTwo = stack.addStack(); + const rowNumber = rowTwo.addText(add); + rowNumber.font = Font.lightSystemFont(textSize); + if (min < 0) { + const rowThree = stack.addStack(); + const minText = rowThree.addText(min); + minText.font = Font.mediumSystemFont(10 * this.basicSetting.scale); + minText.textColor = new Color('fa2d19'); // 支出京豆颜色 + } + [labelText, rowNumber].map((t) => (t.textColor = this.widgetColor)); + } + + rowWalletCell(stack, image, data) { + const stackOne = stack.addStack(); + stackOne.centerAlignContent(); + const stackImage = stackOne.addImage(image); + stackImage.imageSize = new Size( + 127 * 0.17 * this.basicSetting.scale, + 75 * 0.17 * this.basicSetting.scale, + ); + stackOne.addSpacer(5 * this.basicSetting.scale); + const title = stackOne.addText(data.title); + title.font = Font.regularSystemFont(13 * this.basicSetting.scale); + stackOne.addSpacer(); + const number = stackOne.addText(`${data.number}`); + number.font = Font.mediumSystemFont(15 * this.basicSetting.scale); + stackOne.addSpacer(); + const desc = stackOne.addText(data.desc); + desc.font = Font.regularSystemFont(10 * this.basicSetting.scale); + desc.textOpacity = 0.7; + [title, number, desc].map((t) => (t.textColor = this.widgetColor)); + } + + rowSmallWalletCell(stack, image, data) { + const stackOne = stack.addStack(); + stackOne.centerAlignContent(); + const stackImage = stackOne.addImage(image); + stackImage.imageSize = new Size( + 127 * 0.17 * this.basicSetting.scale, + 75 * 0.17 * this.basicSetting.scale, + ); + stackOne.addSpacer(); + const number = stackOne.addText(`${data.number}`); + number.font = Font.mediumSystemFont(15 * this.basicSetting.scale); + stack.addSpacer(5 * this.basicSetting.scale); + const stackTwo = stack.addStack(); + stackTwo.centerAlignContent(); + const title = stackTwo.addText(data.title); + title.font = Font.regularSystemFont(13 * this.basicSetting.scale); + stackTwo.addSpacer(); + const desc = stackTwo.addText(data.desc); + desc.font = Font.regularSystemFont(10 * this.basicSetting.scale); + desc.textOpacity = 0.7; + [number, title, desc].map((t) => (t.textColor = this.widgetColor)); + } + + init = async () => { + try { + let beanCacheKey = `beanData${this.isSmall()}_${this.userName}`; + let beanCacheData = !this.loadStringCache(beanCacheKey) + ? {} + : JSON.parse(this.loadStringCache(beanCacheKey)); + let beanCache = beanCacheData.data + ? beanCacheData.data.assetInfo.beanNum + : 0; + await this.TotalBean(); + await this.getJValue(); + console.log(`京豆数据:${beanCache}`); + console.log(`京豆数据:${this.beanCount}`); + + if (!this.cookie) return; + if (Keychain.contains(this.CACHE_KEY)) { + this.rangeTimer = JSON.parse(Keychain.get(this.CACHE_KEY)); + if ( + this.rangeTimer.hasOwnProperty(this.today) && + beanCache !== 0 && + beanCache == this.beanCount + ) { + this.cacheChart = + this.funcSetting.alwaysRefreshChart === '打开' ? false : true; + console.log('京豆数据:无变化,使用缓存数据'); + return; + } + + this.rangeTimer[this.today] = [0, 0]; + const timerKeys = Object.keys(this.rangeTimer); + if (timerKeys.length > this.maxDays) { + for (let i = 0; i < timerKeys.length - this.maxDays; i++) { + delete this.rangeTimer[timerKeys[i]]; + } + Keychain.set(this.CACHE_KEY, JSON.stringify(this.rangeTimer)); + } + + this.timerKeys = [this.today]; + } else { + this.rangeTimer = this.getDay(5); + this.timerKeys = Object.keys(this.rangeTimer); + } + await this.getAmountData(); + } catch (e) { + console.log(e); + } + }; + + getAmountData = async () => { + let i = 0, + page = 1; + do { + const response = await this.getJingBeanBalanceDetail(page); + const result = response.code === '0'; + console.log(`第${page}页:${result ? '请求成功' : '请求失败'}`); + if (response.code === '3') { + i = 1; + this.notify(this.name, response.message); + console.log(response); + } + if (response && result) { + page++; + let detailList = response.jingDetailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const dates = item.date.split(' '); + if (this.timerKeys.indexOf(dates[0]) > -1) { + const amount = Number(item.amount); + this.rangeTimer[dates[0]][0] += amount; + if (amount < 0) this.rangeTimer[dates[0]][1] += amount; + } else { + i = 1; + Keychain.set(this.CACHE_KEY, JSON.stringify(this.rangeTimer)); + break; + } + } + } + } + } while (i === 0); + }; + + getDay(dayNumber) { + let data = {}; + let i = dayNumber; + do { + const today = new Date(); + const year = today.getFullYear(); + const targetday_milliseconds = today.getTime() - 1000 * 60 * 60 * 24 * i; + today.setTime(targetday_milliseconds); + let month = today.getMonth() + 1; + month = month >= 10 ? month : `0${month}`; + let day = today.getDate(); + day = day >= 10 ? day : `0${day}`; + data[`${year}-${month}-${day}`] = [0, 0]; + i--; + } while (i >= 0); + return data; + } + + TotalBean = async () => { + const dataName = '京豆数据'; + let userCache = `beanData${this.isSmall()}`; + const url = 'https://me-api.jd.com/user_new/info/GetJDUserInfoUnion'; + const options = { + headers: { + cookie: this.cookie, + }, + }; + const response = await this.httpRequest( + dataName, + url, + true, + options, + userCache, + ); + try { + if (response.retcode === '0' && response['data']) { + this.beanCount = response.data.assetInfo.beanNum; + this.userImage = + response.data.userInfo.baseInfo.headImageUrl.replace(/big/, 'mid') || + 'https://img11.360buyimg.com/jdphoto/s120x120_jfs/t21160/90/706848746/2813/d1060df5/5b163ef9N4a3d7aa6.png'; + this.nickName = response.data.userInfo.baseInfo.nickname; + this.isPlus = response.data.userInfo.isPlusVip === '1' ? true : false; + } else { + this.notify(this.name, response.msg); + console.log('京豆数据:获取失败,' + response.msg); + } + } catch (e) { + console.log(e); + } + }; + + getJingBeanBalanceDetail = async (page) => { + try { + const options = { + url: `https://bean.m.jd.com/beanDetail/detail.json`, + body: `page=${page}`, + headers: { + 'X-Requested-With': `XMLHttpRequest`, + Connection: `keep-alive`, + 'Accept-Encoding': `gzip, deflate, br`, + 'Content-Type': `application/x-www-form-urlencoded; charset=UTF-8`, + Origin: `https://bean.m.jd.com`, + 'User-Agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15`, + Cookie: this.cookie, + Host: `bean.m.jd.com`, + Referer: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean`, + 'Accept-Language': `zh-cn`, + Accept: `application/json, text/javascript, */*; q=0.01`, + }, + }; + let params = { ...options, method: 'POST' }; + let request = new Request(params.url); + Object.keys(params).forEach((key) => { + request[key] = params[key]; + }); + return await request.loadJSON(); + } catch (e) { + console.log(e); + } + }; + + getExtraData = async () => { + const JTDataName = '金贴数据'; + const JTUrl = 'https://ms.jr.jd.com/gw/generic/uc/h5/m/mySubsidyBalance'; + const GBDataName = '钢镚数据'; + const GBUrl = 'https://coin.jd.com/m/gb/getBaseInfo.html'; + const options = { + headers: { + cookie: this.cookie, + Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', + }, + }; + try { + const JTData = await this.httpRequest( + JTDataName, + JTUrl, + true, + options, + 'jintieData', + ); + const GBData = await this.httpRequest( + GBDataName, + GBUrl, + true, + options, + 'gangbengData', + ); + if (JTData.resultCode === 0) { + this.extra.jingtie = JTData.resultData.data['balance']; + } else { + this.notify(this.name, JTdata.resultMsg); + console.log('金贴数据:获取失败,' + JTdata.resultMsg); + } + if (GBData.gbBalance) this.extra.gangbeng = GBData.gbBalance; + } catch (e) { + console.log(e); + } + }; + + getPackageData = async () => { + const dataName = '包裹数据'; + const url = + 'https://wq.jd.com/bases/wuliudetail/notify?sceneval=2&sceneval=2&g_login_type=1&callback'; + const options = { + headers: { + cookie: this.cookie, + Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', + }, + }; + try { + const data = await this.httpRequest( + dataName, + url, + true, + options, + 'packageData', + ); + if (data.errCode == 0 && data['dealLogList']) { + console.log('包裹数据:获取成功'); + console.log(`包裹数据:您有${data['dealLogList'].length}个包裹`); + if (data['dealLogList'].length > 0) { + let item = + data.dealLogList[ + Math.floor(Math.random() * data['dealLogList'].length) + ]; + this.package.number = data.dealLogList.length; + this.package.title = item['name']; + this.package.desc = item['wlStateDesc']; + this.package.time = item['createTime']; + this.package.status = item['stateName']; + } + } else { + console.log('包裹数据:获取失败'); + } + } catch (e) { + console.log(e); + } + }; + + getRedPackageData = async () => { + const dataName = '红包数据'; + const url = + 'https://wq.jd.com/user/info/QueryUserRedEnvelopes?channel=1&type=0&page=0&pageSize=0&expiredRedFlag=1&sceneval=2&g_login_type=1'; + const options = { + headers: { + cookie: this.cookie, + Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', + }, + }; + try { + const data = await this.httpRequest( + dataName, + url, + true, + options, + 'redPackageData', + ); + if (data.errcode === 0) { + this.redPackage.number = data.data.balance ? data.data.balance : 0; + if (data.data.expiredBalance && data.data.expiredBalance !== '') + this.redPackage.desc = `今日过期${data.data.expiredBalance}`; + } else { + this.notify(this.name, data.msg); + console.log('红包数据:获取失败,' + data.msg); + } + } catch (e) { + console.log(e); + } + }; + + getExipireBean = async () => { + const dataName = '过期京豆'; + const url = + 'https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=g_login_type=1&sceneval=2'; + const options = { + headers: { + cookie: this.cookie, + Referer: 'https://wqs.jd.com/promote/201801/bean/mybean.html', + }, + }; + try { + let data = await this.httpRequest( + dataName, + url, + false, + options, + 'exipireBeanData', + ); + if (data) { + data = JSON.parse(data.slice(23, -13)); + if (data.ret === 0) { + for (let i = 0; i < data['expirejingdou'].length; i++) { + if (data['expirejingdou'][i]['expireamount'] > 0) { + this.expireBean.number = data['expirejingdou'][i]['expireamount']; + this.expireBean.desc = this.timeFormat( + data['expirejingdou'][i]['time'] * 1000, + ); + break; + } + } + } else { + this.notify(this.name, data.errmsg); + console.log('过期京豆:获取失败,' + data.errmsg); + } + } + } catch (e) { + console.log(e); + } + }; + + getJValue = async () => { + const dataName = '京享数据'; + const url = 'https://vip.m.jd.com/scoreDetail/current'; + const options = { + headers: { + cookie: this.cookie, + }, + }; + try { + const data = await this.httpRequest( + dataName, + url, + true, + options, + 'JValue', + ); + if (data.code === 0) { + this.jValue = data.model.scoreDescription.userScore.score; + } else { + console.log('京享数据:获取失败'); + } + } catch (e) { + console.log(e); + } + }; + + getBaitiaoData = async () => { + const dataName = '白条数据'; + const url = 'https://ms.jr.jd.com/gw/generic/bt/h5/m/firstScreenNew'; + const options = { + body: 'reqData={"clientType":"ios","clientVersion":"13.2.3","deviceId":"","environment":"3"}', + headers: { + cookie: this.cookie, + }, + }; + try { + const data = await this.httpRequest( + dataName, + url, + true, + options, + 'baitiaoData', + 'POST', + false, + ); + if (data.resultCode !== 0) { + return this.notify(this.name, data['resultMsg']); + } + this.baitiao.title = data['resultData']['data']['bill']['title']; + this.baitiao.number = data['resultData']['data']['bill'][ + 'amount' + ].replace(/,/g, ''); + this.baitiao.desc = data['resultData']['data']['bill'][ + 'buttonName' + ].replace(/最近还款日/, ''); + } catch (e) { + console.log(e); + } + }; + + getImageByUrl = async (url, cacheKey, useCache = true, logable = true) => { + if (this.CACHES.indexOf(cacheKey) < 0) { + this.CACHES.push(cacheKey); + this.settings.CACHES = this.CACHES; + this.saveSettings(false); + } + if (useCache) { + const cacheImg = this.loadImgCache(cacheKey); + if (cacheImg != undefined && cacheImg != null) { + if (logable) console.log(`使用缓存:${cacheKey}`); + return this.loadImgCache(cacheKey); + } + } + + try { + if (logable) console.log(`在线请求:${cacheKey}`); + const req = new Request(url); + const imgData = await req.load(); + const img = Image.fromData(imgData); + this.saveImgCache(cacheKey, img); + return img; + } catch (e) { + console.error(`图片加载失败:${e}`); + let cacheImg = this.loadImgCache(cacheKey); + if (cacheImg != undefined) { + console.log(`使用缓存图片:${cacheKey}`); + return cacheImg; + } + console.log(`使用预设图片`); + let ctx = new DrawContext(); + ctx.size = new Size(80, 80); + ctx.setFillColor(Color.darkGray()); + ctx.fillRect(new Rect(0, 0, 80, 80)); + return await ctx.getImage(); + } + }; + + saveImgCache(cacheKey, img) { + if (!this.fm.fileExists(this.cachePath)) { + this.fm.createDirectory(this.cachePath, true); + } + const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); + this.fm.writeImage(cacheFile, img); + } + + loadImgCache(cacheKey) { + const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); + const fileExists = this.fm.fileExists(cacheFile); + let img = undefined; + if (fileExists) { + img = Image.fromFile(cacheFile); + } + return img; + } + + httpRequest = async ( + dataName, + url, + json = true, + options, + key, + method = 'GET', + logable = this.funcSetting.logable === '打开', + ) => { + let cacheKey = `${key}_${this.userName}`; + if (this.CACHES.indexOf(cacheKey) < 0) { + this.CACHES.push(cacheKey); + this.settings.CACHES = this.CACHES; + this.saveSettings(false); + } + const localCache = this.loadStringCache(cacheKey); + const lastCacheTime = this.getCacheModificationDate(cacheKey); + const timeInterval = Math.floor( + (this.getCurrentTimeStamp() - lastCacheTime) / 60, + ); + console.log( + `${dataName}:缓存${timeInterval}分钟前,有效期${this.basicSetting.interval}分钟,${localCache.length}`, + ); + if ( + timeInterval < this.basicSetting.interval && + localCache != null && + localCache.length > 0 + ) { + console.log(`${dataName}:读取缓存`); + return json ? JSON.parse(localCache) : localCache; + } + let data = null; + try { + console.log(`${dataName}:在线请求`); + let req = new Request(url); + req.method = method; + Object.keys(options).forEach((key) => { + req[key] = options[key]; + }); + data = await (json ? req.loadJSON() : req.loadString()); + } catch (e) { + console.error(`${dataName}:请求失败:${e}`); + } + if (!data && localCache != null && localCache.length > 0) { + console.log(`${dataName}:获取失败,读取缓存`); + return json ? JSON.parse(localCache) : localCache; + } + this.saveStringCache(cacheKey, json ? JSON.stringify(data) : data); + if (logable) { + console.log(`${dataName}:在线请求响应数据:${JSON.stringify(data)}`); + } + return data; + }; + + loadStringCache(cacheKey) { + const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); + const fileExists = this.fm.fileExists(cacheFile); + let cacheString = ''; + if (fileExists) { + cacheString = this.fm.readString(cacheFile); + } + return cacheString; + } + + saveStringCache(cacheKey, content) { + if (!this.fm.fileExists(this.cachePath)) { + this.fm.createDirectory(this.cachePath, true); + } + const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); + this.fm.writeString(cacheFile, content); + } + + getCacheModificationDate(cacheKey) { + const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); + const fileExists = this.fm.fileExists(cacheFile); + if (fileExists) { + return this.fm.modificationDate(cacheFile).getTime() / 1000; + } else { + return 0; + } + } + + getCurrentTimeStamp() { + return new Date().getTime() / 1000; + } + + removeCache(cacheKey) { + const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); + const fileExists = this.fm.fileExists(cacheFile); + if (fileExists) { + this.fm.remove(cacheFile); + console.log(`清除缓存:${cacheKey}`); + } + return; + } + + removeCaches(cacheKeyList) { + for (const cacheKey of cacheKeyList) { + this.removeCache(cacheKey); + } + } + + timeFormat(time) { + let date; + if (time) { + date = new Date(time); + } else { + date = new Date(); + } + return ( + (date.getMonth() + 1 >= 10 + ? date.getMonth() + 1 + : '0' + (date.getMonth() + 1)) + + '月' + + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) + + '日' + ); + } + + async updateCheck(version) { + let data; + try { + let updateCheck = new Request( + 'https://raw.githubusercontent.com/anker1209/Scriptable/main/upcoming.json', + ); + data = await updateCheck.loadJSON(); + if (data.version != version) { + let updata = new Alert(); + updata.title = `有新版 ${data.version} 可用`; + updata.addAction('去Github更新'); + updata.addAction('网页版商店更新'); + updata.addCancelAction('稍后'); + updata.message = + '\n更新说明:\n' + data.notes + '\n\n点击相应按钮更新脚本'; + let id = await updata.present(); + if (id == 0) { + Safari.openInApp( + 'https://raw.githubusercontent.com/anker1209/Scriptable/main/scripts/JD-in-one-v2.js', + ); + } else if (id == 1) { + Safari.openInApp('http://scriptablejs.gitee.io/store/#/menu/myInfo'); + } else { + return; + } + } else { + let updata = new Alert(); + updata.title = '暂无更新'; + updata.addCancelAction('好的'); + updata.message = `\n当前版本 ${version} 为最新版本`; + await updata.present(); + } + } catch (e) { + console.log(e); + } + } + + async faqTable() { + const table = new UITable(); + table.showSeparators = false; + let data; + try { + let faq = new Request( + 'https://raw.githubusercontent.com/anker1209/Scriptable/main/faq.json', + ); + data = await faq.loadJSON(); + let info = new UITableRow(); + info.height = parseFloat(data.height); + let desc = info.addText(data.update, data.desc); + desc.subtitleColor = Color.blue(); + desc.titleFont = Font.mediumSystemFont(14); + desc.subtitleFont = Font.systemFont(14); + table.addRow(info); + for (let i = 0; i < data.data.length; i++) { + let header = new UITableRow(); + header.backgroundColor = Color.dynamic( + new Color('F5F5F5'), + new Color('000000'), + ); + let heading = header.addText(data.data[i].name); + heading.titleFont = Font.mediumSystemFont(17); + heading.centerAligned(); + table.addRow(header); + data.data[i].item.forEach((faq) => { + let row = new UITableRow(); + row.height = parseFloat(faq['height']); + let rowtext = row.addText(faq['question'], faq['answer']); + rowtext.titleFont = Font.mediumSystemFont(16); + rowtext.titleColor = Color.blue(); + rowtext.subtitleFont = Font.systemFont(14); + rowtext.subtitleColor = Color.dynamic( + new Color('000000', 0.7), + new Color('ffffff', 0.7), + ); + table.addRow(row); + }); + } + } catch (e) { + console.log(e); + } + await table.present(); + } + + async settingCategory(table, item, outfit, category) { + let header = new UITableRow(); + let heading = header.addText(outfit); + heading.titleFont = Font.mediumSystemFont(17); + heading.centerAligned(); + table.addRow(header); + item.forEach((data) => { + Object.keys(data.option).forEach((key) => { + let row = new UITableRow(); + let rowIcon = row.addImageAtURL(data['icon']); + rowIcon.widthWeight = 100; + let rowtext = row.addText(data['title']); + rowtext.widthWeight = 400; + let rowNumber = row.addText(`${this.settings[category][key]} >`); + rowNumber.widthWeight = 500; + rowNumber.rightAligned(); + rowNumber.titleColor = Color.gray(); + rowNumber.titleFont = Font.systemFont(16); + rowtext.titleFont = Font.systemFont(16); + row.dismissOnSelect = false; + row.onSelect = async () => { + if (data.type == 'text') { + await this.alertInput( + data['title'], + data['desc'], + category, + data['option'], + ); + } else if (data.type == 'menu') { + await this.showAlert( + data['title'], + data['desc'], + data['menu'], + category, + key, + ); + } + await this.tableContent(table); + }; + table.addRow(row); + }); + }); + table.reload(); + } + + async tableContent(table) { + const basic = [ + { + type: 'text', + title: '全局缩放比例', + desc: '排版溢出、显示不全的请优先调低此数,建议递减0.05调整,如0.95、0.90……\n\n缺省值:1.00', + option: { scale: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/scale.png', + }, + { + type: 'text', + title: '京东标志大小', + desc: '京东logo(形象狗)大小\n\n缺省值:30', + option: { logo: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/logo.png', + }, + { + type: 'text', + title: '用户头像大小', + desc: '⚠️注意:若要修改头像,请在京东app上传后将缓存清除再运行脚本。\n\n缺省值:69', + option: { userImage: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/userImage.png', + }, + { + type: 'text', + title: '左侧栏宽度', + desc: '左侧用户信息栏整体宽度\n\n缺省值:103', + option: { userStack: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/userStack.png', + }, + { + type: 'text', + title: '左右栏间距', + desc: '左侧用户信息栏与右侧京豆数据间距\n\n缺省值:25', + option: { division: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/division.png', + }, + { + type: 'text', + title: '缓存时间', + desc: '数据请求间隔时间\n请设置合适时间,避免频繁访问接口数据以及加载缓慢。单位:分钟\n\n缺省值:10', + option: { interval: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/interval.png', + }, + { + type: 'text', + title: '自定义昵称', + desc: '自定义用户信息栏的昵称名称,\n留空将显示京东账号昵称。\n\n注意:单脚本多账户若使用自定义昵称,所有账户将同时显示此昵称,如需单独自定义昵称,请复制脚本单独设置。', + option: { customizeName: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/customizeName.png', + }, + { + type: 'text', + title: '自定义头像', + desc: '自定义用户信息栏的头像,\n留空将显示京东APP头像。\n\n注意:单脚本多账户若使用自定义头像,所有账户将同时显示此头像,如需单独自定义头像,请复制脚本单独设置。', + option: { customizeAvatar: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/customizeAvatar.png', + }, + { + type: 'menu', + title: '小组件显示内容', + desc: '\n缺省值:京豆、钱包数据', + option: { smallShowType: '' }, + menu: ['京豆、钱包数据', '个人信息'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/smallShowType.png', + }, + { + type: 'menu', + title: '钱包显示类型', + desc: '若要显示钱包内容,白条需关闭或者白条打开的情况下无待还白条。\n\n缺省值:红包', + option: { walletShowType: '' }, + menu: ['红包', '钢镚和金贴'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/walletShowType.png', + }, + ]; + const chart = [ + { + type: 'text', + title: '图表高度', + desc: '京豆数据未与日期对齐的,\n请调低此数值\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:130', + option: { height: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/height.png', + }, + { + type: 'text', + title: '日期文字大小', + desc: '京豆图表底部日期文字大小\n\n缺省值:9', + option: { daySize: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/daySize.png', + }, + { + type: 'text', + title: '日期文字后缀', + desc: '京豆图表底部日期文字后缀', + option: { dayText: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/dayText.png', + }, + { + type: 'text', + title: '京豆数文字大小', + desc: '京豆图表数据文字大小\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:18', + option: { textSize: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/textSize.png', + }, + { + type: 'text', + title: '京豆数白天颜色', + desc: '⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:999999', + option: { textDayColor: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/textDayColor.png', + }, + { + type: 'text', + title: '京豆数晚上颜色', + desc: '⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:999999', + option: { textNightColor: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/textNightColor.png', + }, + { + type: 'text', + title: '折线图线条颜色', + desc: '支持渐变色,每个颜色之间以英文逗号分隔,颜色值必须带“#”。\n\n缺省值:#C8E3FA, #ED402E', + option: { lineColor: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/lineColor.png', + }, + { + type: 'text', + title: '折线图表顶边距', + desc: '京豆折线图顶边距\n京豆数据在顶部被剪切显示不全的,\n请调高此数值。\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:15', + option: { linePadding: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/linePadding.png', + }, + { + type: 'text', + title: '柱状图表顶边距', + desc: '京豆柱状图和曲线面积图顶边距\n京豆数据在顶部被剪切显示不全的,\n请调高此数值。\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:5', + option: { barPadding: '' }, + icon: 'https://gitee.com/anker1209/image/raw/master/jd/barPadding.png', + }, + { + type: 'menu', + title: '小组件图表类型', + desc: '\n缺省值:双日视图', + option: { smallShowType: '' }, + menu: ['双日视图', '折线图表', '柱状图表', '曲线面积图'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/smallShowType2.png', + }, + { + type: 'menu', + title: '中组件图表类型', + desc: '\n缺省值:双日视图', + option: { showType: '' }, + menu: ['双日视图', '折线图表', '柱状图表', '曲线面积图'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/showType.png', + }, + { + type: 'menu', + title: '每日京豆数计算', + desc: '\n缺省值:收入-支出', + option: { countBean: '' }, + menu: ['收入-支出', '收入'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/countBean.png', + }, + { + type: 'menu', + title: '多彩柱状图', + desc: '设置为打开时仅对柱状图表生效\n\n缺省值:关闭', + option: { colorful: '' }, + menu: ['打开', '关闭'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/colorful.png', + }, + ]; + const func = [ + { + type: 'menu', + title: '白条信息', + desc: '关闭或者打开后无待还白条的情况下,\n会显示基础设置里选择的钱包内容。\n\n缺省值:打开', + option: { showBaitiao: '' }, + menu: ['打开', '关闭'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/showBaitiao.png', + }, + { + type: 'menu', + title: '包裹信息', + desc: '只有中组件显示一条物流信息,\n若无物流信息会显示图表设置里选择的图表类型。\n\n缺省值:关闭', + option: { showPackage: '' }, + menu: ['打开', '关闭'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/showPackage.png', + }, + { + type: 'menu', + title: '运行日志', + desc: '出现数据异常请将此值设为true,\n查看运行日志。\n\n⚠️注意:\n查看运行日志需将缓存时间更改为0。\n\n缺省值:关闭', + option: { logable: '' }, + menu: ['打开', '关闭'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/logable.png', + }, + { + type: 'menu', + title: '刷新图表', + desc: '打开,每次刷新组件会随机刷新图表颜色(仅柱状图表和曲线面积图);关闭,则只有在京豆数据有变化的情况下刷新图表颜色及数据。建议在排版调整没有问题后,设置为关闭。设置为打开会加长数据载入时间。\n\n⚠️注意:图表设置选项里修改图表高度、颜色、文字大小、顶边距需打开此选项以查看即时反馈。\n\n缺省值:打开', + option: { alwaysRefreshChart: '' }, + menu: ['打开', '关闭'], + icon: 'https://gitee.com/anker1209/image/raw/master/jd/alwaysRefreshChart.png', + }, + ]; + table.removeAllRows(); + let topRow = new UITableRow(); + let leftText = topRow.addButton('教程'); + leftText.widthWeight = 0.25; + leftText.onTap = async () => { + await Safari.open('https://github.com/anker1209/Scriptable#jd_in_one'); + }; + let faqText = topRow.addButton('常见问题'); + faqText.widthWeight = 0.25; + faqText.leftAligned(); + faqText.onTap = async () => { + await this.faqTable(); + }; + let versionText = topRow.addButton('版本检测'); + versionText.widthWeight = 0.25; + versionText.rightAligned(); + versionText.onTap = async () => { + await this.updateCheck(this.version); + }; + let rightText = topRow.addButton('电报群'); + rightText.widthWeight = 0.25; + rightText.rightAligned(); + rightText.onTap = async () => { + await Safari.open('https://t.me/Scriptable_JS'); + }; + table.addRow(topRow); + + let header = new UITableRow(); + let heading = header.addText('重置设置'); + heading.titleFont = Font.mediumSystemFont(17); + heading.centerAligned(); + table.addRow(header); + let row1 = new UITableRow(); + let rowtext1 = row1.addText( + '重置缓存', + '若需要修改头像或数据显示错误,尝试此操作', + ); + rowtext1.titleFont = Font.systemFont(16); + rowtext1.subtitleFont = Font.systemFont(12); + rowtext1.subtitleColor = new Color('999999'); + row1.dismissOnSelect = false; + row1.onSelect = async () => { + const options = ['取消', '重置']; + const message = '所有在线请求的数据缓存将会被清空'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + this.removeCaches(this.settings.CACHES); + delete this.settings['CACHES']; + this.saveSettings(); + }; + table.addRow(row1); + let row2 = new UITableRow(); + let rowtext2 = row2.addText( + '重置京豆数据', + '若京豆数据缺失或显示有误,尝试此操作', + ); + rowtext2.titleFont = Font.systemFont(16); + rowtext2.subtitleFont = Font.systemFont(12); + rowtext2.subtitleColor = new Color('999999'); + row2.dismissOnSelect = false; + row2.onSelect = async () => { + const options = ['取消', '重置']; + const message = + '若缺少京豆数据或显示为0(双日视图或图表的京豆数)采用此操作。京豆数据重置后,将会重新抓取近6天的京豆明细。请勿频繁使用,会产生大量数据'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + Keychain.remove(this.settings.CACHE_KEY); + delete this.settings.CACHE_KEY; + this.saveSettings(); + }; + table.addRow(row2); + let row3 = new UITableRow(); + let rowtext3 = row3.addText( + '重置设置参数', + '设置参数绑定脚本文件名,请勿随意更改脚本文件名', + ); + rowtext3.titleFont = Font.systemFont(16); + rowtext3.subtitleFont = Font.systemFont(12); + rowtext3.subtitleColor = new Color('999999'); + row3.dismissOnSelect = false; + row3.onSelect = async () => { + const options = ['取消', '重置']; + const message = + '本菜单里的所有设置参数将会重置为默认值,重置后请重新打开设置菜单'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + delete this.settings['basicSetting']; + delete this.settings['chartSetting']; + delete this.settings['funcSetting']; + this.saveSettings(); + }; + table.addRow(row3); + await this.settingCategory(table, basic, '基础设置', 'basicSetting'); + await this.settingCategory(table, chart, '图表设置', 'chartSetting'); + await this.settingCategory(table, func, '功能设置', 'funcSetting'); + } + + async editSettings() { + const table = new UITable(); + table.showSeparators = true; + await this.tableContent(table); + await table.present(true); + } + + alertInput = async (title, desc, category, opt = {}) => { + const a = new Alert(); + a.title = title; + a.message = !desc ? '' : desc; + let key = Object.keys(opt)[0]; + a.addTextField(key, `${this.settings[category][key]}`); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + this.settings[category][key] = a.textFieldValue(0); + this.saveSettings(); + }; + + async showAlert(title, message, options, category, key) { + let alert = new Alert(); + alert.title = title; + alert.message = message; + alert.addCancelAction('取消'); + for (const option of options) { + alert.addAction(option); + } + let id = await alert.presentAlert(); + if (id === -1) return; + this.settings[category][key] = options[id]; + this.saveSettings(); + } + + run = (filename, args) => { + if (!this.settings.basicSetting) + this.settings.basicSetting = this.basicSetting; + Object.keys(this.basicSetting).forEach((key) => { + if (!this.settings.basicSetting.hasOwnProperty(key)) + this.settings['basicSetting'][key] = this.basicSetting[key]; + }); + if (!this.settings.chartSetting) + this.settings.chartSetting = this.chartSetting; + Object.keys(this.chartSetting).forEach((key) => { + if (!this.settings.chartSetting.hasOwnProperty(key)) + this.settings['chartSetting'][key] = this.chartSetting[key]; + }); + if (!this.settings.funcSetting) + this.settings.funcSetting = this.funcSetting; + Object.keys(this.funcSetting).forEach((key) => { + if (!this.settings.funcSetting.hasOwnProperty(key)) + this.settings['funcSetting'][key] = this.funcSetting[key]; + }); + if (!this.settings.CACHES) this.settings.CACHES = []; + this.CACHES = this.settings.CACHES; + + if (config.runsInApp) { + this.registerAction( + '参数配置', + this.editSettings, + 'https://gitee.com/anker1209/image/raw/master/jd/setting.png', + ); + this.registerAction( + '账号设置', + async () => { + const index = await this.generateAlert('设置账号信息', [ + '网站登录', + '手动输入', + ]); + if (index === 0) { + await this.jdWebView(); + } else { + await this.setAlertInput( + '账号设置', + '京东账号cookie\n\n⚠️\n用户名和cookie必须输入!\n多账号注意用户名不要重复!', + { + username: '用户名,必须输入!多账号勿重复!', + cookie: 'Cookie', + }, + ); + } + }, + 'https://gitee.com/anker1209/image/raw/master/jd/account.png', + ); + this.registerAction( + '代理缓存', + this.actionSettings, + 'https://gitee.com/anker1209/image/raw/master/jd/boxjs.png', + ); + this.registerAction( + '基础设置', + this.setWidgetConfig, + 'https://gitee.com/anker1209/image/raw/master/jd/preferences.png', + ); + } + Object.keys(this.settings['basicSetting']).forEach((key) => { + if ( + key == 'customizeName' || + key == 'customizeAvatar' || + key == 'smallShowType' || + key == 'walletShowType' + ) { + this.basicSetting[key] = this.settings['basicSetting'][key]; + } else if (!isNaN(this.settings['basicSetting'][key])) { + this.basicSetting[key] = parseFloat(this.settings['basicSetting'][key]); + } + }); + Object.keys(this.settings['chartSetting']).forEach((key) => { + if ( + key == 'textDayColor' || + key == 'textNightColor' || + key == 'showType' || + key == 'smallShowType' || + key == 'countBean' || + key == 'colorful' || + key == 'lineColor' || + key == 'dayText' + ) { + this.chartSetting[key] = this.settings['chartSetting'][key]; + } else if (!isNaN(this.settings['chartSetting'][key])) { + this.chartSetting[key] = parseFloat(this.settings['chartSetting'][key]); + } + }); + Object.keys(this.settings['funcSetting']).forEach((key) => { + this.funcSetting[key] = this.settings['funcSetting'][key]; + }); + + let _md5 = this.md5(filename + this.en); + + if (this.funcSetting.logable === '打开') + console.log('当前配置内容:' + JSON.stringify(this.settings)); + + this.JDindex = + typeof args.widgetParameter === 'string' + ? parseInt(args.widgetParameter) + : false; + try { + let cookieData = this.settings.cookieData ? this.settings.cookieData : []; + if (this.JDindex !== false && cookieData[this.JDindex]) { + this.cookie = cookieData[this.JDindex]['cookie']; + this.userName = cookieData[this.JDindex]['userName']; + } else { + this.userName = this.settings.username; + this.cookie = this.settings.cookie; + } + if (!this.cookie) throw '京东 CK 获取失败'; + this.userName = decodeURI(this.userName); + this.CACHE_KEY = `cache_${_md5}_` + this.userName; + this.settings.CACHE_KEY = this.CACHE_KEY; + this.saveSettings(false); + + return true; + } catch (e) { + this.notify('错误提示', e); + return false; + } + }; + + jdWebView = async () => { + const webView = new WebView(); + const url = + 'https://mcr.jd.com/credit_home/pages/index.html?btPageType=BT&channelName=024'; + await webView.loadURL(url); + await webView.present(true); + 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"}'; + await req.loadJSON(); + const cookies = req.response.cookies; + const account = { username: '', cookie: '' }; + const cookie = []; + cookies.forEach((item) => { + const value = `${item.name}=${item.value}`; + if (item.name === 'pt_key') cookie.push(value); + if (item.name === 'pt_pin') { + account.username = item.value; + cookie.push(value); + } + }); + account.cookie = cookie.join('; '); + console.log(account); + + if (account.cookie) { + this.settings = { ...this.settings, ...account }; + this.saveSettings(false); + console.log(`${this.name}: cookie获取成功,请关闭窗口!`); + this.notify(this.name, 'cookie获取成功,请关闭窗口!'); + } + }; + + _loadJDCk = async () => { + try { + const CookiesData = await this.getCache('CookiesJD'); + if (CookiesData) { + this.CookiesData = this.transforJSON(CookiesData); + } + const CookieJD = await this.getCache('CookieJD'); + if (CookieJD) { + const userName = CookieJD.match(/pt_pin=(.+?);/)[1]; + const ck1 = { + cookie: CookieJD, + userName, + }; + this.CookiesData.push(ck1); + } + const Cookie2JD = await this.getCache('CookieJD2'); + if (Cookie2JD) { + const userName = Cookie2JD.match(/pt_pin=(.+?);/)[1]; + const ck2 = { + cookie: Cookie2JD, + userName, + }; + this.CookiesData.push(ck2); + } + return true; + } catch (e) { + console.log(e); + this.CookiesData = []; + return false; + } + }; + + async actionSettings() { + try { + const table = new UITable(); + if (!(await this._loadJDCk())) throw 'BoxJS 数据读取失败'; + // 如果是节点,则先远程获取 + this.settings.cookieData = this.CookiesData; + this.saveSettings(false); + this.CookiesData.map((t, index) => { + const r = new UITableRow(); + r.addText(`parameter:${index} ${t.userName}`); + r.onSelect = (n) => { + this.settings.username = t.userName; + this.settings.cookie = t.cookie; + this.saveSettings(); + }; + table.addRow(r); + }); + let body = '京东 Ck 缓存成功,根据下标选择相应的 Ck'; + if (this.settings.cookie) { + body += ',或者使用当前选中Ck:' + this.settings.username; + } + this.notify(this.name, body); + table.present(false); + } catch (e) { + this.notify( + this.name, + '', + 'BoxJS 数据读取失败,请点击通知查看教程', + 'https://chavyleung.gitbook.io/boxjs/awesome/videos', + ); + } + } + + async render() { + if (!this.cookie || !this.userName) { + this.notify(this.name, 'cookie或用户名未设置'); + return; + } + await this.init(); + await this.getPackageData(); + await this.getExipireBean(); + if (this.funcSetting.showBaitiao === '打开') await this.getBaitiaoData(); + if (this.funcSetting.logable === '打开') console.log(this.rangeTimer); + const widget = new ListWidget(); + const padding = 14 * this.basicSetting.scale; + widget.setPadding(padding, padding, padding, padding); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + return await this.renderMedium(widget); + } else if (this.widgetFamily === 'large') { + return await this.renderLarge(widget); + } else { + return await this.renderSmall(widget); + } + } +} + +await Runing(Widget, '', false); + +//version:2.2.2 diff --git a/Scripts/JD-all-one.js b/Scripts/JD-all-one.js deleted file mode 100644 index 14f3c8c..0000000 --- a/Scripts/JD-all-one.js +++ /dev/null @@ -1,918 +0,0 @@ -// Author: 脑瓜 -// 电报群: https://t.me/Scriptable_JS @anker1209 -// 京豆收支采用2Ya美女的脚本 https://github.com/dompling/Scriptable/tree/master/Scripts -let widgetParam = args.widgetParameter; -const files = FileManager.local(); -// ######################设置#################### -let cookie = ''; // 两个引号之间输入京东cookie,只需填入pt_key和pt_pin字段即可 -let userID = decodeURIComponent( - cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1], -); -const size = { - logo: 30, // Logo大小 - userImage: 70, // 用户头像大小 - userStack: 103, // 左侧用户信息栏整体宽度 - division: 25, // 左侧与右侧间距 - chartHeight: 120, //京豆K线图高度 -}; -const showBaitiao = false; // 是否显示白条还款信息 -const showPackage = false; // 是否显示包裹信息 - -// ############################################## -const w = new ListWidget(); -w.setPadding(14, 14, 14, 14); - -let isSign; -let CACHE_KEY = 'cache_jd_' + userID; -let packageData; -let packageNum; -let mainData; - -const logo = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/e1902ff8-02e9-4dbf-99c7-cfc85ef3f1b7.png'; -const JDImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/43300bf7-61a2-4bd1-94a1-bf2faa2ed9e8.png'; -const jtImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/dacbd8f6-8115-4fd6-aedc-95cce83788a9.png'; -const gbImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/3947a83b-7aa6-4a53-be34-8fed610ddb77.png'; -const jdImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/7ea91cf8-6dea-477c-ae72-cb4d3f646c34.png'; -const plusImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/11fbba4a-4f92-4f7c-8fb3-dcff653fe20c.png'; -const baitiaoImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/30c40f5b-7428-46c3-a2c0-d81b2b95ec41.png'; -const carImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/3b30040f-e378-4502-bec6-ceddb0841b50.png'; -const plusCircle = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/06f78540-a5a4-462e-b8c5-98cb8059efc1.png'; - -let beanCount = 0; -let incomeBean = 0; -let expenseBean = 0; -let todayIncomeBean = 0; -let todayExpenseBean = 0; -let maxDays = 6; -let rangeTimer = {}; -let timerKeys = []; -let latelyDays = []; -// Keychain.remove(CACHE_KEY) -const chartTextColor = Color.dynamic( - new Color('000000', 1), - new Color('ffffff', 1), -); - -let baitiaoData = {}; -let baitiaoTitle; -let baitiaoAmount; -let baitiaoDesc; - -// #####################小组件################### -async function renderSmallWidget() { - const bodyStack = w.addStack(); - bodyStack.layoutVertically(); - if (widgetParam == 2) { - await setUserShow(bodyStack); - } else { - await setHeaderShow(bodyStack); - bodyStack.addSpacer(); - if (widgetParam == 1) { - await setChartShow(bodyStack); - } else { - await setBeanShow(bodyStack, 22, 40); - } - bodyStack.addSpacer(); - if (showBaitiao && baitiaoAmount > 0) { - await setSmallBaitiaoShow(bodyStack); - } else { - await rowCell(bodyStack, jtImg, 16, mainData.jintie, 16, '金贴', 10); - await rowCell( - bodyStack, - gbImg, - 18, - mainData['gangbeng'].toString(), - 16, - '钢镚', - 10, - ); - } - } - return w; -} -// #####################中组件################### -async function renderMediumWidget() { - const bodyStack = w.addStack(); - await setUserShow(bodyStack); - bodyStack.addSpacer(size.division); - const mainStack = bodyStack.addStack(); - mainStack.layoutVertically(); - await setHeaderShow(mainStack, JDImg); - mainStack.addSpacer(); - if (showPackage && packageNum > 0) { - await setPackageShow(mainStack); - mainStack.addSpacer(); - if (showBaitiao && baitiaoAmount > 0) { - await setBaitiaoShow(mainStack); - } else { - await setCoinShow(mainStack); - } - } else { - if (widgetParam == 1) { - await setChartShow(mainStack); // 显示京豆收支图表 - } else { - await setBeanShow(mainStack, 30, 50); // 显示昨天和今天京豆收支 - } - mainStack.addSpacer(); - if (showBaitiao && baitiaoAmount > 0) { - await setBaitiaoShow(mainStack); - } else { - await setCoinShow(mainStack); - } - } - return w; -} -// #####################大组件################### -async function renderLargeWidget() { - const bodyStack = w.addStack(); - bodyStack.size = new Size(0, 150); - bodyStack.addSpacer(); - await setUserShow(bodyStack); - bodyStack.addSpacer(); - w.addSpacer(20); - const text = w.addText('\u6211\u600e\u4e48\u8fd9\u4e48\u597d\u770b'); - w.addSpacer(20); - text.font = Font.thinSystemFont(30); - text.centerAlignText(); - const emoji = w.addText('🤣🥰🤪'); - emoji.centerAlignText(); - w.addSpacer(); - return w; -} -// #####################用户信息################### -async function setUserShow(widget) { - const userStack = widget.addStack(); - userStack.size = new Size(size.userStack, 0); - userStack.layoutVertically(); - // 头像 - const userImgStack = userStack.addStack(); - userImgStack.addSpacer(); - const imgStack = userImgStack.addStack(); - imgStack.size = new Size(size.userImage, size.userImage); - imgStack.cornerRadius = size.userImage / 2; - imgStack.backgroundImage = await getImage(userImage); - if (plus) { - const userImg = imgStack.addImage(await getImage(plusImg)); - } - userImgStack.addSpacer(); - userStack.addSpacer(); - // 签到和物流提示 - const tipStack = userStack.addStack(); - tipStack.addSpacer(); - let signIcon; - if (isSign == 0) { - signIcon = SFSymbol.named('checkmark.circle.fill'); - } else { - signIcon = SFSymbol.named('xmark.circle.fill'); - } - const signItem = tipStack.addImage(signIcon.image); - signItem.imageSize = new Size(14, 14); - if (packageNum > 0) { - tipStack.addSpacer(3); - const packageIcon = SFSymbol.named(packageNum + '.circle.fill'); - const packageItem = tipStack.addImage(packageIcon.image); - packageItem.imageSize = new Size(14, 14); - packageItem.tintColor = new Color('FC8600'); - } - // ;[signItem, packageIcon].map(t => t.imageSize = new Size(14,14)) - tipStack.addSpacer(); - userStack.addSpacer(); - // 用户名 - const nameStack = userStack.addStack(); - nameStack.centerAlignContent(); - if (plus) { - const nameImg = nameStack.addImage(await getImage(plusCircle)); - nameImg.imageSize = new Size(16, 16); - } else { - const person = SFSymbol.named('person.circle.fill'); - const nameIcon = nameStack.addImage(person.image); - nameIcon.imageSize = new Size(16, 16); - nameIcon.tintColor = new Color('007aff'); - } - nameStack.addSpacer(5); - const name = nameStack.addText(userName); - name.font = Font.regularSystemFont(14); - userStack.addSpacer(5); - // 京享值 - const valueStack = userStack.addStack(); - valueStack.centerAlignContent(); - const tagIcon = SFSymbol.named('tag.circle.fill'); - const lableIcon = valueStack.addImage(tagIcon.image); - lableIcon.imageSize = new Size(16, 16); - lableIcon.tintColor = new Color('fa2d19'); - valueStack.addSpacer(5); - const value = valueStack.addText(jValue.toString()); - value.font = Font.mediumSystemFont(14); - valueStack.addSpacer(3); - const jStack = valueStack.addStack(); - jStack.backgroundColor = new Color('fa2d19'); - jStack.cornerRadius = 5; - jStack.setPadding(1, 4, 1, 4); - const jLable = jStack.addText('京享'); - jLable.font = Font.systemFont(8); - jLable.textColor = Color.white(); - return widget; -} -// #####################顶部内容################### -async function setHeaderShow(widget, image) { - const topStack = widget.addStack(); - topStack.centerAlignContent(); - const JDLogo = topStack.addImage(await getImage(logo)); - JDLogo.imageSize = new Size(size.logo, size.logo); - if (image) { - topStack.addSpacer(10); - const JD = topStack.addImage(await getImage(image)); - JD.imageSize = new Size(194 * 0.2, 78 * 0.2); - } - topStack.addSpacer(); - const jdBean = topStack.addText(beanCount.toString()); - jdBean.font = Font.boldSystemFont(21); - jdBean.textColor = new Color('fa2d19'); - const desStack = topStack.addStack(); - desStack.layoutVertically(); - desStack.addSpacer(5.5); - const desText = desStack.addText(' 京豆'); - desText.font = Font.mediumSystemFont(10); - desText.textColor = jdBean.textColor; - return widget; -} -// #####################京豆收支################### -async function setBeanShow(widget, textSize, imageSize) { - const beanStack = widget.addStack(); - // 今日收支 - const todayStack = beanStack.addStack(); - todayStack.layoutVertically(); - await rowBeanCell( - todayStack, - todayExpenseBean.toString(), - todayIncomeBean.toString(), - textSize, - '今日', - ); - beanStack.addSpacer(); - // 京豆图片 - const ddStack = beanStack.addStack(); - ddStack.layoutVertically(); - const ddImg = ddStack.addImage(await getImage(jdImg)); - ddImg.imageSize = new Size(imageSize, imageSize); - beanStack.addSpacer(); - // 昨日收支 - const yestodayStack = beanStack.addStack(); - yestodayStack.layoutVertically(); - await rowBeanCell( - yestodayStack, - expenseBean.toString(), - incomeBean.toString(), - textSize, - '昨日', - ); - return widget; -} -// #####################京豆图表################### -async function setChartShow(widget) { - let beanNum = [], - beanDate = []; - Object.keys(rangeTimer).forEach(function (day) { - const numValue = rangeTimer[day]; - const arrDay = day.split('-'); - beanDate.push(arrDay[2]); - beanNum.push(numValue); - }); - if (config.widgetFamily == 'small') { - beanDate.splice(0, 2); - beanNum.splice(0, 2); - } - /*const beanNumStack = widget.addStack() - const canva = new DrawContext() - canva.size = new Size(210,10) - canva.opaque = false - canva.respectScreenScale=true - canva.setTextAlignedCenter() - canva.setFont(Font.mediumSystemFont(10)) - for (let i = 0; i < 6; i++) { - canva.drawTextInRect(beanNum[i].toString(), new Rect(0 + i * 210 / 6, 0, 210/6, 10)) - } - beanNumStack.addImage(canva.getImage())*/ - const chartStack = widget.addStack(); - chartStack.addImage(await createChart()); - const beanDateStack = widget.addStack(); - let showDays = config.widgetFamily == 'small' ? 4 : 6; - for (let i = 0; i < showDays; i++) { - beanDateStack.addSpacer(); - let subStack = beanDateStack.addStack(); - let beanDay = beanDateStack.addText(beanDate[i]); - beanDay.font = new Font('ArialMT', 9); - beanDay.textOpacity = 0.8; - beanDateStack.addSpacer(); - } -} -// #####################物流信息################### -async function setPackageShow(widget) { - const packageStack = widget.addStack(); - const detailStack = packageStack.addStack(); - detailStack.layoutVertically(); - const packageTitleStack = detailStack.addStack(); - packageTitleStack.centerAlignContent(); - const carIcon = packageTitleStack.addImage(await getImage(carImg)); - carIcon.imageSize = new Size(18, 18); - packageTitleStack.addSpacer(4); - const packageTitle = packageTitleStack.addText( - packageData.dealLogList[0]['name'], - ); - packageTitle.lineLimit = 1; - packageTitle.font = Font.mediumSystemFont(12); - detailStack.addSpacer(2); - const packageDesc = detailStack.addText( - packageData.dealLogList[0]['wlStateDesc'], - ); - packageDesc.lineLimit = 3; - packageDesc.font = Font.regularSystemFont(12); - detailStack.addSpacer(2); - const packageStateStack = detailStack.addStack(); - const packageTime = packageStateStack.addText( - packageData.dealLogList[0]['createTime'], - ); - packageTime.font = Font.regularSystemFont(9); - packageTime.textOpacity = 0.7; - packageStateStack.addSpacer(); - const packageState = packageStateStack.addText( - packageData.dealLogList[0]['stateName'], - ); - packageState.font = Font.regularSystemFont(9); - packageTime.textOpacity = 0.7; -} -// #####################金贴&钢镚################## -async function setCoinShow(widget) { - const extraData = widget.addStack(); - await rowCell(extraData, jtImg, 18, mainData.jintie, 16, '金贴', 13); - extraData.addSpacer(); - await rowCell( - extraData, - gbImg, - 18, - mainData['gangbeng'].toString(), - 16, - '钢镚', - 13, - ); - return widget; -} -// #####################京东白条################## -async function setBaitiaoShow(widget) { - const baitiaoStack = widget.addStack(); - baitiaoStack.centerAlignContent(); - const baitiaoImage = baitiaoStack.addImage(await getImage(baitiaoImg)); - baitiaoImage.imageSize = new Size(127 * 0.17, 75 * 0.17); - baitiaoStack.addSpacer(5); - const baitiaoText = baitiaoStack.addText(baitiaoTitle); - baitiaoText.font = Font.regularSystemFont(13); - baitiaoStack.addSpacer(); - const baitiaoValue = baitiaoStack.addText(baitiaoAmount); - baitiaoValue.font = Font.mediumSystemFont(15); - baitiaoStack.addSpacer(); - const baitiaoDate = baitiaoStack.addText(baitiaoDesc); - baitiaoDate.font = Font.regularSystemFont(10); - baitiaoDate.textOpacity = 0.7; -} -// ####################小组件白条################## -async function setSmallBaitiaoShow(widget) { - const oneStack = widget.addStack(); - oneStack.centerAlignContent(); - const baitiaoImage = oneStack.addImage(await getImage(baitiaoImg)); - baitiaoImage.imageSize = new Size(127 * 0.17, 75 * 0.17); - oneStack.addSpacer(5); - const baitiaoText = oneStack.addText(baitiaoTitle); - baitiaoText.font = Font.regularSystemFont(13); - oneStack.addSpacer(); - widget.addSpacer(5); - const twoStack = widget.addStack(); - twoStack.centerAlignContent(); - const baitiaoValue = twoStack.addText(baitiaoAmount); - baitiaoValue.font = Font.mediumSystemFont(15); - twoStack.addSpacer(); - const baitiaoDate = twoStack.addText(baitiaoDesc); - baitiaoDate.font = Font.regularSystemFont(10); - baitiaoDate.textOpacity = 0.7; -} - -async function rowCell( - widget, - image, - imageSize, - text, - textSize, - label, - lableSize, -) { - const rowStack = widget.addStack(); - rowStack.centerAlignContent(); - const rowImg = rowStack.addImage(await getImage(image)); - rowImg.imageSize = new Size(imageSize, imageSize); - rowStack.addSpacer(); - const rowNumber = rowStack.addText(text); - rowNumber.font = Font.regularSystemFont(textSize); - rowStack.addSpacer(); - const rowLabel = rowStack.addText(label); - rowLabel.font = Font.systemFont(lableSize); -} - -async function rowBeanCell(widget, min, add, textSize, label) { - const rowOne = widget.addStack(); - const labelText = rowOne.addText(label); - labelText.font = Font.mediumSystemFont(10); - labelText.textOpacity = 0.7; - const rowTwo = widget.addStack(); - const rowNumber = rowTwo.addText(add); - rowNumber.font = Font.lightSystemFont(textSize); - if (min < 0) { - const rowThree = widget.addStack(); - const minText = rowThree.addText(min); - minText.font = Font.mediumSystemFont(10); - minText.textColor = new Color('fa2d19'); - } -} - -async function init() { - try { - if (!cookie) return; - if (Keychain.contains(CACHE_KEY)) { - rangeTimer = JSON.parse(Keychain.get(CACHE_KEY)); - timerKeys = Object.keys(rangeTimer); - latelyDays = Object.keys(rangeTimer); - if (timerKeys.length >= maxDays) { - for (let i = 0; i < timerKeys.length - maxDays; i++) { - delete rangeTimer[timerKeys[i]]; - } - Keychain.set(CACHE_KEY, JSON.stringify(rangeTimer)); - } - rangeTimer[latelyDays[4]] = 0; - rangeTimer[latelyDays[5]] = 0; - timerKeys = [latelyDays[4], latelyDays[5]]; - } else { - rangeTimer = getDay(5); - timerKeys = Object.keys(rangeTimer); - } - await TotalBean(); - await getAmountData(); - } catch (e) { - console.log(e); - } -} - -async function getAmountData() { - let i = 0, - page = 1; - do { - const response = await getJingBeanBalanceDetail(page); - const result = response.code === '0'; - console.log(`第${page}页:${result ? '请求成功' : '请求失败'}`); - if (response.code === '3') { - i = 1; - console.log(response); - } - if (response && result) { - page++; - let detailList = response.jingDetailList; - if (detailList && detailList.length > 0) { - for (let item of detailList) { - const dates = item.date.split(' '); - if (timerKeys.indexOf(dates[0]) > -1) { - const amount = Number(item.amount); - rangeTimer[dates[0]] += amount; - if (latelyDays[4] === dates[0]) { - const yestodayAmount = Number(item.amount); - if (yestodayAmount > 0) incomeBean += yestodayAmount; - if (yestodayAmount < 0) expenseBean += yestodayAmount; - } - if (latelyDays[5] === dates[0]) { - const todayAmount = Number(item.amount); - if (todayAmount > 0) todayIncomeBean += todayAmount; - if (todayAmount < 0) todayExpenseBean += todayAmount; - } - } else { - i = 1; - Keychain.set(CACHE_KEY, JSON.stringify(rangeTimer)); - break; - } - } - } - } - } while (i === 0); -} - -function getDay(dayNumber) { - let data = {}; - let i = dayNumber; - do { - const today = new Date(); - const year = today.getFullYear(); - const targetday_milliseconds = today.getTime() - 1000 * 60 * 60 * 24 * i; - today.setTime(targetday_milliseconds); - let month = today.getMonth() + 1; - month = month >= 10 ? month : `0${month}`; - let day = today.getDate(); - day = day >= 10 ? day : `0${day}`; - data[`${year}-${month}-${day}`] = 0; - i--; - } while (i >= 0); - return data; -} - -async function TotalBean() { - const url = 'https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2'; - const request = new Request(url); - request.headers = { - cookie: cookie, - Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', - }; - const response = await request.loadJSON(); - if (response.retcode === 0) { - beanCount = response.base.jdNum; - userImage = response.base.headImageUrl; - userName = response.base.nickname; - jValue = response.base.jvalue; - plus = response.isPlusVip; - } else { - console.log('京东服务器返回空数据'); - } - return response; -} - -async function getJingBeanBalanceDetail(page) { - try { - const options = { - url: `https://bean.m.jd.com/beanDetail/detail.json`, - body: `page=${page}`, - headers: { - 'X-Requested-With': `XMLHttpRequest`, - Connection: `keep-alive`, - 'Accept-Encoding': `gzip, deflate, br`, - 'Content-Type': `application/x-www-form-urlencoded; charset=UTF-8`, - Origin: `https://bean.m.jd.com`, - 'User-Agent': `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15`, - Cookie: cookie, - Host: `bean.m.jd.com`, - Referer: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean`, - 'Accept-Language': `zh-cn`, - Accept: `application/json, text/javascript, */*; q=0.01`, - }, - }; - let params = { ...options, method: 'POST' }; - let request = new Request(params.url); - Object.keys(params).forEach((key) => { - request[key] = params[key]; - }); - return await request.loadJSON(); - } catch (e) { - console.log(e); - } -} - -async function chartConfig(labels = [], datas = [], chartTextSize, topPadding) { - const chartStr = ` - { - 'type': 'bar', - 'data': { - 'labels': ${JSON.stringify(labels)}, // 替换 - 'datasets': [ - { - type: 'line', - backgroundColor: '#ffffff', - borderColor: getGradientFillHelper('vertical', ['#fa2d19', '#fa2d19']), - 'borderWidth': 2, - pointRadius: 6, - 'fill': false, - 'data': ${JSON.stringify(datas)}, // 数据 - }, - ], - }, - 'options': { - plugins: { - datalabels: { - display: true, - align: 'top', - color: '#${chartTextColor.hex}', // 文字颜色 - font: { - family: 'ArialMT', - size: ${chartTextSize} - } - }, - }, - layout: { - padding: { - left: -20, - right: 0, - top: ${topPadding}, - bottom: 0 - } - }, - responsive: true, - maintainAspectRatio: true, - 'legend': { - 'display': false, - }, - scales: { - xAxes: [ - { - gridLines: { - display: false, - color: '#000000', - }, - ticks: { - display: false, - fontColor: '#000000', - fontSize: '20', - }, - }, - ], - yAxes: [ - { - ticks: { - display: false, - beginAtZero: false, - fontColor: '#000000', - }, - gridLines: { - display: false, - color: '#000000', - }, - }, - ], - }, - }, - }`; - return chartStr; -} - -async function createChart() { - let labels = [], - data = []; - Object.keys(rangeTimer).forEach(function (month) { - const value = rangeTimer[month]; - const arrMonth = month.split('-'); - labels.push(`${arrMonth[1]}.${arrMonth[2]}`); - data.push(value); - }); - let chartTextSize = 18; - let topPadding = 20; - if (config.widgetFamily == 'small') { - data.splice(0, 2); - labels.splice(0, 2); - chartTextSize = chartTextSize + 7; - topPadding = topPadding + 10; - } - const chartStr = await chartConfig(labels, data, chartTextSize, topPadding); - console.log(chartStr); - const url = `https://quickchart.io/chart?w=400&h=${ - size.chartHeight - }&f=png&c=${encodeURIComponent(chartStr)}`; - return await getImage(url); -} - -// 获取金贴和钢镚 -async function getMainData(isSign) { - //津贴查询 - const JTUrl = 'https://ms.jr.jd.com/gw/generic/uc/h5/m/mySubsidyBalance'; - const JTReq = new Request(JTUrl); - JTReq.headers = { - cookie: cookie, - Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', - }; - const JTData = await JTReq.loadJSON(); - //钢镚查询 - const GBUrl = 'https://coin.jd.com/m/gb/getBaseInfo.html'; - const GBReq = new Request(GBUrl); - GBReq.headers = { - cookie: cookie, - Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', - }; - const GBData = await GBReq.loadJSON(); - //签到查询,正则 - const substr = 'pt_key=' + cookie.match(/pt_key=(\S*);/)[1] + ';'; - const substr1 = 'pt_pin=' + cookie.match(/pt_pin=(\S*);/)[1] + ';'; - if (isSign == 1) { - const signUrl = 'http://jd.kzddck.cn:3001/?cookie=' + substr + substr1; - const signReq = new Request(signUrl); - console.log('开始签到'); - try { - console.log('正在签到'); - await signReq.load(); - console.log('签到成功'); - let myDate = new Date(); - let ty = myDate.toLocaleDateString(); - Keychain.set('time' + userID, ty); - console.log('time写入成功'); - } catch (e) { - console.log(e); - console.log('可能签到失败了'); - } - } else if (isSign == 0) { - console.log('今日已签到'); - } - const data = { - jintie: JTData.resultData.data['balance'], - gangbeng: GBData.gbBalance, - }; - return data; -} - -async function cache() { - let cache = Keychain.contains('time' + userID); - let myDate = new Date(); - let ty = myDate.toLocaleDateString(); - if (cache == true) { - let caches = Keychain.get('time' + userID); - if (caches == ty) { - var cachedata = 0; - } - } else { - console.log('还没有签到'); - var cachedata = 1; - } - return cachedata; -} - -async function getPackageData() { - var url = - 'https://wq.jd.com/bases/wuliudetail/notify?sceneval=2&sceneval=2&g_login_type=1&callback'; - var req = new Request(url); - req.headers = { - cookie: cookie, - Referer: 'https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&', - }; - var data = await req.loadJSON(); - if (data.errCode == 0) { - await cache(); - console.log('cookie正常'); - } else { - console.log('cookie失效'); - var data = { - dealLogList: [ - { - stateName: 'Cookie失效了', - name: 'Cookie失效了', - img: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/', - createTime: 'Cookie失效了', - wlStateDesc: 'Cookie失效了', - }, - ], - }; - } - return data; -} - -async function getBaitiaoData() { - 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: cookie, - }; - const res = await req.loadJSON(); - return res; -} - -async function getImage(url) { - const req = await new Request(url); - return await req.loadImage(); -} - -if (typeof require === 'undefined') require = importModule; -const { DmYY, Runing } = require('./DmYY'); -class Widget extends DmYY { - constructor(arg) { - super(arg); - this.name = '京东豆多合一'; - this.en = 'jd_all_one'; - this.run(); - } - - run = () => { - if (config.runsInApp) { - this.registerAction('账号设置', async () => { - await this.setAlertInput('账号设置', '京东账号 Ck', { - username: '昵称', - cookie: 'Cookie', - }); - }); - this.registerAction('代理缓存', this.actionSettings); - this.registerAction('基础设置', this.setWidgetConfig); - } - cookie = this.settings.cookie ? `${this.settings.cookie};` : cookie; - userID = decodeURIComponent( - cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1], - ); - }; - - CookiesData = []; - - // 加载京东 Ck 节点列表 - _loadJDCk = async () => { - try { - const CookiesData = await this.getCache('CookiesJD'); - if (CookiesData) { - this.CookiesData = this.transforJSON(CookiesData); - } - const CookieJD = await this.getCache('CookieJD'); - if (CookieJD) { - const userName = CookieJD.match(/pt_pin=(.+?);/)[1]; - const ck1 = { - cookie: CookieJD, - userName, - }; - this.CookiesData.push(ck1); - } - const Cookie2JD = await this.getCache('CookieJD2'); - if (Cookie2JD) { - const userName = Cookie2JD.match(/pt_pin=(.+?);/)[1]; - const ck2 = { - cookie: Cookie2JD, - userName, - }; - this.CookiesData.push(ck2); - } - return true; - } catch (e) { - console.log(e); - this.CookiesData = []; - return false; - } - }; - - async actionSettings() { - try { - const table = new UITable(); - if (!(await this._loadJDCk())) throw 'BoxJS 数据读取失败'; - // 如果是节点,则先远程获取 - this.settings.cookieData = this.CookiesData; - this.saveSettings(false); - this.CookiesData.map((t, index) => { - const r = new UITableRow(); - r.addText(`parameter:${index} ${t.userName}`); - r.onSelect = (n) => { - this.settings.username = t.userName; - this.settings.cookie = t.cookie; - this.saveSettings(); - }; - table.addRow(r); - }); - let body = '京东 Ck 缓存成功,根据下标选择相应的 Ck'; - if (this.settings.cookie) { - body += ',或者使用当前选中Ck:' + this.settings.username; - } - this.notify(this.name, body); - table.present(false); - } catch (e) { - this.notify( - this.name, - '', - 'BoxJS 数据读取失败,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); - } - } - - async render() { - await this.getWidgetBackgroundImage(w); - isSign = await cache(); - CACHE_KEY = 'cache_jd_' + userID; - packageData = await getPackageData(); - packageNum = packageData.dealLogList.length; - mainData = await getMainData(isSign); - await init(); - if (showBaitiao) { - baitiaoData = await getBaitiaoData(); - baitiaoTitle = baitiaoData['resultData']['data']['bill']['title']; - baitiaoAmount = baitiaoData['resultData']['data']['bill'][ - 'amount' - ].replace(/,/g, ''); - baitiaoDesc = baitiaoData['resultData']['data']['bill'][ - 'buttonName' - ].replace(/最近还款日/g, ''); - } - - if (config.widgetFamily == 'small') { - return await renderSmallWidget(); - } else if (config.widgetFamily == 'large') { - return await renderLargeWidget(); - } else { - return await renderMediumWidget(); - } - } -} - -await Runing(Widget, '', false); - -//version:1.0.0 From a7d02d4e31cd1fb12d9b89071c2e78d3c2e1005b Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Wed, 29 Sep 2021 17:30:16 +0800 Subject: [PATCH 007/152] =?UTF-8?q?15=20bug=20=E5=B7=B2=E7=BB=8F=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=83=A8=E5=88=86=EF=BC=8C=E9=87=8D=E6=96=B0=E6=81=A2?= =?UTF-8?q?=E5=A4=8D15=E5=9B=BE=E6=A0=87=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 7d732fc..1fc91e7 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -525,16 +525,14 @@ class DmYY { const rowIcon = row.addImageAtURL(item.url); rowIcon.widthWeight = 100; } else { - if (parseInt(Device.systemVersion()) < 15) { - const icon = item.icon || {}; - const image = await this.drawTableIcon( - icon.name, - icon.color, - item.cornerWidth, - ); - const imageCell = row.addImage(image); - imageCell.widthWeight = 100; - } + const icon = item.icon || {}; + const image = await this.drawTableIcon( + icon.name, + icon.color, + item.cornerWidth, + ); + const imageCell = row.addImage(image); + imageCell.widthWeight = 100; } let rowTitle = row.addText(item['title']); rowTitle.widthWeight = 400; From 585d178ec63cb6f0a315ccad84802df951bd9844 Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Wed, 29 Sep 2021 17:30:48 +0800 Subject: [PATCH 008/152] =?UTF-8?q?=E5=8E=BB=E6=8E=89=2015=20=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.json b/install.json index b32cb85..3dfcfcf 100644 --- a/install.json +++ b/install.json @@ -5,7 +5,7 @@ "repo": "https://github.com/dompling/Scriptable", "apps": [ { - "version": "1.0.8", + "version": "1.0.9", "description": "DmYY组件库", "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js", "thumb": "https://img.icons8.com/clouds/344/settings.png", From 445647b368a8fbf4f906bf62d5fe74db8e304d90 Mon Sep 17 00:00:00 2001 From: dompling <374779789@qq.com> Date: Tue, 23 Nov 2021 09:19:31 +0800 Subject: [PATCH 009/152] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 485d7a5..2eccdc2 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,7 @@ >首先安装 TF版的 [scriptable](https://testflight.apple.com/join/uN1vTqxk) > 网页安装:(推荐:⭐️⭐️⭐️⭐️⭐️)[WebStore](https://scriptablejs.gitee.io/store/#/) - -> 单个安装:(推荐:⭐️⭐️⭐️⭐️⭐️)[widget.Install](https://raw.githubusercontent.com/dompling/Scriptable/master/widget.Install.js) 安装导入到 scriptable,添加订阅,然后选择即可获取安装列表(覆盖当前下载文件) - -> 全量安装:(推荐:⭐️⭐️⭐️️)[2YaInstall](https://raw.githubusercontent.com/dompling/Scriptable/master/2YaInstall.js) 导入到 scriptable 软件中,点击运行即可(覆盖被修改的同名文件) - -> 收集订阅:(使用 [widget.Install](https://raw.githubusercontent.com/dompling/Scriptable/master/widget.Install.js)添加下方链接即可获取作者小组件) +> 安装教程:[网页安装步骤](https://t.me/Scriptable_JS/101536) - 作者:@2Ya - 订阅安装包 From ad94d017670a6bace9314ffbfd9f6ffbc7dcc9d2 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 30 Dec 2021 09:53:07 +0800 Subject: [PATCH 010/152] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=AF=BB=E5=8F=96=20boxjs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 1 - Scripts/JD-all-one-v2.js | 1380 +++++++++++--------------------------- 2 files changed, 398 insertions(+), 983 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 1fc91e7..84de299 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -89,7 +89,6 @@ class DmYY { try { const url = 'http://' + this.prefix + '/query/boxdata'; const boxdata = await this.$request.get(url); - console.log(boxdata.datas[key]); if (key) return boxdata.datas[key]; return boxdata.datas; } catch (e) { diff --git a/Scripts/JD-all-one-v2.js b/Scripts/JD-all-one-v2.js index 2ff89d7..19321c9 100644 --- a/Scripts/JD-all-one-v2.js +++ b/Scripts/JD-all-one-v2.js @@ -1,11 +1,14 @@ +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: pink; icon-glyph: shopping-cart; // Author: 脑瓜 // 电报群: https://t.me/Scriptable_JS @anker1209 // 采用了2Ya美女的京豆收支脚本及DmYY依赖 https://github.com/dompling/Scriptable/tree/master/Scripts -// version:2.2.2 -// update:2021/04/01 +// version:2.2.5 +// update:2021/11/08 if (typeof require === 'undefined') require = importModule; -const { DmYY, Runing } = require('./DmYY'); +const {DmYY, Runing} = require('./DmYY'); class Widget extends DmYY { constructor(arg) { @@ -15,44 +18,34 @@ class Widget extends DmYY { this.run(module.filename, args); } fm = FileManager.local(); - iCloudInUse = this.fm.isFileStoredIniCloud(module.filename); - fm = this.iCloudInUse ? FileManager.iCloud() : this.fm; CACHE_FOLDER = 'JD_in_one'; - cachePath = this.fm.joinPath(this.fm.documentsDirectory(), this.CACHE_FOLDER); - - logo = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/f09e7977-b161-4361-ac78-e64729192ee6.png'; - JDImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/43300bf7-61a2-4bd1-94a1-bf2faa2ed9e8.png'; - beanImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/7ea91cf8-6dea-477c-ae72-cb4d3f646c34.png'; - plusFG = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/cd0d2b80-0857-4202-8d12-af4eb7d241d6.png'; - plusBG = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/24fc5a14-edea-4b1b-8e30-bdcc1a27a037.png'; - baitiaoImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/30c40f5b-7428-46c3-a2c0-d81b2b95ec41.png'; - plusIcon = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/06f78540-a5a4-462e-b8c5-98cb8059efc1.png'; - walletImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/cd89ceec-7895-41ee-a1a3-3d3e7223035f.png'; - jingtieImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/16a7038e-6082-4ad8-b17f-fdd08266fb22.png'; - gangbengImg = - 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/9704e332-9e7f-47e8-b09a-1f1991d4aa84.png'; - userImage = - 'https://img11.360buyimg.com/jdphoto/s120x120_jfs/t21160/90/706848746/2813/d1060df5/5b163ef9N4a3d7aa6.png'; + cachePath = null; + + logo = 'https://pic.imgdb.cn/item/6187994b2ab3f51d919028cc.png'; + JDImg = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/43300bf7-61a2-4bd1-94a1-bf2faa2ed9e8.png'; + beanImg = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-imgbed/7ea91cf8-6dea-477c-ae72-cb4d3f646c34.png'; + plusFG = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/cd0d2b80-0857-4202-8d12-af4eb7d241d6.png'; + plusBG = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/24fc5a14-edea-4b1b-8e30-bdcc1a27a037.png'; + baitiaoImg = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/30c40f5b-7428-46c3-a2c0-d81b2b95ec41.png'; + plusIcon = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/06f78540-a5a4-462e-b8c5-98cb8059efc1.png'; + walletImg = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/cd89ceec-7895-41ee-a1a3-3d3e7223035f.png'; + jingtieImg = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/16a7038e-6082-4ad8-b17f-fdd08266fb22.png'; + gangbengImg = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-b1ebbd3c-ca49-405b-957b-effe60782276/9704e332-9e7f-47e8-b09a-1f1991d4aa84.png'; + userImage = 'https://img11.360buyimg.com/jdphoto/s120x120_jfs/t21160/90/706848746/2813/d1060df5/5b163ef9N4a3d7aa6.png'; + nameImg = 'https://pic.imgdb.cn/item/6188bfb62ab3f51d91bca276.png'; + tagImg = 'https://pic.imgdb.cn/item/6188bfc72ab3f51d91bcbcb0.png'; // 请勿在此修改参数值 - version = '2.2.2'; + version = '2.2.5'; basicSetting = { - scale: 1.0, + scale: 1.00, logo: 30, userImage: 69, userStack: 103, division: 25, interval: 10, + directory: 'Local', customizeName: '', customizeAvatar: '', smallShowType: '京豆、钱包数据', @@ -63,7 +56,7 @@ class Widget extends DmYY { daySize: 9, dayText: '', textSize: 18, - textDayColor: '999999', + textDayColor: '999999', textNightColor: '999999', lineColor: '#FA6859', linePadding: 15, @@ -76,6 +69,7 @@ class Widget extends DmYY { funcSetting = { showBaitiao: '打开', showPackage: '关闭', + showFruit: '打开', logable: '关闭', alwaysRefreshChart: '打开', }; @@ -92,15 +86,10 @@ class Widget extends DmYY { desc: '', }; redPackage = { - title: '通用红包', + title: '红包', number: 0, desc: '今日无过期', }; - expireBean = { - title: '过期京豆', - number: 0, - desc: '', - }; extra = { jingtie: 0, gangbeng: 0, @@ -124,7 +113,8 @@ class Widget extends DmYY { maxDays = 6; rangeTimer = {}; timerKeys = []; - + fruitState = "😢"; + doubleDate = this.getDay(1); doubleDay = Object.keys(this.doubleDate); yestoday = this.doubleDay[0]; @@ -132,12 +122,8 @@ class Widget extends DmYY { CACHES = []; lineChart(labels = [], datas = [], chartTextSize, topPadding) { - let chartTextColor = Color.dynamic( - new Color(this.chartSetting.textDayColor), - new Color(this.chartSetting.textNightColor), - ); + let chartTextColor = Color.dynamic(new Color(this.chartSetting.textDayColor),new Color(this.chartSetting.textNightColor),); let lineColor = this.chartSetting.lineColor.split(','); - log(lineColor); const chartStr = ` { type: 'bar', @@ -147,9 +133,7 @@ class Widget extends DmYY { { type: 'line', backgroundColor: '#FFFFFF', - borderColor: getGradientFillHelper('horizontal', ${JSON.stringify( - lineColor, - )}), + borderColor: getGradientFillHelper('horizontal', ${JSON.stringify(lineColor)}), borderWidth: ${this.isSmall(true) ? 4 : 3}, pointRadius: ${this.isSmall(true) ? 8 : 6}, fill: false, @@ -212,17 +196,10 @@ class Widget extends DmYY { } barChart(labels = [], datas = [], chartTextSize, topPadding, showType) { - let chartTextColor = Color.dynamic( - new Color(this.chartSetting.textDayColor), - new Color(this.chartSetting.textNightColor), - ); + let chartTextColor = Color.dynamic(new Color(this.chartSetting.textDayColor),new Color(this.chartSetting.textNightColor),); let backgroundColor = []; - if (this.chartSetting.colorful === '打开') - backgroundColor = JSON.stringify(this.colorfulBar()); - else - backgroundColor = `getGradientFillHelper('vertical', ${JSON.stringify( - this.chartColors(), - )})`; + if (this.chartSetting.colorful === '打开') backgroundColor = JSON.stringify(this.colorfulBar()) + else backgroundColor = `getGradientFillHelper('vertical', ${JSON.stringify(this.chartColors())})` const chartStr = ` { type: 'bar', @@ -300,157 +277,21 @@ class Widget extends DmYY { return chartStr; } - chartColors() { - let colorArr = [ - ['#FFF000', '#E62490'], - ['#FDEB71', '#F8D800'], - ['#ABDCFF', '#0396FF'], - ['#FEB692', '#EA5455'], - ['#FEB692', '#EA5455'], - ['#CE9FFC', '#7367F0'], - ['#90F7EC', '#32CCBC'], - ['#FFF6B7', '#F6416C'], - ['#E2B0FF', '#9F44D3'], - ['#F97794', '#F072B6'], - ['#FCCF31', '#F55555'], - ['#5EFCE8', '#736EFE'], - ['#FAD7A1', '#E96D71'], - ['#FFFF1C', '#00C3FF'], - ['#FEC163', '#DE4313'], - ['#F6CEEC', '#D939CD'], - ['#FDD819', '#E80505'], - ['#FFF3B0', '#CA26FF'], - ['#2AFADF', '#4C83FF'], - ['#EECDA3', '#EF629F'], - ['#C2E59C', '#64B3F4'], - ['#FFF886', '#F072B6'], - ['#F5CBFF', '#C346C2'], - ['#FFF720', '#3CD500'], - ['#EE9AE5', '#5961F9'], - ['#FFC371', '#FF5F6D'], - ['#FFD3A5', '#FD6585'], - ['#C2FFD8', '#465EFB'], - ['#FFC600', '#FD6E6A'], - ['#FFC600', '#FD6E6A'], - ['#92FE9D', '#00C9FF'], - ['#FFDDE1', '#EE9CA7'], - ['#F0FF00', '#58CFFB'], - ['#FFE985', '#FA742B'], - ['#72EDF2', '#5151E5'], - ['#F6D242', '#FF52E5'], - ['#F9D423', '#FF4E50'], - ['#3C8CE7', '#00EAFF'], - ['#FCFF00', '#FFA8A8'], - ['#FF96F9', '#C32BAC'], - ['#D0E6A5', '#FFDD94'], - ['#FFDD94', '#FA897B'], - ['#FFCC4B', '#FF7D58'], - ['#D0E6A5', '#86E3CE'], - ['#F0D5B6', '#F16238'], - ['#F8EC70', '#F9C708'], - ['#C4E86B', '#00BCB4'], - ['#F5CEC7', '#E79796'], - ['#FFC446', '#FA0874'], - ['#E1EE32', '#FFB547'], - ['#FFD804', '#2ACCC8'], - ['#E9A6D2', '#E9037B'], - ['#F8EC70', '#49E2F6'], - ['#A2F8CD', '#A2F852'], - ['#49E2F6', '#A2F8CD'], - ['#FDEFE2', '#FE214F'], - ['#F8EC70', '#A2F8CD'], - ['#F8EC70', '#49E2F6'], - ['#D1FFB7', '#FFB7D1'], - ['#B7FFE4', '#E4B7FF'], - ['#FFB7D1', '#E4B7FF'], - ['#D0E6A5', '#86E3CE'], - ['#E8E965', '#64C5C7'], - ]; + chartColors () { + let colorArr = [['#FFF000', '#E62490'], ['#FDEB71', '#F8D800'], ['#ABDCFF', '#0396FF'], ['#FEB692', '#EA5455'], ['#FEB692', '#EA5455'], ['#CE9FFC', '#7367F0'], ['#90F7EC', '#32CCBC'], ['#FFF6B7', '#F6416C'], ['#E2B0FF', '#9F44D3'], ['#F97794', '#F072B6'], ['#FCCF31', '#F55555'], ['#5EFCE8', '#736EFE'], ['#FAD7A1', '#E96D71'], ['#FFFF1C', '#00C3FF'], ['#FEC163', '#DE4313'], ['#F6CEEC', '#D939CD'], ['#FDD819', '#E80505'], ['#FFF3B0', '#CA26FF'], ['#2AFADF', '#4C83FF'], ['#EECDA3', '#EF629F'], ['#C2E59C', '#64B3F4'], ['#FFF886', '#F072B6'], ['#F5CBFF', '#C346C2'], ['#FFF720', '#3CD500'], ['#EE9AE5', '#5961F9'], ['#FFC371', '#FF5F6D'], ['#FFD3A5', '#FD6585'], ['#C2FFD8', '#465EFB'], ['#FFC600', '#FD6E6A'], ['#FFC600', '#FD6E6A'], ['#92FE9D', '#00C9FF'], ['#FFDDE1', '#EE9CA7'], ['#F0FF00', '#58CFFB'], ['#FFE985', '#FA742B'], ['#72EDF2', '#5151E5'], ['#F6D242', '#FF52E5'], ['#F9D423', '#FF4E50'], ['#3C8CE7', '#00EAFF'], ['#FCFF00', '#FFA8A8'], ['#FF96F9', '#C32BAC'], ['#D0E6A5', '#FFDD94'], ['#FFDD94', '#FA897B'], ['#FFCC4B', '#FF7D58'], ['#D0E6A5', '#86E3CE'], ['#F0D5B6', '#F16238'], ['#F8EC70', '#F9C708'], ['#C4E86B', '#00BCB4'], ['#F5CEC7', '#E79796'], ['#FFC446', '#FA0874'], ['#E1EE32', '#FFB547'], ['#FFD804', '#2ACCC8'], ['#E9A6D2', '#E9037B'], ['#F8EC70', '#49E2F6'], ['#A2F8CD', '#A2F852'], ['#49E2F6', '#A2F8CD'], ['#FDEFE2', '#FE214F'], ['#F8EC70', '#A2F8CD'], ['#F8EC70', '#49E2F6'], ['#D1FFB7', '#FFB7D1'], ['#B7FFE4', '#E4B7FF'], ['#FFB7D1', '#E4B7FF'], ['#D0E6A5', '#86E3CE'], ['#E8E965', '#64C5C7']]; let chartColors = colorArr[Math.floor(Math.random() * colorArr.length)]; //chartColors = ['#DB36A4', '#F7FF00']; // 固定京豆图表填充颜色 return chartColors; } - colorfulBar() { - let colorArr = [ - ['#1B9E77', '#D95F02', '#7570B3', '#E7298A', '#66A61E', '#E6AB02'], - ['#D53E4F', '#FC8D59', '#FEE08B', '#E6F598', '#99D594', '#3288BD'], - ['#A6CEE3', '#1F78B4', '#B2DF8A', '#33A02C', '#FB9A99', '#E31A1C'], - ['#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#FFFF33'], - ['#F81B02', '#FC7715', '#AFBF41', '#50C49F', '#3B95C4', '#B560D4'], - ['#FFC000', '#A5D028', '#08CC78', '#F24099', '#5AA6C0', '#F56617'], - ['#F09415', '#C1B56B', '#4BAF73', '#5AA6C0', '#D17DF9', '#FA7E5C'], - ['#0F6FC6', '#009DD9', '#0BD0D9', '#10CF9B', '#7CCA62', '#A5C249'], - ['#2C7C9F', '#244A58', '#E2751D', '#FFB400', '#7EB606', '#C00000'], - ['#AC3EC1', '#477BD1', '#46B298', '#90BA4C', '#DD9D31', '#E25247'], - ['#9ACD4C', '#FAA93A', '#D35940', '#B258D3', '#63A0CC', '#8AC4A7'], - ['#A7EA52', '#EFAB16', '#78AC35', '#35ACA2', '#4083CF', '#FF8021'], - ['#2DA2BF', '#DA1F28', '#EB641B', '#39639D', '#474B78', '#7D3C4A'], - ['#9EC544', '#50BEA3', '#4A9CCC', '#9A66CA', '#C54F71', '#DE9C3C'], - ['#41AEBD', '#97E9D5', '#A2CF49', '#608F3D', '#F4DE3A', '#FCB11C'], - ['#2FA3EE', '#4BCAAD', '#86C157', '#D99C3F', '#CE6633', '#A35DD1'], - ['#3399FF', '#69FFFF', '#CCFF33', '#3333FF', '#9933FF', '#FF33FF'], - ['#FBC01E', '#EFE1A2', '#FA8716', '#BE0204', '#A5D848', '#7E13E3'], - ['#90C226', '#54A021', '#E6B91E', '#E76618', '#C42F1A', '#918655'], - ['#0F6FC6', '#009DD9', '#0BD0D9', '#10CF9B', '#7CCA62', '#A5C249'], - ['#FFB91D', '#F97817', '#6DE304', '#FF0000', '#732BEA', '#C913AD'], - ['#C70F0C', '#DD6B0D', '#FAA700', '#93E50D', '#17C7BA', '#0A96E4'], - ['#40BAD2', '#FAB900', '#90BB23', '#EE7008', '#1AB39F', '#D5393D'], - ['#B71E42', '#DE478E', '#BC72F0', '#795FAF', '#586EA6', '#6892A0'], - ['#80B606', '#E29F1D', '#2397E2', '#35ACA2', '#5430BB', '#8D34E0'], - ['#549E39', '#8AB833', '#C0CF3A', '#029676', '#4AB5C4', '#0989B1'], - ['#99CB38', '#63A537', '#37A76F', '#44C1A3', '#4EB3CF', '#51C3F9'], - ['#8C73D0', '#C2E8C4', '#C5A6E8', '#B45EC7', '#9FDAFB', '#95C5B0'], - ['#749805', '#BACC82', '#6E9EC2', '#2046A5', '#5039C6', '#7411D0'], - ['#1CADE4', '#2683C6', '#27CED7', '#42BA97', '#3E8853', '#62A39F'], - ['#B01513', '#EA6312', '#E6B729', '#6AAC90', '#5F9C9D', '#9E5E9B'], - ['#B31166', '#E33D6F', '#E45F3C', '#E9943A', '#9B6BF2', '#D53DD0'], - ['#76C5EF', '#FEA022', '#FF6700', '#70A525', '#A5D848', '#20768C'], - ['#A1D68B', '#5EC795', '#4DADCF', '#CDB756', '#E29C36', '#8EC0C1'], - ['#418AB3', '#A6B727', '#F69200', '#80C34F', '#FEC306', '#DF5327'], - ['#7FD13B', '#EA157A', '#FEB80A', '#00ADDC', '#738AC8', '#1AB39F'], - ['#F0AD00', '#60B5CC', '#E66C7D', '#6BB76D', '#E88651', '#C64847'], - ['#5B9BD5', '#ED7D31', '#A5D848', '#FFC000', '#4472C4', '#70AD47'], - ['#4F81BD', '#C0504D', '#9BBB59', '#8064A2', '#4BACC6', '#F79646'], - ['#B83D68', '#AC66BB', '#DE6C36', '#F9B639', '#CF6DA4', '#FA8D3D'], - ['#F2D908', '#9DE61E', '#0D8BE6', '#C61B1B', '#E26F08', '#8D35D1'], - ['#A5B592', '#F3A447', '#E7BC29', '#D092A7', '#9C85C0', '#809EC2'], - ['#30ACEC', '#80C34F', '#E29D3E', '#D64A3B', '#D64787', '#A666E1'], - ['#A2C816', '#E07602', '#E4C402', '#7DC1EF', '#21449B', '#A2B170'], - ['#FF7F01', '#F1B015', '#FBEC85', '#D2C2F1', '#DA5AF4', '#9D09D1'], - ['#FDA023', '#A7EA52', '#5ECCF3', '#64A73B', '#EB5605', '#B9CA1A'], - ['#00C6BB', '#6FEBA0', '#B6DF5E', '#EFB251', '#EF755F', '#ED515C'], - ['#E84C22', '#FFBD47', '#B64926', '#FF8427', '#CC9900', '#B22600'], - ['#E32D91', '#C830CC', '#4EA6DC', '#4775E7', '#8971E1', '#D54773'], - ['#1CADE4', '#2683C6', '#27CED7', '#42BA97', '#3E8853', '#62A39F'], - ['#A63212', '#E68230', '#9BB05E', '#6B9BC7', '#4E66B2', '#8976AC'], - ['#073779', '#8FD9FB', '#FFCC00', '#EB6615', '#C76402', '#B523B4'], - ['#4E67C8', '#5ECCF3', '#A7EA52', '#5DCEAF', '#FF8021', '#F14124'], - ['#3891A7', '#FEB80A', '#C32D2E', '#84AA33', '#964305', '#475A8D'], - ['#990000', '#FF6600', '#FFBA00', '#99CC00', '#528A02', '#9C007F'], - ['#F7901E', '#FEC60B', '#9FE62F', '#4EA5D1', '#1C4596', '#542D90'], - ['#51A6C2', '#51C2A9', '#7EC251', '#E1DC53', '#B54721', '#A16BB1'], - ['#E8BC4A', '#83C1C6', '#E78D35', '#909CE1', '#839C41', '#CC5439'], - ['#86CE24', '#00A2E6', '#FAC810', '#7D8F8C', '#D06B20', '#FF8021'], - ['#DF2E28', '#FE801A', '#E9BF35', '#81BB42', '#32C7A9', '#4A9BDC'], - ['#92278F', '#9B57D3', '#755DD9', '#665EB8', '#45A5ED', '#5982DB'], - ['#31B6FD', '#4584D3', '#5BD078', '#A5D028', '#F5C040', '#05E0DB'], - ['#A53010', '#DE7E18', '#9F8351', '#728653', '#92AA4C', '#6AAC91'], - ['#FFCA08', '#F8931D', '#CE8D3E', '#EC7016', '#E64823', '#9C6A6A'], - ['#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F', '#EDC948'], - ['#4E79A7', '#A0CBE8', '#F28E2B', '#FFBE7D', '#59A14F', '#8CD17D'], - ['#E03531', '#F0BD27', '#51B364', '#FF684C', '#FFDA66', '#8ACE7E'], - ['#4E9F50', '#87D180', '#EF8A0C', '#FCC66D', '#3CA8BC', '#98D9E4'], - ['#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', '#9467BD', '#E377C2'], - ['#32A251', '#ACD98D', '#FF7F0F', '#FFB977', '#3CB7CC', '#98D9E4'], - ['#2C69B0', '#F02720', '#AC613C', '#6BA3D6', '#EA6B73', '#E9C39B'], - ]; + colorfulBar () { + let colorArr = [['#1B9E77', '#D95F02', '#7570B3', '#E7298A', '#66A61E', '#E6AB02'], ['#F46277', '#FC8D59', '#FEE08B', '#E6F598', '#99D594', '#3288BD'], ['#A6CEE3', '#1F78B4', '#B2DF8A', '#33A02C', '#FB9A99', '#E31A1C'], ['#E41A1C', '#377EB8', '#4DAF4A', '#984EA3', '#FF7F00', '#9ED80E'], ['#F81B02', '#FC7715', '#AFBF41', '#50C49F', '#3B95C4', '#B560D4'], ['#FFC000', '#A5D028', '#08CC78', '#F24099', '#5AA6C0', '#F56617'], ['#F09415', '#C1B56B', '#4BAF73', '#5AA6C0', '#D17DF9', '#FA7E5C'], ['#0F6FC6', '#009DD9', '#0BD0D9', '#10CF9B', '#7CCA62', '#A5C249'], ['#9ACD4C', '#FAA93A', '#D35940', '#B258D3', '#63A0CC', '#8AC4A7'], ['#A7EA52', '#EFAB16', '#78AC35', '#35ACA2', '#4083CF', '#FF8021'], ['#9EC544', '#50BEA3', '#4A9CCC', '#9A66CA', '#C54F71', '#DE9C3C'], ['#41AEBD', '#97E9D5', '#A2CF49', '#608F3D', '#F4DE3A', '#FCB11C'], ['#2FA3EE', '#4BCAAD', '#86C157', '#D99C3F', '#CE6633', '#A35DD1'], ['#3399FF', '#69FFFF', '#CCFF33', '#3333FF', '#9933FF', '#FF33FF'], ['#FBC01E', '#EFE1A2', '#FA8716', '#F2575F', '#A5D848', '#A155F9'], ['#90C226', '#54A021', '#E6B91E', '#E76618', '#C42F1A', '#FA8716'], ['#0F6FC6', '#009DD9', '#0BD0D9', '#10CF9B', '#7CCA62', '#A5C249'], ['#FFB91D', '#F97817', '#6DE304', '#F98080', '#8F58F9', '#F789EA'], ['#C70F0C', '#DD6B0D', '#FAA700', '#93E50D', '#17C7BA', '#0A96E4'], ['#40BAD2', '#FAB900', '#90BB23', '#EE7008', '#1AB39F', '#D5393D'], ['#80B606', '#E29F1D', '#2397E2', '#35ACA2', '#5430BB', '#8D34E0'], ['#549E39', '#8AB833', '#C0CF3A', '#029676', '#4AB5C4', '#0989B1'], ['#99CB38', '#63A537', '#37A76F', '#44C1A3', '#4EB3CF', '#51C3F9'], ['#8C73D0', '#C2E8C4', '#C5A6E8', '#B45EC7', '#9FDAFB', '#95C5B0'], ['#1CADE4', '#2683C6', '#27CED7', '#42BA97', '#3E8853', '#62A39F'], ['#B31166', '#E33D6F', '#E45F3C', '#E9943A', '#9B6BF2', '#D53DD0'], ['#76C5EF', '#FEA022', '#FF6700', '#70A525', '#A5D848', '#20768C'], ['#A1D68B', '#5EC795', '#4DADCF', '#CDB756', '#E29C36', '#8EC0C1'], ['#418AB3', '#A6B727', '#F69200', '#80C34F', '#FEC306', '#DF5327'], ['#7FD13B', '#EA157A', '#FEB80A', '#00ADDC', '#738AC8', '#1AB39F'], ['#F0AD00', '#60B5CC', '#E66C7D', '#6BB76D', '#E88651', '#C64847'], ['#5B9BD5', '#ED7D31', '#A5D848', '#FFC000', '#4472C4', '#70AD47'], ['#4F81BD', '#C0504D', '#9BBB59', '#8064A2', '#4BACC6', '#F79646'], ['#F95F9A', '#AC66BB', '#DE6C36', '#F9B639', '#CF6DA4', '#FA8D3D'], ['#F2D908', '#9DE61E', '#0D8BE6', '#C61B1B', '#E26F08', '#8D35D1'], ['#A5B592', '#F3A447', '#E7BC29', '#D092A7', '#9C85C0', '#809EC2'], ['#30ACEC', '#80C34F', '#E29D3E', '#D64A3B', '#D64787', '#A666E1'], ['#A2C816', '#E07602', '#E4C402', '#7DC1EF', '#21449B', '#A2B170'], ['#FF7F01', '#F1B015', '#FBEC85', '#D2C2F1', '#DA5AF4', '#9D09D1'], ['#FDA023', '#A7EA52', '#5ECCF3', '#64A73B', '#EB5605', '#B9CA1A'], ['#00C6BB', '#6FEBA0', '#B6DF5E', '#EFB251', '#EF755F', '#ED515C'], ['#E32D91', '#C830CC', '#4EA6DC', '#4775E7', '#8971E1', '#D54773'], ['#1CADE4', '#2683C6', '#27CED7', '#42BA97', '#3E8853', '#62A39F'], ['#073779', '#8FD9FB', '#FFCC00', '#EB6615', '#C76402', '#B523B4'], ['#4E67C8', '#5ECCF3', '#A7EA52', '#5DCEAF', '#FF8021', '#F14124'], ['#3891A7', '#FEB80A', '#FC8389', '#84AA33', '#F9934E', '#4379EF'], ['#990000', '#FF6600', '#FFBA00', '#99CC00', '#528A02', '#9C007F'], ['#F7901E', '#FEC60B', '#9FE62F', '#4EA5D1', '#4282EA', '#854FED'], ['#E8BC4A', '#83C1C6', '#E78D35', '#909CE1', '#839C41', '#F9826E'], ['#86CE24', '#00A2E6', '#FAC810', '#AA69F7', '#D06B20', '#FF8021'], ['#DF2E28', '#FE801A', '#E9BF35', '#81BB42', '#32C7A9', '#4A9BDC'], ['#31B6FD', '#4584D3', '#5BD078', '#A5D028', '#F5C040', '#05E0DB'], ['#FFCA08', '#F8931D', '#CE8D3E', '#EC7016', '#E64823', '#9C6A6A'], ['#4E79A7', '#F28E2B', '#E15759', '#76B7B2', '#59A14F', '#EDC948'], ['#4E79A7', '#A0CBE8', '#F28E2B', '#FFBE7D', '#59A14F', '#8CD17D'], ['#E03531', '#F0BD27', '#51B364', '#FF684C', '#FFDA66', '#8ACE7E'], ['#4E9F50', '#87D180', '#EF8A0C', '#FCC66D', '#3CA8BC', '#98D9E4'], ['#1F77B4', '#FF7F0E', '#2CA02C', '#D62728', '#9467BD', '#E377C2'], ['#32A251', '#ACD98D', '#FF7F0F', '#FFB977', '#3CB7CC', '#98D9E4'], ]; let chartColors = colorArr[Math.floor(Math.random() * colorArr.length)]; - //chartColors = ['#1B9E77', '#D95F02', '#7570B3', '#E7298A', '#66A61E', '#E6AB02']; // 固定京豆图表填充颜色 + //chartColors = ['#C1B14A','#6FBC75','#39B6B3','#86A1CD','#D083AB','#DF786B']; // 固定京豆图表填充颜色 return chartColors; } - isSmall(a = false) { + isSmall (a = false) { if (a) return config.widgetFamily == 'small' ? true : false; else return config.widgetFamily == 'small' ? '_small' : ''; } @@ -465,29 +306,20 @@ class Widget extends DmYY { await this.setHeaderShow(bodyStack); bodyStack.addSpacer(); switch (this.chartSetting.smallShowType) { - case '折线图表': - await this.setChartShow(bodyStack, 1); - break; - case '柱状图表': - await this.setChartShow(bodyStack, 2); - break; + case '折线图表' : + await this.setChartShow(bodyStack, 1); + break; + case '柱状图表' : + await this.setChartShow(bodyStack, 2); + break; case '曲线面积图': - await this.setChartShow(bodyStack, 3); - break; + await this.setChartShow(bodyStack, 3); + break; default: - await this.setBeanShow( - bodyStack, - 22 * this.basicSetting.scale, - 40 * this.basicSetting.scale, - ); + await this.setBeanShow(bodyStack, 22 * this.basicSetting.scale, 40 * this.basicSetting.scale); } bodyStack.addSpacer(5 * this.basicSetting.scale); - if (this.expireBean.number > 0) { - await this.setExpireBeanShow(bodyStack, true); - } else if ( - this.funcSetting.showBaitiao === '打开' && - this.baitiao.number > 0 - ) { + if (this.funcSetting.showBaitiao === '打开' && this.baitiao.number > 0) { await this.setBaitiaoShow(bodyStack, true); } else if (this.basicSetting.walletShowType === '红包') { await this.setRedPackageShow(bodyStack, true); @@ -496,7 +328,7 @@ class Widget extends DmYY { } } return w; - }; + } // #####################中组件################### renderMedium = async (w) => { @@ -513,32 +345,23 @@ class Widget extends DmYY { } else { switch (this.chartSetting.showType) { case '折线图表': - await this.setChartShow(mainStack, 1); - mainStack.addSpacer(5 * this.basicSetting.scale); - break; + await this.setChartShow(mainStack, 1); + mainStack.addSpacer(5 * this.basicSetting.scale); + break; case '柱状图表': - await this.setChartShow(mainStack, 2); - mainStack.addSpacer(5 * this.basicSetting.scale); - break; + await this.setChartShow(mainStack, 2); + mainStack.addSpacer(5 * this.basicSetting.scale); + break; case '曲线面积图': - await this.setChartShow(mainStack, 3); - mainStack.addSpacer(5 * this.basicSetting.scale); - break; + await this.setChartShow(mainStack, 3); + mainStack.addSpacer(5 * this.basicSetting.scale); + break; default: - await this.setBeanShow( - mainStack, - 30 * this.basicSetting.scale, - 50 * this.basicSetting.scale, - ); - mainStack.addSpacer(); + await this.setBeanShow(mainStack, 30 * this.basicSetting.scale, 50 * this.basicSetting.scale); + mainStack.addSpacer(); } } - if (this.expireBean.number > 0) { - await this.setExpireBeanShow(mainStack); - } else if ( - this.funcSetting.showBaitiao === '打开' && - this.baitiao.number > 0 - ) { + if (this.funcSetting.showBaitiao === '打开' && this.baitiao.number > 0) { await this.setBaitiaoShow(mainStack); } else if (this.basicSetting.walletShowType === '红包') { await this.setRedPackageShow(mainStack); @@ -546,7 +369,7 @@ class Widget extends DmYY { await this.setCoinShow(mainStack); } return w; - }; + } // #####################大组件################### renderLarge = async (w) => { @@ -564,68 +387,68 @@ class Widget extends DmYY { emoji.centerAlignText(); w.addSpacer(); return w; - }; + } // #####################用户信息################### async setUserShow(stack) { const userStack = stack.addStack(); - userStack.size = new Size( - this.basicSetting.userStack * this.basicSetting.scale, - 0, - ); + userStack.size = new Size(this.basicSetting.userStack * this.basicSetting.scale, 0); userStack.layoutVertically(); // 头像 const userImgStack = userStack.addStack(); userImgStack.addSpacer(); const imgStack = userImgStack.addStack(); if (this.isPlus) { - imgStack.size = new Size( - this.basicSetting.userImage * this.basicSetting.scale, - this.basicSetting.userImage * this.basicSetting.scale * 1.039, - ); - imgStack.backgroundImage = await this.getImageByUrl( - this.plusBG, - 'plusBGImage.png', - ); + imgStack.size = new Size(this.basicSetting.userImage * this.basicSetting.scale, this.basicSetting.userImage * this.basicSetting.scale * 1.039); + imgStack.backgroundImage = await this.getImageByUrl(this.plusBG, 'plusBGImage.png'); } const subStack = imgStack.addStack(); subStack.url = 'openapp.jdmobile://'; - subStack.size = new Size( - this.basicSetting.userImage * this.basicSetting.scale, - this.basicSetting.userImage * this.basicSetting.scale, - ); - subStack.cornerRadius = - (this.basicSetting.userImage / 2) * this.basicSetting.scale; - subStack.backgroundImage = await this.getImageByUrl( - this.basicSetting.customizeAvatar || this.userImage, - `userImage_${this.userName}.png`, - ); + subStack.size = new Size(this.basicSetting.userImage * this.basicSetting.scale, this.basicSetting.userImage * this.basicSetting.scale); + subStack.cornerRadius = this.basicSetting.userImage / 2 * this.basicSetting.scale; + subStack.backgroundImage = await this.getImageByUrl(this.basicSetting.customizeAvatar || this.userImage, `userImage_${this.userName}.png`); if (this.isPlus) { - const userImg = subStack.addImage( - await this.getImageByUrl(this.plusFG, 'plusFGImage.png'), - ); + const userImg = subStack.addImage(await this.getImageByUrl(this.plusFG, 'plusFGImage.png')); } userImgStack.addSpacer(); userStack.addSpacer(); // 物流提示 const tipStack = userStack.addStack(); tipStack.addSpacer(); - let signIcon = SFSymbol.named('checkmark.circle.fill'); - const signItem = tipStack.addImage(signIcon.image); - signItem.tintColor = new Color('007aff'); // 签到提示图标颜色 - signItem.imageSize = new Size( - 14 * this.basicSetting.scale, - 14 * this.basicSetting.scale, - ); + const signStack = tipStack.addStack(); + signStack.size = new Size(14 * this.basicSetting.scale, 14 * this.basicSetting.scale) + signStack.backgroundColor = new Color('0dD6A0'); + signStack.cornerRadius = 14 * this.basicSetting.scale / 2; + signStack.centerAlignContent(); + let signIcon = SFSymbol.named('checkmark'); + const signItem = signStack.addImage(signIcon.image); + signItem.imageSize = new Size(8 * this.basicSetting.scale, 8 * this.basicSetting.scale); + signItem.tintColor = new Color('FFFFFF'); if (this.package.number > 0) { tipStack.addSpacer(3 * this.basicSetting.scale); - const packageIcon = SFSymbol.named(this.package.number + '.circle.fill'); - const packageItem = tipStack.addImage(packageIcon.image); - packageItem.imageSize = new Size( - 14 * this.basicSetting.scale, - 14 * this.basicSetting.scale, - ); - packageItem.tintColor = new Color('FC8600'); // 物流提示图标颜色 + const packageStack = tipStack.addStack(); + packageStack.size = new Size(14 * this.basicSetting.scale, 14 * this.basicSetting.scale) + packageStack.backgroundColor = new Color('FC8600'); + packageStack.cornerRadius = 14 * this.basicSetting.scale / 2; + packageStack.centerAlignContent(); + packageStack.setPadding(1 * this.basicSetting.scale, 2 * this.basicSetting.scale, 1 * this.basicSetting.scale, 2 * this.basicSetting.scale); + let packageNum = packageStack.addText(this.package.number.toString()); + packageNum.font = Font.mediumSystemFont(15 * this.basicSetting.scale); + packageNum.textColor = new Color('FFFFFF'); + packageNum.minimumScaleFactor = 0.1; + } + if (this.funcSetting.showFruit === '打开') { + tipStack.addSpacer(3 * this.basicSetting.scale); + const fruitStack = tipStack.addStack(); + fruitStack.size = new Size(14 * this.basicSetting.scale, 14 * this.basicSetting.scale) + fruitStack.backgroundColor = new Color('118AB2'); + fruitStack.cornerRadius = 14 * this.basicSetting.scale / 2; + fruitStack.centerAlignContent(); + fruitStack.setPadding(1 * this.basicSetting.scale, 2 * this.basicSetting.scale, 1 * this.basicSetting.scale, 2 * this.basicSetting.scale); + let fruitText = fruitStack.addText(this.fruitState); + fruitText.font = Font.mediumSystemFont(15 * this.basicSetting.scale); + fruitText.textColor = new Color('FFFFFF'); + fruitText.minimumScaleFactor = 0.1; } tipStack.addSpacer(); userStack.addSpacer(); @@ -633,39 +456,22 @@ class Widget extends DmYY { const nameStack = userStack.addStack(); nameStack.centerAlignContent(); if (this.isPlus) { - const nameImg = nameStack.addImage( - await this.getImageByUrl(this.plusIcon, 'plusIcon.png'), - ); - nameImg.imageSize = new Size( - 15 * this.basicSetting.scale, - 15 * this.basicSetting.scale, - ); + const nameImg = nameStack.addImage(await this.getImageByUrl(this.plusIcon, 'plusIcon.png')); + nameImg.imageSize = new Size(15 * this.basicSetting.scale, 15 * this.basicSetting.scale); } else { - const person = SFSymbol.named('person.circle.fill'); - const nameIcon = nameStack.addImage(person.image); - nameIcon.imageSize = new Size( - 15 * this.basicSetting.scale, - 15 * this.basicSetting.scale, - ); - nameIcon.tintColor = new Color('007aff'); // 昵称前图标颜色,Plus用户改不了 + const nameIcon = nameStack.addImage(await this.getImageByUrl(this.nameImg, 'nameImg.png')); + nameIcon.imageSize = new Size(15 * this.basicSetting.scale, 15 * this.basicSetting.scale); } nameStack.addSpacer(5 * this.basicSetting.scale); - const name = nameStack.addText( - this.basicSetting.customizeName || this.nickName, - ); + const name = nameStack.addText(this.basicSetting.customizeName || this.nickName); name.lineLimit = 1; name.font = Font.regularSystemFont(14 * this.basicSetting.scale); userStack.addSpacer(5 * this.basicSetting.scale); // 京享值 const valueStack = userStack.addStack(); valueStack.centerAlignContent(); - const tagIcon = SFSymbol.named('tag.circle.fill'); - const lableIcon = valueStack.addImage(tagIcon.image); - lableIcon.imageSize = new Size( - 15 * this.basicSetting.scale, - 15 * this.basicSetting.scale, - ); - lableIcon.tintColor = new Color('fa2d19'); // 京享值前图标颜色 + const lableIcon = valueStack.addImage(await this.getImageByUrl(this.tagImg, 'tagImg.png')); + lableIcon.imageSize = new Size(15 * this.basicSetting.scale, 15 * this.basicSetting.scale); valueStack.addSpacer(5 * this.basicSetting.scale); const value = valueStack.addText(this.jValue.toString()); value.font = Font.mediumSystemFont(14 * this.basicSetting.scale); @@ -674,64 +480,43 @@ class Widget extends DmYY { const jStack = valueStack.addStack(); jStack.backgroundColor = new Color('fa2d19'); // “京享”二字背景颜色 jStack.cornerRadius = 5; - jStack.setPadding( - 1 * this.basicSetting.scale, - 4 * this.basicSetting.scale, - 1 * this.basicSetting.scale, - 4 * this.basicSetting.scale, - ); + jStack.setPadding(1 * this.basicSetting.scale, 4 * this.basicSetting.scale, 1 * this.basicSetting.scale, 4 * this.basicSetting.scale); const jLable = jStack.addText('京享'); jLable.font = Font.systemFont(8 * this.basicSetting.scale); - jLable.textColor = new Color('FFFFFF'); // “京享”二字字体颜色 - [name, value].map((t) => (t.textColor = this.widgetColor)); + jLable.textColor = new Color('FFFFFF') // “京享”二字字体颜色 + ;[name, value].map(t => t.textColor = this.widgetColor); } // #####################顶部内容################### async setHeaderShow(stack, image) { const topStack = stack.addStack(); topStack.centerAlignContent(); - if (this.widgetFamily === 'small') { - const avatarStack = topStack.addStack(); - avatarStack.size = new Size( - this.basicSetting.logo * this.basicSetting.scale, - this.basicSetting.logo * this.basicSetting.scale, - ); - avatarStack.cornerRadius = - (avatarStack.size.width / 2) * this.basicSetting.scale; - avatarStack.backgroundImage = await this.getImageByUrl( - this.basicSetting.customizeAvatar || this.userImage, - `userImage_${this.userName}.png`, - ); + if (image) { + const JDLogo = topStack.addImage(await this.getImageByUrl(this.logo, 'logoImage.png')); + JDLogo.imageSize = new Size(this.basicSetting.logo * this.basicSetting.scale, this.basicSetting.logo * this.basicSetting.scale); + topStack.addSpacer(10 * this.basicSetting.scale); + const JD = topStack.addImage(await this.getImageByUrl(image, 'jingdongImage.png')); + JD.imageSize = new Size(194 * 0.2 * this.basicSetting.scale, 78 * 0.2 * this.basicSetting.scale); + } else { + const imgStack = topStack.addStack(); if (this.isPlus) { - avatarStack.addImage( - await this.getImageByUrl(this.plusFG, 'plusFGImage.png'), - ); + imgStack.size = new Size(30 * this.basicSetting.scale, 30 * this.basicSetting.scale * 1.039); + imgStack.backgroundImage = await this.getImageByUrl(this.plusBG, 'plusBGImage.png'); } - } else { - const JDLogo = topStack.addImage( - await this.getImageByUrl(this.logo, 'logoImage.png'), - ); - JDLogo.imageSize = new Size( - this.basicSetting.logo * this.basicSetting.scale, - this.basicSetting.logo * this.basicSetting.scale, - ); - if (image) { - topStack.addSpacer(10 * this.basicSetting.scale); - const JD = topStack.addImage( - await this.getImageByUrl(image, 'jingdongImage.png'), - ); - JD.imageSize = new Size( - 194 * 0.2 * this.basicSetting.scale, - 78 * 0.2 * this.basicSetting.scale, - ); + const subStack = imgStack.addStack(); + subStack.url = 'openapp.jdmobile://'; + subStack.size = new Size(30 * this.basicSetting.scale, 30 * this.basicSetting.scale); + subStack.cornerRadius = 30 / 2 * this.basicSetting.scale; + subStack.backgroundImage = await this.getImageByUrl(this.basicSetting.customizeAvatar || this.userImage, `userImage_${this.userName}.png`); + if (this.isPlus) { + const userImg = subStack.addImage(await this.getImageByUrl(this.plusFG, 'plusFGImage.png')); } } topStack.addSpacer(); const jdBean = topStack.addText(this.beanCount.toString()); jdBean.font = Font.mediumSystemFont(20 * this.basicSetting.scale); jdBean.textColor = new Color('fa2d19'); // 右上角京豆数颜色 - jdBean.url = - 'openapp.jdmobile://virtual?params=%7B%22category%22%3A%22jump%22%2C%22des%22%3A%22m%22%2C%22url%22%3A%22https%3A%2F%2Fbean.m.jd.com%2FbeanDetail%2Findex.action%3FresourceValue%3Dbean%22%7D'; + jdBean.url = 'openapp.jdmobile://virtual?params=%7B%22category%22%3A%22jump%22%2C%22des%22%3A%22m%22%2C%22url%22%3A%22https%3A%2F%2Fbean.m.jd.com%2FbeanDetail%2Findex.action%3FresourceValue%3Dbean%22%7D'; const desStack = topStack.addStack(); desStack.layoutVertically(); desStack.addSpacer(5.5 * this.basicSetting.scale); @@ -747,17 +532,12 @@ class Widget extends DmYY { const yestodayStack = beanStack.addStack(); yestodayStack.layoutVertically(); try { - this.bean.ydayIncome = - this.rangeTimer[this.yestoday][0] - this.rangeTimer[this.yestoday][1]; + this.bean.ydayIncome = this.rangeTimer[this.yestoday][0] - this.rangeTimer[this.yestoday][1]; this.bean.ydayExpense = this.rangeTimer[this.yestoday][1]; - this.bean.todayIncome = - this.rangeTimer[this.today][0] - this.rangeTimer[this.today][1]; + this.bean.todayIncome = this.rangeTimer[this.today][0] - this.rangeTimer[this.today][1];; this.bean.todayExpense = this.rangeTimer[this.today][1]; } catch (e) { - this.notify( - this.name, - '\u597d\u50cf\u4f60\u6628\u5929\u6ca1\u6709\u4f7f\u7528\u8be5\u5c0f\u7ec4\u4ef6\uff0c\u8bf7\u91cd\u7f6e\u4eac\u8c46\u6570\u636e', - ); + this.notify(this.name, '\u597d\u50cf\u4f60\u6628\u5929\u6ca1\u6709\u4f7f\u7528\u8be5\u5c0f\u7ec4\u4ef6\uff0c\u8bf7\u91cd\u7f6e\u4eac\u8c46\u6570\u636e'); } this.rowBeanCell( yestodayStack, @@ -765,14 +545,12 @@ class Widget extends DmYY { this.bean.ydayIncome.toString(), textSize, '昨日', - ); + ); beanStack.addSpacer(); // 京豆图片 const ddStack = beanStack.addStack(); ddStack.layoutVertically(); - const ddImg = ddStack.addImage( - await this.getImageByUrl(this.beanImg, 'beanImage.png'), - ); + const ddImg = ddStack.addImage(await this.getImageByUrl(this.beanImg, 'beanImage.png')); ddImg.imageSize = new Size(imageSize, imageSize); beanStack.addSpacer(); // 昨日收支 @@ -784,18 +562,18 @@ class Widget extends DmYY { this.bean.todayIncome.toString(), textSize, '今日', - ); + ); } // #####################京豆图表################### async setChartShow(stack, type) { - let labels = [], - data = []; + let labels = [], data = []; Object.keys(this.rangeTimer).forEach((day) => { const value = this.rangeTimer[day]; const arrDay = day.split('-'); labels.push(arrDay[2]); - if (this.chartSetting.countBean === '收入-支出') data.push(value[0]); + if (this.chartSetting.countBean === '收入-支出') + data.push(value[0]); else data.push(value[0] - value[1]); }); let cacheKey = `chart${type}Image${this.isSmall()}_${this.userName}.png`; @@ -812,17 +590,15 @@ class Widget extends DmYY { let chartStr; switch (type) { case 2: - chartStr = this.barChart(labels, data, textSize, barPadding, 'bar'); - break; + chartStr = this.barChart(labels, data, textSize, barPadding, 'bar'); + break; case 3: - chartStr = this.barChart(labels, data, textSize, barPadding, 'line'); - break; + chartStr = this.barChart(labels, data, textSize, barPadding, 'line'); + break; default: - chartStr = this.lineChart(labels, data, textSize, linePadding); + chartStr = this.lineChart(labels, data, textSize, linePadding); } - const url = `https://quickchart.io/chart?w=${400}&h=${ - this.chartSetting.height - }&f=png&c=${encodeURIComponent(chartStr)}`; + const url = `https://quickchart.io/chart?w=${400}&h=${this.chartSetting.height}&f=png&c=${encodeURIComponent(chartStr)}`; const chart = await this.getImageByUrl(url, cacheKey, this.cacheChart); const chartStack = stack.addStack(); @@ -832,14 +608,9 @@ class Widget extends DmYY { for (let i = 0; i < showDays; i++) { beanDateStack.addSpacer(); let subStack = beanDateStack.addStack(); - let beanDay = beanDateStack.addText( - `${labels[i]}${this.chartSetting.dayText}`, - ); + let beanDay = beanDateStack.addText(`${labels[i]}${this.chartSetting.dayText}`); beanDay.textColor = this.widgetColor; - beanDay.font = new Font( - 'ArialMT', - this.chartSetting.daySize * this.basicSetting.scale, - ); + beanDay.font = new Font('ArialMT', this.chartSetting.daySize * this.basicSetting.scale); beanDay.textOpacity = 0.8; beanDateStack.addSpacer(); } @@ -864,11 +635,9 @@ class Widget extends DmYY { const time = statusStack.addText(this.package.time); statusStack.addSpacer(); const status = statusStack.addText(this.package.status); - [title, desc, time, status].map((t) => (t.textColor = this.widgetColor)); - [time, status].map( - (t) => (t.font = Font.regularSystemFont(9 * this.basicSetting.scale)), - ); - [time, status].map((t) => (t.textOpacity = 0.7)); + ;[title, desc, time, status].map(t => t.textColor = this.widgetColor); + ;[time, status].map(t => t.font = Font.regularSystemFont(9 * this.basicSetting.scale)); + ;[time, status].map(t => t.textOpacity = 0.7); } // #####################金贴&钢镚################## @@ -888,52 +657,28 @@ class Widget extends DmYY { // #####################京东红包################## async setRedPackageShow(stack, small = false) { await this.getRedPackageData(); - const walletImage = await this.getImageByUrl( - this.walletImg, - 'walletImage.png', - ); - small - ? this.rowSmallWalletCell(stack, walletImage, this.redPackage) - : this.rowWalletCell(stack, walletImage, this.redPackage); + const walletImage = await this.getImageByUrl(this.walletImg, 'walletImage.png'); + small ? this.rowSmallWalletCell(stack, walletImage, this.redPackage) : this.rowWalletCell(stack, walletImage, this.redPackage); } // #####################京东白条################## async setBaitiaoShow(stack, small = false) { - const baitiaoImage = await this.getImageByUrl( - this.baitiaoImg, - 'baitiaoImage.png', - ); - small - ? this.rowSmallWalletCell(stack, baitiaoImage, this.baitiao) - : this.rowWalletCell(stack, baitiaoImage, this.baitiao); - } - - // #####################过期京豆################## - async setExpireBeanShow(stack, small = false) { - const walletImage = await this.getImageByUrl( - this.walletImg, - 'walletImage.png', - ); - small - ? this.rowSmallWalletCell(stack, walletImage, this.expireBean) - : this.rowWalletCell(stack, walletImage, this.expireBean); + const baitiaoImage = await this.getImageByUrl(this.baitiaoImg, 'baitiaoImage.png'); + small ? this.rowSmallWalletCell(stack, baitiaoImage, this.baitiao) : this.rowWalletCell(stack, baitiaoImage, this.baitiao); } rowCell(stack, image, value, title) { const rowStack = stack.addStack(); rowStack.centerAlignContent(); const rowImage = rowStack.addImage(image); - rowImage.imageSize = new Size( - 13 * this.basicSetting.scale, - 13 * this.basicSetting.scale, - ); + rowImage.imageSize = new Size(13 * this.basicSetting.scale, 13 * this.basicSetting.scale); rowStack.addSpacer(); const rowValue = rowStack.addText(value); rowValue.font = Font.mediumSystemFont(15 * this.basicSetting.scale); rowStack.addSpacer(); const rowTitle = rowStack.addText(title); rowTitle.font = Font.regularSystemFont(13 * this.basicSetting.scale); - [rowValue, rowTitle].map((t) => (t.textColor = this.widgetColor)); + ;[rowValue, rowTitle].map(t => t.textColor = this.widgetColor); } rowBeanCell(stack, min, add, textSize, label) { @@ -948,19 +693,16 @@ class Widget extends DmYY { const rowThree = stack.addStack(); const minText = rowThree.addText(min); minText.font = Font.mediumSystemFont(10 * this.basicSetting.scale); - minText.textColor = new Color('fa2d19'); // 支出京豆颜色 + minText.textColor = new Color('fa2d19'); // 支出京豆颜色 } - [labelText, rowNumber].map((t) => (t.textColor = this.widgetColor)); + ;[labelText, rowNumber].map(t => t.textColor = this.widgetColor); } rowWalletCell(stack, image, data) { const stackOne = stack.addStack(); stackOne.centerAlignContent(); const stackImage = stackOne.addImage(image); - stackImage.imageSize = new Size( - 127 * 0.17 * this.basicSetting.scale, - 75 * 0.17 * this.basicSetting.scale, - ); + stackImage.imageSize = new Size(127 * 0.17 * this.basicSetting.scale, 75 * 0.17 * this.basicSetting.scale); stackOne.addSpacer(5 * this.basicSetting.scale); const title = stackOne.addText(data.title); title.font = Font.regularSystemFont(13 * this.basicSetting.scale); @@ -971,17 +713,14 @@ class Widget extends DmYY { const desc = stackOne.addText(data.desc); desc.font = Font.regularSystemFont(10 * this.basicSetting.scale); desc.textOpacity = 0.7; - [title, number, desc].map((t) => (t.textColor = this.widgetColor)); + ;[title, number, desc].map(t => t.textColor = this.widgetColor); } rowSmallWalletCell(stack, image, data) { const stackOne = stack.addStack(); stackOne.centerAlignContent(); const stackImage = stackOne.addImage(image); - stackImage.imageSize = new Size( - 127 * 0.17 * this.basicSetting.scale, - 75 * 0.17 * this.basicSetting.scale, - ); + stackImage.imageSize = new Size(127 * 0.17 * this.basicSetting.scale, 75 * 0.17 * this.basicSetting.scale); stackOne.addSpacer(); const number = stackOne.addText(`${data.number}`); number.font = Font.mediumSystemFont(15 * this.basicSetting.scale); @@ -994,33 +733,24 @@ class Widget extends DmYY { const desc = stackTwo.addText(data.desc); desc.font = Font.regularSystemFont(10 * this.basicSetting.scale); desc.textOpacity = 0.7; - [number, title, desc].map((t) => (t.textColor = this.widgetColor)); + ;[number, title, desc].map(t => t.textColor = this.widgetColor); } init = async () => { try { let beanCacheKey = `beanData${this.isSmall()}_${this.userName}`; - let beanCacheData = !this.loadStringCache(beanCacheKey) - ? {} - : JSON.parse(this.loadStringCache(beanCacheKey)); - let beanCache = beanCacheData.data - ? beanCacheData.data.assetInfo.beanNum - : 0; + let beanCacheData = !this.loadStringCache(beanCacheKey) ? {} : JSON.parse(this.loadStringCache(beanCacheKey)); + let beanCache = beanCacheData.data ? beanCacheData.data.assetInfo.beanNum : 0; await this.TotalBean(); - await this.getJValue(); + await this.wxData(); console.log(`京豆数据:${beanCache}`); console.log(`京豆数据:${this.beanCount}`); if (!this.cookie) return; if (Keychain.contains(this.CACHE_KEY)) { this.rangeTimer = JSON.parse(Keychain.get(this.CACHE_KEY)); - if ( - this.rangeTimer.hasOwnProperty(this.today) && - beanCache !== 0 && - beanCache == this.beanCount - ) { - this.cacheChart = - this.funcSetting.alwaysRefreshChart === '打开' ? false : true; + if (this.rangeTimer.hasOwnProperty(this.today) && beanCache !== 0 && beanCache == this.beanCount) { + this.cacheChart = this.funcSetting.alwaysRefreshChart ==='打开' ? false : true; console.log('京豆数据:无变化,使用缓存数据'); return; } @@ -1047,14 +777,14 @@ class Widget extends DmYY { getAmountData = async () => { let i = 0, - page = 1; + page = 1; do { const response = await this.getJingBeanBalanceDetail(page); const result = response.code === '0'; console.log(`第${page}页:${result ? '请求成功' : '请求失败'}`); if (response.code === '3') { i = 1; - this.notify(this.name, response.message); + this.notify(this.name, response.message) console.log(response); } if (response && result) { @@ -1066,7 +796,8 @@ class Widget extends DmYY { if (this.timerKeys.indexOf(dates[0]) > -1) { const amount = Number(item.amount); this.rangeTimer[dates[0]][0] += amount; - if (amount < 0) this.rangeTimer[dates[0]][1] += amount; + if (amount < 0) + this.rangeTimer[dates[0]][1] += amount; } else { i = 1; Keychain.set(this.CACHE_KEY, JSON.stringify(this.rangeTimer)); @@ -1076,7 +807,7 @@ class Widget extends DmYY { } } } while (i === 0); - }; + } getDay(dayNumber) { let data = {}; @@ -1105,29 +836,44 @@ class Widget extends DmYY { cookie: this.cookie, }, }; - const response = await this.httpRequest( - dataName, - url, - true, - options, - userCache, - ); + const response = await this.httpRequest(dataName, url, true, options, userCache); try { if (response.retcode === '0' && response['data']) { this.beanCount = response.data.assetInfo.beanNum; - this.userImage = - response.data.userInfo.baseInfo.headImageUrl.replace(/big/, 'mid') || - 'https://img11.360buyimg.com/jdphoto/s120x120_jfs/t21160/90/706848746/2813/d1060df5/5b163ef9N4a3d7aa6.png'; + this.userImage = response.data.userInfo.baseInfo.headImageUrl.replace(/big/, 'mid') || 'https://img11.360buyimg.com/jdphoto/s120x120_jfs/t21160/90/706848746/2813/d1060df5/5b163ef9N4a3d7aa6.png'; this.nickName = response.data.userInfo.baseInfo.nickname; this.isPlus = response.data.userInfo.isPlusVip === '1' ? true : false; } else { this.notify(this.name, response.msg); - console.log('京豆数据:获取失败,' + response.msg); + console.log('京豆数据:获取失败,' + response.msg) } } catch (e) { console.log(e); + console.log('京豆数据:获取失败,') } - }; + } + + wxData = async () => { + const dataName = '微信数据'; + let userCache = `wxData${this.isSmall()}`; + const url = 'https://wxapp.m.jd.com/kwxhome/myJd/home.json?&useGuideModule=0&bizId=&brandId=&fromType=wxapp'; + const options = { + headers: { + cookie: this.cookie, + }, + }; + const response = await this.httpRequest(dataName, url, true, options, userCache); + try { + if (response['user']) { + this.jValue = response.user.uclass.replace(/[^0-9]/ig, ''); + } else { + this.notify(this.name, response.msg); + console.log('微信数据:获取失败,' + response.msg) + } + } catch (e) { + console.log(e); + } + } getJingBeanBalanceDetail = async (page) => { try { @@ -1148,7 +894,7 @@ class Widget extends DmYY { Accept: `application/json, text/javascript, */*; q=0.01`, }, }; - let params = { ...options, method: 'POST' }; + let params = {...options, method: 'POST'}; let request = new Request(params.url); Object.keys(params).forEach((key) => { request[key] = params[key]; @@ -1157,7 +903,7 @@ class Widget extends DmYY { } catch (e) { console.log(e); } - }; + } getExtraData = async () => { const JTDataName = '金贴数据'; @@ -1171,36 +917,23 @@ class Widget extends DmYY { }, }; try { - const JTData = await this.httpRequest( - JTDataName, - JTUrl, - true, - options, - 'jintieData', - ); - const GBData = await this.httpRequest( - GBDataName, - GBUrl, - true, - options, - 'gangbengData', - ); + const JTData = await this.httpRequest(JTDataName, JTUrl, true, options, 'jintieData'); + const GBData = await this.httpRequest(GBDataName, GBUrl, true, options, 'gangbengData'); if (JTData.resultCode === 0) { this.extra.jingtie = JTData.resultData.data['balance']; } else { this.notify(this.name, JTdata.resultMsg); console.log('金贴数据:获取失败,' + JTdata.resultMsg); - } + }; if (GBData.gbBalance) this.extra.gangbeng = GBData.gbBalance; - } catch (e) { + } catch(e) { console.log(e); } - }; + } getPackageData = async () => { const dataName = '包裹数据'; - const url = - 'https://wq.jd.com/bases/wuliudetail/notify?sceneval=2&sceneval=2&g_login_type=1&callback'; + const url ='https://wq.jd.com/bases/wuliudetail/notify?sceneval=2&sceneval=2&g_login_type=1&callback'; const options = { headers: { cookie: this.cookie, @@ -1208,21 +941,12 @@ class Widget extends DmYY { }, }; try { - const data = await this.httpRequest( - dataName, - url, - true, - options, - 'packageData', - ); + const data = await this.httpRequest(dataName, url, true, options, 'packageData'); if (data.errCode == 0 && data['dealLogList']) { console.log('包裹数据:获取成功'); console.log(`包裹数据:您有${data['dealLogList'].length}个包裹`); if (data['dealLogList'].length > 0) { - let item = - data.dealLogList[ - Math.floor(Math.random() * data['dealLogList'].length) - ]; + let item = data.dealLogList[Math.floor(Math.random() * data['dealLogList'].length)] this.package.number = data.dealLogList.length; this.package.title = item['name']; this.package.desc = item['wlStateDesc']; @@ -1231,16 +955,16 @@ class Widget extends DmYY { } } else { console.log('包裹数据:获取失败'); - } + } } catch (e) { console.log(e); } - }; + } getRedPackageData = async () => { const dataName = '红包数据'; const url = - 'https://wq.jd.com/user/info/QueryUserRedEnvelopes?channel=1&type=0&page=0&pageSize=0&expiredRedFlag=1&sceneval=2&g_login_type=1'; + 'https://wq.jd.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=3&sceneval=2&g_login_type=1'; const options = { headers: { cookie: this.cookie, @@ -1248,17 +972,10 @@ class Widget extends DmYY { }, }; try { - const data = await this.httpRequest( - dataName, - url, - true, - options, - 'redPackageData', - ); + const data = await this.httpRequest(dataName, url, true, options, 'redPackageData'); if (data.errcode === 0) { this.redPackage.number = data.data.balance ? data.data.balance : 0; - if (data.data.expiredBalance && data.data.expiredBalance !== '') - this.redPackage.desc = `今日过期${data.data.expiredBalance}`; + if (data.data.expiredBalance && data.data.expiredBalance !== '') this.redPackage.desc = `即将过期${data.data.expiredBalance}`; } else { this.notify(this.name, data.msg); console.log('红包数据:获取失败,' + data.msg); @@ -1266,47 +983,7 @@ class Widget extends DmYY { } catch (e) { console.log(e); } - }; - - getExipireBean = async () => { - const dataName = '过期京豆'; - const url = - 'https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=g_login_type=1&sceneval=2'; - const options = { - headers: { - cookie: this.cookie, - Referer: 'https://wqs.jd.com/promote/201801/bean/mybean.html', - }, - }; - try { - let data = await this.httpRequest( - dataName, - url, - false, - options, - 'exipireBeanData', - ); - if (data) { - data = JSON.parse(data.slice(23, -13)); - if (data.ret === 0) { - for (let i = 0; i < data['expirejingdou'].length; i++) { - if (data['expirejingdou'][i]['expireamount'] > 0) { - this.expireBean.number = data['expirejingdou'][i]['expireamount']; - this.expireBean.desc = this.timeFormat( - data['expirejingdou'][i]['time'] * 1000, - ); - break; - } - } - } else { - this.notify(this.name, data.errmsg); - console.log('过期京豆:获取失败,' + data.errmsg); - } - } - } catch (e) { - console.log(e); - } - }; + } getJValue = async () => { const dataName = '京享数据'; @@ -1317,22 +994,16 @@ class Widget extends DmYY { }, }; try { - const data = await this.httpRequest( - dataName, - url, - true, - options, - 'JValue', - ); + const data = await this.httpRequest(dataName, url, true, options, 'JValue'); if (data.code === 0) { this.jValue = data.model.scoreDescription.userScore.score; } else { console.log('京享数据:获取失败'); - } + }; } catch (e) { console.log(e); } - }; + } getBaitiaoData = async () => { const dataName = '白条数据'; @@ -1344,31 +1015,49 @@ class Widget extends DmYY { }, }; try { - const data = await this.httpRequest( - dataName, - url, - true, - options, - 'baitiaoData', - 'POST', - false, - ); + const data = await this.httpRequest(dataName, url, true, options, 'baitiaoData', 'POST', false); if (data.resultCode !== 0) { return this.notify(this.name, data['resultMsg']); } this.baitiao.title = data['resultData']['data']['bill']['title']; - this.baitiao.number = data['resultData']['data']['bill'][ - 'amount' - ].replace(/,/g, ''); - this.baitiao.desc = data['resultData']['data']['bill'][ - 'buttonName' - ].replace(/最近还款日/, ''); + this.baitiao.number = data['resultData']['data']['bill']['amount'].replace(/,/g, ''); + this.baitiao.desc = data['resultData']['data']['bill']['buttonName'].replace(/最近还款日/, ''); } catch (e) { console.log(e); } - }; + } - getImageByUrl = async (url, cacheKey, useCache = true, logable = true) => { + getFruitData = async () => { + const dataName = '东东农场'; + const url = 'https://api.m.jd.com/client.action?functionId=initForFarm'; + const options = { + body: 'body=version:4&appid=wh5&clientVersion=9.1.0', + headers: { + 'User-Agent': 'jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0', + 'Content-Type': 'application/x-www-form-urlencoded', + 'cookie': this.cookie, + }, + }; + try { + const data = await this.httpRequest(dataName, url, true, options, 'FruitData', 'POST', false); + if (data.msg && data.msg == 'not login') { + this.fruitState = "X"; + } + else if (data.farmUserPro.treeState == 2 || data.farmUserPro.treeState == 3) { + this.fruitState = "100"; + } + else if (data.farmUserPro.treeState == 0) { + this.fruitState = "X"; + } + else { + this.fruitState = Math.floor((data.farmUserPro.treeEnergy / data.farmUserPro.treeTotalEnergy) * 100).toString(); + } + } catch (e) { + console.log(e); + } + } + + getImageByUrl = async(url, cacheKey, useCache = true, logable = true) => { if (this.CACHES.indexOf(cacheKey) < 0) { this.CACHES.push(cacheKey); this.settings.CACHES = this.CACHES; @@ -1403,12 +1092,12 @@ class Widget extends DmYY { ctx.fillRect(new Rect(0, 0, 80, 80)); return await ctx.getImage(); } - }; + } saveImgCache(cacheKey, img) { if (!this.fm.fileExists(this.cachePath)) { this.fm.createDirectory(this.cachePath, true); - } + }; const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); this.fm.writeImage(cacheFile, img); } @@ -1423,15 +1112,7 @@ class Widget extends DmYY { return img; } - httpRequest = async ( - dataName, - url, - json = true, - options, - key, - method = 'GET', - logable = this.funcSetting.logable === '打开', - ) => { + httpRequest = async(dataName, url, json = true, options, key, method = 'GET', logable = this.funcSetting.logable === '打开') => { let cacheKey = `${key}_${this.userName}`; if (this.CACHES.indexOf(cacheKey) < 0) { this.CACHES.push(cacheKey); @@ -1440,17 +1121,10 @@ class Widget extends DmYY { } const localCache = this.loadStringCache(cacheKey); const lastCacheTime = this.getCacheModificationDate(cacheKey); - const timeInterval = Math.floor( - (this.getCurrentTimeStamp() - lastCacheTime) / 60, - ); + const timeInterval = Math.floor((this.getCurrentTimeStamp() - lastCacheTime) / 60); console.log( - `${dataName}:缓存${timeInterval}分钟前,有效期${this.basicSetting.interval}分钟,${localCache.length}`, - ); - if ( - timeInterval < this.basicSetting.interval && - localCache != null && - localCache.length > 0 - ) { + `${dataName}:缓存${timeInterval}分钟前,有效期${this.basicSetting.interval}分钟,${localCache.length}`); + if (timeInterval < this.basicSetting.interval && localCache != null && localCache.length > 0) { console.log(`${dataName}:读取缓存`); return json ? JSON.parse(localCache) : localCache; } @@ -1475,7 +1149,7 @@ class Widget extends DmYY { console.log(`${dataName}:在线请求响应数据:${JSON.stringify(data)}`); } return data; - }; + } loadStringCache(cacheKey) { const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); @@ -1490,7 +1164,7 @@ class Widget extends DmYY { saveStringCache(cacheKey, content) { if (!this.fm.fileExists(this.cachePath)) { this.fm.createDirectory(this.cachePath, true); - } + }; const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); this.fm.writeString(cacheFile, content); } @@ -1509,22 +1183,6 @@ class Widget extends DmYY { return new Date().getTime() / 1000; } - removeCache(cacheKey) { - const cacheFile = this.fm.joinPath(this.cachePath, cacheKey); - const fileExists = this.fm.fileExists(cacheFile); - if (fileExists) { - this.fm.remove(cacheFile); - console.log(`清除缓存:${cacheKey}`); - } - return; - } - - removeCaches(cacheKeyList) { - for (const cacheKey of cacheKeyList) { - this.removeCache(cacheKey); - } - } - timeFormat(time) { let date; if (time) { @@ -1532,22 +1190,13 @@ class Widget extends DmYY { } else { date = new Date(); } - return ( - (date.getMonth() + 1 >= 10 - ? date.getMonth() + 1 - : '0' + (date.getMonth() + 1)) + - '月' + - (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) + - '日' - ); + return ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '月' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()) + '日'; } - async updateCheck(version) { + async updateCheck(version){ let data; try { - let updateCheck = new Request( - 'https://raw.githubusercontent.com/anker1209/Scriptable/main/upcoming.json', - ); + let updateCheck = new Request('https://raw.githubusercontent.com/anker1209/Scriptable/main/upcoming.json'); data = await updateCheck.loadJSON(); if (data.version != version) { let updata = new Alert(); @@ -1555,13 +1204,10 @@ class Widget extends DmYY { updata.addAction('去Github更新'); updata.addAction('网页版商店更新'); updata.addCancelAction('稍后'); - updata.message = - '\n更新说明:\n' + data.notes + '\n\n点击相应按钮更新脚本'; + updata.message = '\n更新说明:\n' + data.notes + '\n\n点击相应按钮更新脚本'; let id = await updata.present(); if (id == 0) { - Safari.openInApp( - 'https://raw.githubusercontent.com/anker1209/Scriptable/main/scripts/JD-in-one-v2.js', - ); + Safari.openInApp('https://raw.githubusercontent.com/anker1209/Scriptable/main/scripts/JD-in-one-v2.js'); } else if (id == 1) { Safari.openInApp('http://scriptablejs.gitee.io/store/#/menu/myInfo'); } else { @@ -1574,7 +1220,7 @@ class Widget extends DmYY { updata.message = `\n当前版本 ${version} 为最新版本`; await updata.present(); } - } catch (e) { + } catch(e) { console.log(e); } } @@ -1584,9 +1230,7 @@ class Widget extends DmYY { table.showSeparators = false; let data; try { - let faq = new Request( - 'https://raw.githubusercontent.com/anker1209/Scriptable/main/faq.json', - ); + let faq = new Request('https://raw.githubusercontent.com/anker1209/Scriptable/main/faq.json'); data = await faq.loadJSON(); let info = new UITableRow(); info.height = parseFloat(data.height); @@ -1597,26 +1241,20 @@ class Widget extends DmYY { table.addRow(info); for (let i = 0; i < data.data.length; i++) { let header = new UITableRow(); - header.backgroundColor = Color.dynamic( - new Color('F5F5F5'), - new Color('000000'), - ); - let heading = header.addText(data.data[i].name); + header.backgroundColor = Color.dynamic(new Color('F5F5F5'), new Color('000000'));; + let heading = header.addText(data.data[i].name) heading.titleFont = Font.mediumSystemFont(17); heading.centerAligned(); table.addRow(header); data.data[i].item.forEach((faq) => { - let row = new UITableRow(); - row.height = parseFloat(faq['height']); - let rowtext = row.addText(faq['question'], faq['answer']); - rowtext.titleFont = Font.mediumSystemFont(16); - rowtext.titleColor = Color.blue(); - rowtext.subtitleFont = Font.systemFont(14); - rowtext.subtitleColor = Color.dynamic( - new Color('000000', 0.7), - new Color('ffffff', 0.7), - ); - table.addRow(row); + let row = new UITableRow(); + row.height = parseFloat(faq['height']); + let rowtext = row.addText(faq['question'], faq['answer']); + rowtext.titleFont = Font.mediumSystemFont(16); + rowtext.titleColor = Color.blue(); + rowtext.subtitleFont = Font.systemFont(14); + rowtext.subtitleColor = Color.dynamic(new Color('000000', 0.7), new Color('ffffff', 0.7)); + table.addRow(row); }); } } catch (e) { @@ -1627,7 +1265,7 @@ class Widget extends DmYY { async settingCategory(table, item, outfit, category) { let header = new UITableRow(); - let heading = header.addText(outfit); + let heading = header.addText(outfit) heading.titleFont = Font.mediumSystemFont(17); heading.centerAligned(); table.addRow(header); @@ -1647,23 +1285,12 @@ class Widget extends DmYY { row.dismissOnSelect = false; row.onSelect = async () => { if (data.type == 'text') { - await this.alertInput( - data['title'], - data['desc'], - category, - data['option'], - ); + await this.alertInput(data['title'], data['desc'], category, data['option']); } else if (data.type == 'menu') { - await this.showAlert( - data['title'], - data['desc'], - data['menu'], - category, - key, - ); + await this.showAlert(data['title'], data['desc'], data['menu'], category, key,); } await this.tableContent(table); - }; + } table.addRow(row); }); }); @@ -1672,209 +1299,39 @@ class Widget extends DmYY { async tableContent(table) { const basic = [ - { - type: 'text', - title: '全局缩放比例', - desc: '排版溢出、显示不全的请优先调低此数,建议递减0.05调整,如0.95、0.90……\n\n缺省值:1.00', - option: { scale: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/scale.png', - }, - { - type: 'text', - title: '京东标志大小', - desc: '京东logo(形象狗)大小\n\n缺省值:30', - option: { logo: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/logo.png', - }, - { - type: 'text', - title: '用户头像大小', - desc: '⚠️注意:若要修改头像,请在京东app上传后将缓存清除再运行脚本。\n\n缺省值:69', - option: { userImage: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/userImage.png', - }, - { - type: 'text', - title: '左侧栏宽度', - desc: '左侧用户信息栏整体宽度\n\n缺省值:103', - option: { userStack: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/userStack.png', - }, - { - type: 'text', - title: '左右栏间距', - desc: '左侧用户信息栏与右侧京豆数据间距\n\n缺省值:25', - option: { division: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/division.png', - }, - { - type: 'text', - title: '缓存时间', - desc: '数据请求间隔时间\n请设置合适时间,避免频繁访问接口数据以及加载缓慢。单位:分钟\n\n缺省值:10', - option: { interval: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/interval.png', - }, - { - type: 'text', - title: '自定义昵称', - desc: '自定义用户信息栏的昵称名称,\n留空将显示京东账号昵称。\n\n注意:单脚本多账户若使用自定义昵称,所有账户将同时显示此昵称,如需单独自定义昵称,请复制脚本单独设置。', - option: { customizeName: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/customizeName.png', - }, - { - type: 'text', - title: '自定义头像', - desc: '自定义用户信息栏的头像,\n留空将显示京东APP头像。\n\n注意:单脚本多账户若使用自定义头像,所有账户将同时显示此头像,如需单独自定义头像,请复制脚本单独设置。', - option: { customizeAvatar: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/customizeAvatar.png', - }, - { - type: 'menu', - title: '小组件显示内容', - desc: '\n缺省值:京豆、钱包数据', - option: { smallShowType: '' }, - menu: ['京豆、钱包数据', '个人信息'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/smallShowType.png', - }, - { - type: 'menu', - title: '钱包显示类型', - desc: '若要显示钱包内容,白条需关闭或者白条打开的情况下无待还白条。\n\n缺省值:红包', - option: { walletShowType: '' }, - menu: ['红包', '钢镚和金贴'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/walletShowType.png', - }, + {type: 'text', title: '全局缩放比例', desc: '排版溢出、显示不全的请优先调低此数,建议递减0.05调整,如0.95、0.90……\n\n缺省值:1.00', option: {scale: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/scale.png'}, + {type: 'text', title: '京东标志大小', desc: '京东logo(形象狗)大小\n\n缺省值:30', option: {logo: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/logo.png'}, + {type: 'text', title: '用户头像大小', desc: '⚠️注意:若要修改头像,请在京东app上传后将缓存清除再运行脚本。\n\n缺省值:69', option: {userImage: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/userImage.png'}, + {type: 'text', title: '左侧栏宽度', desc: '左侧用户信息栏整体宽度\n\n缺省值:103', option: {userStack: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/userStack.png'}, + {type: 'text', title: '左右栏间距', desc: '左侧用户信息栏与右侧京豆数据间距\n\n缺省值:25', option: {division: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/division.png'}, + {type: 'text', title: '缓存时间', desc: '数据请求间隔时间\n请设置合适时间,避免频繁访问接口数据以及加载缓慢。单位:分钟\n\n缺省值:10', option: {interval: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/interval.png'}, + {type: 'menu', title: '缓存位置', desc: '将缓存保存在Local或者iCloud。\n\n缺省值:Local', option: {directory: ''}, menu: ['Local', 'iCloud'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/directory.png'}, + {type: 'text', title: '自定义昵称', desc: '自定义用户信息栏的昵称名称,\n留空将显示京东账号昵称。\n\n注意:单脚本多账户若使用自定义昵称,所有账户将同时显示此昵称,如需单独自定义昵称,请复制脚本单独设置。', option: {customizeName: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/customizeName.png'}, + {type: 'text', title: '自定义头像', desc: '自定义用户信息栏的头像,\n留空将显示京东APP头像。\n\n注意:单脚本多账户若使用自定义头像,所有账户将同时显示此头像,如需单独自定义头像,请复制脚本单独设置。', option: {customizeAvatar: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/customizeAvatar.png'}, + {type: 'menu', title: '小组件显示内容', desc: '\n缺省值:京豆、钱包数据', option: {smallShowType: ''}, menu: ['京豆、钱包数据', '个人信息'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/smallShowType.png'}, + {type: 'menu', title: '钱包显示类型', desc: '若要显示钱包内容,白条需关闭或者白条打开的情况下无待还白条。\n\n缺省值:红包', option: {walletShowType: ''}, menu: ['红包', '钢镚和金贴'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/walletShowType.png'}, ]; const chart = [ - { - type: 'text', - title: '图表高度', - desc: '京豆数据未与日期对齐的,\n请调低此数值\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:130', - option: { height: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/height.png', - }, - { - type: 'text', - title: '日期文字大小', - desc: '京豆图表底部日期文字大小\n\n缺省值:9', - option: { daySize: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/daySize.png', - }, - { - type: 'text', - title: '日期文字后缀', - desc: '京豆图表底部日期文字后缀', - option: { dayText: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/dayText.png', - }, - { - type: 'text', - title: '京豆数文字大小', - desc: '京豆图表数据文字大小\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:18', - option: { textSize: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/textSize.png', - }, - { - type: 'text', - title: '京豆数白天颜色', - desc: '⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:999999', - option: { textDayColor: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/textDayColor.png', - }, - { - type: 'text', - title: '京豆数晚上颜色', - desc: '⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:999999', - option: { textNightColor: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/textNightColor.png', - }, - { - type: 'text', - title: '折线图线条颜色', - desc: '支持渐变色,每个颜色之间以英文逗号分隔,颜色值必须带“#”。\n\n缺省值:#C8E3FA, #ED402E', - option: { lineColor: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/lineColor.png', - }, - { - type: 'text', - title: '折线图表顶边距', - desc: '京豆折线图顶边距\n京豆数据在顶部被剪切显示不全的,\n请调高此数值。\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:15', - option: { linePadding: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/linePadding.png', - }, - { - type: 'text', - title: '柱状图表顶边距', - desc: '京豆柱状图和曲线面积图顶边距\n京豆数据在顶部被剪切显示不全的,\n请调高此数值。\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:5', - option: { barPadding: '' }, - icon: 'https://gitee.com/anker1209/image/raw/master/jd/barPadding.png', - }, - { - type: 'menu', - title: '小组件图表类型', - desc: '\n缺省值:双日视图', - option: { smallShowType: '' }, - menu: ['双日视图', '折线图表', '柱状图表', '曲线面积图'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/smallShowType2.png', - }, - { - type: 'menu', - title: '中组件图表类型', - desc: '\n缺省值:双日视图', - option: { showType: '' }, - menu: ['双日视图', '折线图表', '柱状图表', '曲线面积图'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/showType.png', - }, - { - type: 'menu', - title: '每日京豆数计算', - desc: '\n缺省值:收入-支出', - option: { countBean: '' }, - menu: ['收入-支出', '收入'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/countBean.png', - }, - { - type: 'menu', - title: '多彩柱状图', - desc: '设置为打开时仅对柱状图表生效\n\n缺省值:关闭', - option: { colorful: '' }, - menu: ['打开', '关闭'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/colorful.png', - }, + {type: 'text', title: '图表高度', desc: '京豆数据未与日期对齐的,\n请调低此数值\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:130', option: {height: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/height.png'}, + {type: 'text', title: '日期文字大小', desc: '京豆图表底部日期文字大小\n\n缺省值:9', option: {daySize: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/daySize.png'}, + {type: 'text', title: '日期文字后缀', desc: '京豆图表底部日期文字后缀', option: {dayText: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/dayText.png'}, + {type: 'text', title: '京豆数文字大小', desc: '京豆图表数据文字大小\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:18', option: {textSize: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/textSize.png'}, + {type: 'text', title: '京豆数白天颜色', desc: '⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:999999', option: {textDayColor: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/textDayColor.png'}, + {type: 'text', title: '京豆数晚上颜色', desc: '⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:999999', option: {textNightColor: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/textNightColor.png'}, + {type: 'text', title: '折线图线条颜色', desc: '支持渐变色,每个颜色之间以英文逗号分隔,颜色值必须带“#”。\n\n缺省值:#FA6859', option: {lineColor: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/lineColor.png'}, + {type: 'text', title: '折线图表顶边距', desc: '京豆折线图顶边距\n京豆数据在顶部被剪切显示不全的,\n请调高此数值。\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:15', option: {linePadding: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/linePadding.png'}, + {type: 'text', title: '柱状图表顶边距', desc: '京豆柱状图和曲线面积图顶边距\n京豆数据在顶部被剪切显示不全的,\n请调高此数值。\n\n⚠️如需即时查看调整效果,\n[功能设置]-->刷新图表 需打开。\n\n缺省值:5', option: {barPadding: ''}, icon: 'https://gitee.com/anker1209/image/raw/master/jd/barPadding.png'}, + {type: 'menu', title: '小组件图表类型', desc: '\n缺省值:双日视图', option: {smallShowType: ''}, menu: ['双日视图', '折线图表', '柱状图表', '曲线面积图'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/smallShowType2.png'}, + {type: 'menu', title: '中组件图表类型', desc: '\n缺省值:双日视图', option: {showType: ''}, menu: ['双日视图', '折线图表', '柱状图表', '曲线面积图'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/showType.png'}, + {type: 'menu', title: '每日京豆数计算', desc: '\n缺省值:收入-支出', option: {countBean: ''}, menu: ['收入-支出', '收入'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/countBean.png'}, + {type: 'menu', title: '多彩柱状图', desc: '设置为打开时仅对柱状图表生效\n\n缺省值:关闭', option: {colorful: ''}, menu: ['打开', '关闭'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/colorful.png'}, ]; const func = [ - { - type: 'menu', - title: '白条信息', - desc: '关闭或者打开后无待还白条的情况下,\n会显示基础设置里选择的钱包内容。\n\n缺省值:打开', - option: { showBaitiao: '' }, - menu: ['打开', '关闭'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/showBaitiao.png', - }, - { - type: 'menu', - title: '包裹信息', - desc: '只有中组件显示一条物流信息,\n若无物流信息会显示图表设置里选择的图表类型。\n\n缺省值:关闭', - option: { showPackage: '' }, - menu: ['打开', '关闭'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/showPackage.png', - }, - { - type: 'menu', - title: '运行日志', - desc: '出现数据异常请将此值设为true,\n查看运行日志。\n\n⚠️注意:\n查看运行日志需将缓存时间更改为0。\n\n缺省值:关闭', - option: { logable: '' }, - menu: ['打开', '关闭'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/logable.png', - }, - { - type: 'menu', - title: '刷新图表', - desc: '打开,每次刷新组件会随机刷新图表颜色(仅柱状图表和曲线面积图);关闭,则只有在京豆数据有变化的情况下刷新图表颜色及数据。建议在排版调整没有问题后,设置为关闭。设置为打开会加长数据载入时间。\n\n⚠️注意:图表设置选项里修改图表高度、颜色、文字大小、顶边距需打开此选项以查看即时反馈。\n\n缺省值:打开', - option: { alwaysRefreshChart: '' }, - menu: ['打开', '关闭'], - icon: 'https://gitee.com/anker1209/image/raw/master/jd/alwaysRefreshChart.png', - }, + {type: 'menu', title: '白条信息', desc: '关闭或者打开后无待还白条的情况下,\n会显示基础设置里选择的钱包内容。\n\n缺省值:打开', option: {showBaitiao: ''}, menu: ['打开', '关闭'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/showBaitiao.png'}, + {type: 'menu', title: '包裹信息', desc: '只有中组件显示一条物流信息,\n若无物流信息会显示图表设置里选择的图表类型。\n\n缺省值:关闭', option: {showPackage: ''}, menu: ['打开', '关闭'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/showPackage.png'}, + {type: 'menu', title: '农场进度', desc: '显示东东农场种植进度。\n\n缺省值:打开', option: {showFruit: ''}, menu: ['打开', '关闭'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/showFruit.png'}, + {type: 'menu', title: '运行日志', desc: '出现数据异常请将此值设为true,\n查看运行日志。\n\n⚠️注意:\n查看运行日志需将缓存时间更改为0。\n\n缺省值:关闭', option: {logable: ''}, menu: ['打开', '关闭'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/logable.png'}, + {type: 'menu', title: '刷新图表', desc: '打开,每次刷新组件会随机刷新图表颜色(仅柱状图表和曲线面积图);关闭,则只有在京豆数据有变化的情况下刷新图表颜色及数据。建议在排版调整没有问题后,设置为关闭。设置为打开会加长数据载入时间。\n\n⚠️注意:图表设置选项里修改图表高度、颜色、文字大小、顶边距需打开此选项以查看即时反馈。\n\n缺省值:打开', option: {alwaysRefreshChart: ''}, menu: ['打开', '关闭'], icon: 'https://gitee.com/anker1209/image/raw/master/jd/alwaysRefreshChart.png'}, ]; table.removeAllRows(); let topRow = new UITableRow(); @@ -1882,37 +1339,34 @@ class Widget extends DmYY { leftText.widthWeight = 0.25; leftText.onTap = async () => { await Safari.open('https://github.com/anker1209/Scriptable#jd_in_one'); - }; + } let faqText = topRow.addButton('常见问题'); faqText.widthWeight = 0.25; faqText.leftAligned(); faqText.onTap = async () => { await this.faqTable(); - }; + } let versionText = topRow.addButton('版本检测'); versionText.widthWeight = 0.25; versionText.rightAligned(); versionText.onTap = async () => { await this.updateCheck(this.version); - }; + } let rightText = topRow.addButton('电报群'); rightText.widthWeight = 0.25; rightText.rightAligned(); rightText.onTap = async () => { await Safari.open('https://t.me/Scriptable_JS'); - }; + } table.addRow(topRow); let header = new UITableRow(); - let heading = header.addText('重置设置'); + let heading = header.addText('重置设置') heading.titleFont = Font.mediumSystemFont(17); heading.centerAligned(); table.addRow(header); let row1 = new UITableRow(); - let rowtext1 = row1.addText( - '重置缓存', - '若需要修改头像或数据显示错误,尝试此操作', - ); + let rowtext1 = row1.addText('重置缓存','若需要修改头像或数据显示错误,尝试此操作'); rowtext1.titleFont = Font.systemFont(16); rowtext1.subtitleFont = Font.systemFont(12); rowtext1.subtitleColor = new Color('999999'); @@ -1922,51 +1376,43 @@ class Widget extends DmYY { const message = '所有在线请求的数据缓存将会被清空'; const index = await this.generateAlert(message, options); if (index === 0) return; - this.removeCaches(this.settings.CACHES); + this.fm.remove(this.cachePath); delete this.settings['CACHES']; this.saveSettings(); - }; + } table.addRow(row1); let row2 = new UITableRow(); - let rowtext2 = row2.addText( - '重置京豆数据', - '若京豆数据缺失或显示有误,尝试此操作', - ); + let rowtext2 = row2.addText('重置京豆数据','若京豆数据缺失或显示有误,尝试此操作'); rowtext2.titleFont = Font.systemFont(16); rowtext2.subtitleFont = Font.systemFont(12); rowtext2.subtitleColor = new Color('999999'); row2.dismissOnSelect = false; row2.onSelect = async () => { const options = ['取消', '重置']; - const message = - '若缺少京豆数据或显示为0(双日视图或图表的京豆数)采用此操作。京豆数据重置后,将会重新抓取近6天的京豆明细。请勿频繁使用,会产生大量数据'; + const message = '若缺少京豆数据或显示为0(双日视图或图表的京豆数)采用此操作。京豆数据重置后,将会重新抓取近6天的京豆明细。请勿频繁使用,会产生大量数据'; const index = await this.generateAlert(message, options); if (index === 0) return; Keychain.remove(this.settings.CACHE_KEY); delete this.settings.CACHE_KEY; this.saveSettings(); - }; + } table.addRow(row2); let row3 = new UITableRow(); - let rowtext3 = row3.addText( - '重置设置参数', - '设置参数绑定脚本文件名,请勿随意更改脚本文件名', - ); + let rowtext3 = row3.addText('重置设置参数','设置参数绑定脚本文件名,请勿随意更改脚本文件名'); rowtext3.titleFont = Font.systemFont(16); rowtext3.subtitleFont = Font.systemFont(12); rowtext3.subtitleColor = new Color('999999'); row3.dismissOnSelect = false; row3.onSelect = async () => { const options = ['取消', '重置']; - const message = - '本菜单里的所有设置参数将会重置为默认值,重置后请重新打开设置菜单'; + const message = '本菜单里的所有设置参数将会重置为默认值,重置后请重新打开设置菜单'; const index = await this.generateAlert(message, options); if (index === 0) return; delete this.settings['basicSetting']; delete this.settings['chartSetting']; delete this.settings['funcSetting']; this.saveSettings(); - }; + } table.addRow(row3); await this.settingCategory(table, basic, '基础设置', 'basicSetting'); await this.settingCategory(table, chart, '图表设置', 'chartSetting'); @@ -1998,10 +1444,10 @@ class Widget extends DmYY { let alert = new Alert(); alert.title = title; alert.message = message; - alert.addCancelAction('取消'); + alert.addCancelAction('取消') for (const option of options) { alert.addAction(option); - } + }; let id = await alert.presentAlert(); if (id === -1) return; this.settings[category][key] = options[id]; @@ -2009,89 +1455,54 @@ class Widget extends DmYY { } run = (filename, args) => { - if (!this.settings.basicSetting) - this.settings.basicSetting = this.basicSetting; + if(!this.settings.basicSetting) this.settings.basicSetting = this.basicSetting; Object.keys(this.basicSetting).forEach((key) => { - if (!this.settings.basicSetting.hasOwnProperty(key)) + if(!this.settings.basicSetting.hasOwnProperty(key)) this.settings['basicSetting'][key] = this.basicSetting[key]; }); - if (!this.settings.chartSetting) - this.settings.chartSetting = this.chartSetting; + if(!this.settings.chartSetting) this.settings.chartSetting = this.chartSetting; Object.keys(this.chartSetting).forEach((key) => { - if (!this.settings.chartSetting.hasOwnProperty(key)) + if(!this.settings.chartSetting.hasOwnProperty(key)) this.settings['chartSetting'][key] = this.chartSetting[key]; }); - if (!this.settings.funcSetting) - this.settings.funcSetting = this.funcSetting; + if(!this.settings.funcSetting) this.settings.funcSetting = this.funcSetting; Object.keys(this.funcSetting).forEach((key) => { - if (!this.settings.funcSetting.hasOwnProperty(key)) + if(!this.settings.funcSetting.hasOwnProperty(key)) this.settings['funcSetting'][key] = this.funcSetting[key]; }); - if (!this.settings.CACHES) this.settings.CACHES = []; + if(!this.settings.CACHES) this.settings.CACHES = []; this.CACHES = this.settings.CACHES; + if (this.settings['basicSetting']['directory'] === 'iCloud') this.fm = FileManager.iCloud(); + this.cachePath = this.fm.joinPath(this.fm.documentsDirectory(), this.CACHE_FOLDER); if (config.runsInApp) { - this.registerAction( - '参数配置', - this.editSettings, - 'https://gitee.com/anker1209/image/raw/master/jd/setting.png', - ); - this.registerAction( - '账号设置', - async () => { - const index = await this.generateAlert('设置账号信息', [ - '网站登录', - '手动输入', - ]); - if (index === 0) { - await this.jdWebView(); - } else { - await this.setAlertInput( - '账号设置', - '京东账号cookie\n\n⚠️\n用户名和cookie必须输入!\n多账号注意用户名不要重复!', - { - username: '用户名,必须输入!多账号勿重复!', - cookie: 'Cookie', - }, - ); - } - }, - 'https://gitee.com/anker1209/image/raw/master/jd/account.png', - ); - this.registerAction( - '代理缓存', - this.actionSettings, - 'https://gitee.com/anker1209/image/raw/master/jd/boxjs.png', - ); - this.registerAction( - '基础设置', - this.setWidgetConfig, - 'https://gitee.com/anker1209/image/raw/master/jd/preferences.png', - ); + this.registerAction('参数配置', this.editSettings, 'https://gitee.com/anker1209/image/raw/master/jd/setting.png'); + this.registerAction('账号设置', async () => { + const index = await this.generateAlert('设置账号信息', [ + '网站登录', + '手动输入', + ]); + if (index === 0) { + await this.jdWebView(); + } else { + await this.setAlertInput('账号设置', '京东账号cookie\n\n⚠️\n用户名和cookie必须输入!\n多账号注意用户名不要重复!', { + username: '用户名,必须输入!多账号勿重复!', + cookie: 'Cookie', + }); + } + }, 'https://gitee.com/anker1209/image/raw/master/jd/account.png'); + this.registerAction('代理缓存', this.actionSettings, 'https://gitee.com/anker1209/image/raw/master/jd/boxjs.png'); + this.registerAction('基础设置', this.setWidgetConfig, 'https://gitee.com/anker1209/image/raw/master/jd/preferences.png'); } Object.keys(this.settings['basicSetting']).forEach((key) => { - if ( - key == 'customizeName' || - key == 'customizeAvatar' || - key == 'smallShowType' || - key == 'walletShowType' - ) { + if (key == 'customizeName' || key == 'customizeAvatar' || key == 'smallShowType' || key == 'walletShowType' || key == 'directory') { this.basicSetting[key] = this.settings['basicSetting'][key]; } else if (!isNaN(this.settings['basicSetting'][key])) { this.basicSetting[key] = parseFloat(this.settings['basicSetting'][key]); } }); Object.keys(this.settings['chartSetting']).forEach((key) => { - if ( - key == 'textDayColor' || - key == 'textNightColor' || - key == 'showType' || - key == 'smallShowType' || - key == 'countBean' || - key == 'colorful' || - key == 'lineColor' || - key == 'dayText' - ) { + if (key == 'textDayColor' || key == 'textNightColor' || key =='showType' || key == 'smallShowType' || key == 'countBean' || key == 'colorful' || key == 'lineColor' || key == 'dayText') { this.chartSetting[key] = this.settings['chartSetting'][key]; } else if (!isNaN(this.settings['chartSetting'][key])) { this.chartSetting[key] = parseFloat(this.settings['chartSetting'][key]); @@ -2101,35 +1512,7 @@ class Widget extends DmYY { this.funcSetting[key] = this.settings['funcSetting'][key]; }); - let _md5 = this.md5(filename + this.en); - - if (this.funcSetting.logable === '打开') - console.log('当前配置内容:' + JSON.stringify(this.settings)); - - this.JDindex = - typeof args.widgetParameter === 'string' - ? parseInt(args.widgetParameter) - : false; - try { - let cookieData = this.settings.cookieData ? this.settings.cookieData : []; - if (this.JDindex !== false && cookieData[this.JDindex]) { - this.cookie = cookieData[this.JDindex]['cookie']; - this.userName = cookieData[this.JDindex]['userName']; - } else { - this.userName = this.settings.username; - this.cookie = this.settings.cookie; - } - if (!this.cookie) throw '京东 CK 获取失败'; - this.userName = decodeURI(this.userName); - this.CACHE_KEY = `cache_${_md5}_` + this.userName; - this.settings.CACHE_KEY = this.CACHE_KEY; - this.saveSettings(false); - - return true; - } catch (e) { - this.notify('错误提示', e); - return false; - } + }; jdWebView = async () => { @@ -2146,7 +1529,7 @@ class Widget extends DmYY { 'reqData={"clientType":"ios","clientVersion":"13.2.3","deviceId":"","environment":"3"}'; await req.loadJSON(); const cookies = req.response.cookies; - const account = { username: '', cookie: '' }; + const account = {username: '', cookie: ''}; const cookie = []; cookies.forEach((item) => { const value = `${item.name}=${item.value}`; @@ -2160,7 +1543,7 @@ class Widget extends DmYY { console.log(account); if (account.cookie) { - this.settings = { ...this.settings, ...account }; + this.settings = {...this.settings, ...account}; this.saveSettings(false); console.log(`${this.name}: cookie获取成功,请关闭窗口!`); this.notify(this.name, 'cookie获取成功,请关闭窗口!'); @@ -2232,15 +1615,50 @@ class Widget extends DmYY { } } + + async getCookie() { + this.JDindex = + typeof args.widgetParameter === 'string' + ? parseInt(args.widgetParameter) + : false; + let _md5 = this.md5(module.filename + this.en); + if (this.funcSetting.logable === '打开') console.log('当前配置内容:' + JSON.stringify(this.settings)); + await this._loadJDCk(); + this.JDindex = + typeof args.widgetParameter === "string" + ? parseInt(args.widgetParameter) + : false; + try { + if (this.JDindex !== false && this.JDindex + 1 > 0) { + this.cookie = this.CookiesData[this.JDindex]['cookie']; + this.userName =this.CookiesData[this.JDindex]["userName"]; + } else { + const cacheCookie = this.CookiesData.find(item=>item.userName === this.settings.username) || {}; + this.userName = cacheCookie.userName; + this.cookie = cacheCookie.cookie; + } + if (!this.cookie) throw "京东 CK 获取失败"; + this.userName = decodeURI(this.userName); + this.CACHE_KEY = `cache_${_md5}_` + this.userName; + this.settings.CACHE_KEY = this.CACHE_KEY; + this.saveSettings(false); + return true; + } catch (e) { + this.notify("错误提示", e); + return false; + } + } + async render() { + await this.getCookie(); if (!this.cookie || !this.userName) { this.notify(this.name, 'cookie或用户名未设置'); return; - } + }; await this.init(); await this.getPackageData(); - await this.getExipireBean(); if (this.funcSetting.showBaitiao === '打开') await this.getBaitiaoData(); + if (this.funcSetting.showFruit === '打开') await this.getFruitData(); if (this.funcSetting.logable === '打开') console.log(this.rangeTimer); const widget = new ListWidget(); const padding = 14 * this.basicSetting.scale; @@ -2256,6 +1674,4 @@ class Widget extends DmYY { } } -await Runing(Widget, '', false); - -//version:2.2.2 +await Runing(Widget, '', false); \ No newline at end of file From 043cc20357c8efbb3c5cc81bd1d5fa6be8321c66 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 4 Jan 2022 14:42:02 +0800 Subject: [PATCH 011/152] =?UTF-8?q?update:=20boxjs=20=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E7=9A=84=E6=8F=90=E5=8F=96=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 84de299..f2c9d6e 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -87,10 +87,10 @@ class DmYY { // 获取 boxJS 缓存 getCache = async (key) => { try { - const url = 'http://' + this.prefix + '/query/boxdata'; + const url = 'http://' + this.prefix + '/query/data/' + key; const boxdata = await this.$request.get(url); - if (key) return boxdata.datas[key]; - return boxdata.datas; + if (boxdata.val) return boxdata.val; + return null; } catch (e) { console.log(e); return false; From 111583bcbb2931471b865de3e1783d04617ced20 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 4 Jan 2022 16:30:38 +0800 Subject: [PATCH 012/152] =?UTF-8?q?DmYY=EF=BC=8C=E6=9B=B4=E6=96=B0boxjs=20?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=E5=A4=B1=E8=B4=A5=E5=A2=9E=E5=8A=A0=E6=95=99?= =?UTF-8?q?=E7=A8=8B=E6=8F=90=E7=A4=BA=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/BiliBiliWatch.js | 72 +++--- Scripts/Birthday.js | 546 +++++++++++++++++++-------------------- Scripts/DmYY.js | 7 +- Scripts/JDDou.js | 16 +- Scripts/JDDouK.js | 7 +- Scripts/JDWuLiu.js | 7 +- Scripts/ZXTrains.js | 452 ++++++++++++++++---------------- 7 files changed, 546 insertions(+), 561 deletions(-) diff --git a/Scripts/BiliBiliWatch.js b/Scripts/BiliBiliWatch.js index 9a5e574..6e8d751 100644 --- a/Scripts/BiliBiliWatch.js +++ b/Scripts/BiliBiliWatch.js @@ -3,21 +3,21 @@ // icon-color: gray; icon-glyph: chalkboard; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === "undefined") require = importModule; -const { DmYY, Runing } = require("./DmYY"); +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { constructor(arg) { super(arg); - this.name = "哔哩哔哩关注"; - this.en = "BiliBiliWatch"; + this.name = '哔哩哔哩关注'; + this.en = 'BiliBiliWatch'; this.logo = - "https://raw.githubusercontent.com/Orz-3/mini/master/Color/bilibili.png"; + 'https://raw.githubusercontent.com/Orz-3/mini/master/Color/bilibili.png'; this.Run(module.filename); } - cookie = ""; + cookie = ''; dataSource = []; init = async () => { @@ -33,7 +33,7 @@ class Widget extends DmYY { const method = `GET`; const headers = { Cookie: this.cookie, - "User-Agent": `bili-universal/10320 CFNetwork/1206 Darwin/20.1.0 os/ios model/iPhone XR mobi_app/iphone build/10320 osVer/14.2 network/2 channel/AppStore`, + 'User-Agent': `bili-universal/10320 CFNetwork/1206 Darwin/20.1.0 os/ios model/iPhone XR mobi_app/iphone build/10320 osVer/14.2 network/2 channel/AppStore`, }; const response = await this.$request.get(url, { method, @@ -69,10 +69,10 @@ class Widget extends DmYY { }); return this.dataSource; } else { - throw "cookie 失效,请重新获取"; + throw 'cookie 失效,请重新获取'; } } catch (e) { - console.log("❌错误信息:" + e); + console.log('❌错误信息:' + e); return false; } }; @@ -81,11 +81,11 @@ class Widget extends DmYY { const { title, url, reply, play, desc, img, timestamp } = data; let body = cell.addStack(); body.url = url; - if (this.widgetFamily !== "small") { + if (this.widgetFamily !== 'small') { const imageView = body.addStack(); imageView.size = new Size(43, 43); imageView.cornerRadius = 5; - const image = await this.$request.get(img, "IMG"); + const image = await this.$request.get(img, 'IMG'); imageView.backgroundImage = image; body.addSpacer(10); } @@ -112,7 +112,7 @@ class Widget extends DmYY { const descView = textView.addStack(); - const icon1 = descView.addText("浏览:"); + const icon1 = descView.addText('浏览:'); icon1.font = Font.lightSystemFont(10); icon1.textColor = this.widgetColor; descView.addSpacer(3); @@ -121,7 +121,7 @@ class Widget extends DmYY { timerText.textColor = this.widgetColor; descView.addSpacer(5); - const icon2 = descView.addText("评论:"); + const icon2 = descView.addText('评论:'); icon2.font = Font.lightSystemFont(10); icon2.textColor = this.widgetColor; @@ -167,15 +167,15 @@ class Widget extends DmYY { const widget = new ListWidget(); await this.getWidgetBackgroundImage(widget); const header = widget.addStack(); - if (this.widgetFamily !== "small") { + if (this.widgetFamily !== 'small') { await this.renderJDHeader(header); } else { await this.renderHeader(header, this.logo, this.name, this.widgetColor); } widget.addSpacer(10); - if (this.widgetFamily === "medium") { + if (this.widgetFamily === 'medium') { return await this.renderMedium(widget); - } else if (this.widgetFamily === "large") { + } else if (this.widgetFamily === 'large') { return await this.renderLarge(widget); } else { return await this.renderSmall(widget); @@ -187,11 +187,11 @@ class Widget extends DmYY { await this.renderHeader(header, this.logo, this.name, this.widgetColor); header.addSpacer(); const headerMore = header.addStack(); - headerMore.url = ""; + headerMore.url = ''; headerMore.setPadding(1, 10, 1, 10); headerMore.cornerRadius = 10; - headerMore.backgroundColor = new Color("#fff", 0.5); - const textItem = headerMore.addText("个人中心"); + headerMore.backgroundColor = new Color('#fff', 0.5); + const textItem = headerMore.addText('个人中心'); textItem.font = Font.boldSystemFont(12); textItem.textColor = this.widgetColor; textItem.lineLimit = 1; @@ -201,55 +201,49 @@ class Widget extends DmYY { Run = (filename) => { if (config.runsInApp) { - this.registerAction("基础设置", this.setWidgetConfig); - this.registerAction("账号设置", this.inputCk); - this.registerAction("代理缓存", this._loadCk); + this.registerAction('基础设置', this.setWidgetConfig); + this.registerAction('账号设置', this.inputCk); + this.registerAction('代理缓存', this._loadCk); } let _md5 = this.md5(filename + this.en); this.CACHE_KEY = `cache_${_md5}`; try { this.cookie = this.settings[this.en]; if (!this.cookie) { - throw "CK 获取失败"; + throw 'CK 获取失败'; } return true; } catch (e) { - this.notify("错误提示", e); + this.notify('错误提示', e); return false; } }; _loadCk = async () => { try { - const cookie = await this.getCache("@bilibili.cookie"); + const cookie = await this.getCache('@bilibili.cookie'); if (cookie) { this.cookie = cookie; this.settings[this.en] = this.cookie; this.saveSettings(); } else { - throw "ck 获取失败"; + throw 'ck 获取失败'; } return true; } catch (e) { console.log(e); - this.cookie = ""; - this.notify( - this.name, - "", - "BoxJS 数据读取失败,请点击通知查看教程", - "https://chavyleung.gitbook.io/boxjs/awesome/videos" - ); + this.cookie = ''; return false; } }; async inputCk() { const a = new Alert(); - a.title = "账号设置"; - a.message = "手动输入 Ck"; - a.addTextField("Cookie", this.cookie); - a.addAction("确定"); - a.addCancelAction("取消"); + a.title = '账号设置'; + a.message = '手动输入 Ck'; + a.addTextField('Cookie', this.cookie); + a.addAction('确定'); + a.addCancelAction('取消'); const id = await a.presentAlert(); if (id === -1) return; this.cookie = a.textFieldValue(0); @@ -261,4 +255,4 @@ class Widget extends DmYY { // @组件代码结束 // await Runing(Widget, "", false); // 正式环境 -await Runing(Widget, "", false); //远程开发环境 +await Runing(Widget, '', false); //远程开发环境 diff --git a/Scripts/Birthday.js b/Scripts/Birthday.js index ef78a85..a1bf774 100644 --- a/Scripts/Birthday.js +++ b/Scripts/Birthday.js @@ -3,305 +3,301 @@ // icon-color: pink; icon-glyph: birthday-cake; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === "undefined") require = importModule; -const { DmYY, Runing } = require("./DmYY"); -const { Calendar } = require("./Calendar"); +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); +const { Calendar } = require('./Calendar'); const $ = new Calendar(); class Widget extends DmYY { - constructor(arg) { - super(arg); - this.name = "破壳日"; - this.en = "birthday"; - this.logo = - "https://raw.githubusercontent.com/Orz-3/mini/master/Color/birthday.png"; - this.LEFT_IMG_KEY = this.FILE_MGR_LOCAL.joinPath( - this.FILE_MGR_LOCAL.documentsDirectory(), - `left_image_${this.SETTING_KEY}.jpg`, - ); - this.defaultData = { ...this.defaultData, ...this.settings[this.en] }; - if (config.runsInApp) { - this.registerAction("基础设置", this.setWidgetConfig); - this.registerAction("生日配置", this.setWidgetInitConfig); - this.registerAction("头像设置", this.setLeftWidgetImage); - this.registerAction("代理缓存", this.setWidgetBoxJSConfig); - } - } + constructor(arg) { + super(arg); + this.name = '破壳日'; + this.en = 'birthday'; + this.logo = + 'https://raw.githubusercontent.com/Orz-3/mini/master/Color/birthday.png'; + this.LEFT_IMG_KEY = this.FILE_MGR_LOCAL.joinPath( + this.FILE_MGR_LOCAL.documentsDirectory(), + `left_image_${this.SETTING_KEY}.jpg`, + ); + this.defaultData = { ...this.defaultData, ...this.settings[this.en] }; + if (config.runsInApp) { + this.registerAction('基础设置', this.setWidgetConfig); + this.registerAction('生日配置', this.setWidgetInitConfig); + this.registerAction('头像设置', this.setLeftWidgetImage); + this.registerAction('代理缓存', this.setWidgetBoxJSConfig); + } + } - defaultData = { - username: "", // 姓名 - time: "", // 生日日期 - nongli: "", // 农历生日 - eday: "", //相识 - isLeapMonth: false, //如果是农历闰月第四个参数赋值true即可 - }; + defaultData = { + username: '', // 姓名 + time: '', // 生日日期 + nongli: '', // 农历生日 + eday: '', //相识 + isLeapMonth: false, //如果是农历闰月第四个参数赋值true即可 + }; - contentText = {}; + contentText = {}; - init = async () => { - try { - this.getCalendarData(); - } catch (e) { - console.log(e); - } - }; + init = async () => { + try { + this.getCalendarData(); + } catch (e) { + console.log(e); + } + }; - getEdayNumber = (date) => { - var initDay = date.split("-"); - var obj = { - cYear: parseInt(initDay[0]), - cMonth: parseInt(initDay[1]), - cDay: parseInt(initDay[2]), - }; - return Math.abs(this.$.daysBetween(obj)); - }; + getEdayNumber = (date) => { + var initDay = date.split('-'); + var obj = { + cYear: parseInt(initDay[0]), + cMonth: parseInt(initDay[1]), + cDay: parseInt(initDay[2]), + }; + return Math.abs(this.$.daysBetween(obj)); + }; - getCalendarData = () => { - const { time, nongli, isLeapMonth, eday } = this.defaultData; - const _data = time.split("-"); - const opt = { - year: parseInt(_data[0]), - month: parseInt(_data[1]), - day: parseInt(_data[2]), - nongli, - isLeapMonth, - }; + getCalendarData = () => { + const { time, nongli, isLeapMonth, eday } = this.defaultData; + const _data = time.split('-'); + const opt = { + year: parseInt(_data[0]), + month: parseInt(_data[1]), + day: parseInt(_data[2]), + nongli, + isLeapMonth, + }; - const response = {}; - response.birthdayText = this.$.birthday(opt); - response.nextBirthday = response.birthdayText[0]; + const response = {}; + response.birthdayText = this.$.birthday(opt); + response.nextBirthday = response.birthdayText[0]; - const solarData = - nongli === "true" - ? this.$.lunar2solar(opt.year, opt.month, opt.day, isLeapMonth) - : this.$.solar2lunar(opt.year, opt.month, opt.day); - response.gregorian = solarData; - response.animal = `${this.$.getAnimalZodiacToEmoji(solarData.Animal)}-${ - solarData.Animal - }`; - response.astro = `${this.$.getAstroToEmoji(solarData.astro)}-${solarData.astro}`; - if (this.$.verifyTime(eday)) { - response.meetDay = this.getEdayNumber(eday); - } - this.contentText = response; - }; + const solarData = + nongli === 'true' + ? this.$.lunar2solar(opt.year, opt.month, opt.day, isLeapMonth) + : this.$.solar2lunar(opt.year, opt.month, opt.day); + response.gregorian = solarData; + response.animal = `${this.$.getAnimalZodiacToEmoji(solarData.Animal)}-${ + solarData.Animal + }`; + response.astro = `${this.$.getAstroToEmoji(solarData.astro)}-${ + solarData.astro + }`; + if (this.$.verifyTime(eday)) { + response.meetDay = this.getEdayNumber(eday); + } + this.contentText = response; + }; - setRightCell = (text, rowCell) => { - const subContent = rowCell.addText(text); - subContent.font = Font.boldSystemFont(14); - subContent.textColor = this.widgetColor; - subContent.lineLimit = 1; - rowCell.addSpacer(5); - }; + setRightCell = (text, rowCell) => { + const subContent = rowCell.addText(text); + subContent.font = Font.boldSystemFont(14); + subContent.textColor = this.widgetColor; + subContent.lineLimit = 1; + rowCell.addSpacer(5); + }; - setLeftView = (w) => { - const leftImg = this.getLeftImage(); - const left = w.addStack(); - left.size = new Size(110, 110); - left.cornerRadius = 5; - left.borderWidth = 2; - left.borderColor = this.widgetColor; - if (leftImg) { - const widgetImg = left.addImage(leftImg); - widgetImg.imageSize = new Size(110, 110); - widgetImg.applyFillingContentMode(); - widgetImg.cornerRadius = 5; - } - return w; - }; + setLeftView = (w) => { + const leftImg = this.getLeftImage(); + const left = w.addStack(); + left.size = new Size(110, 110); + left.cornerRadius = 5; + left.borderWidth = 2; + left.borderColor = this.widgetColor; + if (leftImg) { + const widgetImg = left.addImage(leftImg); + widgetImg.imageSize = new Size(110, 110); + widgetImg.applyFillingContentMode(); + widgetImg.cornerRadius = 5; + } + return w; + }; - setRightView = (right) => { - const { - animal, - astro, - gregorian, - nextBirthday, - meetDay, - birthdayText, - } = this.contentText; - const { IMonthCn, IDayCn } = gregorian; - right.layoutVertically(); - this.setRightCell(`🐽相:${animal}`, right); // 属相 - this.setRightCell(`🌠座:${astro}`, right); // 属相 - if (meetDay) { - this.setRightCell(`💖遇:${meetDay} 天`, right); - } - const _birth = `🎂生:${nextBirthday.cYear}-${nextBirthday.cMonth}-${nextBirthday.cDay} (${birthdayText[1]}天)`; - this.setRightCell(_birth, right); - this.setRightCell(`📆农:${IMonthCn}${IDayCn}`, right); - return right; - }; + setRightView = (right) => { + const { animal, astro, gregorian, nextBirthday, meetDay, birthdayText } = + this.contentText; + const { IMonthCn, IDayCn } = gregorian; + right.layoutVertically(); + this.setRightCell(`🐽相:${animal}`, right); // 属相 + this.setRightCell(`🌠座:${astro}`, right); // 属相 + if (meetDay) { + this.setRightCell(`💖遇:${meetDay} 天`, right); + } + const _birth = `🎂生:${nextBirthday.cYear}-${nextBirthday.cMonth}-${nextBirthday.cDay} (${birthdayText[1]}天)`; + this.setRightCell(_birth, right); + this.setRightCell(`📆农:${IMonthCn}${IDayCn}`, right); + return right; + }; - fetch = async () => { - const response = await this.$request.get( - "https://api.uomg.com/api/rand.qinghua?format=json", - ); - return response.content; - }; + fetch = async () => { + const response = await this.$request.get( + 'https://api.uomg.com/api/rand.qinghua?format=json', + ); + return response.content; + }; - renderSmall = async (w) => { - this.setRightView(w.addStack()); - return w; - }; + renderSmall = async (w) => { + this.setRightView(w.addStack()); + return w; + }; - renderLarge = async (w) => { - w.addSpacer(20); - const body = w.addStack(); - const left = body.addStack(); - this.setLeftView(left); - body.addSpacer(20); - const right = body.addStack(); - this.setRightView(right); + renderLarge = async (w) => { + w.addSpacer(20); + const body = w.addStack(); + const left = body.addStack(); + this.setLeftView(left); + body.addSpacer(20); + const right = body.addStack(); + this.setRightView(right); - w.addSpacer(20); - const footer = w.addStack(); - const text = await this.fetch(); - const subContent = footer.addText(text); - subContent.font = Font.boldSystemFont(16); - subContent.textColor = this.widgetColor; - w.addSpacer(); - return w; - }; + w.addSpacer(20); + const footer = w.addStack(); + const text = await this.fetch(); + const subContent = footer.addText(text); + subContent.font = Font.boldSystemFont(16); + subContent.textColor = this.widgetColor; + w.addSpacer(); + return w; + }; - renderMedium = async (w) => { - const body = w.addStack(); - const left = body.addStack(); - this.setLeftView(left); - body.addSpacer(); - const right = body.addStack(); - this.setRightView(right); - body.addSpacer(); - w.addSpacer(); - return w; - }; + renderMedium = async (w) => { + const body = w.addStack(); + const left = body.addStack(); + this.setLeftView(left); + body.addSpacer(); + const right = body.addStack(); + this.setRightView(right); + body.addSpacer(); + w.addSpacer(); + return w; + }; - /** - * 渲染函数,函数名固定 - * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 - */ - async render() { - await this.init(); - const widget = new ListWidget(); - await this.getWidgetBackgroundImage(widget); - const header = widget.addStack(); - if (this.widgetFamily !== "small") { - await this.renderMoreHeader(header); - } else { - await this.renderHeader(header, this.logo, this.name, this.widgetColor); - } - widget.addSpacer(10); - if (this.widgetFamily === "medium") { - await this.renderMedium(widget); - } else if (this.widgetFamily === "large") { - await this.renderLarge(widget); - } else { - await this.renderSmall(widget); - } - return widget; - } + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + await this.getWidgetBackgroundImage(widget); + const header = widget.addStack(); + if (this.widgetFamily !== 'small') { + await this.renderMoreHeader(header); + } else { + await this.renderHeader(header, this.logo, this.name, this.widgetColor); + } + widget.addSpacer(10); + if (this.widgetFamily === 'medium') { + await this.renderMedium(widget); + } else if (this.widgetFamily === 'large') { + await this.renderLarge(widget); + } else { + await this.renderSmall(widget); + } + return widget; + } - renderMoreHeader = async (header) => { - header.centerAlignContent(); - await this.renderHeader(header, this.logo, this.name, this.widgetColor); - header.addSpacer(); - const headerMore = header.addStack(); - headerMore.setPadding(1, 10, 1, 10); - headerMore.cornerRadius = 10; - headerMore.backgroundColor = new Color("#fff", 0.5); - const textItem = headerMore.addText(this.defaultData.username); - textItem.font = Font.boldSystemFont(12); - textItem.textColor = this.widgetColor; - textItem.lineLimit = 1; - textItem.rightAlignText(); - return header; - }; + renderMoreHeader = async (header) => { + header.centerAlignContent(); + await this.renderHeader(header, this.logo, this.name, this.widgetColor); + header.addSpacer(); + const headerMore = header.addStack(); + headerMore.setPadding(1, 10, 1, 10); + headerMore.cornerRadius = 10; + headerMore.backgroundColor = new Color('#fff', 0.5); + const textItem = headerMore.addText(this.defaultData.username); + textItem.font = Font.boldSystemFont(12); + textItem.textColor = this.widgetColor; + textItem.lineLimit = 1; + textItem.rightAlignText(); + return header; + }; - /** - * 获取当前插件是否有自定义背景图片 - * @reutrn img | false - */ - getLeftImage() { - let result = null; - if (this.FILE_MGR_LOCAL.fileExists(this.LEFT_IMG_KEY)) { - result = Image.fromFile(this.LEFT_IMG_KEY); - } - return result; - } + /** + * 获取当前插件是否有自定义背景图片 + * @reutrn img | false + */ + getLeftImage() { + let result = null; + if (this.FILE_MGR_LOCAL.fileExists(this.LEFT_IMG_KEY)) { + result = Image.fromFile(this.LEFT_IMG_KEY); + } + return result; + } - /** - * 设置当前组件的背景图片 - * @param {image} img - */ - setLeftImage(img, notify = true) { - if (!img) { - // 移除背景 - if (this.FILE_MGR_LOCAL.fileExists(this.LEFT_IMG_KEY)) { - this.FILE_MGR_LOCAL.remove(this.LEFT_IMG_KEY); - } - if (notify) this.notify("移除成功", "小组件图片已移除,稍后刷新生效"); - } else { - // 设置背景 - // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.LEFT_IMG_KEY, img); - if (notify) this.notify("设置成功", "小组件图片已设置!稍后刷新生效"); - } - } + /** + * 设置当前组件的背景图片 + * @param {image} img + */ + setLeftImage(img, notify = true) { + if (!img) { + // 移除背景 + if (this.FILE_MGR_LOCAL.fileExists(this.LEFT_IMG_KEY)) { + this.FILE_MGR_LOCAL.remove(this.LEFT_IMG_KEY); + } + if (notify) this.notify('移除成功', '小组件图片已移除,稍后刷新生效'); + } else { + // 设置背景 + // 全部设置一遍, + this.FILE_MGR_LOCAL.writeImage(this.LEFT_IMG_KEY, img); + if (notify) this.notify('设置成功', '小组件图片已设置!稍后刷新生效'); + } + } - setLeftWidgetImage = async () => { - const alert = new Alert(); - alert.title = "设置左侧图"; - alert.message = "显示左侧图片"; - alert.addAction("设置新图"); - alert.addAction("清空图片"); - alert.addCancelAction("取消"); - const actions = [ - async () => { - const backImage = await this.chooseImg(); - if (!await this.verifyImage(backImage)) return; - await this.setLeftImage(backImage, true); - }, - () => { - this.setLeftImage(false, true); - }, - ]; - const id = await alert.presentAlert(); - if (id === -1) return; - actions[id] && actions[id].call(this); - }; + setLeftWidgetImage = async () => { + const alert = new Alert(); + alert.title = '设置左侧图'; + alert.message = '显示左侧图片'; + alert.addAction('设置新图'); + alert.addAction('清空图片'); + alert.addCancelAction('取消'); + const actions = [ + async () => { + const backImage = await this.chooseImg(); + if (!(await this.verifyImage(backImage))) return; + await this.setLeftImage(backImage, true); + }, + () => { + this.setLeftImage(false, true); + }, + ]; + const id = await alert.presentAlert(); + if (id === -1) return; + actions[id] && actions[id].call(this); + }; - setWidgetInitConfig = async () => { - const a = new Alert(); - a.title = "🐣破壳日配置"; - a.message = "配置破壳日的基础信息"; - a.addTextField("昵称", this.defaultData.username); - a.addTextField("生日/ 年-月-日", this.defaultData.time); - a.addTextField("农历/ true | false", `${this.defaultData.nongli || ""}`); - a.addTextField("相识/ 年-月-日", this.defaultData.eday); - a.addAction("确定"); - a.addCancelAction("取消"); - const id = await a.presentAlert(); - if (id === -1) return; - this.defaultData.username = a.textFieldValue(0); - this.defaultData.time = a.textFieldValue(1); - this.defaultData.nongli = a.textFieldValue(2) === "true"; - this.defaultData.eday = a.textFieldValue(3); - // 保存到本地 - this.settings[this.en] = this.defaultData; - this.saveSettings(); - }; + setWidgetInitConfig = async () => { + const a = new Alert(); + a.title = '🐣破壳日配置'; + a.message = '配置破壳日的基础信息'; + a.addTextField('昵称', this.defaultData.username); + a.addTextField('生日/ 年-月-日', this.defaultData.time); + a.addTextField('农历/ true | false', `${this.defaultData.nongli || ''}`); + a.addTextField('相识/ 年-月-日', this.defaultData.eday); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + this.defaultData.username = a.textFieldValue(0); + this.defaultData.time = a.textFieldValue(1); + this.defaultData.nongli = a.textFieldValue(2) === 'true'; + this.defaultData.eday = a.textFieldValue(3); + // 保存到本地 + this.settings[this.en] = this.defaultData; + this.saveSettings(); + }; - setWidgetBoxJSConfig = async () => { - try { - const datas = await this.getCache(); - Object.keys(this.defaultData).forEach((key) => { - this.defaultData[key] = datas[`@${this.en}.${key}`]; - }); - this.settings[this.en] = this.defaultData; - this.saveSettings(); - } catch (e) { - this.notify(this.name, "", "BoxJS 数据读取失败,请点击通知查看教程", "https://chavyleung.gitbook.io/boxjs/awesome/videos"); - } - }; + setWidgetBoxJSConfig = async () => { + try { + const datas = await this.getCache(); + Object.keys(this.defaultData).forEach((key) => { + this.defaultData[key] = datas[`@${this.en}.${key}`]; + }); + this.settings[this.en] = this.defaultData; + this.saveSettings(); + } catch (e) { + console.log(e); + } + }; } -Runing(Widget, "", false, { $ }); +Runing(Widget, '', false, { $ }); diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index f2c9d6e..b8c5305 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -92,7 +92,12 @@ class DmYY { if (boxdata.val) return boxdata.val; return null; } catch (e) { - console.log(e); + console.log('boxjs 数据读取失败'); + await this.notify( + this.name, + 'BoxJS 数据读取失败,请点击通知查看教程', + 'https://chavyleung.gitbook.io/boxjs/awesome/videos', + ); return false; } }; diff --git a/Scripts/JDDou.js b/Scripts/JDDou.js index ff195dd..af40af9 100644 --- a/Scripts/JDDou.js +++ b/Scripts/JDDou.js @@ -188,24 +188,21 @@ class Widget extends DmYY { body.url = 'https://bean.m.jd.com/'; const letfContainer = body.addStack(); await this.setContainer(letfContainer, { - icon: - 'https://gitee.com/scriptableJS/Scriptable/raw/master/JDDou/jdd.png', + icon: 'https://gitee.com/scriptableJS/Scriptable/raw/master/JDDou/jdd.png', text: `${this.beanCount}`, desc: '当前京豆', }); body.addSpacer(); const centerContainer = body.addStack(); await this.setContainer(centerContainer, { - icon: - 'https://gitee.com/scriptableJS/Scriptable/raw/master/JDDou/jdd.png', + icon: 'https://gitee.com/scriptableJS/Scriptable/raw/master/JDDou/jdd.png', text: `+${this.incomeBean}`, desc: '昨日收入', }); body.addSpacer(); const rightContainer = body.addStack(); await this.setContainer(rightContainer, { - icon: - 'https://gitee.com/scriptableJS/Scriptable/raw/master/JDDou/jdd.png', + icon: 'https://gitee.com/scriptableJS/Scriptable/raw/master/JDDou/jdd.png', text: `${this.expenseBean}`, desc: '昨日支出', }); @@ -408,12 +405,7 @@ class Widget extends DmYY { this.notify(this.name, body); table.present(false); } catch (e) { - this.notify( - this.name, - '', - 'BoxJS 数据读取失败,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); + console.log(e); } } } diff --git a/Scripts/JDDouK.js b/Scripts/JDDouK.js index 897a32f..44b70bb 100644 --- a/Scripts/JDDouK.js +++ b/Scripts/JDDouK.js @@ -466,12 +466,7 @@ module.exports = template;`; this.notify(this.name, body); table.present(false); } catch (e) { - this.notify( - this.name, - '', - 'BoxJS 数据读取失败,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); + console.log(e); } } } diff --git a/Scripts/JDWuLiu.js b/Scripts/JDWuLiu.js index 1dc4b34..a5429eb 100644 --- a/Scripts/JDWuLiu.js +++ b/Scripts/JDWuLiu.js @@ -360,12 +360,7 @@ class Widget extends DmYY { this.notify(this.name, body); table.present(false); } catch (e) { - this.notify( - this.name, - '', - 'BoxJS 数据读取失败,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); + console.log(e); } } } diff --git a/Scripts/ZXTrains.js b/Scripts/ZXTrains.js index 33238dd..d6d24b8 100644 --- a/Scripts/ZXTrains.js +++ b/Scripts/ZXTrains.js @@ -7,232 +7,240 @@ // 2.自动获取待出行列表:https://raw.githubusercontent.com/dompling/Script/master/ZXTrians/ZXTrains.js 按照脚本内容配置 // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === "undefined") require = importModule; -const { DmYY, Runing } = require("./DmYY"); +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { - constructor(arg) { - super(arg); - this.name = "智行火车票"; - this.en = "ZXTrains"; - this.logo = "https://raw.githubusercontent.com/Orz-3/mini/master/Color/zxhc.png"; - this.cacheName = this.md5(`dataSouce_${this.en}`); - if (config.runsInApp) { - this.registerAction("基础设置", this.setWidgetConfig); - } - } - - dataSource = []; - - init = async () => { - try { - this.dataSource = await this.getTrainsList(); - } catch (e) { - console.log(e); - } - }; - - dateToUnixTimestamp(str) { - const dates = new Date(str.replace(/-/g, "/")); - return parseInt(dates.getTime()); - } - - timeAgo(o) { - var n = new Date().getTime(); - var f = n - o; - var bs = f >= 0 ? "前" : "后"; //判断时间点是在当前时间的 之前 还是 之后 - f = Math.abs(f); - if (f < 6e4) { - return "刚刚"; - } //小于60秒,刚刚 - if (f < 36e5) { - return parseInt(f / 6e4) + "分钟" + bs; - } //小于1小时,按分钟 - if (f < 864e5) { - return parseInt(f / 36e5) + "小时" + bs; - } //小于1天按小时 - if (f < 2592e6) { - return parseInt(f / 864e5) + "天" + bs; - } //小于1个月(30天),按天数 - if (f < 31536e6) { - return parseInt(f / 2592e6) + "个月" + bs; - } //小于1年(365天),按月数 - return parseInt(f / 31536e6) + "年" + bs; //大于365天,按年算 - } - - async getTrainsList() { - try { - const travels = await this.getCache("@ZXTrains.travels"); - console.log(travels); - if (travels) return travels; - } catch (e) { - console.log("未找到火车票缓存:" + e); - this.notify(this.name, "", "BoxJS 数据读取失败,请点击通知查看教程", "https://chavyleung.gitbook.io/boxjs/awesome/videos"); - } - return false; - } - - setWidget = async (body) => { - let isNone = true; - try { - for (const item of this.dataSource) { - let { trainFlights, timeDesc } = item.orders[0]; - const data = trainFlights[0]; - const passengerInfos = data.passengerInfos[0]; - const fromDate = this.dateToUnixTimestamp(data.fromTime); - const toDate = this.dateToUnixTimestamp(data.toTime); - const nowDate = parseInt(new Date().getTime()); - if (fromDate - nowDate < 1000 * 60 * 60 * 24 && nowDate < toDate) { - const header = body.addStack(); - this.name = data.title; - await this.renderHeader(header, this.logo, this.name, this.widgetColor); - body.addSpacer(); - - const container = body.addStack(); - container.url = "suanya://"; - container.layoutVertically(); - const timeView = container.addStack(); - timeView.setPadding(10, 10, 10, 10); - timeView.backgroundColor = new Color("#1890ff"); - timeView.cornerRadius = 5; - - const left = timeView.addStack(); - left.layoutVertically(); - left.addSpacer(); - const leftTimer = left.addText(data.showFromTime); - leftTimer.font = Font.boldSystemFont(16); - leftTimer.textColor = Color.white(); - left.addSpacer(); - const leftDesc = left.addText(data.fromCityName); - leftDesc.font = Font.lightSystemFont(12); - leftDesc.textColor = Color.white(); - left.addSpacer(); - - timeView.addSpacer(); - - const center = timeView.addStack(); - center.addSpacer(); - center.layoutVertically(); - const image = await this.$request.get(data.trafficIcon, "IMG"); - const imageView = center.addImage(image); - imageView.imageSize = new Size(40, 40); - center.addSpacer(); - timeView.addSpacer(); - - const right = timeView.addStack(); - right.layoutVertically(); - right.addSpacer(); - const rightTimer = right.addText(data.showToTime); - rightTimer.font = Font.boldSystemFont(16); - rightTimer.textColor = Color.white(); - right.addSpacer(); - const rightDesc = right.addText(data.toCityName); - rightDesc.font = Font.lightSystemFont(12); - rightDesc.textColor = Color.white(); - right.addSpacer(); - - const footerView = container.addStack(); - footerView.setPadding(10, 10, 10, 10); - timeDesc = nowDate < fromDate ? `距离发车还有${this.timeAgo(fromDate)}` : `距离到达还有${this.timeAgo(toDate)}`; - const footerLeftText = footerView.addText(timeDesc); - footerLeftText.font = Font.boldSystemFont(12); - footerLeftText.textColor = this.widgetColor; - footerLeftText.textOpacity = 0.8; - - footerView.addSpacer(); - const footerRightText = footerView.addText( - `${passengerInfos.seatCategory} ${passengerInfos.carriageNo} ${passengerInfos.seatNo} `, - ); - footerRightText.font = Font.boldSystemFont(12); - footerRightText.textColor = this.widgetColor; - footerRightText.textOpacity = 0.8; - - isNone = false; - break; - } - } - } catch (e) { - console.log(e); - } - if (isNone) await this.renderNone(body); - body.addStack(); - return body; - }; - - renderSmall = async (w) => { - return this.renderLarge(w); - }; - - renderLarge = async (w) => { - const header = w.addStack(); - await this.renderHeader(header, this.logo, this.name, this.widgetColor); - w.addSpacer(20); - const text = w.addText("暂不支持"); - text.font = Font.boldSystemFont(20); - text.textColor = this.widgetColor; - w.addSpacer(); - return w; - }; - - renderMedium = async (w) => { - return await this.setWidget(w); - }; - - renderNone = async (widget) => { - const header = widget.addStack(); - await this.renderHeader(header, this.logo, this.name, this.widgetColor); - widget.addSpacer(); - const bodyIcon = await this.$request.get( - "https://images3.c-ctrip.com/ztrip/img/dcx_HUOCHE.png", - "IMG", - ); - - const body = widget.addStack(); - body.url = "suanya://"; - - const container = body.addStack(); - container.layoutVertically(); - const bodyIconView = container.addStack(); - bodyIconView.cornerRadius = 5; - - bodyIconView.addSpacer(); - bodyIconView.backgroundColor = new Color("#1890ff"); - const bodyIconItem = bodyIconView.addImage(bodyIcon); - bodyIconItem.imageSize = new Size(90, 60); - bodyIconView.addSpacer(); - - container.addSpacer(20); - const noneView = container.addStack(); - - noneView.addSpacer(); - const noneText = noneView.addText("暂无未出行行程"); - noneText.font = Font.boldSystemFont(14); - noneText.textColor = this.widgetColor; - noneView.addSpacer(); - - return widget; - }; - - /** - * 渲染函数,函数名固定 - * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 - */ - async render() { - await this.init(); - const widget = new ListWidget(); - await this.getWidgetBackgroundImage(widget); - if (this.widgetFamily === "medium") { - await this.renderMedium(widget); - } else if (this.widgetFamily === "large") { - await this.renderLarge(widget); - } else { - await this.renderSmall(widget); - } - return widget; - } + constructor(arg) { + super(arg); + this.name = '智行火车票'; + this.en = 'ZXTrains'; + this.logo = + 'https://raw.githubusercontent.com/Orz-3/mini/master/Color/zxhc.png'; + this.cacheName = this.md5(`dataSouce_${this.en}`); + if (config.runsInApp) { + this.registerAction('基础设置', this.setWidgetConfig); + } + } + + dataSource = []; + + init = async () => { + try { + this.dataSource = await this.getTrainsList(); + } catch (e) { + console.log(e); + } + }; + + dateToUnixTimestamp(str) { + const dates = new Date(str.replace(/-/g, '/')); + return parseInt(dates.getTime()); + } + + timeAgo(o) { + var n = new Date().getTime(); + var f = n - o; + var bs = f >= 0 ? '前' : '后'; //判断时间点是在当前时间的 之前 还是 之后 + f = Math.abs(f); + if (f < 6e4) { + return '刚刚'; + } //小于60秒,刚刚 + if (f < 36e5) { + return parseInt(f / 6e4) + '分钟' + bs; + } //小于1小时,按分钟 + if (f < 864e5) { + return parseInt(f / 36e5) + '小时' + bs; + } //小于1天按小时 + if (f < 2592e6) { + return parseInt(f / 864e5) + '天' + bs; + } //小于1个月(30天),按天数 + if (f < 31536e6) { + return parseInt(f / 2592e6) + '个月' + bs; + } //小于1年(365天),按月数 + return parseInt(f / 31536e6) + '年' + bs; //大于365天,按年算 + } + + async getTrainsList() { + try { + const travels = await this.getCache('@ZXTrains.travels'); + console.log(travels); + if (travels) return travels; + } catch (e) { + console.log('未找到火车票缓存:' + e); + } + return false; + } + + setWidget = async (body) => { + let isNone = true; + try { + for (const item of this.dataSource) { + let { trainFlights, timeDesc } = item.orders[0]; + const data = trainFlights[0]; + const passengerInfos = data.passengerInfos[0]; + const fromDate = this.dateToUnixTimestamp(data.fromTime); + const toDate = this.dateToUnixTimestamp(data.toTime); + const nowDate = parseInt(new Date().getTime()); + if (fromDate - nowDate < 1000 * 60 * 60 * 24 && nowDate < toDate) { + const header = body.addStack(); + this.name = data.title; + await this.renderHeader( + header, + this.logo, + this.name, + this.widgetColor, + ); + body.addSpacer(); + + const container = body.addStack(); + container.url = 'suanya://'; + container.layoutVertically(); + const timeView = container.addStack(); + timeView.setPadding(10, 10, 10, 10); + timeView.backgroundColor = new Color('#1890ff'); + timeView.cornerRadius = 5; + + const left = timeView.addStack(); + left.layoutVertically(); + left.addSpacer(); + const leftTimer = left.addText(data.showFromTime); + leftTimer.font = Font.boldSystemFont(16); + leftTimer.textColor = Color.white(); + left.addSpacer(); + const leftDesc = left.addText(data.fromCityName); + leftDesc.font = Font.lightSystemFont(12); + leftDesc.textColor = Color.white(); + left.addSpacer(); + + timeView.addSpacer(); + + const center = timeView.addStack(); + center.addSpacer(); + center.layoutVertically(); + const image = await this.$request.get(data.trafficIcon, 'IMG'); + const imageView = center.addImage(image); + imageView.imageSize = new Size(40, 40); + center.addSpacer(); + timeView.addSpacer(); + + const right = timeView.addStack(); + right.layoutVertically(); + right.addSpacer(); + const rightTimer = right.addText(data.showToTime); + rightTimer.font = Font.boldSystemFont(16); + rightTimer.textColor = Color.white(); + right.addSpacer(); + const rightDesc = right.addText(data.toCityName); + rightDesc.font = Font.lightSystemFont(12); + rightDesc.textColor = Color.white(); + right.addSpacer(); + + const footerView = container.addStack(); + footerView.setPadding(10, 10, 10, 10); + timeDesc = + nowDate < fromDate + ? `距离发车还有${this.timeAgo(fromDate)}` + : `距离到达还有${this.timeAgo(toDate)}`; + const footerLeftText = footerView.addText(timeDesc); + footerLeftText.font = Font.boldSystemFont(12); + footerLeftText.textColor = this.widgetColor; + footerLeftText.textOpacity = 0.8; + + footerView.addSpacer(); + const footerRightText = footerView.addText( + `${passengerInfos.seatCategory} ${passengerInfos.carriageNo} ${passengerInfos.seatNo} `, + ); + footerRightText.font = Font.boldSystemFont(12); + footerRightText.textColor = this.widgetColor; + footerRightText.textOpacity = 0.8; + + isNone = false; + break; + } + } + } catch (e) { + console.log(e); + } + if (isNone) await this.renderNone(body); + body.addStack(); + return body; + }; + + renderSmall = async (w) => { + return this.renderLarge(w); + }; + + renderLarge = async (w) => { + const header = w.addStack(); + await this.renderHeader(header, this.logo, this.name, this.widgetColor); + w.addSpacer(20); + const text = w.addText('暂不支持'); + text.font = Font.boldSystemFont(20); + text.textColor = this.widgetColor; + w.addSpacer(); + return w; + }; + + renderMedium = async (w) => { + return await this.setWidget(w); + }; + + renderNone = async (widget) => { + const header = widget.addStack(); + await this.renderHeader(header, this.logo, this.name, this.widgetColor); + widget.addSpacer(); + const bodyIcon = await this.$request.get( + 'https://images3.c-ctrip.com/ztrip/img/dcx_HUOCHE.png', + 'IMG', + ); + + const body = widget.addStack(); + body.url = 'suanya://'; + + const container = body.addStack(); + container.layoutVertically(); + const bodyIconView = container.addStack(); + bodyIconView.cornerRadius = 5; + + bodyIconView.addSpacer(); + bodyIconView.backgroundColor = new Color('#1890ff'); + const bodyIconItem = bodyIconView.addImage(bodyIcon); + bodyIconItem.imageSize = new Size(90, 60); + bodyIconView.addSpacer(); + + container.addSpacer(20); + const noneView = container.addStack(); + + noneView.addSpacer(); + const noneText = noneView.addText('暂无未出行行程'); + noneText.font = Font.boldSystemFont(14); + noneText.textColor = this.widgetColor; + noneView.addSpacer(); + + return widget; + }; + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + await this.renderMedium(widget); + } else if (this.widgetFamily === 'large') { + await this.renderLarge(widget); + } else { + await this.renderSmall(widget); + } + return widget; + } } // @组件代码结束 // await Runing(Widget, "", false); // 正式环境 -await Runing(Widget, "", false); //远程开发环境 +await Runing(Widget, '', false); //远程开发环境 From f1326ff051706e6f728e51ec0485335703a230ba Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 4 Jan 2022 16:37:46 +0800 Subject: [PATCH 013/152] =?UTF-8?q?Update=EF=BC=9A=E6=9B=B4=E6=96=B0=20box?= =?UTF-8?q?js=20=E8=AF=BB=E5=8F=96=E5=A4=B1=E8=B4=A5=E7=9A=84=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index b8c5305..ef309c9 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -95,7 +95,7 @@ class DmYY { console.log('boxjs 数据读取失败'); await this.notify( this.name, - 'BoxJS 数据读取失败,请点击通知查看教程', + '数据读取失败请检查 BoxJS 域名是否为代理复写的域名,不加 http://。\n若没有 BoxJS ,请点击通知查看教程', 'https://chavyleung.gitbook.io/boxjs/awesome/videos', ); return false; From 813a616e961ea5520931f480c07073b9cd2ebef0 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 4 Jan 2022 16:43:17 +0800 Subject: [PATCH 014/152] =?UTF-8?q?=20update:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index ef309c9..a892472 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -94,8 +94,8 @@ class DmYY { } catch (e) { console.log('boxjs 数据读取失败'); await this.notify( - this.name, - '数据读取失败请检查 BoxJS 域名是否为代理复写的域名,不加 http://。\n若没有 BoxJS ,请点击通知查看教程', + `${this.name}-BoxJS 数据读取失败`, + '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', 'https://chavyleung.gitbook.io/boxjs/awesome/videos', ); return false; From 8c8792bb8c86e2ee62e7adc41e0a89d12e1df7be Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 4 Jan 2022 16:43:35 +0800 Subject: [PATCH 015/152] =?UTF-8?q?update=EF=BC=9A=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index a892472..6aca617 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -94,7 +94,7 @@ class DmYY { } catch (e) { console.log('boxjs 数据读取失败'); await this.notify( - `${this.name}-BoxJS 数据读取失败`, + `${this.name} - BoxJS 数据读取失败`, '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', 'https://chavyleung.gitbook.io/boxjs/awesome/videos', ); From 94187f00f0f98a7f6b4498727b7278d00099c877 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 7 Jan 2022 09:47:15 +0800 Subject: [PATCH 016/152] =?UTF-8?q?fix:DmYY=E4=BF=AE=E5=A4=8D=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=85=A8=E5=B1=80=E7=BC=93=E5=AD=98=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 969 ++++++++++++++++++++++++------------------------ 1 file changed, 485 insertions(+), 484 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 6aca617..30f5310 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -9,138 +9,139 @@ class DmYY { constructor(arg) { - this.arg = arg; + this.arg = arg try { - this.init(); + this.init() } catch (error) { - console.log(error); + console.log(error) } - this.isNight = Device.isUsingDarkAppearance(); + this.isNight = Device.isUsingDarkAppearance() } - _actions = {}; - BACKGROUND_NIGHT_KEY; - widgetColor; - backGroundColor; - useBoxJS = true; - isNight; - _actionsIcon = {}; + _actions = {} + BACKGROUND_NIGHT_KEY + widgetColor + backGroundColor + useBoxJS = true + isNight + _actionsIcon = {} // 获取 Request 对象 getRequest = (url = '') => { - return new Request(url); - }; + return new Request(url) + } // 发起请求 http = async (options = { headers: {}, url: '' }, type = 'JSON') => { try { - let request; + let request if (type !== 'IMG') { - request = this.getRequest(); + request = this.getRequest() Object.keys(options).forEach((key) => { - request[key] = options[key]; - }); - request.headers = { ...this.defaultHeaders, ...options.headers }; + request[key] = options[key] + }) + request.headers = { ...this.defaultHeaders, ...options.headers } } else { - request = this.getRequest(options.url); - return (await request.loadImage()) || SFSymbol.named('photo').image; + request = this.getRequest(options.url) + return (await request.loadImage()) || SFSymbol.named('photo').image } if (type === 'JSON') { - return await request.loadJSON(); + return await request.loadJSON() } if (type === 'STRING') { - return await request.loadString(); + return await request.loadString() } - return await request.loadJSON(); + return await request.loadJSON() } catch (e) { - console.log('error:' + e); - if (type === 'IMG') return SFSymbol.named('photo').image; + console.log('error:' + e) + if (type === 'IMG') return SFSymbol.named('photo').image } - }; + } //request 接口请求 $request = { get: async (url = '', options = {}, type = 'JSON') => { - let params = { ...options, method: 'GET' }; + let params = { ...options, method: 'GET' } if (typeof url === 'object') { - params = { ...params, ...url }; + params = { ...params, ...url } } else { - params.url = url; + params.url = url } - let _type = type; - if (typeof options === 'string') _type = options; - return await this.http(params, _type); + let _type = type + if (typeof options === 'string') _type = options + return await this.http(params, _type) }, post: async (url = '', options = {}, type = 'JSON') => { - let params = { ...options, method: 'POST' }; + let params = { ...options, method: 'POST' } if (typeof url === 'object') { - params = { ...params, ...url }; + params = { ...params, ...url } } else { - params.url = url; + params.url = url } - let _type = type; - if (typeof options === 'string') _type = options; - return await this.http(params, _type); + let _type = type + if (typeof options === 'string') _type = options + return await this.http(params, _type) }, - }; + } // 获取 boxJS 缓存 - getCache = async (key) => { + getCache = async (key = '') => { try { - const url = 'http://' + this.prefix + '/query/data/' + key; - const boxdata = await this.$request.get(url); - if (boxdata.val) return boxdata.val; - return null; + let url = 'http://' + this.prefix + '/query/boxdata' + if (key) url = 'http://' + this.prefix + '/query/data/' + key + const boxdata = await this.$request.get(url) + if (boxdata.val) return boxdata.val + return boxdata.datas } catch (e) { - console.log('boxjs 数据读取失败'); + console.log('boxjs 数据读取失败') await this.notify( `${this.name} - BoxJS 数据读取失败`, '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); - return false; + 'https://chavyleung.gitbook.io/boxjs/awesome/videos' + ) + return false } - }; + } transforJSON = (str) => { if (typeof str == 'string') { try { - return JSON.parse(str); + return JSON.parse(str) } catch (e) { - console.log(e); - return str; + console.log(e) + return str } } - console.log('It is not a string!'); - }; + console.log('It is not a string!') + } // 选择图片并缓存 chooseImg = async () => { - return await Photos.fromLibrary(); - }; + return await Photos.fromLibrary() + } // 设置 widget 背景图片 getWidgetBackgroundImage = async (widget) => { - const backgroundImage = this.getBackgroundImage(); + const backgroundImage = this.getBackgroundImage() if (backgroundImage) { const opacity = Device.isUsingDarkAppearance() ? Number(this.settings.darkOpacity) - : Number(this.settings.lightOpacity); + : Number(this.settings.lightOpacity) widget.backgroundImage = await this.shadowImage( backgroundImage, '#000', - opacity, - ); - return true; + opacity + ) + return true } else { if (this.backGroundColor.colors) { - widget.backgroundGradient = this.backGroundColor; + widget.backgroundGradient = this.backGroundColor } else { - widget.backgroundColor = this.backGroundColor; + widget.backgroundColor = this.backGroundColor } - return false; + return false } - }; + } /** * 验证图片尺寸: 图片像素超过 1000 左右的时候会导致背景无法加载 @@ -148,10 +149,10 @@ class DmYY { */ verifyImage = async (img) => { try { - const { width, height } = img.size; - const direct = true; + const { width, height } = img.size + const direct = true if (width > 1000) { - const options = ['取消', '打开图像处理']; + const options = ['取消', '打开图像处理'] const message = '您的图片像素为' + width + @@ -162,17 +163,17 @@ class DmYY { (direct ? '宽度' : '高度') + '调整到 1000 以下\n' + (!direct ? '宽度' : '高度') + - '自动适应'; - const index = await this.generateAlert(message, options); + '自动适应' + const index = await this.generateAlert(message, options) if (index === 1) - Safari.openInApp('https://www.sojson.com/image/change.html', false); - return false; + Safari.openInApp('https://www.sojson.com/image/change.html', false) + return false } - return true; + return true } catch (e) { - return false; + return false } - }; + } /** * 获取截图中的组件剪裁图 @@ -184,11 +185,11 @@ class DmYY { async getWidgetScreenShot(title = null) { // Crop an image into the specified rect. function cropImage(img, rect) { - let draw = new DrawContext(); - draw.size = new Size(rect.width, rect.height); + let draw = new DrawContext() + draw.size = new Size(rect.width, rect.height) - draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)); - return draw.getImage(); + draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)) + return draw.getImage() } // Pixel sizes and positions for widgets on all supported phones. @@ -326,63 +327,63 @@ class DmYY { middle: 618, bottom: 1146, }, - }; + } } let message = - title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续'; - let exitOptions = ['我已截图', '前去截图 >']; - let shouldExit = await this.generateAlert(message, exitOptions); - if (shouldExit) return; + title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续' + let exitOptions = ['我已截图', '前去截图 >'] + let shouldExit = await this.generateAlert(message, exitOptions) + if (shouldExit) return // Get screenshot and determine phone size. - let img = await Photos.fromLibrary(); - let height = img.size.height; - let phone = phoneSizes()[height]; + let img = await Photos.fromLibrary() + let height = img.size.height + let phone = phoneSizes()[height] if (!phone) { - message = '好像您选择的照片不是正确的截图,请先前往桌面'; - await this.generateAlert(message, ['我已知晓']); - return; + message = '好像您选择的照片不是正确的截图,请先前往桌面' + await this.generateAlert(message, ['我已知晓']) + return } // Extra setup needed for 2436-sized phones. if (height === 2436) { - const files = this.FILE_MGR_LOCAL; - let cacheName = 'mz-phone-type'; - let cachePath = files.joinPath(files.libraryDirectory(), cacheName); + const files = this.FILE_MGR_LOCAL + let cacheName = 'mz-phone-type' + let cachePath = files.joinPath(files.libraryDirectory(), cacheName) // If we already cached the phone size, load it. if (files.fileExists(cachePath)) { - let typeString = files.readString(cachePath); - phone = phone[typeString]; + let typeString = files.readString(cachePath) + phone = phone[typeString] // Otherwise, prompt the user. } else { - message = '您的📱型号是?'; - let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X']; - let typeIndex = await this.generateAlert(message, types); - let type = typeIndex === 0 ? 'mini' : 'x'; - phone = phone[type]; - files.writeString(cachePath, type); + message = '您的📱型号是?' + let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X'] + let typeIndex = await this.generateAlert(message, types) + let type = typeIndex === 0 ? 'mini' : 'x' + phone = phone[type] + files.writeString(cachePath, type) } } // Prompt for widget size and position. - message = '截图中要设置透明背景组件的尺寸类型是?'; - let sizes = ['小尺寸', '中尺寸', '大尺寸']; - let size = await this.generateAlert(message, sizes); - let widgetSize = sizes[size]; + message = '截图中要设置透明背景组件的尺寸类型是?' + let sizes = ['小尺寸', '中尺寸', '大尺寸'] + let size = await this.generateAlert(message, sizes) + let widgetSize = sizes[size] - message = '要设置透明背景的小组件在哪个位置?'; + message = '要设置透明背景的小组件在哪个位置?' message += height === 1136 ? ' (备注:当前设备只支持两行小组件,所以下边选项中的「中间」和「底部」的选项是一致的)' - : ''; + : '' // Determine image crop based on phone size. - let crop = { w: '', h: '', x: '', y: '' }; + let crop = { w: '', h: '', x: '', y: '' } if (widgetSize === '小尺寸') { - crop.w = phone.small; - crop.h = phone.small; + crop.w = phone.small + crop.h = phone.small let positions = [ '左上角', '右上角', @@ -390,7 +391,7 @@ class DmYY { '中间右', '左下角', '右下角', - ]; + ] let _posotions = [ 'Top left', 'Top right', @@ -398,55 +399,55 @@ class DmYY { 'Middle right', 'Bottom left', 'Bottom right', - ]; - let position = await this.generateAlert(message, positions); + ] + let position = await this.generateAlert(message, positions) // Convert the two words into two keys for the phone size dictionary. - let keys = _posotions[position].toLowerCase().split(' '); - crop.y = phone[keys[0]]; - crop.x = phone[keys[1]]; + let keys = _posotions[position].toLowerCase().split(' ') + crop.y = phone[keys[0]] + crop.x = phone[keys[1]] } else if (widgetSize === '中尺寸') { - crop.w = phone.medium; - crop.h = phone.small; + crop.w = phone.medium + crop.h = phone.small // Medium and large widgets have a fixed x-value. - crop.x = phone.left; - let positions = ['顶部', '中间', '底部']; - let _positions = ['Top', 'Middle', 'Bottom']; - let position = await this.generateAlert(message, positions); - let key = _positions[position].toLowerCase(); - crop.y = phone[key]; + crop.x = phone.left + let positions = ['顶部', '中间', '底部'] + let _positions = ['Top', 'Middle', 'Bottom'] + let position = await this.generateAlert(message, positions) + let key = _positions[position].toLowerCase() + crop.y = phone[key] } else if (widgetSize === '大尺寸') { - crop.w = phone.medium; - crop.h = phone.large; - crop.x = phone.left; - let positions = ['顶部', '底部']; - let position = await this.generateAlert(message, positions); + crop.w = phone.medium + crop.h = phone.large + crop.x = phone.left + let positions = ['顶部', '底部'] + let position = await this.generateAlert(message, positions) // Large widgets at the bottom have the "middle" y-value. - crop.y = position ? phone.middle : phone.top; + crop.y = position ? phone.middle : phone.top } // Crop image and finalize the widget. - return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)); + return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)) } setLightAndDark = async (title, desc, val) => { try { - const a = new Alert(); - a.title = title; - a.message = desc; - a.addTextField('', `${this.settings[val]}`); - a.addAction('确定'); - a.addCancelAction('取消'); - const id = await a.presentAlert(); - if (id === -1) return; - this.settings[val] = a.textFieldValue(0); - this.saveSettings(); + const a = new Alert() + a.title = title + a.message = desc + a.addTextField('', `${this.settings[val]}`) + a.addAction('确定') + a.addCancelAction('取消') + const id = await a.presentAlert() + if (id === -1) return + this.settings[val] = a.textFieldValue(0) + this.saveSettings() } catch (e) { - console.log(e); + console.log(e) } - }; + } /** * 弹出输入框 @@ -456,27 +457,27 @@ class DmYY { * @returns {Promise} */ setAlertInput = async (title, desc, opt = {}, isSave = true) => { - const a = new Alert(); - a.title = title; - a.message = !desc ? '' : desc; + const a = new Alert() + a.title = title + a.message = !desc ? '' : desc Object.keys(opt).forEach((key) => { - a.addTextField(opt[key], this.settings[key]); - }); - a.addAction('确定'); - a.addCancelAction('取消'); - const id = await a.presentAlert(); - if (id === -1) return; - const data = {}; + a.addTextField(opt[key], this.settings[key]) + }) + a.addAction('确定') + a.addCancelAction('取消') + const id = await a.presentAlert() + if (id === -1) return + const data = {} Object.keys(opt).forEach((key, index) => { - data[key] = a.textFieldValue(index); - }); + data[key] = a.textFieldValue(index) + }) // 保存到本地 if (isSave) { - this.settings = { ...this.settings, ...data }; - return this.saveSettings(); + this.settings = { ...this.settings, ...data } + return this.saveSettings() } - return data; - }; + return data + } /** * 设置当前项目的 boxJS 缓存 @@ -484,87 +485,87 @@ class DmYY { * @returns {Promise} */ setCacheBoxJSData = async (opt = {}) => { - const options = ['取消', '确定']; - const message = '代理缓存仅支持 BoxJS 相关的代理!'; - const index = await this.generateAlert(message, options); - if (index === 0) return; + const options = ['取消', '确定'] + const message = '代理缓存仅支持 BoxJS 相关的代理!' + const index = await this.generateAlert(message, options) + if (index === 0) return try { - const boxJSData = await this.getCache(); + const boxJSData = await this.getCache() Object.keys(opt).forEach((key) => { - this.settings[key] = boxJSData[opt[key]] || ''; - }); + this.settings[key] = boxJSData[opt[key]] || '' + }) // 保存到本地 - this.saveSettings(); + this.saveSettings() } catch (e) { - console.log(e); + console.log(e) this.notify( this.name, 'BoxJS 缓存读取失败!点击查看相关教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); + 'https://chavyleung.gitbook.io/boxjs/awesome/videos' + ) } - }; + } /** * 设置组件内容 * @returns {Promise} */ setWidgetConfig = async () => { - const table = new UITable(); - table.showSeparators = true; - await this.renderDmYYTables(table); - await table.present(); - }; + const table = new UITable() + table.showSeparators = true + await this.renderDmYYTables(table) + await table.present() + } async preferences(table, arr, outfit) { - let header = new UITableRow(); - let heading = header.addText(outfit); - heading.titleFont = Font.mediumSystemFont(17); - heading.centerAligned(); - table.addRow(header); + let header = new UITableRow() + let heading = header.addText(outfit) + heading.titleFont = Font.mediumSystemFont(17) + heading.centerAligned() + table.addRow(header) for (const item of arr) { - const row = new UITableRow(); - row.dismissOnSelect = !!item.dismissOnSelect; + const row = new UITableRow() + row.dismissOnSelect = !!item.dismissOnSelect if (item.url) { - const rowIcon = row.addImageAtURL(item.url); - rowIcon.widthWeight = 100; + const rowIcon = row.addImageAtURL(item.url) + rowIcon.widthWeight = 100 } else { - const icon = item.icon || {}; + const icon = item.icon || {} const image = await this.drawTableIcon( icon.name, icon.color, - item.cornerWidth, - ); - const imageCell = row.addImage(image); - imageCell.widthWeight = 100; + item.cornerWidth + ) + const imageCell = row.addImage(image) + imageCell.widthWeight = 100 } - let rowTitle = row.addText(item['title']); - rowTitle.widthWeight = 400; - rowTitle.titleFont = Font.systemFont(16); + let rowTitle = row.addText(item['title']) + rowTitle.widthWeight = 400 + rowTitle.titleFont = Font.systemFont(16) if (this.settings[item.val] || item.val) { let valText = row.addText( - `${this.settings[item.val] || item.val}`.toUpperCase(), - ); - const fontSize = !item.val ? 26 : 16; - valText.widthWeight = 500; - valText.rightAligned(); - valText.titleColor = Color.blue(); - valText.titleFont = Font.mediumSystemFont(fontSize); + `${this.settings[item.val] || item.val}`.toUpperCase() + ) + const fontSize = !item.val ? 26 : 16 + valText.widthWeight = 500 + valText.rightAligned() + valText.titleColor = Color.blue() + valText.titleFont = Font.mediumSystemFont(fontSize) } else { const imgCell = UITableCell.imageAtURL( - 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png', - ); - imgCell.rightAligned(); - imgCell.widthWeight = 500; - row.addCell(imgCell); + 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png' + ) + imgCell.rightAligned() + imgCell.widthWeight = 500 + row.addCell(imgCell) } row.onSelect = item.onClick ? async () => { try { - await item.onClick(item, table); + await item.onClick(item, table) } catch (e) { - console.log(e); + console.log(e) } } : async () => { @@ -572,49 +573,49 @@ class DmYY { await this.setLightAndDark( item['title'], item['desc'], - item['val'], - ); + item['val'] + ) } else if (item.type == 'setBackground') { - const backImage = await this.getWidgetScreenShot(); + const backImage = await this.getWidgetScreenShot() if (backImage) { - await this.setBackgroundImage(backImage, true); - await this.setBackgroundNightImage(backImage, true); + await this.setBackgroundImage(backImage, true) + await this.setBackgroundNightImage(backImage, true) } } else if (item.type == 'removeBackground') { - const options = ['取消', '清空']; - const message = '该操作不可逆,会清空所有背景图片!'; - const index = await this.generateAlert(message, options); - if (index === 0) return; - await this.setBackgroundImage(false, true); - await this.setBackgroundNightImage(false, true); + const options = ['取消', '清空'] + const message = '该操作不可逆,会清空所有背景图片!' + const index = await this.generateAlert(message, options) + if (index === 0) return + await this.setBackgroundImage(false, true) + await this.setBackgroundNightImage(false, true) } else { - const backImage = await this.chooseImg(); - if (!backImage || !(await this.verifyImage(backImage))) return; + const backImage = await this.chooseImg() + if (!backImage || !(await this.verifyImage(backImage))) return if (item.type == 'setDayBackground') - await this.setBackgroundImage(backImage, true); + await this.setBackgroundImage(backImage, true) if (item.type == 'setNightBackground') - await this.setBackgroundNightImage(backImage, true); + await this.setBackgroundNightImage(backImage, true) } - await this.renderDmYYTables(table); - }; - table.addRow(row); + await this.renderDmYYTables(table) + } + table.addRow(row) } - table.reload(); + table.reload() } drawTableIcon = async ( icon = 'square.grid.2x2', color = '#e8e8e8', - cornerWidth = 42, + cornerWidth = 42 ) => { - const sfi = SFSymbol.named(icon); - sfi.applyFont(Font.mediumSystemFont(30)); - const imgData = Data.fromPNG(sfi.image).toBase64String(); + const sfi = SFSymbol.named(icon) + sfi.applyFont(Font.mediumSystemFont(30)) + const imgData = Data.fromPNG(sfi.image).toBase64String() const html = ` - `; + ` const js = ` var canvas = document.createElement("canvas"); var sourceImg = document.getElementById("sourceImg"); @@ -640,31 +641,31 @@ class DmYY { ctx.putImageData(imgData,0,0); silhouetteImg.src = canvas.toDataURL(); output=canvas.toDataURL() - `; - - let wv = new WebView(); - await wv.loadHTML(html); - const base64Image = await wv.evaluateJavaScript(js); - const iconImage = await new Request(base64Image).loadImage(); - const size = new Size(160, 160); - const ctx = new DrawContext(); - ctx.opaque = false; - ctx.respectScreenScale = true; - ctx.size = size; - const path = new Path(); - const rect = new Rect(0, 0, size.width, size.width); - - path.addRoundedRect(rect, cornerWidth, cornerWidth); - path.closeSubpath(); - ctx.setFillColor(new Color(color)); - ctx.addPath(path); - ctx.fillPath(); - const rate = 36; - const iw = size.width - rate; - const x = (size.width - iw) / 2; - ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)); - return ctx.getImage(); - }; + ` + + let wv = new WebView() + await wv.loadHTML(html) + const base64Image = await wv.evaluateJavaScript(js) + const iconImage = await new Request(base64Image).loadImage() + const size = new Size(160, 160) + const ctx = new DrawContext() + ctx.opaque = false + ctx.respectScreenScale = true + ctx.size = size + const path = new Path() + const rect = new Rect(0, 0, size.width, size.width) + + path.addRoundedRect(rect, cornerWidth, cornerWidth) + path.closeSubpath() + ctx.setFillColor(new Color(color)) + ctx.addPath(path) + ctx.fillPath() + const rate = 36 + const iw = size.width - rate + const x = (size.width - iw) / 2 + ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)) + return ctx.getImage() + } async renderDmYYTables(table) { const basic = [ @@ -703,7 +704,7 @@ class DmYY { desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'darkColor', }, - ]; + ] const background = [ { icon: { name: 'text.below.photo', color: '#faad14' }, @@ -739,53 +740,53 @@ class DmYY { type: 'removeBackground', title: '清空背景图片', }, - ]; + ] const boxjs = { icon: { name: 'shippingbox', color: '#f7bb10' }, type: 'input', title: 'BoxJS 域名', desc: '', val: 'boxjsDomain', - }; - if (this.useBoxJS) basic.push(boxjs); - table.removeAllRows(); - let topRow = new UITableRow(); - topRow.height = 60; - let leftText = topRow.addButton('Github'); - leftText.widthWeight = 0.3; + } + if (this.useBoxJS) basic.push(boxjs) + table.removeAllRows() + let topRow = new UITableRow() + topRow.height = 60 + let leftText = topRow.addButton('Github') + leftText.widthWeight = 0.3 leftText.onTap = async () => { - await Safari.openInApp('https://github.com/dompling/Scriptable'); - }; + await Safari.openInApp('https://github.com/dompling/Scriptable') + } let centerRow = topRow.addImageAtURL( - 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png', - ); - centerRow.widthWeight = 0.4; - centerRow.centerAligned(); + 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png' + ) + centerRow.widthWeight = 0.4 + centerRow.centerAligned() centerRow.onTap = async () => { - await Safari.open('https://t.me/Scriptable_JS'); - }; - let rightText = topRow.addButton('重置所有'); - rightText.widthWeight = 0.3; - rightText.rightAligned(); + await Safari.open('https://t.me/Scriptable_JS') + } + let rightText = topRow.addButton('重置所有') + rightText.widthWeight = 0.3 + rightText.rightAligned() rightText.onTap = async () => { - const options = ['取消', '重置']; + const options = ['取消', '重置'] const message = - '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。'; - const index = await this.generateAlert(message, options); - if (index === 0) return; - this.settings = {}; - await this.setBackgroundImage(false, false); - this.saveSettings(); - }; - table.addRow(topRow); - await this.preferences(table, basic, '基础设置'); - await this.preferences(table, background, '背景图片'); + '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。' + const index = await this.generateAlert(message, options) + if (index === 0) return + this.settings = {} + await this.setBackgroundImage(false, false) + this.saveSettings() + } + table.addRow(topRow) + await this.preferences(table, basic, '基础设置') + await this.preferences(table, background, '背景图片') } init(widgetFamily = config.widgetFamily) { // 组件大小:small,medium,large - this.widgetFamily = widgetFamily; - this.SETTING_KEY = this.md5(Script.name()); + this.widgetFamily = widgetFamily + this.SETTING_KEY = this.md5(Script.name()) //用于配置所有的组件相关设置 // 文件管理器 @@ -793,63 +794,63 @@ class DmYY { this.FILE_MGR = FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' - ](); + ]() // 本地,用于存储图片等 - this.FILE_MGR_LOCAL = FileManager.local(); + this.FILE_MGR_LOCAL = FileManager.local() this.BACKGROUND_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + '.jpg', - ); + 'bg_' + this.SETTING_KEY + '.jpg' + ) this.BACKGROUND_NIGHT_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + 'night.jpg', - ); - - this.settings = this.getSettings(); - this.settings.lightColor = this.settings.lightColor || '#000000'; - this.settings.darkColor = this.settings.darkColor || '#ffffff'; - this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff'; - this.settings.darkBgColor = this.settings.darkBgColor || '#000000'; - this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net'; - this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30'; - this.settings.lightOpacity = this.settings.lightOpacity || '0.4'; - this.settings.darkOpacity = this.settings.darkOpacity || '0.7'; - this.prefix = this.settings.boxjsDomain; - const lightBgColor = this.getColors(this.settings.lightBgColor); - const darkBgColor = this.getColors(this.settings.darkBgColor); + 'bg_' + this.SETTING_KEY + 'night.jpg' + ) + + this.settings = this.getSettings() + this.settings.lightColor = this.settings.lightColor || '#000000' + this.settings.darkColor = this.settings.darkColor || '#ffffff' + this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff' + this.settings.darkBgColor = this.settings.darkBgColor || '#000000' + this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net' + this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30' + this.settings.lightOpacity = this.settings.lightOpacity || '0.4' + this.settings.darkOpacity = this.settings.darkOpacity || '0.7' + this.prefix = this.settings.boxjsDomain + const lightBgColor = this.getColors(this.settings.lightBgColor) + const darkBgColor = this.getColors(this.settings.darkBgColor) if (lightBgColor.length > 1 || darkBgColor.length > 1) { this.backGroundColor = !Device.isUsingDarkAppearance() ? this.getBackgroundColor(lightBgColor) - : this.getBackgroundColor(darkBgColor); + : this.getBackgroundColor(darkBgColor) } else if (lightBgColor.length > 0 && darkBgColor.length > 0) { this.backGroundColor = Color.dynamic( new Color(this.settings.lightBgColor), - new Color(this.settings.darkBgColor), - ); + new Color(this.settings.darkBgColor) + ) } this.widgetColor = Color.dynamic( new Color(this.settings.lightColor), - new Color(this.settings.darkColor), - ); + new Color(this.settings.darkColor) + ) } getColors = (color = '') => { - const colors = typeof color === 'string' ? color.split(',') : color; - return colors; - }; + const colors = typeof color === 'string' ? color.split(',') : color + return colors + } getBackgroundColor = (colors) => { - const locations = []; - const linearColor = new LinearGradient(); - const cLen = colors.length; + const locations = [] + const linearColor = new LinearGradient() + const cLen = colors.length linearColor.colors = colors.map((item, index) => { - locations.push(Math.floor(((index + 1) / cLen) * 100) / 100); - return new Color(item, 1); - }); - linearColor.locations = locations; - return linearColor; - }; + locations.push(Math.floor(((index + 1) / cLen) * 100) / 100) + return new Color(item, 1) + }) + linearColor.locations = locations + return linearColor + } /** * 注册点击操作菜单 @@ -857,8 +858,8 @@ class DmYY { * @param {func} func 点击后执行的函数 */ registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }) { - this._actions[name] = func.bind(this); - this._actionsIcon[name] = icon; + this._actions[name] = func.bind(this) + this._actionsIcon[name] = icon } /** @@ -866,8 +867,8 @@ class DmYY { * @param {string} str 要编码的字符串 */ base64Encode(str) { - const data = Data.fromString(str); - return data.toBase64String(); + const data = Data.fromString(str) + return data.toBase64String() } /** @@ -875,8 +876,8 @@ class DmYY { * @param {string} b64 base64编码的数据 */ base64Decode(b64) { - const data = Data.fromBase64String(b64); - return data.toRawString(); + const data = Data.fromBase64String(b64) + return data.toRawString() } /** @@ -885,34 +886,34 @@ class DmYY { */ md5(str) { function d(n, t) { - var r = (65535 & n) + (65535 & t); - return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r); + var r = (65535 & n) + (65535 & t) + return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r) } function f(n, t, r, e, o, u) { - return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r); - var c, f; + return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r) + var c, f } function l(n, t, r, e, o, u, c) { - return f((t & r) | (~t & e), n, t, o, u, c); + return f((t & r) | (~t & e), n, t, o, u, c) } function v(n, t, r, e, o, u, c) { - return f((t & e) | (r & ~e), n, t, o, u, c); + return f((t & e) | (r & ~e), n, t, o, u, c) } function g(n, t, r, e, o, u, c) { - return f(t ^ r ^ e, n, t, o, u, c); + return f(t ^ r ^ e, n, t, o, u, c) } function m(n, t, r, e, o, u, c) { - return f(r ^ (t | ~e), n, t, o, u, c); + return f(r ^ (t | ~e), n, t, o, u, c) } function i(n, t) { - var r, e, o, u; - (n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t); + var r, e, o, u + ;(n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t) for ( var c = 1732584193, f = -271733879, @@ -944,7 +945,7 @@ class DmYY { a, n[h + 1], 5, - -165796510, + -165796510 )), (a = v(a, c, f, i, n[h + 6], 9, -1069501632)), (i = v(i, a, c, f, n[h + 11], 14, 643717713)), @@ -967,7 +968,7 @@ class DmYY { a, n[h + 5], 4, - -378558, + -378558 )), (a = g(a, c, f, i, n[h + 8], 11, -2022574463)), (i = g(i, a, c, f, n[h + 11], 16, 1839030562)), @@ -990,7 +991,7 @@ class DmYY { a, n[h], 6, - -198630844, + -198630844 )), (a = m(a, c, f, i, n[h + 7], 10, 1126891415)), (i = m(i, a, c, f, n[h + 14], 15, -1416354905)), @@ -1010,39 +1011,39 @@ class DmYY { (c = d(c, r)), (f = d(f, e)), (i = d(i, o)), - (a = d(a, u)); - return [c, f, i, a]; + (a = d(a, u)) + return [c, f, i, a] } function a(n) { for (var t = '', r = 32 * n.length, e = 0; e < r; e += 8) - t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255); - return t; + t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255) + return t } function h(n) { - var t = []; + var t = [] for (t[(n.length >> 2) - 1] = void 0, e = 0; e < t.length; e += 1) - t[e] = 0; + t[e] = 0 for (var r = 8 * n.length, e = 0; e < r; e += 8) - t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32; - return t; + t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32 + return t } function e(n) { for (var t, r = '0123456789abcdef', e = '', o = 0; o < n.length; o += 1) (t = n.charCodeAt(o)), - (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)); - return e; + (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)) + return e } function r(n) { - return unescape(encodeURIComponent(n)); + return unescape(encodeURIComponent(n)) } function o(n) { - return a(i(h((t = r(n))), 8 * t.length)); - var t; + return a(i(h((t = r(n))), 8 * t.length)) + var t } function u(n, t) { @@ -1051,7 +1052,7 @@ class DmYY { e, o = h(n), u = [], - c = []; + c = [] for ( u[15] = c[15] = void 0, 16 < o.length && (o = i(o, 8 * n.length)), @@ -1059,18 +1060,18 @@ class DmYY { r < 16; r += 1 ) - (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]); + (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]) return ( (e = i(u.concat(h(t)), 512 + 8 * t.length)), a(i(c.concat(e), 640)) - ); - })(r(n), r(t)); + ) + })(r(n), r(t)) } function t(n, t, r) { - return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)); + return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)) } - return t(str); + return t(str) } /** @@ -1081,24 +1082,24 @@ class DmYY { * @param {bool|color} color 字体的颜色(自定义背景时使用,默认系统) */ async renderHeader(widget, icon, title, color = false) { - let header = widget.addStack(); - header.centerAlignContent(); + let header = widget.addStack() + header.centerAlignContent() try { - const image = await this.$request.get(icon, 'IMG'); - let _icon = header.addImage(image); - _icon.imageSize = new Size(14, 14); - _icon.cornerRadius = 4; + const image = await this.$request.get(icon, 'IMG') + let _icon = header.addImage(image) + _icon.imageSize = new Size(14, 14) + _icon.cornerRadius = 4 } catch (e) { - console.log(e); + console.log(e) } - header.addSpacer(10); - let _title = header.addText(title); - if (color) _title.textColor = color; - _title.textOpacity = 0.7; - _title.font = Font.boldSystemFont(12); - _title.lineLimit = 1; - widget.addSpacer(15); - return widget; + header.addSpacer(10) + let _title = header.addText(title) + if (color) _title.textColor = color + _title.textOpacity = 0.7 + _title.font = Font.boldSystemFont(12) + _title.lineLimit = 1 + widget.addSpacer(15) + return widget } /** @@ -1108,13 +1109,13 @@ class DmYY { */ async generateAlert(message, options) { - let alert = new Alert(); - alert.message = message; + let alert = new Alert() + alert.message = message for (const option of options) { - alert.addAction(option); + alert.addAction(option) } - return await alert.presentAlert(); + return await alert.presentAlert() } /** @@ -1124,12 +1125,12 @@ class DmYY { * @param {string} url 点击后打开的URL */ async notify(title, body, url, opts = {}) { - let n = new Notification(); - n = Object.assign(n, opts); - n.title = title; - n.body = body; - if (url) n.openURL = url; - return await n.schedule(); + let n = new Notification() + n = Object.assign(n, opts) + n.title = title + n.body = body + if (url) n.openURL = url + return await n.schedule() } /** @@ -1139,19 +1140,19 @@ class DmYY { * @param {float} opacity 透明度 */ async shadowImage(img, color = '#000000', opacity = 0.7) { - if (!img) return; - if (opacity === 0) return img; - let ctx = new DrawContext(); + if (!img) return + if (opacity === 0) return img + let ctx = new DrawContext() // 获取图片的尺寸 - ctx.size = img.size; + ctx.size = img.size ctx.drawImageInRect( img, - new Rect(0, 0, img.size['width'], img.size['height']), - ); - ctx.setFillColor(new Color(color, opacity)); - ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])); - return await ctx.getImage(); + new Rect(0, 0, img.size['width'], img.size['height']) + ) + ctx.setFillColor(new Color(color, opacity)) + ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])) + return await ctx.getImage() } /** @@ -1159,20 +1160,20 @@ class DmYY { * @param {boolean} json 是否为json格式 */ getSettings(json = true) { - let res = json ? {} : ''; - let cache = ''; + let res = json ? {} : '' + let cache = '' if (Keychain.contains(this.SETTING_KEY)) { - cache = Keychain.get(this.SETTING_KEY); + cache = Keychain.get(this.SETTING_KEY) } if (json) { try { - res = JSON.parse(cache); + res = JSON.parse(cache) } catch (e) {} } else { - res = cache; + res = cache } - return res; + return res } /** @@ -1183,9 +1184,9 @@ class DmYY { let res = typeof this.settings === 'object' ? JSON.stringify(this.settings) - : String(this.settings); - Keychain.set(this.SETTING_KEY, res); - if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新'); + : String(this.settings) + Keychain.set(this.SETTING_KEY, res) + if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新') } /** @@ -1193,17 +1194,17 @@ class DmYY { * @reutrn img | false */ getBackgroundImage() { - let result = null; + let result = null if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - result = Image.fromFile(this.BACKGROUND_KEY); + result = Image.fromFile(this.BACKGROUND_KEY) } if ( Device.isUsingDarkAppearance() && this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY) ) { - result = Image.fromFile(this.BACKGROUND_NIGHT_KEY); + result = Image.fromFile(this.BACKGROUND_NIGHT_KEY) } - return result; + return result } /** @@ -1214,16 +1215,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY); + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY) } if (notify) - this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效'); + this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效') } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img); + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img) if (notify) - this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效'); + this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效') } } @@ -1231,16 +1232,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY); + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY) } if (notify) - this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效'); + this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效') } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img); + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img) if (notify) - this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效'); + this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效') } } @@ -1249,15 +1250,15 @@ class DmYY { i = arr.length, min = i - count, temp, - index; - min = min > 0 ? min : 0; + index + min = min > 0 ? min : 0 while (i-- > min) { - index = Math.floor((i + 1) * Math.random()); - temp = shuffled[index]; - shuffled[index] = shuffled[i]; - shuffled[i] = temp; + index = Math.floor((i + 1) * Math.random()) + temp = shuffled[index] + shuffled[index] = shuffled[i] + shuffled[i] = temp } - return shuffled.slice(min); + return shuffled.slice(min) } textFormat = { @@ -1265,107 +1266,107 @@ class DmYY { battery: { size: 10, font: 'bold', color: this.widgetColor }, title: { size: 16, font: 'semibold', color: this.widgetColor }, SFMono: { size: 12, font: 'SF Mono', color: this.widgetColor }, - }; + } provideFont = (fontName, fontSize) => { const fontGenerator = { ultralight: function () { - return Font.ultraLightSystemFont(fontSize); + return Font.ultraLightSystemFont(fontSize) }, light: function () { - return Font.lightSystemFont(fontSize); + return Font.lightSystemFont(fontSize) }, regular: function () { - return Font.regularSystemFont(fontSize); + return Font.regularSystemFont(fontSize) }, medium: function () { - return Font.mediumSystemFont(fontSize); + return Font.mediumSystemFont(fontSize) }, semibold: function () { - return Font.semiboldSystemFont(fontSize); + return Font.semiboldSystemFont(fontSize) }, bold: function () { - return Font.boldSystemFont(fontSize); + return Font.boldSystemFont(fontSize) }, heavy: function () { - return Font.heavySystemFont(fontSize); + return Font.heavySystemFont(fontSize) }, black: function () { - return Font.blackSystemFont(fontSize); + return Font.blackSystemFont(fontSize) }, italic: function () { - return Font.italicSystemFont(fontSize); + return Font.italicSystemFont(fontSize) }, - }; + } - const systemFont = fontGenerator[fontName]; + const systemFont = fontGenerator[fontName] if (systemFont) { - return systemFont(); + return systemFont() } - return new Font(fontName, fontSize); - }; + return new Font(fontName, fontSize) + } provideText = (string, container, format) => { - const textItem = container.addText(string); - const textFont = format.font; - const textSize = format.size; - const textColor = format.color; - - textItem.font = this.provideFont(textFont, textSize); - textItem.textColor = textColor; - return textItem; - }; + const textItem = container.addText(string) + const textFont = format.font + const textSize = format.size + const textColor = format.color + + textItem.font = this.provideFont(textFont, textSize) + textItem.textColor = textColor + return textItem + } } // @base.end const Runing = async (Widget, default_args = '', isDebug = true, extra) => { - let M = null; + let M = null // 判断hash是否和当前设备匹配 if (config.runsInWidget) { - M = new Widget(args.widgetParameter || ''); + M = new Widget(args.widgetParameter || '') if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key]; - }); + M[key] = extra[key] + }) } - const W = await M.render(); + const W = await M.render() try { if (M.settings.refreshAfterDate) { W.refreshAfterDate = new Date( - new Date() + 1000 * 60 * parseInt(M.settings.refreshAfterDate), - ); + new Date() + 1000 * 60 * parseInt(M.settings.refreshAfterDate) + ) } } catch (e) { - console.log(e); + console.log(e) } if (W) { - Script.setWidget(W); - Script.complete(); + Script.setWidget(W) + Script.complete() } } else { - let { act, __arg, __size } = args.queryParameters; - M = new Widget(__arg || default_args || ''); + let { act, __arg, __size } = args.queryParameters + M = new Widget(__arg || default_args || '') if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key]; - }); + M[key] = extra[key] + }) } - if (__size) M.init(__size); + if (__size) M.init(__size) if (!act || !M['_actions']) { // 弹出选择菜单 - const actions = M['_actions']; - const table = new UITable(); + const actions = M['_actions'] + const table = new UITable() const onClick = async (item) => { - M.widgetFamily = item.val; - w = await M.render(); + M.widgetFamily = item.val + w = await M.render() const fnc = item.val .toLowerCase() - .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()); + .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()) if (w) { - return w[`present${fnc}`](); + return w[`present${fnc}`]() } - }; + } const preview = [ { url: 'https://z3.ax1x.com/2021/03/26/6v5wIP.png', @@ -1388,28 +1389,28 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { dismissOnSelect: true, onClick, }, - ]; - await M.preferences(table, preview, '预览组件'); - const extra = []; + ] + await M.preferences(table, preview, '预览组件') + const extra = [] for (let _ in actions) { - const iconItem = M._actionsIcon[_]; - const isUrl = typeof iconItem === 'string'; + const iconItem = M._actionsIcon[_] + const isUrl = typeof iconItem === 'string' const actionItem = { title: _, onClick: actions[_], - }; + } if (isUrl) { - actionItem.url = iconItem; + actionItem.url = iconItem } else { - actionItem.icon = iconItem; + actionItem.icon = iconItem } - extra.push(actionItem); + extra.push(actionItem) } - await M.preferences(table, extra, '配置组件'); - return table.present(); + await M.preferences(table, extra, '配置组件') + return table.present() } } -}; +} // await new DmYY().setWidgetConfig(); -module.exports = { DmYY, Runing }; +module.exports = { DmYY, Runing } From b4d572eadada7b6d196377a656c0ae2bd74702cf Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 7 Jan 2022 09:48:14 +0800 Subject: [PATCH 017/152] =?UTF-8?q?update:=E6=9B=B4=E6=96=B0DmYY=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install.json b/install.json index 3dfcfcf..5840d8c 100644 --- a/install.json +++ b/install.json @@ -5,7 +5,7 @@ "repo": "https://github.com/dompling/Scriptable", "apps": [ { - "version": "1.0.9", + "version": "1.1.0", "description": "DmYY组件库", "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js", "thumb": "https://img.icons8.com/clouds/344/settings.png", @@ -13,6 +13,8 @@ "title": "DmYY", "html": [ "

    更新说明

    ", + "v1.1.0", + "
  • 修复 boxjs 读取问题
  • ", "v1.0.8", "
  • 兼容 ios15 系统,图标引起脚本一直转圈问题
  • ", "v1.0.7", From 611ec5af97b5917ff0dd249f117c05e6fa95d33f Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Mon, 14 Feb 2022 09:39:48 +0800 Subject: [PATCH 018/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=20boxjs=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 30f5310..368fc6f 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -85,20 +85,23 @@ class DmYY { } // 获取 boxJS 缓存 - getCache = async (key = '') => { + getCache = async (key = '', notify = true) => { try { let url = 'http://' + this.prefix + '/query/boxdata' if (key) url = 'http://' + this.prefix + '/query/data/' + key - const boxdata = await this.$request.get(url) + const boxdata = await this.$request.get( + url, + key ? { timeoutInterval: 1 } : {} + ) if (boxdata.val) return boxdata.val return boxdata.datas } catch (e) { - console.log('boxjs 数据读取失败') - await this.notify( - `${this.name} - BoxJS 数据读取失败`, - '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos' - ) + if (notify) + await this.notify( + `${this.name} - BoxJS 数据读取失败`, + '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', + 'https://chavyleung.gitbook.io/boxjs/awesome/videos' + ) return false } } From ff31d3fbb08ee698fed216f134436cd565f1b782 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 9 Jun 2022 11:32:25 +0800 Subject: [PATCH 019/152] fix: phoneSize --- images/ftms.png | Bin 0 -> 92837 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/ftms.png diff --git a/images/ftms.png b/images/ftms.png new file mode 100644 index 0000000000000000000000000000000000000000..59c4bfea1019436b13bbb0116a33c8f195aa2812 GIT binary patch literal 92837 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 z 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

    gbmn_KHIlDo=IGf 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

    *WEd*@1|YcN_mP`fTe_T_%E^>vO6I%m4 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 Date: Thu, 9 Jun 2022 16:08:23 +0800 Subject: [PATCH 020/152] add --- Scripts/Ftms.js | 357 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 Scripts/Ftms.js diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js new file mode 100644 index 0000000..9cb082e --- /dev/null +++ b/Scripts/Ftms.js @@ -0,0 +1,357 @@ +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: deep-gray; icon-glyph: tv; + +// 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 +if (typeof require === 'undefined') require = importModule; +const {DmYY, Runing} = require('./DmYY'); + +// @组件代码开始 +class Widget extends DmYY { + constructor(arg) { + super(arg); + this.name = '一汽丰田'; + this.en = 'ftms'; + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + this.cacheName = this.md5(`dataSouce_${this.en}`); + this.logo = + 'https://www.toyota.com.cn/favicon.ico'; + } + + widgetHeight = 145; + baseOpt = { + headers: { + Connection: `keep-alive`, + Host: `appiov.ftms.com.cn`, + 'Content-Type': `application/json`, + }, + body: ``, + }; + serveInfo = { + carNumber: '', + }; + dataSource = { + remoteInfo: { + datatime: '', + list: [], + userId: '', + carNumber: '', + }, + monitorInfo: { + km: '0', + oilRate: '0', + oilWaste: '0', + }, + }; + + init = async () => { + if (this.settings.dataSource) { + this.serveInfo = this.settings.serveInfo; + this.dataSource = this.settings.dataSource; + } else { + await this.cacheData(); + } + this.cacheData(); + }; + + cacheData = async () => { + try { + await this.getBmuServeHicleInfo(); + await this.getRemoteInfoDetail(); + } catch (e) { + console.log(e); + } + }; + + getBaseOptions(api) { + const baseURL = `https://appiov.ftms.com.cn`; + return {url: `${baseURL}/${api}`, ...this.baseOpt}; + } + + getRemoteInfoDetail = async () => { + const options = this.getBaseOptions( + 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail', + ); + const respones = await this.$request.post(options); + if (respones.msg === 'success') { + this.dataSource.remoteInfo = respones.result; + } + await this.getDrivingMonitorInfo(); + }; + + getDrivingMonitorInfo = async () => { + const options = this.getBaseOptions( + 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo', + ); + const respones = await this.$request.post(options); + if (respones.msg === 'success') { + this.dataSource.monitorInfo = respones.result; + } + this.settings.dataSource = this.dataSource; + this.saveSettings(false); + }; + + getBmuServeHicleInfo = async () => { + let headers = await this.getCache('@ftms.headers'); + headers = JSON.parse(headers || '{}'); + this.baseOpt.headers = {token: headers.token, ...this.baseOpt.headers}; + const options = { + url: `https://superapp.ftms.com.cn/superapp/users/wt/getbmuservehicleinfo?scriptable=1`, + headers, + }; + if (!this.settings.serveInfo) { + const response = await this.$request.post(options); + if (response.code === '200') { + this.settings.serveInfo = response.data; + this.serveInfo = response.data; + this.saveSettings(false); + } + } else { + this.serveInfo = this.settings.serveInfo || {}; + } + this.baseOpt.headers.userId = this.serveInfo.userId; + this.baseOpt.body = JSON.stringify({vin: this.serveInfo.vin}); + this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}`; + }; + + createProgressBar( + soFar, total = 100, width = 400, height = 40, showPercentage = false) { + const context = new DrawContext(); + context.size = new Size(width, height); + context.opaque = false; + context.respectScreenScale = true; + + // bar background + context.setFillColor(new Color('#48484b')); + const bgPath = new Path(); + bgPath.addRoundedRect( + new Rect(0, 0, width, height), height / 2, (height / 2) - 1); + context.addPath(bgPath); + context.fillPath(); + + // bar foreground + context.setFillColor(new Color('#e8e8e8')); + const fgPath = new Path(); + fgPath.addRoundedRect( + new Rect(0, 0, (width * soFar) / total, height), height / 2, + (height / 2) - 1, + ); + context.addPath(fgPath); + context.fillPath(); + + if (showPercentage) { + const percentage = ((soFar / total) * 100).toFixed(2); + let xPos = (width * soFar) / total + 5; + // if over 70%, show in foreground area + // to ensure that it doesn't overflow the display + if (percentage > 70) { + xPos = (width * soFar) / total - 55; + } + + context.setFont(Font.semiboldRoundedSystemFont(14)); + context.setTextColor(primaryTextColor); + context.drawText(`${percentage}%`, new Point(xPos, (height / 14))); + } + + return context.getImage(); + } + + renderBorder = (stack) => { + stack.borderWidth = 1; + }; + + renderImage = async (uri) => { + return this.$request.get(uri, 'IMG'); + }; + + notSupport(w) { + const stack = w.addStack(); + stack.addText('暂不支持'); + return w; + } + + renderSmall = async (w) => { + w.addSpacer(); + + const stack = w.addStack(); + stack.layoutVertically(); + const headerStack = stack.addStack(); + headerStack.centerAlignContent(); + headerStack.addSpacer(10); + const gasImg = await this.renderImage( + `https://img.icons8.com/ios-glyphs/344/gas-station.png`); + + const gasIcon = headerStack.addImage(gasImg); + gasIcon.imageSize = new Size(16, 16); + headerStack.addSpacer(5); + + const oilRateStackText = headerStack.addText( + `${this.dataSource.monitorInfo.oilRate}%`); + oilRateStackText.textColor = this.widgetColor; + oilRateStackText.font = Font.boldSystemFont(14); + + headerStack.addSpacer(); + const logImg = await this.renderImage(this.logo); + const logImgStack = headerStack.addImage(logImg); + logImgStack.imageSize = new Size(20, 20); + headerStack.addSpacer(10); + + const bodyStack = stack.addStack(); + bodyStack.centerAlignContent(); + bodyStack.addSpacer(); + const progressImg = this.createProgressBar( + this.dataSource.monitorInfo.oilRate); + const progressBar = bodyStack.addImage(progressImg); + progressBar.imageSize = new Size(this.widgetHeight, 28); + bodyStack.addSpacer(); + + stack.addSpacer(); + + const oilWasteStack = stack.addStack(); + oilWasteStack.centerAlignContent(); + oilWasteStack.addSpacer(); + const oilWasteStackText = oilWasteStack.addText( + `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km`); + oilWasteStackText.textColor = this.widgetColor; + oilWasteStackText.font = Font.boldSystemFont(10); + oilWasteStack.addSpacer(); + + const kilometerStack = stack.addStack(); + + kilometerStack.centerAlignContent(); + kilometerStack.addSpacer(); + const panoImg = await this.renderImage( + `https://img.icons8.com/ios-glyphs/344/bar-chart.png`); + const panoImgStack = kilometerStack.addStack(); + panoImgStack.setPadding(5, 0, 0, 0); + const panoStack = panoImgStack.addImage(panoImg); + panoStack.imageSize = new Size(20, 20); + kilometerStack.addSpacer(5); + + const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km); + oilWasteText.font = Font.boldSystemFont(28); + oilWasteText.textColor = this.widgetColor; + kilometerStack.addSpacer(5); + const unitStack = kilometerStack.addStack(); + unitStack.setPadding(5, 0, 0, 0); + const oilWasteUnit = unitStack.addText( + 'km'); + oilWasteUnit.font = Font.boldSystemFont(14); + oilWasteUnit.textColor = this.widgetColor; + kilometerStack.addSpacer(); + + stack.addSpacer(); + + const btBodyStack = stack.addStack(); + btBodyStack.addSpacer(); + const bottomStack = btBodyStack.addStack(); + bottomStack.setPadding(10, 0, 10, 0); + bottomStack.centerAlignContent(); + bottomStack.addSpacer(); + bottomStack.cornerRadius = 20; + bottomStack.backgroundColor = new Color('#e8e8e8'); + const dataTime = this.dataSource.remoteInfo.datatime.split(`-`); + const countKmText = bottomStack.addText( + `上传:${dataTime[1]}-${dataTime[2]}`); + countKmText.textColor = this.widgetColor; + countKmText.font = Font.boldSystemFont(12); + countKmText.centerAlignText(); + bottomStack.addSpacer(); + w.addSpacer(); + return w; + }; + + renderLarge = async (w) => { + return this.renderSmall(w); + }; + + renderMedium = async (w) => { + const containerStack = w.addStack(); + containerStack.centerAlignContent(); + const carStack = containerStack.addStack(); + carStack.addSpacer(); + carStack.backgroundColor = new Color('#e8e8e8'); + + carStack.layoutVertically(); + + carStack.centerAlignContent(); + carStack.size = new Size(this.widgetHeight, this.widgetHeight); + carStack.cornerRadius = 20; + const carImg = await this.renderImage( + `https://appiov.ftms.com.cn//ftmsIovUpload/image/20220219/42fb0b0b-e421-440b-9f41-1e25ba5219a1.png`); + + const carImgStack = carStack.addStack(); + const carResStack = carImgStack.addImage(carImg); + carResStack.imageSize = new Size(137.5, 70); + + carStack.addSpacer(); + + const carNumberStack = carStack.addStack(); + carNumberStack.addSpacer(); + carNumberStack.centerAlignContent(); + const carNumebrText = carNumberStack.addText(this.serveInfo.carNumber); + carNumebrText.font = Font.boldSystemFont(24); + carNumebrText.textColor = this.widgetColor; + carNumebrText.centerAlignText(); + carNumberStack.addSpacer(); + + carStack.addSpacer(); + + const carSafeStack = carStack.addStack(); + carSafeStack.addSpacer(); + carSafeStack.centerAlignContent(); + const safeData = this.dataSource.remoteInfo.list.filter( + item => item.security !== 'safe') || []; + let safeText = ``; + let safeIconImg; + if (safeData.length > 0) { + if (safeData.length === 1) { + safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; + } else { + safeText = `隐患:${safeData.length}`; + } + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image); + } else { + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image); + } + + carSafeStack.addSpacer(5); + const statusText = carSafeStack.addText(!safeText ? '已上锁' : safeText); + statusText.centerAlignText(); + statusText.font = Font.systemFont(12); + statusText.textColor = safeText ? new Color('#f5222d') : this.widgetColor; + + safeIconImg.tintColor = statusText.textColor; + safeIconImg.imageSize = new Size(10, 14); + + carSafeStack.addSpacer(); + + carStack.addSpacer(); + + containerStack.addSpacer(); + const rightStack = containerStack.addStack(); + rightStack.layoutVertically(); + await this.renderSmall(rightStack); + + return w; + }; + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + widget.setPadding(10, 10, 10, 10); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + return await this.renderMedium(widget); + } else { + return await this.notSupport(widget); + } + } +} + +// @组件代码结束 +await Runing(Widget, '', false); //远程开发环境 From a791d19c50db0b056e95b7500aabf03c0284e255 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 9 Jun 2022 16:16:06 +0800 Subject: [PATCH 021/152] ftms --- Scripts/Ftms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 9cb082e..98312b5 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -248,7 +248,7 @@ class Widget extends DmYY { bottomStack.setPadding(10, 0, 10, 0); bottomStack.centerAlignContent(); bottomStack.addSpacer(); - bottomStack.cornerRadius = 20; + bottomStack.cornerRadius = 10; bottomStack.backgroundColor = new Color('#e8e8e8'); const dataTime = this.dataSource.remoteInfo.datatime.split(`-`); const countKmText = bottomStack.addText( From 15eab0958cd3103d8c6445841f32704d120e9346 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 9 Jun 2022 16:17:10 +0800 Subject: [PATCH 022/152] add --- Scripts/Ftms.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 98312b5..7502124 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -248,7 +248,7 @@ class Widget extends DmYY { bottomStack.setPadding(10, 0, 10, 0); bottomStack.centerAlignContent(); bottomStack.addSpacer(); - bottomStack.cornerRadius = 10; + bottomStack.cornerRadius = 15; bottomStack.backgroundColor = new Color('#e8e8e8'); const dataTime = this.dataSource.remoteInfo.datatime.split(`-`); const countKmText = bottomStack.addText( From 92b18b51fcb17a8329397734601c8935ad394568 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 9 Jun 2022 17:30:00 +0800 Subject: [PATCH 023/152] picUrl --- Scripts/Ftms.js | 460 +++++++++++++++++++++++++----------------------- 1 file changed, 237 insertions(+), 223 deletions(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 7502124..878a0cf 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -3,22 +3,21 @@ // icon-color: deep-gray; icon-glyph: tv; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +if (typeof require === 'undefined') require = importModule +const { DmYY, Runing } = require('./DmYY') // @组件代码开始 class Widget extends DmYY { constructor(arg) { - super(arg); - this.name = '一汽丰田'; - this.en = 'ftms'; - config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); - this.cacheName = this.md5(`dataSouce_${this.en}`); - this.logo = - 'https://www.toyota.com.cn/favicon.ico'; + super(arg) + this.name = '一汽丰田' + this.en = 'ftms' + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig) + this.cacheName = this.md5(`dataSouce_${this.en}`) + this.logo = 'https://www.toyota.com.cn/favicon.ico' } - widgetHeight = 145; + widgetHeight = 145 baseOpt = { headers: { Connection: `keep-alive`, @@ -26,10 +25,10 @@ class Widget extends DmYY { 'Content-Type': `application/json`, }, body: ``, - }; + } serveInfo = { carNumber: '', - }; + } dataSource = { remoteInfo: { datatime: '', @@ -42,316 +41,331 @@ class Widget extends DmYY { oilRate: '0', oilWaste: '0', }, - }; + } init = async () => { if (this.settings.dataSource) { - this.serveInfo = this.settings.serveInfo; - this.dataSource = this.settings.dataSource; + this.serveInfo = this.settings.serveInfo + this.dataSource = this.settings.dataSource } else { - await this.cacheData(); + await this.cacheData() } - this.cacheData(); - }; + this.cacheData() + } cacheData = async () => { try { - await this.getBmuServeHicleInfo(); - await this.getRemoteInfoDetail(); + await this.getBmuServeHicleInfo() + await this.getRemoteInfoDetail() } catch (e) { - console.log(e); + console.log(e) } - }; + } getBaseOptions(api) { - const baseURL = `https://appiov.ftms.com.cn`; - return {url: `${baseURL}/${api}`, ...this.baseOpt}; + const baseURL = `https://appiov.ftms.com.cn` + return { url: `${baseURL}/${api}`, ...this.baseOpt } } getRemoteInfoDetail = async () => { const options = this.getBaseOptions( - 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail', - ); - const respones = await this.$request.post(options); + 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail' + ) + const respones = await this.$request.post(options) if (respones.msg === 'success') { - this.dataSource.remoteInfo = respones.result; + this.dataSource.remoteInfo = respones.result } - await this.getDrivingMonitorInfo(); - }; + await this.getDrivingMonitorInfo() + } getDrivingMonitorInfo = async () => { const options = this.getBaseOptions( - 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo', - ); - const respones = await this.$request.post(options); + 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo' + ) + const respones = await this.$request.post(options) if (respones.msg === 'success') { - this.dataSource.monitorInfo = respones.result; + this.dataSource.monitorInfo = respones.result } - this.settings.dataSource = this.dataSource; - this.saveSettings(false); - }; + this.settings.dataSource = this.dataSource + this.saveSettings(false) + } getBmuServeHicleInfo = async () => { - let headers = await this.getCache('@ftms.headers'); - headers = JSON.parse(headers || '{}'); - this.baseOpt.headers = {token: headers.token, ...this.baseOpt.headers}; + let headers = await this.getCache('@ftms.headers') + headers = JSON.parse(headers || '{}') + this.baseOpt.headers = { token: headers.token, ...this.baseOpt.headers } const options = { url: `https://superapp.ftms.com.cn/superapp/users/wt/getbmuservehicleinfo?scriptable=1`, headers, - }; + } if (!this.settings.serveInfo) { - const response = await this.$request.post(options); + const response = await this.$request.post(options) if (response.code === '200') { - this.settings.serveInfo = response.data; - this.serveInfo = response.data; - this.saveSettings(false); + this.settings.serveInfo = response.data + this.serveInfo = response.data + this.saveSettings(false) } } else { - this.serveInfo = this.settings.serveInfo || {}; + this.serveInfo = this.settings.serveInfo || {} } - this.baseOpt.headers.userId = this.serveInfo.userId; - this.baseOpt.body = JSON.stringify({vin: this.serveInfo.vin}); - this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}`; - }; + this.baseOpt.headers.userId = this.serveInfo.userId + this.baseOpt.body = JSON.stringify({ vin: this.serveInfo.vin }) + this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}` + } createProgressBar( - soFar, total = 100, width = 400, height = 40, showPercentage = false) { - const context = new DrawContext(); - context.size = new Size(width, height); - context.opaque = false; - context.respectScreenScale = true; + soFar, + total = 100, + width = 400, + height = 40, + showPercentage = false + ) { + const context = new DrawContext() + context.size = new Size(width, height) + context.opaque = false + context.respectScreenScale = true // bar background - context.setFillColor(new Color('#48484b')); - const bgPath = new Path(); + context.setFillColor(new Color('#48484b')) + const bgPath = new Path() bgPath.addRoundedRect( - new Rect(0, 0, width, height), height / 2, (height / 2) - 1); - context.addPath(bgPath); - context.fillPath(); + new Rect(0, 0, width, height), + height / 2, + height / 2 - 1 + ) + context.addPath(bgPath) + context.fillPath() // bar foreground - context.setFillColor(new Color('#e8e8e8')); - const fgPath = new Path(); + context.setFillColor(new Color('#e8e8e8')) + const fgPath = new Path() fgPath.addRoundedRect( - new Rect(0, 0, (width * soFar) / total, height), height / 2, - (height / 2) - 1, - ); - context.addPath(fgPath); - context.fillPath(); + new Rect(0, 0, (width * soFar) / total, height), + height / 2, + height / 2 - 1 + ) + context.addPath(fgPath) + context.fillPath() if (showPercentage) { - const percentage = ((soFar / total) * 100).toFixed(2); - let xPos = (width * soFar) / total + 5; + const percentage = ((soFar / total) * 100).toFixed(2) + let xPos = (width * soFar) / total + 5 // if over 70%, show in foreground area // to ensure that it doesn't overflow the display if (percentage > 70) { - xPos = (width * soFar) / total - 55; + xPos = (width * soFar) / total - 55 } - context.setFont(Font.semiboldRoundedSystemFont(14)); - context.setTextColor(primaryTextColor); - context.drawText(`${percentage}%`, new Point(xPos, (height / 14))); + context.setFont(Font.semiboldRoundedSystemFont(14)) + context.setTextColor(primaryTextColor) + context.drawText(`${percentage}%`, new Point(xPos, height / 14)) } - return context.getImage(); + return context.getImage() } renderBorder = (stack) => { - stack.borderWidth = 1; - }; + stack.borderWidth = 1 + } renderImage = async (uri) => { - return this.$request.get(uri, 'IMG'); - }; + return this.$request.get(uri, 'IMG') + } notSupport(w) { - const stack = w.addStack(); - stack.addText('暂不支持'); - return w; + const stack = w.addStack() + stack.addText('暂不支持') + return w } renderSmall = async (w) => { - w.addSpacer(); + w.addSpacer() - const stack = w.addStack(); - stack.layoutVertically(); - const headerStack = stack.addStack(); - headerStack.centerAlignContent(); - headerStack.addSpacer(10); + const stack = w.addStack() + stack.layoutVertically() + const headerStack = stack.addStack() + headerStack.centerAlignContent() + headerStack.addSpacer(10) const gasImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/gas-station.png`); + `https://img.icons8.com/ios-glyphs/344/gas-station.png` + ) - const gasIcon = headerStack.addImage(gasImg); - gasIcon.imageSize = new Size(16, 16); - headerStack.addSpacer(5); + const gasIcon = headerStack.addImage(gasImg) + gasIcon.imageSize = new Size(16, 16) + headerStack.addSpacer(5) const oilRateStackText = headerStack.addText( - `${this.dataSource.monitorInfo.oilRate}%`); - oilRateStackText.textColor = this.widgetColor; - oilRateStackText.font = Font.boldSystemFont(14); - - headerStack.addSpacer(); - const logImg = await this.renderImage(this.logo); - const logImgStack = headerStack.addImage(logImg); - logImgStack.imageSize = new Size(20, 20); - headerStack.addSpacer(10); - - const bodyStack = stack.addStack(); - bodyStack.centerAlignContent(); - bodyStack.addSpacer(); + `${this.dataSource.monitorInfo.oilRate}%` + ) + oilRateStackText.textColor = this.widgetColor + oilRateStackText.font = Font.boldSystemFont(14) + + headerStack.addSpacer() + const logImg = await this.renderImage(this.logo) + const logImgStack = headerStack.addImage(logImg) + logImgStack.imageSize = new Size(20, 20) + headerStack.addSpacer(10) + + const bodyStack = stack.addStack() + bodyStack.centerAlignContent() + bodyStack.addSpacer() const progressImg = this.createProgressBar( - this.dataSource.monitorInfo.oilRate); - const progressBar = bodyStack.addImage(progressImg); - progressBar.imageSize = new Size(this.widgetHeight, 28); - bodyStack.addSpacer(); + this.dataSource.monitorInfo.oilRate + ) + const progressBar = bodyStack.addImage(progressImg) + progressBar.imageSize = new Size(this.widgetHeight, 28) + bodyStack.addSpacer() - stack.addSpacer(); + stack.addSpacer() - const oilWasteStack = stack.addStack(); - oilWasteStack.centerAlignContent(); - oilWasteStack.addSpacer(); + const oilWasteStack = stack.addStack() + oilWasteStack.centerAlignContent() + oilWasteStack.addSpacer() const oilWasteStackText = oilWasteStack.addText( - `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km`); - oilWasteStackText.textColor = this.widgetColor; - oilWasteStackText.font = Font.boldSystemFont(10); - oilWasteStack.addSpacer(); + `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km` + ) + oilWasteStackText.textColor = this.widgetColor + oilWasteStackText.font = Font.boldSystemFont(10) + oilWasteStack.addSpacer() - const kilometerStack = stack.addStack(); + const kilometerStack = stack.addStack() - kilometerStack.centerAlignContent(); - kilometerStack.addSpacer(); + kilometerStack.centerAlignContent() + kilometerStack.addSpacer() const panoImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/bar-chart.png`); - const panoImgStack = kilometerStack.addStack(); - panoImgStack.setPadding(5, 0, 0, 0); - const panoStack = panoImgStack.addImage(panoImg); - panoStack.imageSize = new Size(20, 20); - kilometerStack.addSpacer(5); - - const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km); - oilWasteText.font = Font.boldSystemFont(28); - oilWasteText.textColor = this.widgetColor; - kilometerStack.addSpacer(5); - const unitStack = kilometerStack.addStack(); - unitStack.setPadding(5, 0, 0, 0); - const oilWasteUnit = unitStack.addText( - 'km'); - oilWasteUnit.font = Font.boldSystemFont(14); - oilWasteUnit.textColor = this.widgetColor; - kilometerStack.addSpacer(); - - stack.addSpacer(); - - const btBodyStack = stack.addStack(); - btBodyStack.addSpacer(); - const bottomStack = btBodyStack.addStack(); - bottomStack.setPadding(10, 0, 10, 0); - bottomStack.centerAlignContent(); - bottomStack.addSpacer(); - bottomStack.cornerRadius = 15; - bottomStack.backgroundColor = new Color('#e8e8e8'); - const dataTime = this.dataSource.remoteInfo.datatime.split(`-`); + `https://img.icons8.com/ios-glyphs/344/bar-chart.png` + ) + const panoImgStack = kilometerStack.addStack() + panoImgStack.setPadding(5, 0, 0, 0) + const panoStack = panoImgStack.addImage(panoImg) + panoStack.imageSize = new Size(20, 20) + kilometerStack.addSpacer(5) + + const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km) + oilWasteText.font = Font.boldSystemFont(28) + oilWasteText.textColor = this.widgetColor + kilometerStack.addSpacer(5) + const unitStack = kilometerStack.addStack() + unitStack.setPadding(5, 0, 0, 0) + const oilWasteUnit = unitStack.addText('km') + oilWasteUnit.font = Font.boldSystemFont(14) + oilWasteUnit.textColor = this.widgetColor + kilometerStack.addSpacer() + + stack.addSpacer() + + const btBodyStack = stack.addStack() + btBodyStack.addSpacer() + const bottomStack = btBodyStack.addStack() + bottomStack.setPadding(10, 0, 10, 0) + bottomStack.centerAlignContent() + bottomStack.addSpacer() + bottomStack.cornerRadius = 15 + bottomStack.backgroundColor = new Color('#e8e8e8') + const dataTime = this.dataSource.remoteInfo.datatime.split(`-`) const countKmText = bottomStack.addText( - `上传:${dataTime[1]}-${dataTime[2]}`); - countKmText.textColor = this.widgetColor; - countKmText.font = Font.boldSystemFont(12); - countKmText.centerAlignText(); - bottomStack.addSpacer(); - w.addSpacer(); - return w; - }; + `上传:${dataTime[1]}-${dataTime[2]}` + ) + countKmText.textColor = this.widgetColor + countKmText.font = Font.boldSystemFont(12) + countKmText.centerAlignText() + bottomStack.addSpacer() + w.addSpacer() + return w + } renderLarge = async (w) => { - return this.renderSmall(w); - }; + return this.renderSmall(w) + } renderMedium = async (w) => { - const containerStack = w.addStack(); - containerStack.centerAlignContent(); - const carStack = containerStack.addStack(); - carStack.addSpacer(); - carStack.backgroundColor = new Color('#e8e8e8'); - - carStack.layoutVertically(); - - carStack.centerAlignContent(); - carStack.size = new Size(this.widgetHeight, this.widgetHeight); - carStack.cornerRadius = 20; - const carImg = await this.renderImage( - `https://appiov.ftms.com.cn//ftmsIovUpload/image/20220219/42fb0b0b-e421-440b-9f41-1e25ba5219a1.png`); - - const carImgStack = carStack.addStack(); - const carResStack = carImgStack.addImage(carImg); - carResStack.imageSize = new Size(137.5, 70); - - carStack.addSpacer(); - - const carNumberStack = carStack.addStack(); - carNumberStack.addSpacer(); - carNumberStack.centerAlignContent(); - const carNumebrText = carNumberStack.addText(this.serveInfo.carNumber); - carNumebrText.font = Font.boldSystemFont(24); - carNumebrText.textColor = this.widgetColor; - carNumebrText.centerAlignText(); - carNumberStack.addSpacer(); - - carStack.addSpacer(); - - const carSafeStack = carStack.addStack(); - carSafeStack.addSpacer(); - carSafeStack.centerAlignContent(); - const safeData = this.dataSource.remoteInfo.list.filter( - item => item.security !== 'safe') || []; - let safeText = ``; - let safeIconImg; + const containerStack = w.addStack() + containerStack.centerAlignContent() + const carStack = containerStack.addStack() + carStack.addSpacer() + carStack.backgroundColor = new Color('#e8e8e8') + + carStack.layoutVertically() + + carStack.centerAlignContent() + carStack.size = new Size(this.widgetHeight, this.widgetHeight) + carStack.cornerRadius = 20 + const carImg = await this.renderImage(this.serveInfo.picUrl) + + const carImgStack = carStack.addStack() + const carResStack = carImgStack.addImage(carImg) + carResStack.imageSize = new Size(137.5, 70) + + carStack.addSpacer() + + const carNumberStack = carStack.addStack() + carNumberStack.addSpacer() + carNumberStack.centerAlignContent() + const carNumebrText = carNumberStack.addText(this.serveInfo.carNumber) + carNumebrText.font = Font.boldSystemFont(24) + carNumebrText.textColor = this.widgetColor + carNumebrText.centerAlignText() + carNumberStack.addSpacer() + + carStack.addSpacer() + + const carSafeStack = carStack.addStack() + carSafeStack.addSpacer() + carSafeStack.centerAlignContent() + const safeData = + this.dataSource.remoteInfo.list.filter( + (item) => item.security !== 'safe' + ) || [] + let safeText = `` + let safeIconImg if (safeData.length > 0) { if (safeData.length === 1) { - safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; + safeText = `${safeData[0].typeName}:${safeData[0].dataName}` } else { - safeText = `隐患:${safeData.length}`; + safeText = `隐患:${safeData.length}` } - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image); + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image) } else { - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image); + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image) } - carSafeStack.addSpacer(5); - const statusText = carSafeStack.addText(!safeText ? '已上锁' : safeText); - statusText.centerAlignText(); - statusText.font = Font.systemFont(12); - statusText.textColor = safeText ? new Color('#f5222d') : this.widgetColor; + carSafeStack.addSpacer(5) + const statusText = carSafeStack.addText(!safeText ? '已上锁' : safeText) + statusText.centerAlignText() + statusText.font = Font.systemFont(12) + statusText.textColor = safeText ? new Color('#f5222d') : this.widgetColor - safeIconImg.tintColor = statusText.textColor; - safeIconImg.imageSize = new Size(10, 14); + safeIconImg.tintColor = statusText.textColor + safeIconImg.imageSize = new Size(10, 14) - carSafeStack.addSpacer(); + carSafeStack.addSpacer() - carStack.addSpacer(); + carStack.addSpacer() - containerStack.addSpacer(); - const rightStack = containerStack.addStack(); - rightStack.layoutVertically(); - await this.renderSmall(rightStack); + containerStack.addSpacer() + const rightStack = containerStack.addStack() + rightStack.layoutVertically() + await this.renderSmall(rightStack) - return w; - }; + return w + } /** * 渲染函数,函数名固定 * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 */ async render() { - await this.init(); - const widget = new ListWidget(); - widget.setPadding(10, 10, 10, 10); - await this.getWidgetBackgroundImage(widget); + await this.init() + const widget = new ListWidget() + widget.setPadding(10, 10, 10, 10) + await this.getWidgetBackgroundImage(widget) if (this.widgetFamily === 'medium') { - return await this.renderMedium(widget); + return await this.renderMedium(widget) } else { - return await this.notSupport(widget); + return await this.notSupport(widget) } } } // @组件代码结束 -await Runing(Widget, '', false); //远程开发环境 +await Runing(Widget, '', false) //远程开发环境 From da60a37a2ba4a2f3f1bd4026f0d650c6a2de0c33 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 10 Jun 2022 12:31:18 +0800 Subject: [PATCH 024/152] add --- Scripts/CarWidget.js | 311 +++++++++++++++++++++++++++++++++++ Scripts/Ftms.js | 383 ++++++------------------------------------- 2 files changed, 364 insertions(+), 330 deletions(-) create mode 100644 Scripts/CarWidget.js diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js new file mode 100644 index 0000000..ee6e252 --- /dev/null +++ b/Scripts/CarWidget.js @@ -0,0 +1,311 @@ +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: deep-gray; icon-glyph: car; + +// 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 +if (typeof require === 'undefined') require = importModule; +const {DmYY, Runing} = require('./DmYY'); + +// @组件代码开始 +class Widget extends DmYY { + constructor(arg) { + super(arg); + config.runsInApp && + this.registerAction('依赖插件', () => { + return this.setAlertInput('设置依赖插件', '汽车的依赖插件地址', { + filePath: '', + }); + }, {name: 'car', color: '#f5222d'}); + config.runsInApp && + this.registerAction('缩放比例', () => { + return this.setAlertInput('设置缩放比例', '比例越大进度条越长', { + scale: '比例默认值1', + }); + }); + + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + this.cacheName = this.md5(`dataSouce_${this.en}`); + const filePath = this.settings.filePath || 'Ftms'; + const carModule = require(`./${filePath}`); + const carService = new carModule(this); + this.scale = parseFloat(this.settings.scale) || 1; // 柱状图比例高度,值越大,柱状范围越广 + this.init = carService.init; + this.name = carService.name; + this.logo = carService.logo; + } + + widgetHeight = 145; + + serveInfo = { + carNumber: '', + }; + dataSource = { + remoteInfo: { + datatime: '', + list: [], + userId: '', + carNumber: '', + }, + monitorInfo: { + km: '0', + oilRate: '0', + oilWaste: '0', + }, + }; + + createProgressBar( + soFar, + total = 100, + width = 400, + height = 40, + showPercentage = false, + ) { + const context = new DrawContext(); + context.size = new Size(width, height); + context.opaque = false; + context.respectScreenScale = true; + + // bar background + context.setFillColor(new Color('#48484b')); + const bgPath = new Path(); + bgPath.addRoundedRect( + new Rect(0, 0, width, height), + height / 2, + height / 2 - 1, + ); + context.addPath(bgPath); + context.fillPath(); + + // bar foreground + context.setFillColor(new Color('#e8e8e8')); + const fgPath = new Path(); + fgPath.addRoundedRect( + new Rect(0, 0, (width * soFar) / total, height), + height / 2, + height / 2 - 1, + ); + context.addPath(fgPath); + context.fillPath(); + + if (showPercentage) { + const percentage = ((soFar / total) * 100).toFixed(2); + let xPos = (width * soFar) / total + 5; + // if over 70%, show in foreground area + // to ensure that it doesn't overflow the display + if (percentage > 70) { + xPos = (width * soFar) / total - 55; + } + + context.setFont(Font.semiboldRoundedSystemFont(14)); + context.setTextColor(primaryTextColor); + context.drawText(`${percentage}%`, new Point(xPos, height / 14)); + } + + return context.getImage(); + } + + renderBorder = (stack) => { + stack.borderWidth = 1; + }; + + renderImage = async (uri) => { + return this.$request.get(uri, 'IMG'); + }; + + notSupport(w) { + const stack = w.addStack(); + stack.addText('暂不支持'); + return w; + } + + renderSmall = async (w) => { + w.addSpacer(); + + const stack = w.addStack(); + stack.layoutVertically(); + const headerStack = stack.addStack(); + headerStack.centerAlignContent(); + headerStack.addSpacer(10); + const gasImg = await this.renderImage( + `https://img.icons8.com/ios-glyphs/344/gas-station.png`, + ); + + const gasIcon = headerStack.addImage(gasImg); + gasIcon.imageSize = new Size(16, 16); + headerStack.addSpacer(5); + + const oilRateStackText = headerStack.addText( + `${this.dataSource.monitorInfo.oilRate}%`, + ); + oilRateStackText.textColor = this.widgetColor; + oilRateStackText.font = Font.boldSystemFont(14); + + headerStack.addSpacer(); + const logImg = await this.renderImage(this.logo); + const logImgStack = headerStack.addImage(logImg); + logImgStack.imageSize = new Size(20, 20); + headerStack.addSpacer(10); + + const bodyStack = stack.addStack(); + bodyStack.centerAlignContent(); + bodyStack.addSpacer(); + const progressImg = this.createProgressBar( + this.dataSource.monitorInfo.oilRate, + ); + const progressBar = bodyStack.addImage(progressImg); + progressBar.imageSize = new Size(this.widgetHeight * this.scale, 28); + bodyStack.addSpacer(); + + stack.addSpacer(); + + const oilWasteStack = stack.addStack(); + oilWasteStack.centerAlignContent(); + oilWasteStack.addSpacer(); + const oilWasteStackText = oilWasteStack.addText( + `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km`, + ); + oilWasteStackText.textColor = this.widgetColor; + oilWasteStackText.font = Font.boldSystemFont(10); + oilWasteStack.addSpacer(); + + const kilometerStack = stack.addStack(); + + kilometerStack.centerAlignContent(); + kilometerStack.addSpacer(); + const panoImg = await this.renderImage( + `https://img.icons8.com/ios-glyphs/344/bar-chart.png`, + ); + const panoImgStack = kilometerStack.addStack(); + panoImgStack.setPadding(5, 0, 0, 0); + const panoStack = panoImgStack.addImage(panoImg); + panoStack.imageSize = new Size(20, 20); + kilometerStack.addSpacer(5); + + const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km); + oilWasteText.font = Font.boldSystemFont(28); + oilWasteText.textColor = this.widgetColor; + kilometerStack.addSpacer(5); + const unitStack = kilometerStack.addStack(); + unitStack.setPadding(5, 0, 0, 0); + const oilWasteUnit = unitStack.addText('km'); + oilWasteUnit.font = Font.boldSystemFont(14); + oilWasteUnit.textColor = this.widgetColor; + kilometerStack.addSpacer(); + + stack.addSpacer(); + + const btBodyStack = stack.addStack(); + btBodyStack.addSpacer(); + const bottomStack = btBodyStack.addStack(); + bottomStack.setPadding(10, 0, 10, 0); + bottomStack.centerAlignContent(); + bottomStack.addSpacer(); + bottomStack.cornerRadius = 15; + bottomStack.backgroundColor = new Color('#e8e8e8'); + const dataTime = this.dataSource.remoteInfo.datatime.split(`-`); + const countKmText = bottomStack.addText( + `上传:${dataTime[1] || ''}-${dataTime[2] || ''}`, + ); + countKmText.textColor = this.widgetColor; + countKmText.font = Font.boldSystemFont(12); + countKmText.centerAlignText(); + bottomStack.addSpacer(); + w.addSpacer(); + return w; + }; + + renderLarge = async (w) => { + return this.renderSmall(w); + }; + + renderMedium = async (w) => { + const containerStack = w.addStack(); + containerStack.centerAlignContent(); + const carStack = containerStack.addStack(); + carStack.addSpacer(); + carStack.backgroundColor = new Color('#e8e8e8'); + + carStack.layoutVertically(); + + carStack.centerAlignContent(); + carStack.size = new Size(this.widgetHeight, this.widgetHeight); + carStack.cornerRadius = 20; + const carImg = await this.renderImage(this.serveInfo.picUrl); + + const carImgStack = carStack.addStack(); + const carResStack = carImgStack.addImage(carImg); + carResStack.imageSize = new Size(137.5, 70); + + carStack.addSpacer(); + + const carNumberStack = carStack.addStack(); + carNumberStack.addSpacer(); + carNumberStack.centerAlignContent(); + const carNumberText = carNumberStack.addText(this.serveInfo.carNumber); + carNumberText.font = Font.boldSystemFont(24); + carNumberText.textColor = this.widgetColor; + carNumberText.centerAlignText(); + carNumberStack.addSpacer(); + + carStack.addSpacer(); + + const carSafeStack = carStack.addStack(); + carSafeStack.addSpacer(); + carSafeStack.centerAlignContent(); + const safeData = + this.dataSource.remoteInfo.list.filter( + (item) => item.security !== 'safe', + ) || []; + let safeText = ``; + let safeIconImg; + if (safeData.length > 0) { + if (safeData.length === 1) { + safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; + } else { + safeText = `隐患:${safeData.length}`; + } + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image); + } else { + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image); + } + + carSafeStack.addSpacer(5); + const statusText = carSafeStack.addText(!safeText ? '已上锁' : safeText); + statusText.centerAlignText(); + statusText.font = Font.systemFont(12); + statusText.textColor = safeText ? new Color('#f5222d') : this.widgetColor; + + safeIconImg.tintColor = statusText.textColor; + safeIconImg.imageSize = new Size(10, 14); + + carSafeStack.addSpacer(); + + carStack.addSpacer(); + + containerStack.addSpacer(); + const rightStack = containerStack.addStack(); + rightStack.layoutVertically(); + await this.renderSmall(rightStack); + + return w; + }; + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + widget.setPadding(10, 10, 10, 10); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + return await this.renderMedium(widget); + } else { + return await this.notSupport(widget); + } + } +} + +// @组件代码结束 +await Runing(Widget, '', false); //远程开发环境 diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 878a0cf..fe1f7ed 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -1,23 +1,13 @@ -// Variables used by Scriptable. -// These must be at the very top of the file. Do not edit. -// icon-color: deep-gray; icon-glyph: tv; +class Ftms { + constructor(carWidget) { + this.$ = carWidget; -// 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === 'undefined') require = importModule -const { DmYY, Runing } = require('./DmYY') - -// @组件代码开始 -class Widget extends DmYY { - constructor(arg) { - super(arg) - this.name = '一汽丰田' - this.en = 'ftms' - config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig) - this.cacheName = this.md5(`dataSouce_${this.en}`) - this.logo = 'https://www.toyota.com.cn/favicon.ico' } - widgetHeight = 145 + name = '一汽丰田'; + en = 'ftms'; + logo = 'https://www.toyota.com.cn/favicon.ico'; + baseOpt = { headers: { Connection: `keep-alive`, @@ -25,347 +15,80 @@ class Widget extends DmYY { 'Content-Type': `application/json`, }, body: ``, - } - serveInfo = { - carNumber: '', - } - dataSource = { - remoteInfo: { - datatime: '', - list: [], - userId: '', - carNumber: '', - }, - monitorInfo: { - km: '0', - oilRate: '0', - oilWaste: '0', - }, - } + }; init = async () => { - if (this.settings.dataSource) { - this.serveInfo = this.settings.serveInfo - this.dataSource = this.settings.dataSource + if (this.$.settings.dataSource) { + this.$.serveInfo = this.$.settings.serveInfo; + this.$.dataSource = this.$.settings.dataSource; } else { - await this.cacheData() + await this.cacheData(); } - this.cacheData() - } + this.cacheData(); + }; cacheData = async () => { try { - await this.getBmuServeHicleInfo() - await this.getRemoteInfoDetail() + await this.getBmuServeHicleInfo(); + await this.getRemoteInfoDetail(); } catch (e) { - console.log(e) + console.log(e); } - } + }; getBaseOptions(api) { - const baseURL = `https://appiov.ftms.com.cn` - return { url: `${baseURL}/${api}`, ...this.baseOpt } + const baseURL = `https://appiov.ftms.com.cn`; + return {url: `${baseURL}/${api}`, ...this.baseOpt}; } getRemoteInfoDetail = async () => { const options = this.getBaseOptions( - 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail' - ) - const respones = await this.$request.post(options) - if (respones.msg === 'success') { - this.dataSource.remoteInfo = respones.result + 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail', + ); + const response = await this.$.$request.post(options); + console.log(response); + if (response.msg === 'success') { + this.$.dataSource.remoteInfo = response.result; } - await this.getDrivingMonitorInfo() - } + await this.getDrivingMonitorInfo(); + }; getDrivingMonitorInfo = async () => { const options = this.getBaseOptions( - 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo' - ) - const respones = await this.$request.post(options) - if (respones.msg === 'success') { - this.dataSource.monitorInfo = respones.result + 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo', + ); + const response = await this.$.$request.post(options); + console.log(response); + if (response.msg === 'success') { + this.$.dataSource.monitorInfo = response.result; } - this.settings.dataSource = this.dataSource - this.saveSettings(false) - } + this.$.settings.dataSource = this.$.dataSource; + this.$.saveSettings(false); + }; getBmuServeHicleInfo = async () => { - let headers = await this.getCache('@ftms.headers') - headers = JSON.parse(headers || '{}') - this.baseOpt.headers = { token: headers.token, ...this.baseOpt.headers } + let headers = await this.$.getCache('@ftms.headers'); + headers = JSON.parse(headers || '{}'); + this.baseOpt.headers = {token: headers.token, ...this.baseOpt.headers}; const options = { url: `https://superapp.ftms.com.cn/superapp/users/wt/getbmuservehicleinfo?scriptable=1`, headers, - } - if (!this.settings.serveInfo) { - const response = await this.$request.post(options) + }; + if (!this.$.settings.serveInfo) { + const response = await this.$.$request.post(options); + console.log(response); if (response.code === '200') { - this.settings.serveInfo = response.data - this.serveInfo = response.data - this.saveSettings(false) - } - } else { - this.serveInfo = this.settings.serveInfo || {} - } - this.baseOpt.headers.userId = this.serveInfo.userId - this.baseOpt.body = JSON.stringify({ vin: this.serveInfo.vin }) - this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}` - } - - createProgressBar( - soFar, - total = 100, - width = 400, - height = 40, - showPercentage = false - ) { - const context = new DrawContext() - context.size = new Size(width, height) - context.opaque = false - context.respectScreenScale = true - - // bar background - context.setFillColor(new Color('#48484b')) - const bgPath = new Path() - bgPath.addRoundedRect( - new Rect(0, 0, width, height), - height / 2, - height / 2 - 1 - ) - context.addPath(bgPath) - context.fillPath() - - // bar foreground - context.setFillColor(new Color('#e8e8e8')) - const fgPath = new Path() - fgPath.addRoundedRect( - new Rect(0, 0, (width * soFar) / total, height), - height / 2, - height / 2 - 1 - ) - context.addPath(fgPath) - context.fillPath() - - if (showPercentage) { - const percentage = ((soFar / total) * 100).toFixed(2) - let xPos = (width * soFar) / total + 5 - // if over 70%, show in foreground area - // to ensure that it doesn't overflow the display - if (percentage > 70) { - xPos = (width * soFar) / total - 55 - } - - context.setFont(Font.semiboldRoundedSystemFont(14)) - context.setTextColor(primaryTextColor) - context.drawText(`${percentage}%`, new Point(xPos, height / 14)) - } - - return context.getImage() - } - - renderBorder = (stack) => { - stack.borderWidth = 1 - } - - renderImage = async (uri) => { - return this.$request.get(uri, 'IMG') - } - - notSupport(w) { - const stack = w.addStack() - stack.addText('暂不支持') - return w - } - - renderSmall = async (w) => { - w.addSpacer() - - const stack = w.addStack() - stack.layoutVertically() - const headerStack = stack.addStack() - headerStack.centerAlignContent() - headerStack.addSpacer(10) - const gasImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/gas-station.png` - ) - - const gasIcon = headerStack.addImage(gasImg) - gasIcon.imageSize = new Size(16, 16) - headerStack.addSpacer(5) - - const oilRateStackText = headerStack.addText( - `${this.dataSource.monitorInfo.oilRate}%` - ) - oilRateStackText.textColor = this.widgetColor - oilRateStackText.font = Font.boldSystemFont(14) - - headerStack.addSpacer() - const logImg = await this.renderImage(this.logo) - const logImgStack = headerStack.addImage(logImg) - logImgStack.imageSize = new Size(20, 20) - headerStack.addSpacer(10) - - const bodyStack = stack.addStack() - bodyStack.centerAlignContent() - bodyStack.addSpacer() - const progressImg = this.createProgressBar( - this.dataSource.monitorInfo.oilRate - ) - const progressBar = bodyStack.addImage(progressImg) - progressBar.imageSize = new Size(this.widgetHeight, 28) - bodyStack.addSpacer() - - stack.addSpacer() - - const oilWasteStack = stack.addStack() - oilWasteStack.centerAlignContent() - oilWasteStack.addSpacer() - const oilWasteStackText = oilWasteStack.addText( - `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km` - ) - oilWasteStackText.textColor = this.widgetColor - oilWasteStackText.font = Font.boldSystemFont(10) - oilWasteStack.addSpacer() - - const kilometerStack = stack.addStack() - - kilometerStack.centerAlignContent() - kilometerStack.addSpacer() - const panoImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/bar-chart.png` - ) - const panoImgStack = kilometerStack.addStack() - panoImgStack.setPadding(5, 0, 0, 0) - const panoStack = panoImgStack.addImage(panoImg) - panoStack.imageSize = new Size(20, 20) - kilometerStack.addSpacer(5) - - const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km) - oilWasteText.font = Font.boldSystemFont(28) - oilWasteText.textColor = this.widgetColor - kilometerStack.addSpacer(5) - const unitStack = kilometerStack.addStack() - unitStack.setPadding(5, 0, 0, 0) - const oilWasteUnit = unitStack.addText('km') - oilWasteUnit.font = Font.boldSystemFont(14) - oilWasteUnit.textColor = this.widgetColor - kilometerStack.addSpacer() - - stack.addSpacer() - - const btBodyStack = stack.addStack() - btBodyStack.addSpacer() - const bottomStack = btBodyStack.addStack() - bottomStack.setPadding(10, 0, 10, 0) - bottomStack.centerAlignContent() - bottomStack.addSpacer() - bottomStack.cornerRadius = 15 - bottomStack.backgroundColor = new Color('#e8e8e8') - const dataTime = this.dataSource.remoteInfo.datatime.split(`-`) - const countKmText = bottomStack.addText( - `上传:${dataTime[1]}-${dataTime[2]}` - ) - countKmText.textColor = this.widgetColor - countKmText.font = Font.boldSystemFont(12) - countKmText.centerAlignText() - bottomStack.addSpacer() - w.addSpacer() - return w - } - - renderLarge = async (w) => { - return this.renderSmall(w) - } - - renderMedium = async (w) => { - const containerStack = w.addStack() - containerStack.centerAlignContent() - const carStack = containerStack.addStack() - carStack.addSpacer() - carStack.backgroundColor = new Color('#e8e8e8') - - carStack.layoutVertically() - - carStack.centerAlignContent() - carStack.size = new Size(this.widgetHeight, this.widgetHeight) - carStack.cornerRadius = 20 - const carImg = await this.renderImage(this.serveInfo.picUrl) - - const carImgStack = carStack.addStack() - const carResStack = carImgStack.addImage(carImg) - carResStack.imageSize = new Size(137.5, 70) - - carStack.addSpacer() - - const carNumberStack = carStack.addStack() - carNumberStack.addSpacer() - carNumberStack.centerAlignContent() - const carNumebrText = carNumberStack.addText(this.serveInfo.carNumber) - carNumebrText.font = Font.boldSystemFont(24) - carNumebrText.textColor = this.widgetColor - carNumebrText.centerAlignText() - carNumberStack.addSpacer() - - carStack.addSpacer() - - const carSafeStack = carStack.addStack() - carSafeStack.addSpacer() - carSafeStack.centerAlignContent() - const safeData = - this.dataSource.remoteInfo.list.filter( - (item) => item.security !== 'safe' - ) || [] - let safeText = `` - let safeIconImg - if (safeData.length > 0) { - if (safeData.length === 1) { - safeText = `${safeData[0].typeName}:${safeData[0].dataName}` - } else { - safeText = `隐患:${safeData.length}` + this.$.settings.serveInfo = response.data; + this.$.serveInfo = response.data; + this.$.saveSettings(false); } - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image) - } else { - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image) - } - - carSafeStack.addSpacer(5) - const statusText = carSafeStack.addText(!safeText ? '已上锁' : safeText) - statusText.centerAlignText() - statusText.font = Font.systemFont(12) - statusText.textColor = safeText ? new Color('#f5222d') : this.widgetColor - - safeIconImg.tintColor = statusText.textColor - safeIconImg.imageSize = new Size(10, 14) - - carSafeStack.addSpacer() - - carStack.addSpacer() - - containerStack.addSpacer() - const rightStack = containerStack.addStack() - rightStack.layoutVertically() - await this.renderSmall(rightStack) - - return w - } - - /** - * 渲染函数,函数名固定 - * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 - */ - async render() { - await this.init() - const widget = new ListWidget() - widget.setPadding(10, 10, 10, 10) - await this.getWidgetBackgroundImage(widget) - if (this.widgetFamily === 'medium') { - return await this.renderMedium(widget) } else { - return await this.notSupport(widget) + this.$.serveInfo = this.$.settings.serveInfo || {}; } - } + this.baseOpt.headers.userId = this.$.serveInfo.userId; + this.baseOpt.body = JSON.stringify({vin: this.$.serveInfo.vin}); + this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}`; + }; } -// @组件代码结束 -await Runing(Widget, '', false) //远程开发环境 +module.exports = Ftms; From f2b684d4b9db3f8b95469131e3bd9719ffce2c5b Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 10 Jun 2022 13:39:35 +0800 Subject: [PATCH 025/152] add --- Scripts/Ftms.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index fe1f7ed..2eccd61 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -1,7 +1,6 @@ class Ftms { constructor(carWidget) { this.$ = carWidget; - } name = '一汽丰田'; From f9b3904efb13470c10a9e4688a826b576a790a22 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 10 Jun 2022 13:49:30 +0800 Subject: [PATCH 026/152] add --- Scripts/CarWidget.js | 25 ++++++++++--------------- Scripts/Ftms.js | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index ee6e252..0c9ab5f 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -39,6 +39,7 @@ class Widget extends DmYY { serveInfo = { carNumber: '', }; + dataSource = { remoteInfo: { datatime: '', @@ -51,6 +52,7 @@ class Widget extends DmYY { oilRate: '0', oilWaste: '0', }, + safeText: '', }; createProgressBar( @@ -202,9 +204,9 @@ class Widget extends DmYY { bottomStack.addSpacer(); bottomStack.cornerRadius = 15; bottomStack.backgroundColor = new Color('#e8e8e8'); - const dataTime = this.dataSource.remoteInfo.datatime.split(`-`); + const dataTime = this.dataSource.remoteInfo.datatime; const countKmText = bottomStack.addText( - `上传:${dataTime[1] || ''}-${dataTime[2] || ''}`, + `上传:${dataTime || '-'}`, ); countKmText.textColor = this.widgetColor; countKmText.font = Font.boldSystemFont(12); @@ -252,28 +254,21 @@ class Widget extends DmYY { const carSafeStack = carStack.addStack(); carSafeStack.addSpacer(); carSafeStack.centerAlignContent(); - const safeData = - this.dataSource.remoteInfo.list.filter( - (item) => item.security !== 'safe', - ) || []; - let safeText = ``; + let safeIconImg; - if (safeData.length > 0) { - if (safeData.length === 1) { - safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; - } else { - safeText = `隐患:${safeData.length}`; - } + if (this.dataSource.safeText) { safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image); } else { safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image); } carSafeStack.addSpacer(5); - const statusText = carSafeStack.addText(!safeText ? '已上锁' : safeText); + const statusText = carSafeStack.addText(this.dataSource.safeText || '已上锁'); statusText.centerAlignText(); statusText.font = Font.systemFont(12); - statusText.textColor = safeText ? new Color('#f5222d') : this.widgetColor; + statusText.textColor = this.dataSource.safeText + ? new Color('#f5222d') + : this.widgetColor; safeIconImg.tintColor = statusText.textColor; safeIconImg.imageSize = new Size(10, 14); diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 2eccd61..08cfbc5 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -48,6 +48,20 @@ class Ftms { console.log(response); if (response.msg === 'success') { this.$.dataSource.remoteInfo = response.result; + const safeData = + this.$.dataSource.remoteInfo.list.filter( + (item) => item.security !== 'safe', + ) || []; + if (safeData.length > 0) { + if (safeData.length === 1) { + this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; + } else { + this.$.dataSource.safeText = `隐患:${safeData.length}`; + } + } + const dataTime = this.$.dataSource.remoteInfo.datatime.split('-'); + this.$.dataSource.remoteInfo.datatime = `${dataTime[1] || + ''}-${dataTime[2] || ''}`; } await this.getDrivingMonitorInfo(); }; @@ -62,6 +76,7 @@ class Ftms { this.$.dataSource.monitorInfo = response.result; } this.$.settings.dataSource = this.$.dataSource; + this.$.saveSettings(false); }; From 49c18ea7d4cca372e907e696261469fbc7a0c3ea Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 10 Jun 2022 14:22:08 +0800 Subject: [PATCH 027/152] =?UTF-8?q?=E7=BC=A9=E6=94=BE=E6=AF=94=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 392 ++++++++++++++++++++++--------------------- 1 file changed, 200 insertions(+), 192 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index 0c9ab5f..cfd4545 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -3,42 +3,50 @@ // icon-color: deep-gray; icon-glyph: car; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +if (typeof require === 'undefined') require = importModule +const { DmYY, Runing } = require('./DmYY') // @组件代码开始 class Widget extends DmYY { constructor(arg) { - super(arg); + super(arg) config.runsInApp && - this.registerAction('依赖插件', () => { - return this.setAlertInput('设置依赖插件', '汽车的依赖插件地址', { - filePath: '', - }); - }, {name: 'car', color: '#f5222d'}); + this.registerAction( + '依赖插件', + () => { + return this.setAlertInput('设置依赖插件', '汽车的依赖插件地址', { + filePath: '', + }) + }, + { name: 'car', color: '#f5222d' } + ) config.runsInApp && - this.registerAction('缩放比例', () => { - return this.setAlertInput('设置缩放比例', '比例越大进度条越长', { - scale: '比例默认值1', - }); - }); - - config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); - this.cacheName = this.md5(`dataSouce_${this.en}`); - const filePath = this.settings.filePath || 'Ftms'; - const carModule = require(`./${filePath}`); - const carService = new carModule(this); - this.scale = parseFloat(this.settings.scale) || 1; // 柱状图比例高度,值越大,柱状范围越广 - this.init = carService.init; - this.name = carService.name; - this.logo = carService.logo; + this.registerAction( + '缩放比例', + () => { + return this.setAlertInput('设置缩放比例', '比例越大进度条越长', { + scale: '比例默认值1', + }) + }, + { name: 'plus.viewfinder', color: '#fa8c16' } + ) + + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig) + this.cacheName = this.md5(`dataSouce_${this.en}`) + const filePath = this.settings.filePath || 'Ftms' + const carModule = require(`./${filePath}`) + const carService = new carModule(this) + this.scale = parseFloat(this.settings.scale) || 1 // 柱状图比例高度,值越大,柱状范围越广 + this.init = carService.init + this.name = carService.name + this.logo = carService.logo } - widgetHeight = 145; + widgetHeight = 145 serveInfo = { carNumber: '', - }; + } dataSource = { remoteInfo: { @@ -53,254 +61,254 @@ class Widget extends DmYY { oilWaste: '0', }, safeText: '', - }; + } createProgressBar( soFar, total = 100, width = 400, height = 40, - showPercentage = false, + showPercentage = false ) { - const context = new DrawContext(); - context.size = new Size(width, height); - context.opaque = false; - context.respectScreenScale = true; + const context = new DrawContext() + context.size = new Size(width, height) + context.opaque = false + context.respectScreenScale = true // bar background - context.setFillColor(new Color('#48484b')); - const bgPath = new Path(); + context.setFillColor(new Color('#48484b')) + const bgPath = new Path() bgPath.addRoundedRect( new Rect(0, 0, width, height), height / 2, - height / 2 - 1, - ); - context.addPath(bgPath); - context.fillPath(); + height / 2 - 1 + ) + context.addPath(bgPath) + context.fillPath() // bar foreground - context.setFillColor(new Color('#e8e8e8')); - const fgPath = new Path(); + context.setFillColor(new Color('#e8e8e8')) + const fgPath = new Path() fgPath.addRoundedRect( new Rect(0, 0, (width * soFar) / total, height), height / 2, - height / 2 - 1, - ); - context.addPath(fgPath); - context.fillPath(); + height / 2 - 1 + ) + context.addPath(fgPath) + context.fillPath() if (showPercentage) { - const percentage = ((soFar / total) * 100).toFixed(2); - let xPos = (width * soFar) / total + 5; + const percentage = ((soFar / total) * 100).toFixed(2) + let xPos = (width * soFar) / total + 5 // if over 70%, show in foreground area // to ensure that it doesn't overflow the display if (percentage > 70) { - xPos = (width * soFar) / total - 55; + xPos = (width * soFar) / total - 55 } - context.setFont(Font.semiboldRoundedSystemFont(14)); - context.setTextColor(primaryTextColor); - context.drawText(`${percentage}%`, new Point(xPos, height / 14)); + context.setFont(Font.semiboldRoundedSystemFont(14)) + context.setTextColor(primaryTextColor) + context.drawText(`${percentage}%`, new Point(xPos, height / 14)) } - return context.getImage(); + return context.getImage() } renderBorder = (stack) => { - stack.borderWidth = 1; - }; + stack.borderWidth = 1 + } renderImage = async (uri) => { - return this.$request.get(uri, 'IMG'); - }; + return this.$request.get(uri, 'IMG') + } notSupport(w) { - const stack = w.addStack(); - stack.addText('暂不支持'); - return w; + const stack = w.addStack() + stack.addText('暂不支持') + return w } renderSmall = async (w) => { - w.addSpacer(); + w.addSpacer() - const stack = w.addStack(); - stack.layoutVertically(); - const headerStack = stack.addStack(); - headerStack.centerAlignContent(); - headerStack.addSpacer(10); + const stack = w.addStack() + stack.layoutVertically() + const headerStack = stack.addStack() + headerStack.centerAlignContent() + headerStack.addSpacer(10) const gasImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/gas-station.png`, - ); + `https://img.icons8.com/ios-glyphs/344/gas-station.png` + ) - const gasIcon = headerStack.addImage(gasImg); - gasIcon.imageSize = new Size(16, 16); - headerStack.addSpacer(5); + const gasIcon = headerStack.addImage(gasImg) + gasIcon.imageSize = new Size(16, 16) + headerStack.addSpacer(5) const oilRateStackText = headerStack.addText( - `${this.dataSource.monitorInfo.oilRate}%`, - ); - oilRateStackText.textColor = this.widgetColor; - oilRateStackText.font = Font.boldSystemFont(14); - - headerStack.addSpacer(); - const logImg = await this.renderImage(this.logo); - const logImgStack = headerStack.addImage(logImg); - logImgStack.imageSize = new Size(20, 20); - headerStack.addSpacer(10); - - const bodyStack = stack.addStack(); - bodyStack.centerAlignContent(); - bodyStack.addSpacer(); + `${this.dataSource.monitorInfo.oilRate}%` + ) + oilRateStackText.textColor = this.widgetColor + oilRateStackText.font = Font.boldSystemFont(14) + + headerStack.addSpacer() + const logImg = await this.renderImage(this.logo) + const logImgStack = headerStack.addImage(logImg) + logImgStack.imageSize = new Size(20, 20) + headerStack.addSpacer(10) + + const bodyStack = stack.addStack() + bodyStack.centerAlignContent() + bodyStack.addSpacer() const progressImg = this.createProgressBar( - this.dataSource.monitorInfo.oilRate, - ); - const progressBar = bodyStack.addImage(progressImg); - progressBar.imageSize = new Size(this.widgetHeight * this.scale, 28); - bodyStack.addSpacer(); + this.dataSource.monitorInfo.oilRate + ) + const progressBar = bodyStack.addImage(progressImg) + progressBar.imageSize = new Size(this.widgetHeight * this.scale, 28) + bodyStack.addSpacer() - stack.addSpacer(); + stack.addSpacer() - const oilWasteStack = stack.addStack(); - oilWasteStack.centerAlignContent(); - oilWasteStack.addSpacer(); + const oilWasteStack = stack.addStack() + oilWasteStack.centerAlignContent() + oilWasteStack.addSpacer() const oilWasteStackText = oilWasteStack.addText( - `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km`, - ); - oilWasteStackText.textColor = this.widgetColor; - oilWasteStackText.font = Font.boldSystemFont(10); - oilWasteStack.addSpacer(); + `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km` + ) + oilWasteStackText.textColor = this.widgetColor + oilWasteStackText.font = Font.boldSystemFont(10) + oilWasteStack.addSpacer() - const kilometerStack = stack.addStack(); + const kilometerStack = stack.addStack() - kilometerStack.centerAlignContent(); - kilometerStack.addSpacer(); + kilometerStack.centerAlignContent() + kilometerStack.addSpacer() const panoImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/bar-chart.png`, - ); - const panoImgStack = kilometerStack.addStack(); - panoImgStack.setPadding(5, 0, 0, 0); - const panoStack = panoImgStack.addImage(panoImg); - panoStack.imageSize = new Size(20, 20); - kilometerStack.addSpacer(5); - - const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km); - oilWasteText.font = Font.boldSystemFont(28); - oilWasteText.textColor = this.widgetColor; - kilometerStack.addSpacer(5); - const unitStack = kilometerStack.addStack(); - unitStack.setPadding(5, 0, 0, 0); - const oilWasteUnit = unitStack.addText('km'); - oilWasteUnit.font = Font.boldSystemFont(14); - oilWasteUnit.textColor = this.widgetColor; - kilometerStack.addSpacer(); - - stack.addSpacer(); - - const btBodyStack = stack.addStack(); - btBodyStack.addSpacer(); - const bottomStack = btBodyStack.addStack(); - bottomStack.setPadding(10, 0, 10, 0); - bottomStack.centerAlignContent(); - bottomStack.addSpacer(); - bottomStack.cornerRadius = 15; - bottomStack.backgroundColor = new Color('#e8e8e8'); - const dataTime = this.dataSource.remoteInfo.datatime; - const countKmText = bottomStack.addText( - `上传:${dataTime || '-'}`, - ); - countKmText.textColor = this.widgetColor; - countKmText.font = Font.boldSystemFont(12); - countKmText.centerAlignText(); - bottomStack.addSpacer(); - w.addSpacer(); - return w; - }; + `https://img.icons8.com/ios-glyphs/344/bar-chart.png` + ) + const panoImgStack = kilometerStack.addStack() + panoImgStack.setPadding(5, 0, 0, 0) + const panoStack = panoImgStack.addImage(panoImg) + panoStack.imageSize = new Size(20, 20) + kilometerStack.addSpacer(5) + + const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km) + oilWasteText.font = Font.boldSystemFont(28) + oilWasteText.textColor = this.widgetColor + kilometerStack.addSpacer(5) + const unitStack = kilometerStack.addStack() + unitStack.setPadding(5, 0, 0, 0) + const oilWasteUnit = unitStack.addText('km') + oilWasteUnit.font = Font.boldSystemFont(14) + oilWasteUnit.textColor = this.widgetColor + kilometerStack.addSpacer() + + stack.addSpacer() + + const btBodyStack = stack.addStack() + btBodyStack.addSpacer() + const bottomStack = btBodyStack.addStack() + bottomStack.setPadding(10, 0, 10, 0) + bottomStack.centerAlignContent() + bottomStack.addSpacer() + bottomStack.cornerRadius = 15 + bottomStack.backgroundColor = new Color('#e8e8e8') + const dataTime = this.dataSource.remoteInfo.datatime + const countKmText = bottomStack.addText(`上传:${dataTime || '-'}`) + countKmText.textColor = this.widgetColor + countKmText.font = Font.boldSystemFont(12) + countKmText.centerAlignText() + bottomStack.addSpacer() + w.addSpacer() + return w + } renderLarge = async (w) => { - return this.renderSmall(w); - }; + return this.renderSmall(w) + } renderMedium = async (w) => { - const containerStack = w.addStack(); - containerStack.centerAlignContent(); - const carStack = containerStack.addStack(); - carStack.addSpacer(); - carStack.backgroundColor = new Color('#e8e8e8'); + const containerStack = w.addStack() + containerStack.centerAlignContent() + const carStack = containerStack.addStack() + carStack.addSpacer() + carStack.backgroundColor = new Color('#e8e8e8') - carStack.layoutVertically(); + carStack.layoutVertically() - carStack.centerAlignContent(); - carStack.size = new Size(this.widgetHeight, this.widgetHeight); - carStack.cornerRadius = 20; - const carImg = await this.renderImage(this.serveInfo.picUrl); + carStack.centerAlignContent() + carStack.size = new Size(this.widgetHeight, this.widgetHeight) + carStack.cornerRadius = 20 + const carImg = await this.renderImage(this.serveInfo.picUrl) - const carImgStack = carStack.addStack(); - const carResStack = carImgStack.addImage(carImg); - carResStack.imageSize = new Size(137.5, 70); + const carImgStack = carStack.addStack() + const carResStack = carImgStack.addImage(carImg) + carResStack.imageSize = new Size(137.5, 70) - carStack.addSpacer(); + carStack.addSpacer() - const carNumberStack = carStack.addStack(); - carNumberStack.addSpacer(); - carNumberStack.centerAlignContent(); - const carNumberText = carNumberStack.addText(this.serveInfo.carNumber); - carNumberText.font = Font.boldSystemFont(24); - carNumberText.textColor = this.widgetColor; - carNumberText.centerAlignText(); - carNumberStack.addSpacer(); + const carNumberStack = carStack.addStack() + carNumberStack.addSpacer() + carNumberStack.centerAlignContent() + const carNumberText = carNumberStack.addText(this.serveInfo.carNumber) + carNumberText.font = Font.boldSystemFont(24) + carNumberText.textColor = this.widgetColor + carNumberText.centerAlignText() + carNumberStack.addSpacer() - carStack.addSpacer(); + carStack.addSpacer() - const carSafeStack = carStack.addStack(); - carSafeStack.addSpacer(); - carSafeStack.centerAlignContent(); + const carSafeStack = carStack.addStack() + carSafeStack.addSpacer() + carSafeStack.centerAlignContent() - let safeIconImg; + let safeIconImg if (this.dataSource.safeText) { - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image); + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image) } else { - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image); + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image) } - carSafeStack.addSpacer(5); - const statusText = carSafeStack.addText(this.dataSource.safeText || '已上锁'); - statusText.centerAlignText(); - statusText.font = Font.systemFont(12); + carSafeStack.addSpacer(5) + const statusText = carSafeStack.addText( + this.dataSource.safeText || '已上锁' + ) + statusText.centerAlignText() + statusText.font = Font.systemFont(12) statusText.textColor = this.dataSource.safeText ? new Color('#f5222d') - : this.widgetColor; + : this.widgetColor - safeIconImg.tintColor = statusText.textColor; - safeIconImg.imageSize = new Size(10, 14); + safeIconImg.tintColor = statusText.textColor + safeIconImg.imageSize = new Size(10, 14) - carSafeStack.addSpacer(); + carSafeStack.addSpacer() - carStack.addSpacer(); + carStack.addSpacer() - containerStack.addSpacer(); - const rightStack = containerStack.addStack(); - rightStack.layoutVertically(); - await this.renderSmall(rightStack); + containerStack.addSpacer() + const rightStack = containerStack.addStack() + rightStack.layoutVertically() + await this.renderSmall(rightStack) - return w; - }; + return w + } /** * 渲染函数,函数名固定 * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 */ async render() { - await this.init(); - const widget = new ListWidget(); - widget.setPadding(10, 10, 10, 10); - await this.getWidgetBackgroundImage(widget); + await this.init() + const widget = new ListWidget() + widget.setPadding(10, 10, 10, 10) + await this.getWidgetBackgroundImage(widget) if (this.widgetFamily === 'medium') { - return await this.renderMedium(widget); + return await this.renderMedium(widget) } else { - return await this.notSupport(widget); + return await this.notSupport(widget) } } } // @组件代码结束 -await Runing(Widget, '', false); //远程开发环境 +await Runing(Widget, '', false) //远程开发环境 From 13bebf6de5cc5b8fe2a3e7c6111e47e94a48bb55 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 14 Jun 2022 11:47:00 +0800 Subject: [PATCH 028/152] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B2=B9=E4=BB=B7?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 15 ++++- Scripts/Ftms.js | 138 ++++++++++++++++++++++++++----------------- 2 files changed, 96 insertions(+), 57 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index cfd4545..0979c1f 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -59,8 +59,10 @@ class Widget extends DmYY { km: '0', oilRate: '0', oilWaste: '0', + oilWasteText: '', }, safeText: '', + oilPriceText: '', } createProgressBar( @@ -172,10 +174,17 @@ class Widget extends DmYY { oilWasteStack.centerAlignContent() oilWasteStack.addSpacer() const oilWasteStackText = oilWasteStack.addText( - `油耗:${this.dataSource.monitorInfo.oilWaste}L/100km` + this.dataSource.monitorInfo.oilWasteText ) oilWasteStackText.textColor = this.widgetColor oilWasteStackText.font = Font.boldSystemFont(10) + oilWasteStack.addSpacer(5) + const oilPriceStackText = oilWasteStack.addText( + this.dataSource.oilPriceText + ) + oilPriceStackText.textColor = this.widgetColor + oilPriceStackText.font = Font.boldSystemFont(10) + oilWasteStack.addSpacer() const kilometerStack = stack.addStack() @@ -211,7 +220,7 @@ class Widget extends DmYY { bottomStack.centerAlignContent() bottomStack.addSpacer() bottomStack.cornerRadius = 15 - bottomStack.backgroundColor = new Color('#e8e8e8') + bottomStack.backgroundColor = new Color('#d9d9d9') const dataTime = this.dataSource.remoteInfo.datatime const countKmText = bottomStack.addText(`上传:${dataTime || '-'}`) countKmText.textColor = this.widgetColor @@ -231,7 +240,7 @@ class Widget extends DmYY { containerStack.centerAlignContent() const carStack = containerStack.addStack() carStack.addSpacer() - carStack.backgroundColor = new Color('#e8e8e8') + carStack.backgroundColor = new Color('#d9d9d9') carStack.layoutVertically() diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 08cfbc5..266349b 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -1,11 +1,11 @@ class Ftms { constructor(carWidget) { - this.$ = carWidget; + this.$ = carWidget } - name = '一汽丰田'; - en = 'ftms'; - logo = 'https://www.toyota.com.cn/favicon.ico'; + name = '一汽丰田' + en = 'ftms' + logo = 'https://www.toyota.com.cn/favicon.ico' baseOpt = { headers: { @@ -14,95 +14,125 @@ class Ftms { 'Content-Type': `application/json`, }, body: ``, - }; + } init = async () => { if (this.$.settings.dataSource) { - this.$.serveInfo = this.$.settings.serveInfo; - this.$.dataSource = this.$.settings.dataSource; + this.$.serveInfo = this.$.settings.serveInfo + this.$.dataSource = this.$.settings.dataSource } else { - await this.cacheData(); + await this.cacheData() } - this.cacheData(); - }; + this.cacheData() + } cacheData = async () => { try { - await this.getBmuServeHicleInfo(); - await this.getRemoteInfoDetail(); + await this.getOilPrice() + await this.getBmuServeHicleInfo() + await this.getRemoteInfoDetail() } catch (e) { - console.log(e); + console.log(e) } - }; + } getBaseOptions(api) { - const baseURL = `https://appiov.ftms.com.cn`; - return {url: `${baseURL}/${api}`, ...this.baseOpt}; + const baseURL = `https://appiov.ftms.com.cn` + return { url: `${baseURL}/${api}`, ...this.baseOpt } } getRemoteInfoDetail = async () => { const options = this.getBaseOptions( - 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail', - ); - const response = await this.$.$request.post(options); - console.log(response); + 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail' + ) + const response = await this.$.$request.post(options) + console.log(response) if (response.msg === 'success') { - this.$.dataSource.remoteInfo = response.result; + this.$.dataSource.remoteInfo = response.result const safeData = this.$.dataSource.remoteInfo.list.filter( - (item) => item.security !== 'safe', - ) || []; + (item) => item.security !== 'safe' + ) || [] if (safeData.length > 0) { if (safeData.length === 1) { - this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; + this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}` } else { - this.$.dataSource.safeText = `隐患:${safeData.length}`; + this.$.dataSource.safeText = `隐患:${safeData.length}` } } - const dataTime = this.$.dataSource.remoteInfo.datatime.split('-'); - this.$.dataSource.remoteInfo.datatime = `${dataTime[1] || - ''}-${dataTime[2] || ''}`; + const dataTime = this.$.dataSource.remoteInfo.datatime.split('-') + this.$.dataSource.remoteInfo.datatime = `${dataTime[1] || ''}-${ + dataTime[2] || '' + }` } - await this.getDrivingMonitorInfo(); - }; + await this.getDrivingMonitorInfo() + } getDrivingMonitorInfo = async () => { const options = this.getBaseOptions( - 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo', - ); - const response = await this.$.$request.post(options); - console.log(response); + 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo' + ) + const response = await this.$.$request.post(options) + console.log(response) if (response.msg === 'success') { - this.$.dataSource.monitorInfo = response.result; + this.$.dataSource.monitorInfo = response.result } - this.$.settings.dataSource = this.$.dataSource; - - this.$.saveSettings(false); - }; + this.$.dataSource.monitorInfo.oilWasteText = `油耗:${this.$.dataSource.monitorInfo.oilWaste}L/100km` + this.$.settings.dataSource = this.$.dataSource + this.$.saveSettings(false) + } getBmuServeHicleInfo = async () => { - let headers = await this.$.getCache('@ftms.headers'); - headers = JSON.parse(headers || '{}'); - this.baseOpt.headers = {token: headers.token, ...this.baseOpt.headers}; + let headers = await this.$.getCache('@ftms.headers') + headers = JSON.parse(headers || '{}') + this.baseOpt.headers = { token: headers.token, ...this.baseOpt.headers } const options = { url: `https://superapp.ftms.com.cn/superapp/users/wt/getbmuservehicleinfo?scriptable=1`, headers, - }; + } if (!this.$.settings.serveInfo) { - const response = await this.$.$request.post(options); - console.log(response); + const response = await this.$.$request.post(options) + console.log(response) if (response.code === '200') { - this.$.settings.serveInfo = response.data; - this.$.serveInfo = response.data; - this.$.saveSettings(false); + this.$.settings.serveInfo = response.data + this.$.serveInfo = response.data + this.$.saveSettings(false) } } else { - this.$.serveInfo = this.$.settings.serveInfo || {}; + this.$.serveInfo = this.$.settings.serveInfo || {} } - this.baseOpt.headers.userId = this.$.serveInfo.userId; - this.baseOpt.body = JSON.stringify({vin: this.$.serveInfo.vin}); - this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}`; - }; + this.baseOpt.headers.userId = this.$.serveInfo.userId + this.baseOpt.body = JSON.stringify({ vin: this.$.serveInfo.vin }) + this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}` + } + + getOilPrice = async () => { + const location = await Location.current() + const locationText = await Location.reverseGeocode( + location.latitude, + location.longitude + ) + const { administrativeArea = '' } = locationText[0] || {} + + const oilNumber = this.$.settings.oilNumber || '92' + const oilType = this.$.settings.oilType || '汽油' + + const filter = `(BHNAME="${oilNumber}#${oilType}")(CITYNAME="${administrativeArea.replace( + '省', + '' + )}")` + const time = Date.now() + const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPTA_WEB_YJ_DQBD&columns=ALL&filter=${encodeURIComponent( + filter + )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=1&source=WEB&_=${time}` + + const options = { url } + const response = await this.$.$request.post(options) + if (response.result) { + this.$.dataSource.oilPrice = response.result.data[0] + this.$.dataSource.oilPriceText = `油价:${response.result.data[0].VALUE}` + } + } } -module.exports = Ftms; +module.exports = Ftms From e62890bc25a99a0aa95c494bb9c10c2d87686b8e Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 14 Jun 2022 11:53:06 +0800 Subject: [PATCH 029/152] =?UTF-8?q?=E6=B2=B9=E4=BB=B7=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index 0979c1f..cc2ffac 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -10,6 +10,17 @@ const { DmYY, Runing } = require('./DmYY') class Widget extends DmYY { constructor(arg) { super(arg) + config.runsInApp && + this.registerAction( + '油价设置', + () => { + return this.setAlertInput('油价设置', '设置油价的价格和类型', { + oilNumber: '92|95|98', + oilType: '汽油|柴油', + }) + }, + { name: 'paperplane', color: '#722ed1' } + ) config.runsInApp && this.registerAction( '依赖插件', From 4f2d1586085a9ac2e32c35adfbf8d0403a30b6b9 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 14 Jun 2022 14:14:25 +0800 Subject: [PATCH 030/152] . --- Scripts/CarWidget.js | 6 ++++-- images/count.svg | 1 + images/gas-night.svg | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 images/count.svg create mode 100644 images/gas-night.svg diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index cc2ffac..f0ea056 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -51,6 +51,7 @@ class Widget extends DmYY { this.init = carService.init this.name = carService.name this.logo = carService.logo + this.viewColor = Color.dynamic(new Color('#d9d9d9'), new Color('#8c8c8c')) } widgetHeight = 145 @@ -205,6 +206,7 @@ class Widget extends DmYY { const panoImg = await this.renderImage( `https://img.icons8.com/ios-glyphs/344/bar-chart.png` ) + const panoImgStack = kilometerStack.addStack() panoImgStack.setPadding(5, 0, 0, 0) const panoStack = panoImgStack.addImage(panoImg) @@ -231,7 +233,7 @@ class Widget extends DmYY { bottomStack.centerAlignContent() bottomStack.addSpacer() bottomStack.cornerRadius = 15 - bottomStack.backgroundColor = new Color('#d9d9d9') + bottomStack.backgroundColor = this.viewColor const dataTime = this.dataSource.remoteInfo.datatime const countKmText = bottomStack.addText(`上传:${dataTime || '-'}`) countKmText.textColor = this.widgetColor @@ -251,7 +253,7 @@ class Widget extends DmYY { containerStack.centerAlignContent() const carStack = containerStack.addStack() carStack.addSpacer() - carStack.backgroundColor = new Color('#d9d9d9') + carStack.backgroundColor = this.viewColor carStack.layoutVertically() diff --git a/images/count.svg b/images/count.svg new file mode 100644 index 0000000..f9cf690 --- /dev/null +++ b/images/count.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/gas-night.svg b/images/gas-night.svg new file mode 100644 index 0000000..300993b --- /dev/null +++ b/images/gas-night.svg @@ -0,0 +1 @@ + \ No newline at end of file From bbd8430f3097aebcdce57a9ce6ef90e871e869c4 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 14 Jun 2022 14:18:18 +0800 Subject: [PATCH 031/152] gas --- Scripts/CarWidget.js | 8 ++++++-- images/gas-night.svg | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index f0ea056..b12e1d2 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -151,7 +151,9 @@ class Widget extends DmYY { headerStack.centerAlignContent() headerStack.addSpacer(10) const gasImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/gas-station.png` + this.isNight + ? 'https://raw.githubusercontent.com/dompling/Scriptable/master/images/gas-night.svg' + : `https://img.icons8.com/ios-glyphs/344/gas-station.png` ) const gasIcon = headerStack.addImage(gasImg) @@ -204,7 +206,9 @@ class Widget extends DmYY { kilometerStack.centerAlignContent() kilometerStack.addSpacer() const panoImg = await this.renderImage( - `https://img.icons8.com/ios-glyphs/344/bar-chart.png` + this.isNight + ? `https://raw.githubusercontent.com/dompling/Scriptable/master/images/count.svg` + : `https://img.icons8.com/ios-glyphs/344/bar-chart.png` ) const panoImgStack = kilometerStack.addStack() diff --git a/images/gas-night.svg b/images/gas-night.svg index 300993b..c9a1e93 100644 --- a/images/gas-night.svg +++ b/images/gas-night.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From 5abcb57c22f1662b41869d2ad987b00863fa54f1 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 14 Jun 2022 14:26:14 +0800 Subject: [PATCH 032/152] . --- Scripts/CarWidget.js | 4 ++-- images/count.png | Bin 0 -> 268 bytes images/count.svg | 1 - images/gas-night.png | Bin 0 -> 2210 bytes images/gas-night.svg | 1 - 5 files changed, 2 insertions(+), 4 deletions(-) create mode 100644 images/count.png delete mode 100644 images/count.svg create mode 100644 images/gas-night.png delete mode 100644 images/gas-night.svg diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index b12e1d2..cb0f5b2 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -152,7 +152,7 @@ class Widget extends DmYY { headerStack.addSpacer(10) const gasImg = await this.renderImage( this.isNight - ? 'https://raw.githubusercontent.com/dompling/Scriptable/master/images/gas-night.svg' + ? 'https://raw.githubusercontent.com/dompling/Scriptable/master/images/gas-night.png' : `https://img.icons8.com/ios-glyphs/344/gas-station.png` ) @@ -207,7 +207,7 @@ class Widget extends DmYY { kilometerStack.addSpacer() const panoImg = await this.renderImage( this.isNight - ? `https://raw.githubusercontent.com/dompling/Scriptable/master/images/count.svg` + ? `https://raw.githubusercontent.com/dompling/Scriptable/master/images/count.png` : `https://img.icons8.com/ios-glyphs/344/bar-chart.png` ) diff --git a/images/count.png b/images/count.png new file mode 100644 index 0000000000000000000000000000000000000000..919c7fbf93ebd5d0a9e812d04bc989489e64618b GIT binary patch literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^Ye1NV8AyuAN4*A8>H$6>u0Z-f5n!FImnBdsPf3tp zFar}SI~T8jh`ep)^r-9#IFB1T?#teyre7`u65*j@P6sMTh0KU)`A8SG^%ZN38p3(nb)K+dB9B zj>Ubk-2ab31c2f<;%~mwG6~&SoA{I!rVgqcLj6vS|M7dur_26 \ No newline at end of file diff --git a/images/gas-night.png b/images/gas-night.png new file mode 100644 index 0000000000000000000000000000000000000000..74f0508e8fe4ce1e4a0e3222ccd6dae74565c897 GIT binary patch literal 2210 zcmeHH{XY{37+>@L{=RNBObs!~+sa#Y%S($i&dm&EM8+av>R7aoot#9mowk#gEbVMH zF;fWhl9L(N#e`F>6wOPwVRtI0AMW$Hf8c(*@8|nG&*%Hw^L(G@^Aw>&0`;`bwE+Nt z9_ol+*jD9y2~Cx)Jhm)Y004kd=-_bwExGwW{&(O%aNsq6-FNG}1~bD#z5#3ls;H`| zYiMd|>*(qm7#bOyn3{pMe+4$T*a5M$vWCKJ?d*3u!kzXw?{#r?bN4{(+wbY+?c;m! z&|$xTz$2)mLBYq+--KhZk+`Vnm=pN;QwfQu2`R+Xw6o_jv$D^BmqX6WzeFjZ7G5s; zq4;WPc?InTgZWccb!{E1;ST%fMh^GxJzmrO<`#Zy+k=Pg9i3f0!rs1t$HSr#@#xso z-^M2-lh3DSexH5uO8WZE+}n5a3-4u%OUo-C{*WtH*VdJPZhZXonZCxkur<@RxS&A4 zLCC|1Apk%Pit_t9{QUF9nT>1{e^ZSWCIZFOv^ii{Zvezu9<|CxAM!Ucn$5SyRp3G` zA2oi62{Lmu^*5y*-A2_mS5>QZrw$-)w{+&w56V)XC7v!H9$A|9JpHI^amF*_z-jSq z?|E4;ppu;|$%1?WdKiYSeEkO?*+C^s=P)$2P{AcU0{j z$E|vQSNZvk4L76w9l>?IsF_|JSn7s#95R>ri8Dy|t%*DTD$DN2Hs~uaLD)tVvK|@L zu9-5QkjJ}41M&>&juVXY$zo^OI*`}!QK(OAYo+UMQ2QMwBsU&Krqfc0{1^dSV0ou; zE<`jGK`dmJJ{;K7G@mtVD(DQkJe9do?~(bt3$uCZFImVzC(z0RvPb)@-fceEc?3lL zBsDh@GwOPEi8bJB5zG>Dz;Kz=GUtnmVwP|X-B&(7(NDp7@*^dU{*-{5b~4_zj5^3hL)j9>L*FkAa@5d) zL40s1tfo9E0T1mEoaMU13)W3Jw8A%|NBfXUIgsz#q?W>pgHE3)!|VYe)d;Y7s3LM3 zZW61xIC9bvqEoAKA@Aw6QYxf!nGd6iSS+fj7WRGCcv!Dj@-O(R76nfqN5QtzZRl)R zQ38Pw2gcQ5bDX~AaOrSRPMkLW!}(oy2q*2FJ}1ygaZ&#rYgy!kr0dDKxc6HNxY{-l z=VP~a*hR8^)E5B}Q6Z5ILh~T4?yJ>D1UK3{cfBZS0ym&l5jRbW=eZLPZ_!g_{!q!t zG`4TJ7O~y4^8R9lN{*Km$L?i!Vz{twAQ|p2%W%M3g=)2j!-%KQPqtAE!Igd z&BCyKiXeO|>Ed+|s7bEg+PdcI0=G?U;%6(2dtXt(#4}k|E^v}J9NN|Sqk5}NJS6kb ziEPSmg~(@;mcheiVm@s{wHTMCsA9gWsmd-IkRlYc3(C5u&BP@@NmEas+Z;>Jiy$@x z55o7AMl|ND$pe&rTC$nBa%c^(RY?i0WC1}WFtw1@&G2?`x4%RlwkJja+kdt1;Hr|S zp_fxQ1IhoQ!xeI%mdy3m=v=;sZU3*TJdc2vhErZWN$J-BBu1#Rq@?p%Qu-BPeU+yi z93NMWFmDO#W<<>r6XQf=w8idN0hqRvvq_>cz1PM=yT=(U4_%qYz`VSFmo4MCIqRfM zFvUnq&0SY7>tpW8&q?N%EzoqKRh81aV8rw zVP?b^QH{BZyyE>73r-|#8W_$y8zhz#IWGzBE>*1BJ^p#4_+4!6fltfq9%rT?_4(T8 zmz!|Qg`2tsJf4GebbqLRJ&$*#bM?%G=#Z|?n}d597f*FjLY5lCdeoWO4^}2}z{l~E z%ULsR&1uoi)f2A!nt$9h#?3F#Gce_2(zHG2ly}`a#{|Rijzdd0!GrXtQk{D$kS)9o zPD>`pJ-JhFS0cAZf2{?^^-@0>vFe?L_$qe?jbfesJhSVZHe|d9<{ys3NDMe!Y%r~M z{T%03beEf)vxE54dnPhgT7;ivYc(X05PxbYasw{dn51uPeNF(%Kg91YGM4f;-8@&j literal 0 HcmV?d00001 diff --git a/images/gas-night.svg b/images/gas-night.svg deleted file mode 100644 index c9a1e93..0000000 --- a/images/gas-night.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From bf8783d0522cf320fd40349a4125567c97407a2e Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 09:32:22 +0800 Subject: [PATCH 033/152] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B2=B9=E4=BB=B7?= =?UTF-8?q?=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 13 +++++++++++-- Scripts/DmYY.js | 13 ++++++++++++- Scripts/Ftms.js | 16 ++++++++-------- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index cb0f5b2..e3ff074 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -14,9 +14,8 @@ class Widget extends DmYY { this.registerAction( '油价设置', () => { - return this.setAlertInput('油价设置', '设置油价的价格和类型', { + return this.setAlertInput('油价设置', '设置油价的价格', { oilNumber: '92|95|98', - oilType: '汽油|柴油', }) }, { name: 'paperplane', color: '#722ed1' } @@ -75,6 +74,7 @@ class Widget extends DmYY { }, safeText: '', oilPriceText: '', + oilZDE: 0, } createProgressBar( @@ -198,6 +198,15 @@ class Widget extends DmYY { ) oilPriceStackText.textColor = this.widgetColor oilPriceStackText.font = Font.boldSystemFont(10) + oilWasteStack.addSpacer(2) + const oildStatus = this.dataSource.oilZDE > 0 + const oilZdeImage = SFSymbol.named( + oildStatus ? 'arrow.up' : 'arrow.up' + ).image + + const oilZdeWidgetImg = oilWasteStack.addImage(oilZdeImage) + oilZdeWidgetImg.tintColor = new Color(oildStatus ? '#f5222d' : '#a0d911') + oilZdeWidgetImg.imageSize = new Size(10, 10) oilWasteStack.addSpacer() diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 368fc6f..a0c8646 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -43,7 +43,18 @@ class DmYY { request.headers = { ...this.defaultHeaders, ...options.headers } } else { request = this.getRequest(options.url) - return (await request.loadImage()) || SFSymbol.named('photo').image + const fileName = this.md5(options.url) + const imagePath = this.FILE_MGR_LOCAL.joinPath( + this.FILE_MGR_LOCAL.documentsDirectory(), + fileName + ) + console.log(imagePath) + if (this.FILE_MGR_LOCAL.fileExists(fileName)) { + return Image.fromFile(imagePath) + } + const response = await request.loadImage() + this.FILE_MGR_LOCAL.writeImage(imagePath, response) + return response } if (type === 'JSON') { return await request.loadJSON() diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 266349b..5f65b92 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -114,23 +114,23 @@ class Ftms { ) const { administrativeArea = '' } = locationText[0] || {} - const oilNumber = this.$.settings.oilNumber || '92' - const oilType = this.$.settings.oilType || '汽油' + const oilNumber = `${this.$.settings.oilNumber || '92'}` - const filter = `(BHNAME="${oilNumber}#${oilType}")(CITYNAME="${administrativeArea.replace( - '省', - '' - )}")` + const filter = `(CITYNAME="${administrativeArea.replace('省', '')}")` const time = Date.now() - const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPTA_WEB_YJ_DQBD&columns=ALL&filter=${encodeURIComponent( + const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPTA_WEB_YJ_JH&columns=ALL&filter=${encodeURIComponent( filter )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=1&source=WEB&_=${time}` const options = { url } const response = await this.$.$request.post(options) + console.log(response) if (response.result) { this.$.dataSource.oilPrice = response.result.data[0] - this.$.dataSource.oilPriceText = `油价:${response.result.data[0].VALUE}` + this.$.dataSource.oilZDE = response.result.data[0][`ZDE${oilNumber}`] + this.$.dataSource.oilPriceText = `油价:${ + response.result.data[0][`V${oilNumber}`] + }` } } } From a55e9bffddcd6194edf5e5e39a43efe3a9548bc2 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 09:58:02 +0800 Subject: [PATCH 034/152] 1 --- Scripts/CarWidget.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index e3ff074..eeeff5b 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -14,8 +14,8 @@ class Widget extends DmYY { this.registerAction( '油价设置', () => { - return this.setAlertInput('油价设置', '设置油价的价格', { - oilNumber: '92|95|98', + return this.setAlertInput('油价设置', '设置类型', { + oilNumber: '89|92|95|98|0', }) }, { name: 'paperplane', color: '#722ed1' } @@ -24,7 +24,7 @@ class Widget extends DmYY { this.registerAction( '依赖插件', () => { - return this.setAlertInput('设置依赖插件', '汽车的依赖插件地址', { + return this.setAlertInput('设置依赖插件', '汽车的依赖插件例如 Ftms', { filePath: '', }) }, From 1cfac136a7f51f7ec5e23db887e2e6dce38d6b5a Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 14:43:18 +0800 Subject: [PATCH 035/152] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B2=B9=E4=BB=B7?= =?UTF-8?q?=E5=B0=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 6 +- Scripts/Oild.js | 245 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 Scripts/Oild.js diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index eeeff5b..501aab5 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -199,13 +199,13 @@ class Widget extends DmYY { oilPriceStackText.textColor = this.widgetColor oilPriceStackText.font = Font.boldSystemFont(10) oilWasteStack.addSpacer(2) - const oildStatus = this.dataSource.oilZDE > 0 + const oilStatus = this.dataSource.oilZDE > 0 const oilZdeImage = SFSymbol.named( - oildStatus ? 'arrow.up' : 'arrow.up' + oilStatus ? 'arrow.up' : 'arrow.up' ).image const oilZdeWidgetImg = oilWasteStack.addImage(oilZdeImage) - oilZdeWidgetImg.tintColor = new Color(oildStatus ? '#f5222d' : '#a0d911') + oilZdeWidgetImg.tintColor = new Color(oilStatus ? '#f5222d' : '#a0d911') oilZdeWidgetImg.imageSize = new Size(10, 10) oilWasteStack.addSpacer() diff --git a/Scripts/Oild.js b/Scripts/Oild.js new file mode 100644 index 0000000..41cc100 --- /dev/null +++ b/Scripts/Oild.js @@ -0,0 +1,245 @@ +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: deep-gray; icon-glyph: car; + +// 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 +if (typeof require === 'undefined') require = importModule; +const {DmYY, Runing} = require('./DmYY'); + +const enumConfig = { + 89: '汽油', + 92: '汽油', + 95: '汽油', + 98: '汽油', + 0: '柴油', +}; + +// @组件代码开始 +class Widget extends DmYY { + constructor(arg) { + super(arg); + config.runsInApp && + this.registerAction( + '油价设置', + () => { + return this.setAlertInput('油价设置', '设置类型,多个英文逗号分割', { + oilNumber: '92,95,89,0', + }); + }, + {name: 'paperplane', color: '#722ed1'}, + ); + this.en = 'oilWidget'; + this.name = '油价'; + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + this.cacheName = this.md5(`dataSource_${this.en}`); + this.oilNumber = `${this.settings.oilNumber || '92'}`.split(','); + } + + dataSource = { + DIM_ID: '', + DIM_DATE: '', + CITYNAME: '', + V0: 0, + V95: 0, + V92: 0, + V89: 0, + ZDE0: 0, + ZDE92: 0, + ZDE95: 0, + ZDE89: 0, + QE0: 0, + QE92: 0, + QE95: 0, + QE89: 0, + }; + + init = async () => { + if (this.settings.dataSource) { + this.dataSource = this.settings.dataSource; + } else { + await this.cacheData(); + } + this.cacheData(); + }; + + cacheData = async () => { + try { + await this.getOilPrice(); + } catch (e) { + console.log(e); + } + }; + + getOilPrice = async () => { + const location = await Location.current(); + const locationText = await Location.reverseGeocode( + location.latitude, + location.longitude, + ); + const {administrativeArea = ''} = locationText[0] || {}; + const filter = `(CITYNAME="${administrativeArea.replace('省', '')}")`; + const time = Date.now(); + const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPTA_WEB_YJ_JH&columns=ALL&filter=${encodeURIComponent( + filter, + )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=1&source=WEB&_=${time}`; + + const options = {url}; + const response = await this.$request.post(options); + console.log(response); + if (response.result) { + this.dataSource = response.result.data[0]; + this.settings.dataSource = this.dataSource; + this.saveSettings(false); + } + }; + + renderImage = async (uri) => { + return this.$request.get(uri, 'IMG'); + }; + + notSupport(w) { + const stack = w.addStack(); + stack.addText('暂不支持'); + return w; + } + + renderSmall = async (w) => { + w.addSpacer(); + const topStack = w.addStack(); + topStack.centerAlignContent(); + + const oilPrice = this.dataSource[`V${this.oilNumber[0]}`]; + const timer = (this.dataSource.DIM_DATE.split(' ')[0] || '').split('-'); + const oilNumText = topStack.addText(`${oilPrice}`); + oilNumText.textColor = this.widgetColor; + oilNumText.font = Font.boldSystemFont(42); + + const oilStatus = this.dataSource[`ZDE${this.oilNumber[0]}`] > 0; + const oilZdeImage = SFSymbol.named( + oilStatus ? 'arrow.up' : 'arrow.up', + ).image; + topStack.addSpacer(5); + const topRStack = topStack.addStack(); + topRStack.setPadding(4, 0, 0, 0); + + topRStack.layoutVertically(); + topRStack.centerAlignContent(); + const zdeStack = topRStack.addStack(); + zdeStack.setPadding(2, 6, 0, 0); + const oilZdeWidgetImg = zdeStack.addImage(oilZdeImage); + oilZdeWidgetImg.tintColor = new Color(oilStatus ? '#f5222d' : '#a0d911'); + oilZdeWidgetImg.imageSize = new Size(16, 16); + + const timerText = topRStack.addText(`${timer[2]}/${timer[1]}`); + timerText.textColor = this.widgetColor; + timerText.font = Font.systemFont(12); + + w.addSpacer(); + + const bottomStack = w.addStack(); + bottomStack.addSpacer(); + const rightText = bottomStack.addText( + `${this.oilNumber[0]}#${enumConfig[this.oilNumber[0]]}`); + oilNumText.textColor = this.widgetColor; + rightText.font = Font.boldSystemFont(18); + rightText.textOpacity = 0.3; + rightText.rightAlignText(); + bottomStack.addSpacer(5); + return w; + }; + + rowData = (w, oilNumber) => { + const colStack = w.addStack(); + + colStack.backgroundColor = Color.dynamic( + new Color('#d9d9d9'), + new Color('#434343'), + ); + + colStack.cornerRadius = 10; + colStack.setPadding(10, 10, 10, 10); + colStack.centerAlignContent(); + + const oilNumText = colStack.addText(`${oilNumber}`); + oilNumText.textColor = this.widgetColor; + oilNumText.font = Font.boldSystemFont(20); + + colStack.addSpacer(5); + + const oilTypeText = colStack.addText(`#${enumConfig[oilNumber]}`); + oilTypeText.textColor = this.widgetColor; + oilTypeText.font = Font.boldSystemFont(12); + + colStack.addSpacer(); + + const zdeText = colStack.addText('涨跌'); + zdeText.textColor = this.widgetColor; + zdeText.font = Font.boldSystemFont(12); + + colStack.addSpacer(5); + + const zdeValue = this.dataSource[`ZDE${oilNumber}`]; + const oilStatus = zdeValue > 0; + const zdeColor = new Color(oilStatus ? '#f5222d' : '#a0d911'); + const zdeValueText = colStack.addText(`${zdeValue}`); + zdeValueText.textColor = zdeColor; + zdeValueText.font = Font.boldSystemFont(12); + + colStack.addSpacer(5); + + const oilZdeImage = SFSymbol.named( + oilStatus ? 'arrow.up' : 'arrow.up', + ).image; + const oilZdeWidgetImg = colStack.addImage(oilZdeImage); + oilZdeWidgetImg.tintColor = zdeColor; + oilZdeWidgetImg.imageSize = new Size(12, 12); + + colStack.addSpacer(); + + const dollarImage = SFSymbol.named(`dollarsign.circle.fill`).image; + const dollarWidgetImage = colStack.addImage(dollarImage); + dollarWidgetImage.tintColor = this.widgetColor; + dollarWidgetImage.imageSize = new Size(18, 18); + + colStack.addSpacer(5); + + const oilPrice = this.dataSource[`V${oilNumber}`]; + const priceText = colStack.addText(`${oilPrice}`); + priceText.textColor = this.widgetColor; + priceText.font = Font.boldSystemFont(20); + }; + + renderLarge = async (w) => { + return this.notSupport(w); + }; + + renderMedium = async (w) => { + const oilNumbers = this.getRandomArrayElements(this.oilNumber, 3); + w.addSpacer(); + oilNumbers.map((oilNumber) => { + this.rowData(w, oilNumber); + w.addSpacer(); + }); + return w; + }; + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + return await this.renderMedium(widget); + } else if (this.widgetFamily === 'large') { + return await this.renderLarge(widget); + } else { + return await this.renderSmall(widget); + } + } +} + +// @组件代码结束 +await Runing(Widget, '', false); //远程开发环境 From 8f98278d1232d45955d751fc85634050308c557e Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 14:44:45 +0800 Subject: [PATCH 036/152] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=B2=B9=E4=BB=B7?= =?UTF-8?q?=E5=B0=8F=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.json b/install.json index 5840d8c..cacdf21 100644 --- a/install.json +++ b/install.json @@ -399,8 +399,8 @@ }, { "version": "1.0.0", - "description": "显示定位信息的油价使用的情况", - "scriptURL": "https://raw.githubusercontent.com/dompling/scriptableTsx/master/scripts/TodayOilPrice.js", + "description": "获取当前省份油价", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/Oild.js", "thumb": "https://img.icons8.com/clouds/344/engine-oil-level.png", "name": "TodayOilPrice", "title": "今日油价" From 246e9ce2719204b344622d9b4b3ec1e359f437c2 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 14:48:22 +0800 Subject: [PATCH 037/152] fix --- Scripts/Oild.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index 41cc100..7f106f3 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -196,7 +196,7 @@ class Widget extends DmYY { colStack.addSpacer(); - const dollarImage = SFSymbol.named(`dollarsign.circle.fill`).image; + const dollarImage = SFSymbol.named(`dollarsign.circle`).image; const dollarWidgetImage = colStack.addImage(dollarImage); dollarWidgetImage.tintColor = this.widgetColor; dollarWidgetImage.imageSize = new Size(18, 18); From de3ef226687672339c30bad52d98d1f37d70c0d4 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 15:28:45 +0800 Subject: [PATCH 038/152] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Oild.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index 7f106f3..be36bf0 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -196,7 +196,7 @@ class Widget extends DmYY { colStack.addSpacer(); - const dollarImage = SFSymbol.named(`dollarsign.circle`).image; + const dollarImage = SFSymbol.named(`yensign.circle`).image; const dollarWidgetImage = colStack.addImage(dollarImage); dollarWidgetImage.tintColor = this.widgetColor; dollarWidgetImage.imageSize = new Size(18, 18); From 9e82eb102feeb7f23f30b423645dee8ac7c82d0c Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 16:34:16 +0800 Subject: [PATCH 039/152] fix --- Scripts/Oild.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index be36bf0..5aa7705 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -181,7 +181,7 @@ class Widget extends DmYY { const zdeValue = this.dataSource[`ZDE${oilNumber}`]; const oilStatus = zdeValue > 0; const zdeColor = new Color(oilStatus ? '#f5222d' : '#a0d911'); - const zdeValueText = colStack.addText(`${zdeValue}`); + const zdeValueText = colStack.addText(`${zdeValue.toFixed(2)}`); zdeValueText.textColor = zdeColor; zdeValueText.font = Font.boldSystemFont(12); @@ -204,7 +204,7 @@ class Widget extends DmYY { colStack.addSpacer(5); const oilPrice = this.dataSource[`V${oilNumber}`]; - const priceText = colStack.addText(`${oilPrice}`); + const priceText = colStack.addText(`${oilPrice.toFixed(2)}`); priceText.textColor = this.widgetColor; priceText.font = Font.boldSystemFont(20); }; From 3d72d66598afe870bf5c694f1ad941fa271cc630 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 16:41:42 +0800 Subject: [PATCH 040/152] fix --- Scripts/Oild.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index 5aa7705..31c8ca6 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -108,7 +108,7 @@ class Widget extends DmYY { const topStack = w.addStack(); topStack.centerAlignContent(); - const oilPrice = this.dataSource[`V${this.oilNumber[0]}`]; + const oilPrice = this.dataSource[`V${this.oilNumber[0]}`].toFixed(2); const timer = (this.dataSource.DIM_DATE.split(' ')[0] || '').split('-'); const oilNumText = topStack.addText(`${oilPrice}`); oilNumText.textColor = this.widgetColor; From 7e0b092e5b75cb51d22938034b83b4c6f3f25889 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 15 Jun 2022 17:20:26 +0800 Subject: [PATCH 041/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B0=8F=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Oild.js | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index 31c8ca6..0031361 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -104,26 +104,38 @@ class Widget extends DmYY { } renderSmall = async (w) => { + const headerStack = w.addStack(); + const dollarImage = SFSymbol.named(`yensign.circle`).image; + headerStack.centerAlignContent(); + const dollarWidgetImg = headerStack.addImage(dollarImage); + dollarWidgetImg.tintColor = new Color('#f5222d'); + dollarWidgetImg.imageSize = new Size(24, 24); + + headerStack.addSpacer(); + w.addSpacer(); const topStack = w.addStack(); - topStack.centerAlignContent(); - + const topLStack = topStack.addStack(); + topLStack.layoutVertically(); + topLStack.addSpacer(); + topLStack.bottomAlignContent(); const oilPrice = this.dataSource[`V${this.oilNumber[0]}`].toFixed(2); const timer = (this.dataSource.DIM_DATE.split(' ')[0] || '').split('-'); - const oilNumText = topStack.addText(`${oilPrice}`); + const oilNumText = topLStack.addText(`${oilPrice}`); oilNumText.textColor = this.widgetColor; - oilNumText.font = Font.boldSystemFont(42); + oilNumText.minimumScaleFactor = 0.6; + oilNumText.font = Font.boldSystemFont(38); + topLStack.addSpacer(); const oilStatus = this.dataSource[`ZDE${this.oilNumber[0]}`] > 0; const oilZdeImage = SFSymbol.named( oilStatus ? 'arrow.up' : 'arrow.up', ).image; - topStack.addSpacer(5); + topStack.addSpacer(); const topRStack = topStack.addStack(); - topRStack.setPadding(4, 0, 0, 0); - + topRStack.addSpacer(); topRStack.layoutVertically(); - topRStack.centerAlignContent(); + topRStack.bottomAlignContent(); const zdeStack = topRStack.addStack(); zdeStack.setPadding(2, 6, 0, 0); const oilZdeWidgetImg = zdeStack.addImage(oilZdeImage); @@ -133,6 +145,7 @@ class Widget extends DmYY { const timerText = topRStack.addText(`${timer[2]}/${timer[1]}`); timerText.textColor = this.widgetColor; timerText.font = Font.systemFont(12); + topRStack.addSpacer(); w.addSpacer(); From 2082e400f02b547a12efa02f5f5acc6b54f98091 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 16 Jun 2022 11:45:00 +0800 Subject: [PATCH 042/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=AD=E5=8F=B7?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=BE=9D=E8=B5=96=20DmYY=EF=BC=8C?= =?UTF-8?q?=E8=AF=B7=E5=9C=A8=E5=B0=8F=E5=95=86=E5=BA=97=E8=87=AA=E8=A1=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20DmYY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 2 +- Scripts/DmYY.js | 1080 +++++++++++++++++++++--------------------- Scripts/Oild.js | 156 ++++-- 3 files changed, 660 insertions(+), 578 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index 501aab5..7d2d909 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -201,7 +201,7 @@ class Widget extends DmYY { oilWasteStack.addSpacer(2) const oilStatus = this.dataSource.oilZDE > 0 const oilZdeImage = SFSymbol.named( - oilStatus ? 'arrow.up' : 'arrow.up' + oilStatus ? 'arrow.up' : 'arrow.down' ).image const oilZdeWidgetImg = oilWasteStack.addImage(oilZdeImage) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index a0c8646..0fa73ab 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -9,153 +9,153 @@ class DmYY { constructor(arg) { - this.arg = arg + this.arg = arg; try { - this.init() + this.init(); } catch (error) { - console.log(error) + console.log(error); } - this.isNight = Device.isUsingDarkAppearance() + this.isNight = Device.isUsingDarkAppearance(); } - _actions = {} - BACKGROUND_NIGHT_KEY - widgetColor - backGroundColor - useBoxJS = true - isNight - _actionsIcon = {} + _actions = {}; + BACKGROUND_NIGHT_KEY; + widgetColor; + backGroundColor; + useBoxJS = true; + isNight; + _actionsIcon = {}; // 获取 Request 对象 getRequest = (url = '') => { - return new Request(url) - } + return new Request(url); + }; // 发起请求 - http = async (options = { headers: {}, url: '' }, type = 'JSON') => { + http = async (options = {headers: {}, url: ''}, type = 'JSON') => { try { - let request + let request; if (type !== 'IMG') { - request = this.getRequest() + request = this.getRequest(); Object.keys(options).forEach((key) => { - request[key] = options[key] - }) - request.headers = { ...this.defaultHeaders, ...options.headers } + request[key] = options[key]; + }); + request.headers = {...this.defaultHeaders, ...options.headers}; } else { - request = this.getRequest(options.url) - const fileName = this.md5(options.url) + request = this.getRequest(options.url); + const fileName = this.md5(options.url); const imagePath = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - fileName - ) - console.log(imagePath) + fileName, + ); + console.log(imagePath); if (this.FILE_MGR_LOCAL.fileExists(fileName)) { - return Image.fromFile(imagePath) + return Image.fromFile(imagePath); } - const response = await request.loadImage() - this.FILE_MGR_LOCAL.writeImage(imagePath, response) - return response + const response = await request.loadImage(); + this.FILE_MGR_LOCAL.writeImage(imagePath, response); + return response; } if (type === 'JSON') { - return await request.loadJSON() + return await request.loadJSON(); } if (type === 'STRING') { - return await request.loadString() + return await request.loadString(); } - return await request.loadJSON() + return await request.loadJSON(); } catch (e) { - console.log('error:' + e) - if (type === 'IMG') return SFSymbol.named('photo').image + console.log('error:' + e); + if (type === 'IMG') return SFSymbol.named('photo').image; } - } + }; //request 接口请求 $request = { get: async (url = '', options = {}, type = 'JSON') => { - let params = { ...options, method: 'GET' } + let params = {...options, method: 'GET'}; if (typeof url === 'object') { - params = { ...params, ...url } + params = {...params, ...url}; } else { - params.url = url + params.url = url; } - let _type = type - if (typeof options === 'string') _type = options - return await this.http(params, _type) + let _type = type; + if (typeof options === 'string') _type = options; + return await this.http(params, _type); }, post: async (url = '', options = {}, type = 'JSON') => { - let params = { ...options, method: 'POST' } + let params = {...options, method: 'POST'}; if (typeof url === 'object') { - params = { ...params, ...url } + params = {...params, ...url}; } else { - params.url = url + params.url = url; } - let _type = type - if (typeof options === 'string') _type = options - return await this.http(params, _type) + let _type = type; + if (typeof options === 'string') _type = options; + return await this.http(params, _type); }, - } + }; // 获取 boxJS 缓存 getCache = async (key = '', notify = true) => { try { - let url = 'http://' + this.prefix + '/query/boxdata' - if (key) url = 'http://' + this.prefix + '/query/data/' + key + let url = 'http://' + this.prefix + '/query/boxdata'; + if (key) url = 'http://' + this.prefix + '/query/data/' + key; const boxdata = await this.$request.get( url, - key ? { timeoutInterval: 1 } : {} - ) - if (boxdata.val) return boxdata.val - return boxdata.datas + key ? {timeoutInterval: 1} : {}, + ); + if (boxdata.val) return boxdata.val; + return boxdata.datas; } catch (e) { if (notify) await this.notify( `${this.name} - BoxJS 数据读取失败`, '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos' - ) - return false + 'https://chavyleung.gitbook.io/boxjs/awesome/videos', + ); + return false; } - } + }; transforJSON = (str) => { if (typeof str == 'string') { try { - return JSON.parse(str) + return JSON.parse(str); } catch (e) { - console.log(e) - return str + console.log(e); + return str; } } - console.log('It is not a string!') - } + console.log('It is not a string!'); + }; // 选择图片并缓存 chooseImg = async () => { - return await Photos.fromLibrary() - } + return await Photos.fromLibrary(); + }; // 设置 widget 背景图片 getWidgetBackgroundImage = async (widget) => { - const backgroundImage = this.getBackgroundImage() + const backgroundImage = this.getBackgroundImage(); if (backgroundImage) { const opacity = Device.isUsingDarkAppearance() ? Number(this.settings.darkOpacity) - : Number(this.settings.lightOpacity) + : Number(this.settings.lightOpacity); widget.backgroundImage = await this.shadowImage( backgroundImage, '#000', - opacity - ) - return true + opacity, + ); + return true; } else { if (this.backGroundColor.colors) { - widget.backgroundGradient = this.backGroundColor + widget.backgroundGradient = this.backGroundColor; } else { - widget.backgroundColor = this.backGroundColor + widget.backgroundColor = this.backGroundColor; } - return false + return false; } - } + }; /** * 验证图片尺寸: 图片像素超过 1000 左右的时候会导致背景无法加载 @@ -163,10 +163,10 @@ class DmYY { */ verifyImage = async (img) => { try { - const { width, height } = img.size - const direct = true + const {width, height} = img.size; + const direct = true; if (width > 1000) { - const options = ['取消', '打开图像处理'] + const options = ['取消', '打开图像处理']; const message = '您的图片像素为' + width + @@ -177,17 +177,17 @@ class DmYY { (direct ? '宽度' : '高度') + '调整到 1000 以下\n' + (!direct ? '宽度' : '高度') + - '自动适应' - const index = await this.generateAlert(message, options) + '自动适应'; + const index = await this.generateAlert(message, options); if (index === 1) - Safari.openInApp('https://www.sojson.com/image/change.html', false) - return false + Safari.openInApp('https://www.sojson.com/image/change.html', false); + return false; } - return true + return true; } catch (e) { - return false + return false; } - } + }; /** * 获取截图中的组件剪裁图 @@ -199,11 +199,11 @@ class DmYY { async getWidgetScreenShot(title = null) { // Crop an image into the specified rect. function cropImage(img, rect) { - let draw = new DrawContext() - draw.size = new Size(rect.width, rect.height) + let draw = new DrawContext(); + draw.size = new Size(rect.width, rect.height); - draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)) - return draw.getImage() + draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)); + return draw.getImage(); } // Pixel sizes and positions for widgets on all supported phones. @@ -341,63 +341,63 @@ class DmYY { middle: 618, bottom: 1146, }, - } + }; } let message = - title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续' - let exitOptions = ['我已截图', '前去截图 >'] - let shouldExit = await this.generateAlert(message, exitOptions) - if (shouldExit) return + title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续'; + let exitOptions = ['我已截图', '前去截图 >']; + let shouldExit = await this.generateAlert(message, exitOptions); + if (shouldExit) return; // Get screenshot and determine phone size. - let img = await Photos.fromLibrary() - let height = img.size.height - let phone = phoneSizes()[height] + let img = await Photos.fromLibrary(); + let height = img.size.height; + let phone = phoneSizes()[height]; if (!phone) { - message = '好像您选择的照片不是正确的截图,请先前往桌面' - await this.generateAlert(message, ['我已知晓']) - return + message = '好像您选择的照片不是正确的截图,请先前往桌面'; + await this.generateAlert(message, ['我已知晓']); + return; } // Extra setup needed for 2436-sized phones. if (height === 2436) { - const files = this.FILE_MGR_LOCAL - let cacheName = 'mz-phone-type' - let cachePath = files.joinPath(files.libraryDirectory(), cacheName) + const files = this.FILE_MGR_LOCAL; + let cacheName = 'mz-phone-type'; + let cachePath = files.joinPath(files.libraryDirectory(), cacheName); // If we already cached the phone size, load it. if (files.fileExists(cachePath)) { - let typeString = files.readString(cachePath) - phone = phone[typeString] + let typeString = files.readString(cachePath); + phone = phone[typeString]; // Otherwise, prompt the user. } else { - message = '您的📱型号是?' - let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X'] - let typeIndex = await this.generateAlert(message, types) - let type = typeIndex === 0 ? 'mini' : 'x' - phone = phone[type] - files.writeString(cachePath, type) + message = '您的📱型号是?'; + let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X']; + let typeIndex = await this.generateAlert(message, types); + let type = typeIndex === 0 ? 'mini' : 'x'; + phone = phone[type]; + files.writeString(cachePath, type); } } // Prompt for widget size and position. - message = '截图中要设置透明背景组件的尺寸类型是?' - let sizes = ['小尺寸', '中尺寸', '大尺寸'] - let size = await this.generateAlert(message, sizes) - let widgetSize = sizes[size] + message = '截图中要设置透明背景组件的尺寸类型是?'; + let sizes = ['小尺寸', '中尺寸', '大尺寸']; + let size = await this.generateAlert(message, sizes); + let widgetSize = sizes[size]; - message = '要设置透明背景的小组件在哪个位置?' + message = '要设置透明背景的小组件在哪个位置?'; message += height === 1136 ? ' (备注:当前设备只支持两行小组件,所以下边选项中的「中间」和「底部」的选项是一致的)' - : '' + : ''; // Determine image crop based on phone size. - let crop = { w: '', h: '', x: '', y: '' } + let crop = {w: '', h: '', x: '', y: ''}; if (widgetSize === '小尺寸') { - crop.w = phone.small - crop.h = phone.small + crop.w = phone.small; + crop.h = phone.small; let positions = [ '左上角', '右上角', @@ -405,7 +405,7 @@ class DmYY { '中间右', '左下角', '右下角', - ] + ]; let _posotions = [ 'Top left', 'Top right', @@ -413,55 +413,55 @@ class DmYY { 'Middle right', 'Bottom left', 'Bottom right', - ] - let position = await this.generateAlert(message, positions) + ]; + let position = await this.generateAlert(message, positions); // Convert the two words into two keys for the phone size dictionary. - let keys = _posotions[position].toLowerCase().split(' ') - crop.y = phone[keys[0]] - crop.x = phone[keys[1]] + let keys = _posotions[position].toLowerCase().split(' '); + crop.y = phone[keys[0]]; + crop.x = phone[keys[1]]; } else if (widgetSize === '中尺寸') { - crop.w = phone.medium - crop.h = phone.small + crop.w = phone.medium; + crop.h = phone.small; // Medium and large widgets have a fixed x-value. - crop.x = phone.left - let positions = ['顶部', '中间', '底部'] - let _positions = ['Top', 'Middle', 'Bottom'] - let position = await this.generateAlert(message, positions) - let key = _positions[position].toLowerCase() - crop.y = phone[key] + crop.x = phone.left; + let positions = ['顶部', '中间', '底部']; + let _positions = ['Top', 'Middle', 'Bottom']; + let position = await this.generateAlert(message, positions); + let key = _positions[position].toLowerCase(); + crop.y = phone[key]; } else if (widgetSize === '大尺寸') { - crop.w = phone.medium - crop.h = phone.large - crop.x = phone.left - let positions = ['顶部', '底部'] - let position = await this.generateAlert(message, positions) + crop.w = phone.medium; + crop.h = phone.large; + crop.x = phone.left; + let positions = ['顶部', '底部']; + let position = await this.generateAlert(message, positions); // Large widgets at the bottom have the "middle" y-value. - crop.y = position ? phone.middle : phone.top + crop.y = position ? phone.middle : phone.top; } // Crop image and finalize the widget. - return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)) + return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)); } setLightAndDark = async (title, desc, val) => { try { - const a = new Alert() - a.title = title - a.message = desc - a.addTextField('', `${this.settings[val]}`) - a.addAction('确定') - a.addCancelAction('取消') - const id = await a.presentAlert() - if (id === -1) return - this.settings[val] = a.textFieldValue(0) - this.saveSettings() + const a = new Alert(); + a.title = title; + a.message = desc; + a.addTextField('', `${this.settings[val]}`); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + this.settings[val] = a.textFieldValue(0); + this.saveSettings(); } catch (e) { - console.log(e) + console.log(e); } - } + }; /** * 弹出输入框 @@ -471,27 +471,27 @@ class DmYY { * @returns {Promise} */ setAlertInput = async (title, desc, opt = {}, isSave = true) => { - const a = new Alert() - a.title = title - a.message = !desc ? '' : desc + const a = new Alert(); + a.title = title; + a.message = !desc ? '' : desc; Object.keys(opt).forEach((key) => { - a.addTextField(opt[key], this.settings[key]) - }) - a.addAction('确定') - a.addCancelAction('取消') - const id = await a.presentAlert() - if (id === -1) return - const data = {} + a.addTextField(opt[key], this.settings[key]); + }); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + const data = {}; Object.keys(opt).forEach((key, index) => { - data[key] = a.textFieldValue(index) - }) + data[key] = a.textFieldValue(index); + }); // 保存到本地 if (isSave) { - this.settings = { ...this.settings, ...data } - return this.saveSettings() + this.settings = {...this.settings, ...data}; + return this.saveSettings(); } - return data - } + return data; + }; /** * 设置当前项目的 boxJS 缓存 @@ -499,137 +499,137 @@ class DmYY { * @returns {Promise} */ setCacheBoxJSData = async (opt = {}) => { - const options = ['取消', '确定'] - const message = '代理缓存仅支持 BoxJS 相关的代理!' - const index = await this.generateAlert(message, options) - if (index === 0) return + const options = ['取消', '确定']; + const message = '代理缓存仅支持 BoxJS 相关的代理!'; + const index = await this.generateAlert(message, options); + if (index === 0) return; try { - const boxJSData = await this.getCache() + const boxJSData = await this.getCache(); Object.keys(opt).forEach((key) => { - this.settings[key] = boxJSData[opt[key]] || '' - }) + this.settings[key] = boxJSData[opt[key]] || ''; + }); // 保存到本地 - this.saveSettings() + this.saveSettings(); } catch (e) { - console.log(e) + console.log(e); this.notify( this.name, 'BoxJS 缓存读取失败!点击查看相关教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos' - ) + 'https://chavyleung.gitbook.io/boxjs/awesome/videos', + ); } - } + }; /** * 设置组件内容 * @returns {Promise} */ setWidgetConfig = async () => { - const table = new UITable() - table.showSeparators = true - await this.renderDmYYTables(table) - await table.present() - } + const table = new UITable(); + table.showSeparators = true; + await this.renderDmYYTables(table); + await table.present(); + }; async preferences(table, arr, outfit) { - let header = new UITableRow() - let heading = header.addText(outfit) - heading.titleFont = Font.mediumSystemFont(17) - heading.centerAligned() - table.addRow(header) + let header = new UITableRow(); + let heading = header.addText(outfit); + heading.titleFont = Font.mediumSystemFont(17); + heading.centerAligned(); + table.addRow(header); for (const item of arr) { - const row = new UITableRow() - row.dismissOnSelect = !!item.dismissOnSelect + const row = new UITableRow(); + row.dismissOnSelect = !!item.dismissOnSelect; if (item.url) { - const rowIcon = row.addImageAtURL(item.url) - rowIcon.widthWeight = 100 + const rowIcon = row.addImageAtURL(item.url); + rowIcon.widthWeight = 100; } else { - const icon = item.icon || {} + const icon = item.icon || {}; const image = await this.drawTableIcon( icon.name, icon.color, - item.cornerWidth - ) - const imageCell = row.addImage(image) - imageCell.widthWeight = 100 + item.cornerWidth, + ); + const imageCell = row.addImage(image); + imageCell.widthWeight = 100; } - let rowTitle = row.addText(item['title']) - rowTitle.widthWeight = 400 - rowTitle.titleFont = Font.systemFont(16) + let rowTitle = row.addText(item['title']); + rowTitle.widthWeight = 400; + rowTitle.titleFont = Font.systemFont(16); if (this.settings[item.val] || item.val) { let valText = row.addText( - `${this.settings[item.val] || item.val}`.toUpperCase() - ) - const fontSize = !item.val ? 26 : 16 - valText.widthWeight = 500 - valText.rightAligned() - valText.titleColor = Color.blue() - valText.titleFont = Font.mediumSystemFont(fontSize) + `${this.settings[item.val] || item.val}`.toUpperCase(), + ); + const fontSize = !item.val ? 26 : 16; + valText.widthWeight = 500; + valText.rightAligned(); + valText.titleColor = Color.blue(); + valText.titleFont = Font.mediumSystemFont(fontSize); } else { const imgCell = UITableCell.imageAtURL( - 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png' - ) - imgCell.rightAligned() - imgCell.widthWeight = 500 - row.addCell(imgCell) + 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png', + ); + imgCell.rightAligned(); + imgCell.widthWeight = 500; + row.addCell(imgCell); } row.onSelect = item.onClick ? async () => { - try { - await item.onClick(item, table) - } catch (e) { - console.log(e) - } + try { + await item.onClick(item, table); + } catch (e) { + console.log(e); } + } : async () => { - if (item.type == 'input') { - await this.setLightAndDark( - item['title'], - item['desc'], - item['val'] - ) - } else if (item.type == 'setBackground') { - const backImage = await this.getWidgetScreenShot() - if (backImage) { - await this.setBackgroundImage(backImage, true) - await this.setBackgroundNightImage(backImage, true) - } - } else if (item.type == 'removeBackground') { - const options = ['取消', '清空'] - const message = '该操作不可逆,会清空所有背景图片!' - const index = await this.generateAlert(message, options) - if (index === 0) return - await this.setBackgroundImage(false, true) - await this.setBackgroundNightImage(false, true) - } else { - const backImage = await this.chooseImg() - if (!backImage || !(await this.verifyImage(backImage))) return - if (item.type == 'setDayBackground') - await this.setBackgroundImage(backImage, true) - if (item.type == 'setNightBackground') - await this.setBackgroundNightImage(backImage, true) + if (item.type == 'input') { + await this.setLightAndDark( + item['title'], + item['desc'], + item['val'], + ); + } else if (item.type == 'setBackground') { + const backImage = await this.getWidgetScreenShot(); + if (backImage) { + await this.setBackgroundImage(backImage, true); + await this.setBackgroundNightImage(backImage, true); } - await this.renderDmYYTables(table) + } else if (item.type == 'removeBackground') { + const options = ['取消', '清空']; + const message = '该操作不可逆,会清空所有背景图片!'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + await this.setBackgroundImage(false, true); + await this.setBackgroundNightImage(false, true); + } else { + const backImage = await this.chooseImg(); + if (!backImage || !(await this.verifyImage(backImage))) return; + if (item.type == 'setDayBackground') + await this.setBackgroundImage(backImage, true); + if (item.type == 'setNightBackground') + await this.setBackgroundNightImage(backImage, true); } - table.addRow(row) + await this.renderDmYYTables(table); + }; + table.addRow(row); } - table.reload() + table.reload(); } drawTableIcon = async ( icon = 'square.grid.2x2', color = '#e8e8e8', - cornerWidth = 42 + cornerWidth = 42, ) => { - const sfi = SFSymbol.named(icon) - sfi.applyFont(Font.mediumSystemFont(30)) - const imgData = Data.fromPNG(sfi.image).toBase64String() + const sfi = SFSymbol.named(icon); + sfi.applyFont(Font.mediumSystemFont(30)); + const imgData = Data.fromPNG(sfi.image).toBase64String(); const html = ` - ` + `; const js = ` var canvas = document.createElement("canvas"); var sourceImg = document.getElementById("sourceImg"); @@ -655,152 +655,152 @@ class DmYY { ctx.putImageData(imgData,0,0); silhouetteImg.src = canvas.toDataURL(); output=canvas.toDataURL() - ` - - let wv = new WebView() - await wv.loadHTML(html) - const base64Image = await wv.evaluateJavaScript(js) - const iconImage = await new Request(base64Image).loadImage() - const size = new Size(160, 160) - const ctx = new DrawContext() - ctx.opaque = false - ctx.respectScreenScale = true - ctx.size = size - const path = new Path() - const rect = new Rect(0, 0, size.width, size.width) - - path.addRoundedRect(rect, cornerWidth, cornerWidth) - path.closeSubpath() - ctx.setFillColor(new Color(color)) - ctx.addPath(path) - ctx.fillPath() - const rate = 36 - const iw = size.width - rate - const x = (size.width - iw) / 2 - ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)) - return ctx.getImage() - } + `; + + let wv = new WebView(); + await wv.loadHTML(html); + const base64Image = await wv.evaluateJavaScript(js); + const iconImage = await new Request(base64Image).loadImage(); + const size = new Size(160, 160); + const ctx = new DrawContext(); + ctx.opaque = false; + ctx.respectScreenScale = true; + ctx.size = size; + const path = new Path(); + const rect = new Rect(0, 0, size.width, size.width); + + path.addRoundedRect(rect, cornerWidth, cornerWidth); + path.closeSubpath(); + ctx.setFillColor(new Color(color)); + ctx.addPath(path); + ctx.fillPath(); + const rate = 36; + const iw = size.width - rate; + const x = (size.width - iw) / 2; + ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)); + return ctx.getImage(); + }; async renderDmYYTables(table) { const basic = [ { - icon: { name: 'arrow.clockwise', color: '#1890ff' }, + icon: {name: 'arrow.clockwise', color: '#1890ff'}, type: 'input', title: '刷新时间', desc: '刷新时间仅供参考,具体刷新时间由系统判断,单位:分钟', val: 'refreshAfterDate', }, { - icon: { name: 'photo', color: '#13c2c2' }, + icon: {name: 'photo', color: '#13c2c2'}, type: 'input', title: '白天背景颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', val: 'lightBgColor', }, { - icon: { name: 'photo.fill', color: '#52c41a' }, + icon: {name: 'photo.fill', color: '#52c41a'}, type: 'input', title: '晚上背景颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', val: 'darkBgColor', }, { - icon: { name: 'sun.max.fill', color: '#d48806' }, + icon: {name: 'sun.max.fill', color: '#d48806'}, type: 'input', title: '白天字体颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'lightColor', }, { - icon: { name: 'moon.stars.fill', color: '#d4b106' }, + icon: {name: 'moon.stars.fill', color: '#d4b106'}, type: 'input', title: '晚上字体颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'darkColor', }, - ] + ]; const background = [ { - icon: { name: 'text.below.photo', color: '#faad14' }, + icon: {name: 'text.below.photo', color: '#faad14'}, type: 'setBackground', title: '透明背景设置', }, { - icon: { name: 'photo.on.rectangle', color: '#fa8c16' }, + icon: {name: 'photo.on.rectangle', color: '#fa8c16'}, type: 'setDayBackground', title: '白天背景图片', }, { - icon: { name: 'photo.fill.on.rectangle.fill', color: '#fa541c' }, + icon: {name: 'photo.fill.on.rectangle.fill', color: '#fa541c'}, type: 'setNightBackground', title: '晚上背景图片', }, { - icon: { name: 'record.circle', color: '#722ed1' }, + icon: {name: 'record.circle', color: '#722ed1'}, type: 'input', title: '白天蒙层透明', desc: '完全透明请设置为0', val: 'lightOpacity', }, { - icon: { name: 'record.circle.fill', color: '#eb2f96' }, + icon: {name: 'record.circle.fill', color: '#eb2f96'}, type: 'input', title: '晚上蒙层透明', desc: '完全透明请设置为0', val: 'darkOpacity', }, { - icon: { name: 'clear', color: '#f5222d' }, + icon: {name: 'clear', color: '#f5222d'}, type: 'removeBackground', title: '清空背景图片', }, - ] + ]; const boxjs = { - icon: { name: 'shippingbox', color: '#f7bb10' }, + icon: {name: 'shippingbox', color: '#f7bb10'}, type: 'input', title: 'BoxJS 域名', desc: '', val: 'boxjsDomain', - } - if (this.useBoxJS) basic.push(boxjs) - table.removeAllRows() - let topRow = new UITableRow() - topRow.height = 60 - let leftText = topRow.addButton('Github') - leftText.widthWeight = 0.3 + }; + if (this.useBoxJS) basic.push(boxjs); + table.removeAllRows(); + let topRow = new UITableRow(); + topRow.height = 60; + let leftText = topRow.addButton('Github'); + leftText.widthWeight = 0.3; leftText.onTap = async () => { - await Safari.openInApp('https://github.com/dompling/Scriptable') - } + await Safari.openInApp('https://github.com/dompling/Scriptable'); + }; let centerRow = topRow.addImageAtURL( - 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png' - ) - centerRow.widthWeight = 0.4 - centerRow.centerAligned() + 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png', + ); + centerRow.widthWeight = 0.4; + centerRow.centerAligned(); centerRow.onTap = async () => { - await Safari.open('https://t.me/Scriptable_JS') - } - let rightText = topRow.addButton('重置所有') - rightText.widthWeight = 0.3 - rightText.rightAligned() + await Safari.open('https://t.me/Scriptable_JS'); + }; + let rightText = topRow.addButton('重置所有'); + rightText.widthWeight = 0.3; + rightText.rightAligned(); rightText.onTap = async () => { - const options = ['取消', '重置'] + const options = ['取消', '重置']; const message = - '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。' - const index = await this.generateAlert(message, options) - if (index === 0) return - this.settings = {} - await this.setBackgroundImage(false, false) - this.saveSettings() - } - table.addRow(topRow) - await this.preferences(table, basic, '基础设置') - await this.preferences(table, background, '背景图片') + '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + this.settings = {}; + await this.setBackgroundImage(false, false); + this.saveSettings(); + }; + table.addRow(topRow); + await this.preferences(table, basic, '基础设置'); + await this.preferences(table, background, '背景图片'); } init(widgetFamily = config.widgetFamily) { // 组件大小:small,medium,large - this.widgetFamily = widgetFamily - this.SETTING_KEY = this.md5(Script.name()) + this.widgetFamily = widgetFamily; + this.SETTING_KEY = this.md5(Script.name()); //用于配置所有的组件相关设置 // 文件管理器 @@ -808,72 +808,72 @@ class DmYY { this.FILE_MGR = FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' - ]() + ](); // 本地,用于存储图片等 - this.FILE_MGR_LOCAL = FileManager.local() + this.FILE_MGR_LOCAL = FileManager.local(); this.BACKGROUND_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + '.jpg' - ) + 'bg_' + this.SETTING_KEY + '.jpg', + ); this.BACKGROUND_NIGHT_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + 'night.jpg' - ) - - this.settings = this.getSettings() - this.settings.lightColor = this.settings.lightColor || '#000000' - this.settings.darkColor = this.settings.darkColor || '#ffffff' - this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff' - this.settings.darkBgColor = this.settings.darkBgColor || '#000000' - this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net' - this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30' - this.settings.lightOpacity = this.settings.lightOpacity || '0.4' - this.settings.darkOpacity = this.settings.darkOpacity || '0.7' - this.prefix = this.settings.boxjsDomain - const lightBgColor = this.getColors(this.settings.lightBgColor) - const darkBgColor = this.getColors(this.settings.darkBgColor) + 'bg_' + this.SETTING_KEY + 'night.jpg', + ); + + this.settings = this.getSettings(); + this.settings.lightColor = this.settings.lightColor || '#000000'; + this.settings.darkColor = this.settings.darkColor || '#ffffff'; + this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff'; + this.settings.darkBgColor = this.settings.darkBgColor || '#000000'; + this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net'; + this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30'; + this.settings.lightOpacity = this.settings.lightOpacity || '0.4'; + this.settings.darkOpacity = this.settings.darkOpacity || '0.7'; + this.prefix = this.settings.boxjsDomain; + const lightBgColor = this.getColors(this.settings.lightBgColor); + const darkBgColor = this.getColors(this.settings.darkBgColor); if (lightBgColor.length > 1 || darkBgColor.length > 1) { this.backGroundColor = !Device.isUsingDarkAppearance() ? this.getBackgroundColor(lightBgColor) - : this.getBackgroundColor(darkBgColor) + : this.getBackgroundColor(darkBgColor); } else if (lightBgColor.length > 0 && darkBgColor.length > 0) { this.backGroundColor = Color.dynamic( new Color(this.settings.lightBgColor), - new Color(this.settings.darkBgColor) - ) + new Color(this.settings.darkBgColor), + ); } this.widgetColor = Color.dynamic( new Color(this.settings.lightColor), - new Color(this.settings.darkColor) - ) + new Color(this.settings.darkColor), + ); } getColors = (color = '') => { - const colors = typeof color === 'string' ? color.split(',') : color - return colors - } + const colors = typeof color === 'string' ? color.split(',') : color; + return colors; + }; getBackgroundColor = (colors) => { - const locations = [] - const linearColor = new LinearGradient() - const cLen = colors.length + const locations = []; + const linearColor = new LinearGradient(); + const cLen = colors.length; linearColor.colors = colors.map((item, index) => { - locations.push(Math.floor(((index + 1) / cLen) * 100) / 100) - return new Color(item, 1) - }) - linearColor.locations = locations - return linearColor - } + locations.push(Math.floor(((index + 1) / cLen) * 100) / 100); + return new Color(item, 1); + }); + linearColor.locations = locations; + return linearColor; + }; /** * 注册点击操作菜单 * @param {string} name 操作函数名 * @param {func} func 点击后执行的函数 */ - registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }) { - this._actions[name] = func.bind(this) - this._actionsIcon[name] = icon + registerAction(name, func, icon = {name: 'gear', color: '#096dd9'}) { + this._actions[name] = func.bind(this); + this._actionsIcon[name] = icon; } /** @@ -881,8 +881,8 @@ class DmYY { * @param {string} str 要编码的字符串 */ base64Encode(str) { - const data = Data.fromString(str) - return data.toBase64String() + const data = Data.fromString(str); + return data.toBase64String(); } /** @@ -890,8 +890,8 @@ class DmYY { * @param {string} b64 base64编码的数据 */ base64Decode(b64) { - const data = Data.fromBase64String(b64) - return data.toRawString() + const data = Data.fromBase64String(b64); + return data.toRawString(); } /** @@ -900,34 +900,34 @@ class DmYY { */ md5(str) { function d(n, t) { - var r = (65535 & n) + (65535 & t) - return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r) + var r = (65535 & n) + (65535 & t); + return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r); } function f(n, t, r, e, o, u) { - return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r) - var c, f + return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r); + var c, f; } function l(n, t, r, e, o, u, c) { - return f((t & r) | (~t & e), n, t, o, u, c) + return f((t & r) | (~t & e), n, t, o, u, c); } function v(n, t, r, e, o, u, c) { - return f((t & e) | (r & ~e), n, t, o, u, c) + return f((t & e) | (r & ~e), n, t, o, u, c); } function g(n, t, r, e, o, u, c) { - return f(t ^ r ^ e, n, t, o, u, c) + return f(t ^ r ^ e, n, t, o, u, c); } function m(n, t, r, e, o, u, c) { - return f(r ^ (t | ~e), n, t, o, u, c) + return f(r ^ (t | ~e), n, t, o, u, c); } function i(n, t) { var r, e, o, u - ;(n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t) + ;(n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t); for ( var c = 1732584193, f = -271733879, @@ -959,7 +959,7 @@ class DmYY { a, n[h + 1], 5, - -165796510 + -165796510, )), (a = v(a, c, f, i, n[h + 6], 9, -1069501632)), (i = v(i, a, c, f, n[h + 11], 14, 643717713)), @@ -982,7 +982,7 @@ class DmYY { a, n[h + 5], 4, - -378558 + -378558, )), (a = g(a, c, f, i, n[h + 8], 11, -2022574463)), (i = g(i, a, c, f, n[h + 11], 16, 1839030562)), @@ -1005,7 +1005,7 @@ class DmYY { a, n[h], 6, - -198630844 + -198630844, )), (a = m(a, c, f, i, n[h + 7], 10, 1126891415)), (i = m(i, a, c, f, n[h + 14], 15, -1416354905)), @@ -1025,67 +1025,67 @@ class DmYY { (c = d(c, r)), (f = d(f, e)), (i = d(i, o)), - (a = d(a, u)) - return [c, f, i, a] + (a = d(a, u)); + return [c, f, i, a]; } function a(n) { for (var t = '', r = 32 * n.length, e = 0; e < r; e += 8) - t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255) - return t + t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255); + return t; } function h(n) { - var t = [] + var t = []; for (t[(n.length >> 2) - 1] = void 0, e = 0; e < t.length; e += 1) - t[e] = 0 + t[e] = 0; for (var r = 8 * n.length, e = 0; e < r; e += 8) - t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32 - return t + t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32; + return t; } function e(n) { for (var t, r = '0123456789abcdef', e = '', o = 0; o < n.length; o += 1) (t = n.charCodeAt(o)), - (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)) - return e + (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)); + return e; } function r(n) { - return unescape(encodeURIComponent(n)) + return unescape(encodeURIComponent(n)); } function o(n) { - return a(i(h((t = r(n))), 8 * t.length)) - var t + return a(i(h((t = r(n))), 8 * t.length)); + var t; } function u(n, t) { - return (function (n, t) { + return (function(n, t) { var r, e, o = h(n), u = [], - c = [] + c = []; for ( u[15] = c[15] = void 0, - 16 < o.length && (o = i(o, 8 * n.length)), + 16 < o.length && (o = i(o, 8 * n.length)), r = 0; r < 16; r += 1 ) - (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]) + (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]); return ( (e = i(u.concat(h(t)), 512 + 8 * t.length)), a(i(c.concat(e), 640)) - ) - })(r(n), r(t)) + ); + })(r(n), r(t)); } function t(n, t, r) { - return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)) + return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)); } - return t(str) + return t(str); } /** @@ -1096,24 +1096,24 @@ class DmYY { * @param {bool|color} color 字体的颜色(自定义背景时使用,默认系统) */ async renderHeader(widget, icon, title, color = false) { - let header = widget.addStack() - header.centerAlignContent() + let header = widget.addStack(); + header.centerAlignContent(); try { - const image = await this.$request.get(icon, 'IMG') - let _icon = header.addImage(image) - _icon.imageSize = new Size(14, 14) - _icon.cornerRadius = 4 + const image = await this.$request.get(icon, 'IMG'); + let _icon = header.addImage(image); + _icon.imageSize = new Size(14, 14); + _icon.cornerRadius = 4; } catch (e) { - console.log(e) + console.log(e); } - header.addSpacer(10) - let _title = header.addText(title) - if (color) _title.textColor = color - _title.textOpacity = 0.7 - _title.font = Font.boldSystemFont(12) - _title.lineLimit = 1 - widget.addSpacer(15) - return widget + header.addSpacer(10); + let _title = header.addText(title); + if (color) _title.textColor = color; + _title.textOpacity = 0.7; + _title.font = Font.boldSystemFont(12); + _title.lineLimit = 1; + widget.addSpacer(15); + return widget; } /** @@ -1123,13 +1123,13 @@ class DmYY { */ async generateAlert(message, options) { - let alert = new Alert() - alert.message = message + let alert = new Alert(); + alert.message = message; for (const option of options) { - alert.addAction(option) + alert.addAction(option); } - return await alert.presentAlert() + return await alert.presentAlert(); } /** @@ -1139,12 +1139,12 @@ class DmYY { * @param {string} url 点击后打开的URL */ async notify(title, body, url, opts = {}) { - let n = new Notification() - n = Object.assign(n, opts) - n.title = title - n.body = body - if (url) n.openURL = url - return await n.schedule() + let n = new Notification(); + n = Object.assign(n, opts); + n.title = title; + n.body = body; + if (url) n.openURL = url; + return await n.schedule(); } /** @@ -1154,19 +1154,19 @@ class DmYY { * @param {float} opacity 透明度 */ async shadowImage(img, color = '#000000', opacity = 0.7) { - if (!img) return - if (opacity === 0) return img - let ctx = new DrawContext() + if (!img) return; + if (opacity === 0) return img; + let ctx = new DrawContext(); // 获取图片的尺寸 - ctx.size = img.size + ctx.size = img.size; ctx.drawImageInRect( img, - new Rect(0, 0, img.size['width'], img.size['height']) - ) - ctx.setFillColor(new Color(color, opacity)) - ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])) - return await ctx.getImage() + new Rect(0, 0, img.size['width'], img.size['height']), + ); + ctx.setFillColor(new Color(color, opacity)); + ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])); + return await ctx.getImage(); } /** @@ -1174,20 +1174,20 @@ class DmYY { * @param {boolean} json 是否为json格式 */ getSettings(json = true) { - let res = json ? {} : '' - let cache = '' + let res = json ? {} : ''; + let cache = ''; if (Keychain.contains(this.SETTING_KEY)) { - cache = Keychain.get(this.SETTING_KEY) + cache = Keychain.get(this.SETTING_KEY); } if (json) { try { - res = JSON.parse(cache) + res = JSON.parse(cache); } catch (e) {} } else { - res = cache + res = cache; } - return res + return res; } /** @@ -1198,9 +1198,9 @@ class DmYY { let res = typeof this.settings === 'object' ? JSON.stringify(this.settings) - : String(this.settings) - Keychain.set(this.SETTING_KEY, res) - if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新') + : String(this.settings); + Keychain.set(this.SETTING_KEY, res); + if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新'); } /** @@ -1208,17 +1208,17 @@ class DmYY { * @reutrn img | false */ getBackgroundImage() { - let result = null + let result = null; if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - result = Image.fromFile(this.BACKGROUND_KEY) + result = Image.fromFile(this.BACKGROUND_KEY); } if ( Device.isUsingDarkAppearance() && this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY) ) { - result = Image.fromFile(this.BACKGROUND_NIGHT_KEY) + result = Image.fromFile(this.BACKGROUND_NIGHT_KEY); } - return result + return result; } /** @@ -1229,16 +1229,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY) + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY); } if (notify) - this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效') + this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效'); } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img) + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img); if (notify) - this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效') + this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效'); } } @@ -1246,16 +1246,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY) + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY); } if (notify) - this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效') + this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效'); } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img) + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img); if (notify) - this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效') + this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效'); } } @@ -1264,123 +1264,131 @@ class DmYY { i = arr.length, min = i - count, temp, - index - min = min > 0 ? min : 0 + index; + min = min > 0 ? min : 0; while (i-- > min) { - index = Math.floor((i + 1) * Math.random()) - temp = shuffled[index] - shuffled[index] = shuffled[i] - shuffled[i] = temp + index = Math.floor((i + 1) * Math.random()); + temp = shuffled[index]; + shuffled[index] = shuffled[i]; + shuffled[i] = temp; } - return shuffled.slice(min) + return shuffled.slice(min); } textFormat = { - defaultText: { size: 14, font: 'regular', color: this.widgetColor }, - battery: { size: 10, font: 'bold', color: this.widgetColor }, - title: { size: 16, font: 'semibold', color: this.widgetColor }, - SFMono: { size: 12, font: 'SF Mono', color: this.widgetColor }, - } + defaultText: {size: 14, font: 'regular', color: this.widgetColor}, + battery: {size: 10, font: 'bold', color: this.widgetColor}, + title: {size: 16, font: 'semibold', color: this.widgetColor}, + SFMono: {size: 12, font: 'SF Mono', color: this.widgetColor}, + }; provideFont = (fontName, fontSize) => { const fontGenerator = { - ultralight: function () { - return Font.ultraLightSystemFont(fontSize) + ultralight: function() { + return Font.ultraLightSystemFont(fontSize); }, - light: function () { - return Font.lightSystemFont(fontSize) + light: function() { + return Font.lightSystemFont(fontSize); }, - regular: function () { - return Font.regularSystemFont(fontSize) + regular: function() { + return Font.regularSystemFont(fontSize); }, - medium: function () { - return Font.mediumSystemFont(fontSize) + medium: function() { + return Font.mediumSystemFont(fontSize); }, - semibold: function () { - return Font.semiboldSystemFont(fontSize) + semibold: function() { + return Font.semiboldSystemFont(fontSize); }, - bold: function () { - return Font.boldSystemFont(fontSize) + bold: function() { + return Font.boldSystemFont(fontSize); }, - heavy: function () { - return Font.heavySystemFont(fontSize) + heavy: function() { + return Font.heavySystemFont(fontSize); }, - black: function () { - return Font.blackSystemFont(fontSize) + black: function() { + return Font.blackSystemFont(fontSize); }, - italic: function () { - return Font.italicSystemFont(fontSize) + italic: function() { + return Font.italicSystemFont(fontSize); }, - } + }; - const systemFont = fontGenerator[fontName] + const systemFont = fontGenerator[fontName]; if (systemFont) { - return systemFont() + return systemFont(); } - return new Font(fontName, fontSize) - } - - provideText = (string, container, format) => { - const textItem = container.addText(string) - const textFont = format.font - const textSize = format.size - const textColor = format.color - - textItem.font = this.provideFont(textFont, textSize) - textItem.textColor = textColor - return textItem - } + return new Font(fontName, fontSize); + }; + + provideText = ( + string, container, format = { + font: 'light', + size: 14, + color: this.widgetColor, + opacity: 1, + minimumScaleFactor: 1, + }) => { + const textItem = container.addText(string); + const textFont = format.font; + const textSize = format.size; + const textColor = format.color; + + textItem.font = this.provideFont(textFont, textSize); + textItem.textColor = textColor; + textItem.textOpacity = format.opacity || 1; + textItem.minimumScaleFactor = format.minimumScaleFactor || 1; + return textItem; + }; } // @base.end const Runing = async (Widget, default_args = '', isDebug = true, extra) => { - let M = null + let M = null; // 判断hash是否和当前设备匹配 if (config.runsInWidget) { - M = new Widget(args.widgetParameter || '') + M = new Widget(args.widgetParameter || ''); if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key] - }) + M[key] = extra[key]; + }); } - const W = await M.render() + const W = await M.render(); try { if (M.settings.refreshAfterDate) { W.refreshAfterDate = new Date( - new Date() + 1000 * 60 * parseInt(M.settings.refreshAfterDate) - ) + new Date() + 1000 * 60 * parseInt(M.settings.refreshAfterDate), + ); } } catch (e) { - console.log(e) + console.log(e); } if (W) { - Script.setWidget(W) - Script.complete() + Script.setWidget(W); + Script.complete(); } } else { - let { act, __arg, __size } = args.queryParameters - M = new Widget(__arg || default_args || '') + let {act, __arg, __size} = args.queryParameters; + M = new Widget(__arg || default_args || ''); if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key] - }) + M[key] = extra[key]; + }); } - if (__size) M.init(__size) + if (__size) M.init(__size); if (!act || !M['_actions']) { // 弹出选择菜单 - const actions = M['_actions'] - const table = new UITable() + const actions = M['_actions']; + const table = new UITable(); const onClick = async (item) => { - M.widgetFamily = item.val - w = await M.render() - const fnc = item.val - .toLowerCase() - .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()) + M.widgetFamily = item.val; + w = await M.render(); + const fnc = item.val.toLowerCase().replace( + /( |^)[a-z]/g, (L) => L.toUpperCase()); if (w) { - return w[`present${fnc}`]() + return w[`present${fnc}`](); } - } + }; const preview = [ { url: 'https://z3.ax1x.com/2021/03/26/6v5wIP.png', @@ -1403,28 +1411,28 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { dismissOnSelect: true, onClick, }, - ] - await M.preferences(table, preview, '预览组件') - const extra = [] + ]; + await M.preferences(table, preview, '预览组件'); + const extra = []; for (let _ in actions) { - const iconItem = M._actionsIcon[_] - const isUrl = typeof iconItem === 'string' + const iconItem = M._actionsIcon[_]; + const isUrl = typeof iconItem === 'string'; const actionItem = { title: _, onClick: actions[_], - } + }; if (isUrl) { - actionItem.url = iconItem + actionItem.url = iconItem; } else { - actionItem.icon = iconItem + actionItem.icon = iconItem; } - extra.push(actionItem) + extra.push(actionItem); } - await M.preferences(table, extra, '配置组件') - return table.present() + await M.preferences(table, extra, '配置组件'); + return table.present(); } } -} +}; // await new DmYY().setWidgetConfig(); -module.exports = { DmYY, Runing } +module.exports = {DmYY, Runing}; diff --git a/Scripts/Oild.js b/Scripts/Oild.js index 0031361..b3cf1ac 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -14,6 +14,12 @@ const enumConfig = { 0: '柴油', }; +const barHeight = [36, 30, 25, 32, 15, 20]; +const squareColor = '#8165AC'; +const processColor = [`#7517F8`, `#E323FF`]; +const processBarColor = [`#4da1ff`, `#4dffdf`]; +const processBarBgColor = '#5A5A89'; + // @组件代码开始 class Widget extends DmYY { constructor(arg) { @@ -119,7 +125,8 @@ class Widget extends DmYY { topLStack.layoutVertically(); topLStack.addSpacer(); topLStack.bottomAlignContent(); - const oilPrice = this.dataSource[`V${this.oilNumber[0]}`].toFixed(2); + const oilPrice = (this.dataSource[`V${this.oilNumber[0]}`] || '').toFixed( + 2); const timer = (this.dataSource.DIM_DATE.split(' ')[0] || '').split('-'); const oilNumText = topLStack.addText(`${oilPrice}`); oilNumText.textColor = this.widgetColor; @@ -162,77 +169,144 @@ class Widget extends DmYY { }; rowData = (w, oilNumber) => { + + const oilPrice = (this.dataSource[`V${oilNumber}`] || '').toFixed(2); + const oilZde = (this.dataSource[`ZDE${oilNumber}`] || '').toFixed(2); + const oilType = enumConfig[oilNumber] || ''; + const colStack = w.addStack(); - colStack.backgroundColor = Color.dynamic( - new Color('#d9d9d9'), - new Color('#434343'), + const oilNumberStack = colStack.addStack(); + const colSize = new Size(40, 40); + oilNumberStack.size = colSize; + oilNumberStack.cornerRadius = 8; + oilNumberStack.borderWidth = 4; + oilNumberStack.borderColor = new Color(squareColor); + oilNumberStack.centerAlignContent(); + this.provideText( + `${oilNumber}`, oilNumberStack, + {font: 'bold', size: 26, color: new Color(squareColor)}, ); - colStack.cornerRadius = 10; - colStack.setPadding(10, 10, 10, 10); - colStack.centerAlignContent(); + colStack.addSpacer(7); - const oilNumText = colStack.addText(`${oilNumber}`); - oilNumText.textColor = this.widgetColor; - oilNumText.font = Font.boldSystemFont(20); + const oilInfoStack = colStack.addStack(); + oilInfoStack.size = new Size(65, colSize.height); + oilInfoStack.layoutVertically(); + oilInfoStack.addSpacer(); + this.provideText( + `#${oilType}`, oilInfoStack, + {font: 'light', size: 12, color: this.widgetColor, opacity: 0.5}, + ); - colStack.addSpacer(5); + oilInfoStack.addSpacer(2); - const oilTypeText = colStack.addText(`#${enumConfig[oilNumber]}`); - oilTypeText.textColor = this.widgetColor; - oilTypeText.font = Font.boldSystemFont(12); + this.provideText( + `${oilPrice}`, oilInfoStack, + {font: 'medium', size: 18, color: this.widgetColor}, + ); + oilInfoStack.addSpacer(); + + const processStack = colStack.addStack(); + processStack.centerAlignContent(); + const processVerWidth = 10; + + for (let i = 0; i < 6; i++) { + const processItemStack = processStack.addStack(); + processItemStack.size = new Size(processVerWidth, colSize.height); + processItemStack.cornerRadius = processVerWidth / 2; + processItemStack.backgroundColor = new Color(processBarBgColor); + processItemStack.addSpacer(); + processItemStack.layoutVertically(); + + const itemBarStack = processItemStack.addStack(); + itemBarStack.cornerRadius = 7.5; + itemBarStack.size = new Size(processVerWidth, barHeight[i]); + itemBarStack.backgroundGradient = this.gradient(processColor); + + processStack.addSpacer(); + } colStack.addSpacer(); - const zdeText = colStack.addText('涨跌'); - zdeText.textColor = this.widgetColor; - zdeText.font = Font.boldSystemFont(12); + const oilZdeStack = colStack.addStack(); - colStack.addSpacer(5); + const oilZdeSize = new Size(80, 10); - const zdeValue = this.dataSource[`ZDE${oilNumber}`]; - const oilStatus = zdeValue > 0; - const zdeColor = new Color(oilStatus ? '#f5222d' : '#a0d911'); - const zdeValueText = colStack.addText(`${zdeValue.toFixed(2)}`); - zdeValueText.textColor = zdeColor; - zdeValueText.font = Font.boldSystemFont(12); + oilZdeStack.layoutVertically(); + oilZdeStack.size = new Size(oilZdeSize.width, colSize.height); + oilZdeStack.centerAlignContent(); - colStack.addSpacer(5); + const oilZdeValueStack = oilZdeStack.addStack(); + oilZdeValueStack.centerAlignContent(); + oilZdeValueStack.addSpacer(); + this.provideText( + `${oilZde > 0 ? '+' : '-'} ${oilZde}`, oilZdeValueStack, + {font: 'light', size: 14, color: this.widgetColor}, + ); const oilZdeImage = SFSymbol.named( - oilStatus ? 'arrow.up' : 'arrow.up', + oilZde > 0 ? 'arrow.up' : 'arrow.down', ).image; - const oilZdeWidgetImg = colStack.addImage(oilZdeImage); - oilZdeWidgetImg.tintColor = zdeColor; - oilZdeWidgetImg.imageSize = new Size(12, 12); - colStack.addSpacer(); + oilZdeValueStack.addSpacer(10); - const dollarImage = SFSymbol.named(`yensign.circle`).image; - const dollarWidgetImage = colStack.addImage(dollarImage); - dollarWidgetImage.tintColor = this.widgetColor; - dollarWidgetImage.imageSize = new Size(18, 18); + const oilZdeWidgetImg = oilZdeValueStack.addImage(oilZdeImage); + oilZdeWidgetImg.tintColor = new Color(oilZde > 0 ? '#f5222d' : '#a0d911'); + oilZdeWidgetImg.imageSize = new Size(10, 10); + + oilZdeValueStack.addSpacer(); - colStack.addSpacer(5); + oilZdeStack.addSpacer(5); - const oilPrice = this.dataSource[`V${oilNumber}`]; - const priceText = colStack.addText(`${oilPrice.toFixed(2)}`); - priceText.textColor = this.widgetColor; - priceText.font = Font.boldSystemFont(20); + const oilZdeValue = Math.abs(parseFloat(oilZde)); + const processBarBgStack = oilZdeStack.addStack(); + + processBarBgStack.cornerRadius = 5; + processBarBgStack.size = oilZdeSize; + processBarBgStack.backgroundColor = new Color(processBarBgColor); + + if (oilZde < 0) processBarBgStack.addSpacer(); + + const processBarStack = processBarBgStack.addStack(); + + const linear = new LinearGradient(); + linear.colors = processBarColor.map(item => new Color(item)); + linear.locations = [0, 0.5]; + linear.startPoint = new Point(0, 0); + linear.endPoint = new Point(1, 1); + + processBarStack.backgroundGradient = linear; + processBarStack.cornerRadius = oilZdeSize.height / 2; + processBarStack.size = new Size( + parseInt(oilZdeSize.width * oilZdeValue), oilZdeSize.height); + + if (oilZde > 0) processBarBgStack.addSpacer(); }; renderLarge = async (w) => { return this.notSupport(w); }; + renderBorder = (stack) => { + stack.borderWidth = 1; + }; + + gradient = (color, config = {locations: [0, 0.5]}) => { + const linear = new LinearGradient(); + linear.colors = color.map(item => new Color(item)); + linear.locations = config.locations; + return linear; + }; + renderMedium = async (w) => { - const oilNumbers = this.getRandomArrayElements(this.oilNumber, 3); w.addSpacer(); - oilNumbers.map((oilNumber) => { + this.oilNumber.forEach((oilNumber, index) => { + if (index > 2) return; this.rowData(w, oilNumber); w.addSpacer(); }); + return w; }; From 43c9c427e1e5b589ac8bc06ce2d82ea1ce919ff2 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 16 Jun 2022 15:23:22 +0800 Subject: [PATCH 043/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=AD=E5=8F=B7?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=BE=9D=E8=B5=96=20DmYY=EF=BC=8C?= =?UTF-8?q?=E8=AF=B7=E5=9C=A8=E5=B0=8F=E5=95=86=E5=BA=97=E8=87=AA=E8=A1=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20DmYY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Oild.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index b3cf1ac..34df76c 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -14,7 +14,6 @@ const enumConfig = { 0: '柴油', }; -const barHeight = [36, 30, 25, 32, 15, 20]; const squareColor = '#8165AC'; const processColor = [`#7517F8`, `#E323FF`]; const processBarColor = [`#4da1ff`, `#4dffdf`]; @@ -61,7 +60,7 @@ class Widget extends DmYY { init = async () => { if (this.settings.dataSource) { - this.dataSource = this.settings.dataSource; + this.dataSource = this.settings.dataSource[0]; } else { await this.cacheData(); } @@ -87,14 +86,14 @@ class Widget extends DmYY { const time = Date.now(); const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPTA_WEB_YJ_JH&columns=ALL&filter=${encodeURIComponent( filter, - )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=1&source=WEB&_=${time}`; + )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=6&source=WEB&_=${time}`; const options = {url}; const response = await this.$request.post(options); console.log(response); if (response.result) { this.dataSource = response.result.data[0]; - this.settings.dataSource = this.dataSource; + this.settings.dataSource = response.result.data; this.saveSettings(false); } }; @@ -211,21 +210,33 @@ class Widget extends DmYY { processStack.centerAlignContent(); const processVerWidth = 10; - for (let i = 0; i < 6; i++) { + let maxCount = 0; + const oilHistory = this.settings.dataSource.map( + item => { + const value = (item[`ZDE${oilNumber}`] / + item[`QE${oilNumber}`]).toFixed(2) * 100; + if (maxCount < value) maxCount = value; + return value; + }); + + maxCount = maxCount * 1.5; + + oilHistory.forEach(item => { const processItemStack = processStack.addStack(); processItemStack.size = new Size(processVerWidth, colSize.height); processItemStack.cornerRadius = processVerWidth / 2; processItemStack.backgroundColor = new Color(processBarBgColor); - processItemStack.addSpacer(); + if (item > 0) processItemStack.addSpacer(); processItemStack.layoutVertically(); const itemBarStack = processItemStack.addStack(); itemBarStack.cornerRadius = 7.5; - itemBarStack.size = new Size(processVerWidth, barHeight[i]); + itemBarStack.size = new Size( + processVerWidth, colSize.height * (Math.abs(item) / maxCount)); itemBarStack.backgroundGradient = this.gradient(processColor); - + if (item < 0) processItemStack.addSpacer(); processStack.addSpacer(); - } + }); colStack.addSpacer(); From c5417124deb38130ee20e11fe4ca66d361aca6d7 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 16 Jun 2022 15:25:32 +0800 Subject: [PATCH 044/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=AD=E5=8F=B7?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=BE=9D=E8=B5=96=20DmYY=EF=BC=8C?= =?UTF-8?q?=E8=AF=B7=E5=9C=A8=E5=B0=8F=E5=95=86=E5=BA=97=E8=87=AA=E8=A1=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20DmYY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Oild.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index 34df76c..cd1b7ba 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -230,7 +230,7 @@ class Widget extends DmYY { processItemStack.layoutVertically(); const itemBarStack = processItemStack.addStack(); - itemBarStack.cornerRadius = 7.5; + itemBarStack.cornerRadius = processVerWidth / 2; itemBarStack.size = new Size( processVerWidth, colSize.height * (Math.abs(item) / maxCount)); itemBarStack.backgroundGradient = this.gradient(processColor); From bebee748446a25b77ed5cc810c363009a615f0f7 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 16 Jun 2022 15:26:14 +0800 Subject: [PATCH 045/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=AD=E5=8F=B7?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=EF=BC=8C=E4=BE=9D=E8=B5=96=20DmYY=EF=BC=8C?= =?UTF-8?q?=E8=AF=B7=E5=9C=A8=E5=B0=8F=E5=95=86=E5=BA=97=E8=87=AA=E8=A1=8C?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20DmYY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Oild.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index cd1b7ba..e6c3842 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -230,7 +230,7 @@ class Widget extends DmYY { processItemStack.layoutVertically(); const itemBarStack = processItemStack.addStack(); - itemBarStack.cornerRadius = processVerWidth / 2; + itemBarStack.cornerRadius = processItemStack.cornerRadius; itemBarStack.size = new Size( processVerWidth, colSize.height * (Math.abs(item) / maxCount)); itemBarStack.backgroundGradient = this.gradient(processColor); From f93d539e1d695ffa57a0e4d6dc0c84c5a8cc1342 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Thu, 23 Jun 2022 10:47:16 +0800 Subject: [PATCH 046/152] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Ftms.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 5f65b92..3a09bfe 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -23,6 +23,7 @@ class Ftms { } else { await this.cacheData() } +// console.log(this.$.dataSource) this.cacheData() } @@ -46,19 +47,17 @@ class Ftms { 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail' ) const response = await this.$.$request.post(options) - console.log(response) +// console.log(response) if (response.msg === 'success') { this.$.dataSource.remoteInfo = response.result const safeData = - this.$.dataSource.remoteInfo.list.filter( + response.result.list.filter( (item) => item.security !== 'safe' ) || [] if (safeData.length > 0) { - if (safeData.length === 1) { this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}` - } else { - this.$.dataSource.safeText = `隐患:${safeData.length}` - } + }else{ + this.$.dataSource.safeText = `` } const dataTime = this.$.dataSource.remoteInfo.datatime.split('-') this.$.dataSource.remoteInfo.datatime = `${dataTime[1] || ''}-${ @@ -79,6 +78,7 @@ class Ftms { } this.$.dataSource.monitorInfo.oilWasteText = `油耗:${this.$.dataSource.monitorInfo.oilWaste}L/100km` this.$.settings.dataSource = this.$.dataSource +// console.log(this.$.dataSource) this.$.saveSettings(false) } From f19848370496998385017b7e7d58f8a51a359c72 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Mon, 27 Jun 2022 15:50:47 +0800 Subject: [PATCH 047/152] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20refreshAfterDate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 1080 ++++++++++++++++++++++++----------------------- 1 file changed, 542 insertions(+), 538 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 0fa73ab..f538efc 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -9,153 +9,153 @@ class DmYY { constructor(arg) { - this.arg = arg; + this.arg = arg try { - this.init(); + this.init() } catch (error) { - console.log(error); + console.log(error) } - this.isNight = Device.isUsingDarkAppearance(); + this.isNight = Device.isUsingDarkAppearance() } - _actions = {}; - BACKGROUND_NIGHT_KEY; - widgetColor; - backGroundColor; - useBoxJS = true; - isNight; - _actionsIcon = {}; + _actions = {} + BACKGROUND_NIGHT_KEY + widgetColor + backGroundColor + useBoxJS = true + isNight + _actionsIcon = {} // 获取 Request 对象 getRequest = (url = '') => { - return new Request(url); - }; + return new Request(url) + } // 发起请求 - http = async (options = {headers: {}, url: ''}, type = 'JSON') => { + http = async (options = { headers: {}, url: '' }, type = 'JSON') => { try { - let request; + let request if (type !== 'IMG') { - request = this.getRequest(); + request = this.getRequest() Object.keys(options).forEach((key) => { - request[key] = options[key]; - }); - request.headers = {...this.defaultHeaders, ...options.headers}; + request[key] = options[key] + }) + request.headers = { ...this.defaultHeaders, ...options.headers } } else { - request = this.getRequest(options.url); - const fileName = this.md5(options.url); + request = this.getRequest(options.url) + const fileName = this.md5(options.url) const imagePath = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - fileName, - ); - console.log(imagePath); + fileName + ) + console.log(imagePath) if (this.FILE_MGR_LOCAL.fileExists(fileName)) { - return Image.fromFile(imagePath); + return Image.fromFile(imagePath) } - const response = await request.loadImage(); - this.FILE_MGR_LOCAL.writeImage(imagePath, response); - return response; + const response = await request.loadImage() + this.FILE_MGR_LOCAL.writeImage(imagePath, response) + return response } if (type === 'JSON') { - return await request.loadJSON(); + return await request.loadJSON() } if (type === 'STRING') { - return await request.loadString(); + return await request.loadString() } - return await request.loadJSON(); + return await request.loadJSON() } catch (e) { - console.log('error:' + e); - if (type === 'IMG') return SFSymbol.named('photo').image; + console.log('error:' + e) + if (type === 'IMG') return SFSymbol.named('photo').image } - }; + } //request 接口请求 $request = { get: async (url = '', options = {}, type = 'JSON') => { - let params = {...options, method: 'GET'}; + let params = { ...options, method: 'GET' } if (typeof url === 'object') { - params = {...params, ...url}; + params = { ...params, ...url } } else { - params.url = url; + params.url = url } - let _type = type; - if (typeof options === 'string') _type = options; - return await this.http(params, _type); + let _type = type + if (typeof options === 'string') _type = options + return await this.http(params, _type) }, post: async (url = '', options = {}, type = 'JSON') => { - let params = {...options, method: 'POST'}; + let params = { ...options, method: 'POST' } if (typeof url === 'object') { - params = {...params, ...url}; + params = { ...params, ...url } } else { - params.url = url; + params.url = url } - let _type = type; - if (typeof options === 'string') _type = options; - return await this.http(params, _type); + let _type = type + if (typeof options === 'string') _type = options + return await this.http(params, _type) }, - }; + } // 获取 boxJS 缓存 getCache = async (key = '', notify = true) => { try { - let url = 'http://' + this.prefix + '/query/boxdata'; - if (key) url = 'http://' + this.prefix + '/query/data/' + key; + let url = 'http://' + this.prefix + '/query/boxdata' + if (key) url = 'http://' + this.prefix + '/query/data/' + key const boxdata = await this.$request.get( url, - key ? {timeoutInterval: 1} : {}, - ); - if (boxdata.val) return boxdata.val; - return boxdata.datas; + key ? { timeoutInterval: 1 } : {} + ) + if (boxdata.val) return boxdata.val + return boxdata.datas } catch (e) { if (notify) await this.notify( `${this.name} - BoxJS 数据读取失败`, '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); - return false; + 'https://chavyleung.gitbook.io/boxjs/awesome/videos' + ) + return false } - }; + } transforJSON = (str) => { if (typeof str == 'string') { try { - return JSON.parse(str); + return JSON.parse(str) } catch (e) { - console.log(e); - return str; + console.log(e) + return str } } - console.log('It is not a string!'); - }; + console.log('It is not a string!') + } // 选择图片并缓存 chooseImg = async () => { - return await Photos.fromLibrary(); - }; + return await Photos.fromLibrary() + } // 设置 widget 背景图片 getWidgetBackgroundImage = async (widget) => { - const backgroundImage = this.getBackgroundImage(); + const backgroundImage = this.getBackgroundImage() if (backgroundImage) { const opacity = Device.isUsingDarkAppearance() ? Number(this.settings.darkOpacity) - : Number(this.settings.lightOpacity); + : Number(this.settings.lightOpacity) widget.backgroundImage = await this.shadowImage( backgroundImage, '#000', - opacity, - ); - return true; + opacity + ) + return true } else { if (this.backGroundColor.colors) { - widget.backgroundGradient = this.backGroundColor; + widget.backgroundGradient = this.backGroundColor } else { - widget.backgroundColor = this.backGroundColor; + widget.backgroundColor = this.backGroundColor } - return false; + return false } - }; + } /** * 验证图片尺寸: 图片像素超过 1000 左右的时候会导致背景无法加载 @@ -163,10 +163,10 @@ class DmYY { */ verifyImage = async (img) => { try { - const {width, height} = img.size; - const direct = true; + const { width, height } = img.size + const direct = true if (width > 1000) { - const options = ['取消', '打开图像处理']; + const options = ['取消', '打开图像处理'] const message = '您的图片像素为' + width + @@ -177,17 +177,17 @@ class DmYY { (direct ? '宽度' : '高度') + '调整到 1000 以下\n' + (!direct ? '宽度' : '高度') + - '自动适应'; - const index = await this.generateAlert(message, options); + '自动适应' + const index = await this.generateAlert(message, options) if (index === 1) - Safari.openInApp('https://www.sojson.com/image/change.html', false); - return false; + Safari.openInApp('https://www.sojson.com/image/change.html', false) + return false } - return true; + return true } catch (e) { - return false; + return false } - }; + } /** * 获取截图中的组件剪裁图 @@ -199,11 +199,11 @@ class DmYY { async getWidgetScreenShot(title = null) { // Crop an image into the specified rect. function cropImage(img, rect) { - let draw = new DrawContext(); - draw.size = new Size(rect.width, rect.height); + let draw = new DrawContext() + draw.size = new Size(rect.width, rect.height) - draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)); - return draw.getImage(); + draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)) + return draw.getImage() } // Pixel sizes and positions for widgets on all supported phones. @@ -341,63 +341,63 @@ class DmYY { middle: 618, bottom: 1146, }, - }; + } } let message = - title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续'; - let exitOptions = ['我已截图', '前去截图 >']; - let shouldExit = await this.generateAlert(message, exitOptions); - if (shouldExit) return; + title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续' + let exitOptions = ['我已截图', '前去截图 >'] + let shouldExit = await this.generateAlert(message, exitOptions) + if (shouldExit) return // Get screenshot and determine phone size. - let img = await Photos.fromLibrary(); - let height = img.size.height; - let phone = phoneSizes()[height]; + let img = await Photos.fromLibrary() + let height = img.size.height + let phone = phoneSizes()[height] if (!phone) { - message = '好像您选择的照片不是正确的截图,请先前往桌面'; - await this.generateAlert(message, ['我已知晓']); - return; + message = '好像您选择的照片不是正确的截图,请先前往桌面' + await this.generateAlert(message, ['我已知晓']) + return } // Extra setup needed for 2436-sized phones. if (height === 2436) { - const files = this.FILE_MGR_LOCAL; - let cacheName = 'mz-phone-type'; - let cachePath = files.joinPath(files.libraryDirectory(), cacheName); + const files = this.FILE_MGR_LOCAL + let cacheName = 'mz-phone-type' + let cachePath = files.joinPath(files.libraryDirectory(), cacheName) // If we already cached the phone size, load it. if (files.fileExists(cachePath)) { - let typeString = files.readString(cachePath); - phone = phone[typeString]; + let typeString = files.readString(cachePath) + phone = phone[typeString] // Otherwise, prompt the user. } else { - message = '您的📱型号是?'; - let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X']; - let typeIndex = await this.generateAlert(message, types); - let type = typeIndex === 0 ? 'mini' : 'x'; - phone = phone[type]; - files.writeString(cachePath, type); + message = '您的📱型号是?' + let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X'] + let typeIndex = await this.generateAlert(message, types) + let type = typeIndex === 0 ? 'mini' : 'x' + phone = phone[type] + files.writeString(cachePath, type) } } // Prompt for widget size and position. - message = '截图中要设置透明背景组件的尺寸类型是?'; - let sizes = ['小尺寸', '中尺寸', '大尺寸']; - let size = await this.generateAlert(message, sizes); - let widgetSize = sizes[size]; + message = '截图中要设置透明背景组件的尺寸类型是?' + let sizes = ['小尺寸', '中尺寸', '大尺寸'] + let size = await this.generateAlert(message, sizes) + let widgetSize = sizes[size] - message = '要设置透明背景的小组件在哪个位置?'; + message = '要设置透明背景的小组件在哪个位置?' message += height === 1136 ? ' (备注:当前设备只支持两行小组件,所以下边选项中的「中间」和「底部」的选项是一致的)' - : ''; + : '' // Determine image crop based on phone size. - let crop = {w: '', h: '', x: '', y: ''}; + let crop = { w: '', h: '', x: '', y: '' } if (widgetSize === '小尺寸') { - crop.w = phone.small; - crop.h = phone.small; + crop.w = phone.small + crop.h = phone.small let positions = [ '左上角', '右上角', @@ -405,7 +405,7 @@ class DmYY { '中间右', '左下角', '右下角', - ]; + ] let _posotions = [ 'Top left', 'Top right', @@ -413,55 +413,55 @@ class DmYY { 'Middle right', 'Bottom left', 'Bottom right', - ]; - let position = await this.generateAlert(message, positions); + ] + let position = await this.generateAlert(message, positions) // Convert the two words into two keys for the phone size dictionary. - let keys = _posotions[position].toLowerCase().split(' '); - crop.y = phone[keys[0]]; - crop.x = phone[keys[1]]; + let keys = _posotions[position].toLowerCase().split(' ') + crop.y = phone[keys[0]] + crop.x = phone[keys[1]] } else if (widgetSize === '中尺寸') { - crop.w = phone.medium; - crop.h = phone.small; + crop.w = phone.medium + crop.h = phone.small // Medium and large widgets have a fixed x-value. - crop.x = phone.left; - let positions = ['顶部', '中间', '底部']; - let _positions = ['Top', 'Middle', 'Bottom']; - let position = await this.generateAlert(message, positions); - let key = _positions[position].toLowerCase(); - crop.y = phone[key]; + crop.x = phone.left + let positions = ['顶部', '中间', '底部'] + let _positions = ['Top', 'Middle', 'Bottom'] + let position = await this.generateAlert(message, positions) + let key = _positions[position].toLowerCase() + crop.y = phone[key] } else if (widgetSize === '大尺寸') { - crop.w = phone.medium; - crop.h = phone.large; - crop.x = phone.left; - let positions = ['顶部', '底部']; - let position = await this.generateAlert(message, positions); + crop.w = phone.medium + crop.h = phone.large + crop.x = phone.left + let positions = ['顶部', '底部'] + let position = await this.generateAlert(message, positions) // Large widgets at the bottom have the "middle" y-value. - crop.y = position ? phone.middle : phone.top; + crop.y = position ? phone.middle : phone.top } // Crop image and finalize the widget. - return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)); + return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)) } setLightAndDark = async (title, desc, val) => { try { - const a = new Alert(); - a.title = title; - a.message = desc; - a.addTextField('', `${this.settings[val]}`); - a.addAction('确定'); - a.addCancelAction('取消'); - const id = await a.presentAlert(); - if (id === -1) return; - this.settings[val] = a.textFieldValue(0); - this.saveSettings(); + const a = new Alert() + a.title = title + a.message = desc + a.addTextField('', `${this.settings[val]}`) + a.addAction('确定') + a.addCancelAction('取消') + const id = await a.presentAlert() + if (id === -1) return + this.settings[val] = a.textFieldValue(0) + this.saveSettings() } catch (e) { - console.log(e); + console.log(e) } - }; + } /** * 弹出输入框 @@ -471,27 +471,27 @@ class DmYY { * @returns {Promise} */ setAlertInput = async (title, desc, opt = {}, isSave = true) => { - const a = new Alert(); - a.title = title; - a.message = !desc ? '' : desc; + const a = new Alert() + a.title = title + a.message = !desc ? '' : desc Object.keys(opt).forEach((key) => { - a.addTextField(opt[key], this.settings[key]); - }); - a.addAction('确定'); - a.addCancelAction('取消'); - const id = await a.presentAlert(); - if (id === -1) return; - const data = {}; + a.addTextField(opt[key], this.settings[key]) + }) + a.addAction('确定') + a.addCancelAction('取消') + const id = await a.presentAlert() + if (id === -1) return + const data = {} Object.keys(opt).forEach((key, index) => { - data[key] = a.textFieldValue(index); - }); + data[key] = a.textFieldValue(index) + }) // 保存到本地 if (isSave) { - this.settings = {...this.settings, ...data}; - return this.saveSettings(); + this.settings = { ...this.settings, ...data } + return this.saveSettings() } - return data; - }; + return data + } /** * 设置当前项目的 boxJS 缓存 @@ -499,137 +499,137 @@ class DmYY { * @returns {Promise} */ setCacheBoxJSData = async (opt = {}) => { - const options = ['取消', '确定']; - const message = '代理缓存仅支持 BoxJS 相关的代理!'; - const index = await this.generateAlert(message, options); - if (index === 0) return; + const options = ['取消', '确定'] + const message = '代理缓存仅支持 BoxJS 相关的代理!' + const index = await this.generateAlert(message, options) + if (index === 0) return try { - const boxJSData = await this.getCache(); + const boxJSData = await this.getCache() Object.keys(opt).forEach((key) => { - this.settings[key] = boxJSData[opt[key]] || ''; - }); + this.settings[key] = boxJSData[opt[key]] || '' + }) // 保存到本地 - this.saveSettings(); + this.saveSettings() } catch (e) { - console.log(e); + console.log(e) this.notify( this.name, 'BoxJS 缓存读取失败!点击查看相关教程', - 'https://chavyleung.gitbook.io/boxjs/awesome/videos', - ); + 'https://chavyleung.gitbook.io/boxjs/awesome/videos' + ) } - }; + } /** * 设置组件内容 * @returns {Promise} */ setWidgetConfig = async () => { - const table = new UITable(); - table.showSeparators = true; - await this.renderDmYYTables(table); - await table.present(); - }; + const table = new UITable() + table.showSeparators = true + await this.renderDmYYTables(table) + await table.present() + } async preferences(table, arr, outfit) { - let header = new UITableRow(); - let heading = header.addText(outfit); - heading.titleFont = Font.mediumSystemFont(17); - heading.centerAligned(); - table.addRow(header); + let header = new UITableRow() + let heading = header.addText(outfit) + heading.titleFont = Font.mediumSystemFont(17) + heading.centerAligned() + table.addRow(header) for (const item of arr) { - const row = new UITableRow(); - row.dismissOnSelect = !!item.dismissOnSelect; + const row = new UITableRow() + row.dismissOnSelect = !!item.dismissOnSelect if (item.url) { - const rowIcon = row.addImageAtURL(item.url); - rowIcon.widthWeight = 100; + const rowIcon = row.addImageAtURL(item.url) + rowIcon.widthWeight = 100 } else { - const icon = item.icon || {}; + const icon = item.icon || {} const image = await this.drawTableIcon( icon.name, icon.color, - item.cornerWidth, - ); - const imageCell = row.addImage(image); - imageCell.widthWeight = 100; + item.cornerWidth + ) + const imageCell = row.addImage(image) + imageCell.widthWeight = 100 } - let rowTitle = row.addText(item['title']); - rowTitle.widthWeight = 400; - rowTitle.titleFont = Font.systemFont(16); + let rowTitle = row.addText(item['title']) + rowTitle.widthWeight = 400 + rowTitle.titleFont = Font.systemFont(16) if (this.settings[item.val] || item.val) { let valText = row.addText( - `${this.settings[item.val] || item.val}`.toUpperCase(), - ); - const fontSize = !item.val ? 26 : 16; - valText.widthWeight = 500; - valText.rightAligned(); - valText.titleColor = Color.blue(); - valText.titleFont = Font.mediumSystemFont(fontSize); + `${this.settings[item.val] || item.val}`.toUpperCase() + ) + const fontSize = !item.val ? 26 : 16 + valText.widthWeight = 500 + valText.rightAligned() + valText.titleColor = Color.blue() + valText.titleFont = Font.mediumSystemFont(fontSize) } else { const imgCell = UITableCell.imageAtURL( - 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png', - ); - imgCell.rightAligned(); - imgCell.widthWeight = 500; - row.addCell(imgCell); + 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png' + ) + imgCell.rightAligned() + imgCell.widthWeight = 500 + row.addCell(imgCell) } row.onSelect = item.onClick ? async () => { - try { - await item.onClick(item, table); - } catch (e) { - console.log(e); + try { + await item.onClick(item, table) + } catch (e) { + console.log(e) + } } - } : async () => { - if (item.type == 'input') { - await this.setLightAndDark( - item['title'], - item['desc'], - item['val'], - ); - } else if (item.type == 'setBackground') { - const backImage = await this.getWidgetScreenShot(); - if (backImage) { - await this.setBackgroundImage(backImage, true); - await this.setBackgroundNightImage(backImage, true); + if (item.type == 'input') { + await this.setLightAndDark( + item['title'], + item['desc'], + item['val'] + ) + } else if (item.type == 'setBackground') { + const backImage = await this.getWidgetScreenShot() + if (backImage) { + await this.setBackgroundImage(backImage, true) + await this.setBackgroundNightImage(backImage, true) + } + } else if (item.type == 'removeBackground') { + const options = ['取消', '清空'] + const message = '该操作不可逆,会清空所有背景图片!' + const index = await this.generateAlert(message, options) + if (index === 0) return + await this.setBackgroundImage(false, true) + await this.setBackgroundNightImage(false, true) + } else { + const backImage = await this.chooseImg() + if (!backImage || !(await this.verifyImage(backImage))) return + if (item.type == 'setDayBackground') + await this.setBackgroundImage(backImage, true) + if (item.type == 'setNightBackground') + await this.setBackgroundNightImage(backImage, true) } - } else if (item.type == 'removeBackground') { - const options = ['取消', '清空']; - const message = '该操作不可逆,会清空所有背景图片!'; - const index = await this.generateAlert(message, options); - if (index === 0) return; - await this.setBackgroundImage(false, true); - await this.setBackgroundNightImage(false, true); - } else { - const backImage = await this.chooseImg(); - if (!backImage || !(await this.verifyImage(backImage))) return; - if (item.type == 'setDayBackground') - await this.setBackgroundImage(backImage, true); - if (item.type == 'setNightBackground') - await this.setBackgroundNightImage(backImage, true); + await this.renderDmYYTables(table) } - await this.renderDmYYTables(table); - }; - table.addRow(row); + table.addRow(row) } - table.reload(); + table.reload() } drawTableIcon = async ( icon = 'square.grid.2x2', color = '#e8e8e8', - cornerWidth = 42, + cornerWidth = 42 ) => { - const sfi = SFSymbol.named(icon); - sfi.applyFont(Font.mediumSystemFont(30)); - const imgData = Data.fromPNG(sfi.image).toBase64String(); + const sfi = SFSymbol.named(icon) + sfi.applyFont(Font.mediumSystemFont(30)) + const imgData = Data.fromPNG(sfi.image).toBase64String() const html = ` - `; + ` const js = ` var canvas = document.createElement("canvas"); var sourceImg = document.getElementById("sourceImg"); @@ -655,152 +655,152 @@ class DmYY { ctx.putImageData(imgData,0,0); silhouetteImg.src = canvas.toDataURL(); output=canvas.toDataURL() - `; - - let wv = new WebView(); - await wv.loadHTML(html); - const base64Image = await wv.evaluateJavaScript(js); - const iconImage = await new Request(base64Image).loadImage(); - const size = new Size(160, 160); - const ctx = new DrawContext(); - ctx.opaque = false; - ctx.respectScreenScale = true; - ctx.size = size; - const path = new Path(); - const rect = new Rect(0, 0, size.width, size.width); - - path.addRoundedRect(rect, cornerWidth, cornerWidth); - path.closeSubpath(); - ctx.setFillColor(new Color(color)); - ctx.addPath(path); - ctx.fillPath(); - const rate = 36; - const iw = size.width - rate; - const x = (size.width - iw) / 2; - ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)); - return ctx.getImage(); - }; + ` + + let wv = new WebView() + await wv.loadHTML(html) + const base64Image = await wv.evaluateJavaScript(js) + const iconImage = await new Request(base64Image).loadImage() + const size = new Size(160, 160) + const ctx = new DrawContext() + ctx.opaque = false + ctx.respectScreenScale = true + ctx.size = size + const path = new Path() + const rect = new Rect(0, 0, size.width, size.width) + + path.addRoundedRect(rect, cornerWidth, cornerWidth) + path.closeSubpath() + ctx.setFillColor(new Color(color)) + ctx.addPath(path) + ctx.fillPath() + const rate = 36 + const iw = size.width - rate + const x = (size.width - iw) / 2 + ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)) + return ctx.getImage() + } async renderDmYYTables(table) { const basic = [ { - icon: {name: 'arrow.clockwise', color: '#1890ff'}, + icon: { name: 'arrow.clockwise', color: '#1890ff' }, type: 'input', title: '刷新时间', desc: '刷新时间仅供参考,具体刷新时间由系统判断,单位:分钟', val: 'refreshAfterDate', }, { - icon: {name: 'photo', color: '#13c2c2'}, + icon: { name: 'photo', color: '#13c2c2' }, type: 'input', title: '白天背景颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', val: 'lightBgColor', }, { - icon: {name: 'photo.fill', color: '#52c41a'}, + icon: { name: 'photo.fill', color: '#52c41a' }, type: 'input', title: '晚上背景颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', val: 'darkBgColor', }, { - icon: {name: 'sun.max.fill', color: '#d48806'}, + icon: { name: 'sun.max.fill', color: '#d48806' }, type: 'input', title: '白天字体颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'lightColor', }, { - icon: {name: 'moon.stars.fill', color: '#d4b106'}, + icon: { name: 'moon.stars.fill', color: '#d4b106' }, type: 'input', title: '晚上字体颜色', desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'darkColor', }, - ]; + ] const background = [ { - icon: {name: 'text.below.photo', color: '#faad14'}, + icon: { name: 'text.below.photo', color: '#faad14' }, type: 'setBackground', title: '透明背景设置', }, { - icon: {name: 'photo.on.rectangle', color: '#fa8c16'}, + icon: { name: 'photo.on.rectangle', color: '#fa8c16' }, type: 'setDayBackground', title: '白天背景图片', }, { - icon: {name: 'photo.fill.on.rectangle.fill', color: '#fa541c'}, + icon: { name: 'photo.fill.on.rectangle.fill', color: '#fa541c' }, type: 'setNightBackground', title: '晚上背景图片', }, { - icon: {name: 'record.circle', color: '#722ed1'}, + icon: { name: 'record.circle', color: '#722ed1' }, type: 'input', title: '白天蒙层透明', desc: '完全透明请设置为0', val: 'lightOpacity', }, { - icon: {name: 'record.circle.fill', color: '#eb2f96'}, + icon: { name: 'record.circle.fill', color: '#eb2f96' }, type: 'input', title: '晚上蒙层透明', desc: '完全透明请设置为0', val: 'darkOpacity', }, { - icon: {name: 'clear', color: '#f5222d'}, + icon: { name: 'clear', color: '#f5222d' }, type: 'removeBackground', title: '清空背景图片', }, - ]; + ] const boxjs = { - icon: {name: 'shippingbox', color: '#f7bb10'}, + icon: { name: 'shippingbox', color: '#f7bb10' }, type: 'input', title: 'BoxJS 域名', desc: '', val: 'boxjsDomain', - }; - if (this.useBoxJS) basic.push(boxjs); - table.removeAllRows(); - let topRow = new UITableRow(); - topRow.height = 60; - let leftText = topRow.addButton('Github'); - leftText.widthWeight = 0.3; + } + if (this.useBoxJS) basic.push(boxjs) + table.removeAllRows() + let topRow = new UITableRow() + topRow.height = 60 + let leftText = topRow.addButton('Github') + leftText.widthWeight = 0.3 leftText.onTap = async () => { - await Safari.openInApp('https://github.com/dompling/Scriptable'); - }; + await Safari.openInApp('https://github.com/dompling/Scriptable') + } let centerRow = topRow.addImageAtURL( - 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png', - ); - centerRow.widthWeight = 0.4; - centerRow.centerAligned(); + 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png' + ) + centerRow.widthWeight = 0.4 + centerRow.centerAligned() centerRow.onTap = async () => { - await Safari.open('https://t.me/Scriptable_JS'); - }; - let rightText = topRow.addButton('重置所有'); - rightText.widthWeight = 0.3; - rightText.rightAligned(); + await Safari.open('https://t.me/Scriptable_JS') + } + let rightText = topRow.addButton('重置所有') + rightText.widthWeight = 0.3 + rightText.rightAligned() rightText.onTap = async () => { - const options = ['取消', '重置']; + const options = ['取消', '重置'] const message = - '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。'; - const index = await this.generateAlert(message, options); - if (index === 0) return; - this.settings = {}; - await this.setBackgroundImage(false, false); - this.saveSettings(); - }; - table.addRow(topRow); - await this.preferences(table, basic, '基础设置'); - await this.preferences(table, background, '背景图片'); + '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。' + const index = await this.generateAlert(message, options) + if (index === 0) return + this.settings = {} + await this.setBackgroundImage(false, false) + this.saveSettings() + } + table.addRow(topRow) + await this.preferences(table, basic, '基础设置') + await this.preferences(table, background, '背景图片') } init(widgetFamily = config.widgetFamily) { // 组件大小:small,medium,large - this.widgetFamily = widgetFamily; - this.SETTING_KEY = this.md5(Script.name()); + this.widgetFamily = widgetFamily + this.SETTING_KEY = this.md5(Script.name()) //用于配置所有的组件相关设置 // 文件管理器 @@ -808,72 +808,72 @@ class DmYY { this.FILE_MGR = FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' - ](); + ]() // 本地,用于存储图片等 - this.FILE_MGR_LOCAL = FileManager.local(); + this.FILE_MGR_LOCAL = FileManager.local() this.BACKGROUND_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + '.jpg', - ); + 'bg_' + this.SETTING_KEY + '.jpg' + ) this.BACKGROUND_NIGHT_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + 'night.jpg', - ); - - this.settings = this.getSettings(); - this.settings.lightColor = this.settings.lightColor || '#000000'; - this.settings.darkColor = this.settings.darkColor || '#ffffff'; - this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff'; - this.settings.darkBgColor = this.settings.darkBgColor || '#000000'; - this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net'; - this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30'; - this.settings.lightOpacity = this.settings.lightOpacity || '0.4'; - this.settings.darkOpacity = this.settings.darkOpacity || '0.7'; - this.prefix = this.settings.boxjsDomain; - const lightBgColor = this.getColors(this.settings.lightBgColor); - const darkBgColor = this.getColors(this.settings.darkBgColor); + 'bg_' + this.SETTING_KEY + 'night.jpg' + ) + + this.settings = this.getSettings() + this.settings.lightColor = this.settings.lightColor || '#000000' + this.settings.darkColor = this.settings.darkColor || '#ffffff' + this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff' + this.settings.darkBgColor = this.settings.darkBgColor || '#000000' + this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net' + this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30' + this.settings.lightOpacity = this.settings.lightOpacity || '0.4' + this.settings.darkOpacity = this.settings.darkOpacity || '0.7' + this.prefix = this.settings.boxjsDomain + const lightBgColor = this.getColors(this.settings.lightBgColor) + const darkBgColor = this.getColors(this.settings.darkBgColor) if (lightBgColor.length > 1 || darkBgColor.length > 1) { this.backGroundColor = !Device.isUsingDarkAppearance() ? this.getBackgroundColor(lightBgColor) - : this.getBackgroundColor(darkBgColor); + : this.getBackgroundColor(darkBgColor) } else if (lightBgColor.length > 0 && darkBgColor.length > 0) { this.backGroundColor = Color.dynamic( new Color(this.settings.lightBgColor), - new Color(this.settings.darkBgColor), - ); + new Color(this.settings.darkBgColor) + ) } this.widgetColor = Color.dynamic( new Color(this.settings.lightColor), - new Color(this.settings.darkColor), - ); + new Color(this.settings.darkColor) + ) } getColors = (color = '') => { - const colors = typeof color === 'string' ? color.split(',') : color; - return colors; - }; + const colors = typeof color === 'string' ? color.split(',') : color + return colors + } getBackgroundColor = (colors) => { - const locations = []; - const linearColor = new LinearGradient(); - const cLen = colors.length; + const locations = [] + const linearColor = new LinearGradient() + const cLen = colors.length linearColor.colors = colors.map((item, index) => { - locations.push(Math.floor(((index + 1) / cLen) * 100) / 100); - return new Color(item, 1); - }); - linearColor.locations = locations; - return linearColor; - }; + locations.push(Math.floor(((index + 1) / cLen) * 100) / 100) + return new Color(item, 1) + }) + linearColor.locations = locations + return linearColor + } /** * 注册点击操作菜单 * @param {string} name 操作函数名 * @param {func} func 点击后执行的函数 */ - registerAction(name, func, icon = {name: 'gear', color: '#096dd9'}) { - this._actions[name] = func.bind(this); - this._actionsIcon[name] = icon; + registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }) { + this._actions[name] = func.bind(this) + this._actionsIcon[name] = icon } /** @@ -881,8 +881,8 @@ class DmYY { * @param {string} str 要编码的字符串 */ base64Encode(str) { - const data = Data.fromString(str); - return data.toBase64String(); + const data = Data.fromString(str) + return data.toBase64String() } /** @@ -890,8 +890,8 @@ class DmYY { * @param {string} b64 base64编码的数据 */ base64Decode(b64) { - const data = Data.fromBase64String(b64); - return data.toRawString(); + const data = Data.fromBase64String(b64) + return data.toRawString() } /** @@ -900,34 +900,34 @@ class DmYY { */ md5(str) { function d(n, t) { - var r = (65535 & n) + (65535 & t); - return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r); + var r = (65535 & n) + (65535 & t) + return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r) } function f(n, t, r, e, o, u) { - return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r); - var c, f; + return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r) + var c, f } function l(n, t, r, e, o, u, c) { - return f((t & r) | (~t & e), n, t, o, u, c); + return f((t & r) | (~t & e), n, t, o, u, c) } function v(n, t, r, e, o, u, c) { - return f((t & e) | (r & ~e), n, t, o, u, c); + return f((t & e) | (r & ~e), n, t, o, u, c) } function g(n, t, r, e, o, u, c) { - return f(t ^ r ^ e, n, t, o, u, c); + return f(t ^ r ^ e, n, t, o, u, c) } function m(n, t, r, e, o, u, c) { - return f(r ^ (t | ~e), n, t, o, u, c); + return f(r ^ (t | ~e), n, t, o, u, c) } function i(n, t) { var r, e, o, u - ;(n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t); + ;(n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t) for ( var c = 1732584193, f = -271733879, @@ -959,7 +959,7 @@ class DmYY { a, n[h + 1], 5, - -165796510, + -165796510 )), (a = v(a, c, f, i, n[h + 6], 9, -1069501632)), (i = v(i, a, c, f, n[h + 11], 14, 643717713)), @@ -982,7 +982,7 @@ class DmYY { a, n[h + 5], 4, - -378558, + -378558 )), (a = g(a, c, f, i, n[h + 8], 11, -2022574463)), (i = g(i, a, c, f, n[h + 11], 16, 1839030562)), @@ -1005,7 +1005,7 @@ class DmYY { a, n[h], 6, - -198630844, + -198630844 )), (a = m(a, c, f, i, n[h + 7], 10, 1126891415)), (i = m(i, a, c, f, n[h + 14], 15, -1416354905)), @@ -1025,67 +1025,67 @@ class DmYY { (c = d(c, r)), (f = d(f, e)), (i = d(i, o)), - (a = d(a, u)); - return [c, f, i, a]; + (a = d(a, u)) + return [c, f, i, a] } function a(n) { for (var t = '', r = 32 * n.length, e = 0; e < r; e += 8) - t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255); - return t; + t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255) + return t } function h(n) { - var t = []; + var t = [] for (t[(n.length >> 2) - 1] = void 0, e = 0; e < t.length; e += 1) - t[e] = 0; + t[e] = 0 for (var r = 8 * n.length, e = 0; e < r; e += 8) - t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32; - return t; + t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32 + return t } function e(n) { for (var t, r = '0123456789abcdef', e = '', o = 0; o < n.length; o += 1) (t = n.charCodeAt(o)), - (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)); - return e; + (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)) + return e } function r(n) { - return unescape(encodeURIComponent(n)); + return unescape(encodeURIComponent(n)) } function o(n) { - return a(i(h((t = r(n))), 8 * t.length)); - var t; + return a(i(h((t = r(n))), 8 * t.length)) + var t } function u(n, t) { - return (function(n, t) { + return (function (n, t) { var r, e, o = h(n), u = [], - c = []; + c = [] for ( u[15] = c[15] = void 0, - 16 < o.length && (o = i(o, 8 * n.length)), + 16 < o.length && (o = i(o, 8 * n.length)), r = 0; r < 16; r += 1 ) - (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]); + (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]) return ( (e = i(u.concat(h(t)), 512 + 8 * t.length)), a(i(c.concat(e), 640)) - ); - })(r(n), r(t)); + ) + })(r(n), r(t)) } function t(n, t, r) { - return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)); + return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)) } - return t(str); + return t(str) } /** @@ -1096,24 +1096,24 @@ class DmYY { * @param {bool|color} color 字体的颜色(自定义背景时使用,默认系统) */ async renderHeader(widget, icon, title, color = false) { - let header = widget.addStack(); - header.centerAlignContent(); + let header = widget.addStack() + header.centerAlignContent() try { - const image = await this.$request.get(icon, 'IMG'); - let _icon = header.addImage(image); - _icon.imageSize = new Size(14, 14); - _icon.cornerRadius = 4; + const image = await this.$request.get(icon, 'IMG') + let _icon = header.addImage(image) + _icon.imageSize = new Size(14, 14) + _icon.cornerRadius = 4 } catch (e) { - console.log(e); + console.log(e) } - header.addSpacer(10); - let _title = header.addText(title); - if (color) _title.textColor = color; - _title.textOpacity = 0.7; - _title.font = Font.boldSystemFont(12); - _title.lineLimit = 1; - widget.addSpacer(15); - return widget; + header.addSpacer(10) + let _title = header.addText(title) + if (color) _title.textColor = color + _title.textOpacity = 0.7 + _title.font = Font.boldSystemFont(12) + _title.lineLimit = 1 + widget.addSpacer(15) + return widget } /** @@ -1123,13 +1123,13 @@ class DmYY { */ async generateAlert(message, options) { - let alert = new Alert(); - alert.message = message; + let alert = new Alert() + alert.message = message for (const option of options) { - alert.addAction(option); + alert.addAction(option) } - return await alert.presentAlert(); + return await alert.presentAlert() } /** @@ -1139,12 +1139,12 @@ class DmYY { * @param {string} url 点击后打开的URL */ async notify(title, body, url, opts = {}) { - let n = new Notification(); - n = Object.assign(n, opts); - n.title = title; - n.body = body; - if (url) n.openURL = url; - return await n.schedule(); + let n = new Notification() + n = Object.assign(n, opts) + n.title = title + n.body = body + if (url) n.openURL = url + return await n.schedule() } /** @@ -1154,19 +1154,19 @@ class DmYY { * @param {float} opacity 透明度 */ async shadowImage(img, color = '#000000', opacity = 0.7) { - if (!img) return; - if (opacity === 0) return img; - let ctx = new DrawContext(); + if (!img) return + if (opacity === 0) return img + let ctx = new DrawContext() // 获取图片的尺寸 - ctx.size = img.size; + ctx.size = img.size ctx.drawImageInRect( img, - new Rect(0, 0, img.size['width'], img.size['height']), - ); - ctx.setFillColor(new Color(color, opacity)); - ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])); - return await ctx.getImage(); + new Rect(0, 0, img.size['width'], img.size['height']) + ) + ctx.setFillColor(new Color(color, opacity)) + ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])) + return await ctx.getImage() } /** @@ -1174,20 +1174,20 @@ class DmYY { * @param {boolean} json 是否为json格式 */ getSettings(json = true) { - let res = json ? {} : ''; - let cache = ''; + let res = json ? {} : '' + let cache = '' if (Keychain.contains(this.SETTING_KEY)) { - cache = Keychain.get(this.SETTING_KEY); + cache = Keychain.get(this.SETTING_KEY) } if (json) { try { - res = JSON.parse(cache); + res = JSON.parse(cache) } catch (e) {} } else { - res = cache; + res = cache } - return res; + return res } /** @@ -1198,9 +1198,9 @@ class DmYY { let res = typeof this.settings === 'object' ? JSON.stringify(this.settings) - : String(this.settings); - Keychain.set(this.SETTING_KEY, res); - if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新'); + : String(this.settings) + Keychain.set(this.SETTING_KEY, res) + if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新') } /** @@ -1208,17 +1208,17 @@ class DmYY { * @reutrn img | false */ getBackgroundImage() { - let result = null; + let result = null if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - result = Image.fromFile(this.BACKGROUND_KEY); + result = Image.fromFile(this.BACKGROUND_KEY) } if ( Device.isUsingDarkAppearance() && this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY) ) { - result = Image.fromFile(this.BACKGROUND_NIGHT_KEY); + result = Image.fromFile(this.BACKGROUND_NIGHT_KEY) } - return result; + return result } /** @@ -1229,16 +1229,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY); + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY) } if (notify) - this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效'); + this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效') } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img); + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img) if (notify) - this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效'); + this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效') } } @@ -1246,16 +1246,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY); + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY) } if (notify) - this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效'); + this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效') } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img); + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img) if (notify) - this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效'); + this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效') } } @@ -1264,131 +1264,135 @@ class DmYY { i = arr.length, min = i - count, temp, - index; - min = min > 0 ? min : 0; + index + min = min > 0 ? min : 0 while (i-- > min) { - index = Math.floor((i + 1) * Math.random()); - temp = shuffled[index]; - shuffled[index] = shuffled[i]; - shuffled[i] = temp; + index = Math.floor((i + 1) * Math.random()) + temp = shuffled[index] + shuffled[index] = shuffled[i] + shuffled[i] = temp } - return shuffled.slice(min); + return shuffled.slice(min) } textFormat = { - defaultText: {size: 14, font: 'regular', color: this.widgetColor}, - battery: {size: 10, font: 'bold', color: this.widgetColor}, - title: {size: 16, font: 'semibold', color: this.widgetColor}, - SFMono: {size: 12, font: 'SF Mono', color: this.widgetColor}, - }; + defaultText: { size: 14, font: 'regular', color: this.widgetColor }, + battery: { size: 10, font: 'bold', color: this.widgetColor }, + title: { size: 16, font: 'semibold', color: this.widgetColor }, + SFMono: { size: 12, font: 'SF Mono', color: this.widgetColor }, + } provideFont = (fontName, fontSize) => { const fontGenerator = { - ultralight: function() { - return Font.ultraLightSystemFont(fontSize); + ultralight: function () { + return Font.ultraLightSystemFont(fontSize) }, - light: function() { - return Font.lightSystemFont(fontSize); + light: function () { + return Font.lightSystemFont(fontSize) }, - regular: function() { - return Font.regularSystemFont(fontSize); + regular: function () { + return Font.regularSystemFont(fontSize) }, - medium: function() { - return Font.mediumSystemFont(fontSize); + medium: function () { + return Font.mediumSystemFont(fontSize) }, - semibold: function() { - return Font.semiboldSystemFont(fontSize); + semibold: function () { + return Font.semiboldSystemFont(fontSize) }, - bold: function() { - return Font.boldSystemFont(fontSize); + bold: function () { + return Font.boldSystemFont(fontSize) }, - heavy: function() { - return Font.heavySystemFont(fontSize); + heavy: function () { + return Font.heavySystemFont(fontSize) }, - black: function() { - return Font.blackSystemFont(fontSize); + black: function () { + return Font.blackSystemFont(fontSize) }, - italic: function() { - return Font.italicSystemFont(fontSize); + italic: function () { + return Font.italicSystemFont(fontSize) }, - }; + } - const systemFont = fontGenerator[fontName]; + const systemFont = fontGenerator[fontName] if (systemFont) { - return systemFont(); + return systemFont() } - return new Font(fontName, fontSize); - }; + return new Font(fontName, fontSize) + } provideText = ( - string, container, format = { + string, + container, + format = { font: 'light', size: 14, color: this.widgetColor, opacity: 1, minimumScaleFactor: 1, - }) => { - const textItem = container.addText(string); - const textFont = format.font; - const textSize = format.size; - const textColor = format.color; - - textItem.font = this.provideFont(textFont, textSize); - textItem.textColor = textColor; - textItem.textOpacity = format.opacity || 1; - textItem.minimumScaleFactor = format.minimumScaleFactor || 1; - return textItem; - }; + } + ) => { + const textItem = container.addText(string) + const textFont = format.font + const textSize = format.size + const textColor = format.color + + textItem.font = this.provideFont(textFont, textSize) + textItem.textColor = textColor + textItem.textOpacity = format.opacity || 1 + textItem.minimumScaleFactor = format.minimumScaleFactor || 1 + return textItem + } } // @base.end const Runing = async (Widget, default_args = '', isDebug = true, extra) => { - let M = null; + let M = null // 判断hash是否和当前设备匹配 if (config.runsInWidget) { - M = new Widget(args.widgetParameter || ''); + M = new Widget(args.widgetParameter || '') if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key]; - }); + M[key] = extra[key] + }) } - const W = await M.render(); + const W = await M.render() try { if (M.settings.refreshAfterDate) { - W.refreshAfterDate = new Date( - new Date() + 1000 * 60 * parseInt(M.settings.refreshAfterDate), - ); + const refreshTime = parseInt(M.settings.refreshAfterDate) * 1000 * 60 + const timeStr = new Date().getTime() + refreshTime + W.refreshAfterDate = new Date(timeStr) } } catch (e) { - console.log(e); + console.log(e) } if (W) { - Script.setWidget(W); - Script.complete(); + Script.setWidget(W) + Script.complete() } } else { - let {act, __arg, __size} = args.queryParameters; - M = new Widget(__arg || default_args || ''); + let { act, __arg, __size } = args.queryParameters + M = new Widget(__arg || default_args || '') if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key]; - }); + M[key] = extra[key] + }) } - if (__size) M.init(__size); + if (__size) M.init(__size) if (!act || !M['_actions']) { // 弹出选择菜单 - const actions = M['_actions']; - const table = new UITable(); + const actions = M['_actions'] + const table = new UITable() const onClick = async (item) => { - M.widgetFamily = item.val; - w = await M.render(); - const fnc = item.val.toLowerCase().replace( - /( |^)[a-z]/g, (L) => L.toUpperCase()); + M.widgetFamily = item.val + w = await M.render() + const fnc = item.val + .toLowerCase() + .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()) if (w) { - return w[`present${fnc}`](); + return w[`present${fnc}`]() } - }; + } const preview = [ { url: 'https://z3.ax1x.com/2021/03/26/6v5wIP.png', @@ -1411,28 +1415,28 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { dismissOnSelect: true, onClick, }, - ]; - await M.preferences(table, preview, '预览组件'); - const extra = []; + ] + await M.preferences(table, preview, '预览组件') + const extra = [] for (let _ in actions) { - const iconItem = M._actionsIcon[_]; - const isUrl = typeof iconItem === 'string'; + const iconItem = M._actionsIcon[_] + const isUrl = typeof iconItem === 'string' const actionItem = { title: _, onClick: actions[_], - }; + } if (isUrl) { - actionItem.url = iconItem; + actionItem.url = iconItem } else { - actionItem.icon = iconItem; + actionItem.icon = iconItem } - extra.push(actionItem); + extra.push(actionItem) } - await M.preferences(table, extra, '配置组件'); - return table.present(); + await M.preferences(table, extra, '配置组件') + return table.present() } } -}; +} // await new DmYY().setWidgetConfig(); -module.exports = {DmYY, Runing}; +module.exports = { DmYY, Runing } From 38f5a972eeafdbad0311e93349ac0bb7a27635b2 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 29 Jun 2022 09:53:32 +0800 Subject: [PATCH 048/152] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B2=B9=E4=BB=B7?= =?UTF-8?q?=E4=B8=8B=E9=99=8D=E8=B4=9F=E5=8F=B7=E9=87=8D=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Oild.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Oild.js b/Scripts/Oild.js index e6c3842..b8b5d20 100644 --- a/Scripts/Oild.js +++ b/Scripts/Oild.js @@ -252,7 +252,7 @@ class Widget extends DmYY { oilZdeValueStack.centerAlignContent(); oilZdeValueStack.addSpacer(); this.provideText( - `${oilZde > 0 ? '+' : '-'} ${oilZde}`, oilZdeValueStack, + `${oilZde > 0 ? '+' : ''} ${oilZde}`, oilZdeValueStack, {font: 'light', size: 14, color: this.widgetColor}, ); From 5c066d99e27a5ff39ec9e853ed1528977227d725 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 27 Jul 2022 11:36:29 +0800 Subject: [PATCH 049/152] =?UTF-8?q?=E4=B8=B0=E7=94=B0=E6=B1=BD=E8=BD=A6?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Ftms.js | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 3a09bfe..4d6faf4 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -23,7 +23,6 @@ class Ftms { } else { await this.cacheData() } -// console.log(this.$.dataSource) this.cacheData() } @@ -47,22 +46,21 @@ class Ftms { 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail' ) const response = await this.$.$request.post(options) -// console.log(response) if (response.msg === 'success') { this.$.dataSource.remoteInfo = response.result const safeData = - response.result.list.filter( - (item) => item.security !== 'safe' - ) || [] + response.result.list.filter((item) => item.security !== 'safe') || [] if (safeData.length > 0) { - this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}` - }else{ - this.$.dataSource.safeText = `` + this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}` + } else { + this.$.dataSource.safeText = `` } const dataTime = this.$.dataSource.remoteInfo.datatime.split('-') this.$.dataSource.remoteInfo.datatime = `${dataTime[1] || ''}-${ dataTime[2] || '' }` + } else { + this.$.notify(this.name, response.msg) } await this.getDrivingMonitorInfo() } @@ -78,7 +76,6 @@ class Ftms { } this.$.dataSource.monitorInfo.oilWasteText = `油耗:${this.$.dataSource.monitorInfo.oilWaste}L/100km` this.$.settings.dataSource = this.$.dataSource -// console.log(this.$.dataSource) this.$.saveSettings(false) } @@ -97,6 +94,8 @@ class Ftms { this.$.settings.serveInfo = response.data this.$.serveInfo = response.data this.$.saveSettings(false) + } else { + this.$.notify(this.name, response.msg) } } else { this.$.serveInfo = this.$.settings.serveInfo || {} From c4dbab5135b799e8bc7095554792768dc18b7f31 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Wed, 3 Aug 2022 10:34:26 +0800 Subject: [PATCH 050/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=20boxjs=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E8=AF=BB=E5=8F=96=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index f538efc..aaa898d 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -104,9 +104,20 @@ class DmYY { url, key ? { timeoutInterval: 1 } : {} ) + if (key) { + this.settings.BoxJSData = { + ...this.settings.BoxJSData, + [key]: boxdata.val, + } + this.saveSettings() + } if (boxdata.val) return boxdata.val + return boxdata.datas } catch (e) { + if (key && this.settings.BoxJSData[key]) { + return this.settings.BoxJSData[key] + } if (notify) await this.notify( `${this.name} - BoxJS 数据读取失败`, From 1b90ecbf446b4193ea812b772a616f88b417078a Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 5 Aug 2022 14:22:12 +0800 Subject: [PATCH 051/152] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20boxjs=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index aaa898d..7cf9c70 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -109,7 +109,7 @@ class DmYY { ...this.settings.BoxJSData, [key]: boxdata.val, } - this.saveSettings() + this.saveSettings(false) } if (boxdata.val) return boxdata.val From 28e38c97425bfaa24f5af05817d9e744932acff7 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 9 Aug 2022 09:41:49 +0800 Subject: [PATCH 052/152] =?UTF-8?q?update=EF=BC=9A=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=B0=8F=E7=BB=84=E4=BB=B6=E5=9B=BE=E7=89=87=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 7cf9c70..875a353 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -33,29 +33,31 @@ class DmYY { // 发起请求 http = async (options = { headers: {}, url: '' }, type = 'JSON') => { + let request, fileName, imagePath + if (type === 'IMG') { + fileName = this.md5(options.url) + imagePath = this.FILE_MGR_LOCAL.joinPath( + this.FILE_MGR_LOCAL.documentsDirectory(), + fileName + ) + if (this.FILE_MGR_LOCAL.fileExists(fileName)) { + return Image.fromFile(imagePath) + } + } try { - let request - if (type !== 'IMG') { - request = this.getRequest() - Object.keys(options).forEach((key) => { - request[key] = options[key] - }) - request.headers = { ...this.defaultHeaders, ...options.headers } - } else { + if (type === 'IMG') { request = this.getRequest(options.url) - const fileName = this.md5(options.url) - const imagePath = this.FILE_MGR_LOCAL.joinPath( - this.FILE_MGR_LOCAL.documentsDirectory(), - fileName - ) console.log(imagePath) - if (this.FILE_MGR_LOCAL.fileExists(fileName)) { - return Image.fromFile(imagePath) - } const response = await request.loadImage() this.FILE_MGR_LOCAL.writeImage(imagePath, response) return response } + request = this.getRequest() + Object.keys(options).forEach((key) => { + request[key] = options[key] + }) + request.headers = { ...this.defaultHeaders, ...options.headers } + if (type === 'JSON') { return await request.loadJSON() } From 467bc0cbcec5ebac91bbd1db61a6ec3581d1bf46 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 16 Aug 2022 09:38:07 +0800 Subject: [PATCH 053/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 875a353..3d2a3ac 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -33,23 +33,15 @@ class DmYY { // 发起请求 http = async (options = { headers: {}, url: '' }, type = 'JSON') => { - let request, fileName, imagePath - if (type === 'IMG') { - fileName = this.md5(options.url) - imagePath = this.FILE_MGR_LOCAL.joinPath( - this.FILE_MGR_LOCAL.documentsDirectory(), - fileName - ) - if (this.FILE_MGR_LOCAL.fileExists(fileName)) { - return Image.fromFile(imagePath) - } - } + let request try { if (type === 'IMG') { + const fileName = `${this.cacheImage}/${this.md5(options.url)}` + console.log(fileName) + if (this.FILE_MGR.fileExists(fileName)) return Image.fromFile(fileName) request = this.getRequest(options.url) - console.log(imagePath) const response = await request.loadImage() - this.FILE_MGR_LOCAL.writeImage(imagePath, response) + this.FILE_MGR.writeImage(fileName, response) return response } request = this.getRequest() @@ -822,6 +814,16 @@ class DmYY { FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' ]() + + this.cacheImage = this.FILE_MGR.joinPath( + this.FILE_MGR.libraryDirectory(), + `${Script.name()}/images` + ) + + if (!this.FILE_MGR.fileExists(this.cacheImage)) { + this.FILE_MGR.createDirectory(this.cacheImage, true) + } + // 本地,用于存储图片等 this.FILE_MGR_LOCAL = FileManager.local() this.BACKGROUND_KEY = this.FILE_MGR_LOCAL.joinPath( From 1bf4d0a6c222d0202330e5c3ca0697d92e74e3b6 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Tue, 16 Aug 2022 10:13:28 +0800 Subject: [PATCH 054/152] =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 3d2a3ac..3173248 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -38,10 +38,18 @@ class DmYY { if (type === 'IMG') { const fileName = `${this.cacheImage}/${this.md5(options.url)}` console.log(fileName) - if (this.FILE_MGR.fileExists(fileName)) return Image.fromFile(fileName) request = this.getRequest(options.url) - const response = await request.loadImage() - this.FILE_MGR.writeImage(fileName, response) + let response + if (this.FILE_MGR.fileExists(fileName)) { + request.loadImage().then((res) => { + console.log(res) + this.FILE_MGR.writeImage(fileName, res) + }) + return Image.fromFile(fileName) + } else { + response = await request.loadImage() + this.FILE_MGR.writeImage(fileName, response) + } return response } request = this.getRequest() @@ -795,6 +803,7 @@ class DmYY { if (index === 0) return this.settings = {} await this.setBackgroundImage(false, false) + this.FILE_MGR.remove(this.cacheImage) this.saveSettings() } table.addRow(topRow) From fe0e3986758ccdc2c1e5b1d3c63e1ed031830d79 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 26 Aug 2022 09:41:15 +0800 Subject: [PATCH 055/152] fix --- Scripts/Health.js | 489 +++++++++++++++++++++++----------------------- 1 file changed, 243 insertions(+), 246 deletions(-) diff --git a/Scripts/Health.js b/Scripts/Health.js index b6efbc4..582bbbe 100644 --- a/Scripts/Health.js +++ b/Scripts/Health.js @@ -9,326 +9,326 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === 'undefined') require = importModule; -const { DmYY, Runing } = require('./DmYY'); +if (typeof require === 'undefined') require = importModule +const { DmYY, Runing } = require('./DmYY') // @组件代码开始 class Widget extends DmYY { constructor(arg) { - super(arg); - this.name = '健康行走步数'; - this.en = 'healthCenter'; - this.maxMonthDist = parseInt(this.settings.maxMonthDist) || 5; // 柱状图比例高度,值越大,柱状范围越广 - this.Run(); + super(arg) + this.name = '健康行走步数' + this.en = 'healthCenter' + this.maxMonthDist = parseInt(this.settings.maxMonthDist) || 5 // 柱状图比例高度,值越大,柱状范围越广 + this.Run() } - widgetFamily = 'medium'; - maxYearDist = 1500; + widgetFamily = 'medium' + maxYearDist = 1500 - color1 = Color.orange(); - lineColor = new Color('#48484b'); - useBoxJS = false; + color1 = Color.orange() + lineColor = new Color('#48484b') + useBoxJS = false - running = {}; - stepsCount = 0; - stepsToday = 0; + running = {} + stepsCount = 0 + stepsToday = 0 init = async () => { try { - await this.getData(); + await this.getData() } catch (e) { - console.log(e); + console.log(e) } - }; + } numberFormat(value) { try { - const param = {}; - let k = 10000; - const size = ['', '万', '亿', '万亿']; - let i; + const param = {} + let k = 10000 + const size = ['', '万', '亿', '万亿'] + let i if (value < k) { - param.value = value; - param.unit = ''; + param.value = value + param.unit = '' } else { - i = Math.floor(Math.log(value) / Math.log(k)); - param.value = (value / Math.pow(k, i)).toFixed(2); - param.unit = size[i]; + i = Math.floor(Math.log(value) / Math.log(k)) + param.value = (value / Math.pow(k, i)).toFixed(2) + param.unit = size[i] } - return param; + return param } catch (e) { - console.log(e); + console.log(e) } } getData = async () => { try { - const fileICloud = FileManager.iCloud(); - const dir = fileICloud.documentsDirectory(); - const path = fileICloud.joinPath(dir, 'health.txt'); - const response = fileICloud.readString(path); - let data = JSON.parse(response); - const dateToday = new Date(); - const year = dateToday.getFullYear(); - let month = dateToday.getMonth() + 1; - let day = dateToday.getDate(); - month = month >= 10 ? month : `0${month}`; - day = day >= 10 ? day : `0${day}`; - const today = `${year}-${month}-${day}`; + const fileICloud = FileManager.iCloud() + const dir = fileICloud.documentsDirectory() + const path = fileICloud.joinPath(dir, 'health.txt') + const response = fileICloud.readString(path) + let data = JSON.parse(response) + const dateToday = new Date() + const year = dateToday.getFullYear() + let month = dateToday.getMonth() + 1 + let day = dateToday.getDate() + month = month >= 10 ? month : `0${month}` + day = day >= 10 ? day : `0${day}` + const today = `${year}-${month}-${day}` data.forEach((item) => { if (item.health_type === 'Walking + Running Distance') { item.samples.forEach((run, index) => { - if (item.samples.length - 1 === index) return; - const date = run.date; - if (!this.running[date]) this.running[date] = 0; - this.running[date] += parseFloat(run.value); - }); + if (item.samples.length - 1 === index) return + const date = run.date + if (!this.running[date]) this.running[date] = 0 + this.running[date] += parseFloat(run.value) + }) } if (item.health_type === 'Steps') { item.samples.forEach((step) => { - if (step.date === today) this.stepsToday = step.value; - this.stepsCount += parseInt(step.value); - }); + if (step.date === today) this.stepsToday = step.value + this.stepsCount += parseInt(step.value) + }) } - }); + }) Object.keys(this.running).forEach((key) => { - this.running[key] = Math.floor(this.running[key] * 100) / 100; - }); + this.running[key] = Math.floor(this.running[key] * 100) / 100 + }) } catch (e) { this.notify( this.name, '健康数据读取失败,请点击使用健康数据快捷指令更新步数', - 'https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf', - ); - return false; + 'https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf' + ) + return false } - }; + } /*------------------------------------------------------------------------------ 50 km Linien ------------------------------------------------------------------------------*/ createLines(stack) { - let canvas, path; + let canvas, path // 50km Linien - canvas = new DrawContext(); - canvas.size = new Size(292, 82); - canvas.opaque = false; - canvas.respectScreenScale = true; - canvas.setFillColor(this.lineColor); - path = new Path(); - path.addRect(new Rect(0, 0, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - path = new Path(); - path.addRect(new Rect(0, 15, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - path = new Path(); - path.addRect(new Rect(0, 30, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - path = new Path(); - path.addRect(new Rect(0, 45, 292, 1)); - canvas.addPath(path); - canvas.fillPath(); - stack.backgroundImage = canvas.getImage(); + canvas = new DrawContext() + canvas.size = new Size(292, 82) + canvas.opaque = false + canvas.respectScreenScale = true + canvas.setFillColor(this.lineColor) + path = new Path() + path.addRect(new Rect(0, 0, 292, 1)) + canvas.addPath(path) + canvas.fillPath() + path = new Path() + path.addRect(new Rect(0, 15, 292, 1)) + canvas.addPath(path) + canvas.fillPath() + path = new Path() + path.addRect(new Rect(0, 30, 292, 1)) + canvas.addPath(path) + canvas.fillPath() + path = new Path() + path.addRect(new Rect(0, 45, 292, 1)) + canvas.addPath(path) + canvas.fillPath() + stack.backgroundImage = canvas.getImage() } async buildWidget(widget) { // // Stacks definieren - let stackYear = widget.addStack(); - widget.addSpacer(); - let stackMonth = widget.addStack(); + let stackYear = widget.addStack() + widget.addSpacer() + let stackMonth = widget.addStack() // Stacks für Symbol und Jahresauswertung aufbereiten - let stackYear1 = stackYear.addStack(); - stackYear.addSpacer(10); - let stackYear2 = stackYear.addStack(); - let sym = SFSymbol.named('figure.walk'); - let img = stackYear1.addImage(sym.image); - img.tintColor = this.color1; - img.imageSize = new Size(25, 25); - stackYear2.layoutVertically(); - let stackYearCurr = stackYear2.addStack(); - let stackThemItem = stackYear2.addStack(); - let stackToday = stackYear2.addStack(); - - let data = 0; - const runningData = Object.keys(this.running); - if (runningData.length > 12) runningData.splice(0, runningData.length - 12); + let stackYear1 = stackYear.addStack() + stackYear.addSpacer(10) + let stackYear2 = stackYear.addStack() + let sym = SFSymbol.named('figure.walk') + let img = stackYear1.addImage(sym.image) + img.tintColor = this.color1 + img.imageSize = new Size(25, 25) + stackYear2.layoutVertically() + let stackYearCurr = stackYear2.addStack() + let stackThemItem = stackYear2.addStack() + let stackToday = stackYear2.addStack() + + let data = 0 + const runningData = Object.keys(this.running) + if (runningData.length > 12) runningData.splice(0, runningData.length - 12) runningData.forEach((date) => { - const [_, month, day] = date.split('-'); - const stackDay = stackMonth.addStack(); - const value = this.running[date]; - this.createProgressMonth(stackDay, `${month}.${day}`, value); - stackMonth.addSpacer(2); - data += value; - }); - this.createProgressYear(stackYearCurr, '运动', data, this.color1); - - const count = (18 * this.stepsCount) / ((20000 * this.maxMonthDist) / 4); + const [_, month, day] = date.split('-') + const stackDay = stackMonth.addStack() + const value = this.running[date] + this.createProgressMonth(stackDay, `${month}.${day}`, value) + stackMonth.addSpacer(2) + data += value + }) + this.createProgressYear(stackYearCurr, '运动', data, this.color1) + + const count = (18 * this.stepsCount) / ((20000 * this.maxMonthDist) / 4) this.createProgressSteps( stackThemItem, '步数', this.stepsCount, this.color1, - count, - ); - const today = (18 * this.stepsToday) / ((2000 * this.maxMonthDist) / 4); + count + ) + const today = (18 * this.stepsToday) / ((2000 * this.maxMonthDist) / 4) this.createProgressSteps( stackToday, '今日', this.stepsToday, this.color1, - today, - ); + today + ) // 50km Linie - this.createLines(stackMonth); - return widget; + this.createLines(stackMonth) + return widget } createProgressYear(stack, year, dist, color) { - let stackDesc, stackPBar, stackDist, canvas, path, txt, img; + let stackDesc, stackPBar, stackDist, canvas, path, txt, img // Initialisierung - stack.centerAlignContent(); + stack.centerAlignContent() // Stacks definieren - stackDesc = stack.addStack(); - stackPBar = stack.addStack(); - stackDist = stack.addStack(); + stackDesc = stack.addStack() + stackPBar = stack.addStack() + stackDist = stack.addStack() // Beschreibung - stackDesc.size = new Size(30, 0); - txt = stackDesc.addText(year); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - stackDesc.addSpacer(); + stackDesc.size = new Size(30, 0) + txt = stackDesc.addText(year) + txt.font = Font.systemFont(7) + txt.textColor = this.widgetColor + stackDesc.addSpacer() // Progress-Bar - canvas = new DrawContext(); - canvas.size = new Size(180, 7); - canvas.opaque = false; - canvas.respectScreenScale = true; - canvas.setFillColor(new Color('#48484b')); - path = new Path(); - path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - canvas.setFillColor(color); - path = new Path(); + canvas = new DrawContext() + canvas.size = new Size(180, 7) + canvas.opaque = false + canvas.respectScreenScale = true + canvas.setFillColor(new Color('#48484b')) + path = new Path() + path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2) + canvas.addPath(path) + canvas.fillPath() + canvas.setFillColor(color) + path = new Path() path.addRoundedRect( new Rect(0, 0, (180 * dist) / ((200 * this.maxMonthDist) / 4), 5), 3, - 2, - ); - canvas.addPath(path); - canvas.fillPath(); - img = stackPBar.addImage(canvas.getImage()); - img.imageSize = new Size(180, 7); + 2 + ) + canvas.addPath(path) + canvas.fillPath() + img = stackPBar.addImage(canvas.getImage()) + img.imageSize = new Size(180, 7) // Distanz - stackDist.addSpacer(10); - txt = stackDist.addText(Math.round(dist).toString() + ' km'); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; + stackDist.addSpacer(10) + txt = stackDist.addText(Math.round(dist).toString() + ' km') + txt.font = Font.systemFont(7) + txt.textColor = this.widgetColor } createProgressSteps(stack, year, dist, color, rectScale) { - let stackDesc, stackPBar, stackDist, canvas, path, txt, img; + let stackDesc, stackPBar, stackDist, canvas, path, txt, img // Initialisierung - stack.centerAlignContent(); + stack.centerAlignContent() // Stacks definieren - stackDesc = stack.addStack(); - stackPBar = stack.addStack(); - stackDist = stack.addStack(); + stackDesc = stack.addStack() + stackPBar = stack.addStack() + stackDist = stack.addStack() // Beschreibung - stackDesc.size = new Size(30, 0); - txt = stackDesc.addText(year); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - stackDesc.addSpacer(); + stackDesc.size = new Size(30, 0) + txt = stackDesc.addText(year) + txt.font = Font.systemFont(7) + txt.textColor = this.widgetColor + stackDesc.addSpacer() // Progress-Bar - canvas = new DrawContext(); - canvas.size = new Size(180, 7); - canvas.opaque = false; - canvas.respectScreenScale = true; - canvas.setFillColor(new Color('#48484b')); - path = new Path(); - path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - canvas.setFillColor(color); - path = new Path(); - const numberText = this.numberFormat(dist); - - path.addRoundedRect(new Rect(0, 0, rectScale, 5), 3, 2); - canvas.addPath(path); - canvas.fillPath(); - img = stackPBar.addImage(canvas.getImage()); - img.imageSize = new Size(180, 7); + canvas = new DrawContext() + canvas.size = new Size(180, 7) + canvas.opaque = false + canvas.respectScreenScale = true + canvas.setFillColor(new Color('#48484b')) + path = new Path() + path.addRoundedRect(new Rect(0, 0, 180, 5), 3, 2) + canvas.addPath(path) + canvas.fillPath() + canvas.setFillColor(color) + path = new Path() + const numberText = this.numberFormat(dist) + + path.addRoundedRect(new Rect(0, 0, rectScale, 5), 3, 2) + canvas.addPath(path) + canvas.fillPath() + img = stackPBar.addImage(canvas.getImage()) + img.imageSize = new Size(180, 7) // Distanz - stackDist.addSpacer(10); + stackDist.addSpacer(10) - txt = stackDist.addText(numberText.value + ` ${numberText.unit}步`); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; + txt = stackDist.addText(numberText.value + ` ${numberText.unit}步`) + txt.font = Font.systemFont(7) + txt.textColor = this.widgetColor } createTemplateItem(stack, desc) { // Stacks - const txt = stack.addText(desc); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; + const txt = stack.addText(desc) + txt.font = Font.systemFont(7) + txt.textColor = this.widgetColor } /*------------------------------------------------------------------------------ Balkenanzeige für Monatsauswertung aufbereiten ------------------------------------------------------------------------------*/ createProgressMonth(stack, month, dist3) { - let stackDist, stackPBar, stackDesc, canvas, path, s, img, txt; + let stackDist, stackPBar, stackDesc, canvas, path, s, img, txt // Stacks definieren - stack.layoutVertically(); - stackPBar = stack.addStack(); - stack.addSpacer(5); - stackDesc = stack.addStack(); - stackDist = stack.addStack(); + stack.layoutVertically() + stackPBar = stack.addStack() + stack.addSpacer(5) + stackDesc = stack.addStack() + stackDist = stack.addStack() // Progress-Bar - canvas = new DrawContext(); - canvas.size = new Size(17, 60); - canvas.opaque = false; - canvas.respectScreenScale = true; - - canvas.setFillColor(this.color1); - path = new Path(); - s = (50 * dist3) / this.maxMonthDist; - path.addRect(new Rect(6, 60 - s, 8, s)); - canvas.addPath(path); - canvas.fillPath(); - img = stackPBar.addImage(canvas.getImage()); - img.imageSize = new Size(17, 60); + canvas = new DrawContext() + canvas.size = new Size(17, 60) + canvas.opaque = false + canvas.respectScreenScale = true + + canvas.setFillColor(this.color1) + path = new Path() + s = (50 * dist3) / this.maxMonthDist + path.addRect(new Rect(6, 60 - s, 8, s)) + canvas.addPath(path) + canvas.fillPath() + img = stackPBar.addImage(canvas.getImage()) + img.imageSize = new Size(17, 60) // Monat - stackDesc.size = new Size(23, 10); - txt = stackDesc.addText(month); - txt.font = Font.systemFont(7); - txt.textColor = this.widgetColor; - txt.centerAlignText(); + stackDesc.size = new Size(23, 10) + txt = stackDesc.addText(month) + txt.font = Font.systemFont(7) + txt.textColor = this.widgetColor + txt.centerAlignText() // Distanz aktuelle Jahr - stackDist.size = new Size(20, 8); - txt = stackDist.addText(Math.round(dist3).toString()); - txt.font = Font.systemFont(6); - txt.textColor = this.widgetColor; - txt.centerAlignText(); + stackDist.size = new Size(20, 8) + txt = stackDist.addText(Math.round(dist3).toString()) + txt.font = Font.systemFont(6) + txt.textColor = this.widgetColor + txt.centerAlignText() } /** @@ -336,12 +336,12 @@ Balkenanzeige für Monatsauswertung aufbereiten * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 */ async render() { - await this.init(); - const widget = new ListWidget(); - await this.getWidgetBackgroundImage(widget); - await this.buildWidget(widget); - await widget.presentMedium(); - if (config.runsFromHomeScreen) return widget; + await this.init() + const widget = new ListWidget() + await this.getWidgetBackgroundImage(widget) + await this.buildWidget(widget) + await widget.presentMedium() + if (config.runsFromHomeScreen) return widget } Run = () => { @@ -350,58 +350,55 @@ Balkenanzeige für Monatsauswertung aufbereiten await this.notify( this.name, '点击安装捷径', - 'https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf', - ); - }); + 'https://www.icloud.com/shortcuts/beb65db5ea0a474abe7ff080410b9ddf' + ) + }) this.registerAction('柱状比例', async () => { await this.setAlertInput( '设置柱状比例', ' 柱状图比例高度,值越大,柱状范围越广', - { maxMonthDist: '比例默认值,5' }, - ); - }); - this.registerAction('皮肤颜色', this.setWidgetSkin); - this.registerAction('刻度颜色', this.setWidgetScale); - this.registerAction('基础设置', this.setWidgetConfig); + { maxMonthDist: '比例默认值,5' } + ) + }) + this.registerAction('皮肤颜色', this.setWidgetSkin) + this.registerAction('刻度颜色', this.setWidgetScale) + this.registerAction('基础设置', this.setWidgetConfig) } const skinColor = !this.isNight ? this.settings.lightSkinColor - : this.settings.darkSkinColor; - this.color1 = skinColor ? new Color(skinColor) : this.color1; + : this.settings.darkSkinColor + this.color1 = skinColor ? new Color(skinColor) : this.color1 const scaleColor = !this.isNight ? this.settings.lightScaleColor - : this.settings.darkScaleColor; - this.lineColor = scaleColor ? new Color(scaleColor) : this.lineColor; - }; + : this.settings.darkScaleColor + this.lineColor = scaleColor ? new Color(scaleColor) : this.lineColor + } setWidgetSkin = async () => { await this.setLightAndDark( '柱状颜色', false, 'lightSkinColor', - 'darkSkinColor', - ); - }; + 'darkSkinColor' + ) + } setWidgetScale = async () => { await this.setLightAndDark( '刻度颜色', false, 'lightScaleColor', - 'darkScaleColor', - ); - }; + 'darkScaleColor' + ) + } } - -// @组件代码结束 -if (config.runsFromHomeScreen || config.runsInApp) { - Runing(Widget, '', false); +let params = args.shortcutParameter +if (params) { + const fileICloud = FileManager.iCloud() + const path = fileICloud.documentsDirectory() + fileICloud.writeString(path + '/health.txt', JSON.stringify(params)) + Script.complete() } else { - let params = args.shortcutParameter; - if (params) { - const fileICloud = FileManager.iCloud(); - const path = fileICloud.documentsDirectory(); - fileICloud.writeString(path + '/health.txt', JSON.stringify(params)); - Script.complete(); - } + await Runing(Widget, '', false) } +// @组件代码结束 From 50a325c7c657ab12e884e0d12e5623feb0c017fb Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 9 Sep 2022 11:08:38 +0800 Subject: [PATCH 056/152] fix --- Scripts/CarWidget.js | 402 +++++++++++++++++++++---------------------- Scripts/DmYY.js | 1 + 2 files changed, 199 insertions(+), 204 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index 7d2d909..1a10f25 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -3,61 +3,61 @@ // icon-color: deep-gray; icon-glyph: car; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === 'undefined') require = importModule -const { DmYY, Runing } = require('./DmYY') +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { constructor(arg) { - super(arg) + super(arg); config.runsInApp && this.registerAction( '油价设置', () => { return this.setAlertInput('油价设置', '设置类型', { oilNumber: '89|92|95|98|0', - }) + }); }, { name: 'paperplane', color: '#722ed1' } - ) + ); config.runsInApp && this.registerAction( '依赖插件', () => { return this.setAlertInput('设置依赖插件', '汽车的依赖插件例如 Ftms', { filePath: '', - }) + }); }, { name: 'car', color: '#f5222d' } - ) + ); config.runsInApp && this.registerAction( '缩放比例', () => { return this.setAlertInput('设置缩放比例', '比例越大进度条越长', { scale: '比例默认值1', - }) + }); }, { name: 'plus.viewfinder', color: '#fa8c16' } - ) - - config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig) - this.cacheName = this.md5(`dataSouce_${this.en}`) - const filePath = this.settings.filePath || 'Ftms' - const carModule = require(`./${filePath}`) - const carService = new carModule(this) - this.scale = parseFloat(this.settings.scale) || 1 // 柱状图比例高度,值越大,柱状范围越广 - this.init = carService.init - this.name = carService.name - this.logo = carService.logo - this.viewColor = Color.dynamic(new Color('#d9d9d9'), new Color('#8c8c8c')) + ); + + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + this.cacheName = this.md5(`dataSouce_${this.en}`); + const filePath = this.settings.filePath || 'Ftms'; + const carModule = require(`./${filePath}`); + const carService = new carModule(this); + this.scale = parseFloat(this.settings.scale) || 1; // 柱状图比例高度,值越大,柱状范围越广 + this.init = carService.init; + this.name = carService.name; + this.logo = carService.logo; + this.viewColor = Color.dynamic(new Color('#d9d9d9'), new Color('#8c8c8c')); } - widgetHeight = 145 + widgetHeight = 145; serveInfo = { carNumber: '', - } + }; dataSource = { remoteInfo: { @@ -75,7 +75,7 @@ class Widget extends DmYY { safeText: '', oilPriceText: '', oilZDE: 0, - } + }; createProgressBar( soFar, @@ -84,266 +84,260 @@ class Widget extends DmYY { height = 40, showPercentage = false ) { - const context = new DrawContext() - context.size = new Size(width, height) - context.opaque = false - context.respectScreenScale = true + const context = new DrawContext(); + context.size = new Size(width, height); + context.opaque = false; + context.respectScreenScale = true; // bar background - context.setFillColor(new Color('#48484b')) - const bgPath = new Path() + context.setFillColor(new Color('#48484b')); + const bgPath = new Path(); bgPath.addRoundedRect( new Rect(0, 0, width, height), height / 2, height / 2 - 1 - ) - context.addPath(bgPath) - context.fillPath() + ); + context.addPath(bgPath); + context.fillPath(); // bar foreground - context.setFillColor(new Color('#e8e8e8')) - const fgPath = new Path() + context.setFillColor(new Color('#e8e8e8')); + const fgPath = new Path(); fgPath.addRoundedRect( new Rect(0, 0, (width * soFar) / total, height), height / 2, height / 2 - 1 - ) - context.addPath(fgPath) - context.fillPath() + ); + context.addPath(fgPath); + context.fillPath(); if (showPercentage) { - const percentage = ((soFar / total) * 100).toFixed(2) - let xPos = (width * soFar) / total + 5 + const percentage = ((soFar / total) * 100).toFixed(2); + let xPos = (width * soFar) / total + 5; // if over 70%, show in foreground area // to ensure that it doesn't overflow the display if (percentage > 70) { - xPos = (width * soFar) / total - 55 + xPos = (width * soFar) / total - 55; } - context.setFont(Font.semiboldRoundedSystemFont(14)) - context.setTextColor(primaryTextColor) - context.drawText(`${percentage}%`, new Point(xPos, height / 14)) + context.setFont(Font.semiboldRoundedSystemFont(14)); + context.setTextColor(primaryTextColor); + context.drawText(`${percentage}%`, new Point(xPos, height / 14)); } - return context.getImage() + return context.getImage(); } renderBorder = (stack) => { - stack.borderWidth = 1 - } + stack.borderWidth = 1; + }; renderImage = async (uri) => { - return this.$request.get(uri, 'IMG') - } + return this.$request.get(uri, 'IMG'); + }; notSupport(w) { - const stack = w.addStack() - stack.addText('暂不支持') - return w + const stack = w.addStack(); + stack.addText('暂不支持'); + return w; } renderSmall = async (w) => { - w.addSpacer() - - const stack = w.addStack() - stack.layoutVertically() - const headerStack = stack.addStack() - headerStack.centerAlignContent() - headerStack.addSpacer(10) - const gasImg = await this.renderImage( - this.isNight - ? 'https://raw.githubusercontent.com/dompling/Scriptable/master/images/gas-night.png' - : `https://img.icons8.com/ios-glyphs/344/gas-station.png` - ) - - const gasIcon = headerStack.addImage(gasImg) - gasIcon.imageSize = new Size(16, 16) - headerStack.addSpacer(5) + w.addSpacer(); + + const stack = w.addStack(); + stack.layoutVertically(); + const headerStack = stack.addStack(); + headerStack.centerAlignContent(); + headerStack.addSpacer(10); + const gasImg = SFSymbol.named('fuelpump').image; + + const gasIcon = headerStack.addImage(gasImg); + gasIcon.imageSize = new Size(16, 16); + gasIcon.tintColor = this.widgetColor; + headerStack.addSpacer(5); const oilRateStackText = headerStack.addText( `${this.dataSource.monitorInfo.oilRate}%` - ) - oilRateStackText.textColor = this.widgetColor - oilRateStackText.font = Font.boldSystemFont(14) - - headerStack.addSpacer() - const logImg = await this.renderImage(this.logo) - const logImgStack = headerStack.addImage(logImg) - logImgStack.imageSize = new Size(20, 20) - headerStack.addSpacer(10) - - const bodyStack = stack.addStack() - bodyStack.centerAlignContent() - bodyStack.addSpacer() + ); + oilRateStackText.textColor = this.widgetColor; + oilRateStackText.font = Font.boldSystemFont(14); + + headerStack.addSpacer(); + const logImg = await this.renderImage(this.logo); + const logImgStack = headerStack.addImage(logImg); + logImgStack.imageSize = new Size(20, 20); + headerStack.addSpacer(10); + + const bodyStack = stack.addStack(); + bodyStack.centerAlignContent(); + bodyStack.addSpacer(); const progressImg = this.createProgressBar( this.dataSource.monitorInfo.oilRate - ) - const progressBar = bodyStack.addImage(progressImg) - progressBar.imageSize = new Size(this.widgetHeight * this.scale, 28) - bodyStack.addSpacer() + ); + const progressBar = bodyStack.addImage(progressImg); + progressBar.imageSize = new Size(this.widgetHeight * this.scale, 28); + bodyStack.addSpacer(); - stack.addSpacer() + stack.addSpacer(); - const oilWasteStack = stack.addStack() - oilWasteStack.centerAlignContent() - oilWasteStack.addSpacer() + const oilWasteStack = stack.addStack(); + oilWasteStack.centerAlignContent(); + oilWasteStack.addSpacer(); const oilWasteStackText = oilWasteStack.addText( this.dataSource.monitorInfo.oilWasteText - ) - oilWasteStackText.textColor = this.widgetColor - oilWasteStackText.font = Font.boldSystemFont(10) - oilWasteStack.addSpacer(5) + ); + oilWasteStackText.textColor = this.widgetColor; + oilWasteStackText.font = Font.boldSystemFont(10); + oilWasteStack.addSpacer(5); const oilPriceStackText = oilWasteStack.addText( this.dataSource.oilPriceText - ) - oilPriceStackText.textColor = this.widgetColor - oilPriceStackText.font = Font.boldSystemFont(10) - oilWasteStack.addSpacer(2) - const oilStatus = this.dataSource.oilZDE > 0 + ); + oilPriceStackText.textColor = this.widgetColor; + oilPriceStackText.font = Font.boldSystemFont(10); + oilWasteStack.addSpacer(2); + const oilStatus = this.dataSource.oilZDE > 0; const oilZdeImage = SFSymbol.named( oilStatus ? 'arrow.up' : 'arrow.down' - ).image - - const oilZdeWidgetImg = oilWasteStack.addImage(oilZdeImage) - oilZdeWidgetImg.tintColor = new Color(oilStatus ? '#f5222d' : '#a0d911') - oilZdeWidgetImg.imageSize = new Size(10, 10) - - oilWasteStack.addSpacer() - - const kilometerStack = stack.addStack() - - kilometerStack.centerAlignContent() - kilometerStack.addSpacer() - const panoImg = await this.renderImage( - this.isNight - ? `https://raw.githubusercontent.com/dompling/Scriptable/master/images/count.png` - : `https://img.icons8.com/ios-glyphs/344/bar-chart.png` - ) - - const panoImgStack = kilometerStack.addStack() - panoImgStack.setPadding(5, 0, 0, 0) - const panoStack = panoImgStack.addImage(panoImg) - panoStack.imageSize = new Size(20, 20) - kilometerStack.addSpacer(5) - - const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km) - oilWasteText.font = Font.boldSystemFont(28) - oilWasteText.textColor = this.widgetColor - kilometerStack.addSpacer(5) - const unitStack = kilometerStack.addStack() - unitStack.setPadding(5, 0, 0, 0) - const oilWasteUnit = unitStack.addText('km') - oilWasteUnit.font = Font.boldSystemFont(14) - oilWasteUnit.textColor = this.widgetColor - kilometerStack.addSpacer() - - stack.addSpacer() - - const btBodyStack = stack.addStack() - btBodyStack.addSpacer() - const bottomStack = btBodyStack.addStack() - bottomStack.setPadding(10, 0, 10, 0) - bottomStack.centerAlignContent() - bottomStack.addSpacer() - bottomStack.cornerRadius = 15 - bottomStack.backgroundColor = this.viewColor - const dataTime = this.dataSource.remoteInfo.datatime - const countKmText = bottomStack.addText(`上传:${dataTime || '-'}`) - countKmText.textColor = this.widgetColor - countKmText.font = Font.boldSystemFont(12) - countKmText.centerAlignText() - bottomStack.addSpacer() - w.addSpacer() - return w - } + ).image; + + const oilZdeWidgetImg = oilWasteStack.addImage(oilZdeImage); + oilZdeWidgetImg.tintColor = new Color(oilStatus ? '#f5222d' : '#a0d911'); + oilZdeWidgetImg.imageSize = new Size(10, 10); + + oilWasteStack.addSpacer(); + + const kilometerStack = stack.addStack(); + + kilometerStack.centerAlignContent(); + kilometerStack.addSpacer(); + const panoImg = SFSymbol.named('speedometer').image; + + const panoImgStack = kilometerStack.addStack(); + panoImgStack.setPadding(5, 0, 0, 0); + const panoStack = panoImgStack.addImage(panoImg); + panoStack.tintColor = this.widgetColor; + panoStack.imageSize = new Size(20, 20); + kilometerStack.addSpacer(5); + + const oilWasteText = kilometerStack.addText(this.dataSource.monitorInfo.km); + oilWasteText.font = Font.boldSystemFont(28); + oilWasteText.textColor = this.widgetColor; + kilometerStack.addSpacer(5); + const unitStack = kilometerStack.addStack(); + unitStack.setPadding(5, 0, 0, 0); + const oilWasteUnit = unitStack.addText('km'); + oilWasteUnit.font = Font.boldSystemFont(14); + oilWasteUnit.textColor = this.widgetColor; + kilometerStack.addSpacer(); + + stack.addSpacer(); + + const btBodyStack = stack.addStack(); + btBodyStack.addSpacer(); + const bottomStack = btBodyStack.addStack(); + bottomStack.setPadding(10, 0, 10, 0); + bottomStack.centerAlignContent(); + bottomStack.addSpacer(); + bottomStack.cornerRadius = 15; + bottomStack.backgroundColor = this.viewColor; + const dataTime = this.dataSource.remoteInfo.datatime; + const countKmText = bottomStack.addText(`上传:${dataTime || '-'}`); + countKmText.textColor = this.widgetColor; + countKmText.font = Font.boldSystemFont(12); + countKmText.centerAlignText(); + bottomStack.addSpacer(); + w.addSpacer(); + return w; + }; renderLarge = async (w) => { - return this.renderSmall(w) - } + return this.renderSmall(w); + }; renderMedium = async (w) => { - const containerStack = w.addStack() - containerStack.centerAlignContent() - const carStack = containerStack.addStack() - carStack.addSpacer() - carStack.backgroundColor = this.viewColor + const containerStack = w.addStack(); + containerStack.centerAlignContent(); + const carStack = containerStack.addStack(); + carStack.addSpacer(); + carStack.backgroundColor = this.viewColor; - carStack.layoutVertically() + carStack.layoutVertically(); - carStack.centerAlignContent() - carStack.size = new Size(this.widgetHeight, this.widgetHeight) - carStack.cornerRadius = 20 - const carImg = await this.renderImage(this.serveInfo.picUrl) + carStack.centerAlignContent(); + carStack.size = new Size(this.widgetHeight, this.widgetHeight); + carStack.cornerRadius = 20; + const carImg = await this.renderImage(this.serveInfo.picUrl); - const carImgStack = carStack.addStack() - const carResStack = carImgStack.addImage(carImg) - carResStack.imageSize = new Size(137.5, 70) + const carImgStack = carStack.addStack(); + const carResStack = carImgStack.addImage(carImg); + carResStack.imageSize = new Size(137.5, 70); - carStack.addSpacer() + carStack.addSpacer(); - const carNumberStack = carStack.addStack() - carNumberStack.addSpacer() - carNumberStack.centerAlignContent() - const carNumberText = carNumberStack.addText(this.serveInfo.carNumber) - carNumberText.font = Font.boldSystemFont(24) - carNumberText.textColor = this.widgetColor - carNumberText.centerAlignText() - carNumberStack.addSpacer() + const carNumberStack = carStack.addStack(); + carNumberStack.addSpacer(); + carNumberStack.centerAlignContent(); + const carNumberText = carNumberStack.addText(this.serveInfo.carNumber); + carNumberText.font = Font.boldSystemFont(24); + carNumberText.textColor = this.widgetColor; + carNumberText.centerAlignText(); + carNumberStack.addSpacer(); - carStack.addSpacer() + carStack.addSpacer(); - const carSafeStack = carStack.addStack() - carSafeStack.addSpacer() - carSafeStack.centerAlignContent() + const carSafeStack = carStack.addStack(); + carSafeStack.addSpacer(); + carSafeStack.centerAlignContent(); - let safeIconImg + let safeIconImg; if (this.dataSource.safeText) { - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image) + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock.open').image); } else { - safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image) + safeIconImg = carSafeStack.addImage(SFSymbol.named('lock').image); } - carSafeStack.addSpacer(5) + carSafeStack.addSpacer(5); const statusText = carSafeStack.addText( this.dataSource.safeText || '已上锁' - ) - statusText.centerAlignText() - statusText.font = Font.systemFont(12) + ); + statusText.centerAlignText(); + statusText.font = Font.systemFont(12); statusText.textColor = this.dataSource.safeText ? new Color('#f5222d') - : this.widgetColor + : this.widgetColor; - safeIconImg.tintColor = statusText.textColor - safeIconImg.imageSize = new Size(10, 14) + safeIconImg.tintColor = statusText.textColor; + safeIconImg.imageSize = new Size(10, 14); - carSafeStack.addSpacer() + carSafeStack.addSpacer(); - carStack.addSpacer() + carStack.addSpacer(); - containerStack.addSpacer() - const rightStack = containerStack.addStack() - rightStack.layoutVertically() - await this.renderSmall(rightStack) + containerStack.addSpacer(); + const rightStack = containerStack.addStack(); + rightStack.layoutVertically(); + await this.renderSmall(rightStack); - return w - } + return w; + }; /** * 渲染函数,函数名固定 * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 */ async render() { - await this.init() - const widget = new ListWidget() - widget.setPadding(10, 10, 10, 10) - await this.getWidgetBackgroundImage(widget) + await this.init(); + const widget = new ListWidget(); + widget.setPadding(10, 10, 10, 10); + await this.getWidgetBackgroundImage(widget); if (this.widgetFamily === 'medium') { - return await this.renderMedium(widget) + return await this.renderMedium(widget); } else { - return await this.notSupport(widget) + return await this.notSupport(widget); } } } // @组件代码结束 -await Runing(Widget, '', false) //远程开发环境 +await Runing(Widget, '', false); //远程开发环境 diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 3173248..b014415 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -846,6 +846,7 @@ class DmYY { ) this.settings = this.getSettings() + console.log(this.settings) this.settings.lightColor = this.settings.lightColor || '#000000' this.settings.darkColor = this.settings.darkColor || '#ffffff' this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff' From a15f73c81259568fb9972ec993bfde2c9b28a478 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 9 Sep 2022 11:18:18 +0800 Subject: [PATCH 057/152] fix --- Scripts/CarWidget.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index 1a10f25..693e6f5 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -50,7 +50,10 @@ class Widget extends DmYY { this.init = carService.init; this.name = carService.name; this.logo = carService.logo; - this.viewColor = Color.dynamic(new Color('#d9d9d9'), new Color('#8c8c8c')); + this.viewColor = Color.dynamic( + new Color('#d9d9d9', parseFloat(this.settings.lightOpacity || 1)), + new Color('#8c8c8c', parseFloat(this.settings.darkOpacity || 1)) + ); } widgetHeight = 145; From be78ec2c9ca32df6a6815863edfd5672e8caf994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=84=91=E7=93=9C?= <76637082+anker1209@users.noreply.github.com> Date: Mon, 26 Sep 2022 16:14:55 +0800 Subject: [PATCH 058/152] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=9B=BE=E6=A0=87=E6=97=A0=E6=B3=95=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index b014415..d38a927 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -1420,21 +1420,21 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { } const preview = [ { - url: 'https://z3.ax1x.com/2021/03/26/6v5wIP.png', + url: 'https://pic1.imgdb.cn/item/63315c3616f2c2beb1a2931a.png', title: '小尺寸', val: 'small', dismissOnSelect: true, onClick, }, { - url: 'https://z3.ax1x.com/2021/03/26/6v5dat.png', + url: 'https://pic1.imgdb.cn/item/63315c2c16f2c2beb1a28706.png', title: '中尺寸', val: 'medium', dismissOnSelect: true, onClick, }, { - url: 'https://z3.ax1x.com/2021/03/26/6v5BPf.png', + url: 'https://pic1.imgdb.cn/item/63315c2716f2c2beb1a27f24.png', title: '大尺寸', val: 'large', dismissOnSelect: true, From 09843f3b111c527480d7536db263440ade4cf352 Mon Sep 17 00:00:00 2001 From: ShellManager <374779789@qq.com> Date: Fri, 14 Oct 2022 09:53:49 +0800 Subject: [PATCH 059/152] fix --- Scripts/Ftms.js | 141 +++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 66 deletions(-) diff --git a/Scripts/Ftms.js b/Scripts/Ftms.js index 4d6faf4..59acc51 100644 --- a/Scripts/Ftms.js +++ b/Scripts/Ftms.js @@ -1,11 +1,11 @@ class Ftms { constructor(carWidget) { - this.$ = carWidget + this.$ = carWidget; } - name = '一汽丰田' - en = 'ftms' - logo = 'https://www.toyota.com.cn/favicon.ico' + name = '一汽丰田'; + en = 'ftms'; + logo = 'https://www.toyota.com.cn/favicon.ico'; baseOpt = { headers: { @@ -14,124 +14,133 @@ class Ftms { 'Content-Type': `application/json`, }, body: ``, - } + }; init = async () => { if (this.$.settings.dataSource) { - this.$.serveInfo = this.$.settings.serveInfo - this.$.dataSource = this.$.settings.dataSource + this.$.serveInfo = this.$.settings.serveInfo; + this.$.dataSource = this.$.settings.dataSource; } else { - await this.cacheData() + await this.cacheData(); } - this.cacheData() - } + this.cacheData(); + }; cacheData = async () => { try { - await this.getOilPrice() - await this.getBmuServeHicleInfo() - await this.getRemoteInfoDetail() + await this.getOilPrice(); + await this.getBmuServeHicleInfo(); + await this.getRemoteInfoDetail(); } catch (e) { - console.log(e) + console.log(e); } - } + }; getBaseOptions(api) { - const baseURL = `https://appiov.ftms.com.cn` - return { url: `${baseURL}/${api}`, ...this.baseOpt } + const baseURL = `https://appiov.ftms.com.cn`; + console.log({ url: `${baseURL}/${api}`, ...this.baseOpt }); + return { url: `${baseURL}/${api}`, ...this.baseOpt }; } getRemoteInfoDetail = async () => { const options = this.getBaseOptions( 'ftms-iov-app-gbook/api/gbook/getRemoteInfoDetail' - ) - const response = await this.$.$request.post(options) + ); + const response = await this.$.$request.post(options); if (response.msg === 'success') { - this.$.dataSource.remoteInfo = response.result + this.$.dataSource.remoteInfo = response.result; const safeData = - response.result.list.filter((item) => item.security !== 'safe') || [] + response.result.list.filter((item) => item.security !== 'safe') || []; if (safeData.length > 0) { - this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}` + this.$.dataSource.safeText = `${safeData[0].typeName}:${safeData[0].dataName}`; } else { - this.$.dataSource.safeText = `` + this.$.dataSource.safeText = ``; } - const dataTime = this.$.dataSource.remoteInfo.datatime.split('-') + const dataTime = this.$.dataSource.remoteInfo.datatime.split('-'); this.$.dataSource.remoteInfo.datatime = `${dataTime[1] || ''}-${ dataTime[2] || '' - }` + }`; } else { - this.$.notify(this.name, response.msg) + this.$.notify(this.name, response.msg); } - await this.getDrivingMonitorInfo() - } + await this.getDrivingMonitorInfo(); + }; getDrivingMonitorInfo = async () => { const options = this.getBaseOptions( 'ftms-iov-app-gbook/api/gbook/getDrivingMonitorInfo' - ) - const response = await this.$.$request.post(options) - console.log(response) + ); + const response = await this.$.$request.post(options); + console.log(response); if (response.msg === 'success') { - this.$.dataSource.monitorInfo = response.result + this.$.dataSource.monitorInfo = response.result; } - this.$.dataSource.monitorInfo.oilWasteText = `油耗:${this.$.dataSource.monitorInfo.oilWaste}L/100km` - this.$.settings.dataSource = this.$.dataSource - this.$.saveSettings(false) - } + this.$.dataSource.monitorInfo.oilWasteText = `油耗:${this.$.dataSource.monitorInfo.oilWaste}L/100km`; + this.$.settings.dataSource = this.$.dataSource; + this.$.saveSettings(false); + }; getBmuServeHicleInfo = async () => { - let headers = await this.$.getCache('@ftms.headers') - headers = JSON.parse(headers || '{}') - this.baseOpt.headers = { token: headers.token, ...this.baseOpt.headers } + let headers = await this.$.getCache('@ftms.headers'); + headers = JSON.parse(headers || '{}'); + this.baseOpt.headers = { + token: headers.token, + 'User-Agent': headers['User-Agent'], + ...this.baseOpt.headers, + }; const options = { url: `https://superapp.ftms.com.cn/superapp/users/wt/getbmuservehicleinfo?scriptable=1`, headers, - } + }; if (!this.$.settings.serveInfo) { - const response = await this.$.$request.post(options) - console.log(response) + const response = await this.$.$request.post(options); + console.log(response); if (response.code === '200') { - this.$.settings.serveInfo = response.data - this.$.serveInfo = response.data - this.$.saveSettings(false) + this.$.settings.serveInfo = response.data; + this.$.serveInfo = response.data; + this.$.saveSettings(false); } else { - this.$.notify(this.name, response.msg) + this.$.notify(this.name, response.msg); } } else { - this.$.serveInfo = this.$.settings.serveInfo || {} + this.$.serveInfo = this.$.settings.serveInfo || {}; } - this.baseOpt.headers.userId = this.$.serveInfo.userId - this.baseOpt.body = JSON.stringify({ vin: this.$.serveInfo.vin }) - this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}` - } + + this.baseOpt.headers.userId = this.$.serveInfo.userId; + this.baseOpt.headers['USER-ID'] = this.$.serveInfo.userId; + this.baseOpt.body = JSON.stringify({ vin: this.$.serveInfo.vin }); + this.baseOpt.headers.Authorization = `Bearer ${this.baseOpt.headers.token}`; + this.baseOpt.headers.accessToken = this.baseOpt.headers.token; + this.baseOpt.headers['ACCESS-TOKEN'] = this.baseOpt.headers.token; + }; getOilPrice = async () => { - const location = await Location.current() + const location = await Location.current(); const locationText = await Location.reverseGeocode( location.latitude, location.longitude - ) - const { administrativeArea = '' } = locationText[0] || {} + ); + const { administrativeArea = '' } = locationText[0] || {}; - const oilNumber = `${this.$.settings.oilNumber || '92'}` + const oilNumber = `${this.$.settings.oilNumber || '92'}`; - const filter = `(CITYNAME="${administrativeArea.replace('省', '')}")` - const time = Date.now() + const filter = `(CITYNAME="${administrativeArea.replace('省', '')}")`; + const time = Date.now(); const url = `https://datacenter-web.eastmoney.com/api/data/v1/get?reportName=RPTA_WEB_YJ_JH&columns=ALL&filter=${encodeURIComponent( filter - )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=1&source=WEB&_=${time}` + )}&sortColumns=DIM_DATE&sortTypes=-1&pageNumber=1&pageSize=1&source=WEB&_=${time}`; - const options = { url } - const response = await this.$.$request.post(options) - console.log(response) + const options = { url }; + const response = await this.$.$request.post(options); + console.log(response); if (response.result) { - this.$.dataSource.oilPrice = response.result.data[0] - this.$.dataSource.oilZDE = response.result.data[0][`ZDE${oilNumber}`] + this.$.dataSource.oilPrice = response.result.data[0]; + this.$.dataSource.oilZDE = response.result.data[0][`ZDE${oilNumber}`]; this.$.dataSource.oilPriceText = `油价:${ response.result.data[0][`V${oilNumber}`] - }` + }`; } - } + }; } -module.exports = Ftms +module.exports = Ftms; From c25c3e55812b1ca27ee4227bdee2c1626c13ccd1 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Fri, 28 Oct 2022 11:31:21 +0800 Subject: [PATCH 060/152] =?UTF-8?q?add=EF=BC=9A=E4=BA=A4=E7=AE=A1=2012123,?= =?UTF-8?q?=E5=BE=85=E5=AE=8C=E5=96=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 164 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 Scripts/12123.js diff --git a/Scripts/12123.js b/Scripts/12123.js new file mode 100644 index 0000000..3d60490 --- /dev/null +++ b/Scripts/12123.js @@ -0,0 +1,164 @@ +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: deep-gray; icon-glyph: car; + +// 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 +if (typeof require === 'undefined') require = importModule; +const {DmYY, Runing} = require('./DmYY'); + +// @组件代码开始 +class Widget extends DmYY { + constructor(arg) { + super(arg); + this.en = '12123'; + this.name = '交管 12123'; + config.runsInApp && this.registerAction('Token', async () => { + const token = this.settings.token; + this.settings.token = await this.getCache('token_12123') || token; + if (this.settings.token) this.saveSettings(false); + return this.setAlertInput('Token', '设置 token', { + token: '获取Token作者: @FoKit', + }); + }, {name: 'paperplane', color: '#722ed1'}); + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + } + + dataSource = { + left: { + title: '川 G88888', icon: 'car.fill', listItem: [ + {label: '未处违法', value: `0`, unit: '条'}, + {label: '车辆状态', value: '正常'}, + {label: '上次更新', value: '10:40'}, + ], + }, right: { + title: '驾驶证', icon: 'creditcard.fill', listItem: [ + {label: '累计积分', value: `0`, unit: '分'}, + {label: '证件状态', value: '正常'}, + ], + }, + }; + + init = async () => { + if (this.settings.dataSource) { + this.dataSource = this.settings.dataSource; + } else { + await this.cacheData(); + } + this.cacheData(); + }; + + cacheData = async () => { + try { + const response = await this.$request.post( + `https://miniappcsfw.122.gov.cn:8443/openapi/invokeApi/business/biz`, { + body: `params=${JSON.stringify({ + productId: 'p10000000000000000001', + api: 'biz.vio.unhandledVioCount.query"', + verifyToken: this.settings.token, + })}`, + }); + console.log(response); + } catch (e) { + console.log(e); + } + }; + + renderImage = async (uri) => { + return this.$request.get(uri, 'IMG'); + }; + + notSupport(w) { + const stack = w.addStack(); + stack.addText('暂不支持'); + return w; + } + + renderSmall = async (w) => { + this.notSupport(w); + return w; + }; + + renderLarge = async (w) => { + return this.notSupport(w); + }; + + renderCard = (w, data) => { + w.borderColor = this.widgetColor; + w.borderWidth = 2; + w.cornerRadius = 8; + + w.layoutVertically(); + w.setPadding(10, 10, 10, 10); + const topStack = w.addStack(); + topStack.layoutHorizontally(); + topStack.centerAlignContent(); + const iconImage = SFSymbol.named(data.icon).image; + const iconImageStack = topStack.addImage(iconImage); + iconImageStack.tintColor = this.widgetColor; + iconImageStack.imageSize = new Size(30, 30); + + topStack.addSpacer(10); + + const licensePlateText = topStack.addText(data.title); + licensePlateText.textColor = this.widgetColor; + licensePlateText.font = this.provideFont('bold', 14); + + w.addSpacer(); + data.listItem.forEach((item, index) => { + const listItemStack = w.addStack(); + listItemStack.centerAlignContent(); + const labelText = listItemStack.addText(item.label); + labelText.textColor = this.widgetColor; + labelText.font = this.provideFont('medium', 14); + + listItemStack.addSpacer(); + if (index !== data.listItem.length - 1) w.addSpacer(); + + const valueText = listItemStack.addText(item.value); + valueText.textColor = this.widgetColor; + valueText.font = this.provideFont('medium', 14); + + if (item.unit) { + const unitText = listItemStack.addText(item.unit); + unitText.textColor = this.widgetColor; + unitText.font = this.provideFont('medium', 14); + } + + }); + }; + + renderMedium = async (w) => { + const containerStack = w.addStack(); + containerStack.layoutHorizontally(); + containerStack.centerAlignContent(); + + const leftStack = containerStack.addStack(); + this.renderCard(leftStack, this.dataSource.left); + + containerStack.addSpacer(10); + + const rightStack = containerStack.addStack(); + this.renderCard(rightStack, this.dataSource.right); + return w; + }; + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + return await this.renderMedium(widget); + } else if (this.widgetFamily === 'large') { + return await this.renderLarge(widget); + } else { + return await this.renderSmall(widget); + } + } +} + +// @组件代码结束 +await Runing(Widget, '', false); //远程开发环境 From bff8877779c8ba96a3f05fd48aba216ef7b7592a Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 7 Nov 2022 15:52:20 +0800 Subject: [PATCH 061/152] =?UTF-8?q?12123=E6=B5=8B=E8=AF=95=E5=B0=8F?= =?UTF-8?q?=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 114 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 28 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index 3d60490..34ebb1d 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -4,7 +4,21 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +const { DmYY, Runing } = require('./DmYY'); + +const API_PARAMS = { + api4: 'biz.vio.detail.query', + infoURL: 'https://miniappcsfw.122.gov.cn:8443/openapi/invokeApi/business/biz', + api1: 'biz.vio.unhandledVioCount.query', + productId: 'p10000000000000000001', + alipay: 'alipays://platformapi/startapp?appId=2019050964403523', + api2: 'biz.vio.peccancyChannelList.query', + status: + 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', + update: 'https://gitcode.net/4qiao/scriptable/raw/master/api/violation.js', + api3: 'biz.vio.peccancyUnhandleInfoList.query', + Ver: 'Version 1.2\n\nverifyToken过期需打开Quantumult-X', +}; // @组件代码开始 class Widget extends DmYY { @@ -12,28 +26,60 @@ class Widget extends DmYY { super(arg); this.en = '12123'; this.name = '交管 12123'; - config.runsInApp && this.registerAction('Token', async () => { - const token = this.settings.token; - this.settings.token = await this.getCache('token_12123') || token; - if (this.settings.token) this.saveSettings(false); - return this.setAlertInput('Token', '设置 token', { - token: '获取Token作者: @FoKit', - }); - }, {name: 'paperplane', color: '#722ed1'}); + config.runsInApp && + this.registerAction( + '车牌号', + async () => { + return this.setAlertInput('车牌号设置', '设置车牌', { + carNumber: '川 G88888', + }); + }, + { name: 'car', color: '#2d84ef' } + ); + config.runsInApp && + this.registerAction( + 'Token', + async () => { + const token = this.settings.token; + this.settings.token = (await this.getCache('token_12123')) || token; + if (this.settings.token) this.saveSettings(false); + return this.setAlertInput('Token', '设置 token', { + token: '获取Token作者: @FoKit', + }); + }, + { name: 'paperplane', color: '#722ed1' } + ); config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); } + format = (str) => { + return parseInt(str) >= 10 ? str : `0${str}`; + }; + + date = new Date(); + arrUpdateTime = [ + this.format(this.date.getMonth() + 1), + this.format(this.date.getDate()), + this.format(this.date.getHours()), + this.format(this.date.getMinutes()), + ]; + dataSource = { left: { - title: '川 G88888', icon: 'car.fill', listItem: [ - {label: '未处违法', value: `0`, unit: '条'}, - {label: '车辆状态', value: '正常'}, - {label: '上次更新', value: '10:40'}, + title: '川 G88888', + icon: 'car.fill', + listItem: [ + { label: '未处违法', value: `0`, unit: '条' }, + { label: '车辆状态', value: '正常' }, + { label: '上次更新', value: '00:00' }, ], - }, right: { - title: '驾驶证', icon: 'creditcard.fill', listItem: [ - {label: '累计积分', value: `0`, unit: '分'}, - {label: '证件状态', value: '正常'}, + }, + right: { + title: '驾驶证', + icon: 'creditcard.fill', + listItem: [ + { label: '累计积分', value: `0`, unit: '分' }, + { label: '证件状态', value: '正常' }, ], }, }; @@ -49,15 +95,27 @@ class Widget extends DmYY { cacheData = async () => { try { - const response = await this.$request.post( - `https://miniappcsfw.122.gov.cn:8443/openapi/invokeApi/business/biz`, { - body: `params=${JSON.stringify({ - productId: 'p10000000000000000001', - api: 'biz.vio.unhandledVioCount.query"', - verifyToken: this.settings.token, - })}`, - }); - console.log(response); + const response = await this.$request.post(API_PARAMS.infoURL, { + body: `params=${encodeURIComponent( + `{"productId": "${API_PARAMS.productId}","api": "${API_PARAMS.api1}","verifyToken": "${this.settings.token}"}` + )}`, + }); + + if (response.success) { + const illegal = response.data.list[0] || {}; + this.dataSource.left.listItem[0].value = illegal.count || 0; + const integral = response.data.list[1] || {}; + this.dataSource.right.listItem[0].value = integral.count || 0; + this.dataSource.left.listItem[2].value = `${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`; + this.settings.dataSource = this.dataSource; + this.saveSettings(false); + } else { + this.notify( + `verifyToken已过期 ⚠️`, + '点击通知框自动跳转到支付宝12123小程序页面获取最新的Token ( 请确保已打开辅助工具 )', + 'alipays://platformapi/startapp?appId=2019050964403523' + ); + } } catch (e) { console.log(e); } @@ -114,7 +172,7 @@ class Widget extends DmYY { listItemStack.addSpacer(); if (index !== data.listItem.length - 1) w.addSpacer(); - const valueText = listItemStack.addText(item.value); + const valueText = listItemStack.addText(`${item.value}`); valueText.textColor = this.widgetColor; valueText.font = this.provideFont('medium', 14); @@ -123,7 +181,6 @@ class Widget extends DmYY { unitText.textColor = this.widgetColor; unitText.font = this.provideFont('medium', 14); } - }); }; @@ -148,6 +205,7 @@ class Widget extends DmYY { */ async render() { await this.init(); + this.dataSource.left.title = this.settings.carNumber; const widget = new ListWidget(); await this.getWidgetBackgroundImage(widget); if (this.widgetFamily === 'medium') { From 61c24bd0ac9d444af9716a1dee43f559c679b9e8 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 7 Nov 2022 15:56:09 +0800 Subject: [PATCH 062/152] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=2012123=20=E5=B0=8F?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=BE=85=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/install.json b/install.json index cacdf21..b496e45 100644 --- a/install.json +++ b/install.json @@ -426,6 +426,20 @@ "

  • 调整大尺寸排列效果
  • ", "
  • 调整下班倒计时默认不开启
  • " ] + }, + { + "version": "1.0.0", + "description": "交管 12123 违章和扣分查询", + "scriptURL": "https://raw.githubusercontent.com/dompling/scriptableTsx/master/scripts/12123.js", + "thumb": "https://is5-ssl.mzstatic.com/image/thumb/Purple112/v4/a7/a1/61/a7a16170-e644-079e-a362-9eb273becf9d/AppIcon-1x_U007emarketing-0-4-0-0-85-220.png/492x0w.webp", + "name": "12123", + "title": "交管 12123", + "html": [ + "

    Token获取说明

    ", + "
  • 获取Token重写:https://raw.githubusercontent.com/FoKit/Scripts/main/rewrite/get_12123_token.sgmodule
  • ", + "
  • 使用方法:配置重写规则,手动运行小组件,按提示跳转到 支付宝12123小程序 登录即可自动抓取/更新Token。
  • ", + "
  • 使用前,请确保您的代理APP已配置好BoxJs重写,BoxJs配置方法:https://chavyleung.gitbook.io/boxjs/
  • " + ] } ] } From df5a4f9a140758142e2919b958c8293b2f4a927e Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 7 Nov 2022 16:01:04 +0800 Subject: [PATCH 063/152] fix --- install.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.json b/install.json index b496e45..e85b6a5 100644 --- a/install.json +++ b/install.json @@ -430,7 +430,7 @@ { "version": "1.0.0", "description": "交管 12123 违章和扣分查询", - "scriptURL": "https://raw.githubusercontent.com/dompling/scriptableTsx/master/scripts/12123.js", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/scripts/12123.js", "thumb": "https://is5-ssl.mzstatic.com/image/thumb/Purple112/v4/a7/a1/61/a7a16170-e644-079e-a362-9eb273becf9d/AppIcon-1x_U007emarketing-0-4-0-0-85-220.png/492x0w.webp", "name": "12123", "title": "交管 12123", From a603b0ed78cadeaf85d11e944b495cdfd9ca7676 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 7 Nov 2022 16:03:12 +0800 Subject: [PATCH 064/152] =?UTF-8?q?update:=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- install.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/install.json b/install.json index e85b6a5..4458145 100644 --- a/install.json +++ b/install.json @@ -436,9 +436,9 @@ "title": "交管 12123", "html": [ "

    Token获取说明

    ", - "
  • 获取Token重写:https://raw.githubusercontent.com/FoKit/Scripts/main/rewrite/get_12123_token.sgmodule
  • ", + "
    ", "
  • 使用方法:配置重写规则,手动运行小组件,按提示跳转到 支付宝12123小程序 登录即可自动抓取/更新Token。
  • ", - "
  • 使用前,请确保您的代理APP已配置好BoxJs重写,BoxJs配置方法:https://chavyleung.gitbook.io/boxjs/
  • " + "
  • 使用前,请确保您的代理APP已配置好BoxJs重写,BoxJs配置方法:BoxJS教程
  • " ] } ] From d468ccf3e645a3469174d244c73bde5334934966 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 7 Nov 2022 16:04:59 +0800 Subject: [PATCH 065/152] fix:download url --- install.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.json b/install.json index 4458145..0843d56 100644 --- a/install.json +++ b/install.json @@ -430,7 +430,7 @@ { "version": "1.0.0", "description": "交管 12123 违章和扣分查询", - "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/scripts/12123.js", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/12123.js", "thumb": "https://is5-ssl.mzstatic.com/image/thumb/Purple112/v4/a7/a1/61/a7a16170-e644-079e-a362-9eb273becf9d/AppIcon-1x_U007emarketing-0-4-0-0-85-220.png/492x0w.webp", "name": "12123", "title": "交管 12123", From d42ef4e7f1c650b3432d7937d037b471fa405013 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Tue, 8 Nov 2022 13:31:55 +0800 Subject: [PATCH 066/152] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 81 ++-- Scripts/DmYY.js | 979 ++++++++++++++++++++++++----------------------- 2 files changed, 552 insertions(+), 508 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index 34ebb1d..8512f2c 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -8,43 +8,43 @@ const { DmYY, Runing } = require('./DmYY'); const API_PARAMS = { api4: 'biz.vio.detail.query', - infoURL: 'https://miniappcsfw.122.gov.cn:8443/openapi/invokeApi/business/biz', + infoURL: 'https://miniappwx.122.gov.cn:8553/openapi/invokeApi/business/biz', api1: 'biz.vio.unhandledVioCount.query', productId: 'p10000000000000000001', - alipay: 'alipays://platformapi/startapp?appId=2019050964403523', api2: 'biz.vio.peccancyChannelList.query', - status: - 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', - update: 'https://gitcode.net/4qiao/scriptable/raw/master/api/violation.js', api3: 'biz.vio.peccancyUnhandleInfoList.query', - Ver: 'Version 1.2\n\nverifyToken过期需打开Quantumult-X', }; // @组件代码开始 class Widget extends DmYY { constructor(arg) { - super(arg); + super(arg, { + lightBgColor: '#2581f2', + darkBgColor: '#2581f2', + darkColor: '#fff', + lightColor: '#fff', + }); this.en = '12123'; this.name = '交管 12123'; config.runsInApp && this.registerAction( - '车牌号', + '微信小程序 ID', async () => { - return this.setAlertInput('车牌号设置', '设置车牌', { - carNumber: '川 G88888', + return this.setAlertInput('小程序 ID', '设置小程序跳转 ID', { + wxmini: '微信小程序交管12123跳转 ID', }); }, - { name: 'car', color: '#2d84ef' } + { name: 'chat', color: '#722ed1' } ); config.runsInApp && this.registerAction( 'Token', async () => { const token = this.settings.token; - this.settings.token = (await this.getCache('token_12123')) || token; + this.settings.token = (await this.getCache('wx_12123')) || token; if (this.settings.token) this.saveSettings(false); return this.setAlertInput('Token', '设置 token', { - token: '获取Token作者: @FoKit', + token: '微信小程序交管12123获取', }); }, { name: 'paperplane', color: '#722ed1' } @@ -78,8 +78,9 @@ class Widget extends DmYY { title: '驾驶证', icon: 'creditcard.fill', listItem: [ - { label: '累计积分', value: `0`, unit: '分' }, { label: '证件状态', value: '正常' }, + { label: '累计积分', value: `0`, unit: '分' }, + { label: '重置日期', value: '—' }, ], }, }; @@ -95,25 +96,61 @@ class Widget extends DmYY { cacheData = async () => { try { + const token = this.settings.token.replace('params=', ''); + const body = JSON.parse(decodeURIComponent(token)); + const params = { + sign: body.sign, + businessId: body.businessId, + verifyToken: body.verifyToken, + businessPrincipalId: body.businessPrincipalId, + }; + const response = await this.$request.post(API_PARAMS.infoURL, { - body: `params=${encodeURIComponent( - `{"productId": "${API_PARAMS.productId}","api": "${API_PARAMS.api1}","verifyToken": "${this.settings.token}"}` - )}`, + body: `params=${JSON.stringify({ + api: API_PARAMS.api1, + productId: API_PARAMS.productId, + ...params, + })}`, }); if (response.success) { const illegal = response.data.list[0] || {}; this.dataSource.left.listItem[0].value = illegal.count || 0; - const integral = response.data.list[1] || {}; - this.dataSource.right.listItem[0].value = integral.count || 0; + + const details = await this.$request.post(API_PARAMS.infoURL, { + body: `params=${encodeURIComponent( + JSON.stringify({ + api: 'biz.user.integration.query', + productId: API_PARAMS.productId, + ...params, + }) + )}`, + }); + + if (details.success) { + const { drivingLicense, vehicles } = details.data; + const reaccDate = drivingLicense.reaccDate.split('-'); + this.dataSource.right.title = `驾驶证 ${drivingLicense.allowToDrive}`; + this.dataSource.right.listItem[1].value = + drivingLicense.cumulativePoint; + this.dataSource.right.listItem[2].value = `${reaccDate[1]}-${reaccDate[2]}`; + + if (vehicles.length) { + this.dataSource.left.title = vehicles[0].plateNumber; + } + } + this.dataSource.left.listItem[2].value = `${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`; + console.log(this.dataSource); this.settings.dataSource = this.dataSource; this.saveSettings(false); } else { this.notify( `verifyToken已过期 ⚠️`, - '点击通知框自动跳转到支付宝12123小程序页面获取最新的Token ( 请确保已打开辅助工具 )', - 'alipays://platformapi/startapp?appId=2019050964403523' + '点击通知框自动跳转到微信小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', + this.settings.wxmini + ? `weixin://dl/business/?t=${this.settings.wxmini}` + : '' ); } } catch (e) { @@ -162,6 +199,7 @@ class Widget extends DmYY { licensePlateText.font = this.provideFont('bold', 14); w.addSpacer(); + data.listItem.forEach((item, index) => { const listItemStack = w.addStack(); listItemStack.centerAlignContent(); @@ -205,7 +243,6 @@ class Widget extends DmYY { */ async render() { await this.init(); - this.dataSource.left.title = this.settings.carNumber; const widget = new ListWidget(); await this.getWidgetBackgroundImage(widget); if (this.widgetFamily === 'medium') { diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index d38a927..062064e 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -8,167 +8,168 @@ */ class DmYY { - constructor(arg) { - this.arg = arg + constructor(arg, defaultSettings) { + this.arg = arg; + this.defaultSettings = defaultSettings || {}; try { - this.init() + this.init(); } catch (error) { - console.log(error) + console.log(error); } - this.isNight = Device.isUsingDarkAppearance() + this.isNight = Device.isUsingDarkAppearance(); } - _actions = {} - BACKGROUND_NIGHT_KEY - widgetColor - backGroundColor - useBoxJS = true - isNight - _actionsIcon = {} + _actions = {}; + BACKGROUND_NIGHT_KEY; + widgetColor; + backGroundColor; + useBoxJS = true; + isNight; + _actionsIcon = {}; // 获取 Request 对象 getRequest = (url = '') => { - return new Request(url) - } + return new Request(url); + }; // 发起请求 http = async (options = { headers: {}, url: '' }, type = 'JSON') => { - let request + let request; try { if (type === 'IMG') { - const fileName = `${this.cacheImage}/${this.md5(options.url)}` - console.log(fileName) - request = this.getRequest(options.url) - let response + const fileName = `${this.cacheImage}/${this.md5(options.url)}`; + console.log(fileName); + request = this.getRequest(options.url); + let response; if (this.FILE_MGR.fileExists(fileName)) { request.loadImage().then((res) => { - console.log(res) - this.FILE_MGR.writeImage(fileName, res) - }) - return Image.fromFile(fileName) + console.log(res); + this.FILE_MGR.writeImage(fileName, res); + }); + return Image.fromFile(fileName); } else { - response = await request.loadImage() - this.FILE_MGR.writeImage(fileName, response) + response = await request.loadImage(); + this.FILE_MGR.writeImage(fileName, response); } - return response + return response; } - request = this.getRequest() + request = this.getRequest(); Object.keys(options).forEach((key) => { - request[key] = options[key] - }) - request.headers = { ...this.defaultHeaders, ...options.headers } + request[key] = options[key]; + }); + request.headers = { ...this.defaultHeaders, ...options.headers }; if (type === 'JSON') { - return await request.loadJSON() + return await request.loadJSON(); } if (type === 'STRING') { - return await request.loadString() + return await request.loadString(); } - return await request.loadJSON() + return await request.loadJSON(); } catch (e) { - console.log('error:' + e) - if (type === 'IMG') return SFSymbol.named('photo').image + console.log('error:' + e); + if (type === 'IMG') return SFSymbol.named('photo').image; } - } + }; //request 接口请求 $request = { get: async (url = '', options = {}, type = 'JSON') => { - let params = { ...options, method: 'GET' } + let params = { ...options, method: 'GET' }; if (typeof url === 'object') { - params = { ...params, ...url } + params = { ...params, ...url }; } else { - params.url = url + params.url = url; } - let _type = type - if (typeof options === 'string') _type = options - return await this.http(params, _type) + let _type = type; + if (typeof options === 'string') _type = options; + return await this.http(params, _type); }, post: async (url = '', options = {}, type = 'JSON') => { - let params = { ...options, method: 'POST' } + let params = { ...options, method: 'POST' }; if (typeof url === 'object') { - params = { ...params, ...url } + params = { ...params, ...url }; } else { - params.url = url + params.url = url; } - let _type = type - if (typeof options === 'string') _type = options - return await this.http(params, _type) + let _type = type; + if (typeof options === 'string') _type = options; + return await this.http(params, _type); }, - } + }; // 获取 boxJS 缓存 getCache = async (key = '', notify = true) => { try { - let url = 'http://' + this.prefix + '/query/boxdata' - if (key) url = 'http://' + this.prefix + '/query/data/' + key + let url = 'http://' + this.prefix + '/query/boxdata'; + if (key) url = 'http://' + this.prefix + '/query/data/' + key; const boxdata = await this.$request.get( url, key ? { timeoutInterval: 1 } : {} - ) + ); if (key) { this.settings.BoxJSData = { ...this.settings.BoxJSData, [key]: boxdata.val, - } - this.saveSettings(false) + }; + this.saveSettings(false); } - if (boxdata.val) return boxdata.val + if (boxdata.val) return boxdata.val; - return boxdata.datas + return boxdata.datas; } catch (e) { if (key && this.settings.BoxJSData[key]) { - return this.settings.BoxJSData[key] + return this.settings.BoxJSData[key]; } if (notify) await this.notify( `${this.name} - BoxJS 数据读取失败`, '请检查 BoxJS 域名是否为代理复写的域名,如(boxjs.net 或 boxjs.com)。\n若没有配置 BoxJS 相关模块,请点击通知查看教程', 'https://chavyleung.gitbook.io/boxjs/awesome/videos' - ) - return false + ); + return false; } - } + }; transforJSON = (str) => { if (typeof str == 'string') { try { - return JSON.parse(str) + return JSON.parse(str); } catch (e) { - console.log(e) - return str + console.log(e); + return str; } } - console.log('It is not a string!') - } + console.log('It is not a string!'); + }; // 选择图片并缓存 chooseImg = async () => { - return await Photos.fromLibrary() - } + return await Photos.fromLibrary(); + }; // 设置 widget 背景图片 getWidgetBackgroundImage = async (widget) => { - const backgroundImage = this.getBackgroundImage() + const backgroundImage = this.getBackgroundImage(); if (backgroundImage) { const opacity = Device.isUsingDarkAppearance() ? Number(this.settings.darkOpacity) - : Number(this.settings.lightOpacity) + : Number(this.settings.lightOpacity); widget.backgroundImage = await this.shadowImage( backgroundImage, '#000', opacity - ) - return true + ); + return true; } else { if (this.backGroundColor.colors) { - widget.backgroundGradient = this.backGroundColor + widget.backgroundGradient = this.backGroundColor; } else { - widget.backgroundColor = this.backGroundColor + widget.backgroundColor = this.backGroundColor; } - return false + return false; } - } + }; /** * 验证图片尺寸: 图片像素超过 1000 左右的时候会导致背景无法加载 @@ -176,10 +177,10 @@ class DmYY { */ verifyImage = async (img) => { try { - const { width, height } = img.size - const direct = true + const { width, height } = img.size; + const direct = true; if (width > 1000) { - const options = ['取消', '打开图像处理'] + const options = ['取消', '打开图像处理']; const message = '您的图片像素为' + width + @@ -190,17 +191,17 @@ class DmYY { (direct ? '宽度' : '高度') + '调整到 1000 以下\n' + (!direct ? '宽度' : '高度') + - '自动适应' - const index = await this.generateAlert(message, options) + '自动适应'; + const index = await this.generateAlert(message, options); if (index === 1) - Safari.openInApp('https://www.sojson.com/image/change.html', false) - return false + Safari.openInApp('https://www.sojson.com/image/change.html', false); + return false; } - return true + return true; } catch (e) { - return false + return false; } - } + }; /** * 获取截图中的组件剪裁图 @@ -212,11 +213,11 @@ class DmYY { async getWidgetScreenShot(title = null) { // Crop an image into the specified rect. function cropImage(img, rect) { - let draw = new DrawContext() - draw.size = new Size(rect.width, rect.height) + let draw = new DrawContext(); + draw.size = new Size(rect.width, rect.height); - draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)) - return draw.getImage() + draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y)); + return draw.getImage(); } // Pixel sizes and positions for widgets on all supported phones. @@ -354,63 +355,63 @@ class DmYY { middle: 618, bottom: 1146, }, - } + }; } let message = - title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续' - let exitOptions = ['我已截图', '前去截图 >'] - let shouldExit = await this.generateAlert(message, exitOptions) - if (shouldExit) return + title || '开始之前,请先前往桌面,截取空白界面的截图。然后回来继续'; + let exitOptions = ['我已截图', '前去截图 >']; + let shouldExit = await this.generateAlert(message, exitOptions); + if (shouldExit) return; // Get screenshot and determine phone size. - let img = await Photos.fromLibrary() - let height = img.size.height - let phone = phoneSizes()[height] + let img = await Photos.fromLibrary(); + let height = img.size.height; + let phone = phoneSizes()[height]; if (!phone) { - message = '好像您选择的照片不是正确的截图,请先前往桌面' - await this.generateAlert(message, ['我已知晓']) - return + message = '好像您选择的照片不是正确的截图,请先前往桌面'; + await this.generateAlert(message, ['我已知晓']); + return; } // Extra setup needed for 2436-sized phones. if (height === 2436) { - const files = this.FILE_MGR_LOCAL - let cacheName = 'mz-phone-type' - let cachePath = files.joinPath(files.libraryDirectory(), cacheName) + const files = this.FILE_MGR_LOCAL; + let cacheName = 'mz-phone-type'; + let cachePath = files.joinPath(files.libraryDirectory(), cacheName); // If we already cached the phone size, load it. if (files.fileExists(cachePath)) { - let typeString = files.readString(cachePath) - phone = phone[typeString] + let typeString = files.readString(cachePath); + phone = phone[typeString]; // Otherwise, prompt the user. } else { - message = '您的📱型号是?' - let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X'] - let typeIndex = await this.generateAlert(message, types) - let type = typeIndex === 0 ? 'mini' : 'x' - phone = phone[type] - files.writeString(cachePath, type) + message = '您的📱型号是?'; + let types = ['iPhone 12 mini', 'iPhone 11 Pro, XS, or X']; + let typeIndex = await this.generateAlert(message, types); + let type = typeIndex === 0 ? 'mini' : 'x'; + phone = phone[type]; + files.writeString(cachePath, type); } } // Prompt for widget size and position. - message = '截图中要设置透明背景组件的尺寸类型是?' - let sizes = ['小尺寸', '中尺寸', '大尺寸'] - let size = await this.generateAlert(message, sizes) - let widgetSize = sizes[size] + message = '截图中要设置透明背景组件的尺寸类型是?'; + let sizes = ['小尺寸', '中尺寸', '大尺寸']; + let size = await this.generateAlert(message, sizes); + let widgetSize = sizes[size]; - message = '要设置透明背景的小组件在哪个位置?' + message = '要设置透明背景的小组件在哪个位置?'; message += height === 1136 ? ' (备注:当前设备只支持两行小组件,所以下边选项中的「中间」和「底部」的选项是一致的)' - : '' + : ''; // Determine image crop based on phone size. - let crop = { w: '', h: '', x: '', y: '' } + let crop = { w: '', h: '', x: '', y: '' }; if (widgetSize === '小尺寸') { - crop.w = phone.small - crop.h = phone.small + crop.w = phone.small; + crop.h = phone.small; let positions = [ '左上角', '右上角', @@ -418,7 +419,7 @@ class DmYY { '中间右', '左下角', '右下角', - ] + ]; let _posotions = [ 'Top left', 'Top right', @@ -426,55 +427,55 @@ class DmYY { 'Middle right', 'Bottom left', 'Bottom right', - ] - let position = await this.generateAlert(message, positions) + ]; + let position = await this.generateAlert(message, positions); // Convert the two words into two keys for the phone size dictionary. - let keys = _posotions[position].toLowerCase().split(' ') - crop.y = phone[keys[0]] - crop.x = phone[keys[1]] + let keys = _posotions[position].toLowerCase().split(' '); + crop.y = phone[keys[0]]; + crop.x = phone[keys[1]]; } else if (widgetSize === '中尺寸') { - crop.w = phone.medium - crop.h = phone.small + crop.w = phone.medium; + crop.h = phone.small; // Medium and large widgets have a fixed x-value. - crop.x = phone.left - let positions = ['顶部', '中间', '底部'] - let _positions = ['Top', 'Middle', 'Bottom'] - let position = await this.generateAlert(message, positions) - let key = _positions[position].toLowerCase() - crop.y = phone[key] + crop.x = phone.left; + let positions = ['顶部', '中间', '底部']; + let _positions = ['Top', 'Middle', 'Bottom']; + let position = await this.generateAlert(message, positions); + let key = _positions[position].toLowerCase(); + crop.y = phone[key]; } else if (widgetSize === '大尺寸') { - crop.w = phone.medium - crop.h = phone.large - crop.x = phone.left - let positions = ['顶部', '底部'] - let position = await this.generateAlert(message, positions) + crop.w = phone.medium; + crop.h = phone.large; + crop.x = phone.left; + let positions = ['顶部', '底部']; + let position = await this.generateAlert(message, positions); // Large widgets at the bottom have the "middle" y-value. - crop.y = position ? phone.middle : phone.top + crop.y = position ? phone.middle : phone.top; } // Crop image and finalize the widget. - return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)) + return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)); } setLightAndDark = async (title, desc, val) => { try { - const a = new Alert() - a.title = title - a.message = desc - a.addTextField('', `${this.settings[val]}`) - a.addAction('确定') - a.addCancelAction('取消') - const id = await a.presentAlert() - if (id === -1) return - this.settings[val] = a.textFieldValue(0) - this.saveSettings() + const a = new Alert(); + a.title = title; + a.message = desc; + a.addTextField('', `${this.settings[val]}`); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + this.settings[val] = a.textFieldValue(0); + this.saveSettings(); } catch (e) { - console.log(e) + console.log(e); } - } + }; /** * 弹出输入框 @@ -484,27 +485,27 @@ class DmYY { * @returns {Promise} */ setAlertInput = async (title, desc, opt = {}, isSave = true) => { - const a = new Alert() - a.title = title - a.message = !desc ? '' : desc + const a = new Alert(); + a.title = title; + a.message = !desc ? '' : desc; Object.keys(opt).forEach((key) => { - a.addTextField(opt[key], this.settings[key]) - }) - a.addAction('确定') - a.addCancelAction('取消') - const id = await a.presentAlert() - if (id === -1) return - const data = {} + a.addTextField(opt[key], this.settings[key]); + }); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + const data = {}; Object.keys(opt).forEach((key, index) => { - data[key] = a.textFieldValue(index) - }) + data[key] = a.textFieldValue(index); + }); // 保存到本地 if (isSave) { - this.settings = { ...this.settings, ...data } - return this.saveSettings() + this.settings = { ...this.settings, ...data }; + return this.saveSettings(); } - return data - } + return data; + }; /** * 设置当前项目的 boxJS 缓存 @@ -512,87 +513,87 @@ class DmYY { * @returns {Promise} */ setCacheBoxJSData = async (opt = {}) => { - const options = ['取消', '确定'] - const message = '代理缓存仅支持 BoxJS 相关的代理!' - const index = await this.generateAlert(message, options) - if (index === 0) return + const options = ['取消', '确定']; + const message = '代理缓存仅支持 BoxJS 相关的代理!'; + const index = await this.generateAlert(message, options); + if (index === 0) return; try { - const boxJSData = await this.getCache() + const boxJSData = await this.getCache(); Object.keys(opt).forEach((key) => { - this.settings[key] = boxJSData[opt[key]] || '' - }) + this.settings[key] = boxJSData[opt[key]] || ''; + }); // 保存到本地 - this.saveSettings() + this.saveSettings(); } catch (e) { - console.log(e) + console.log(e); this.notify( this.name, 'BoxJS 缓存读取失败!点击查看相关教程', 'https://chavyleung.gitbook.io/boxjs/awesome/videos' - ) + ); } - } + }; /** * 设置组件内容 * @returns {Promise} */ setWidgetConfig = async () => { - const table = new UITable() - table.showSeparators = true - await this.renderDmYYTables(table) - await table.present() - } + const table = new UITable(); + table.showSeparators = true; + await this.renderDmYYTables(table); + await table.present(); + }; async preferences(table, arr, outfit) { - let header = new UITableRow() - let heading = header.addText(outfit) - heading.titleFont = Font.mediumSystemFont(17) - heading.centerAligned() - table.addRow(header) + let header = new UITableRow(); + let heading = header.addText(outfit); + heading.titleFont = Font.mediumSystemFont(17); + heading.centerAligned(); + table.addRow(header); for (const item of arr) { - const row = new UITableRow() - row.dismissOnSelect = !!item.dismissOnSelect + const row = new UITableRow(); + row.dismissOnSelect = !!item.dismissOnSelect; if (item.url) { - const rowIcon = row.addImageAtURL(item.url) - rowIcon.widthWeight = 100 + const rowIcon = row.addImageAtURL(item.url); + rowIcon.widthWeight = 100; } else { - const icon = item.icon || {} + const icon = item.icon || {}; const image = await this.drawTableIcon( icon.name, icon.color, item.cornerWidth - ) - const imageCell = row.addImage(image) - imageCell.widthWeight = 100 + ); + const imageCell = row.addImage(image); + imageCell.widthWeight = 100; } - let rowTitle = row.addText(item['title']) - rowTitle.widthWeight = 400 - rowTitle.titleFont = Font.systemFont(16) + let rowTitle = row.addText(item['title']); + rowTitle.widthWeight = 400; + rowTitle.titleFont = Font.systemFont(16); if (this.settings[item.val] || item.val) { let valText = row.addText( `${this.settings[item.val] || item.val}`.toUpperCase() - ) - const fontSize = !item.val ? 26 : 16 - valText.widthWeight = 500 - valText.rightAligned() - valText.titleColor = Color.blue() - valText.titleFont = Font.mediumSystemFont(fontSize) + ); + const fontSize = !item.val ? 26 : 16; + valText.widthWeight = 500; + valText.rightAligned(); + valText.titleColor = Color.blue(); + valText.titleFont = Font.mediumSystemFont(fontSize); } else { const imgCell = UITableCell.imageAtURL( 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png' - ) - imgCell.rightAligned() - imgCell.widthWeight = 500 - row.addCell(imgCell) + ); + imgCell.rightAligned(); + imgCell.widthWeight = 500; + row.addCell(imgCell); } row.onSelect = item.onClick ? async () => { try { - await item.onClick(item, table) + await item.onClick(item, table); } catch (e) { - console.log(e) + console.log(e); } } : async () => { @@ -601,33 +602,33 @@ class DmYY { item['title'], item['desc'], item['val'] - ) + ); } else if (item.type == 'setBackground') { - const backImage = await this.getWidgetScreenShot() + const backImage = await this.getWidgetScreenShot(); if (backImage) { - await this.setBackgroundImage(backImage, true) - await this.setBackgroundNightImage(backImage, true) + await this.setBackgroundImage(backImage, true); + await this.setBackgroundNightImage(backImage, true); } } else if (item.type == 'removeBackground') { - const options = ['取消', '清空'] - const message = '该操作不可逆,会清空所有背景图片!' - const index = await this.generateAlert(message, options) - if (index === 0) return - await this.setBackgroundImage(false, true) - await this.setBackgroundNightImage(false, true) + const options = ['取消', '清空']; + const message = '该操作不可逆,会清空所有背景图片!'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + await this.setBackgroundImage(false, true); + await this.setBackgroundNightImage(false, true); } else { - const backImage = await this.chooseImg() - if (!backImage || !(await this.verifyImage(backImage))) return + const backImage = await this.chooseImg(); + if (!backImage || !(await this.verifyImage(backImage))) return; if (item.type == 'setDayBackground') - await this.setBackgroundImage(backImage, true) + await this.setBackgroundImage(backImage, true); if (item.type == 'setNightBackground') - await this.setBackgroundNightImage(backImage, true) + await this.setBackgroundNightImage(backImage, true); } - await this.renderDmYYTables(table) - } - table.addRow(row) + await this.renderDmYYTables(table); + }; + table.addRow(row); } - table.reload() + table.reload(); } drawTableIcon = async ( @@ -635,14 +636,14 @@ class DmYY { color = '#e8e8e8', cornerWidth = 42 ) => { - const sfi = SFSymbol.named(icon) - sfi.applyFont(Font.mediumSystemFont(30)) - const imgData = Data.fromPNG(sfi.image).toBase64String() + const sfi = SFSymbol.named(icon); + sfi.applyFont(Font.mediumSystemFont(30)); + const imgData = Data.fromPNG(sfi.image).toBase64String(); const html = ` - ` + `; const js = ` var canvas = document.createElement("canvas"); var sourceImg = document.getElementById("sourceImg"); @@ -668,31 +669,31 @@ class DmYY { ctx.putImageData(imgData,0,0); silhouetteImg.src = canvas.toDataURL(); output=canvas.toDataURL() - ` - - let wv = new WebView() - await wv.loadHTML(html) - const base64Image = await wv.evaluateJavaScript(js) - const iconImage = await new Request(base64Image).loadImage() - const size = new Size(160, 160) - const ctx = new DrawContext() - ctx.opaque = false - ctx.respectScreenScale = true - ctx.size = size - const path = new Path() - const rect = new Rect(0, 0, size.width, size.width) - - path.addRoundedRect(rect, cornerWidth, cornerWidth) - path.closeSubpath() - ctx.setFillColor(new Color(color)) - ctx.addPath(path) - ctx.fillPath() - const rate = 36 - const iw = size.width - rate - const x = (size.width - iw) / 2 - ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)) - return ctx.getImage() - } + `; + + let wv = new WebView(); + await wv.loadHTML(html); + const base64Image = await wv.evaluateJavaScript(js); + const iconImage = await new Request(base64Image).loadImage(); + const size = new Size(160, 160); + const ctx = new DrawContext(); + ctx.opaque = false; + ctx.respectScreenScale = true; + ctx.size = size; + const path = new Path(); + const rect = new Rect(0, 0, size.width, size.width); + + path.addRoundedRect(rect, cornerWidth, cornerWidth); + path.closeSubpath(); + ctx.setFillColor(new Color(color)); + ctx.addPath(path); + ctx.fillPath(); + const rate = 36; + const iw = size.width - rate; + const x = (size.width - iw) / 2; + ctx.drawImageInRect(iconImage, new Rect(x, x, iw, iw)); + return ctx.getImage(); + }; async renderDmYYTables(table) { const basic = [ @@ -731,7 +732,7 @@ class DmYY { desc: '请自行去网站上搜寻颜色(Hex 颜色)', val: 'darkColor', }, - ] + ]; const background = [ { icon: { name: 'text.below.photo', color: '#faad14' }, @@ -767,54 +768,54 @@ class DmYY { type: 'removeBackground', title: '清空背景图片', }, - ] + ]; const boxjs = { icon: { name: 'shippingbox', color: '#f7bb10' }, type: 'input', title: 'BoxJS 域名', desc: '', val: 'boxjsDomain', - } - if (this.useBoxJS) basic.push(boxjs) - table.removeAllRows() - let topRow = new UITableRow() - topRow.height = 60 - let leftText = topRow.addButton('Github') - leftText.widthWeight = 0.3 + }; + if (this.useBoxJS) basic.push(boxjs); + table.removeAllRows(); + let topRow = new UITableRow(); + topRow.height = 60; + let leftText = topRow.addButton('Github'); + leftText.widthWeight = 0.3; leftText.onTap = async () => { - await Safari.openInApp('https://github.com/dompling/Scriptable') - } + await Safari.openInApp('https://github.com/dompling/Scriptable'); + }; let centerRow = topRow.addImageAtURL( 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png' - ) - centerRow.widthWeight = 0.4 - centerRow.centerAligned() + ); + centerRow.widthWeight = 0.4; + centerRow.centerAligned(); centerRow.onTap = async () => { - await Safari.open('https://t.me/Scriptable_JS') - } - let rightText = topRow.addButton('重置所有') - rightText.widthWeight = 0.3 - rightText.rightAligned() + await Safari.open('https://t.me/Scriptable_JS'); + }; + let rightText = topRow.addButton('重置所有'); + rightText.widthWeight = 0.3; + rightText.rightAligned(); rightText.onTap = async () => { - const options = ['取消', '重置'] + const options = ['取消', '重置']; const message = - '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。' - const index = await this.generateAlert(message, options) - if (index === 0) return - this.settings = {} - await this.setBackgroundImage(false, false) - this.FILE_MGR.remove(this.cacheImage) - this.saveSettings() - } - table.addRow(topRow) - await this.preferences(table, basic, '基础设置') - await this.preferences(table, background, '背景图片') + '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。'; + const index = await this.generateAlert(message, options); + if (index === 0) return; + this.settings = {}; + await this.setBackgroundImage(false, false); + this.FILE_MGR.remove(this.cacheImage); + this.saveSettings(); + }; + table.addRow(topRow); + await this.preferences(table, basic, '基础设置'); + await this.preferences(table, background, '背景图片'); } init(widgetFamily = config.widgetFamily) { // 组件大小:small,medium,large - this.widgetFamily = widgetFamily - this.SETTING_KEY = this.md5(Script.name()) + this.widgetFamily = widgetFamily; + this.SETTING_KEY = this.md5(Script.name()); //用于配置所有的组件相关设置 // 文件管理器 @@ -822,74 +823,80 @@ class DmYY { this.FILE_MGR = FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' - ]() + ](); this.cacheImage = this.FILE_MGR.joinPath( this.FILE_MGR.libraryDirectory(), `${Script.name()}/images` - ) + ); if (!this.FILE_MGR.fileExists(this.cacheImage)) { - this.FILE_MGR.createDirectory(this.cacheImage, true) + this.FILE_MGR.createDirectory(this.cacheImage, true); } // 本地,用于存储图片等 - this.FILE_MGR_LOCAL = FileManager.local() + this.FILE_MGR_LOCAL = FileManager.local(); this.BACKGROUND_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), 'bg_' + this.SETTING_KEY + '.jpg' - ) + ); this.BACKGROUND_NIGHT_KEY = this.FILE_MGR_LOCAL.joinPath( this.FILE_MGR_LOCAL.documentsDirectory(), 'bg_' + this.SETTING_KEY + 'night.jpg' - ) - - this.settings = this.getSettings() - console.log(this.settings) - this.settings.lightColor = this.settings.lightColor || '#000000' - this.settings.darkColor = this.settings.darkColor || '#ffffff' - this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff' - this.settings.darkBgColor = this.settings.darkBgColor || '#000000' - this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net' - this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30' - this.settings.lightOpacity = this.settings.lightOpacity || '0.4' - this.settings.darkOpacity = this.settings.darkOpacity || '0.7' - this.prefix = this.settings.boxjsDomain - const lightBgColor = this.getColors(this.settings.lightBgColor) - const darkBgColor = this.getColors(this.settings.darkBgColor) + ); + + this.settings = this.getSettings(); + + this.settings = { ...this.defaultSettings, ...this.settings }; + + console.log(this.settings); + + this.settings.lightColor = this.settings.lightColor || '#000000'; + this.settings.darkColor = this.settings.darkColor || '#ffffff'; + this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff'; + this.settings.darkBgColor = this.settings.darkBgColor || '#000000'; + this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net'; + this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30'; + this.settings.lightOpacity = this.settings.lightOpacity || '0.4'; + this.settings.darkOpacity = this.settings.darkOpacity || '0.7'; + + this.prefix = this.settings.boxjsDomain; + const lightBgColor = this.getColors(this.settings.lightBgColor); + const darkBgColor = this.getColors(this.settings.darkBgColor); if (lightBgColor.length > 1 || darkBgColor.length > 1) { this.backGroundColor = !Device.isUsingDarkAppearance() ? this.getBackgroundColor(lightBgColor) - : this.getBackgroundColor(darkBgColor) + : this.getBackgroundColor(darkBgColor); } else if (lightBgColor.length > 0 && darkBgColor.length > 0) { this.backGroundColor = Color.dynamic( new Color(this.settings.lightBgColor), new Color(this.settings.darkBgColor) - ) + ); } + this.widgetColor = Color.dynamic( new Color(this.settings.lightColor), new Color(this.settings.darkColor) - ) + ); } getColors = (color = '') => { - const colors = typeof color === 'string' ? color.split(',') : color - return colors - } + const colors = typeof color === 'string' ? color.split(',') : color; + return colors; + }; getBackgroundColor = (colors) => { - const locations = [] - const linearColor = new LinearGradient() - const cLen = colors.length + const locations = []; + const linearColor = new LinearGradient(); + const cLen = colors.length; linearColor.colors = colors.map((item, index) => { - locations.push(Math.floor(((index + 1) / cLen) * 100) / 100) - return new Color(item, 1) - }) - linearColor.locations = locations - return linearColor - } + locations.push(Math.floor(((index + 1) / cLen) * 100) / 100); + return new Color(item, 1); + }); + linearColor.locations = locations; + return linearColor; + }; /** * 注册点击操作菜单 @@ -897,8 +904,8 @@ class DmYY { * @param {func} func 点击后执行的函数 */ registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }) { - this._actions[name] = func.bind(this) - this._actionsIcon[name] = icon + this._actions[name] = func.bind(this); + this._actionsIcon[name] = icon; } /** @@ -906,8 +913,8 @@ class DmYY { * @param {string} str 要编码的字符串 */ base64Encode(str) { - const data = Data.fromString(str) - return data.toBase64String() + const data = Data.fromString(str); + return data.toBase64String(); } /** @@ -915,8 +922,8 @@ class DmYY { * @param {string} b64 base64编码的数据 */ base64Decode(b64) { - const data = Data.fromBase64String(b64) - return data.toRawString() + const data = Data.fromBase64String(b64); + return data.toRawString(); } /** @@ -925,34 +932,34 @@ class DmYY { */ md5(str) { function d(n, t) { - var r = (65535 & n) + (65535 & t) - return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r) + var r = (65535 & n) + (65535 & t); + return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r); } function f(n, t, r, e, o, u) { - return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r) - var c, f + return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r); + var c, f; } function l(n, t, r, e, o, u, c) { - return f((t & r) | (~t & e), n, t, o, u, c) + return f((t & r) | (~t & e), n, t, o, u, c); } function v(n, t, r, e, o, u, c) { - return f((t & e) | (r & ~e), n, t, o, u, c) + return f((t & e) | (r & ~e), n, t, o, u, c); } function g(n, t, r, e, o, u, c) { - return f(t ^ r ^ e, n, t, o, u, c) + return f(t ^ r ^ e, n, t, o, u, c); } function m(n, t, r, e, o, u, c) { - return f(r ^ (t | ~e), n, t, o, u, c) + return f(r ^ (t | ~e), n, t, o, u, c); } function i(n, t) { - var r, e, o, u - ;(n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t) + var r, e, o, u; + (n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t); for ( var c = 1732584193, f = -271733879, @@ -1050,39 +1057,39 @@ class DmYY { (c = d(c, r)), (f = d(f, e)), (i = d(i, o)), - (a = d(a, u)) - return [c, f, i, a] + (a = d(a, u)); + return [c, f, i, a]; } function a(n) { for (var t = '', r = 32 * n.length, e = 0; e < r; e += 8) - t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255) - return t + t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255); + return t; } function h(n) { - var t = [] + var t = []; for (t[(n.length >> 2) - 1] = void 0, e = 0; e < t.length; e += 1) - t[e] = 0 + t[e] = 0; for (var r = 8 * n.length, e = 0; e < r; e += 8) - t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32 - return t + t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32; + return t; } function e(n) { for (var t, r = '0123456789abcdef', e = '', o = 0; o < n.length; o += 1) (t = n.charCodeAt(o)), - (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)) - return e + (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)); + return e; } function r(n) { - return unescape(encodeURIComponent(n)) + return unescape(encodeURIComponent(n)); } function o(n) { - return a(i(h((t = r(n))), 8 * t.length)) - var t + return a(i(h((t = r(n))), 8 * t.length)); + var t; } function u(n, t) { @@ -1091,7 +1098,7 @@ class DmYY { e, o = h(n), u = [], - c = [] + c = []; for ( u[15] = c[15] = void 0, 16 < o.length && (o = i(o, 8 * n.length)), @@ -1099,18 +1106,18 @@ class DmYY { r < 16; r += 1 ) - (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]) + (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]); return ( (e = i(u.concat(h(t)), 512 + 8 * t.length)), a(i(c.concat(e), 640)) - ) - })(r(n), r(t)) + ); + })(r(n), r(t)); } function t(n, t, r) { - return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)) + return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)); } - return t(str) + return t(str); } /** @@ -1121,24 +1128,24 @@ class DmYY { * @param {bool|color} color 字体的颜色(自定义背景时使用,默认系统) */ async renderHeader(widget, icon, title, color = false) { - let header = widget.addStack() - header.centerAlignContent() + let header = widget.addStack(); + header.centerAlignContent(); try { - const image = await this.$request.get(icon, 'IMG') - let _icon = header.addImage(image) - _icon.imageSize = new Size(14, 14) - _icon.cornerRadius = 4 + const image = await this.$request.get(icon, 'IMG'); + let _icon = header.addImage(image); + _icon.imageSize = new Size(14, 14); + _icon.cornerRadius = 4; } catch (e) { - console.log(e) + console.log(e); } - header.addSpacer(10) - let _title = header.addText(title) - if (color) _title.textColor = color - _title.textOpacity = 0.7 - _title.font = Font.boldSystemFont(12) - _title.lineLimit = 1 - widget.addSpacer(15) - return widget + header.addSpacer(10); + let _title = header.addText(title); + if (color) _title.textColor = color; + _title.textOpacity = 0.7; + _title.font = Font.boldSystemFont(12); + _title.lineLimit = 1; + widget.addSpacer(15); + return widget; } /** @@ -1148,13 +1155,13 @@ class DmYY { */ async generateAlert(message, options) { - let alert = new Alert() - alert.message = message + let alert = new Alert(); + alert.message = message; for (const option of options) { - alert.addAction(option) + alert.addAction(option); } - return await alert.presentAlert() + return await alert.presentAlert(); } /** @@ -1164,12 +1171,12 @@ class DmYY { * @param {string} url 点击后打开的URL */ async notify(title, body, url, opts = {}) { - let n = new Notification() - n = Object.assign(n, opts) - n.title = title - n.body = body - if (url) n.openURL = url - return await n.schedule() + let n = new Notification(); + n = Object.assign(n, opts); + n.title = title; + n.body = body; + if (url) n.openURL = url; + return await n.schedule(); } /** @@ -1179,19 +1186,19 @@ class DmYY { * @param {float} opacity 透明度 */ async shadowImage(img, color = '#000000', opacity = 0.7) { - if (!img) return - if (opacity === 0) return img - let ctx = new DrawContext() + if (!img) return; + if (opacity === 0) return img; + let ctx = new DrawContext(); // 获取图片的尺寸 - ctx.size = img.size + ctx.size = img.size; ctx.drawImageInRect( img, new Rect(0, 0, img.size['width'], img.size['height']) - ) - ctx.setFillColor(new Color(color, opacity)) - ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])) - return await ctx.getImage() + ); + ctx.setFillColor(new Color(color, opacity)); + ctx.fillRect(new Rect(0, 0, img.size['width'], img.size['height'])); + return await ctx.getImage(); } /** @@ -1199,20 +1206,20 @@ class DmYY { * @param {boolean} json 是否为json格式 */ getSettings(json = true) { - let res = json ? {} : '' - let cache = '' + let res = json ? {} : ''; + let cache = ''; if (Keychain.contains(this.SETTING_KEY)) { - cache = Keychain.get(this.SETTING_KEY) + cache = Keychain.get(this.SETTING_KEY); } if (json) { try { - res = JSON.parse(cache) + res = JSON.parse(cache); } catch (e) {} } else { - res = cache + res = cache; } - return res + return res; } /** @@ -1223,9 +1230,9 @@ class DmYY { let res = typeof this.settings === 'object' ? JSON.stringify(this.settings) - : String(this.settings) - Keychain.set(this.SETTING_KEY, res) - if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新') + : String(this.settings); + Keychain.set(this.SETTING_KEY, res); + if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新'); } /** @@ -1233,17 +1240,17 @@ class DmYY { * @reutrn img | false */ getBackgroundImage() { - let result = null + let result = null; if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - result = Image.fromFile(this.BACKGROUND_KEY) + result = Image.fromFile(this.BACKGROUND_KEY); } if ( Device.isUsingDarkAppearance() && this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY) ) { - result = Image.fromFile(this.BACKGROUND_NIGHT_KEY) + result = Image.fromFile(this.BACKGROUND_NIGHT_KEY); } - return result + return result; } /** @@ -1254,16 +1261,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY) + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_KEY); } if (notify) - this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效') + this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效'); } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img) + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_KEY, img); if (notify) - this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效') + this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效'); } } @@ -1271,16 +1278,16 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR_LOCAL.fileExists(this.BACKGROUND_NIGHT_KEY)) { - this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY) + this.FILE_MGR_LOCAL.remove(this.BACKGROUND_NIGHT_KEY); } if (notify) - this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效') + this.notify('移除成功', '小组件夜间背景图片已移除,稍后刷新生效'); } else { // 设置背景 // 全部设置一遍, - this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img) + this.FILE_MGR_LOCAL.writeImage(this.BACKGROUND_NIGHT_KEY, img); if (notify) - this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效') + this.notify('设置成功', '小组件夜间背景图片已设置!稍后刷新生效'); } } @@ -1289,15 +1296,15 @@ class DmYY { i = arr.length, min = i - count, temp, - index - min = min > 0 ? min : 0 + index; + min = min > 0 ? min : 0; while (i-- > min) { - index = Math.floor((i + 1) * Math.random()) - temp = shuffled[index] - shuffled[index] = shuffled[i] - shuffled[i] = temp + index = Math.floor((i + 1) * Math.random()); + temp = shuffled[index]; + shuffled[index] = shuffled[i]; + shuffled[i] = temp; } - return shuffled.slice(min) + return shuffled.slice(min); } textFormat = { @@ -1305,45 +1312,45 @@ class DmYY { battery: { size: 10, font: 'bold', color: this.widgetColor }, title: { size: 16, font: 'semibold', color: this.widgetColor }, SFMono: { size: 12, font: 'SF Mono', color: this.widgetColor }, - } + }; provideFont = (fontName, fontSize) => { const fontGenerator = { ultralight: function () { - return Font.ultraLightSystemFont(fontSize) + return Font.ultraLightSystemFont(fontSize); }, light: function () { - return Font.lightSystemFont(fontSize) + return Font.lightSystemFont(fontSize); }, regular: function () { - return Font.regularSystemFont(fontSize) + return Font.regularSystemFont(fontSize); }, medium: function () { - return Font.mediumSystemFont(fontSize) + return Font.mediumSystemFont(fontSize); }, semibold: function () { - return Font.semiboldSystemFont(fontSize) + return Font.semiboldSystemFont(fontSize); }, bold: function () { - return Font.boldSystemFont(fontSize) + return Font.boldSystemFont(fontSize); }, heavy: function () { - return Font.heavySystemFont(fontSize) + return Font.heavySystemFont(fontSize); }, black: function () { - return Font.blackSystemFont(fontSize) + return Font.blackSystemFont(fontSize); }, italic: function () { - return Font.italicSystemFont(fontSize) + return Font.italicSystemFont(fontSize); }, - } + }; - const systemFont = fontGenerator[fontName] + const systemFont = fontGenerator[fontName]; if (systemFont) { - return systemFont() + return systemFont(); } - return new Font(fontName, fontSize) - } + return new Font(fontName, fontSize); + }; provideText = ( string, @@ -1356,68 +1363,68 @@ class DmYY { minimumScaleFactor: 1, } ) => { - const textItem = container.addText(string) - const textFont = format.font - const textSize = format.size - const textColor = format.color - - textItem.font = this.provideFont(textFont, textSize) - textItem.textColor = textColor - textItem.textOpacity = format.opacity || 1 - textItem.minimumScaleFactor = format.minimumScaleFactor || 1 - return textItem - } + const textItem = container.addText(string); + const textFont = format.font; + const textSize = format.size; + const textColor = format.color; + + textItem.font = this.provideFont(textFont, textSize); + textItem.textColor = textColor; + textItem.textOpacity = format.opacity || 1; + textItem.minimumScaleFactor = format.minimumScaleFactor || 1; + return textItem; + }; } // @base.end const Runing = async (Widget, default_args = '', isDebug = true, extra) => { - let M = null + let M = null; // 判断hash是否和当前设备匹配 if (config.runsInWidget) { - M = new Widget(args.widgetParameter || '') + M = new Widget(args.widgetParameter || ''); if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key] - }) + M[key] = extra[key]; + }); } - const W = await M.render() + const W = await M.render(); try { if (M.settings.refreshAfterDate) { - const refreshTime = parseInt(M.settings.refreshAfterDate) * 1000 * 60 - const timeStr = new Date().getTime() + refreshTime - W.refreshAfterDate = new Date(timeStr) + const refreshTime = parseInt(M.settings.refreshAfterDate) * 1000 * 60; + const timeStr = new Date().getTime() + refreshTime; + W.refreshAfterDate = new Date(timeStr); } } catch (e) { - console.log(e) + console.log(e); } if (W) { - Script.setWidget(W) - Script.complete() + Script.setWidget(W); + Script.complete(); } } else { - let { act, __arg, __size } = args.queryParameters - M = new Widget(__arg || default_args || '') + let { act, __arg, __size } = args.queryParameters; + M = new Widget(__arg || default_args || ''); if (extra) { Object.keys(extra).forEach((key) => { - M[key] = extra[key] - }) + M[key] = extra[key]; + }); } - if (__size) M.init(__size) + if (__size) M.init(__size); if (!act || !M['_actions']) { // 弹出选择菜单 - const actions = M['_actions'] - const table = new UITable() + const actions = M['_actions']; + const table = new UITable(); const onClick = async (item) => { - M.widgetFamily = item.val - w = await M.render() + M.widgetFamily = item.val; + w = await M.render(); const fnc = item.val .toLowerCase() - .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()) + .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()); if (w) { - return w[`present${fnc}`]() + return w[`present${fnc}`](); } - } + }; const preview = [ { url: 'https://pic1.imgdb.cn/item/63315c3616f2c2beb1a2931a.png', @@ -1440,28 +1447,28 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { dismissOnSelect: true, onClick, }, - ] - await M.preferences(table, preview, '预览组件') - const extra = [] + ]; + await M.preferences(table, preview, '预览组件'); + const extra = []; for (let _ in actions) { - const iconItem = M._actionsIcon[_] - const isUrl = typeof iconItem === 'string' + const iconItem = M._actionsIcon[_]; + const isUrl = typeof iconItem === 'string'; const actionItem = { title: _, onClick: actions[_], - } + }; if (isUrl) { - actionItem.url = iconItem + actionItem.url = iconItem; } else { - actionItem.icon = iconItem + actionItem.icon = iconItem; } - extra.push(actionItem) + extra.push(actionItem); } - await M.preferences(table, extra, '配置组件') - return table.present() + await M.preferences(table, extra, '配置组件'); + return table.present(); } } -} +}; // await new DmYY().setWidgetConfig(); -module.exports = { DmYY, Runing } +module.exports = { DmYY, Runing }; From 9e0490d3571b6fd4f37a77009a2be287561cd741 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Tue, 8 Nov 2022 13:55:09 +0800 Subject: [PATCH 067/152] =?UTF-8?q?add:=20=E6=96=B0=E5=A2=9E=E4=BA=A4?= =?UTF-8?q?=E7=AE=A1=2012123=E5=B0=8F=E7=BB=84=E4=BB=B6=EF=BC=8Ctoken?= =?UTF-8?q?=E5=BE=88=E9=87=8D=E8=A6=81=E8=AF=B7=E5=8B=BF=E6=B3=84=E6=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index 8512f2c..fab4d74 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -34,7 +34,7 @@ class Widget extends DmYY { wxmini: '微信小程序交管12123跳转 ID', }); }, - { name: 'chat', color: '#722ed1' } + { name: 'message', color: '#722ed1' } ); config.runsInApp && this.registerAction( @@ -86,6 +86,8 @@ class Widget extends DmYY { }; init = async () => { + this.settings.token = + (await this.getCache('wx_12123')) || this.settings.token; if (this.settings.dataSource) { this.dataSource = this.settings.dataSource; } else { @@ -112,7 +114,7 @@ class Widget extends DmYY { ...params, })}`, }); - + console.log(response); if (response.success) { const illegal = response.data.list[0] || {}; this.dataSource.left.listItem[0].value = illegal.count || 0; From 03bce5759b65b5560670a08d869b8112f2e6a99d Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Tue, 8 Nov 2022 14:45:32 +0800 Subject: [PATCH 068/152] =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=9B=B4=E6=8D=A2?= =?UTF-8?q?=E5=88=B0=E6=94=AF=E4=BB=98=E5=AE=9D=E5=B0=8F=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index fab4d74..2cdc504 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -8,7 +8,7 @@ const { DmYY, Runing } = require('./DmYY'); const API_PARAMS = { api4: 'biz.vio.detail.query', - infoURL: 'https://miniappwx.122.gov.cn:8553/openapi/invokeApi/business/biz', + infoURL: 'https://miniappcsfw.122.gov.cn:8443/openapi/invokeApi/business/biz', api1: 'biz.vio.unhandledVioCount.query', productId: 'p10000000000000000001', api2: 'biz.vio.peccancyChannelList.query', @@ -102,9 +102,9 @@ class Widget extends DmYY { const body = JSON.parse(decodeURIComponent(token)); const params = { sign: body.sign, - businessId: body.businessId, + // businessId: body.businessId, verifyToken: body.verifyToken, - businessPrincipalId: body.businessPrincipalId, + // businessPrincipalId: body.businessPrincipalId, }; const response = await this.$request.post(API_PARAMS.infoURL, { @@ -129,6 +129,8 @@ class Widget extends DmYY { )}`, }); + console.log(details) + if (details.success) { const { drivingLicense, vehicles } = details.data; const reaccDate = drivingLicense.reaccDate.split('-'); @@ -143,7 +145,7 @@ class Widget extends DmYY { } this.dataSource.left.listItem[2].value = `${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`; - console.log(this.dataSource); + this.settings.dataSource = this.dataSource; this.saveSettings(false); } else { From 9f5a3536512bccc31c96f329c427da6e2f4e9160 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Tue, 8 Nov 2022 15:21:31 +0800 Subject: [PATCH 069/152] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index 2cdc504..da3eb4f 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -11,8 +11,13 @@ const API_PARAMS = { infoURL: 'https://miniappcsfw.122.gov.cn:8443/openapi/invokeApi/business/biz', api1: 'biz.vio.unhandledVioCount.query', productId: 'p10000000000000000001', + alipay: 'alipays://platformapi/startapp?appId=2019050964403523', api2: 'biz.vio.peccancyChannelList.query', + status: + 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', + update: 'https://gitcode.net/4qiao/scriptable/raw/master/api/violation.js', api3: 'biz.vio.peccancyUnhandleInfoList.query', + Ver: 'Version 1.2\n\nverifyToken过期需打开Quantumult-X', }; // @组件代码开始 @@ -26,16 +31,6 @@ class Widget extends DmYY { }); this.en = '12123'; this.name = '交管 12123'; - config.runsInApp && - this.registerAction( - '微信小程序 ID', - async () => { - return this.setAlertInput('小程序 ID', '设置小程序跳转 ID', { - wxmini: '微信小程序交管12123跳转 ID', - }); - }, - { name: 'message', color: '#722ed1' } - ); config.runsInApp && this.registerAction( 'Token', @@ -129,7 +124,7 @@ class Widget extends DmYY { )}`, }); - console.log(details) + console.log(details); if (details.success) { const { drivingLicense, vehicles } = details.data; @@ -145,16 +140,14 @@ class Widget extends DmYY { } this.dataSource.left.listItem[2].value = `${this.arrUpdateTime[2]}:${this.arrUpdateTime[3]}`; - + this.settings.dataSource = this.dataSource; this.saveSettings(false); } else { this.notify( `verifyToken已过期 ⚠️`, - '点击通知框自动跳转到微信小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', - this.settings.wxmini - ? `weixin://dl/business/?t=${this.settings.wxmini}` - : '' + '点击通知框自动跳转到支付宝小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', + API_PARAMS.alipay ); } } catch (e) { From 879156af6a7df6b5fd36938e2f2b52979c67e613 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Tue, 8 Nov 2022 16:03:39 +0800 Subject: [PATCH 070/152] =?UTF-8?q?=E6=89=A3=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index da3eb4f..0319af5 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -74,7 +74,7 @@ class Widget extends DmYY { icon: 'creditcard.fill', listItem: [ { label: '证件状态', value: '正常' }, - { label: '累计积分', value: `0`, unit: '分' }, + { label: '累计扣分', value: `0`, unit: '分' }, { label: '重置日期', value: '—' }, ], }, From a446d2c762dafc11f087831a0e032b0c840c06b3 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 10 Nov 2022 16:20:38 +0800 Subject: [PATCH 071/152] =?UTF-8?q?add:=E5=A2=9E=E5=8A=A0=E6=AF=94?= =?UTF-8?q?=E7=89=B9=E5=B8=81=E7=A7=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/BTC.js | 294 ++++++++++++++++++++++++++++++++++++++++++++++++ Scripts/DmYY.js | 2 - install.json | 75 +++++++++++- 3 files changed, 365 insertions(+), 6 deletions(-) create mode 100644 Scripts/BTC.js diff --git a/Scripts/BTC.js b/Scripts/BTC.js new file mode 100644 index 0000000..94515e8 --- /dev/null +++ b/Scripts/BTC.js @@ -0,0 +1,294 @@ +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: deep-blue; icon-glyph: magic; +// Variables used by Scriptable. +// These must be at the very top of the file. Do not edit. +// icon-color: deep-gray; icon-glyph: car; + +// 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 +if (typeof require === 'undefined') require = importModule; +const {DmYY, Runing} = require('./DmYY'); + +// @组件代码开始 +class Widget extends DmYY { + constructor(arg) { + super(arg); + this.en = ' btc'; + this.name = '比特币'; + config.runsInApp && + this.registerAction( + '关注种类', + async () => { + return this.setAlertInput('比特币种类', '设置关注种类', { + btcType: 'BTC,ETH,BNB', + }); + }, + {name: 'centsign.circle', color: '#feda31'}, + ); + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + } + + format = (str) => { + return parseInt(str) >= 10 ? str : `0${str}`; + }; + + endpoint = 'https://api.coingecko.com/api/v3'; + nomicsEndpoint = 'https://api.nomics.com/v1'; + + dataSource = []; + + init = async () => { + if (this.settings.dataSource && !config.runsInApp) { + this.dataSource = this.settings.dataSource; + } else { + await this.cacheData(this.settings.btcType); + } + this.cacheData(this.settings.btcType); + }; + + cacheData = async (params = '') => { + try { + const ids = await this.transforBtcType(params); + let response = await this.$request.get( + `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}` + , 'STRING'); + this.dataSource = []; + response = JSON.parse(response); + if (!response.length) response = await this.getAllJson(); + response.forEach((it, index) => { + if (index > 5) return; + if (!ids || ids.split(',').includes(it.id)) { + this.dataSource.push({ + id: it.id, + name: it.name, + image: it.image, + symbol: it.symbol.toUpperCase(), + current_price: '' + it.current_price, + high_24h: it.high_24h, + low_24h: it.low_24h, + price_change_percentage_24h: it.price_change_percentage_24h, + last_updated: it.last_updated, + }); + } + }); + this.settings.dataSource = this.dataSource; + this.saveSettings(false); + } catch (e) { + console.log(e); + return []; + } + }; + + transforBtcType = async (params = 'BTC,ETH,BNB') => { + const btcType = params.split(','); + const btcAll = await this.getAllJson(); + return btcType.map((item) => { + const result = btcAll.find((btc) => btc.symbol.toUpperCase() === item) || + {}; + return result.id; + }).filter((item) => !!item).join(','); + }; + + getAllJson = async () => { + const cachePath = this.FILE_MGR.joinPath( + this.FILE_MGR.libraryDirectory(), + `${Script.name()}/datas`, + ); + const filename = `${cachePath}/BTC.json`; + if (!this.FILE_MGR.fileExists(cachePath)) this.FILE_MGR.createDirectory( + cachePath, true); + + if (this.FILE_MGR.fileExists(filename)) { + const data = Data.fromFile(`${cachePath}/BTC.json`).toRawString(); + return JSON.parse(data); + } else { + const response = await this.$request.get( + `${this.endpoint}/coins/markets?vs_currency=usd&ids=`, + ); + const data = Data.fromString(JSON.stringify(response)); + this.FILE_MGR.write(filename, data); + return response; + } + }; + + renderImage = async (uri) => { + return this.$request.get(uri, 'IMG'); + }; + + notSupport(w) { + const stack = w.addStack(); + stack.addText('暂不支持'); + return w; + } + + getSmallBg = async (url) => { + const webview = new WebView(); + let js = `const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => { + const { width, height } = img + canvas.width = width + canvas.height = height + ctx.globalAlpha = 0.3 + ctx.drawImage( + img, + -width / 2 + 50, + -height / 2 + 50, + width, + height + ) + const uri = canvas.toDataURL() + completion(uri); + }; + img.src = 'data:image/png;base64,${Data.fromPNG(url).toBase64String()}'`; + let image = await webview.evaluateJavaScript(js, true); + image = image.replace(/^data\:image\/\w+;base64,/, ''); + return Image.fromData(Data.fromBase64String(image)); + }; + + renderSmall = async (widget) => { + const market = this.dataSource[0] || {}; + const image = await this.renderImage(market.image); + const backgroundImg = await this.getSmallBg(image); + widget.backgroundColor = this.backGroundColor; + widget.backgroundImage = backgroundImg; + widget.setPadding(12, 12, 12, 12); + const coin = widget.addText(market.symbol.toUpperCase()); + coin.font = Font.heavySystemFont(24); + coin.textColor = this.widgetColor; + + coin.rightAlignText(); + const name = widget.addText(market.name); + name.font = Font.systemFont(10); + name.textColor = Color.gray(); + name.rightAlignText(); + widget.addSpacer(); + + const trend = widget.addText( + `${market.price_change_percentage_24h.toFixed(2)}%`); + trend.font = Font.semiboldSystemFont(16); + trend.textColor = market.price_change_percentage_24h >= 0 + ? Color.green() + : Color.red(); + + trend.rightAlignText(); + const price = widget.addText(`$ ${market.current_price}`); + price.font = Font.boldSystemFont(28); + price.textColor = this.widgetColor; + price.rightAlignText(); + price.lineLimit = 1; + price.minimumScaleFactor = 0.1; + const history = widget.addText( + `H: ${market.high_24h}, L: ${market.low_24h}`); + history.font = Font.systemFont(10); + history.textColor = Color.gray(); + history.rightAlignText(); + history.lineLimit = 1; + history.minimumScaleFactor = 0.1; + return widget; + }; + + rowCell = async (rowStack, market) => { + rowStack.layoutHorizontally(); + const image = await this.renderImage(market.image); + const iconImage = rowStack.addImage(image); + iconImage.imageSize = new Size(28, 28); + iconImage.cornerRadius = 14; + + rowStack.addSpacer(10); + + const centerStack = rowStack.addStack(); + centerStack.layoutVertically(); + + const topCenterStack = centerStack.addStack(); + topCenterStack.layoutHorizontally(); + + const titleText = topCenterStack.addText(market.symbol); + titleText.textColor = this.widgetColor; + titleText.font = this.provideFont('heavy', 16); + + topCenterStack.addSpacer(); + + const priceText = topCenterStack.addText(`$ ${market.current_price}`); + priceText.textColor = this.widgetColor; + priceText.font = this.provideFont('heavy', 15); + priceText.rightAlignText(); + + const bottomCenterStack = centerStack.addStack(); + bottomCenterStack.layoutHorizontally(); + + const subText = bottomCenterStack.addText(market.name); + subText.textColor = Color.gray(); + subText.font = this.provideFont('semibold', 10); + + bottomCenterStack.addSpacer(); + + const historyText = bottomCenterStack.addText( + `H: ${market.high_24h}, L: ${market.low_24h}`); + historyText.textColor = Color.gray(); + historyText.font = this.provideFont('semibold', 10); + historyText.rightAlignText(); + + rowStack.addSpacer(8); + + const rateStack = rowStack.addStack(); + rateStack.size = new Size(72, 28); + rateStack.centerAlignContent(); + rateStack.cornerRadius = 4; + rateStack.backgroundColor = market.price_change_percentage_24h >= 0 + ? Color.green() + : Color.red(); + const rateText = rateStack.addText( + (market.price_change_percentage_24h >= 0 ? '+' : '') + + market.price_change_percentage_24h.toFixed(2) + '%'); + rateText.font = this.provideFont('heavy', 14); + rateText.minimumScaleFactor = 0.01; + rateText.lineLimit = 1; + }; + + renderLarge = async (widget) => { + widget.setPadding(12, 12, 12, 12); + const containerStack = widget.addStack(); + containerStack.layoutVertically(); + for (let index = 0; index < this.dataSource.length; index++) { + const item = this.dataSource[index]; + const rowCellStack = containerStack.addStack(); + await this.rowCell(rowCellStack, item); + if (index !== this.dataSource.length - 1) containerStack.addSpacer(); + } + return widget; + }; + + renderMedium = async (widget) => { + widget.setPadding(12, 12, 12, 12); + const containerStack = widget.addStack(); + containerStack.layoutVertically(); + for (let index = 0; index < this.dataSource.length; index++) { + if (index > 2) return; + const item = this.dataSource[index]; + const rowCellStack = containerStack.addStack(); + await this.rowCell(rowCellStack, item); + if (index !== 2) containerStack.addSpacer(); + } + return widget; + }; + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + if (this.widgetFamily === 'small') await this.renderSmall(widget); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') await this.renderMedium(widget); + if (this.widgetFamily === 'large') await this.renderLarge(widget); + return widget; + } +} + +// @组件代码结束 +await Runing(Widget, '', false); //远程开发环境 diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 062064e..283e7e7 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -38,12 +38,10 @@ class DmYY { try { if (type === 'IMG') { const fileName = `${this.cacheImage}/${this.md5(options.url)}`; - console.log(fileName); request = this.getRequest(options.url); let response; if (this.FILE_MGR.fileExists(fileName)) { request.loadImage().then((res) => { - console.log(res); this.FILE_MGR.writeImage(fileName, res); }); return Image.fromFile(fileName); diff --git a/install.json b/install.json index 0843d56..a8293cc 100644 --- a/install.json +++ b/install.json @@ -59,6 +59,12 @@ "html": [ "

    京东组件教程

    ", "

    " + ], + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } ] }, { @@ -88,7 +94,13 @@ "scriptURL": "https://raw.githubusercontent.com/dompling/scriptableTsx/master/scripts/BiliBili.js", "thumb": "https://raw.githubusercontent.com/Orz-3/mini/master/Color/bilibili.png", "name": "BiliBili", - "title": "今日番剧" + "title": "今日番剧", + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } + ] }, { "version": "1.0.0", @@ -124,7 +136,13 @@ "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/Calendar.js", "thumb": "https://img.icons8.com/clouds/344/edit-calendar.png", "name": "Calendar", - "title": "日历函数" + "title": "日历函数", + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } + ] }, { "version": "1.0.0", @@ -363,6 +381,12 @@ "
    ", "

    Mobile登陆地址接口:

    ", "
  • 请自行使用代理软件查看搜索即可,操作方式类似 PC 登陆地址的查看步骤
  • " + ], + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } ] }, { @@ -403,7 +427,13 @@ "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/Oild.js", "thumb": "https://img.icons8.com/clouds/344/engine-oil-level.png", "name": "TodayOilPrice", - "title": "今日油价" + "title": "今日油价", + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } + ] }, { "version": "1.0.0", @@ -411,7 +441,13 @@ "scriptURL": "https://raw.githubusercontent.com/dompling/scriptableTsx/master/scripts/COVID-19.js", "thumb": "https://img.icons8.com/clouds/344/coronavirus.png", "name": "COVID-19", - "title": "疫情日报" + "title": "疫情日报", + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } + ] }, { "version": "1.0.1", @@ -425,6 +461,12 @@ "v1.0.1", "
  • 调整大尺寸排列效果
  • ", "
  • 调整下班倒计时默认不开启
  • " + ], + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } ] }, { @@ -439,6 +481,31 @@ "
  • 获取Token重写:Surge 12123重写模块
  • ", "
  • 使用方法:配置重写规则,手动运行小组件,按提示跳转到 支付宝12123小程序 登录即可自动抓取/更新Token。
  • ", "
  • 使用前,请确保您的代理APP已配置好BoxJs重写,BoxJs配置方法:BoxJS教程
  • " + ], + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } + ] + }, + { + "version": "1.0.0", + "description": "比特币币种", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/BTC.js", + "thumb": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png", + "name": "BTC", + "title": "比特币", + "html": [ + "

    迁移自JSBox脚本

    ", + "
  • 原项目:wuzeyou/PriceWidgets
  • ", + "
  • 特别感谢大佬:@Jackie Xiang
  • " + ], + "depend": [ + { + "name": "DmYY", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/DmYY.js" + } ] } ] From 1b0a825c18d47ddfb309ee080f2b64919ba8885c Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 10 Nov 2022 16:27:19 +0800 Subject: [PATCH 072/152] =?UTF-8?q?add:=E5=A2=9E=E5=8A=A0=E6=AF=94?= =?UTF-8?q?=E7=89=B9=E5=B8=81=E7=A7=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/BTC.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Scripts/BTC.js b/Scripts/BTC.js index 94515e8..c9ce186 100644 --- a/Scripts/BTC.js +++ b/Scripts/BTC.js @@ -1,9 +1,6 @@ // Variables used by Scriptable. // These must be at the very top of the file. Do not edit. -// icon-color: deep-blue; icon-glyph: magic; -// Variables used by Scriptable. -// These must be at the very top of the file. Do not edit. -// icon-color: deep-gray; icon-glyph: car; +// icon-color: deep-blue; icon-glyph: dollar; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; From 57484fc4df24b645688cefa78b7ca87dcd648515 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 10 Nov 2022 16:34:12 +0800 Subject: [PATCH 073/152] =?UTF-8?q?update:=E6=9B=B4=E6=96=B0=E5=B0=8F?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E6=8F=8F=E8=BF=B0=E5=92=8C=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/{BTC.js => PriceWidgets.js} | 0 install.json | 8 ++++---- 2 files changed, 4 insertions(+), 4 deletions(-) rename Scripts/{BTC.js => PriceWidgets.js} (100%) diff --git a/Scripts/BTC.js b/Scripts/PriceWidgets.js similarity index 100% rename from Scripts/BTC.js rename to Scripts/PriceWidgets.js diff --git a/install.json b/install.json index a8293cc..20b105a 100644 --- a/install.json +++ b/install.json @@ -491,11 +491,11 @@ }, { "version": "1.0.0", - "description": "比特币币种", - "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/BTC.js", + "description": "币种涨幅", + "scriptURL": "https://raw.githubusercontent.com/dompling/Scriptable/master/Scripts/PriceWidgets.js", "thumb": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png", - "name": "BTC", - "title": "比特币", + "name": "PriceWidgets", + "title": "网络货币", "html": [ "

    迁移自JSBox脚本

    ", "
  • 原项目:wuzeyou/PriceWidgets
  • ", From 5597befc839e60aff780944bae8181dddd394070 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 10 Nov 2022 17:03:31 +0800 Subject: [PATCH 074/152] =?UTF-8?q?add:=E5=A2=9E=E5=8A=A0=E8=B4=A7?= =?UTF-8?q?=E5=B8=81=E8=B7=B3=E8=BD=AC=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/PriceWidgets.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Scripts/PriceWidgets.js b/Scripts/PriceWidgets.js index c9ce186..dab5737 100644 --- a/Scripts/PriceWidgets.js +++ b/Scripts/PriceWidgets.js @@ -147,6 +147,9 @@ class Widget extends DmYY { renderSmall = async (widget) => { const market = this.dataSource[0] || {}; + + widget.url = `https://www.coingecko.com/en/coins/${market.id}`; + const image = await this.renderImage(market.image); const backgroundImg = await this.getSmallBg(image); widget.backgroundColor = this.backGroundColor; @@ -188,6 +191,7 @@ class Widget extends DmYY { }; rowCell = async (rowStack, market) => { + rowStack.url = `https://www.coingecko.com/en/coins/${market.id}`; rowStack.layoutHorizontally(); const image = await this.renderImage(market.image); const iconImage = rowStack.addImage(image); From 319fd49f31312b130e72353960d056ff4ad12870 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 10 Nov 2022 17:23:21 +0800 Subject: [PATCH 075/152] =?UTF-8?q?fix:=E7=BD=91=E7=BB=9C=E8=B4=A7?= =?UTF-8?q?=E5=B8=81=E4=BF=AE=E5=A4=8D=E5=85=B3=E6=B3=A8=E7=A7=8D=E7=B1=BB?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/PriceWidgets.js | 90 ++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 32 deletions(-) diff --git a/Scripts/PriceWidgets.js b/Scripts/PriceWidgets.js index dab5737..557bf8b 100644 --- a/Scripts/PriceWidgets.js +++ b/Scripts/PriceWidgets.js @@ -4,7 +4,7 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { @@ -13,15 +13,15 @@ class Widget extends DmYY { this.en = ' btc'; this.name = '比特币'; config.runsInApp && - this.registerAction( + this.registerAction( '关注种类', async () => { return this.setAlertInput('比特币种类', '设置关注种类', { btcType: 'BTC,ETH,BNB', }); }, - {name: 'centsign.circle', color: '#feda31'}, - ); + { name: 'centsign.circle', color: '#feda31' } + ); config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); } @@ -47,14 +47,33 @@ class Widget extends DmYY { try { const ids = await this.transforBtcType(params); let response = await this.$request.get( - `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}` - , 'STRING'); + `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}`, + 'STRING' + ); this.dataSource = []; response = JSON.parse(response); if (!response.length) response = await this.getAllJson(); - response.forEach((it, index) => { - if (index > 5) return; - if (!ids || ids.split(',').includes(it.id)) { + if (ids) { + const idsData = ids.split(','); + idsData.forEach((id) => { + const it = response.find((item) => item.id === id); + if (it && this.dataSource.length < 6) { + this.dataSource.push({ + id: it.id, + name: it.name, + image: it.image, + symbol: it.symbol.toUpperCase(), + current_price: '' + it.current_price, + high_24h: it.high_24h, + low_24h: it.low_24h, + price_change_percentage_24h: it.price_change_percentage_24h, + last_updated: it.last_updated, + }); + } + }); + } else { + response.forEach((it, index) => { + if (index > 5) return; this.dataSource.push({ id: it.id, name: it.name, @@ -66,8 +85,9 @@ class Widget extends DmYY { price_change_percentage_24h: it.price_change_percentage_24h, last_updated: it.last_updated, }); - } - }); + }); + } + this.settings.dataSource = this.dataSource; this.saveSettings(false); } catch (e) { @@ -79,28 +99,31 @@ class Widget extends DmYY { transforBtcType = async (params = 'BTC,ETH,BNB') => { const btcType = params.split(','); const btcAll = await this.getAllJson(); - return btcType.map((item) => { - const result = btcAll.find((btc) => btc.symbol.toUpperCase() === item) || - {}; - return result.id; - }).filter((item) => !!item).join(','); + return btcType + .map((item) => { + const result = + btcAll.find((btc) => btc.symbol.toUpperCase() === item) || {}; + return result.id; + }) + .filter((item) => !!item) + .join(','); }; getAllJson = async () => { const cachePath = this.FILE_MGR.joinPath( - this.FILE_MGR.libraryDirectory(), - `${Script.name()}/datas`, + this.FILE_MGR.libraryDirectory(), + `${Script.name()}/datas` ); const filename = `${cachePath}/BTC.json`; - if (!this.FILE_MGR.fileExists(cachePath)) this.FILE_MGR.createDirectory( - cachePath, true); + if (!this.FILE_MGR.fileExists(cachePath)) + this.FILE_MGR.createDirectory(cachePath, true); if (this.FILE_MGR.fileExists(filename)) { const data = Data.fromFile(`${cachePath}/BTC.json`).toRawString(); return JSON.parse(data); } else { const response = await this.$request.get( - `${this.endpoint}/coins/markets?vs_currency=usd&ids=`, + `${this.endpoint}/coins/markets?vs_currency=usd&ids=` ); const data = Data.fromString(JSON.stringify(response)); this.FILE_MGR.write(filename, data); @@ -167,11 +190,11 @@ class Widget extends DmYY { widget.addSpacer(); const trend = widget.addText( - `${market.price_change_percentage_24h.toFixed(2)}%`); + `${market.price_change_percentage_24h.toFixed(2)}%` + ); trend.font = Font.semiboldSystemFont(16); - trend.textColor = market.price_change_percentage_24h >= 0 - ? Color.green() - : Color.red(); + trend.textColor = + market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); trend.rightAlignText(); const price = widget.addText(`$ ${market.current_price}`); @@ -181,7 +204,8 @@ class Widget extends DmYY { price.lineLimit = 1; price.minimumScaleFactor = 0.1; const history = widget.addText( - `H: ${market.high_24h}, L: ${market.low_24h}`); + `H: ${market.high_24h}, L: ${market.low_24h}` + ); history.font = Font.systemFont(10); history.textColor = Color.gray(); history.rightAlignText(); @@ -227,7 +251,8 @@ class Widget extends DmYY { bottomCenterStack.addSpacer(); const historyText = bottomCenterStack.addText( - `H: ${market.high_24h}, L: ${market.low_24h}`); + `H: ${market.high_24h}, L: ${market.low_24h}` + ); historyText.textColor = Color.gray(); historyText.font = this.provideFont('semibold', 10); historyText.rightAlignText(); @@ -238,12 +263,13 @@ class Widget extends DmYY { rateStack.size = new Size(72, 28); rateStack.centerAlignContent(); rateStack.cornerRadius = 4; - rateStack.backgroundColor = market.price_change_percentage_24h >= 0 - ? Color.green() - : Color.red(); + rateStack.backgroundColor = + market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); const rateText = rateStack.addText( - (market.price_change_percentage_24h >= 0 ? '+' : '') + - market.price_change_percentage_24h.toFixed(2) + '%'); + (market.price_change_percentage_24h >= 0 ? '+' : '') + + market.price_change_percentage_24h.toFixed(2) + + '%' + ); rateText.font = this.provideFont('heavy', 14); rateText.minimumScaleFactor = 0.01; rateText.lineLimit = 1; From 241248bb0e611ddda62d9f3edf4d93ff15f571af Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Fri, 11 Nov 2022 09:20:33 +0800 Subject: [PATCH 076/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E8=B4=A7=E5=B8=81=E8=AF=B7=E6=B1=82=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/PriceWidgets.js | 55 ++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/Scripts/PriceWidgets.js b/Scripts/PriceWidgets.js index 557bf8b..6a572c4 100644 --- a/Scripts/PriceWidgets.js +++ b/Scripts/PriceWidgets.js @@ -4,7 +4,7 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; -const { DmYY, Runing } = require('./DmYY'); +const {DmYY, Runing} = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { @@ -13,15 +13,15 @@ class Widget extends DmYY { this.en = ' btc'; this.name = '比特币'; config.runsInApp && - this.registerAction( + this.registerAction( '关注种类', async () => { return this.setAlertInput('比特币种类', '设置关注种类', { btcType: 'BTC,ETH,BNB', }); }, - { name: 'centsign.circle', color: '#feda31' } - ); + {name: 'centsign.circle', color: '#feda31'}, + ); config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); } @@ -43,12 +43,12 @@ class Widget extends DmYY { this.cacheData(this.settings.btcType); }; - cacheData = async (params = '') => { + cacheData = async (params) => { try { const ids = await this.transforBtcType(params); let response = await this.$request.get( - `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}`, - 'STRING' + `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}`, + 'STRING', ); this.dataSource = []; response = JSON.parse(response); @@ -96,23 +96,26 @@ class Widget extends DmYY { } }; - transforBtcType = async (params = 'BTC,ETH,BNB') => { - const btcType = params.split(','); + transforBtcType = async (params) => { + let btcType; + if (params) btcType = params.split(','); + const btcAll = await this.getAllJson(); - return btcType - .map((item) => { - const result = + + if (!btcType) return btcAll.filter((item, index) => index < 6).map( + item => item.id).join(','); + + return btcType.map((item) => { + const result = btcAll.find((btc) => btc.symbol.toUpperCase() === item) || {}; - return result.id; - }) - .filter((item) => !!item) - .join(','); + return result.id; + }).filter((item) => !!item).join(','); }; getAllJson = async () => { const cachePath = this.FILE_MGR.joinPath( - this.FILE_MGR.libraryDirectory(), - `${Script.name()}/datas` + this.FILE_MGR.libraryDirectory(), + `${Script.name()}/datas`, ); const filename = `${cachePath}/BTC.json`; if (!this.FILE_MGR.fileExists(cachePath)) @@ -123,7 +126,7 @@ class Widget extends DmYY { return JSON.parse(data); } else { const response = await this.$request.get( - `${this.endpoint}/coins/markets?vs_currency=usd&ids=` + `${this.endpoint}/coins/markets?vs_currency=usd&ids=`, ); const data = Data.fromString(JSON.stringify(response)); this.FILE_MGR.write(filename, data); @@ -190,11 +193,11 @@ class Widget extends DmYY { widget.addSpacer(); const trend = widget.addText( - `${market.price_change_percentage_24h.toFixed(2)}%` + `${market.price_change_percentage_24h.toFixed(2)}%`, ); trend.font = Font.semiboldSystemFont(16); trend.textColor = - market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); + market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); trend.rightAlignText(); const price = widget.addText(`$ ${market.current_price}`); @@ -204,7 +207,7 @@ class Widget extends DmYY { price.lineLimit = 1; price.minimumScaleFactor = 0.1; const history = widget.addText( - `H: ${market.high_24h}, L: ${market.low_24h}` + `H: ${market.high_24h}, L: ${market.low_24h}`, ); history.font = Font.systemFont(10); history.textColor = Color.gray(); @@ -251,7 +254,7 @@ class Widget extends DmYY { bottomCenterStack.addSpacer(); const historyText = bottomCenterStack.addText( - `H: ${market.high_24h}, L: ${market.low_24h}` + `H: ${market.high_24h}, L: ${market.low_24h}`, ); historyText.textColor = Color.gray(); historyText.font = this.provideFont('semibold', 10); @@ -264,11 +267,11 @@ class Widget extends DmYY { rateStack.centerAlignContent(); rateStack.cornerRadius = 4; rateStack.backgroundColor = - market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); + market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); const rateText = rateStack.addText( - (market.price_change_percentage_24h >= 0 ? '+' : '') + + (market.price_change_percentage_24h >= 0 ? '+' : '') + market.price_change_percentage_24h.toFixed(2) + - '%' + '%', ); rateText.font = this.provideFont('heavy', 14); rateText.minimumScaleFactor = 0.01; From 1dc57176c3dc5e9af70dcfa01aec4877e5a132bc Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Fri, 11 Nov 2022 09:21:41 +0800 Subject: [PATCH 077/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E8=B4=A7=E5=B8=81=E8=AF=B7=E6=B1=82=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 283e7e7..4db8c1c 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -847,8 +847,6 @@ class DmYY { this.settings = this.getSettings(); this.settings = { ...this.defaultSettings, ...this.settings }; - - console.log(this.settings); this.settings.lightColor = this.settings.lightColor || '#000000'; this.settings.darkColor = this.settings.darkColor || '#ffffff'; From 1b16ec900cdf4d0a2c5c7a952829cefd1a2ccd0d Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Fri, 11 Nov 2022 09:31:49 +0800 Subject: [PATCH 078/152] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=201213=20?= =?UTF-8?q?=E6=9C=AA=E6=89=93=E5=BC=80=20vpn=20=E6=97=B6=E5=80=99=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E9=80=9A=E7=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index 0319af5..34a9b72 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -4,7 +4,7 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; -const { DmYY, Runing } = require('./DmYY'); +const {DmYY, Runing} = require('./DmYY'); const API_PARAMS = { api4: 'biz.vio.detail.query', @@ -14,7 +14,7 @@ const API_PARAMS = { alipay: 'alipays://platformapi/startapp?appId=2019050964403523', api2: 'biz.vio.peccancyChannelList.query', status: - 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', + 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', update: 'https://gitcode.net/4qiao/scriptable/raw/master/api/violation.js', api3: 'biz.vio.peccancyUnhandleInfoList.query', Ver: 'Version 1.2\n\nverifyToken过期需打开Quantumult-X', @@ -32,18 +32,19 @@ class Widget extends DmYY { this.en = '12123'; this.name = '交管 12123'; config.runsInApp && - this.registerAction( + this.registerAction( 'Token', async () => { const token = this.settings.token; - this.settings.token = (await this.getCache('wx_12123')) || token; + this.settings.token = (await this.getCache('wx_12123', false)) || + token; if (this.settings.token) this.saveSettings(false); return this.setAlertInput('Token', '设置 token', { token: '微信小程序交管12123获取', }); }, - { name: 'paperplane', color: '#722ed1' } - ); + {name: 'paperplane', color: '#722ed1'}, + ); config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); } @@ -64,25 +65,25 @@ class Widget extends DmYY { title: '川 G88888', icon: 'car.fill', listItem: [ - { label: '未处违法', value: `0`, unit: '条' }, - { label: '车辆状态', value: '正常' }, - { label: '上次更新', value: '00:00' }, + {label: '未处违法', value: `0`, unit: '条'}, + {label: '车辆状态', value: '正常'}, + {label: '上次更新', value: '00:00'}, ], }, right: { title: '驾驶证', icon: 'creditcard.fill', listItem: [ - { label: '证件状态', value: '正常' }, - { label: '累计扣分', value: `0`, unit: '分' }, - { label: '重置日期', value: '—' }, + {label: '证件状态', value: '正常'}, + {label: '累计扣分', value: `0`, unit: '分'}, + {label: '重置日期', value: '—'}, ], }, }; init = async () => { this.settings.token = - (await this.getCache('wx_12123')) || this.settings.token; + (await this.getCache('wx_12123', false)) || this.settings.token; if (this.settings.dataSource) { this.dataSource = this.settings.dataSource; } else { @@ -116,22 +117,22 @@ class Widget extends DmYY { const details = await this.$request.post(API_PARAMS.infoURL, { body: `params=${encodeURIComponent( - JSON.stringify({ - api: 'biz.user.integration.query', - productId: API_PARAMS.productId, - ...params, - }) + JSON.stringify({ + api: 'biz.user.integration.query', + productId: API_PARAMS.productId, + ...params, + }), )}`, }); console.log(details); if (details.success) { - const { drivingLicense, vehicles } = details.data; + const {drivingLicense, vehicles} = details.data; const reaccDate = drivingLicense.reaccDate.split('-'); this.dataSource.right.title = `驾驶证 ${drivingLicense.allowToDrive}`; this.dataSource.right.listItem[1].value = - drivingLicense.cumulativePoint; + drivingLicense.cumulativePoint; this.dataSource.right.listItem[2].value = `${reaccDate[1]}-${reaccDate[2]}`; if (vehicles.length) { @@ -145,9 +146,9 @@ class Widget extends DmYY { this.saveSettings(false); } else { this.notify( - `verifyToken已过期 ⚠️`, - '点击通知框自动跳转到支付宝小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', - API_PARAMS.alipay + `verifyToken已过期 ⚠️`, + '点击通知框自动跳转到支付宝小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', + API_PARAMS.alipay, ); } } catch (e) { From eb788a5acfecd2ec7ed277ef0fe111763c4705ca Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 23 Nov 2022 17:05:19 +0800 Subject: [PATCH 079/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/PriceWidgets.js | 59 +++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/Scripts/PriceWidgets.js b/Scripts/PriceWidgets.js index 6a572c4..2ec32a4 100644 --- a/Scripts/PriceWidgets.js +++ b/Scripts/PriceWidgets.js @@ -4,7 +4,7 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { @@ -13,15 +13,15 @@ class Widget extends DmYY { this.en = ' btc'; this.name = '比特币'; config.runsInApp && - this.registerAction( + this.registerAction( '关注种类', async () => { return this.setAlertInput('比特币种类', '设置关注种类', { btcType: 'BTC,ETH,BNB', }); }, - {name: 'centsign.circle', color: '#feda31'}, - ); + { name: 'centsign.circle', color: '#feda31' } + ); config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); } @@ -47,8 +47,8 @@ class Widget extends DmYY { try { const ids = await this.transforBtcType(params); let response = await this.$request.get( - `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}`, - 'STRING', + `${this.endpoint}/coins/markets?vs_currency=usd&ids=${ids}`, + 'STRING' ); this.dataSource = []; response = JSON.parse(response); @@ -102,20 +102,26 @@ class Widget extends DmYY { const btcAll = await this.getAllJson(); - if (!btcType) return btcAll.filter((item, index) => index < 6).map( - item => item.id).join(','); + if (!btcType) + return btcAll + .filter((item, index) => index < 6) + .map((item) => item.id) + .join(','); - return btcType.map((item) => { - const result = + return btcType + .map((item) => { + const result = btcAll.find((btc) => btc.symbol.toUpperCase() === item) || {}; - return result.id; - }).filter((item) => !!item).join(','); + return result.id; + }) + .filter((item) => !!item) + .join(','); }; getAllJson = async () => { const cachePath = this.FILE_MGR.joinPath( - this.FILE_MGR.libraryDirectory(), - `${Script.name()}/datas`, + this.FILE_MGR.libraryDirectory(), + `${Script.name()}/datas` ); const filename = `${cachePath}/BTC.json`; if (!this.FILE_MGR.fileExists(cachePath)) @@ -126,7 +132,7 @@ class Widget extends DmYY { return JSON.parse(data); } else { const response = await this.$request.get( - `${this.endpoint}/coins/markets?vs_currency=usd&ids=`, + `${this.endpoint}/coins/markets?vs_currency=usd&ids=` ); const data = Data.fromString(JSON.stringify(response)); this.FILE_MGR.write(filename, data); @@ -193,11 +199,11 @@ class Widget extends DmYY { widget.addSpacer(); const trend = widget.addText( - `${market.price_change_percentage_24h.toFixed(2)}%`, + `${market.price_change_percentage_24h.toFixed(2)}%` ); trend.font = Font.semiboldSystemFont(16); trend.textColor = - market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); + market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); trend.rightAlignText(); const price = widget.addText(`$ ${market.current_price}`); @@ -207,7 +213,7 @@ class Widget extends DmYY { price.lineLimit = 1; price.minimumScaleFactor = 0.1; const history = widget.addText( - `H: ${market.high_24h}, L: ${market.low_24h}`, + `H: ${market.high_24h}, L: ${market.low_24h}` ); history.font = Font.systemFont(10); history.textColor = Color.gray(); @@ -218,7 +224,7 @@ class Widget extends DmYY { }; rowCell = async (rowStack, market) => { - rowStack.url = `https://www.coingecko.com/en/coins/${market.id}`; + rowStack.url = `https://www.coingecko.com/zh/coins/${market.id}`; rowStack.layoutHorizontally(); const image = await this.renderImage(market.image); const iconImage = rowStack.addImage(image); @@ -235,13 +241,13 @@ class Widget extends DmYY { const titleText = topCenterStack.addText(market.symbol); titleText.textColor = this.widgetColor; - titleText.font = this.provideFont('heavy', 16); + titleText.font = this.provideFont('semibold', 16); topCenterStack.addSpacer(); const priceText = topCenterStack.addText(`$ ${market.current_price}`); priceText.textColor = this.widgetColor; - priceText.font = this.provideFont('heavy', 15); + priceText.font = this.provideFont('semibold', 15); priceText.rightAlignText(); const bottomCenterStack = centerStack.addStack(); @@ -254,7 +260,7 @@ class Widget extends DmYY { bottomCenterStack.addSpacer(); const historyText = bottomCenterStack.addText( - `H: ${market.high_24h}, L: ${market.low_24h}`, + `H: ${market.high_24h}, L: ${market.low_24h}` ); historyText.textColor = Color.gray(); historyText.font = this.provideFont('semibold', 10); @@ -267,13 +273,14 @@ class Widget extends DmYY { rateStack.centerAlignContent(); rateStack.cornerRadius = 4; rateStack.backgroundColor = - market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); + market.price_change_percentage_24h >= 0 ? Color.green() : Color.red(); const rateText = rateStack.addText( - (market.price_change_percentage_24h >= 0 ? '+' : '') + + (market.price_change_percentage_24h >= 0 ? '+' : '') + market.price_change_percentage_24h.toFixed(2) + - '%', + '%' ); - rateText.font = this.provideFont('heavy', 14); + rateText.textColor = new Color('#fff', 0.9); + rateText.font = this.provideFont('semibold', 14); rateText.minimumScaleFactor = 0.01; rateText.lineLimit = 1; }; From 9e7469e5d78fbdf2e1723be5057b03d28d004281 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 7 Dec 2022 11:54:38 +0800 Subject: [PATCH 080/152] =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CalendarFnc.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 Scripts/CalendarFnc.js diff --git a/Scripts/CalendarFnc.js b/Scripts/CalendarFnc.js new file mode 100644 index 0000000..c4ed6d0 --- /dev/null +++ b/Scripts/CalendarFnc.js @@ -0,0 +1 @@ +new (class{lunarInfo=[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,0x0d520,];solarMonth=[31,28,31,30,31,30,31,31,30,31,30,31];Gan=['\u7532','\u4e59','\u4e19','\u4e01','\u620a','\u5df1','\u5e9a','\u8f9b','\u58ec','\u7678',];Zhi=['\u5b50','\u4e11','\u5bc5','\u536f','\u8fb0','\u5df3','\u5348','\u672a','\u7533','\u9149','\u620c','\u4ea5',];Animals=['\u9f20','\u725b','\u864e','\u5154','\u9f99','\u86c7','\u9a6c','\u7f8a','\u7334','\u9e21','\u72d7','\u732a',];solarTerm=['\u5c0f\u5bd2','\u5927\u5bd2','\u7acb\u6625','\u96e8\u6c34','\u60ca\u86f0','\u6625\u5206','\u6e05\u660e','\u8c37\u96e8','\u7acb\u590f','\u5c0f\u6ee1','\u8292\u79cd','\u590f\u81f3','\u5c0f\u6691','\u5927\u6691','\u7acb\u79cb','\u5904\u6691','\u767d\u9732','\u79cb\u5206','\u5bd2\u9732','\u971c\u964d','\u7acb\u51ac','\u5c0f\u96ea','\u5927\u96ea','\u51ac\u81f3',];sTermInfo=['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e','97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e','97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd','7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',];nStr1=['\u65e5','\u4e00','\u4e8c','\u4e09','\u56db','\u4e94','\u516d','\u4e03','\u516b','\u4e5d','\u5341',];nStr2=['\u521d','\u5341','\u5eff','\u5345'];nStr3=['\u6b63','\u4e8c','\u4e09','\u56db','\u4e94','\u516d','\u4e03','\u516b','\u4e5d','\u5341','\u51ac','\u814a',];lYearDays=(y)=>{let i,sum=348;for(i=0x8000;i>0x8;i>>=1){sum+=this.lunarInfo[y-1900]&i?1:0}return sum+this.leapDays(y)};leapMonth=(y)=>{return this.lunarInfo[y-1900]&0xf};leapDays=(y)=>{if(this.leapMonth(y)){return this.lunarInfo[y-1900]&0x10000?30:29}return 0};monthDays=(y,m)=>{if(m>12||m<1){return-1}return this.lunarInfo[y-1900]&(0x10000>>m)?30:29};solarDays=(y,m)=>{if(m>12||m<1){return-1}let ms=m-1;if(ms==1){return(y%4==0&&y%100!=0)||y%400==0?29:28}else{return this.solarMonth[ms]}};toGanZhiYear=(lYear)=>{let ganKey=(lYear-3)%10;let zhiKey=(lYear-3)%12;if(ganKey==0)ganKey=10;if(zhiKey==0)zhiKey=12;return this.Gan[ganKey-1]+this.Zhi[zhiKey-1]};toAstro=(cMonth,cDay)=>{let s='\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf';let arr=[20,19,21,21,21,22,23,23,23,23,22,22];return(s.substr(cMonth*2-(cDay{return this.Gan[offset%10]+this.Zhi[offset%12]};getTerm=(y,n)=>{if(y<1900||y>2100){return-1}if(n<1||n>24){return-1}let _table=this.sTermInfo[y-1900];let _info=[parseInt('0x'+_table.substr(0,5)).toString(),parseInt('0x'+_table.substr(5,5)).toString(),parseInt('0x'+_table.substr(10,5)).toString(),parseInt('0x'+_table.substr(15,5)).toString(),parseInt('0x'+_table.substr(20,5)).toString(),parseInt('0x'+_table.substr(25,5)).toString(),];let _calday=[_info[0].substr(0,1),_info[0].substr(1,2),_info[0].substr(3,1),_info[0].substr(4,2),_info[1].substr(0,1),_info[1].substr(1,2),_info[1].substr(3,1),_info[1].substr(4,2),_info[2].substr(0,1),_info[2].substr(1,2),_info[2].substr(3,1),_info[2].substr(4,2),_info[3].substr(0,1),_info[3].substr(1,2),_info[3].substr(3,1),_info[3].substr(4,2),_info[4].substr(0,1),_info[4].substr(1,2),_info[4].substr(3,1),_info[4].substr(4,2),_info[5].substr(0,1),_info[5].substr(1,2),_info[5].substr(3,1),_info[5].substr(4,2),];return parseInt(_calday[n-1])};toChinaMonth=(m)=>{if(m>12||m<1){return-1}let s=this.nStr3[m-1];s+='\u6708';return s};toChinaDay=(d)=>{let s;switch(d){case 10:s='\u521d\u5341';break;case 20:s='\u4e8c\u5341';break;case 30:s='\u4e09\u5341';break;default:s=this.nStr2[Math.floor(d/10)];s+=this.nStr1[d%10]}return s};getAnimal=(y)=>{return this.Animals[(y-4)%12]};solar2lunar=(_y,_m,_d)=>{if(_y<1900||_y>2100){return-1}if(_y==1900&&_m==1&&_d<31){return-1}let objDate;if(!_y){objDate=new Date()}else{objDate=new Date(_y,parseInt(_m)-1,_d)}let i,leap=0,temp=0;let y=objDate.getFullYear(),m=objDate.getMonth()+1,d=objDate.getDate();let offset=(Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate())-Date.UTC(1900,0,31))/86400000;for(i=1900;i<2101&&offset>0;i++){temp=this.lYearDays(i);offset-=temp}if(offset<0){offset+=temp;i--}let isTodayObj=new Date(),isToday=false;if(isTodayObj.getFullYear()==y&&isTodayObj.getMonth()+1==m&&isTodayObj.getDate()==d){isToday=true}let nWeek=objDate.getDay(),cWeek=this.nStr1[nWeek];if(nWeek==0){nWeek=7}let year=i;leap=this.leapMonth(i);let isLeap=false;for(i=1;i<13&&offset>0;i++){if(leap>0&&i==leap+1&&isLeap==false){--i;isLeap=true;temp=this.leapDays(year)}else{temp=this.monthDays(year,i)}if(isLeap==true&&i==leap+1){isLeap=false}offset-=temp}if(offset==0&&leap>0&&i==leap+1){if(isLeap){isLeap=false}else{isLeap=true;--i}}if(offset<0){offset+=temp;--i}let month=i;let day=offset+1;let sm=m-1;let gzY=this.toGanZhiYear(year);let firstNode=this.getTerm(y,m*2-1);let secondNode=this.getTerm(y,m*2);let gzM=this.toGanZhi((y-1900)*12+m+11);if(d>=firstNode){gzM=this.toGanZhi((y-1900)*12+m+12)}let isTerm=false;let Term=null;if(firstNode==d){isTerm=true;Term=this.solarTerm[m*2-2]}if(secondNode==d){isTerm=true;Term=this.solarTerm[m*2-1]}let dayCyclical=Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;let gzD=this.toGanZhi(dayCyclical+d-1);let astro=this.toAstro(m,d);return{lYear:year,lMonth:month,lDay:day,Animal:this.getAnimal(year),IMonthCn:(isLeap?'\u95f0':'')+this.toChinaMonth(month),IDayCn:this.toChinaDay(day),cYear:y,cMonth:m,cDay:d,gzYear:gzY,gzMonth:gzM,gzDay:gzD,isToday:isToday,isLeap:isLeap,nWeek:nWeek,ncWeek:'\u661f\u671f'+cWeek,isTerm:isTerm,Term:Term,astro:astro,}};lunar2solar=(y,m,d,_isLeapMonth)=>{let isLeapMonth=!!_isLeapMonth;let leapMonth=this.leapMonth(y);if(isLeapMonth&&leapMonth!=m){return-1}if((y==2100&&m==12&&d>1)||(y==1900&&m==1&&d<31)){return-1}let day=this.monthDays(y,m);let _day=day;if(isLeapMonth){_day=this.leapDays(y,m)}if(y<1900||y>2100||d>_day){return-1}let offset=0;for(let i=1900;i0){offset+=this.leapDays(y);isAdd=true}}offset+=this.monthDays(y,i)}if(isLeapMonth){offset+=day}let stmap=Date.UTC(1900,1,30,0,0,0);let calObj=new Date((offset+d-31)*86400000+stmap);let cY=calObj.getUTCFullYear();let cM=calObj.getUTCMonth()+1;let cD=calObj.getUTCDate();return this.solar2lunar(cY,cM,cD)};birthday=(config)=>{let y=parseInt(config.year),m=parseInt(config.month),d=parseInt(config.day),nongli=config.nongli,isLeapMonth=config.isLeapMonth;let date;let now=new Date();if(nongli){let now_d=this.solar2lunar(now.getFullYear(),now.getMonth()+1,now.getDate());let now_year=now_d.lYear;date=this.birthBylunar(now_year,m,d,isLeapMonth);if(this.daysBetween(date)<=0){now_year++;date=this.birthBylunar(now_year,m,d,isLeapMonth)}}else{let now_year=now.getFullYear();date=this.solar2lunar(now_year,m,d);if(this.daysBetween(date)<=0){now_year++;date=this.solar2lunar(now_year,m,d)}}let result=[date,this.daysBetween(date)];return result};birthBylunar=(y,m,d,isLeapMonth)=>{if(isLeapMonth&&this.leapMonth(y)==m){d=this.lunar2solar(y,m,d,isLeapMonth)}else{d=this.lunar2solar(y,m,d,false)}return d};daysBetween=(d)=>{let now=new Date();let date=new Date(d.cYear,d.cMonth-1,d.cDay);return parseInt((date.getTime()-now.getTime())/(24*3600*1000))};getAstroToEmoji=(astro)=>{const data={白羊座:'♈',金牛座:'♉',双子座:'♊',巨蟹座:'♋',狮子座:'♌',处女座:'♍',天秤座:'♎',天蝎座:'♏',射手座:'♐',摩羯座:'♑',水瓶座:'♒',双鱼座:'♓',蛇夫座:'⛎',};return data[astro]||''};getAnimalZodiacToEmoji=(zodiac)=>{const data={鼠:'🐭',牛:'🐂',虎:'🐯',兔:'🐇',龙:'🐲',蛇:'🐍',马:'🐴',羊:'🐑',猴:'🐵',鸡:'🐔',狗:'🐶',猪:'🐷',};return data[zodiac]||''};verifyTime(date){let dateFormat=/^(\d{4})-(\d{1,2})-(\d{1,2})$/;return dateFormat.test(date)}})() \ No newline at end of file From e67dd85b5ec292ffcdd335ba4c2b17275eb187fc Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 7 Dec 2022 12:03:18 +0800 Subject: [PATCH 081/152] =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CalendarFnc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/CalendarFnc.js b/Scripts/CalendarFnc.js index c4ed6d0..a8b5f21 100644 --- a/Scripts/CalendarFnc.js +++ b/Scripts/CalendarFnc.js @@ -1 +1 @@ -new (class{lunarInfo=[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,0x0d520,];solarMonth=[31,28,31,30,31,30,31,31,30,31,30,31];Gan=['\u7532','\u4e59','\u4e19','\u4e01','\u620a','\u5df1','\u5e9a','\u8f9b','\u58ec','\u7678',];Zhi=['\u5b50','\u4e11','\u5bc5','\u536f','\u8fb0','\u5df3','\u5348','\u672a','\u7533','\u9149','\u620c','\u4ea5',];Animals=['\u9f20','\u725b','\u864e','\u5154','\u9f99','\u86c7','\u9a6c','\u7f8a','\u7334','\u9e21','\u72d7','\u732a',];solarTerm=['\u5c0f\u5bd2','\u5927\u5bd2','\u7acb\u6625','\u96e8\u6c34','\u60ca\u86f0','\u6625\u5206','\u6e05\u660e','\u8c37\u96e8','\u7acb\u590f','\u5c0f\u6ee1','\u8292\u79cd','\u590f\u81f3','\u5c0f\u6691','\u5927\u6691','\u7acb\u79cb','\u5904\u6691','\u767d\u9732','\u79cb\u5206','\u5bd2\u9732','\u971c\u964d','\u7acb\u51ac','\u5c0f\u96ea','\u5927\u96ea','\u51ac\u81f3',];sTermInfo=['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e','97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e','97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd','7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',];nStr1=['\u65e5','\u4e00','\u4e8c','\u4e09','\u56db','\u4e94','\u516d','\u4e03','\u516b','\u4e5d','\u5341',];nStr2=['\u521d','\u5341','\u5eff','\u5345'];nStr3=['\u6b63','\u4e8c','\u4e09','\u56db','\u4e94','\u516d','\u4e03','\u516b','\u4e5d','\u5341','\u51ac','\u814a',];lYearDays=(y)=>{let i,sum=348;for(i=0x8000;i>0x8;i>>=1){sum+=this.lunarInfo[y-1900]&i?1:0}return sum+this.leapDays(y)};leapMonth=(y)=>{return this.lunarInfo[y-1900]&0xf};leapDays=(y)=>{if(this.leapMonth(y)){return this.lunarInfo[y-1900]&0x10000?30:29}return 0};monthDays=(y,m)=>{if(m>12||m<1){return-1}return this.lunarInfo[y-1900]&(0x10000>>m)?30:29};solarDays=(y,m)=>{if(m>12||m<1){return-1}let ms=m-1;if(ms==1){return(y%4==0&&y%100!=0)||y%400==0?29:28}else{return this.solarMonth[ms]}};toGanZhiYear=(lYear)=>{let ganKey=(lYear-3)%10;let zhiKey=(lYear-3)%12;if(ganKey==0)ganKey=10;if(zhiKey==0)zhiKey=12;return this.Gan[ganKey-1]+this.Zhi[zhiKey-1]};toAstro=(cMonth,cDay)=>{let s='\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf';let arr=[20,19,21,21,21,22,23,23,23,23,22,22];return(s.substr(cMonth*2-(cDay{return this.Gan[offset%10]+this.Zhi[offset%12]};getTerm=(y,n)=>{if(y<1900||y>2100){return-1}if(n<1||n>24){return-1}let _table=this.sTermInfo[y-1900];let _info=[parseInt('0x'+_table.substr(0,5)).toString(),parseInt('0x'+_table.substr(5,5)).toString(),parseInt('0x'+_table.substr(10,5)).toString(),parseInt('0x'+_table.substr(15,5)).toString(),parseInt('0x'+_table.substr(20,5)).toString(),parseInt('0x'+_table.substr(25,5)).toString(),];let _calday=[_info[0].substr(0,1),_info[0].substr(1,2),_info[0].substr(3,1),_info[0].substr(4,2),_info[1].substr(0,1),_info[1].substr(1,2),_info[1].substr(3,1),_info[1].substr(4,2),_info[2].substr(0,1),_info[2].substr(1,2),_info[2].substr(3,1),_info[2].substr(4,2),_info[3].substr(0,1),_info[3].substr(1,2),_info[3].substr(3,1),_info[3].substr(4,2),_info[4].substr(0,1),_info[4].substr(1,2),_info[4].substr(3,1),_info[4].substr(4,2),_info[5].substr(0,1),_info[5].substr(1,2),_info[5].substr(3,1),_info[5].substr(4,2),];return parseInt(_calday[n-1])};toChinaMonth=(m)=>{if(m>12||m<1){return-1}let s=this.nStr3[m-1];s+='\u6708';return s};toChinaDay=(d)=>{let s;switch(d){case 10:s='\u521d\u5341';break;case 20:s='\u4e8c\u5341';break;case 30:s='\u4e09\u5341';break;default:s=this.nStr2[Math.floor(d/10)];s+=this.nStr1[d%10]}return s};getAnimal=(y)=>{return this.Animals[(y-4)%12]};solar2lunar=(_y,_m,_d)=>{if(_y<1900||_y>2100){return-1}if(_y==1900&&_m==1&&_d<31){return-1}let objDate;if(!_y){objDate=new Date()}else{objDate=new Date(_y,parseInt(_m)-1,_d)}let i,leap=0,temp=0;let y=objDate.getFullYear(),m=objDate.getMonth()+1,d=objDate.getDate();let offset=(Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate())-Date.UTC(1900,0,31))/86400000;for(i=1900;i<2101&&offset>0;i++){temp=this.lYearDays(i);offset-=temp}if(offset<0){offset+=temp;i--}let isTodayObj=new Date(),isToday=false;if(isTodayObj.getFullYear()==y&&isTodayObj.getMonth()+1==m&&isTodayObj.getDate()==d){isToday=true}let nWeek=objDate.getDay(),cWeek=this.nStr1[nWeek];if(nWeek==0){nWeek=7}let year=i;leap=this.leapMonth(i);let isLeap=false;for(i=1;i<13&&offset>0;i++){if(leap>0&&i==leap+1&&isLeap==false){--i;isLeap=true;temp=this.leapDays(year)}else{temp=this.monthDays(year,i)}if(isLeap==true&&i==leap+1){isLeap=false}offset-=temp}if(offset==0&&leap>0&&i==leap+1){if(isLeap){isLeap=false}else{isLeap=true;--i}}if(offset<0){offset+=temp;--i}let month=i;let day=offset+1;let sm=m-1;let gzY=this.toGanZhiYear(year);let firstNode=this.getTerm(y,m*2-1);let secondNode=this.getTerm(y,m*2);let gzM=this.toGanZhi((y-1900)*12+m+11);if(d>=firstNode){gzM=this.toGanZhi((y-1900)*12+m+12)}let isTerm=false;let Term=null;if(firstNode==d){isTerm=true;Term=this.solarTerm[m*2-2]}if(secondNode==d){isTerm=true;Term=this.solarTerm[m*2-1]}let dayCyclical=Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;let gzD=this.toGanZhi(dayCyclical+d-1);let astro=this.toAstro(m,d);return{lYear:year,lMonth:month,lDay:day,Animal:this.getAnimal(year),IMonthCn:(isLeap?'\u95f0':'')+this.toChinaMonth(month),IDayCn:this.toChinaDay(day),cYear:y,cMonth:m,cDay:d,gzYear:gzY,gzMonth:gzM,gzDay:gzD,isToday:isToday,isLeap:isLeap,nWeek:nWeek,ncWeek:'\u661f\u671f'+cWeek,isTerm:isTerm,Term:Term,astro:astro,}};lunar2solar=(y,m,d,_isLeapMonth)=>{let isLeapMonth=!!_isLeapMonth;let leapMonth=this.leapMonth(y);if(isLeapMonth&&leapMonth!=m){return-1}if((y==2100&&m==12&&d>1)||(y==1900&&m==1&&d<31)){return-1}let day=this.monthDays(y,m);let _day=day;if(isLeapMonth){_day=this.leapDays(y,m)}if(y<1900||y>2100||d>_day){return-1}let offset=0;for(let i=1900;i0){offset+=this.leapDays(y);isAdd=true}}offset+=this.monthDays(y,i)}if(isLeapMonth){offset+=day}let stmap=Date.UTC(1900,1,30,0,0,0);let calObj=new Date((offset+d-31)*86400000+stmap);let cY=calObj.getUTCFullYear();let cM=calObj.getUTCMonth()+1;let cD=calObj.getUTCDate();return this.solar2lunar(cY,cM,cD)};birthday=(config)=>{let y=parseInt(config.year),m=parseInt(config.month),d=parseInt(config.day),nongli=config.nongli,isLeapMonth=config.isLeapMonth;let date;let now=new Date();if(nongli){let now_d=this.solar2lunar(now.getFullYear(),now.getMonth()+1,now.getDate());let now_year=now_d.lYear;date=this.birthBylunar(now_year,m,d,isLeapMonth);if(this.daysBetween(date)<=0){now_year++;date=this.birthBylunar(now_year,m,d,isLeapMonth)}}else{let now_year=now.getFullYear();date=this.solar2lunar(now_year,m,d);if(this.daysBetween(date)<=0){now_year++;date=this.solar2lunar(now_year,m,d)}}let result=[date,this.daysBetween(date)];return result};birthBylunar=(y,m,d,isLeapMonth)=>{if(isLeapMonth&&this.leapMonth(y)==m){d=this.lunar2solar(y,m,d,isLeapMonth)}else{d=this.lunar2solar(y,m,d,false)}return d};daysBetween=(d)=>{let now=new Date();let date=new Date(d.cYear,d.cMonth-1,d.cDay);return parseInt((date.getTime()-now.getTime())/(24*3600*1000))};getAstroToEmoji=(astro)=>{const data={白羊座:'♈',金牛座:'♉',双子座:'♊',巨蟹座:'♋',狮子座:'♌',处女座:'♍',天秤座:'♎',天蝎座:'♏',射手座:'♐',摩羯座:'♑',水瓶座:'♒',双鱼座:'♓',蛇夫座:'⛎',};return data[astro]||''};getAnimalZodiacToEmoji=(zodiac)=>{const data={鼠:'🐭',牛:'🐂',虎:'🐯',兔:'🐇',龙:'🐲',蛇:'🐍',马:'🐴',羊:'🐑',猴:'🐵',鸡:'🐔',狗:'🐶',猪:'🐷',};return data[zodiac]||''};verifyTime(date){let dateFormat=/^(\d{4})-(\d{1,2})-(\d{1,2})$/;return dateFormat.test(date)}})() \ No newline at end of file +function calendarFun(){const calendar={lunarInfo:[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50,0x06b20,0x1a6c4,0x0aae0,0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,0x0d520,],solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31],Gan:["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678",],Zhi:["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5",],Animals:["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a",],solarTerm:["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3",],sTermInfo:["9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c3598082c95f8c965cc920f","97bd0b06bdb0722c965ce1cfcc920f","b027097bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd0b06bdb0722c965ce1cfcc920f","b027097bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd0b06bdb0722c965ce1cfcc920f","b027097bd097c36b0b6fc9274c91aa","9778397bd19801ec9210c965cc920e","97b6b97bd19801ec95f8c965cc920f","97bd09801d98082c95f8e1cfcc920f","97bd097bd097c36b0b6fc9210c8dc2","9778397bd197c36c9210c9274c91aa","97b6b97bd19801ec95f8c965cc920e","97bd09801d98082c95f8e1cfcc920f","97bd097bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c91aa","97b6b97bd19801ec95f8c965cc920e","97bcf97c3598082c95f8e1cfcc920f","97bd097bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c3598082c95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c3598082c95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd097bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf97c359801ec95f8c965cc920f","97bd097bd07f595b0b6fc920fb0722","9778397bd097c36b0b6fc9210c8dc2","9778397bd19801ec9210c9274c920e","97b6b97bd19801ec95f8c965cc920f","97bd07f5307f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c920e","97b6b97bd19801ec95f8c965cc920f","97bd07f5307f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c91aa","97b6b97bd19801ec9210c965cc920e","97bd07f1487f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf7f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf7f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf7f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c965cc920e","97bcf7f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b97bd19801ec9210c9274c920e","97bcf7f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9210c91aa","97b6b97bd197c36c9210c9274c920e","97bcf7f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9210c8dc2","9778397bd097c36c9210c9274c920e","97b6b7f0e47f531b0723b0b6fb0722","7f0e37f5307f595b0b0bc920fb0722","7f0e397bd097c36b0b6fc9210c8dc2","9778397bd097c36b0b70c9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e37f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc9210c8dc2","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e27f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9274c91aa","97b6b7f0e47f531b0723b0787b0721","7f0e27f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9210c91aa","97b6b7f0e47f149b0723b0787b0721","7f0e27f0e47f531b0723b0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","9778397bd097c36b0b6fc9210c8dc2","977837f0e37f149b0723b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e37f5307f595b0b0bc920fb0722","7f0e397bd097c35b0b6fc9210c8dc2","977837f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0721","7f0e37f1487f595b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc9210c8dc2","977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd097c35b0b6fc920fb0722","977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14998082b0787b06bd","7f07e7f0e47f149b0723b0787b0721","7f0e27f0e47f531b0b0bb0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14998082b0723b06bd","7f07e7f0e37f149b0723b0787b0721","7f0e27f0e47f531b0723b0b6fb0722","7f0e397bd07f595b0b0bc920fb0722","977837f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e37f1487f595b0b0bb0b6fb0722","7f0e37f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e37f1487f531b0b0bb0b6fb0722","7f0e37f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e37f1487f531b0b0bb0b6fb0722","7f0e37f0e37f14898082b072297c35","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e37f0e37f14898082b072297c35","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f149b0723b0787b0721","7f0e27f1487f531b0b0bb0b6fb0722","7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14998082b0723b06bd","7f07e7f0e47f149b0723b0787b0721","7f0e27f0e47f531b0723b0b6fb0722","7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14998082b0723b06bd","7f07e7f0e37f14998083b0787b0721","7f0e27f0e47f531b0723b0b6fb0722","7f0e37f0e366aa89801eb072297c35","7ec967f0e37f14898082b0723b02d5","7f07e7f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e36665b66aa89801e9808297c35","665f67f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b0721","7f07e7f0e47f531b0723b0b6fb0722","7f0e36665b66a449801e9808297c35","665f67f0e37f14898082b0723b02d5","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e36665b66a449801e9808297c35","665f67f0e37f14898082b072297c35","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e26665b66a449801e9808297c35","665f67f0e37f1489801eb072297c35","7ec967f0e37f14998082b0787b06bd","7f07e7f0e47f531b0723b0b6fb0721","7f0e27f1487f531b0b0bb0b6fb0722",],nStr1:["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341",],nStr2:["\u521d","\u5341","\u5eff","\u5345"],nStr3:["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a",],lYearDays:function(y){var i,sum=348;for(i=0x8000;i>0x8;i>>=1){sum+=calendar.lunarInfo[y-1900]&i?1:0}return sum+calendar.leapDays(y)},leapMonth:function(y){return calendar.lunarInfo[y-1900]&0xf},leapDays:function(y){if(calendar.leapMonth(y)){return calendar.lunarInfo[y-1900]&0x10000?30:29}return 0},monthDays:function(y,m){if(m>12||m<1){return-1}return calendar.lunarInfo[y-1900]&(0x10000>>m)?30:29},solarDays:function(y,m){if(m>12||m<1){return-1}var ms=m-1;if(ms==1){return(y%4==0&&y%100!=0)||y%400==0?29:28}else{return calendar.solarMonth[ms]}},toGanZhiYear:function(lYear){var ganKey=(lYear-3)%10;var zhiKey=(lYear-3)%12;if(ganKey==0)ganKey=10;if(zhiKey==0)zhiKey=12;return calendar.Gan[ganKey-1]+calendar.Zhi[zhiKey-1]},toAstro:function(cMonth,cDay){var s="\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";var arr=[20,19,21,21,21,22,23,23,23,23,22,22];return(s.substr(cMonth*2-(cDay2100){return-1}if(n<1||n>24){return-1}var _table=calendar.sTermInfo[y-1900];var _info=[parseInt("0x"+_table.substr(0,5)).toString(),parseInt("0x"+_table.substr(5,5)).toString(),parseInt("0x"+_table.substr(10,5)).toString(),parseInt("0x"+_table.substr(15,5)).toString(),parseInt("0x"+_table.substr(20,5)).toString(),parseInt("0x"+_table.substr(25,5)).toString(),];var _calday=[_info[0].substr(0,1),_info[0].substr(1,2),_info[0].substr(3,1),_info[0].substr(4,2),_info[1].substr(0,1),_info[1].substr(1,2),_info[1].substr(3,1),_info[1].substr(4,2),_info[2].substr(0,1),_info[2].substr(1,2),_info[2].substr(3,1),_info[2].substr(4,2),_info[3].substr(0,1),_info[3].substr(1,2),_info[3].substr(3,1),_info[3].substr(4,2),_info[4].substr(0,1),_info[4].substr(1,2),_info[4].substr(3,1),_info[4].substr(4,2),_info[5].substr(0,1),_info[5].substr(1,2),_info[5].substr(3,1),_info[5].substr(4,2),];return parseInt(_calday[n-1])},toChinaMonth:function(m){if(m>12||m<1){return-1}var s=calendar.nStr3[m-1];s+="\u6708";return s},toChinaDay:function(d){var s;switch(d){case 10:s="\u521d\u5341";break;case 20:s="\u4e8c\u5341";break;break;case 30:s="\u4e09\u5341";break;break;default:s=calendar.nStr2[Math.floor(d/10)];s+=calendar.nStr1[d%10]}return s},getAnimal:function(y){return calendar.Animals[(y-4)%12]},solar2lunar:function(y,m,d){if(y<1900||y>2100){return-1}if(y==1900&&m==1&&d<31){return-1}if(!y){var objDate=new Date()}else{var objDate=new Date(y,parseInt(m)-1,d)}var i,leap=0,temp=0;var y=objDate.getFullYear(),m=objDate.getMonth()+1,d=objDate.getDate();var offset=(Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate())-Date.UTC(1900,0,31))/86400000;for(i=1900;i<2101&&offset>0;i++){temp=calendar.lYearDays(i);offset-=temp}if(offset<0){offset+=temp;i--}var isTodayObj=new Date(),isToday=false;if(isTodayObj.getFullYear()==y&&isTodayObj.getMonth()+1==m&&isTodayObj.getDate()==d){isToday=true}var nWeek=objDate.getDay(),cWeek=calendar.nStr1[nWeek];if(nWeek==0){nWeek=7}var year=i;var leap=calendar.leapMonth(i);var isLeap=false;for(i=1;i<13&&offset>0;i++){if(leap>0&&i==leap+1&&isLeap==false){--i;isLeap=true;temp=calendar.leapDays(year)}else{temp=calendar.monthDays(year,i)}if(isLeap==true&&i==leap+1){isLeap=false}offset-=temp}if(offset==0&&leap>0&&i==leap+1){if(isLeap){isLeap=false}else{isLeap=true;--i}}if(offset<0){offset+=temp;--i}var month=i;var day=offset+1;var sm=m-1;var gzY=calendar.toGanZhiYear(year);var firstNode=calendar.getTerm(y,m*2-1);var secondNode=calendar.getTerm(y,m*2);var gzM=calendar.toGanZhi((y-1900)*12+m+11);if(d>=firstNode){gzM=calendar.toGanZhi((y-1900)*12+m+12)}var isTerm=false;var Term=null;if(firstNode==d){isTerm=true;Term=calendar.solarTerm[m*2-2]}if(secondNode==d){isTerm=true;Term=calendar.solarTerm[m*2-1]}var dayCyclical=Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;var gzD=calendar.toGanZhi(dayCyclical+d-1);var astro=calendar.toAstro(m,d);return{lYear:year,lMonth:month,lDay:day,Animal:calendar.getAnimal(year),IMonthCn:(isLeap?"\u95f0":"")+calendar.toChinaMonth(month),IDayCn:calendar.toChinaDay(day),cYear:y,cMonth:m,cDay:d,gzYear:gzY,gzMonth:gzM,gzDay:gzD,isToday:isToday,isLeap:isLeap,nWeek:nWeek,ncWeek:"\u661f\u671f"+cWeek,isTerm:isTerm,Term:Term,astro:astro,}},lunar2solar:function(y,m,d,isLeapMonth){var isLeapMonth=!!isLeapMonth;var leapOffset=0;var leapMonth=calendar.leapMonth(y);var leapDay=calendar.leapDays(y);if(isLeapMonth&&leapMonth!=m){return-1}if((y==2100&&m==12&&d>1)||(y==1900&&m==1&&d<31)){return-1}var day=calendar.monthDays(y,m);var _day=day;if(isLeapMonth){_day=calendar.leapDays(y,m)}if(y<1900||y>2100||d>_day){return-1}var offset=0;for(var i=1900;i0){offset+=calendar.leapDays(y);isAdd=true}}offset+=calendar.monthDays(y,i)}if(isLeapMonth){offset+=day}var stmap=Date.UTC(1900,1,30,0,0,0);var calObj=new Date((offset+d-31)*86400000+stmap);var cY=calObj.getUTCFullYear();var cM=calObj.getUTCMonth()+1;var cD=calObj.getUTCDate();return calendar.solar2lunar(cY,cM,cD)},birthday:function(y,m,d,nongli,isLeapMonth){var date;var now=new Date();if(nongli){var now_d=this.solar2lunar(now.getFullYear(),now.getMonth()+1,now.getDate());var now_year=now_d.lYear;date=this.birthBylunar(now_year,m,d,isLeapMonth);if(this.daysBetween(date)<=0){now_year++;date=this.birthBylunar(now_year,m,d,isLeapMonth)}}else{var now_year=now.getFullYear();date=this.solar2lunar(now_year,m,d);if(this.daysBetween(date)<=0){now_year++;date=this.solar2lunar(now_year,m,d)}}return[date.cYear,date.cMonth,date.cDay,this.daysBetween(date)]},birthBylunar:function(y,m,d,isLeapMonth){if(isLeapMonth&&this.leapMonth(y)==m){d=this.lunar2solar(y,m,d,isLeapMonth)}else{d=this.lunar2solar(y,m,d,false)}return d},daysBetween:function(d){var now=new Date();var date=new Date(d.cYear,d.cMonth-1,d.cDay);return parseInt((date.getTime()-now.getTime())/(24*3600*1000))},verifyTime(date){var dateFormat=/^(\d{4})-(\d{1,2})-(\d{1,2})$/;return dateFormat.test(date)},getAnimalZodiacToEmoji(zodiac){var data={鼠:"🐭",牛:"🐂",虎:"🐯",兔:"🐇",龙:"🐲",蛇:"🐍",马:"🐴",羊:"🐑",猴:"🐵",鸡:"🐔",狗:"🐶",猪:"🐷",};return data[zodiac]||""},getAstroToEmoji(astro){var data={白羊座:"♈",金牛座:"♉",双子座:"♊",巨蟹座:"♋",狮子座:"♌",处女座:"♍",天秤座:"♎",天蝎座:"♏",射手座:"♐",摩羯座:"♑",水瓶座:"♒",双鱼座:"♓",蛇夫座:"⛎",};return data[astro]||""},};return calendar} \ No newline at end of file From 437620a34755bd2ef871441e3fb844e500a29888 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 5 Jan 2023 16:45:54 +0800 Subject: [PATCH 082/152] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E5=9B=BE=E6=A0=87=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 4db8c1c..5a63afa 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -553,7 +553,8 @@ class DmYY { const row = new UITableRow(); row.dismissOnSelect = !!item.dismissOnSelect; if (item.url) { - const rowIcon = row.addImageAtURL(item.url); + const imageIcon = await this.$request.get(item.url,"IMG"); + const rowIcon = row.addImage(imageIcon); rowIcon.widthWeight = 100; } else { const icon = item.icon || {}; From 16c85f3045d7caafd66e575fa309c4c474b86292 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 2 Feb 2023 14:50:13 +0800 Subject: [PATCH 083/152] =?UTF-8?q?update:=E5=9B=BE=E6=A0=87=E6=95=88?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 5a63afa..b13ee46 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -553,7 +553,7 @@ class DmYY { const row = new UITableRow(); row.dismissOnSelect = !!item.dismissOnSelect; if (item.url) { - const imageIcon = await this.$request.get(item.url,"IMG"); + const imageIcon = await this.$request.get(item.url, 'IMG'); const rowIcon = row.addImage(imageIcon); rowIcon.widthWeight = 100; } else { @@ -579,9 +579,11 @@ class DmYY { valText.titleColor = Color.blue(); valText.titleFont = Font.mediumSystemFont(fontSize); } else { - const imgCell = UITableCell.imageAtURL( - 'https://gitee.com/scriptableJS/Scriptable/raw/master/images/more.png' + const forward = await this.$request.get( + `https://img.icons8.com/ios/512/more-than.png`, + 'IMG' ); + const imgCell = UITableCell.image(forward); imgCell.rightAligned(); imgCell.widthWeight = 500; row.addCell(imgCell); From 30cfd6532d2c6d55f1465d2fddd07c077cd517d5 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 2 Feb 2023 15:22:15 +0800 Subject: [PATCH 084/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E7=BD=91?= =?UTF-8?q?=E7=BB=9C=E5=9B=BE=E7=89=87=E5=AD=98=E5=82=A8=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index b13ee46..39ee9b3 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -825,10 +825,10 @@ class DmYY { FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' ](); - + this.cacheImage = this.FILE_MGR.joinPath( - this.FILE_MGR.libraryDirectory(), - `${Script.name()}/images` + this.FILE_MGR.documentsDirectory(), + `/images/${Script.name()}` ); if (!this.FILE_MGR.fileExists(this.cacheImage)) { From 7a975e2b933f94ddc57aa441af9df254f59b7eef Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 10:29:46 +0800 Subject: [PATCH 085/152] =?UTF-8?q?update=EF=BC=9A=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B5=E9=9D=A2=20UI=20=E6=95=88=E6=9E=9C?= =?UTF-8?q?=EF=BC=8C=E5=8F=82=E8=80=83=E8=87=AA=20@LSP=20=E5=A4=A7?= =?UTF-8?q?=E4=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/CarWidget.js | 56 +- Scripts/DmYY.js | 1213 ++++++++++++++++++++++++------------------ 2 files changed, 732 insertions(+), 537 deletions(-) diff --git a/Scripts/CarWidget.js b/Scripts/CarWidget.js index 693e6f5..02cb286 100644 --- a/Scripts/CarWidget.js +++ b/Scripts/CarWidget.js @@ -10,36 +10,32 @@ const { DmYY, Runing } = require('./DmYY'); class Widget extends DmYY { constructor(arg) { super(arg); - config.runsInApp && - this.registerAction( - '油价设置', - () => { - return this.setAlertInput('油价设置', '设置类型', { - oilNumber: '89|92|95|98|0', - }); - }, - { name: 'paperplane', color: '#722ed1' } - ); - config.runsInApp && - this.registerAction( - '依赖插件', - () => { - return this.setAlertInput('设置依赖插件', '汽车的依赖插件例如 Ftms', { - filePath: '', - }); - }, - { name: 'car', color: '#f5222d' } - ); - config.runsInApp && - this.registerAction( - '缩放比例', - () => { - return this.setAlertInput('设置缩放比例', '比例越大进度条越长', { - scale: '比例默认值1', - }); - }, - { name: 'plus.viewfinder', color: '#fa8c16' } - ); + if (config.runsInApp) { + this.registerAction({ + icon: { name: 'paperplane', color: '#722ed1' }, + type: 'input', + title: '油价设置', + desc: '89|92|95|0', + val: 'oilNumber', + }); + + this.registerAction({ + icon: { name: 'car', color: '#f5222d' }, + type: 'input', + title: '依赖插件', + desc: '汽车的依赖插件例如 Ftms', + val: 'filePath', + }); + + this.registerAction({ + icon: { name: 'plus.viewfinder', color: '#fa8c16' }, + type: 'input', + title: '缩放比例', + desc: '比例越大进度条越长', + placeholder: '取值 0~1', + val: 'scale', + }); + } config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); this.cacheName = this.md5(`dataSouce_${this.en}`); diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 39ee9b3..20385c5 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -5,8 +5,8 @@ /* * Author: 2Ya * Github: https://github.com/dompling + * UI 配置升级 感谢 @LSP 大佬提供代码 */ - class DmYY { constructor(arg, defaultSettings) { this.arg = arg; @@ -19,13 +19,11 @@ class DmYY { this.isNight = Device.isUsingDarkAppearance(); } - _actions = {}; - BACKGROUND_NIGHT_KEY; + _actions = []; widgetColor; backGroundColor; useBoxJS = true; isNight; - _actionsIcon = {}; // 获取 Request 对象 getRequest = (url = '') => { @@ -33,7 +31,10 @@ class DmYY { }; // 发起请求 - http = async (options = { headers: {}, url: '' }, type = 'JSON') => { + http = async ( + options = { headers: {}, url: '', cache: tru }, + type = 'JSON' + ) => { let request; try { if (type === 'IMG') { @@ -458,12 +459,12 @@ class DmYY { return cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h)); } - setLightAndDark = async (title, desc, val) => { + setLightAndDark = async (title, desc, val, placeholder = '') => { try { const a = new Alert(); a.title = title; a.message = desc; - a.addTextField('', `${this.settings[val]}`); + a.addTextField(placeholder, `${this.settings[val]}`); a.addAction('确定'); a.addCancelAction('取消'); const id = await a.presentAlert(); @@ -537,100 +538,170 @@ class DmYY { * @returns {Promise} */ setWidgetConfig = async () => { - const table = new UITable(); - table.showSeparators = true; - await this.renderDmYYTables(table); - await table.present(); - }; + const basic = [ + { + icon: { name: 'arrow.clockwise', color: '#1890ff' }, + type: 'input', + title: '刷新时间', + desc: '刷新时间仅供参考,具体刷新时间由系统判断,单位:分钟', + val: 'refreshAfterDate', + }, + { + icon: { name: 'sun.max.fill', color: '#d48806' }, + type: 'color', + title: '白天字体颜色', + desc: '请自行去网站上搜寻颜色(Hex 颜色)', + val: 'lightColor', + }, + { + icon: { name: 'moon.stars.fill', color: '#d4b106' }, + type: 'color', + title: '晚上字体颜色', + desc: '请自行去网站上搜寻颜色(Hex 颜色)', + val: 'darkColor', + }, + ]; - async preferences(table, arr, outfit) { - let header = new UITableRow(); - let heading = header.addText(outfit); - heading.titleFont = Font.mediumSystemFont(17); - heading.centerAligned(); - table.addRow(header); - for (const item of arr) { - const row = new UITableRow(); - row.dismissOnSelect = !!item.dismissOnSelect; - if (item.url) { - const imageIcon = await this.$request.get(item.url, 'IMG'); - const rowIcon = row.addImage(imageIcon); - rowIcon.widthWeight = 100; - } else { - const icon = item.icon || {}; - const image = await this.drawTableIcon( - icon.name, - icon.color, - item.cornerWidth - ); - const imageCell = row.addImage(image); - imageCell.widthWeight = 100; - } - let rowTitle = row.addText(item['title']); - rowTitle.widthWeight = 400; - rowTitle.titleFont = Font.systemFont(16); - if (this.settings[item.val] || item.val) { - let valText = row.addText( - `${this.settings[item.val] || item.val}`.toUpperCase() - ); - const fontSize = !item.val ? 26 : 16; - valText.widthWeight = 500; - valText.rightAligned(); - valText.titleColor = Color.blue(); - valText.titleFont = Font.mediumSystemFont(fontSize); - } else { - const forward = await this.$request.get( - `https://img.icons8.com/ios/512/more-than.png`, - 'IMG' - ); - const imgCell = UITableCell.image(forward); - imgCell.rightAligned(); - imgCell.widthWeight = 500; - row.addCell(imgCell); - } + const boxjs = { + icon: { name: 'shippingbox', color: '#f7bb10' }, + type: 'input', + title: 'BoxJS 域名', + desc: '', + val: 'boxjsDomain', + }; - row.onSelect = item.onClick - ? async () => { - try { - await item.onClick(item, table); - } catch (e) { - console.log(e); - } - } - : async () => { - if (item.type == 'input') { - await this.setLightAndDark( - item['title'], - item['desc'], - item['val'] - ); - } else if (item.type == 'setBackground') { + if (this.useBoxJS) basic.push(boxjs); + + return this.renderAppView([ + { title: '基础设置', menu: basic }, + { + title: '背景设置', + menu: [ + { + icon: { name: 'photo', color: '#13c2c2' }, + type: 'color', + title: '白天背景颜色', + desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', + val: 'lightBgColor', + }, + { + icon: { name: 'photo.fill', color: '#52c41a' }, + type: 'color', + title: '晚上背景颜色', + desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', + val: 'darkBgColor', + }, + ], + }, + { + menu: [ + { + icon: { name: 'photo.on.rectangle', color: '#fa8c16' }, + name: 'dayBg', + type: 'img', + title: '日间背景', + }, + { + icon: { name: 'photo.fill.on.rectangle.fill', color: '#fa541c' }, + name: 'nightBg', + type: 'img', + title: '夜间背景', + }, + { + icon: { name: 'text.below.photo', color: '#faad14' }, + type: 'img', + name: 'transparentBg', + title: '透明背景', + onClick: async (_, __, previewWebView) => { const backImage = await this.getWidgetScreenShot(); - if (backImage) { - await this.setBackgroundImage(backImage, true); - await this.setBackgroundNightImage(backImage, true); - } - } else if (item.type == 'removeBackground') { - const options = ['取消', '清空']; - const message = '该操作不可逆,会清空所有背景图片!'; + if (!backImage || !(await this.verifyImage(backImage))) return; + const base64Img = await this.setBackgroundImage( + backImage, + 'transparentBg' + ); + this.insertTextByElementId( + previewWebView, + 'transparentBg', + `` + ); + this.dismissLoading(previewWebView); + }, + }, + ], + }, + { + menu: [ + { + icon: { name: 'record.circle', color: '#722ed1' }, + type: 'input', + title: '日间蒙层', + desc: '完全透明请设置为0', + val: 'lightOpacity', + }, + { + icon: { name: 'record.circle.fill', color: '#eb2f96' }, + type: 'input', + title: '夜间蒙层', + desc: '完全透明请设置为0', + val: 'darkOpacity', + }, + ], + }, + { + menu: [ + { + icon: { name: 'clear', color: '#f5222d' }, + name: 'removeBackground', + title: '清空背景图片', + onClick: async (_, __, previewWebView) => { + const options = [ + '取消', + '清空日间', + '清空夜间', + '清空透明', + `清空全部`, + ]; + const message = '该操作不可逆,会清空背景图片!'; const index = await this.generateAlert(message, options); if (index === 0) return; - await this.setBackgroundImage(false, true); - await this.setBackgroundNightImage(false, true); - } else { - const backImage = await this.chooseImg(); - if (!backImage || !(await this.verifyImage(backImage))) return; - if (item.type == 'setDayBackground') - await this.setBackgroundImage(backImage, true); - if (item.type == 'setNightBackground') - await this.setBackgroundNightImage(backImage, true); - } - await this.renderDmYYTables(table); - }; - table.addRow(row); - } - table.reload(); - } + switch (index) { + case 1: + await this.setBackgroundImage(false, 'dayBg'); + this.insertTextByElementId(previewWebView, 'dayBg', ``); + return; + case 2: + await this.setBackgroundImage(false, 'nightBg'); + this.insertTextByElementId(previewWebView, 'nightBg', ``); + return; + case 3: + await this.setBackgroundImage(false, 'transparentBg'); + this.insertTextByElementId( + previewWebView, + 'transparentBg', + `` + ); + return; + default: + await this.setBackgroundImage(false, 'dayBg'); + await this.setBackgroundImage(false, 'nightBg'); + await this.setBackgroundImage(false, 'transparentBg'); + this.insertTextByElementId(previewWebView, 'dayBg', ``); + this.insertTextByElementId(previewWebView, 'nightBg', ``); + this.insertTextByElementId( + previewWebView, + 'transparentBg', + `` + ); + break; + } + }, + }, + ], + }, + ]).catch((e) => { + console.log(e); + }); + }; drawTableIcon = async ( icon = 'square.grid.2x2', @@ -641,36 +712,36 @@ class DmYY { sfi.applyFont(Font.mediumSystemFont(30)); const imgData = Data.fromPNG(sfi.image).toBase64String(); const html = ` - - - - `; + + + + `; const js = ` - var canvas = document.createElement("canvas"); - var sourceImg = document.getElementById("sourceImg"); - var silhouetteImg = document.getElementById("silhouetteImg"); - var ctx = canvas.getContext('2d'); - var size = sourceImg.width > sourceImg.height ? sourceImg.width : sourceImg.height; - canvas.width = size; - canvas.height = size; - ctx.drawImage(sourceImg, (canvas.width - sourceImg.width) / 2, (canvas.height - sourceImg.height) / 2); - var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); - var pix = imgData.data; - //convert the image into a silhouette - for (var i=0, n = pix.length; i < n; i+= 4){ - //set red to 0 - pix[i] = 255; - //set green to 0 - pix[i+1] = 255; - //set blue to 0 - pix[i+2] = 255; - //retain the alpha value - pix[i+3] = pix[i+3]; - } - ctx.putImageData(imgData,0,0); - silhouetteImg.src = canvas.toDataURL(); - output=canvas.toDataURL() - `; + var canvas = document.createElement("canvas"); + var sourceImg = document.getElementById("sourceImg"); + var silhouetteImg = document.getElementById("silhouetteImg"); + var ctx = canvas.getContext('2d'); + var size = sourceImg.width > sourceImg.height ? sourceImg.width : sourceImg.height; + canvas.width = size; + canvas.height = size; + ctx.drawImage(sourceImg, (canvas.width - sourceImg.width) / 2, (canvas.height - sourceImg.height) / 2); + var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); + var pix = imgData.data; + //convert the image into a silhouette + for (var i=0, n = pix.length; i < n; i+= 4){ + //set red to 0 + pix[i] = 255; + //set green to 0 + pix[i+1] = 255; + //set blue to 0 + pix[i+2] = 255; + //retain the alpha value + pix[i+3] = pix[i+3]; + } + ctx.putImageData(imgData,0,0); + silhouetteImg.src = canvas.toDataURL(); + output=canvas.toDataURL() + `; let wv = new WebView(); await wv.loadHTML(html); @@ -696,121 +767,447 @@ class DmYY { return ctx.getImage(); }; - async renderDmYYTables(table) { - const basic = [ - { - icon: { name: 'arrow.clockwise', color: '#1890ff' }, - type: 'input', - title: '刷新时间', - desc: '刷新时间仅供参考,具体刷新时间由系统判断,单位:分钟', - val: 'refreshAfterDate', - }, - { - icon: { name: 'photo', color: '#13c2c2' }, - type: 'input', - title: '白天背景颜色', - desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', - val: 'lightBgColor', - }, - { - icon: { name: 'photo.fill', color: '#52c41a' }, - type: 'input', - title: '晚上背景颜色', - desc: '请自行去网站上搜寻颜色(Hex 颜色)\n支持渐变色,各颜色之间以英文逗号分隔', - val: 'darkBgColor', - }, - { - icon: { name: 'sun.max.fill', color: '#d48806' }, - type: 'input', - title: '白天字体颜色', - desc: '请自行去网站上搜寻颜色(Hex 颜色)', - val: 'lightColor', - }, - { - icon: { name: 'moon.stars.fill', color: '#d4b106' }, - type: 'input', - title: '晚上字体颜色', - desc: '请自行去网站上搜寻颜色(Hex 颜色)', - val: 'darkColor', - }, - ]; - const background = [ - { - icon: { name: 'text.below.photo', color: '#faad14' }, - type: 'setBackground', - title: '透明背景设置', - }, - { - icon: { name: 'photo.on.rectangle', color: '#fa8c16' }, - type: 'setDayBackground', - title: '白天背景图片', - }, - { - icon: { name: 'photo.fill.on.rectangle.fill', color: '#fa541c' }, - type: 'setNightBackground', - title: '晚上背景图片', - }, - { - icon: { name: 'record.circle', color: '#722ed1' }, - type: 'input', - title: '白天蒙层透明', - desc: '完全透明请设置为0', - val: 'lightOpacity', - }, - { - icon: { name: 'record.circle.fill', color: '#eb2f96' }, - type: 'input', - title: '晚上蒙层透明', - desc: '完全透明请设置为0', - val: 'darkOpacity', - }, - { - icon: { name: 'clear', color: '#f5222d' }, - type: 'removeBackground', - title: '清空背景图片', - }, - ]; - const boxjs = { - icon: { name: 'shippingbox', color: '#f7bb10' }, - type: 'input', - title: 'BoxJS 域名', - desc: '', - val: 'boxjsDomain', - }; - if (this.useBoxJS) basic.push(boxjs); - table.removeAllRows(); - let topRow = new UITableRow(); - topRow.height = 60; - let leftText = topRow.addButton('Github'); - leftText.widthWeight = 0.3; - leftText.onTap = async () => { - await Safari.openInApp('https://github.com/dompling/Scriptable'); - }; - let centerRow = topRow.addImageAtURL( - 'https://s3.ax1x.com/2021/03/16/6y4oJ1.png' + dismissLoading = (webView) => { + webView.evaluateJavaScript( + "window.dispatchEvent(new CustomEvent('JWeb', { detail: { code: 'finishLoading' } }))", + false ); - centerRow.widthWeight = 0.4; - centerRow.centerAligned(); - centerRow.onTap = async () => { - await Safari.open('https://t.me/Scriptable_JS'); - }; - let rightText = topRow.addButton('重置所有'); - rightText.widthWeight = 0.3; - rightText.rightAligned(); - rightText.onTap = async () => { - const options = ['取消', '重置']; - const message = - '该操作不可逆,会清空所有组件配置!重置后请重新打开设置菜单。'; - const index = await this.generateAlert(message, options); - if (index === 0) return; - this.settings = {}; - await this.setBackgroundImage(false, false); - this.FILE_MGR.remove(this.cacheImage); - this.saveSettings(); + }; + + insertTextByElementId = (webView, elementId, text) => { + const scripts = `document.getElementById("${elementId}_val").innerHTML=\`${text}\`;`; + webView.evaluateJavaScript(scripts, false); + }; + + loadSF2B64 = async ( + icon = 'square.grid.2x2', + color = '#56A8D6', + cornerWidth = 42 + ) => { + const sfImg = await this.drawTableIcon(icon, color, cornerWidth); + return `data:image/png;base64,${Data.fromPNG(sfImg).toBase64String()}`; + }; + + async renderAppView(options = [], previewWebView = new WebView()) { + const settingItemFontSize = 16, + authorNameFontSize = 20, + authorDescFontSize = 12; + // ================== 配置界面样式 =================== + const style = ` + :root { + --color-primary: #007aff; + --divider-color: rgba(60,60,67,0.16); + --card-background: #fff; + --card-radius: 8px; + --list-header-color: rgba(60,60,67,0.6); + } + * { + -webkit-user-select: none; + user-select: none; + } + body { + margin: 10px 0; + -webkit-font-smoothing: antialiased; + font-family: "SF Pro Display","SF Pro Icons","Helvetica Neue","Helvetica","Arial",sans-serif; + accent-color: var(--color-primary); + background: #f6f6f6; + } + .list { + margin: 15px; + } + .list__header { + margin: 0 18px; + color: var(--list-header-color); + font-size: 13px; + } + .list__body { + margin-top: 10px; + background: var(--card-background); + border-radius: var(--card-radius); + overflow: hidden; + } + .form-item-auth { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 4em; + padding: 0.5em 18px; + position: relative; + } + .form-item-auth-name { + margin: 0px 12px; + font-size: ${authorNameFontSize}px; + font-weight: 430; + } + .form-item-auth-desc { + margin: 0px 12px; + font-size: ${authorDescFontSize}px; + font-weight: 400; + } + .form-label-author-avatar { + width: 62px; + height: 62px; + border-radius:50%; + border: 1px solid #F6D377; + } + .form-item { + display: flex; + align-items: center; + justify-content: space-between; + font-size: ${settingItemFontSize}px; + font-weight: 400; + min-height: 2.2em; + padding: 0.5em 18px; + position: relative; + } + .form-label { + display: flex; + align-items: center; + } + .form-label-img { + height: 30px; + } + .form-label-title { + margin-left: 8px + } + .bottom-bg { + margin: 30px 15px 15px 15px; + } + .form-item--link .icon-arrow-right { + color: #86868b; + } + .form-item-right-desc { + font-size: 13px; + color: #86868b; + margin: 0 4px 0 auto; + } + .form-item + .form-item::before { + content: ""; + position: absolute; + top: 0; + left: 20px; + right: 0; + border-top: 0.5px solid var(--divider-color); + } + .form-item input[type="checkbox"] { + width: 2em; + height: 2em; + } + input[type='number'] { + width: 6em; + height: 2.3em; + outline-style: none; + text-align: right; + padding: 0px 10px; + border: 1px solid #ddd; + font-size: 14px; + color: #86868b; + } + input[type='input'] { + width: 6em; + height: 2.3em; + outline-style: none; + text-align: right; + padding: 0px 10px; + border: 1px solid #ddd; + font-size: 14px; + color: #86868b; + } + input[type='text'] { + width: 6em; + height: 2.3em; + outline-style: none; + text-align: right; + padding: 0px 10px; + border: 1px solid #ddd; + font-size: 14px; + color: #86868b; + } + input[type='checkbox'][role='switch'] { + position: relative; + display: inline-block; + appearance: none; + width: 40px; + height: 24px; + border-radius: 24px; + background: #ccc; + transition: 0.3s ease-in-out; + } + input[type='checkbox'][role='switch']::before { + content: ''; + position: absolute; + left: 2px; + top: 2px; + width: 20px; + height: 20px; + border-radius: 50%; + background: #fff; + transition: 0.3s ease-in-out; + } + input[type='checkbox'][role='switch']:checked { + background: var(--color-primary); + } + input[type='checkbox'][role='switch']:checked::before { + transform: translateX(16px); + } + .copyright { + display: flex; + align-items: center; + justify-content: space-between; + margin: 15px; + font-size: 10px; + color: #86868b; + } + .copyright a { + color: #515154; + text-decoration: none; + } + .preview.loading { + pointer-events: none; + } + .icon-loading { + display: inline-block; + animation: 1s linear infinite spin; + } + .normal-loading { + display: inline-block; + animation: 20s linear infinite spin; + } + @keyframes spin { + 0% { + transform: rotate(0); + } + 100% { + transform: rotate(1turn); + } + } + @media (prefers-color-scheme: dark) { + :root { + --divider-color: rgba(84,84,88,0.65); + --card-background: #1c1c1e; + --list-header-color: rgba(235,235,245,0.6); + } + body { + background: #000; + color: #fff; + } + }`; + + const js = ` + (() => { + + window.invoke = (code, data) => { + window.dispatchEvent( + new CustomEvent( + 'JBridge', + { detail: { code, data } } + ) + ) + } + + // 切换ico的loading效果 + const toggleIcoLoading = (e) => { + const target = e.currentTarget + target.classList.add('loading') + const icon = e.currentTarget.querySelector('.iconfont') + const className = icon.className + icon.className = 'iconfont icon-loading' + const listener = (event) => { + const { code } = event.detail + if (code === 'finishLoading') { + target.classList.remove('loading') + icon.className = className + window.removeEventListener('JWeb', listener); + } + } + window.addEventListener('JWeb', listener) + }; + + for (const btn of document.querySelectorAll('.form-item')) { + btn.addEventListener('click', (e) => { + toggleIcoLoading(e); + if(e.target.id) invoke(e.target.id); + }) + } + + for (const btn of document.querySelectorAll('.form-item__input')) { + btn.addEventListener('change', (e) => { + if(e.target.name) invoke(e.target.name, e.target.value); + }) + } + + })()`; + + let configList = ``; + let actionsConfig = []; + for (const key in options) { + const item = options[key]; + actionsConfig = [...item.menu, ...actionsConfig]; + configList += ` +
    +
    ${item.title || ''}
    +
    + `; + + for (const menuItem of item.menu) { + let iconBase64 = ``; + if (menuItem.url) { + try { + const imageIcon = await this.$request.get(menuItem.url, 'IMG'); + if (menuItem.url.indexOf('png') !== -1) { + iconBase64 = `data:image/png;base64,${Data.fromPNG( + imageIcon + ).toBase64String()}`; + } else { + iconBase64 = `data:image/png;base64,${Data.fromJPEG( + imageIcon + ).toBase64String()}`; + } + } catch (e) { + iconBase64 = await this.loadSF2B64('photo'); + } + } else { + const icon = menuItem.icon || {}; + iconBase64 = await this.loadSF2B64(icon.name, icon.color); + } + const idName = menuItem.name || menuItem.val; + menuItem.defaultValue = ''; + let defaultHtml = ``; + if (menuItem.val !== undefined) + menuItem.defaultValue = this.settings[menuItem.val] || ''; + + if (menuItem.defaultValue && menuItem.type === 'input') { + defaultHtml = menuItem.defaultValue; + } else if (menuItem.type === 'color') { + defaultHtml = ``; + } else if (menuItem.type === 'img') { + const cachePath = `${this.cacheImage}/${menuItem.name}`; + if (this.FILE_MGR.fileExists(cachePath)) { + const imageSrc = `data:image/png;base64,${Data.fromFile( + cachePath + ).toBase64String()}`; + defaultHtml = ``; + } + } + + configList += ` + + `; + } + configList += `
    `; + } + + const html = ` + + + + + + + + ${configList} + + + + `; + + // 预览web + await previewWebView.loadHTML(html).catch((err) => { + console.log(err); + }); + + const injectListener = async () => { + const event = await previewWebView + .evaluateJavaScript( + `(() => { + try { + const controller = new AbortController() + const listener = (e) => { + completion(e.detail) + controller.abort() + } + window.addEventListener( + 'JBridge', + listener, + { signal: controller.signal } + ) + } catch (e) { + alert("预览界面出错:" + e); + throw new Error("界面处理出错: " + e); + return; + } + })()`, + true + ) + .catch((err) => { + console.error(err); + this.dismissLoading(previewWebView); + }); + const { code, data } = event; + + const actionItem = actionsConfig.find( + (item) => (item.name || item.val) === code + ); + + if (!actionItem) { + this.notify('异常提示', '当前操作异常'); + } else { + const idName = actionItem?.name || actionItem?.val; + if (actionItem?.onClick) { + await actionItem?.onClick?.(actionItem, data, previewWebView); + } else if (actionItem.type == 'input') { + await this.setLightAndDark( + actionItem['title'], + actionItem['desc'], + actionItem['val'], + actionItem['placeholder'] + ); + this.insertTextByElementId( + previewWebView, + idName, + this.settings[actionItem.val] + ); + } else if (actionItem.type === 'img') { + const backImage = await this.chooseImg(); + if (!backImage || !(await this.verifyImage(backImage))) return; + const base64Img = await this.setBackgroundImage(backImage, idName); + this.insertTextByElementId( + previewWebView, + idName, + `` + ); + } else { + if (data !== undefined) { + this.settings[actionItem.val] = data; + this.saveSettings(false); + } + } + } + this.dismissLoading(previewWebView); + + injectListener(); }; - table.addRow(topRow); - await this.preferences(table, basic, '基础设置'); - await this.preferences(table, background, '背景图片'); + + injectListener().catch((e) => { + console.error(e); + this.dismissLoading(previewWebView); + if (!config.runsInApp) { + this.notify('主界面', `🚫 ${e}`); + } + }); + + previewWebView.present(); } init(widgetFamily = config.widgetFamily) { @@ -825,27 +1222,24 @@ class DmYY { FileManager[ module.filename.includes('Documents/iCloud~') ? 'iCloud' : 'local' ](); - + this.cacheImage = this.FILE_MGR.joinPath( this.FILE_MGR.documentsDirectory(), `/images/${Script.name()}` ); + this.cacheImageBgPath = [ + `${this.cacheImage}/transparentBg`, + `${this.cacheImage}/dayBg`, + `${this.cacheImage}/nightBg`, + ]; + if (!this.FILE_MGR.fileExists(this.cacheImage)) { this.FILE_MGR.createDirectory(this.cacheImage, true); } // 本地,用于存储图片等 this.FILE_MGR_LOCAL = FileManager.local(); - this.BACKGROUND_KEY = this.FILE_MGR_LOCAL.joinPath( - this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + '.jpg' - ); - - this.BACKGROUND_NIGHT_KEY = this.FILE_MGR_LOCAL.joinPath( - this.FILE_MGR_LOCAL.documentsDirectory(), - 'bg_' + this.SETTING_KEY + 'night.jpg' - ); this.settings = this.getSettings(); @@ -861,18 +1255,24 @@ class DmYY { this.settings.darkOpacity = this.settings.darkOpacity || '0.7'; this.prefix = this.settings.boxjsDomain; - const lightBgColor = this.getColors(this.settings.lightBgColor); - const darkBgColor = this.getColors(this.settings.darkBgColor); - if (lightBgColor.length > 1 || darkBgColor.length > 1) { - this.backGroundColor = !Device.isUsingDarkAppearance() - ? this.getBackgroundColor(lightBgColor) - : this.getBackgroundColor(darkBgColor); - } else if (lightBgColor.length > 0 && darkBgColor.length > 0) { - this.backGroundColor = Color.dynamic( - new Color(this.settings.lightBgColor), - new Color(this.settings.darkBgColor) - ); - } + + this.backGroundColor = Color.dynamic( + new Color(this.settings.lightBgColor), + new Color(this.settings.darkBgColor) + ); + + // const lightBgColor = this.getColors(this.settings.lightBgColor); + // const darkBgColor = this.getColors(this.settings.darkBgColor); + // if (lightBgColor.length > 1 || darkBgColor.length > 1) { + // this.backGroundColor = !Device.isUsingDarkAppearance() + // ? this.getBackgroundColor(lightBgColor) + // : this.getBackgroundColor(darkBgColor); + // } else if (lightBgColor.length > 0 && darkBgColor.length > 0) { + // this.backGroundColor = Color.dynamic( + // new Color(this.settings.lightBgColor), + // new Color(this.settings.darkBgColor) + // ); + // } this.widgetColor = Color.dynamic( new Color(this.settings.lightColor), @@ -902,9 +1302,22 @@ class DmYY { * @param {string} name 操作函数名 * @param {func} func 点击后执行的函数 */ - registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }) { - this._actions[name] = func.bind(this); - this._actionsIcon[name] = icon; + registerAction(name, func, icon = { name: 'gear', color: '#096dd9' }, type) { + if (typeof name === 'object') return this._actions.push(name); + const action = { + name, + type, + title: name, + onClick: func.bind(this), + }; + + if (typeof icon === 'string') { + action.url = icon; + } else { + action.icon = icon; + } + + this._actions.push(action); } /** @@ -929,195 +1342,8 @@ class DmYY { * md5 加密字符串 * @param {string} str 要加密成md5的数据 */ - md5(str) { - function d(n, t) { - var r = (65535 & n) + (65535 & t); - return (((n >> 16) + (t >> 16) + (r >> 16)) << 16) | (65535 & r); - } - - function f(n, t, r, e, o, u) { - return d(((c = d(d(t, n), d(e, u))) << (f = o)) | (c >>> (32 - f)), r); - var c, f; - } - - function l(n, t, r, e, o, u, c) { - return f((t & r) | (~t & e), n, t, o, u, c); - } - - function v(n, t, r, e, o, u, c) { - return f((t & e) | (r & ~e), n, t, o, u, c); - } - - function g(n, t, r, e, o, u, c) { - return f(t ^ r ^ e, n, t, o, u, c); - } - - function m(n, t, r, e, o, u, c) { - return f(r ^ (t | ~e), n, t, o, u, c); - } - - function i(n, t) { - var r, e, o, u; - (n[t >> 5] |= 128 << t % 32), (n[14 + (((t + 64) >>> 9) << 4)] = t); - for ( - var c = 1732584193, - f = -271733879, - i = -1732584194, - a = 271733878, - h = 0; - h < n.length; - h += 16 - ) - (c = l((r = c), (e = f), (o = i), (u = a), n[h], 7, -680876936)), - (a = l(a, c, f, i, n[h + 1], 12, -389564586)), - (i = l(i, a, c, f, n[h + 2], 17, 606105819)), - (f = l(f, i, a, c, n[h + 3], 22, -1044525330)), - (c = l(c, f, i, a, n[h + 4], 7, -176418897)), - (a = l(a, c, f, i, n[h + 5], 12, 1200080426)), - (i = l(i, a, c, f, n[h + 6], 17, -1473231341)), - (f = l(f, i, a, c, n[h + 7], 22, -45705983)), - (c = l(c, f, i, a, n[h + 8], 7, 1770035416)), - (a = l(a, c, f, i, n[h + 9], 12, -1958414417)), - (i = l(i, a, c, f, n[h + 10], 17, -42063)), - (f = l(f, i, a, c, n[h + 11], 22, -1990404162)), - (c = l(c, f, i, a, n[h + 12], 7, 1804603682)), - (a = l(a, c, f, i, n[h + 13], 12, -40341101)), - (i = l(i, a, c, f, n[h + 14], 17, -1502002290)), - (c = v( - c, - (f = l(f, i, a, c, n[h + 15], 22, 1236535329)), - i, - a, - n[h + 1], - 5, - -165796510 - )), - (a = v(a, c, f, i, n[h + 6], 9, -1069501632)), - (i = v(i, a, c, f, n[h + 11], 14, 643717713)), - (f = v(f, i, a, c, n[h], 20, -373897302)), - (c = v(c, f, i, a, n[h + 5], 5, -701558691)), - (a = v(a, c, f, i, n[h + 10], 9, 38016083)), - (i = v(i, a, c, f, n[h + 15], 14, -660478335)), - (f = v(f, i, a, c, n[h + 4], 20, -405537848)), - (c = v(c, f, i, a, n[h + 9], 5, 568446438)), - (a = v(a, c, f, i, n[h + 14], 9, -1019803690)), - (i = v(i, a, c, f, n[h + 3], 14, -187363961)), - (f = v(f, i, a, c, n[h + 8], 20, 1163531501)), - (c = v(c, f, i, a, n[h + 13], 5, -1444681467)), - (a = v(a, c, f, i, n[h + 2], 9, -51403784)), - (i = v(i, a, c, f, n[h + 7], 14, 1735328473)), - (c = g( - c, - (f = v(f, i, a, c, n[h + 12], 20, -1926607734)), - i, - a, - n[h + 5], - 4, - -378558 - )), - (a = g(a, c, f, i, n[h + 8], 11, -2022574463)), - (i = g(i, a, c, f, n[h + 11], 16, 1839030562)), - (f = g(f, i, a, c, n[h + 14], 23, -35309556)), - (c = g(c, f, i, a, n[h + 1], 4, -1530992060)), - (a = g(a, c, f, i, n[h + 4], 11, 1272893353)), - (i = g(i, a, c, f, n[h + 7], 16, -155497632)), - (f = g(f, i, a, c, n[h + 10], 23, -1094730640)), - (c = g(c, f, i, a, n[h + 13], 4, 681279174)), - (a = g(a, c, f, i, n[h], 11, -358537222)), - (i = g(i, a, c, f, n[h + 3], 16, -722521979)), - (f = g(f, i, a, c, n[h + 6], 23, 76029189)), - (c = g(c, f, i, a, n[h + 9], 4, -640364487)), - (a = g(a, c, f, i, n[h + 12], 11, -421815835)), - (i = g(i, a, c, f, n[h + 15], 16, 530742520)), - (c = m( - c, - (f = g(f, i, a, c, n[h + 2], 23, -995338651)), - i, - a, - n[h], - 6, - -198630844 - )), - (a = m(a, c, f, i, n[h + 7], 10, 1126891415)), - (i = m(i, a, c, f, n[h + 14], 15, -1416354905)), - (f = m(f, i, a, c, n[h + 5], 21, -57434055)), - (c = m(c, f, i, a, n[h + 12], 6, 1700485571)), - (a = m(a, c, f, i, n[h + 3], 10, -1894986606)), - (i = m(i, a, c, f, n[h + 10], 15, -1051523)), - (f = m(f, i, a, c, n[h + 1], 21, -2054922799)), - (c = m(c, f, i, a, n[h + 8], 6, 1873313359)), - (a = m(a, c, f, i, n[h + 15], 10, -30611744)), - (i = m(i, a, c, f, n[h + 6], 15, -1560198380)), - (f = m(f, i, a, c, n[h + 13], 21, 1309151649)), - (c = m(c, f, i, a, n[h + 4], 6, -145523070)), - (a = m(a, c, f, i, n[h + 11], 10, -1120210379)), - (i = m(i, a, c, f, n[h + 2], 15, 718787259)), - (f = m(f, i, a, c, n[h + 9], 21, -343485551)), - (c = d(c, r)), - (f = d(f, e)), - (i = d(i, o)), - (a = d(a, u)); - return [c, f, i, a]; - } - - function a(n) { - for (var t = '', r = 32 * n.length, e = 0; e < r; e += 8) - t += String.fromCharCode((n[e >> 5] >>> e % 32) & 255); - return t; - } - - function h(n) { - var t = []; - for (t[(n.length >> 2) - 1] = void 0, e = 0; e < t.length; e += 1) - t[e] = 0; - for (var r = 8 * n.length, e = 0; e < r; e += 8) - t[e >> 5] |= (255 & n.charCodeAt(e / 8)) << e % 32; - return t; - } - - function e(n) { - for (var t, r = '0123456789abcdef', e = '', o = 0; o < n.length; o += 1) - (t = n.charCodeAt(o)), - (e += r.charAt((t >>> 4) & 15) + r.charAt(15 & t)); - return e; - } - - function r(n) { - return unescape(encodeURIComponent(n)); - } - - function o(n) { - return a(i(h((t = r(n))), 8 * t.length)); - var t; - } - - function u(n, t) { - return (function (n, t) { - var r, - e, - o = h(n), - u = [], - c = []; - for ( - u[15] = c[15] = void 0, - 16 < o.length && (o = i(o, 8 * n.length)), - r = 0; - r < 16; - r += 1 - ) - (u[r] = 909522486 ^ o[r]), (c[r] = 1549556828 ^ o[r]); - return ( - (e = i(u.concat(h(t)), 512 + 8 * t.length)), a(i(c.concat(e), 640)) - ); - })(r(n), r(t)); - } - - function t(n, t, r) { - return t ? (r ? u(t, n) : e(u(t, n))) : r ? o(n) : e(o(n)); - } - - return t(str); - } + // prettier-ignore + md5(str){function d(n,t){var r=(65535&n)+(65535&t);return(((n>>16)+(t>>16)+(r>>16))<<16)|(65535&r)}function f(n,t,r,e,o,u){return d(((c=d(d(t,n),d(e,u)))<<(f=o))|(c>>>(32-f)),r);var c,f}function l(n,t,r,e,o,u,c){return f((t&r)|(~t&e),n,t,o,u,c)}function v(n,t,r,e,o,u,c){return f((t&e)|(r&~e),n,t,o,u,c)}function g(n,t,r,e,o,u,c){return f(t^r^e,n,t,o,u,c)}function m(n,t,r,e,o,u,c){return f(r^(t|~e),n,t,o,u,c)}function i(n,t){var r,e,o,u;(n[t>>5]|=128<>>9)<<4)]=t);for(var c=1732584193,f=-271733879,i=-1732584194,a=271733878,h=0;h>5]>>>e%32)&255);return t}function h(n){var t=[];for(t[(n.length>>2)-1]=void 0,e=0;e>5]|=(255&n.charCodeAt(e/8))<>>4)&15)+r.charAt(15&t));return e}function r(n){return unescape(encodeURIComponent(n))}function o(n){return a(i(h((t=r(n))),8*t.length));var t}function u(n,t){return(function(n,t){var r,e,o=h(n),u=[],c=[];for(u[15]=c[15]=void 0,16 { if (!act || !M['_actions']) { // 弹出选择菜单 const actions = M['_actions']; - const table = new UITable(); const onClick = async (item) => { M.widgetFamily = item.val; w = await M.render(); @@ -1426,48 +1636,37 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { }; const preview = [ { - url: 'https://pic1.imgdb.cn/item/63315c3616f2c2beb1a2931a.png', + icon: { name: 'app', color: '#504ED5' }, title: '小尺寸', val: 'small', + name: 'small', dismissOnSelect: true, onClick, }, { - url: 'https://pic1.imgdb.cn/item/63315c2c16f2c2beb1a28706.png', + icon: { name: 'rectangle', color: '#504ED5' }, title: '中尺寸', val: 'medium', + name: 'medium', dismissOnSelect: true, onClick, }, { - url: 'https://pic1.imgdb.cn/item/63315c2716f2c2beb1a27f24.png', + icon: { name: 'app', color: '#504ED5' }, title: '大尺寸', val: 'large', + name: 'large', dismissOnSelect: true, onClick, }, ]; - await M.preferences(table, preview, '预览组件'); - const extra = []; - for (let _ in actions) { - const iconItem = M._actionsIcon[_]; - const isUrl = typeof iconItem === 'string'; - const actionItem = { - title: _, - onClick: actions[_], - }; - if (isUrl) { - actionItem.url = iconItem; - } else { - actionItem.icon = iconItem; - } - extra.push(actionItem); - } - await M.preferences(table, extra, '配置组件'); - return table.present(); + const menuConfig = [ + { title: '预览组件', menu: preview }, + { title: '组件配置', menu: actions }, + ]; + return M.renderAppView(menuConfig); } } }; - // await new DmYY().setWidgetConfig(); module.exports = { DmYY, Runing }; From d423363d46e5f0570b82f68895bd36039b1a66e2 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 11:27:40 +0800 Subject: [PATCH 086/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/12123.js | 56 ++--- Scripts/Contact.js | 440 +++++++++++++++++++++------------------- Scripts/DmYY.js | 58 +++++- Scripts/PriceWidgets.js | 23 ++- 4 files changed, 323 insertions(+), 254 deletions(-) diff --git a/Scripts/12123.js b/Scripts/12123.js index 34a9b72..3714c6c 100644 --- a/Scripts/12123.js +++ b/Scripts/12123.js @@ -4,7 +4,7 @@ // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 if (typeof require === 'undefined') require = importModule; -const {DmYY, Runing} = require('./DmYY'); +const { DmYY, Runing } = require('./DmYY'); const API_PARAMS = { api4: 'biz.vio.detail.query', @@ -14,7 +14,7 @@ const API_PARAMS = { alipay: 'alipays://platformapi/startapp?appId=2019050964403523', api2: 'biz.vio.peccancyChannelList.query', status: - 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', + 'alipays://platformapi/startapp?appId=2019050964403523&page=pages%2Flicense%2Flicense', update: 'https://gitcode.net/4qiao/scriptable/raw/master/api/violation.js', api3: 'biz.vio.peccancyUnhandleInfoList.query', Ver: 'Version 1.2\n\nverifyToken过期需打开Quantumult-X', @@ -32,19 +32,23 @@ class Widget extends DmYY { this.en = '12123'; this.name = '交管 12123'; config.runsInApp && - this.registerAction( - 'Token', - async () => { + this.registerAction({ + icon: { name: 'paperplane', color: '#722ed1' }, + type: 'input', + title: 'Token', + desc: '微信小程序交管12123获取', + val: 'Token', + onClick: async () => { const token = this.settings.token; - this.settings.token = (await this.getCache('wx_12123', false)) || - token; + this.settings.token = + (await this.getCache('wx_12123', false)) || token; if (this.settings.token) this.saveSettings(false); return this.setAlertInput('Token', '设置 token', { token: '微信小程序交管12123获取', }); }, - {name: 'paperplane', color: '#722ed1'}, - ); + }); + config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); } @@ -65,25 +69,25 @@ class Widget extends DmYY { title: '川 G88888', icon: 'car.fill', listItem: [ - {label: '未处违法', value: `0`, unit: '条'}, - {label: '车辆状态', value: '正常'}, - {label: '上次更新', value: '00:00'}, + { label: '未处违法', value: `0`, unit: '条' }, + { label: '车辆状态', value: '正常' }, + { label: '上次更新', value: '00:00' }, ], }, right: { title: '驾驶证', icon: 'creditcard.fill', listItem: [ - {label: '证件状态', value: '正常'}, - {label: '累计扣分', value: `0`, unit: '分'}, - {label: '重置日期', value: '—'}, + { label: '证件状态', value: '正常' }, + { label: '累计扣分', value: `0`, unit: '分' }, + { label: '重置日期', value: '—' }, ], }, }; init = async () => { this.settings.token = - (await this.getCache('wx_12123', false)) || this.settings.token; + (await this.getCache('wx_12123', false)) || this.settings.token; if (this.settings.dataSource) { this.dataSource = this.settings.dataSource; } else { @@ -117,22 +121,22 @@ class Widget extends DmYY { const details = await this.$request.post(API_PARAMS.infoURL, { body: `params=${encodeURIComponent( - JSON.stringify({ - api: 'biz.user.integration.query', - productId: API_PARAMS.productId, - ...params, - }), + JSON.stringify({ + api: 'biz.user.integration.query', + productId: API_PARAMS.productId, + ...params, + }) )}`, }); console.log(details); if (details.success) { - const {drivingLicense, vehicles} = details.data; + const { drivingLicense, vehicles } = details.data; const reaccDate = drivingLicense.reaccDate.split('-'); this.dataSource.right.title = `驾驶证 ${drivingLicense.allowToDrive}`; this.dataSource.right.listItem[1].value = - drivingLicense.cumulativePoint; + drivingLicense.cumulativePoint; this.dataSource.right.listItem[2].value = `${reaccDate[1]}-${reaccDate[2]}`; if (vehicles.length) { @@ -146,9 +150,9 @@ class Widget extends DmYY { this.saveSettings(false); } else { this.notify( - `verifyToken已过期 ⚠️`, - '点击通知框自动跳转到支付宝小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', - API_PARAMS.alipay, + `verifyToken已过期 ⚠️`, + '点击通知框自动跳转到支付宝小程序交管12123页面获取最新的Token ( 请确保已打开辅助工具 )', + API_PARAMS.alipay ); } } catch (e) { diff --git a/Scripts/Contact.js b/Scripts/Contact.js index 9e58caf..9237e34 100644 --- a/Scripts/Contact.js +++ b/Scripts/Contact.js @@ -3,219 +3,239 @@ // icon-color: deep-green; icon-glyph: mobile-alt; // 添加require,是为了vscode中可以正确引入包,以获得自动补全等功能 -if (typeof require === "undefined") require = importModule; -const { DmYY, Runing } = require("./DmYY"); +if (typeof require === 'undefined') require = importModule; +const { DmYY, Runing } = require('./DmYY'); // @组件代码开始 class Widget extends DmYY { - constructor(arg) { - super(arg); - this.name = "桌面联系人"; - this.en = "ContactTable"; - this.userName = arg || "Ya"; - this.Run(); - } - - - today = ""; - useBoxJS = false; - dataSource = {}; - phoneNumber = {}; - size1 = new Size(15, 15); - size2 = new Size(30, 30); - - - init = async () => { - try { - const cardAll = await ContactsContainer.all(); - const data = await Contact.all(cardAll); - if (!this.userName) { - this.dataSource = data[0]; - } else { - this.dataSource = data.find(item => { - return (item.familyName === this.userName || - item.givenName === this.userName || - item.nickname === this.userName || - `${item.familyName}${item.givenName}` === this.userName - ); - }); - } - if (!this.dataSource) return this.notify(this.name, "未找到通讯录相关联系人,请重新设置"); - this.userName = `${this.dataSource.familyName}${this.dataSource.givenName}`; - const phoneNumbers = this.dataSource.phoneNumbers; - if (phoneNumbers.length) { - this.phoneNumber = phoneNumbers[0]; - this.phoneNumber.value = this.phoneNumber.value.replaceAll(" ", ""); - } - } catch (e) { - console.log(e); - } - }; - - setAvatar = (w) => { - const stackBody = w.addStack(); - const stackLeft = stackBody.addStack(); - stackLeft.setPadding(10, 10, 10, 0); - stackLeft.layoutVertically(); - stackLeft.addSpacer(); - const stackAvatar = stackLeft.addStack(); - stackAvatar.centerAlignContent(); - stackAvatar.size = new Size(80, 80); - stackAvatar.borderWidth = 7; - stackAvatar.borderColor = new Color("#222", 0.7); - stackAvatar.cornerRadius = 40; - if (this.dataSource.image) { - const imgAvatar = stackAvatar.addImage(this.dataSource.image); - imgAvatar.imageSize = new Size(80, 80); - } else { - let textFormat = this.textFormat.title; - textFormat.color = this.widgetColor; - textFormat.size = 42; - this.provideText(this.userName.substr(0, 1) || "", stackAvatar, textFormat); - } - stackLeft.addSpacer(); - stackBody.addSpacer(5); - return stackBody; - }; - - setContentCenter = (stackBody) => { - const stackCenter = stackBody.addStack(); - stackCenter.setPadding(10, 0, 10, 10); - stackCenter.layoutVertically(); - stackCenter.addSpacer(); - const stackUsername = stackCenter.addStack(); - stackUsername.centerAlignContent(); - stackCenter.addSpacer(15); - const stackPhoneNumber = stackCenter.addStack(); - stackPhoneNumber.centerAlignContent(); - stackCenter.addSpacer(15); - const stackNote = stackCenter.addStack(); - stackNote.centerAlignContent(); - stackCenter.addSpacer(); - - let textFormat = this.textFormat.defaultText; - textFormat.color = this.widgetColor; - textFormat.size = 18; - const phoneNumber = this.phoneNumber.value || ""; - - const iconPerson = SFSymbol.named("person"); - const imgPerson = stackUsername.addImage(iconPerson.image); - imgPerson.tintColor = this.widgetColor; - imgPerson.imageSize = this.size1; - stackUsername.addSpacer(5); - - const iconPhone = SFSymbol.named("iphone"); - const imgIphone = stackPhoneNumber.addImage(iconPhone.image); - imgIphone.tintColor = this.widgetColor; - imgIphone.imageSize = this.size1; - stackPhoneNumber.addSpacer(5); - - const iconNote = SFSymbol.named("envelope"); - const imgNote = stackNote.addImage(iconNote.image); - imgNote.tintColor = this.widgetColor; - imgNote.imageSize = this.size1; - stackNote.addSpacer(5); - - const data = this.dataSource.emailAddresses; - const email = data.length ? data[0] : {}; - this.provideText(this.userName || "", stackUsername, textFormat); - this.provideText(phoneNumber || "", stackPhoneNumber, textFormat); - const mailTextItem = this.provideText(email.value || "", stackNote, textFormat); - mailTextItem.lineLimit = 1; - - stackBody.addSpacer(); - return stackBody; - }; - - stepActionRight = (stackBody) => { - const stackRight = stackBody.addStack(); - stackRight.setPadding(10, 20, 10, 20); - stackRight.layoutVertically(); - stackRight.backgroundColor = this.widgetOpacityColor; - - stackRight.addSpacer(); - const stackCallPhone = stackRight.addStack(); - stackRight.addSpacer(); - const stackSendMessage = stackRight.addStack(); - stackRight.addSpacer(); - const stackDetail = stackRight.addStack(); - stackRight.addSpacer(); - - const phone = this.phoneNumber.value || ""; - const data = this.dataSource.emailAddresses; - const email = data.length ? data[0] : {}; - - stackCallPhone.url = `tel:${phone}`; - stackSendMessage.url = `sms:${phone}`; - stackDetail.url = `mailto:${email.value || ""}`; - - const iconVideo = SFSymbol.named("video"); - const imgVideo = stackCallPhone.addImage(iconVideo.image); - imgVideo.tintColor = this.backGroundColor; - imgVideo.imageSize = this.size2; - - const iconMessage = SFSymbol.named("message"); - const imgMessage = stackSendMessage.addImage(iconMessage.image); - imgMessage.tintColor = this.backGroundColor; - imgMessage.imageSize = this.size2; - - const iconEnvelope = SFSymbol.named("envelope.open"); - const imgEnvelope = stackDetail.addImage(iconEnvelope.image); - imgEnvelope.tintColor = this.backGroundColor; - imgEnvelope.imageSize = this.size2; - - return stackBody; - }; - - renderSmall = (w) => { - this.setContentCenter(stackBody); - this.stepActionRight(stackBody); - return w; - }; - - renderLarge = (w) => { - const stackBody = this.setAvatar(w); - this.setContentCenter(stackBody); - this.stepActionRight(stackBody); - return w; - }; - - renderMedium = (w) => { - const stackBody = this.setAvatar(w); - this.setContentCenter(stackBody); - this.stepActionRight(stackBody); - return w; - }; - - Run() { - if (config.runsInApp) { - this.registerAction("右侧透明", async () => { - await this.setAlertInput("右侧透明", "若不需要右侧背景设置透明度 0 即可", { rightOpacity: "透明度 0~1" }); - }); - this.registerAction("基础设置", this.setWidgetConfig); - } - const light = new Color(this.settings.lightColor, parseInt(this.settings.rightOpacity || 1)); - const dark = new Color(this.settings.darkColor, parseInt(this.settings.rightOpacity || 1)); - this.widgetOpacityColor = Color.dynamic(light, dark); - } - - /** - * 渲染函数,函数名固定 - * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 - */ - async render() { - await this.init(); - const widget = new ListWidget(); - widget.setPadding(0, 0, 0, 0); - await this.getWidgetBackgroundImage(widget); - if (this.widgetFamily === "medium") { - return await this.renderMedium(widget); - } else if (this.widgetFamily === "large") { - return await this.renderLarge(widget); - } else { - return await this.renderSmall(widget); - } - } + constructor(arg) { + super(arg); + this.name = '桌面联系人'; + this.en = 'ContactTable'; + this.userName = arg || 'Ya'; + this.Run(); + } + + today = ''; + useBoxJS = false; + dataSource = {}; + phoneNumber = {}; + size1 = new Size(15, 15); + size2 = new Size(30, 30); + + init = async () => { + try { + const cardAll = await ContactsContainer.all(); + const data = await Contact.all(cardAll); + if (!this.userName) { + this.dataSource = data[0]; + } else { + this.dataSource = data.find((item) => { + return ( + item.familyName === this.userName || + item.givenName === this.userName || + item.nickname === this.userName || + `${item.familyName}${item.givenName}` === this.userName + ); + }); + } + if (!this.dataSource) + return this.notify(this.name, '未找到通讯录相关联系人,请重新设置'); + this.userName = `${this.dataSource.familyName}${this.dataSource.givenName}`; + const phoneNumbers = this.dataSource.phoneNumbers; + if (phoneNumbers.length) { + this.phoneNumber = phoneNumbers[0]; + this.phoneNumber.value = this.phoneNumber.value.replaceAll(' ', ''); + } + } catch (e) { + console.log(e); + } + }; + + setAvatar = (w) => { + const stackBody = w.addStack(); + const stackLeft = stackBody.addStack(); + stackLeft.setPadding(10, 10, 10, 0); + stackLeft.layoutVertically(); + stackLeft.addSpacer(); + const stackAvatar = stackLeft.addStack(); + stackAvatar.centerAlignContent(); + stackAvatar.size = new Size(80, 80); + stackAvatar.borderWidth = 7; + stackAvatar.borderColor = new Color('#222', 0.7); + stackAvatar.cornerRadius = 40; + if (this.dataSource.image) { + const imgAvatar = stackAvatar.addImage(this.dataSource.image); + imgAvatar.imageSize = new Size(80, 80); + } else { + let textFormat = this.textFormat.title; + textFormat.color = this.widgetColor; + textFormat.size = 42; + this.provideText( + this.userName.substr(0, 1) || '', + stackAvatar, + textFormat + ); + } + stackLeft.addSpacer(); + stackBody.addSpacer(5); + return stackBody; + }; + + setContentCenter = (stackBody) => { + const stackCenter = stackBody.addStack(); + stackCenter.setPadding(10, 0, 10, 10); + stackCenter.layoutVertically(); + stackCenter.addSpacer(); + const stackUsername = stackCenter.addStack(); + stackUsername.centerAlignContent(); + stackCenter.addSpacer(15); + const stackPhoneNumber = stackCenter.addStack(); + stackPhoneNumber.centerAlignContent(); + stackCenter.addSpacer(15); + const stackNote = stackCenter.addStack(); + stackNote.centerAlignContent(); + stackCenter.addSpacer(); + + let textFormat = this.textFormat.defaultText; + textFormat.color = this.widgetColor; + textFormat.size = 18; + const phoneNumber = this.phoneNumber.value || ''; + + const iconPerson = SFSymbol.named('person'); + const imgPerson = stackUsername.addImage(iconPerson.image); + imgPerson.tintColor = this.widgetColor; + imgPerson.imageSize = this.size1; + stackUsername.addSpacer(5); + + const iconPhone = SFSymbol.named('iphone'); + const imgIphone = stackPhoneNumber.addImage(iconPhone.image); + imgIphone.tintColor = this.widgetColor; + imgIphone.imageSize = this.size1; + stackPhoneNumber.addSpacer(5); + + const iconNote = SFSymbol.named('envelope'); + const imgNote = stackNote.addImage(iconNote.image); + imgNote.tintColor = this.widgetColor; + imgNote.imageSize = this.size1; + stackNote.addSpacer(5); + + const data = this.dataSource.emailAddresses; + const email = data.length ? data[0] : {}; + this.provideText(this.userName || '', stackUsername, textFormat); + this.provideText(phoneNumber || '', stackPhoneNumber, textFormat); + const mailTextItem = this.provideText( + email.value || '', + stackNote, + textFormat + ); + mailTextItem.lineLimit = 1; + + stackBody.addSpacer(); + return stackBody; + }; + + stepActionRight = (stackBody) => { + const stackRight = stackBody.addStack(); + stackRight.setPadding(10, 20, 10, 20); + stackRight.layoutVertically(); + stackRight.backgroundColor = this.widgetOpacityColor; + + stackRight.addSpacer(); + const stackCallPhone = stackRight.addStack(); + stackRight.addSpacer(); + const stackSendMessage = stackRight.addStack(); + stackRight.addSpacer(); + const stackDetail = stackRight.addStack(); + stackRight.addSpacer(); + + const phone = this.phoneNumber.value || ''; + const data = this.dataSource.emailAddresses; + const email = data.length ? data[0] : {}; + + stackCallPhone.url = `tel:${phone}`; + stackSendMessage.url = `sms:${phone}`; + stackDetail.url = `mailto:${email.value || ''}`; + + const iconVideo = SFSymbol.named('video'); + const imgVideo = stackCallPhone.addImage(iconVideo.image); + imgVideo.tintColor = this.backGroundColor; + imgVideo.imageSize = this.size2; + + const iconMessage = SFSymbol.named('message'); + const imgMessage = stackSendMessage.addImage(iconMessage.image); + imgMessage.tintColor = this.backGroundColor; + imgMessage.imageSize = this.size2; + + const iconEnvelope = SFSymbol.named('envelope.open'); + const imgEnvelope = stackDetail.addImage(iconEnvelope.image); + imgEnvelope.tintColor = this.backGroundColor; + imgEnvelope.imageSize = this.size2; + + return stackBody; + }; + + renderSmall = (w) => { + this.setContentCenter(stackBody); + this.stepActionRight(stackBody); + return w; + }; + + renderLarge = (w) => { + const stackBody = this.setAvatar(w); + this.setContentCenter(stackBody); + this.stepActionRight(stackBody); + return w; + }; + + renderMedium = (w) => { + const stackBody = this.setAvatar(w); + this.setContentCenter(stackBody); + this.stepActionRight(stackBody); + return w; + }; + + Run() { + if (config.runsInApp) { + this.registerAction({ + icon: { name: 'phone', color: '#722ed1' }, + type: 'input', + title: '右侧透明', + desc: '若不需要右侧背景设置透明度 0 即可', + placeholder: '透明度 0~1', + val: 'rightOpacity', + }); + + this.registerAction('基础设置', this.setWidgetConfig); + } + const light = new Color( + this.settings.lightColor, + parseInt(this.settings.rightOpacity || 1) + ); + const dark = new Color( + this.settings.darkColor, + parseInt(this.settings.rightOpacity || 1) + ); + this.widgetOpacityColor = Color.dynamic(light, dark); + } + + /** + * 渲染函数,函数名固定 + * 可以根据 this.widgetFamily 来判断小组件尺寸,以返回不同大小的内容 + */ + async render() { + await this.init(); + const widget = new ListWidget(); + widget.setPadding(0, 0, 0, 0); + await this.getWidgetBackgroundImage(widget); + if (this.widgetFamily === 'medium') { + return await this.renderMedium(widget); + } else if (this.widgetFamily === 'large') { + return await this.renderLarge(widget); + } else { + return await this.renderSmall(widget); + } + } } // @组件代码结束 diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 20385c5..1af2f4c 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -464,7 +464,7 @@ class DmYY { const a = new Alert(); a.title = title; a.message = desc; - a.addTextField(placeholder, `${this.settings[val]}`); + a.addTextField(placeholder, `${this.settings[val] || ''}`); a.addAction('确定'); a.addCancelAction('取消'); const id = await a.presentAlert(); @@ -774,6 +774,10 @@ class DmYY { ); }; + dismissWeb = (webView) => { + webView.evaluateJavaScript('window.close()', false); + }; + insertTextByElementId = (webView, elementId, text) => { const scripts = `document.getElementById("${elementId}_val").innerHTML=\`${text}\`;`; webView.evaluateJavaScript(scripts, false); @@ -789,7 +793,7 @@ class DmYY { }; async renderAppView(options = [], previewWebView = new WebView()) { - const settingItemFontSize = 16, + const settingItemFontSize = 14, authorNameFontSize = 20, authorDescFontSize = 12; // ================== 配置界面样式 =================== @@ -880,6 +884,9 @@ class DmYY { font-size: 13px; color: #86868b; margin: 0 4px 0 auto; + max-width: 100px; + overflow: hidden; + text-overflow: ellipsis; } .form-item + .form-item::before { content: ""; @@ -1035,7 +1042,12 @@ class DmYY { if(e.target.name) invoke(e.target.name, e.target.value); }) } - + + document.querySelectorAll('.form-item-auth')[0].addEventListener('click', (e) => { + toggleIcoLoading(e); + invoke("reset"); + }) + })()`; let configList = ``; @@ -1064,7 +1076,7 @@ class DmYY { ).toBase64String()}`; } } catch (e) { - iconBase64 = await this.loadSF2B64('photo'); + iconBase64 = await this.loadSF2B64('gear'); } } else { const icon = menuItem.icon || {}; @@ -1114,6 +1126,23 @@ class DmYY { +
    +
    + +
    +
    ${configList}
    @@ -1160,9 +1189,22 @@ class DmYY { (item) => (item.name || item.val) === code ); - if (!actionItem) { - this.notify('异常提示', '当前操作异常'); - } else { + if (code === 'reset') { + const options = ['取消', '确定']; + const message = '确定要重置当前所有配置吗?'; + const index = await this.generateAlert(message, options); + if (index === 1) { + this.settings = {}; + await this.setBackgroundImage(false, 'dayBg', false); + await this.setBackgroundImage(false, 'nightBg', false); + await this.setBackgroundImage(false, 'transparentBg', false); + this.saveSettings(false); + this.dismissWeb(previewWebView); + await this.notify('重置成功', '请关闭窗口之后,重新运行当前脚本'); + } + } + + if (actionItem) { const idName = actionItem?.name || actionItem?.val; if (actionItem?.onClick) { await actionItem?.onClick?.(actionItem, data, previewWebView); @@ -1256,6 +1298,8 @@ class DmYY { this.prefix = this.settings.boxjsDomain; + config.runsInApp && this.saveSettings(false); + this.backGroundColor = Color.dynamic( new Color(this.settings.lightBgColor), new Color(this.settings.darkBgColor) diff --git a/Scripts/PriceWidgets.js b/Scripts/PriceWidgets.js index 2ec32a4..fd60bf6 100644 --- a/Scripts/PriceWidgets.js +++ b/Scripts/PriceWidgets.js @@ -12,17 +12,18 @@ class Widget extends DmYY { super(arg); this.en = ' btc'; this.name = '比特币'; - config.runsInApp && - this.registerAction( - '关注种类', - async () => { - return this.setAlertInput('比特币种类', '设置关注种类', { - btcType: 'BTC,ETH,BNB', - }); - }, - { name: 'centsign.circle', color: '#feda31' } - ); - config.runsInApp && this.registerAction('基础设置', this.setWidgetConfig); + + if (config.runsInApp) { + this.registerAction({ + icon: { name: 'centsign.circle', color: '#feda31' }, + type: 'input', + title: '比特币种类', + desc: '设置关注种类', + placeholder: 'BTC,ETH,BNB', + val: 'btcType', + }); + this.registerAction('基础设置', this.setWidgetConfig); + } } format = (str) => { From cd13f4a54f89a5ddf48746d0bbda1e190a95b04c Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 11:33:48 +0800 Subject: [PATCH 087/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E5=AD=90?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 1af2f4c..1e0593b 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -792,7 +792,11 @@ class DmYY { return `data:image/png;base64,${Data.fromPNG(sfImg).toBase64String()}`; }; - async renderAppView(options = [], previewWebView = new WebView()) { + async renderAppView( + options = [], + renderAvatar = false, + previewWebView = new WebView() + ) { const settingItemFontSize = 14, authorNameFontSize = 20, authorDescFontSize = 12; @@ -1126,23 +1130,28 @@ class DmYY { -
    -
    - -
    -
    + ${ + renderAvatar + ? ` +
    +
    + +
    +
    ` + : '' + } ${configList}
    @@ -1708,7 +1717,7 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { { title: '预览组件', menu: preview }, { title: '组件配置', menu: actions }, ]; - return M.renderAppView(menuConfig); + return M.renderAppView(menuConfig, true); } } }; From 5151fdaf3810906b7aaab168d4cccbbc5e895bfc Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 11:38:21 +0800 Subject: [PATCH 088/152] Fix:undefined --- Scripts/DmYY.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 1e0593b..812925a 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -1227,7 +1227,7 @@ class DmYY { this.insertTextByElementId( previewWebView, idName, - this.settings[actionItem.val] + this.settings[actionItem.val] || '' ); } else if (actionItem.type === 'img') { const backImage = await this.chooseImg(); From fc61b69d22809277b9ec86b7da0ca1fdd5cd90a3 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 11:43:36 +0800 Subject: [PATCH 089/152] =?UTF-8?q?add:=E5=A2=9E=E5=8A=A0=E9=80=92?= =?UTF-8?q?=E5=BD=92=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 812925a..6268801 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -1067,6 +1067,11 @@ class DmYY { for (const menuItem of item.menu) { let iconBase64 = ``; + if (menuItem.children) { + menuItem.onClick = () => { + this.renderAppView(menuItem.children); + }; + } if (menuItem.url) { try { const imageIcon = await this.$request.get(menuItem.url, 'IMG'); From 3465117c429cc024765acd8006b0dcaceb84a768 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 12:47:11 +0800 Subject: [PATCH 090/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=8A=A0=E8=BD=BD=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 56 +++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 6268801..f92672f 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -32,8 +32,11 @@ class DmYY { // 发起请求 http = async ( - options = { headers: {}, url: '', cache: tru }, - type = 'JSON' + options = { headers: {}, url: '' }, + type = 'JSON', + onError = () => { + return SFSymbol.named('photo').image; + } ) => { let request; try { @@ -67,13 +70,13 @@ class DmYY { return await request.loadJSON(); } catch (e) { console.log('error:' + e); - if (type === 'IMG') return SFSymbol.named('photo').image; + if (type === 'IMG') return onError?.(); } }; //request 接口请求 $request = { - get: async (url = '', options = {}, type = 'JSON') => { + get: (url = '', options = {}, type = 'JSON') => { let params = { ...options, method: 'GET' }; if (typeof url === 'object') { params = { ...params, ...url }; @@ -82,9 +85,9 @@ class DmYY { } let _type = type; if (typeof options === 'string') _type = options; - return await this.http(params, _type); + return this.http(params, _type); }, - post: async (url = '', options = {}, type = 'JSON') => { + post: (url = '', options = {}, type = 'JSON') => { let params = { ...options, method: 'POST' }; if (typeof url === 'object') { params = { ...params, ...url }; @@ -93,7 +96,7 @@ class DmYY { } let _type = type; if (typeof options === 'string') _type = options; - return await this.http(params, _type); + return this.http(params, _type); }, }; @@ -705,7 +708,7 @@ class DmYY { drawTableIcon = async ( icon = 'square.grid.2x2', - color = '#e8e8e8', + color = '#504ED5', cornerWidth = 42 ) => { const sfi = SFSymbol.named(icon); @@ -1073,19 +1076,22 @@ class DmYY { }; } if (menuItem.url) { - try { - const imageIcon = await this.$request.get(menuItem.url, 'IMG'); - if (menuItem.url.indexOf('png') !== -1) { - iconBase64 = `data:image/png;base64,${Data.fromPNG( - imageIcon - ).toBase64String()}`; - } else { - iconBase64 = `data:image/png;base64,${Data.fromJPEG( - imageIcon - ).toBase64String()}`; + const imageIcon = await this.http( + { url: menuItem.url }, + 'IMG', + () => { + return this.drawTableIcon('gear'); } - } catch (e) { - iconBase64 = await this.loadSF2B64('gear'); + ); + + if (menuItem.url.indexOf('png') !== -1) { + iconBase64 = `data:image/png;base64,${Data.fromPNG( + imageIcon + ).toBase64String()}`; + } else { + iconBase64 = `data:image/png;base64,${Data.fromJPEG( + imageIcon + ).toBase64String()}`; } } else { const icon = menuItem.icon || {}; @@ -1285,9 +1291,9 @@ class DmYY { ); this.cacheImageBgPath = [ - `${this.cacheImage}/transparentBg`, - `${this.cacheImage}/dayBg`, - `${this.cacheImage}/nightBg`, + `${this.cacheImage}/transparentBg.jpg`, + `${this.cacheImage}/dayBg.jpg`, + `${this.cacheImage}/nightBg.jpg`, ]; if (!this.FILE_MGR.fileExists(this.cacheImage)) { @@ -1541,7 +1547,7 @@ class DmYY { * @param {Image} img */ setBackgroundImage(img, key, notify = true) { - const cacheKey = `${this.cacheImage}/${key}`; + const cacheKey = `${this.cacheImage}/${key}.jpg`; if (!img) { // 移除背景 if (this.FILE_MGR.fileExists(cacheKey)) this.FILE_MGR.remove(cacheKey); @@ -1722,7 +1728,7 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { { title: '预览组件', menu: preview }, { title: '组件配置', menu: actions }, ]; - return M.renderAppView(menuConfig, true); + M.renderAppView(menuConfig, true); } } }; From f87eadf60183761c1dde7ecf5df10a9893e4679a Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 13:10:26 +0800 Subject: [PATCH 091/152] =?UTF-8?q?fix=EF=BC=9A=E5=9B=BE=E7=89=87=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index f92672f..4367bd5 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -658,25 +658,25 @@ class DmYY { title: '清空背景图片', onClick: async (_, __, previewWebView) => { const options = [ - '取消', '清空日间', '清空夜间', '清空透明', `清空全部`, + '取消', ]; const message = '该操作不可逆,会清空背景图片!'; const index = await this.generateAlert(message, options); - if (index === 0) return; + if (index === 4) return; switch (index) { - case 1: + case 0: await this.setBackgroundImage(false, 'dayBg'); this.insertTextByElementId(previewWebView, 'dayBg', ``); return; - case 2: + case 1: await this.setBackgroundImage(false, 'nightBg'); this.insertTextByElementId(previewWebView, 'nightBg', ``); return; - case 3: + case 2: await this.setBackgroundImage(false, 'transparentBg'); this.insertTextByElementId( previewWebView, @@ -1108,7 +1108,7 @@ class DmYY { } else if (menuItem.type === 'color') { defaultHtml = ``; } else if (menuItem.type === 'img') { - const cachePath = `${this.cacheImage}/${menuItem.name}`; + const cachePath = `${this.cacheImage}/${menuItem.name}.jpg`; if (this.FILE_MGR.fileExists(cachePath)) { const imageSrc = `data:image/png;base64,${Data.fromFile( cachePath From 874e98ed7057cbc69d3342182fef326cfa4825a8 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 13:12:30 +0800 Subject: [PATCH 092/152] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E5=9B=BE=E7=89=87=E6=8F=8F=E8=BF=B0=E6=96=87=E6=A1=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 4367bd5..f35b27c 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -685,8 +685,8 @@ class DmYY { ); return; default: - await this.setBackgroundImage(false, 'dayBg'); - await this.setBackgroundImage(false, 'nightBg'); + await this.setBackgroundImage(false, 'dayBg', false); + await this.setBackgroundImage(false, 'nightBg', false); await this.setBackgroundImage(false, 'transparentBg'); this.insertTextByElementId(previewWebView, 'dayBg', ``); this.insertTextByElementId(previewWebView, 'nightBg', ``); @@ -1551,14 +1551,12 @@ class DmYY { if (!img) { // 移除背景 if (this.FILE_MGR.fileExists(cacheKey)) this.FILE_MGR.remove(cacheKey); - if (notify) - this.notify('移除成功', '小组件白天背景图片已移除,稍后刷新生效'); + if (notify) this.notify('移除成功', '背景图片已移除,稍后刷新生效'); } else { // 设置背景 this.FILE_MGR.writeImage(cacheKey, img); - if (notify) - this.notify('设置成功', '小组件白天背景图片已设置!稍后刷新生效'); + if (notify) this.notify('设置成功', '背景图片已设置!稍后刷新生效'); return `data:image/png;base64,${Data.fromFile( cacheKey ).toBase64String()}`; From e26b90ba7ba59218ef34ad021d5b1195941aeea6 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 16:38:28 +0800 Subject: [PATCH 093/152] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 72 +++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 38 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index f35b27c..4a962ed 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -472,7 +472,7 @@ class DmYY { a.addCancelAction('取消'); const id = await a.presentAlert(); if (id === -1) return; - this.settings[val] = a.textFieldValue(0); + this.settings[val] = a.textFieldValue(0) || ''; this.saveSettings(); } catch (e) { console.log(e); @@ -499,7 +499,7 @@ class DmYY { if (id === -1) return; const data = {}; Object.keys(opt).forEach((key, index) => { - data[key] = a.textFieldValue(index); + data[key] = a.textFieldValue(index) || ''; }); // 保存到本地 if (isSave) { @@ -777,10 +777,6 @@ class DmYY { ); }; - dismissWeb = (webView) => { - webView.evaluateJavaScript('window.close()', false); - }; - insertTextByElementId = (webView, elementId, text) => { const scripts = `document.getElementById("${elementId}_val").innerHTML=\`${text}\`;`; webView.evaluateJavaScript(scripts, false); @@ -1021,20 +1017,27 @@ class DmYY { // 切换ico的loading效果 const toggleIcoLoading = (e) => { - const target = e.currentTarget - target.classList.add('loading') - const icon = e.currentTarget.querySelector('.iconfont') - const className = icon.className - icon.className = 'iconfont icon-loading' - const listener = (event) => { - const { code } = event.detail - if (code === 'finishLoading') { - target.classList.remove('loading') - icon.className = className - window.removeEventListener('JWeb', listener); + try{ + const target = e.currentTarget + target.classList.add('loading') + const icon = e.currentTarget.querySelector('.iconfont') + const className = icon.className + icon.className = 'iconfont icon-loading' + const listener = (event) => { + const { code } = event.detail + if (code === 'finishLoading') { + target.classList.remove('loading') + icon.className = className + window.removeEventListener('JWeb', listener); + } } - } - window.addEventListener('JWeb', listener) + window.addEventListener('JWeb', listener) + }catch(e){ + for (const loading of document.querySelectorAll('.icon-loading')) { + loading.classList.remove('loading'); + loading.className = "iconfont icon-arrow-right"; + } + } }; for (const btn of document.querySelectorAll('.form-item')) { @@ -1177,19 +1180,14 @@ class DmYY { }); const injectListener = async () => { - const event = await previewWebView - .evaluateJavaScript( - `(() => { + const event = await previewWebView.evaluateJavaScript( + `(() => { try { - const controller = new AbortController() - const listener = (e) => { - completion(e.detail) - controller.abort() - } window.addEventListener( 'JBridge', - listener, - { signal: controller.signal } + (e)=>{ + completion(JSON.stringify(e.detail||{})) + } ) } catch (e) { alert("预览界面出错:" + e); @@ -1197,14 +1195,12 @@ class DmYY { return; } })()`, - true - ) - .catch((err) => { - console.error(err); - this.dismissLoading(previewWebView); - }); - const { code, data } = event; + true + ); + + const { code, data } = JSON.parse(event); + const actionItem = actionsConfig.find( (item) => (item.name || item.val) === code ); @@ -1219,7 +1215,6 @@ class DmYY { await this.setBackgroundImage(false, 'nightBg', false); await this.setBackgroundImage(false, 'transparentBg', false); this.saveSettings(false); - this.dismissWeb(previewWebView); await this.notify('重置成功', '请关闭窗口之后,重新运行当前脚本'); } } @@ -1726,9 +1721,10 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { { title: '预览组件', menu: preview }, { title: '组件配置', menu: actions }, ]; - M.renderAppView(menuConfig, true); + await M.renderAppView(menuConfig, true); } } }; + // await new DmYY().setWidgetConfig(); module.exports = { DmYY, Runing }; From 40fbc129e15e71d5ee1d3874def6cb90a430e178 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Wed, 8 Feb 2023 17:20:02 +0800 Subject: [PATCH 094/152] =?UTF-8?q?fix:=E8=83=8C=E6=99=AF=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 4a962ed..a499ee0 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -1197,10 +1197,9 @@ class DmYY { })()`, true ); - + const { code, data } = JSON.parse(event); - const actionItem = actionsConfig.find( (item) => (item.name || item.val) === code ); @@ -1527,14 +1526,14 @@ class DmYY { if (this.FILE_MGR.fileExists(this.cacheImageBgPath[0])) return Image.fromFile(this.cacheImageBgPath[0]); - if ( - Device.isUsingDarkAppearance() && - this.FILE_MGR.fileExists(this.cacheImageBgPath[1]) - ) - return Image.fromFile(this.cacheImageBgPath[1]); - - if (this.FILE_MGR.fileExists(this.cacheImageBgPath[2])) - return this.cacheImageBgPath[2]; + if (Device.isUsingDarkAppearance()) + return this.FILE_MGR.fileExists(this.cacheImageBgPath[1]) + ? Image.fromFile(this.cacheImageBgPath[1]) + : undefined; + else + return this.FILE_MGR.fileExists(this.cacheImageBgPath[2]) + ? Image.fromFile(this.cacheImageBgPath[2]) + : undefined; } /** From b2785222a2f7811162c4bbba688a2d8efee37af1 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Thu, 9 Feb 2023 11:42:48 +0800 Subject: [PATCH 095/152] =?UTF-8?q?update:=E5=A2=9E=E5=8A=A0=E4=B8=AA?= =?UTF-8?q?=E6=80=A7=E5=8C=96=E8=AE=BE=E7=BD=AE=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 433 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 332 insertions(+), 101 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index a499ee0..e480162 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -19,12 +19,14 @@ class DmYY { this.isNight = Device.isUsingDarkAppearance(); } + BaseCacheKey = 'DmYY'; _actions = []; widgetColor; backGroundColor; - useBoxJS = true; isNight; + userConfigKey = ['avatar', 'nickname', 'homePageDesc']; + // 获取 Request 对象 getRequest = (url = '') => { return new Request(url); @@ -147,7 +149,9 @@ class DmYY { // 选择图片并缓存 chooseImg = async () => { - return await Photos.fromLibrary(); + return Photos.fromLibrary().catch(() => { + console.log('取消选择图片'); + }); }; // 设置 widget 背景图片 @@ -509,6 +513,26 @@ class DmYY { return data; }; + setBaseAlertInput = async (title, desc, opt = {}, isSave = true) => { + const a = new Alert(); + a.title = title; + a.message = !desc ? '' : desc; + Object.keys(opt).forEach((key) => { + a.addTextField(opt[key], this.baseSettings[key] || ''); + }); + a.addAction('确定'); + a.addCancelAction('取消'); + const id = await a.presentAlert(); + if (id === -1) return; + const data = {}; + Object.keys(opt).forEach((key, index) => { + data[key] = a.textFieldValue(index) || ''; + }); + // 保存到本地 + if (isSave) return this.saveBaseSettings(data); + return data; + }; + /** * 设置当前项目的 boxJS 缓存 * @param opt key value @@ -565,16 +589,6 @@ class DmYY { }, ]; - const boxjs = { - icon: { name: 'shippingbox', color: '#f7bb10' }, - type: 'input', - title: 'BoxJS 域名', - desc: '', - val: 'boxjsDomain', - }; - - if (this.useBoxJS) basic.push(boxjs); - return this.renderAppView([ { title: '基础设置', menu: basic }, { @@ -603,31 +617,34 @@ class DmYY { name: 'dayBg', type: 'img', title: '日间背景', + val: this.cacheImage, }, { icon: { name: 'photo.fill.on.rectangle.fill', color: '#fa541c' }, name: 'nightBg', type: 'img', title: '夜间背景', + val: this.cacheImage, }, { icon: { name: 'text.below.photo', color: '#faad14' }, type: 'img', name: 'transparentBg', title: '透明背景', - onClick: async (_, __, previewWebView) => { + val: this.cacheImage, + onClick: async (item, __, previewWebView) => { const backImage = await this.getWidgetScreenShot(); if (!backImage || !(await this.verifyImage(backImage))) return; + const cachePath = `${item.val}/${item.name}`; const base64Img = await this.setBackgroundImage( backImage, - 'transparentBg' + cachePath ); this.insertTextByElementId( previewWebView, - 'transparentBg', - `` + item.name, + `` ); - this.dismissLoading(previewWebView); }, }, ], @@ -791,6 +808,160 @@ class DmYY { return `data:image/png;base64,${Data.fromPNG(sfImg).toBase64String()}`; }; + setUserInfo = async () => { + const baseOnClick = async (item, _, previewWebView) => { + const data = await this.setBaseAlertInput(item.title, item.desc, { + [item.val]: item.placeholder, + }); + if (!data) return; + this.insertTextByElementId(previewWebView, item.name, data[item.val]); + }; + + return this.renderAppView([ + { + title: '个性设置', + menu: [ + { + icon: { name: 'person', color: '#fa541c' }, + name: this.userConfigKey[0], + title: '首页头像', + type: 'img', + val: this.baseImage, + onClick: async (_, __, previewWebView) => { + const options = ['相册选择', '在线链接', '取消']; + const message = '设置个性化头像'; + const index = await this.generateAlert(message, options); + if (index === 2) return; + const cachePath = `${_.val}/${_.name}`; + switch (index) { + case 0: + const albumOptions = ['选择图片', '清空图片', '取消']; + + const albumIndex = await this.generateAlert('', albumOptions); + if (albumIndex === 2) return; + if (albumIndex === 1) { + await this.setBackgroundImage(false, _.name, false); + this.insertTextByElementId(previewWebView, _.name, ``); + return; + } + + const backImage = await this.chooseImg(); + const base64Img = await this.setBackgroundImage( + backImage, + cachePath + ); + + this.insertTextByElementId( + previewWebView, + _.name, + `` + ); + + break; + case 1: + const data = await this.setBaseAlertInput( + '在线链接', + '首页头像在线链接', + { + avatar: '🔗请输入 URL 图片链接', + } + ); + if (!data) return; + + if (data[_.name] !== '') { + const backImage = await this.$request.get( + data[_.name], + 'IMG' + ); + const base64Img = await this.setBackgroundImage( + backImage, + cachePath + ); + + this.insertTextByElementId( + previewWebView, + _.name, + `` + ); + } else { + await this.setBackgroundImage(false, cachePath); + this.insertTextByElementId(previewWebView, 'avatar'); + } + + break; + default: + break; + } + }, + }, + { + icon: { name: 'pencil', color: '#fa8c16' }, + type: 'input', + title: '首页昵称', + desc: '个性化首页昵称', + placeholder: '👤请输入头像昵称', + val: this.userConfigKey[1], + name: this.userConfigKey[1], + defaultValue: this.baseSettings.nickname, + onClick: baseOnClick, + }, + { + icon: { name: 'lineweight', color: '#a0d911' }, + type: 'input', + title: '首页昵称描述', + desc: '个性化首页昵称描述', + placeholder: '请输入描述', + val: this.userConfigKey[2], + name: this.userConfigKey[2], + defaultValue: this.baseSettings.homePageDesc, + onClick: baseOnClick, + }, + ], + }, + { + menu: [ + { + icon: { name: 'shippingbox', color: '#f7bb10' }, + type: 'input', + title: 'BoxJS 域名', + desc: '设置BoxJS访问域名,如:boxjs.net 或 boxjs.com', + val: 'boxjsDomain', + name: 'boxjsDomain', + placeholder: 'boxjs.net', + defaultValue: this.baseSettings.boxjsDomain, + onClick: baseOnClick, + }, + { + icon: { name: 'clear', color: '#f5222d' }, + title: '恢复默认设置', + name: 'reset', + onClick: async () => { + const options = ['取消', '确定']; + const message = '确定要恢复当前所有配置吗?'; + const index = await this.generateAlert(message, options); + if (index === 1) { + this.settings = {}; + this.baseSettings = {}; + for (const item of this.cacheImageBgPath) { + await this.setBackgroundImage(false, item, false); + } + this.saveSettings(false); + this.saveBaseSettings(); + await this.notify( + '重置成功', + '请关闭窗口之后,重新运行当前脚本' + ); + Safari.open( + `scriptable:///run/${encodeURIComponent(Script.name())}` + ); + } + }, + }, + ], + }, + ]); + }; + async renderAppView( options = [], renderAvatar = false, @@ -891,6 +1062,13 @@ class DmYY { overflow: hidden; text-overflow: ellipsis; } + + .form-item-right-desc img{ + width:30px; + height:30px; + border-radius:3px; + } + .form-item + .form-item::before { content: ""; position: absolute; @@ -1042,26 +1220,29 @@ class DmYY { for (const btn of document.querySelectorAll('.form-item')) { btn.addEventListener('click', (e) => { + if(!e.target.id)return; toggleIcoLoading(e); - if(e.target.id) invoke(e.target.id); + invoke(e.target.id); }) } for (const btn of document.querySelectorAll('.form-item__input')) { btn.addEventListener('change', (e) => { - if(e.target.name) invoke(e.target.name, e.target.value); + if(!e.target.name)return; + invoke(e.target.name, e.target.value); }) } document.querySelectorAll('.form-item-auth')[0].addEventListener('click', (e) => { toggleIcoLoading(e); - invoke("reset"); + invoke("userInfo"); }) })()`; let configList = ``; let actionsConfig = []; + for (const key in options) { const item = options[key]; actionsConfig = [...item.menu, ...actionsConfig]; @@ -1101,9 +1282,9 @@ class DmYY { iconBase64 = await this.loadSF2B64(icon.name, icon.color); } const idName = menuItem.name || menuItem.val; - menuItem.defaultValue = ''; + let defaultHtml = ``; - if (menuItem.val !== undefined) + if (menuItem.val !== undefined && !menuItem.defaultValue) menuItem.defaultValue = this.settings[menuItem.val] || ''; if (menuItem.defaultValue && menuItem.type === 'input') { @@ -1111,12 +1292,12 @@ class DmYY { } else if (menuItem.type === 'color') { defaultHtml = ``; } else if (menuItem.type === 'img') { - const cachePath = `${this.cacheImage}/${menuItem.name}.jpg`; + const cachePath = `${menuItem.val}/${menuItem.name}`; if (this.FILE_MGR.fileExists(cachePath)) { const imageSrc = `data:image/png;base64,${Data.fromFile( cachePath ).toBase64String()}`; - defaultHtml = ``; + defaultHtml = ``; } } @@ -1136,6 +1317,44 @@ class DmYY { configList += ``; } + let avatarHtml = ''; + if (renderAvatar) { + const cachePath = `${this.baseImage}/${this.userConfigKey[0]}`; + const avatarConfig = { + avatar: `https://avatars.githubusercontent.com/u/23498579?v=4`, + nickname: this.baseSettings[this.userConfigKey[1]] || 'Dompling', + homPageDesc: + this.baseSettings[this.userConfigKey[2]] || + '18岁,来自九仙山的设计师', + }; + + if (this.FILE_MGR.fileExists(cachePath)) { + avatarConfig.avatar = `data:image/png;base64,${Data.fromFile( + cachePath + ).toBase64String()}`; + } + + avatarHtml = ` +
    +
    + +
    +
    + `; + } + const html = ` @@ -1144,28 +1363,7 @@ class DmYY { - ${ - renderAvatar - ? ` -
    -
    - -
    -
    ` - : '' - } + ${avatarHtml} ${configList}
    @@ -1199,59 +1397,54 @@ class DmYY { ); const { code, data } = JSON.parse(event); + try { + const actionItem = actionsConfig.find( + (item) => (item.name || item.val) === code + ); - const actionItem = actionsConfig.find( - (item) => (item.name || item.val) === code - ); - - if (code === 'reset') { - const options = ['取消', '确定']; - const message = '确定要重置当前所有配置吗?'; - const index = await this.generateAlert(message, options); - if (index === 1) { - this.settings = {}; - await this.setBackgroundImage(false, 'dayBg', false); - await this.setBackgroundImage(false, 'nightBg', false); - await this.setBackgroundImage(false, 'transparentBg', false); - this.saveSettings(false); - await this.notify('重置成功', '请关闭窗口之后,重新运行当前脚本'); - } - } - - if (actionItem) { - const idName = actionItem?.name || actionItem?.val; - if (actionItem?.onClick) { - await actionItem?.onClick?.(actionItem, data, previewWebView); - } else if (actionItem.type == 'input') { - await this.setLightAndDark( - actionItem['title'], - actionItem['desc'], - actionItem['val'], - actionItem['placeholder'] - ); - this.insertTextByElementId( - previewWebView, - idName, - this.settings[actionItem.val] || '' - ); - } else if (actionItem.type === 'img') { - const backImage = await this.chooseImg(); - if (!backImage || !(await this.verifyImage(backImage))) return; - const base64Img = await this.setBackgroundImage(backImage, idName); - this.insertTextByElementId( - previewWebView, - idName, - `` - ); - } else { - if (data !== undefined) { - this.settings[actionItem.val] = data; - this.saveSettings(false); + if (code === 'userInfo') await this.setUserInfo(); + + if (actionItem) { + const idName = actionItem?.name || actionItem?.val; + if (actionItem?.onClick) { + await actionItem?.onClick?.(actionItem, data, previewWebView); + } else if (actionItem.type == 'input') { + await this.setLightAndDark( + actionItem['title'], + actionItem['desc'], + actionItem['val'], + actionItem['placeholder'] + ); + this.insertTextByElementId( + previewWebView, + idName, + this.settings[actionItem.val] || '' + ); + } else if (actionItem.type === 'img') { + const backImage = await this.chooseImg(); + if (!backImage || !(await this.verifyImage(backImage))) return; + const cachePath = `${actionItem.val}/${actionItem.name}`; + const base64Img = await this.setBackgroundImage( + backImage, + cachePath, + false + ); + this.insertTextByElementId( + previewWebView, + idName, + `` + ); + } else { + if (data !== undefined) { + this.settings[actionItem.val] = data; + this.saveSettings(false); + } } } + } catch (error) { + console.log('异常操作:' + error); } this.dismissLoading(previewWebView); - injectListener(); }; @@ -1284,10 +1477,16 @@ class DmYY { `/images/${Script.name()}` ); + this.baseImage = this.FILE_MGR.joinPath( + this.FILE_MGR.documentsDirectory(), + `/images/` + ); + this.cacheImageBgPath = [ - `${this.cacheImage}/transparentBg.jpg`, - `${this.cacheImage}/dayBg.jpg`, - `${this.cacheImage}/nightBg.jpg`, + `${this.cacheImage}/transparentBg`, + `${this.cacheImage}/dayBg`, + `${this.cacheImage}/nightBg`, + `${this.baseImage}/avatar`, ]; if (!this.FILE_MGR.fileExists(this.cacheImage)) { @@ -1299,13 +1498,15 @@ class DmYY { this.settings = this.getSettings(); + this.baseSettings = this.getBaseSettings(); + this.settings = { ...this.defaultSettings, ...this.settings }; this.settings.lightColor = this.settings.lightColor || '#000000'; this.settings.darkColor = this.settings.darkColor || '#ffffff'; this.settings.lightBgColor = this.settings.lightBgColor || '#ffffff'; this.settings.darkBgColor = this.settings.darkBgColor || '#000000'; - this.settings.boxjsDomain = this.settings.boxjsDomain || 'boxjs.net'; + this.settings.boxjsDomain = this.baseSettings.boxjsDomain || 'boxjs.net'; this.settings.refreshAfterDate = this.settings.refreshAfterDate || '30'; this.settings.lightOpacity = this.settings.lightOpacity || '0.4'; this.settings.darkOpacity = this.settings.darkOpacity || '0.7'; @@ -1494,6 +1695,7 @@ class DmYY { if (Keychain.contains(this.SETTING_KEY)) { cache = Keychain.get(this.SETTING_KEY); } + if (json) { try { res = JSON.parse(cache); @@ -1505,6 +1707,32 @@ class DmYY { return res; } + getBaseSettings(json = true) { + let res = json ? {} : ''; + let cache = ''; + if (Keychain.contains(this.BaseCacheKey)) { + cache = Keychain.get(this.BaseCacheKey); + } + + if (json) { + try { + res = JSON.parse(cache); + } catch (e) {} + } else { + res = cache; + } + + return res; + } + + saveBaseSettings(res = {}, notify = true) { + const data = { ...(this.baseSettings || {}), ...res }; + this.baseSettings = data; + Keychain.set(this.BaseCacheKey, JSON.stringify(data)); + if (notify) this.notify('设置成功', '通用设置需重新运行脚本生效'); + return data; + } + /** * 存储当前设置 * @param {bool} notify 是否通知提示 @@ -1515,7 +1743,10 @@ class DmYY { ? JSON.stringify(this.settings) : String(this.settings); Keychain.set(this.SETTING_KEY, res); + if (notify) this.notify('设置成功', '桌面组件稍后将自动刷新'); + + return res; } /** @@ -1526,7 +1757,7 @@ class DmYY { if (this.FILE_MGR.fileExists(this.cacheImageBgPath[0])) return Image.fromFile(this.cacheImageBgPath[0]); - if (Device.isUsingDarkAppearance()) + if (!this.isNight) return this.FILE_MGR.fileExists(this.cacheImageBgPath[1]) ? Image.fromFile(this.cacheImageBgPath[1]) : undefined; @@ -1540,8 +1771,8 @@ class DmYY { * 设置当前组件的背景图片 * @param {Image} img */ - setBackgroundImage(img, key, notify = true) { - const cacheKey = `${this.cacheImage}/${key}.jpg`; + setBackgroundImage(img, filePath = this.baseImage, notify = true) { + const cacheKey = filePath; if (!img) { // 移除背景 if (this.FILE_MGR.fileExists(cacheKey)) this.FILE_MGR.remove(cacheKey); From 7c9d80e8e6d83f69bbf0fb2db9ce61d987542ecc Mon Sep 17 00:00:00 2001 From: 2YA <374779789@qq.com> Date: Thu, 9 Feb 2023 20:52:47 +0800 Subject: [PATCH 096/152] Update DmYY.js --- Scripts/DmYY.js | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index e480162..69517d9 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -149,8 +149,12 @@ class DmYY { // 选择图片并缓存 chooseImg = async () => { - return Photos.fromLibrary().catch(() => { - console.log('取消选择图片'); + return Photos.fromLibrary().then(async(response)=>{ + const bool = this.verifyImage(response); + if(bool) return response; + throw new Error("图片超过限制"); + }).catch((err) => { + console.log('图片选择异常:'+err); }); }; @@ -846,7 +850,8 @@ class DmYY { } const backImage = await this.chooseImg(); - const base64Img = await this.setBackgroundImage( + if(backImage){ + const base64Img = await this.setBackgroundImage( backImage, cachePath ); @@ -856,6 +861,8 @@ class DmYY { _.name, `` ); + } + break; case 1: @@ -1422,18 +1429,19 @@ class DmYY { ); } else if (actionItem.type === 'img') { const backImage = await this.chooseImg(); - if (!backImage || !(await this.verifyImage(backImage))) return; - const cachePath = `${actionItem.val}/${actionItem.name}`; - const base64Img = await this.setBackgroundImage( - backImage, - cachePath, - false - ); - this.insertTextByElementId( - previewWebView, - idName, - `` - ); + if(backImage){ + const cachePath = `${actionItem.val}/${actionItem.name}`; + const base64Img = await this.setBackgroundImage( + backImage, + cachePath, + false + ); + this.insertTextByElementId( + previewWebView, + idName, + `` + ); + } } else { if (data !== undefined) { this.settings[actionItem.val] = data; From 9920b6a98172aa65048d7532f8121eb1b9951cf3 Mon Sep 17 00:00:00 2001 From: 2YA <374779789@qq.com> Date: Thu, 9 Feb 2023 21:02:48 +0800 Subject: [PATCH 097/152] Update DmYY.js --- Scripts/DmYY.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 69517d9..6b2d363 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -1921,6 +1921,11 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { const actions = M['_actions']; const onClick = async (item) => { M.widgetFamily = item.val; + try { + M.init(); + } catch (error) { + console.log("初始化异常:" + error); + } w = await M.render(); const fnc = item.val .toLowerCase() From 5198cdee5ca7f1f620c55067a2795eb0f767f3d5 Mon Sep 17 00:00:00 2001 From: 2YA <374779789@qq.com> Date: Thu, 9 Feb 2023 21:10:11 +0800 Subject: [PATCH 098/152] Update DmYY.js --- Scripts/DmYY.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 6b2d363..76e422a 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -11,11 +11,7 @@ class DmYY { constructor(arg, defaultSettings) { this.arg = arg; this.defaultSettings = defaultSettings || {}; - try { - this.init(); - } catch (error) { - console.log(error); - } + this._init(); this.isNight = Device.isUsingDarkAppearance(); } @@ -1467,7 +1463,7 @@ class DmYY { previewWebView.present(); } - init(widgetFamily = config.widgetFamily) { + _init(widgetFamily = config.widgetFamily) { // 组件大小:small,medium,large this.widgetFamily = widgetFamily; this.SETTING_KEY = this.md5(Script.name()); @@ -1915,14 +1911,14 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { M[key] = extra[key]; }); } - if (__size) M.init(__size); + if (__size) M._init(__size); if (!act || !M['_actions']) { // 弹出选择菜单 const actions = M['_actions']; const onClick = async (item) => { M.widgetFamily = item.val; try { - M.init(); + M._init(item.val); } catch (error) { console.log("初始化异常:" + error); } From c58364638b5e4e301244ae214c8bd564812133e6 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 13 Feb 2023 10:02:40 +0800 Subject: [PATCH 099/152] =?UTF-8?q?update:=E6=98=BE=E7=A4=BA=E5=9B=BE?= =?UTF-8?q?=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- images/large.png | Bin 0 -> 3246 bytes images/medium.png | Bin 0 -> 3209 bytes images/small.png | Bin 0 -> 3126 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 images/large.png create mode 100644 images/medium.png create mode 100644 images/small.png diff --git a/images/large.png b/images/large.png new file mode 100644 index 0000000000000000000000000000000000000000..31eba02c260f75e2129fa3e93047d048dd6c37e3 GIT binary patch literal 3246 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 literal 0 HcmV?d00001 diff --git a/images/medium.png b/images/medium.png new file mode 100644 index 0000000000000000000000000000000000000000..c336dca4659060e8f7ec0d6feb68d501958433ac GIT binary patch literal 3209 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 YGx{bMq}-Jb76E|iB`cG1W4A~D0V?19_5c6? literal 0 HcmV?d00001 From fa256ac95e909c996d75bf0661f8928135562125 Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 13 Feb 2023 10:03:05 +0800 Subject: [PATCH 100/152] =?UTF-8?q?=20update:=E6=9B=B4=E6=96=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 86 ++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 40 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index 76e422a..e13d071 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -145,13 +145,15 @@ class DmYY { // 选择图片并缓存 chooseImg = async () => { - return Photos.fromLibrary().then(async(response)=>{ - const bool = this.verifyImage(response); - if(bool) return response; - throw new Error("图片超过限制"); - }).catch((err) => { - console.log('图片选择异常:'+err); - }); + return Photos.fromLibrary() + .then(async (response) => { + const bool = this.verifyImage(response); + if (bool) return response; + throw new Error('图片超过限制'); + }) + .catch((err) => { + console.log('图片选择异常:' + err); + }); }; // 设置 widget 背景图片 @@ -673,6 +675,7 @@ class DmYY { icon: { name: 'clear', color: '#f5222d' }, name: 'removeBackground', title: '清空背景图片', + val: `${this.cacheImage}/`, onClick: async (_, __, previewWebView) => { const options = [ '清空日间', @@ -686,15 +689,15 @@ class DmYY { if (index === 4) return; switch (index) { case 0: - await this.setBackgroundImage(false, 'dayBg'); + await this.setBackgroundImage(false, _.val + 'dayBg'); this.insertTextByElementId(previewWebView, 'dayBg', ``); return; case 1: - await this.setBackgroundImage(false, 'nightBg'); + await this.setBackgroundImage(false, _.val + 'nightBg'); this.insertTextByElementId(previewWebView, 'nightBg', ``); return; case 2: - await this.setBackgroundImage(false, 'transparentBg'); + await this.setBackgroundImage(false, _.val + 'transparentBg'); this.insertTextByElementId( previewWebView, 'transparentBg', @@ -702,9 +705,13 @@ class DmYY { ); return; default: - await this.setBackgroundImage(false, 'dayBg', false); - await this.setBackgroundImage(false, 'nightBg', false); - await this.setBackgroundImage(false, 'transparentBg'); + await this.setBackgroundImage(false, _.val + 'dayBg', false); + await this.setBackgroundImage( + false, + _.val + 'nightBg', + false + ); + await this.setBackgroundImage(false, _.val + 'transparentBg'); this.insertTextByElementId(previewWebView, 'dayBg', ``); this.insertTextByElementId(previewWebView, 'nightBg', ``); this.insertTextByElementId( @@ -846,19 +853,18 @@ class DmYY { } const backImage = await this.chooseImg(); - if(backImage){ + if (backImage) { const base64Img = await this.setBackgroundImage( - backImage, - cachePath - ); + backImage, + cachePath + ); - this.insertTextByElementId( - previewWebView, - _.name, - `` - ); + this.insertTextByElementId( + previewWebView, + _.name, + `` + ); } - break; case 1: @@ -1425,18 +1431,18 @@ class DmYY { ); } else if (actionItem.type === 'img') { const backImage = await this.chooseImg(); - if(backImage){ - const cachePath = `${actionItem.val}/${actionItem.name}`; - const base64Img = await this.setBackgroundImage( - backImage, - cachePath, - false - ); - this.insertTextByElementId( - previewWebView, - idName, - `` - ); + if (backImage) { + const cachePath = `${actionItem.val}/${actionItem.name}`; + const base64Img = await this.setBackgroundImage( + backImage, + cachePath, + false + ); + this.insertTextByElementId( + previewWebView, + idName, + `` + ); } } else { if (data !== undefined) { @@ -1917,10 +1923,10 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { const actions = M['_actions']; const onClick = async (item) => { M.widgetFamily = item.val; - try { + try { M._init(item.val); } catch (error) { - console.log("初始化异常:" + error); + console.log('初始化异常:' + error); } w = await M.render(); const fnc = item.val @@ -1932,7 +1938,7 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { }; const preview = [ { - icon: { name: 'app', color: '#504ED5' }, + url: `https://raw.githubusercontent.com/dompling/Scriptable/master/images/small.png`, title: '小尺寸', val: 'small', name: 'small', @@ -1940,7 +1946,7 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { onClick, }, { - icon: { name: 'rectangle', color: '#504ED5' }, + url: `https://raw.githubusercontent.com/dompling/Scriptable/master/images/medium.png`, title: '中尺寸', val: 'medium', name: 'medium', @@ -1948,7 +1954,7 @@ const Runing = async (Widget, default_args = '', isDebug = true, extra) => { onClick, }, { - icon: { name: 'app', color: '#504ED5' }, + url: `https://raw.githubusercontent.com/dompling/Scriptable/master/images/large.png`, title: '大尺寸', val: 'large', name: 'large', From 1564cb3c4c3f93e12b98a176151741175e30c83c Mon Sep 17 00:00:00 2001 From: dumpling <374779789@qq.com> Date: Mon, 13 Feb 2023 15:52:29 +0800 Subject: [PATCH 101/152] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/DmYY.js | 131 ++++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 55 deletions(-) diff --git a/Scripts/DmYY.js b/Scripts/DmYY.js index e13d071..06a67a3 100644 --- a/Scripts/DmYY.js +++ b/Scripts/DmYY.js @@ -17,6 +17,7 @@ class DmYY { BaseCacheKey = 'DmYY'; _actions = []; + _menuActions = []; widgetColor; backGroundColor; isNight; @@ -477,9 +478,10 @@ class DmYY { a.addAction('确定'); a.addCancelAction('取消'); const id = await a.presentAlert(); - if (id === -1) return; + if (id === -1) return false; this.settings[val] = a.textFieldValue(0) || ''; this.saveSettings(); + return true; } catch (e) { console.log(e); } @@ -960,9 +962,7 @@ class DmYY { '重置成功', '请关闭窗口之后,重新运行当前脚本' ); - Safari.open( - `scriptable:///run/${encodeURIComponent(Script.name())}` - ); + this.reopenScript(); } }, }, @@ -971,6 +971,10 @@ class DmYY { ]); }; + reopenScript = () => { + Safari.open(`scriptable:///run/${encodeURIComponent(Script.name())}`); + }; + async renderAppView( options = [], renderAvatar = false, @@ -1050,12 +1054,14 @@ class DmYY { .form-label { display: flex; align-items: center; + flex-wrap:nowrap } .form-label-img { height: 30px; } .form-label-title { - margin-left: 8px + margin-left: 8px; + white-space: nowrap; } .bottom-bg { margin: 30px 15px 15px 15px; @@ -1063,6 +1069,7 @@ class DmYY { .form-item--link .icon-arrow-right { color: #86868b; } + .form-item-right-desc { font-size: 13px; color: #86868b; @@ -1070,6 +1077,8 @@ class DmYY { max-width: 100px; overflow: hidden; text-overflow: ellipsis; + display:flex; + align-items: center; } .form-item-right-desc img{ @@ -1090,28 +1099,8 @@ class DmYY { width: 2em; height: 2em; } - input[type='number'] { - width: 6em; - height: 2.3em; - outline-style: none; - text-align: right; - padding: 0px 10px; - border: 1px solid #ddd; - font-size: 14px; - color: #86868b; - } - input[type='input'] { - width: 6em; - height: 2.3em; - outline-style: none; - text-align: right; - padding: 0px 10px; - border: 1px solid #ddd; - font-size: 14px; - color: #86868b; - } - input[type='text'] { - width: 6em; + input[type='input'],select { + width: 100%; height: 2.3em; outline-style: none; text-align: right; @@ -1119,6 +1108,7 @@ class DmYY { border: 1px solid #ddd; font-size: 14px; color: #86868b; + border-radius:4px; } input[type='checkbox'][role='switch'] { position: relative; @@ -1227,7 +1217,7 @@ class DmYY { } }; - for (const btn of document.querySelectorAll('.form-item')) { + for (const btn of document.querySelectorAll('.label-link')) { btn.addEventListener('click', (e) => { if(!e.target.id)return; toggleIcoLoading(e); @@ -1238,14 +1228,16 @@ class DmYY { for (const btn of document.querySelectorAll('.form-item__input')) { btn.addEventListener('change', (e) => { if(!e.target.name)return; - invoke(e.target.name, e.target.value); + invoke(e.target.name,e.target.type==="checkbox"?\`\${e.target.checked}\`: e.target.value); }) } - document.querySelectorAll('.form-item-auth')[0].addEventListener('click', (e) => { - toggleIcoLoading(e); - invoke("userInfo"); - }) + if(${renderAvatar}){ + document.querySelectorAll('.form-item-auth')[0].addEventListener('click', (e) => { + toggleIcoLoading(e); + invoke("userInfo"); + }) + } })()`; @@ -1265,7 +1257,11 @@ class DmYY { let iconBase64 = ``; if (menuItem.children) { menuItem.onClick = () => { - this.renderAppView(menuItem.children); + return this.renderAppView( + typeof menuItem.children === 'function' + ? menuItem.children() + : menuItem.children + ); }; } if (menuItem.url) { @@ -1296,10 +1292,8 @@ class DmYY { if (menuItem.val !== undefined && !menuItem.defaultValue) menuItem.defaultValue = this.settings[menuItem.val] || ''; - if (menuItem.defaultValue && menuItem.type === 'input') { - defaultHtml = menuItem.defaultValue; - } else if (menuItem.type === 'color') { - defaultHtml = ``; + if (menuItem.type === 'input') { + defaultHtml = menuItem.defaultValue || ''; } else if (menuItem.type === 'img') { const cachePath = `${menuItem.val}/${menuItem.name}`; if (this.FILE_MGR.fileExists(cachePath)) { @@ -1308,10 +1302,32 @@ class DmYY { ).toBase64String()}`; defaultHtml = ``; } + } else if (menuItem.type === 'select') { + let selectOptions = ''; + + menuItem.options.forEach((option) => { + let selected = `selected="selected"`; + selectOptions += ``; + }); + defaultHtml = ``; + } else if (menuItem.type === 'switch') { + const checked = + menuItem.defaultValue === 'true' ? `checked="checked"` : ''; + defaultHtml += ``; + } else if (menuItem.type) { + defaultHtml = ``; } configList += ` -
  • 获取Token重写:Surge 12123重写模块