Files
qinglong/脚本库/web版/抓包/10-返利好省/2023-09-20_raw_main_flhs_da39a1b1.js
2026-05-24 05:33:05 +00:00

984 lines
33 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// # Source: https://github.com/xfmeng970526/ql/blob/main/raw_main_flhs.js
// # Raw: https://raw.githubusercontent.com/xfmeng970526/ql/main/raw_main_flhs.js
// # Repo: xfmeng970526/ql
// # Path: raw_main_flhs.js
// # UploadedAt: 2023-09-20T12:13:28+08:00
// # SHA256: da39a1b1bf2c6fa79de3178c2c966b11406aa95b175f80f941b3946a28f00ec2
// # Category: web版/抓包
// # Evidence: web/H5关键词 + cookie/token/header
//
/*
软件名称:返利好省
完成时间2021-11-6 @YaphetS0903
脚本说明:返利好省。。。下载地址带邀请(介意的话appstore搜索下载)https://raw.githubusercontent.com/YaphetS0903/JStest/main/image/flhs.png
保存到相册微信扫码,点击立即下单后下载
收益:
一天3-4毛注册后点现金福利弹出一个弹窗看广告看完后会有1元豆子兑换去提现1元秒到
不需要绑定手机,微信登录即可,多账号上吧
请更新脚本和boxjs。
本脚本以学习为主
获取数据: 进入软件,点击现金福利获取数据
TG通知群:https://t.me/tom_ww
TG电报交流群: https://t.me/tom_210120
boxjs地址 :
https://raw.githubusercontent.com/YaphetS0903/JStest/main/YaphteS0903.boxjs.json
返利好省
青龙环境抓取链接https://api.uutequan.com/v1/welfare/page
随便哪一个Cookie应该都行
环境配置(@隔开json格式)
export flhsCookie='抓取的Cookie1@抓取的Cookie2'
圈X配置如下其他自行测试
一小时运行一次即可
cron: 4 4,22 * * *
new Env('10-返利好省');
项目名称:返利好省
https://raw.githubusercontent.com/YaphetS0903/JStest/main/flhs.js, tag=返利好省, enabled=true
[rewrite_local]
#返利好省
https://api.uutequan.com/v1/welfare/page url script-request-header https://raw.githubusercontent.com/YaphetS0903/JStest/main/flhs.js
[MITM]
hostname = api.uutequan.com
*/
const $ = new Env('返利好省');
let status;
status = (status = ($.getval("flhsstatus") || "1")) > 1 ? `${status}` : "";
let flhsCookieArr = [], flhscount = ''
let flhsCookie = $.isNode() ? (process.env.flhsCookie ? process.env.flhsCookie : "") : ($.getdata('flhsCookie') ? $.getdata('flhsCookie') : "")
// //13位时间戳
// let times = new Date().getTime()
let DD = RT(2000, 3500)
let tz = ($.getval('tz') || '1');
let tx = ($.getval('tx') || '1');
let id = '', platform = '', flhsextra = '', boxid = '', boxdbid = '', boxdbtype = ''
$.message = ''
let flhsCookies = ""
!(async () => {
if (typeof $request !== "undefined") {
await flhsck()
} else {
if (!$.isNode()) {
flhsCookieArr.push($.getdata('flhsCookie'))
let flhscount = ($.getval('flhscount') || '1');
for (let i = 2; i <= flhscount; i++) {
flhsCookieArr.push($.getdata(`flhsCookie${i}`))
}
console.log(
`\n\n=============================================== 脚本执行 - 北京时间(UTC+8)${new Date(
new Date().getTime() +
new Date().getTimezoneOffset() * 60 * 1000 +
8 * 60 * 60 * 1000
).toLocaleString()} ===============================================\n`);
for (let i = 0; i < flhsCookieArr.length; i++) {
if (flhsCookieArr[i]) {
flhsCookie = flhsCookieArr[i];
$.index = i + 1;
console.log(`\n\n开始【返利好省${$.index}作者@YaphetS0903】`)
await flhsvideoreceive()
await $.wait(10000)
await flhsboxid()
// message()
}
}
} else {
if (process.env.flhsCookie && process.env.flhsCookie.indexOf('@') > -1) {
flhsCookieArr = process.env.flhsCookie.split('@');
console.log(`您选择的是用"@"隔开\n`)
} else {
flhsCookies = [process.env.flhsCookie]
};
Object.keys(flhsCookies).forEach((item) => {
if (flhsCookies[item]) {
flhsCookieArr.push(flhsCookies[item])
}
})
console.log(`${flhsCookieArr.length}个cookie`)
for (let k = 0; k < flhsCookieArr.length; k++) {
$.message = ""
flhsCookie = flhsCookieArr[k];
$.index = k + 1;
console.log(`\n开始【返利好省${$.index}作者@YaphetS0903】`)
await flhsvideoreceive()
await $.wait(10000)
await flhsboxid()
// message()
}
}
}
})()
.catch((e) => $.logErr(e))
.finally(() => $.done())
//https://api.uutequan.com/v1/welfare/page
function flhsck() {
if ($request.url.indexOf("welfare/page") > -1) {
const flhsCookie = $request.headers['Cookie']
if (flhsCookie) $.setdata(flhsCookie, `flhsCookie${status}`)
$.log(flhsCookie)
$.msg($.name, "", `返利好省${status}获取数据成功`)
}
}
//接受看视频任务
function flhsvideoreceive(timeout = 0) {
return new Promise((resolve) => {
let url = {
url: `https://api.uutequan.com/v1/welfare/mission/watch_video`,
headers: {
"Cookie": flhsCookie,
},
}
$.get(url, async (err, resp, data) => {
try {
const result = JSON.parse(data)
if (result.errcode == 0) {
console.log(`【接受看视频任务成功】\n`)
platform =result.data.ad_platform
flhsextra=result.data.params.extra
await $.wait(15000)
await flhstaskcomplete()
} else {
console.log(`【接受看视频任务失败】\n`)
}
} catch (e) {
} finally {
resolve()
}
}, timeout)
})
}
//完成所有任务
function flhstaskcomplete(timeout = 0) {
return new Promise((resolve) => {
let url = {
url: `https://api.uutequan.com/v1/advertisement/client/notify`,
headers: {"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-Hans-CN;q=1",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Cookie": flhsCookie,
"Host": "api.uutequan.com",
},
body: `{
"ad_platform": ${platform},
"platform_order_no": "12345",
"params": {
"pos_id": "123456",
"secret": "12345",
"extra": "${flhsextra}"
}
}`
}
$.post(url, async (err, resp, data) => {
try {
const result = JSON.parse(data)
if (result.errcode == 0) {
console.log(`【完成任务成功】\n`)
await $.wait(15000)
await flhsallreward()
} else {
console.log(`【完成任务失败】\n`)
}
} catch (e) {
} finally {
resolve()
}
}, timeout)
})
}
//领取所有奖励
function flhsallreward(timeout = 0) {
return new Promise((resolve) => {
let url = {
url: `https://api.uutequan.com/v1/welfare/award/all`,
headers: {"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-Hans-CN;q=1",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Cookie": flhsCookie,
"Host": "api.uutequan.com",
},
body: `{}`
}
$.post(url, async (err, resp, data) => {
try {
const result = JSON.parse(data)
if (result.errcode == 0) {
console.log(`【1】${result.data[0].title}【获得金币】${result.data[0].award_amount}\n`)
} else {
console.log(`【领取奖励失败,请检查配置】\n`)
}
} catch (e) {
} finally {
resolve()
}
}, timeout)
})
}
//宝箱任务获取id
function flhsboxid(timeout = 0) {
return new Promise((resolve) => {
let url = {
url: `https://api.uutequan.com/v1/welfare/treasure_box`,
headers: {
"Cookie": flhsCookie,
},
}
$.get(url, async (err, resp, data) => {
try {
const result = JSON.parse(data)
if (result.errcode == 0) {
console.log(`【查询宝箱id为】${result.data.config_id}\n`)
boxid=result.data.config_id
await $.wait(15000)
await flhsboxreceive()
} else {
console.log(`【查询宝箱id失败】\n`)
}
} catch (e) {
} finally {
resolve()
}
}, timeout)
})
}
//拆宝箱
function flhsboxreceive(timeout = 0) {
return new Promise((resolve) => {
let url = {
url: `https://api.uutequan.com/v1/welfare/treasure_box`,
headers: {"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-Hans-CN;q=1",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Cookie": flhsCookie,
"Host": "api.uutequan.com",
},
body: `{
"config_id": ${boxid}
}`
}
$.post(url, async (err, resp, data) => {
try {
const result = JSON.parse(data)
if (result.errcode == 0) {
console.log(`【拆宝箱】${result.data.title}\n`)
boxdbid=result.data.welfare_record_id
boxdbtype=result.data.welfare_type
await $.wait(15000)
await flhsboxdbreceive()
} else {
console.log(`【拆宝箱失败】\n`)
}
} catch (e) {
} finally {
resolve()
}
}, timeout)
})
}
//拆宝箱翻倍任务接受
function flhsboxdbreceive(timeout = 0) {
return new Promise((resolve) => {
let url = {
url: `https://api.uutequan.com/v1/welfare/award/multiple`,
headers: {"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-Hans-CN;q=1",
"Connection": "keep-alive",
"Content-Type": "application/json",
"Cookie": flhsCookie,
"Host": "api.uutequan.com",
},
body: `{
"welfare_record_id": ${boxdbid},
"welfare_type": ${boxdbtype}
}`
}
$.post(url, async (err, resp, data) => {
try {
const result = JSON.parse(data)
if (result.errcode == 0) {
console.log(`【接受看拆宝箱翻倍任务成功】\n`)
platform =result.data.ad_platform
flhsextra=result.data.params.extra
await $.wait(15000)
await flhstaskcomplete()
} else {
console.log(`【接受看拆宝箱翻倍任务失败】\n`)
}
} catch (e) {
} finally {
resolve()
}
}, timeout)
})
}
function message() {
if (tz == 1) { $.msg($.name, "", $.message) }
}
//时间
nowTimes = new Date(
new Date().getTime() +
new Date().getTimezoneOffset() * 60 * 1000 +
8 * 60 * 60 * 1000
);
function RT(X, Y) {
do rt = Math.floor(Math.random() * Y);
while (rt < X)
return rt;
}
//console.log('\n'+getCurrentDate());
function getCurrentDate() {
var date = new Date();
var seperator1 = "-";
var seperator2 = ":";
var month = date.getMonth() + 1;
var strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate
+ " " + date.getHours() + seperator2 + date.getMinutes()
+ seperator2 + date.getSeconds();
return currentdate;
}
function Env(name, opts) {
class Http {
constructor(env) {
this.env = env
}
send(opts, method = 'GET') {
opts = typeof opts === 'string' ? {
url: opts
} : opts
let sender = this.get
if (method === 'POST') {
sender = this.post
}
return new Promise((resolve, reject) => {
sender.call(this, opts, (err, resp, body) => {
if (err) reject(err)
else resolve(resp)
})
})
}
get(opts) {
return this.send.call(this.env, opts)
}
post(opts) {
return this.send.call(this.env, opts, 'POST')
}
}
return new (class {
constructor(name, opts) {
this.name = name
this.http = new Http(this)
this.data = null
this.dataFile = 'box.dat'
this.logs = []
this.isMute = false
this.isNeedRewrite = false
this.logSeparator = '\n'
this.startTime = new Date().getTime()
Object.assign(this, opts)
this.log('', `🔔${this.name
}, 开始!`)
}
isNode() {
return 'undefined' !== typeof module && !!module.exports
}
isQuanX() {
return 'undefined' !== typeof $task
}
isSurge() {
return 'undefined' !== typeof $httpClient && 'undefined' === typeof $loon
}
isLoon() {
return 'undefined' !== typeof $loon
}
isShadowrocket() {
return 'undefined' !== typeof $rocket
}
toObj(str, defaultValue = null) {
try {
return JSON.parse(str)
} catch {
return defaultValue
}
}
toStr(obj, defaultValue = null) {
try {
return JSON.stringify(obj)
} catch {
return defaultValue
}
}
getjson(key, defaultValue) {
let json = defaultValue
const val = this.getdata(key)
if (val) {
try {
json = JSON.parse(this.getdata(key))
} catch { }
}
return json
}
setjson(val, key) {
try {
return this.setdata(JSON.stringify(val), key)
} catch {
return false
}
}
getScript(url) {
return new Promise((resolve) => {
this.get({
url
}, (err, resp, body) => resolve(body))
})
}
runScript(script, runOpts) {
return new Promise((resolve) => {
let httpapi = this.getdata('@chavy_boxjs_userCfgs.httpapi')
httpapi = httpapi ? httpapi.replace(/\n/g, '').trim() : httpapi
let httpapi_timeout = this.getdata('@chavy_boxjs_userCfgs.httpapi_timeout')
httpapi_timeout = httpapi_timeout ? httpapi_timeout * 1 : 20
httpapi_timeout = runOpts && runOpts.timeout ? runOpts.timeout : httpapi_timeout
const [key, addr] = httpapi.split('@')
const opts = {
url: `http: //${addr}/v1/scripting/evaluate`,
body: {
script_text: script,
mock_type: 'cron',
timeout: httpapi_timeout
},
headers: {
'X-Key': key,
'Accept': '*/*'
}
}
this.post(opts, (err, resp, body) => resolve(body))
}).catch((e) => this.logErr(e))
}
loaddata() {
if (this.isNode()) {
this.fs = this.fs ? this.fs : require('fs')
this.path = this.path ? this.path : require('path')
const curDirDataFilePath = this.path.resolve(this.dataFile)
const rootDirDataFilePath = this.path.resolve(process.cwd(), this.dataFile)
const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath)
const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath)
if (isCurDirDataFile || isRootDirDataFile) {
const datPath = isCurDirDataFile ? curDirDataFilePath : rootDirDataFilePath
try {
return JSON.parse(this.fs.readFileSync(datPath))
} catch (e) {
return {}
}
} else return {}
} else return {}
}
writedata() {
if (this.isNode()) {
this.fs = this.fs ? this.fs : require('fs')
this.path = this.path ? this.path : require('path')
const curDirDataFilePath = this.path.resolve(this.dataFile)
const rootDirDataFilePath = this.path.resolve(process.cwd(), this.dataFile)
const isCurDirDataFile = this.fs.existsSync(curDirDataFilePath)
const isRootDirDataFile = !isCurDirDataFile && this.fs.existsSync(rootDirDataFilePath)
const jsondata = JSON.stringify(this.data)
if (isCurDirDataFile) {
this.fs.writeFileSync(curDirDataFilePath, jsondata)
} else if (isRootDirDataFile) {
this.fs.writeFileSync(rootDirDataFilePath, jsondata)
} else {
this.fs.writeFileSync(curDirDataFilePath, jsondata)
}
}
}
lodash_get(source, path, defaultValue = undefined) {
const paths = path.replace(/[(d+)]/g, '.$1').split('.')
let result = source
for (const p of paths) {
result = Object(result)[p]
if (result === undefined) {
return defaultValue
}
}
return result
}
lodash_set(obj, path, value) {
if (Object(obj) !== obj) return obj
if (!Array.isArray(path)) path = path.toString().match(/[^.[]]+/g) || []
path
.slice(0, -1)
.reduce((a, c, i) => (Object(a[c]) === a[c] ? a[c] : (a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : {})), obj)[
path[path.length - 1]
] = value
return obj
}
getdata(key) {
let val = this.getval(key)
// 如果以 @
if (/^@/.test(key)) {
const [, objkey, paths] = /^@(.*?).(.*?)$/.exec(key)
const objval = objkey ? this.getval(objkey) : ''
if (objval) {
try {
const objedval = JSON.parse(objval)
val = objedval ? this.lodash_get(objedval, paths, '') : val
} catch (e) {
val = ''
}
}
}
return val
}
setdata(val, key) {
let issuc = false
if (/^@/.test(key)) {
const [, objkey, paths] = /^@(.*?).(.*?)$/.exec(key)
const objdat = this.getval(objkey)
const objval = objkey ? (objdat === 'null' ? null : objdat || '{}') : '{}'
try {
const objedval = JSON.parse(objval)
this.lodash_set(objedval, paths, val)
issuc = this.setval(JSON.stringify(objedval), objkey)
} catch (e) {
const objedval = {}
this.lodash_set(objedval, paths, val)
issuc = this.setval(JSON.stringify(objedval), objkey)
}
} else {
issuc = this.setval(val, key)
}
return issuc
}
getval(key) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.read(key)
} else if (this.isQuanX()) {
return $prefs.valueForKey(key)
} else if (this.isNode()) {
this.data = this.loaddata()
return this.data[key]
} else {
return (this.data && this.data[key]) || null
}
}
setval(val, key) {
if (this.isSurge() || this.isLoon()) {
return $persistentStore.write(val, key)
} else if (this.isQuanX()) {
return $prefs.setValueForKey(val, key)
} else if (this.isNode()) {
this.data = this.loaddata()
this.data[key] = val
this.writedata()
return true
} else {
return (this.data && this.data[key]) || null
}
}
initGotEnv(opts) {
this.got = this.got ? this.got : require('got')
this.cktough = this.cktough ? this.cktough : require('tough-cookie')
this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar()
if (opts) {
opts.headers = opts.headers ? opts.headers : {}
if (undefined === opts.headers.Cookie && undefined === opts.cookieJar) {
opts.cookieJar = this.ckjar
}
}
}
get(opts, callback = () => { }) {
if (opts.headers) {
delete opts.headers['Content-Type']
delete opts.headers['Content-Length']
}
if (this.isSurge() || this.isLoon()) {
if (this.isSurge() && this.isNeedRewrite) {
opts.headers = opts.headers || {}
Object.assign(opts.headers, {
'X-Surge-Skip-Scripting': false
})
}
$httpClient.get(opts, (err, resp, body) => {
if (!err && resp) {
resp.body = body
resp.statusCode = resp.status
}
callback(err, resp, body)
})
} else if (this.isQuanX()) {
if (this.isNeedRewrite) {
opts.opts = opts.opts || {}
Object.assign(opts.opts, {
hints: false
})
}
$task.fetch(opts).then(
(resp) => {
const {
statusCode: status,
statusCode,
headers,
body
} = resp
callback(null, {
status,
statusCode,
headers,
body
}, body)
},
(err) => callback(err)
)
} else if (this.isNode()) {
this.initGotEnv(opts)
this.got(opts)
.on('redirect', (resp, nextOpts) => {
try {
if (resp.headers['set-cookie']) {
const ck = resp.headers['set-cookie'].map(this.cktough.Cookie.parse).toString()
if (ck) {
this.ckjar.setCookieSync(ck, null)
}
nextOpts.cookieJar = this.ckjar
}
} catch (e) {
this.logErr(e)
}
// this.ckjar.setCookieSync(resp.headers['set-cookie'].map(Cookie.parse).toString())
})
.then(
(resp) => {
const {
statusCode: status,
statusCode,
headers,
body
} = resp
callback(null, {
status,
statusCode,
headers,
body
}, body)
},
(err) => {
const {
message: error,
response: resp
} = err
callback(error, resp, resp && resp.body)
}
)
}
}
post(opts, callback = () => { }) {
const method = opts.method ? opts.method.toLocaleLowerCase() : 'post'
// 如果指定了请求体, 但没指定`Content-Type`, 则自动生成
if (opts.body && opts.headers && !opts.headers['Content-Type']) {
opts.headers['Content-Type'] = 'application/x-www-form-urlencoded'
}
if (opts.headers) delete opts.headers['Content-Length']
if (this.isSurge() || this.isLoon()) {
if (this.isSurge() && this.isNeedRewrite) {
opts.headers = opts.headers || {}
Object.assign(opts.headers, {
'X-Surge-Skip-Scripting': false
})
}
$httpClient[method](opts, (err, resp, body) => {
if (!err && resp) {
resp.body = body
resp.statusCode = resp.status
}
callback(err, resp, body)
})
} else if (this.isQuanX()) {
opts.method = method
if (this.isNeedRewrite) {
opts.opts = opts.opts || {}
Object.assign(opts.opts, {
hints: false
})
}
$task.fetch(opts).then(
(resp) => {
const {
statusCode: status,
statusCode,
headers,
body
} = resp
callback(null, {
status,
statusCode,
headers,
body
}, body)
},
(err) => callback(err)
)
} else if (this.isNode()) {
this.initGotEnv(opts)
const {
url,
..._opts
} = opts
this.got[method](url, _opts).then(
(resp) => {
const {
statusCode: status,
statusCode,
headers,
body
} = resp
callback(null, {
status,
statusCode,
headers,
body
}, body)
},
(err) => {
const {
message: error,
response: resp
} = err
callback(error, resp, resp && resp.body)
}
)
}
}
/**
*
* 示例:$.time('yyyy-MM-dd qq HH:mm:ss.S')
* :$.time('yyyyMMddHHmmssS')
* y:年 M:月 d:日 q:季 H:时 m:分 s:秒 S:毫秒
* 其中y可选0-4位占位符、S可选0-1位占位符其余可选0-2位占位符
* @param {string} fmt 格式化参数
* @param {number} 可选: 根据指定时间戳返回格式化日期
*
*/
time(fmt, ts = null) {
const date = ts ? new Date(ts) : new Date()
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'H+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds(),
'q+': Math.floor((date.getMonth() + 3) / 3),
'S': date.getMilliseconds()
}
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
for (let k in o)
if (new RegExp('(' + k + ')').test(fmt))
fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
return fmt
}
/**
* 系统通知
*
* > 通知参数: 同时支持 QuanX 和 Loon 两种格式, EnvJs根据运行环境自动转换, Surge 环境不支持多媒体通知
*
* 示例:
* $.msg(title, subt, desc, 'twitter://')
* $.msg(title, subt, desc, { 'open-url': 'twitter://', 'media-url': 'https://github.githubassets.com/images/modules/open_graph/github-mark.png' })
* $.msg(title, subt, desc, { 'open-url': 'https://bing.com', 'media-url': 'https://github.githubassets.com/images/modules/open_graph/github-mark.png' })
*
* @param {*} title 标题
* @param {*} subt 副标题
* @param {*} desc 通知详情
* @param {*} opts 通知参数
*
*/
msg(title = name, subt = '', desc = '', opts) {
const toEnvOpts = (rawopts) => {
if (!rawopts) return rawopts
if (typeof rawopts === 'string') {
if (this.isLoon()) return rawopts
else if (this.isQuanX()) return {
'open-url': rawopts
}
else if (this.isSurge()) return {
url: rawopts
}
else return undefined
} else if (typeof rawopts === 'object') {
if (this.isLoon()) {
let openUrl = rawopts.openUrl || rawopts.url || rawopts['open-url']
let mediaUrl = rawopts.mediaUrl || rawopts['media-url']
return {
openUrl,
mediaUrl
}
} else if (this.isQuanX()) {
let openUrl = rawopts['open-url'] || rawopts.url || rawopts.openUrl
let mediaUrl = rawopts['media-url'] || rawopts.mediaUrl
return {
'open-url': openUrl,
'media-url': mediaUrl
}
} else if (this.isSurge()) {
let openUrl = rawopts.url || rawopts.openUrl || rawopts['open-url']
return {
url: openUrl
}
}
} else {
return undefined
}
}
if (!this.isMute) {
if (this.isSurge() || this.isLoon()) {
$notification.post(title, subt, desc, toEnvOpts(opts))
} else if (this.isQuanX()) {
$notify(title, subt, desc, toEnvOpts(opts))
}
}
if (!this.isMuteLog) {
let logs = ['', '==============📣系统通知📣==============']
logs.push(title)
subt ? logs.push(subt) : ''
desc ? logs.push(desc) : ''
console.log(logs.join('\n'))
this.logs = this.logs.concat(logs)
}
}
log(...logs) {
if (logs.length > 0) {
this.logs = [...this.logs, ...logs]
}
console.log(logs.join(this.logSeparator))
}
logErr(err, msg) {
const isPrintSack = !this.isSurge() && !this.isQuanX() && !this.isLoon()
if (!isPrintSack) {
this.log('', `❗️${this.name
}, 错误!`, err)
} else {
this.log('', `❗️${this.name
}, 错误!`, err.stack)
}
}
wait(time) {
return new Promise((resolve) => setTimeout(resolve, time))
}
done(val = {}) {
const endTime = new Date().getTime()
const costTime = (endTime - this.startTime) / 1000
this.log('', `🔔${this.name
}, 结束!🕛${costTime}`)
this.log()
if (this.isSurge() || this.isQuanX() || this.isLoon()) {
$done(val)
}
}
})(name, opts)
}