mirror of
https://github.com/smallfawn/QLScriptPublic.git
synced 2026-06-12 21:01:21 +08:00
perf:ddsy.js update
优化整体流程代码
This commit is contained in:
parent
32cdacc725
commit
b336ab51da
@ -7,8 +7,8 @@ cron: 8 30 * * *
|
||||
------------------------------------------
|
||||
#Notice:
|
||||
APP 抓包的登录接口uaa2c.chery.cn 里面的返回的access_token就是环境变量需要的token,多个账号换行或者&
|
||||
|
||||
|
||||
自助获取变量
|
||||
https://logintools.smallfawn.top/chery.html
|
||||
⚠️【免责声明】
|
||||
------------------------------------------
|
||||
1、此脚本仅用于学习研究,不保证其合法性、准确性、有效性,请根据情况自行判断,本人对此不承担任何保证责任。
|
||||
@ -20,7 +20,7 @@ APP 抓包的登录接口uaa2c.chery.cn 里面的返回的access_token就是环
|
||||
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本,即视为您已接受此免责声明。
|
||||
*/
|
||||
|
||||
const { Env } = require("./tools/env")
|
||||
const { Env } = require("../tools/env")
|
||||
const $ = new Env("奇瑞汽车");
|
||||
let ckName = `chery`;
|
||||
const strSplitor = "#";
|
||||
|
||||
152
daily/ddsy.js
Normal file
152
daily/ddsy.js
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
------------------------------------------
|
||||
@Author: sm
|
||||
@Date: 2024.06.07 19:15
|
||||
@Description: ddky
|
||||
cron: 9 30 * * *
|
||||
------------------------------------------
|
||||
#Notice:
|
||||
变量值:https://hapi.ddky.com/mcp/weixin/rest.htm?后面的loginToken&userId&uDate 多账户换行或者&分隔
|
||||
网页版登录 https://m.ddky.com/
|
||||
小程序登录叮当快药
|
||||
APP 都可以找到这三个值
|
||||
⚠️【免责声明】
|
||||
------------------------------------------
|
||||
1、此脚本仅用于学习研究,不保证其合法性、准确性、有效性,请根据情况自行判断,本人对此不承担任何保证责任。
|
||||
2、由于此脚本仅用于学习研究,您必须在下载后 24 小时内将所有内容从您的计算机或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
|
||||
3、请勿将此脚本用于任何商业或非法目的,若违反规定请自行对此负责。
|
||||
4、此脚本涉及应用与本人无关,本人对因此引起的任何隐私泄漏或其他后果不承担任何责任。
|
||||
5、本人对任何脚本引发的问题概不负责,包括但不限于由脚本错误引起的任何损失和损害。
|
||||
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利,应及时通知并提供身份证明,所有权证明,我们将在收到认证文件确认后删除此脚本。
|
||||
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改或补充此声明的权利。一旦您使用或复制了此脚本,即视为您已接受此免责声明。
|
||||
*/
|
||||
|
||||
const { Env } = require("./tools/env")
|
||||
const $ = new Env("叮当快药");
|
||||
let ckName = `ddky`;
|
||||
const strSplitor = "#";
|
||||
const axios = require("axios");
|
||||
const defaultUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.31(0x18001e31) NetType/WIFI Language/zh_CN miniProgram"
|
||||
|
||||
|
||||
class Task {
|
||||
constructor(env) {
|
||||
this.index = $.userIdx++
|
||||
this.token = env.split(strSplitor)[0]; //单账号多变量分隔符
|
||||
|
||||
this.userId = env.split(strSplitor)[1];
|
||||
this.uDate = env.split(strSplitor)[2];
|
||||
|
||||
}
|
||||
|
||||
async run() {
|
||||
|
||||
await this.getSignInId()
|
||||
}
|
||||
|
||||
getSign(s) {
|
||||
const crypto = require("crypto");//SIGN TYPE 1是签到 2是补签
|
||||
return crypto.createHash('md5').update(s).digest('hex');
|
||||
}
|
||||
getTime() {
|
||||
var now = new Date();
|
||||
var year = now.getFullYear()
|
||||
, month = now.getMonth() + 1
|
||||
, day = now.getDate()
|
||||
, hours = now.getHours()
|
||||
, minutes = now.getMinutes()
|
||||
, seconds = now.getSeconds();
|
||||
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
|
||||
}
|
||||
getSignDay() {
|
||||
var now = new Date();
|
||||
var year = now.getFullYear()
|
||||
, month = now.getMonth() + 1
|
||||
, day = now.getDate()
|
||||
return year + '-' + month + '-' + day
|
||||
}
|
||||
async getSignInId() {
|
||||
const time = this.getTime()
|
||||
const method = `ddky.promotion.signin.pageinfo`
|
||||
const signDay = this.getSignDay()
|
||||
const str = method +
|
||||
`loginToken${this.token}` +
|
||||
`method${method}` +
|
||||
`platH5` +
|
||||
`platformH5` +
|
||||
`signDay${signDay}` +
|
||||
`t${time}` +
|
||||
`uDate${this.uDate}` +
|
||||
`userId${this.userId}` +
|
||||
`v1.0` +
|
||||
`versionName4.9.0` +
|
||||
`6C57AB91A1308E26B797F4CD382AC79D`
|
||||
let sign = (this.getSign(str)).toUpperCase();
|
||||
let callbackStr = new Date().getTime()
|
||||
try {
|
||||
let options = {
|
||||
url: `https://hapi.ddky.com/mcp/weixin/rest.htm?sign=${sign}&loginToken=${this.token}&method=${method}&plat=H5&platform=H5&signDay=${signDay}&t=${time}&uDate=${this.uDate}&userId=${this.userId}&v=1.0&versionName=4.9.0&callback=Zepto${callbackStr}`,
|
||||
headers: {},
|
||||
}
|
||||
let { data: response } = await axios.request(options);
|
||||
let result = response.replace(`Zepto${callbackStr}`, "")
|
||||
result = result.replaceAll("(", "")
|
||||
result = result.replaceAll(")", "")
|
||||
result = JSON.parse(result)
|
||||
if (result.code = "0") {
|
||||
await this.user_info(result.result.signDayVo.signinId)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
async user_info(signInId) {
|
||||
let callbackStr = new Date().getTime()
|
||||
const time = this.getTime()
|
||||
const str = `ddky.promotion.signin.sign` + `channelH5` + `laterSignType1` + `loginToken${this.token}` + `methodddky.promotion.signin.sign` +
|
||||
`platH5` + `platformH5` + `signinId${signInId}` + `t${time}` + `uDate${this.uDate}` + `userId${this.userId}` + `v1.0` + `versionName4.9.0` +
|
||||
`6C57AB91A1308E26B797F4CD382AC79D`
|
||||
let sign = (this.getSign(str)).toUpperCase();
|
||||
try {
|
||||
let options = {
|
||||
url: `https://hapi.ddky.com/mcp/weixin/rest.htm?sign=${sign}&channel=H5&laterSignType=1&loginToken=${this.token}&method=ddky.promotion.signin.sign&plat=H5&platform=H5&signinId=${signInId}&t=${time}&uDate=${this.uDate}&userId=${this.userId}&v=1.0&versionName=4.9.0&callback=Zepto${callbackStr}`,
|
||||
headers: {},
|
||||
}
|
||||
let { data: response } = await axios.request(options);
|
||||
console.log(response);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
!(async () => {
|
||||
await getNotice()
|
||||
$.checkEnv(ckName);
|
||||
|
||||
for (let user of $.userList) {
|
||||
await new Task(user).run();
|
||||
}
|
||||
})()
|
||||
.catch((e) => console.log(e))
|
||||
.finally(() => $.done());
|
||||
|
||||
async function getNotice() {
|
||||
let options = {
|
||||
url: `https://ghproxy.net/https://raw.githubusercontent.com/smallfawn/Note/refs/heads/main/Notice.json`,
|
||||
headers: {
|
||||
"User-Agent": defaultUserAgent,
|
||||
}
|
||||
}
|
||||
let { data: res } = await axios.request(options);
|
||||
$.log(res)
|
||||
return res
|
||||
}
|
||||
454
dayuecheng.js
454
dayuecheng.js
@ -1,454 +0,0 @@
|
||||
/*
|
||||
* 大悦城自动任务脚本 for 青龙面板
|
||||
* 环境变量:dyc
|
||||
* 格式:MallId#Token#PublicKey#mpOpenId
|
||||
* 多账号:MallId#Token#PublicKey#mpOpenId&MallId#Token#PublicKey#mpOpenId
|
||||
*
|
||||
* 功能说明:
|
||||
* 1. 检查用户状态
|
||||
* 2. 自动签到
|
||||
* 3. 获取积分信息
|
||||
*/
|
||||
|
||||
const $ = new Env("大悦城自动任务");
|
||||
const notify = $.isNode() ? require("./sendNotify") : "";
|
||||
|
||||
// 环境变量名
|
||||
const envName = "dyc";
|
||||
|
||||
// 固定参数
|
||||
const mpAppId = "wxc1f0da607b34c3bd";
|
||||
const systemInfo = {
|
||||
model: "microsoft",
|
||||
SDKVersion: "3.13.1",
|
||||
system: "Windows 10 x64",
|
||||
version: "4.1.6.46",
|
||||
miniVersion: "1.0.96"
|
||||
};
|
||||
|
||||
class Dayuecheng {
|
||||
constructor(mallId, token, publicKey, mpOpenId) {
|
||||
this.mallId = mallId;
|
||||
this.token = token;
|
||||
this.publicKey = publicKey;
|
||||
this.mpOpenId = mpOpenId;
|
||||
this.baseUrl = "https://m-crm.joycity.mobi/api";
|
||||
this.headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf254162e) XWEB/18151",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "*/*",
|
||||
"Referer": "https://servicewechat.com/wxc1f0da607b34c3bd/40/page-frame.html",
|
||||
"xweb_xhr": "1"
|
||||
};
|
||||
this.retryCount = 3;
|
||||
this.retryDelay = 2000;
|
||||
}
|
||||
|
||||
generateSign(timestamp, data) {
|
||||
const crypto = require("crypto");
|
||||
let signStr = timestamp + this.publicKey;
|
||||
|
||||
if (data && data.trim() !== "") {
|
||||
signStr += data;
|
||||
}
|
||||
|
||||
return crypto.createHash("md5").update(signStr).digest("hex");
|
||||
}
|
||||
|
||||
generateSignAndTimestamp(data = "") {
|
||||
const timestamp = Date.now().toString();
|
||||
const sign = this.generateSign(timestamp, data);
|
||||
return { sign, timestamp };
|
||||
}
|
||||
|
||||
async requestWithRetry(path, data, method = "POST", retry = this.retryCount) {
|
||||
let lastError;
|
||||
|
||||
for (let i = 0; i < retry; i++) {
|
||||
try {
|
||||
if (i > 0) {
|
||||
$.log(`🔄 第${i + 1}次重试请求: ${path}`);
|
||||
await $.wait(this.retryDelay);
|
||||
}
|
||||
|
||||
return await this.request(path, data, method);
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
$.log(`⚠️ 请求失败 (${i + 1}/${retry}): ${error.message}`);
|
||||
|
||||
if (error.code === 'ECONNABORTED' || error.code === 'ENETUNREACH' ||
|
||||
error.code === 'ETIMEDOUT' || error.message.includes('timeout')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError || new Error(`请求失败,重试${retry}次后仍然失败`);
|
||||
}
|
||||
|
||||
async request(path, data, method = "POST") {
|
||||
const { sign, timestamp } = this.generateSignAndTimestamp(JSON.stringify(data));
|
||||
|
||||
const headers = {
|
||||
...this.headers,
|
||||
"Sign": sign,
|
||||
"Timestamp": timestamp,
|
||||
"PublicKey": this.publicKey
|
||||
};
|
||||
|
||||
let requestData = {};
|
||||
|
||||
if (path.includes("getSnsInfo")) {
|
||||
requestData = {
|
||||
MallId: this.mallId,
|
||||
mpAppId: mpAppId,
|
||||
mpOpenId: this.mpOpenId,
|
||||
Header: {
|
||||
Token: this.token,
|
||||
systemInfo: systemInfo
|
||||
}
|
||||
};
|
||||
} else {
|
||||
requestData = {
|
||||
MallID: this.mallId,
|
||||
Header: {
|
||||
Token: this.token,
|
||||
systemInfo: systemInfo
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (data && typeof data === 'object') {
|
||||
requestData = { ...requestData, ...data };
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await $.httpRequest({
|
||||
url: `${this.baseUrl}${path}`,
|
||||
method: method,
|
||||
headers: headers,
|
||||
data: JSON.stringify(requestData),
|
||||
timeout: 15000
|
||||
});
|
||||
|
||||
const result = typeof response.data === "object" ? response.data : JSON.parse(response.data);
|
||||
|
||||
$.log(`📡 ${method} ${path} -> ${result.m === 1 ? '成功' : '失败'}`);
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
$.log(`❌ 请求异常: ${error.message}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async checkUserStatus() {
|
||||
$.log("🔍 检查用户状态...");
|
||||
try {
|
||||
const result = await this.requestWithRetry("/passport/wx/mp/getSnsInfo", {});
|
||||
|
||||
if (result.m === 1) {
|
||||
const authorized = result.d?.authorized;
|
||||
if (authorized) {
|
||||
$.log("✅ 用户状态正常");
|
||||
return { success: true, data: result.d };
|
||||
} else {
|
||||
$.log("❌ 用户授权已失效");
|
||||
return { success: false, message: "用户授权已失效" };
|
||||
}
|
||||
} else if (result.code === 401 || result.status === 401) {
|
||||
$.log("❌ Token已过期,需要重新获取");
|
||||
return { success: false, message: "Token已过期" };
|
||||
} else {
|
||||
$.log(`❌ 检查用户状态失败: ${result.e || "未知错误"}`);
|
||||
return { success: false, message: result.e || "未知错误" };
|
||||
}
|
||||
} catch (error) {
|
||||
$.log(`❌ 检查用户状态异常: ${error.message}`);
|
||||
return { success: false, message: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
async autoCheckin() {
|
||||
$.log("🔍 开始签到...");
|
||||
try {
|
||||
const result = await this.requestWithRetry("/user/User/CheckinV2", {});
|
||||
|
||||
if (result.m === 1) {
|
||||
const data = result.d;
|
||||
if (data.IsCheckIn) {
|
||||
$.log(`✅ 签到成功: ${data.Msg || "签到完成"}`);
|
||||
if (data.NickName) {
|
||||
$.log(`👤 用户: ${data.NickName}`);
|
||||
}
|
||||
if (data.Title) {
|
||||
$.log(`📝 ${data.Title}`);
|
||||
}
|
||||
return { success: true, data: data };
|
||||
} else {
|
||||
$.log(`❌ 签到失败: ${data.Msg || "未知原因"}`);
|
||||
return { success: false, message: data.Msg || "未知原因" };
|
||||
}
|
||||
} else {
|
||||
$.log(`❌ 签到接口调用失败: ${result.e || "未知错误"}`);
|
||||
return { success: false, message: result.e || "未知错误" };
|
||||
}
|
||||
} catch (error) {
|
||||
$.log(`❌ 签到异常: ${error.message}`);
|
||||
return { success: false, message: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
async getUserPoints() {
|
||||
$.log("🔍 获取用户积分...");
|
||||
try {
|
||||
const result = await this.requestWithRetry("/user/user/GetMallCard_Encrypt", {});
|
||||
|
||||
if (result.m === 1) {
|
||||
const data = result.d;
|
||||
const points = data.Bonus;
|
||||
$.log(`💰 当前积分: ${points}`);
|
||||
if (data.CardTitle) {
|
||||
$.log(`🎫 卡片类型: ${data.CardTitle}`);
|
||||
}
|
||||
if (data.CardLevel) {
|
||||
$.log(`⭐ 卡片等级: ${data.CardLevel}`);
|
||||
}
|
||||
return { success: true, points: points, data: data };
|
||||
} else {
|
||||
$.log(`❌ 获取积分失败: ${result.e || "未知错误"}`);
|
||||
return { success: false, message: result.e || "未知错误" };
|
||||
}
|
||||
} catch (error) {
|
||||
$.log(`❌ 获取积分异常: ${error.message}`);
|
||||
return { success: false, message: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
async runAllTasks() {
|
||||
$.log(`🏪 开始处理大悦城账号: ${this.mallId}`);
|
||||
|
||||
const taskResults = [];
|
||||
|
||||
const statusResult = await this.checkUserStatus();
|
||||
taskResults.push({ name: "用户状态检查", success: statusResult.success });
|
||||
|
||||
if (!statusResult.success) {
|
||||
$.log("❌ 用户状态异常,跳过后续任务");
|
||||
return {
|
||||
success: false,
|
||||
message: statusResult.message || "用户状态异常",
|
||||
taskResults: taskResults
|
||||
};
|
||||
}
|
||||
|
||||
const checkinResult = await this.autoCheckin();
|
||||
taskResults.push({ name: "自动签到", success: checkinResult.success });
|
||||
|
||||
const pointsResult = await this.getUserPoints();
|
||||
taskResults.push({ name: "获取积分", success: pointsResult.success });
|
||||
|
||||
const successCount = taskResults.filter(r => r.success).length;
|
||||
const totalCount = taskResults.length;
|
||||
|
||||
$.log(`\n📊 任务执行汇总: ${successCount}/${totalCount} 成功`);
|
||||
taskResults.forEach((task, index) => {
|
||||
$.log(`${task.success ? '✅' : '❌'} ${index + 1}. ${task.name}`);
|
||||
});
|
||||
|
||||
return {
|
||||
success: successCount === totalCount,
|
||||
taskResults: taskResults,
|
||||
summary: {
|
||||
successCount: successCount,
|
||||
totalCount: totalCount,
|
||||
mallId: this.mallId,
|
||||
publicKey: this.publicKey,
|
||||
mpOpenId: this.mpOpenId
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function Env(name) {
|
||||
this.name = name;
|
||||
this.logs = [];
|
||||
|
||||
this.log = (...args) => {
|
||||
const msg = args.join(" ");
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const logMsg = `[${timestamp}] ${msg}`;
|
||||
this.logs.push(logMsg);
|
||||
console.log(logMsg);
|
||||
};
|
||||
|
||||
this.isNode = () => {
|
||||
return typeof process !== "undefined" && process.release && process.release.name === 'node';
|
||||
};
|
||||
|
||||
this.getdata = (key) => {
|
||||
if (this.isNode()) {
|
||||
return process.env[key] || "";
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
this.wait = (ms) => {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
};
|
||||
|
||||
this.httpRequest = async (config) => {
|
||||
if (this.isNode()) {
|
||||
const axios = require('axios');
|
||||
try {
|
||||
const response = await axios({
|
||||
...config,
|
||||
validateStatus: function (status) {
|
||||
return status >= 200 && status < 500;
|
||||
}
|
||||
});
|
||||
return response;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
} else {
|
||||
throw new Error("非Node环境不支持HTTP请求");
|
||||
}
|
||||
};
|
||||
|
||||
this.done = () => {
|
||||
if (this.isNode()) {
|
||||
process.exit(0);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const envValue = $.getdata(envName);
|
||||
if (!envValue) {
|
||||
$.log(`❌ 未找到环境变量 ${envName}`);
|
||||
$.log(`💡 请添加环境变量 ${envName},格式: MallId#Token#PublicKey#mpOpenId`);
|
||||
$.log(`📝 多账号格式: MallId#Token#PublicKey#mpOpenId&MallId#Token#PublicKey#mpOpenId`);
|
||||
return;
|
||||
}
|
||||
|
||||
const accounts = [];
|
||||
const accountStrings = envValue.split('&').filter(Boolean);
|
||||
|
||||
for (const accountStr of accountStrings) {
|
||||
const parts = accountStr.split('#');
|
||||
if (parts.length === 4) {
|
||||
const mallId = parts[0].trim();
|
||||
const token = parts[1].trim();
|
||||
const publicKey = parts[2].trim();
|
||||
const mpOpenId = parts[3].trim();
|
||||
|
||||
if (mallId && token && publicKey && mpOpenId) {
|
||||
accounts.push({ mallId, token, publicKey, mpOpenId });
|
||||
} else {
|
||||
$.log(`⚠️ 忽略无效账号格式: ${accountStr}`);
|
||||
}
|
||||
} else {
|
||||
$.log(`⚠️ 忽略格式错误的账号(需要4个参数): ${accountStr}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (accounts.length === 0) {
|
||||
$.log("❌ 未找到有效的账号配置");
|
||||
$.log("💡 正确格式: MallId#Token#PublicKey#mpOpenId");
|
||||
$.log("💡 多账号: MallId#Token#PublicKey#mpOpenId&MallId#Token#PublicKey#mpOpenId");
|
||||
return;
|
||||
}
|
||||
|
||||
$.log(`🎯 共找到 ${accounts.length} 个有效账号`);
|
||||
|
||||
const allResults = [];
|
||||
|
||||
for (let i = 0; i < accounts.length; i++) {
|
||||
const account = accounts[i];
|
||||
$.log(`\n📱 开始处理第 ${i + 1} 个账号 (MallId: ${account.mallId})`);
|
||||
|
||||
try {
|
||||
const dyc = new Dayuecheng(account.mallId, account.token, account.publicKey, account.mpOpenId);
|
||||
const result = await dyc.runAllTasks();
|
||||
|
||||
allResults.push({
|
||||
mallId: account.mallId,
|
||||
...result
|
||||
});
|
||||
|
||||
if (i < accounts.length - 1) {
|
||||
$.log(`⏳ 等待3秒后处理下一个账号...`);
|
||||
await $.wait(3000);
|
||||
}
|
||||
} catch (error) {
|
||||
$.log(`❌ 处理账号异常: ${error.message}`);
|
||||
allResults.push({
|
||||
mallId: account.mallId,
|
||||
success: false,
|
||||
error: error.message,
|
||||
taskResults: []
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$.log("\n" + "=".repeat(60));
|
||||
$.log("📈 所有账号任务执行汇总:");
|
||||
$.log("=".repeat(60));
|
||||
|
||||
let totalSuccess = 0;
|
||||
let totalTasks = 0;
|
||||
|
||||
allResults.forEach((result, index) => {
|
||||
const successCount = result.taskResults ? result.taskResults.filter(r => r.success).length : 0;
|
||||
const totalCount = result.taskResults ? result.taskResults.length : 0;
|
||||
|
||||
$.log(`\n账号 ${index + 1} (MallId: ${result.mallId}):`);
|
||||
$.log(` ${result.success ? '✅ 成功' : '❌ 失败'} (${successCount}/${totalCount} 任务成功)`);
|
||||
|
||||
if (result.taskResults) {
|
||||
result.taskResults.forEach((task, taskIndex) => {
|
||||
$.log(` ${task.success ? '✅' : '❌'} ${task.name}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (result.error) {
|
||||
$.log(` 错误: ${result.error}`);
|
||||
}
|
||||
|
||||
totalSuccess += successCount;
|
||||
totalTasks += totalCount;
|
||||
});
|
||||
|
||||
$.log("\n" + "=".repeat(60));
|
||||
$.log(`📊 总体统计: ${totalSuccess}/${totalTasks} 个任务成功完成`);
|
||||
$.log("=".repeat(60));
|
||||
|
||||
if ($.isNode() && notify) {
|
||||
try {
|
||||
const summaryText = allResults.map(r => {
|
||||
const successCount = r.taskResults ? r.taskResults.filter(t => t.success).length : 0;
|
||||
const totalCount = r.taskResults ? r.taskResults.length : 0;
|
||||
return `MallId: ${r.mallId} - ${successCount}/${totalCount} 成功`;
|
||||
}).join('\n');
|
||||
|
||||
const title = `大悦城自动任务 - ${allResults.filter(r => r.success).length}/${allResults.length} 个账号成功`;
|
||||
const content = $.logs.join("\n") + "\n\n" + summaryText;
|
||||
|
||||
await notify.sendNotify(title, content);
|
||||
} catch (error) {
|
||||
$.log(`⚠️ 发送通知失败: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main().catch(e => {
|
||||
$.log(`❌ 脚本执行异常: ${e.message}`);
|
||||
console.error(e.stack);
|
||||
}).finally(() => {
|
||||
$.done();
|
||||
});
|
||||
}
|
||||
180
ddsy_songyao.js
180
ddsy_songyao.js
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user