├── COVID-19.js ├── README.md ├── freq.js └── snap ├── qr.jpg ├── snap.jpg ├── snap1.jpg └── snap2.jpg /COVID-19.js: -------------------------------------------------------------------------------- 1 | // 别人框架抄过来的,可以加配置信息,懒得改了 2 | const inputValue = "1" 3 | 4 | if (inputValue) { 5 | let resp =await $http.post({ 6 | url: "https://smartgate.ywtbsupappw.sh.gov.cn/ebus/suishenma/epidemicPrevention/getNucleicAcidTest", 7 | 8 | // header 需要使用微信的随申办抓包,目测"X-Tif-Did"、"X-Tif-Sid"、"Token"、"Authentication" 都是需要的 9 | header: { 10 | "Connection": "keep-alive", 11 | "X-Tif-Did": "", 12 | "X-Tif-Sid": "", 13 | "Content-Type": "application/json", 14 | "Authentication": "", 15 | "Token": "", 16 | "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x18001725) NetType/4G Language/zh_CN", 17 | "Referer": "https://servicewechat.com/wxc5059c3803665d9c/456/page-frame.html", 18 | "Accept-Encoding": "gzip", 19 | }, 20 | //后面有个sessionId,需要加一下? 21 | body: {"params":{},"userSystemData":{"brand":"iPhone","model":"iPhone 13 Pro Max","version":"8.0.23","system":"iOS 15.5","platform":"ios","SDKVersion":"2.24.5","windowWidth":428},"sessionId":""} 22 | }); 23 | 24 | let data = resp.data.data 25 | let username = data.name 26 | let sampleDate = data.sampleDate 27 | let title = data.collectModeName 28 | let logo = "https://wx.qlogo.cn/mmhead/Q3auHgzwzM76niaZYsWjwHial7D9wvGqOwlL8F9BYLOicicTTuPOAibN4Xw/0" 29 | 30 | 31 | let counters =[0,1] 32 | let counter_view = [] 33 | let type_view = [] 34 | 35 | const now = new Date(); 36 | const sampleDate_datetime = new Date(sampleDate.replace(/-/g,"/")) 37 | const expireDate = parseInt(72-(now.getTime()-sampleDate_datetime)/60/60/1000) 38 | 39 | // 本来想多放点数据的,发现没有,for也不改了 40 | for (var i in counters) { 41 | counter_view.push({ 42 | type: "text", 43 | props: { 44 | text: expireDate.toString()+"h", 45 | font: $font("bold", 18), 46 | light: "#282828", 47 | dark: "white", 48 | minimumScaleFactor: 0.5, 49 | lineLimit: 1 50 | } 51 | }) 52 | type_view.push({ 53 | type: "text", 54 | props: { 55 | text: "72h倒计时", 56 | font: $font(10), 57 | color: $color("#aaaaaa"), 58 | minimumScaleFactor: 0.5, 59 | lineLimit: 1 60 | } 61 | }) 62 | } 63 | 64 | $widget.setTimeline({ 65 | render: ctx => { 66 | //$widget.family = 0 67 | const family = ctx.family; 68 | const width = $widget.displaySize.width 69 | const height = $widget.displaySize.height 70 | 71 | const logo_view = { 72 | type: "image", 73 | props: { 74 | uri: logo, 75 | frame: { 76 | width: 60, 77 | height: 60 78 | }, 79 | resizable: true, 80 | cornerRadius: 15 81 | } 82 | } 83 | 84 | const desc = { 85 | type: "text", 86 | props: { 87 | text: "上次核酸", 88 | font: $font(10), 89 | color: $color("#aaaaaa"), 90 | minimumScaleFactor: 0.5, 91 | lineLimit: 1 92 | } 93 | } 94 | 95 | const title_view = { 96 | type: "text", 97 | props: { 98 | text: title, 99 | font: family == 0 ? $font("bold", 20) : $font("bold", 25), 100 | light: "#282828", 101 | dark: "white", 102 | minimumScaleFactor: 0.5, 103 | lineLimit: 1 104 | } 105 | } 106 | 107 | const path_view = { 108 | type: "text", 109 | props: { 110 | text: "@" + sampleDate, 111 | font: $font(10), 112 | color: $color("#2481cc"), 113 | minimumScaleFactor: 0.5, 114 | lineLimit: 1 115 | } 116 | } 117 | 118 | const small_widget = [ 119 | { 120 | 121 | type: "hstack", 122 | props: { 123 | 124 | alignment: $widget.verticalAlignment.center, 125 | frame: { 126 | width: width - 30, 127 | height: 60 128 | }, 129 | spacing: 0 130 | }, 131 | views: [ 132 | logo_view, 133 | { 134 | type: "vstack", 135 | props: { 136 | 137 | 138 | alignment: $widget.horizontalAlignment.center, 139 | frame: { 140 | maxWidth: Infinity, 141 | maxHeight: Infinity 142 | }, 143 | spacing: 0 144 | }, 145 | views: [ 146 | counter_view.concat(type_view)[0], 147 | counter_view.concat(type_view)[counter_view.concat(type_view).length / 2] 148 | ] 149 | } 150 | ] 151 | }, 152 | spacerMaker(10, width - 30), 153 | desc, 154 | spacerMaker(3, width - 30), 155 | title_view, 156 | spacerMaker(3, width - 30), 157 | path_view 158 | ] 159 | 160 | 161 | // blaunch ,是app store 需要安装「小捷径」才能跳转 162 | return { 163 | type: "vstack", 164 | props: { 165 | 166 | alignment: $widget.horizontalAlignment.leading, 167 | frame: { 168 | width: width - 30, 169 | height: height 170 | }, 171 | 172 | spacing: 0, 173 | widgetURL: "blaunch://wx?id=gh_d4acc9de8978&path=pages/suishenma/jiankangma/index.html?needLogin=false&scene=0" 174 | 175 | }, 176 | views: small_widget 177 | } 178 | } 179 | }) 180 | } 181 | 182 | function spacerMaker(height, width) { 183 | return { 184 | type: "spacer", 185 | 186 | props: { 187 | frame: { 188 | width: width, 189 | height: height 190 | } 191 | } 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # COVID-19_ios_widget 2 | 上海核酸倒计时提示桌面组件,72小时内,自动提示一下。 3 | 4 | 5 | ### 效果 6 | ![snap](./snap/snap1.jpg) 7 | * 自动获取最后一次核酸检测记录,还有多长时间超过72小时 8 | 9 | ![snap](./snap/snap2.jpg) 10 | * 获取最近的一些核酸记录,每一列7天,就是一周。最右边是当前周。 11 | 12 | 13 | ### 需要 14 | * JSBOX,添加widget 15 | * 自己会抓包,小程序点一下随申码,就会有那个网络请求。按照代码修改下个人信息。 16 | * 安装「小捷径」App:点击可以跳转到随申码小程序页面。 17 | 18 | 19 | ### 买杯咖啡 20 | ![snap](./snap/qr.jpg) -------------------------------------------------------------------------------- /freq.js: -------------------------------------------------------------------------------- 1 | /* 2 | 需要抓取的信息比较多,抓随申办的包,需要进入 3 | 1、随申码界面 4 | 2、核酸记录页面,加载更多页面 5 | 就能抓到下面所有的请求,把自己的header和body贴入即可。 6 | */ 7 | 8 | const inputValue = "1"; 9 | const theme_colors = { 10 | green: ["#ebedf0", "#9be9a8", "#40c463", "#30a14e", "#216e39"], 11 | blue: ["#ebedf0", "#79B8FE", "#2188FF", "#005CC5", "#044289"] 12 | } 13 | 14 | 15 | if (inputValue) { 16 | // let username = inputValue.split(",")[0] 17 | let theme = inputValue.split(",")[1] ? theme_colors[inputValue.split(",")[1]] : theme_colors.green 18 | 19 | // 用默认logo替换头像 20 | let logo = "https://wx.qlogo.cn/mmhead/Q3auHgzwzM76niaZYsWjwHial7D9wvGqOwlL8F9BYLOicicTTuPOAibN4Xw/0" 21 | 22 | 23 | // 抓取mw,用于获取核酸记录的授权信息 24 | let resp_mw = await await $http.post({ 25 | url: "https://smartgate.ywtbsupappw.sh.gov.cn/ebus/swift/mw/v1", 26 | header: { 27 | //这里需要替换自己的 28 | }, 29 | body: { 30 | //这里需要替换自己的 31 | } 32 | }); 33 | 34 | let mw = resp_mw.data.data 35 | 36 | // 抓取第一页的核酸记录 37 | let resp_hs = await await $http.post({ 38 | url: "https://suishenmaback2.sh.gov.cn/smzy/shspace/hs/getByMwV3", 39 | header: { 40 | //这里需要替换自己的 41 | }, 42 | form: {"mw":mw}, 43 | }); 44 | 45 | let data_hs = resp_hs.data.data 46 | let data_hs_sessionId = resp_hs.data.sessionId 47 | 48 | 49 | // 抓取第二页的核酸记录,sessionId 从第一页的返回里获取 50 | let resp_hs_2 = await await $http.post({ 51 | url: "https://suishenmaback2.sh.gov.cn/smzy/shspace/hs/getHistory", 52 | header: { 53 | //这里需要替换自己的 54 | }, 55 | form: {"sessionId":data_hs_sessionId}, 56 | }); 57 | 58 | let data_hs_2 = resp_hs_2.data.data 59 | 60 | // 抓取随申码的头像,不过太丑了,最后没用 61 | let resp_avatar = await await $http.post({ 62 | url: "https://smartgate.ywtbsupappw.sh.gov.cn/ebus/suishenma/unified/photo/v3", 63 | header: { 64 | //这里需要替换自己的 65 | }, 66 | body: { 67 | //这里需要替换自己的 68 | } 69 | }); 70 | let avatar = resp_avatar.data.data.img 71 | 72 | // 抓取随申码的姓名,注意隐私的也可以不用 73 | let resp_username =await $http.post({ 74 | url: "https://smartgate.ywtbsupappw.sh.gov.cn/ebus/suishenma/epidemicPrevention/getNucleicAcidTest", 75 | header: { 76 | //这里需要替换自己的 77 | }, 78 | body: { 79 | //这里需要替换自己的 80 | } 81 | }); 82 | 83 | let username = resp_username.data.data.name 84 | 85 | let data_all = data_hs.concat(data_hs_2) // 合并两页核算记录 86 | let color_data = data2array(data_all) // 转换成颜色值 87 | 88 | $widget.setTimeline({ 89 | render: ctx => { 90 | //$widget.family = 1 91 | const family = ctx.family; 92 | const width = $widget.displaySize.width 93 | const height = $widget.displaySize.height 94 | 95 | let colors_row_spacing = 2 96 | let colors_column_spacing = 4 97 | 98 | colors_data=color_data 99 | let colors_view = [] 100 | let colors_square_width = family == 0 ? (width - 30 - 8 * colors_row_spacing) / 9 : (width - 30 - 19 * colors_row_spacing) / 20 101 | 102 | for (var i = 0; i < colors_data.length; i++) { 103 | colors_view.push({ 104 | type: "color", 105 | props: { 106 | light: theme[colors_data[i]], 107 | dark: colors_data[i] == "0" ? "#3E3E41" : theme[colors_data[i]], 108 | frame: { 109 | width: colors_square_width, 110 | height: colors_square_width 111 | }, 112 | cornerRadius: 2 113 | } 114 | }) 115 | } 116 | 117 | return { 118 | type: "vstack", 119 | props: { 120 | alignment: $widget.horizontalAlignment.leading, 121 | spacing: 10, 122 | frame: { 123 | width: width - 30, 124 | height: height 125 | }, 126 | // widgetURL: url 127 | }, 128 | views: [ 129 | { 130 | type: "hstack", 131 | props: { 132 | alignment: $widget.verticalAlignment.center, 133 | spacing: 3 134 | }, 135 | views: [ 136 | { 137 | type: "image", 138 | props: { 139 | 140 | // image: $image("data:image/png;base64,"+avatar), 141 | uri: logo, // 这里用默认logo,如果要用自己的头像,用上一行。 142 | frame: { 143 | width: 20, 144 | height: 20 145 | }, 146 | cornerRadius: { 147 | value: 10, 148 | style: 0 149 | }, 150 | resizable: true 151 | } 152 | }, 153 | { 154 | type: "text", 155 | props: { 156 | text: "@"+username, 157 | font: $font("bold", 13), 158 | color: $color("#9A9AA1"), 159 | minimumScaleFactor: 0.5, 160 | lineLimit: 1 161 | } 162 | }, 163 | 164 | ] 165 | }, 166 | { 167 | type: "hgrid", 168 | props: { 169 | rows: Array(7).fill({ 170 | flexible: { 171 | minimum: 10, 172 | maximum: Infinity 173 | }, 174 | spacing: colors_column_spacing 175 | }), 176 | spacing: colors_row_spacing 177 | }, 178 | views: colors_view 179 | } 180 | ] 181 | } 182 | } 183 | }) 184 | } 185 | 186 | 187 | 188 | // 转换日期到网格,瞎写的 189 | 190 | function data2array(arr) { 191 | 192 | const now = new Date() 193 | const nowTime = now.getTime() 194 | const day = now.getDay() 195 | const oneDayTime = 24 * 60 * 60 * 1000 196 | 197 | const FirstTime = nowTime - (day - 1) * oneDayTime-56 * oneDayTime 198 | const monday = new Date(FirstTime) 199 | 200 | is_has =[] 201 | 202 | for (var i = 0; i < arr.length; i++) { 203 | let report_date = new Date(arr[i].report_date.replace(/-/g,"/")) 204 | let date = dateFormat("yyyy-mm-dd",report_date) 205 | is_has.push(date) 206 | } 207 | 208 | let output = [] 209 | for (var i = 0; i < day+56; i++) { 210 | x = new Date( monday.setDate(monday.getDate()+1)); 211 | y = dateFormat("yyyy-mm-dd",x) 212 | let inc = is_has.includes(y) 213 | if (inc === true) { 214 | output.push(2) 215 | }else{ 216 | output.push(0) 217 | } 218 | } 219 | return output 220 | } 221 | 222 | 223 | // 日期格式转换,百度复制粘贴的 224 | function dateFormat(fmt, date) { 225 | let ret; 226 | const opt = { 227 | "y+": date.getFullYear().toString(), // 年 228 | "m+": (date.getMonth() + 1).toString(), // 月 229 | "d+": date.getDate().toString(), // 日 230 | "H+": date.getHours().toString(), // 时 231 | "M+": date.getMinutes().toString(), // 分 232 | "S+": date.getSeconds().toString() // 秒 233 | 234 | }; 235 | for (let k in opt) { 236 | ret = new RegExp("(" + k + ")").exec(fmt); 237 | if (ret) { 238 | fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0"))) 239 | }; 240 | }; 241 | return fmt; 242 | } 243 | -------------------------------------------------------------------------------- /snap/qr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svcvit/COVID-19_ios_widget/df941f781073e100a4bfdeb21a6b62c6b75fb548/snap/qr.jpg -------------------------------------------------------------------------------- /snap/snap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svcvit/COVID-19_ios_widget/df941f781073e100a4bfdeb21a6b62c6b75fb548/snap/snap.jpg -------------------------------------------------------------------------------- /snap/snap1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svcvit/COVID-19_ios_widget/df941f781073e100a4bfdeb21a6b62c6b75fb548/snap/snap1.jpg -------------------------------------------------------------------------------- /snap/snap2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/svcvit/COVID-19_ios_widget/df941f781073e100a4bfdeb21a6b62c6b75fb548/snap/snap2.jpg --------------------------------------------------------------------------------