perf:ddsy.js update

优化整体流程代码
This commit is contained in:
smallfawn 2026-04-02 18:56:39 +08:00
parent 32cdacc725
commit b336ab51da
4 changed files with 155 additions and 637 deletions

View File

@ -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
View 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
}

View File

@ -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();
});
}

File diff suppressed because one or more lines are too long