commit 61f66423e58b8ec4c1d7d57623d21de909b3eddb Author: 黄志军 Date: Tue Oct 26 19:20:52 2021 +0800 初始化代码 diff --git a/.readme/B5F8E89A-CE33-4a78-A461-E9014B10A3D9.png b/.readme/B5F8E89A-CE33-4a78-A461-E9014B10A3D9.png new file mode 100644 index 0000000..c8c4011 Binary files /dev/null and b/.readme/B5F8E89A-CE33-4a78-A461-E9014B10A3D9.png differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3d38d29 --- /dev/null +++ b/pom.xml @@ -0,0 +1,204 @@ + + + 4.0.0 + + Java_Utils + Java_Utils + 1.0.0 + war + + + 1.4.9 + UTF-8 + 1.7 + 1.7 + UTF-8 + 1.8 + 7.0 + 3.0 + yyyyMMddHHmmss + + + + + + + + javax.servlet + jstl + 1.2 + + + javax + javaee-web-api + ${javax.version} + provided + + + + com.belerweb + pinyin4j + 2.5.0 + + + org.slf4j + slf4j-api + 1.7.25 + + + com.google.guava + guava + 19.0 + + + com.google.code.google-collections + google-collect + snapshot-20080530 + + + + org.springframework + spring-core + 4.3.1.RELEASE + + + + + + com.itextpdf + itextpdf + 5.5.11 + + + com.itextpdf + itext-asian + 5.2.0 + + + com.itextpdf.tool + xmlworker + 5.5.11 + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.7.2 + + + + + + net.coobird + thumbnailator + 0.4.8 + + + + + + com.google.zxing + core + 2.2 + + + + + org.apache.commons + commons-configuration2 + 2.2 + + + + + org.apache.commons + commons-compress + 1.18 + + + + + com.alibaba + fastjson + 1.2.54 + + + + + redis.clients + jedis + 2.7.1 + + + org.springframework.data + spring-data-redis + 1.6.2.RELEASE + + + org.springframework + spring-web + 4.3.7.RELEASE + + + + + Java_Utils + + + + maven-clean-plugin + 3.0.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.7.0 + + + maven-surefire-plugin + 2.20.1 + + + maven-war-plugin + 3.2.0 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + + + + src/main/java + + **/*.properties + **/*.xml + + false + + + + diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..93df11c --- /dev/null +++ b/readme.md @@ -0,0 +1,32 @@ +# 我的公众号 +![](.readme/B5F8E89A-CE33-4a78-A461-E9014B10A3D9.png) + +# 作用 +保存java遇到的部分工具类写法,在需要的时候可以直接拿出来使用 + +# 更新日志 + +2020/5/11 : 创建工程、添加PageUtil以及单测类,添加PatternUtil,添加StringUtils以及单测类 + +2020/5/12 : 添加部分工具类,未实现单测处理,包括: +- MessageUtils +- ShellUtils +- FileUtil +- Base64Util +- DateTimeUtil +- FillFullTimeValueUtil +- RedisUtil +- PDFUtils +- ResponseEntityUtil +- ClassUtils +- ClassVisitorUtils +- MethodVisitorUtils + +2020/5/15 : 添加zip压缩工具类ZipOutputUtil、TarArchiveGZIPOutputUtil及其单测类ZipTest、添加树节点工具类TreeUtils和单测类 +添加验证码工具类CaptchaUtil和单测、添加二维码工具类QRCodeUtil和单测,修改FileUtil添加部分方法、删除log4j依赖 + +2020/5/18 : 添加xml、json转换工具JsonBinder和XmlBinder,添加测试代码,添加图片压缩工具类PicturesCompressUtil以及单测,增加FileUtil中文件内容读入读出方法 + +2020/5/22 : 添加FullFillTimeValueUtil单测类、添加FileUtil文件夹方法、添加FileUtilTest单测类 + +2020/6/30 :添加FileUtil获取文件夹文件、单测 \ No newline at end of file diff --git a/src/main/java/additive/ValidTool.java b/src/main/java/additive/ValidTool.java new file mode 100644 index 0000000..01ab4e4 --- /dev/null +++ b/src/main/java/additive/ValidTool.java @@ -0,0 +1,10 @@ +package additive; + +public class ValidTool { + + public static void assertIsTrue(boolean expression, String message) { + if (!expression) { + throw new IllegalArgumentException(message); + } + } +} diff --git a/src/main/java/entity/CaptchaItem.java b/src/main/java/entity/CaptchaItem.java new file mode 100644 index 0000000..2fa47cf --- /dev/null +++ b/src/main/java/entity/CaptchaItem.java @@ -0,0 +1,137 @@ +package entity; + +import java.awt.*; + +/** + * 验证码属性设值对象 + */ +public class CaptchaItem { + + /** + * 验证码图片高度 + */ + private double height; + + /** + * 验证码图片宽度 + */ + private double width; + + /** + * 验证码长度 + */ + private int codeLength; + + /** + * 验证码从这里面进行取值 + */ + private String codeValue; + + /** + * 是否使用随机背景颜色 + */ + private boolean backgroundRandom; + + /** + * 是否使用随机验证码颜色 + */ + private boolean captchaColorRandom; + + /** + * 背景颜色 + */ + private int backgroundColor; + + /** + * 验证码颜色 + */ + private int captchaColor; + + /** + * 字体属性 + */ + private Font font; + + public CaptchaItem() { + //直接进行默认值的处理 + this.captchaColorRandom = true; + this.backgroundRandom = true; + this.codeLength = 4; + this.height = 100; + this.width = 200; + this.codeValue = "abcdefghijklmnopqrstuvwxyz1234567890"; + this.font = new Font("Algerian", Font.ITALIC, (int)this.height - 4); + } + + public Font getFont() { + return font; + } + + public void setFont(Font font) { + this.font = font; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public double getWidth() { + return width; + } + + public void setWidth(double width) { + this.width = width; + } + + public int getCodeLength() { + return codeLength; + } + + public void setCodeLength(int codeLength) { + this.codeLength = codeLength; + } + + public String getCodeValue() { + return codeValue; + } + + public void setCodeValue(String codeValue) { + this.codeValue = codeValue; + } + + public boolean isBackgroundRandom() { + return backgroundRandom; + } + + public void setBackgroundRandom(boolean backgroundRandom) { + this.backgroundRandom = backgroundRandom; + } + + public boolean isCaptchaColorRandom() { + return captchaColorRandom; + } + + public void setCaptchaColorRandom(boolean captchaColorRandom) { + this.captchaColorRandom = captchaColorRandom; + } + + public int getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(int backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public int getCaptchaColor() { + return captchaColor; + } + + public void setCaptchaColor(int captchaColor) { + this.captchaColor = captchaColor; + } +} diff --git a/src/main/java/entity/CommonPageResp.java b/src/main/java/entity/CommonPageResp.java new file mode 100644 index 0000000..8348fbf --- /dev/null +++ b/src/main/java/entity/CommonPageResp.java @@ -0,0 +1,74 @@ +/* + * @(#) PagingQueryResp + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-11-24 19:57:07 + */ + +package entity; + + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 分页返回数据 + * + * @author yexr + */ +public class CommonPageResp { + /** + * 页数 + */ + @Min(0) + @NotNull + private Integer pageIndex; + /** + * 页面大小 + */ + @NotNull + @Min(1) + private Integer pageSize; + + + public Integer getPageIndex() { + return pageIndex; + } + + public void setPageIndex(Integer pageIndex) { + this.pageIndex = pageIndex; + } + + public Integer getPageSize() { + return pageSize; + } + + public void setPageSize(Integer pageSize) { + this.pageSize = pageSize; + } + + private Integer total; + + private List resultList; + + public Integer getTotal() { + return total; + } + + public void setTotal(Integer total) { + this.total = total; + } + + public List getResultList() { + return resultList; + } + + public void setResultList(List resultList) { + this.resultList = resultList; + } +} diff --git a/src/main/java/entity/FileItem.java b/src/main/java/entity/FileItem.java new file mode 100644 index 0000000..91c235c --- /dev/null +++ b/src/main/java/entity/FileItem.java @@ -0,0 +1,28 @@ + + +package entity; + +import java.io.InputStream; + +public class FileItem { + + private String fileName; + + private InputStream inputStream; + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public InputStream getInputStream() { + return inputStream; + } + + public void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } +} diff --git a/src/main/java/entity/OriginTimeValue.java b/src/main/java/entity/OriginTimeValue.java new file mode 100644 index 0000000..54819a8 --- /dev/null +++ b/src/main/java/entity/OriginTimeValue.java @@ -0,0 +1,41 @@ + + +package entity; + +/** + * 原始的时间点 + * @author huangzj + */ +public class OriginTimeValue { + + /** + * 时间 + */ + private long time; + + /** + * 数值 + */ + private long value; + + public OriginTimeValue(long time, long value) { + this.time = time; + this.value = value; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + + public long getValue() { + return value; + } + + public void setValue(long value) { + this.value = value; + } +} diff --git a/src/main/java/entity/QRCodeItem.java b/src/main/java/entity/QRCodeItem.java new file mode 100644 index 0000000..ca6d5aa --- /dev/null +++ b/src/main/java/entity/QRCodeItem.java @@ -0,0 +1,245 @@ +package entity; + +import com.google.zxing.EncodeHintType; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; + +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +public class QRCodeItem { + + + /** + * 二维码上面的文字内容 + */ + private String content; + + /** + * 文字颜色 + */ + private Color contentColor; + + /** + * 文字字体 + */ + private Font contentFont; + + /** + * 宽度 + */ + private int width; + + /** + * 高度 + */ + private int height; + + /** + * 图片后缀 + */ + private String suffix; + + /** + * logo的文件地址 + */ + private String logoPath; + + /** + * 二维码参数,这边会有默认的配置.具体配置可以参考: + * @see EncodeHintType + */ + private Map hints = new HashMap<>(); + + + /** + * 二维码背景颜色 + */ + private Color backgroundColor; + + /** + * 二维码条纹颜色 + */ + private Color stripeColor; + + + /** + * 是否自定义文字位置,如果false,直接按照程序里面的设定处理 + */ + private boolean isDiyContentPosition; + + /** + * 文字的x轴位置 + */ + private int contentX; + + + /** + * 文字的Y轴位置 + */ + private int contentY; + + + /** + * 是否自定义logo位置,如果false,直接按照程序里面的设定处理 + */ + private boolean isDiyLogoPosition; + + /** + * logo的X轴位置 + */ + private int logoX; + + /** + * logo的Y轴位置 + */ + private int logoY; + + public QRCodeItem() { + this.width= this.height = 300; + this.content = " "; + this.contentColor =Color.BLACK; + this.suffix = "png"; + //设置字符集 + this.hints.put(EncodeHintType.CHARACTER_SET,"UTF-8"); + //设置纠错等级,分为四级 + this.hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.Q); + //设置边框空白边距 + this.hints.put(EncodeHintType.MARGIN,0); + this.contentFont= new Font("宋体",Font.BOLD, 12); + this.logoPath = "F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\QRCode\\log.png"; + this.backgroundColor = Color.WHITE; + this.stripeColor = Color.BLACK; + this.isDiyContentPosition = false; + this.isDiyLogoPosition = false; + } + + public String getLogoPath() { + return logoPath; + } + + public void setLogoPath(String logoPath) { + this.logoPath = logoPath; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + + public Font getContentFont() { + return contentFont; + } + + public void setContentFont(Font contentFont) { + this.contentFont = contentFont; + } + + public Color getContentColor() { + return contentColor; + } + + public void setContentColor(Color contentColor) { + this.contentColor = contentColor; + } + + public Map getHints() { + return hints; + } + + public void setHints(Map hints) { + this.hints = hints; + } + + public Color getBackgroundColor() { + return backgroundColor; + } + + public void setBackgroundColor(Color backgroundColor) { + this.backgroundColor = backgroundColor; + } + + public Color getStripeColor() { + return stripeColor; + } + + public void setStripeColor(Color stripeColor) { + this.stripeColor = stripeColor; + } + + public boolean isDiyContentPosition() { + return isDiyContentPosition; + } + + public void setDiyContentPosition(boolean diyContentPosition) { + isDiyContentPosition = diyContentPosition; + } + + public int getContentX() { + return contentX; + } + + public void setContentX(int contentX) { + this.contentX = contentX; + } + + public int getContentY() { + return contentY; + } + + public void setContentY(int contentY) { + this.contentY = contentY; + } + + public boolean isDiyLogoPosition() { + return isDiyLogoPosition; + } + + public void setDiyLogoPosition(boolean diyLogoPosition) { + isDiyLogoPosition = diyLogoPosition; + } + + public int getLogoX() { + return logoX; + } + + public void setLogoX(int logoX) { + this.logoX = logoX; + } + + public int getLogoY() { + return logoY; + } + + public void setLogoY(int logoY) { + this.logoY = logoY; + } +} diff --git a/src/main/java/entity/TargetTimeValue.java b/src/main/java/entity/TargetTimeValue.java new file mode 100644 index 0000000..bb8025d --- /dev/null +++ b/src/main/java/entity/TargetTimeValue.java @@ -0,0 +1,30 @@ + + +package entity; + +/** + * 补时间点后的对象 + */ +public class TargetTimeValue { + private long time; + /** + * 统计值,其中null值表示没有数据 + */ + private Long value; + + public void setTime(long time) { + this.time = time; + } + + public void setValue(Long value) { + this.value = value; + } + + public long getTime() { + return time; + } + + public Long getValue() { + return value; + } +} diff --git a/src/main/java/exception/BeanCloneException.java b/src/main/java/exception/BeanCloneException.java new file mode 100644 index 0000000..b54da1f --- /dev/null +++ b/src/main/java/exception/BeanCloneException.java @@ -0,0 +1,34 @@ +/* + * @(#) BeanCloneException + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 17:13:13 + */ + +package exception; + +public class BeanCloneException extends RuntimeException { + public BeanCloneException() { + super(); + } + + public BeanCloneException(String message) { + super(message); + } + + public BeanCloneException(String message, Throwable cause) { + super(message, cause); + } + + public BeanCloneException(Throwable cause) { + super(cause); + } + + protected BeanCloneException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/exception/BeanPropertiesCopyException.java b/src/main/java/exception/BeanPropertiesCopyException.java new file mode 100644 index 0000000..10ab2bf --- /dev/null +++ b/src/main/java/exception/BeanPropertiesCopyException.java @@ -0,0 +1,35 @@ +/* + * @(#) BeanPropertiesCopyException + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 17:13:13 + */ + +package exception; + +public class BeanPropertiesCopyException extends RuntimeException { + + public BeanPropertiesCopyException() { + super(); + } + + public BeanPropertiesCopyException(String message) { + super(message); + } + + public BeanPropertiesCopyException(String message, Throwable cause) { + super(message, cause); + } + + public BeanPropertiesCopyException(Throwable cause) { + super(cause); + } + + protected BeanPropertiesCopyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/exception/SerializableDeepCloneException.java b/src/main/java/exception/SerializableDeepCloneException.java new file mode 100644 index 0000000..09e7a36 --- /dev/null +++ b/src/main/java/exception/SerializableDeepCloneException.java @@ -0,0 +1,35 @@ +/* + * @(#) SerializableDeepCloneException + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 17:13:13 + */ + +package exception; + +public class SerializableDeepCloneException extends RuntimeException { + + public SerializableDeepCloneException() { + super(); + } + + public SerializableDeepCloneException(String message) { + super(message); + } + + public SerializableDeepCloneException(String message, Throwable cause) { + super(message, cause); + } + + public SerializableDeepCloneException(Throwable cause) { + super(cause); + } + + protected SerializableDeepCloneException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/type/CloneType.java b/src/main/java/type/CloneType.java new file mode 100644 index 0000000..4fbb0bb --- /dev/null +++ b/src/main/java/type/CloneType.java @@ -0,0 +1,33 @@ +/* + * @(#) CloneType + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 17:13:13 + */ + +package type; + +/** + * @author selfImpr + */ +public enum CloneType { + + /** + * 基本类型和final的不需要复制的类型 + */ + SIMPLE_TYPE, + + /** + * 数组 + */ + ARRAY, + + /** + * 需要深度克隆的类 + */ + DEEP_CLONE_CLASS +} diff --git a/src/main/java/util/Base64Util.java b/src/main/java/util/Base64Util.java new file mode 100644 index 0000000..5644daa --- /dev/null +++ b/src/main/java/util/Base64Util.java @@ -0,0 +1,293 @@ +package util; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Writer; + +/** + * 该工具是很久之前在网上找的,现在已经忘记了对应的代码地址 + */ +public class Base64Util { + private static final char[] S_BASE64CHAR = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', + 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; + private static final char S_BASE64PAD = '='; + private static final byte[] S_DECODETABLE = new byte[128]; + private static final char EQUAL_SIGN = '='; + + public Base64Util() { + } + + private static int decode0(char[] ibuf, byte[] obuf, int wp) { + int outlen = 3; + if (ibuf[3] == EQUAL_SIGN) { + outlen = 2; + } + + if (ibuf[2] ==EQUAL_SIGN ) { + outlen = 1; + } + + int b0 = S_DECODETABLE[ibuf[0]]; + int b1 = S_DECODETABLE[ibuf[1]]; + int b2 = S_DECODETABLE[ibuf[2]]; + int b3 = S_DECODETABLE[ibuf[3]]; + switch (outlen) { + case 1: + obuf[wp] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3); + return 1; + case 2: + obuf[wp++] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3); + obuf[wp] = (byte) (b1 << 4 & 240 | b2 >> 2 & 15); + return 2; + case 3: + obuf[wp++] = (byte) (b0 << 2 & 252 | b1 >> 4 & 3); + obuf[wp++] = (byte) (b1 << 4 & 240 | b2 >> 2 & 15); + obuf[wp] = (byte) (b2 << 6 & 192 | b3 & 63); + return 3; + default: + throw new RuntimeException("Internal Errror"); + } + } + + public static byte[] decode(char[] data, int off, int len) { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[len / 4 * 3 + 3]; + int obufcount = 0; + + for (int i = off; i < off + len; ++i) { + char ch = data[i]; + if (ch == '=' || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + return decodeResult(obufcount,obuf); + } + + private static byte[] decodeResult(int obufcount, byte[] obuf) { + if (obufcount == obuf.length) { + return obuf; + } else { + byte[] ret = new byte[obufcount]; + System.arraycopy(obuf, 0, ret, 0, obufcount); + return ret; + } + } + + public static byte[] decode(String data) { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[data.length() / 4 * 3 + 3]; + int obufcount = 0; + + for (int i = 0; i < data.length(); ++i) { + char ch = data.charAt(i); + if (ch == '=' || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + + return decodeResult(obufcount,obuf); + } + + public static void decode(char[] data, int off, int len, OutputStream ostream) throws IOException { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[3]; + + for (int i = off; i < off + len; ++i) { + char ch = data[i]; + decodeProcess(ch,ibuf,ibufcount,ostream,obuf); + } + + } + + private static void decodeProcess(char ch, char[] ibuf, int ibufcount, OutputStream ostream, byte[] obuf) throws IOException { + if (ch == '=' || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + int obufcount = decode0(ibuf, obuf, 0); + ostream.write(obuf, 0, obufcount); + } + } + } + + public static void decode(String data, OutputStream ostream) throws IOException { + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[3]; + + for (int i = 0; i < data.length(); ++i) { + char ch = data.charAt(i); + decodeProcess(ch,ibuf,ibufcount,ostream,obuf); + } + + } + + public static String encode(byte[] data) { + return encode(data, 0, data.length); + } + + public static String encode(byte[] data, int off, int len) { + if (len <= 0) { + return ""; + } else { + char[] out = new char[len / 3 * 4 + 4]; + int rindex = off; + int windex = 0; + + int rest; + int i; + for (rest = len; rest >= 3; rest -= 3) { + i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255); + out[windex++] = S_BASE64CHAR[i >> 18]; + out[windex++] = S_BASE64CHAR[i >> 12 & 63]; + out[windex++] = S_BASE64CHAR[i >> 6 & 63]; + out[windex++] = S_BASE64CHAR[i & 63]; + rindex += 3; + } + + if (rest == 1) { + i = data[rindex] & 255; + out[windex++] = S_BASE64CHAR[i >> 2]; + out[windex++] = S_BASE64CHAR[i << 4 & 63]; + out[windex++] = '='; + out[windex++] = '='; + } else if (rest == 2) { + i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255); + out[windex++] = S_BASE64CHAR[i >> 10]; + out[windex++] = S_BASE64CHAR[i >> 4 & 63]; + out[windex++] = S_BASE64CHAR[i << 2 & 63]; + out[windex++] = '='; + } + + return new String(out, 0, windex); + } + } + + public static void encode(byte[] data, int off, int len, OutputStream ostream) throws IOException { + if (len > 0) { + byte[] out = new byte[4]; + int rindex = off; + + int rest; + int i; + for (rest = len; rest >= 3; rest -= 3) { + i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255); + out[0] = (byte) S_BASE64CHAR[i >> 18]; + out[1] = (byte) S_BASE64CHAR[i >> 12 & 63]; + out[2] = (byte) S_BASE64CHAR[i >> 6 & 63]; + out[3] = (byte) S_BASE64CHAR[i & 63]; + ostream.write(out, 0, 4); + rindex += 3; + } + + if (rest == 1) { + i = data[rindex] & 255; + out[0] = (byte) S_BASE64CHAR[i >> 2]; + out[1] = (byte) S_BASE64CHAR[i << 4 & 63]; + out[2] = 61; + out[3] = 61; + ostream.write(out, 0, 4); + } else if (rest == 2) { + i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255); + out[0] = (byte) S_BASE64CHAR[i >> 10]; + out[1] = (byte) S_BASE64CHAR[i >> 4 & 63]; + out[2] = (byte) S_BASE64CHAR[i << 2 & 63]; + out[3] = 61; + ostream.write(out, 0, 4); + } + + } + } + + public static void encode(byte[] data, int off, int len, Writer writer) throws IOException { + if (len > 0) { + char[] out = new char[4]; + int rindex = off; + int rest = len; + int output = 0; + + int i; + while (rest >= 3) { + i = ((data[rindex] & 255) << 16) + ((data[rindex + 1] & 255) << 8) + (data[rindex + 2] & 255); + out[0] = S_BASE64CHAR[i >> 18]; + out[1] = S_BASE64CHAR[i >> 12 & 63]; + out[2] = S_BASE64CHAR[i >> 6 & 63]; + out[3] = S_BASE64CHAR[i & 63]; + writer.write(out, 0, 4); + rindex += 3; + rest -= 3; + output += 4; + if (output % 76 == 0) { + writer.write("\n"); + } + } + + if (rest == 1) { + i = data[rindex] & 255; + out[0] = S_BASE64CHAR[i >> 2]; + out[1] = S_BASE64CHAR[i << 4 & 63]; + out[2] = '='; + out[3] = '='; + writer.write(out, 0, 4); + } else if (rest == 2) { + i = ((data[rindex] & 255) << 8) + (data[rindex + 1] & 255); + out[0] = S_BASE64CHAR[i >> 10]; + out[1] = S_BASE64CHAR[i >> 4 & 63]; + out[2] = S_BASE64CHAR[i << 2 & 63]; + out[3] = '='; + writer.write(out, 0, 4); + } + + } + } + + static { + int i; + for (i = 0; i < S_DECODETABLE.length; ++i) { + S_DECODETABLE[i] = 127; + } + + for (i = 0; i < S_BASE64CHAR.length; ++i) { + S_DECODETABLE[S_BASE64CHAR[i]] = (byte) i; + } + + } + + public static byte[] decodeByte(String data) { + + char[] ibuf = new char[4]; + int ibufcount = 0; + byte[] obuf = new byte[data.length() / 4 * 3 + 3]; + int obufcount = 0; + for (int i = 0; i < data.length(); i++) { + char ch = data.charAt(i); + if (ch == S_BASE64PAD || ch < S_DECODETABLE.length && S_DECODETABLE[ch] != Byte.MAX_VALUE) { + ibuf[ibufcount++] = ch; + if (ibufcount == ibuf.length) { + ibufcount = 0; + obufcount += decode0(ibuf, obuf, obufcount); + } + } + } + if (obufcount == obuf.length) { + return obuf; + } + byte[] ret = new byte[obufcount]; + System.arraycopy(obuf, 0, ret, 0, obufcount); + return ret; + } + + +} diff --git a/src/main/java/util/FileUtil.java b/src/main/java/util/FileUtil.java new file mode 100644 index 0000000..4d4899c --- /dev/null +++ b/src/main/java/util/FileUtil.java @@ -0,0 +1,263 @@ + + +package util; + + +import com.google.common.collect.Lists; +import entity.FileItem; +import org.springframework.util.CollectionUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; +import java.util.Objects; + +/** + * + * @author 志军 + */ +public class FileUtil { + + private static final byte[] BUF = new byte[1024]; + + private static final int BUF_SIZE = 1024; + + public static void deleteFile(String filePath) { + File file = new File(filePath); + if (!file.exists()) { + throw new RuntimeException("文件不存在"); + } + + file.delete(); + } + + + /** + * 支持输入流存储到对应文件夹下,仅对文件夹有效 + * @param fileItems 输入流、文件名 数组 + * @param dirPath 文件夹路径 + */ + public static void storeFiles(List fileItems, String dirPath) { + File file = new File(dirPath); + if (!file.exists() && !file.isDirectory()) { + file.mkdir(); + } + + fileItems.forEach(fileItem -> { + File fileItemFile = new File(dirPath + File.separator + fileItem.getFileName()); + FileOutputStream fileOutputStream; + + try { + //创建文件 + fileItemFile.createNewFile(); + fileOutputStream = new FileOutputStream(fileItemFile); + int len; + while ((len = fileItem.getInputStream().read(BUF, 0, BUF_SIZE)) != -1) { + fileOutputStream.write(BUF, 0, len); + } + + fileOutputStream.close(); + fileItem.getInputStream().close(); + } catch (IOException e) { + throw new RuntimeException("生成文件错误"); + } + }); + } + + public static boolean fileExist(String filePath){ + File file = new File(filePath); + return file.exists(); + } + + public static boolean isFile(String filePath){ + File file = new File(filePath); + if ( file.exists()){ + return file.isFile(); + } + return false; + } + + public static boolean isDir(String filePath){ + File file = new File(filePath); + if ( file.exists()){ + return file.isDirectory(); + } + return false; + } + + /** + * 文件已存在或者创建成功返回true + * 文件不存在或者非文件(文件夹)或者创建失败,返回false + */ + public static boolean createFile(String filePath){ + if(fileExist(filePath)){ + return isFile(filePath); + } + File file = new File(filePath); + try { + return file.createNewFile(); + } catch (IOException e) { + return false; + } + } + + /** + * 创建并获取一个File对象 + * 如果是文件、创建成功返回对应的文件对象 + * 其他情况直接返回null. + */ + public static File createGetFile(String filePath){ + if(fileExist(filePath)){ + if ( isFile(filePath)){ + return new File(filePath); + } + } + File file = new File(filePath); + try { + boolean result = file.createNewFile(); + if (result){ + return file; + } + } catch (IOException e) { + return null; + } + return null; + } + + /** + * 文件转换成byte数组 + */ + public static byte[] fileToByte(String filePath) { + FileInputStream in = null; + try { + in = new FileInputStream(new File(filePath)); + byte[] bytes = new byte[in.available()]; + in.read(bytes); + return bytes; + } catch (IOException e) { + throw new RuntimeException("转换失败",e); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + /** + * byte数组写入文件 + */ + public static void bytesToFile(String filePath,byte[] content){ + FileOutputStream out = null; + try { + out = new FileOutputStream(new File(filePath)); + out.write(content); + out.flush(); + } catch (IOException e) { + throw new RuntimeException("写入失败",e); + } finally { + if (out != null) { + try { + out.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + + /** + * 拿到文件夹下面的所有文件夹(包括它自己) + */ + public static List findAllDirFromDir(String dirPath){ + File dir = new File(dirPath); + if(!dir.exists() || !dir.isDirectory()){ + throw new RuntimeException("非文件夹或者文件夹位置错误"); + } + List result = findDir(dir); + result.add(dir); + return result; + } + + private static List findDir(File file ){ + List list = Lists.newArrayList(); + for(File child : Objects.requireNonNull(file.listFiles())){ + if(child.isDirectory()){ + list.add(child); + List tempList = findDir(child); + if(!CollectionUtils.isEmpty(tempList)){ + list.addAll(tempList); + } + } + } + return list; + } + + + /** + * 拿到文件夹下面的所有空文件夹 + */ + public static List findAllEmptyDirFromDir( String dirPath){ + List list = Lists.newArrayList(); + File dir = new File(dirPath); + if(!dir.exists() || !dir.isDirectory()){ + throw new RuntimeException("非文件夹或者文件夹位置错误"); + } + List allList = findAllDirFromDir(dirPath); + for(File dirFile:allList){ + if(isEmptyFile(dirFile)){ + list.add(dirFile); + } + } + return list; + } + + + /** + * 通过目录获取目录下所有的文件 + */ + public static List findAllFile(File dir){ + List list = Lists.newArrayList(); + for (File file : Objects.requireNonNull(dir.listFiles())){ + if(file.isFile()){ + list.add(file); + }else{ + List tempList = findAllFile(file); + if(!CollectionUtils.isEmpty(tempList)){ + list.addAll(tempList); + } + } + } + return list; + } + + private static boolean isEmptyFile(File dir) { + List child = findAllFile(dir); + return CollectionUtils.isEmpty(child); + } + + + /** + * 拿到文件夹下面的所有非空文件夹 + */ + public static List findAllNotEmptyDirFromDir( String dirPath){ + List list = Lists.newArrayList(); + File dir = new File(dirPath); + if(!dir.exists() || !dir.isDirectory()){ + throw new RuntimeException("非文件夹或者文件夹位置错误"); + } + List allList = findAllDirFromDir(dirPath); + for(File dirFile:allList){ + if(!isEmptyFile(dir)){ + list.add(dirFile); + } + } + return list; + } +} diff --git a/src/main/java/util/MessageUtils.java b/src/main/java/util/MessageUtils.java new file mode 100644 index 0000000..c5d5816 --- /dev/null +++ b/src/main/java/util/MessageUtils.java @@ -0,0 +1,27 @@ +package util; + +import org.slf4j.helpers.MessageFormatter; + +import java.text.MessageFormat; + +/** + * Created by huangzj on 2017/8/21. + * @author 志军 + */ +public class MessageUtils { + /** + * 格式化信息,支持message={0}或message={}格式的信息模板。 + * + * @param pattern 信息模板 + * @param parameters 参数值 + * @return 格式化后的信息 + */ + public static String format(String pattern, Object... parameters) { + try { + return MessageFormat.format(pattern, parameters); + } catch (IllegalArgumentException e) { + //上面的MessageFormat报错进来这边的,这边的测试只测试出当格式不正确的情况才会进来 + return MessageFormatter.arrayFormat(pattern, parameters).getMessage(); + } + } +} diff --git a/src/main/java/util/PageUtil.java b/src/main/java/util/PageUtil.java new file mode 100644 index 0000000..2997ca4 --- /dev/null +++ b/src/main/java/util/PageUtil.java @@ -0,0 +1,93 @@ +/* + * @(#) PageUtil + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-11-24 19:55:37 + */ + +package util; + + +import entity.CommonPageResp; + +import java.util.Collections; +import java.util.List; + +import static additive.ValidTool.assertIsTrue; +import static java.lang.Math.min; + + +/** + * 分页工具类 + * + * @author 志军 + * @date + */ +public class PageUtil { + + private static final int ZERO = 0; + + /** + * 前端传,从0开始分页(对list进行分页) + * @param list 列表 + * @param pageIndex 页码 + * @param pageSize 页数 + * @param T + * @return 分页通用对象 + */ + public static CommonPageResp pagingListFromZero(List list, int pageIndex, int pageSize) { + assertIsTrue(pageIndex >= 0, "pageIndex必需大于等于0"); + + if (list == null ) { + return nullPage(pageSize); + } + CommonPageResp pagingQueryResp = new CommonPageResp<>(); + int index = min(((list.size() - 1) / pageSize), pageIndex); + pagingQueryResp.setPageIndex(index); + pagingQueryResp.setPageSize(pageSize); + pagingQueryResp.setTotal(list.size()); + pagingQueryResp.setResultList(list.subList(index * pageSize, min((index + 1) * pageSize, list.size()))); + return pagingQueryResp; + } + + + + /** + * 前端传,从1开始分页(对list进行分页) + * @param list 列表 + * @param pageIndex 页码 + * @param pageSize 页数 + * @param T + * @return 分页通用对象 + */ + static CommonPageResp pagingListFromOne(List list, int pageIndex, int pageSize) { + if ( pageIndex<1){ + pageIndex = 1; + } + CommonPageResp pagingQueryResp = new CommonPageResp<>(); + + if (list == null) { + return nullPage(pageSize); + } + int index = min(((list.size() - 1 )/ pageSize + 1), pageIndex); + pagingQueryResp.setPageIndex(index); + pagingQueryResp.setPageSize(pageSize); + pagingQueryResp.setTotal(list.size()); + pagingQueryResp.setResultList(list.subList((index - 1) * pageSize, min(index * pageSize, list.size()))); + return pagingQueryResp; + } + + private static CommonPageResp nullPage(int pageSize) { + CommonPageResp pagingQueryResp = new CommonPageResp<>(); + pagingQueryResp.setResultList(Collections.emptyList()); + pagingQueryResp.setTotal(ZERO); + pagingQueryResp.setPageIndex(ZERO); + pagingQueryResp.setPageSize(pageSize); + return pagingQueryResp; + } + +} diff --git a/src/main/java/util/PatternUtils.java b/src/main/java/util/PatternUtils.java new file mode 100644 index 0000000..e88bbe0 --- /dev/null +++ b/src/main/java/util/PatternUtils.java @@ -0,0 +1,105 @@ +package util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 这个就是一个储备的工作工具,不具备学习的用处,反正我是学不来 + * 参考网上的地址:http://tools.jb51.net/regex/create_reg + * https://www.jb51.net/article/115170.htm + * + * @author 志军 + */ +public class PatternUtils { + + /** + * 全是中文 + */ + private static final String ALL_CHINESS_PATTERN = "[\\u4e00-\\u9fa5]+"; + + /** + * 是不是E-mail地址 + */ + private static final String EMAIL_ADDRESS_PATTERN = "\\w[-\\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\\.)+[A-Za-z]{2,14}"; + + /** + * 是不是网址 + * + */ + private static final String INTERNET_URL_PATTERN = "^((https|http|ftp|rtsp|mms)?:\\/\\/)[^\\s]+"; + + /** + * 2018目前国内的手机 + */ + private static final String MOBILE_PHONE_PATTERN = "/^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$/"; + + /** + * 2018目前国内的电话 + */ + private static final String TEL_PHONE_PATTERN = "[0-9-()()]{7,18}"; + + /** + * qq号码 + */ + private static final String QQ_PATTERN = "[1-9]([0-9]{5,11})"; + + /** + * 邮政编码 + */ + private static final String POSTAL_CODE_PATTERN = "\\d{6}"; + + /** + * 身份证,验证15位和18位 + * https://www.jb51.net/article/109384.htm + */ + private static final String ID_CARD_PATTERN = " ^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)" + + "\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$"; + + /** + * IPv4地址正则 + */ + private static final String IPV4_PATTERN = "/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}" + + "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/"; + + /** + * 微信号,6至20位,以字母开头,字母,数字,减号,下划线 + */ + private static final String WEIXIN_PATTERN = "/^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/"; + + /** + * 车牌号 + */ + private static final String LICENSE_PLATE_PATTERN = " /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/"; + + /** + * 日期正则,复杂判定 + */ + private static final String DATE_PATTERN = "/^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-" + + "(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/"; + + /** + * 用户名正则,,4到16位(字母,数字,下划线,减号) + */ + private static final String USER_NAME_PATTERN = "/^[a-zA-Z0-9_-]{4,16}$/"; + + /** + * 密码正则 最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符 + */ + private static final String PASSWORD_PATTERN = "/^.*(?=.{6,})(?=.*\\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/"; + + /** + * 文件路径及拓展名校验 + */ + private static final String FILE_PATH_PATTERN = "([a-zA-Z]\\\\:|\\\\\\\\)\\\\\\\\([^\\\\\\\\]+\\\\\\\\)*[^\\\\/:*?\"<>|]+\\\\.txt(l)?$"; + + /** + * 这边就不一一写出来了,以后要用的时候再说 + * + */ + private static boolean commonPattern(String pattern, String str) { + Pattern r = Pattern.compile(pattern); + Matcher m = r.matcher(str); + return m.matches(); + } + +} diff --git a/src/main/java/util/ShellUtils.java b/src/main/java/util/ShellUtils.java new file mode 100644 index 0000000..32b1d3f --- /dev/null +++ b/src/main/java/util/ShellUtils.java @@ -0,0 +1,49 @@ + + +package util; + + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; + +/** + * 调用shell命令 + * @author 志军 + */ +public class ShellUtils { + + + /** + * 压缩文件 + * @param originPath 源文件位置 + * @param tarPath 新文件位置 + */ + public void compressFile(String originPath, String tarPath) { + InputStream in = null; + try { + Process cd = Runtime.getRuntime().exec(new String[]{"cd", " ", originPath}); + cd.waitFor(); + Process pro = Runtime.getRuntime().exec(new String[]{"tar", " -czf", tarPath, "*.tar.gz"}); + pro.waitFor(); + in = pro.getInputStream(); + BufferedReader read = new BufferedReader(new InputStreamReader(in)); + String result = read.readLine(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void deleteFile(String tempPathOnTime) { + InputStream in = null; + try { + Process pro = Runtime.getRuntime().exec(new String[]{"rm", "-rf", " ", tempPathOnTime}); + pro.waitFor(); + in = pro.getInputStream(); + BufferedReader read = new BufferedReader(new InputStreamReader(in)); + String result = read.readLine(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/util/StringUtils.java b/src/main/java/util/StringUtils.java new file mode 100644 index 0000000..9995ac2 --- /dev/null +++ b/src/main/java/util/StringUtils.java @@ -0,0 +1,197 @@ +/* + * @(#) StringUtils + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 17:13:13 + */ + +package util; + +import net.sourceforge.pinyin4j.PinyinHelper; +import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; +import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; +import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; +import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType; +import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; + +import java.nio.charset.StandardCharsets; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author 志军 + * 补充Strings的缺失 + */ +class StringUtils { + + private static char A_LETTER = 'a'; + private static char Z_LETTER = 'z'; + private static Pattern p = Pattern.compile("[\u4e00-\u9fa5]"); + + /** + * 首字母小写 + */ + static String lowerFirstLetter(String word) { + char[] chars = word.toCharArray(); + if (chars[0] >= A_LETTER && chars[0] <= Z_LETTER) { + chars[0] += 32; + } + + return String.valueOf(chars); + } + + /** + * 首字母大写 + */ + static String upperFirstLetter(String word) { + char[] chars = word.toCharArray(); + if (chars[0] >= A_LETTER && chars[0] <= Z_LETTER) { + chars[0] -= 32; + } + + return String.valueOf(chars); + } + + static String upperAllLetter(String word){ + StringBuilder stringBuilder = new StringBuilder(); + char[] chars = word.toCharArray(); + for( int i= 0;i= A_LETTER && chars[0] <= Z_LETTER) { + chars[0] -= 32; + } + stringBuilder.append(chars[i]); + } + return stringBuilder.toString(); + } + + static String lowerAllLetter(String word) { + StringBuilder stringBuilder = new StringBuilder(); + char[] chars = word.toCharArray(); + for( int i= 0;i= A_LETTER && chars[0] <= Z_LETTER) { + chars[0] += 32; + } + stringBuilder.append(chars[i]); + } + return stringBuilder.toString(); + } + + + static String appendAll(String... word){ + StringBuilder stringBuilder = new StringBuilder(); + for (String aWord : word) { + stringBuilder.append(aWord); + } + return stringBuilder.toString(); + } + + + /** + * 判断字符串中是否包含中文 + */ + static boolean isContainChinese(String str) { + Matcher m = p.matcher(str); + return m.find(); + } + + + /** + * 校验一个字符是否是汉字 + */ + static boolean isChineseChar(char c) { + try { + return String.valueOf(c).getBytes(StandardCharsets.UTF_8).length > 1; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + static String toPinyinUpper(String word) throws BadHanyuPinyinOutputFormatCombination { + StringBuilder stringBuilder = new StringBuilder(); + HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); + format.setCaseType(HanyuPinyinCaseType.UPPERCASE); + format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); + char[] chars = word.toCharArray(); + buildChars(chars,stringBuilder,format); + return stringBuilder.toString(); + } + + static String toPinyinLower(String word) throws BadHanyuPinyinOutputFormatCombination { + StringBuilder stringBuilder = new StringBuilder(); + HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); + format.setCaseType(HanyuPinyinCaseType.LOWERCASE); + format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); + char[] chars = word.toCharArray(); + buildChars(chars,stringBuilder,format); + return stringBuilder.toString(); + } + + + private static void buildChars(char[] chars,StringBuilder stringBuilder,HanyuPinyinOutputFormat format) throws BadHanyuPinyinOutputFormatCombination { + for (char aChar : chars) { + if (isChineseChar(aChar)) { + String[] result = PinyinHelper.toHanyuPinyinStringArray(aChar, format); + for(String s : result){ + stringBuilder.append(s); + } + continue; + } + //处理非中文的部分 + stringBuilder.append(aChar); + } + } + + + + + static String toPinyinPhoneticSignUpper(String word ) throws BadHanyuPinyinOutputFormatCombination { + StringBuilder stringBuilder = new StringBuilder(); + HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); + format.setToneType(HanyuPinyinToneType.WITH_TONE_MARK); + format.setCaseType(HanyuPinyinCaseType.UPPERCASE); + format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE); + char[] chars = word.toCharArray(); + buildChars(chars,stringBuilder,format); + return stringBuilder.toString(); + } + + static String toPinyinPhoneticSignLower(String word ) throws BadHanyuPinyinOutputFormatCombination { + StringBuilder stringBuilder = new StringBuilder(); + HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); + format.setCaseType(HanyuPinyinCaseType.LOWERCASE); + format.setToneType(HanyuPinyinToneType.WITH_TONE_MARK); + format.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE); + char[] chars = word.toCharArray(); + buildChars(chars,stringBuilder,format); + return stringBuilder.toString(); + } + + + /** + * 通过正则表达式进行替换 + */ + static String replacePattern(String word,String pattern){ + if (word != null) { + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(word); + word = m.replaceAll(""); + } + return word; + } + + static String replacePattern(String word,String replace,String pattern){ + if (word != null) { + Pattern p = Pattern.compile(pattern); + Matcher m = p.matcher(word); + word = m.replaceAll(replace); + } + return word; + } + +} diff --git a/src/main/java/util/clazz/ClassUtils.java b/src/main/java/util/clazz/ClassUtils.java new file mode 100644 index 0000000..4e16700 --- /dev/null +++ b/src/main/java/util/clazz/ClassUtils.java @@ -0,0 +1,356 @@ +package util.clazz; + + +import exception.BeanCloneException; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.internal.org.objectweb.asm.Type; +import type.CloneType; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.util.*; + + +/** + * 类操作的工具类 + * + * @author selfImpr + */ +public class ClassUtils { + + /** + * final基本类型对象 + */ + private static List basicWrapType; + + + static { + basicWrapType = Arrays.asList(new Class[]{Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Boolean + .class, Character.class, String.class}); + } + + public static CloneType getCloneType(Object object) { + //判断是不是基本类型 + if (object.getClass().isPrimitive()) { + return CloneType.SIMPLE_TYPE; + } + + if (basicWrapType.contains(object.getClass())) { + return CloneType.SIMPLE_TYPE; + } + + if (object.getClass().isArray()) { + return CloneType.ARRAY; + } + + return CloneType.DEEP_CLONE_CLASS; + } + + public static List getAllField(Object object) { + List fields = new ArrayList<>(); + if (object == null) { + return fields; + } + + //TODO 这边的这个类型会不会有问题 + return Arrays.asList(object.getClass().getDeclaredFields()); + } + + public static List getAllFieldName(Object object) { + List attributes = new ArrayList<>(); + Field[] fields = object.getClass().getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + attributes.add(fields[i].getName()); + } + return attributes; + } + + + /** + * 获取类层面上的泛型类型 + * 但是这边应该是有一个限制条件:因为java是泛型擦出,所以是拿不到具体的类型的.... + * 这边做一个变通就是说去拿里面数据的类型,如果没有数据的话,就统一返回Object + *

+ *

+ * 并且还不能判断自定义的泛型类型。 + * + * @param object + */ + public static List getGenericParamType(Object object) { + List genericParamType = new ArrayList<>(); + + + java.lang.reflect.Type type = object.getClass().getGenericSuperclass(); + if (type instanceof ParameterizedType) { + if (Collection.class.isAssignableFrom(object.getClass())) { + if (((Collection) object).size() == 0) { + genericParamType.add(Object.class); + return genericParamType; + } + + genericParamType.add(((Collection) object).iterator().next().getClass()); + } + + if (Map.class.isAssignableFrom(object.getClass())) { + if (((Map) object).size() == 0) { + genericParamType.add(Object.class); + genericParamType.add(Object.class); + return genericParamType; + } + + //设置key和value的值 + genericParamType.add(((Map) object).keySet().iterator().next().getClass()); + genericParamType.add(((Map) object).values().iterator().next().getClass()); + + } + + } else { + //TODO 怎么判断自定义的类型是不是存在泛型? + } + + return genericParamType; + } + + + /** + * 通过Field去获取泛型的类型 + */ + public static List getGenericParamTypeInField(Field field) { + List genericParamType = new ArrayList<>(); + if (field.getGenericType() instanceof ParameterizedType) { + java.lang.reflect.Type[] types = ((ParameterizedType) field.getGenericType()).getActualTypeArguments(); + for (java.lang.reflect.Type type : types) { + genericParamType.add(type.getClass()); + } + + return genericParamType; + } + + //TODO 这边还是没有解决自定义拥有泛型类型参数的问题啊... + + genericParamType.add(field.getType()); + + return genericParamType; + } + + + /** + * 如果有一个的某个参数为空是处理不了泛型的.... + * + */ + public static boolean isParamterTypeSame(Object originBean, Object newObject) { + //第一个条件就是:两个类型都相同 + if (ClassUtils.getCloneType(originBean) == ClassUtils.getCloneType(newObject)) { + switch (ClassUtils.getCloneType(originBean)) { + case SIMPLE_TYPE: + return isSimpleTypeSame(originBean, newObject); + case ARRAY: + return isArrayTypeSame(originBean, newObject); + case DEEP_CLONE_CLASS: + return isClassTypeSame(originBean, newObject); + default: + throw new BeanCloneException("判断参数类型的时候出错了"); + } + } + return false; + } + + private static boolean isSimpleTypeSame(Object originBean, Object newObject) { + if (originBean.getClass() == Class.class || newObject.getClass() == Class.class) { + return originBean == newObject; + } + return originBean.getClass() == newObject.getClass(); + } + + private static boolean isArrayTypeSame(Object originBean, Object newObject) { + if (originBean.getClass() == Class.class || newObject.getClass() == Class.class) { + return originBean == newObject; + } + return originBean.getClass() == newObject.getClass(); + } + + + /** + * 不处理泛型的问题了,这个太复杂了 + * 这个方法有严重bug... + * + */ + private static boolean isClassTypeSame(Object originBean, Object newObject) { + //这边是为了判断如果传进来的是集合的泛型或者是参数中的域的类型 + if (ClassUtils.getCloneType(originBean) == ClassUtils.getCloneType(newObject)) { + + if (originBean.getClass() == Class.class || newObject.getClass() == Class.class) { + return originBean == newObject; + } + + if (ClassUtils.getCloneType(originBean) == CloneType.SIMPLE_TYPE) { + return isSimpleTypeSame(originBean, newObject); + } + + if (ClassUtils.getCloneType(originBean) == CloneType.ARRAY) { + return isArrayTypeSame(originBean, newObject); + } + + if (Collection.class.isAssignableFrom(originBean.getClass())) { + return isClassTypeSame(ClassUtils.getGenericParamType(originBean).get(0), ClassUtils.getGenericParamType(newObject).get(0)); + } + + if (Map.class.isAssignableFrom(originBean.getClass())) { + return isClassTypeSame(ClassUtils.getGenericParamType(originBean).get(0), ClassUtils.getGenericParamType(newObject).get + (0)) && isClassTypeSame(ClassUtils.getGenericParamType(originBean).get(1), ClassUtils.getGenericParamType(newObject) + .get(1)); + } + + return originBean.getClass() == newObject.getClass(); + } + + return false; + } + + + @SuppressWarnings("unchecked") + public static Set getClassesByInterface(String[] filePath, Class interfaceClass) { + Set interfaceImpClasses = new HashSet<>(); + Set classes = new HashSet<>(); + + for (String path : filePath) { + //把前面那个"/"去掉 + Set set = getAllClass(new File(interfaceClass.getResource("/" + path.replaceAll("\\.", "/")).getPath()), + path); + interfaceImpClasses.addAll(set); + } + + for (Class clazz : interfaceImpClasses) { + if (!interfaceClass.isAssignableFrom(clazz)) { + continue; + } + + if (!clazz.isInterface() && !clazz.isAnnotation() && !Modifier.isAbstract(clazz.getModifiers())) { + classes.add(clazz); + } + } + return classes; + } + + /** + * @param file 查找路径的File对象 -- 不区分是不是抽象类或者是借口 + * @param packageName 查找的路径(根) + */ + public static Set getAllClass(File file, String packageName) { + Set classSet = new HashSet<>(); + for (File f : Objects.requireNonNull(file.listFiles())) { + + if (f.isDirectory()) { + String packageName1 = packageName + "." + f.getName(); + classSet.addAll(getAllClass(f, packageName1)); + } else if (f.getPath().endsWith(".class")) { + try { + classSet.add(Class.forName(packageName + "." + f.getName().replaceAll(".class", ""))); + } catch (ClassNotFoundException e) { + //TODO 内部类也会单独生成一个.class文件,也被加入这里面。怎么办? + throw new RuntimeException("初始化出错了"); + } + } + } + return classSet; + } + + + /** + * 我在做方法的反射的时候会遇到就是说去反射java自定义的那些方法的时候,出错。 + * 那这个方法就是说返回所有父类的java的类的方法,我不去反射他们 + */ + public static List getSuperClassMethod(Class clazz) { + List methods = new ArrayList<>(); + if (clazz.getSuperclass() == null) { + //java自带的类加载器是null + if (clazz.getClassLoader() == null) { + methods.addAll(Arrays.asList(clazz.getMethods())); + return methods; + } else { + return methods; + } + } else { + return getSuperClassMethod(clazz.getSuperclass()); + } + } + + + /** + * 通过这个方法,拿到方法的参数的名称(用户自己定义的) + * 参考地址:https://blog.csdn.net/mhmyqn/article/details/47294485 + */ + public static String[] getParameterNames(Class clazz, Method method) { + final Class[] parameterTypes = method.getParameterTypes(); + System.out.println("method name : " + method.getName()); + if (parameterTypes.length == 0) { + return null; + } + + //应该还要排除一种情况就是说java自带的方法。我们不处理这类的方法 + List methods = getSuperClassMethod(clazz); + if (methods.contains(method)) { + return null; + } + + + //这边有一个需要注意的就是说如果是static的方法,这边的param的数组数量是正常的,非static方法数量要加一 + String[] parameterNames; + parameterNames = new String[parameterTypes.length]; + // if (Modifier.isStatic(method.getModifiers())) { + // } else { + // parameterNames = new String[parameterTypes.length + 1]; + // } + + final Type[] types = new Type[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + types[i] = Type.getType(parameterTypes[i]); + } + + //拿到类名 比如 org.framework.abc 拿到 abc.class + String className = clazz.getName().substring(clazz.getName().lastIndexOf(".") + 1) + ".class"; + InputStream is = clazz.getResourceAsStream(className); + + try { + ClassReader classReader = new ClassReader(is); + //我们重写了这下面的方法 + classReader.accept(new ClassVisitorUtils(Opcodes.ASM4, method, types, parameterNames), 0); + } catch (IOException e) { + throw new RuntimeException("读取类的信息出错了"); + } + + return parameterNames; + } + + + @SuppressWarnings("unchecked") + public static T newInstance(String className,Class superClass){ + Class classType = null; + try { + classType = Class.forName(className); + } catch (ClassNotFoundException e) { + throw new RuntimeException("生成Class出错",e); + } + + if(!superClass.isAssignableFrom(classType)){ + throw new RuntimeException("类必须继承" + superClass.getName()); + } + + Class classes = (Class) classType; + + try { + return classes.newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException("类实例化出错"+e); + } catch (IllegalAccessException e) { + throw new RuntimeException("类实例化出错了" + e); + } + } + +} diff --git a/src/main/java/util/clazz/ClassVisitorUtils.java b/src/main/java/util/clazz/ClassVisitorUtils.java new file mode 100644 index 0000000..fb16111 --- /dev/null +++ b/src/main/java/util/clazz/ClassVisitorUtils.java @@ -0,0 +1,61 @@ +/* + * @(#) ClassVisitorUtils + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 22:38:38 + */ + +package util.clazz; + +import jdk.internal.org.objectweb.asm.ClassVisitor; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.internal.org.objectweb.asm.Type; + +import java.lang.reflect.Method; +import java.util.Arrays; + +public class ClassVisitorUtils extends ClassVisitor { + + /**需要获取到参数名称的方法*/ + private Method method; + + /***/ + private Type[] types; + + /**存放参数名称的数组*/ + private String[] parameterNames; + + public ClassVisitorUtils(int i) { + super(i); + } + + public ClassVisitorUtils(int i, ClassVisitor classVisitor) { + super(i, classVisitor); + } + + public ClassVisitorUtils(int i, Method method, Type[] types, String[] parameterNames) { + super(i); + this.method = method; + this.types = types; + this.parameterNames = parameterNames; + } + + /**我们重写这个方法在我们的ClassUtils里面去使用*/ + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + Type[] argumentTypes = Type.getArgumentTypes(desc); + if (!method.getName().equals(name) || !Arrays.equals(argumentTypes, types)) { + return null; + } + + /**这个地方注意每次调用结束的重置*/ + MethodVisitorUtils methodVisitorUtils = new MethodVisitorUtils(Opcodes.ASM4, argumentTypes, method, parameterNames); + methodVisitorUtils.resetParamLocation(); + return methodVisitorUtils; + } +} diff --git a/src/main/java/util/clazz/MethodVisitorUtils.java b/src/main/java/util/clazz/MethodVisitorUtils.java new file mode 100644 index 0000000..ca5d141 --- /dev/null +++ b/src/main/java/util/clazz/MethodVisitorUtils.java @@ -0,0 +1,74 @@ +/* + * @(#) MethodVisitorUtils + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-10-07 22:55:01 + */ + +package util.clazz; + +import jdk.internal.org.objectweb.asm.Label; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Type; + +import java.lang.reflect.Method; + +public class MethodVisitorUtils extends MethodVisitor { + + /**方法的参数的位置,因为asm返回的参数有一些没看懂,所以这边使用这个方式来标记位置*/ + private int paramLocation = 0; + + private Type[] argumentTypes; + + /**需要获取到参数名称的方法*/ + private Method method; + + /**存放参数名称的数组*/ + private String[] parameterNames; + + public MethodVisitorUtils(int i) { + super(i); + } + + public MethodVisitorUtils(int i, MethodVisitor methodVisitor) { + super(i, methodVisitor); + } + + public MethodVisitorUtils(int i, Type[] argumentTypes, Method method, String[] parameterNames) { + super(i); + this.parameterNames = parameterNames; + this.method = method; + this.argumentTypes = argumentTypes; + } + + /**这个方法好像不需要...其实他每次都是new一下这个玩意。*/ + public void resetParamLocation() { + this.paramLocation = 0; + } + + @Override + public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { + + //这里还要注意的就是他比较完 ,全部以后还会去比较 + if (paramLocation > argumentTypes.length - 1) { + return; + } + + //他这里会返回一些奇怪的参数,具体我也不知道为什么,所以这边以我们拿到匹配的参数开始计算 + if (argumentTypes[paramLocation].toString().equals(desc)) { + // 静态方法第一个参数就是方法的参数,如果是实例方法,第一个参数是this + // if (Modifier.isStatic(method.getModifiers())) { + parameterNames[paramLocation] = name; + System.out.println(name); + // } else if (index > 0) { + // parameterNames[paramLocation + 1] = name; + // System.out.println(name); + // } + paramLocation++; + } + } +} diff --git a/src/main/java/util/http/ResponseEntityUtil.java b/src/main/java/util/http/ResponseEntityUtil.java new file mode 100644 index 0000000..401c370 --- /dev/null +++ b/src/main/java/util/http/ResponseEntityUtil.java @@ -0,0 +1,46 @@ + +package util.http; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +/** + * Spring 返回前端对象,主要用于文件下载 + * @author huangzj + */ +public class ResponseEntityUtil { + + public static ResponseEntity getResponseEntity(File file, String fileName) { + HttpHeaders headers = new HttpHeaders(); + headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=\"" + fileName + "\";"); + headers.add(HttpHeaders.EXPIRES, "0"); + headers.add(HttpHeaders.LAST_MODIFIED, new Date().toString()); + headers.add(HttpHeaders.ETAG, String.valueOf(System.currentTimeMillis())); + + return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.APPLICATION_OCTET_STREAM).body(new + FileSystemResource(file)); + } + + + public static String processFileName(HttpServletRequest request, String fileName) throws UnsupportedEncodingException { + //火狐和其他浏览器好像有区别 + if (request.getHeader(HttpHeaders.USER_AGENT).toUpperCase().indexOf("MSIE") > 0) { + fileName = URLEncoder.encode(fileName, "UTF-8"); + } else { + fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO8859-1"); + } + return fileName; + } + + // headers.add("Pragma", "no-cache"); + // headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); +} diff --git a/src/main/java/util/image/CaptchaUtil.java b/src/main/java/util/image/CaptchaUtil.java new file mode 100644 index 0000000..f0990e2 --- /dev/null +++ b/src/main/java/util/image/CaptchaUtil.java @@ -0,0 +1,235 @@ +package util.image; + +import entity.CaptchaItem; +import util.FileUtil; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Random; + +/** + * 验证码生成工具 + * 参考地址:http://blog.csdn.net/ruixue0117/article/details/22829557 + * 参考地址:http://www.iteye.com/topic/573456 + */ +public class CaptchaUtil { + /** + * 验证码处理对象,这边直接采用默认的配置,可以通过set方式进行设置 + */ + private CaptchaItem captchaItem = new CaptchaItem(); + + + /** + * 可支持生成随机验证码 + */ + public String generalCode() { + StringBuilder generalCode = new StringBuilder(); + Random random = new Random(); + for (int i = 0; i < captchaItem.getCodeLength(); i++) { + int position = random.nextInt(captchaItem.getCodeValue().length()-1); + generalCode.append(captchaItem.getCodeValue().charAt(position)); + } + return generalCode.toString(); + } + + /** + * 生成验证码图片.这边可支持自定义的code传入 + * @param imagePath 图片地址 + * @param captchaCode 验证码数值 + */ + public void generateCaptchaImage(String imagePath, String captchaCode){ + File imageFile = FileUtil.createGetFile(imagePath); + if(imageFile == null){ + throw new RuntimeException("文件不存在或者生成失败"); + } + BufferedImage image = generateBufferedImage(captchaCode); + try { + ImageIO.write(image, "jpg", new FileOutputStream(imageFile)); + } catch (IOException e) { + throw new RuntimeException("文件生成失败"); + } + } + + /** + * 生成验证码图片.code按照设定的方式进行处理 + * @param imagePath 图片地址 + */ + public void generateCaptchaImage(String imagePath){ + File imageFile = FileUtil.createGetFile(imagePath); + if(imageFile == null){ + throw new RuntimeException("文件不存在或者生成失败"); + } + BufferedImage image = generateBufferedImage(generalCode()); + try { + ImageIO.write(image, "jpg", new FileOutputStream(imageFile)); + } catch (IOException e) { + throw new RuntimeException("文件生成失败"); + } + } + + + /** + * 设置BufferedImage对象,实现图片流的处理 + */ + private BufferedImage generateBufferedImage(String captchaCode){ + BufferedImage bi = new BufferedImage((int)captchaItem.getWidth(), (int)captchaItem.getHeight() , BufferedImage.TYPE_INT_RGB); + Graphics2D g2 = bi.createGraphics(); + //判断是否生成随机颜色还是通过设置的颜色进行处理 + Color backColor =captchaItem.isBackgroundRandom()? getColor(new Random().nextInt(100), new Random().nextInt(200)+100): getColor(captchaItem.getCaptchaColor(),captchaItem.getCaptchaColor()); + //设置背景色 + setColorTone(g2,backColor); + //设置干扰线 + setVictimLine(g2); + // 添加噪点 + setHotPixel(bi); + // 使图片扭曲 + shear(g2, (int)captchaItem.getWidth(), (int)captchaItem.getHeight(), backColor); + //设置写入文字的属性以及验证码 + setCaptchaCode(g2,captchaCode); + g2.dispose(); + return bi; + } + + private void setCaptchaCode(Graphics2D g2, String captchaCode) { + Color fontColor =captchaItem.isCaptchaColorRandom()? getColor(new Random().nextInt(100), new Random().nextInt(200)+100): getColor(captchaItem.getCaptchaColor(),captchaItem.getCaptchaColor()); + g2.setColor(fontColor); + double fontSize = captchaItem.getHeight() - 4; + g2.setFont(captchaItem.getFont()); + char[] chars = captchaCode.toCharArray(); + + for (int i = 0; i < captchaCode.length(); i++) { + AffineTransform transform = new AffineTransform(); + transform.setToRotation(Math.PI / 4 * new Random().nextDouble() * (new Random().nextBoolean() ? 1 : -1), + (captchaItem.getWidth() / captchaCode.length()) * i + fontSize / 2, captchaItem.getHeight() / 2); + g2.setTransform(transform); + g2.drawChars(chars, i, 1, (int)((captchaItem.getWidth() - 10) / captchaCode.length()) * i + 5, (int)(captchaItem.getHeight() / 2 + fontSize / 2 - 10)); + } + } + + private void setHotPixel(BufferedImage bi) { + Random random = new Random(); + // 噪声率 + float yawpRate = 0.05f; + int area = (int) (yawpRate * captchaItem.getWidth() * captchaItem.getHeight()); + for (int i = 0; i < area; i++) { + int x = random.nextInt((int)captchaItem.getWidth()); + int y = random.nextInt((int)captchaItem.getHeight()); + int rgb = getRandomIntColor(); + bi.setRGB(x, y, rgb); + } + } + + private void setVictimLine(Graphics2D g2) { + //绘制干扰线 设置线条的颜色 + Random random = new Random(); + g2.setColor(getColor(160, 200)); + for (int i = 0; i < 20; i++) { + int x = random.nextInt((int)captchaItem.getWidth() - 1); + int y = random.nextInt((int)captchaItem.getHeight() - 1); + int xl = random.nextInt(6) + 1; + int yl = random.nextInt(12) + 1; + g2.drawLine(x, y, x + xl + 40, y + yl + 20); + } + } + + private void setColorTone(Graphics2D g2,Color backColor) { + //设置色调 + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + // 设置边框色 + g2.setColor(Color.GRAY); + g2.fillRect(0, 0,(int)captchaItem.getWidth(), (int)captchaItem.getHeight() ); + // 设置背景色 + g2.setColor(backColor); + g2.fillRect(0, 2,(int)captchaItem.getWidth(), (int)captchaItem.getHeight() - 4); + } + + private int getRandomIntColor() { + int[] rgb = getRandomRgb(); + int color = 0; + for (int c : rgb) { + color = color << 8; + color = color | c; + } + return color; + } + + private int[] getRandomRgb() { + int[] rgb = new int[3]; + for (int i = 0; i < 3; i++) { + rgb[i] = new Random().nextInt(255); + } + return rgb; + } + + + //图片扭曲 + private void shear(Graphics g, int w1, int h1, Color color) { + shearX(g, w1, h1, color); + shearY(g, w1, h1, color); + } + + private void shearX(Graphics g, int w1, int h1, Color color) { + int period = new Random().nextInt(2); + int frames = 1; + int phase = new Random().nextInt(2); + for (int i = 0; i < h1; i++) { + double d = (double) (period >> 1) + * Math.sin((double) i / (double) period + + (6.2831853071795862D * (double) phase) + / (double) frames); + g.copyArea(0, i, w1, 1, (int) d, 0); + g.setColor(color); + g.drawLine((int) d, i, 0, i); + g.drawLine((int) d + w1, i, w1, i); + } + } + + private void shearY(Graphics g, int w1, int h1, Color color) { + int period = new Random().nextInt(40) + 10; + int frames = 20; + int phase = 7; + for (int i = 0; i < w1; i++) { + double d = (double) (period >> 1) + * Math.sin((double) i / (double) period + + (6.2831853071795862D * (double) phase) + / (double) frames); + g.copyArea(i, 0, 1, h1, 0, (int) d); + g.setColor(color); + g.drawLine(i, (int) d, i, 0); + g.drawLine(i, (int) d + h1, i, h1); + } + } + + /** + * 生成随机背景颜色 + */ + private Color getColor(int fc, int bc) { + if (fc > 255){ + fc = 254; + } + if (bc > 255){ + bc = 255; + } + int r = fc + new Random().nextInt(bc - fc); + int g = fc + new Random().nextInt(bc - fc); + int b = fc + new Random().nextInt(bc - fc); + return new Color(r, g, b); + } + + + /** + * -------------------------------对验证码对象进行查看和设置值---------------------- + */ + public CaptchaItem getCaptchaItem() { + return captchaItem; + } + + public void setCaptchaItem(CaptchaItem captchaItem1) { + captchaItem = captchaItem1; + } +} diff --git a/src/main/java/util/image/PicturesCompressUtil.java b/src/main/java/util/image/PicturesCompressUtil.java new file mode 100644 index 0000000..f206e90 --- /dev/null +++ b/src/main/java/util/image/PicturesCompressUtil.java @@ -0,0 +1,28 @@ +package util.image; + +import net.coobird.thumbnailator.Thumbnails; +import util.FileUtil; + +import java.io.IOException; + +public class PicturesCompressUtil { + /** + * 设置压缩之后的图片比例(默认比例是50%) + */ + private float scale = (float)0.5; + + public float getScale() { + return scale; + } + + public void setScale(float scale) { + this.scale = scale; + } + + public void compress(String srcPath, String desPath) throws IOException { + if ( !FileUtil.fileExist(srcPath)){ + throw new RuntimeException("文件路径不存在"); + } + Thumbnails.of(srcPath).scale(scale).toFile(desPath); + } +} diff --git a/src/main/java/util/image/QRCodeUtil.java b/src/main/java/util/image/QRCodeUtil.java new file mode 100644 index 0000000..f42ab5d --- /dev/null +++ b/src/main/java/util/image/QRCodeUtil.java @@ -0,0 +1,131 @@ +package util.image; + +import com.google.zxing.BarcodeFormat; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import entity.QRCodeItem; +import org.apache.commons.lang3.StringUtils; +import util.FileUtil; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +/** + * @author 黄志军 + * 二维码生成工具 + * 参考地址:http://blog.csdn.net/fly_to_the_winds/article/details/62042142 + */ +public class QRCodeUtil { + + private QRCodeItem qrCodeItem = new QRCodeItem(); + + /** + * 生成一个最原始的二维码图片对象,后面的方法可以用于自由组合或者直接该方法输出图片 + */ + public BufferedImage createQrCodeImage(){ + BufferedImage image; + try { + MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); + //这边如果内容为""或者为空会报错,如果没有内容用" "给他 + String content = StringUtils.isBlank(qrCodeItem.getContent())?" ":qrCodeItem.getContent(); + // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数 (这边会设置参数但是如果不调用logo和content相关的代码,依然不会生成对应的图片和文字) + BitMatrix bm = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeItem.getWidth(), qrCodeItem.getHeight(), qrCodeItem.getHints()); + int w = bm.getWidth(); + int h = bm.getHeight(); + image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色 + for (int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + image.setRGB(x, y, bm.get(x, y) ? qrCodeItem.getStripeColor().getRGB() : qrCodeItem.getBackgroundColor().getRGB()); + } + } + } catch (WriterException e) { + throw new RuntimeException("生成BufferedImage失败"); + } + return image; + } + + + /** + * 通过BufferedImage进行logo绘制,这边返回一个携带logo信息的BufferedImage对象 + */ + public BufferedImage drawLogo(BufferedImage image){ + try { + Graphics2D g2 = image.createGraphics(); + //logo + File logoPic = new File(qrCodeItem.getLogoPath()); + BufferedImage logo = ImageIO.read(logoPic); + //设置logo大小 + int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null), + heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null); + //开始绘制图片 + if (qrCodeItem.isDiyLogoPosition()){ + g2.drawImage(logo, qrCodeItem.getLogoX(),qrCodeItem.getLogoY() ,widthLogo, heightLogo, null); + }else{ + g2.drawImage(logo, (image.getWidth() - widthLogo) / 2, (image.getHeight() - heightLogo) / 2, widthLogo, heightLogo, null); + } + g2.dispose(); + logo.flush(); + return image; + } catch (IOException e) { + throw new RuntimeException("画logo失败了"); + } + } + + /** + * 通过BufferedImage进行内容的绘制,这边返回一个携带内容的BufferedImage对象 + * 这边只是提供一个简单的模板写法,如果需要根据文字内容进行自适应需要修改这么方法的写法 + */ + public BufferedImage drawContent(BufferedImage image){ + BufferedImage image1 = null; + //在文字内容不为空的情况下进行处理 + if(StringUtils.isNotBlank(qrCodeItem.getContent())){ + //生成新的画板 + image1 = new BufferedImage(qrCodeItem.getWidth(),qrCodeItem.getHeight(),BufferedImage.TYPE_4BYTE_ABGR); + Graphics2D g2 = image1.createGraphics(); + //将二维码画在新画板上 + g2.drawImage(image,0,0, qrCodeItem.getWidth(),qrCodeItem.getHeight(),null); + //设置画笔信息 + g2.setColor(qrCodeItem.getContentColor()); + g2.setFont(qrCodeItem.getContentFont()); + //这里不判断文字的长度,只设置书写一行的文字。 + if(qrCodeItem.isDiyContentPosition()){ + g2.drawString(qrCodeItem.getContent(),qrCodeItem.getContentX(),qrCodeItem.getContentY()); + }else{ + int strWidth = g2.getFontMetrics().stringWidth(qrCodeItem.getContent()); + g2.drawString(qrCodeItem.getContent(),(qrCodeItem.getWidth()-strWidth)/2,image.getHeight()-g2.getFont().getSize() -10); + } + g2.dispose(); + image1.flush(); + } + return image1==null? image : image1; + } + + public void createQrCodeWithImage(String filePath, BufferedImage image){ + File file = FileUtil.createGetFile(filePath); + if (file == null){ + throw new RuntimeException("文件不存在或者创建失败"); + } + try { + ImageIO.write(image,qrCodeItem.getSuffix(),file); + } catch (IOException e) { + throw new RuntimeException("文件创建失败"); + } + } + + + /** + * -------------------------------对二维码对象进行查看和设置值---------------------- + */ + public QRCodeItem getQrCodeItem() { + return qrCodeItem; + } + + public void setQrCodeItem(QRCodeItem qrCodeItem) { + this.qrCodeItem = qrCodeItem; + } +} diff --git a/src/main/java/util/itext/FillTemplateHelper.java b/src/main/java/util/itext/FillTemplateHelper.java new file mode 100644 index 0000000..aa2e29f --- /dev/null +++ b/src/main/java/util/itext/FillTemplateHelper.java @@ -0,0 +1,196 @@ +/* + * @(#) FillTemplateHelper + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-11-13 20:19:49 + */ + +package util.itext; + +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.*; +import com.itextpdf.tool.xml.ElementList; +import com.itextpdf.tool.xml.XMLWorker; +import com.itextpdf.tool.xml.XMLWorkerHelper; +import com.itextpdf.tool.xml.css.CssFile; +import com.itextpdf.tool.xml.css.StyleAttrCSSResolver; +import com.itextpdf.tool.xml.html.TagProcessorFactory; +import com.itextpdf.tool.xml.parser.XMLParser; +import com.itextpdf.tool.xml.pipeline.css.CSSResolver; +import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline; +import com.itextpdf.tool.xml.pipeline.end.ElementHandlerPipeline; +import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline; +import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; + +/** + * @author iText + */ +public class FillTemplateHelper extends PdfPageEventHelper { + + // initialized in constructor + protected PdfReader reader; + protected Rectangle pageSize; + protected Rectangle body; + protected float mLeft, mRight, mTop, mBottom; + protected Rectangle to; + protected Rectangle from; + protected Rectangle date; + protected Rectangle footer; + protected BaseFont basefont; + protected Font font; + // initialized with setter + protected String sender = ""; + protected String receiver = ""; + // initialized upon opening the document + protected PdfTemplate background; + protected PdfTemplate total; + + public FillTemplateHelper(String stationery) throws IOException, DocumentException { + reader = new PdfReader(stationery); + AcroFields fields = reader.getAcroFields(); + pageSize = reader.getPageSize(1); + body = fields.getFieldPositions("body").get(0).position; + mLeft = body.getLeft() - pageSize.getLeft(); + mRight = pageSize.getRight() - body.getRight(); + mTop = pageSize.getTop() - body.getTop(); + mBottom = body.getBottom() - pageSize.getBottom(); + footer = fields.getFieldPositions("footer").get(0).position; + basefont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); + font = new Font(basefont, 12); + + } + + public static ElementList parseHtml(String content, String style, TagProcessorFactory tagProcessors) throws IOException { + // CSS + CSSResolver cssResolver = new StyleAttrCSSResolver(); + CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream(style)); + cssResolver.addCss(cssFile); + // HTML + HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); + htmlContext.setTagFactory(tagProcessors); + htmlContext.autoBookmark(false); + // Pipelines + ElementList elements = new ElementList(); + ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null); + HtmlPipeline html = new HtmlPipeline(htmlContext, end); + CssResolverPipeline css = new CssResolverPipeline(cssResolver, html); + // XML Worker + XMLWorker worker = new XMLWorker(css, true); + XMLParser p = new XMLParser(worker); + p.parse(new FileInputStream(content), Charset.forName("utf8")); + return elements; + } + + public static ElementList parseHtmlContent(String content, String style, TagProcessorFactory tagProcessors) throws IOException { + // CSS + CSSResolver cssResolver = new StyleAttrCSSResolver(); + CssFile cssFile = XMLWorkerHelper.getCSS(new FileInputStream(style)); + cssResolver.addCss(cssFile); + // HTML + HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); + htmlContext.setTagFactory(tagProcessors); + htmlContext.autoBookmark(false); + // Pipelines + ElementList elements = new ElementList(); + ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null); + HtmlPipeline html = new HtmlPipeline(htmlContext, end); + CssResolverPipeline css = new CssResolverPipeline(cssResolver, html); + // XML Worker + XMLWorker worker = new XMLWorker(css, true); + XMLParser p = new XMLParser(worker); + try { + p.parse(getStringStream(content), Charset.forName("utf8")); + } catch (Exception e) { + e.printStackTrace(); + } + return elements; + } + + public static InputStream getStringStream(String sInputString) { + if (sInputString != null && !sInputString.trim().equals("")) { + try { + ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(sInputString.getBytes("UTF-8")); + return tInputStringStream; + } catch (Exception ex) { + ex.printStackTrace(); + } + } + return null; + } + + public void setSender(String sender) { + this.sender = sender; + } + + public void setReceiver(String receiver) { + this.receiver = receiver; + } + + public Rectangle getPageSize() { + return pageSize; + } + + public float getmLeft() { + return mLeft; + } + + public float getmRight() { + return mRight; + } + + public float getmTop() { + return mTop; + } + + public float getmBottom() { + return mBottom; + } + + public Rectangle getBody() { + return body; + } + + @Override + public void onOpenDocument(PdfWriter writer, Document document) { + background = writer.getImportedPage(reader, 1); + total = writer.getDirectContent().createTemplate(30, 15); + } + + @Override + public void onEndPage(PdfWriter writer, Document document) { + PdfContentByte canvas = writer.getDirectContentUnder(); + // background + canvas.addTemplate(background, 0, 0); + try { + ColumnText ct = new ColumnText(canvas); + ct.setSimpleColumn(footer); + ct.addText(new Chunk(" " + writer.getPageNumber(), font)); + ct.addText(new Chunk(Image.getInstance(total), 0, 0)); + ct.go(); + } catch (DocumentException e) { + // can never happen, but if it does, we want to know! + throw new ExceptionConverter(e); + + } + } + + @Override + public void onCloseDocument(PdfWriter writer, Document document) { + // 关闭时可以知道总页数,写入页码 + String s = "/ " + (writer.getPageNumber()); + Phrase p = new Phrase(12, s, font); + ColumnText.showTextAligned(total, Element.ALIGN_LEFT, p, 0.5f, 0, 0); + } + + +} \ No newline at end of file diff --git a/src/main/java/util/itext/PDFUtils.java b/src/main/java/util/itext/PDFUtils.java new file mode 100644 index 0000000..ba55ab0 --- /dev/null +++ b/src/main/java/util/itext/PDFUtils.java @@ -0,0 +1,175 @@ + + +package util.itext; + +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.*; +import com.itextpdf.tool.xml.ElementList; +import com.itextpdf.tool.xml.html.Tags; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by huangzhijun on 2017/8/22. + * itext 用于生成pdf的工具类 + */ +public class PDFUtils { + /** + * 通过模板生成pdf文件 + * + * @param templatePath 模板路径 + * @param resultPath 生成路径 + * @param cssPath css路径 + * @param content 生成pdf的内容 + * @throws Exception + */ + public static void generalPDF(String templatePath, String resultPath, String cssPath, String content) throws Exception { + // 读取模板 + FillTemplateHelper template = new FillTemplateHelper(templatePath); + Document document = new Document(template.getPageSize(), + template.getmLeft(), template.getmRight(), template.getmTop(), template.getmBottom()); + // 创建pdf写对象 + PdfWriter writer = null; + FileOutputStream outputStream = new FileOutputStream(resultPath); + try { + writer = PdfWriter.getInstance(document, outputStream); + } catch (Exception e) { + e.printStackTrace(); + } + writer.setPageEvent(template); + //打开文件 + document.open(); + // 填充数据到文件中 + ElementList elements = FillTemplateHelper.parseHtmlContent(content, cssPath, Tags.getHtmlTagProcessorFactory()); + for (Element e : elements) { + document.add(e); + } + writer.setPageEmpty(false); + //关闭流操作 + document.close(); + writer.close(); + outputStream.close(); + } + + /** + * PDF盖章操作 + * 在PDF文档的最后一页盖章 + * @param RES 需要盖章的pdf文件地址 + * @param DEST 生成的新pdf文件地址 + * @param SEAL 印章图片的地址 + * @param company 落款名称及部门 + * @param dateName 落款时间名称 + * @throws DocumentException + * @throws IOException + */ + public static void sealDocument(String RES, String DEST, String SEAL, String company, String dateName, String time) throws DocumentException, IOException { + + PdfReader reader = new PdfReader(RES); + int numberOfPages = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + Document doc = new Document(pageSize); + PdfWriter writer_ = PdfWriter.getInstance(doc, new FileOutputStream(DEST)); + // 打开文档 + doc.open(); + PdfContentByte cb = writer_.getDirectContent(); + for (int i = 0; i < numberOfPages; ) { + { + i++; + //设置指定页的PagSize 包含Rotation(页面旋转度) +// doc.setPageSize(reader.getPageSizeWithRotation(i)); + //创建一个新的页面,需要注意的调用NewPage() ,PdfContentByte cb 对象会默认清空 + doc.newPage(); +// //获取指定页面的旋转度 +// int rotation = reader.getPageRotation(i); + //获取加载PDF的指定页内容 + PdfImportedPage page1 = writer_.getImportedPage(reader, i); + + //添加内容页到新的页面,并更加旋转度设置对应的旋转 + /* switch (rotation) { + case 90: + cb.addTemplate(page1, 0, -1, 1, 0, 0, reader.getPageSizeWithRotation(i).getHeight()); + break; + case 180: + cb.addTemplate(page1, -1, 0, 0, -1, reader.getPageSizeWithRotation(i).getWidth(), reader.getPageSizeWithRotation(i).getHeight()); + break; + case 270: + cb.addTemplate(page1, 0, 1, -1, 0, reader.getPageSizeWithRotation(i).getWidth(), 0); + break; + default: + cb.addTemplate(page1, 1, 0, 0, 1, 0, 0);//等同于 cb.AddTemplate(page1, 0,0) + break; + }*/ + cb.addTemplate(page1, 0, 0); + + if (i == numberOfPages)//如果是最后一页加入指定的图片 + { + //创建一个图片对象 + Image img = Image.getInstance(SEAL); + //设置图片的指定大小 + //img.ScaleToFit(140F, 320F); + //按比例缩放 + img.scalePercent(100); + BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", com.itextpdf.text.pdf.BaseFont.NOT_EMBEDDED); + cb.beginText(); + //设置字体 大小 + cb.setFontAndSize(bf, 13); + //指定添加文字的绝对位置 + cb.setTextMatrix(350, 75); + //增加文本 + cb.showText(company); + //结束 + cb.endText(); + cb.beginText(); + //设置字体 大小 + cb.setFontAndSize(bf, 13); + //指定添加文字的绝对位置 + cb.setTextMatrix(350, 55); + if (org.apache.commons.lang3.StringUtils.isBlank(time)) { + Date date = new Date(); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + time = format.format(date); + } + //增加文本 + cb.showText(dateName + ":" + time); + //结束 + cb.endText(); + //把图片增加到内容页的指定位子 b width c height e bottom f left +// use addImage(image, image_width, 0, 0, image_height, x, y) + cb.addImage(img, 130, 0, 0, 130, 400, 55); + } + } + } + System.out.println("盖章成功"); + doc.close(); + writer_.close(); + reader.close(); + + } + + /** + * 将页面传过来的内容重新组装为html + * @param content + * @return + */ + public String transToHtml(String content) { + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append(""); + sb.append("

"); + sb.append("
"); + sb.append(content); + sb.append("
"); + sb.append("
"); + sb.append(""); + sb.append(""); + return sb.toString(); + } + + +} diff --git a/src/main/java/util/redis/RedisUtil.java b/src/main/java/util/redis/RedisUtil.java new file mode 100644 index 0000000..784992c --- /dev/null +++ b/src/main/java/util/redis/RedisUtil.java @@ -0,0 +1,527 @@ + +package util.redis; + +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +/** + * 网上copy的别人写的redis的工具 + * @author QLQ + * 基于spring和redis的redisTemplate工具类 + * 针对所有的hash 都是以h开头的方法 + * 针对所有的Set 都是以s开头的方法 不含通用方法 + * 针对所有的List 都是以l开头的方法 + */ +public class RedisUtil { + + private RedisTemplate redisTemplate; + + public void setRedisTemplate(RedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + //=============================common============================ + + /** + * 指定缓存失效时间 + * @param key 键 + * @param time 时间(秒) + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key 获取过期时间 + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + redisTemplate.delete(CollectionUtils.arrayToList(key)); + } + } + } + + //============================String============================= + + /** + * 普通缓存获取 + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + /** + * 普通缓存放入并设置时间 + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 + * @param key 键 + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * @param key 键 + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + //================================Map================================= + + /** + * HashGet + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + //============================set============================= + + /** + * 根据key获取Set中的所有值 + * @param key 键 + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0){ + expire(key, time); + } + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 + * @param key 键 + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + //===============================list================================= + + /** + * 获取list缓存的内容 + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 + * @param key 键 + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + * @param time 时间(秒) + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * @param key 键 + * @param value 值 + * @param time 时间(秒) + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * @param key 键 + * @param index 索引 + * @param value 值 + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + +} \ No newline at end of file diff --git a/src/main/java/util/time/DateTimeUtil.java b/src/main/java/util/time/DateTimeUtil.java new file mode 100644 index 0000000..0c75cdb --- /dev/null +++ b/src/main/java/util/time/DateTimeUtil.java @@ -0,0 +1,210 @@ + +package util.time; + + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.TimeZone; + +import static additive.ValidTool.assertIsTrue; + +public class DateTimeUtil { + + private static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd"; + private static final String DEFAULT_TIME_PATTERN = "HH:mm:ss"; + private static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss"; + private static final String DEFAULT_PATTERN_CLOSE = "yyyyMMddHHmmss"; + private static final String DATE_TIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm"; + private static final String ISO_8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ"; + private static final String lO_G_PARAM_TIME_PATTERN = "yyyy-MM-dd-HHmm"; + + + /** + * 获取当天日期,"yyyy-MM-dd" + */ + public static String getCurrentDate() { + return LocalDate.now().toString(); + } + + /** + * 获取当前时间,yyyy-MM-dd HH:mm:ss + */ + public static String getCurrentDateTime() { + return LocalDateTime.now().format(DateTimeFormatter.ofPattern(DEFAULT_PATTERN)); + } + + + /** + * 获取与所给日期间隔要求天数的日期 + * @param localDate 参考日期, yyyy-MM-dd + * @param dayOffset 间隔天数 + */ + public static String plusDay(final String localDate, final int dayOffset) { + assertIsTrue(dayOffset >= 0, "偏移量必须大于0"); + return LocalDate.parse(localDate).plusDays(dayOffset).format(DateTimeFormatter.ISO_LOCAL_DATE); + } + + /** + * 获取与所给日期间隔要求天数的日期 + * @param localDate 参考日期, yyyy-MM-dd + * @param dayOffset 间隔天数 + */ + public static String minusDay(final String localDate, final int dayOffset) { + assertIsTrue(dayOffset >= 0, "偏移量必须大于0"); + return LocalDate.parse(localDate).minusDays(dayOffset).format(DateTimeFormatter.ISO_LOCAL_DATE); + } + + + /** + * 将日期时间转换成指定格式的时间 + */ + public static String dateToString(String pattern, LocalDateTime dateTime) { + return DateTimeFormatter.ofPattern(pattern).format(dateTime); + } + + /** + * 时间戳转换为指定格式字符串(秒) + */ + public static String dateToString(String pattern, long epochSecond, TimeZone timeZone) { + return dateToString(pattern, LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), timeZone.toZoneId())); + } + + + /** + * 时间戳转成指定格式字符串(毫秒) + */ + public static String timestampToString(String pattern, long timestamp, TimeZone timeZone) { + return dateToString(pattern, LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), timeZone.toZoneId())); + } + + public static String dateToString(String pattern, ZonedDateTime dateTime) { + return DateTimeFormatter.ofPattern(pattern) + .format(dateTime); + } + + /** + * 将LocalDateTime转换成指定格式字符串 + */ + public static String localTimeToString(LocalDateTime localDateTime, String pattern) { + LocalTime localTime = localDateTime.toLocalTime(); + return DateTimeFormatter.ofPattern(pattern).format(localTime); + } + + /** + * 将时间格式换成"HH:mm:ss" 格式 + */ + public static String formatDateToTime(LocalDateTime date) { + return DateTimeUtil.dateToString(DEFAULT_TIME_PATTERN, date); + } + + /** + * 将时间格式换成"yyyy-MM-dd" 格式 + */ + public static String formatDateToDay(LocalDateTime date) { + return DateTimeUtil.dateToString(DEFAULT_DATE_PATTERN, date); + } + + /** + * @param timeString yyyy-MM-dd-HHmm + * @return yyyy-MM-dd HH:mm 格式的时间字符串 + */ + public static String paramTimeFormat(String timeString) throws ParseException { + Date newDate = new SimpleDateFormat(lO_G_PARAM_TIME_PATTERN).parse(timeString); + return new SimpleDateFormat(DATE_TIME_MINUTE_PATTERN).format(newDate); + } + + + /** + * 获取当前时间,yyyy-MM-dd HH:mm:ss + * 注意:使用当前系统默认的时区 + */ + public static LocalDateTime getNow() { + return LocalDateTime.now(); + } + + /** + * 将时间戳(单位:毫秒)转成 LocalDateTime + */ + public static LocalDateTime timeStampToLocalDateTime(long timeStamp) { + return Instant.ofEpochMilli(timeStamp).atZone(ZoneId.systemDefault()).toLocalDateTime(); + } + + /** + * 将时间戳(单位为:秒)转成 LocalDateTime + */ + public static LocalDateTime epochSecondToLocalDateTime(long epochSecond, TimeZone timeZone) { + return epochSecondToLocalDateTime(epochSecond, timeZone.toZoneId()); + } + + + /** + * 将时间戳(单位为:秒)转成 LocalDateTime + */ + public static LocalDateTime epochSecondToLocalDateTime(long epochSecond, ZoneId zoneId) { + return Instant.ofEpochSecond(epochSecond).atZone(zoneId).toLocalDateTime(); + } + + /** + * LocalDateTime转成时间戳:毫秒 + */ + public static long toEpochMilli(LocalDateTime localDateTime, TimeZone timeZone) { + return Instant.from(localDateTime.atZone(timeZone.toZoneId())).toEpochMilli(); + } + + /** + * 将字符串转换为LocalDateTime + */ + public static LocalDateTime stringToLocalDateTime(String dateStr, String pattern) { + DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); + return LocalDateTime.parse(dateStr, df); + } + + + /** + * 到天的字符串,转成LocalDateTime + * @param dayStr 如"2017-11-16" + * @return 返回0点0分0秒的时间 如 "2017-11-16 00:00:00" + */ + public static LocalDateTime dayStringToLocalDateTime(String dayStr) { + return LocalDate.parse(dayStr, DateTimeFormatter.ofPattern(DEFAULT_DATE_PATTERN)).atTime(0, 0, 0); + } + + /** + * LocalDateTime转成时间戳:秒 + */ + public static long toEpochSecond(LocalDateTime localDateTime, TimeZone timeZone) { + return Instant.from(localDateTime.atZone(timeZone.toZoneId())).getEpochSecond(); + } + + + public static long toEpochSecond(LocalDateTime localDateTime, ZoneId zoneId) { + return localDateTime.atZone(zoneId).toEpochSecond(); + } + + + /** + * 获取当前时间的秒数 + */ + public static long getNowSeconds(){ + return + LocalDateTime.now().toEpochSecond(ZoneOffset.MAX); + } + + /** + * 是否同一个时间点 + */ + public static boolean isTheSameDay(LocalDateTime startDate, LocalDateTime endDate) { + return startDate.toLocalDate() + .isEqual(endDate.toLocalDate()); + } + + /** + * LocalDateTime 转成时间戳 + */ + public static Instant toInstant(LocalDateTime endDate, TimeZone timeZone) { + return endDate.atZone(timeZone.toZoneId()).toInstant(); + } +} diff --git a/src/main/java/util/time/FillFullTimeValueUtil.java b/src/main/java/util/time/FillFullTimeValueUtil.java new file mode 100644 index 0000000..4eff825 --- /dev/null +++ b/src/main/java/util/time/FillFullTimeValueUtil.java @@ -0,0 +1,119 @@ + + +package util.time; + +import com.google.common.collect.Lists; +import entity.OriginTimeValue; +import entity.TargetTimeValue; +import org.springframework.util.CollectionUtils; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 补时间点工具类 + * 之前在ws上班的时候,处理图标数据会遇到某些点没有数据的情况,就需要对这些时间点进行补点处理 + * + * @author huangzj + * @date 2018-11-23 22:43:36 + */ +public enum FillFullTimeValueUtil { + /** + * 分钟粒度 + */ + MINUTE { + @Override + public List fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval, + List originTimeValues, TimeZone timeZone) { + //Myview 向前聚合,返回前XX秒为最开始计数时间 + Instant firstInstant = toInstant(startDate, timeZone); + Instant finalInstant = toInstant(endDate, timeZone); + //补时间点--规则一样,间隔转换成秒 + return fullFillRule(originTimeValues, firstInstant, finalInstant, timeInterval * 60); + } + }, + /** + * 小时粒度 + */ + HOUR { + @Override + public List fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval, + List originTimeValues, TimeZone timeZone) { + Instant firstInstant = toInstant(startDate, timeZone); + Instant finalInstant = toInstant(endDate, timeZone); + //补时间点--规则一样 + return fullFillRule(originTimeValues, firstInstant, finalInstant, timeInterval * 60 * 60); + } + }, + /** + * 天粒度 + */ + DAY { + @Override + public List fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval, + List originTimeValues, TimeZone timeZone) { + //区别,把时间转成天 + Instant firstInstant = toInstant(LocalDateTime.of(startDate.toLocalDate(), LocalTime.of(0, 0, 0)), timeZone); + Instant finalInstant = toInstant(LocalDateTime.of(endDate.toLocalDate(), LocalTime.of(0, 0, 0)), timeZone); + //补时间点--规则一样 + return fullFillRule(originTimeValues, firstInstant, finalInstant, timeInterval * 60 * 60 * 24); + } + }; + + + /** + * 抽象方法,实现补充时间点 + * @param startDate 开始时间 格式如:yyyy-MM-dd 00:00:00 + * @param endDate 结束时间:格式如:yyyy-MM-dd 23:59:59 + * @param timeInterval 数据采集粒度,单位:分钟、小时、天 + * @param originTimeValues 缺少时间点对象(统一处理成long、long) + * @param timeZone 时区 + * @return 补时间点后对象,没有补null + */ + public abstract List fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, + int timeInterval, List originTimeValues, TimeZone timeZone); + + + /** + * + * @param dateTime 时间 + * @param timeZone 时区 + * @return Instant,和TimeStamp类似 + */ + private static Instant toInstant(LocalDateTime dateTime, TimeZone timeZone) { + return dateTime.atZone(timeZone.toZoneId()) + .toInstant(); + } + + + private static List fullFillRule(List originTimeValues, Instant firstInstant, Instant finalInstant, + int seconds) { + //转换为Time-value形式的map + if (CollectionUtils.isEmpty(originTimeValues)) { + originTimeValues = Lists.newArrayList(); + } + Map timeValueMap = originTimeValues.stream().collect(Collectors.toMap(OriginTimeValue::getTime, + OriginTimeValue::getValue)); + final List resultList = new ArrayList<>(); + + Instant cursorInstant = firstInstant; + //循环按照时间粒度补充时间点。 + while (cursorInstant.isBefore(finalInstant) || cursorInstant.equals(finalInstant)) { + long epochSecond = cursorInstant.getEpochSecond(); + TargetTimeValue timeValueInRule = new TargetTimeValue(); + timeValueInRule.setValue(timeValueMap.getOrDefault(epochSecond, null)); + timeValueInRule.setTime(epochSecond); + resultList.add(timeValueInRule); + + //移动到下一个数据点 + cursorInstant = cursorInstant.plusSeconds(seconds); + } + //按时间排序,最新的排在最后面 + return resultList.parallelStream() + .sorted(Comparator.comparing(TargetTimeValue::getTime)) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/util/transform/JsonBinder.java b/src/main/java/util/transform/JsonBinder.java new file mode 100644 index 0000000..76d15bb --- /dev/null +++ b/src/main/java/util/transform/JsonBinder.java @@ -0,0 +1,38 @@ +package util.transform; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +import java.io.IOException; + +/** + * @author: 志军 + * @description: json对象转java对象,java对象转json + * @date: 2017/12/25 18:01 + */ +public class JsonBinder { + + + public static T fromJson(String json, Class type) { + try { + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); + return objectMapper.readValue(json, type); + } catch (JsonParseException | JsonMappingException e) { + throw new RuntimeException("JsonParseException | JsonMappingException 错误", e); + } catch (IOException e) { + throw new RuntimeException("IOException 错误", e); + } + } + + public static String toJson(Object object) { + try { + ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json().build(); + return objectMapper.writeValueAsString(object); + } catch (JsonProcessingException e) { + throw new RuntimeException("对象转换为json字符串失败", e); + } + } +} diff --git a/src/main/java/util/transform/XmlBinder.java b/src/main/java/util/transform/XmlBinder.java new file mode 100644 index 0000000..b6371cb --- /dev/null +++ b/src/main/java/util/transform/XmlBinder.java @@ -0,0 +1,108 @@ +package util.transform; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import java.io.*; + +/** + * Xml的转换需要在对象的class上加上@XmlRootElement注释,在属性上加上@XmlElement注释 + * @author 志军 + * {@XmlRootElement(name = "xml") + * @XmlAccessorType(XmlAccessType.FIELD) + * static class JsonObject { + * @XmlElement(name = "x1") + * int x1; + * @XmlElement(name = "x2") + * String x2; + * @XmlElement(name = "x3") + * JsonObject x3; + * get..set... + * } + * + */ +public class XmlBinder { + + + /** + * 将对象转化成xml字符串 + */ + static String convertToXml(Object object) { + //创建输出流 + StringWriter writer = new StringWriter(); + + try { + Marshaller marshaller = getMarshaller(object); + marshaller.marshal(object, writer); + } catch (JAXBException e) { + throw new RuntimeException("解析错误", e); + } + return writer.toString(); + } + + /** + * 将对象转换为xml文件 + */ + static void convertToXml(Object object, String path){ + FileWriter writer; + try { + Marshaller marshaller = getMarshaller(object); + writer = new FileWriter(path); + marshaller.marshal(object,writer); + } catch (JAXBException | IOException e) { + throw new RuntimeException("转换失败",e); + } + } + + /** + * 将字符串形式的xml转化成对象 + */ + @SuppressWarnings("unchecked") + static T convertXmlStrToObject(String xml, Class clazz){ + T xmlObject = null; + try { + Unmarshaller unmarshaller = getUnmarshaller(clazz); + StringReader reader = new StringReader(xml); + xmlObject = (T)unmarshaller.unmarshal(reader); + } catch (JAXBException e) { + throw new RuntimeException("解析错误", e); + } + return xmlObject; + } + + /** + * 从文件中转换出类 + */ + public static Object convertXmlFileToObject(String path,Class clazz){ + try { + Unmarshaller unmarshaller = getUnmarshaller(clazz); + FileReader reader = new FileReader(path); + return unmarshaller.unmarshal(reader); + } catch (JAXBException | FileNotFoundException e) { + throw new RuntimeException("解析错误", e); + } + } + + + /** + * 公共方法 --得到JAXB用于对象转化为xml + */ + private static Marshaller getMarshaller(Object object) throws JAXBException { + //利用java的类生成实例 + JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass()); + Marshaller marshaller = jaxbContext.createMarshaller(); + //格式化xml输出格式 --格式化 + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + marshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8"); + return marshaller; + } + + /** + * 公共方法 --得到JAXB用于xml转化为对象 + */ + private static Unmarshaller getUnmarshaller(Class clazz) throws JAXBException { + JAXBContext context = JAXBContext.newInstance(clazz); + return context.createUnmarshaller(); + } +} diff --git a/src/main/java/util/tree/TreeNode.java b/src/main/java/util/tree/TreeNode.java new file mode 100644 index 0000000..e613d74 --- /dev/null +++ b/src/main/java/util/tree/TreeNode.java @@ -0,0 +1,61 @@ +/* + * @(#) TreeNode + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2019 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2019-01-02 22:24:56 + */ + +package util.tree; + +/** + * 树节点,主要是包含了path和parentCode的通用属性 + * @author 黄志军 + */ +public class TreeNode { + + /** + * 当前节点的标识,code + */ + private String code; + + /** + * 父节点标识 + */ + private String parentCode; + + /** + * 包含所有节点的code,包括自己 + * 比如说该节点为1,父节点为2,爷爷节点为3,网上根节点保存的是4. + * path保存的就是4;3;2;1; + */ + private String path; + + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getParentCode() { + return parentCode; + } + + public void setParentCode(String parentCode) { + this.parentCode = parentCode; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } +} diff --git a/src/main/java/util/tree/TreeNode2.java b/src/main/java/util/tree/TreeNode2.java new file mode 100644 index 0000000..75799ac --- /dev/null +++ b/src/main/java/util/tree/TreeNode2.java @@ -0,0 +1,49 @@ +package util.tree; + +import java.util.List; + +/** + * 这个对象主要用于处理从父推子的一条链路的处理 + * @author 黄志军 + */ +public class TreeNode2 { + + /** + * 当前节点的标识,code + */ + private String code; + + /** + * 父节点标识 + */ + private String parentCode; + + /** + * 子节点对象数组 + */ + private List childNodeList; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getParentCode() { + return parentCode; + } + + public void setParentCode(String parentCode) { + this.parentCode = parentCode; + } + + public List getChildNodeList() { + return childNodeList; + } + + public void setChildNodeList(List childNodeList) { + this.childNodeList = childNodeList; + } +} diff --git a/src/main/java/util/tree/TreeUtils.java b/src/main/java/util/tree/TreeUtils.java new file mode 100644 index 0000000..e576e77 --- /dev/null +++ b/src/main/java/util/tree/TreeUtils.java @@ -0,0 +1,129 @@ +/* + * @(#) TreeUtils + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2019 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2019-01-02 22:24:06 + */ + +package util.tree; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.springframework.util.CollectionUtils; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * 树数据的操作工具 + * 参考SI,兰姐,导入业务(参考ws的业务) + * @author 黄志军 + */ +class TreeUtils { + + private static final String SEMICOLON = ";"; + + /** + * 获取path的值(从根节点到当前节点的路径值),这边这个方法会对对应的code进行path的生成(前提是根节点的parentCode是空,或者用其他的标识也可以) + * + * @param treeNodeList 所有的树节点,因为这个主要是导入业务,所以数据包含文件和数据库中的 + * @param code 节点code + * @return 从根节点到当前节点的路径值 + */ + static String getCodePath(List treeNodeList, String code) { + //对所有的节点进行校验,校验规则是不能存在两个code一样的节点 + validTreeNodeList(treeNodeList); + Map treeNodeMap = Maps.newHashMap(); + //创建 code-节点的键值对关系 + treeNodeList.forEach(treeNode -> treeNodeMap.put(treeNode.getCode(), treeNode)); + //通过 递归函数 获取父节点以上的path关系 + StringBuffer pathStringBuffer = findParentCodes(treeNodeMap, code); + //把父节点code和节点code拼接进去,如果这边本身就不存在这个code,就直接返回空,而不把这个code进行append + if(treeNodeMap.get(code)!=null){ + pathStringBuffer.append(SEMICOLON).append(code).append(SEMICOLON); + } + return pathStringBuffer.toString(); + } + + /** + * + * + * @param treeNodeMap code-节点信息的map + * @param code 节点信息(这个code是作为递归的起点) + * @return 该节点父节点以上的path字符串 + */ + private static StringBuffer findParentCodes(Map treeNodeMap, String code) { + StringBuffer result = new StringBuffer(); + TreeNode treeNode = treeNodeMap.get(code); + //如果当前节点不为空。往下查找他的父节点 + if (treeNode != null) { + TreeNode parentTreeNode = treeNodeMap.get(treeNode.getParentCode()); + //如果父节点不为空 + if (parentTreeNode != null) { + //把父节点的code插入到最前面。 + result.insert(0, SEMICOLON + parentTreeNode.getCode()); + //通过递归,把父节点上面的节点找出来 + result.insert(0, findParentCodes(treeNodeMap, parentTreeNode.getCode())); + } else { + return result; + } + } + //直到当前节点为空,返回拼接的字符串 + return result; + } + + + static TreeNode2 getTreeWithChildNodeList(List treeNodeList ,String code){ + TreeNode2 destNode = validTreeNode2List(treeNodeList,code); + if (destNode == null ){ + return null; + } + Map> treeNodeMap = Maps.newHashMap(); + //创建 父code-节点的键值对关系 + treeNodeList.forEach(treeNode -> { + List list = treeNodeMap.get(treeNode.getParentCode()); + if (list == null ){ + list = Lists.newArrayList(); + } + list.add(treeNode); + treeNodeMap.put(treeNode.getParentCode(),list); + }); + //通过 递归函数 获取父节点以上的path关系 + destNode.setChildNodeList(getChildNodeList(treeNodeMap,code)); + return destNode; + } + + private static List getChildNodeList( Map> treeNodeMap, String code) { + List list = treeNodeMap.get(code); + if( list == null || CollectionUtils.isEmpty(list)){ + return null; + } + for(TreeNode2 treeNode2:list){ + treeNode2.setChildNodeList(getChildNodeList(treeNodeMap,treeNode2.getCode())); + } + + return list; + } + + + private static void validTreeNodeList(List treeNodeList){ + List codeList = treeNodeList.stream().map(TreeNode::getCode).distinct().collect(Collectors.toList()); + if(codeList.size() != treeNodeList.size()){ + throw new RuntimeException("存在相同的code"); + } + } + + private static TreeNode2 validTreeNode2List(List treeNodeList,String code){ + List codeList = treeNodeList.stream().map(TreeNode2::getCode).distinct().collect(Collectors.toList()); + if(codeList.size() != treeNodeList.size()){ + throw new RuntimeException("存在相同的code"); + } + List list = treeNodeList.stream().filter(item->item.getCode().equals(code)).collect(Collectors.toList()); + return CollectionUtils.isEmpty(list) ?null:list.get(0); + } +} diff --git a/src/main/java/util/zip/PrintTool.java b/src/main/java/util/zip/PrintTool.java new file mode 100644 index 0000000..02242d7 --- /dev/null +++ b/src/main/java/util/zip/PrintTool.java @@ -0,0 +1,21 @@ +package util.zip; + +import org.springframework.util.StopWatch; + +import java.io.File; + +class PrintTool { + + static void calculateTimeAndLength(File[] files, StopWatch stopWatch, File resultFile){ + //计算一下文件的大小 + double length = 0.0000; + + for (File file : files) { + length = length + file.length(); + } + + System.out.println( + "文件大小:" + length / 1024.00 / 1024.00 + "M,转换时间:" + stopWatch.getTotalTimeMillis() / 1000.000 + " s," + "压缩后文件大小:" + resultFile + .length() / 1024.00 / 1024.00 + " M"); + } +} diff --git a/src/main/java/util/zip/TarArchiveGZIPOutputUtil.java b/src/main/java/util/zip/TarArchiveGZIPOutputUtil.java new file mode 100644 index 0000000..6493dd6 --- /dev/null +++ b/src/main/java/util/zip/TarArchiveGZIPOutputUtil.java @@ -0,0 +1,193 @@ +package util.zip; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.utils.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StopWatch; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.zip.GZIPOutputStream; + +import static util.zip.PrintTool.calculateTimeAndLength; + +/** + * 总体思路 + * 1.将文件列表传入,通过tarArchiveOutputStream打包 + * 2.将tarArchiveOutputStream打包的文件,通过GZIPOutputStream进行压缩 + * + * @author selfImpr + * 参考地址:https://www.cnblogs.com/guochunyi/p/5311261.html + */ +public class TarArchiveGZIPOutputUtil { + + /** + * 设定读入缓冲区尺寸 + */ + private static final byte[] BUF = new byte[1024]; + + private static final int BUF_SIZE = 1024; + + private static final Logger LOGGER = LoggerFactory.getLogger(TarArchiveGZIPOutputUtil.class); + + private static final String GZ_SUFFIX = ".gz"; + + + /** + * 根据传入的文件夹位置,打包对应的所有文件 + * @param dirPath 文件夹位置 + * @param zipFilePath 生成gz文件的位置 + * @return .tar.gz文件 + * @throws IOException io异常 + */ + static File compress(String dirPath, String zipFilePath) throws IOException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + File dir = new File(dirPath); + if (dir.exists() && dir.isDirectory()) { + //遍历文件夹的所有文件 + File[] files = dir.listFiles(); + assert files != null; + return compress(Arrays.asList(files), zipFilePath); + } + return null; + } + + /** + * 压缩成gzip格式,最后的文件格式为 tar.gz + * + * @param files 文件 + * @param tarPath 存储位置 + * @throws IOException Io异常 + * @return tar.gz结尾的文件 + */ + static File compress(List files, String tarPath) throws IOException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + //先进行打包 + packToTar(tarPath, files); + //在进行压缩 + File file = compressToGz(tarPath); + stopWatch.stop(); + + //输出文件大小和运行时间 + calculateTimeAndLength(files.toArray(new File[]{}),stopWatch,file); + return file; + } + + /** + * 只打包成tar文件,最后的格式为.tar + * + * @param files 文件 + * @param tarPath 存储位置 + * @throws IOException Io异常 + * @return tar结尾的文件 + */ + static File compressToTar(List files, String tarPath) throws IOException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + //先进行打包 + File file = packToTar(tarPath, files); + stopWatch.stop(); + //输出文件大小和运行时间 + calculateTimeAndLength(files.toArray(new File[]{}),stopWatch,file); + return file; + } + + /** + * 根据地址找到所有的文件进行打包 + * @param dirPath 文件夹位置 + * @param tarFilePath 生成tar文件位置 + * @return .tar文件 + * @throws IOException io异常 + */ + static File compressToTar(String dirPath, String tarFilePath) throws IOException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + File dir = new File(dirPath); + if (dir.exists() && dir.isDirectory()) { + //遍历文件夹的所有文件 + File[] files = dir.listFiles(); + assert files != null; + return compressToTar(Arrays.asList(files), tarFilePath); + } + return null; + } + + /** + * 打包成tar格式 + * + * @param tarPath 存储位置 这边传入的存储地址必须是.tar结尾的才会被转换成对应的格式,否则转换出来需要自己去重命名 + * @param files 文件 + * @throws IOException io异常 + * @return 返回打包对应的文件对象 + */ + private static File packToTar(String tarPath, List files) throws IOException { + //建立压缩文件输出流 + FileOutputStream fileOutputStream = new FileOutputStream(tarPath); + TarArchiveOutputStream tarArchiveOutputStream = new TarArchiveOutputStream(fileOutputStream); + FileInputStream fin = null; + try { + //建立tar压缩输出流 + for (File file : files) { + //打开需压缩文件作为文件输入流 + fin = new FileInputStream(file); + TarArchiveEntry tarEn = new TarArchiveEntry(file); + //此处需重置名称,默认是带全路径的,否则打包后会带全路径 + tarEn.setName(file.getName()); + tarArchiveOutputStream.putArchiveEntry(tarEn); + //IOUtils只是写入 + IOUtils.copy(fin, tarArchiveOutputStream); + tarArchiveOutputStream.closeArchiveEntry(); + fin.close(); + } + tarArchiveOutputStream.close(); + return new File(tarPath); + } catch (IOException ex) { + LOGGER.info("", ex); + } finally { + if (fin != null) { + fin.close(); + } + fileOutputStream.close(); + } + return null; + } + + /** + * 压缩成GZIP格式 + * + * @param tarPath 压缩路径 + * @throws IOException 压缩失败,文件路径找不到 + */ + private static File compressToGz(String tarPath) throws IOException { + //建立压缩文件输出流 + String zipPath = tarPath + GZ_SUFFIX; + FileOutputStream gzFileOutputStream = new FileOutputStream(zipPath); + GZIPOutputStream gzipOutputStream = new GZIPOutputStream(gzFileOutputStream); + FileInputStream tarFileInputStream = new FileInputStream(tarPath); + try { + //建立gzip压缩输出流,这个不能使用IOUtils的copy,可以具体看一下方法 + int len; + while ((len = tarFileInputStream.read(BUF, 0, BUF_SIZE)) != -1) { + gzipOutputStream.write(BUF, 0, len); + } + gzipOutputStream.close(); + return new File(zipPath); + } catch (IOException e) { + LOGGER.info("e"); + } finally { + gzFileOutputStream.close(); + tarFileInputStream.close(); + } + return null; + } +} diff --git a/src/main/java/util/zip/ZipOutputUtil.java b/src/main/java/util/zip/ZipOutputUtil.java new file mode 100644 index 0000000..7dba2a1 --- /dev/null +++ b/src/main/java/util/zip/ZipOutputUtil.java @@ -0,0 +1,68 @@ + + +package util.zip; + +import org.apache.commons.compress.utils.IOUtils; +import org.springframework.util.StopWatch; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import static util.zip.PrintTool.calculateTimeAndLength; + +/** + * 压缩成ZIP文件,这边主要是通过 zipOutputStream 这个类进行对应的实现,所以其实也算是一个使用的实现例子 + * @author 黄志军 + */ +class ZipOutputUtil { + /** + * @param originPath 此方法只压缩文件夹 + * @param zipFilePath 压缩文件的路径 + * @return 压缩之后的文件对象 + */ + static File compress(String originPath, String zipFilePath) throws IOException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + File dir = new File(originPath); + if (dir.exists() && dir.isDirectory()) { + //遍历文件夹的所有文件 + File[] files = dir.listFiles(); + assert files != null; + //进行ZipOutputStream的压缩操作 + File file = compress(files, zipFilePath); + stopWatch.stop(); + //输出文件大小和运行时间 + calculateTimeAndLength(files,stopWatch,file); + return file; + } + System.out.println("文件夹不存在或者非文件夹"); + return null; + } + + + + + private static File compress(File[] files, String zipFilePath) throws IOException { + File zipFile = new File(zipFilePath); + // 文件输出流 + FileOutputStream outputStream = new FileOutputStream(zipFile); + // 压缩流 + ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream); + for (File file : files) { + FileInputStream inputStream = new FileInputStream(file); + ZipEntry zipEntry = new ZipEntry(file.getName()); + zipOutputStream.putNextEntry(zipEntry); + IOUtils.copy(inputStream, zipOutputStream); + inputStream.close(); + zipOutputStream.closeEntry(); + } + zipOutputStream.close(); + outputStream.close(); + return zipFile; + } +} diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml new file mode 100644 index 0000000..32cab36 --- /dev/null +++ b/src/main/resources/log4j2.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/test_assets.js b/src/main/resources/test_assets.js new file mode 100644 index 0000000..8bf6aa5 --- /dev/null +++ b/src/main/resources/test_assets.js @@ -0,0 +1,2183 @@ +/* +京东资产变动通知脚本:https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js +Modified time: 2021-05-17 15:25:41 +统计昨日京豆的变化情况,包括收入,支出,以及显示当前京豆数量,目前小问题:下单使用京豆后,退款重新购买,计算统计会出现异常 +统计红包以及过期红包 +网页查看地址 : https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean +支持京东双账号 +脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js +============QuantumultX============== +[task_local] +#京东资产变动通知 +2 9 * * * https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, tag=京东资产变动通知, img-url=https://raw.githubusercontent.com/Orz-3/mini/master/Color/jd.png, enabled=true +================Loon=============== +[Script] +cron "2 9 * * *" script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, tag=京东资产变动通知 +=============Surge=========== +[Script] +京东资产变动通知 = type=cron,cronexp="2 9 * * *",wake-system=1,timeout=3600,script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js +============小火箭========= +京东资产变动通知 = type=cron,script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, cronexpr="2 9 * * *", timeout=3600, enable=true + */ +let roleMap = { + "jd_4521b375ebb5d":"锟子怪", + "jd_542c10c0222bc":"康子怪", + "jd_66dcb31363ef6":"涛子怪", + "jd_45d917547c763":"跑腿小怪", + "417040678_m":"斌子怪", + "jd_73d88459d908e":"杰杰子", + "381550701lol":"漪漪子", +} +let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" +const $ = new Env('京东资产变动通知'); +let jdFruitShareArr = [], isBox = false, notify, newShareCodes; +//助力好友分享码(最多4个,否则后面的助力失败),原因:动动农场每人每天只有四次助力机会 +//此此内容是IOS用户下载脚本到本地使用,填写互助码的地方,同一动动账号的好友互助码请使用@符号隔开。 +//下面给出两个账号的填写示例(iOS只支持2个动动账号) +let shareCodes = + [ // 这个列表填入你要助力的好友的shareCode +] +let subTitle = '', option = {}, isFruitFinished = false; +const retainWater = 100;//保留水滴大于多少g,默认100g; +let jdNotify = false;//是否关闭通知,false打开通知推送,true关闭通知推送 +let jdFruitBeanCard = false;//农场使用水滴换豆卡(如果出现限时活动时100g水换20豆,此时比浇水划算,推荐换豆),true表示换豆(不浇水),false表示不换豆(继续浇水),脚本默认是浇水 +let randomCount = $.isNode() ? 0 : 0; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +const urlSchema = `openjd://virtual?params=%7B%20%22category%22:%20%22jump%22,%20%22des%22:%20%22m%22,%20%22url%22:%20%22https://h5.m.jd.com/babelDiy/Zeus/3KSjXqQabiTuD1cJ28QskrpWoBKT/index.html%22%20%7D`; + +let allMessage = ''; +let message = ""; +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +!(async () => { + await requireConfig(); + message += "[通知] 资产变动 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + let count = 0 + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.beanCount = 0; + $.incomeBean = 0; + $.expenseBean = 0; + $.todayIncomeBean = 0; + $.errorMsg = ''; + $.isLogin = true; + $.nickName = ''; + $.balance = 0; + $.expiredBalance = 0; + + username = $.UserName + if (roleMap[username] == undefined){ + continue + } + username = roleMap[username] + + await TotalBean(); + //加上名称 + message = message + "【羊毛姐妹】" + username + `( ${$.nickName} )`+ " \n\n " + + console.log(`\n********开始【京东账号${$.index}】${$.nickName || $.UserName}******\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await bean(); + await showMsg(); + await shareCodesFormat(); + await jdFruit(); + await jdWish() + } + message += "----\n\n" + if( (count+1)%4 ==0 || i == cookiesArr.length -1 ){ + message = message + getPic() + postToDingTalk(message) + message = "" + } + count ++ + } + + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + if (message != ""){ + postToDingTalk(message) + } + $.done(); + }) + + + function requireConfig() { + return new Promise(resolve => { + that.log('开始获取配置文件\n') + notify = $.isNode() ? require('./sendNotify') : ''; + //Node.js用户请在jdCookie.js处填写动动ck; + const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + const jdFruitShareCodes = $.isNode() ? require('./jdFruitShareCodes.js') : ''; + //IOS等用户直接用NobyDa的jd cookie + if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; + } else { + let cookiesData = $.getdata('CookiesJD') || "[]"; + cookiesData = jsonParse(cookiesData); + cookiesArr = cookiesData.map(item => item.cookie); + cookiesArr.reverse(); + cookiesArr.push(...[$.getdata('CookieJD2'), $.getdata('CookieJD')]); + cookiesArr.reverse(); + cookiesArr = cookiesArr.filter(item => item !== "" && item !== null && item !== undefined); + } + that.log(`共${cookiesArr.length}个动动账号\n`) + resolve() + }) + } + +async function showMsg() { + // if ($.errorMsg) return + allMessage += `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆 🐶${$.message}${$.index !== cookiesArr.length ? '\n\n' : ''}`; + message += "" + `【总京豆】:${$.beanCount}( 今日将过期${$.expirejingdou} )京豆 🐶` +"\n\n" + message += "" + `【今日收入】:${$.todayIncomeBean}京豆 🐶` +"\n\n" + message += "" + `【昨日收入】:${$.incomeBean}京豆 🐶` +"\n\n" + message += "" + `【昨日支出】:${$.expenseBean}京豆 🐶` +"\n\n" + + + + message += "" + `【当前总红包】:${$.balance}( 今日总过期${$.expiredBalance} )元 🧧` +"\n\n" + message += "" + `【京喜红包】:${$.jxRed}( 今日将过期${$.jxRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【极速红包】:${$.jsRed}( 今日将过期${$.jsRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【京东红包】:${$.jdRed}( 今日将过期${$.jdRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【健康红包】:${$.jdhRed}( 今日将过期${$.jdhRedExpire.toFixed(2)} )元 🧧` +"\n\n" + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `账号${$.index}:${$.nickName || $.UserName}\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}京豆 🐶${$.message}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + // } + $.msg($.name, '', `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶${$.message}`, {"open-url": "https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean"}); +} + +async function bean() { + // console.log(`北京时间零点时间戳:${parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000}`); + // console.log(`北京时间2020-10-28 06:16:05::${new Date("2020/10/28 06:16:05+08:00").getTime()}`) + // 不管哪个时区。得到都是当前时刻北京时间的时间戳 new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000 + + //前一天的0:0:0时间戳 + const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - (24 * 60 * 60 * 1000); + // 今天0:0:0时间戳 + const tm1 = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + let page = 1, t = 0, yesterdayArr = [], todayArr = []; + do { + let response = await getJingBeanBalanceDetail(page); + // console.log(`第${page}页: ${JSON.stringify(response)}`); + if (response && response.code === "0") { + page++; + let detailList = response.detailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const date = item.date.replace(/-/g, '/') + "+08:00"; + if (new Date(date).getTime() >= tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + todayArr.push(item); + } else if (tm <= new Date(date).getTime() && new Date(date).getTime() < tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + //昨日的 + yesterdayArr.push(item); + } else if (tm > new Date(date).getTime()) { + //前天的 + t = 1; + break; + } + } + } else { + $.errorMsg = `数据异常`; + $.msg($.name, ``, `账号${$.index}:${$.nickName}\n${$.errorMsg}`); + t = 1; + } + } else if (response && response.code === "3") { + console.log(`cookie已过期,或者填写不规范,跳出`) + t = 1; + } else { + console.log(`未知情况:${JSON.stringify(response)}`); + console.log(`未知情况,跳出`) + t = 1; + } + } while (t === 0); + for (let item of yesterdayArr) { + if (Number(item.amount) > 0) { + $.incomeBean += Number(item.amount); + } else if (Number(item.amount) < 0) { + $.expenseBean += Number(item.amount); + } + } + for (let item of todayArr) { + if (Number(item.amount) > 0) { + $.todayIncomeBean += Number(item.amount); + } + } + await queryexpirejingdou();//过期京豆 + await redPacket();//过期红包 + // console.log(`昨日收入:${$.incomeBean}个京豆 🐶`); + // console.log(`昨日支出:${$.expenseBean}个京豆 🐶`) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + if (data['retcode'] === '0' && data.data && data.data['assetInfo']) { + $.beanCount = data.data && data.data['assetInfo']['beanNum']; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} +function getJingBeanBalanceDetail(page) { + return new Promise(async resolve => { + const options = { + "url": `https://api.m.jd.com/client.action?functionId=getJingBeanBalanceDetail`, + "body": `body=${escape(JSON.stringify({"pageSize": "20", "page": page.toString()}))}&appid=ld`, + "headers": { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + // console.log(data) + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function queryexpirejingdou() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=${Date.now()}&g_login_type=1&sceneval=2`, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Host": "wq.jd.com", + "Referer": "https://wqs.jd.com/promote/201801/bean/mybean.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1" + } + } + $.expirejingdou = 0; + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // console.log(data) + data = JSON.parse(data.slice(23, -13)); + // console.log(data) + if (data.ret === 0) { + data['expirejingdou'].map(item => { + console.log(`${timeFormat(item['time'] * 1000)}日过期京豆:${item['expireamount']}\n`); + }) + $.expirejingdou = data['expirejingdou'][0]['expireamount']; + // if ($.expirejingdou > 0) { + // $.message += `\n今日将过期:${$.expirejingdou}京豆 🐶`; + // } + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function redPacket() { + return new Promise(async resolve => { + const options = { + "url": `https://m.jingxi.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=1&_=${+new Date()}&sceneval=2&g_login_type=1&g_ty=ls`, + "headers": { + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://st.jingxi.com/my/redpacket.shtml?newPg=App&jxsid=16156262265849285961', + 'Accept-Encoding': 'gzip, deflate, br', + "Cookie": cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data).data + $.jxRed = 0, $.jsRed = 0, $.jdRed = 0, $.jdhRed = 0, $.jxRedExpire = 0, $.jsRedExpire = 0, $.jdRedExpire = 0, $.jdhRedExpire = 0; + let t = new Date() + t.setDate(t.getDate() + 1) + t.setHours(0, 0, 0, 0) + t = parseInt((t - 1) / 1000) + for (let vo of data.useRedInfo.redList || []) { + if (vo.orgLimitStr && vo.orgLimitStr.includes("京喜")) { + $.jxRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jxRedExpire += parseFloat(vo.balance) + } + } else if (vo.activityName.includes("极速版")) { + $.jsRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jsRedExpire += parseFloat(vo.balance) + } + } else if (vo.orgLimitStr && vo.orgLimitStr.includes("京东健康")) { + $.jdhRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdhRedExpire += parseFloat(vo.balance) + } + } else { + $.jdRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdRedExpire += parseFloat(vo.balance) + } + } + } + $.jxRed = $.jxRed.toFixed(2) + $.jsRed = $.jsRed.toFixed(2) + $.jdRed = $.jdRed.toFixed(2) + $.jdhRed = $.jdhRed.toFixed(2) + $.balance = data.balance + $.expiredBalance = ($.jxRedExpire + $.jsRedExpire + $.jdRedExpire).toFixed(2) + $.message += `\n当前总红包:${$.balance}(今日总过期${$.expiredBalance})元 🧧\n京喜红包:${$.jxRed}(今日将过期${$.jxRedExpire.toFixed(2)})元 🧧\n极速红包:${$.jsRed}(今日将过期${$.jsRedExpire.toFixed(2)})元 🧧\n京东红包:${$.jdRed}(今日将过期${$.jdRedExpire.toFixed(2)})元 🧧\n健康红包:${$.jdhRed}(今日将过期${$.jdhRedExpire.toFixed(2)})元 🧧`; + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} +// prettier-ignore +function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + +//农场代码 + +async function jdFruit() { + subTitle = `【动动账号${$.index}】${$.nickName}`; + try { + await initForFarm(); + if ($.farmInfo.farmUserPro) { + // option['media-url'] = $.farmInfo.farmUserPro.goodsImage; + message = message + "【水果名称】 " + `${$.farmInfo.farmUserPro.name}` + "\n\n"; + // message += "【已兑换水果】" + `${$.farmInfo.farmUserPro.winTimes}` + "次\n\n"; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.farmInfo.farmUserPro.shareCode}\n`); + that.log(`\n【已成功兑换水果】${$.farmInfo.farmUserPro.winTimes}次\n`); + await getHelp(); + await masterHelpShare();//助力好友 + await setHelp(); + if ($.farmInfo.treeState === 2 || $.farmInfo.treeState === 3) { + option['open-url'] = urlSchema; + message = message + " " + $.UserName + "\n【提醒⏰】" + fruitName + "已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达" + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看`); + } + return + } else if ($.farmInfo.treeState === 1) { + that.log(`\n${$.farmInfo.farmUserPro.name}种植中...\n`) + } else if ($.farmInfo.treeState === 0) { + //已下单购买, 但未开始种植新的水果 + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】 ${$.nickName || $.UserName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达`, option); + message = message + " " + $.UserName + " \n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达" + "" + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 您忘了种植新的水果`, `动动账号${$.index} ${$.nickName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果`); + } + return + } + await doDailyTask(); + await doTenWater();//浇水十次 + await getFirstWaterAward();//领取首次浇水奖励 + await getTenWaterAward();//领取10浇水奖励 + await getWaterFriendGotAward();//领取为2好友浇水奖励 + await duck(); + await doTenWaterAgain();//再次浇水 + await predictionFruit();//预测水果成熟时间 + } else { + that.log(`初始化农场数据异常, 请登录动动 app查看农场0元水果功能是否正常,农场初始化数据: ${JSON.stringify($.farmInfo)}`); + } + } catch (e) { + that.log(`任务执行异常,请检查执行日志 ‼️‼️`); + $.logErr(e); + } + } + async function doDailyTask() { + await taskInitForFarm(); + that.log(`开始签到`); + if (!$.farmTask.signInit.todaySigned) { + await signForFarm(); //签到 + if ($.signResult.code === "0") { + that.log(`【签到成功】获得${$.signResult.amount}g💧\\n`) + //message += `【签到成功】获得${$.signResult.amount}g💧\n`//连续签到${signResult.signDay}天 + } else { + // message += `签到失败,详询日志\n`; + that.log(`签到结果: ${JSON.stringify($.signResult)}`); + } + } else { + that.log(`今天已签到,连续签到${$.farmTask.signInit.totalSigned},下次签到可得${$.farmTask.signInit.signEnergyEachAmount}g\n`); + } + // 被水滴砸中 + that.log(`被水滴砸中: ${$.farmInfo.todayGotWaterGoalTask.canPop ? '是' : '否'}`); + if ($.farmInfo.todayGotWaterGoalTask.canPop) { + await gotWaterGoalTaskForFarm(); + if ($.goalResult.code === '0') { + that.log(`【被水滴砸中】获得${$.goalResult.addEnergy}g💧\\n`); + // message += `【被水滴砸中】获得${$.goalResult.addEnergy}g💧\n` + } + } + that.log(`签到结束,开始广告浏览任务`); + if (!$.farmTask.gotBrowseTaskAdInit.f) { + let adverts = $.farmTask.gotBrowseTaskAdInit.userBrowseTaskAds + let browseReward = 0 + let browseSuccess = 0 + let browseFail = 0 + for (let advert of adverts) { //开始浏览广告 + if (advert.limit <= advert.hadFinishedTimes) { + // browseReward+=advert.reward + that.log(`${advert.mainTitle}+ ' 已完成`);//,获得${advert.reward}g + continue; + } + that.log('正在进行广告浏览任务: ' + advert.mainTitle); + await browseAdTaskForFarm(advert.advertId, 0); + if ($.browseResult.code === '0') { + that.log(`${advert.mainTitle}浏览任务完成`); + //领取奖励 + await browseAdTaskForFarm(advert.advertId, 1); + if ($.browseRwardResult.code === '0') { + that.log(`领取浏览${advert.mainTitle}广告奖励成功,获得${$.browseRwardResult.amount}g`) + browseReward += $.browseRwardResult.amount + browseSuccess++ + } else { + browseFail++ + that.log(`领取浏览广告奖励结果: ${JSON.stringify($.browseRwardResult)}`) + } + } else { + browseFail++ + that.log(`广告浏览任务结果: ${JSON.stringify($.browseResult)}`); + } + } + if (browseFail > 0) { + that.log(`【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\\n`); + // message += `【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\n`; + } else { + that.log(`【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`); + // message += `【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`; + } + } else { + that.log(`今天已经做过浏览广告任务\n`); + } + //定时领水 + if (!$.farmTask.gotThreeMealInit.f) { + // + await gotThreeMealForFarm(); + if ($.threeMeal.code === "0") { + that.log(`【定时领水】获得${$.threeMeal.amount}g💧\n`); + // message += `【定时领水】获得${$.threeMeal.amount}g💧\n`; + } else { + // message += `【定时领水】失败,详询日志\n`; + that.log(`定时领水成功结果: ${JSON.stringify($.threeMeal)}`); + } + } else { + that.log('当前不在定时领水时间断或者已经领过\n') + } + //给好友浇水 + if (!$.farmTask.waterFriendTaskInit.f) { + if ($.farmTask.waterFriendTaskInit.waterFriendCountKey < $.farmTask.waterFriendTaskInit.waterFriendMax) { + await doFriendsWater(); + } + } else { + that.log(`给${$.farmTask.waterFriendTaskInit.waterFriendMax}个好友浇水任务已完成\n`) + } + // await Promise.all([ + // clockInIn(),//打卡领水 + // executeWaterRains(),//水滴雨 + // masterHelpShare(),//助力好友 + // getExtraAward(),//领取额外水滴奖励 + // turntableFarm()//天天抽奖得好礼 + // ]) + // await getAwardInviteFriend(); + await clockInIn();//打卡领水 + await executeWaterRains();//水滴雨 + await getExtraAward();//领取额外水滴奖励 + await turntableFarm()//天天抽奖得好礼 + } + async function predictionFruit() { + that.log('开始预测水果成熟时间\n'); + await initForFarm(); + await taskInitForFarm(); + let waterEveryDayT = $.farmTask.totalWaterTaskInit.totalWaterTaskTimes;//今天到到目前为止,浇了多少次水 + // message += "【今日共浇水】" + `${waterEveryDayT}` + "次 \n\n" + message += "【剩余 水滴】" + `${$.farmInfo.farmUserPro.totalEnergy}` + "g💧 \n\n" + message += "【水果🍉进度】" + `${(($.farmInfo.farmUserPro.treeEnergy / + $.farmInfo.farmUserPro.treeTotalEnergy) * 100).toFixed(2)}` + "%,已浇水" +`${$.farmInfo.farmUserPro.treeEnergy / 10}` + "次,还需"+`${($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10}` +"次 \n\n" + if ($.farmInfo.toFlowTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【开花进度】再浇水${$.farmInfo.toFlowTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次开花\n\n` +"\n\n" + } else if ($.farmInfo.toFruitTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【结果进度】再浇水${$.farmInfo.toFruitTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次结果\n\n` + "\n\n" + } + // 预测n天后水果课可兑换功能 + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + message = message + "" + `【预测🍉收获时间】${waterD === 1 ? '明天' : waterD === 2 ? '后天' : waterD + '天之后'}(${timeFormat(24 * 60 * 60 * 1000 * waterD + Date.now())}日)可兑换水果🍉` +"\n\n"; + } + //浇水十次 + async function doTenWater() { + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match(`限时翻倍`) && beanCard > 0) { + that.log(`您设置的是使用水滴换豆卡,且背包有水滴换豆卡${beanCard}张, 跳过10次浇水任务`) + return + } + if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + that.log(`\n准备浇水十次`); + let waterCount = 0; + isFruitFinished = false; + for (; waterCount < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit - $.farmTask.totalWaterTaskInit.totalWaterTaskTimes; waterCount++) { + that.log(`第${waterCount + 1}次浇水`); + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`剩余水滴${$.waterResult.totalEnergy}g`); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + if ($.waterResult.totalEnergy < 10) { + that.log(`水滴不够,结束浇水`) + break + } + await gotStageAward();//领取阶段性水滴奖励 + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log('\n今日已完成10次浇水任务\n'); + } + } + //领取首次浇水奖励 + async function getFirstWaterAward() { + await taskInitForFarm(); + //领取首次浇水奖励 + if (!$.farmTask.firstWaterInit.f && $.farmTask.firstWaterInit.totalWaterTimes > 0) { + await firstWaterTaskForFarm(); + if ($.firstWaterReward.code === '0') { + that.log(`【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`); + // message += `【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`; + } else { + // message += '【首次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取首次浇水奖励结果: ${JSON.stringify($.firstWaterReward)}`); + } + } else { + that.log('首次浇水奖励已领取\n') + } + } + //领取十次浇水奖励 + async function getTenWaterAward() { + //领取10次浇水奖励 + if (!$.farmTask.totalWaterTaskInit.f && $.farmTask.totalWaterTaskInit.totalWaterTaskTimes >= $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + await totalWaterTaskForFarm(); + if ($.totalWaterReward.code === '0') { + that.log(`【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`); + // message += `【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`; + } else { + // message += '【十次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取10次浇水奖励结果: ${JSON.stringify($.totalWaterReward)}`); + } + } else if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + // message += `【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`; + that.log(`【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`); + } + that.log('finished 水果任务完成!'); + } + //再次浇水 + async function doTenWaterAgain() { + that.log('开始检查剩余水滴能否再次浇水再次浇水\n'); + await initForFarm(); + let totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + that.log(`剩余水滴${totalEnergy}g\n`); + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + that.log(`背包已有道具:\n快速浇水卡:${fastCard === -1 ? '未解锁': fastCard + '张'}\n水滴翻倍卡:${doubleCard === -1 ? '未解锁': doubleCard + '张'}\n水滴换京豆卡:${beanCard === -1 ? '未解锁' : beanCard + '张'}\n加签卡:${signCard === -1 ? '未解锁' : signCard + '张'}\n`) + if (totalEnergy >= 100 && doubleCard > 0) { + //使用翻倍水滴卡 + for (let i = 0; i < new Array(doubleCard).fill('').length; i++) { + await userMyCardForFarm('doubleCard'); + that.log(`使用翻倍水滴卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + if (signCard > 0) { + //使用加签卡 + for (let i = 0; i < new Array(signCard).fill('').length; i++) { + await userMyCardForFarm('signCard'); + that.log(`使用加签卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match('限时翻倍')) { + that.log(`\n您设置的是水滴换豆功能,现在为您换豆`); + if (totalEnergy >= 100 && $.myCardInfoRes.beanCard > 0) { + //使用水滴换豆卡 + await userMyCardForFarm('beanCard'); + that.log(`使用水滴换豆卡结果:${JSON.stringify($.userMyCardRes)}`); + if ($.userMyCardRes.code === '0') { + // message +="【水果🍉进度】" + `【水滴换豆卡】获得${$.userMyCardRes.beanCount}个京豆\n` + "\n\n"; + return + } + } else { + that.log(`您目前水滴:${totalEnergy}g,水滴换豆卡${$.myCardInfoRes.beanCard}张,暂不满足水滴换豆的条件,为您继续浇水`) + } + } + // if (totalEnergy > 100 && $.myCardInfoRes.fastCard > 0) { + // //使用快速浇水卡 + // await userMyCardForFarm('fastCard'); + // that.log(`使用快速浇水卡结果:${JSON.stringify($.userMyCardRes)}`); + // if ($.userMyCardRes.code === '0') { + // that.log(`已使用快速浇水卡浇水${$.userMyCardRes.waterEnergy}g`); + // } + // await initForFarm(); + // totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + // } + // 所有的浇水(10次浇水)任务,获取水滴任务完成后,如果剩余水滴大于等于60g,则继续浇水(保留部分水滴是用于完成第二天的浇水10次的任务) + let overageEnergy = totalEnergy - retainWater; + if (totalEnergy >= ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy)) { + //如果现有的水滴,大于水果可兑换所需的对滴(也就是把水滴浇完,水果就能兑换了) + isFruitFinished = false; + for (let i = 0; i < ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10; i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果(水果马上就可兑换了): ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log('\n浇水10g成功\n'); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + that.log(`目前水滴【${$.waterResult.totalEnergy}】g,继续浇水,水果马上就可以兑换了`) + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else if (overageEnergy >= 10) { + that.log("目前剩余水滴:【" + totalEnergy + "】g,可继续浇水"); + isFruitFinished = false; + for (let i = 0; i < parseInt(overageEnergy / 10); i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`\n浇水10g成功,剩余${$.waterResult.totalEnergy}\n`) + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + await gotStageAward() + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log("目前剩余水滴:【" + totalEnergy + "】g,不再继续浇水,保留部分水滴用于完成第二天【十次浇水得水滴】任务") + } + } + //领取阶段性水滴奖励 + function gotStageAward() { + return new Promise(async resolve => { + if ($.waterResult.waterStatus === 0 && $.waterResult.treeEnergy === 10) { + that.log('果树发芽了,奖励30g水滴'); + await gotStageAwardForFarm('1'); + that.log(`浇水阶段奖励1领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`; + that.log(`【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`); + } + } else if ($.waterResult.waterStatus === 1) { + that.log('果树开花了,奖励40g水滴'); + await gotStageAwardForFarm('2'); + that.log(`浇水阶段奖励2领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } else if ($.waterResult.waterStatus === 2) { + that.log('果树长出小果子啦, 奖励50g水滴'); + await gotStageAwardForFarm('3'); + that.log(`浇水阶段奖励3领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`) + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } + resolve() + }) + } + //天天抽奖活动 + async function turntableFarm() { + await initForTurntableFarm(); + if ($.initForTurntableFarmRes.code === '0') { + //领取定时奖励 //4小时一次 + let {timingIntervalHours, timingLastSysTime, sysTime, timingGotStatus, remainLotteryTimes, turntableInfos} = $.initForTurntableFarmRes; + + if (!timingGotStatus) { + that.log(`是否到了领取免费赠送的抽奖机会----${sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)}`) + if (sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)) { + await timingAwardForTurntableFarm(); + that.log(`领取定时奖励结果${JSON.stringify($.timingAwardRes)}`); + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } else { + that.log(`免费赠送的抽奖机会未到时间`) + } + } else { + that.log('4小时候免费赠送的抽奖机会已领取') + } + if ($.initForTurntableFarmRes.turntableBrowserAds && $.initForTurntableFarmRes.turntableBrowserAds.length > 0) { + for (let index = 0; index < $.initForTurntableFarmRes.turntableBrowserAds.length; index++) { + if (!$.initForTurntableFarmRes.turntableBrowserAds[index].status) { + that.log(`开始浏览天天抽奖的第${index + 1}个逛会场任务`) + await browserForTurntableFarm(1, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0' && $.browserForTurntableFarmRes.status) { + that.log(`第${index + 1}个逛会场任务完成,开始领取水滴奖励\n`) + await browserForTurntableFarm(2, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0') { + that.log(`第${index + 1}个逛会场任务领取水滴奖励完成\n`) + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } + } + } else { + that.log(`浏览天天抽奖的第${index + 1}个逛会场任务已完成`) + } + } + } + //天天抽奖助力 + that.log('开始天天抽奖--好友助力--每人每天只有三次助力机会.') + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('天天抽奖-不能自己给自己助力\n') + continue + } + await lotteryMasterHelp(code); + // that.log('天天抽奖助力结果',lotteryMasterHelpRes.helpResult) + if ($.lotteryMasterHelpRes.helpResult.code === '0') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}成功\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '11') { + that.log(`天天抽奖-不要重复助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '13') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}失败,助力次数耗尽\n`); + break; + } + } + that.log(`---天天抽奖次数remainLotteryTimes----${remainLotteryTimes}次`) + //抽奖 + if (remainLotteryTimes > 0) { + that.log('开始抽奖') + let lotteryResult = ''; + for (let i = 0; i < new Array(remainLotteryTimes).fill('').length; i++) { + await lotteryForTurntableFarm() + that.log(`第${i + 1}次抽奖结果${JSON.stringify($.lotteryRes)}`); + if ($.lotteryRes.code === '0') { + turntableInfos.map((item) => { + if (item.type === $.lotteryRes.type) { + that.log(`lotteryRes.type${$.lotteryRes.type}`); + if ($.lotteryRes.type.match(/bean/g) && $.lotteryRes.type.match(/bean/g)[0] === 'bean') { + lotteryResult += `${item.name}个,`; + } else if ($.lotteryRes.type.match(/water/g) && $.lotteryRes.type.match(/water/g)[0] === 'water') { + lotteryResult += `${item.name},`; + } else { + lotteryResult += `${item.name},`; + } + } + }) + //没有次数了 + if ($.lotteryRes.remainLotteryTimes === 0) { + break + } + } + } + if (lotteryResult) { + that.log(`【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`) + // message += `【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`; + } + } else { + that.log('天天抽奖--抽奖机会为0次') + } + } else { + that.log('初始化天天抽奖得好礼失败') + } + } + //领取额外奖励水滴 + async function getExtraAward() { + await masterHelpTaskInitForFarm(); + if ($.masterHelpResult.code === '0') { + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length >= 5) { + // 已有五人助力。领取助力后的奖励 + if (!$.masterHelpResult.masterGotFinal) { + await masterGotFinishedTaskForFarm(); + if ($.masterGotFinished.code === '0') { + that.log(`已成功领取好友助力奖励:【${$.masterGotFinished.amount}】g水`); + // message += "【额外奖励】" + `${$.masterGotFinished.amount}` + "g水领取成功\n\n"; + } + } else { + that.log("已经领取过5好友助力额外奖励"); + // message += "【水果🍉进度】" + `【额外奖励】已被领取过\n` + "\n\n"; + } + } else { + that.log("助力好友未达到5个"); + // message += "【额外奖励】领取失败,原因:给您助力的人未达5个\n\n"; + } + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length > 0) { + let str = ''; + $.masterHelpResult.masterHelpPeoples.map((item, index) => { + if (index === ($.masterHelpResult.masterHelpPeoples.length - 1)) { + str += item.nickName || "匿名用户"; + } else { + str += (item.nickName || "匿名用户") + ','; + } + let date = new Date(item.time); + let time = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getMinutes(); + that.log(`\n动动昵称【${item.nickName || "匿名用户"}】 在 ${time} 给您助过力\n`); + }) + // message += "【助力您的好友】 " + `${str}` + "\n\n" + } + that.log('领取额外奖励水滴结束\n'); + } + } + + function getHelp() { + newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jd_fruit/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.farmInfo.farmUserPro.shareCode) { + $.get({ + url: "http://api.tyh52.com/act/set/jd_fruit/" + $.farmInfo.farmUserPro.shareCode + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + //助力好友 + async function masterHelpShare() { + that.log('开始助力好友') + let salveHelpAddWater = 0; + let remainTimes = 4;//今日剩余助力次数,默认4次(动动农场每人每天4次助力机会)。 + let helpSuccessPeoples = '';//成功助力好友 + that.log(`格式化后的助力码::${JSON.stringify(newShareCodes)}\n`); + + for (let code of newShareCodes) { + that.log(`开始助力动动账号${$.index} - ${$.nickName}的好友: ${code}`); + if (!code) continue; + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('不能为自己助力哦,跳过自己的shareCode\n') + continue + } + await masterHelp(code); + if ($.helpResult.code === '0') { + if ($.helpResult.helpResult.code === '0') { + //助力成功 + salveHelpAddWater += $.helpResult.helpResult.salveHelpAddWater; + that.log(`【助力好友结果】: 已成功给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力`); + that.log(`给好友【${$.helpResult.helpResult.masterUserInfo.nickName}】助力获得${$.helpResult.helpResult.salveHelpAddWater}g水滴`) + helpSuccessPeoples += ($.helpResult.helpResult.masterUserInfo.nickName || '匿名用户') + ','; + } else if ($.helpResult.helpResult.code === '8') { + that.log(`【助力好友结果】: 助力【${$.helpResult.helpResult.masterUserInfo.nickName}】失败,您今天助力次数已耗尽`); + } else if ($.helpResult.helpResult.code === '9') { + that.log(`【助力好友结果】: 之前给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力过了`); + } else if ($.helpResult.helpResult.code === '10') { + that.log(`【助力好友结果】: 好友【${$.helpResult.helpResult.masterUserInfo.nickName}】已满五人助力`); + } else { + that.log(`助力其他情况:${JSON.stringify($.helpResult.helpResult)}`); + } + that.log(`【今日助力次数还剩】${$.helpResult.helpResult.remainTimes}次\n`); + remainTimes = $.helpResult.helpResult.remainTimes; + if ($.helpResult.helpResult.remainTimes === 0) { + that.log(`您当前助力次数已耗尽,跳出助力`); + break + } + } else { + that.log(`助力失败::${JSON.stringify($.helpResult)}`); + } + } + if (helpSuccessPeoples && helpSuccessPeoples.length > 0) { + // message += " " + `【您助力的好友👬】${helpSuccessPeoples.substr(0, helpSuccessPeoples.length - 1)}\n` + "\n\n"; + } + if (salveHelpAddWater > 0) { + // message += `【助力好友👬】获得${salveHelpAddWater}g💧\n`; + that.log(`【助力好友👬】获得${salveHelpAddWater}g💧\n`); + } + // message += "" + `【今日剩余助力👬】${remainTimes}次\n` + "\n\n"; + that.log('助力好友结束,即将开始领取额外水滴奖励\n'); + } + //水滴雨 + async function executeWaterRains() { + let executeWaterRain = !$.farmTask.waterRainInit.f; + if (executeWaterRain) { + that.log(`水滴雨任务,每天两次,最多可得10g水滴`); + that.log(`两次水滴雨任务是否全部完成:${$.farmTask.waterRainInit.f ? '是' : '否'}`); + if ($.farmTask.waterRainInit.lastTime) { + if (Date.now() < ($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000)) { + executeWaterRain = false; + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`; + that.log(`\`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`); + } + } + if (executeWaterRain) { + that.log(`开始水滴雨任务,这是第${$.farmTask.waterRainInit.winTimes + 1}次,剩余${2 - ($.farmTask.waterRainInit.winTimes + 1)}次`); + await waterRainForFarm(); + that.log('水滴雨waterRain'); + if ($.waterRain.code === '0') { + that.log('水滴雨任务执行成功,获得水滴:' + $.waterRain.addEnergy + 'g'); + that.log(`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`); + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`; + } + } + } else { + // message += `【水滴雨】已全部完成,获得20g💧\n`; + } + } + //打卡领水活动 + async function clockInIn() { + that.log('开始打卡领水活动(签到,关注,领券)'); + await clockInInitForFarm(); + if ($.clockInInit.code === '0') { + // 签到得水滴 + if (!$.clockInInit.todaySigned) { + that.log('开始今日签到'); + await clockInForFarm(); + that.log(`打卡结果${JSON.stringify($.clockInForFarmRes)}`); + if ($.clockInForFarmRes.code === '0') { + // message += `【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`; + that.log(`【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`) + if ($.clockInForFarmRes.signDay === 7) { + //可以领取惊喜礼包 + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + } + } + if ($.clockInInit.todaySigned && $.clockInInit.totalSigned === 7) { + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + // 限时关注得水滴 + if ($.clockInInit.themes && $.clockInInit.themes.length > 0) { + for (let item of $.clockInInit.themes) { + if (!item.hadGot) { + that.log(`关注ID${item.id}`); + await clockInFollowForFarm(item.id, "theme", "1"); + that.log(`themeStep1--结果${JSON.stringify($.themeStep1)}`); + if ($.themeStep1.code === '0') { + await clockInFollowForFarm(item.id, "theme", "2"); + that.log(`themeStep2--结果${JSON.stringify($.themeStep2)}`); + if ($.themeStep2.code === '0') { + that.log(`关注${item.name},获得水滴${$.themeStep2.amount}g`); + } + } + } + } + } + // 限时领券得水滴 + if ($.clockInInit.venderCoupons && $.clockInInit.venderCoupons.length > 0) { + for (let item of $.clockInInit.venderCoupons) { + if (!item.hadGot) { + that.log(`领券的ID${item.id}`); + await clockInFollowForFarm(item.id, "venderCoupon", "1"); + that.log(`venderCouponStep1--结果${JSON.stringify($.venderCouponStep1)}`); + if ($.venderCouponStep1.code === '0') { + await clockInFollowForFarm(item.id, "venderCoupon", "2"); + if ($.venderCouponStep2.code === '0') { + that.log(`venderCouponStep2--结果${JSON.stringify($.venderCouponStep2)}`); + that.log(`从${item.name}领券,获得水滴${$.venderCouponStep2.amount}g`); + } + } + } + } + } + } + that.log('开始打卡领水活动(签到,关注,领券)结束\n'); + } + // + async function getAwardInviteFriend() { + await friendListInitForFarm();//查询好友列表 + that.log(`查询好友列表数据:\n`) + if ($.friendList) { + that.log(`\n今日已邀请好友${$.friendList.inviteFriendCount}个 / 每日邀请上限${$.friendList.inviteFriendMax}个`); + that.log(`开始删除${$.friendList.friends && $.friendList.friends.length}个好友,可拿每天的邀请奖励`); + if ($.friendList.friends && $.friendList.friends.length > 0) { + for (let friend of $.friendList.friends) { + that.log(`\n开始删除好友 [${friend.shareCode}]`); + const deleteFriendForFarm = await request('deleteFriendForFarm', { "shareCode": `${friend.shareCode}`,"version":8,"channel":1 }); + if (deleteFriendForFarm && deleteFriendForFarm.code === '0') { + that.log(`删除好友 [${friend.shareCode}] 成功\n`); + } + } + } + await receiveFriendInvite();//为他人助力,接受邀请成为别人的好友 + if ($.friendList.inviteFriendCount > 0) { + if ($.friendList.inviteFriendCount > $.friendList.inviteFriendGotAwardCount) { + that.log('开始领取邀请好友的奖励'); + await awardInviteFriendForFarm(); + that.log(`领取邀请好友的奖励结果::${JSON.stringify($.awardInviteFriendRes)}`); + } + } else { + that.log('今日未邀请过好友') + } + } else { + that.log(`查询好友列表失败\n`); + } + } + //给好友浇水 + async function doFriendsWater() { + await friendListInitForFarm(); + that.log('开始给好友浇水...'); + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax } = $.farmTask.waterFriendTaskInit; + that.log(`今日已给${waterFriendCountKey}个好友浇水`); + if (waterFriendCountKey < waterFriendMax) { + let needWaterFriends = []; + if ($.friendList.friends && $.friendList.friends.length > 0) { + $.friendList.friends.map((item, index) => { + if (item.friendState === 1) { + if (needWaterFriends.length < (waterFriendMax - waterFriendCountKey)) { + needWaterFriends.push(item.shareCode); + } + } + }); + //TODO ,发现bug,github action运行发现有些账号第一次没有给3个好友浇水 + that.log(`需要浇水的好友列表shareCodes:${JSON.stringify(needWaterFriends)}`); + let waterFriendsCount = 0, cardInfoStr = ''; + for (let index = 0; index < needWaterFriends.length; index ++) { + await waterFriendForFarm(needWaterFriends[index]); + that.log(`为第${index+1}个好友浇水结果:${JSON.stringify($.waterFriendForFarmRes)}\n`) + if ($.waterFriendForFarmRes.code === '0') { + waterFriendsCount ++; + if ($.waterFriendForFarmRes.cardInfo) { + that.log('为好友浇水获得道具了'); + if ($.waterFriendForFarmRes.cardInfo.type === 'beanCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴换豆卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'fastCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `快速浇水卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'doubleCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴翻倍卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'signCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `加签卡,`; + } + } + } else if ($.waterFriendForFarmRes.code === '11') { + that.log('水滴不够,跳出浇水') + } + } + // message += `【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`; + that.log(`【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`); + if (cardInfoStr && cardInfoStr.length > 0) { + // message += `【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`; + that.log(`【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`); + } + } else { + that.log('您的好友列表暂无好友,快去邀请您的好友吧!') + } + } else { + that.log(`今日已为好友浇水量已达${waterFriendMax}个`) + } + } + //领取给3个好友浇水后的奖励水滴 + async function getWaterFriendGotAward() { + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax, waterFriendSendWater, waterFriendGotAward } = $.farmTask.waterFriendTaskInit + if (waterFriendCountKey >= waterFriendMax) { + if (!waterFriendGotAward) { + await waterFriendGotAwardForFarm(); + that.log(`领取给${waterFriendMax}个好友浇水后的奖励水滴::${JSON.stringify($.waterFriendGotAwardRes)}`) + if ($.waterFriendGotAwardRes.code === '0') { + // message += `【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`; + that.log(`【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`); + } + } else { + that.log(`给好友浇水的${waterFriendSendWater}g水滴奖励已领取\n`); + // message += `【给${waterFriendMax}好友浇水】奖励${waterFriendSendWater}g水滴已领取\n`; + } + } else { + that.log(`暂未给${waterFriendMax}个好友浇水\n`); + } + } + //接收成为对方好友的邀请 + async function receiveFriendInvite() { + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('自己不能邀请自己成为好友噢\n') + continue + } + await inviteFriend(code); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + if ($.inviteFriendRes.helpResult.code === '0') { + that.log(`接收邀请成为好友结果成功,您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + } else if ($.inviteFriendRes.helpResult.code === '17') { + that.log(`接收邀请成为好友结果失败,对方已是您的好友`) + } + } + // that.log(`开始接受6fbd26cc27ac44d6a7fed34092453f77的邀请\n`) + // await inviteFriend('6fbd26cc27ac44d6a7fed34092453f77'); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + // if ($.inviteFriendRes.helpResult.code === '0') { + // that.log(`您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + // } else if ($.inviteFriendRes.helpResult.code === '17') { + // that.log(`对方已是您的好友`) + // } + } + async function duck() { + for (let i = 0; i < 10; i++) { + //这里循环十次 + await getFullCollectionReward(); + if ($.duckRes.code === '0') { + if (!$.duckRes.hasLimit) { + that.log(`小鸭子游戏:${$.duckRes.title}`); + // if ($.duckRes.type !== 3) { + // that.log(`${$.duckRes.title}`); + // if ($.duckRes.type === 1) { + // message += `【小鸭子】为你带回了水滴\n`; + // } else if ($.duckRes.type === 2) { + // message += `【小鸭子】为你带回快速浇水卡\n` + // } + // } + } else { + that.log(`${$.duckRes.title}`) + break; + } + } else if ($.duckRes.code === '10') { + that.log(`小鸭子游戏达到上限`) + break; + } + } + } + // ========================API调用接口======================== + //鸭子,点我有惊喜 + async function getFullCollectionReward() { + return new Promise(resolve => { + const body = {"type": 2, "version": 6, "channel": 2}; + $.post(taskUrl("getFullCollectionReward", body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + /** + * 领取10次浇水奖励API + */ + async function totalWaterTaskForFarm() { + const functionId = 'totalWaterTaskForFarm'; + $.totalWaterReward = await request(functionId); + } + //领取首次浇水奖励API + async function firstWaterTaskForFarm() { + const functionId = 'firstWaterTaskForFarm'; + $.firstWaterReward = await request(functionId); + } + //领取给3个好友浇水后的奖励水滴API + async function waterFriendGotAwardForFarm() { + const functionId = 'waterFriendGotAwardForFarm'; + $.waterFriendGotAwardRes = await request(functionId, {"version": 4, "channel": 1}); + } + // 查询背包道具卡API + async function myCardInfoForFarm() { + const functionId = 'myCardInfoForFarm'; + $.myCardInfoRes = await request(functionId, {"version": 5, "channel": 1}); + } + //使用道具卡API + async function userMyCardForFarm(cardType) { + const functionId = 'userMyCardForFarm'; + $.userMyCardRes = await request(functionId, {"cardType": cardType}); + } + /** + * 领取浇水过程中的阶段性奖励 + * @param type + * @returns {Promise} + */ + async function gotStageAwardForFarm(type) { + $.gotStageAwardForFarmRes = await request('gotStageAwardForFarm', {'type': type}); + } + //浇水API + async function waterGoodForFarm() { + await $.wait(1000); + that.log('等待了1秒'); + + const functionId = 'waterGoodForFarm'; + $.waterResult = await request(functionId); + } + // 初始化集卡抽奖活动数据API + async function initForTurntableFarm() { + $.initForTurntableFarmRes = await request('initForTurntableFarm', {version: 4, channel: 1}); + } + async function lotteryForTurntableFarm() { + await $.wait(2000); + that.log('等待了2秒'); + $.lotteryRes = await request('lotteryForTurntableFarm', {type: 1, version: 4, channel: 1}); + } + + async function timingAwardForTurntableFarm() { + $.timingAwardRes = await request('timingAwardForTurntableFarm', {version: 4, channel: 1}); + } + + async function browserForTurntableFarm(type, adId) { + if (type === 1) { + that.log('浏览爆品会场'); + } + if (type === 2) { + that.log('天天抽奖浏览任务领取水滴'); + } + const body = {"type": type,"adId": adId,"version":4,"channel":1}; + $.browserForTurntableFarmRes = await request('browserForTurntableFarm', body); + // 浏览爆品会场8秒 + } + //天天抽奖浏览任务领取水滴API + async function browserForTurntableFarm2(type) { + const body = {"type":2,"adId": type,"version":4,"channel":1}; + $.browserForTurntableFarm2Res = await request('browserForTurntableFarm', body); + } + /** + * 天天抽奖拿好礼-助力API(每人每天三次助力机会) + */ + async function lotteryMasterHelp() { + $.lotteryMasterHelpRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-3', + babelChannel: "3", + version: 4, + channel: 1 + }); + } + + //领取5人助力后的额外奖励API + async function masterGotFinishedTaskForFarm() { + const functionId = 'masterGotFinishedTaskForFarm'; + $.masterGotFinished = await request(functionId); + } + //助力好友信息API + async function masterHelpTaskInitForFarm() { + const functionId = 'masterHelpTaskInitForFarm'; + $.masterHelpResult = await request(functionId); + } + //接受对方邀请,成为对方好友的API + async function inviteFriend() { + $.inviteFriendRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-inviteFriend', + version: 4, + channel: 2 + }); + } + // 助力好友API + async function masterHelp() { + $.helpResult = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0], + babelChannel: "3", + version: 2, + channel: 1 + }); + } + /** + * 水滴雨API + */ + async function waterRainForFarm() { + const functionId = 'waterRainForFarm'; + const body = {"type": 1, "hongBaoTimes": 100, "version": 3}; + $.waterRain = await request(functionId, body); + } + /** + * 打卡领水API + */ + async function clockInInitForFarm() { + const functionId = 'clockInInitForFarm'; + $.clockInInit = await request(functionId); + } + + // 连续签到API + async function clockInForFarm() { + const functionId = 'clockInForFarm'; + $.clockInForFarmRes = await request(functionId, {"type": 1}); + } + + //关注,领券等API + async function clockInFollowForFarm(id, type, step) { + const functionId = 'clockInFollowForFarm'; + let body = { + id, + type, + step + } + if (type === 'theme') { + if (step === '1') { + $.themeStep1 = await request(functionId, body); + } else if (step === '2') { + $.themeStep2 = await request(functionId, body); + } + } else if (type === 'venderCoupon') { + if (step === '1') { + $.venderCouponStep1 = await request(functionId, body); + } else if (step === '2') { + $.venderCouponStep2 = await request(functionId, body); + } + } + } + + // 领取连续签到7天的惊喜礼包API + async function gotClockInGift() { + $.gotClockInGiftRes = await request('clockInForFarm', {"type": 2}) + } + + //定时领水API + async function gotThreeMealForFarm() { + const functionId ='gotThreeMealForFarm'; + $.threeMeal = await request(functionId); + } + /** + * 浏览广告任务API + * type为0时, 完成浏览任务 + * type为1时, 领取浏览任务奖励 + */ + async function browseAdTaskForFarm(advertId, type) { + const functionId = 'browseAdTaskForFarm'; + if (type === 0) { + $.browseResult = await request(functionId, {advertId, type}); + } else if (type === 1) { + $.browseRwardResult = await request(functionId, {advertId, type}); + } + } + // 被水滴砸中API + async function gotWaterGoalTaskForFarm() { + $.goalResult = await request('gotWaterGoalTaskForFarm', {type: 3}); + } + //签到API + async function signForFarm() { + const functionId = 'signForFarm'; + $.signResult = await request(functionId); + } + /** + * 初始化农场, 可获取果树及用户信息API + */ + async function initForFarm() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "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" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + // 初始化任务列表API + async function taskInitForFarm() { + that.log('\n初始化任务列表') + const functionId = 'taskInitForFarm'; + $.farmTask = await request(functionId); + } + //获取好友列表API + async function friendListInitForFarm() { + $.friendList = await request('friendListInitForFarm', {"version": 4, "channel": 1}); + // that.log('aa', aa); + } + // 领取邀请好友的奖励API + async function awardInviteFriendForFarm() { + $.awardInviteFriendRes = await request('awardInviteFriendForFarm'); + } + //为好友浇水API + async function waterFriendForFarm(shareCode) { + const body = {"shareCode": shareCode, "version": 6, "channel": 1} + $.waterFriendForFarmRes = await request('waterFriendForFarm', body); + } + + + function readShareCode() { + return new Promise(async resolve => { + $.get({url: `http://jd.turinglabs.net/api/v2/jd/farm/read/${randomCount}/`, timeout: 10000,}, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + that.log(`随机取个${randomCount}码放到您固定的互助码后面(不影响已有固定互助)`) + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + await $.wait(10000); + resolve() + }) + } + function shareCodesFormat() { + return new Promise(async resolve => { + // that.log(`第${$.index}个动动账号的助力码:::${jdFruitShareArr[$.index - 1]}`) + newShareCodes = []; + // if (jdFruitShareArr[$.index - 1]) { + // newShareCodes = jdFruitShareArr[$.index - 1].split('@'); + // } else { + // that.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + // const tempIndex = $.index > shareCodes.length ? (shareCodes.length - 1) : ($.index - 1); + // newShareCodes = shareCodes[tempIndex].split('@'); + // } + // const readShareCodeRes = await readShareCode(); + // if (readShareCodeRes && readShareCodeRes.code === 200) { + // // newShareCodes = newShareCodes.concat(readShareCodeRes.data || []); + // newShareCodes = [...new Set([...newShareCodes, ...(readShareCodeRes.data || [])])]; + // } + // that.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify(newShareCodes)}`) + resolve(); + }) + } + + function request(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️') + that.log(JSON.stringify(err)); + that.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) + } + function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } + } + function taskUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + }, + timeout: 10000, + } + } + //-------------------------------------------------东东赚赚------------------------------------------------------------ + + +async function jdWish() { + $.bean = 0 + $.tuan = null + $.hasOpen = false + await getTaskList(true) + await getUserTuanInfo() + if (!$.tuan) { + await openTuan() + if ($.hasOpen) await getUserTuanInfo() + } + if ($.tuan) $.tuanList.push($.tuan) + await helpFriends() + await getUserInfo() + $.nowBean = parseInt($.totalBeanNum) + $.nowNum = parseInt($.totalNum) + for (let i = 0; i < $.taskList.length; ++i) { + let task = $.taskList[i] + if (task['taskId'] === 1 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + } else if (task['taskId'] !== 3 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + if(task['itemId']) + await doTask({"itemId":task['itemId'],"taskId":task['taskId'],"mpVersion":"3.4.0"}) + else + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + await $.wait(3000) + } + } + await getTaskList(); + await showMsg1(); + } + + + function helpFriendTuan(body) { + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_assist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.success) { + that.log('助力成功') + } else { + if (data.resultCode === '9200008') that.log('不能助力自己') + else if (data.resultCode === '9200011') that.log('已经助力过') + else if (data.resultCode === '2400205') that.log('团已满') + else if (data.resultCode === '2400203') {that.log('助力次数已耗尽');$.canHelp = false} + else that.log(`未知错误`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getUserTuanInfo() { + let body = {"paramData": {"channel": "FISSION_BEAN"}} + return new Promise(resolve => { + $.get(taskTuanUrl("distributeBeanActivityInfo", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data && !data.data.canStartNewAssist) { + $.tuan = { + "activityIdEncrypted": data.data.id, + "assistStartRecordId": data.data.assistStartRecordId, + "assistedPinEncrypted": data.data.encPin, + "channel": "FISSION_BEAN" + } + $.tuanActId = data.data.id + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function openTuan() { + let body = {"activityIdEncrypted": $.tuanActId, "channel": "FISSION_BEAN"} + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_startAssist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['success']) { + $.hasOpen = true + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getUserInfo() { + return new Promise(resolve => { + $.get(taskUrl1("interactIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // if (data.data.shareTaskRes) { + // that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${data.data.shareTaskRes.itemId}\n`); + // } else { + // that.log(`\n\n已满5人助力或助力功能已下线,故暂时无${$.name}好友助力码\n\n`) + // } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getTaskList(flag = false) { + return new Promise(resolve => { + $.get(taskUrl1("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.taskList = data.data.taskDetailResList + $.totalNum = data.data.totalNum + $.totalBeanNum = data.data.totalBeanNum + if (flag && $.taskList.filter(item => !!item && item['taskId']=== 3) && $.taskList.filter(item => !!item && item['taskId']=== 3).length) { + $.shareId=$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + // 完成 + function doTask(body, func = "doInteractTask") { + // that.log(taskUrl("doInteractTask", body)) + return new Promise(resolve => { + $.get(taskUrl1(func, body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // that.log(data) + if (func === "doInteractTask") { + if (data.subCode === "S000") { + that.log(`任务完成,获得 ${data.data.taskDetailResList[0].incomeAmountConf} 金币,${data.data.taskDetailResList[0].beanNum} 京豆`) + $.bean += parseInt(data.data.taskDetailResList[0].beanNum) + } else { + that.log(`任务失败,错误信息:${data.message}`) + } + } else { + that.log(`${data.data.helpResDesc}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + async function helpFriends() { + await getHelp(); + for (let code of $.newShareCodes) { + if (!code) continue + await doTask({"itemId": code, "taskId": "3", "mpVersion": "3.4.0"}, "doHelpTask") + } + await setHelp(); + } + + function getHelp() { + $.newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzz/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + $.newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.shareId) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzz/" + $.shareId + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function getHelpTuan() { + $.tuanList = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzzTuan/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var item of list) { + let its=item.split('@'); + if(its.length==2){ + let tuan={ + "activityIdEncrypted": $.tuanActId, + "assistStartRecordId": its[0], + "assistedPinEncrypted": its[1], + "channel": "FISSION_BEAN" + } + $.tuanList.push(tuan); + } + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelpTuan() { + return new Promise(resolve => { + if ($.tuan) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzzTuan/" + $.tuan.assistStartRecordId+'@'+$.tuan.assistedPinEncrypted + }, (err, resp, data) => { + try { + if (data) { + that.log(data); + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的开团碼成功"); + }else{ + that.log("提交开团码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function taskUrl1(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } + } + + function taskTuanUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&body=${escape(JSON.stringify(body))}&appid=swat_miniprogram&osVersion=5.0.0&clientVersion=3.1.3&fromType=wxapp×tamp=${new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 + 8 * 60 * 60 * 1000}`, + headers: { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "api.m.jd.com", + "Referer": "https://servicewechat.com/wxa5bf5ee667d91626/108/page-frame.html", + "Cookie": cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + } + } + } + + + + function showMsg1() { + return new Promise(async resolve => { + that.log( "" + `本次获得${parseInt($.totalBeanNum) - $.nowBean}京豆,${parseInt($.totalNum) - $.nowNum}金币\n` + "\n\n") + message += "" + `累计获得${$.totalBeanNum}京豆,${$.totalNum}金币\n可兑换${$.totalNum / 10000}元无门槛红包` + "\n\n" + if (parseInt($.totalBeanNum) - $.nowBean > 0) { + $.msg($.name, '', `动动账号${$.index} ${$.nickName}\n${message}`); + } else { + $.log(message) + } + // 云端大于10元无门槛红包时进行通知推送 + if ($.isNode() && $.totalNum >= 1000000) await notify.sendNotify(`${$.name} - 动动账号${$.index} - ${$.nickName}`, `动动账号${$.index} ${$.nickName}\n当前金币:${$.totalNum}个\n可兑换无门槛红包:${parseInt($.totalNum) / 10000}元\n`,) + resolve(); + }) + } + + + + + +//我加的函数 +function postToDingTalk(messgae) { + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"资产变动", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_assets_new.js b/src/main/resources/test_assets_new.js new file mode 100644 index 0000000..2aae754 --- /dev/null +++ b/src/main/resources/test_assets_new.js @@ -0,0 +1,1216 @@ +/* +cron "30 10,22 * * *" jd_bean_change.js, tag:资产变化强化版by-ccwav +*/ +let roleMap = { + "jd_4521b375ebb5d":"锟子怪", + "jd_542c10c0222bc":"康子怪", + "jd_66dcb31363ef6":"涛子怪", + "jd_45d917547c763":"跑腿小怪", + "417040678_m":"斌子怪", + "jd_73d88459d908e":"杰杰子", + "381550701lol":"漪漪子", +} +let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" +//更新by ccwav,20210821 +const $ = new Env('京东资产变动通知'); +const notify = $.isNode() ? require('./sendNotify') : ''; +const JXUserAgent = $.isNode() ? (process.env.JX_USER_AGENT ? process.env.JX_USER_AGENT : ``):``; +//Node.js用户请在jdCookie.js处填写京东ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +let allMessage = ''; +let message = ""; +let ReturnMessage = ''; +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; + +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} +!(async () => { + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + message += "[通知] 资产变动 \n\n --- \n\n" + let count = 0 + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.beanCount = 0; + $.incomeBean = 0; + $.expenseBean = 0; + $.todayIncomeBean = 0; + $.errorMsg = ''; + $.isLogin = true; + $.nickName = ''; + $.message = ''; + $.balance = 0; + $.expiredBalance = 0; + $.JdzzNum=0; + $.JdMsScore = 0; + $.JdFarmProdName = ''; + $.JdtreeEnergy=0; + $.JdtreeTotalEnergy=0; + $.JdwaterTotalT = 0; + $.JdwaterD = 0; + $.JDwaterEveryDayT=0; + $.JDtotalcash=0; + $.JDEggcnt=0; + $.Jxmctoken=''; + await TotalBean(); + + username = $.UserName + if (roleMap[username] == undefined){ + continue + } + username = roleMap[username] + + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + console.log(`\n********开始【京东账号${$.index}】${$.nickName || $.UserName}******\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await getJdZZ(); + await getMs(); + await jdfruitRequest('taskInitForFarm', {"version":14,"channel":1,"babelChannel":"120"}); + await getjdfruit(); + await cash(); + await requestAlgo(); + await JxmcGetRequest(); + await bean(); + await getJxFactory(); //惊喜工厂 + await getDdFactoryInfo(); // 京东工厂 + await showMsg(); + message += "----\n\n" + } + + if( (count+1)%4 ==0 ){ + postToDingTalk(message) + message = "" + } + count ++ + } + + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + if (message != ""){ + postToDingTalk(message) + } + $.done(); + }) +async function showMsg() { + if ($.errorMsg) return + //allMessage += `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆 🐶${$.message}${$.index !== cookiesArr.length ? '\n\n' : ''}`; + + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `账号${$.index}:${$.nickName || $.UserName}\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}京豆 🐶${$.message}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + // } + + ReturnMessage=`📣=============账号${$.index}=============📣\n` + ReturnMessage+=`账号名称:${$.nickName || $.UserName}\n`; + ReturnMessage+=`今日收入:${$.todayIncomeBean}京豆 🐶\n`; + ReturnMessage+=`昨日支出:${$.expenseBean}京豆 🐶\n`; + ReturnMessage+=`昨日收入:${$.incomeBean}京豆 🐶\n`; + ReturnMessage+=`当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶\n`; + + message += "" + `当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶\n` +"\n\n" + message += "" +`今日收入:${$.todayIncomeBean}京豆 🐶\n` + "\n\n" + message += "" + `昨日收入:${$.incomeBean}京豆 🐶\n` +"\n\n" + message += "" +`昨日支出:${$.expenseBean}京豆 🐶\n` +"\n\n" + // message += "" +`🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶` +"\n\n" + + + if(typeof $.JDtotalcash !== "undefined"){ + ReturnMessage+=`极速金币:${$.JDtotalcash}金币(≈${$.JDtotalcash / 10000}元)\n`; + message += "" + `极速金币:${$.JDtotalcash}金币(≈${$.JDtotalcash / 10000}元)\n` +"\n\n" + } + if(typeof $.JdzzNum !== "undefined"){ + ReturnMessage+=`京东赚赚:${$.JdzzNum}金币(≈${$.JdzzNum / 10000}元)\n`; + message += "" + `京东赚赚:${$.JdzzNum}金币(≈${$.JdzzNum / 10000}元)\n` +"\n\n" + } + if($.JdMsScore!=0){ + ReturnMessage+=`京东秒杀:${$.JdMsScore}秒秒币(≈${$.JdMsScore / 1000}元)\n`; + message += "" + `京东秒杀:${$.JdMsScore}秒秒币(≈${$.JdMsScore / 1000}元)\n` +"\n\n" + } + + // message += "" +`🏭🏭🏭🏭🏭🏭🏭🏭🏭🏭` +"\n\n" + + + if(typeof $.JDEggcnt !== "undefined"){ + ReturnMessage+=`京喜牧场:${$.JDEggcnt}枚鸡蛋\n`; + message += "" + `京喜牧场:${$.JDEggcnt}枚鸡蛋\n` +"\n\n" + } + if($.JdFarmProdName != ""){ + if($.JdtreeEnergy!=0){ + ReturnMessage+=`东东农场:${$.JdFarmProdName},进度${(($.JdtreeEnergy / $.JdtreeTotalEnergy) * 100).toFixed(2)}%`; + message += "" + `东东农场:${$.JdFarmProdName},进度${(($.JdtreeEnergy / $.JdtreeTotalEnergy) * 100).toFixed(2)}%` + if($.JdwaterD!='Infinity' && $.JdwaterD!='-Infinity'){ + ReturnMessage+=`,${$.JdwaterD === 1 ? '明天' : $.JdwaterD === 2 ? '后天' : $.JdwaterD + '天后'}可兑🍉\n`; + message += "" + `,${$.JdwaterD === 1 ? '明天' : $.JdwaterD === 2 ? '后天' : $.JdwaterD + '天后'}可兑🍉\n` +"\n\n" + } else { + ReturnMessage+=`\n` + "\n\n"; + } + } else { + ReturnMessage+=`东东农场:${$.JdFarmProdName}\n`; + message += "" +`东东农场:${$.JdFarmProdName}\n` +"\n\n" + } + } + if ($.jxFactoryInfo) { + ReturnMessage += `京喜工厂:${$.jxFactoryInfo}🏭\n` + message += "" + `京喜工厂:${$.jxFactoryInfo}🏭\n` +"\n\n" + } + if ($.ddFactoryInfo) { + ReturnMessage += `东东工厂:${$.ddFactoryInfo}🏭\n` + message += "" + `东东工厂:${$.ddFactoryInfo}🏭\n` +"\n\n" + } + + const response = await await PetRequest('energyCollect'); + const initPetTownRes = await PetRequest('initPetTown'); + if (initPetTownRes.code === '0' && initPetTownRes.resultCode === '0' && initPetTownRes.message === 'success') { + $.petInfo = initPetTownRes.result; + if (response.resultCode === '0') { + ReturnMessage += `东东萌宠:${$.petInfo.goodsInfo.goodsName},`; + ReturnMessage += `勋章${response.result.medalNum}/${response.result.medalNum+response.result.needCollectMedalNum}块(${response.result.medalPercent}%)\n`; + //ReturnMessage += ` 已有${response.result.medalNum}块勋章,还需${response.result.needCollectMedalNum}块\n`; + message += "" +`东东萌宠:${$.petInfo.goodsInfo.goodsName},` + message += "" + `勋章${response.result.medalNum}/${response.result.medalNum+response.result.needCollectMedalNum}块(${response.result.medalPercent}%)\n` +"\n\n" + + } + } + ReturnMessage+=`🧧🧧🧧🧧红包明细🧧🧧🧧🧧`; + message += "" +`🧧🧧🧧🧧红包明细🧧🧧🧧🧧` + "\n\n" + ReturnMessage+=`${$.message}\n\n`; + message += "" + `${$.message}\n\n` +"\n\n" + allMessage+=ReturnMessage; + $.msg($.name, '', ReturnMessage , {"open-url": "https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean"}); +} +async function bean() { + // console.log(`北京时间零点时间戳:${parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000}`); + // console.log(`北京时间2020-10-28 06:16:05::${new Date("2020/10/28 06:16:05+08:00").getTime()}`) + // 不管哪个时区。得到都是当前时刻北京时间的时间戳 new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000 + + //前一天的0:0:0时间戳 + const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - (24 * 60 * 60 * 1000); + // 今天0:0:0时间戳 + const tm1 = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + let page = 1, t = 0, yesterdayArr = [], todayArr = []; + do { + let response = await getJingBeanBalanceDetail(page); + // console.log(`第${page}页: ${JSON.stringify(response)}`); + if (response && response.code === "0") { + page++; + let detailList = response.detailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const date = item.date.replace(/-/g, '/') + "+08:00"; + if (new Date(date).getTime() >= tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + todayArr.push(item); + } else if (tm <= new Date(date).getTime() && new Date(date).getTime() < tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + //昨日的 + yesterdayArr.push(item); + } else if (tm > new Date(date).getTime()) { + //前天的 + t = 1; + break; + } + } + } else { + //$.errorMsg = `数据异常`; + //$.msg($.name, ``, `账号${$.index}:${$.nickName}\n${$.errorMsg}`); + t = 1; + } + } else if (response && response.code === "3") { + console.log(`cookie已过期,或者填写不规范,跳出`) + t = 1; + } else { + console.log(`未知情况:${JSON.stringify(response)}`); + console.log(`未知情况,跳出`) + t = 1; + } + } while (t === 0); + for (let item of yesterdayArr) { + if (Number(item.amount) > 0) { + $.incomeBean += Number(item.amount); + } else if (Number(item.amount) < 0) { + $.expenseBean += Number(item.amount); + } + } + for (let item of todayArr) { + if (Number(item.amount) > 0) { + $.todayIncomeBean += Number(item.amount); + } + } + await queryexpirejingdou();//过期京豆 + await redPacket();//过期红包 + // console.log(`昨日收入:${$.incomeBean}个京豆 🐶`); + // console.log(`昨日支出:${$.expenseBean}个京豆 🐶`) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + if (data['retcode'] === '0' && data.data && data.data['assetInfo']) { + $.beanCount = data.data && data.data['assetInfo']['beanNum']; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} +function getJingBeanBalanceDetail(page) { + return new Promise(async resolve => { + const options = { + "url": `https://api.m.jd.com/client.action?functionId=getJingBeanBalanceDetail`, + "body": `body=${escape(JSON.stringify({"pageSize": "20", "page": page.toString()}))}&appid=ld`, + "headers": { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + // console.log(data) + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function queryexpirejingdou() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=${Date.now()}&g_login_type=1&sceneval=2`, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Host": "wq.jd.com", + "Referer": "https://wqs.jd.com/promote/201801/bean/mybean.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1" + } + } + $.expirejingdou = 0; + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // console.log(data) + data = JSON.parse(data.slice(23, -13)); + // console.log(data) + if (data.ret === 0) { + data['expirejingdou'].map(item => { + console.log(`${timeFormat(item['time'] * 1000)}日过期京豆:${item['expireamount']}\n`); + }) + $.expirejingdou = data['expirejingdou'][0]['expireamount']; + // if ($.expirejingdou > 0) { + // $.message += `\n今日将过期:${$.expirejingdou}京豆 🐶`; + // } + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function redPacket() { + return new Promise(async resolve => { + const options = { + "url": `https://m.jingxi.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=1&_=${+new Date()}&sceneval=2&g_login_type=1&g_ty=ls`, + "headers": { + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://st.jingxi.com/my/redpacket.shtml?newPg=App&jxsid=16156262265849285961', + 'Accept-Encoding': 'gzip, deflate, br', + "Cookie": cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data).data + $.jxRed = 0, $.jsRed = 0, $.jdRed = 0, $.jdhRed = 0, $.jxRedExpire = 0, $.jsRedExpire = 0, $.jdRedExpire = 0, $.jdhRedExpire = 0; + let t = new Date() + t.setDate(t.getDate() + 1) + t.setHours(0, 0, 0, 0) + t = parseInt((t - 1) / 1000) + for (let vo of data.useRedInfo.redList || []) { + if (vo.orgLimitStr && vo.orgLimitStr.includes("京喜")) { + $.jxRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jxRedExpire += parseFloat(vo.balance) + } + } else if (vo.activityName.includes("极速版")) { + $.jsRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jsRedExpire += parseFloat(vo.balance) + } + } else if (vo.orgLimitStr && vo.orgLimitStr.includes("京东健康")) { + $.jdhRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdhRedExpire += parseFloat(vo.balance) + } + } else { + $.jdRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdRedExpire += parseFloat(vo.balance) + } + } + } + $.jxRed = $.jxRed.toFixed(2) + $.jsRed = $.jsRed.toFixed(2) + $.jdRed = $.jdRed.toFixed(2) + $.jdhRed = $.jdhRed.toFixed(2) + $.balance = data.balance + $.expiredBalance = ($.jxRedExpire + $.jsRedExpire + $.jdRedExpire).toFixed(2) + // $.message += `\n当前总红包:${$.balance}(今日总过期${$.expiredBalance})元 🧧\n京喜红包:${$.jxRed}(今日将过期${$.jxRedExpire.toFixed(2)})元 🧧\n极速红包:${$.jsRed}(今日将过期${$.jsRedExpire.toFixed(2)})元 🧧\n京东红包:${$.jdRed}(今日将过期${$.jdRedExpire.toFixed(2)})元 🧧\n健康红包:${$.jdhRed}(今日将过期${$.jdhRedExpire.toFixed(2)})元 🧧`; + + $.message += "" + `【当前总红包】:${$.balance}( 今日总过期${$.expiredBalance} )元 🧧` +"\n\n" + $.message += "" + `【京喜红包】:${$.jxRed}( 今日将过期${$.jxRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【极速红包】:${$.jsRed}( 今日将过期${$.jsRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【京东红包】:${$.jdRed}( 今日将过期${$.jdRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【健康红包】:${$.jdhRed}( 今日将过期${$.jdhRedExpire.toFixed(2)} )元 🧧` +"\n\n" + + + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getJdZZ() { + return new Promise(resolve => { + $.get(taskJDZZUrl("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JdzzNum = data.data.totalNum + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function taskJDZZUrl(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +function getMs() { + return new Promise(resolve => { + $.post(taskMsPostUrl('homePageV2', {}, 'appid=SecKill2020'), (err, resp, data) => { + try { + if (err) { + console.log(`${err},${jsonParse(resp.body)['message']}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data) + if (data.code === 2041) { + $.JdMsScore = data.result.assignment.assignmentPoints || 0 + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + + +function taskMsPostUrl(function_id, body = {}, extra = '', function_id2) { + let url = `${JD_API_HOST}`; + if (function_id2) { + url += `?functionId=${function_id2}`; + } + return { + url, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=1.0.0&${extra}`, + headers: { + "Cookie": cookie, + "origin": "https://h5.m.jd.com", + "referer": "https://h5.m.jd.com/babelDiy/Zeus/2NUvze9e1uWf4amBhe1AV6ynmSuH/index.html", + 'Content-Type': 'application/x-www-form-urlencoded', + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + } + } +} + +async function getjdfruit() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Content-Type": "application/x-www-form-urlencoded" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + console.log('\n东东农场: API查询请求失败 ‼️‼️'); + console.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + if ($.farmInfo.farmUserPro) { + $.JdFarmProdName=$.farmInfo.farmUserPro.name; + $.JdtreeEnergy=$.farmInfo.farmUserPro.treeEnergy; + $.JdtreeTotalEnergy=$.farmInfo.farmUserPro.treeTotalEnergy; + + let waterEveryDayT = $.JDwaterEveryDayT; + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + $.JdwaterTotalT = waterTotalT; + $.JdwaterD = waterD; + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function jdfruitRequest(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskfruitUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n东东农场: API查询请求失败 ‼️‼️') + console.log(JSON.stringify(err)); + console.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JDwaterEveryDayT = data.totalWaterTaskInit.totalWaterTaskTimes; + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) +} + + +async function PetRequest(function_id, body = {}) { + await $.wait(3000); + return new Promise((resolve, reject) => { + $.post(taskPetUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n东东萌宠: API查询请求失败 ‼️‼️'); + console.log(JSON.stringify(err)); + $.logErr(err); + } else { + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data) + } + }) + }) +} +function taskPetUrl(function_id, body = {}) { + body["version"] = 2; + body["channel"] = 'app'; + return { + url: `${JD_API_HOST}?functionId=${function_id}`, + body: `body=${escape(JSON.stringify(body))}&appid=wh5&loginWQBiz=pet-town&clientVersion=9.0.4`, + headers: { + 'Cookie': cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + } + }; +} + +function taskfruitUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + }, + timeout: 10000, + } +} + +function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + console.log(e); + console.log(`京东服务器访问数据为空,请检查自身设备网络情况`); + return false; + } +} + +function cash() { + return new Promise(resolve => { + $.get(taskcashUrl('MyAssetsService.execute', + {"method": "userCashRecord", "data": {"channel": 1, "pageNum": 1, "pageSize": 20}}), + async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JDtotalcash = data.data.goldBalance ; + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "", "", "", "", "jsjia", "mi.com"]; + +function taskcashUrl(_0x7683x2, _0x7683x3 = {}) { + let _0x7683x4 = +new Date(); + let _0x7683x5 = `${__Oxb24bc[0x0]}${JSON[__Oxb24bc[0x1]](_0x7683x3)}${__Oxb24bc[0x2]}${_0x7683x2}${__Oxb24bc[0x3]}${_0x7683x4}${__Oxb24bc[0x4]}`; + let _0x7683x6 = __Oxb24bc[0x5]; + const _0x7683x7 = $[__Oxb24bc[0x6]]() ? require(__Oxb24bc[0x7]) : $.CryptoJS; + let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString(); + return { + url: `${__Oxb24bc[0x8]}${JD_API_HOST}${__Oxb24bc[0x9]}${_0x7683x2}${__Oxb24bc[0xa]}${escape(JSON[__Oxb24bc[0x1]](_0x7683x3))}${__Oxb24bc[0xb]}${_0x7683x4}${__Oxb24bc[0xc]}${_0x7683x8}${__Oxb24bc[0x8]}`, + headers: { + 'Host': __Oxb24bc[0xd], + 'accept': __Oxb24bc[0xe], + 'kernelplatform': __Oxb24bc[0xf], + 'user-agent': __Oxb24bc[0x10], + 'accept-language': __Oxb24bc[0x11], + 'Cookie': cookie + } + } +}(function(_0x7683x9, _0x7683xa, _0x7683xb, _0x7683xc, _0x7683xd, _0x7683xe) { + _0x7683xe = __Oxb24bc[0x12]; + _0x7683xc = function(_0x7683xf) { + if (typeof alert !== _0x7683xe) { + alert(_0x7683xf) + }; + if (typeof console !== _0x7683xe) { + console[__Oxb24bc[0x13]](_0x7683xf) + } + }; + _0x7683xb = function(_0x7683x7, _0x7683x9) { + return _0x7683x7 + _0x7683x9 + }; + _0x7683xd = _0x7683xb(__Oxb24bc[0x14], _0x7683xb(_0x7683xb(__Oxb24bc[0x15], __Oxb24bc[0x16]), __Oxb24bc[0x17])); + try { + _0x7683x9 = __encode; + if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === _0x7683xb(__Oxb24bc[0x18], __Oxb24bc[0x19]))) { + _0x7683xc(_0x7683xd) + } + } catch (e) { + _0x7683xc(_0x7683xd) + } +})({}) + +async function JxmcGetRequest() { + let url = ``; + let myRequest = ``; + url = `https://m.jingxi.com/jxmc/queryservice/GetHomePageInfo?channel=7&sceneid=1001&activeid=null&activekey=null&isgift=1&isquerypicksite=1&_stk=channel%2Csceneid&_ste=1`; + url += `&h5st=${decrypt(Date.now(), '', '', url)}&_=${Date.now() + 2}&sceneval=2&g_login_type=1&callback=jsonpCBK${String.fromCharCode(Math.floor(Math.random() * 26) + "A".charCodeAt(0))}&g_ty=ls`; + myRequest = getGetRequest(`GetHomePageInfo`, url); + + + return new Promise(async resolve => { + $.get(myRequest, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`API请求失败,请检查网路重试`) + $.runFlag = false; + console.log(`请求失败`) + } else { + data = JSON.parse(data.match(new RegExp(/jsonpCBK.?\((.*);*/))[1]); + if (data.ret === 0) { + $.JDEggcnt=data.data.eggcnt; + } + } + } catch (e) { + console.log(data); + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +// 惊喜工厂信息查询 +function getJxFactory() { + return new Promise(async resolve => { + let infoMsg = ""; + await $.get(jxTaskurl('userinfo/GetUserInfo', `pin=&sharePin=&shareType=&materialTuanPin=&materialTuanId=&source=`, '_time,materialTuanId,materialTuanPin,pin,sharePin,shareType,source,zone'), async (err, resp, data) => { + try { + if (err) { + $.jxFactoryInfo = "查询失败!"; + //console.log("jx工厂查询失败" + err) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['ret'] === 0) { + data = data['data']; + $.unActive = true;//标记是否开启了京喜活动或者选购了商品进行生产 + if (data.factoryList && data.productionList) { + const production = data.productionList[0]; + const factory = data.factoryList[0]; + //const productionStage = data.productionStage; + $.commodityDimId = production.commodityDimId; + // subTitle = data.user.pin; + await GetCommodityDetails();//获取已选购的商品信息 + infoMsg = `${$.jxProductName} ,进度:${((production.investedElectric / production.needElectric) * 100).toFixed(2)}%`; + if (production.investedElectric >= production.needElectric) { + if (production['exchangeStatus'] === 1) { + infoMsg = `${$.productName} ,已经可兑换,请手动兑换`; + } + if (production['exchangeStatus'] === 3) { + if (new Date().getHours() === 9) { + infoMsg = `${$.productName} ,兑换已超时,请选择新商品进行制造`; + } + } + // await exchangeProNotify() + } else { + infoMsg += ` ,预计:${((production.needElectric - production.investedElectric) / (2 * 60 * 60 * 24)).toFixed(2)}天可兑换` + } + if (production.status === 3) { + infoMsg = "${$.productName} ,已经超时失效, 请选择新商品进行制造" + } + } else { + $.unActive = false;//标记是否开启了京喜活动或者选购了商品进行生产 + if (!data.factoryList) { + // infoMsg = "当前未开始生产商品,请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动" + // $.msg($.name, '【提示】', `京东账号${$.index}[${$.nickName}]京喜工厂活动未开始\n请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动`); + } else if (data.factoryList && !data.productionList) { + // infoMsg = "当前未开始生产商品,请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动" + } + } + } + } else { + console.log(`GetUserInfo异常:${JSON.stringify(data)}`) + } + } + $.jxFactoryInfo = infoMsg; + // console.log(infoMsg); + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + } + ) +} + +// 惊喜的Taskurl +function jxTaskurl(functionId, body = '', stk) { + let url = `https://m.jingxi.com/dreamfactory/${functionId}?zone=dream_factory&${body}&sceneval=2&g_login_type=1&_time=${Date.now()}&_=${Date.now() + 2}&_ste=1` + url += `&h5st=${decrypt(Date.now(), stk, '', url)}` + if (stk) { + url += `&_stk=${encodeURIComponent(stk)}`; + } + return { + url, + headers: { + 'Cookie': cookie, + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'User-Agent': functionId === 'AssistFriend' ? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" : 'jdpingou', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://wqsd.jd.com/pingou/dream_factory/index.html', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +//惊喜查询当前生产的商品名称 +function GetCommodityDetails() { + return new Promise(async resolve => { + // const url = `/dreamfactory/diminfo/GetCommodityDetails?zone=dream_factory&sceneval=2&g_login_type=1&commodityId=${$.commodityDimId}`; + $.get(jxTaskurl('diminfo/GetCommodityDetails', `commodityId=${$.commodityDimId}`, `_time,commodityId,zone`), (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['ret'] === 0) { + data = data['data']; + $.jxProductName = data['commodityList'][0].name; + } else { + console.log(`GetCommodityDetails异常:${JSON.stringify(data)}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +// 东东工厂信息查询 +async function getDdFactoryInfo() { + // 当心仪的商品存在,并且收集起来的电量满足当前商品所需,就投入 + let infoMsg = ""; + return new Promise(resolve => { + $.post(ddFactoryTaskUrl('jdfactory_getHomeData'), async (err, resp, data) => { + try { + if (err) { + $.ddFactoryInfo = "获取失败!" + /*console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`)*/ + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data.bizCode === 0) { + // $.newUser = data.data.result.newUser; + //let wantProduct = $.isNode() ? (process.env.FACTORAY_WANTPRODUCT_NAME ? process.env.FACTORAY_WANTPRODUCT_NAME : wantProduct) : ($.getdata('FACTORAY_WANTPRODUCT_NAME') ? $.getdata('FACTORAY_WANTPRODUCT_NAME') : wantProduct); + if (data.data.result.factoryInfo) { + let { + totalScore, + useScore, + produceScore, + remainScore, + couponCount, + name + } = data.data.result.factoryInfo; + infoMsg = `${name} 剩余${couponCount};电力投入情况 ${useScore}/${totalScore};当前总电力:${remainScore * 1 + useScore * 1} ;完成度:${((remainScore * 1 + useScore * 1) / (totalScore * 1)).toFixed(2) * 100}%` + + if (((remainScore * 1 + useScore * 1) >= totalScore * 1 + 100000) && (couponCount * 1 > 0)) { + // await jdfactory_addEnergy(); + infoMsg = `${name} ,目前数量:${couponCount},当前总电量为:${remainScore * 1 + useScore * 1},已经可以兑换此商品所需总电量:${totalScore},请🔥速去活动页面查看` + } + + } else { + // infoMsg = `当前未选择商品(或未开启活动) , 请到京东APP=>首页=>京东电器=>(底栏)东东工厂 选择商品!` + } + } else { + $.ddFactoryInfo = "获取失败!" + console.log(`异常:${JSON.stringify(data)}`) + } + } + } + $.ddFactoryInfo = infoMsg; + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function ddFactoryTaskUrl(function_id, body = {}, function_id2) { + let url = `${JD_API_HOST}`; + if (function_id2) { + url += `?functionId=${function_id2}`; + } + return { + url, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=1.1.0`, + headers: { + "Accept": "application/json, text/plain, */*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": cookie, + "Host": "api.m.jd.com", + "Origin": "https://h5.m.jd.com", + "Referer": "https://h5.m.jd.com/babelDiy/Zeus/2uSsV2wHEkySvompfjB43nuKkcHp/index.html", + "User-Agent": "jdapp;iPhone;9.3.4;14.3;88732f840b77821b345bf07fd71f609e6ff12f43;network/4g;ADID/1C141FDD-C62F-425B-8033-9AAB7E4AE6A3;supportApplePay/0;hasUPPay/0;hasOCPay/0;model/iPhone11,8;addressid/2005183373;supportBestPay/0;appBuild/167502;jdSupportDarkMode/0;pv/414.19;apprpd/Babel_Native;ref/TTTChannelViewContoller;psq/5;ads/;psn/88732f840b77821b345bf07fd71f609e6ff12f43|1701;jdv/0|iosapp|t_335139774|appshare|CopyURL|1610885480412|1610885486;adk/;app_device/IOS;pap/JA2015_311210|9.3.4|IOS 14.3;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", + }, + timeout: 10000, + } +} +function randomString(e) { + e = e || 32; + let t = "0123456789abcdef", a = t.length, n = ""; + for (let i = 0; i < e; i++) + n += t.charAt(Math.floor(Math.random() * a)); + return n +} + +function getGetRequest(type, url) { + UA = `jdpingou;iPhone;4.13.0;14.4.2;${randomString(40)};network/wifi;model/iPhone10,2;appBuild/100609;ADID/00000000-0000-0000-0000-000000000000;supportApplePay/1;hasUPPay/0;pushNoticeIsOpen/1;hasOCPay/0;supportBestPay/0;session/${Math.random * 98 + 1};pap/JA2019_3111789;brand/apple;supportJDSHWK/1;Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148` + + const method = `GET`; + let headers = { + 'Origin': `https://st.jingxi.com`, + 'Cookie': cookie, + 'Connection': `keep-alive`, + 'Accept': `application/json`, + 'Referer': `https://st.jingxi.com/pingou/jxmc/index.html`, + 'Host': `m.jingxi.com`, + 'User-Agent': UA, + 'Accept-Encoding': `gzip, deflate, br`, + 'Accept-Language': `zh-cn` + }; + return {url: url, method: method, headers: headers}; +} + + +Date.prototype.Format = function (fmt) { + var e, + n = this, d = fmt, l = { + "M+": n.getMonth() + 1, + "d+": n.getDate(), + "D+": n.getDate(), + "h+": n.getHours(), + "H+": n.getHours(), + "m+": n.getMinutes(), + "s+": n.getSeconds(), + "w+": n.getDay(), + "q+": Math.floor((n.getMonth() + 3) / 3), + "S+": n.getMilliseconds() + }; + /(y+)/i.test(d) && (d = d.replace(RegExp.$1, "".concat(n.getFullYear()).substr(4 - RegExp.$1.length))); + for (var k in l) { + if (new RegExp("(".concat(k, ")")).test(d)) { + var t, a = "S+" === k ? "000" : "00"; + d = d.replace(RegExp.$1, 1 == RegExp.$1.length ? l[k] : ("".concat(a) + l[k]).substr("".concat(l[k]).length)) + } + } + return d; +} + +function decrypt(time, stk, type, url) { + stk = stk || (url ? getJxmcUrlData(url, '_stk') : '') + if (stk) { + const timestamp = new Date(time).Format("yyyyMMddhhmmssSSS"); + let hash1 = ''; + if ($.fingerprint && $.Jxmctoken && $.enCryptMethodJD) { + hash1 = $.enCryptMethodJD($.Jxmctoken, $.fingerprint.toString(), timestamp.toString(), $.appId.toString(), $.CryptoJS).toString($.CryptoJS.enc.Hex); + } else { + const random = '5gkjB6SpmC9s'; + $.Jxmctoken = `tk01wcdf61cb3a8nYUtHcmhSUFFCfddDPRvKvYaMjHkxo6Aj7dhzO+GXGFa9nPXfcgT+mULoF1b1YIS1ghvSlbwhE0Xc`; + $.fingerprint = 5287160221454703; + const str = `${$.Jxmctoken}${$.fingerprint}${timestamp}${$.appId}${random}`; + hash1 = $.CryptoJS.SHA512(str, $.Jxmctoken).toString($.CryptoJS.enc.Hex); + } + let st = ''; + stk.split(',').map((item, index) => { + st += `${item}:${getJxmcUrlData(url, item)}${index === stk.split(',').length - 1 ? '' : '&'}`; + }) + const hash2 = $.CryptoJS.HmacSHA256(st, hash1.toString()).toString($.CryptoJS.enc.Hex); + return encodeURIComponent(["".concat(timestamp.toString()), "".concat($.fingerprint.toString()), "".concat($.appId.toString()), "".concat($.Jxmctoken), "".concat(hash2)].join(";")) + } else { + return '20210318144213808;8277529360925161;10001;tk01w952a1b73a8nU0luMGtBanZTHCgj0KFVwDa4n5pJ95T/5bxO/m54p4MtgVEwKNev1u/BUjrpWAUMZPW0Kz2RWP8v;86054c036fe3bf0991bd9a9da1a8d44dd130c6508602215e50bb1e385326779d' + } +} + +async function requestAlgo() { + $.fingerprint = await generateFp(); + $.appId = 10028; + const options = { + "url": `https://cactus.jd.com/request_algo?g_ty=ajax`, + "headers": { + 'Authority': 'cactus.jd.com', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + 'Accept': 'application/json', + 'User-Agent':$.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + //'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1', + 'Content-Type': 'application/json', + 'Origin': 'https://st.jingxi.com', + 'Sec-Fetch-Site': 'cross-site', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Dest': 'empty', + 'Referer': 'https://st.jingxi.com/', + 'Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7' + }, + 'body': JSON.stringify({ + "version": "1.0", + "fp": $.fingerprint, + "appId": $.appId.toString(), + "timestamp": Date.now(), + "platform": "web", + "expandParams": "" + }) + } + new Promise(async resolve => { + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`request_algo 签名参数API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['status'] === 200) { + $.Jxmctoken = data.data.result.tk; + let enCryptMethodJDString = data.data.result.algo; + // if (enCryptMethodJDString) $.enCryptMethodJD = new Function(`return ${enCryptMethodJDString}`)(); + eval(enCryptMethodJDString+';$.enCryptMethodJD=test'); + } else { + console.log('request_algo 签名参数API请求失败:') + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function generateFp() { + let e = "0123456789"; + let a = 13; + let i = ''; + for (; a--;) + i += e[Math.random() * e.length | 0]; + return (i + Date.now()).slice(0, 16) +} + +function getJxmcUrlData(url, name) { + if (typeof URL !== "undefined") { + let urls = new URL(url); + let data = urls.searchParams.get(name); + return data ? data : ''; + } else { + const query = url.match(/\?.*/)[0].substring(1) + const vars = query.split('&') + for (let i = 0; i < vars.length; i++) { + const pair = vars[i].split('=') + if (pair[0] === name) { + return vars[i].substr(vars[i].indexOf('=') + 1); + } + } + return '' + } +} + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} + + +// prettier-ignore +function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + + +//我加的函数 +function postToDingTalk(messgae) { + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"资产变动", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} diff --git a/src/main/resources/test_bean.js b/src/main/resources/test_bean.js new file mode 100644 index 0000000..72a38c1 --- /dev/null +++ b/src/main/resources/test_bean.js @@ -0,0 +1,839 @@ +/* +种豆得豆 脚本更新地址:https://raw.githubusercontent.com/Aaron-lv/sync/jd_scripts/jd_plantBean.js +更新时间:2021-04-9 +活动入口:动动APP我的-更多工具-种豆得豆 +已支持IOS动动多账号,云端多动动账号 +脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js +注:会自动关注任务中的店铺跟商品,介意者勿使用。 +互助码shareCode请先手动运行脚本查看打印可看到 +每个动动账号每天只能帮助3个人。多出的助力码将会助力失败。 +=====================================Quantumult X================================= +[task_local] +1 7-21/2 * * * https://raw.githubusercontent.com/Aaron-lv/sync/jd_scripts/jd_plantBean.js, tag=种豆得豆, img-url=https://raw.githubusercontent.com/58xinian/icon/master/jdzd.png, enabled=true + +=====================================Loon================================ +[Script] +cron "1 7-21/2 * * *" script-path=https://raw.githubusercontent.com/Aaron-lv/sync/jd_scripts/jd_plantBean.js,tag=动动种豆得豆 + +======================================Surge========================== +动动种豆得豆 = type=cron,cronexp="1 7-21/2 * * *",wake-system=1,timeout=3600,script-path=https://raw.githubusercontent.com/Aaron-lv/sync/jd_scripts/jd_plantBean.js + +====================================小火箭============================= +动动种豆得豆 = type=cron,script-path=https://raw.githubusercontent.com/Aaron-lv/sync/jd_scripts/jd_plantBean.js, cronexpr="1 7-21/2 * * *", timeout=3600, enable=true + +*/ +const $ = new Env('动动种豆得豆'); +//Node.js用户请在jdCookie.js处填写动动ck; +//ios等软件用户直接用NobyDa的jd cookie +let jdNotify = true;//是否开启静默运行。默认true开启 +let cookiesArr = [], cookie = '', jdPlantBeanShareArr = [], isBox = false, notify, newShareCodes, option,subTitle; +let message = "" +//动动接口地址 +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +//助力好友分享码(最多3个,否则后面的助力失败) +//此此内容是IOS用户下载脚本到本地使用,填写互助码的地方,同一动动账号的好友互助码请使用@符号隔开。 +//下面给出两个账号的填写示例(iOS只支持2个动动账号) +let shareCodes = [''] +let allMessage = ``; +let currentRoundId = null;//本期活动id +let lastRoundId = null;//上期id +let roundList = []; +let awardState = '';//上期活动的豆豆是否收取 +let randomCount = $.isNode() ? 20 : 5; +let num; +!(async () => { + message += "[通知] 种豆得豆 \n\n --- \n\n" + await requireConfig(); + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + + + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + await TotalBean(); + console.log(`\n开始【动动账号${$.index}】${$.nickName || $.UserName}\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + subTitle = ''; + option = {}; + await shareCodesFormat(); + await jdPlantBean(); + await showMsg(); + } + + message += "----\n\n" + } + + that.log(message) + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`) + } +})().catch((e) => { + message += " " + `❌ ${$.name}, 失败! 原因: ${e}!` + "\n\n" + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') +}).finally(() => { + // message += getPic() + that.log(message) + postToDingTalk(message) + $.done(); +}) + +async function jdPlantBean() { + try { + console.log(`获取任务及基本信息`) + await plantBeanIndex(); + for (let i = 0; i < $.plantBeanIndexResult.data.roundList.length; i++) { + if ($.plantBeanIndexResult.data.roundList[i].roundState === "2") { + num = i + break + } + } + // console.log(plantBeanIndexResult.data.taskList); + if ($.plantBeanIndexResult && $.plantBeanIndexResult.code === '0' && $.plantBeanIndexResult.data) { + const shareUrl = $.plantBeanIndexResult.data.jwordShareInfo.shareUrl + $.myPlantUuid = getParam(shareUrl, 'plantUuid') + console.log(`\n【动动账号${$.index}(${$.UserName})的${$.name}好友互助码】${$.myPlantUuid}\n`); + roundList = $.plantBeanIndexResult.data.roundList; + currentRoundId = roundList[num].roundId;//本期的roundId + lastRoundId = roundList[num - 1].roundId;//上期的roundId + awardState = roundList[num - 1].awardState; + $.taskList = $.plantBeanIndexResult.data.taskList; + subTitle = `【动动昵称】${$.plantBeanIndexResult.data.plantUserInfo.plantNickName}`; + message += " " + `【上期时间】${roundList[num - 1].dateDesc.replace('上期 ', '')}\n` + "\n\n"; + message += " " + `【上期成长值】${roundList[num - 1].growth}\n` + "\n\n"; + await receiveNutrients();//定时领取营养液 + await doHelp();//助力 + await doTask();//做日常任务 + await doEgg(); + await stealFriendWater(); + await doCultureBean(); + await doGetReward(); + await showTaskProcess(); + await plantShareSupportList(); + } else { + console.log(`种豆得豆-初始失败: ${JSON.stringify($.plantBeanIndexResult)}`); + } + } catch (e) { + $.logErr(e); + const errMsg = `动动账号${$.index} ${$.nickName || $.UserName}\n任务执行异常,请检查执行日志 ‼️‼️`; + if ($.isNode()) await notify.sendNotify(`${$.name}`, errMsg); + $.msg($.name, '', `${errMsg}`) + } +} +async function doGetReward() { + console.log(`【上轮豆豆】${awardState === '4' ? '采摘中' : awardState === '5' ? '可收获了' : '已领取'}`); + if (awardState === '4') { + //豆豆采摘中... + message += "" + `【上期状态】${roundList[num - 1].tipBeanEndTitle}\n` + "\n\n"; + } else if (awardState === '5') { + //收获 + await getReward(); + console.log('开始领取豆豆'); + if ($.getReward && $.getReward.code === '0') { + console.log('豆豆领取成功'); + message += "" + `【上期兑换豆豆】${$.getReward.data.awardBean}个\n` + "\n\n"; + $.msg($.name, subTitle, message); + allMessage += `动动账号${$.index} ${$.nickName}\n${message}${$.index !== cookiesArr.length ? '\n\n' : ''}` + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}`, `动动账号${$.index} ${$.nickName}\n${message}`); + // } + } else { + console.log(`$.getReward 异常:${JSON.stringify($.getReward)}`) + } + } else if (awardState === '6') { + //豆豆已领取 + message += "" + `【上期兑换豆豆】${roundList[num - 1].awardBeans}个\n` + "\n\n"; + } + if (roundList[num].dateDesc.indexOf('本期 ') > -1) { + roundList[num].dateDesc = roundList[num].dateDesc.substr(roundList[num].dateDesc.indexOf('本期 ') + 3, roundList[num].dateDesc.length); + } + message += "" + `【本期时间】${roundList[num].dateDesc}\n` + "\n\n"; + message += "" + `【本期成长值】${roundList[num].growth}\n` + "\n\n"; +} +async function doCultureBean() { + await plantBeanIndex(); + if ($.plantBeanIndexResult && $.plantBeanIndexResult.code === '0') { + const plantBeanRound = $.plantBeanIndexResult.data.roundList[num] + if (plantBeanRound.roundState === '2') { + //收取营养液 + if (plantBeanRound.bubbleInfos && plantBeanRound.bubbleInfos.length) console.log(`开始收取营养液`) + for (let bubbleInfo of plantBeanRound.bubbleInfos) { + console.log(`收取-${bubbleInfo.name}-的营养液`) + await cultureBean(plantBeanRound.roundId, bubbleInfo.nutrientsType) + console.log(`收取营养液结果:${JSON.stringify($.cultureBeanRes)}`) + } + } + } else { + console.log(`plantBeanIndexResult:${JSON.stringify($.plantBeanIndexResult)}`) + } +} +async function stealFriendWater() { + await stealFriendList(); + if ($.stealFriendList && $.stealFriendList.code === '0') { + if ($.stealFriendList.data && $.stealFriendList.data.tips) { + console.log('\n\n今日偷取好友营养液已达上限\n\n'); + return + } + if ($.stealFriendList.data && $.stealFriendList.data.friendInfoList && $.stealFriendList.data.friendInfoList.length > 0) { + let nowTimes = new Date(new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000); + for (let item of $.stealFriendList.data.friendInfoList) { + if (new Date(nowTimes).getHours() === 20) { + if (item.nutrCount >= 2) { + // console.log(`可以偷的好友的信息::${JSON.stringify(item)}`); + console.log(`可以偷的好友的信息paradiseUuid::${JSON.stringify(item.paradiseUuid)}`); + await collectUserNutr(item.paradiseUuid); + console.log(`偷取好友营养液情况:${JSON.stringify($.stealFriendRes)}`) + if ($.stealFriendRes && $.stealFriendRes.code === '0') { + console.log(`偷取好友营养液成功`) + } + } + } else { + if (item.nutrCount >= 3) { + // console.log(`可以偷的好友的信息::${JSON.stringify(item)}`); + console.log(`可以偷的好友的信息paradiseUuid::${JSON.stringify(item.paradiseUuid)}`); + await collectUserNutr(item.paradiseUuid); + console.log(`偷取好友营养液情况:${JSON.stringify($.stealFriendRes)}`) + if ($.stealFriendRes && $.stealFriendRes.code === '0') { + console.log(`偷取好友营养液成功`) + } + } + } + } + } + } else { + console.log(`$.stealFriendList 异常: ${JSON.stringify($.stealFriendList)}`) + } +} +async function doEgg() { + await egg(); + if ($.plantEggLotteryRes && $.plantEggLotteryRes.code === '0') { + if ($.plantEggLotteryRes.data.restLotteryNum > 0) { + const eggL = new Array($.plantEggLotteryRes.data.restLotteryNum).fill(''); + console.log(`目前共有${eggL.length}次扭蛋的机会`) + for (let i = 0; i < eggL.length; i++) { + console.log(`开始第${i + 1}次扭蛋`); + await plantEggDoLottery(); + console.log(`天天扭蛋成功:${JSON.stringify($.plantEggDoLotteryResult)}`); + } + } else { + console.log('暂无扭蛋机会') + } + } else { + console.log('查询天天扭蛋的机会失败' + JSON.stringify($.plantEggLotteryRes)) + } +} +async function doTask() { + if ($.taskList && $.taskList.length > 0) { + for (let item of $.taskList) { + if (item.isFinished === 1) { + console.log(`${item.taskName} 任务已完成\n`); + continue; + } else { + if (item.taskType === 8) { + console.log(`\n【${item.taskName}】任务未完成,需自行手动去动动APP完成,${item.desc}营养液\n`) + } else { + console.log(`\n【${item.taskName}】任务未完成,${item.desc}营养液\n`) + } + } + if (item.dailyTimes === 1 && item.taskType !== 8) { + console.log(`\n开始做 ${item.taskName}任务`); + // $.receiveNutrientsTaskRes = await receiveNutrientsTask(item.taskType); + await receiveNutrientsTask(item.taskType); + console.log(`做 ${item.taskName}任务结果:${JSON.stringify($.receiveNutrientsTaskRes)}\n`); + } + if (item.taskType === 3) { + //浏览店铺 + console.log(`开始做 ${item.taskName}任务`); + let unFinishedShopNum = item.totalNum - item.gainedNum; + if (unFinishedShopNum === 0) { + continue + } + await shopTaskList(); + const { data } = $.shopTaskListRes; + let goodShopListARR = [], moreShopListARR = [], shopList = []; + const { goodShopList, moreShopList } = data; + for (let i of goodShopList) { + if (i.taskState === '2') { + goodShopListARR.push(i); + } + } + for (let j of moreShopList) { + if (j.taskState === '2') { + moreShopListARR.push(j); + } + } + shopList = goodShopListARR.concat(moreShopListARR); + for (let shop of shopList) { + const { shopId, shopTaskId } = shop; + const body = { + "monitor_refer": "plant_shopNutrientsTask", + "shopId": shopId, + "shopTaskId": shopTaskId + } + const shopRes = await requestGet('shopNutrientsTask', body); + console.log(`shopRes结果:${JSON.stringify(shopRes)}`); + if (shopRes && shopRes.code === '0') { + if (shopRes.data && shopRes.data.nutrState && shopRes.data.nutrState === '1') { + unFinishedShopNum --; + } + } + if (unFinishedShopNum <= 0) { + console.log(`${item.taskName}任务已做完\n`) + break; + } + } + } + if (item.taskType === 5) { + //挑选商品 + console.log(`开始做 ${item.taskName}任务`); + let unFinishedProductNum = item.totalNum - item.gainedNum; + if (unFinishedProductNum === 0) { + continue + } + await productTaskList(); + // console.log('productTaskList', $.productTaskList); + const { data } = $.productTaskList; + let productListARR = [], productList = []; + const { productInfoList } = data; + for (let i = 0; i < productInfoList.length; i++) { + for (let j = 0; j < productInfoList[i].length; j++){ + productListARR.push(productInfoList[i][j]); + } + } + for (let i of productListARR) { + if (i.taskState === '2') { + productList.push(i); + } + } + for (let product of productList) { + const { skuId, productTaskId } = product; + const body = { + "monitor_refer": "plant_productNutrientsTask", + "productTaskId": productTaskId, + "skuId": skuId + } + const productRes = await requestGet('productNutrientsTask', body); + if (productRes && productRes.code === '0') { + // console.log('nutrState', productRes) + //这里添加多重判断,有时候会出现活动太火爆的问题,导致nutrState没有 + if (productRes.data && productRes.data.nutrState && productRes.data.nutrState === '1') { + unFinishedProductNum --; + } + } + if (unFinishedProductNum <= 0) { + console.log(`${item.taskName}任务已做完\n`) + break; + } + } + } + if (item.taskType === 10) { + //关注频道 + console.log(`开始做 ${item.taskName}任务`); + let unFinishedChannelNum = item.totalNum - item.gainedNum; + if (unFinishedChannelNum === 0) { + continue + } + await plantChannelTaskList(); + const { data } = $.plantChannelTaskList; + // console.log('goodShopList', data.goodShopList); + // console.log('moreShopList', data.moreShopList); + let goodChannelListARR = [], normalChannelListARR = [], channelList = []; + const { goodChannelList, normalChannelList } = data; + for (let i of goodChannelList) { + if (i.taskState === '2') { + goodChannelListARR.push(i); + } + } + for (let j of normalChannelList) { + if (j.taskState === '2') { + normalChannelListARR.push(j); + } + } + channelList = goodChannelListARR.concat(normalChannelListARR); + for (let channelItem of channelList) { + const { channelId, channelTaskId } = channelItem; + const body = { + "channelId": channelId, + "channelTaskId": channelTaskId + } + const channelRes = await requestGet('plantChannelNutrientsTask', body); + console.log(`channelRes结果:${JSON.stringify(channelRes)}`); + if (channelRes && channelRes.code === '0') { + if (channelRes.data && channelRes.data.nutrState && channelRes.data.nutrState === '1') { + unFinishedChannelNum --; + } + } + if (unFinishedChannelNum <= 0) { + console.log(`${item.taskName}任务已做完\n`) + break; + } + } + } + } + } +} +function showTaskProcess() { + return new Promise(async resolve => { + await plantBeanIndex(); + $.taskList = $.plantBeanIndexResult.data.taskList; + if ($.taskList && $.taskList.length > 0) { + console.log(" 任务 进度"); + for (let item of $.taskList) { + console.log(`[${item["taskName"]}] ${item["gainedNum"]}/${item["totalNum"]} ${item["isFinished"]}`); + } + } + resolve() + }) +} +//助力好友 +async function doHelp() { + for (let plantUuid of newShareCodes) { + console.log(`开始助力动动账号${$.index} - ${$.nickName}的好友: ${plantUuid}`); + if (!plantUuid) continue; + if (plantUuid === $.myPlantUuid) { + console.log(`\n跳过自己的plantUuid\n`) + continue + } + await helpShare(plantUuid); + if ($.helpResult && $.helpResult.code === '0') { + // console.log(`助力好友结果: ${JSON.stringify($.helpResult.data.helpShareRes)}`); + if ($.helpResult.data.helpShareRes) { + if ($.helpResult.data.helpShareRes.state === '1') { + console.log(`助力好友${plantUuid}成功`) + console.log(`${$.helpResult.data.helpShareRes.promptText}\n`); + } else if ($.helpResult.data.helpShareRes.state === '2') { + console.log('您今日助力的机会已耗尽,已不能再帮助好友助力了\n'); + break; + } else if ($.helpResult.data.helpShareRes.state === '3') { + console.log('该好友今日已满9人助力/20瓶营养液,明天再来为Ta助力吧\n') + } else if ($.helpResult.data.helpShareRes.state === '4') { + console.log(`${$.helpResult.data.helpShareRes.promptText}\n`) + } else { + console.log(`助力其他情况:${JSON.stringify($.helpResult.data.helpShareRes)}`); + } + } + } else { + console.log(`助力好友失败: ${JSON.stringify($.helpResult)}`); + } + } +} +function showMsg() { + $.log(`\n${message}\n`); + jdNotify = $.getdata('jdPlantBeanNotify') ? $.getdata('jdPlantBeanNotify') : jdNotify; + if (!jdNotify || jdNotify === 'false') { + $.msg($.name, subTitle, message); + } +} +// ================================================此处是API================================= +//每轮种豆活动获取结束后,自动收取豆豆 +async function getReward() { + const body = { + "roundId": lastRoundId + } + $.getReward = await request('receivedBean', body); +} +//收取营养液 +async function cultureBean(currentRoundId, nutrientsType) { + let functionId = arguments.callee.name.toString(); + let body = { + "roundId": currentRoundId, + "nutrientsType": nutrientsType, + } + $.cultureBeanRes = await request(functionId, body); +} +//偷营养液大于等于3瓶的好友 +//①查询好友列表 +async function stealFriendList() { + const body = { + pageNum: '1' + } + $.stealFriendList = await request('plantFriendList', body); +} + +//②执行偷好友营养液的动作 +async function collectUserNutr(paradiseUuid) { + console.log('开始偷好友'); + // console.log(paradiseUuid); + let functionId = arguments.callee.name.toString(); + const body = { + "paradiseUuid": paradiseUuid, + "roundId": currentRoundId + } + $.stealFriendRes = await request(functionId, body); +} +async function receiveNutrients() { + $.receiveNutrientsRes = await request('receiveNutrients', {"roundId": currentRoundId, "monitor_refer": "plant_receiveNutrients"}) + // console.log(`定时领取营养液结果:${JSON.stringify($.receiveNutrientsRes)}`) +} +async function plantEggDoLottery() { + $.plantEggDoLotteryResult = await requestGet('plantEggDoLottery'); +} +//查询天天扭蛋的机会 +async function egg() { + $.plantEggLotteryRes = await requestGet('plantEggLotteryIndex'); +} +async function productTaskList() { + let functionId = arguments.callee.name.toString(); + $.productTaskList = await requestGet(functionId, {"monitor_refer": "plant_productTaskList"}); +} +async function plantChannelTaskList() { + let functionId = arguments.callee.name.toString(); + $.plantChannelTaskList = await requestGet(functionId); + // console.log('$.plantChannelTaskList', $.plantChannelTaskList) +} +async function shopTaskList() { + let functionId = arguments.callee.name.toString(); + $.shopTaskListRes = await requestGet(functionId, {"monitor_refer": "plant_receiveNutrients"}); + // console.log('$.shopTaskListRes', $.shopTaskListRes) +} +async function receiveNutrientsTask(awardType) { + const functionId = arguments.callee.name.toString(); + const body = { + "monitor_refer": "receiveNutrientsTask", + "awardType": `${awardType}`, + } + $.receiveNutrientsTaskRes = await requestGet(functionId, body); +} +async function plantShareSupportList() { + $.shareSupportList = await requestGet('plantShareSupportList', {"roundId": ""}); + if ($.shareSupportList && $.shareSupportList.code === '0') { + const { data } = $.shareSupportList; + //当日北京时间0点时间戳 + const UTC8_Zero_Time = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + //次日北京时间0点时间戳 + const UTC8_End_Time = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 + (24 * 60 * 60 * 1000); + let friendList = []; + data.map(item => { + if (UTC8_Zero_Time <= item['createTime'] && item['createTime'] < UTC8_End_Time) { + friendList.push(item); + } + }) + message += "" `【助力您的好友】共${friendList.length}人` + "\n\n"; + } else { + console.log(`异常情况:${JSON.stringify($.shareSupportList)}`) + } +} +//助力好友的api +async function helpShare(plantUuid) { + console.log(`\n开始助力好友: ${plantUuid}`); + const body = { + "plantUuid": plantUuid, + "wxHeadImgUrl": "", + "shareUuid": "", + "followType": "1", + } + $.helpResult = await request(`plantBeanIndex`, body); + console.log(`助力结果的code:${$.helpResult && $.helpResult.code}`); +} +async function plantBeanIndex() { + $.plantBeanIndexResult = await request('plantBeanIndex');//plantBeanIndexBody +} +function readShareCode() { + return new Promise(async resolve => { + $.get({url: ``, timeout: 10000}, (err, resp, data) => { + try { + if (err) { + //console.log(`${JSON.stringify(err)}`) + //console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + console.log(`随机取个${randomCount}码放到您固定的互助码后面(不影响已有固定互助)`) + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + await $.wait(15000); + resolve() + }) +} +//格式化助力码 +function shareCodesFormat() { + return new Promise(async resolve => { + // console.log(`第${$.index}个动动账号的助力码:::${$.shareCodesArr[$.index - 1]}`) + newShareCodes = []; + if ($.shareCodesArr[$.index - 1]) { + newShareCodes = $.shareCodesArr[$.index - 1].split('@'); + } else { + console.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + const tempIndex = $.index > shareCodes.length ? (shareCodes.length - 1) : ($.index - 1); + newShareCodes = shareCodes[tempIndex].split('@'); + } + // const readShareCodeRes = await readShareCode(); + // if (readShareCodeRes && readShareCodeRes.code === 200) { + // newShareCodes = [...new Set([...newShareCodes, ...(readShareCodeRes.data || [])])]; + // } + console.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify(newShareCodes)}`) + resolve(); + }) +} +function requireConfig() { + return new Promise(resolve => { + console.log('开始获取种豆得豆配置文件\n') + notify = $.isNode() ? require('./sendNotify') : ''; + //Node.js用户请在jdCookie.js处填写动动ck; + const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + const jdPlantBeanShareCodes = $.isNode() ? require('./jdPlantBeanShareCodes.js') : ''; + //IOS等用户直接用NobyDa的jd cookie + if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; + } else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + console.log(`共${cookiesArr.length}个动动账号\n`) + $.shareCodesArr = []; + if ($.isNode()) { + Object.keys(jdPlantBeanShareCodes).forEach((item) => { + if (jdPlantBeanShareCodes[item]) { + $.shareCodesArr.push(jdPlantBeanShareCodes[item]) + } + }) + } else { + if ($.getdata('jd_plantbean_inviter')) $.shareCodesArr = $.getdata('jd_plantbean_inviter').split('\n').filter(item => !!item); + console.log(`\nBoxJs设置的${$.name}好友邀请码:${$.getdata('jd_plantbean_inviter') ? $.getdata('jd_plantbean_inviter') : '暂无'}\n`); + } + // console.log(`\n种豆得豆助力码::${JSON.stringify($.shareCodesArr)}`); + console.log(`您提供了${$.shareCodesArr.length}个账号的种豆得豆助力码\n`); + resolve() + }) +} +function requestGet(function_id, body = {}) { + if (!body.version) { + body["version"] = "9.0.0.1"; + } + body["monitor_source"] = "plant_app_plant_index"; + body["monitor_refer"] = ""; + return new Promise(async resolve => { + await $.wait(2000); + const option = { + url: `${JD_API_HOST}?functionId=${function_id}&body=${escape(JSON.stringify(body))}&appid=ld`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'User-Agent': 'JD4iPhone/167283 (iPhone;iOS 13.6.1;Scale/3.00)', + 'Accept-Language': 'zh-Hans-CN;q=1,en-CN;q=0.9', + 'Accept-Encoding': 'gzip, deflate, br', + 'Content-Type': "application/x-www-form-urlencoded" + }, + timeout: 10000, + }; + $.get(option, (err, resp, data) => { + try { + if (err) { + console.log('\n种豆得豆: API查询请求失败 ‼️‼️') + $.logErr(err); + } else { + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + console.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function request(function_id, body = {}){ + return new Promise(async resolve => { + await $.wait(2000); + $.post(taskUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n种豆得豆: API查询请求失败 ‼️‼️') + console.log(`function_id:${function_id}`) + $.logErr(err); + } else { + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }) +} +function taskUrl(function_id, body) { + body["version"] = "9.2.4.0"; + body["monitor_source"] = "plant_app_plant_index"; + body["monitor_refer"] = ""; + return { + url: JD_API_HOST, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&appid=ld&client=apple&area=19_1601_50258_51885&build=167490&clientVersion=9.3.2`, + headers: { + "Cookie": cookie, + "Host": "api.m.jd.com", + "Accept": "*/*", + "Connection": "keep-alive", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-Hans-CN;q=1,en-CN;q=0.9", + "Accept-Encoding": "gzip, deflate, br", + "Content-Type": "application/x-www-form-urlencoded" + }, + timeout: 10000, + } +} +function getParam(url, name) { + const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i") + const r = url.match(reg) + if (r != null) return unescape(r[2]); + return null; +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +// prettier-ignore +function Env(t,e){"undefined"!=typeof process&&JSON.stringify(process.env).indexOf("GITHUB")>-1&&process.exit(0);class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + + + + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"种豆得豆", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +// function getPic(){ +// let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] +// let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + +// pos = parseInt(11*Math.random()) +// address = address + code[pos] + ")" +// return address +// } \ No newline at end of file diff --git a/src/main/resources/test_egg.js b/src/main/resources/test_egg.js new file mode 100644 index 0000000..c842428 --- /dev/null +++ b/src/main/resources/test_egg.js @@ -0,0 +1,303 @@ +let cookiesArr = [], cookie = ''; +const JD_API_HOST = 'https://ms.jr.jd.com/gw/generic/uc/h5/m'; +const notify = $.isNode() ? require('./sendNotify') : ''; +let message = "" +//Node.js用户请在jdCookie.js处填写动动ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} +!(async () => { + + message += "[通知] 天天提鹅 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await TotalBean(); + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + that.log(`\n***********开始【动动账号${$.index}】${$.nickName || $.UserName}********\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await jdDailyEgg(); + } + message = message +"----\n\n" + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + that.log(message) + postToDingTalk(message) + $.done(); + }) +async function jdDailyEgg() { + await toDailyHome() + await toWithdraw() + await toGoldExchange(); +} +function toGoldExchange() { + return new Promise(async resolve => { + const body = { + "timeSign": 0, + "environment": "jrApp", + "riskDeviceInfo": "{}" + } + $.post(taskUrl('toGoldExchange', body), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // that.log(data) + data = JSON.parse(data); + if (data.resultCode === 0) { + if (data.resultData.code === '0000') { + that.log(`兑换金币:${data.resultData.data.cnumber}`); + message += "" + `兑换金币:${data.resultData.data.cnumber}` + "\n\n" + that.log(`当前总金币:${data.resultData.data.goldTotal}`); + message += "" + `当前总金币:${data.resultData.data.goldTotal}` +"\n\n" + } else if (data.resultData.code !== '0000') { + that.log(`兑换金币失败:${data.resultData.msg}`) + } + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function toWithdraw() { + return new Promise(async resolve => { + const body = { + "timeSign": 0, + "environment": "jrApp", + "riskDeviceInfo": "{}" + } + $.post(taskUrl('toWithdraw', body), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // that.log(data) + data = JSON.parse(data); + if (data.resultCode === 0) { + if (data.resultData.code === '0000') { + message += "" +`收取鹅蛋:${data.resultData.data.eggTotal}个成功` + "\n\n" + message += "" + `当前总鹅蛋数量:${data.resultData.data.userLevelDto.userHaveEggNum}` + "\n\n" + that.log(`收取鹅蛋:${data.resultData.data.eggTotal}个成功`); + that.log(`当前总鹅蛋数量:${data.resultData.data.userLevelDto.userHaveEggNum}`); + } else if (data.resultData.code !== '0000') { + that.log(`收取鹅蛋失败:${data.resultData.msg}`) + message += "" + `收取鹅蛋失败:${data.resultData.msg}` + "\n\n" + } + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function toDailyHome() { + return new Promise(async resolve => { + const body = { + "timeSign": 0, + "environment": "jrApp", + "riskDeviceInfo": "{}" + } + $.post(taskUrl('toDailyHome', body), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // that.log(data) + data = JSON.parse(data); + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function taskUrl(function_id, body) { + return { + url: `${JD_API_HOST}/${function_id}`, + body: `reqData=${encodeURIComponent(JSON.stringify(body))}`, + headers: { + 'Accept' : `application/json`, + 'Origin' : `https://uua.jr.jd.com`, + 'Cookie' : cookie, + 'Content-Type' : `application/x-www-form-urlencoded;charset=UTF-8`, + 'Host' : `ms.jr.jd.com`, + 'Connection' : `keep-alive`, + 'User-Agent' : $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Referer' : `https://uua.jr.jd.com/uc-fe-wxgrowing/moneytree/index`, + 'Accept-Language' : `zh-cn` + } + } +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"天天提鹅", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_fruit.js b/src/main/resources/test_fruit.js new file mode 100644 index 0000000..cc86ec7 --- /dev/null +++ b/src/main/resources/test_fruit.js @@ -0,0 +1,1518 @@ +let cookiesArr = [], cookie = '', jdFruitShareArr = [], isBox = false, notify, newShareCodes; +//助力好友分享码(最多4个,否则后面的助力失败),原因:动动农场每人每天只有四次助力机会 +//此此内容是IOS用户下载脚本到本地使用,填写互助码的地方,同一动动账号的好友互助码请使用@符号隔开。 +//下面给出两个账号的填写示例(iOS只支持2个动动账号) +let shareCodes = + [ // 这个列表填入你要助力的好友的shareCode +] +let message = '', subTitle = '', option = {}, isFruitFinished = false; +const retainWater = 100;//保留水滴大于多少g,默认100g; +let jdNotify = false;//是否关闭通知,false打开通知推送,true关闭通知推送 +let jdFruitBeanCard = false;//农场使用水滴换豆卡(如果出现限时活动时100g水换20豆,此时比浇水划算,推荐换豆),true表示换豆(不浇水),false表示不换豆(继续浇水),脚本默认是浇水 +let randomCount = $.isNode() ? 0 : 0; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +const urlSchema = `openjd://virtual?params=%7B%20%22category%22:%20%22jump%22,%20%22des%22:%20%22m%22,%20%22url%22:%20%22https://h5.m.jd.com/babelDiy/Zeus/3KSjXqQabiTuD1cJ28QskrpWoBKT/index.html%22%20%7D`; +!(async () => { + await requireConfig(); + message += "[通知] 动动农场 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await TotalBean(); + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + + + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + that.log(`\n开始【动动账号${$.index}】${$.nickName || $.UserName}\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + subTitle = ''; + option = {}; + await shareCodesFormat(); + await jdFruit(); + } + message += "----\n\n" + } + + that.log(message) + +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + that.log(message) + message = message + getPic() + postToDingTalk(message) + $.done(); + }) + + + +async function jdFruit() { + subTitle = `【动动账号${$.index}】${$.nickName}`; + try { + await initForFarm(); + if ($.farmInfo.farmUserPro) { + // option['media-url'] = $.farmInfo.farmUserPro.goodsImage; + message = message + "【水果名称】 " + `${$.farmInfo.farmUserPro.name}` + "\n\n"; + message += "【已兑换水果】" + `${$.farmInfo.farmUserPro.winTimes}` + "次\n\n"; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.farmInfo.farmUserPro.shareCode}\n`); + that.log(`\n【已成功兑换水果】${$.farmInfo.farmUserPro.winTimes}次\n`); + await getHelp(); + await masterHelpShare();//助力好友 + await setHelp(); + if ($.farmInfo.treeState === 2 || $.farmInfo.treeState === 3) { + option['open-url'] = urlSchema; + message = message + " " + $.UserName + "\n【提醒⏰】" + fruitName + "已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达" + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看`); + } + return + } else if ($.farmInfo.treeState === 1) { + that.log(`\n${$.farmInfo.farmUserPro.name}种植中...\n`) + } else if ($.farmInfo.treeState === 0) { + //已下单购买, 但未开始种植新的水果 + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】 ${$.nickName || $.UserName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达`, option); + message = message + " " + $.UserName + " \n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达" + "" + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 您忘了种植新的水果`, `动动账号${$.index} ${$.nickName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果`); + } + return + } + await doDailyTask(); + await doTenWater();//浇水十次 + await getFirstWaterAward();//领取首次浇水奖励 + await getTenWaterAward();//领取10浇水奖励 + await getWaterFriendGotAward();//领取为2好友浇水奖励 + await duck(); + await doTenWaterAgain();//再次浇水 + await predictionFruit();//预测水果成熟时间 + message = message + "----\n\n" + } else { + that.log(`初始化农场数据异常, 请登录动动 app查看农场0元水果功能是否正常,农场初始化数据: ${JSON.stringify($.farmInfo)}`); + message = message + " " + `初始化农场数据异常, 请登录动动 app查看农场0元水果功能是否正常,农场初始化数据: ${JSON.stringify($.farmInfo)}` + "\n\n"; + } + } catch (e) { + that.log(`任务执行异常,请检查执行日志 ‼️‼️`); + message = message + " " + `任务执行异常,请检查执行日志 ‼️‼️` + e + "\n\n"; + $.logErr(e); + } + await showMsg(); +} +async function doDailyTask() { + await taskInitForFarm(); + that.log(`开始签到`); + if (!$.farmTask.signInit.todaySigned) { + await signForFarm(); //签到 + if ($.signResult.code === "0") { + that.log(`【签到成功】获得${$.signResult.amount}g💧\\n`) + //message += `【签到成功】获得${$.signResult.amount}g💧\n`//连续签到${signResult.signDay}天 + } else { + // message += `签到失败,详询日志\n`; + that.log(`签到结果: ${JSON.stringify($.signResult)}`); + } + } else { + that.log(`今天已签到,连续签到${$.farmTask.signInit.totalSigned},下次签到可得${$.farmTask.signInit.signEnergyEachAmount}g\n`); + } + // 被水滴砸中 + that.log(`被水滴砸中: ${$.farmInfo.todayGotWaterGoalTask.canPop ? '是' : '否'}`); + if ($.farmInfo.todayGotWaterGoalTask.canPop) { + await gotWaterGoalTaskForFarm(); + if ($.goalResult.code === '0') { + that.log(`【被水滴砸中】获得${$.goalResult.addEnergy}g💧\\n`); + // message += `【被水滴砸中】获得${$.goalResult.addEnergy}g💧\n` + } + } + that.log(`签到结束,开始广告浏览任务`); + if (!$.farmTask.gotBrowseTaskAdInit.f) { + let adverts = $.farmTask.gotBrowseTaskAdInit.userBrowseTaskAds + let browseReward = 0 + let browseSuccess = 0 + let browseFail = 0 + for (let advert of adverts) { //开始浏览广告 + if (advert.limit <= advert.hadFinishedTimes) { + // browseReward+=advert.reward + that.log(`${advert.mainTitle}+ ' 已完成`);//,获得${advert.reward}g + continue; + } + that.log('正在进行广告浏览任务: ' + advert.mainTitle); + await browseAdTaskForFarm(advert.advertId, 0); + if ($.browseResult.code === '0') { + that.log(`${advert.mainTitle}浏览任务完成`); + //领取奖励 + await browseAdTaskForFarm(advert.advertId, 1); + if ($.browseRwardResult.code === '0') { + that.log(`领取浏览${advert.mainTitle}广告奖励成功,获得${$.browseRwardResult.amount}g`) + browseReward += $.browseRwardResult.amount + browseSuccess++ + } else { + browseFail++ + that.log(`领取浏览广告奖励结果: ${JSON.stringify($.browseRwardResult)}`) + } + } else { + browseFail++ + that.log(`广告浏览任务结果: ${JSON.stringify($.browseResult)}`); + } + } + if (browseFail > 0) { + that.log(`【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\\n`); + // message += `【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\n`; + } else { + that.log(`【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`); + // message += `【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`; + } + } else { + that.log(`今天已经做过浏览广告任务\n`); + } + //定时领水 + if (!$.farmTask.gotThreeMealInit.f) { + // + await gotThreeMealForFarm(); + if ($.threeMeal.code === "0") { + that.log(`【定时领水】获得${$.threeMeal.amount}g💧\n`); + // message += `【定时领水】获得${$.threeMeal.amount}g💧\n`; + } else { + // message += `【定时领水】失败,详询日志\n`; + that.log(`定时领水成功结果: ${JSON.stringify($.threeMeal)}`); + } + } else { + that.log('当前不在定时领水时间断或者已经领过\n') + } + //给好友浇水 + if (!$.farmTask.waterFriendTaskInit.f) { + if ($.farmTask.waterFriendTaskInit.waterFriendCountKey < $.farmTask.waterFriendTaskInit.waterFriendMax) { + await doFriendsWater(); + } + } else { + that.log(`给${$.farmTask.waterFriendTaskInit.waterFriendMax}个好友浇水任务已完成\n`) + } + // await Promise.all([ + // clockInIn(),//打卡领水 + // executeWaterRains(),//水滴雨 + // masterHelpShare(),//助力好友 + // getExtraAward(),//领取额外水滴奖励 + // turntableFarm()//天天抽奖得好礼 + // ]) + // await getAwardInviteFriend(); + await clockInIn();//打卡领水 + await executeWaterRains();//水滴雨 + await getExtraAward();//领取额外水滴奖励 + await turntableFarm()//天天抽奖得好礼 +} +async function predictionFruit() { + that.log('开始预测水果成熟时间\n'); + await initForFarm(); + await taskInitForFarm(); + let waterEveryDayT = $.farmTask.totalWaterTaskInit.totalWaterTaskTimes;//今天到到目前为止,浇了多少次水 + message += "【今日共浇水】" + `${waterEveryDayT}` + "次 \n\n" + message += "【剩余 水滴】" + `${$.farmInfo.farmUserPro.totalEnergy}` + "g💧 \n\n" + message += "【水果🍉进度】" + `${(($.farmInfo.farmUserPro.treeEnergy / + $.farmInfo.farmUserPro.treeTotalEnergy) * 100).toFixed(2)}` + "%,已浇水" +`${$.farmInfo.farmUserPro.treeEnergy / 10}` + "次,还需"+`${($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10}` +"次 \n\n" + if ($.farmInfo.toFlowTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【开花进度】再浇水${$.farmInfo.toFlowTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次开花\n\n` +"\n\n" + } else if ($.farmInfo.toFruitTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【结果进度】再浇水${$.farmInfo.toFruitTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次结果\n\n` + "\n\n" + } + // 预测n天后水果课可兑换功能 + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + message = message + "" + `【预测】${waterD === 1 ? '明天' : waterD === 2 ? '后天' : waterD + '天之后'}(${timeFormat(24 * 60 * 60 * 1000 * waterD + Date.now())}日)可兑换水果🍉` +"\n\n"; +} +//浇水十次 +async function doTenWater() { + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match(`限时翻倍`) && beanCard > 0) { + that.log(`您设置的是使用水滴换豆卡,且背包有水滴换豆卡${beanCard}张, 跳过10次浇水任务`) + return + } + if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + that.log(`\n准备浇水十次`); + let waterCount = 0; + isFruitFinished = false; + for (; waterCount < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit - $.farmTask.totalWaterTaskInit.totalWaterTaskTimes; waterCount++) { + that.log(`第${waterCount + 1}次浇水`); + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`剩余水滴${$.waterResult.totalEnergy}g`); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + if ($.waterResult.totalEnergy < 10) { + that.log(`水滴不够,结束浇水`) + break + } + await gotStageAward();//领取阶段性水滴奖励 + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log('\n今日已完成10次浇水任务\n'); + } +} +//领取首次浇水奖励 +async function getFirstWaterAward() { + await taskInitForFarm(); + //领取首次浇水奖励 + if (!$.farmTask.firstWaterInit.f && $.farmTask.firstWaterInit.totalWaterTimes > 0) { + await firstWaterTaskForFarm(); + if ($.firstWaterReward.code === '0') { + that.log(`【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`); + // message += `【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`; + } else { + // message += '【首次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取首次浇水奖励结果: ${JSON.stringify($.firstWaterReward)}`); + } + } else { + that.log('首次浇水奖励已领取\n') + } +} +//领取十次浇水奖励 +async function getTenWaterAward() { + //领取10次浇水奖励 + if (!$.farmTask.totalWaterTaskInit.f && $.farmTask.totalWaterTaskInit.totalWaterTaskTimes >= $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + await totalWaterTaskForFarm(); + if ($.totalWaterReward.code === '0') { + that.log(`【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`); + // message += `【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`; + } else { + // message += '【十次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取10次浇水奖励结果: ${JSON.stringify($.totalWaterReward)}`); + } + } else if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + // message += `【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`; + that.log(`【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`); + } + that.log('finished 水果任务完成!'); +} +//再次浇水 +async function doTenWaterAgain() { + that.log('开始检查剩余水滴能否再次浇水再次浇水\n'); + await initForFarm(); + let totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + that.log(`剩余水滴${totalEnergy}g\n`); + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + that.log(`背包已有道具:\n快速浇水卡:${fastCard === -1 ? '未解锁': fastCard + '张'}\n水滴翻倍卡:${doubleCard === -1 ? '未解锁': doubleCard + '张'}\n水滴换京豆卡:${beanCard === -1 ? '未解锁' : beanCard + '张'}\n加签卡:${signCard === -1 ? '未解锁' : signCard + '张'}\n`) + if (totalEnergy >= 100 && doubleCard > 0) { + //使用翻倍水滴卡 + for (let i = 0; i < new Array(doubleCard).fill('').length; i++) { + await userMyCardForFarm('doubleCard'); + that.log(`使用翻倍水滴卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + if (signCard > 0) { + //使用加签卡 + for (let i = 0; i < new Array(signCard).fill('').length; i++) { + await userMyCardForFarm('signCard'); + that.log(`使用加签卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match('限时翻倍')) { + that.log(`\n您设置的是水滴换豆功能,现在为您换豆`); + if (totalEnergy >= 100 && $.myCardInfoRes.beanCard > 0) { + //使用水滴换豆卡 + await userMyCardForFarm('beanCard'); + that.log(`使用水滴换豆卡结果:${JSON.stringify($.userMyCardRes)}`); + if ($.userMyCardRes.code === '0') { + message +="【水果🍉进度】" + `【水滴换豆卡】获得${$.userMyCardRes.beanCount}个京豆\n` + "\n\n"; + return + } + } else { + that.log(`您目前水滴:${totalEnergy}g,水滴换豆卡${$.myCardInfoRes.beanCard}张,暂不满足水滴换豆的条件,为您继续浇水`) + } + } + // if (totalEnergy > 100 && $.myCardInfoRes.fastCard > 0) { + // //使用快速浇水卡 + // await userMyCardForFarm('fastCard'); + // that.log(`使用快速浇水卡结果:${JSON.stringify($.userMyCardRes)}`); + // if ($.userMyCardRes.code === '0') { + // that.log(`已使用快速浇水卡浇水${$.userMyCardRes.waterEnergy}g`); + // } + // await initForFarm(); + // totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + // } + // 所有的浇水(10次浇水)任务,获取水滴任务完成后,如果剩余水滴大于等于60g,则继续浇水(保留部分水滴是用于完成第二天的浇水10次的任务) + let overageEnergy = totalEnergy - retainWater; + if (totalEnergy >= ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy)) { + //如果现有的水滴,大于水果可兑换所需的对滴(也就是把水滴浇完,水果就能兑换了) + isFruitFinished = false; + for (let i = 0; i < ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10; i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果(水果马上就可兑换了): ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log('\n浇水10g成功\n'); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + that.log(`目前水滴【${$.waterResult.totalEnergy}】g,继续浇水,水果马上就可以兑换了`) + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else if (overageEnergy >= 10) { + that.log("目前剩余水滴:【" + totalEnergy + "】g,可继续浇水"); + isFruitFinished = false; + for (let i = 0; i < parseInt(overageEnergy / 10); i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`\n浇水10g成功,剩余${$.waterResult.totalEnergy}\n`) + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + await gotStageAward() + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log("目前剩余水滴:【" + totalEnergy + "】g,不再继续浇水,保留部分水滴用于完成第二天【十次浇水得水滴】任务") + } +} +//领取阶段性水滴奖励 +function gotStageAward() { + return new Promise(async resolve => { + if ($.waterResult.waterStatus === 0 && $.waterResult.treeEnergy === 10) { + that.log('果树发芽了,奖励30g水滴'); + await gotStageAwardForFarm('1'); + that.log(`浇水阶段奖励1领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`; + that.log(`【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`); + } + } else if ($.waterResult.waterStatus === 1) { + that.log('果树开花了,奖励40g水滴'); + await gotStageAwardForFarm('2'); + that.log(`浇水阶段奖励2领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } else if ($.waterResult.waterStatus === 2) { + that.log('果树长出小果子啦, 奖励50g水滴'); + await gotStageAwardForFarm('3'); + that.log(`浇水阶段奖励3领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`) + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } + resolve() + }) +} +//天天抽奖活动 +async function turntableFarm() { + await initForTurntableFarm(); + if ($.initForTurntableFarmRes.code === '0') { + //领取定时奖励 //4小时一次 + let {timingIntervalHours, timingLastSysTime, sysTime, timingGotStatus, remainLotteryTimes, turntableInfos} = $.initForTurntableFarmRes; + + if (!timingGotStatus) { + that.log(`是否到了领取免费赠送的抽奖机会----${sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)}`) + if (sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)) { + await timingAwardForTurntableFarm(); + that.log(`领取定时奖励结果${JSON.stringify($.timingAwardRes)}`); + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } else { + that.log(`免费赠送的抽奖机会未到时间`) + } + } else { + that.log('4小时候免费赠送的抽奖机会已领取') + } + if ($.initForTurntableFarmRes.turntableBrowserAds && $.initForTurntableFarmRes.turntableBrowserAds.length > 0) { + for (let index = 0; index < $.initForTurntableFarmRes.turntableBrowserAds.length; index++) { + if (!$.initForTurntableFarmRes.turntableBrowserAds[index].status) { + that.log(`开始浏览天天抽奖的第${index + 1}个逛会场任务`) + await browserForTurntableFarm(1, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0' && $.browserForTurntableFarmRes.status) { + that.log(`第${index + 1}个逛会场任务完成,开始领取水滴奖励\n`) + await browserForTurntableFarm(2, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0') { + that.log(`第${index + 1}个逛会场任务领取水滴奖励完成\n`) + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } + } + } else { + that.log(`浏览天天抽奖的第${index + 1}个逛会场任务已完成`) + } + } + } + //天天抽奖助力 + that.log('开始天天抽奖--好友助力--每人每天只有三次助力机会.') + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('天天抽奖-不能自己给自己助力\n') + continue + } + await lotteryMasterHelp(code); + // that.log('天天抽奖助力结果',lotteryMasterHelpRes.helpResult) + if ($.lotteryMasterHelpRes.helpResult.code === '0') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}成功\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '11') { + that.log(`天天抽奖-不要重复助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '13') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}失败,助力次数耗尽\n`); + break; + } + } + that.log(`---天天抽奖次数remainLotteryTimes----${remainLotteryTimes}次`) + //抽奖 + if (remainLotteryTimes > 0) { + that.log('开始抽奖') + let lotteryResult = ''; + for (let i = 0; i < new Array(remainLotteryTimes).fill('').length; i++) { + await lotteryForTurntableFarm() + that.log(`第${i + 1}次抽奖结果${JSON.stringify($.lotteryRes)}`); + if ($.lotteryRes.code === '0') { + turntableInfos.map((item) => { + if (item.type === $.lotteryRes.type) { + that.log(`lotteryRes.type${$.lotteryRes.type}`); + if ($.lotteryRes.type.match(/bean/g) && $.lotteryRes.type.match(/bean/g)[0] === 'bean') { + lotteryResult += `${item.name}个,`; + } else if ($.lotteryRes.type.match(/water/g) && $.lotteryRes.type.match(/water/g)[0] === 'water') { + lotteryResult += `${item.name},`; + } else { + lotteryResult += `${item.name},`; + } + } + }) + //没有次数了 + if ($.lotteryRes.remainLotteryTimes === 0) { + break + } + } + } + if (lotteryResult) { + that.log(`【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`) + // message += `【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`; + } + } else { + that.log('天天抽奖--抽奖机会为0次') + } + } else { + that.log('初始化天天抽奖得好礼失败') + } +} +//领取额外奖励水滴 +async function getExtraAward() { + await masterHelpTaskInitForFarm(); + if ($.masterHelpResult.code === '0') { + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length >= 5) { + // 已有五人助力。领取助力后的奖励 + if (!$.masterHelpResult.masterGotFinal) { + await masterGotFinishedTaskForFarm(); + if ($.masterGotFinished.code === '0') { + that.log(`已成功领取好友助力奖励:【${$.masterGotFinished.amount}】g水`); + message += "【额外奖励】" + `${$.masterGotFinished.amount}` + "g水领取成功\n\n"; + } + } else { + that.log("已经领取过5好友助力额外奖励"); + message += "【水果🍉进度】" + `【额外奖励】已被领取过\n` + "\n\n"; + } + } else { + that.log("助力好友未达到5个"); + message += "【额外奖励】领取失败,原因:给您助力的人未达5个\n\n"; + } + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length > 0) { + let str = ''; + $.masterHelpResult.masterHelpPeoples.map((item, index) => { + if (index === ($.masterHelpResult.masterHelpPeoples.length - 1)) { + str += item.nickName || "匿名用户"; + } else { + str += (item.nickName || "匿名用户") + ','; + } + let date = new Date(item.time); + let time = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getMinutes(); + that.log(`\n动动昵称【${item.nickName || "匿名用户"}】 在 ${time} 给您助过力\n`); + }) + message += "【助力您的好友】 " + `${str}` + "\n\n" + } + that.log('领取额外奖励水滴结束\n'); + } +} + +function getHelp() { + newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jd_fruit/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.farmInfo.farmUserPro.shareCode) { + $.get({ + url: "http://api.tyh52.com/act/set/jd_fruit/" + $.farmInfo.farmUserPro.shareCode + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + +//助力好友 +async function masterHelpShare() { + that.log('开始助力好友') + let salveHelpAddWater = 0; + let remainTimes = 4;//今日剩余助力次数,默认4次(动动农场每人每天4次助力机会)。 + let helpSuccessPeoples = '';//成功助力好友 + that.log(`格式化后的助力码::${JSON.stringify(newShareCodes)}\n`); + + for (let code of newShareCodes) { + that.log(`开始助力动动账号${$.index} - ${$.nickName}的好友: ${code}`); + if (!code) continue; + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('不能为自己助力哦,跳过自己的shareCode\n') + continue + } + await masterHelp(code); + if ($.helpResult.code === '0') { + if ($.helpResult.helpResult.code === '0') { + //助力成功 + salveHelpAddWater += $.helpResult.helpResult.salveHelpAddWater; + that.log(`【助力好友结果】: 已成功给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力`); + that.log(`给好友【${$.helpResult.helpResult.masterUserInfo.nickName}】助力获得${$.helpResult.helpResult.salveHelpAddWater}g水滴`) + helpSuccessPeoples += ($.helpResult.helpResult.masterUserInfo.nickName || '匿名用户') + ','; + } else if ($.helpResult.helpResult.code === '8') { + that.log(`【助力好友结果】: 助力【${$.helpResult.helpResult.masterUserInfo.nickName}】失败,您今天助力次数已耗尽`); + } else if ($.helpResult.helpResult.code === '9') { + that.log(`【助力好友结果】: 之前给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力过了`); + } else if ($.helpResult.helpResult.code === '10') { + that.log(`【助力好友结果】: 好友【${$.helpResult.helpResult.masterUserInfo.nickName}】已满五人助力`); + } else { + that.log(`助力其他情况:${JSON.stringify($.helpResult.helpResult)}`); + } + that.log(`【今日助力次数还剩】${$.helpResult.helpResult.remainTimes}次\n`); + remainTimes = $.helpResult.helpResult.remainTimes; + if ($.helpResult.helpResult.remainTimes === 0) { + that.log(`您当前助力次数已耗尽,跳出助力`); + break + } + } else { + that.log(`助力失败::${JSON.stringify($.helpResult)}`); + } + } + if (helpSuccessPeoples && helpSuccessPeoples.length > 0) { + message += " " + `【您助力的好友👬】${helpSuccessPeoples.substr(0, helpSuccessPeoples.length - 1)}\n` + "\n\n"; + } + if (salveHelpAddWater > 0) { + // message += `【助力好友👬】获得${salveHelpAddWater}g💧\n`; + that.log(`【助力好友👬】获得${salveHelpAddWater}g💧\n`); + } + message += "" + `【今日剩余助力👬】${remainTimes}次\n` + "\n\n"; + that.log('助力好友结束,即将开始领取额外水滴奖励\n'); +} +//水滴雨 +async function executeWaterRains() { + let executeWaterRain = !$.farmTask.waterRainInit.f; + if (executeWaterRain) { + that.log(`水滴雨任务,每天两次,最多可得10g水滴`); + that.log(`两次水滴雨任务是否全部完成:${$.farmTask.waterRainInit.f ? '是' : '否'}`); + if ($.farmTask.waterRainInit.lastTime) { + if (Date.now() < ($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000)) { + executeWaterRain = false; + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`; + that.log(`\`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`); + } + } + if (executeWaterRain) { + that.log(`开始水滴雨任务,这是第${$.farmTask.waterRainInit.winTimes + 1}次,剩余${2 - ($.farmTask.waterRainInit.winTimes + 1)}次`); + await waterRainForFarm(); + that.log('水滴雨waterRain'); + if ($.waterRain.code === '0') { + that.log('水滴雨任务执行成功,获得水滴:' + $.waterRain.addEnergy + 'g'); + that.log(`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`); + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`; + } + } + } else { + // message += `【水滴雨】已全部完成,获得20g💧\n`; + } +} +//打卡领水活动 +async function clockInIn() { + that.log('开始打卡领水活动(签到,关注,领券)'); + await clockInInitForFarm(); + if ($.clockInInit.code === '0') { + // 签到得水滴 + if (!$.clockInInit.todaySigned) { + that.log('开始今日签到'); + await clockInForFarm(); + that.log(`打卡结果${JSON.stringify($.clockInForFarmRes)}`); + if ($.clockInForFarmRes.code === '0') { + // message += `【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`; + that.log(`【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`) + if ($.clockInForFarmRes.signDay === 7) { + //可以领取惊喜礼包 + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + } + } + if ($.clockInInit.todaySigned && $.clockInInit.totalSigned === 7) { + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + // 限时关注得水滴 + if ($.clockInInit.themes && $.clockInInit.themes.length > 0) { + for (let item of $.clockInInit.themes) { + if (!item.hadGot) { + that.log(`关注ID${item.id}`); + await clockInFollowForFarm(item.id, "theme", "1"); + that.log(`themeStep1--结果${JSON.stringify($.themeStep1)}`); + if ($.themeStep1.code === '0') { + await clockInFollowForFarm(item.id, "theme", "2"); + that.log(`themeStep2--结果${JSON.stringify($.themeStep2)}`); + if ($.themeStep2.code === '0') { + that.log(`关注${item.name},获得水滴${$.themeStep2.amount}g`); + } + } + } + } + } + // 限时领券得水滴 + if ($.clockInInit.venderCoupons && $.clockInInit.venderCoupons.length > 0) { + for (let item of $.clockInInit.venderCoupons) { + if (!item.hadGot) { + that.log(`领券的ID${item.id}`); + await clockInFollowForFarm(item.id, "venderCoupon", "1"); + that.log(`venderCouponStep1--结果${JSON.stringify($.venderCouponStep1)}`); + if ($.venderCouponStep1.code === '0') { + await clockInFollowForFarm(item.id, "venderCoupon", "2"); + if ($.venderCouponStep2.code === '0') { + that.log(`venderCouponStep2--结果${JSON.stringify($.venderCouponStep2)}`); + that.log(`从${item.name}领券,获得水滴${$.venderCouponStep2.amount}g`); + } + } + } + } + } + } + that.log('开始打卡领水活动(签到,关注,领券)结束\n'); +} +// +async function getAwardInviteFriend() { + await friendListInitForFarm();//查询好友列表 + that.log(`查询好友列表数据:\n`) + if ($.friendList) { + that.log(`\n今日已邀请好友${$.friendList.inviteFriendCount}个 / 每日邀请上限${$.friendList.inviteFriendMax}个`); + that.log(`开始删除${$.friendList.friends && $.friendList.friends.length}个好友,可拿每天的邀请奖励`); + if ($.friendList.friends && $.friendList.friends.length > 0) { + for (let friend of $.friendList.friends) { + that.log(`\n开始删除好友 [${friend.shareCode}]`); + const deleteFriendForFarm = await request('deleteFriendForFarm', { "shareCode": `${friend.shareCode}`,"version":8,"channel":1 }); + if (deleteFriendForFarm && deleteFriendForFarm.code === '0') { + that.log(`删除好友 [${friend.shareCode}] 成功\n`); + } + } + } + await receiveFriendInvite();//为他人助力,接受邀请成为别人的好友 + if ($.friendList.inviteFriendCount > 0) { + if ($.friendList.inviteFriendCount > $.friendList.inviteFriendGotAwardCount) { + that.log('开始领取邀请好友的奖励'); + await awardInviteFriendForFarm(); + that.log(`领取邀请好友的奖励结果::${JSON.stringify($.awardInviteFriendRes)}`); + } + } else { + that.log('今日未邀请过好友') + } + } else { + that.log(`查询好友列表失败\n`); + } +} +//给好友浇水 +async function doFriendsWater() { + await friendListInitForFarm(); + that.log('开始给好友浇水...'); + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax } = $.farmTask.waterFriendTaskInit; + that.log(`今日已给${waterFriendCountKey}个好友浇水`); + if (waterFriendCountKey < waterFriendMax) { + let needWaterFriends = []; + if ($.friendList.friends && $.friendList.friends.length > 0) { + $.friendList.friends.map((item, index) => { + if (item.friendState === 1) { + if (needWaterFriends.length < (waterFriendMax - waterFriendCountKey)) { + needWaterFriends.push(item.shareCode); + } + } + }); + //TODO ,发现bug,github action运行发现有些账号第一次没有给3个好友浇水 + that.log(`需要浇水的好友列表shareCodes:${JSON.stringify(needWaterFriends)}`); + let waterFriendsCount = 0, cardInfoStr = ''; + for (let index = 0; index < needWaterFriends.length; index ++) { + await waterFriendForFarm(needWaterFriends[index]); + that.log(`为第${index+1}个好友浇水结果:${JSON.stringify($.waterFriendForFarmRes)}\n`) + if ($.waterFriendForFarmRes.code === '0') { + waterFriendsCount ++; + if ($.waterFriendForFarmRes.cardInfo) { + that.log('为好友浇水获得道具了'); + if ($.waterFriendForFarmRes.cardInfo.type === 'beanCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴换豆卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'fastCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `快速浇水卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'doubleCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴翻倍卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'signCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `加签卡,`; + } + } + } else if ($.waterFriendForFarmRes.code === '11') { + that.log('水滴不够,跳出浇水') + } + } + // message += `【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`; + that.log(`【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`); + if (cardInfoStr && cardInfoStr.length > 0) { + // message += `【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`; + that.log(`【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`); + } + } else { + that.log('您的好友列表暂无好友,快去邀请您的好友吧!') + } + } else { + that.log(`今日已为好友浇水量已达${waterFriendMax}个`) + } +} +//领取给3个好友浇水后的奖励水滴 +async function getWaterFriendGotAward() { + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax, waterFriendSendWater, waterFriendGotAward } = $.farmTask.waterFriendTaskInit + if (waterFriendCountKey >= waterFriendMax) { + if (!waterFriendGotAward) { + await waterFriendGotAwardForFarm(); + that.log(`领取给${waterFriendMax}个好友浇水后的奖励水滴::${JSON.stringify($.waterFriendGotAwardRes)}`) + if ($.waterFriendGotAwardRes.code === '0') { + // message += `【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`; + that.log(`【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`); + } + } else { + that.log(`给好友浇水的${waterFriendSendWater}g水滴奖励已领取\n`); + // message += `【给${waterFriendMax}好友浇水】奖励${waterFriendSendWater}g水滴已领取\n`; + } + } else { + that.log(`暂未给${waterFriendMax}个好友浇水\n`); + } +} +//接收成为对方好友的邀请 +async function receiveFriendInvite() { + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('自己不能邀请自己成为好友噢\n') + continue + } + await inviteFriend(code); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + if ($.inviteFriendRes.helpResult.code === '0') { + that.log(`接收邀请成为好友结果成功,您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + } else if ($.inviteFriendRes.helpResult.code === '17') { + that.log(`接收邀请成为好友结果失败,对方已是您的好友`) + } + } + // that.log(`开始接受6fbd26cc27ac44d6a7fed34092453f77的邀请\n`) + // await inviteFriend('6fbd26cc27ac44d6a7fed34092453f77'); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + // if ($.inviteFriendRes.helpResult.code === '0') { + // that.log(`您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + // } else if ($.inviteFriendRes.helpResult.code === '17') { + // that.log(`对方已是您的好友`) + // } +} +async function duck() { + for (let i = 0; i < 10; i++) { + //这里循环十次 + await getFullCollectionReward(); + if ($.duckRes.code === '0') { + if (!$.duckRes.hasLimit) { + that.log(`小鸭子游戏:${$.duckRes.title}`); + // if ($.duckRes.type !== 3) { + // that.log(`${$.duckRes.title}`); + // if ($.duckRes.type === 1) { + // message += `【小鸭子】为你带回了水滴\n`; + // } else if ($.duckRes.type === 2) { + // message += `【小鸭子】为你带回快速浇水卡\n` + // } + // } + } else { + that.log(`${$.duckRes.title}`) + break; + } + } else if ($.duckRes.code === '10') { + that.log(`小鸭子游戏达到上限`) + break; + } + } +} +// ========================API调用接口======================== +//鸭子,点我有惊喜 +async function getFullCollectionReward() { + return new Promise(resolve => { + const body = {"type": 2, "version": 6, "channel": 2}; + $.post(taskUrl("getFullCollectionReward", body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +/** + * 领取10次浇水奖励API + */ +async function totalWaterTaskForFarm() { + const functionId = 'totalWaterTaskForFarm'; + $.totalWaterReward = await request(functionId); +} +//领取首次浇水奖励API +async function firstWaterTaskForFarm() { + const functionId = 'firstWaterTaskForFarm'; + $.firstWaterReward = await request(functionId); +} +//领取给3个好友浇水后的奖励水滴API +async function waterFriendGotAwardForFarm() { + const functionId = 'waterFriendGotAwardForFarm'; + $.waterFriendGotAwardRes = await request(functionId, {"version": 4, "channel": 1}); +} +// 查询背包道具卡API +async function myCardInfoForFarm() { + const functionId = 'myCardInfoForFarm'; + $.myCardInfoRes = await request(functionId, {"version": 5, "channel": 1}); +} +//使用道具卡API +async function userMyCardForFarm(cardType) { + const functionId = 'userMyCardForFarm'; + $.userMyCardRes = await request(functionId, {"cardType": cardType}); +} +/** + * 领取浇水过程中的阶段性奖励 + * @param type + * @returns {Promise} + */ +async function gotStageAwardForFarm(type) { + $.gotStageAwardForFarmRes = await request('gotStageAwardForFarm', {'type': type}); +} +//浇水API +async function waterGoodForFarm() { + await $.wait(1000); + that.log('等待了1秒'); + + const functionId = 'waterGoodForFarm'; + $.waterResult = await request(functionId); +} +// 初始化集卡抽奖活动数据API +async function initForTurntableFarm() { + $.initForTurntableFarmRes = await request('initForTurntableFarm', {version: 4, channel: 1}); +} +async function lotteryForTurntableFarm() { + await $.wait(2000); + that.log('等待了2秒'); + $.lotteryRes = await request('lotteryForTurntableFarm', {type: 1, version: 4, channel: 1}); +} + +async function timingAwardForTurntableFarm() { + $.timingAwardRes = await request('timingAwardForTurntableFarm', {version: 4, channel: 1}); +} + +async function browserForTurntableFarm(type, adId) { + if (type === 1) { + that.log('浏览爆品会场'); + } + if (type === 2) { + that.log('天天抽奖浏览任务领取水滴'); + } + const body = {"type": type,"adId": adId,"version":4,"channel":1}; + $.browserForTurntableFarmRes = await request('browserForTurntableFarm', body); + // 浏览爆品会场8秒 +} +//天天抽奖浏览任务领取水滴API +async function browserForTurntableFarm2(type) { + const body = {"type":2,"adId": type,"version":4,"channel":1}; + $.browserForTurntableFarm2Res = await request('browserForTurntableFarm', body); +} +/** + * 天天抽奖拿好礼-助力API(每人每天三次助力机会) + */ +async function lotteryMasterHelp() { + $.lotteryMasterHelpRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-3', + babelChannel: "3", + version: 4, + channel: 1 + }); +} + +//领取5人助力后的额外奖励API +async function masterGotFinishedTaskForFarm() { + const functionId = 'masterGotFinishedTaskForFarm'; + $.masterGotFinished = await request(functionId); +} +//助力好友信息API +async function masterHelpTaskInitForFarm() { + const functionId = 'masterHelpTaskInitForFarm'; + $.masterHelpResult = await request(functionId); +} +//接受对方邀请,成为对方好友的API +async function inviteFriend() { + $.inviteFriendRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-inviteFriend', + version: 4, + channel: 2 + }); +} +// 助力好友API +async function masterHelp() { + $.helpResult = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0], + babelChannel: "3", + version: 2, + channel: 1 + }); +} +/** + * 水滴雨API + */ +async function waterRainForFarm() { + const functionId = 'waterRainForFarm'; + const body = {"type": 1, "hongBaoTimes": 100, "version": 3}; + $.waterRain = await request(functionId, body); +} +/** + * 打卡领水API + */ +async function clockInInitForFarm() { + const functionId = 'clockInInitForFarm'; + $.clockInInit = await request(functionId); +} + +// 连续签到API +async function clockInForFarm() { + const functionId = 'clockInForFarm'; + $.clockInForFarmRes = await request(functionId, {"type": 1}); +} + +//关注,领券等API +async function clockInFollowForFarm(id, type, step) { + const functionId = 'clockInFollowForFarm'; + let body = { + id, + type, + step + } + if (type === 'theme') { + if (step === '1') { + $.themeStep1 = await request(functionId, body); + } else if (step === '2') { + $.themeStep2 = await request(functionId, body); + } + } else if (type === 'venderCoupon') { + if (step === '1') { + $.venderCouponStep1 = await request(functionId, body); + } else if (step === '2') { + $.venderCouponStep2 = await request(functionId, body); + } + } +} + +// 领取连续签到7天的惊喜礼包API +async function gotClockInGift() { + $.gotClockInGiftRes = await request('clockInForFarm', {"type": 2}) +} + +//定时领水API +async function gotThreeMealForFarm() { + const functionId ='gotThreeMealForFarm'; + $.threeMeal = await request(functionId); +} +/** + * 浏览广告任务API + * type为0时, 完成浏览任务 + * type为1时, 领取浏览任务奖励 + */ +async function browseAdTaskForFarm(advertId, type) { + const functionId = 'browseAdTaskForFarm'; + if (type === 0) { + $.browseResult = await request(functionId, {advertId, type}); + } else if (type === 1) { + $.browseRwardResult = await request(functionId, {advertId, type}); + } +} +// 被水滴砸中API +async function gotWaterGoalTaskForFarm() { + $.goalResult = await request('gotWaterGoalTaskForFarm', {type: 3}); +} +//签到API +async function signForFarm() { + const functionId = 'signForFarm'; + $.signResult = await request(functionId); +} +/** + * 初始化农场, 可获取果树及用户信息API + */ +async function initForFarm() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "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" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +// 初始化任务列表API +async function taskInitForFarm() { + that.log('\n初始化任务列表') + const functionId = 'taskInitForFarm'; + $.farmTask = await request(functionId); +} +//获取好友列表API +async function friendListInitForFarm() { + $.friendList = await request('friendListInitForFarm', {"version": 4, "channel": 1}); + // that.log('aa', aa); +} +// 领取邀请好友的奖励API +async function awardInviteFriendForFarm() { + $.awardInviteFriendRes = await request('awardInviteFriendForFarm'); +} +//为好友浇水API +async function waterFriendForFarm(shareCode) { + const body = {"shareCode": shareCode, "version": 6, "channel": 1} + $.waterFriendForFarmRes = await request('waterFriendForFarm', body); +} +async function showMsg() { + let ctrTemp; + if ($.isNode() && process.env.FRUIT_NOTIFY_CONTROL) { + ctrTemp = `${process.env.FRUIT_NOTIFY_CONTROL}` === 'false'; + } else if ($.getdata('jdFruitNotify')) { + ctrTemp = $.getdata('jdFruitNotify') === 'false'; + } else { + ctrTemp = `${jdNotify}` === 'false'; + } + if (ctrTemp) { + $.msg($.name, subTitle, message, option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `${subTitle}\n${message}`); + } + } else { + $.log(`\n${message}\n`); + } +} + +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} +function readShareCode() { + return new Promise(async resolve => { + $.get({url: `http://jd.turinglabs.net/api/v2/jd/farm/read/${randomCount}/`, timeout: 10000,}, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + that.log(`随机取个${randomCount}码放到您固定的互助码后面(不影响已有固定互助)`) + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + await $.wait(10000); + resolve() + }) +} +function shareCodesFormat() { + return new Promise(async resolve => { + // that.log(`第${$.index}个动动账号的助力码:::${jdFruitShareArr[$.index - 1]}`) + newShareCodes = []; + // if (jdFruitShareArr[$.index - 1]) { + // newShareCodes = jdFruitShareArr[$.index - 1].split('@'); + // } else { + // that.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + // const tempIndex = $.index > shareCodes.length ? (shareCodes.length - 1) : ($.index - 1); + // newShareCodes = shareCodes[tempIndex].split('@'); + // } + // const readShareCodeRes = await readShareCode(); + // if (readShareCodeRes && readShareCodeRes.code === 200) { + // // newShareCodes = newShareCodes.concat(readShareCodeRes.data || []); + // newShareCodes = [...new Set([...newShareCodes, ...(readShareCodeRes.data || [])])]; + // } + // that.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify(newShareCodes)}`) + resolve(); + }) +} +function requireConfig() { + return new Promise(resolve => { + that.log('开始获取配置文件\n') + notify = $.isNode() ? require('./sendNotify') : ''; + //Node.js用户请在jdCookie.js处填写动动ck; + const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + const jdFruitShareCodes = $.isNode() ? require('./jdFruitShareCodes.js') : ''; + //IOS等用户直接用NobyDa的jd cookie + if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; + } else { + let cookiesData = $.getdata('CookiesJD') || "[]"; + cookiesData = jsonParse(cookiesData); + cookiesArr = cookiesData.map(item => item.cookie); + cookiesArr.reverse(); + cookiesArr.push(...[$.getdata('CookieJD2'), $.getdata('CookieJD')]); + cookiesArr.reverse(); + cookiesArr = cookiesArr.filter(item => item !== "" && item !== null && item !== undefined); + } + that.log(`共${cookiesArr.length}个动动账号\n`) + resolve() + }) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + //$.nickName = data['base'].nickname; + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function request(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️') + that.log(JSON.stringify(err)); + that.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) +} +function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } +} +function taskUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + }, + timeout: 10000, + } +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动农场", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_guochuang.js b/src/main/resources/test_guochuang.js new file mode 100644 index 0000000..d58e87e --- /dev/null +++ b/src/main/resources/test_guochuang.js @@ -0,0 +1,386 @@ + +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + +const randomCount = $.isNode() ? 20 : 5; +const notify = $.isNode() ? require('./sendNotify') : ''; +let merge = {} +let codeList = [] +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [],message =- "",timeout,l, + cookie = ''; +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} + +const JD_API_HOST = `https://api.m.jd.com/client.action`; + +!(async () => { + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/', { + "open-url": "https://bean.m.jd.com/" + }); + return; + } + message += "[通知] 动动国创 \n\n --- \n\n" + + + for (let i = 0; i < cookiesArr.length; i++) { + cookie = cookiesArr[i]; + if (cookie) { + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + $.beans = 0 + $.cando = true + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + that.log(`\n******开始【动动账号${$.index}】${$.nickName || $.UserName}*********\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, { + "open-url": "https://bean.m.jd.com/bean/signIndex.action" + }); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + let actdata= await getid("superBrandSecondFloorMainPage","secondfloor") + if($.cando){ + $.actid = actdata.actid + $.enpid = actdata.enpid + //{actid,actname,enpid} + // await doTask("44spR7W6XFhQXzMvPva99WYLTscr", "1000000157", "3") //关注 + // await superBrandTaskLottery() + await getCode() + + await doTask("secondfloor",$.enpid,$.taskList[0].encryptAssignmentId,$.taskList[0].ext.followShop[0].itemId,$.taskList[0].assignmentType) + await doTask("secondfloor",$.enpid,$.taskList[2].encryptAssignmentId,$.taskList[2].ext.brandMemberList[0].itemId,$.taskList[2].assignmentType) + let signdata= await getid("showSecondFloorSignInfo","sign") + await doTask("sign",signdata.enpid,signdata.eid,1,5) + that.log("开始抽奖") + await superBrandTaskLottery() + await superBrandTaskLottery() + await superBrandTaskLottery() + } + + cookie = cookiesArr[i]; + if (cookie) { + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + // $.beans = 0 + // message = '' + + // await shareCodesFormat(); + that.log(`\n******开始【动动账号${$.index}】\n`); + + for (l = 0; l < codeList.length; l++) { + that.log(`为 ${codeList[l]}助力中`) + await doTask("secondfloor",$.enpid,$.inviteenaid, codeList[l], 2) + } + } + + cookie = cookiesArr[i]; + if (cookie) { + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + // await shareCodesFormat(); + that.log(`\n******开始【动动账号${$.index}】抽奖\n`); + await superBrandTaskLottery() + await superBrandTaskLottery() + await superBrandTaskLottery() + // that.log(`共获得${$.beans} 京豆`) + } + message = message + "" + `共获得${$.beans} 京豆\n` + "\n\n" + } + message = message +"----\n\n" + } +})() +.catch((e) => { + $.logErr(e) + message = message + "" + e + "\n\n" + }) + .finally(() => { + message = message + getPic() + that.log(message) + // postToDingTalk(message) + $.done() + }) +//获取活动信息 + +function getid(functionid,source) { + return new Promise(async (resolve) => { + const options = taskPostUrl(functionid, `{"source":"${source}"}`) + // that.log(options) + $.post(options, async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`); + that.log(`${$.name} API请求失败,请检查网路重试`); + } else { + data = JSON.parse(data); + // that.log(data) + if ( data.data && data.code === "0"&&data.data.result) { + let json = {} + let result =data.data.result + json.actid = result.activityBaseInfo.activityId + json.actname= result.activityBaseInfo.activityName + json.enpid = result.activityBaseInfo.encryptProjectId + if(source === "sign"){json.eid=result.activitySign1Info.encryptAssignmentId} + resolve(json) + that.log(`当前活动:${json.actname} ${json.actid}`) + }else{ + that.log("获取失败") + $.cando = false + resolve() + } + + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(); + } + }); + }); +} +function getsignid() { + return new Promise(async (resolve) => { + const options = taskPostUrl("superBrandSecondFloorMainPage", `{"source":"secondfloor"}`) + // that.log(options) + $.post(options, async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`); + that.log(`${$.name} API请求失败,请检查网路重试`); + } else { + data = JSON.parse(data); + // that.log(data) + if ( data.data && data.code === "0") { + $.actid = data.data.result.activityBaseInfo.activityId + $.actname=data.data.result.activityBaseInfo.activityName + $.enpid = data.data.result.activityBaseInfo.encryptProjectId + that.log(`当前活动:${actname} ${$.actid}`) + } + + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(); + } + }); + }); +} + +function getCode() { + return new Promise(async (resolve) => { + const options = taskPostUrl("superBrandTaskList", `{"source":"secondfloor","activityId":${$.actid},"assistInfoFlag":1}`) + // that.log(options) + $.post(options, async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`); + that.log(`${$.name} API请求失败,请检查网路重试`); + } else { + data = JSON.parse(data); + // that.log(data.data.result) + if (data && data.data && data.code === "0") { + if (data.data.result && data.data.result.taskList && data.data.result.taskList[3]) { + $.taskList = data.data.result.taskList + let result = data.data.result.taskList[3] + let encryptAssignmentId = result.encryptAssignmentId + let itemid = result.ext.assistTaskDetail.itemId + $.inviteenaid=result.encryptAssignmentId + codeList[codeList.length] = itemid + that.log(`获取邀请码成功 ${itemid}`); + } else { + that.log(data) + } + } + + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(); + } + }); + }); +} + +function doTask(source,pid,encryptAssignmentId, id, type) { + return new Promise(async (resolve) => { + const options = taskPostUrl(`superBrandDoTask`, `{"source":"${source}","activityId":${$.actid},"encryptProjectId":"${pid}","encryptAssignmentId":"${encryptAssignmentId}","assignmentType":${type},"itemId":"${id}","actionType":0}`) + // that.log(options) + $.post(options, async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`); + that.log(`${$.name} API请求失败,请检查网路重试`); + } else { + // that.log(data) + data = JSON.parse(data); + if (data && data.code === "0") { + if (data.data.bizCode === "0") { + that.log("任务成功啦~") + } else { + that.log(data.data.bizMsg) + } + resolve(data.data.bizCode) + } else { + that.log(data) + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(); + } + }); + }); +} + +function superBrandTaskLottery() { + return new Promise(async (resolve) => { + const options = taskPostUrl("superBrandTaskLottery", `{"source":"secondfloor","activityId":${$.actid}}`) + $.post(options, async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`); + that.log(`${$.name} API请求失败,请检查网路重试`); + } else { + data = JSON.parse(data); + // that.log(data) + if (data && data.code === "0") { + if (data.data.bizCode === "TK000") { + that.log(`获得 你猜获得了啥🐶 ${data.data.bizMsg}`) + message += "" + `获得 你猜获得了啥🐶 ${data.data.bizMsg}` + "\n\n" + } else { + that.log(data.data.bizMsg) + } + } else { + that.log(data) + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(); + } + }); + }); +} + + + +function taskPostUrl(functionid, body) { + const time = Date.now(); + return { + url: `https://api.m.jd.com/api?functionId=${functionid}&appid=ProductZ4Brand&client=wh5&t=${time}&body=${encodeURIComponent(body)}`, + body: "", + headers: { + Accept: "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + Connection: "keep-alive", + Cookie: cookie, + Host: "api.m.jd.com", + Referer: "https://prodev.m.jd.com/mall/active/NrHM6Egy96gxeG4eb7vFX7fYXf3/index.html?activityId=1000007&encryptProjectId=cUNnf3E6aMLQcEQbTVxn8AyhjXb&assistEncryptAssignmentId=2jpJFvC9MBNC7Qsqrt8WzEEcVoiT&assistItemId=S5ijz_8ukVww&tttparams=GgS7lUeyJnTGF0IjoiMzMuMjUyNzYyIiwiZ0xuZyI6IjEwNy4xNjA1MDcifQ6%3D%3D&lng=107.147022&lat=33.255229&sid=e5150a3fdd017952350b4b41294b145w&un_area=27_2442_2444_31912", + "User-Agent": "jdapp;android;9.4.4;10;3b78ecc3f490c7ba;network/UNKNOWN;model/M2006J10C;addressid/138543439;aid/3b78ecc3f490c7ba;oaid/7d5870c5a1696881;osVer/29;appBuild/85576;psn/3b78ecc3f490c7ba|541;psq/2;uid/3b78ecc3f490c7ba;adk/;ads/;pap/JA2015_311210|9.2.4|ANDROID 10;osv/10;pv/548.2;jdv/0|iosapp|t_335139774|appshare|CopyURL|1606277982178|1606277986;ref/com.jd.lib.personal.view.fragment.JDPersonalFragment;partner/xiaomi001;apprpd/MyJD_Main;Mozilla/5.0 (Linux; Android 10; M2006J10C Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045227 Mobile Safari/537.36", + } + } +} + + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=fa87e34729eaa6113fddfa857efebb477dea0a433d6eecfe93b1d3f5e24847b9" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动国创", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} diff --git a/src/main/resources/test_lwq.js b/src/main/resources/test_lwq.js new file mode 100644 index 0000000..f4da1a7 --- /dev/null +++ b/src/main/resources/test_lwq.js @@ -0,0 +1,2180 @@ +/* +京东资产变动通知脚本:https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js +Modified time: 2021-05-17 15:25:41 +统计昨日京豆的变化情况,包括收入,支出,以及显示当前京豆数量,目前小问题:下单使用京豆后,退款重新购买,计算统计会出现异常 +统计红包以及过期红包 +网页查看地址 : https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean +支持京东双账号 +脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js +============QuantumultX============== +[task_local] +#京东资产变动通知 +2 9 * * * https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, tag=京东资产变动通知, img-url=https://raw.githubusercontent.com/Orz-3/mini/master/Color/jd.png, enabled=true +================Loon=============== +[Script] +cron "2 9 * * *" script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, tag=京东资产变动通知 +=============Surge=========== +[Script] +京东资产变动通知 = type=cron,cronexp="2 9 * * *",wake-system=1,timeout=3600,script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js +============小火箭========= +京东资产变动通知 = type=cron,script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, cronexpr="2 9 * * *", timeout=3600, enable=true + */ +let roleMap = { + "好吧好吧5577":"wq_好吧好吧5577", + "jd_qapvwBDaRqgW":"wgh_19970291531", + "18070420956_p":"刘吴奇", +} +let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" +const $ = new Env('京东资产变动通知'); +let jdFruitShareArr = [], isBox = false, notify, newShareCodes; +//助力好友分享码(最多4个,否则后面的助力失败),原因:动动农场每人每天只有四次助力机会 +//此此内容是IOS用户下载脚本到本地使用,填写互助码的地方,同一动动账号的好友互助码请使用@符号隔开。 +//下面给出两个账号的填写示例(iOS只支持2个动动账号) +let shareCodes = + [ // 这个列表填入你要助力的好友的shareCode +] +let subTitle = '', option = {}, isFruitFinished = false; +const retainWater = 100;//保留水滴大于多少g,默认100g; +let jdNotify = false;//是否关闭通知,false打开通知推送,true关闭通知推送 +let jdFruitBeanCard = false;//农场使用水滴换豆卡(如果出现限时活动时100g水换20豆,此时比浇水划算,推荐换豆),true表示换豆(不浇水),false表示不换豆(继续浇水),脚本默认是浇水 +let randomCount = $.isNode() ? 0 : 0; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +const urlSchema = `openjd://virtual?params=%7B%20%22category%22:%20%22jump%22,%20%22des%22:%20%22m%22,%20%22url%22:%20%22https://h5.m.jd.com/babelDiy/Zeus/3KSjXqQabiTuD1cJ28QskrpWoBKT/index.html%22%20%7D`; + +let allMessage = ''; +let message = ""; +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +!(async () => { + await requireConfig(); + message += "[通知] 资产变动 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + let count = 0 + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.beanCount = 0; + $.incomeBean = 0; + $.expenseBean = 0; + $.todayIncomeBean = 0; + $.errorMsg = ''; + $.isLogin = true; + $.nickName = ''; + $.balance = 0; + $.expiredBalance = 0; + + username = $.UserName + if (roleMap[username] == undefined){ + continue + } + username = roleMap[username] + + await TotalBean(); + //加上名称 + message = message + "【羊毛姐妹】" + username + `( ${$.nickName} )`+ " \n\n " + + console.log(`\n********开始【京东账号${$.index}】${$.nickName || $.UserName}******\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await bean(); + await showMsg(); + await shareCodesFormat(); + await jdFruit(); + await jdWish() + } + message += "----\n\n" + if( (count+1)%4 ==0 || i == cookiesArr.length -1 ){ + message = message + getPic() + postToDingTalk(message) + message = "" + } + count ++ + } + + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + if (message != ""){ + postToDingTalk(message) + + } + $.done(); + }) + + + function requireConfig() { + return new Promise(resolve => { + that.log('开始获取配置文件\n') + notify = $.isNode() ? require('./sendNotify') : ''; + //Node.js用户请在jdCookie.js处填写动动ck; + const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + const jdFruitShareCodes = $.isNode() ? require('./jdFruitShareCodes.js') : ''; + //IOS等用户直接用NobyDa的jd cookie + if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; + } else { + let cookiesData = $.getdata('CookiesJD') || "[]"; + cookiesData = jsonParse(cookiesData); + cookiesArr = cookiesData.map(item => item.cookie); + cookiesArr.reverse(); + cookiesArr.push(...[$.getdata('CookieJD2'), $.getdata('CookieJD')]); + cookiesArr.reverse(); + cookiesArr = cookiesArr.filter(item => item !== "" && item !== null && item !== undefined); + } + that.log(`共${cookiesArr.length}个动动账号\n`) + resolve() + }) + } + +async function showMsg() { + // if ($.errorMsg) return + allMessage += `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆 🐶${$.message}${$.index !== cookiesArr.length ? '\n\n' : ''}`; + message += "" + `【总京豆】:${$.beanCount}( 今日将过期${$.expirejingdou} )京豆 🐶` +"\n\n" + message += "" + `【今日收入】:${$.todayIncomeBean}京豆 🐶` +"\n\n" + message += "" + `【昨日收入】:${$.incomeBean}京豆 🐶` +"\n\n" + message += "" + `【昨日支出】:${$.expenseBean}京豆 🐶` +"\n\n" + + + + message += "" + `【当前总红包】:${$.balance}( 今日总过期${$.expiredBalance} )元 🧧` +"\n\n" + message += "" + `【京喜红包】:${$.jxRed}( 今日将过期${$.jxRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【极速红包】:${$.jsRed}( 今日将过期${$.jsRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【京东红包】:${$.jdRed}( 今日将过期${$.jdRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【健康红包】:${$.jdhRed}( 今日将过期${$.jdhRedExpire.toFixed(2)} )元 🧧` +"\n\n" + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `账号${$.index}:${$.nickName || $.UserName}\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}京豆 🐶${$.message}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + // } + $.msg($.name, '', `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶${$.message}`, {"open-url": "https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean"}); +} + +async function bean() { + // console.log(`北京时间零点时间戳:${parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000}`); + // console.log(`北京时间2020-10-28 06:16:05::${new Date("2020/10/28 06:16:05+08:00").getTime()}`) + // 不管哪个时区。得到都是当前时刻北京时间的时间戳 new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000 + + //前一天的0:0:0时间戳 + const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - (24 * 60 * 60 * 1000); + // 今天0:0:0时间戳 + const tm1 = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + let page = 1, t = 0, yesterdayArr = [], todayArr = []; + do { + let response = await getJingBeanBalanceDetail(page); + // console.log(`第${page}页: ${JSON.stringify(response)}`); + if (response && response.code === "0") { + page++; + let detailList = response.detailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const date = item.date.replace(/-/g, '/') + "+08:00"; + if (new Date(date).getTime() >= tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + todayArr.push(item); + } else if (tm <= new Date(date).getTime() && new Date(date).getTime() < tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + //昨日的 + yesterdayArr.push(item); + } else if (tm > new Date(date).getTime()) { + //前天的 + t = 1; + break; + } + } + } else { + $.errorMsg = `数据异常`; + $.msg($.name, ``, `账号${$.index}:${$.nickName}\n${$.errorMsg}`); + t = 1; + } + } else if (response && response.code === "3") { + console.log(`cookie已过期,或者填写不规范,跳出`) + t = 1; + } else { + console.log(`未知情况:${JSON.stringify(response)}`); + console.log(`未知情况,跳出`) + t = 1; + } + } while (t === 0); + for (let item of yesterdayArr) { + if (Number(item.amount) > 0) { + $.incomeBean += Number(item.amount); + } else if (Number(item.amount) < 0) { + $.expenseBean += Number(item.amount); + } + } + for (let item of todayArr) { + if (Number(item.amount) > 0) { + $.todayIncomeBean += Number(item.amount); + } + } + await queryexpirejingdou();//过期京豆 + await redPacket();//过期红包 + // console.log(`昨日收入:${$.incomeBean}个京豆 🐶`); + // console.log(`昨日支出:${$.expenseBean}个京豆 🐶`) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + if (data['retcode'] === '0' && data.data && data.data['assetInfo']) { + $.beanCount = data.data && data.data['assetInfo']['beanNum']; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} +function getJingBeanBalanceDetail(page) { + return new Promise(async resolve => { + const options = { + "url": `https://api.m.jd.com/client.action?functionId=getJingBeanBalanceDetail`, + "body": `body=${escape(JSON.stringify({"pageSize": "20", "page": page.toString()}))}&appid=ld`, + "headers": { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + // console.log(data) + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function queryexpirejingdou() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=${Date.now()}&g_login_type=1&sceneval=2`, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Host": "wq.jd.com", + "Referer": "https://wqs.jd.com/promote/201801/bean/mybean.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1" + } + } + $.expirejingdou = 0; + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // console.log(data) + data = JSON.parse(data.slice(23, -13)); + // console.log(data) + if (data.ret === 0) { + data['expirejingdou'].map(item => { + console.log(`${timeFormat(item['time'] * 1000)}日过期京豆:${item['expireamount']}\n`); + }) + $.expirejingdou = data['expirejingdou'][0]['expireamount']; + // if ($.expirejingdou > 0) { + // $.message += `\n今日将过期:${$.expirejingdou}京豆 🐶`; + // } + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function redPacket() { + return new Promise(async resolve => { + const options = { + "url": `https://m.jingxi.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=1&_=${+new Date()}&sceneval=2&g_login_type=1&g_ty=ls`, + "headers": { + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://st.jingxi.com/my/redpacket.shtml?newPg=App&jxsid=16156262265849285961', + 'Accept-Encoding': 'gzip, deflate, br', + "Cookie": cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data).data + $.jxRed = 0, $.jsRed = 0, $.jdRed = 0, $.jdhRed = 0, $.jxRedExpire = 0, $.jsRedExpire = 0, $.jdRedExpire = 0, $.jdhRedExpire = 0; + let t = new Date() + t.setDate(t.getDate() + 1) + t.setHours(0, 0, 0, 0) + t = parseInt((t - 1) / 1000) + for (let vo of data.useRedInfo.redList || []) { + if (vo.orgLimitStr && vo.orgLimitStr.includes("京喜")) { + $.jxRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jxRedExpire += parseFloat(vo.balance) + } + } else if (vo.activityName.includes("极速版")) { + $.jsRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jsRedExpire += parseFloat(vo.balance) + } + } else if (vo.orgLimitStr && vo.orgLimitStr.includes("京东健康")) { + $.jdhRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdhRedExpire += parseFloat(vo.balance) + } + } else { + $.jdRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdRedExpire += parseFloat(vo.balance) + } + } + } + $.jxRed = $.jxRed.toFixed(2) + $.jsRed = $.jsRed.toFixed(2) + $.jdRed = $.jdRed.toFixed(2) + $.jdhRed = $.jdhRed.toFixed(2) + $.balance = data.balance + $.expiredBalance = ($.jxRedExpire + $.jsRedExpire + $.jdRedExpire).toFixed(2) + $.message += `\n当前总红包:${$.balance}(今日总过期${$.expiredBalance})元 🧧\n京喜红包:${$.jxRed}(今日将过期${$.jxRedExpire.toFixed(2)})元 🧧\n极速红包:${$.jsRed}(今日将过期${$.jsRedExpire.toFixed(2)})元 🧧\n京东红包:${$.jdRed}(今日将过期${$.jdRedExpire.toFixed(2)})元 🧧\n健康红包:${$.jdhRed}(今日将过期${$.jdhRedExpire.toFixed(2)})元 🧧`; + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} +// prettier-ignore +function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + +//农场代码 + +async function jdFruit() { + subTitle = `【动动账号${$.index}】${$.nickName}`; + try { + await initForFarm(); + if ($.farmInfo.farmUserPro) { + // option['media-url'] = $.farmInfo.farmUserPro.goodsImage; + message = message + "【水果名称】 " + `${$.farmInfo.farmUserPro.name}` + "\n\n"; + // message += "【已兑换水果】" + `${$.farmInfo.farmUserPro.winTimes}` + "次\n\n"; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.farmInfo.farmUserPro.shareCode}\n`); + that.log(`\n【已成功兑换水果】${$.farmInfo.farmUserPro.winTimes}次\n`); + await getHelp(); + await masterHelpShare();//助力好友 + await setHelp(); + if ($.farmInfo.treeState === 2 || $.farmInfo.treeState === 3) { + option['open-url'] = urlSchema; + message = message + " " + $.UserName + "\n【提醒⏰】" + fruitName + "已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达" + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看`); + } + return + } else if ($.farmInfo.treeState === 1) { + that.log(`\n${$.farmInfo.farmUserPro.name}种植中...\n`) + } else if ($.farmInfo.treeState === 0) { + //已下单购买, 但未开始种植新的水果 + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】 ${$.nickName || $.UserName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达`, option); + message = message + " " + $.UserName + " \n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达" + "" + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 您忘了种植新的水果`, `动动账号${$.index} ${$.nickName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果`); + } + return + } + await doDailyTask(); + await doTenWater();//浇水十次 + await getFirstWaterAward();//领取首次浇水奖励 + await getTenWaterAward();//领取10浇水奖励 + await getWaterFriendGotAward();//领取为2好友浇水奖励 + await duck(); + await doTenWaterAgain();//再次浇水 + await predictionFruit();//预测水果成熟时间 + } else { + that.log(`初始化农场数据异常, 请登录动动 app查看农场0元水果功能是否正常,农场初始化数据: ${JSON.stringify($.farmInfo)}`); + } + } catch (e) { + that.log(`任务执行异常,请检查执行日志 ‼️‼️`); + $.logErr(e); + } + } + async function doDailyTask() { + await taskInitForFarm(); + that.log(`开始签到`); + if (!$.farmTask.signInit.todaySigned) { + await signForFarm(); //签到 + if ($.signResult.code === "0") { + that.log(`【签到成功】获得${$.signResult.amount}g💧\\n`) + //message += `【签到成功】获得${$.signResult.amount}g💧\n`//连续签到${signResult.signDay}天 + } else { + // message += `签到失败,详询日志\n`; + that.log(`签到结果: ${JSON.stringify($.signResult)}`); + } + } else { + that.log(`今天已签到,连续签到${$.farmTask.signInit.totalSigned},下次签到可得${$.farmTask.signInit.signEnergyEachAmount}g\n`); + } + // 被水滴砸中 + that.log(`被水滴砸中: ${$.farmInfo.todayGotWaterGoalTask.canPop ? '是' : '否'}`); + if ($.farmInfo.todayGotWaterGoalTask.canPop) { + await gotWaterGoalTaskForFarm(); + if ($.goalResult.code === '0') { + that.log(`【被水滴砸中】获得${$.goalResult.addEnergy}g💧\\n`); + // message += `【被水滴砸中】获得${$.goalResult.addEnergy}g💧\n` + } + } + that.log(`签到结束,开始广告浏览任务`); + if (!$.farmTask.gotBrowseTaskAdInit.f) { + let adverts = $.farmTask.gotBrowseTaskAdInit.userBrowseTaskAds + let browseReward = 0 + let browseSuccess = 0 + let browseFail = 0 + for (let advert of adverts) { //开始浏览广告 + if (advert.limit <= advert.hadFinishedTimes) { + // browseReward+=advert.reward + that.log(`${advert.mainTitle}+ ' 已完成`);//,获得${advert.reward}g + continue; + } + that.log('正在进行广告浏览任务: ' + advert.mainTitle); + await browseAdTaskForFarm(advert.advertId, 0); + if ($.browseResult.code === '0') { + that.log(`${advert.mainTitle}浏览任务完成`); + //领取奖励 + await browseAdTaskForFarm(advert.advertId, 1); + if ($.browseRwardResult.code === '0') { + that.log(`领取浏览${advert.mainTitle}广告奖励成功,获得${$.browseRwardResult.amount}g`) + browseReward += $.browseRwardResult.amount + browseSuccess++ + } else { + browseFail++ + that.log(`领取浏览广告奖励结果: ${JSON.stringify($.browseRwardResult)}`) + } + } else { + browseFail++ + that.log(`广告浏览任务结果: ${JSON.stringify($.browseResult)}`); + } + } + if (browseFail > 0) { + that.log(`【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\\n`); + // message += `【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\n`; + } else { + that.log(`【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`); + // message += `【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`; + } + } else { + that.log(`今天已经做过浏览广告任务\n`); + } + //定时领水 + if (!$.farmTask.gotThreeMealInit.f) { + // + await gotThreeMealForFarm(); + if ($.threeMeal.code === "0") { + that.log(`【定时领水】获得${$.threeMeal.amount}g💧\n`); + // message += `【定时领水】获得${$.threeMeal.amount}g💧\n`; + } else { + // message += `【定时领水】失败,详询日志\n`; + that.log(`定时领水成功结果: ${JSON.stringify($.threeMeal)}`); + } + } else { + that.log('当前不在定时领水时间断或者已经领过\n') + } + //给好友浇水 + if (!$.farmTask.waterFriendTaskInit.f) { + if ($.farmTask.waterFriendTaskInit.waterFriendCountKey < $.farmTask.waterFriendTaskInit.waterFriendMax) { + await doFriendsWater(); + } + } else { + that.log(`给${$.farmTask.waterFriendTaskInit.waterFriendMax}个好友浇水任务已完成\n`) + } + // await Promise.all([ + // clockInIn(),//打卡领水 + // executeWaterRains(),//水滴雨 + // masterHelpShare(),//助力好友 + // getExtraAward(),//领取额外水滴奖励 + // turntableFarm()//天天抽奖得好礼 + // ]) + // await getAwardInviteFriend(); + await clockInIn();//打卡领水 + await executeWaterRains();//水滴雨 + await getExtraAward();//领取额外水滴奖励 + await turntableFarm()//天天抽奖得好礼 + } + async function predictionFruit() { + that.log('开始预测水果成熟时间\n'); + await initForFarm(); + await taskInitForFarm(); + let waterEveryDayT = $.farmTask.totalWaterTaskInit.totalWaterTaskTimes;//今天到到目前为止,浇了多少次水 + // message += "【今日共浇水】" + `${waterEveryDayT}` + "次 \n\n" + message += "【剩余 水滴】" + `${$.farmInfo.farmUserPro.totalEnergy}` + "g💧 \n\n" + message += "【水果🍉进度】" + `${(($.farmInfo.farmUserPro.treeEnergy / + $.farmInfo.farmUserPro.treeTotalEnergy) * 100).toFixed(2)}` + "%,已浇水" +`${$.farmInfo.farmUserPro.treeEnergy / 10}` + "次,还需"+`${($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10}` +"次 \n\n" + if ($.farmInfo.toFlowTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【开花进度】再浇水${$.farmInfo.toFlowTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次开花\n\n` +"\n\n" + } else if ($.farmInfo.toFruitTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【结果进度】再浇水${$.farmInfo.toFruitTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次结果\n\n` + "\n\n" + } + // 预测n天后水果课可兑换功能 + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + message = message + "" + `【预测🍉收获时间】${waterD === 1 ? '明天' : waterD === 2 ? '后天' : waterD + '天之后'}(${timeFormat(24 * 60 * 60 * 1000 * waterD + Date.now())}日)可兑换水果🍉` +"\n\n"; + } + //浇水十次 + async function doTenWater() { + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match(`限时翻倍`) && beanCard > 0) { + that.log(`您设置的是使用水滴换豆卡,且背包有水滴换豆卡${beanCard}张, 跳过10次浇水任务`) + return + } + if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + that.log(`\n准备浇水十次`); + let waterCount = 0; + isFruitFinished = false; + for (; waterCount < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit - $.farmTask.totalWaterTaskInit.totalWaterTaskTimes; waterCount++) { + that.log(`第${waterCount + 1}次浇水`); + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`剩余水滴${$.waterResult.totalEnergy}g`); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + if ($.waterResult.totalEnergy < 10) { + that.log(`水滴不够,结束浇水`) + break + } + await gotStageAward();//领取阶段性水滴奖励 + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log('\n今日已完成10次浇水任务\n'); + } + } + //领取首次浇水奖励 + async function getFirstWaterAward() { + await taskInitForFarm(); + //领取首次浇水奖励 + if (!$.farmTask.firstWaterInit.f && $.farmTask.firstWaterInit.totalWaterTimes > 0) { + await firstWaterTaskForFarm(); + if ($.firstWaterReward.code === '0') { + that.log(`【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`); + // message += `【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`; + } else { + // message += '【首次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取首次浇水奖励结果: ${JSON.stringify($.firstWaterReward)}`); + } + } else { + that.log('首次浇水奖励已领取\n') + } + } + //领取十次浇水奖励 + async function getTenWaterAward() { + //领取10次浇水奖励 + if (!$.farmTask.totalWaterTaskInit.f && $.farmTask.totalWaterTaskInit.totalWaterTaskTimes >= $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + await totalWaterTaskForFarm(); + if ($.totalWaterReward.code === '0') { + that.log(`【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`); + // message += `【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`; + } else { + // message += '【十次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取10次浇水奖励结果: ${JSON.stringify($.totalWaterReward)}`); + } + } else if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + // message += `【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`; + that.log(`【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`); + } + that.log('finished 水果任务完成!'); + } + //再次浇水 + async function doTenWaterAgain() { + that.log('开始检查剩余水滴能否再次浇水再次浇水\n'); + await initForFarm(); + let totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + that.log(`剩余水滴${totalEnergy}g\n`); + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + that.log(`背包已有道具:\n快速浇水卡:${fastCard === -1 ? '未解锁': fastCard + '张'}\n水滴翻倍卡:${doubleCard === -1 ? '未解锁': doubleCard + '张'}\n水滴换京豆卡:${beanCard === -1 ? '未解锁' : beanCard + '张'}\n加签卡:${signCard === -1 ? '未解锁' : signCard + '张'}\n`) + if (totalEnergy >= 100 && doubleCard > 0) { + //使用翻倍水滴卡 + for (let i = 0; i < new Array(doubleCard).fill('').length; i++) { + await userMyCardForFarm('doubleCard'); + that.log(`使用翻倍水滴卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + if (signCard > 0) { + //使用加签卡 + for (let i = 0; i < new Array(signCard).fill('').length; i++) { + await userMyCardForFarm('signCard'); + that.log(`使用加签卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match('限时翻倍')) { + that.log(`\n您设置的是水滴换豆功能,现在为您换豆`); + if (totalEnergy >= 100 && $.myCardInfoRes.beanCard > 0) { + //使用水滴换豆卡 + await userMyCardForFarm('beanCard'); + that.log(`使用水滴换豆卡结果:${JSON.stringify($.userMyCardRes)}`); + if ($.userMyCardRes.code === '0') { + // message +="【水果🍉进度】" + `【水滴换豆卡】获得${$.userMyCardRes.beanCount}个京豆\n` + "\n\n"; + return + } + } else { + that.log(`您目前水滴:${totalEnergy}g,水滴换豆卡${$.myCardInfoRes.beanCard}张,暂不满足水滴换豆的条件,为您继续浇水`) + } + } + // if (totalEnergy > 100 && $.myCardInfoRes.fastCard > 0) { + // //使用快速浇水卡 + // await userMyCardForFarm('fastCard'); + // that.log(`使用快速浇水卡结果:${JSON.stringify($.userMyCardRes)}`); + // if ($.userMyCardRes.code === '0') { + // that.log(`已使用快速浇水卡浇水${$.userMyCardRes.waterEnergy}g`); + // } + // await initForFarm(); + // totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + // } + // 所有的浇水(10次浇水)任务,获取水滴任务完成后,如果剩余水滴大于等于60g,则继续浇水(保留部分水滴是用于完成第二天的浇水10次的任务) + let overageEnergy = totalEnergy - retainWater; + if (totalEnergy >= ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy)) { + //如果现有的水滴,大于水果可兑换所需的对滴(也就是把水滴浇完,水果就能兑换了) + isFruitFinished = false; + for (let i = 0; i < ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10; i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果(水果马上就可兑换了): ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log('\n浇水10g成功\n'); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + that.log(`目前水滴【${$.waterResult.totalEnergy}】g,继续浇水,水果马上就可以兑换了`) + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else if (overageEnergy >= 10) { + that.log("目前剩余水滴:【" + totalEnergy + "】g,可继续浇水"); + isFruitFinished = false; + for (let i = 0; i < parseInt(overageEnergy / 10); i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`\n浇水10g成功,剩余${$.waterResult.totalEnergy}\n`) + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + await gotStageAward() + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log("目前剩余水滴:【" + totalEnergy + "】g,不再继续浇水,保留部分水滴用于完成第二天【十次浇水得水滴】任务") + } + } + //领取阶段性水滴奖励 + function gotStageAward() { + return new Promise(async resolve => { + if ($.waterResult.waterStatus === 0 && $.waterResult.treeEnergy === 10) { + that.log('果树发芽了,奖励30g水滴'); + await gotStageAwardForFarm('1'); + that.log(`浇水阶段奖励1领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`; + that.log(`【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`); + } + } else if ($.waterResult.waterStatus === 1) { + that.log('果树开花了,奖励40g水滴'); + await gotStageAwardForFarm('2'); + that.log(`浇水阶段奖励2领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } else if ($.waterResult.waterStatus === 2) { + that.log('果树长出小果子啦, 奖励50g水滴'); + await gotStageAwardForFarm('3'); + that.log(`浇水阶段奖励3领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`) + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } + resolve() + }) + } + //天天抽奖活动 + async function turntableFarm() { + await initForTurntableFarm(); + if ($.initForTurntableFarmRes.code === '0') { + //领取定时奖励 //4小时一次 + let {timingIntervalHours, timingLastSysTime, sysTime, timingGotStatus, remainLotteryTimes, turntableInfos} = $.initForTurntableFarmRes; + + if (!timingGotStatus) { + that.log(`是否到了领取免费赠送的抽奖机会----${sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)}`) + if (sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)) { + await timingAwardForTurntableFarm(); + that.log(`领取定时奖励结果${JSON.stringify($.timingAwardRes)}`); + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } else { + that.log(`免费赠送的抽奖机会未到时间`) + } + } else { + that.log('4小时候免费赠送的抽奖机会已领取') + } + if ($.initForTurntableFarmRes.turntableBrowserAds && $.initForTurntableFarmRes.turntableBrowserAds.length > 0) { + for (let index = 0; index < $.initForTurntableFarmRes.turntableBrowserAds.length; index++) { + if (!$.initForTurntableFarmRes.turntableBrowserAds[index].status) { + that.log(`开始浏览天天抽奖的第${index + 1}个逛会场任务`) + await browserForTurntableFarm(1, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0' && $.browserForTurntableFarmRes.status) { + that.log(`第${index + 1}个逛会场任务完成,开始领取水滴奖励\n`) + await browserForTurntableFarm(2, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0') { + that.log(`第${index + 1}个逛会场任务领取水滴奖励完成\n`) + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } + } + } else { + that.log(`浏览天天抽奖的第${index + 1}个逛会场任务已完成`) + } + } + } + //天天抽奖助力 + that.log('开始天天抽奖--好友助力--每人每天只有三次助力机会.') + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('天天抽奖-不能自己给自己助力\n') + continue + } + await lotteryMasterHelp(code); + // that.log('天天抽奖助力结果',lotteryMasterHelpRes.helpResult) + if ($.lotteryMasterHelpRes.helpResult.code === '0') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}成功\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '11') { + that.log(`天天抽奖-不要重复助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '13') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}失败,助力次数耗尽\n`); + break; + } + } + that.log(`---天天抽奖次数remainLotteryTimes----${remainLotteryTimes}次`) + //抽奖 + if (remainLotteryTimes > 0) { + that.log('开始抽奖') + let lotteryResult = ''; + for (let i = 0; i < new Array(remainLotteryTimes).fill('').length; i++) { + await lotteryForTurntableFarm() + that.log(`第${i + 1}次抽奖结果${JSON.stringify($.lotteryRes)}`); + if ($.lotteryRes.code === '0') { + turntableInfos.map((item) => { + if (item.type === $.lotteryRes.type) { + that.log(`lotteryRes.type${$.lotteryRes.type}`); + if ($.lotteryRes.type.match(/bean/g) && $.lotteryRes.type.match(/bean/g)[0] === 'bean') { + lotteryResult += `${item.name}个,`; + } else if ($.lotteryRes.type.match(/water/g) && $.lotteryRes.type.match(/water/g)[0] === 'water') { + lotteryResult += `${item.name},`; + } else { + lotteryResult += `${item.name},`; + } + } + }) + //没有次数了 + if ($.lotteryRes.remainLotteryTimes === 0) { + break + } + } + } + if (lotteryResult) { + that.log(`【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`) + // message += `【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`; + } + } else { + that.log('天天抽奖--抽奖机会为0次') + } + } else { + that.log('初始化天天抽奖得好礼失败') + } + } + //领取额外奖励水滴 + async function getExtraAward() { + await masterHelpTaskInitForFarm(); + if ($.masterHelpResult.code === '0') { + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length >= 5) { + // 已有五人助力。领取助力后的奖励 + if (!$.masterHelpResult.masterGotFinal) { + await masterGotFinishedTaskForFarm(); + if ($.masterGotFinished.code === '0') { + that.log(`已成功领取好友助力奖励:【${$.masterGotFinished.amount}】g水`); + // message += "【额外奖励】" + `${$.masterGotFinished.amount}` + "g水领取成功\n\n"; + } + } else { + that.log("已经领取过5好友助力额外奖励"); + // message += "【水果🍉进度】" + `【额外奖励】已被领取过\n` + "\n\n"; + } + } else { + that.log("助力好友未达到5个"); + // message += "【额外奖励】领取失败,原因:给您助力的人未达5个\n\n"; + } + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length > 0) { + let str = ''; + $.masterHelpResult.masterHelpPeoples.map((item, index) => { + if (index === ($.masterHelpResult.masterHelpPeoples.length - 1)) { + str += item.nickName || "匿名用户"; + } else { + str += (item.nickName || "匿名用户") + ','; + } + let date = new Date(item.time); + let time = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getMinutes(); + that.log(`\n动动昵称【${item.nickName || "匿名用户"}】 在 ${time} 给您助过力\n`); + }) + // message += "【助力您的好友】 " + `${str}` + "\n\n" + } + that.log('领取额外奖励水滴结束\n'); + } + } + + function getHelp() { + newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jd_fruit/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.farmInfo.farmUserPro.shareCode) { + $.get({ + url: "http://api.tyh52.com/act/set/jd_fruit/" + $.farmInfo.farmUserPro.shareCode + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + //助力好友 + async function masterHelpShare() { + that.log('开始助力好友') + let salveHelpAddWater = 0; + let remainTimes = 4;//今日剩余助力次数,默认4次(动动农场每人每天4次助力机会)。 + let helpSuccessPeoples = '';//成功助力好友 + that.log(`格式化后的助力码::${JSON.stringify(newShareCodes)}\n`); + + for (let code of newShareCodes) { + that.log(`开始助力动动账号${$.index} - ${$.nickName}的好友: ${code}`); + if (!code) continue; + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('不能为自己助力哦,跳过自己的shareCode\n') + continue + } + await masterHelp(code); + if ($.helpResult.code === '0') { + if ($.helpResult.helpResult.code === '0') { + //助力成功 + salveHelpAddWater += $.helpResult.helpResult.salveHelpAddWater; + that.log(`【助力好友结果】: 已成功给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力`); + that.log(`给好友【${$.helpResult.helpResult.masterUserInfo.nickName}】助力获得${$.helpResult.helpResult.salveHelpAddWater}g水滴`) + helpSuccessPeoples += ($.helpResult.helpResult.masterUserInfo.nickName || '匿名用户') + ','; + } else if ($.helpResult.helpResult.code === '8') { + that.log(`【助力好友结果】: 助力【${$.helpResult.helpResult.masterUserInfo.nickName}】失败,您今天助力次数已耗尽`); + } else if ($.helpResult.helpResult.code === '9') { + that.log(`【助力好友结果】: 之前给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力过了`); + } else if ($.helpResult.helpResult.code === '10') { + that.log(`【助力好友结果】: 好友【${$.helpResult.helpResult.masterUserInfo.nickName}】已满五人助力`); + } else { + that.log(`助力其他情况:${JSON.stringify($.helpResult.helpResult)}`); + } + that.log(`【今日助力次数还剩】${$.helpResult.helpResult.remainTimes}次\n`); + remainTimes = $.helpResult.helpResult.remainTimes; + if ($.helpResult.helpResult.remainTimes === 0) { + that.log(`您当前助力次数已耗尽,跳出助力`); + break + } + } else { + that.log(`助力失败::${JSON.stringify($.helpResult)}`); + } + } + if (helpSuccessPeoples && helpSuccessPeoples.length > 0) { + // message += " " + `【您助力的好友👬】${helpSuccessPeoples.substr(0, helpSuccessPeoples.length - 1)}\n` + "\n\n"; + } + if (salveHelpAddWater > 0) { + // message += `【助力好友👬】获得${salveHelpAddWater}g💧\n`; + that.log(`【助力好友👬】获得${salveHelpAddWater}g💧\n`); + } + // message += "" + `【今日剩余助力👬】${remainTimes}次\n` + "\n\n"; + that.log('助力好友结束,即将开始领取额外水滴奖励\n'); + } + //水滴雨 + async function executeWaterRains() { + let executeWaterRain = !$.farmTask.waterRainInit.f; + if (executeWaterRain) { + that.log(`水滴雨任务,每天两次,最多可得10g水滴`); + that.log(`两次水滴雨任务是否全部完成:${$.farmTask.waterRainInit.f ? '是' : '否'}`); + if ($.farmTask.waterRainInit.lastTime) { + if (Date.now() < ($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000)) { + executeWaterRain = false; + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`; + that.log(`\`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`); + } + } + if (executeWaterRain) { + that.log(`开始水滴雨任务,这是第${$.farmTask.waterRainInit.winTimes + 1}次,剩余${2 - ($.farmTask.waterRainInit.winTimes + 1)}次`); + await waterRainForFarm(); + that.log('水滴雨waterRain'); + if ($.waterRain.code === '0') { + that.log('水滴雨任务执行成功,获得水滴:' + $.waterRain.addEnergy + 'g'); + that.log(`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`); + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`; + } + } + } else { + // message += `【水滴雨】已全部完成,获得20g💧\n`; + } + } + //打卡领水活动 + async function clockInIn() { + that.log('开始打卡领水活动(签到,关注,领券)'); + await clockInInitForFarm(); + if ($.clockInInit.code === '0') { + // 签到得水滴 + if (!$.clockInInit.todaySigned) { + that.log('开始今日签到'); + await clockInForFarm(); + that.log(`打卡结果${JSON.stringify($.clockInForFarmRes)}`); + if ($.clockInForFarmRes.code === '0') { + // message += `【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`; + that.log(`【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`) + if ($.clockInForFarmRes.signDay === 7) { + //可以领取惊喜礼包 + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + } + } + if ($.clockInInit.todaySigned && $.clockInInit.totalSigned === 7) { + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + // 限时关注得水滴 + if ($.clockInInit.themes && $.clockInInit.themes.length > 0) { + for (let item of $.clockInInit.themes) { + if (!item.hadGot) { + that.log(`关注ID${item.id}`); + await clockInFollowForFarm(item.id, "theme", "1"); + that.log(`themeStep1--结果${JSON.stringify($.themeStep1)}`); + if ($.themeStep1.code === '0') { + await clockInFollowForFarm(item.id, "theme", "2"); + that.log(`themeStep2--结果${JSON.stringify($.themeStep2)}`); + if ($.themeStep2.code === '0') { + that.log(`关注${item.name},获得水滴${$.themeStep2.amount}g`); + } + } + } + } + } + // 限时领券得水滴 + if ($.clockInInit.venderCoupons && $.clockInInit.venderCoupons.length > 0) { + for (let item of $.clockInInit.venderCoupons) { + if (!item.hadGot) { + that.log(`领券的ID${item.id}`); + await clockInFollowForFarm(item.id, "venderCoupon", "1"); + that.log(`venderCouponStep1--结果${JSON.stringify($.venderCouponStep1)}`); + if ($.venderCouponStep1.code === '0') { + await clockInFollowForFarm(item.id, "venderCoupon", "2"); + if ($.venderCouponStep2.code === '0') { + that.log(`venderCouponStep2--结果${JSON.stringify($.venderCouponStep2)}`); + that.log(`从${item.name}领券,获得水滴${$.venderCouponStep2.amount}g`); + } + } + } + } + } + } + that.log('开始打卡领水活动(签到,关注,领券)结束\n'); + } + // + async function getAwardInviteFriend() { + await friendListInitForFarm();//查询好友列表 + that.log(`查询好友列表数据:\n`) + if ($.friendList) { + that.log(`\n今日已邀请好友${$.friendList.inviteFriendCount}个 / 每日邀请上限${$.friendList.inviteFriendMax}个`); + that.log(`开始删除${$.friendList.friends && $.friendList.friends.length}个好友,可拿每天的邀请奖励`); + if ($.friendList.friends && $.friendList.friends.length > 0) { + for (let friend of $.friendList.friends) { + that.log(`\n开始删除好友 [${friend.shareCode}]`); + const deleteFriendForFarm = await request('deleteFriendForFarm', { "shareCode": `${friend.shareCode}`,"version":8,"channel":1 }); + if (deleteFriendForFarm && deleteFriendForFarm.code === '0') { + that.log(`删除好友 [${friend.shareCode}] 成功\n`); + } + } + } + await receiveFriendInvite();//为他人助力,接受邀请成为别人的好友 + if ($.friendList.inviteFriendCount > 0) { + if ($.friendList.inviteFriendCount > $.friendList.inviteFriendGotAwardCount) { + that.log('开始领取邀请好友的奖励'); + await awardInviteFriendForFarm(); + that.log(`领取邀请好友的奖励结果::${JSON.stringify($.awardInviteFriendRes)}`); + } + } else { + that.log('今日未邀请过好友') + } + } else { + that.log(`查询好友列表失败\n`); + } + } + //给好友浇水 + async function doFriendsWater() { + await friendListInitForFarm(); + that.log('开始给好友浇水...'); + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax } = $.farmTask.waterFriendTaskInit; + that.log(`今日已给${waterFriendCountKey}个好友浇水`); + if (waterFriendCountKey < waterFriendMax) { + let needWaterFriends = []; + if ($.friendList.friends && $.friendList.friends.length > 0) { + $.friendList.friends.map((item, index) => { + if (item.friendState === 1) { + if (needWaterFriends.length < (waterFriendMax - waterFriendCountKey)) { + needWaterFriends.push(item.shareCode); + } + } + }); + //TODO ,发现bug,github action运行发现有些账号第一次没有给3个好友浇水 + that.log(`需要浇水的好友列表shareCodes:${JSON.stringify(needWaterFriends)}`); + let waterFriendsCount = 0, cardInfoStr = ''; + for (let index = 0; index < needWaterFriends.length; index ++) { + await waterFriendForFarm(needWaterFriends[index]); + that.log(`为第${index+1}个好友浇水结果:${JSON.stringify($.waterFriendForFarmRes)}\n`) + if ($.waterFriendForFarmRes.code === '0') { + waterFriendsCount ++; + if ($.waterFriendForFarmRes.cardInfo) { + that.log('为好友浇水获得道具了'); + if ($.waterFriendForFarmRes.cardInfo.type === 'beanCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴换豆卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'fastCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `快速浇水卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'doubleCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴翻倍卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'signCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `加签卡,`; + } + } + } else if ($.waterFriendForFarmRes.code === '11') { + that.log('水滴不够,跳出浇水') + } + } + // message += `【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`; + that.log(`【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`); + if (cardInfoStr && cardInfoStr.length > 0) { + // message += `【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`; + that.log(`【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`); + } + } else { + that.log('您的好友列表暂无好友,快去邀请您的好友吧!') + } + } else { + that.log(`今日已为好友浇水量已达${waterFriendMax}个`) + } + } + //领取给3个好友浇水后的奖励水滴 + async function getWaterFriendGotAward() { + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax, waterFriendSendWater, waterFriendGotAward } = $.farmTask.waterFriendTaskInit + if (waterFriendCountKey >= waterFriendMax) { + if (!waterFriendGotAward) { + await waterFriendGotAwardForFarm(); + that.log(`领取给${waterFriendMax}个好友浇水后的奖励水滴::${JSON.stringify($.waterFriendGotAwardRes)}`) + if ($.waterFriendGotAwardRes.code === '0') { + // message += `【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`; + that.log(`【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`); + } + } else { + that.log(`给好友浇水的${waterFriendSendWater}g水滴奖励已领取\n`); + // message += `【给${waterFriendMax}好友浇水】奖励${waterFriendSendWater}g水滴已领取\n`; + } + } else { + that.log(`暂未给${waterFriendMax}个好友浇水\n`); + } + } + //接收成为对方好友的邀请 + async function receiveFriendInvite() { + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('自己不能邀请自己成为好友噢\n') + continue + } + await inviteFriend(code); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + if ($.inviteFriendRes.helpResult.code === '0') { + that.log(`接收邀请成为好友结果成功,您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + } else if ($.inviteFriendRes.helpResult.code === '17') { + that.log(`接收邀请成为好友结果失败,对方已是您的好友`) + } + } + // that.log(`开始接受6fbd26cc27ac44d6a7fed34092453f77的邀请\n`) + // await inviteFriend('6fbd26cc27ac44d6a7fed34092453f77'); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + // if ($.inviteFriendRes.helpResult.code === '0') { + // that.log(`您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + // } else if ($.inviteFriendRes.helpResult.code === '17') { + // that.log(`对方已是您的好友`) + // } + } + async function duck() { + for (let i = 0; i < 10; i++) { + //这里循环十次 + await getFullCollectionReward(); + if ($.duckRes.code === '0') { + if (!$.duckRes.hasLimit) { + that.log(`小鸭子游戏:${$.duckRes.title}`); + // if ($.duckRes.type !== 3) { + // that.log(`${$.duckRes.title}`); + // if ($.duckRes.type === 1) { + // message += `【小鸭子】为你带回了水滴\n`; + // } else if ($.duckRes.type === 2) { + // message += `【小鸭子】为你带回快速浇水卡\n` + // } + // } + } else { + that.log(`${$.duckRes.title}`) + break; + } + } else if ($.duckRes.code === '10') { + that.log(`小鸭子游戏达到上限`) + break; + } + } + } + // ========================API调用接口======================== + //鸭子,点我有惊喜 + async function getFullCollectionReward() { + return new Promise(resolve => { + const body = {"type": 2, "version": 6, "channel": 2}; + $.post(taskUrl("getFullCollectionReward", body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + /** + * 领取10次浇水奖励API + */ + async function totalWaterTaskForFarm() { + const functionId = 'totalWaterTaskForFarm'; + $.totalWaterReward = await request(functionId); + } + //领取首次浇水奖励API + async function firstWaterTaskForFarm() { + const functionId = 'firstWaterTaskForFarm'; + $.firstWaterReward = await request(functionId); + } + //领取给3个好友浇水后的奖励水滴API + async function waterFriendGotAwardForFarm() { + const functionId = 'waterFriendGotAwardForFarm'; + $.waterFriendGotAwardRes = await request(functionId, {"version": 4, "channel": 1}); + } + // 查询背包道具卡API + async function myCardInfoForFarm() { + const functionId = 'myCardInfoForFarm'; + $.myCardInfoRes = await request(functionId, {"version": 5, "channel": 1}); + } + //使用道具卡API + async function userMyCardForFarm(cardType) { + const functionId = 'userMyCardForFarm'; + $.userMyCardRes = await request(functionId, {"cardType": cardType}); + } + /** + * 领取浇水过程中的阶段性奖励 + * @param type + * @returns {Promise} + */ + async function gotStageAwardForFarm(type) { + $.gotStageAwardForFarmRes = await request('gotStageAwardForFarm', {'type': type}); + } + //浇水API + async function waterGoodForFarm() { + await $.wait(1000); + that.log('等待了1秒'); + + const functionId = 'waterGoodForFarm'; + $.waterResult = await request(functionId); + } + // 初始化集卡抽奖活动数据API + async function initForTurntableFarm() { + $.initForTurntableFarmRes = await request('initForTurntableFarm', {version: 4, channel: 1}); + } + async function lotteryForTurntableFarm() { + await $.wait(2000); + that.log('等待了2秒'); + $.lotteryRes = await request('lotteryForTurntableFarm', {type: 1, version: 4, channel: 1}); + } + + async function timingAwardForTurntableFarm() { + $.timingAwardRes = await request('timingAwardForTurntableFarm', {version: 4, channel: 1}); + } + + async function browserForTurntableFarm(type, adId) { + if (type === 1) { + that.log('浏览爆品会场'); + } + if (type === 2) { + that.log('天天抽奖浏览任务领取水滴'); + } + const body = {"type": type,"adId": adId,"version":4,"channel":1}; + $.browserForTurntableFarmRes = await request('browserForTurntableFarm', body); + // 浏览爆品会场8秒 + } + //天天抽奖浏览任务领取水滴API + async function browserForTurntableFarm2(type) { + const body = {"type":2,"adId": type,"version":4,"channel":1}; + $.browserForTurntableFarm2Res = await request('browserForTurntableFarm', body); + } + /** + * 天天抽奖拿好礼-助力API(每人每天三次助力机会) + */ + async function lotteryMasterHelp() { + $.lotteryMasterHelpRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-3', + babelChannel: "3", + version: 4, + channel: 1 + }); + } + + //领取5人助力后的额外奖励API + async function masterGotFinishedTaskForFarm() { + const functionId = 'masterGotFinishedTaskForFarm'; + $.masterGotFinished = await request(functionId); + } + //助力好友信息API + async function masterHelpTaskInitForFarm() { + const functionId = 'masterHelpTaskInitForFarm'; + $.masterHelpResult = await request(functionId); + } + //接受对方邀请,成为对方好友的API + async function inviteFriend() { + $.inviteFriendRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-inviteFriend', + version: 4, + channel: 2 + }); + } + // 助力好友API + async function masterHelp() { + $.helpResult = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0], + babelChannel: "3", + version: 2, + channel: 1 + }); + } + /** + * 水滴雨API + */ + async function waterRainForFarm() { + const functionId = 'waterRainForFarm'; + const body = {"type": 1, "hongBaoTimes": 100, "version": 3}; + $.waterRain = await request(functionId, body); + } + /** + * 打卡领水API + */ + async function clockInInitForFarm() { + const functionId = 'clockInInitForFarm'; + $.clockInInit = await request(functionId); + } + + // 连续签到API + async function clockInForFarm() { + const functionId = 'clockInForFarm'; + $.clockInForFarmRes = await request(functionId, {"type": 1}); + } + + //关注,领券等API + async function clockInFollowForFarm(id, type, step) { + const functionId = 'clockInFollowForFarm'; + let body = { + id, + type, + step + } + if (type === 'theme') { + if (step === '1') { + $.themeStep1 = await request(functionId, body); + } else if (step === '2') { + $.themeStep2 = await request(functionId, body); + } + } else if (type === 'venderCoupon') { + if (step === '1') { + $.venderCouponStep1 = await request(functionId, body); + } else if (step === '2') { + $.venderCouponStep2 = await request(functionId, body); + } + } + } + + // 领取连续签到7天的惊喜礼包API + async function gotClockInGift() { + $.gotClockInGiftRes = await request('clockInForFarm', {"type": 2}) + } + + //定时领水API + async function gotThreeMealForFarm() { + const functionId ='gotThreeMealForFarm'; + $.threeMeal = await request(functionId); + } + /** + * 浏览广告任务API + * type为0时, 完成浏览任务 + * type为1时, 领取浏览任务奖励 + */ + async function browseAdTaskForFarm(advertId, type) { + const functionId = 'browseAdTaskForFarm'; + if (type === 0) { + $.browseResult = await request(functionId, {advertId, type}); + } else if (type === 1) { + $.browseRwardResult = await request(functionId, {advertId, type}); + } + } + // 被水滴砸中API + async function gotWaterGoalTaskForFarm() { + $.goalResult = await request('gotWaterGoalTaskForFarm', {type: 3}); + } + //签到API + async function signForFarm() { + const functionId = 'signForFarm'; + $.signResult = await request(functionId); + } + /** + * 初始化农场, 可获取果树及用户信息API + */ + async function initForFarm() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "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" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + // 初始化任务列表API + async function taskInitForFarm() { + that.log('\n初始化任务列表') + const functionId = 'taskInitForFarm'; + $.farmTask = await request(functionId); + } + //获取好友列表API + async function friendListInitForFarm() { + $.friendList = await request('friendListInitForFarm', {"version": 4, "channel": 1}); + // that.log('aa', aa); + } + // 领取邀请好友的奖励API + async function awardInviteFriendForFarm() { + $.awardInviteFriendRes = await request('awardInviteFriendForFarm'); + } + //为好友浇水API + async function waterFriendForFarm(shareCode) { + const body = {"shareCode": shareCode, "version": 6, "channel": 1} + $.waterFriendForFarmRes = await request('waterFriendForFarm', body); + } + + + function readShareCode() { + return new Promise(async resolve => { + $.get({url: `http://jd.turinglabs.net/api/v2/jd/farm/read/${randomCount}/`, timeout: 10000,}, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + that.log(`随机取个${randomCount}码放到您固定的互助码后面(不影响已有固定互助)`) + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + await $.wait(10000); + resolve() + }) + } + function shareCodesFormat() { + return new Promise(async resolve => { + // that.log(`第${$.index}个动动账号的助力码:::${jdFruitShareArr[$.index - 1]}`) + newShareCodes = []; + // if (jdFruitShareArr[$.index - 1]) { + // newShareCodes = jdFruitShareArr[$.index - 1].split('@'); + // } else { + // that.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + // const tempIndex = $.index > shareCodes.length ? (shareCodes.length - 1) : ($.index - 1); + // newShareCodes = shareCodes[tempIndex].split('@'); + // } + // const readShareCodeRes = await readShareCode(); + // if (readShareCodeRes && readShareCodeRes.code === 200) { + // // newShareCodes = newShareCodes.concat(readShareCodeRes.data || []); + // newShareCodes = [...new Set([...newShareCodes, ...(readShareCodeRes.data || [])])]; + // } + // that.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify(newShareCodes)}`) + resolve(); + }) + } + + function request(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️') + that.log(JSON.stringify(err)); + that.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) + } + function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } + } + function taskUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + }, + timeout: 10000, + } + } + //-------------------------------------------------东东赚赚------------------------------------------------------------ + + +async function jdWish() { + $.bean = 0 + $.tuan = null + $.hasOpen = false + await getTaskList(true) + await getUserTuanInfo() + if (!$.tuan) { + await openTuan() + if ($.hasOpen) await getUserTuanInfo() + } + if ($.tuan) $.tuanList.push($.tuan) + await helpFriends() + await getUserInfo() + $.nowBean = parseInt($.totalBeanNum) + $.nowNum = parseInt($.totalNum) + for (let i = 0; i < $.taskList.length; ++i) { + let task = $.taskList[i] + if (task['taskId'] === 1 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + } else if (task['taskId'] !== 3 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + if(task['itemId']) + await doTask({"itemId":task['itemId'],"taskId":task['taskId'],"mpVersion":"3.4.0"}) + else + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + await $.wait(3000) + } + } + await getTaskList(); + await showMsg1(); + } + + + function helpFriendTuan(body) { + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_assist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.success) { + that.log('助力成功') + } else { + if (data.resultCode === '9200008') that.log('不能助力自己') + else if (data.resultCode === '9200011') that.log('已经助力过') + else if (data.resultCode === '2400205') that.log('团已满') + else if (data.resultCode === '2400203') {that.log('助力次数已耗尽');$.canHelp = false} + else that.log(`未知错误`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getUserTuanInfo() { + let body = {"paramData": {"channel": "FISSION_BEAN"}} + return new Promise(resolve => { + $.get(taskTuanUrl("distributeBeanActivityInfo", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data && !data.data.canStartNewAssist) { + $.tuan = { + "activityIdEncrypted": data.data.id, + "assistStartRecordId": data.data.assistStartRecordId, + "assistedPinEncrypted": data.data.encPin, + "channel": "FISSION_BEAN" + } + $.tuanActId = data.data.id + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function openTuan() { + let body = {"activityIdEncrypted": $.tuanActId, "channel": "FISSION_BEAN"} + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_startAssist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['success']) { + $.hasOpen = true + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getUserInfo() { + return new Promise(resolve => { + $.get(taskUrl1("interactIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // if (data.data.shareTaskRes) { + // that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${data.data.shareTaskRes.itemId}\n`); + // } else { + // that.log(`\n\n已满5人助力或助力功能已下线,故暂时无${$.name}好友助力码\n\n`) + // } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getTaskList(flag = false) { + return new Promise(resolve => { + $.get(taskUrl1("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.taskList = data.data.taskDetailResList + $.totalNum = data.data.totalNum + $.totalBeanNum = data.data.totalBeanNum + if (flag && $.taskList.filter(item => !!item && item['taskId']=== 3) && $.taskList.filter(item => !!item && item['taskId']=== 3).length) { + $.shareId=$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + // 完成 + function doTask(body, func = "doInteractTask") { + // that.log(taskUrl("doInteractTask", body)) + return new Promise(resolve => { + $.get(taskUrl1(func, body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // that.log(data) + if (func === "doInteractTask") { + if (data.subCode === "S000") { + that.log(`任务完成,获得 ${data.data.taskDetailResList[0].incomeAmountConf} 金币,${data.data.taskDetailResList[0].beanNum} 京豆`) + $.bean += parseInt(data.data.taskDetailResList[0].beanNum) + } else { + that.log(`任务失败,错误信息:${data.message}`) + } + } else { + that.log(`${data.data.helpResDesc}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + async function helpFriends() { + await getHelp(); + for (let code of $.newShareCodes) { + if (!code) continue + await doTask({"itemId": code, "taskId": "3", "mpVersion": "3.4.0"}, "doHelpTask") + } + await setHelp(); + } + + function getHelp() { + $.newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzz/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + $.newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.shareId) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzz/" + $.shareId + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function getHelpTuan() { + $.tuanList = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzzTuan/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var item of list) { + let its=item.split('@'); + if(its.length==2){ + let tuan={ + "activityIdEncrypted": $.tuanActId, + "assistStartRecordId": its[0], + "assistedPinEncrypted": its[1], + "channel": "FISSION_BEAN" + } + $.tuanList.push(tuan); + } + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelpTuan() { + return new Promise(resolve => { + if ($.tuan) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzzTuan/" + $.tuan.assistStartRecordId+'@'+$.tuan.assistedPinEncrypted + }, (err, resp, data) => { + try { + if (data) { + that.log(data); + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的开团碼成功"); + }else{ + that.log("提交开团码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function taskUrl1(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } + } + + function taskTuanUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&body=${escape(JSON.stringify(body))}&appid=swat_miniprogram&osVersion=5.0.0&clientVersion=3.1.3&fromType=wxapp×tamp=${new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 + 8 * 60 * 60 * 1000}`, + headers: { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "api.m.jd.com", + "Referer": "https://servicewechat.com/wxa5bf5ee667d91626/108/page-frame.html", + "Cookie": cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + } + } + } + + + + function showMsg1() { + return new Promise(async resolve => { + that.log( "" + `本次获得${parseInt($.totalBeanNum) - $.nowBean}京豆,${parseInt($.totalNum) - $.nowNum}金币\n` + "\n\n") + message += "" + `累计获得${$.totalBeanNum}京豆,${$.totalNum}金币\n可兑换${$.totalNum / 10000}元无门槛红包` + "\n\n" + if (parseInt($.totalBeanNum) - $.nowBean > 0) { + $.msg($.name, '', `动动账号${$.index} ${$.nickName}\n${message}`); + } else { + $.log(message) + } + // 云端大于10元无门槛红包时进行通知推送 + if ($.isNode() && $.totalNum >= 1000000) await notify.sendNotify(`${$.name} - 动动账号${$.index} - ${$.nickName}`, `动动账号${$.index} ${$.nickName}\n当前金币:${$.totalNum}个\n可兑换无门槛红包:${parseInt($.totalNum) / 10000}元\n`,) + resolve(); + }) + } + + + + + +//我加的函数 +function postToDingTalk(messgae) { + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"资产变动", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_lwq_new.js b/src/main/resources/test_lwq_new.js new file mode 100644 index 0000000..278ce33 --- /dev/null +++ b/src/main/resources/test_lwq_new.js @@ -0,0 +1,1213 @@ +/* +cron "30 10,22 * * *" jd_bean_change.js, tag:资产变化强化版by-ccwav +*/ +let roleMap = { + "好吧好吧5577":"wq_好吧好吧5577", + "jd_qapvwBDaRqgW":"wgh_19970291531", + "18070420956_p":"刘吴奇", +} + +let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" +//更新by ccwav,20210821 +const $ = new Env('京东资产变动通知'); +const notify = $.isNode() ? require('./sendNotify') : ''; +const JXUserAgent = $.isNode() ? (process.env.JX_USER_AGENT ? process.env.JX_USER_AGENT : ``):``; +//Node.js用户请在jdCookie.js处填写京东ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +let allMessage = ''; +let message = ""; +let ReturnMessage = ''; +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; + +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} +!(async () => { + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + message += "[通知] 资产变动 \n\n --- \n\n" + let count = 0 + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.beanCount = 0; + $.incomeBean = 0; + $.expenseBean = 0; + $.todayIncomeBean = 0; + $.errorMsg = ''; + $.isLogin = true; + $.nickName = ''; + $.message = ''; + $.balance = 0; + $.expiredBalance = 0; + $.JdzzNum=0; + $.JdMsScore = 0; + $.JdFarmProdName = ''; + $.JdtreeEnergy=0; + $.JdtreeTotalEnergy=0; + $.JdwaterTotalT = 0; + $.JdwaterD = 0; + $.JDwaterEveryDayT=0; + $.JDtotalcash=0; + $.JDEggcnt=0; + $.Jxmctoken=''; + await TotalBean(); + + username = $.UserName + if (roleMap[username] == undefined){ + continue + } + username = roleMap[username] + + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + console.log(`\n********开始【京东账号${$.index}】${$.nickName || $.UserName}******\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await getJdZZ(); + await getMs(); + await jdfruitRequest('taskInitForFarm', {"version":14,"channel":1,"babelChannel":"120"}); + await getjdfruit(); + await cash(); + await requestAlgo(); + await JxmcGetRequest(); + await bean(); + await getJxFactory(); //惊喜工厂 + await getDdFactoryInfo(); // 京东工厂 + await showMsg(); + message += "----\n\n" + } + + if( (count+1)%4 ==0 ){ + postToDingTalk(message) + message = "" + } + count ++ + } + + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + if (message != ""){ + postToDingTalk(message) + } + $.done(); + }) +async function showMsg() { + if ($.errorMsg) return + //allMessage += `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆 🐶${$.message}${$.index !== cookiesArr.length ? '\n\n' : ''}`; + + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `账号${$.index}:${$.nickName || $.UserName}\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}京豆 🐶${$.message}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + // } + + ReturnMessage=`📣=============账号${$.index}=============📣\n` + ReturnMessage+=`账号名称:${$.nickName || $.UserName}\n`; + ReturnMessage+=`今日收入:${$.todayIncomeBean}京豆 🐶\n`; + ReturnMessage+=`昨日支出:${$.expenseBean}京豆 🐶\n`; + ReturnMessage+=`昨日收入:${$.incomeBean}京豆 🐶\n`; + ReturnMessage+=`当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶\n`; + + message += "" + `当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶\n` +"\n\n" + message += "" +`今日收入:${$.todayIncomeBean}京豆 🐶\n` + "\n\n" + message += "" + `昨日收入:${$.incomeBean}京豆 🐶\n` +"\n\n" + message += "" +`昨日支出:${$.expenseBean}京豆 🐶\n` +"\n\n" + // message += "" +`🐶🐶🐶🐶🐶🐶🐶🐶🐶🐶` +"\n\n" + + + if(typeof $.JDtotalcash !== "undefined"){ + ReturnMessage+=`极速金币:${$.JDtotalcash}金币(≈${$.JDtotalcash / 10000}元)\n`; + message += "" + `极速金币:${$.JDtotalcash}金币(≈${$.JDtotalcash / 10000}元)\n` +"\n\n" + } + if(typeof $.JdzzNum !== "undefined"){ + ReturnMessage+=`京东赚赚:${$.JdzzNum}金币(≈${$.JdzzNum / 10000}元)\n`; + message += "" + `京东赚赚:${$.JdzzNum}金币(≈${$.JdzzNum / 10000}元)\n` +"\n\n" + } + if($.JdMsScore!=0){ + ReturnMessage+=`京东秒杀:${$.JdMsScore}秒秒币(≈${$.JdMsScore / 1000}元)\n`; + message += "" + `京东秒杀:${$.JdMsScore}秒秒币(≈${$.JdMsScore / 1000}元)\n` +"\n\n" + } + + // message += "" +`🏭🏭🏭🏭🏭🏭🏭🏭🏭🏭` +"\n\n" + + + if(typeof $.JDEggcnt !== "undefined"){ + ReturnMessage+=`京喜牧场:${$.JDEggcnt}枚鸡蛋\n`; + message += "" + `京喜牧场:${$.JDEggcnt}枚鸡蛋\n` +"\n\n" + } + if($.JdFarmProdName != ""){ + if($.JdtreeEnergy!=0){ + ReturnMessage+=`东东农场:${$.JdFarmProdName},进度${(($.JdtreeEnergy / $.JdtreeTotalEnergy) * 100).toFixed(2)}%`; + message += "" + `东东农场:${$.JdFarmProdName},进度${(($.JdtreeEnergy / $.JdtreeTotalEnergy) * 100).toFixed(2)}%` + if($.JdwaterD!='Infinity' && $.JdwaterD!='-Infinity'){ + ReturnMessage+=`,${$.JdwaterD === 1 ? '明天' : $.JdwaterD === 2 ? '后天' : $.JdwaterD + '天后'}可兑🍉\n`; + message += "" + `,${$.JdwaterD === 1 ? '明天' : $.JdwaterD === 2 ? '后天' : $.JdwaterD + '天后'}可兑🍉\n` +"\n\n" + } else { + ReturnMessage+=`\n` + "\n\n"; + } + } else { + ReturnMessage+=`东东农场:${$.JdFarmProdName}\n`; + message += "" +`东东农场:${$.JdFarmProdName}\n` +"\n\n" + } + } + if ($.jxFactoryInfo) { + ReturnMessage += `京喜工厂:${$.jxFactoryInfo}🏭\n` + message += "" + `京喜工厂:${$.jxFactoryInfo}🏭\n` +"\n\n" + } + if ($.ddFactoryInfo) { + ReturnMessage += `东东工厂:${$.ddFactoryInfo}🏭\n` + message += "" + `东东工厂:${$.ddFactoryInfo}🏭\n` +"\n\n" + } + + const response = await await PetRequest('energyCollect'); + const initPetTownRes = await PetRequest('initPetTown'); + if (initPetTownRes.code === '0' && initPetTownRes.resultCode === '0' && initPetTownRes.message === 'success') { + $.petInfo = initPetTownRes.result; + if (response.resultCode === '0') { + ReturnMessage += `东东萌宠:${$.petInfo.goodsInfo.goodsName},`; + ReturnMessage += `勋章${response.result.medalNum}/${response.result.medalNum+response.result.needCollectMedalNum}块(${response.result.medalPercent}%)\n`; + //ReturnMessage += ` 已有${response.result.medalNum}块勋章,还需${response.result.needCollectMedalNum}块\n`; + message += "" +`东东萌宠:${$.petInfo.goodsInfo.goodsName},` + message += "" + `勋章${response.result.medalNum}/${response.result.medalNum+response.result.needCollectMedalNum}块(${response.result.medalPercent}%)\n` +"\n\n" + + } + } + ReturnMessage+=`🧧🧧🧧🧧红包明细🧧🧧🧧🧧`; + message += "" +`🧧🧧🧧🧧红包明细🧧🧧🧧🧧` + "\n\n" + ReturnMessage+=`${$.message}\n\n`; + message += "" + `${$.message}\n\n` +"\n\n" + allMessage+=ReturnMessage; + $.msg($.name, '', ReturnMessage , {"open-url": "https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean"}); +} +async function bean() { + // console.log(`北京时间零点时间戳:${parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000}`); + // console.log(`北京时间2020-10-28 06:16:05::${new Date("2020/10/28 06:16:05+08:00").getTime()}`) + // 不管哪个时区。得到都是当前时刻北京时间的时间戳 new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000 + + //前一天的0:0:0时间戳 + const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - (24 * 60 * 60 * 1000); + // 今天0:0:0时间戳 + const tm1 = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + let page = 1, t = 0, yesterdayArr = [], todayArr = []; + do { + let response = await getJingBeanBalanceDetail(page); + // console.log(`第${page}页: ${JSON.stringify(response)}`); + if (response && response.code === "0") { + page++; + let detailList = response.detailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const date = item.date.replace(/-/g, '/') + "+08:00"; + if (new Date(date).getTime() >= tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + todayArr.push(item); + } else if (tm <= new Date(date).getTime() && new Date(date).getTime() < tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + //昨日的 + yesterdayArr.push(item); + } else if (tm > new Date(date).getTime()) { + //前天的 + t = 1; + break; + } + } + } else { + //$.errorMsg = `数据异常`; + //$.msg($.name, ``, `账号${$.index}:${$.nickName}\n${$.errorMsg}`); + t = 1; + } + } else if (response && response.code === "3") { + console.log(`cookie已过期,或者填写不规范,跳出`) + t = 1; + } else { + console.log(`未知情况:${JSON.stringify(response)}`); + console.log(`未知情况,跳出`) + t = 1; + } + } while (t === 0); + for (let item of yesterdayArr) { + if (Number(item.amount) > 0) { + $.incomeBean += Number(item.amount); + } else if (Number(item.amount) < 0) { + $.expenseBean += Number(item.amount); + } + } + for (let item of todayArr) { + if (Number(item.amount) > 0) { + $.todayIncomeBean += Number(item.amount); + } + } + await queryexpirejingdou();//过期京豆 + await redPacket();//过期红包 + // console.log(`昨日收入:${$.incomeBean}个京豆 🐶`); + // console.log(`昨日支出:${$.expenseBean}个京豆 🐶`) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + if (data['retcode'] === '0' && data.data && data.data['assetInfo']) { + $.beanCount = data.data && data.data['assetInfo']['beanNum']; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} +function getJingBeanBalanceDetail(page) { + return new Promise(async resolve => { + const options = { + "url": `https://api.m.jd.com/client.action?functionId=getJingBeanBalanceDetail`, + "body": `body=${escape(JSON.stringify({"pageSize": "20", "page": page.toString()}))}&appid=ld`, + "headers": { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + // console.log(data) + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function queryexpirejingdou() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=${Date.now()}&g_login_type=1&sceneval=2`, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Host": "wq.jd.com", + "Referer": "https://wqs.jd.com/promote/201801/bean/mybean.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1" + } + } + $.expirejingdou = 0; + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // console.log(data) + data = JSON.parse(data.slice(23, -13)); + // console.log(data) + if (data.ret === 0) { + data['expirejingdou'].map(item => { + console.log(`${timeFormat(item['time'] * 1000)}日过期京豆:${item['expireamount']}\n`); + }) + $.expirejingdou = data['expirejingdou'][0]['expireamount']; + // if ($.expirejingdou > 0) { + // $.message += `\n今日将过期:${$.expirejingdou}京豆 🐶`; + // } + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function redPacket() { + return new Promise(async resolve => { + const options = { + "url": `https://m.jingxi.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=1&_=${+new Date()}&sceneval=2&g_login_type=1&g_ty=ls`, + "headers": { + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://st.jingxi.com/my/redpacket.shtml?newPg=App&jxsid=16156262265849285961', + 'Accept-Encoding': 'gzip, deflate, br', + "Cookie": cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data).data + $.jxRed = 0, $.jsRed = 0, $.jdRed = 0, $.jdhRed = 0, $.jxRedExpire = 0, $.jsRedExpire = 0, $.jdRedExpire = 0, $.jdhRedExpire = 0; + let t = new Date() + t.setDate(t.getDate() + 1) + t.setHours(0, 0, 0, 0) + t = parseInt((t - 1) / 1000) + for (let vo of data.useRedInfo.redList || []) { + if (vo.orgLimitStr && vo.orgLimitStr.includes("京喜")) { + $.jxRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jxRedExpire += parseFloat(vo.balance) + } + } else if (vo.activityName.includes("极速版")) { + $.jsRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jsRedExpire += parseFloat(vo.balance) + } + } else if (vo.orgLimitStr && vo.orgLimitStr.includes("京东健康")) { + $.jdhRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdhRedExpire += parseFloat(vo.balance) + } + } else { + $.jdRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdRedExpire += parseFloat(vo.balance) + } + } + } + $.jxRed = $.jxRed.toFixed(2) + $.jsRed = $.jsRed.toFixed(2) + $.jdRed = $.jdRed.toFixed(2) + $.jdhRed = $.jdhRed.toFixed(2) + $.balance = data.balance + $.expiredBalance = ($.jxRedExpire + $.jsRedExpire + $.jdRedExpire).toFixed(2) + // $.message += `\n当前总红包:${$.balance}(今日总过期${$.expiredBalance})元 🧧\n京喜红包:${$.jxRed}(今日将过期${$.jxRedExpire.toFixed(2)})元 🧧\n极速红包:${$.jsRed}(今日将过期${$.jsRedExpire.toFixed(2)})元 🧧\n京东红包:${$.jdRed}(今日将过期${$.jdRedExpire.toFixed(2)})元 🧧\n健康红包:${$.jdhRed}(今日将过期${$.jdhRedExpire.toFixed(2)})元 🧧`; + + $.message += "" + `【当前总红包】:${$.balance}( 今日总过期${$.expiredBalance} )元 🧧` +"\n\n" + $.message += "" + `【京喜红包】:${$.jxRed}( 今日将过期${$.jxRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【极速红包】:${$.jsRed}( 今日将过期${$.jsRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【京东红包】:${$.jdRed}( 今日将过期${$.jdRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【健康红包】:${$.jdhRed}( 今日将过期${$.jdhRedExpire.toFixed(2)} )元 🧧` +"\n\n" + + + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getJdZZ() { + return new Promise(resolve => { + $.get(taskJDZZUrl("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JdzzNum = data.data.totalNum + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function taskJDZZUrl(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +function getMs() { + return new Promise(resolve => { + $.post(taskMsPostUrl('homePageV2', {}, 'appid=SecKill2020'), (err, resp, data) => { + try { + if (err) { + console.log(`${err},${jsonParse(resp.body)['message']}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data) + if (data.code === 2041) { + $.JdMsScore = data.result.assignment.assignmentPoints || 0 + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + + +function taskMsPostUrl(function_id, body = {}, extra = '', function_id2) { + let url = `${JD_API_HOST}`; + if (function_id2) { + url += `?functionId=${function_id2}`; + } + return { + url, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=1.0.0&${extra}`, + headers: { + "Cookie": cookie, + "origin": "https://h5.m.jd.com", + "referer": "https://h5.m.jd.com/babelDiy/Zeus/2NUvze9e1uWf4amBhe1AV6ynmSuH/index.html", + 'Content-Type': 'application/x-www-form-urlencoded', + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + } + } +} + +async function getjdfruit() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Content-Type": "application/x-www-form-urlencoded" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + console.log('\n东东农场: API查询请求失败 ‼️‼️'); + console.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + if ($.farmInfo.farmUserPro) { + $.JdFarmProdName=$.farmInfo.farmUserPro.name; + $.JdtreeEnergy=$.farmInfo.farmUserPro.treeEnergy; + $.JdtreeTotalEnergy=$.farmInfo.farmUserPro.treeTotalEnergy; + + let waterEveryDayT = $.JDwaterEveryDayT; + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + $.JdwaterTotalT = waterTotalT; + $.JdwaterD = waterD; + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function jdfruitRequest(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskfruitUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n东东农场: API查询请求失败 ‼️‼️') + console.log(JSON.stringify(err)); + console.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JDwaterEveryDayT = data.totalWaterTaskInit.totalWaterTaskTimes; + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) +} + + +async function PetRequest(function_id, body = {}) { + await $.wait(3000); + return new Promise((resolve, reject) => { + $.post(taskPetUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n东东萌宠: API查询请求失败 ‼️‼️'); + console.log(JSON.stringify(err)); + $.logErr(err); + } else { + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data) + } + }) + }) +} +function taskPetUrl(function_id, body = {}) { + body["version"] = 2; + body["channel"] = 'app'; + return { + url: `${JD_API_HOST}?functionId=${function_id}`, + body: `body=${escape(JSON.stringify(body))}&appid=wh5&loginWQBiz=pet-town&clientVersion=9.0.4`, + headers: { + 'Cookie': cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + } + }; +} + +function taskfruitUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + }, + timeout: 10000, + } +} + +function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + console.log(e); + console.log(`京东服务器访问数据为空,请检查自身设备网络情况`); + return false; + } +} + +function cash() { + return new Promise(resolve => { + $.get(taskcashUrl('MyAssetsService.execute', + {"method": "userCashRecord", "data": {"channel": 1, "pageNum": 1, "pageSize": 20}}), + async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JDtotalcash = data.data.goldBalance ; + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "", "", "", "", "jsjia", "mi.com"]; + +function taskcashUrl(_0x7683x2, _0x7683x3 = {}) { + let _0x7683x4 = +new Date(); + let _0x7683x5 = `${__Oxb24bc[0x0]}${JSON[__Oxb24bc[0x1]](_0x7683x3)}${__Oxb24bc[0x2]}${_0x7683x2}${__Oxb24bc[0x3]}${_0x7683x4}${__Oxb24bc[0x4]}`; + let _0x7683x6 = __Oxb24bc[0x5]; + const _0x7683x7 = $[__Oxb24bc[0x6]]() ? require(__Oxb24bc[0x7]) : $.CryptoJS; + let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString(); + return { + url: `${__Oxb24bc[0x8]}${JD_API_HOST}${__Oxb24bc[0x9]}${_0x7683x2}${__Oxb24bc[0xa]}${escape(JSON[__Oxb24bc[0x1]](_0x7683x3))}${__Oxb24bc[0xb]}${_0x7683x4}${__Oxb24bc[0xc]}${_0x7683x8}${__Oxb24bc[0x8]}`, + headers: { + 'Host': __Oxb24bc[0xd], + 'accept': __Oxb24bc[0xe], + 'kernelplatform': __Oxb24bc[0xf], + 'user-agent': __Oxb24bc[0x10], + 'accept-language': __Oxb24bc[0x11], + 'Cookie': cookie + } + } +}(function(_0x7683x9, _0x7683xa, _0x7683xb, _0x7683xc, _0x7683xd, _0x7683xe) { + _0x7683xe = __Oxb24bc[0x12]; + _0x7683xc = function(_0x7683xf) { + if (typeof alert !== _0x7683xe) { + alert(_0x7683xf) + }; + if (typeof console !== _0x7683xe) { + console[__Oxb24bc[0x13]](_0x7683xf) + } + }; + _0x7683xb = function(_0x7683x7, _0x7683x9) { + return _0x7683x7 + _0x7683x9 + }; + _0x7683xd = _0x7683xb(__Oxb24bc[0x14], _0x7683xb(_0x7683xb(__Oxb24bc[0x15], __Oxb24bc[0x16]), __Oxb24bc[0x17])); + try { + _0x7683x9 = __encode; + if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === _0x7683xb(__Oxb24bc[0x18], __Oxb24bc[0x19]))) { + _0x7683xc(_0x7683xd) + } + } catch (e) { + _0x7683xc(_0x7683xd) + } +})({}) + +async function JxmcGetRequest() { + let url = ``; + let myRequest = ``; + url = `https://m.jingxi.com/jxmc/queryservice/GetHomePageInfo?channel=7&sceneid=1001&activeid=null&activekey=null&isgift=1&isquerypicksite=1&_stk=channel%2Csceneid&_ste=1`; + url += `&h5st=${decrypt(Date.now(), '', '', url)}&_=${Date.now() + 2}&sceneval=2&g_login_type=1&callback=jsonpCBK${String.fromCharCode(Math.floor(Math.random() * 26) + "A".charCodeAt(0))}&g_ty=ls`; + myRequest = getGetRequest(`GetHomePageInfo`, url); + + + return new Promise(async resolve => { + $.get(myRequest, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`API请求失败,请检查网路重试`) + $.runFlag = false; + console.log(`请求失败`) + } else { + data = JSON.parse(data.match(new RegExp(/jsonpCBK.?\((.*);*/))[1]); + if (data.ret === 0) { + $.JDEggcnt=data.data.eggcnt; + } + } + } catch (e) { + console.log(data); + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +// 惊喜工厂信息查询 +function getJxFactory() { + return new Promise(async resolve => { + let infoMsg = ""; + await $.get(jxTaskurl('userinfo/GetUserInfo', `pin=&sharePin=&shareType=&materialTuanPin=&materialTuanId=&source=`, '_time,materialTuanId,materialTuanPin,pin,sharePin,shareType,source,zone'), async (err, resp, data) => { + try { + if (err) { + $.jxFactoryInfo = "查询失败!"; + //console.log("jx工厂查询失败" + err) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['ret'] === 0) { + data = data['data']; + $.unActive = true;//标记是否开启了京喜活动或者选购了商品进行生产 + if (data.factoryList && data.productionList) { + const production = data.productionList[0]; + const factory = data.factoryList[0]; + //const productionStage = data.productionStage; + $.commodityDimId = production.commodityDimId; + // subTitle = data.user.pin; + await GetCommodityDetails();//获取已选购的商品信息 + infoMsg = `${$.jxProductName} ,进度:${((production.investedElectric / production.needElectric) * 100).toFixed(2)}%`; + if (production.investedElectric >= production.needElectric) { + if (production['exchangeStatus'] === 1) { + infoMsg = `${$.productName} ,已经可兑换,请手动兑换`; + } + if (production['exchangeStatus'] === 3) { + if (new Date().getHours() === 9) { + infoMsg = `${$.productName} ,兑换已超时,请选择新商品进行制造`; + } + } + // await exchangeProNotify() + } else { + infoMsg += ` ,预计:${((production.needElectric - production.investedElectric) / (2 * 60 * 60 * 24)).toFixed(2)}天可兑换` + } + if (production.status === 3) { + infoMsg = "${$.productName} ,已经超时失效, 请选择新商品进行制造" + } + } else { + $.unActive = false;//标记是否开启了京喜活动或者选购了商品进行生产 + if (!data.factoryList) { + // infoMsg = "当前未开始生产商品,请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动" + // $.msg($.name, '【提示】', `京东账号${$.index}[${$.nickName}]京喜工厂活动未开始\n请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动`); + } else if (data.factoryList && !data.productionList) { + // infoMsg = "当前未开始生产商品,请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动" + } + } + } + } else { + console.log(`GetUserInfo异常:${JSON.stringify(data)}`) + } + } + $.jxFactoryInfo = infoMsg; + // console.log(infoMsg); + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + } + ) +} + +// 惊喜的Taskurl +function jxTaskurl(functionId, body = '', stk) { + let url = `https://m.jingxi.com/dreamfactory/${functionId}?zone=dream_factory&${body}&sceneval=2&g_login_type=1&_time=${Date.now()}&_=${Date.now() + 2}&_ste=1` + url += `&h5st=${decrypt(Date.now(), stk, '', url)}` + if (stk) { + url += `&_stk=${encodeURIComponent(stk)}`; + } + return { + url, + headers: { + 'Cookie': cookie, + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'User-Agent': functionId === 'AssistFriend' ? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" : 'jdpingou', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://wqsd.jd.com/pingou/dream_factory/index.html', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +//惊喜查询当前生产的商品名称 +function GetCommodityDetails() { + return new Promise(async resolve => { + // const url = `/dreamfactory/diminfo/GetCommodityDetails?zone=dream_factory&sceneval=2&g_login_type=1&commodityId=${$.commodityDimId}`; + $.get(jxTaskurl('diminfo/GetCommodityDetails', `commodityId=${$.commodityDimId}`, `_time,commodityId,zone`), (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['ret'] === 0) { + data = data['data']; + $.jxProductName = data['commodityList'][0].name; + } else { + console.log(`GetCommodityDetails异常:${JSON.stringify(data)}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +// 东东工厂信息查询 +async function getDdFactoryInfo() { + // 当心仪的商品存在,并且收集起来的电量满足当前商品所需,就投入 + let infoMsg = ""; + return new Promise(resolve => { + $.post(ddFactoryTaskUrl('jdfactory_getHomeData'), async (err, resp, data) => { + try { + if (err) { + $.ddFactoryInfo = "获取失败!" + /*console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`)*/ + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data.bizCode === 0) { + // $.newUser = data.data.result.newUser; + //let wantProduct = $.isNode() ? (process.env.FACTORAY_WANTPRODUCT_NAME ? process.env.FACTORAY_WANTPRODUCT_NAME : wantProduct) : ($.getdata('FACTORAY_WANTPRODUCT_NAME') ? $.getdata('FACTORAY_WANTPRODUCT_NAME') : wantProduct); + if (data.data.result.factoryInfo) { + let { + totalScore, + useScore, + produceScore, + remainScore, + couponCount, + name + } = data.data.result.factoryInfo; + infoMsg = `${name} 剩余${couponCount};电力投入情况 ${useScore}/${totalScore};当前总电力:${remainScore * 1 + useScore * 1} ;完成度:${((remainScore * 1 + useScore * 1) / (totalScore * 1)).toFixed(2) * 100}%` + + if (((remainScore * 1 + useScore * 1) >= totalScore * 1 + 100000) && (couponCount * 1 > 0)) { + // await jdfactory_addEnergy(); + infoMsg = `${name} ,目前数量:${couponCount},当前总电量为:${remainScore * 1 + useScore * 1},已经可以兑换此商品所需总电量:${totalScore},请🔥速去活动页面查看` + } + + } else { + // infoMsg = `当前未选择商品(或未开启活动) , 请到京东APP=>首页=>京东电器=>(底栏)东东工厂 选择商品!` + } + } else { + $.ddFactoryInfo = "获取失败!" + console.log(`异常:${JSON.stringify(data)}`) + } + } + } + $.ddFactoryInfo = infoMsg; + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function ddFactoryTaskUrl(function_id, body = {}, function_id2) { + let url = `${JD_API_HOST}`; + if (function_id2) { + url += `?functionId=${function_id2}`; + } + return { + url, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=1.1.0`, + headers: { + "Accept": "application/json, text/plain, */*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": cookie, + "Host": "api.m.jd.com", + "Origin": "https://h5.m.jd.com", + "Referer": "https://h5.m.jd.com/babelDiy/Zeus/2uSsV2wHEkySvompfjB43nuKkcHp/index.html", + "User-Agent": "jdapp;iPhone;9.3.4;14.3;88732f840b77821b345bf07fd71f609e6ff12f43;network/4g;ADID/1C141FDD-C62F-425B-8033-9AAB7E4AE6A3;supportApplePay/0;hasUPPay/0;hasOCPay/0;model/iPhone11,8;addressid/2005183373;supportBestPay/0;appBuild/167502;jdSupportDarkMode/0;pv/414.19;apprpd/Babel_Native;ref/TTTChannelViewContoller;psq/5;ads/;psn/88732f840b77821b345bf07fd71f609e6ff12f43|1701;jdv/0|iosapp|t_335139774|appshare|CopyURL|1610885480412|1610885486;adk/;app_device/IOS;pap/JA2015_311210|9.3.4|IOS 14.3;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", + }, + timeout: 10000, + } +} +function randomString(e) { + e = e || 32; + let t = "0123456789abcdef", a = t.length, n = ""; + for (let i = 0; i < e; i++) + n += t.charAt(Math.floor(Math.random() * a)); + return n +} + +function getGetRequest(type, url) { + UA = `jdpingou;iPhone;4.13.0;14.4.2;${randomString(40)};network/wifi;model/iPhone10,2;appBuild/100609;ADID/00000000-0000-0000-0000-000000000000;supportApplePay/1;hasUPPay/0;pushNoticeIsOpen/1;hasOCPay/0;supportBestPay/0;session/${Math.random * 98 + 1};pap/JA2019_3111789;brand/apple;supportJDSHWK/1;Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148` + + const method = `GET`; + let headers = { + 'Origin': `https://st.jingxi.com`, + 'Cookie': cookie, + 'Connection': `keep-alive`, + 'Accept': `application/json`, + 'Referer': `https://st.jingxi.com/pingou/jxmc/index.html`, + 'Host': `m.jingxi.com`, + 'User-Agent': UA, + 'Accept-Encoding': `gzip, deflate, br`, + 'Accept-Language': `zh-cn` + }; + return {url: url, method: method, headers: headers}; +} + + +Date.prototype.Format = function (fmt) { + var e, + n = this, d = fmt, l = { + "M+": n.getMonth() + 1, + "d+": n.getDate(), + "D+": n.getDate(), + "h+": n.getHours(), + "H+": n.getHours(), + "m+": n.getMinutes(), + "s+": n.getSeconds(), + "w+": n.getDay(), + "q+": Math.floor((n.getMonth() + 3) / 3), + "S+": n.getMilliseconds() + }; + /(y+)/i.test(d) && (d = d.replace(RegExp.$1, "".concat(n.getFullYear()).substr(4 - RegExp.$1.length))); + for (var k in l) { + if (new RegExp("(".concat(k, ")")).test(d)) { + var t, a = "S+" === k ? "000" : "00"; + d = d.replace(RegExp.$1, 1 == RegExp.$1.length ? l[k] : ("".concat(a) + l[k]).substr("".concat(l[k]).length)) + } + } + return d; +} + +function decrypt(time, stk, type, url) { + stk = stk || (url ? getJxmcUrlData(url, '_stk') : '') + if (stk) { + const timestamp = new Date(time).Format("yyyyMMddhhmmssSSS"); + let hash1 = ''; + if ($.fingerprint && $.Jxmctoken && $.enCryptMethodJD) { + hash1 = $.enCryptMethodJD($.Jxmctoken, $.fingerprint.toString(), timestamp.toString(), $.appId.toString(), $.CryptoJS).toString($.CryptoJS.enc.Hex); + } else { + const random = '5gkjB6SpmC9s'; + $.Jxmctoken = `tk01wcdf61cb3a8nYUtHcmhSUFFCfddDPRvKvYaMjHkxo6Aj7dhzO+GXGFa9nPXfcgT+mULoF1b1YIS1ghvSlbwhE0Xc`; + $.fingerprint = 5287160221454703; + const str = `${$.Jxmctoken}${$.fingerprint}${timestamp}${$.appId}${random}`; + hash1 = $.CryptoJS.SHA512(str, $.Jxmctoken).toString($.CryptoJS.enc.Hex); + } + let st = ''; + stk.split(',').map((item, index) => { + st += `${item}:${getJxmcUrlData(url, item)}${index === stk.split(',').length - 1 ? '' : '&'}`; + }) + const hash2 = $.CryptoJS.HmacSHA256(st, hash1.toString()).toString($.CryptoJS.enc.Hex); + return encodeURIComponent(["".concat(timestamp.toString()), "".concat($.fingerprint.toString()), "".concat($.appId.toString()), "".concat($.Jxmctoken), "".concat(hash2)].join(";")) + } else { + return '20210318144213808;8277529360925161;10001;tk01w952a1b73a8nU0luMGtBanZTHCgj0KFVwDa4n5pJ95T/5bxO/m54p4MtgVEwKNev1u/BUjrpWAUMZPW0Kz2RWP8v;86054c036fe3bf0991bd9a9da1a8d44dd130c6508602215e50bb1e385326779d' + } +} + +async function requestAlgo() { + $.fingerprint = await generateFp(); + $.appId = 10028; + const options = { + "url": `https://cactus.jd.com/request_algo?g_ty=ajax`, + "headers": { + 'Authority': 'cactus.jd.com', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + 'Accept': 'application/json', + 'User-Agent':$.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + //'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1', + 'Content-Type': 'application/json', + 'Origin': 'https://st.jingxi.com', + 'Sec-Fetch-Site': 'cross-site', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Dest': 'empty', + 'Referer': 'https://st.jingxi.com/', + 'Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7' + }, + 'body': JSON.stringify({ + "version": "1.0", + "fp": $.fingerprint, + "appId": $.appId.toString(), + "timestamp": Date.now(), + "platform": "web", + "expandParams": "" + }) + } + new Promise(async resolve => { + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`request_algo 签名参数API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['status'] === 200) { + $.Jxmctoken = data.data.result.tk; + let enCryptMethodJDString = data.data.result.algo; + // if (enCryptMethodJDString) $.enCryptMethodJD = new Function(`return ${enCryptMethodJDString}`)(); + eval(enCryptMethodJDString+';$.enCryptMethodJD=test'); + } else { + console.log('request_algo 签名参数API请求失败:') + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function generateFp() { + let e = "0123456789"; + let a = 13; + let i = ''; + for (; a--;) + i += e[Math.random() * e.length | 0]; + return (i + Date.now()).slice(0, 16) +} + +function getJxmcUrlData(url, name) { + if (typeof URL !== "undefined") { + let urls = new URL(url); + let data = urls.searchParams.get(name); + return data ? data : ''; + } else { + const query = url.match(/\?.*/)[0].substring(1) + const vars = query.split('&') + for (let i = 0; i < vars.length; i++) { + const pair = vars[i].split('=') + if (pair[0] === name) { + return vars[i].substr(vars[i].indexOf('=') + 1); + } + } + return '' + } +} + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} + + +// prettier-ignore +function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + + +//我加的函数 +function postToDingTalk(messgae) { + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"资产变动", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} diff --git a/src/main/resources/test_money_money.js b/src/main/resources/test_money_money.js new file mode 100644 index 0000000..6c03835 --- /dev/null +++ b/src/main/resources/test_money_money.js @@ -0,0 +1,710 @@ +const notify = $.isNode() ? require('./sendNotify') : ''; +//Node.js用户请在jdCookie.js处填写动动ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +let helpAuthor=true; // 帮助作者 +const randomCount = $.isNode() ? 0 : 5; +let jdNotify = true; // 是否关闭通知,false打开通知推送,true关闭通知推送 +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = '', message = ""; +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => { + }; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +const inviteCodes = [ +] +!(async () => { + message += "[通知] 动动赚赚 \n\n --- \n\n" + $.tuanList = [] + await requireConfig(); + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await TotalBean(); + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + that.log(`\n******开始【动动账号${$.index}】${$.nickName || $.UserName}*********\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await shareCodesFormat() + await jdWish() + } + message += "----\n\n" + } + + for (let i = 0; i < cookiesArr.length; i++) { + $.canHelp = true + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + await getUserTuanInfo() + await getHelpTuan(); + for (let j = 0; j < $.tuanList.length; ++j) { + await helpFriendTuan($.tuanList[j]) + if(!$.canHelp) break + } + await setHelpTuan(); + } + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + message = message + getPic() + that.log(message) + postToDingTalk(message) + $.done(); + }) + +async function jdWish() { + $.bean = 0 + $.tuan = null + $.hasOpen = false + await getTaskList(true) + await getUserTuanInfo() + if (!$.tuan) { + await openTuan() + if ($.hasOpen) await getUserTuanInfo() + } + if ($.tuan) $.tuanList.push($.tuan) + await helpFriends() + await getUserInfo() + $.nowBean = parseInt($.totalBeanNum) + $.nowNum = parseInt($.totalNum) + for (let i = 0; i < $.taskList.length; ++i) { + let task = $.taskList[i] + if (task['taskId'] === 1 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + } else if (task['taskId'] !== 3 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + if(task['itemId']) + await doTask({"itemId":task['itemId'],"taskId":task['taskId'],"mpVersion":"3.4.0"}) + else + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + await $.wait(3000) + } + } + await getTaskList(); + await showMsg(); +} + +function showMsg() { + return new Promise(async resolve => { + message += "" + `本次获得${parseInt($.totalBeanNum) - $.nowBean}京豆,${parseInt($.totalNum) - $.nowNum}金币\n` + "\n\n" + message += "" + `累计获得${$.totalBeanNum}京豆,${$.totalNum}金币\n可兑换${$.totalNum / 10000}元无门槛红包` + "\n\n" + if (parseInt($.totalBeanNum) - $.nowBean > 0) { + $.msg($.name, '', `动动账号${$.index} ${$.nickName}\n${message}`); + } else { + $.log(message) + } + // 云端大于10元无门槛红包时进行通知推送 + if ($.isNode() && $.totalNum >= 1000000) await notify.sendNotify(`${$.name} - 动动账号${$.index} - ${$.nickName}`, `动动账号${$.index} ${$.nickName}\n当前金币:${$.totalNum}个\n可兑换无门槛红包:${parseInt($.totalNum) / 10000}元\n`,) + resolve(); + }) +} +// function getAuthorShareCode(url) { +// return new Promise(resolve => { +// $.get({url: `${url}?${new Date()}`, +// headers:{ +// "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1 Edg/87.0.4280.88" +// }}, async (err, resp, data) => { +// try { +// if (err) { +// } else { +// $.tuanList = $.tuanList.concat(JSON.parse(data)) +// that.log(`作者助力码获取成功`) +// } +// } catch (e) { +// $.logErr(e, resp) +// } finally { +// resolve(); +// } +// }) +// }) +// } +function helpFriendTuan(body) { + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_assist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.success) { + that.log('助力成功') + } else { + if (data.resultCode === '9200008') that.log('不能助力自己') + else if (data.resultCode === '9200011') that.log('已经助力过') + else if (data.resultCode === '2400205') that.log('团已满') + else if (data.resultCode === '2400203') {that.log('助力次数已耗尽');$.canHelp = false} + else that.log(`未知错误`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getUserTuanInfo() { + let body = {"paramData": {"channel": "FISSION_BEAN"}} + return new Promise(resolve => { + $.get(taskTuanUrl("distributeBeanActivityInfo", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data && !data.data.canStartNewAssist) { + $.tuan = { + "activityIdEncrypted": data.data.id, + "assistStartRecordId": data.data.assistStartRecordId, + "assistedPinEncrypted": data.data.encPin, + "channel": "FISSION_BEAN" + } + $.tuanActId = data.data.id + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function openTuan() { + let body = {"activityIdEncrypted": $.tuanActId, "channel": "FISSION_BEAN"} + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_startAssist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['success']) { + $.hasOpen = true + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getUserInfo() { + return new Promise(resolve => { + $.get(taskUrl("interactIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // if (data.data.shareTaskRes) { + // that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${data.data.shareTaskRes.itemId}\n`); + // } else { + // that.log(`\n\n已满5人助力或助力功能已下线,故暂时无${$.name}好友助力码\n\n`) + // } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getTaskList(flag = false) { + return new Promise(resolve => { + $.get(taskUrl("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.taskList = data.data.taskDetailResList + $.totalNum = data.data.totalNum + $.totalBeanNum = data.data.totalBeanNum + if (flag && $.taskList.filter(item => !!item && item['taskId']=== 3) && $.taskList.filter(item => !!item && item['taskId']=== 3).length) { + $.shareId=$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +// 完成 +function doTask(body, func = "doInteractTask") { + // that.log(taskUrl("doInteractTask", body)) + return new Promise(resolve => { + $.get(taskUrl(func, body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // that.log(data) + if (func === "doInteractTask") { + if (data.subCode === "S000") { + that.log(`任务完成,获得 ${data.data.taskDetailResList[0].incomeAmountConf} 金币,${data.data.taskDetailResList[0].beanNum} 京豆`) + $.bean += parseInt(data.data.taskDetailResList[0].beanNum) + } else { + that.log(`任务失败,错误信息:${data.message}`) + } + } else { + that.log(`${data.data.helpResDesc}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function helpFriends() { + await getHelp(); + for (let code of $.newShareCodes) { + if (!code) continue + await doTask({"itemId": code, "taskId": "3", "mpVersion": "3.4.0"}, "doHelpTask") + } + await setHelp(); +} +// function readShareCode() { +// that.log(`开始`) +// return new Promise(async resolve => { +// $.get({url: `https://code.chiang.fun/api/v1/jd/jdzz/read/${randomCount}/`, 'timeout': 10000}, (err, resp, data) => { +// try { +// if (err) { +// that.log(`${JSON.stringify(err)}`) +// that.log(`${$.name} API请求失败,请检查网路重试`) +// } else { +// if (data) { +// that.log(`随机取${randomCount}个码放到您固定的互助码后面(不影响已有固定互助)`) +// data = JSON.parse(data); +// } +// } +// } catch (e) { +// $.logErr(e, resp) +// } finally { +// resolve(data); +// } +// }) +// await $.wait(10000); +// resolve() +// }) +// } +function getHelp() { + $.newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzz/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + $.newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.shareId) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzz/" + $.shareId + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function getHelpTuan() { + $.tuanList = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzzTuan/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var item of list) { + let its=item.split('@'); + if(its.length==2){ + let tuan={ + "activityIdEncrypted": $.tuanActId, + "assistStartRecordId": its[0], + "assistedPinEncrypted": its[1], + "channel": "FISSION_BEAN" + } + $.tuanList.push(tuan); + } + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelpTuan() { + return new Promise(resolve => { + if ($.tuan) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzzTuan/" + $.tuan.assistStartRecordId+'@'+$.tuan.assistedPinEncrypted + }, (err, resp, data) => { + try { + if (data) { + that.log(data); + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的开团碼成功"); + }else{ + that.log("提交开团码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } +//格式化助力码 +function shareCodesFormat() { + return new Promise(async resolve => { + // that.log(`第${$.index}个动动账号的助力码:::${$.shareCodesArr[$.index - 1]}`) + $.newShareCodes = []; + // if ($.shareCodesArr[$.index - 1]) { + // $.newShareCodes = $.shareCodesArr[$.index - 1].split('@'); + // } else { + // that.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + // const tempIndex = $.index > inviteCodes.length ? (inviteCodes.length - 1) : ($.index - 1); + // $.newShareCodes = inviteCodes[tempIndex].split('@'); + // } + // const readShareCodeRes = await readShareCode(); + // if (readShareCodeRes && readShareCodeRes.code === 200) { + // $.newShareCodes = [...new Set([...$.newShareCodes, ...(readShareCodeRes.data || [])])]; + // } + // that.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify($.newShareCodes)}`) + resolve(); + }) +} + +function requireConfig() { + return new Promise(resolve => { + that.log(`开始获取${$.name}配置文件\n`); + //Node.js用户请在jdCookie.js处填写动动ck; + let shareCodes = []; + if ($.isNode()) { + if (process.env.JDZZ_SHARECODES) { + if (process.env.JDZZ_SHARECODES.indexOf('\n') > -1) { + shareCodes = process.env.JDZZ_SHARECODES.split('\n'); + } else { + shareCodes = process.env.JDZZ_SHARECODES.split('&'); + } + } + } + that.log(`共${cookiesArr.length}个动动账号\n`); + $.shareCodesArr = []; + if ($.isNode()) { + Object.keys(shareCodes).forEach((item) => { + if (shareCodes[item]) { + $.shareCodesArr.push(shareCodes[item]) + } + }) + } + that.log(`您提供了${$.shareCodesArr.length}个账号的${$.name}助力码\n`); + resolve() + }) +} + +function taskUrl(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +function taskTuanUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&body=${escape(JSON.stringify(body))}&appid=swat_miniprogram&osVersion=5.0.0&clientVersion=3.1.3&fromType=wxapp×tamp=${new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 + 8 * 60 * 60 * 1000}`, + headers: { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "api.m.jd.com", + "Referer": "https://servicewechat.com/wxa5bf5ee667d91626/108/page-frame.html", + "Cookie": cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + } + } +} + +function taskPostUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}`, + body: body, + headers: { + "Cookie": cookie, + 'Content-Type': 'application/x-www-form-urlencoded', + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + } + } +} + +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0") + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } +} + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '不要在BoxJS手动复制粘贴修改cookie') + return []; + } + } +} + + + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动赚赚", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_money_tree.js b/src/main/resources/test_money_tree.js new file mode 100644 index 0000000..b755ebf --- /dev/null +++ b/src/main/resources/test_money_tree.js @@ -0,0 +1,937 @@ +const notify = $.isNode() ? require('./sendNotify') : ''; +//Node.js用户请在jdCookie.js处填写京东ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = '', allMsg = ``; +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} + +let jdNotify = true;//是否开启静默运行,默认true +let sellFruit = true;//是否卖出金果得到金币,默认'false' +const JD_API_HOST = 'https://ms.jr.jd.com/gw/generic/uc/h5/m'; +let userInfo = null, taskInfo = [], message = "", subTitle = '', fruitTotal = 0; +!(async () => { + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + } + message += "[通知] 动动摇钱树 \n\n --- \n\n" + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + + await TotalBean(); + that.log(`\n****开始【京东账号${$.index}】${$.nickName || $.UserName}****\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + subTitle = ''; + await jd_moneyTree(); + } + } + if (allMsg) { + jdNotify = $.isNode() ? (process.env.MONEYTREE_NOTIFY_CONTROL ? process.env.MONEYTREE_NOTIFY_CONTROL : jdNotify) : ($.getdata('jdMoneyTreeNotify') ? $.getdata('jdMoneyTreeNotify') : jdNotify); + if (!jdNotify || jdNotify === 'false') { + if ($.isNode()) await notify.sendNotify($.name, allMsg); + $.msg($.name, '', allMsg) + } + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + message += getPic() + taht.log(message) + postToDingTalk(message) + $.done(); + }) + +async function jd_moneyTree() { + try { + const userRes = await user_info(); + if (!userRes || !userRes.realName) return + await signEveryDay(); + await dayWork(); + await harvest(); + await sell(); + await myWealth(); + await stealFriendFruit() + + $.log(`\n${message}\n`); + } catch (e) { + $.logErr(e) + } +} + +function user_info() { + that.log('初始化摇钱树个人信息'); + const params = { + "sharePin": "", + "shareType": 1, + "channelLV": "", + "source": 2, + "riskDeviceParam": { + "eid": "", + "fp": "", + "sdkToken": "", + "token": "", + "jstub": "", + "appType": "2", + } + } + params.riskDeviceParam = JSON.stringify(params.riskDeviceParam); + await $.wait(5000); //歇口气儿, 不然会报操作频繁 + return new Promise((resolve, reject) => { + $.post(taskurl('login', params), async (err, resp, data) => { + try { + if (err) { + that.log("\n摇钱树京东API请求失败 ‼️‼️") + that.log(JSON.stringify(err)); + } else { + if (data) { + const res = JSON.parse(data); + if (res && res.resultCode === 0) { + $.isLogin = true; + that.log('resultCode为0') + if (res.resultData.data) { + userInfo = res.resultData.data; + // userInfo.realName = null; + if (userInfo.realName) { + // that.log(`助力码sharePin为::${userInfo.sharePin}`); + $.treeMsgTime = userInfo.sharePin; + subTitle = `【${userInfo.nick}】${userInfo.treeInfo.treeName}`; + message += "" + `【我的金果数量】${userInfo.treeInfo.fruit}\n` + "\n\n"; + message += "" + `【我的金币数量】${userInfo.treeInfo.coin}\n` + "\n\n"; + message += "" + `【距离${userInfo.treeInfo.level + 1}级摇钱树还差】${userInfo.treeInfo.progressLeft}\n` + "\n\n"; + } else { + $.log(`京东账号${$.index}${$.UserName}运行失败\n此账号未实名认证或者未参与过此活动\n①如未参与活动,请先去京东app参加摇钱树活动\n入口:我的->游戏与互动->查看更多\n②如未实名认证,请进行实名认证`) + // $.msg($.name, `【提示】京东账号${$.index}${$.UserName}运行失败`, '此账号未实名认证或者未参与过此活动\n①如未参与活动,请先去京东app参加摇钱树活动\n入口:我的->游戏与互动->查看更多\n②如未实名认证,请进行实名认证', {"open-url": "openApp.jdMobile://"}); + message += "" + `运行失败\n此账号未实名认证或者未参与过此活动\n①如未参与活动,请先去京东app参加摇钱树活动\n入口:我的->游戏与互动->查看更多\n②如未实名认证,请进行实名认证` + "\n\n" + } + } + } else { + that.log(`其他情况::${JSON.stringify(res)}`); + } + } else { + that.log(`京豆api返回数据为空,请检查自身原因`) + } + } + } catch (eor) { + $.logErr(eor, err) + } finally { + resolve(userInfo) + } + }) + }) +} + +async function dayWork() { + that.log(`开始做任务userInfo了\n`) + return new Promise(async resolve => { + const data = { + "source": 0, + "linkMissionIds": ["666", "667"], + "LinkMissionIdValues": [7, 7], + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + }; + let response = await request('dayWork', data); + // that.log(`获取任务的信息:${JSON.stringify(response)}\n`) + let canTask = []; + taskInfo = []; + if (response && response.resultCode === 0) { + if (response.resultData.code === '200') { + response.resultData.data.map((item) => { + if (item.prizeType === 2) { + canTask.push(item); + } + if (item.workType === 7 && item.prizeType === 0) { + // missionId.push(item.mid); + taskInfo.push(item); + } + // if (item.workType === 7 && item.prizeType === 0) { + // missionId2 = item.mid; + // } + }) + } + } + that.log(`canTask::${JSON.stringify(canTask)}\n`) + that.log(`浏览任务列表taskInfo::${JSON.stringify(taskInfo)}\n`) + for (let item of canTask) { + if (item.workType === 1) { + // 签到任务 + // let signRes = await sign(); + // that.log(`签到结果:${JSON.stringify(signRes)}`); + if (item.workStatus === 0) { + // const data = {"source":2,"workType":1,"opType":2}; + // let signRes = await request('doWork', data); + let signRes = await sign(); + that.log(`三餐签到结果:${JSON.stringify(signRes)}`); + } else if (item.workStatus === 2) { + that.log(`三餐签到任务已经做过`) + } else if (item.workStatus === -1) { + that.log(`三餐签到任务不在时间范围内`) + } + } else if (item.workType === 2) { + // 分享任务 + if (item.workStatus === 0) { + // share(); + const data = {"source": 0, "workType": 2, "opType": 1}; + //开始分享 + // let shareRes = await request('doWork', data); + let shareRes = await share(data); + that.log(`开始分享的动作:${JSON.stringify(shareRes)}`); + const b = {"source": 0, "workType": 2, "opType": 2}; + // let shareResJL = await request('doWork', b); + let shareResJL = await share(b); + that.log(`领取分享后的奖励:${JSON.stringify(shareResJL)}`) + } else if (item.workStatus === 2) { + that.log(`分享任务已经做过`) + } + } + } + for (let task of taskInfo) { + if (task.mid && task.workStatus === 0) { + that.log('开始做浏览任务'); + // yield setUserLinkStatus(task.mid); + let aa = await setUserLinkStatus(task.mid); + that.log(`aaa${JSON.stringify(aa)}`); + } else if (task.mid && task.workStatus === 1) { + that.log(`workStatus === 1开始领取浏览后的奖励:mid:${task.mid}`); + let receiveAwardRes = await receiveAward(task.mid); + that.log(`领取浏览任务奖励成功:${JSON.stringify(receiveAwardRes)}`) + } else if (task.mid && task.workStatus === 2) { + that.log('所有的浏览任务都做完了') + } + } + resolve(); + }); +} + +function harvest() { + if (!userInfo) return + const data = { + "source": 2, + "sharePin": "", + "userId": userInfo.userInfo, + "userToken": userInfo.userToken, + "shareType": 1, + "channel": "", + "riskDeviceParam": { + "eid": "", + "appType": 2, + "fp": "", + "jstub": "", + "sdkToken": "", + "token": "" + } + } + data.riskDeviceParam = JSON.stringify(data.riskDeviceParam); + return new Promise((rs, rj) => { + request('harvest', data).then((harvestRes) => { + if (harvestRes && harvestRes.resultCode === 0 && harvestRes.resultData.code === '200') { + that.log(`\n收获金果成功:${JSON.stringify(harvestRes)}\n`) + let data = harvestRes.resultData.data; + message +="" + `【距离${data.treeInfo.level + 1}级摇钱树还差】${data.treeInfo.progressLeft}\n` + "\n\n"; + fruitTotal = data.treeInfo.fruit; + } else { + that.log(`\n收获金果异常:${JSON.stringify(harvestRes)}`) + } + rs() + // gen.next(); + }) + }) + // request('harvest', data).then((harvestRes) => { + // if (harvestRes.resultCode === 0 && harvestRes.resultData.code === '200') { + // let data = harvestRes.resultData.data; + // message += `【距离${data.treeInfo.level + 1}级摇钱树还差】${data.treeInfo.progressLeft}\n`; + // fruitTotal = data.treeInfo.fruit; + // gen.next(); + // } + // }) +} + +//卖出金果,得到金币 +function sell() { + return new Promise((rs, rj) => { + const params = { + "source": 2, + "jtCount": 7.000000000000001, + "riskDeviceParam": { + "eid": "", + "fp": "", + "sdkToken": "", + "token": "", + "jstub": "", + "appType": 2, + } + } + params.riskDeviceParam = JSON.stringify(params.riskDeviceParam);//这一步,不可省略,否则提交会报错(和login接口一样) + that.log(`目前金果数量${fruitTotal}`) + sellFruit = $.isNode() ? (process.env.MONEY_TREE_SELL_FRUIT ? process.env.MONEY_TREE_SELL_FRUIT : `${sellFruit}`) : ($.getdata('MONEY_TREE_SELL_FRUIT') ? $.getdata('MONEY_TREE_SELL_FRUIT') : `${sellFruit}`); + if (sellFruit && sellFruit === 'false') { + that.log(`\n设置的不卖出金果\n`) + rs() + return + } + if (fruitTotal >= 8000 * 7) { + if (userInfo['jtRest'] === 0) { + that.log(`\n今日已卖出5.6万金果(已达上限),获得0.07金贴\n`) + rs() + return + } + request('sell', params).then((sellRes) => { + if (sellRes && sellRes['resultCode'] === 0) { + if (sellRes['resultData']['code'] === '200') { + if (sellRes['resultData']['data']['sell'] === 0) { + that.log(`卖出金果成功,获得0.07金贴\n`); + allMsg += `账号${$.index}:${$.nickName || $.UserName}\n今日成功卖出5.6万金果,获得0.07金贴${$.index !== cookiesArr.length ? '\n\n' : ''}` + } else { + that.log(`卖出金果失败:${JSON.stringify(sellRes)}\n`) + } + } + } + rs() + }) + } else { + that.log(`当前金果数量不够兑换 0.07金贴\n`); + rs() + } + // request('sell', params).then(response => { + // rs(response); + // }) + }) + // request('sell', params).then((sellRes) => { + // that.log(`卖出金果结果:${JSON.stringify(sellRes)}\n`) + // gen.next(); + // }) +} + +//获取金币和金果数量 +function myWealth() { + return new Promise((resolve) => { + const params = { + "source": 2, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + params.riskDeviceParam = JSON.stringify(params.riskDeviceParam);//这一步,不可省略,否则提交会报错(和login接口一样) + request('myWealth', params).then(res => { + if (res && res.resultCode === 0 && res.resultData.code === '200') { + that.log(`金贴和金果数量::${JSON.stringify(res)}`); + message += "" + `【我的金果数量】${res.resultData.data.gaAmount}\n` + "\n\n"; + message += "" + `【我的金贴数量】${res.resultData.data.gcAmount / 100}\n` + "\n\n"; + } + resolve(); + }) + }); +} + +function sign() { + that.log('开始三餐签到') + const data = {"source": 2, "workType": 1, "opType": 2}; + return new Promise((rs, rj) => { + request('doWork', data).then(response => { + rs(response); + }) + }) +} + +function signIndex() { + const params = { + "source": 0, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + return new Promise((rs, rj) => { + request('signIndex', params).then(response => { + rs(response); + }) + }) +} + +async function signEveryDay() { + return new Promise(async (resolve) => { + try { + let signIndexRes = await signIndex(); + if (signIndexRes.resultCode === 0) { + that.log(`每日签到条件查询:${signIndexRes.resultData.data.canSign === 2 ? '可以签到' : '已经签到过了'}`); + if (signIndexRes.resultData && signIndexRes.resultData.data.canSign == 2) { + that.log('准备每日签到') + let signOneRes = await signOne(signIndexRes.resultData.data.signDay); + that.log(`第${signIndexRes.resultData.data.signDay}日签到结果:${JSON.stringify(signOneRes)}`); + if (signIndexRes.resultData.data.signDay === 7) { + let getSignAwardRes = await getSignAward(); + that.log(`店铺券(49-10)领取结果:${JSON.stringify(getSignAwardRes)}`) + if (getSignAwardRes.resultCode === 0 && getSignAwardRes.data.code === 0) { + message += "" + `【7日签到奖励领取】${getSignAwardRes.datamessage}\n` + "\n\n" + } + } + } + } + } catch (e) { + $.logErr(e); + } finally { + resolve() + } + }) +} + +function signOne(signDay) { + const params = { + "source": 0, + "signDay": signDay, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + return new Promise((rs, rj) => { + request('signOne', params).then(response => { + rs(response); + }) + }) +} + +// 领取七日签到后的奖励(店铺优惠券) +function getSignAward() { + const params = { + "source": 2, + "awardType": 2, + "deviceRiskParam": 1, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + return new Promise((rs, rj) => { + request('getSignAward', params).then(response => { + rs(response); + }) + }) +} + +// 浏览任务 +async function setUserLinkStatus(missionId) { + let index = 0; + do { + const params = { + "missionId": missionId, + "pushStatus": 1, + "keyValue": index, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + let response = await request('setUserLinkStatus', params) + that.log(`missionId为${missionId}::第${index + 1}次浏览活动完成: ${JSON.stringify(response)}`); + // if (resultCode === 0) { + // let sportRevardResult = await getSportReward(); + // that.log(`领取遛狗奖励完成: ${JSON.stringify(sportRevardResult)}`); + // } + index++; + } while (index < 7) //不知道结束的条件,目前写死循环7次吧 + that.log('浏览店铺任务结束'); + that.log('开始领取浏览后的奖励'); + let receiveAwardRes = await receiveAward(missionId); + that.log(`领取浏览任务奖励成功:${JSON.stringify(receiveAwardRes)}`) + return new Promise((resolve, reject) => { + resolve(receiveAwardRes); + }) + // gen.next(); +} + +// 领取浏览后的奖励 +function receiveAward(mid) { + if (!mid) return + mid = mid + ""; + const params = { + "source": 0, + "workType": 7, + "opType": 2, + "mid": mid, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + return new Promise((rs, rj) => { + request('doWork', params).then(response => { + rs(response); + }) + }) +} + +function share(data) { + if (data.opType === 1) { + that.log(`开始做分享任务\n`) + } else { + that.log(`开始做领取分享后的奖励\n`) + } + return new Promise((rs, rj) => { + request('doWork', data).then(response => { + rs(response); + }) + }) +} + +async function stealFriendFruit() { + await friendRank(); + if ($.friendRankList && $.friendRankList.length > 0) { + const canSteal = $.friendRankList.some((item) => { + const boxShareCode = item.steal + return (boxShareCode === true); + }); + if (canSteal) { + $.amount = 0; + for (let item of $.friendRankList) { + if (!item.self && item.steal) { + await friendTreeRoom(item.encryPin); + const stealFruitRes = await stealFruit(item.encryPin, $.friendTree.stoleInfo); + if (stealFruitRes && stealFruitRes.resultCode === 0 && stealFruitRes.resultData.code === '200') { + $.amount += stealFruitRes.resultData.data.amount; + } + } + } + message +="" + `【偷取好友金果】共${$.amount}个\n` + "\n\n"; + } else { + that.log(`今日已偷过好友的金果了,暂无好友可偷,请明天再来\n`) + } + } else { + that.log(`您暂无好友,故跳过`); + } +} + +//获取好友列表API +async function friendRank() { + await $.wait(1000); //歇口气儿, 不然会报操作频繁 + const params = { + "source": 2, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + params.riskDeviceParam = JSON.stringify(params.riskDeviceParam);//这一步,不可省略,否则提交会报错(和login接口一样) + return new Promise((resolve, reject) => { + $.post(taskurl('friendRank', params), (err, resp, data) => { + try { + if (err) { + that.log("\n摇钱树京东API请求失败 ‼️‼️"); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (data) { + data = JSON.parse(data); + $.friendRankList = data.resultData.data; + } else { + that.log(`京豆api返回数据为空,请检查自身原因`) + } + } + } catch (eor) { + $.logErr(eor, err) + } finally { + resolve() + } + }) + }) +} + +// 进入好友房间API +async function friendTreeRoom(friendPin) { + await $.wait(1000); //歇口气儿, 不然会报操作频繁 + const params = { + "source": 2, + "friendPin": friendPin, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + params.riskDeviceParam = JSON.stringify(params.riskDeviceParam);//这一步,不可省略,否则提交会报错(和login接口一样) + return new Promise((resolve, reject) => { + $.post(taskurl('friendTree', params), (err, resp, data) => { + try { + if (err) { + that.log("\n摇钱树京东API请求失败 ‼️‼️"); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (data) { + data = JSON.parse(data); + $.friendTree = data.resultData.data; + } else { + that.log(`京豆api返回数据为空,请检查自身原因`) + } + } + } catch (eor) { + $.logErr(eor, err) + } finally { + resolve() + } + }) + }) +} + +//偷好友金果API +async function stealFruit(friendPin, stoleId) { + await $.wait(1000); //歇口气儿, 不然会报操作频繁 + const params = { + "source": 2, + "friendPin": friendPin, + "stoleId": stoleId, + "riskDeviceParam": { + "eid": "", + "dt": "", + "ma": "", + "im": "", + "os": "", + "osv": "", + "ip": "", + "apid": "", + "ia": "", + "uu": "", + "cv": "", + "nt": "", + "at": "1", + "fp": "", + "token": "" + } + } + params.riskDeviceParam = JSON.stringify(params.riskDeviceParam);//这一步,不可省略,否则提交会报错(和login接口一样) + return new Promise((resolve, reject) => { + $.post(taskurl('stealFruit', params), (err, resp, data) => { + try { + if (err) { + that.log("\n摇钱树京东API请求失败 ‼️‼️"); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (data) { + data = JSON.parse(data); + } else { + that.log(`京豆api返回数据为空,请检查自身原因`) + } + } + } catch (eor) { + $.logErr(eor, err) + } finally { + resolve(data) + } + }) + }) +} + + +async function request(function_id, body = {}) { + await $.wait(1000); //歇口气儿, 不然会报操作频繁 + return new Promise((resolve, reject) => { + $.post(taskurl(function_id, body), (err, resp, data) => { + try { + if (err) { + that.log("\n摇钱树京东API请求失败 ‼️‼️"); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (data) { + data = JSON.parse(data); + } else { + that.log(`京豆api返回数据为空,请检查自身原因`) + } + } + } catch (eor) { + $.msg("摇钱树-初始化个人信息" + eor.name + "‼️", JSON.stringify(eor), eor.message) + } finally { + resolve(data) + } + }) + }) +} + +function taskurl(function_id, body) { + return { + url: JD_API_HOST + '/' + function_id + '?_=' + new Date().getTime() * 1000, + body: `reqData=${function_id === 'harvest' || function_id === 'login' || function_id === 'signIndex' || function_id === 'signOne' || function_id === 'setUserLinkStatus' || function_id === 'dayWork' || function_id === 'getSignAward' || function_id === 'sell' || function_id === 'friendRank' || function_id === 'friendTree' || function_id === 'stealFruit' ? encodeURIComponent(JSON.stringify(body)) : JSON.stringify(body)}`, + headers: { + 'Accept': `application/json`, + 'Origin': `https://uua.jr.jd.com`, + 'Accept-Encoding': `gzip, deflate, br`, + 'Cookie': cookie, + 'Content-Type': `application/x-www-form-urlencoded;charset=UTF-8`, + 'Host': `ms.jr.jd.com`, + 'Connection': `keep-alive`, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Referer': `https://uua.jr.jd.com/uc-fe-wxgrowing/moneytree/index`, + 'Accept-Language': `zh-cn` + } + } +} + +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} + + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动摇钱树", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} diff --git a/src/main/resources/test_our.js b/src/main/resources/test_our.js new file mode 100644 index 0000000..1f09910 --- /dev/null +++ b/src/main/resources/test_our.js @@ -0,0 +1,2162 @@ +/* +京东资产变动通知脚本:https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js +Modified time: 2021-05-17 15:25:41 +统计昨日京豆的变化情况,包括收入,支出,以及显示当前京豆数量,目前小问题:下单使用京豆后,退款重新购买,计算统计会出现异常 +统计红包以及过期红包 +网页查看地址 : https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean +支持京东双账号 +脚本兼容: QuantumultX, Surge, Loon, JSBox, Node.js +============QuantumultX============== +[task_local] +#京东资产变动通知 +2 9 * * * https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, tag=京东资产变动通知, img-url=https://raw.githubusercontent.com/Orz-3/mini/master/Color/jd.png, enabled=true +================Loon=============== +[Script] +cron "2 9 * * *" script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, tag=京东资产变动通知 +=============Surge=========== +[Script] +京东资产变动通知 = type=cron,cronexp="2 9 * * *",wake-system=1,timeout=3600,script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js +============小火箭========= +京东资产变动通知 = type=cron,script-path=https://jdsharedresourcescdn.azureedge.net/jdresource/jd_bean_change.js, cronexpr="2 9 * * *", timeout=3600, enable=true + */ +let roleMap = { + "jd_66ea783827d30":"军军酱", + "jd_4311ac0ff4456":"居居酱" +} +let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" +const $ = new Env('京东资产变动通知'); +let jdFruitShareArr = [], isBox = false, notify, newShareCodes; +//助力好友分享码(最多4个,否则后面的助力失败),原因:动动农场每人每天只有四次助力机会 +//此此内容是IOS用户下载脚本到本地使用,填写互助码的地方,同一动动账号的好友互助码请使用@符号隔开。 +//下面给出两个账号的填写示例(iOS只支持2个动动账号) +let shareCodes = + [ // 这个列表填入你要助力的好友的shareCode +] +let subTitle = '', option = {}, isFruitFinished = false; +const retainWater = 100;//保留水滴大于多少g,默认100g; +let jdNotify = false;//是否关闭通知,false打开通知推送,true关闭通知推送 +let jdFruitBeanCard = false;//农场使用水滴换豆卡(如果出现限时活动时100g水换20豆,此时比浇水划算,推荐换豆),true表示换豆(不浇水),false表示不换豆(继续浇水),脚本默认是浇水 +let randomCount = $.isNode() ? 0 : 0; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +const urlSchema = `openjd://virtual?params=%7B%20%22category%22:%20%22jump%22,%20%22des%22:%20%22m%22,%20%22url%22:%20%22https://h5.m.jd.com/babelDiy/Zeus/3KSjXqQabiTuD1cJ28QskrpWoBKT/index.html%22%20%7D`; + +let allMessage = ''; +let message = ""; +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +!(async () => { + await requireConfig(); + message += "[通知] 资产变动 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.beanCount = 0; + $.incomeBean = 0; + $.expenseBean = 0; + $.todayIncomeBean = 0; + $.errorMsg = ''; + $.isLogin = true; + $.nickName = ''; + $.balance = 0; + $.expiredBalance = 0; + + username = $.UserName + if (roleMap[username] == undefined){ + continue + } + username = roleMap[username] + + await TotalBean(); + //加上名称 + message = message + "【羊毛姐妹】" + username + `( ${$.nickName} )`+ " \n\n " + + console.log(`\n********开始【京东账号${$.index}】${$.nickName || $.UserName}******\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await bean(); + await showMsg(); + await shareCodesFormat(); + await jdFruit(); + await jdWish() + } + message += "----\n\n" + } + + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + message = message + postToDingTalk(message) + $.done(); + }) + + + function requireConfig() { + return new Promise(resolve => { + that.log('开始获取配置文件\n') + notify = $.isNode() ? require('./sendNotify') : ''; + //Node.js用户请在jdCookie.js处填写动动ck; + const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + const jdFruitShareCodes = $.isNode() ? require('./jdFruitShareCodes.js') : ''; + //IOS等用户直接用NobyDa的jd cookie + if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; + } else { + let cookiesData = $.getdata('CookiesJD') || "[]"; + cookiesData = jsonParse(cookiesData); + cookiesArr = cookiesData.map(item => item.cookie); + cookiesArr.reverse(); + cookiesArr.push(...[$.getdata('CookieJD2'), $.getdata('CookieJD')]); + cookiesArr.reverse(); + cookiesArr = cookiesArr.filter(item => item !== "" && item !== null && item !== undefined); + } + that.log(`共${cookiesArr.length}个动动账号\n`) + resolve() + }) + } + +async function showMsg() { + // if ($.errorMsg) return + allMessage += `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆 🐶${$.message}${$.index !== cookiesArr.length ? '\n\n' : ''}`; + message += "" + `【总京豆】:${$.beanCount}( 今日将过期${$.expirejingdou} )京豆 🐶` +"\n\n" + message += "" + `【今日收入】:${$.todayIncomeBean}京豆 🐶` +"\n\n" + message += "" + `【昨日收入】:${$.incomeBean}京豆 🐶` +"\n\n" + message += "" + `【昨日支出】:${$.expenseBean}京豆 🐶` +"\n\n" + + + + message += "" + `【当前总红包】:${$.balance}( 今日总过期${$.expiredBalance} )元 🧧` +"\n\n" + message += "" + `【京喜红包】:${$.jxRed}( 今日将过期${$.jxRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【极速红包】:${$.jsRed}( 今日将过期${$.jsRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【京东红包】:${$.jdRed}( 今日将过期${$.jdRedExpire.toFixed(2)} )元 🧧` +"\n\n" + message += "" + `【健康红包】:${$.jdhRed}( 今日将过期${$.jdhRedExpire.toFixed(2)} )元 🧧` +"\n\n" + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `账号${$.index}:${$.nickName || $.UserName}\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}京豆 🐶${$.message}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + // } + $.msg($.name, '', `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶${$.message}`, {"open-url": "https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean"}); +} + +async function bean() { + // console.log(`北京时间零点时间戳:${parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000}`); + // console.log(`北京时间2020-10-28 06:16:05::${new Date("2020/10/28 06:16:05+08:00").getTime()}`) + // 不管哪个时区。得到都是当前时刻北京时间的时间戳 new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000 + + //前一天的0:0:0时间戳 + const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - (24 * 60 * 60 * 1000); + // 今天0:0:0时间戳 + const tm1 = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + let page = 1, t = 0, yesterdayArr = [], todayArr = []; + do { + let response = await getJingBeanBalanceDetail(page); + // console.log(`第${page}页: ${JSON.stringify(response)}`); + if (response && response.code === "0") { + page++; + let detailList = response.detailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const date = item.date.replace(/-/g, '/') + "+08:00"; + if (new Date(date).getTime() >= tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + todayArr.push(item); + } else if (tm <= new Date(date).getTime() && new Date(date).getTime() < tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + //昨日的 + yesterdayArr.push(item); + } else if (tm > new Date(date).getTime()) { + //前天的 + t = 1; + break; + } + } + } else { + $.errorMsg = `数据异常`; + $.msg($.name, ``, `账号${$.index}:${$.nickName}\n${$.errorMsg}`); + t = 1; + } + } else if (response && response.code === "3") { + console.log(`cookie已过期,或者填写不规范,跳出`) + t = 1; + } else { + console.log(`未知情况:${JSON.stringify(response)}`); + console.log(`未知情况,跳出`) + t = 1; + } + } while (t === 0); + for (let item of yesterdayArr) { + if (Number(item.amount) > 0) { + $.incomeBean += Number(item.amount); + } else if (Number(item.amount) < 0) { + $.expenseBean += Number(item.amount); + } + } + for (let item of todayArr) { + if (Number(item.amount) > 0) { + $.todayIncomeBean += Number(item.amount); + } + } + await queryexpirejingdou();//过期京豆 + await redPacket();//过期红包 + // console.log(`昨日收入:${$.incomeBean}个京豆 🐶`); + // console.log(`昨日支出:${$.expenseBean}个京豆 🐶`) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + if (data['retcode'] === '0' && data.data && data.data['assetInfo']) { + $.beanCount = data.data && data.data['assetInfo']['beanNum']; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} +function getJingBeanBalanceDetail(page) { + return new Promise(async resolve => { + const options = { + "url": `https://api.m.jd.com/client.action?functionId=getJingBeanBalanceDetail`, + "body": `body=${escape(JSON.stringify({"pageSize": "20", "page": page.toString()}))}&appid=ld`, + "headers": { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + // console.log(data) + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function queryexpirejingdou() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=${Date.now()}&g_login_type=1&sceneval=2`, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Host": "wq.jd.com", + "Referer": "https://wqs.jd.com/promote/201801/bean/mybean.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1" + } + } + $.expirejingdou = 0; + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // console.log(data) + data = JSON.parse(data.slice(23, -13)); + // console.log(data) + if (data.ret === 0) { + data['expirejingdou'].map(item => { + console.log(`${timeFormat(item['time'] * 1000)}日过期京豆:${item['expireamount']}\n`); + }) + $.expirejingdou = data['expirejingdou'][0]['expireamount']; + // if ($.expirejingdou > 0) { + // $.message += `\n今日将过期:${$.expirejingdou}京豆 🐶`; + // } + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function redPacket() { + return new Promise(async resolve => { + const options = { + "url": `https://m.jingxi.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=1&_=${+new Date()}&sceneval=2&g_login_type=1&g_ty=ls`, + "headers": { + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://st.jingxi.com/my/redpacket.shtml?newPg=App&jxsid=16156262265849285961', + 'Accept-Encoding': 'gzip, deflate, br', + "Cookie": cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data).data + $.jxRed = 0, $.jsRed = 0, $.jdRed = 0, $.jdhRed = 0, $.jxRedExpire = 0, $.jsRedExpire = 0, $.jdRedExpire = 0, $.jdhRedExpire = 0; + let t = new Date() + t.setDate(t.getDate() + 1) + t.setHours(0, 0, 0, 0) + t = parseInt((t - 1) / 1000) + for (let vo of data.useRedInfo.redList || []) { + if (vo.orgLimitStr && vo.orgLimitStr.includes("京喜")) { + $.jxRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jxRedExpire += parseFloat(vo.balance) + } + } else if (vo.activityName.includes("极速版")) { + $.jsRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jsRedExpire += parseFloat(vo.balance) + } + } else if (vo.orgLimitStr && vo.orgLimitStr.includes("京东健康")) { + $.jdhRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdhRedExpire += parseFloat(vo.balance) + } + } else { + $.jdRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdRedExpire += parseFloat(vo.balance) + } + } + } + $.jxRed = $.jxRed.toFixed(2) + $.jsRed = $.jsRed.toFixed(2) + $.jdRed = $.jdRed.toFixed(2) + $.jdhRed = $.jdhRed.toFixed(2) + $.balance = data.balance + $.expiredBalance = ($.jxRedExpire + $.jsRedExpire + $.jdRedExpire).toFixed(2) + $.message += `\n当前总红包:${$.balance}(今日总过期${$.expiredBalance})元 🧧\n京喜红包:${$.jxRed}(今日将过期${$.jxRedExpire.toFixed(2)})元 🧧\n极速红包:${$.jsRed}(今日将过期${$.jsRedExpire.toFixed(2)})元 🧧\n京东红包:${$.jdRed}(今日将过期${$.jdRedExpire.toFixed(2)})元 🧧\n健康红包:${$.jdhRed}(今日将过期${$.jdhRedExpire.toFixed(2)})元 🧧`; + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} +// prettier-ignore +function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + +//农场代码 + +async function jdFruit() { + subTitle = `【动动账号${$.index}】${$.nickName}`; + try { + await initForFarm(); + if ($.farmInfo.farmUserPro) { + // option['media-url'] = $.farmInfo.farmUserPro.goodsImage; + message = message + "【水果名称】 " + `${$.farmInfo.farmUserPro.name}` + "\n\n"; + // message += "【已兑换水果】" + `${$.farmInfo.farmUserPro.winTimes}` + "次\n\n"; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.farmInfo.farmUserPro.shareCode}\n`); + that.log(`\n【已成功兑换水果】${$.farmInfo.farmUserPro.winTimes}次\n`); + await getHelp(); + await masterHelpShare();//助力好友 + await setHelp(); + if ($.farmInfo.treeState === 2 || $.farmInfo.treeState === 3) { + option['open-url'] = urlSchema; + message = message + " " + $.UserName + "\n【提醒⏰】" + fruitName + "已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达" + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看`); + } + return + } else if ($.farmInfo.treeState === 1) { + that.log(`\n${$.farmInfo.farmUserPro.name}种植中...\n`) + } else if ($.farmInfo.treeState === 0) { + //已下单购买, 但未开始种植新的水果 + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】 ${$.nickName || $.UserName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达`, option); + message = message + " " + $.UserName + " \n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果\n点击弹窗即达" + "" + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 您忘了种植新的水果`, `动动账号${$.index} ${$.nickName}\n【提醒⏰】您忘了种植新的水果\n请去动动APP或微信小程序选购并种植新的水果`); + } + return + } + await doDailyTask(); + await doTenWater();//浇水十次 + await getFirstWaterAward();//领取首次浇水奖励 + await getTenWaterAward();//领取10浇水奖励 + await getWaterFriendGotAward();//领取为2好友浇水奖励 + await duck(); + await doTenWaterAgain();//再次浇水 + await predictionFruit();//预测水果成熟时间 + } else { + that.log(`初始化农场数据异常, 请登录动动 app查看农场0元水果功能是否正常,农场初始化数据: ${JSON.stringify($.farmInfo)}`); + } + } catch (e) { + that.log(`任务执行异常,请检查执行日志 ‼️‼️`); + $.logErr(e); + } + } + async function doDailyTask() { + await taskInitForFarm(); + that.log(`开始签到`); + if (!$.farmTask.signInit.todaySigned) { + await signForFarm(); //签到 + if ($.signResult.code === "0") { + that.log(`【签到成功】获得${$.signResult.amount}g💧\\n`) + //message += `【签到成功】获得${$.signResult.amount}g💧\n`//连续签到${signResult.signDay}天 + } else { + // message += `签到失败,详询日志\n`; + that.log(`签到结果: ${JSON.stringify($.signResult)}`); + } + } else { + that.log(`今天已签到,连续签到${$.farmTask.signInit.totalSigned},下次签到可得${$.farmTask.signInit.signEnergyEachAmount}g\n`); + } + // 被水滴砸中 + that.log(`被水滴砸中: ${$.farmInfo.todayGotWaterGoalTask.canPop ? '是' : '否'}`); + if ($.farmInfo.todayGotWaterGoalTask.canPop) { + await gotWaterGoalTaskForFarm(); + if ($.goalResult.code === '0') { + that.log(`【被水滴砸中】获得${$.goalResult.addEnergy}g💧\\n`); + // message += `【被水滴砸中】获得${$.goalResult.addEnergy}g💧\n` + } + } + that.log(`签到结束,开始广告浏览任务`); + if (!$.farmTask.gotBrowseTaskAdInit.f) { + let adverts = $.farmTask.gotBrowseTaskAdInit.userBrowseTaskAds + let browseReward = 0 + let browseSuccess = 0 + let browseFail = 0 + for (let advert of adverts) { //开始浏览广告 + if (advert.limit <= advert.hadFinishedTimes) { + // browseReward+=advert.reward + that.log(`${advert.mainTitle}+ ' 已完成`);//,获得${advert.reward}g + continue; + } + that.log('正在进行广告浏览任务: ' + advert.mainTitle); + await browseAdTaskForFarm(advert.advertId, 0); + if ($.browseResult.code === '0') { + that.log(`${advert.mainTitle}浏览任务完成`); + //领取奖励 + await browseAdTaskForFarm(advert.advertId, 1); + if ($.browseRwardResult.code === '0') { + that.log(`领取浏览${advert.mainTitle}广告奖励成功,获得${$.browseRwardResult.amount}g`) + browseReward += $.browseRwardResult.amount + browseSuccess++ + } else { + browseFail++ + that.log(`领取浏览广告奖励结果: ${JSON.stringify($.browseRwardResult)}`) + } + } else { + browseFail++ + that.log(`广告浏览任务结果: ${JSON.stringify($.browseResult)}`); + } + } + if (browseFail > 0) { + that.log(`【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\\n`); + // message += `【广告浏览】完成${browseSuccess}个,失败${browseFail},获得${browseReward}g💧\n`; + } else { + that.log(`【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`); + // message += `【广告浏览】完成${browseSuccess}个,获得${browseReward}g💧\n`; + } + } else { + that.log(`今天已经做过浏览广告任务\n`); + } + //定时领水 + if (!$.farmTask.gotThreeMealInit.f) { + // + await gotThreeMealForFarm(); + if ($.threeMeal.code === "0") { + that.log(`【定时领水】获得${$.threeMeal.amount}g💧\n`); + // message += `【定时领水】获得${$.threeMeal.amount}g💧\n`; + } else { + // message += `【定时领水】失败,详询日志\n`; + that.log(`定时领水成功结果: ${JSON.stringify($.threeMeal)}`); + } + } else { + that.log('当前不在定时领水时间断或者已经领过\n') + } + //给好友浇水 + if (!$.farmTask.waterFriendTaskInit.f) { + if ($.farmTask.waterFriendTaskInit.waterFriendCountKey < $.farmTask.waterFriendTaskInit.waterFriendMax) { + await doFriendsWater(); + } + } else { + that.log(`给${$.farmTask.waterFriendTaskInit.waterFriendMax}个好友浇水任务已完成\n`) + } + // await Promise.all([ + // clockInIn(),//打卡领水 + // executeWaterRains(),//水滴雨 + // masterHelpShare(),//助力好友 + // getExtraAward(),//领取额外水滴奖励 + // turntableFarm()//天天抽奖得好礼 + // ]) + // await getAwardInviteFriend(); + await clockInIn();//打卡领水 + await executeWaterRains();//水滴雨 + await getExtraAward();//领取额外水滴奖励 + await turntableFarm()//天天抽奖得好礼 + } + async function predictionFruit() { + that.log('开始预测水果成熟时间\n'); + await initForFarm(); + await taskInitForFarm(); + let waterEveryDayT = $.farmTask.totalWaterTaskInit.totalWaterTaskTimes;//今天到到目前为止,浇了多少次水 + // message += "【今日共浇水】" + `${waterEveryDayT}` + "次 \n\n" + message += "【剩余 水滴】" + `${$.farmInfo.farmUserPro.totalEnergy}` + "g💧 \n\n" + message += "【水果🍉进度】" + `${(($.farmInfo.farmUserPro.treeEnergy / + $.farmInfo.farmUserPro.treeTotalEnergy) * 100).toFixed(2)}` + "%,已浇水" +`${$.farmInfo.farmUserPro.treeEnergy / 10}` + "次,还需"+`${($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10}` +"次 \n\n" + if ($.farmInfo.toFlowTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【开花进度】再浇水${$.farmInfo.toFlowTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次开花\n\n` +"\n\n" + } else if ($.farmInfo.toFruitTimes > ($.farmInfo.farmUserPro.treeEnergy / 10)) { + message += "【水果🍉进度】" + `【结果进度】再浇水${$.farmInfo.toFruitTimes - $.farmInfo.farmUserPro.treeEnergy / 10}次结果\n\n` + "\n\n" + } + // 预测n天后水果课可兑换功能 + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + message = message + "" + `【预测🍉收获时间】${waterD === 1 ? '明天' : waterD === 2 ? '后天' : waterD + '天之后'}(${timeFormat(24 * 60 * 60 * 1000 * waterD + Date.now())}日)可兑换水果🍉` +"\n\n"; + } + //浇水十次 + async function doTenWater() { + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match(`限时翻倍`) && beanCard > 0) { + that.log(`您设置的是使用水滴换豆卡,且背包有水滴换豆卡${beanCard}张, 跳过10次浇水任务`) + return + } + if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + that.log(`\n准备浇水十次`); + let waterCount = 0; + isFruitFinished = false; + for (; waterCount < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit - $.farmTask.totalWaterTaskInit.totalWaterTaskTimes; waterCount++) { + that.log(`第${waterCount + 1}次浇水`); + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`剩余水滴${$.waterResult.totalEnergy}g`); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + if ($.waterResult.totalEnergy < 10) { + that.log(`水滴不够,结束浇水`) + break + } + await gotStageAward();//领取阶段性水滴奖励 + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log('\n今日已完成10次浇水任务\n'); + } + } + //领取首次浇水奖励 + async function getFirstWaterAward() { + await taskInitForFarm(); + //领取首次浇水奖励 + if (!$.farmTask.firstWaterInit.f && $.farmTask.firstWaterInit.totalWaterTimes > 0) { + await firstWaterTaskForFarm(); + if ($.firstWaterReward.code === '0') { + that.log(`【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`); + // message += `【首次浇水奖励】获得${$.firstWaterReward.amount}g💧\n`; + } else { + // message += '【首次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取首次浇水奖励结果: ${JSON.stringify($.firstWaterReward)}`); + } + } else { + that.log('首次浇水奖励已领取\n') + } + } + //领取十次浇水奖励 + async function getTenWaterAward() { + //领取10次浇水奖励 + if (!$.farmTask.totalWaterTaskInit.f && $.farmTask.totalWaterTaskInit.totalWaterTaskTimes >= $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + await totalWaterTaskForFarm(); + if ($.totalWaterReward.code === '0') { + that.log(`【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`); + // message += `【十次浇水奖励】获得${$.totalWaterReward.totalWaterTaskEnergy}g💧\n`; + } else { + // message += '【十次浇水奖励】领取奖励失败,详询日志\n'; + that.log(`领取10次浇水奖励结果: ${JSON.stringify($.totalWaterReward)}`); + } + } else if ($.farmTask.totalWaterTaskInit.totalWaterTaskTimes < $.farmTask.totalWaterTaskInit.totalWaterTaskLimit) { + // message += `【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`; + that.log(`【十次浇水奖励】任务未完成,今日浇水${$.farmTask.totalWaterTaskInit.totalWaterTaskTimes}次\n`); + } + that.log('finished 水果任务完成!'); + } + //再次浇水 + async function doTenWaterAgain() { + that.log('开始检查剩余水滴能否再次浇水再次浇水\n'); + await initForFarm(); + let totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + that.log(`剩余水滴${totalEnergy}g\n`); + await myCardInfoForFarm(); + const { fastCard, doubleCard, beanCard, signCard } = $.myCardInfoRes; + that.log(`背包已有道具:\n快速浇水卡:${fastCard === -1 ? '未解锁': fastCard + '张'}\n水滴翻倍卡:${doubleCard === -1 ? '未解锁': doubleCard + '张'}\n水滴换京豆卡:${beanCard === -1 ? '未解锁' : beanCard + '张'}\n加签卡:${signCard === -1 ? '未解锁' : signCard + '张'}\n`) + if (totalEnergy >= 100 && doubleCard > 0) { + //使用翻倍水滴卡 + for (let i = 0; i < new Array(doubleCard).fill('').length; i++) { + await userMyCardForFarm('doubleCard'); + that.log(`使用翻倍水滴卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + if (signCard > 0) { + //使用加签卡 + for (let i = 0; i < new Array(signCard).fill('').length; i++) { + await userMyCardForFarm('signCard'); + that.log(`使用加签卡结果:${JSON.stringify($.userMyCardRes)}`); + } + await initForFarm(); + totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + } + jdFruitBeanCard = $.getdata('jdFruitBeanCard') ? $.getdata('jdFruitBeanCard') : jdFruitBeanCard; + if ($.isNode() && process.env.FRUIT_BEAN_CARD) { + jdFruitBeanCard = process.env.FRUIT_BEAN_CARD; + } + if (`${jdFruitBeanCard}` === 'true' && JSON.stringify($.myCardInfoRes).match('限时翻倍')) { + that.log(`\n您设置的是水滴换豆功能,现在为您换豆`); + if (totalEnergy >= 100 && $.myCardInfoRes.beanCard > 0) { + //使用水滴换豆卡 + await userMyCardForFarm('beanCard'); + that.log(`使用水滴换豆卡结果:${JSON.stringify($.userMyCardRes)}`); + if ($.userMyCardRes.code === '0') { + // message +="【水果🍉进度】" + `【水滴换豆卡】获得${$.userMyCardRes.beanCount}个京豆\n` + "\n\n"; + return + } + } else { + that.log(`您目前水滴:${totalEnergy}g,水滴换豆卡${$.myCardInfoRes.beanCard}张,暂不满足水滴换豆的条件,为您继续浇水`) + } + } + // if (totalEnergy > 100 && $.myCardInfoRes.fastCard > 0) { + // //使用快速浇水卡 + // await userMyCardForFarm('fastCard'); + // that.log(`使用快速浇水卡结果:${JSON.stringify($.userMyCardRes)}`); + // if ($.userMyCardRes.code === '0') { + // that.log(`已使用快速浇水卡浇水${$.userMyCardRes.waterEnergy}g`); + // } + // await initForFarm(); + // totalEnergy = $.farmInfo.farmUserPro.totalEnergy; + // } + // 所有的浇水(10次浇水)任务,获取水滴任务完成后,如果剩余水滴大于等于60g,则继续浇水(保留部分水滴是用于完成第二天的浇水10次的任务) + let overageEnergy = totalEnergy - retainWater; + if (totalEnergy >= ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy)) { + //如果现有的水滴,大于水果可兑换所需的对滴(也就是把水滴浇完,水果就能兑换了) + isFruitFinished = false; + for (let i = 0; i < ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy) / 10; i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果(水果马上就可兑换了): ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log('\n浇水10g成功\n'); + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + that.log(`目前水滴【${$.waterResult.totalEnergy}】g,继续浇水,水果马上就可以兑换了`) + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else if (overageEnergy >= 10) { + that.log("目前剩余水滴:【" + totalEnergy + "】g,可继续浇水"); + isFruitFinished = false; + for (let i = 0; i < parseInt(overageEnergy / 10); i++) { + await waterGoodForFarm(); + that.log(`本次浇水结果: ${JSON.stringify($.waterResult)}`); + if ($.waterResult.code === '0') { + that.log(`\n浇水10g成功,剩余${$.waterResult.totalEnergy}\n`) + if ($.waterResult.finished) { + // 已证实,waterResult.finished为true,表示水果可以去领取兑换了 + isFruitFinished = true; + break + } else { + await gotStageAward() + } + } else { + that.log('浇水出现失败异常,跳出不在继续浇水') + break; + } + } + if (isFruitFinished) { + option['open-url'] = urlSchema; + $.msg($.name, ``, `【动动账号${$.index}】${$.nickName || $.UserName}\n【提醒⏰】${$.farmInfo.farmUserPro.name}已可领取\n请去动动APP或微信小程序查看\n点击弹窗即达`, option); + $.done(); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}水果已可领取`, `动动账号${$.index} ${$.nickName}\n${$.farmInfo.farmUserPro.name}已可领取`); + } + } + } else { + that.log("目前剩余水滴:【" + totalEnergy + "】g,不再继续浇水,保留部分水滴用于完成第二天【十次浇水得水滴】任务") + } + } + //领取阶段性水滴奖励 + function gotStageAward() { + return new Promise(async resolve => { + if ($.waterResult.waterStatus === 0 && $.waterResult.treeEnergy === 10) { + that.log('果树发芽了,奖励30g水滴'); + await gotStageAwardForFarm('1'); + that.log(`浇水阶段奖励1领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`; + that.log(`【果树发芽了】奖励${$.gotStageAwardForFarmRes.addEnergy}\n`); + } + } else if ($.waterResult.waterStatus === 1) { + that.log('果树开花了,奖励40g水滴'); + await gotStageAwardForFarm('2'); + that.log(`浇水阶段奖励2领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`); + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树开花了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } else if ($.waterResult.waterStatus === 2) { + that.log('果树长出小果子啦, 奖励50g水滴'); + await gotStageAwardForFarm('3'); + that.log(`浇水阶段奖励3领取结果 ${JSON.stringify($.gotStageAwardForFarmRes)}`) + if ($.gotStageAwardForFarmRes.code === '0') { + // message += `【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`; + that.log(`【果树结果了】奖励${$.gotStageAwardForFarmRes.addEnergy}g💧\n`); + } + } + resolve() + }) + } + //天天抽奖活动 + async function turntableFarm() { + await initForTurntableFarm(); + if ($.initForTurntableFarmRes.code === '0') { + //领取定时奖励 //4小时一次 + let {timingIntervalHours, timingLastSysTime, sysTime, timingGotStatus, remainLotteryTimes, turntableInfos} = $.initForTurntableFarmRes; + + if (!timingGotStatus) { + that.log(`是否到了领取免费赠送的抽奖机会----${sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)}`) + if (sysTime > (timingLastSysTime + 60*60*timingIntervalHours*1000)) { + await timingAwardForTurntableFarm(); + that.log(`领取定时奖励结果${JSON.stringify($.timingAwardRes)}`); + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } else { + that.log(`免费赠送的抽奖机会未到时间`) + } + } else { + that.log('4小时候免费赠送的抽奖机会已领取') + } + if ($.initForTurntableFarmRes.turntableBrowserAds && $.initForTurntableFarmRes.turntableBrowserAds.length > 0) { + for (let index = 0; index < $.initForTurntableFarmRes.turntableBrowserAds.length; index++) { + if (!$.initForTurntableFarmRes.turntableBrowserAds[index].status) { + that.log(`开始浏览天天抽奖的第${index + 1}个逛会场任务`) + await browserForTurntableFarm(1, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0' && $.browserForTurntableFarmRes.status) { + that.log(`第${index + 1}个逛会场任务完成,开始领取水滴奖励\n`) + await browserForTurntableFarm(2, $.initForTurntableFarmRes.turntableBrowserAds[index].adId); + if ($.browserForTurntableFarmRes.code === '0') { + that.log(`第${index + 1}个逛会场任务领取水滴奖励完成\n`) + await initForTurntableFarm(); + remainLotteryTimes = $.initForTurntableFarmRes.remainLotteryTimes; + } + } + } else { + that.log(`浏览天天抽奖的第${index + 1}个逛会场任务已完成`) + } + } + } + //天天抽奖助力 + that.log('开始天天抽奖--好友助力--每人每天只有三次助力机会.') + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('天天抽奖-不能自己给自己助力\n') + continue + } + await lotteryMasterHelp(code); + // that.log('天天抽奖助力结果',lotteryMasterHelpRes.helpResult) + if ($.lotteryMasterHelpRes.helpResult.code === '0') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}成功\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '11') { + that.log(`天天抽奖-不要重复助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}\n`) + } else if ($.lotteryMasterHelpRes.helpResult.code === '13') { + that.log(`天天抽奖-助力${$.lotteryMasterHelpRes.helpResult.masterUserInfo.nickName}失败,助力次数耗尽\n`); + break; + } + } + that.log(`---天天抽奖次数remainLotteryTimes----${remainLotteryTimes}次`) + //抽奖 + if (remainLotteryTimes > 0) { + that.log('开始抽奖') + let lotteryResult = ''; + for (let i = 0; i < new Array(remainLotteryTimes).fill('').length; i++) { + await lotteryForTurntableFarm() + that.log(`第${i + 1}次抽奖结果${JSON.stringify($.lotteryRes)}`); + if ($.lotteryRes.code === '0') { + turntableInfos.map((item) => { + if (item.type === $.lotteryRes.type) { + that.log(`lotteryRes.type${$.lotteryRes.type}`); + if ($.lotteryRes.type.match(/bean/g) && $.lotteryRes.type.match(/bean/g)[0] === 'bean') { + lotteryResult += `${item.name}个,`; + } else if ($.lotteryRes.type.match(/water/g) && $.lotteryRes.type.match(/water/g)[0] === 'water') { + lotteryResult += `${item.name},`; + } else { + lotteryResult += `${item.name},`; + } + } + }) + //没有次数了 + if ($.lotteryRes.remainLotteryTimes === 0) { + break + } + } + } + if (lotteryResult) { + that.log(`【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`) + // message += `【天天抽奖】${lotteryResult.substr(0, lotteryResult.length - 1)}\n`; + } + } else { + that.log('天天抽奖--抽奖机会为0次') + } + } else { + that.log('初始化天天抽奖得好礼失败') + } + } + //领取额外奖励水滴 + async function getExtraAward() { + await masterHelpTaskInitForFarm(); + if ($.masterHelpResult.code === '0') { + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length >= 5) { + // 已有五人助力。领取助力后的奖励 + if (!$.masterHelpResult.masterGotFinal) { + await masterGotFinishedTaskForFarm(); + if ($.masterGotFinished.code === '0') { + that.log(`已成功领取好友助力奖励:【${$.masterGotFinished.amount}】g水`); + // message += "【额外奖励】" + `${$.masterGotFinished.amount}` + "g水领取成功\n\n"; + } + } else { + that.log("已经领取过5好友助力额外奖励"); + // message += "【水果🍉进度】" + `【额外奖励】已被领取过\n` + "\n\n"; + } + } else { + that.log("助力好友未达到5个"); + // message += "【额外奖励】领取失败,原因:给您助力的人未达5个\n\n"; + } + if ($.masterHelpResult.masterHelpPeoples && $.masterHelpResult.masterHelpPeoples.length > 0) { + let str = ''; + $.masterHelpResult.masterHelpPeoples.map((item, index) => { + if (index === ($.masterHelpResult.masterHelpPeoples.length - 1)) { + str += item.nickName || "匿名用户"; + } else { + str += (item.nickName || "匿名用户") + ','; + } + let date = new Date(item.time); + let time = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getMinutes(); + that.log(`\n动动昵称【${item.nickName || "匿名用户"}】 在 ${time} 给您助过力\n`); + }) + // message += "【助力您的好友】 " + `${str}` + "\n\n" + } + that.log('领取额外奖励水滴结束\n'); + } + } + + function getHelp() { + newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jd_fruit/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.farmInfo.farmUserPro.shareCode) { + $.get({ + url: "http://api.tyh52.com/act/set/jd_fruit/" + $.farmInfo.farmUserPro.shareCode + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + //助力好友 + async function masterHelpShare() { + that.log('开始助力好友') + let salveHelpAddWater = 0; + let remainTimes = 4;//今日剩余助力次数,默认4次(动动农场每人每天4次助力机会)。 + let helpSuccessPeoples = '';//成功助力好友 + that.log(`格式化后的助力码::${JSON.stringify(newShareCodes)}\n`); + + for (let code of newShareCodes) { + that.log(`开始助力动动账号${$.index} - ${$.nickName}的好友: ${code}`); + if (!code) continue; + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('不能为自己助力哦,跳过自己的shareCode\n') + continue + } + await masterHelp(code); + if ($.helpResult.code === '0') { + if ($.helpResult.helpResult.code === '0') { + //助力成功 + salveHelpAddWater += $.helpResult.helpResult.salveHelpAddWater; + that.log(`【助力好友结果】: 已成功给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力`); + that.log(`给好友【${$.helpResult.helpResult.masterUserInfo.nickName}】助力获得${$.helpResult.helpResult.salveHelpAddWater}g水滴`) + helpSuccessPeoples += ($.helpResult.helpResult.masterUserInfo.nickName || '匿名用户') + ','; + } else if ($.helpResult.helpResult.code === '8') { + that.log(`【助力好友结果】: 助力【${$.helpResult.helpResult.masterUserInfo.nickName}】失败,您今天助力次数已耗尽`); + } else if ($.helpResult.helpResult.code === '9') { + that.log(`【助力好友结果】: 之前给【${$.helpResult.helpResult.masterUserInfo.nickName}】助力过了`); + } else if ($.helpResult.helpResult.code === '10') { + that.log(`【助力好友结果】: 好友【${$.helpResult.helpResult.masterUserInfo.nickName}】已满五人助力`); + } else { + that.log(`助力其他情况:${JSON.stringify($.helpResult.helpResult)}`); + } + that.log(`【今日助力次数还剩】${$.helpResult.helpResult.remainTimes}次\n`); + remainTimes = $.helpResult.helpResult.remainTimes; + if ($.helpResult.helpResult.remainTimes === 0) { + that.log(`您当前助力次数已耗尽,跳出助力`); + break + } + } else { + that.log(`助力失败::${JSON.stringify($.helpResult)}`); + } + } + if (helpSuccessPeoples && helpSuccessPeoples.length > 0) { + // message += " " + `【您助力的好友👬】${helpSuccessPeoples.substr(0, helpSuccessPeoples.length - 1)}\n` + "\n\n"; + } + if (salveHelpAddWater > 0) { + // message += `【助力好友👬】获得${salveHelpAddWater}g💧\n`; + that.log(`【助力好友👬】获得${salveHelpAddWater}g💧\n`); + } + // message += "" + `【今日剩余助力👬】${remainTimes}次\n` + "\n\n"; + that.log('助力好友结束,即将开始领取额外水滴奖励\n'); + } + //水滴雨 + async function executeWaterRains() { + let executeWaterRain = !$.farmTask.waterRainInit.f; + if (executeWaterRain) { + that.log(`水滴雨任务,每天两次,最多可得10g水滴`); + that.log(`两次水滴雨任务是否全部完成:${$.farmTask.waterRainInit.f ? '是' : '否'}`); + if ($.farmTask.waterRainInit.lastTime) { + if (Date.now() < ($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000)) { + executeWaterRain = false; + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`; + that.log(`\`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】未到时间,请${new Date($.farmTask.waterRainInit.lastTime + 3 * 60 * 60 * 1000).toLocaleTimeString()}再试\n`); + } + } + if (executeWaterRain) { + that.log(`开始水滴雨任务,这是第${$.farmTask.waterRainInit.winTimes + 1}次,剩余${2 - ($.farmTask.waterRainInit.winTimes + 1)}次`); + await waterRainForFarm(); + that.log('水滴雨waterRain'); + if ($.waterRain.code === '0') { + that.log('水滴雨任务执行成功,获得水滴:' + $.waterRain.addEnergy + 'g'); + that.log(`【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`); + // message += `【第${$.farmTask.waterRainInit.winTimes + 1}次水滴雨】获得${$.waterRain.addEnergy}g水滴\n`; + } + } + } else { + // message += `【水滴雨】已全部完成,获得20g💧\n`; + } + } + //打卡领水活动 + async function clockInIn() { + that.log('开始打卡领水活动(签到,关注,领券)'); + await clockInInitForFarm(); + if ($.clockInInit.code === '0') { + // 签到得水滴 + if (!$.clockInInit.todaySigned) { + that.log('开始今日签到'); + await clockInForFarm(); + that.log(`打卡结果${JSON.stringify($.clockInForFarmRes)}`); + if ($.clockInForFarmRes.code === '0') { + // message += `【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`; + that.log(`【第${$.clockInForFarmRes.signDay}天签到】获得${$.clockInForFarmRes.amount}g💧\n`) + if ($.clockInForFarmRes.signDay === 7) { + //可以领取惊喜礼包 + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + } + } + if ($.clockInInit.todaySigned && $.clockInInit.totalSigned === 7) { + that.log('开始领取--惊喜礼包38g水滴'); + await gotClockInGift(); + if ($.gotClockInGiftRes.code === '0') { + // message += `【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`; + that.log(`【惊喜礼包】获得${$.gotClockInGiftRes.amount}g💧\n`); + } + } + // 限时关注得水滴 + if ($.clockInInit.themes && $.clockInInit.themes.length > 0) { + for (let item of $.clockInInit.themes) { + if (!item.hadGot) { + that.log(`关注ID${item.id}`); + await clockInFollowForFarm(item.id, "theme", "1"); + that.log(`themeStep1--结果${JSON.stringify($.themeStep1)}`); + if ($.themeStep1.code === '0') { + await clockInFollowForFarm(item.id, "theme", "2"); + that.log(`themeStep2--结果${JSON.stringify($.themeStep2)}`); + if ($.themeStep2.code === '0') { + that.log(`关注${item.name},获得水滴${$.themeStep2.amount}g`); + } + } + } + } + } + // 限时领券得水滴 + if ($.clockInInit.venderCoupons && $.clockInInit.venderCoupons.length > 0) { + for (let item of $.clockInInit.venderCoupons) { + if (!item.hadGot) { + that.log(`领券的ID${item.id}`); + await clockInFollowForFarm(item.id, "venderCoupon", "1"); + that.log(`venderCouponStep1--结果${JSON.stringify($.venderCouponStep1)}`); + if ($.venderCouponStep1.code === '0') { + await clockInFollowForFarm(item.id, "venderCoupon", "2"); + if ($.venderCouponStep2.code === '0') { + that.log(`venderCouponStep2--结果${JSON.stringify($.venderCouponStep2)}`); + that.log(`从${item.name}领券,获得水滴${$.venderCouponStep2.amount}g`); + } + } + } + } + } + } + that.log('开始打卡领水活动(签到,关注,领券)结束\n'); + } + // + async function getAwardInviteFriend() { + await friendListInitForFarm();//查询好友列表 + that.log(`查询好友列表数据:\n`) + if ($.friendList) { + that.log(`\n今日已邀请好友${$.friendList.inviteFriendCount}个 / 每日邀请上限${$.friendList.inviteFriendMax}个`); + that.log(`开始删除${$.friendList.friends && $.friendList.friends.length}个好友,可拿每天的邀请奖励`); + if ($.friendList.friends && $.friendList.friends.length > 0) { + for (let friend of $.friendList.friends) { + that.log(`\n开始删除好友 [${friend.shareCode}]`); + const deleteFriendForFarm = await request('deleteFriendForFarm', { "shareCode": `${friend.shareCode}`,"version":8,"channel":1 }); + if (deleteFriendForFarm && deleteFriendForFarm.code === '0') { + that.log(`删除好友 [${friend.shareCode}] 成功\n`); + } + } + } + await receiveFriendInvite();//为他人助力,接受邀请成为别人的好友 + if ($.friendList.inviteFriendCount > 0) { + if ($.friendList.inviteFriendCount > $.friendList.inviteFriendGotAwardCount) { + that.log('开始领取邀请好友的奖励'); + await awardInviteFriendForFarm(); + that.log(`领取邀请好友的奖励结果::${JSON.stringify($.awardInviteFriendRes)}`); + } + } else { + that.log('今日未邀请过好友') + } + } else { + that.log(`查询好友列表失败\n`); + } + } + //给好友浇水 + async function doFriendsWater() { + await friendListInitForFarm(); + that.log('开始给好友浇水...'); + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax } = $.farmTask.waterFriendTaskInit; + that.log(`今日已给${waterFriendCountKey}个好友浇水`); + if (waterFriendCountKey < waterFriendMax) { + let needWaterFriends = []; + if ($.friendList.friends && $.friendList.friends.length > 0) { + $.friendList.friends.map((item, index) => { + if (item.friendState === 1) { + if (needWaterFriends.length < (waterFriendMax - waterFriendCountKey)) { + needWaterFriends.push(item.shareCode); + } + } + }); + //TODO ,发现bug,github action运行发现有些账号第一次没有给3个好友浇水 + that.log(`需要浇水的好友列表shareCodes:${JSON.stringify(needWaterFriends)}`); + let waterFriendsCount = 0, cardInfoStr = ''; + for (let index = 0; index < needWaterFriends.length; index ++) { + await waterFriendForFarm(needWaterFriends[index]); + that.log(`为第${index+1}个好友浇水结果:${JSON.stringify($.waterFriendForFarmRes)}\n`) + if ($.waterFriendForFarmRes.code === '0') { + waterFriendsCount ++; + if ($.waterFriendForFarmRes.cardInfo) { + that.log('为好友浇水获得道具了'); + if ($.waterFriendForFarmRes.cardInfo.type === 'beanCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴换豆卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'fastCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `快速浇水卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'doubleCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `水滴翻倍卡,`; + } else if ($.waterFriendForFarmRes.cardInfo.type === 'signCard') { + that.log(`获取道具卡:${$.waterFriendForFarmRes.cardInfo.rule}`); + cardInfoStr += `加签卡,`; + } + } + } else if ($.waterFriendForFarmRes.code === '11') { + that.log('水滴不够,跳出浇水') + } + } + // message += `【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`; + that.log(`【好友浇水】已给${waterFriendsCount}个好友浇水,消耗${waterFriendsCount * 10}g水\n`); + if (cardInfoStr && cardInfoStr.length > 0) { + // message += `【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`; + that.log(`【好友浇水奖励】${cardInfoStr.substr(0, cardInfoStr.length - 1)}\n`); + } + } else { + that.log('您的好友列表暂无好友,快去邀请您的好友吧!') + } + } else { + that.log(`今日已为好友浇水量已达${waterFriendMax}个`) + } + } + //领取给3个好友浇水后的奖励水滴 + async function getWaterFriendGotAward() { + await taskInitForFarm(); + const { waterFriendCountKey, waterFriendMax, waterFriendSendWater, waterFriendGotAward } = $.farmTask.waterFriendTaskInit + if (waterFriendCountKey >= waterFriendMax) { + if (!waterFriendGotAward) { + await waterFriendGotAwardForFarm(); + that.log(`领取给${waterFriendMax}个好友浇水后的奖励水滴::${JSON.stringify($.waterFriendGotAwardRes)}`) + if ($.waterFriendGotAwardRes.code === '0') { + // message += `【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`; + that.log(`【给${waterFriendMax}好友浇水】奖励${$.waterFriendGotAwardRes.addWater}g水滴\n`); + } + } else { + that.log(`给好友浇水的${waterFriendSendWater}g水滴奖励已领取\n`); + // message += `【给${waterFriendMax}好友浇水】奖励${waterFriendSendWater}g水滴已领取\n`; + } + } else { + that.log(`暂未给${waterFriendMax}个好友浇水\n`); + } + } + //接收成为对方好友的邀请 + async function receiveFriendInvite() { + for (let code of newShareCodes) { + if (code === $.farmInfo.farmUserPro.shareCode) { + that.log('自己不能邀请自己成为好友噢\n') + continue + } + await inviteFriend(code); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + if ($.inviteFriendRes.helpResult.code === '0') { + that.log(`接收邀请成为好友结果成功,您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + } else if ($.inviteFriendRes.helpResult.code === '17') { + that.log(`接收邀请成为好友结果失败,对方已是您的好友`) + } + } + // that.log(`开始接受6fbd26cc27ac44d6a7fed34092453f77的邀请\n`) + // await inviteFriend('6fbd26cc27ac44d6a7fed34092453f77'); + // that.log(`接收邀请成为好友结果:${JSON.stringify($.inviteFriendRes.helpResult)}`) + // if ($.inviteFriendRes.helpResult.code === '0') { + // that.log(`您已成为${$.inviteFriendRes.helpResult.masterUserInfo.nickName}的好友`) + // } else if ($.inviteFriendRes.helpResult.code === '17') { + // that.log(`对方已是您的好友`) + // } + } + async function duck() { + for (let i = 0; i < 10; i++) { + //这里循环十次 + await getFullCollectionReward(); + if ($.duckRes.code === '0') { + if (!$.duckRes.hasLimit) { + that.log(`小鸭子游戏:${$.duckRes.title}`); + // if ($.duckRes.type !== 3) { + // that.log(`${$.duckRes.title}`); + // if ($.duckRes.type === 1) { + // message += `【小鸭子】为你带回了水滴\n`; + // } else if ($.duckRes.type === 2) { + // message += `【小鸭子】为你带回快速浇水卡\n` + // } + // } + } else { + that.log(`${$.duckRes.title}`) + break; + } + } else if ($.duckRes.code === '10') { + that.log(`小鸭子游戏达到上限`) + break; + } + } + } + // ========================API调用接口======================== + //鸭子,点我有惊喜 + async function getFullCollectionReward() { + return new Promise(resolve => { + const body = {"type": 2, "version": 6, "channel": 2}; + $.post(taskUrl("getFullCollectionReward", body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + /** + * 领取10次浇水奖励API + */ + async function totalWaterTaskForFarm() { + const functionId = 'totalWaterTaskForFarm'; + $.totalWaterReward = await request(functionId); + } + //领取首次浇水奖励API + async function firstWaterTaskForFarm() { + const functionId = 'firstWaterTaskForFarm'; + $.firstWaterReward = await request(functionId); + } + //领取给3个好友浇水后的奖励水滴API + async function waterFriendGotAwardForFarm() { + const functionId = 'waterFriendGotAwardForFarm'; + $.waterFriendGotAwardRes = await request(functionId, {"version": 4, "channel": 1}); + } + // 查询背包道具卡API + async function myCardInfoForFarm() { + const functionId = 'myCardInfoForFarm'; + $.myCardInfoRes = await request(functionId, {"version": 5, "channel": 1}); + } + //使用道具卡API + async function userMyCardForFarm(cardType) { + const functionId = 'userMyCardForFarm'; + $.userMyCardRes = await request(functionId, {"cardType": cardType}); + } + /** + * 领取浇水过程中的阶段性奖励 + * @param type + * @returns {Promise} + */ + async function gotStageAwardForFarm(type) { + $.gotStageAwardForFarmRes = await request('gotStageAwardForFarm', {'type': type}); + } + //浇水API + async function waterGoodForFarm() { + await $.wait(1000); + that.log('等待了1秒'); + + const functionId = 'waterGoodForFarm'; + $.waterResult = await request(functionId); + } + // 初始化集卡抽奖活动数据API + async function initForTurntableFarm() { + $.initForTurntableFarmRes = await request('initForTurntableFarm', {version: 4, channel: 1}); + } + async function lotteryForTurntableFarm() { + await $.wait(2000); + that.log('等待了2秒'); + $.lotteryRes = await request('lotteryForTurntableFarm', {type: 1, version: 4, channel: 1}); + } + + async function timingAwardForTurntableFarm() { + $.timingAwardRes = await request('timingAwardForTurntableFarm', {version: 4, channel: 1}); + } + + async function browserForTurntableFarm(type, adId) { + if (type === 1) { + that.log('浏览爆品会场'); + } + if (type === 2) { + that.log('天天抽奖浏览任务领取水滴'); + } + const body = {"type": type,"adId": adId,"version":4,"channel":1}; + $.browserForTurntableFarmRes = await request('browserForTurntableFarm', body); + // 浏览爆品会场8秒 + } + //天天抽奖浏览任务领取水滴API + async function browserForTurntableFarm2(type) { + const body = {"type":2,"adId": type,"version":4,"channel":1}; + $.browserForTurntableFarm2Res = await request('browserForTurntableFarm', body); + } + /** + * 天天抽奖拿好礼-助力API(每人每天三次助力机会) + */ + async function lotteryMasterHelp() { + $.lotteryMasterHelpRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-3', + babelChannel: "3", + version: 4, + channel: 1 + }); + } + + //领取5人助力后的额外奖励API + async function masterGotFinishedTaskForFarm() { + const functionId = 'masterGotFinishedTaskForFarm'; + $.masterGotFinished = await request(functionId); + } + //助力好友信息API + async function masterHelpTaskInitForFarm() { + const functionId = 'masterHelpTaskInitForFarm'; + $.masterHelpResult = await request(functionId); + } + //接受对方邀请,成为对方好友的API + async function inviteFriend() { + $.inviteFriendRes = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0] + '-inviteFriend', + version: 4, + channel: 2 + }); + } + // 助力好友API + async function masterHelp() { + $.helpResult = await request(`initForFarm`, { + imageUrl: "", + nickName: "", + shareCode: arguments[0], + babelChannel: "3", + version: 2, + channel: 1 + }); + } + /** + * 水滴雨API + */ + async function waterRainForFarm() { + const functionId = 'waterRainForFarm'; + const body = {"type": 1, "hongBaoTimes": 100, "version": 3}; + $.waterRain = await request(functionId, body); + } + /** + * 打卡领水API + */ + async function clockInInitForFarm() { + const functionId = 'clockInInitForFarm'; + $.clockInInit = await request(functionId); + } + + // 连续签到API + async function clockInForFarm() { + const functionId = 'clockInForFarm'; + $.clockInForFarmRes = await request(functionId, {"type": 1}); + } + + //关注,领券等API + async function clockInFollowForFarm(id, type, step) { + const functionId = 'clockInFollowForFarm'; + let body = { + id, + type, + step + } + if (type === 'theme') { + if (step === '1') { + $.themeStep1 = await request(functionId, body); + } else if (step === '2') { + $.themeStep2 = await request(functionId, body); + } + } else if (type === 'venderCoupon') { + if (step === '1') { + $.venderCouponStep1 = await request(functionId, body); + } else if (step === '2') { + $.venderCouponStep2 = await request(functionId, body); + } + } + } + + // 领取连续签到7天的惊喜礼包API + async function gotClockInGift() { + $.gotClockInGiftRes = await request('clockInForFarm', {"type": 2}) + } + + //定时领水API + async function gotThreeMealForFarm() { + const functionId ='gotThreeMealForFarm'; + $.threeMeal = await request(functionId); + } + /** + * 浏览广告任务API + * type为0时, 完成浏览任务 + * type为1时, 领取浏览任务奖励 + */ + async function browseAdTaskForFarm(advertId, type) { + const functionId = 'browseAdTaskForFarm'; + if (type === 0) { + $.browseResult = await request(functionId, {advertId, type}); + } else if (type === 1) { + $.browseRwardResult = await request(functionId, {advertId, type}); + } + } + // 被水滴砸中API + async function gotWaterGoalTaskForFarm() { + $.goalResult = await request('gotWaterGoalTaskForFarm', {type: 3}); + } + //签到API + async function signForFarm() { + const functionId = 'signForFarm'; + $.signResult = await request(functionId); + } + /** + * 初始化农场, 可获取果树及用户信息API + */ + async function initForFarm() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "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" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + // 初始化任务列表API + async function taskInitForFarm() { + that.log('\n初始化任务列表') + const functionId = 'taskInitForFarm'; + $.farmTask = await request(functionId); + } + //获取好友列表API + async function friendListInitForFarm() { + $.friendList = await request('friendListInitForFarm', {"version": 4, "channel": 1}); + // that.log('aa', aa); + } + // 领取邀请好友的奖励API + async function awardInviteFriendForFarm() { + $.awardInviteFriendRes = await request('awardInviteFriendForFarm'); + } + //为好友浇水API + async function waterFriendForFarm(shareCode) { + const body = {"shareCode": shareCode, "version": 6, "channel": 1} + $.waterFriendForFarmRes = await request('waterFriendForFarm', body); + } + + + function readShareCode() { + return new Promise(async resolve => { + $.get({url: `http://jd.turinglabs.net/api/v2/jd/farm/read/${randomCount}/`, timeout: 10000,}, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + that.log(`随机取个${randomCount}码放到您固定的互助码后面(不影响已有固定互助)`) + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + await $.wait(10000); + resolve() + }) + } + function shareCodesFormat() { + return new Promise(async resolve => { + // that.log(`第${$.index}个动动账号的助力码:::${jdFruitShareArr[$.index - 1]}`) + newShareCodes = []; + // if (jdFruitShareArr[$.index - 1]) { + // newShareCodes = jdFruitShareArr[$.index - 1].split('@'); + // } else { + // that.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + // const tempIndex = $.index > shareCodes.length ? (shareCodes.length - 1) : ($.index - 1); + // newShareCodes = shareCodes[tempIndex].split('@'); + // } + // const readShareCodeRes = await readShareCode(); + // if (readShareCodeRes && readShareCodeRes.code === 200) { + // // newShareCodes = newShareCodes.concat(readShareCodeRes.data || []); + // newShareCodes = [...new Set([...newShareCodes, ...(readShareCodeRes.data || [])])]; + // } + // that.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify(newShareCodes)}`) + resolve(); + }) + } + + function request(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动农场: API查询请求失败 ‼️‼️') + that.log(JSON.stringify(err)); + that.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) + } + function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } + } + function taskUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + }, + timeout: 10000, + } + } + //-------------------------------------------------东东赚赚------------------------------------------------------------ + + +async function jdWish() { + $.bean = 0 + $.tuan = null + $.hasOpen = false + await getTaskList(true) + await getUserTuanInfo() + if (!$.tuan) { + await openTuan() + if ($.hasOpen) await getUserTuanInfo() + } + if ($.tuan) $.tuanList.push($.tuan) + await helpFriends() + await getUserInfo() + $.nowBean = parseInt($.totalBeanNum) + $.nowNum = parseInt($.totalNum) + for (let i = 0; i < $.taskList.length; ++i) { + let task = $.taskList[i] + if (task['taskId'] === 1 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + } else if (task['taskId'] !== 3 && task['status'] !== 2) { + that.log(`去做任务:${task.taskName}`) + if(task['itemId']) + await doTask({"itemId":task['itemId'],"taskId":task['taskId'],"mpVersion":"3.4.0"}) + else + await doTask({"taskId": task['taskId'],"mpVersion":"3.4.0"}) + await $.wait(3000) + } + } + await getTaskList(); + await showMsg1(); + } + + + function helpFriendTuan(body) { + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_assist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.success) { + that.log('助力成功') + } else { + if (data.resultCode === '9200008') that.log('不能助力自己') + else if (data.resultCode === '9200011') that.log('已经助力过') + else if (data.resultCode === '2400205') that.log('团已满') + else if (data.resultCode === '2400203') {that.log('助力次数已耗尽');$.canHelp = false} + else that.log(`未知错误`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getUserTuanInfo() { + let body = {"paramData": {"channel": "FISSION_BEAN"}} + return new Promise(resolve => { + $.get(taskTuanUrl("distributeBeanActivityInfo", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data && !data.data.canStartNewAssist) { + $.tuan = { + "activityIdEncrypted": data.data.id, + "assistStartRecordId": data.data.assistStartRecordId, + "assistedPinEncrypted": data.data.encPin, + "channel": "FISSION_BEAN" + } + $.tuanActId = data.data.id + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function openTuan() { + let body = {"activityIdEncrypted": $.tuanActId, "channel": "FISSION_BEAN"} + return new Promise(resolve => { + $.get(taskTuanUrl("vvipclub_distributeBean_startAssist", body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['success']) { + $.hasOpen = true + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getUserInfo() { + return new Promise(resolve => { + $.get(taskUrl1("interactIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // if (data.data.shareTaskRes) { + // that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${data.data.shareTaskRes.itemId}\n`); + // } else { + // that.log(`\n\n已满5人助力或助力功能已下线,故暂时无${$.name}好友助力码\n\n`) + // } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function getTaskList(flag = false) { + return new Promise(resolve => { + $.get(taskUrl1("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.taskList = data.data.taskDetailResList + $.totalNum = data.data.totalNum + $.totalBeanNum = data.data.totalBeanNum + if (flag && $.taskList.filter(item => !!item && item['taskId']=== 3) && $.taskList.filter(item => !!item && item['taskId']=== 3).length) { + $.shareId=$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']; + that.log(`\n【动动账号${$.index}(${$.nickName || $.UserName})的${$.name}好友互助码】${$.taskList.filter(item => !!item && item['taskId']=== 3)[0]['itemId']}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + // 完成 + function doTask(body, func = "doInteractTask") { + // that.log(taskUrl("doInteractTask", body)) + return new Promise(resolve => { + $.get(taskUrl1(func, body), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + // that.log(data) + if (func === "doInteractTask") { + if (data.subCode === "S000") { + that.log(`任务完成,获得 ${data.data.taskDetailResList[0].incomeAmountConf} 金币,${data.data.taskDetailResList[0].beanNum} 京豆`) + $.bean += parseInt(data.data.taskDetailResList[0].beanNum) + } else { + that.log(`任务失败,错误信息:${data.message}`) + } + } else { + that.log(`${data.data.helpResDesc}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + async function helpFriends() { + await getHelp(); + for (let code of $.newShareCodes) { + if (!code) continue + await doTask({"itemId": code, "taskId": "3", "mpVersion": "3.4.0"}, "doHelpTask") + } + await setHelp(); + } + + function getHelp() { + $.newShareCodes = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzz/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var i in list) { + $.newShareCodes.push(list[i]); + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelp() { + return new Promise(resolve => { + if ($.shareId) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzz/" + $.shareId + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的邀請碼成功"); + } else { + that.log("提交邀请码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function getHelpTuan() { + $.tuanList = []; + return new Promise(resolve => { + $.get({ + url: "http://api.tyh52.com/act/get/jdzzTuan/3" + }, (err, resp, data) => { + try { + if (data) { + data = JSON.parse(data); + if (data.code == 1) { + let list = data.data; + if (!(list instanceof Array)) { + list = JSON.parse(list); + } + if (list.length > 0) { + for (var item of list) { + let its=item.split('@'); + if(its.length==2){ + let tuan={ + "activityIdEncrypted": $.tuanActId, + "assistStartRecordId": its[0], + "assistedPinEncrypted": its[1], + "channel": "FISSION_BEAN" + } + $.tuanList.push(tuan); + } + } + } + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }); + } + + function setHelpTuan() { + return new Promise(resolve => { + if ($.tuan) { + $.get({ + url: "http://api.tyh52.com/act/set/jdzzTuan/" + $.tuan.assistStartRecordId+'@'+$.tuan.assistedPinEncrypted + }, (err, resp, data) => { + try { + if (data) { + that.log(data); + data = JSON.parse(data); + if (data.code == 1) { + that.log("提交自己的开团碼成功"); + }else{ + that.log("提交开团码失败," + data.message); + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + } else { + resolve(); + } + + }); + } + + function taskUrl1(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } + } + + function taskTuanUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&body=${escape(JSON.stringify(body))}&appid=swat_miniprogram&osVersion=5.0.0&clientVersion=3.1.3&fromType=wxapp×tamp=${new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 + 8 * 60 * 60 * 1000}`, + headers: { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Host": "api.m.jd.com", + "Referer": "https://servicewechat.com/wxa5bf5ee667d91626/108/page-frame.html", + "Cookie": cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + } + } + } + + + + function showMsg1() { + return new Promise(async resolve => { + that.log( "" + `本次获得${parseInt($.totalBeanNum) - $.nowBean}京豆,${parseInt($.totalNum) - $.nowNum}金币\n` + "\n\n") + message += "" + `累计获得${$.totalBeanNum}京豆,${$.totalNum}金币\n可兑换${$.totalNum / 10000}元无门槛红包` + "\n\n" + if (parseInt($.totalBeanNum) - $.nowBean > 0) { + $.msg($.name, '', `动动账号${$.index} ${$.nickName}\n${message}`); + } else { + $.log(message) + } + // 云端大于10元无门槛红包时进行通知推送 + if ($.isNode() && $.totalNum >= 1000000) await notify.sendNotify(`${$.name} - 动动账号${$.index} - ${$.nickName}`, `动动账号${$.index} ${$.nickName}\n当前金币:${$.totalNum}个\n可兑换无门槛红包:${parseInt($.totalNum) / 10000}元\n`,) + resolve(); + }) + } + + + + + +//我加的函数 +function postToDingTalk(messgae) { + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"资产变动", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} diff --git a/src/main/resources/test_our_new.js b/src/main/resources/test_our_new.js new file mode 100644 index 0000000..76fa090 --- /dev/null +++ b/src/main/resources/test_our_new.js @@ -0,0 +1,1195 @@ +/* +cron "30 10,22 * * *" jd_bean_change.js, tag:资产变化强化版by-ccwav +*/ + +let roleMap = { + "jd_66ea783827d30":"军军酱", + "jd_4311ac0ff4456":"居居酱" +} +let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" +//更新by ccwav,20210821 +const $ = new Env('京东资产变动通知'); +const notify = $.isNode() ? require('./sendNotify') : ''; +const JXUserAgent = $.isNode() ? (process.env.JX_USER_AGENT ? process.env.JX_USER_AGENT : ``):``; +//Node.js用户请在jdCookie.js处填写京东ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +let allMessage = ''; +let message = ""; +let ReturnMessage = ''; +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +const JD_API_HOST = 'https://api.m.jd.com/client.action'; + +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => {}; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} +!(async () => { + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + message += "[通知] 资产变动 \n\n --- \n\n" + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.beanCount = 0; + $.incomeBean = 0; + $.expenseBean = 0; + $.todayIncomeBean = 0; + $.errorMsg = ''; + $.isLogin = true; + $.nickName = ''; + $.message = ''; + $.balance = 0; + $.expiredBalance = 0; + $.JdzzNum=0; + $.JdMsScore = 0; + $.JdFarmProdName = ''; + $.JdtreeEnergy=0; + $.JdtreeTotalEnergy=0; + $.JdwaterTotalT = 0; + $.JdwaterD = 0; + $.JDwaterEveryDayT=0; + $.JDtotalcash=0; + $.JDEggcnt=0; + $.Jxmctoken=''; + await TotalBean(); + + username = $.UserName + if (roleMap[username] == undefined){ + continue + } + username = roleMap[username] + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + + console.log(`\n********开始【京东账号${$.index}】${$.nickName || $.UserName}******\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await getJdZZ(); + await getMs(); + await jdfruitRequest('taskInitForFarm', {"version":14,"channel":1,"babelChannel":"120"}); + await getjdfruit(); + await cash(); + await requestAlgo(); + await JxmcGetRequest(); + await bean(); + await getJxFactory(); //惊喜工厂 + await getDdFactoryInfo(); // 京东工厂 + await showMsg(); + } + } + + if ($.isNode() && allMessage) { + await notify.sendNotify(`${$.name}`, `${allMessage}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + postToDingTalk(message) + $.done(); + }) +async function showMsg() { + if ($.errorMsg) return + //allMessage += `账号${$.index}:${$.nickName || $.UserName}\n今日收入:${$.todayIncomeBean}京豆 🐶\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆 🐶${$.message}${$.index !== cookiesArr.length ? '\n\n' : ''}`; + + // if ($.isNode()) { + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `账号${$.index}:${$.nickName || $.UserName}\n昨日收入:${$.incomeBean}京豆 🐶\n昨日支出:${$.expenseBean}京豆 🐶\n当前京豆:${$.beanCount}京豆 🐶${$.message}`, { url: `https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean` }) + // } + + ReturnMessage=`📣=============账号${$.index}=============📣\n` + ReturnMessage+=`账号名称:${$.nickName || $.UserName}\n`; + ReturnMessage+=`今日收入:${$.todayIncomeBean}京豆 🐶\n`; + message += "" +`今日收入:${$.todayIncomeBean}京豆 🐶\n` + "\n\n" + ReturnMessage+=`昨日收入:${$.incomeBean}京豆 🐶\n`; + message += "" + `昨日收入:${$.incomeBean}京豆 🐶\n` +"\n\n" + ReturnMessage+=`昨日支出:${$.expenseBean}京豆 🐶\n`; + message += "" +`昨日支出:${$.expenseBean}京豆 🐶\n` +"\n\n" + ReturnMessage+=`当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶\n`; + message += "" + `当前京豆:${$.beanCount}(今日将过期${$.expirejingdou})京豆🐶\n` +"\n\n" + + if(typeof $.JDEggcnt !== "undefined"){ + ReturnMessage+=`京喜牧场:${$.JDEggcnt}枚鸡蛋\n`; + message += "" + `京喜牧场:${$.JDEggcnt}枚鸡蛋\n` +"\n\n" + } + if(typeof $.JDtotalcash !== "undefined"){ + ReturnMessage+=`极速金币:${$.JDtotalcash}金币(≈${$.JDtotalcash / 10000}元)\n`; + message += "" + `极速金币:${$.JDtotalcash}金币(≈${$.JDtotalcash / 10000}元)\n` +"\n\n" + } + if(typeof $.JdzzNum !== "undefined"){ + ReturnMessage+=`京东赚赚:${$.JdzzNum}金币(≈${$.JdzzNum / 10000}元)\n`; + message += "" + `京东赚赚:${$.JdzzNum}金币(≈${$.JdzzNum / 10000}元)\n` +"\n\n" + } + if($.JdMsScore!=0){ + ReturnMessage+=`京东秒杀:${$.JdMsScore}秒秒币(≈${$.JdMsScore / 1000}元)\n`; + message += "" + `京东秒杀:${$.JdMsScore}秒秒币(≈${$.JdMsScore / 1000}元)\n` +"\n\n" + } + if($.JdFarmProdName != ""){ + if($.JdtreeEnergy!=0){ + ReturnMessage+=`东东农场:${$.JdFarmProdName},进度${(($.JdtreeEnergy / $.JdtreeTotalEnergy) * 100).toFixed(2)}%`; + message += "" + `东东农场:${$.JdFarmProdName},进度${(($.JdtreeEnergy / $.JdtreeTotalEnergy) * 100).toFixed(2)}%` +"\n\n" + if($.JdwaterD!='Infinity' && $.JdwaterD!='-Infinity'){ + ReturnMessage+=`,${$.JdwaterD === 1 ? '明天' : $.JdwaterD === 2 ? '后天' : $.JdwaterD + '天后'}可兑🍉\n`; + message += "" + `,${$.JdwaterD === 1 ? '明天' : $.JdwaterD === 2 ? '后天' : $.JdwaterD + '天后'}可兑🍉\n` +"\n\n" + } else { + ReturnMessage+=`\n`; + } + } else { + ReturnMessage+=`东东农场:${$.JdFarmProdName}\n`; + message += "" +`东东农场:${$.JdFarmProdName}\n` +"\n\n" + } + } + if ($.jxFactoryInfo) { + ReturnMessage += `京喜工厂:${$.jxFactoryInfo}🏭\n` + message += "" + `京喜工厂:${$.jxFactoryInfo}🏭\n` +"\n\n" + } + if ($.ddFactoryInfo) { + ReturnMessage += `东东工厂:${$.ddFactoryInfo}🏭\n` + message += "" + `东东工厂:${$.ddFactoryInfo}🏭\n` +"\n\n" + } + + const response = await await PetRequest('energyCollect'); + const initPetTownRes = await PetRequest('initPetTown'); + if (initPetTownRes.code === '0' && initPetTownRes.resultCode === '0' && initPetTownRes.message === 'success') { + $.petInfo = initPetTownRes.result; + if (response.resultCode === '0') { + ReturnMessage += `东东萌宠:${$.petInfo.goodsInfo.goodsName},`; + ReturnMessage += `勋章${response.result.medalNum}/${response.result.medalNum+response.result.needCollectMedalNum}块(${response.result.medalPercent}%)\n`; + //ReturnMessage += ` 已有${response.result.medalNum}块勋章,还需${response.result.needCollectMedalNum}块\n`; + message += "" +`东东萌宠:${$.petInfo.goodsInfo.goodsName},` +"\n\n" + message += "" + `勋章${response.result.medalNum}/${response.result.medalNum+response.result.needCollectMedalNum}块(${response.result.medalPercent}%)\n` +"\n\n" + + } + } + ReturnMessage+=`🧧🧧🧧🧧红包明细🧧🧧🧧🧧`; + message += "" +`🧧🧧🧧🧧红包明细🧧🧧🧧🧧` + "\n\n" + ReturnMessage+=`${$.message}\n\n`; + message += "" + `${$.message}\n\n` +"\n\n" + allMessage+=ReturnMessage; + $.msg($.name, '', ReturnMessage , {"open-url": "https://bean.m.jd.com/beanDetail/index.action?resourceValue=bean"}); +} +async function bean() { + // console.log(`北京时间零点时间戳:${parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000}`); + // console.log(`北京时间2020-10-28 06:16:05::${new Date("2020/10/28 06:16:05+08:00").getTime()}`) + // 不管哪个时区。得到都是当前时刻北京时间的时间戳 new Date().getTime() + new Date().getTimezoneOffset()*60*1000 + 8*60*60*1000 + + //前一天的0:0:0时间戳 + const tm = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000 - (24 * 60 * 60 * 1000); + // 今天0:0:0时间戳 + const tm1 = parseInt((Date.now() + 28800000) / 86400000) * 86400000 - 28800000; + let page = 1, t = 0, yesterdayArr = [], todayArr = []; + do { + let response = await getJingBeanBalanceDetail(page); + // console.log(`第${page}页: ${JSON.stringify(response)}`); + if (response && response.code === "0") { + page++; + let detailList = response.detailList; + if (detailList && detailList.length > 0) { + for (let item of detailList) { + const date = item.date.replace(/-/g, '/') + "+08:00"; + if (new Date(date).getTime() >= tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + todayArr.push(item); + } else if (tm <= new Date(date).getTime() && new Date(date).getTime() < tm1 && (!item['eventMassage'].includes("退还") && !item['eventMassage'].includes('扣赠'))) { + //昨日的 + yesterdayArr.push(item); + } else if (tm > new Date(date).getTime()) { + //前天的 + t = 1; + break; + } + } + } else { + //$.errorMsg = `数据异常`; + //$.msg($.name, ``, `账号${$.index}:${$.nickName}\n${$.errorMsg}`); + t = 1; + } + } else if (response && response.code === "3") { + console.log(`cookie已过期,或者填写不规范,跳出`) + t = 1; + } else { + console.log(`未知情况:${JSON.stringify(response)}`); + console.log(`未知情况,跳出`) + t = 1; + } + } while (t === 0); + for (let item of yesterdayArr) { + if (Number(item.amount) > 0) { + $.incomeBean += Number(item.amount); + } else if (Number(item.amount) < 0) { + $.expenseBean += Number(item.amount); + } + } + for (let item of todayArr) { + if (Number(item.amount) > 0) { + $.todayIncomeBean += Number(item.amount); + } + } + await queryexpirejingdou();//过期京豆 + await redPacket();//过期红包 + // console.log(`昨日收入:${$.incomeBean}个京豆 🐶`); + // console.log(`昨日支出:${$.expenseBean}个京豆 🐶`) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + url: "https://me-api.jd.com/user_new/info/GetJDUserInfoUnion", + headers: { + Host: "me-api.jd.com", + Accept: "*/*", + Connection: "keep-alive", + Cookie: cookie, + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Accept-Language": "zh-cn", + "Referer": "https://home.m.jd.com/myJd/newhome.action?sceneval=2&ufc=&", + "Accept-Encoding": "gzip, deflate, br" + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + $.logErr(err) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === "1001") { + $.isLogin = false; //cookie过期 + return; + } + if (data['retcode'] === "0" && data.data && data.data.hasOwnProperty("userInfo")) { + $.nickName = data.data.userInfo.baseInfo.nickname; + } + if (data['retcode'] === '0' && data.data && data.data['assetInfo']) { + $.beanCount = data.data && data.data['assetInfo']['beanNum']; + } + } else { + $.log('京东服务器返回空数据'); + } + } + } catch (e) { + $.logErr(e) + } finally { + resolve(); + } + }) + }) +} +function getJingBeanBalanceDetail(page) { + return new Promise(async resolve => { + const options = { + "url": `https://api.m.jd.com/client.action?functionId=getJingBeanBalanceDetail`, + "body": `body=${escape(JSON.stringify({"pageSize": "20", "page": page.toString()}))}&appid=ld`, + "headers": { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + // console.log(data) + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function queryexpirejingdou() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/activep3/singjd/queryexpirejingdou?_=${Date.now()}&g_login_type=1&sceneval=2`, + "headers": { + "Accept": "*/*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Host": "wq.jd.com", + "Referer": "https://wqs.jd.com/promote/201801/bean/mybean.html", + "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Mobile/15E148 Safari/604.1" + } + } + $.expirejingdou = 0; + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + // console.log(data) + data = JSON.parse(data.slice(23, -13)); + // console.log(data) + if (data.ret === 0) { + data['expirejingdou'].map(item => { + console.log(`${timeFormat(item['time'] * 1000)}日过期京豆:${item['expireamount']}\n`); + }) + $.expirejingdou = data['expirejingdou'][0]['expireamount']; + // if ($.expirejingdou > 0) { + // $.message += `\n今日将过期:${$.expirejingdou}京豆 🐶`; + // } + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function redPacket() { + return new Promise(async resolve => { + const options = { + "url": `https://m.jingxi.com/user/info/QueryUserRedEnvelopesV2?type=1&orgFlag=JD_PinGou_New&page=1&cashRedType=1&redBalanceFlag=1&channel=1&_=${+new Date()}&sceneval=2&g_login_type=1&g_ty=ls`, + "headers": { + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://st.jingxi.com/my/redpacket.shtml?newPg=App&jxsid=16156262265849285961', + 'Accept-Encoding': 'gzip, deflate, br', + "Cookie": cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.get(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data).data + $.jxRed = 0, $.jsRed = 0, $.jdRed = 0, $.jdhRed = 0, $.jxRedExpire = 0, $.jsRedExpire = 0, $.jdRedExpire = 0, $.jdhRedExpire = 0; + let t = new Date() + t.setDate(t.getDate() + 1) + t.setHours(0, 0, 0, 0) + t = parseInt((t - 1) / 1000) + for (let vo of data.useRedInfo.redList || []) { + if (vo.orgLimitStr && vo.orgLimitStr.includes("京喜")) { + $.jxRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jxRedExpire += parseFloat(vo.balance) + } + } else if (vo.activityName.includes("极速版")) { + $.jsRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jsRedExpire += parseFloat(vo.balance) + } + } else if (vo.orgLimitStr && vo.orgLimitStr.includes("京东健康")) { + $.jdhRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdhRedExpire += parseFloat(vo.balance) + } + } else { + $.jdRed += parseFloat(vo.balance) + if (vo['endTime'] === t) { + $.jdRedExpire += parseFloat(vo.balance) + } + } + } + $.jxRed = $.jxRed.toFixed(2) + $.jsRed = $.jsRed.toFixed(2) + $.jdRed = $.jdRed.toFixed(2) + $.jdhRed = $.jdhRed.toFixed(2) + $.balance = data.balance + $.expiredBalance = ($.jxRedExpire + $.jsRedExpire + $.jdRedExpire).toFixed(2) + // $.message += `\n当前总红包:${$.balance}(今日总过期${$.expiredBalance})元 🧧\n京喜红包:${$.jxRed}(今日将过期${$.jxRedExpire.toFixed(2)})元 🧧\n极速红包:${$.jsRed}(今日将过期${$.jsRedExpire.toFixed(2)})元 🧧\n京东红包:${$.jdRed}(今日将过期${$.jdRedExpire.toFixed(2)})元 🧧\n健康红包:${$.jdhRed}(今日将过期${$.jdhRedExpire.toFixed(2)})元 🧧`; + + $.message += "" + `【当前总红包】:${$.balance}( 今日总过期${$.expiredBalance} )元 🧧` +"\n\n" + $.message += "" + `【京喜红包】:${$.jxRed}( 今日将过期${$.jxRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【极速红包】:${$.jsRed}( 今日将过期${$.jsRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【京东红包】:${$.jdRed}( 今日将过期${$.jdRedExpire.toFixed(2)} )元 🧧` +"\n\n" + $.message += "" + `【健康红包】:${$.jdhRed}( 今日将过期${$.jdhRedExpire.toFixed(2)} )元 🧧` +"\n\n" + + + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getJdZZ() { + return new Promise(resolve => { + $.get(taskJDZZUrl("interactTaskIndex"), async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JdzzNum = data.data.totalNum + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function taskJDZZUrl(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=9.1.0`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'http://wq.jd.com/wxapp/pages/hd-interaction/index/index', + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Accept-Language': 'zh-cn', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +function getMs() { + return new Promise(resolve => { + $.post(taskMsPostUrl('homePageV2', {}, 'appid=SecKill2020'), (err, resp, data) => { + try { + if (err) { + console.log(`${err},${jsonParse(resp.body)['message']}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data) + if (data.code === 2041) { + $.JdMsScore = data.result.assignment.assignmentPoints || 0 + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + + +function taskMsPostUrl(function_id, body = {}, extra = '', function_id2) { + let url = `${JD_API_HOST}`; + if (function_id2) { + url += `?functionId=${function_id2}`; + } + return { + url, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=1.0.0&${extra}`, + headers: { + "Cookie": cookie, + "origin": "https://h5.m.jd.com", + "referer": "https://h5.m.jd.com/babelDiy/Zeus/2NUvze9e1uWf4amBhe1AV6ynmSuH/index.html", + 'Content-Type': 'application/x-www-form-urlencoded', + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + } + } +} + +async function getjdfruit() { + return new Promise(resolve => { + const option = { + url: `${JD_API_HOST}?functionId=initForFarm`, + body: `body=${escape(JSON.stringify({"version":4}))}&appid=wh5&clientVersion=9.1.0`, + headers: { + "accept": "*/*", + "accept-encoding": "gzip, deflate, br", + "accept-language": "zh-CN,zh;q=0.9", + "cache-control": "no-cache", + "cookie": cookie, + "origin": "https://home.m.jd.com", + "pragma": "no-cache", + "referer": "https://home.m.jd.com/myJd/newhome.action", + "sec-fetch-dest": "empty", + "sec-fetch-mode": "cors", + "sec-fetch-site": "same-site", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + "Content-Type": "application/x-www-form-urlencoded" + }, + timeout: 10000, + }; + $.post(option, (err, resp, data) => { + try { + if (err) { + console.log('\n东东农场: API查询请求失败 ‼️‼️'); + console.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.farmInfo = JSON.parse(data) + if ($.farmInfo.farmUserPro) { + $.JdFarmProdName=$.farmInfo.farmUserPro.name; + $.JdtreeEnergy=$.farmInfo.farmUserPro.treeEnergy; + $.JdtreeTotalEnergy=$.farmInfo.farmUserPro.treeTotalEnergy; + + let waterEveryDayT = $.JDwaterEveryDayT; + let waterTotalT = ($.farmInfo.farmUserPro.treeTotalEnergy - $.farmInfo.farmUserPro.treeEnergy - $.farmInfo.farmUserPro.totalEnergy) / 10;//一共还需浇多少次水 + let waterD = Math.ceil(waterTotalT / waterEveryDayT); + + $.JdwaterTotalT = waterTotalT; + $.JdwaterD = waterD; + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function jdfruitRequest(function_id, body = {}, timeout = 1000){ + return new Promise(resolve => { + setTimeout(() => { + $.get(taskfruitUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n东东农场: API查询请求失败 ‼️‼️') + console.log(JSON.stringify(err)); + console.log(`function_id:${function_id}`) + $.logErr(err); + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JDwaterEveryDayT = data.totalWaterTaskInit.totalWaterTaskTimes; + } + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }, timeout) + }) +} + + +async function PetRequest(function_id, body = {}) { + await $.wait(3000); + return new Promise((resolve, reject) => { + $.post(taskPetUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + console.log('\n东东萌宠: API查询请求失败 ‼️‼️'); + console.log(JSON.stringify(err)); + $.logErr(err); + } else { + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data) + } + }) + }) +} +function taskPetUrl(function_id, body = {}) { + body["version"] = 2; + body["channel"] = 'app'; + return { + url: `${JD_API_HOST}?functionId=${function_id}`, + body: `body=${escape(JSON.stringify(body))}&appid=wh5&loginWQBiz=pet-town&clientVersion=9.0.4`, + headers: { + 'Cookie': cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + } + }; +} + +function taskfruitUrl(function_id, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&body=${escape(JSON.stringify(body))}`, + headers: { + Cookie: cookie, + UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + }, + timeout: 10000, + } +} + +function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + console.log(e); + console.log(`京东服务器访问数据为空,请检查自身设备网络情况`); + return false; + } +} + +function cash() { + return new Promise(resolve => { + $.get(taskcashUrl('MyAssetsService.execute', + {"method": "userCashRecord", "data": {"channel": 1, "pageNum": 1, "pageSize": 20}}), + async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.JDtotalcash = data.data.goldBalance ; + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +var __Oxb24bc = ["lite-android&", "stringify", "&android&3.1.0&", "&", "&846c4c32dae910ef", "12aea658f76e453faf803d15c40a72e0", "isNode", "crypto-js", "", "api?functionId=", "&body=", "&appid=lite-android&client=android&uuid=846c4c32dae910ef&clientVersion=3.1.0&t=", "&sign=", "api.m.jd.com", "*/*", "RN", "JDMobileLite/3.1.0 (iPad; iOS 14.4; Scale/2.00)", "zh-Hans-CN;q=1, ja-CN;q=0.9", "undefined", "log", "", "", "", "", "jsjia", "mi.com"]; + +function taskcashUrl(_0x7683x2, _0x7683x3 = {}) { + let _0x7683x4 = +new Date(); + let _0x7683x5 = `${__Oxb24bc[0x0]}${JSON[__Oxb24bc[0x1]](_0x7683x3)}${__Oxb24bc[0x2]}${_0x7683x2}${__Oxb24bc[0x3]}${_0x7683x4}${__Oxb24bc[0x4]}`; + let _0x7683x6 = __Oxb24bc[0x5]; + const _0x7683x7 = $[__Oxb24bc[0x6]]() ? require(__Oxb24bc[0x7]) : $.CryptoJS; + let _0x7683x8 = _0x7683x7.HmacSHA256(_0x7683x5, _0x7683x6).toString(); + return { + url: `${__Oxb24bc[0x8]}${JD_API_HOST}${__Oxb24bc[0x9]}${_0x7683x2}${__Oxb24bc[0xa]}${escape(JSON[__Oxb24bc[0x1]](_0x7683x3))}${__Oxb24bc[0xb]}${_0x7683x4}${__Oxb24bc[0xc]}${_0x7683x8}${__Oxb24bc[0x8]}`, + headers: { + 'Host': __Oxb24bc[0xd], + 'accept': __Oxb24bc[0xe], + 'kernelplatform': __Oxb24bc[0xf], + 'user-agent': __Oxb24bc[0x10], + 'accept-language': __Oxb24bc[0x11], + 'Cookie': cookie + } + } +}(function(_0x7683x9, _0x7683xa, _0x7683xb, _0x7683xc, _0x7683xd, _0x7683xe) { + _0x7683xe = __Oxb24bc[0x12]; + _0x7683xc = function(_0x7683xf) { + if (typeof alert !== _0x7683xe) { + alert(_0x7683xf) + }; + if (typeof console !== _0x7683xe) { + console[__Oxb24bc[0x13]](_0x7683xf) + } + }; + _0x7683xb = function(_0x7683x7, _0x7683x9) { + return _0x7683x7 + _0x7683x9 + }; + _0x7683xd = _0x7683xb(__Oxb24bc[0x14], _0x7683xb(_0x7683xb(__Oxb24bc[0x15], __Oxb24bc[0x16]), __Oxb24bc[0x17])); + try { + _0x7683x9 = __encode; + if (!(typeof _0x7683x9 !== _0x7683xe && _0x7683x9 === _0x7683xb(__Oxb24bc[0x18], __Oxb24bc[0x19]))) { + _0x7683xc(_0x7683xd) + } + } catch (e) { + _0x7683xc(_0x7683xd) + } +})({}) + +async function JxmcGetRequest() { + let url = ``; + let myRequest = ``; + url = `https://m.jingxi.com/jxmc/queryservice/GetHomePageInfo?channel=7&sceneid=1001&activeid=null&activekey=null&isgift=1&isquerypicksite=1&_stk=channel%2Csceneid&_ste=1`; + url += `&h5st=${decrypt(Date.now(), '', '', url)}&_=${Date.now() + 2}&sceneval=2&g_login_type=1&callback=jsonpCBK${String.fromCharCode(Math.floor(Math.random() * 26) + "A".charCodeAt(0))}&g_ty=ls`; + myRequest = getGetRequest(`GetHomePageInfo`, url); + + + return new Promise(async resolve => { + $.get(myRequest, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`API请求失败,请检查网路重试`) + $.runFlag = false; + console.log(`请求失败`) + } else { + data = JSON.parse(data.match(new RegExp(/jsonpCBK.?\((.*);*/))[1]); + if (data.ret === 0) { + $.JDEggcnt=data.data.eggcnt; + } + } + } catch (e) { + console.log(data); + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +// 惊喜工厂信息查询 +function getJxFactory() { + return new Promise(async resolve => { + let infoMsg = ""; + await $.get(jxTaskurl('userinfo/GetUserInfo', `pin=&sharePin=&shareType=&materialTuanPin=&materialTuanId=&source=`, '_time,materialTuanId,materialTuanPin,pin,sharePin,shareType,source,zone'), async (err, resp, data) => { + try { + if (err) { + $.jxFactoryInfo = "查询失败!"; + //console.log("jx工厂查询失败" + err) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['ret'] === 0) { + data = data['data']; + $.unActive = true;//标记是否开启了京喜活动或者选购了商品进行生产 + if (data.factoryList && data.productionList) { + const production = data.productionList[0]; + const factory = data.factoryList[0]; + //const productionStage = data.productionStage; + $.commodityDimId = production.commodityDimId; + // subTitle = data.user.pin; + await GetCommodityDetails();//获取已选购的商品信息 + infoMsg = `${$.jxProductName} ,进度:${((production.investedElectric / production.needElectric) * 100).toFixed(2)}%`; + if (production.investedElectric >= production.needElectric) { + if (production['exchangeStatus'] === 1) { + infoMsg = `${$.productName} ,已经可兑换,请手动兑换`; + } + if (production['exchangeStatus'] === 3) { + if (new Date().getHours() === 9) { + infoMsg = `${$.productName} ,兑换已超时,请选择新商品进行制造`; + } + } + // await exchangeProNotify() + } else { + infoMsg += ` ,预计:${((production.needElectric - production.investedElectric) / (2 * 60 * 60 * 24)).toFixed(2)}天可兑换` + } + if (production.status === 3) { + infoMsg = "${$.productName} ,已经超时失效, 请选择新商品进行制造" + } + } else { + $.unActive = false;//标记是否开启了京喜活动或者选购了商品进行生产 + if (!data.factoryList) { + infoMsg = "当前未开始生产商品,请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动" + // $.msg($.name, '【提示】', `京东账号${$.index}[${$.nickName}]京喜工厂活动未开始\n请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动`); + } else if (data.factoryList && !data.productionList) { + infoMsg = "当前未开始生产商品,请手动去京东APP->游戏与互动->查看更多->京喜工厂 开启活动" + } + } + } + } else { + console.log(`GetUserInfo异常:${JSON.stringify(data)}`) + } + } + $.jxFactoryInfo = infoMsg; + // console.log(infoMsg); + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + } + ) +} + +// 惊喜的Taskurl +function jxTaskurl(functionId, body = '', stk) { + let url = `https://m.jingxi.com/dreamfactory/${functionId}?zone=dream_factory&${body}&sceneval=2&g_login_type=1&_time=${Date.now()}&_=${Date.now() + 2}&_ste=1` + url += `&h5st=${decrypt(Date.now(), stk, '', url)}` + if (stk) { + url += `&_stk=${encodeURIComponent(stk)}`; + } + return { + url, + headers: { + 'Cookie': cookie, + 'Host': 'm.jingxi.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'User-Agent': functionId === 'AssistFriend' ? "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" : 'jdpingou', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://wqsd.jd.com/pingou/dream_factory/index.html', + 'Accept-Encoding': 'gzip, deflate, br', + } + } +} + +//惊喜查询当前生产的商品名称 +function GetCommodityDetails() { + return new Promise(async resolve => { + // const url = `/dreamfactory/diminfo/GetCommodityDetails?zone=dream_factory&sceneval=2&g_login_type=1&commodityId=${$.commodityDimId}`; + $.get(jxTaskurl('diminfo/GetCommodityDetails', `commodityId=${$.commodityDimId}`, `_time,commodityId,zone`), (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data['ret'] === 0) { + data = data['data']; + $.jxProductName = data['commodityList'][0].name; + } else { + console.log(`GetCommodityDetails异常:${JSON.stringify(data)}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +// 东东工厂信息查询 +async function getDdFactoryInfo() { + // 当心仪的商品存在,并且收集起来的电量满足当前商品所需,就投入 + let infoMsg = ""; + return new Promise(resolve => { + $.post(ddFactoryTaskUrl('jdfactory_getHomeData'), async (err, resp, data) => { + try { + if (err) { + $.ddFactoryInfo = "获取失败!" + /*console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`)*/ + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data.bizCode === 0) { + // $.newUser = data.data.result.newUser; + //let wantProduct = $.isNode() ? (process.env.FACTORAY_WANTPRODUCT_NAME ? process.env.FACTORAY_WANTPRODUCT_NAME : wantProduct) : ($.getdata('FACTORAY_WANTPRODUCT_NAME') ? $.getdata('FACTORAY_WANTPRODUCT_NAME') : wantProduct); + if (data.data.result.factoryInfo) { + let { + totalScore, + useScore, + produceScore, + remainScore, + couponCount, + name + } = data.data.result.factoryInfo; + infoMsg = `${name} 剩余${couponCount};电力投入情况 ${useScore}/${totalScore};当前总电力:${remainScore * 1 + useScore * 1} ;完成度:${((remainScore * 1 + useScore * 1) / (totalScore * 1)).toFixed(2) * 100}%` + + if (((remainScore * 1 + useScore * 1) >= totalScore * 1 + 100000) && (couponCount * 1 > 0)) { + // await jdfactory_addEnergy(); + infoMsg = `${name} ,目前数量:${couponCount},当前总电量为:${remainScore * 1 + useScore * 1},已经可以兑换此商品所需总电量:${totalScore},请🔥速去活动页面查看` + } + + } else { + infoMsg = `当前未选择商品(或未开启活动) , 请到京东APP=>首页=>京东电器=>(底栏)东东工厂 选择商品!` + } + } else { + $.ddFactoryInfo = "获取失败!" + console.log(`异常:${JSON.stringify(data)}`) + } + } + } + $.ddFactoryInfo = infoMsg; + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function ddFactoryTaskUrl(function_id, body = {}, function_id2) { + let url = `${JD_API_HOST}`; + if (function_id2) { + url += `?functionId=${function_id2}`; + } + return { + url, + body: `functionId=${function_id}&body=${escape(JSON.stringify(body))}&client=wh5&clientVersion=1.1.0`, + headers: { + "Accept": "application/json, text/plain, */*", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Content-Type": "application/x-www-form-urlencoded", + "Cookie": cookie, + "Host": "api.m.jd.com", + "Origin": "https://h5.m.jd.com", + "Referer": "https://h5.m.jd.com/babelDiy/Zeus/2uSsV2wHEkySvompfjB43nuKkcHp/index.html", + "User-Agent": "jdapp;iPhone;9.3.4;14.3;88732f840b77821b345bf07fd71f609e6ff12f43;network/4g;ADID/1C141FDD-C62F-425B-8033-9AAB7E4AE6A3;supportApplePay/0;hasUPPay/0;hasOCPay/0;model/iPhone11,8;addressid/2005183373;supportBestPay/0;appBuild/167502;jdSupportDarkMode/0;pv/414.19;apprpd/Babel_Native;ref/TTTChannelViewContoller;psq/5;ads/;psn/88732f840b77821b345bf07fd71f609e6ff12f43|1701;jdv/0|iosapp|t_335139774|appshare|CopyURL|1610885480412|1610885486;adk/;app_device/IOS;pap/JA2015_311210|9.3.4|IOS 14.3;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1", + }, + timeout: 10000, + } +} +function randomString(e) { + e = e || 32; + let t = "0123456789abcdef", a = t.length, n = ""; + for (let i = 0; i < e; i++) + n += t.charAt(Math.floor(Math.random() * a)); + return n +} + +function getGetRequest(type, url) { + UA = `jdpingou;iPhone;4.13.0;14.4.2;${randomString(40)};network/wifi;model/iPhone10,2;appBuild/100609;ADID/00000000-0000-0000-0000-000000000000;supportApplePay/1;hasUPPay/0;pushNoticeIsOpen/1;hasOCPay/0;supportBestPay/0;session/${Math.random * 98 + 1};pap/JA2019_3111789;brand/apple;supportJDSHWK/1;Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148` + + const method = `GET`; + let headers = { + 'Origin': `https://st.jingxi.com`, + 'Cookie': cookie, + 'Connection': `keep-alive`, + 'Accept': `application/json`, + 'Referer': `https://st.jingxi.com/pingou/jxmc/index.html`, + 'Host': `m.jingxi.com`, + 'User-Agent': UA, + 'Accept-Encoding': `gzip, deflate, br`, + 'Accept-Language': `zh-cn` + }; + return {url: url, method: method, headers: headers}; +} + + +Date.prototype.Format = function (fmt) { + var e, + n = this, d = fmt, l = { + "M+": n.getMonth() + 1, + "d+": n.getDate(), + "D+": n.getDate(), + "h+": n.getHours(), + "H+": n.getHours(), + "m+": n.getMinutes(), + "s+": n.getSeconds(), + "w+": n.getDay(), + "q+": Math.floor((n.getMonth() + 3) / 3), + "S+": n.getMilliseconds() + }; + /(y+)/i.test(d) && (d = d.replace(RegExp.$1, "".concat(n.getFullYear()).substr(4 - RegExp.$1.length))); + for (var k in l) { + if (new RegExp("(".concat(k, ")")).test(d)) { + var t, a = "S+" === k ? "000" : "00"; + d = d.replace(RegExp.$1, 1 == RegExp.$1.length ? l[k] : ("".concat(a) + l[k]).substr("".concat(l[k]).length)) + } + } + return d; +} + +function decrypt(time, stk, type, url) { + stk = stk || (url ? getJxmcUrlData(url, '_stk') : '') + if (stk) { + const timestamp = new Date(time).Format("yyyyMMddhhmmssSSS"); + let hash1 = ''; + if ($.fingerprint && $.Jxmctoken && $.enCryptMethodJD) { + hash1 = $.enCryptMethodJD($.Jxmctoken, $.fingerprint.toString(), timestamp.toString(), $.appId.toString(), $.CryptoJS).toString($.CryptoJS.enc.Hex); + } else { + const random = '5gkjB6SpmC9s'; + $.Jxmctoken = `tk01wcdf61cb3a8nYUtHcmhSUFFCfddDPRvKvYaMjHkxo6Aj7dhzO+GXGFa9nPXfcgT+mULoF1b1YIS1ghvSlbwhE0Xc`; + $.fingerprint = 5287160221454703; + const str = `${$.Jxmctoken}${$.fingerprint}${timestamp}${$.appId}${random}`; + hash1 = $.CryptoJS.SHA512(str, $.Jxmctoken).toString($.CryptoJS.enc.Hex); + } + let st = ''; + stk.split(',').map((item, index) => { + st += `${item}:${getJxmcUrlData(url, item)}${index === stk.split(',').length - 1 ? '' : '&'}`; + }) + const hash2 = $.CryptoJS.HmacSHA256(st, hash1.toString()).toString($.CryptoJS.enc.Hex); + return encodeURIComponent(["".concat(timestamp.toString()), "".concat($.fingerprint.toString()), "".concat($.appId.toString()), "".concat($.Jxmctoken), "".concat(hash2)].join(";")) + } else { + return '20210318144213808;8277529360925161;10001;tk01w952a1b73a8nU0luMGtBanZTHCgj0KFVwDa4n5pJ95T/5bxO/m54p4MtgVEwKNev1u/BUjrpWAUMZPW0Kz2RWP8v;86054c036fe3bf0991bd9a9da1a8d44dd130c6508602215e50bb1e385326779d' + } +} + +async function requestAlgo() { + $.fingerprint = await generateFp(); + $.appId = 10028; + const options = { + "url": `https://cactus.jd.com/request_algo?g_ty=ajax`, + "headers": { + 'Authority': 'cactus.jd.com', + 'Pragma': 'no-cache', + 'Cache-Control': 'no-cache', + 'Accept': 'application/json', + 'User-Agent':$.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + //'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1', + 'Content-Type': 'application/json', + 'Origin': 'https://st.jingxi.com', + 'Sec-Fetch-Site': 'cross-site', + 'Sec-Fetch-Mode': 'cors', + 'Sec-Fetch-Dest': 'empty', + 'Referer': 'https://st.jingxi.com/', + 'Accept-Language': 'zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7' + }, + 'body': JSON.stringify({ + "version": "1.0", + "fp": $.fingerprint, + "appId": $.appId.toString(), + "timestamp": Date.now(), + "platform": "web", + "expandParams": "" + }) + } + new Promise(async resolve => { + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`request_algo 签名参数API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['status'] === 200) { + $.Jxmctoken = data.data.result.tk; + let enCryptMethodJDString = data.data.result.algo; + // if (enCryptMethodJDString) $.enCryptMethodJD = new Function(`return ${enCryptMethodJDString}`)(); + eval(enCryptMethodJDString+';$.enCryptMethodJD=test'); + } else { + console.log('request_algo 签名参数API请求失败:') + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function generateFp() { + let e = "0123456789"; + let a = 13; + let i = ''; + for (; a--;) + i += e[Math.random() * e.length | 0]; + return (i + Date.now()).slice(0, 16) +} + +function getJxmcUrlData(url, name) { + if (typeof URL !== "undefined") { + let urls = new URL(url); + let data = urls.searchParams.get(name); + return data ? data : ''; + } else { + const query = url.match(/\?.*/)[0].substring(1) + const vars = query.split('&') + for (let i = 0; i < vars.length; i++) { + const pair = vars[i].split('=') + if (pair[0] === name) { + return vars[i].substr(vars[i].indexOf('=') + 1); + } + } + return '' + } +} + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} +function timeFormat(time) { + let date; + if (time) { + date = new Date(time) + } else { + date = new Date(); + } + return date.getFullYear() + '-' + ((date.getMonth() + 1) >= 10 ? (date.getMonth() + 1) : '0' + (date.getMonth() + 1)) + '-' + (date.getDate() >= 10 ? date.getDate() : '0' + date.getDate()); +} + + +// prettier-ignore +function Env(t,e){class s{constructor(t){this.env=t}send(t,e="GET"){t="string"==typeof t?{url:t}:t;let s=this.get;return"POST"===e&&(s=this.post),new Promise((e,i)=>{s.call(this,t,(t,s,r)=>{t?i(t):e(s)})})}get(t){return this.send.call(this.env,t)}post(t){return this.send.call(this.env,t,"POST")}}return new class{constructor(t,e){this.name=t,this.http=new s(this),this.data=null,this.dataFile="box.dat",this.logs=[],this.isMute=!1,this.isNeedRewrite=!1,this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,e),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}toObj(t,e=null){try{return JSON.parse(t)}catch{return e}}toStr(t,e=null){try{return JSON.stringify(t)}catch{return e}}getjson(t,e){let s=e;const i=this.getdata(t);if(i)try{s=JSON.parse(this.getdata(t))}catch{}return s}setjson(t,e){try{return this.setdata(JSON.stringify(t),e)}catch{return!1}}getScript(t){return new Promise(e=>{this.get({url:t},(t,s,i)=>e(i))})}runScript(t,e){return new Promise(s=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let r=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");r=r?1*r:20,r=e&&e.timeout?e.timeout:r;const[o,h]=i.split("@"),n={url:`http://${h}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:r},headers:{"X-Key":o,Accept:"*/*"}};this.post(n,(t,e,i)=>s(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e);if(!s&&!i)return{};{const i=s?t:e;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),e=this.path.resolve(process.cwd(),this.dataFile),s=this.fs.existsSync(t),i=!s&&this.fs.existsSync(e),r=JSON.stringify(this.data);s?this.fs.writeFileSync(t,r):i?this.fs.writeFileSync(e,r):this.fs.writeFileSync(t,r)}}lodash_get(t,e,s){const i=e.replace(/\[(\d+)\]/g,".$1").split(".");let r=t;for(const t of i)if(r=Object(r)[t],void 0===r)return s;return r}lodash_set(t,e,s){return Object(t)!==t?t:(Array.isArray(e)||(e=e.toString().match(/[^.[\]]+/g)||[]),e.slice(0,-1).reduce((t,s,i)=>Object(t[s])===t[s]?t[s]:t[s]=Math.abs(e[i+1])>>0==+e[i+1]?[]:{},t)[e[e.length-1]]=s,t)}getdata(t){let e=this.getval(t);if(/^@/.test(t)){const[,s,i]=/^@(.*?)\.(.*?)$/.exec(t),r=s?this.getval(s):"";if(r)try{const t=JSON.parse(r);e=t?this.lodash_get(t,i,""):e}catch(t){e=""}}return e}setdata(t,e){let s=!1;if(/^@/.test(e)){const[,i,r]=/^@(.*?)\.(.*?)$/.exec(e),o=this.getval(i),h=i?"null"===o?null:o||"{}":"{}";try{const e=JSON.parse(h);this.lodash_set(e,r,t),s=this.setval(JSON.stringify(e),i)}catch(e){const o={};this.lodash_set(o,r,t),s=this.setval(JSON.stringify(o),i)}}else s=this.setval(t,e);return s}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,e){return this.isSurge()||this.isLoon()?$persistentStore.write(t,e):this.isQuanX()?$prefs.setValueForKey(t,e):this.isNode()?(this.data=this.loaddata(),this.data[e]=t,this.writedata(),!0):this.data&&this.data[e]||null}initGotEnv(t){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,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,e=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?(this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.get(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)})):this.isQuanX()?(this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t))):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,e)=>{try{if(t.headers["set-cookie"]){const s=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();s&&this.ckjar.setCookieSync(s,null),e.cookieJar=this.ckjar}}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)}))}post(t,e=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),t.headers&&delete t.headers["Content-Length"],this.isSurge()||this.isLoon())this.isSurge()&&this.isNeedRewrite&&(t.headers=t.headers||{},Object.assign(t.headers,{"X-Surge-Skip-Scripting":!1})),$httpClient.post(t,(t,s,i)=>{!t&&s&&(s.body=i,s.statusCode=s.status),e(t,s,i)});else if(this.isQuanX())t.method="POST",this.isNeedRewrite&&(t.opts=t.opts||{},Object.assign(t.opts,{hints:!1})),$task.fetch(t).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>e(t));else if(this.isNode()){this.initGotEnv(t);const{url:s,...i}=t;this.got.post(s,i).then(t=>{const{statusCode:s,statusCode:i,headers:r,body:o}=t;e(null,{status:s,statusCode:i,headers:r,body:o},o)},t=>{const{message:s,response:i}=t;e(s,i,i&&i.body)})}}time(t,e=null){const s=e?new Date(e):new Date;let i={"M+":s.getMonth()+1,"d+":s.getDate(),"H+":s.getHours(),"m+":s.getMinutes(),"s+":s.getSeconds(),"q+":Math.floor((s.getMonth()+3)/3),S:s.getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,(s.getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in i)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?i[e]:("00"+i[e]).substr((""+i[e]).length)));return t}msg(e=t,s="",i="",r){const o=t=>{if(!t)return t;if("string"==typeof t)return this.isLoon()?t:this.isQuanX()?{"open-url":t}:this.isSurge()?{url:t}:void 0;if("object"==typeof t){if(this.isLoon()){let e=t.openUrl||t.url||t["open-url"],s=t.mediaUrl||t["media-url"];return{openUrl:e,mediaUrl:s}}if(this.isQuanX()){let e=t["open-url"]||t.url||t.openUrl,s=t["media-url"]||t.mediaUrl;return{"open-url":e,"media-url":s}}if(this.isSurge()){let e=t.url||t.openUrl||t["open-url"];return{url:e}}}};if(this.isMute||(this.isSurge()||this.isLoon()?$notification.post(e,s,i,o(r)):this.isQuanX()&&$notify(e,s,i,o(r))),!this.isMuteLog){let t=["","==============📣系统通知📣=============="];t.push(e),s&&t.push(s),i&&t.push(i),console.log(t.join("\n")),this.logs=this.logs.concat(t)}}log(...t){t.length>0&&(this.logs=[...this.logs,...t]),console.log(t.join(this.logSeparator))}logErr(t,e){const s=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();s?this.log("",`❗️${this.name}, 错误!`,t.stack):this.log("",`❗️${this.name}, 错误!`,t)}wait(t){return new Promise(e=>setTimeout(e,t))}done(t={}){const e=(new Date).getTime(),s=(e-this.startTime)/1e3;this.log("",`🔔${this.name}, 结束! 🕛 ${s} 秒`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,e)} + + +//我加的函数 +function postToDingTalk(messgae) { + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"资产变动", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} diff --git a/src/main/resources/test_pet.js b/src/main/resources/test_pet.js new file mode 100644 index 0000000..2b9dec9 --- /dev/null +++ b/src/main/resources/test_pet.js @@ -0,0 +1,709 @@ +let cookiesArr = [], cookie = '', jdPetShareArr = [], isBox = false, notify, newShareCodes, allMessage = ''; +//助力好友分享码(最多5个,否则后面的助力失败),原因:动动农场每人每天只有四次助力机会 +//此此内容是IOS用户下载脚本到本地使用,填写互助码的地方,同一动动账号的好友互助码请使用@符号隔开。 +//下面给出两个账号的填写示例(iOS只支持2个动动账号) +let shareCodes = [ // IOS本地脚本用户这个列表填入你要助力的好友的shareCode +] +let message = "", subTitle = '', option = {}; +let jdNotify = false;//是否关闭通知,false打开通知推送,true关闭通知推送 +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +let goodsUrl = '', taskInfoKey = []; +let randomCount = $.isNode() ? 20 : 5; +!(async () => { + await requireConfig(); + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + + message += "[通知] 动动萌宠 \n\n --- \n\n" + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=([^; ]+)(?=;?)/) && cookie.match(/pt_pin=([^; ]+)(?=;?)/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + await TotalBean(); + that.log(`\n开始【动动账号${$.index}】${$.nickName || $.UserName}\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + subTitle = ''; + goodsUrl = ''; + taskInfoKey = []; + option = {}; + await shareCodesFormat(); + await jdPet(); + } + message += "----\n\n" + } + if ($.isNode() && allMessage && $.ctrTemp) { + await notify.sendNotify(`${$.name}`, `${allMessage}`) + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + message += getPic() + postToDingTalk(message) + taht.log(message) + $.done(); + }) +async function jdPet() { + try { + //查询jd宠物信息 + const initPetTownRes = await request('initPetTown'); + if (initPetTownRes.code === '0' && initPetTownRes.resultCode === '0' && initPetTownRes.message === 'success') { + $.petInfo = initPetTownRes.result; + if ($.petInfo.userStatus === 0) { + // $.msg($.name, '', `【提示】动动账号${$.index}${$.nickName}\n萌宠活动未开启\n请手动去动动APP开启活动\n入口:我的->游戏与互动->查看更多开启`, { "open-url": "openapp.jdmoble://" }); + await slaveHelp();//助力好友 + message = message + ""+ "动动萌宠未开启\n请手动去动动APP开启活动\n入口:我的->游戏与互动->查看更多开启\n\n" + $.log($.name, '', `【提示】动动账号${$.index}${$.nickName}\n萌宠活动未开启\n请手动去动动APP开启活动\n入口:我的->游戏与互动->查看更多开启`); + return + } + if (!$.petInfo.goodsInfo) { + message = message + ""+ "暂未选购新的商品\n\n" + $.msg($.name, '', `【提示】动动账号${$.index}${$.nickName}\n暂未选购新的商品`, { "open-url": "openapp.jdmoble://" }); + if ($.isNode()) await notify.sendNotify(`${$.name} - ${$.index} - ${$.nickName}`, `【提示】动动账号${$.index}${$.nickName}\n暂未选购新的商品`); + return + } + goodsUrl = $.petInfo.goodsInfo && $.petInfo.goodsInfo.goodsUrl; + // option['media-url'] = goodsUrl; + // that.log(`初始化萌宠信息完成: ${JSON.stringify(petInfo)}`); + if ($.petInfo.petStatus === 5) { + await slaveHelp();//可以兑换而没有去兑换,也能继续助力好友 + option['open-url'] = "openApp.jdMobile://"; + message = message + ""+ `【提醒⏰】${$.petInfo.goodsInfo.goodsName}已可领取`, '请去动动APP或微信小程序查看' +"\n\n" + $.msg($.name, `【提醒⏰】${$.petInfo.goodsInfo.goodsName}已可领取`, '请去动动APP或微信小程序查看', option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}奖品已可领取`, `动动账号${$.index} ${$.nickName}\n${$.petInfo.goodsInfo.goodsName}已可领取`); + } + return + } else if ($.petInfo.petStatus === 6) { + await slaveHelp();//已领取红包,但未领养新的,也能继续助力好友 + option['open-url'] = "openApp.jdMobile://"; + message = message + ""+ `【提醒⏰】已领取红包,但未继续领养新的物品`, '请去动动APP或微信小程序继续领养' + "\n\n" + $.msg($.name, `【提醒⏰】已领取红包,但未继续领养新的物品`, '请去动动APP或微信小程序继续领养', option); + if ($.isNode()) { + await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName || $.UserName}奖品已可领取`, `动动账号${$.index} ${$.nickName}\n已领取红包,但未继续领养新的物品`); + } + return + } + that.log(`\n【动动账号${$.index}(${$.UserName})的${$.name}好友互助码】${$.petInfo.shareCode}\n`); + await taskInit(); + if ($.taskInit.resultCode === '9999' || !$.taskInit.result) { + that.log('初始化任务异常, 请稍后再试'); + return + } + $.taskInfo = $.taskInit.result; + + await petSport();//遛弯 + await slaveHelp();//助力好友 + await masterHelpInit();//获取助力的信息 + await doTask();//做日常任务 + await feedPetsAgain();//再次投食 + await energyCollect();//收集好感度 + await showMsg(); + that.log('全部任务完成, 如果帮助到您可以点下🌟STAR鼓励我一下, 明天见~'); + } else if (initPetTownRes.code === '0'){ + that.log(`初始化萌宠失败: ${initPetTownRes.message}`); + } + } catch (e) { + $.logErr(e) + const errMsg = `动动账号${$.index} ${$.nickName || $.UserName}\n任务执行异常,请检查执行日志 ‼️‼️`; + if ($.isNode()) await notify.sendNotify(`${$.name}`, errMsg); + $.msg($.name, '', `动动账号${$.index} ${$.nickName || $.UserName}\n${errMsg}`) + } +} +// 收取所有好感度 +async function energyCollect() { + that.log('开始收取任务奖励好感度'); + let function_id = 'energyCollect'; + const response = await request(function_id); + // that.log(`收取任务奖励好感度完成:${JSON.stringify(response)}`); + if (response.resultCode === '0') { + message = message + ""+ `【第${response.result.medalNum + 1}块勋章完成进度】${response.result.medalPercent}%,还需收集${response.result.needCollectEnergy}好感\n` + "\n\n"; + message = message + ""+ `【已获得勋章】${response.result.medalNum}块,还需收集${response.result.needCollectMedalNum}块即可兑换奖品“${$.petInfo.goodsInfo.goodsName}”\n` + "\n\n"; + } +} +//再次投食 +async function feedPetsAgain() { + const response = await request('initPetTown');//再次初始化萌宠 + if (response.code === '0' && response.resultCode === '0' && response.message === 'success') { + $.petInfo = response.result; + let foodAmount = $.petInfo.foodAmount; //剩余狗粮 + if (foodAmount - 100 >= 10) { + for (let i = 0; i < parseInt((foodAmount - 100) / 10); i++) { + const feedPetRes = await request('feedPets'); + that.log(`投食feedPetRes`); + if (feedPetRes.resultCode == 0 && feedPetRes.code == 0) { + that.log('投食成功') + } + } + const response2 = await request('initPetTown'); + $.petInfo = response2.result; + subTitle = $.petInfo.goodsInfo.goodsName; + // message += `【与爱宠相识】${$.petInfo.meetDays}天\n`; + // message += `【剩余狗粮】${$.petInfo.foodAmount}g\n`; + } else { + that.log("目前剩余狗粮:【" + foodAmount + "】g,不再继续投食,保留部分狗粮用于完成第二天任务"); + subTitle = $.petInfo.goodsInfo && $.petInfo.goodsInfo.goodsName; + // message += `【与爱宠相识】${$.petInfo.meetDays}天\n`; + // message += `【剩余狗粮】${$.petInfo.foodAmount}g\n`; + } + } else { + that.log(`初始化萌宠失败: ${JSON.stringify($.petInfo)}`); + } +} + + +async function doTask() { + const { signInit, threeMealInit, firstFeedInit, feedReachInit, inviteFriendsInit, browseShopsInit, taskList } = $.taskInfo; + for (let item of taskList) { + if ($.taskInfo[item].finished) { + that.log(`任务 ${item} 已完成`) + } + } + //每日签到 + if (signInit && !signInit.finished) { + await signInitFun(); + } + // 首次喂食 + if (firstFeedInit && !firstFeedInit.finished) { + await firstFeedInitFun(); + } + // 三餐 + if (threeMealInit && !threeMealInit.finished) { + if (threeMealInit.timeRange === -1) { + that.log(`未到三餐时间`); + } else { + await threeMealInitFun(); + } + } + if (browseShopsInit && !browseShopsInit.finished) { + await browseShopsInitFun(); + } + let browseSingleShopInitList = []; + taskList.map((item) => { + if (item.indexOf('browseSingleShopInit') > -1) { + browseSingleShopInitList.push(item); + } + }); + // 去逛逛好货会场 + for (let item of browseSingleShopInitList) { + const browseSingleShopInitTask = $.taskInfo[item]; + if (browseSingleShopInitTask && !browseSingleShopInitTask.finished) { + await browseSingleShopInit(browseSingleShopInitTask); + } + } + if (inviteFriendsInit && !inviteFriendsInit.finished) { + await inviteFriendsInitFun(); + } + // 投食10次 + if (feedReachInit && !feedReachInit.finished) { + await feedReachInitFun(); + } +} +// 好友助力信息 +async function masterHelpInit() { + let res = await request('masterHelpInit'); + // that.log(`助力信息: ${JSON.stringify(res)}`); + if (res.code === '0' && res.resultCode === '0') { + if (res.result.masterHelpPeoples && res.result.masterHelpPeoples.length >= 5) { + if(!res.result.addedBonusFlag) { + that.log("开始领取额外奖励"); + let getHelpAddedBonusResult = await request('getHelpAddedBonus'); + if (getHelpAddedBonusResult.resultCode === '0') { + message += ""+ `【额外奖励${getHelpAddedBonusResult.result.reward}领取】${getHelpAddedBonusResult.message}\n` + "\n\n"; + } + that.log(`领取30g额外奖励结果:【${getHelpAddedBonusResult.message}】`); + } else { + that.log("已经领取过5好友助力额外奖励"); + message += ""+ `【额外奖励】已领取\n` + "\n\n"; + } + } else { + that.log("助力好友未达到5个") + message += ""+ `【额外奖励】领取失败,原因:给您助力的人未达5个\n` + "\n\n"; + } + if (res.result.masterHelpPeoples && res.result.masterHelpPeoples.length > 0) { + that.log('帮您助力的好友的名单开始') + let str = ''; + res.result.masterHelpPeoples.map((item, index) => { + if (index === (res.result.masterHelpPeoples.length - 1)) { + str += item.nickName || "匿名用户"; + } else { + str += (item.nickName || "匿名用户") + ','; + } + }) + message += ""+ `【助力您的好友】${str}\n` + "\n\n"; + } + } +} +/** + * 助力好友, 暂时支持一个好友, 需要拿到shareCode + * shareCode为你要助力的好友的 + * 运行脚本时你自己的shareCode会在控制台输出, 可以将其分享给他人 + */ +async function slaveHelp() { + //$.log(`\n因1.6日好友助力功能下线。故暂时屏蔽\n`) + //return + let helpPeoples = ''; + for (let code of newShareCodes) { + that.log(`开始助力动动账号${$.index} - ${$.nickName}的好友: ${code}`); + if (!code) continue; + let response = await request('slaveHelp', {'shareCode': code}); + if (response.code === '0' && response.resultCode === '0') { + if (response.result.helpStatus === 0) { + that.log('已给好友: 【' + response.result.masterNickName + '】助力成功'); + helpPeoples += response.result.masterNickName + ','; + } else if (response.result.helpStatus === 1) { + // 您今日已无助力机会 + that.log(`助力好友${response.result.masterNickName}失败,您今日已无助力机会`); + break; + } else if (response.result.helpStatus === 2) { + //该好友已满5人助力,无需您再次助力 + that.log(`该好友${response.result.masterNickName}已满5人助力,无需您再次助力`); + } else { + that.log(`助力其他情况:${JSON.stringify(response)}`); + } + } else { + that.log(`助力好友结果: ${response.message}`); + } + } + if (helpPeoples && helpPeoples.length > 0) { + message = message + ""+ `【您助力的好友】${helpPeoples.substr(0, helpPeoples.length - 1)}\n` +"\n\n"; + } +} +// 遛狗, 每天次数上限10次, 随机给狗粮, 每次遛狗结束需调用getSportReward领取奖励, 才能进行下一次遛狗 +async function petSport() { + that.log('开始遛弯'); + let times = 1 + const code = 0 + let resultCode = 0 + do { + let response = await request('petSport') + that.log(`第${times}次遛狗完成: ${JSON.stringify(response)}`); + resultCode = response.resultCode; + if (resultCode == 0) { + let sportRevardResult = await request('getSportReward'); + that.log(`领取遛狗奖励完成: ${JSON.stringify(sportRevardResult)}`); + } + times++; + } while (resultCode == 0 && code == 0) + if (times > 1) { + // message += '【十次遛狗】已完成\n'; + } +} +// 初始化任务, 可查询任务完成情况 +async function taskInit() { + that.log('开始任务初始化'); + $.taskInit = await request('taskInit', {"version":1}); +} +// 每日签到, 每天一次 +async function signInitFun() { + that.log('准备每日签到'); + const response = await request("getSignReward"); + that.log(`每日签到结果: ${JSON.stringify(response)}`); + if (response.code === '0' && response.resultCode === '0') { + that.log(`【每日签到成功】奖励${response.result.signReward}g狗粮\n`); + // message += `【每日签到成功】奖励${response.result.signReward}g狗粮\n`; + } else { + that.log(`【每日签到】${response.message}\n`); + // message += `【每日签到】${response.message}\n`; + } +} + +// 三餐签到, 每天三段签到时间 +async function threeMealInitFun() { + that.log('准备三餐签到'); + const response = await request("getThreeMealReward"); + that.log(`三餐签到结果: ${JSON.stringify(response)}`); + if (response.code === '0' && response.resultCode === '0') { + that.log(`【定时领狗粮】获得${response.result.threeMealReward}g\n`); + // message += `【定时领狗粮】获得${response.result.threeMealReward}g\n`; + } else { + that.log(`【定时领狗粮】${response.message}\n`); + // message += `【定时领狗粮】${response.message}\n`; + } +} + +// 浏览指定店铺 任务 +async function browseSingleShopInit(item) { + that.log(`开始做 ${item.title} 任务, ${item.desc}`); + const body = {"index": item['index'], "version":1, "type":1}; + const body2 = {"index": item['index'], "version":1, "type":2}; + const response = await request("getSingleShopReward", body); + // that.log(`点击进去response::${JSON.stringify(response)}`); + if (response.code === '0' && response.resultCode === '0') { + const response2 = await request("getSingleShopReward", body2); + // that.log(`浏览完毕领取奖励:response2::${JSON.stringify(response2)}`); + if (response2.code === '0' && response2.resultCode === '0') { + that.log(`【浏览指定店铺】获取${response2.result.reward}g\n`); + // message += `【浏览指定店铺】获取${response2.result.reward}g\n`; + } + } +} + +// 浏览店铺任务, 任务可能为多个? 目前只有一个 +async function browseShopsInitFun() { + that.log('开始浏览店铺任务'); + let times = 0; + let resultCode = 0; + let code = 0; + do { + let response = await request("getBrowseShopsReward"); + that.log(`第${times}次浏览店铺结果: ${JSON.stringify(response)}`); + code = response.code; + resultCode = response.resultCode; + times++; + } while (resultCode == 0 && code == 0 && times < 5) + that.log('浏览店铺任务结束'); +} +// 首次投食 任务 +function firstFeedInitFun() { + that.log('首次投食任务合并到10次喂食任务中\n'); +} + +// 邀请新用户 +async function inviteFriendsInitFun() { + that.log('邀请新用户功能未实现'); + if ($.taskInfo.inviteFriendsInit.status == 1 && $.taskInfo.inviteFriendsInit.inviteFriendsNum > 0) { + // 如果有邀请过新用户,自动领取60gg奖励 + const res = await request('getInviteFriendsReward'); + if (res.code == 0 && res.resultCode == 0) { + that.log(`领取邀请新用户奖励成功,获得狗粮现有狗粮${$.taskInfo.inviteFriendsInit.reward}g,${res.result.foodAmount}g`); + message += ""+ `【邀请新用户】获取狗粮${$.taskInfo.inviteFriendsInit.reward}g\n` +"\n\n"; + } + } +} + +/** + * 投食10次 任务 + */ +async function feedReachInitFun() { + that.log('投食任务开始...'); + let finishedTimes = $.taskInfo.feedReachInit.hadFeedAmount / 10; //已经喂养了几次 + let needFeedTimes = 10 - finishedTimes; //还需要几次 + let tryTimes = 20; //尝试次数 + do { + that.log(`还需要投食${needFeedTimes}次`); + const response = await request('feedPets'); + that.log(`本次投食结果: ${JSON.stringify(response)}`); + if (response.resultCode == 0 && response.code == 0) { + needFeedTimes--; + } + if (response.resultCode == 3003 && response.code == 0) { + that.log('剩余狗粮不足, 投食结束'); + needFeedTimes = 0; + } + tryTimes--; + } while (needFeedTimes > 0 && tryTimes > 0) + that.log('投食任务结束...\n'); +} +async function showMsg() { + if ($.isNode() && process.env.PET_NOTIFY_CONTROL) { + $.ctrTemp = `${process.env.PET_NOTIFY_CONTROL}` === 'false'; + } else if ($.getdata('jdPetNotify')) { + $.ctrTemp = $.getdata('jdPetNotify') === 'false'; + } else { + $.ctrTemp = `${jdNotify}` === 'false'; + } + // jdNotify = `${notify.petNotifyControl}` === 'false' && `${jdNotify}` === 'false' && $.getdata('jdPetNotify') === 'false'; + if ($.ctrTemp) { + $.msg($.name, subTitle, message, option); + if ($.isNode()) { + allMessage += `${subTitle}\n${message}${$.index !== cookiesArr.length ? '\n\n' : ''}` + // await notify.sendNotify(`${$.name} - 账号${$.index} - ${$.nickName}`, `${subTitle}\n${message}`); + } + } else { + $.log(`\n${message}\n`); + } +} +function readShareCode() { + return new Promise(async resolve => { + $.get({url: `http://jd.turinglabs.net/api/v2/jd/pet/read/${randomCount}/`, 'timeout': 10000}, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + that.log(`随机取个${randomCount}码放到您固定的互助码后面(不影响已有固定互助)`) + data = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + await $.wait(10000); + resolve() + }) +} +function shareCodesFormat() { + return new Promise(async resolve => { + // that.log(`第${$.index}个动动账号的助力码:::${jdPetShareArr[$.index - 1]}`) + newShareCodes = []; + if (jdPetShareArr[$.index - 1]) { + newShareCodes = jdPetShareArr[$.index - 1].split('@'); + } else { + that.log(`由于您第${$.index}个动动账号未提供shareCode,将采纳本脚本自带的助力码\n`) + if(shareCodes.length>0){ + const tempIndex = $.index > shareCodes.length ? (shareCodes.length - 1) : ($.index - 1); + newShareCodes = shareCodes[tempIndex].split('@'); + } + } + //因好友助力功能下线。故暂时屏蔽 + //const readShareCodeRes = await readShareCode(); + const readShareCodeRes = null; + if (readShareCodeRes && readShareCodeRes.code === 200) { + newShareCodes = [...new Set([...newShareCodes, ...(readShareCodeRes.data || [])])]; + } + that.log(`第${$.index}个动动账号将要助力的好友${JSON.stringify(newShareCodes)}`) + resolve(); + }) +} +function requireConfig() { + return new Promise(resolve => { + that.log('开始获取动动萌宠配置文件\n') + notify = $.isNode() ? require('./sendNotify') : ''; + //Node.js用户请在jdCookie.js处填写动动ck; + const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + const jdPetShareCodes = $.isNode() ? require('./jdPetShareCodes.js') : ''; + //IOS等用户直接用NobyDa的jd cookie + if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; + } else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + that.log(`共${cookiesArr.length}个动动账号\n`) + if ($.isNode()) { + Object.keys(jdPetShareCodes).forEach((item) => { + if (jdPetShareCodes[item]) { + jdPetShareArr.push(jdPetShareCodes[item]) + } + }) + } else { + const boxShareCodeArr = ['jd_pet1', 'jd_pet2', 'jd_pet3', 'jd_pet4', 'jd_pet5']; + const boxShareCodeArr2 = ['jd2_pet1', 'jd2_pet2', 'jd2_pet3', 'jd2_pet4', 'jd2_pet5']; + const isBox1 = boxShareCodeArr.some((item) => { + const boxShareCode = $.getdata(item); + return (boxShareCode !== undefined && boxShareCode !== null && boxShareCode !== ''); + }); + const isBox2 = boxShareCodeArr2.some((item) => { + const boxShareCode = $.getdata(item); + return (boxShareCode !== undefined && boxShareCode !== null && boxShareCode !== ''); + }); + isBox = isBox1 ? isBox1 : isBox2; + if (isBox1) { + let temp = []; + for (const item of boxShareCodeArr) { + if ($.getdata(item)) { + temp.push($.getdata(item)) + } + } + jdPetShareArr.push(temp.join('@')); + } + if (isBox2) { + let temp = []; + for (const item of boxShareCodeArr2) { + if ($.getdata(item)) { + temp.push($.getdata(item)) + } + } + jdPetShareArr.push(temp.join('@')); + } + } + // that.log(`jdPetShareArr::${JSON.stringify(jdPetShareArr)}`) + // that.log(`jdPetShareArr账号长度::${jdPetShareArr.length}`) + that.log(`您提供了${jdPetShareArr.length}个账号的动动萌宠助力码\n`); + resolve() + }) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +// 请求 +async function request(function_id, body = {}) { + await $.wait(3000); //歇口气儿, 不然会报操作频繁 + return new Promise((resolve, reject) => { + $.post(taskUrl(function_id, body), (err, resp, data) => { + try { + if (err) { + that.log('\n动动萌宠: API查询请求失败 ‼️‼️'); + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data) + } + }) + }) +} +// function taskUrl(function_id, body = {}) { +// return { +// url: `${JD_API_HOST}?functionId=${function_id}&appid=wh5&loginWQBiz=pet-town&body=${escape(JSON.stringify(body))}`, +// headers: { +// Cookie: cookie, +// UserAgent: $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), +// } +// }; +// } +function taskUrl(function_id, body = {}) { + body["version"] = 2; + body["channel"] = 'app'; + return { + url: `${JD_API_HOST}?functionId=${function_id}`, + body: `body=${escape(JSON.stringify(body))}&appid=wh5&loginWQBiz=pet-town&clientVersion=9.0.4`, + headers: { + 'Cookie': cookie, + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + } + }; +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + + + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动萌宠", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_shop.js b/src/main/resources/test_shop.js new file mode 100644 index 0000000..e969b28 --- /dev/null +++ b/src/main/resources/test_shop.js @@ -0,0 +1,279 @@ +const notify = $.isNode() ? require('./sendNotify') : ''; +//Node.js用户请在jdCookie.js处填写动动ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; + +//IOS等用户直接用NobyDa的jd cookie +let cookiesArr = [], cookie = ''; +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => {}; +} else { + let cookiesData = $.getdata('CookiesJD') || "[]"; + cookiesData = jsonParse(cookiesData); + cookiesArr = cookiesData.map(item => item.cookie); + cookiesArr.reverse(); + cookiesArr.push(...[$.getdata('CookieJD2'), $.getdata('CookieJD')]); + cookiesArr.reverse(); + cookiesArr = cookiesArr.filter(item => item !== "" && item !== null && item !== undefined); +} +let message = '', subTitle = ''; + +const JD_API_HOST = 'https://api.m.jd.com/client.action'; +!(async () => { + + message += "[通知] 动动超市 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await TotalBean(); + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + that.log(`\n开始【动动账号${$.index}】${$.nickName || $.UserName}\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + subTitle = ''; + await jdShop(); + } + message += "----\n\n" + } +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + message = message + "" +`❌ ${$.name}, 失败! 原因: ${e}!` + "\n\n" + }) + .finally(() => { + message += getPic() + that.log(message) + // postToDingTalk(message) + $.done(); + }) +async function jdShop() { + const taskData = await getTask(); + if (taskData.code === '0') { + if (!taskData.data.taskList) { + that.log(`${taskData.data.taskErrorTips}\n`); + $.msg($.name, '', `动动账号 ${$.index} ${$.nickName}\n${taskData.data.taskErrorTips}`); + message += "" + `${taskData.data.taskErrorTips}` + "\n\n" + } else { + const { taskList } = taskData.data; + let beanCount = 0; + for (let item of taskList) { + if (item.taskStatus === 3) { + that.log(`${item.shopName} 已拿到2京豆\n`) + message += "" + `成功领取${beanCount}京豆` + "\n\n" + } else { + that.log(`taskId::${item.taskId}`) + const doTaskRes = await doTask(item.taskId); + if (doTaskRes.code === '0') { + beanCount += 2; + } + } + } + that.log(`beanCount::${beanCount}`); + message += "" + `成功领取${beanCount}京豆` + "\n\n" + $.msg($.name, '', `动动账号 ${$.index} ${$.nickName}\n成功领取${beanCount}京豆`); + } + } +} +function doTask(taskId) { + that.log(`doTask-taskId::${taskId}`) + return new Promise(resolve => { + const body = { 'taskId': `${taskId}` }; + const options = { + url: `${JD_API_HOST}`, + body: `functionId=takeTask&body=${escape(JSON.stringify(body))}&appid=ld`, + headers: { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log('\n进店领豆: API查询请求失败 ‼️‼️') + $.logErr(err); + } else { + // that.log(data) + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }) +} +function getTask(body = {}) { + return new Promise(resolve => { + const options = { + url: `${JD_API_HOST}`, + body: `functionId=queryTaskIndex&body=${escape(JSON.stringify(body))}&appid=ld`, + headers: { + 'User-Agent': $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0"), + 'Host': 'api.m.jd.com', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Cookie': cookie, + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log('\n进店领豆: API查询请求失败 ‼️‼️') + $.logErr(err); + } else { + // that.log(data) + data = JSON.parse(data); + } + } catch (e) { + $.logErr(e, resp); + } finally { + resolve(data); + } + }) + }) +} +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0") + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=fa87e34729eaa6113fddfa857efebb477dea0a433d6eecfe93b1d3f5e24847b9" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动超市", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_speed_red.js b/src/main/resources/test_speed_red.js new file mode 100644 index 0000000..db40219 --- /dev/null +++ b/src/main/resources/test_speed_red.js @@ -0,0 +1,336 @@ + +const JD_API_HOST = 'https://api.m.jd.com/'; + +const notify = $.isNode() ? require('./sendNotify') : ''; +let cookiesArr = [], cookie = '', message = ''; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => { + }; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} + +$.linkId=""; +$.linkIds=["9wdf1YTT2L59Vr-meKskLA"]; +!(async () => { + message += "[通知] 极速签到领红包 \n\n --- \n\n" + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + for(var index=0;index<$.linkIds.length;index++){ + $.linkId=$.linkIds[index]; + that.log("当前linkId:"+$.linkId); + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1]) + + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + await spring_reward_query(); + if ($.data) { + that.log("当前剩余次数:" + $.data.remainChance); + if ($.data.remainChance) { + for (var j = 0; j < $.data.remainChance; j++) { + await spring_reward_receive(); + await $.wait(2000); + if ($.reward) { + if ($.reward.prizeType == 1) { + message = message + "" + "获得优惠券:" + $.reward.prizeDesc + ',面值:' + $.reward.amount + ",满" + $.reward.useLimit + "可用" + "\n\n" + that.log("获得优惠券:" + $.reward.prizeDesc + ',面值:' + $.reward.amount + ",满" + $.reward.useLimit + "可用"); + } else if ($.reward.prizeType == 4) { + message = message + "" + "获得现金:" + $.reward.amount + ',描述:' + $.reward.prizeDesc + "\n\n" + that.log("获得现金:" + $.reward.amount + ',描述:' + $.reward.prizeDesc); + } else { + message = message + "" + "获得" + $.reward.prizeDesc + ",面值:" + $.reward.amount + "\n\n" + that.log("获得" + $.reward.prizeDesc + ",面值:" + $.reward.amount); + } + } + } + } + } + await spring_reward_list(); + if ($.list) { + for (var item of $.list) { + if (item.state == 0 && item.prizeType == 4) { + message = message + "" + "有" + item.amount + "现金没有提现,尝试提现中" + "\n\n" + that.log("有" + item.amount + "现金没有提现,尝试提现中"); + await apCashWithDraw(item); + await $.wait(1000); + } + } + } + } + } + } + + })() + .catch((e) => { + message = message + "" + `❌ ${$.name}, 失败! 原因: ${e}!` + "\n\n" + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + message += getPic() + taht.log(message) + $.done(); + }) + + function spring_reward_receive() { + return new Promise((resolve) => { + $.get(taskUrl("spring_reward_receive", { + "linkId": $.linkId, + "inviter": "UhBiP5ZPaM28-O0MOaGu2g" + }), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + $.reward = data.data.received; + } else { + that.log(JSON.stringify(data)); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function spring_reward_query() { + return new Promise((resolve) => { + $.get(taskUrl("spring_reward_query", { + "linkId": $.linkId, + "inviter": "UhBiP5ZPaM28-O0MOaGu2g" + }), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + $.data = data.data; + } else { + that.log(JSON.stringify(data)); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function spring_reward_list() { + return new Promise((resolve) => { + $.get(taskUrl("spring_reward_list", { + "pageNum": 1, + "pageSize": 10, + "linkId": $.linkId, + "inviter": "UhBiP5ZPaM28-O0MOaGu2g" + }), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + $.list = data.data.items; + } else { + that.log(JSON.stringify(data)); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function apCashWithDraw(item) { + console.log(item); + return new Promise((resolve) => { + $.post(taskUrlPost("apCashWithDraw", { + "businessSource": "SPRING_FESTIVAL_RED_ENVELOPE", + "base": { + "id": item.id, + "business": null, + "poolBaseId": item.poolBaseId, + "prizeGroupId": item.prizeGroupId, + "prizeBaseId": item.prizeBaseId, + "prizeType": 4 + }, + "linkId": $.linkId, + "inviter": "UhBiP5ZPaM28-O0MOaGu2g" + }), (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + that.log(JSON.stringify(data.data)); + //that.log("如果提示null,请手动去提现一次(绑定微信)"); + } else { + that.log(JSON.stringify(data)); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) + } + + function taskUrl(functionId, body = {}) { + return { + url: `${JD_API_HOST}?functionId=${functionId}&body=${escape(JSON.stringify(body))}&appid=activities_platform&_t=${new Date().getTime()}`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/json', + 'Referer': 'https://prodev.m.jd.com/jdlite/active/31U4T6S4PbcK83HyLPioeCWrD63j/index.html?channel=qqh5fx&inviter=UhBiP5ZPaM28-O0MOaGu2g&utm_user=plusmember&ad_od=share&cu=true&utm_source=kong&utm_medium=jingfen&utm_campaign=t_1000217905_&utm_term=2555319d90df4c66b502437958986790', + 'User-Agent': "jdltapp;android;3.1.0;9;", + 'Accept-Language': 'zh-cn', + } + } + } + + function taskUrlPost(functionId, body = {}) { + return { + url: `${JD_API_HOST}`, + body: `functionId=${functionId}&body=${escape(JSON.stringify(body))}&appid=activities_platform&_t=${new Date().getTime()}`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Connection': 'keep-alive', + 'Content-Type': 'application/x-www-form-urlencoded', + 'Referer': 'https://prodev.m.jd.com/jdlite/active/q1eB6WUB8oC4eH1BsCLWvQakVsX/index.html', + 'User-Agent': "jdltapp;android;3.1.0;9;", + 'Accept-Language': 'zh-cn', + } + } + } + + function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } + } + + function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '不要在BoxJS手动复制粘贴修改cookie') + return []; + } + } +} + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=fa87e34729eaa6113fddfa857efebb477dea0a433d6eecfe93b1d3f5e24847b9" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"极速签到领红包", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_speed_sign.js b/src/main/resources/test_speed_sign.js new file mode 100644 index 0000000..310f017 --- /dev/null +++ b/src/main/resources/test_speed_sign.js @@ -0,0 +1,942 @@ +const notify = $.isNode() ? require('./sendNotify') : ''; +//Node.js用户请在jdCookie.js处填写动动ck; +const jdCookieNode = $.isNode() ? require('./jdCookie.js') : ''; +let CryptoJS=$.CryptoJS; +$.toObj = (t, e = null) => { + try { + return JSON.parse(t) + } catch { + return e + } +} +$.toStr = (t, e = null) => { + try { + return JSON.stringify(t) + } catch { + return e + } +} +const linkId = "AkOULcXbUA_8EAPbYLLMgg"; +const signLinkId = '9WA12jYGulArzWS7vcrwhw'; +let cookiesArr = [], cookie = ''; +let message = "" +if ($.isNode()) { + Object.keys(jdCookieNode).forEach((item) => { + cookiesArr.push(jdCookieNode[item]) + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') that.log = () => { + }; +} else { + cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); +} + +const JD_API_HOST = 'https://api.m.jd.com/', actCode = 'visa-card-001'; + + +!(async () => { + if (!cookiesArr[0]) { + $.msg($.name, '【提示】请先获取动动账号一cookie\n直接使用NobyDa的动动签到获取', 'https://bean.m.jd.com/bean/signIndex.action', {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + return; + } + message += "[通知] 极速签到挣金币 \n\n --- \n\n" + for (let i = 0; i < cookiesArr.length; i++) { + if (cookiesArr[i]) { + cookie = cookiesArr[i]; + $.UserName = decodeURIComponent(cookie.match(/pt_pin=(.+?);/) && cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + await TotalBean(); + that.log(`\n******开始【动动账号${$.index}】${$.nickName || $.UserName}*********\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `动动账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, {"open-url": "https://bean.m.jd.com/bean/signIndex.action"}); + + if ($.isNode()) { + await notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `动动账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + } + continue + } + await jdGlobal() + } + message = message +"----\n" +} + +})() + .catch((e) => { + $.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '') + }) + .finally(() => { + message += getPic() + taht.log(message) + postToDingTalk(message) + $.done(); + }) + +async function jdGlobal() { + try { + await signInit() + await sign() + await getPacketList();//领红包提现 + await signPrizeDetailList(); + await invite() + await invite2() + $.score = 0 + $.total = 0 + await taskList() + await queryJoy() + await signInit() + await cash() + await showMsg() + } catch (e) { + $.logErr(e) + } +} + + +function showMsg() { + return new Promise(resolve => { + message += "" + `本次运行获得${$.score}金币,共计${$.total}金币` + "\n\n" + $.msg($.name, '', `动动账号${$.index}${$.nickName}\n${message}`); + resolve() + }) +} + +async function sign() { + return new Promise(resolve => { + const body = {"linkId":signLinkId,"serviceName":"dayDaySignGetRedEnvelopeSignService","business":1}; + const options = { + url: `https://api.m.jd.com`, + body: `functionId=apSignIn_day&body=${escape(JSON.stringify(body))}&_t=${+new Date()}&appid=activities_platform`, + headers: { + 'Cookie': cookie, + "Host": "api.m.jd.com", + 'Origin': 'https://daily-redpacket.jd.com', + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "Connection": "keep-alive", + "User-Agent": "jdltapp;iPhone;3.3.2;14.5.1network/wifi;hasUPPay/0;pushNoticeIsOpen/1;lang/zh_CN;model/iPhone13,2;addressid/137923973;hasOCPay/0;appBuild/1047;supportBestPay/0;pv/467.11;apprpd/MyJD_Main;", + "Accept-Language": "zh-Hans-CN;q=1, en-CN;q=0.9, zh-Hant-CN;q=0.8", + 'Referer': 'https://daily-redpacket.jd.com/?activityId=9WA12jYGulArzWS7vcrwhw', + "Accept-Encoding": "gzip, deflate, br" + } + } + $.post(options, async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = $.toObj(data); + if (data.code === 0) { + if (data.data.retCode === 0) { + // message += `极速版签到提现:签到成功\n`; + console.log(`极速版签到提现:签到成功\n`); + } else { + message += "" + `极速版签到提现:签到异常:${JSON.stringify(data)}\n` + "\n\n" + console.log(`极速版签到提现:签到失败:${data.data.retMessage}\n`); + } + } else { + message += "" + `极速版签到提现:签到异常:${JSON.stringify(data)}\n` + "\n\n" + console.log(`极速版签到提现:签到异常:${JSON.stringify(data)}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +async function signInit() { + return new Promise(resolve => { + $.get(taskUrl('speedSignInit', { + "activityId": "8a8fabf3cccb417f8e691b6774938bc2", + "kernelPlatform": "RN", + "inviterId":"y3gfQAo9OlMun43uVNyOgQ==" + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + //that.log(data) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +// async function sign() { +// return new Promise(resolve => { +// $.get(taskUrl('speedSign', { +// "kernelPlatform": "RN", +// "activityId": "8a8fabf3cccb417f8e691b6774938bc2", +// "noWaitPrize": "false" +// }), +// async (err, resp, data) => { +// try { +// if (err) { +// that.log(`${JSON.stringify(err)}`) +// that.log(`${$.name} API请求失败,请检查网路重试`) +// } else { +// if (safeGet(data)) { +// data = JSON.parse(data); +// if (data.subCode === 0) { +// that.log(`签到获得${data.data.signAmount}现金,共计获得${data.data.cashDrawAmount}`) +// } else { +// that.log(`签到失败,${data.msg}`) +// } +// } +// } +// } catch (e) { +// $.logErr(e, resp) +// } finally { +// resolve(data); +// } +// }) +// }) +// } + +async function taskList() { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', { + "version": "3.1.0", + "method": "newTaskCenterPage", + "data": {"channel": 1} + }), + async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + for (let task of data.data) { + $.taskName = task.taskInfo.mainTitle + if (task.taskInfo.status === 0) { + if (task.taskType >= 1000) { + await doTask(task.taskType) + await $.wait(1000) + } else { + $.canStartNewItem = true + while ($.canStartNewItem) { + if (task.taskType !== 3) { + await queryItem(task.taskType) + } else { + await startItem("", task.taskType) + } + } + } + } else { + that.log(`${task.taskInfo.mainTitle}已完成`) + } + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function doTask(taskId) { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', { + "method": "marketTaskRewardPayment", + "data": {"channel": 1, "clientTime": +new Date() + 0.588, "activeType": taskId} + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + message +="" + `${data.data.taskInfo.mainTitle}任务完成成功,预计获得${data.data.reward}金币` + "\n\n" + that.log(`${data.data.taskInfo.mainTitle}任务完成成功,预计获得${data.data.reward}金币`) + } else { + message +="" + `${data.data.taskInfo.mainTitle}任务发生异常${data.errMsg}` + "\n\n" + that.log(`任务完成失败,${data.message}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +function getPacketList() { + return new Promise(resolve => { + $.get(taskGetUrl("spring_reward_list",{"pageNum":1,"pageSize":100,linkId,"inviter":""}), async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + for(let item of data.data.items.filter(vo => vo.prizeType===4)){ + if(item.state===0){ + console.log(`去提现${item.amount}微信现金`) + message +="" + `提现${item.amount}微信现金,` + "\n\n" + await cashOut(item.id,item.poolBaseId,item.prizeGroupId,item.prizeBaseId) + } + } + } else { + message +="" + `提现发生异常:${data.errMsg}` + "\n\n" + console.log(data.errMsg) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function signPrizeDetailList() { + return new Promise(resolve => { + const body = {"linkId":signLinkId,"serviceName":"dayDaySignGetRedEnvelopeSignService","business":1,"pageSize":20,"page":1}; + const options = { + url: `https://api.m.jd.com`, + body: `functionId=signPrizeDetailList&body=${escape(JSON.stringify(body))}&_t=${+new Date()}&appid=activities_platform`, + headers: { + 'Cookie': cookie, + "Host": "api.m.jd.com", + 'Origin': 'https://daily-redpacket.jd.com', + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "Connection": "keep-alive", + "User-Agent": "jdltapp;iPhone;3.3.2;14.5.1network/wifi;hasUPPay/0;pushNoticeIsOpen/1;lang/zh_CN;model/iPhone13,2;addressid/137923973;hasOCPay/0;appBuild/1047;supportBestPay/0;pv/467.11;apprpd/MyJD_Main;", + "Accept-Language": "zh-Hans-CN;q=1, en-CN;q=0.9, zh-Hant-CN;q=0.8", + 'Referer': 'https://daily-redpacket.jd.com/?activityId=9WA12jYGulArzWS7vcrwhw', + "Accept-Encoding": "gzip, deflate, br" + } + } + $.post(options, async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = $.toObj(data); + if (data.code === 0) { + if (data.data.code === 0) { + const list = (data.data.prizeDrawBaseVoPageBean.items || []).filter(vo => vo['prizeType'] === 4 && vo['prizeStatus'] === 0); + for (let code of list) { + console.log(`极速版签到提现,去提现${code['prizeValue']}现金\n`); + message += "" + `极速版签到提现,去提现${code['prizeValue']}微信现金,` + "\n\n" + await apCashWithDraw(code['id'], code['poolBaseId'], code['prizeGroupId'], code['prizeBaseId']); + } + } else { + console.log(`极速版签到查询奖品:失败:${JSON.stringify(data)}\n`); + } + } else { + console.log(`极速版签到查询奖品:异常:${JSON.stringify(data)}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function apCashWithDraw(id, poolBaseId, prizeGroupId, prizeBaseId) { + return new Promise(resolve => { + const body = { + "linkId": signLinkId, + "businessSource": "DAY_DAY_RED_PACKET_SIGN", + "base": { + "prizeType": 4, + "business": "dayDayRedPacket", + "id": id, + "poolBaseId": poolBaseId, + "prizeGroupId": prizeGroupId, + "prizeBaseId": prizeBaseId + } + } + const options = { + url: `https://api.m.jd.com`, + body: `functionId=apCashWithDraw&body=${escape(JSON.stringify(body))}&_t=${+new Date()}&appid=activities_platform`, + headers: { + 'Cookie': cookie, + "Host": "api.m.jd.com", + 'Origin': 'https://daily-redpacket.jd.com', + "Content-Type": "application/x-www-form-urlencoded", + "Accept": "*/*", + "Connection": "keep-alive", + "User-Agent": "jdltapp;iPhone;3.3.2;14.5.1network/wifi;hasUPPay/0;pushNoticeIsOpen/1;lang/zh_CN;model/iPhone13,2;addressid/137923973;hasOCPay/0;appBuild/1047;supportBestPay/0;pv/467.11;apprpd/MyJD_Main;", + "Accept-Language": "zh-Hans-CN;q=1, en-CN;q=0.9, zh-Hant-CN;q=0.8", + 'Referer': 'https://daily-redpacket.jd.com/?activityId=9WA12jYGulArzWS7vcrwhw', + "Accept-Encoding": "gzip, deflate, br" + } + } + $.post(options, async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = $.toObj(data); + if (data.code === 0) { + if (data.data.status === "310") { + console.log(`极速版签到提现现金成功!`) + // message += `极速版签到提现现金成功!`; + } else { + console.log(`极速版签到提现现金:失败:${JSON.stringify(data)}\n`); + message +="" + `极速版签到提现现金:失败:${JSON.stringify(data)}\n` + "\n\n" + } + } else { + message +="" + `极速版签到提现现金:失败:${JSON.stringify(data)}\n` + "\n\n" + console.log(`极速版签到提现现金:异常:${JSON.stringify(data)}\n`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} +function cashOut(id,poolBaseId,prizeGroupId,prizeBaseId,) { + let body = { + "businessSource": "SPRING_FESTIVAL_RED_ENVELOPE", + "base": { + "id": id, + "business": null, + "poolBaseId": poolBaseId, + "prizeGroupId": prizeGroupId, + "prizeBaseId": prizeBaseId, + "prizeType": 4 + }, + linkId, + "inviter": "" + } + return new Promise(resolve => { + $.post(taskPostUrl("apCashWithDraw",body), async (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + console.log(`提现零钱结果:${data}`) + data = JSON.parse(data); + if (data.code === 0) { + if (data['data']['status'] === "310") { + console.log(`提现成功!`) + // message += `提现成功!\n`; + } else { + console.log(`提现失败:${data['data']['message']}`); + message +="" + `提现失败:${data['data']['message']}` + "\n\n"; + } + } else { + message +="" + `提现失败:${data['data']['message']}` + "\n\n"; + console.log(`提现异常:${data['errMsg']}`); + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function queryJoy() { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', {"method": "queryJoyPage", "data": {"channel": 1}}), + async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.data.taskBubbles) + for (let task of data.data.taskBubbles) { + await rewardTask(task.id, task.activeType) + await $.wait(500) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function rewardTask(id, taskId) { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', { + "method": "joyTaskReward", + "data": {"id": id, "channel": 1, "clientTime": +new Date() + 0.588, "activeType": taskId} + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0) { + $.score += data.data.reward + that.log(`气泡收取成功,获得${data.data.reward}金币`) + } else { + that.log(`气泡收取失败,${data.message}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + + +async function queryItem(activeType = 1) { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', { + "method": "queryNextTask", + "data": {"channel": 1, "activeType": activeType} + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0 && data.data) { + await startItem(data.data.nextResource, activeType) + } else { + that.log(`商品任务开启失败,${data.message}`) + $.canStartNewItem = false + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function startItem(activeId, activeType) { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', { + "method": "enterAndLeave", + "data": { + "activeId": activeId, + "clientTime": +new Date(), + "channel": "1", + "messageType": "1", + "activeType": activeType, + } + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0 && data.data) { + if (data.data.taskInfo.isTaskLimit === 0) { + let {videoBrowsing, taskCompletionProgress, taskCompletionLimit} = data.data.taskInfo + if (activeType !== 3) + videoBrowsing = activeType === 1 ? 5 : 10 + that.log(`【${taskCompletionProgress + 1}/${taskCompletionLimit}】浏览商品任务记录成功,等待${videoBrowsing}秒`) + await $.wait(videoBrowsing * 1000) + await endItem(data.data.uuid, activeType, activeId, activeType === 3 ? videoBrowsing : "") + } else { + that.log(`${$.taskName}任务已达上限`) + $.canStartNewItem = false + } + } else { + $.canStartNewItem = false + that.log(`${$.taskName}任务开启失败,${data.message}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function endItem(uuid, activeType, activeId = "", videoTimeLength = "") { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', + { + "method": "enterAndLeave", + "data": { + "channel": "1", + "clientTime": +new Date(), + "uuid": uuid, + "videoTimeLength": videoTimeLength, + "messageType": "2", + "activeType": activeType, + "activeId": activeId + } + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0 && data.isSuccess) { + await rewardItem(uuid, activeType, activeId, videoTimeLength) + } else { + that.log(`${$.taskName}任务结束失败,${data.message}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function rewardItem(uuid, activeType, activeId = "", videoTimeLength = "") { + return new Promise(resolve => { + $.get(taskUrl('ClientHandleService.execute', + { + "method": "rewardPayment", + "data": { + "channel": "1", + "clientTime": +new Date(), + "uuid": uuid, + "videoTimeLength": videoTimeLength, + "messageType": "2", + "activeType": activeType, + "activeId": activeId + } + }), async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + if (data.code === 0 && data.isSuccess) { + $.score += data.data.reward + that.log(`${$.taskName}任务完成,获得${data.data.reward}金币`) + } else { + that.log(`${$.taskName}任务失败,${data.message}`) + } + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + +async function cash() { + return new Promise(resolve => { + $.get(taskUrl('MyAssetsService.execute', + {"method": "userCashRecord", "data": {"channel": 1, "pageNum": 1, "pageSize": 20}}), + async (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (safeGet(data)) { + data = JSON.parse(data); + $.total = data.data.goldBalance + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(data); + } + }) + }) +} + + +var __encode ='jsjiami.com',_a={}, _0xb483=["\x5F\x64\x65\x63\x6F\x64\x65","\x68\x74\x74\x70\x3A\x2F\x2F\x77\x77\x77\x2E\x73\x6F\x6A\x73\x6F\x6E\x2E\x63\x6F\x6D\x2F\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x6F\x62\x66\x75\x73\x63\x61\x74\x6F\x72\x2E\x68\x74\x6D\x6C"];(function(_0xd642x1){_0xd642x1[_0xb483[0]]= _0xb483[1]})(_a);var __Oxb24bc=["\x6C\x69\x74\x65\x2D\x61\x6E\x64\x72\x6F\x69\x64\x26","\x73\x74\x72\x69\x6E\x67\x69\x66\x79","\x26\x61\x6E\x64\x72\x6F\x69\x64\x26\x33\x2E\x31\x2E\x30\x26","\x26","\x26\x38\x34\x36\x63\x34\x63\x33\x32\x64\x61\x65\x39\x31\x30\x65\x66","\x31\x32\x61\x65\x61\x36\x35\x38\x66\x37\x36\x65\x34\x35\x33\x66\x61\x66\x38\x30\x33\x64\x31\x35\x63\x34\x30\x61\x37\x32\x65\x30","\x69\x73\x4E\x6F\x64\x65","\x63\x72\x79\x70\x74\x6F\x2D\x6A\x73","","\x61\x70\x69\x3F\x66\x75\x6E\x63\x74\x69\x6F\x6E\x49\x64\x3D","\x26\x62\x6F\x64\x79\x3D","\x26\x61\x70\x70\x69\x64\x3D\x6C\x69\x74\x65\x2D\x61\x6E\x64\x72\x6F\x69\x64\x26\x63\x6C\x69\x65\x6E\x74\x3D\x61\x6E\x64\x72\x6F\x69\x64\x26\x75\x75\x69\x64\x3D\x38\x34\x36\x63\x34\x63\x33\x32\x64\x61\x65\x39\x31\x30\x65\x66\x26\x63\x6C\x69\x65\x6E\x74\x56\x65\x72\x73\x69\x6F\x6E\x3D\x33\x2E\x31\x2E\x30\x26\x74\x3D","\x26\x73\x69\x67\x6E\x3D","\x61\x70\x69\x2E\x6D\x2E\x6A\x64\x2E\x63\x6F\x6D","\x2A\x2F\x2A","\x52\x4E","\x4A\x44\x4D\x6F\x62\x69\x6C\x65\x4C\x69\x74\x65\x2F\x33\x2E\x31\x2E\x30\x20\x28\x69\x50\x61\x64\x3B\x20\x69\x4F\x53\x20\x31\x34\x2E\x34\x3B\x20\x53\x63\x61\x6C\x65\x2F\x32\x2E\x30\x30\x29","\x7A\x68\x2D\x48\x61\x6E\x73\x2D\x43\x4E\x3B\x71\x3D\x31\x2C\x20\x6A\x61\x2D\x43\x4E\x3B\x71\x3D\x30\x2E\x39","\x75\x6E\x64\x65\x66\x69\x6E\x65\x64","\x6C\x6F\x67","\u5220\u9664","\u7248\u672C\u53F7\uFF0C\x6A\x73\u4F1A\u5B9A","\u671F\u5F39\u7A97\uFF0C","\u8FD8\u8BF7\u652F\u6301\u6211\u4EEC\u7684\u5DE5\u4F5C","\x6A\x73\x6A\x69\x61","\x6D\x69\x2E\x63\x6F\x6D"];function taskUrl(_0x7683x2,_0x7683x3= {}){let _0x7683x4=+ new Date();let _0x7683x5=`${__Oxb24bc[0x0]}${JSON[__Oxb24bc[0x1]](_0x7683x3)}${__Oxb24bc[0x2]}${_0x7683x2}${__Oxb24bc[0x3]}${_0x7683x4}${__Oxb24bc[0x4]}`;let _0x7683x6=__Oxb24bc[0x5];const _0x7683x7=$[__Oxb24bc[0x6]]()?require(__Oxb24bc[0x7]):CryptoJS;let _0x7683x8=_0x7683x7.HmacSHA256(_0x7683x5,_0x7683x6).toString();return {url:`${__Oxb24bc[0x8]}${JD_API_HOST}${__Oxb24bc[0x9]}${_0x7683x2}${__Oxb24bc[0xa]}${escape(JSON[__Oxb24bc[0x1]](_0x7683x3))}${__Oxb24bc[0xb]}${_0x7683x4}${__Oxb24bc[0xc]}${_0x7683x8}${__Oxb24bc[0x8]}`,headers:{'\x48\x6F\x73\x74':__Oxb24bc[0xd],'\x61\x63\x63\x65\x70\x74':__Oxb24bc[0xe],'\x6B\x65\x72\x6E\x65\x6C\x70\x6C\x61\x74\x66\x6F\x72\x6D':__Oxb24bc[0xf],'\x75\x73\x65\x72\x2D\x61\x67\x65\x6E\x74':__Oxb24bc[0x10],'\x61\x63\x63\x65\x70\x74\x2D\x6C\x61\x6E\x67\x75\x61\x67\x65':__Oxb24bc[0x11],'\x43\x6F\x6F\x6B\x69\x65':cookie}}}(function(_0x7683x9,_0x7683xa,_0x7683xb,_0x7683xc,_0x7683xd,_0x7683xe){_0x7683xe= __Oxb24bc[0x12];_0x7683xc= function(_0x7683xf){if( typeof alert!== _0x7683xe){alert(_0x7683xf)};if( typeof that!== _0x7683xe){that[__Oxb24bc[0x13]](_0x7683xf)}};_0x7683xb= function(_0x7683x7,_0x7683x9){return _0x7683x7+ _0x7683x9};_0x7683xd= _0x7683xb(__Oxb24bc[0x14],_0x7683xb(_0x7683xb(__Oxb24bc[0x15],__Oxb24bc[0x16]),__Oxb24bc[0x17]));try{_0x7683x9= __encode;if(!( typeof _0x7683x9!== _0x7683xe&& _0x7683x9=== _0x7683xb(__Oxb24bc[0x18],__Oxb24bc[0x19]))){_0x7683xc(_0x7683xd)}}catch(e){_0x7683xc(_0x7683xd)}})({}) + +function invite2() { + let t = +new Date() + var headers = { + 'Host': 'api.m.jd.com', + 'accept': 'application/json, text/plain, */*', + 'content-type': 'application/x-www-form-urlencoded', + 'origin': 'https://assignment.jd.com', + 'accept-language': 'zh-cn', + 'user-agent': 'jdltapp;iPad;3.1.0;14.4;a54abe779c8fbeb4e8e34f01fdc5cc4dd78173a2;network/wifi;ADID/BB69CC09-77D8-43A2-8645-CBC4CCE49911;hasUPPay/0;pushNoticeIsOpen/0;lang/zh_CN;model/iPad13,1;addressid/3438850002;hasOCPay/0;appBuild/1017;supportBestPay/0;pv/14.9;apprpd/ProductCoupon_MergeMain;ref/FSPromListViewController;psq/0;ads/;psn/a54abe779c8fbeb4e8e34f01fdc5cc4dd78173a2|27;jdv/0|kong|t_1000170135|tuiguang|notset|1613101365448|1613101365;adk/;app_device/IOS;pap/JA2020_3112531|3.1.0|IOS 14.4;Mozilla/5.0 (iPad; CPU OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'referer': 'https://assignment.jd.com/?inviterId=GaYxmFpHAG%2BJLi7W28KWYw==&lng=0.000000&lat=0.000000&sid=2131b85f0bcb82714e032402628cc2fw&un_area=12_904_50647_57886', + 'Cookie': cookie + }; + + var dataString = `functionId=TaskInviteService&body={"method":"participateInviteTask","data":{"channel":"1","encryptionInviterPin":"GaYxmFpHAG%2BJLi7W28KWYw%3D%3D","type":1}}&appid=market-task-h5&uuid=&_t=${t}`; + + var options = { + url: 'https://api.m.jd.com/', + headers: headers, + body: dataString + } + $.post(options, (err, resp, data) => { + // that.log(data) + }) +} + +function invite() { + let t = +new Date() + var headers = { + 'Host': 'api.m.jd.com', + 'accept': 'application/json, text/plain, */*', + 'content-type': 'application/x-www-form-urlencoded', + 'origin': 'https://invite-reward.jd.com', + 'accept-language': 'zh-cn', + 'user-agent': 'jdltapp;iPad;3.1.0;14.4;Mozilla/5.0 (iPad; CPU OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'referer': 'https://invite-reward.jd.com/?lng=0.000000&lat=0.000000&sid=2131b85f0bcb82714e032402628cc2fw&un_area=12_904_50647_57886', + 'Cookie': cookie + }; + + var dataString = `functionId=InviteFriendApiService&body={"method":"attendInviteActivity","data":{"inviterPin":"GaYxmFpHAG%2BJLi7W28KWYw%3D%3D","channel":1,"token":"","frontendInitStatus":""}}&referer=-1&eid=eidIf3dd8121b7sdmiBLGdxRR46OlWyh62kFAZogTJFnYqqRkwgr63%2BdGmMlcv7EQJ5v0HBic81xHXzXLwKM6fh3i963zIa7Ym2v5ehnwo2B7uDN92Q0&aid=&client=ios&clientVersion=14.4&networkType=wifi&fp=-1&appid=market-task-h5&_t=${t}`; + + var options = { + url: 'https://api.m.jd.com/?t=1613645706861', + headers: headers, + body: dataString + }; + $.post(options, (err, resp, data) => { + // that.log(data) + }) +} + +function TotalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.2.2;14.2;%E4%BA%AC%E4%B8%9C/9.2.2 CFNetwork/1206 Darwin/20.1.0") + } + } + $.post(options, (err, resp, data) => { + try { + if (err) { + that.log(`${JSON.stringify(err)}`) + that.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + that.log(`动动服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) +} + +function safeGet(data) { + try { + if (typeof JSON.parse(data) == "object") { + return true; + } + } catch (e) { + that.log(e); + that.log(`动动服务器访问数据为空,请检查自身设备网络情况`); + return false; + } +} + +function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + that.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } +} + +function taskGetUrl(function_id, body) { + return { + url: `https://api.m.jd.com/?appid=activities_platform&functionId=${function_id}&body=${escape(JSON.stringify(body))}&t=${+new Date()}`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + 'user-agent': $.isNode() ? (process.env.JS_USER_AGENT ? process.env.JS_USER_AGENT : (require('./JS_USER_AGENTS').USER_AGENT)) : ($.getdata('JSUA') ? $.getdata('JSUA') : "'jdltapp;iPad;3.1.0;14.4;network/wifi;Mozilla/5.0 (iPad; CPU OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'Accept-Language': 'zh-Hans-CN;q=1,en-CN;q=0.9', + 'Accept-Encoding': 'gzip, deflate, br', + 'Content-Type': "application/x-www-form-urlencoded", + "referer": "https://an.jd.com/babelDiy/Zeus/q1eB6WUB8oC4eH1BsCLWvQakVsX/index.html" + } + } +} + +function taskPostUrl(function_id, body) { + return { + url: `https://api.m.jd.com/`, + body: `appid=activities_platform&functionId=${function_id}&body=${escape(JSON.stringify(body))}&t=${+new Date()}`, + headers: { + 'Cookie': cookie, + 'Host': 'api.m.jd.com', + 'Accept': '*/*', + 'Connection': 'keep-alive', + // 'user-agent': $.isNode() ? (process.env.JS_USER_AGENT ? process.env.JS_USER_AGENT : (require('./JS_USER_AGENTS').USER_AGENT)) : ($.getdata('JSUA') ? $.getdata('JSUA') : "'jdltapp;iPad;3.1.0;14.4;network/wifi;Mozilla/5.0 (iPad; CPU OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1"), + 'user-agent': "jdltapp;iPhone;3.3.2;14.3;b488010ad24c40885d846e66931abaf532ed26a5;network/4g;hasUPPay/0;pushNoticeIsOpen/0;lang/zh_CN;model/iPhone11,8;addressid/2005183373;hasOCPay/0;appBuild/1049;supportBestPay/0;pv/220.46;apprpd/;ref/JDLTSubMainPageViewController;psq/0;ads/;psn/b488010ad24c40885d846e66931abaf532ed26a5|520;jdv/0|iosapp|t_335139774|liteshare|CopyURL|1618673222002|1618673227;adk/;app_device/IOS;pap/JA2020_3112531|3.3.2|IOS 14.3;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1 ", + 'Accept-Language': 'zh-Hans-CN;q=1,en-CN;q=0.9', + 'Accept-Encoding': 'gzip, deflate, br', + 'Content-Type': "application/x-www-form-urlencoded", + "referer": "https://an.jd.com/babelDiy/Zeus/q1eB6WUB8oC4eH1BsCLWvQakVsX/index.html" + } + } +} + + +//我加的函数 +function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动极速签到", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") +} + + +function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } +} + +function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address +} \ No newline at end of file diff --git a/src/main/resources/test_try_joy.js b/src/main/resources/test_try_joy.js new file mode 100644 index 0000000..a86cfd7 --- /dev/null +++ b/src/main/resources/test_try_joy.js @@ -0,0 +1,1099 @@ +/* + * 由ZCY01二次修改:脚本默认不运行 + * 由 X1a0He 修复:依然保持脚本默认不运行 + * 如需运行请自行添加环境变量:JD_TRY,值填 true 即可运行 + * TG交流群:https://t.me/jd_zero205 + * TG通知频道:https://t.me/jd_zero205_tz + * + update 2021/09/05 + 京东试用:脚本更新地址 https://github.com/zero205/JD_tencent_scf/raw/main/jd_try.js + 脚本兼容: Node.js + 每天最多关注300个商店,但用户商店关注上限为500个。 + 请配合取关脚本试用,使用 jd_unsubscribe.js 提前取关至少250个商店确保京东试用脚本正常运行。 + * + * X1a0He留 + * 由于没有兼容Qx,原脚本已失效,建议原脚本的兼容Qx注释删了 + * 脚本是否耗时只看args_xh.maxLength的大小 + * 上一作者说了每天最多300个商店,总上限为500个,jd_unsubscribe.js我已更新为批量取关版 + * 请提前取关至少250个商店确保京东试用脚本正常运行 + * 没有写通知,是否申请成功没有进行通知,但脚本会把状态log出日志 + */ + let maxSize = 20 + const $ = new Env('京东试用') + const URL = 'https://api.m.jd.com/client.action' + let trialActivityIdList = [] + let trialActivityTitleList = [] + let notifyMsg = '' + let message = "" + let process={ + env:{ + "JD_TRY":"true" + } + } + // default params + let args_xh = { + /* + * 是否进行通知 + * 可设置环境变量:JD_TRY_NOTIFY + * */ + // isNotify: process.env.JD_TRY_NOTIFY || true, + // 商品原价,低于这个价格都不会试用 + jdPrice: process.env.JD_TRY_PRICE || 0, + /* + * 获取试用商品类型,默认为1 + * 1 - 精选 + * 2 - 闪电试用 + * 3 - 家用电器(可能会有变化) + * 4 - 手机数码(可能会有变化) + * 5 - 电脑办公(可能会有变化) + * 可设置环境变量:JD_TRY_TABID + * */ + // TODO: tab ids as array(support multi tabIds) + // tabId: process.env.JD_TRY_TABID && process.env.JD_TRY_TABID.split('@').map(Number) || [1], + tabId: process.env.JD_TRY_TABID || 1, + /* + * 试用商品标题过滤 + * 可设置环境变量:JD_TRY_TITLEFILTERS,关键词与关键词之间用@分隔 + * */ + titleFilters: process.env.JD_TRY_TITLEFILTERS && process.env.JD_TRY_TITLEFILTERS.split('@') || ["避孕","锁精","延时","延迟","润滑","私处","跳蛋","乳贴","情趣","龟头","自慰","啪啪","情趣","避孕套","润滑","延时","飞机杯"], + // 试用价格(中了要花多少钱),高于这个价格都不会试用,小于等于才会试用 + trialPrice: 100, + /* + * 最小提供数量,例如试用商品只提供2份试用资格,当前设置为1,则会进行申请 + * 若只提供5分试用资格,当前设置为10,则不会申请 + * 可设置环境变量:JD_TRY_MINSUPPLYNUM + * */ + minSupplyNum: process.env.JD_TRY_MINSUPPLYNUM || 1, + /* + * 过滤大于设定值的已申请人数,例如下面设置的1000,A商品已经有1001人申请了,则A商品不会进行申请,会被跳过 + * 可设置环境变量:JD_TRY_APPLYNUMFILTER + * */ + applyNumFilter: process.env.JD_TRY_APPLYNUMFILTER || 99999, + /* + * 商品试用之间和获取商品之间的间隔, 单位:毫秒(1秒=1000毫秒) + * 可设置环境变量:JD_TRY_APPLYINTERVAL + * */ + applyInterval: process.env.JD_TRY_APPLYINTERVAL || 5000, + /* + * 商品数组的最大长度,通俗来说就是即将申请的商品队列长度 + * 例如设置为20,当第一次获取后获得12件,过滤后剩下5件,将会进行第二次获取,过滤后加上第一次剩余件数 + * 例如是18件,将会进行第三次获取,直到过滤完毕后为20件才会停止,不建议设置太大 + * 可设置环境变量:JD_TRY_MAXLENGTH + * */ + maxLength: 50 + } + + !(async() => { + // console.log(`\n本脚本默认不运行,也不建议运行\n如需运行请自行添加环境变量:JD_TRY,值填:true\n`) + await $.wait(1000) + if(process.env.JD_TRY && process.env.JD_TRY === 'true'){ + await requireConfig() + if(!$.cookiesArr[0]){ + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/', { + "open-url": "https://bean.m.jd.com/" + }) + return + } + for(let i = 0; i < $.cookiesArr.length; i++){ + message += "[通知] 动动试用(搞笑版) \n\n --- \n\n" + if($.cookiesArr[i]){ + $.cookie = $.cookiesArr[i]; + $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await totalBean(); + console.log(`\n开始【京东账号${$.index}】${$.nickName || $.UserName}\n`); + if(!$.isLogin){ + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, { + "open-url": "https://bean.m.jd.com/bean/signIndex.action" + }); + await $.notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + continue + } + + username = $.UserName + if ($.UserName == "jd_66ea783827d30"){ + username = "跑腿小弟" + } + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟锟" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康康" + } + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + + $.totalTry = 0 + $.totalSuccess = 0 + let size = 1; + while(trialActivityIdList.length < args_xh.maxLength && size < maxSize){ + console.log(`\n正在进行第 ${size} 次获取试用商品\n`) + await try_feedsList(1, size++) + await try_feedsList(2, size++) + await try_feedsList(5, size++) + await try_feedsList(16, size++) + if(trialActivityIdList.length < args_xh.maxLength){ + console.log(`间隔延时中,请等待 ${args_xh.applyInterval} ms`) + await $.wait(args_xh.applyInterval); + } + } + console.log("正在执行试用申请...") + await $.wait(args_xh.applyInterval); + for(let i = 0; i < trialActivityIdList.length; i++){ + await try_apply(trialActivityTitleList[i], trialActivityIdList[i]) + console.log(`间隔延时中,请等待 ${args_xh.applyInterval} ms\n`) + await $.wait(args_xh.applyInterval); + } + console.log("试用申请执行完毕...") + + // await try_MyTrials(1, 1) //申请中的商品 + await try_MyTrials(1, 2) //申请成功的商品 + // await try_MyTrials(1, 3) //申请失败的商品 + await showMsg() + } + postToDingTalk(message) + message = "" + } + await $.notify.sendNotify(`${$.name}`, notifyMsg); + } else { + console.log(`\n您未设置运行【京东试用】脚本,结束运行!\n`) + } + })().catch((e) => { + console.log(`❗️ ${$.name} 运行错误!\n${e}`) + }).finally(() => { + $.done() + }) + + function requireConfig(){ + return new Promise(resolve => { + console.log('开始获取配置文件\n') + $.notify = $.isNode() ? require('./sendNotify') : { sendNotify: async() => { } } + //获取 Cookies + $.cookiesArr = [] + if($.isNode()){ + //Node.js用户请在jdCookie.js处填写京东ck; + const jdCookieNode = require('./jdCookie.js'); + Object.keys(jdCookieNode).forEach((item) => { + if(jdCookieNode[item]){ + $.cookiesArr.push(jdCookieNode[item]) + } + }) + if(process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { }; + } else { + //IOS等用户直接用NobyDa的jd $.cookie + $.cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + console.log(`共${$.cookiesArr.length}个京东账号\n`) + for (const key in args_xh) { + if(typeof args_xh[key] == 'string') { + args_xh[key] = Number(args_xh[key]) + } + } + // console.debug(args_xh) + resolve() + }) + } + + //获取商品列表并且过滤 By X1a0He + function try_feedsList(tabId, page){ + return new Promise((resolve, reject) => { + const body = JSON.stringify({ + "tabId": `${tabId}`, + "page": page, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_feedsList', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.debug(data) + // return + data = JSON.parse(data) + if(data.success){ + $.totalPages = data.data.pages + console.log(`获取到商品 ${data.data.feedList.length} 条\n`) + for(let i = 0; i < data.data.feedList.length; i++){ + if(trialActivityIdList.length > args_xh.maxLength){ + console.log('商品列表长度已满.结束获取') + }else + if(data.data.feedList[i].applyState === 1){ + console.log(`商品已申请试用:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].applyState !== null){ + console.log(`商品状态异常,跳过:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].skuTitle){ + console.log(`检测第 ${page} 页 第 ${i + 1} 个商品\n${data.data.feedList[i].skuTitle}`) + if(parseFloat(data.data.feedList[i].jdPrice) <= args_xh.jdPrice){ + console.log(`商品被过滤,${data.data.feedList[i].jdPrice} < ${args_xh.jdPrice} \n`) + }else if(parseFloat(data.data.feedList[i].supplyNum) < args_xh.minSupplyNum && data.data.feedList[i].supplyNum !== null){ + console.log(`商品被过滤,提供申请的份数小于预设申请的份数 \n`) + }else if(parseFloat(data.data.feedList[i].applyNum) > args_xh.applyNumFilter && data.data.feedList[i].applyNum !== null){ + console.log(`商品被过滤,已申请试用人数大于预设人数 \n`) + }else if(parseFloat(data.data.feedList[i].trialPrice) > args_xh.trialPrice){ + console.log(`商品被过滤,期待价格高于预设价格 \n`) + }else if(args_xh.titleFilters.some(fileter_word => data.data.feedList[i].skuTitle.includes(fileter_word))){ + console.log(`商品通过,将加入试用组,trialActivityId为${data.data.feedList[i].trialActivityId}\n`) + trialActivityIdList.push(data.data.feedList[i].trialActivityId) + trialActivityTitleList.push(data.data.feedList[i].skuTitle) + } + }else{ + console.log('skuTitle解析异常') + return + } + } + console.log(`当前试用组id如下,长度为:${trialActivityIdList.length}\n${trialActivityIdList}\n`) + } else { + console.log(`💩 获得试用列表失败: ${data.message}`) + } + } + } catch(e){ + console.log(e); + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_apply(title, activityId){ + return new Promise((resolve, reject) => { + console.log(`申请试用商品中...`) + console.log(`商品:${title}`) + console.log(`id为:${activityId}`) + const body = JSON.stringify({ + "activityId": activityId, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_apply', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + $.totalTry++ + data = JSON.parse(data) + if(data.success && data.code === "1"){ // 申请成功 + message += "" + title + "\n\n" + console.log(data.message) + $.totalSuccess++ + } else if(data.code === "-106"){ + console.log(data.message) // 未在申请时间内! + } else if(data.code === "-110"){ + console.log(data.message) // 您的申请已成功提交,请勿重复申请… + } else if(data.code === "-120"){ + console.log(data.message) // 您还不是会员,本品只限会员申请试用,请注册会员后申请! + } else if(data.code === "-167"){ + console.log(data.message) // 抱歉,此试用需为种草官才能申请。查看下方详情了解更多。 + } else { + console.log("申请失败", JSON.stringify(data)) + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_MyTrials(page, selected){ + return new Promise((resolve, reject) => { + switch(selected){ + case 1: + console.log('正在获取已申请的商品...') + break; + case 2: + console.log('正在获取申请成功的商品...') + break; + case 3: + console.log('正在获取申请失败的商品...') + break; + default: + console.log('selected错误') + } + const body = JSON.stringify({ + "page": page, + "selected": selected, // 1 - 已申请 2 - 成功列表,3 - 失败列表 + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_MyTrials', body) + option.headers.Referer = 'https://pro.m.jd.com/' + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.log(data) + // return + data = JSON.parse(data) + if(data.success){ + //temp adjustment + if(selected == 2){ + if (data.success && data.data) { + $.successList = data.data.list.filter(item => { + if (item.text.text.includes('请尽快领取')){ + message += "" + item.text.text + "\n\n" + } + return item.text.text.includes('请尽快领取') + }) + console.log(`待领取: ${$.successList.length}个`) + } else { + console.log(`获得成功列表失败: ${data.message}`) + } + } + // if(data.data.list.length > 0){ + // for(let item of data.data.list){ + // console.log(`申请时间:${new Date(parseInt(item.applyTime)).toLocaleString()}`) + // console.log(`申请商品:${item.trialName}`) + // console.log(`当前状态:${item.text.text}`) + // console.log(`剩余时间:${remaining(item.leftTime)}`) + // console.log() + // } + // } else { + // switch(selected){ + // case 1: + // console.log('无已申请的商品\n') + // break; + // case 2: + // console.log('无申请成功的商品\n') + // break; + // case 3: + // console.log('无申请失败的商品\n') + // break; + // default: + // console.log('selected错误') + // } + // } + } else { + console.log(`ERROR:try_MyTrials`) + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function remaining(time){ + let days = parseInt(time / (1000 * 60 * 60 * 24)); + let hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + let minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60)); + return `${days} 天 ${hours} 小时 ${minutes} 分` + } + + function taskurl_xh(appid, functionId, body = JSON.stringify({})){ + return { + "url": `${URL}?appid=${appid}&functionId=${functionId}&clientVersion=10.1.2&client=wh5&body=${encodeURIComponent(body)}`, + 'headers': { + 'Host': 'api.m.jd.com', + 'Accept-Encoding': 'gzip, deflate, br', + 'Cookie': $.cookie, + 'Connection': 'keep-alive', + 'UserAgent': 'jdapp;iPhone;10.1.2;15.0;ff2caa92a8529e4788a34b3d8d4df66d9573f499;network/wifi;model/iPhone13,4;addressid/2074196292;appBuild/167802;jdSupportDarkMode/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://prodev.m.jd.com/' + }, + } + } + + async function showMsg(){ + let message1 = `京东账号${$.index} ${$.nickName || $.UserName}\n🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + message += "" + `🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + "\n\n" + if(!args_xh.jdNotify || args_xh.jdNotify === 'false'){ + $.msg($.name, ``, message1, { + "open-url": 'https://try.m.jd.com/user' + }) + if($.isNode()) + notifyMsg += `${message1}\n\n` + } else { + console.log(message1) + } + } + + function totalBean(){ + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": $.cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try{ + if(err){ + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if(data){ + data = JSON.parse(data); + if(data['retcode'] === 13){ + $.isLogin = false; //cookie过期 + return + } + if(data['retcode'] === 0){ + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch(e){ + $.logErr(e, resp) + } finally{ + resolve(); + } + }) + }) + } + + function jsonParse(str){ + if(typeof str == "string"){ + try{ + return JSON.parse(str); + } catch(e){ + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } + } + + // 来自 @chavyleung 大佬 + // https://raw.githubusercontent.com/chavyleung/scripts/master/Env.js + 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 + } + + 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 = () => { }){ + // 如果指定了请求体, 但没指定`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.post(opts, (err, resp, body) => { + if(!err && resp){ + resp.body = body + resp.statusCode = resp.status + } + callback(err, resp, body) + }) + } else if(this.isQuanX()){ + opts.method = 'POST' + 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.post(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 {*} fmt 格式化参数 + * + */ + time(fmt){ + let o = { + 'M+': new Date().getMonth() + 1, + 'd+': new Date().getDate(), + 'H+': new Date().getHours(), + 'm+': new Date().getMinutes(), + 's+': new Date().getSeconds(), + 'q+': Math.floor((new Date().getMonth() + 3) / 3), + 'S': new Date().getMilliseconds() + } + if(/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (new 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) + } + + + //我加的函数 + function postToDingTalk(messgae) { + const dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=18444b555747aad3381bc1d1e3dea72b03158e152a846f818d82a1ca946bd430" + + const message1 = "" + messgae + that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"动动试用(搞笑版)", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") + } + + + function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } + } + + function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address + } \ No newline at end of file diff --git a/src/main/resources/test_trytry.js b/src/main/resources/test_trytry.js new file mode 100644 index 0000000..2c40dfa --- /dev/null +++ b/src/main/resources/test_trytry.js @@ -0,0 +1,1148 @@ +/* + * 由ZCY01二次修改:脚本默认不运行 + * 由 X1a0He 修复:依然保持脚本默认不运行 + * 如需运行请自行添加环境变量:JD_TRY,值填 true 即可运行 + * TG交流群:https://t.me/jd_zero205 + * TG通知频道:https://t.me/jd_zero205_tz + * + update 2021/09/05 + 京东试用:脚本更新地址 https://github.com/zero205/JD_tencent_scf/raw/main/jd_try.js + 脚本兼容: Node.js + 每天最多关注300个商店,但用户商店关注上限为500个。 + 请配合取关脚本试用,使用 jd_unsubscribe.js 提前取关至少250个商店确保京东试用脚本正常运行。 + * + * X1a0He留 + * 由于没有兼容Qx,原脚本已失效,建议原脚本的兼容Qx注释删了 + * 脚本是否耗时只看args_xh.maxLength的大小 + * 上一作者说了每天最多300个商店,总上限为500个,jd_unsubscribe.js我已更新为批量取关版 + * 请提前取关至少250个商店确保京东试用脚本正常运行 + * 没有写通知,是否申请成功没有进行通知,但脚本会把状态log出日志 + */ + let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" + let maxSize = 15 + let totalPages = 999999 //总页数 + const $ = new Env('京东试用') + const URL = 'https://api.m.jd.com/client.action' + let trialActivityIdList = [] + let trialActivityTitleList = [] + let notifyMsg = '' + let message = "" + let maped = { + 0:[1,5,10], + 1:[5,1,10], + 2:[1,10,5], + 3:[10,5,1], + 4:[10,5,1], + 5:[5,10,1] + } + let process={ + env:{ + "JD_TRY":"true" + } + } + // default params + let args_xh = { + /* + * 是否进行通知 + * 可设置环境变量:JD_TRY_NOTIFY + * */ + // isNotify: process.env.JD_TRY_NOTIFY || true, + // 商品原价,低于这个价格都不会试用 + jdPrice: process.env.JD_TRY_PRICE || 0, + /* + * 获取试用商品类型,默认为1 + * 1 - 精选 + * 2 - 闪电试用 + * 3 - 家用电器(可能会有变化) + * 4 - 手机数码(可能会有变化) + * 5 - 电脑办公(可能会有变化) + * 可设置环境变量:JD_TRY_TABID + * */ + // TODO: tab ids as array(support multi tabIds) + // tabId: process.env.JD_TRY_TABID && process.env.JD_TRY_TABID.split('@').map(Number) || [1], + tabId: process.env.JD_TRY_TABID || 1, + /* + * 试用商品标题过滤 + * 可设置环境变量:JD_TRY_TITLEFILTERS,关键词与关键词之间用@分隔 + * */ + titleFilters: ["测电笔","测试","请勿下单", "牛舌","儿童玩具枪", "宣纸", "洋娃娃", "口琴","磨砂壳", "亲子互动", "防卫尖刺", "折叠锯子","牙签防水","购物券","材料包","水勺","碎发","整理棒","内裤","莆田官网","蚊香","遥控器","马桶垫","锅铲","电容笔","茶勺","瓜刨","耳钉","茶杯","滤杯","红绳","装修", "钥匙扣","美容院","芦荟","仿真小蛋糕","儿童便捷","遮瑕膏","香水","汽车摆件","水枪","润唇膏","衬衫","中老年","拐杖","牙签盒","电风扇罩","茶杯","袜子","掏耳","爬爬垫","滑板车","格子长袖","牙线","粉扑","粉扑盒子","停车牌","小勺子","爽肤水","防蚊裤","0-12岁","宝宝牙刷","玩具女孩","固定器","润唇膏","商务休闲", "儿童背包","塑料士兵小军人玩具","串珠玩具","儿童串珠玩具", "运势书","背心马甲","示宽灯","收银机","收钱码","空调罩","效果图","米小芽", "抵用券" ,"手工黏土", "儿童拌饭", "伊威", "菲妮小熊", "刀片" ,"割草机", "儿童n95","儿童口罩", "音频线","土工布","抑菌膏","win10","日历","玻璃吊","竖笛","角阀","三角阀","反光镜","倒车","童装","童装男女童","女童裤子","八倍镜","手提秤","电子秤","钓鱼手竿","鱼饵","护栏","栅网","狗链","切割片","汽油锯","滤芯","饲料","九九乘法","铁丝","监狱","隔离网","宝宝玩具车", "成长裤", "女士内裤", "小兔女士", "浮漂", "儿童磨牙饼", "墙纸", "壁纸", "传菜铃" ,"红包封", "光驱","挂绳","增高","宝宝鞋子", "女童裤子", "宝宝牙刷", "童装", "宝宝灯笼裤", "吃饭衣", "围兜", "牙刷收纳盒","安全锤","抛光机","机油","合成机油","铅笔","吸奶器","鱼钩","翻板钩","口罩盒","九九乘除","耐火泥","尼龙网","侧挂式","手术刀","喷雾器","注射器","驱虫","女士内裤,少女内裤","树苗","塑身裤","笼子","捆扎绳","打包绳","捆绑绳","插销","水乳","光和青春","测评","在线直播", "HDMI","LED","SD","SD卡","VGA","hdmi","hpv","led开关电源","windows","一次性","一片装","一盒","万用表","万藓灵","丝袜","中国电信","丰胸","丸","乳液","乳腺","交换","交换机","享底价","亿优信","会员","会员卡","会议杯子","便秘","保健","保护套","保暖女裤","保暖裤","修护","修眉","修眉剪","倒车镜","假睫毛","儿童奶粉","儿童口罩","儿童成长","充电头","充电桩","免钉胶水","养芝堂","内衣","冻干粉","净水剂","减肥","分流","分流器","别针","刮痧","刮痧板","刷牙头","剂","剃须刀配件","削皮刀","前列腺","剥虾","剪","剪钳","办公会议茶杯","办公杯","加温器","包皮","化妆","半身不遂","卡","卡套","卡尺","卡托","卧铺垫","卸妆","卸妆水","压片","参肽片","反光条贴","反光板","反光贴","口红","口腔","口腔抑菌","号码卡","同仁堂","吸顶灯","咬钩","咽炎","哑光","哨","哺乳","哺乳套装","唇釉","啪啪","嚼片","围裙","图钉","地吸","地漏","坐垫","培训","增生贴","墨","墨水","墨盒","墨粉","复合肥","外用","多功能尺子","天线","头","夹","奶瓶","奶粉","妆","妇女","婴","婴儿","孕妇装","学习卡","孩子","安全帽","安全裤","定做","定做榻榻米","定制","宝宝奶粉","宝宝口罩","宝宝成长","实验课","宠物","密封条","小学","尤尖锐湿疣","尺","尼龙管","尿","尿素","尿素霜","屏蔽袋","屏风","工作手册","工作服","巾","带","帽","幕","平衡线","幼儿","幼儿园","幼儿配方","座垫","座套","康复","延时","延迟","延迟喷雾","开果器","彩带","情趣","成人票","手册","手套","手机卡","手机壳","手机维修","打底","打草绳","打钉枪","托","扩音器","把手","护理","护肤","护腿套","护踝","报警器","抽屉轨道","拔毒膏","挂钩","指套","挑逗","挡风","挤奶器","掏耳朵","插座","摄像头镜片","敏感","敏肌","教","教学视频","教材","数据线","文胸","替换头","月子","有机肥","机顶盒","条码","架","染发剂","柔肤水","框","梯","梯子","模具","止痒","毛囊","毛孔","水平仪","水晶头","水龙头","汤勺","汽车脚垫","油漆","泡沫","泡沫胶","泥灸","注射针","泳衣","洁面","洗面","流量卡","浮标","润滑","润颜乳","液","清水剂","清洁","渔具","滤网","漆","漱口水","灯泡","灶台贴纸","烟","烧水棒","热熔胶枪","煤油","燃气报警器","爸爸装","牙刷头","牙刷替换头","牛仔裤","犬粮","狗狗沐浴露","狗粮","猪油","猫咪","猫咪玩具","猫玩具","猫砂","猫粮","玛咖片","玻尿酸","玻璃镜片","玻璃防雾剂","班","理发","用友","甲醛","电池","电缆剪","电话卡","电话牌","男士用品","男童","疣","疮","痉挛","痔疮","瘙痒","皮带","眉笔","眼影","眼镜","眼霜","睡裤","睫毛","矫正","矫正器","矫正带","砂盆","砂纸","硅胶","磨脚","磨脚石","祛斑霜","神露","福来油","空气滤芯","空调滤","窗帘","筒灯","筷子","管","粉刺","粉底","粉饼","精华","精华乳","精油","纱窗","纱网","纳米砖","纸尿裤","纹眉","纹眉色料","线上","线上课程","绑带","维修","维生素","绿幕","绿草皮","美容棒","美工刀","美甲","美缝","美胸","翻身","老人用品","老爷车","老花","考","耳塞","耳罩","职业装","肥佬","肥料","胖子","胶囊","胶带","脚垫","腋毛","腋毛神器","腮红","腰带","膜","自慰","舒缓水","色料","艾条","花萃","葛根","虾青素","蚊帐","蚯蚓粪","蟑螂药","补墙","补水","表带","袋","袖套","裁纸刀","裤头","裸妆","视线盲区贴纸","解码线","训练器","试听课","试用装","课","贴","赠品","足浴粉","车漆","车篓子","车轮","车锁","轨道","转换","转换器","转接","轮胎","轮胎专用胶水","软膏","辅食","运费专拍","连衣裙","适配","适配器","遮挡布","避光垫","避孕套","酒","金属探测","金属探测器","钉子","钙咀嚼片","钢化膜","钢化蛋","钳","铆管","锁精环","镜片","镰刀","长筒袜","门帘","门把手","门槛条","门锁","防撞条","防静电","阴囊","阴部","雨刮","雨披","雨衣","霜","露","青春痘","静电","静脉曲张","非卖品","面膜","鞋垫","鞋带","领结","额头贴","飞机","飞机杯","香薰精油","鱼线","鸭肠","鹿鞭","黄膏贴","鼠标垫","鼻影","鼻毛","鼻毛器","龟头","锯片","单拍不发货","火花塞","红花手套","温度计"], + // 试用价格(中了要花多少钱),高于这个价格都不会试用,小于等于才会试用 + trialPrice: 0, + /* + * 最小提供数量,例如试用商品只提供2份试用资格,当前设置为1,则会进行申请 + * 若只提供5分试用资格,当前设置为10,则不会申请 + * 可设置环境变量:JD_TRY_MINSUPPLYNUM + * */ + minSupplyNum: 20, + /* + * 过滤大于设定值的已申请人数,例如下面设置的1000,A商品已经有1001人申请了,则A商品不会进行申请,会被跳过 + * 可设置环境变量:JD_TRY_APPLYNUMFILTER + * */ + applyNumFilter: process.env.JD_TRY_APPLYNUMFILTER || 99999, + /* + * 商品试用之间和获取商品之间的间隔, 单位:毫秒(1秒=1000毫秒) + * 可设置环境变量:JD_TRY_APPLYINTERVAL + * */ + applyInterval: process.env.JD_TRY_APPLYINTERVAL || 5000, + /* + * 商品数组的最大长度,通俗来说就是即将申请的商品队列长度 + * 例如设置为20,当第一次获取后获得12件,过滤后剩下5件,将会进行第二次获取,过滤后加上第一次剩余件数 + * 例如是18件,将会进行第三次获取,直到过滤完毕后为20件才会停止,不建议设置太大 + * 可设置环境变量:JD_TRY_MAXLENGTH + * */ + maxLength: 10 + } + + !(async() => { + // console.log(`\n本脚本默认不运行,也不建议运行\n如需运行请自行添加环境变量:JD_TRY,值填:true\n`) + await $.wait(1000) + if(process.env.JD_TRY && process.env.JD_TRY === 'true'){ + await requireConfig() + if(!$.cookiesArr[0]){ + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/', { + "open-url": "https://bean.m.jd.com/" + }) + return + } + for(let i = 0; i < $.cookiesArr.length; i++){ + message += "[通知] 试用精选 \n\n --- \n\n" + if($.cookiesArr[i]){ + $.cookie = $.cookiesArr[i]; + $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await totalBean(); + console.log(`\n开始【京东账号${$.index}】${$.nickName || $.UserName}\n`); + if(!$.isLogin){ + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, { + "open-url": "https://bean.m.jd.com/bean/signIndex.action" + }); + await $.notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + continue + } + + username = $.UserName + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟子" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康子" + } + if($.UserName == "jd_66dcb31363ef6"){ + username = "涛子" + } + if($.UserName == "18070420956_p"){ + username = "奇怪子" + } + if($.UserName == "jd_45d917547c763"){ + username = "跑腿小弟子" + } + if ($.UserName == "jd_66ea783827d30"){ + username = "军子" + } + if ($.UserName == "jd_4311ac0ff4456"){ + username = "居子" + } + maxSize = Math.floor(Math.random() * (10) + 8) + args_xh.maxLength = Math.floor(Math.random() * (10) + 8) + let list = maped[Math.floor(Math.random() * (6) + 0)] + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + message = message + "最大页数:" + maxSize + "最大长度:"+ args_xh.maxLength +"申请列表:" + list +" \n\n " + + $.totalTry = 0 + $.totalSuccess = 0 + let size = 1; + + for (let i =0;i { + console.log(`❗️ ${$.name} 运行错误!\n${e}`) + postToDingTalk(e) + }).finally(() => { + $.done() + }) + + + function requireConfig(){ + return new Promise(resolve => { + console.log('开始获取配置文件\n') + $.notify = $.isNode() ? require('./sendNotify') : { sendNotify: async() => { } } + //获取 Cookies + $.cookiesArr = [] + if($.isNode()){ + //Node.js用户请在jdCookie.js处填写京东ck; + const jdCookieNode = require('./jdCookie.js'); + Object.keys(jdCookieNode).forEach((item) => { + if(jdCookieNode[item]){ + $.cookiesArr.push(jdCookieNode[item]) + } + }) + if(process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { }; + } else { + //IOS等用户直接用NobyDa的jd $.cookie + $.cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + console.log(`共${$.cookiesArr.length}个京东账号\n`) + for (const key in args_xh) { + if(typeof args_xh[key] == 'string') { + args_xh[key] = Number(args_xh[key]) + } + } + // console.debug(args_xh) + resolve() + }) + } + + //获取商品列表并且过滤 By X1a0He + function try_feedsList(tabId, page){ + return new Promise((resolve, reject) => { + const body = JSON.stringify({ + "tabId": `${tabId}`, + "page": page, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_feedsList', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.debug(data) + // return + data = JSON.parse(data) + if(data.success){ + $.totalPages = data.data.pages + totalPages = $.totalPages + console.log(`获取到商品 ${data.data.feedList.length} 条\n`) + for(let i = 0; i < data.data.feedList.length; i++){ + if(trialActivityIdList.length > args_xh.maxLength){ + console.log('商品列表长度已满.结束获取') + }else + if(data.data.feedList[i].applyState === 1){ + console.log(`商品已申请试用:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].applyState !== null){ + console.log(`商品状态异常,跳过:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].skuTitle){ + console.log(`检测第 ${page} 页 第 ${i + 1} 个商品\n${data.data.feedList[i].skuTitle}`) + if(parseFloat(data.data.feedList[i].jdPrice) <= args_xh.jdPrice){ + console.log(`商品被过滤,${data.data.feedList[i].jdPrice} < ${args_xh.jdPrice} \n`) + }else if(parseFloat(data.data.feedList[i].supplyNum) > args_xh.minSupplyNum && data.data.feedList[i].supplyNum !== null){ + console.log(`商品被过滤,提供申请的份数大于预设申请的份数 \n`) + }else if(parseFloat(data.data.feedList[i].applyNum) > args_xh.applyNumFilter && data.data.feedList[i].applyNum !== null){ + console.log(`商品被过滤,已申请试用人数大于预设人数 \n`) + }else if(parseFloat(data.data.feedList[i].trialPrice) > args_xh.trialPrice){ + console.log(`商品被过滤,期待价格高于预设价格 \n`) + }else if(args_xh.titleFilters.some(fileter_word => data.data.feedList[i].skuTitle.includes(fileter_word))){ + console.log('商品被过滤,含有关键词 \n') + }else{ + console.log(`商品通过,将加入试用组,trialActivityId为${data.data.feedList[i].trialActivityId}\n`) + trialActivityIdList.push(data.data.feedList[i].trialActivityId) + trialActivityTitleList.push(data.data.feedList[i].skuTitle) + } + }else{ + console.log('skuTitle解析异常') + return + } + } + console.log(`当前试用组id如下,长度为:${trialActivityIdList.length}\n${trialActivityIdList}\n`) + } else { + console.log(`💩 获得试用列表失败: ${data.message}`) + } + } + } catch(e){ + console.log(e); + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + console.log(`${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_apply(title, activityId){ + return new Promise((resolve, reject) => { + console.log(`申请试用商品中...`) + console.log(`商品:${title}`) + console.log(`id为:${activityId}`) + const body = JSON.stringify({ + "activityId": activityId, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_apply', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + $.totalTry++ + data = JSON.parse(data) + if(data.success && data.code === "1"){ // 申请成功 + message += "" + title + "\n\n" + message += "" + `--------` + "\n\n" + console.log(data.message) + $.totalSuccess++ + } else if(data.code === "-106"){ + console.log(data.message) // 未在申请时间内! + } else if(data.code === "-110"){ + console.log(data.message) // 您的申请已成功提交,请勿重复申请… + } else if(data.code === "-120"){ + console.log(data.message) // 您还不是会员,本品只限会员申请试用,请注册会员后申请! + } else if(data.code === "-167"){ + console.log(data.message) // 抱歉,此试用需为种草官才能申请。查看下方详情了解更多。 + } else { + console.log("申请失败", JSON.stringify(data)) + message += "" + JSON.stringify(data) + "\n\n" + message += "" + `--------` + "\n\n" + } + } + } catch(e){ + console.log(data) + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_MyTrials(page, selected){ + return new Promise((resolve, reject) => { + switch(selected){ + case 1: + console.log('正在获取已申请的商品...') + break; + case 2: + console.log('正在获取申请成功的商品...') + break; + case 3: + console.log('正在获取申请失败的商品...') + break; + default: + console.log('selected错误') + } + const body = JSON.stringify({ + "page": page, + "selected": selected, // 1 - 已申请 2 - 成功列表,3 - 失败列表 + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_MyTrials', body) + option.headers.Referer = 'https://pro.m.jd.com/' + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.log(data) + // return + data = JSON.parse(data) + if(data.success){ + //temp adjustment + if(selected == 2){ + if (data.success && data.data) { + $.successList = data.data.list.filter(item => { + + return item.text.text.includes('试用资格将保留10天') + }) + console.log(`待领取: ${$.successList.length}个`) + } else { + console.log(`获得成功列表失败: ${data.message}`) + } + } + + if(data.data.list.length > 0){ + let count = 0 + for(let item of data.data.list){ + console.log(`申请时间:${new Date(parseInt(item.applyTime)).toLocaleString()}`) + console.log(`申请商品:${item.trialName}`) + console.log(`当前状态:${item.text.text}`) + console.log(`剩余时间:${remaining(item.leftTime)}`) + console.log() + + if (count < 3){ + message += "" + `申请商品:${item.trialName}` + "\n\n" + message += "" + `当前状态:${item.text.text}` + "\n\n" + message += "" + `-----\n\n` + "\n\n" + count ++ + } + } + } + // else { + // switch(selected){ + // case 1: + // console.log('无已申请的商品\n') + // break; + // case 2: + // console.log('无申请成功的商品\n') + // break; + // case 3: + // console.log('无申请失败的商品\n') + // break; + // default: + // console.log('selected错误') + // } + // } + } else { + console.log(`ERROR:try_MyTrials`) + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function remaining(time){ + let days = parseInt(time / (1000 * 60 * 60 * 24)); + let hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + let minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60)); + return `${days} 天 ${hours} 小时 ${minutes} 分` + } + + function taskurl_xh(appid, functionId, body = JSON.stringify({})){ + return { + "url": `${URL}?appid=${appid}&functionId=${functionId}&clientVersion=10.1.2&client=wh5&body=${encodeURIComponent(body)}`, + 'headers': { + 'Host': 'api.m.jd.com', + 'Accept-Encoding': 'gzip, deflate, br', + 'Cookie': $.cookie, + 'Connection': 'keep-alive', + 'UserAgent': 'jdapp;iPhone;10.1.2;15.0;ff2caa92a8529e4788a34b3d8d4df66d9573f499;network/wifi;model/iPhone13,4;addressid/2074196292;appBuild/167802;jdSupportDarkMode/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://prodev.m.jd.com/' + }, + } + } + + async function showMsg(){ + let message1 = `京东账号${$.index} ${$.nickName || $.UserName}\n🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + message += "" + `🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + "\n\n" + if(!args_xh.jdNotify || args_xh.jdNotify === 'false'){ + $.msg($.name, ``, message1, { + "open-url": 'https://try.m.jd.com/user' + }) + if($.isNode()) + notifyMsg += `${message1}\n\n` + } else { + console.log(message1) + } + } + + function totalBean(){ + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": $.cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try{ + if(err){ + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if(data){ + data = JSON.parse(data); + if(data['retcode'] === 13){ + $.isLogin = false; //cookie过期 + return + } + if(data['retcode'] === 0){ + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch(e){ + $.logErr(e, resp) + } finally{ + resolve(); + } + }) + }) + } + + function jsonParse(str){ + if(typeof str == "string"){ + try{ + return JSON.parse(str); + } catch(e){ + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } + } + + // 来自 @chavyleung 大佬 + // https://raw.githubusercontent.com/chavyleung/scripts/master/Env.js + 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 + } + + 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 = () => { }){ + // 如果指定了请求体, 但没指定`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.post(opts, (err, resp, body) => { + if(!err && resp){ + resp.body = body + resp.statusCode = resp.status + } + callback(err, resp, body) + }) + } else if(this.isQuanX()){ + opts.method = 'POST' + 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.post(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 {*} fmt 格式化参数 + * + */ + time(fmt){ + let o = { + 'M+': new Date().getMonth() + 1, + 'd+': new Date().getDate(), + 'H+': new Date().getHours(), + 'm+': new Date().getMinutes(), + 's+': new Date().getSeconds(), + 'q+': Math.floor((new Date().getMonth() + 3) / 3), + 'S': new Date().getMilliseconds() + } + if(/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (new 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) + } + + + //我加的函数 + function postToDingTalk(messgae) { + const message1 = "" + messgae + // that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"试用精选", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": true + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") + } + + + function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } + } + + function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address + } \ No newline at end of file diff --git a/src/main/resources/test_trytry1.js b/src/main/resources/test_trytry1.js new file mode 100644 index 0000000..3021d00 --- /dev/null +++ b/src/main/resources/test_trytry1.js @@ -0,0 +1,1148 @@ +/* + * 由ZCY01二次修改:脚本默认不运行 + * 由 X1a0He 修复:依然保持脚本默认不运行 + * 如需运行请自行添加环境变量:JD_TRY,值填 true 即可运行 + * TG交流群:https://t.me/jd_zero205 + * TG通知频道:https://t.me/jd_zero205_tz + * + update 2021/09/05 + 京东试用:脚本更新地址 https://github.com/zero205/JD_tencent_scf/raw/main/jd_try.js + 脚本兼容: Node.js + 每天最多关注300个商店,但用户商店关注上限为500个。 + 请配合取关脚本试用,使用 jd_unsubscribe.js 提前取关至少250个商店确保京东试用脚本正常运行。 + * + * X1a0He留 + * 由于没有兼容Qx,原脚本已失效,建议原脚本的兼容Qx注释删了 + * 脚本是否耗时只看args_xh.maxLength的大小 + * 上一作者说了每天最多300个商店,总上限为500个,jd_unsubscribe.js我已更新为批量取关版 + * 请提前取关至少250个商店确保京东试用脚本正常运行 + * 没有写通知,是否申请成功没有进行通知,但脚本会把状态log出日志 + */ + + let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" + let maxSize = 15 + let totalPages = 999999 //总页数 + const $ = new Env('京东试用') + const URL = 'https://api.m.jd.com/client.action' + let trialActivityIdList = [] + let trialActivityTitleList = [] + let notifyMsg = '' + let message = "" + let maped = { + 0:[2,8,11], + 1:[8,2,11], + 2:[2,11,8], + 3:[8,11,2], + 4:[11,8,2], + 5:[11,2,8] + } + let process={ + env:{ + "JD_TRY":"true" + } + } + // default params + let args_xh = { + /* + * 是否进行通知 + * 可设置环境变量:JD_TRY_NOTIFY + * */ + // isNotify: process.env.JD_TRY_NOTIFY || true, + // 商品原价,低于这个价格都不会试用 + jdPrice: process.env.JD_TRY_PRICE || 0, + /* + * 获取试用商品类型,默认为1 + * 1 - 精选 + * 2 - 闪电试用 + * 3 - 家用电器(可能会有变化) + * 4 - 手机数码(可能会有变化) + * 5 - 电脑办公(可能会有变化) + * 可设置环境变量:JD_TRY_TABID + * */ + // TODO: tab ids as array(support multi tabIds) + // tabId: process.env.JD_TRY_TABID && process.env.JD_TRY_TABID.split('@').map(Number) || [1], + tabId: process.env.JD_TRY_TABID || 1, + /* + * 试用商品标题过滤 + * 可设置环境变量:JD_TRY_TITLEFILTERS,关键词与关键词之间用@分隔 + * */ + titleFilters: ["测电笔","测试","请勿下单", "牛舌","儿童玩具枪", "宣纸", "洋娃娃", "口琴","磨砂壳", "亲子互动", "防卫尖刺", "折叠锯子","牙签防水","购物券","材料包","水勺","碎发","整理棒","内裤","莆田官网","蚊香","遥控器","马桶垫","锅铲","电容笔","茶勺","瓜刨","耳钉","茶杯","滤杯","红绳","装修", "钥匙扣", "美容院","芦荟","仿真小蛋糕","儿童便捷","遮瑕膏","香水","汽车摆件","水枪","润唇膏","衬衫","中老年","拐杖","牙签盒","电风扇罩","茶杯","袜子","掏耳","爬爬垫","滑板车","格子长袖","牙线","粉扑","粉扑盒子","停车牌","小勺子","爽肤水","防蚊裤","0-12岁","宝宝牙刷","玩具女孩","固定器","润唇膏","商务休闲", "儿童背包","塑料士兵小军人玩具","串珠玩具","儿童串珠玩具", "运势书","背心马甲","示宽灯","收银机","收钱码","空调罩","效果图","米小芽", "抵用券" ,"手工黏土", "儿童拌饭", "伊威", "菲妮小熊", "刀片" ,"割草机", "儿童n95","儿童口罩", "音频线","土工布","抑菌膏","win10","日历","玻璃吊","竖笛","角阀","三角阀","反光镜","倒车","童装","童装男女童","女童裤子","八倍镜","手提秤","电子秤","钓鱼手竿","鱼饵","护栏","栅网","狗链","切割片","汽油锯","滤芯","饲料","九九乘法","铁丝","监狱","隔离网","宝宝玩具车", "成长裤", "女士内裤", "小兔女士", "浮漂", "儿童磨牙饼", "墙纸", "壁纸", "传菜铃" ,"红包封", "光驱","挂绳","增高","宝宝鞋子", "女童裤子", "宝宝牙刷", "童装", "宝宝灯笼裤", "吃饭衣", "围兜", "牙刷收纳盒","安全锤","抛光机","机油","合成机油","铅笔","吸奶器","鱼钩","翻板钩","口罩盒","九九乘除","耐火泥","尼龙网","侧挂式","手术刀","喷雾器","注射器","驱虫","女士内裤,少女内裤","树苗","塑身裤","笼子","捆扎绳","打包绳","捆绑绳","插销","水乳","光和青春","测评","在线直播", "HDMI","LED","SD","SD卡","VGA","hdmi","hpv","led开关电源","windows","一次性","一片装","一盒","万用表","万藓灵","丝袜","中国电信","丰胸","丸","乳液","乳腺","交换","交换机","享底价","亿优信","会员","会员卡","会议杯子","便秘","保健","保护套","保暖女裤","保暖裤","修护","修眉","修眉剪","倒车镜","假睫毛","儿童奶粉","儿童口罩","儿童成长","充电头","充电桩","免钉胶水","养芝堂","内衣","冻干粉","净水剂","减肥","分流","分流器","别针","刮痧","刮痧板","刷牙头","剂","剃须刀配件","削皮刀","前列腺","剥虾","剪","剪钳","办公会议茶杯","办公杯","加温器","包皮","化妆","半身不遂","卡","卡套","卡尺","卡托","卧铺垫","卸妆","卸妆水","压片","参肽片","反光条贴","反光板","反光贴","口红","口腔","口腔抑菌","号码卡","同仁堂","吸顶灯","咬钩","咽炎","哑光","哨","哺乳","哺乳套装","唇釉","啪啪","嚼片","围裙","图钉","地吸","地漏","坐垫","培训","增生贴","墨","墨水","墨盒","墨粉","复合肥","外用","多功能尺子","天线","头","夹","奶瓶","奶粉","妆","妇女","婴","婴儿","孕妇装","学习卡","孩子","安全帽","安全裤","定做","定做榻榻米","定制","宝宝奶粉","宝宝口罩","宝宝成长","实验课","宠物","密封条","小学","尤尖锐湿疣","尺","尼龙管","尿","尿素","尿素霜","屏蔽袋","屏风","工作手册","工作服","巾","带","帽","幕","平衡线","幼儿","幼儿园","幼儿配方","座垫","座套","康复","延时","延迟","延迟喷雾","开果器","彩带","情趣","成人票","手册","手套","手机卡","手机壳","手机维修","打底","打草绳","打钉枪","托","扩音器","把手","护理","护肤","护腿套","护踝","报警器","抽屉轨道","拔毒膏","挂钩","指套","挑逗","挡风","挤奶器","掏耳朵","插座","摄像头镜片","敏感","敏肌","教","教学视频","教材","数据线","文胸","替换头","月子","有机肥","机顶盒","条码","架","染发剂","柔肤水","框","梯","梯子","模具","止痒","毛囊","毛孔","水平仪","水晶头","水龙头","汤勺","汽车脚垫","油漆","泡沫","泡沫胶","泥灸","注射针","泳衣","洁面","洗面","流量卡","浮标","润滑","润颜乳","液","清水剂","清洁","渔具","滤网","漆","漱口水","灯泡","灶台贴纸","烟","烧水棒","热熔胶枪","煤油","燃气报警器","爸爸装","牙刷头","牙刷替换头","牛仔裤","犬粮","狗狗沐浴露","狗粮","猪油","猫咪","猫咪玩具","猫玩具","猫砂","猫粮","玛咖片","玻尿酸","玻璃镜片","玻璃防雾剂","班","理发","用友","甲醛","电池","电缆剪","电话卡","电话牌","男士用品","男童","疣","疮","痉挛","痔疮","瘙痒","皮带","眉笔","眼影","眼镜","眼霜","睡裤","睫毛","矫正","矫正器","矫正带","砂盆","砂纸","硅胶","磨脚","磨脚石","祛斑霜","神露","福来油","空气滤芯","空调滤","窗帘","筒灯","筷子","管","粉刺","粉底","粉饼","精华","精华乳","精油","纱窗","纱网","纳米砖","纸尿裤","纹眉","纹眉色料","线上","线上课程","绑带","维修","维生素","绿幕","绿草皮","美容棒","美工刀","美甲","美缝","美胸","翻身","老人用品","老爷车","老花","考","耳塞","耳罩","职业装","肥佬","肥料","胖子","胶囊","胶带","脚垫","腋毛","腋毛神器","腮红","腰带","膜","自慰","舒缓水","色料","艾条","花萃","葛根","虾青素","蚊帐","蚯蚓粪","蟑螂药","补墙","补水","表带","袋","袖套","裁纸刀","裤头","裸妆","视线盲区贴纸","解码线","训练器","试听课","试用装","课","贴","赠品","足浴粉","车漆","车篓子","车轮","车锁","轨道","转换","转换器","转接","轮胎","轮胎专用胶水","软膏","辅食","运费专拍","连衣裙","适配","适配器","遮挡布","避光垫","避孕套","酒","金属探测","金属探测器","钉子","钙咀嚼片","钢化膜","钢化蛋","钳","铆管","锁精环","镜片","镰刀","长筒袜","门帘","门把手","门槛条","门锁","防撞条","防静电","阴囊","阴部","雨刮","雨披","雨衣","霜","露","青春痘","静电","静脉曲张","非卖品","面膜","鞋垫","鞋带","领结","额头贴","飞机","飞机杯","香薰精油","鱼线","鸭肠","鹿鞭","黄膏贴","鼠标垫","鼻影","鼻毛","鼻毛器","龟头","锯片","单拍不发货","火花塞","红花手套","温度计"], + // 试用价格(中了要花多少钱),高于这个价格都不会试用,小于等于才会试用 + trialPrice: 0, + /* + * 最小提供数量,例如试用商品只提供2份试用资格,当前设置为1,则会进行申请 + * 若只提供5分试用资格,当前设置为10,则不会申请 + * 可设置环境变量:JD_TRY_MINSUPPLYNUM + * */ + minSupplyNum:20, + /* + * 过滤大于设定值的已申请人数,例如下面设置的1000,A商品已经有1001人申请了,则A商品不会进行申请,会被跳过 + * 可设置环境变量:JD_TRY_APPLYNUMFILTER + * */ + applyNumFilter: process.env.JD_TRY_APPLYNUMFILTER || 99999, + /* + * 商品试用之间和获取商品之间的间隔, 单位:毫秒(1秒=1000毫秒) + * 可设置环境变量:JD_TRY_APPLYINTERVAL + * */ + applyInterval: process.env.JD_TRY_APPLYINTERVAL || 5000, + /* + * 商品数组的最大长度,通俗来说就是即将申请的商品队列长度 + * 例如设置为20,当第一次获取后获得12件,过滤后剩下5件,将会进行第二次获取,过滤后加上第一次剩余件数 + * 例如是18件,将会进行第三次获取,直到过滤完毕后为20件才会停止,不建议设置太大 + * 可设置环境变量:JD_TRY_MAXLENGTH + * */ + maxLength: 10 + } + + !(async() => { + // console.log(`\n本脚本默认不运行,也不建议运行\n如需运行请自行添加环境变量:JD_TRY,值填:true\n`) + await $.wait(1000) + if(process.env.JD_TRY && process.env.JD_TRY === 'true'){ + await requireConfig() + if(!$.cookiesArr[0]){ + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/', { + "open-url": "https://bean.m.jd.com/" + }) + return + } + for(let i = 0; i < $.cookiesArr.length; i++){ + message += "[通知] 试用生鲜美食 \n\n --- \n\n" + if($.cookiesArr[i]){ + $.cookie = $.cookiesArr[i]; + $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await totalBean(); + console.log(`\n开始【京东账号${$.index}】${$.nickName || $.UserName}\n`); + if(!$.isLogin){ + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, { + "open-url": "https://bean.m.jd.com/bean/signIndex.action" + }); + await $.notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + continue + } + + username = $.UserName + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟子" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康子" + } + if($.UserName == "jd_66dcb31363ef6"){ + username = "涛子" + } + if($.UserName == "18070420956_p"){ + username = "奇怪子" + } + if($.UserName == "jd_45d917547c763"){ + username = "跑腿小弟子" + } + if ($.UserName == "jd_66ea783827d30"){ + username = "军子" + } + if ($.UserName == "jd_4311ac0ff4456"){ + username = "居子" + } + maxSize = Math.floor(Math.random() * (10) + 8) + args_xh.maxLength = Math.floor(Math.random() * (10) + 8) + let list = maped[Math.floor(Math.random() * (6) + 0)] + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + message = message + "最大页数:" + maxSize + "最大长度:"+ args_xh.maxLength +"申请列表:" + list +" \n\n " + + $.totalTry = 0 + $.totalSuccess = 0 + let size = 1; + + for (let i =0;i { + console.log(`❗️ ${$.name} 运行错误!\n${e}`) + postToDingTalk(e) + }).finally(() => { + $.done() + }) + + function requireConfig(){ + return new Promise(resolve => { + console.log('开始获取配置文件\n') + $.notify = $.isNode() ? require('./sendNotify') : { sendNotify: async() => { } } + //获取 Cookies + $.cookiesArr = [] + if($.isNode()){ + //Node.js用户请在jdCookie.js处填写京东ck; + const jdCookieNode = require('./jdCookie.js'); + Object.keys(jdCookieNode).forEach((item) => { + if(jdCookieNode[item]){ + $.cookiesArr.push(jdCookieNode[item]) + } + }) + if(process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { }; + } else { + //IOS等用户直接用NobyDa的jd $.cookie + $.cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + console.log(`共${$.cookiesArr.length}个京东账号\n`) + for (const key in args_xh) { + if(typeof args_xh[key] == 'string') { + args_xh[key] = Number(args_xh[key]) + } + } + // console.debug(args_xh) + resolve() + }) + } + + //获取商品列表并且过滤 By X1a0He + function try_feedsList(tabId, page){ + return new Promise((resolve, reject) => { + const body = JSON.stringify({ + "tabId": `${tabId}`, + "page": page, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_feedsList', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.debug(data) + // return + data = JSON.parse(data) + if(data.success){ + $.totalPages = data.data.pages + totalPages = $.totalPages + console.log(`获取到商品 ${data.data.feedList.length} 条\n`) + for(let i = 0; i < data.data.feedList.length; i++){ + if(trialActivityIdList.length > args_xh.maxLength){ + console.log('商品列表长度已满.结束获取') + }else + if(data.data.feedList[i].applyState === 1){ + console.log(`商品已申请试用:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].applyState !== null){ + console.log(`商品状态异常,跳过:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].skuTitle){ + console.log(`检测第 ${page} 页 第 ${i + 1} 个商品\n${data.data.feedList[i].skuTitle}`) + if(parseFloat(data.data.feedList[i].jdPrice) <= args_xh.jdPrice){ + console.log(`商品被过滤,${data.data.feedList[i].jdPrice} < ${args_xh.jdPrice} \n`) + }else if(parseFloat(data.data.feedList[i].supplyNum) > args_xh.minSupplyNum && data.data.feedList[i].supplyNum !== null){ + console.log(`商品被过滤,提供申请的份数大于预设申请的份数 \n`) + }else if(parseFloat(data.data.feedList[i].applyNum) > args_xh.applyNumFilter && data.data.feedList[i].applyNum !== null){ + console.log(`商品被过滤,已申请试用人数大于预设人数 \n`) + }else if(parseFloat(data.data.feedList[i].trialPrice) > args_xh.trialPrice){ + console.log(`商品被过滤,期待价格高于预设价格 \n`) + }else if(args_xh.titleFilters.some(fileter_word => data.data.feedList[i].skuTitle.includes(fileter_word))){ + console.log('商品被过滤,含有关键词 \n') + }else{ + console.log(`商品通过,将加入试用组,trialActivityId为${data.data.feedList[i].trialActivityId}\n`) + trialActivityIdList.push(data.data.feedList[i].trialActivityId) + trialActivityTitleList.push(data.data.feedList[i].skuTitle) + } + }else{ + console.log('skuTitle解析异常') + return + } + } + console.log(`当前试用组id如下,长度为:${trialActivityIdList.length}\n${trialActivityIdList}\n`) + } else { + console.log(`💩 获得试用列表失败: ${data.message}`) + } + } + } catch(e){ + console.log(e); + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + console.log(`${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_apply(title, activityId){ + return new Promise((resolve, reject) => { + console.log(`申请试用商品中...`) + console.log(`商品:${title}`) + console.log(`id为:${activityId}`) + const body = JSON.stringify({ + "activityId": activityId, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_apply', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + $.totalTry++ + data = JSON.parse(data) + if(data.success && data.code === "1"){ // 申请成功 + message += "" + title + "\n\n" + message += "" + `--------` + "\n\n" + console.log(data.message) + $.totalSuccess++ + } else if(data.code === "-106"){ + console.log(data.message) // 未在申请时间内! + } else if(data.code === "-110"){ + console.log(data.message) // 您的申请已成功提交,请勿重复申请… + } else if(data.code === "-120"){ + console.log(data.message) // 您还不是会员,本品只限会员申请试用,请注册会员后申请! + } else if(data.code === "-167"){ + console.log(data.message) // 抱歉,此试用需为种草官才能申请。查看下方详情了解更多。 + } else { + console.log("申请失败", JSON.stringify(data)) + message += "" + JSON.stringify(data) + "\n\n" + message += "" + `--------` + "\n\n" + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_MyTrials(page, selected){ + return new Promise((resolve, reject) => { + switch(selected){ + case 1: + console.log('正在获取已申请的商品...') + break; + case 2: + console.log('正在获取申请成功的商品...') + break; + case 3: + console.log('正在获取申请失败的商品...') + break; + default: + console.log('selected错误') + } + const body = JSON.stringify({ + "page": page, + "selected": selected, // 1 - 已申请 2 - 成功列表,3 - 失败列表 + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_MyTrials', body) + option.headers.Referer = 'https://pro.m.jd.com/' + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.log(data) + // return + data = JSON.parse(data) + if(data.success){ + //temp adjustment + if(selected == 2){ + if (data.success && data.data) { + $.successList = data.data.list.filter(item => { + + return item.text.text.includes('试用资格将保留10天') + }) + console.log(`待领取: ${$.successList.length}个`) + } else { + console.log(`获得成功列表失败: ${data.message}`) + } + } + if(data.data.list.length > 0){ + let count = 0 + for(let item of data.data.list){ + console.log(`申请时间:${new Date(parseInt(item.applyTime)).toLocaleString()}`) + console.log(`申请商品:${item.trialName}`) + console.log(`当前状态:${item.text.text}`) + console.log(`剩余时间:${remaining(item.leftTime)}`) + console.log() + + + if (count < 3){ + message += "" + `申请商品:${item.trialName}` + "\n\n" + message += "" + `当前状态:${item.text.text}` + "\n\n" + message += "" + `-----\n\n` + "\n\n" + count ++ + } + + } + } + // else { + // switch(selected){ + // case 1: + // console.log('无已申请的商品\n') + // break; + // case 2: + // console.log('无申请成功的商品\n') + // break; + // case 3: + // console.log('无申请失败的商品\n') + // break; + // default: + // console.log('selected错误') + // } + // } + } else { + console.log(`ERROR:try_MyTrials`) + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function remaining(time){ + let days = parseInt(time / (1000 * 60 * 60 * 24)); + let hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + let minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60)); + return `${days} 天 ${hours} 小时 ${minutes} 分` + } + + function taskurl_xh(appid, functionId, body = JSON.stringify({})){ + return { + "url": `${URL}?appid=${appid}&functionId=${functionId}&clientVersion=10.1.2&client=wh5&body=${encodeURIComponent(body)}`, + 'headers': { + 'Host': 'api.m.jd.com', + 'Accept-Encoding': 'gzip, deflate, br', + 'Cookie': $.cookie, + 'Connection': 'keep-alive', + 'UserAgent': 'jdapp;iPhone;10.1.2;15.0;ff2caa92a8529e4788a34b3d8d4df66d9573f499;network/wifi;model/iPhone13,4;addressid/2074196292;appBuild/167802;jdSupportDarkMode/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://prodev.m.jd.com/' + }, + } + } + + async function showMsg(){ + let message1 = `京东账号${$.index} ${$.nickName || $.UserName}\n🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + message += "" + `🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + "\n\n" + if(!args_xh.jdNotify || args_xh.jdNotify === 'false'){ + $.msg($.name, ``, message1, { + "open-url": 'https://try.m.jd.com/user' + }) + if($.isNode()) + notifyMsg += `${message1}\n\n` + } else { + console.log(message1) + } + } + + function totalBean(){ + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": $.cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try{ + if(err){ + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if(data){ + data = JSON.parse(data); + if(data['retcode'] === 13){ + $.isLogin = false; //cookie过期 + return + } + if(data['retcode'] === 0){ + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch(e){ + $.logErr(e, resp) + } finally{ + resolve(); + } + }) + }) + } + + function jsonParse(str){ + if(typeof str == "string"){ + try{ + return JSON.parse(str); + } catch(e){ + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } + } + + // 来自 @chavyleung 大佬 + // https://raw.githubusercontent.com/chavyleung/scripts/master/Env.js + 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 + } + + 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 = () => { }){ + // 如果指定了请求体, 但没指定`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.post(opts, (err, resp, body) => { + if(!err && resp){ + resp.body = body + resp.statusCode = resp.status + } + callback(err, resp, body) + }) + } else if(this.isQuanX()){ + opts.method = 'POST' + 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.post(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 {*} fmt 格式化参数 + * + */ + time(fmt){ + let o = { + 'M+': new Date().getMonth() + 1, + 'd+': new Date().getDate(), + 'H+': new Date().getHours(), + 'm+': new Date().getMinutes(), + 's+': new Date().getSeconds(), + 'q+': Math.floor((new Date().getMonth() + 3) / 3), + 'S': new Date().getMilliseconds() + } + if(/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (new 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) + } + + + //我加的函数 + function postToDingTalk(messgae) { + const message1 = "" + messgae + // that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"试用生鲜美食", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") + } + + + function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } + } + + function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address + } \ No newline at end of file diff --git a/src/main/resources/test_trytry2.js b/src/main/resources/test_trytry2.js new file mode 100644 index 0000000..5d1d6f5 --- /dev/null +++ b/src/main/resources/test_trytry2.js @@ -0,0 +1,1146 @@ +/* + * 由ZCY01二次修改:脚本默认不运行 + * 由 X1a0He 修复:依然保持脚本默认不运行 + * 如需运行请自行添加环境变量:JD_TRY,值填 true 即可运行 + * TG交流群:https://t.me/jd_zero205 + * TG通知频道:https://t.me/jd_zero205_tz + * + update 2021/09/05 + 京东试用:脚本更新地址 https://github.com/zero205/JD_tencent_scf/raw/main/jd_try.js + 脚本兼容: Node.js + 每天最多关注300个商店,但用户商店关注上限为500个。 + 请配合取关脚本试用,使用 jd_unsubscribe.js 提前取关至少250个商店确保京东试用脚本正常运行。 + * + * X1a0He留 + * 由于没有兼容Qx,原脚本已失效,建议原脚本的兼容Qx注释删了 + * 脚本是否耗时只看args_xh.maxLength的大小 + * 上一作者说了每天最多300个商店,总上限为500个,jd_unsubscribe.js我已更新为批量取关版 + * 请提前取关至少250个商店确保京东试用脚本正常运行 + * 没有写通知,是否申请成功没有进行通知,但脚本会把状态log出日志 + */ + + let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" + let maxSize = 15 + let totalPages = 999999 //总页数 + const $ = new Env('京东试用') + const URL = 'https://api.m.jd.com/client.action' + let trialActivityIdList = [] + let trialActivityTitleList = [] + let notifyMsg = '' + let message = "" + let maped = { + 0:[3,9,15], + 1:[9,15,3], + 2:[3,15,9], + 3:[15,3,9], + 4:[9,3,15], + 5:[15,9,3] + } + let process={ + env:{ + "JD_TRY":"true" + } + } + // default params + let args_xh = { + /* + * 是否进行通知 + * 可设置环境变量:JD_TRY_NOTIFY + * */ + // isNotify: process.env.JD_TRY_NOTIFY || true, + // 商品原价,低于这个价格都不会试用 + jdPrice: process.env.JD_TRY_PRICE || 0, + /* + * 获取试用商品类型,默认为1 + * 1 - 精选 + * 2 - 闪电试用 + * 3 - 家用电器(可能会有变化) + * 4 - 手机数码(可能会有变化) + * 5 - 电脑办公(可能会有变化) + * 可设置环境变量:JD_TRY_TABID + * */ + // TODO: tab ids as array(support multi tabIds) + // tabId: process.env.JD_TRY_TABID && process.env.JD_TRY_TABID.split('@').map(Number) || [1], + tabId: process.env.JD_TRY_TABID || 1, + /* + * 试用商品标题过滤 + * 可设置环境变量:JD_TRY_TITLEFILTERS,关键词与关键词之间用@分隔 + * */ + titleFilters: ["测电笔","测试","请勿下单", "牛舌","儿童玩具枪", "宣纸", "洋娃娃", "口琴","磨砂壳", "亲子互动", "防卫尖刺","折叠锯子","牙签防水","购物券","材料包","水勺","碎发","整理棒","内裤","莆田官网","蚊香","遥控器","马桶垫","锅铲","电容笔","茶勺","瓜刨","耳钉","茶杯","滤杯","红绳","装修", "钥匙扣","美容院","芦荟","仿真小蛋糕","儿童便捷","遮瑕膏","香水","汽车摆件","水枪","润唇膏","衬衫","中老年","拐杖","牙签盒","电风扇罩","茶杯","袜子","掏耳","爬爬垫","滑板车","格子长袖","牙线","粉扑","粉扑盒子","停车牌","小勺子","爽肤水","防蚊裤","0-12岁","宝宝牙刷","玩具女孩","固定器","润唇膏","商务休闲", "儿童背包","塑料士兵小军人玩具","串珠玩具","儿童串珠玩具", "运势书","背心马甲","示宽灯","收银机","收钱码","空调罩","效果图","米小芽", "抵用券" ,"手工黏土", "儿童拌饭", "伊威", "菲妮小熊", "刀片" ,"割草机", "儿童n95","儿童口罩", "音频线","土工布","抑菌膏","win10","日历","玻璃吊","竖笛","角阀","三角阀","反光镜","倒车","童装","童装男女童","女童裤子","八倍镜","手提秤","电子秤","钓鱼手竿","鱼饵","护栏","栅网","狗链","切割片","汽油锯","滤芯","饲料","九九乘法","铁丝","监狱","隔离网","宝宝玩具车", "成长裤", "女士内裤", "小兔女士", "浮漂", "儿童磨牙饼", "墙纸", "壁纸", "传菜铃" ,"红包封", "光驱","挂绳","增高","宝宝鞋子", "女童裤子", "宝宝牙刷", "童装", "宝宝灯笼裤", "吃饭衣", "围兜", "牙刷收纳盒","安全锤","抛光机","机油","合成机油","铅笔","吸奶器","鱼钩","翻板钩","口罩盒","九九乘除","耐火泥","尼龙网","侧挂式","手术刀","喷雾器","注射器","驱虫","女士内裤,少女内裤","树苗","塑身裤","笼子","捆扎绳","打包绳","捆绑绳","插销","水乳","光和青春","测评","在线直播", "HDMI","LED","SD","SD卡","VGA","hdmi","hpv","led开关电源","windows","一次性","一片装","一盒","万用表","万藓灵","丝袜","中国电信","丰胸","丸","乳液","乳腺","交换","交换机","享底价","亿优信","会员","会员卡","会议杯子","便秘","保健","保护套","保暖女裤","保暖裤","修护","修眉","修眉剪","倒车镜","假睫毛","儿童奶粉","儿童口罩","儿童成长","充电头","充电桩","免钉胶水","养芝堂","内衣","冻干粉","净水剂","减肥","分流","分流器","别针","刮痧","刮痧板","刷牙头","剂","剃须刀配件","削皮刀","前列腺","剥虾","剪","剪钳","办公会议茶杯","办公杯","加温器","包皮","化妆","半身不遂","卡","卡套","卡尺","卡托","卧铺垫","卸妆","卸妆水","压片","参肽片","反光条贴","反光板","反光贴","口红","口腔","口腔抑菌","号码卡","同仁堂","吸顶灯","咬钩","咽炎","哑光","哨","哺乳","哺乳套装","唇釉","啪啪","嚼片","围裙","图钉","地吸","地漏","坐垫","培训","增生贴","墨","墨水","墨盒","墨粉","复合肥","外用","多功能尺子","天线","头","夹","奶瓶","奶粉","妆","妇女","婴","婴儿","孕妇装","学习卡","孩子","安全帽","安全裤","定做","定做榻榻米","定制","宝宝奶粉","宝宝口罩","宝宝成长","实验课","宠物","密封条","小学","尤尖锐湿疣","尺","尼龙管","尿","尿素","尿素霜","屏蔽袋","屏风","工作手册","工作服","巾","带","帽","幕","平衡线","幼儿","幼儿园","幼儿配方","座垫","座套","康复","延时","延迟","延迟喷雾","开果器","彩带","情趣","成人票","手册","手套","手机卡","手机壳","手机维修","打底","打草绳","打钉枪","托","扩音器","把手","护理","护肤","护腿套","护踝","报警器","抽屉轨道","拔毒膏","挂钩","指套","挑逗","挡风","挤奶器","掏耳朵","插座","摄像头镜片","敏感","敏肌","教","教学视频","教材","数据线","文胸","替换头","月子","有机肥","机顶盒","条码","架","染发剂","柔肤水","框","梯","梯子","模具","止痒","毛囊","毛孔","水平仪","水晶头","水龙头","汤勺","汽车脚垫","油漆","泡沫","泡沫胶","泥灸","注射针","泳衣","洁面","洗面","流量卡","浮标","润滑","润颜乳","液","清水剂","清洁","渔具","滤网","漆","漱口水","灯泡","灶台贴纸","烟","烧水棒","热熔胶枪","煤油","燃气报警器","爸爸装","牙刷头","牙刷替换头","牛仔裤","犬粮","狗狗沐浴露","狗粮","猪油","猫咪","猫咪玩具","猫玩具","猫砂","猫粮","玛咖片","玻尿酸","玻璃镜片","玻璃防雾剂","班","理发","用友","甲醛","电池","电缆剪","电话卡","电话牌","男士用品","男童","疣","疮","痉挛","痔疮","瘙痒","皮带","眉笔","眼影","眼镜","眼霜","睡裤","睫毛","矫正","矫正器","矫正带","砂盆","砂纸","硅胶","磨脚","磨脚石","祛斑霜","神露","福来油","空气滤芯","空调滤","窗帘","筒灯","筷子","管","粉刺","粉底","粉饼","精华","精华乳","精油","纱窗","纱网","纳米砖","纸尿裤","纹眉","纹眉色料","线上","线上课程","绑带","维修","维生素","绿幕","绿草皮","美容棒","美工刀","美甲","美缝","美胸","翻身","老人用品","老爷车","老花","考","耳塞","耳罩","职业装","肥佬","肥料","胖子","胶囊","胶带","脚垫","腋毛","腋毛神器","腮红","腰带","膜","自慰","舒缓水","色料","艾条","花萃","葛根","虾青素","蚊帐","蚯蚓粪","蟑螂药","补墙","补水","表带","袋","袖套","裁纸刀","裤头","裸妆","视线盲区贴纸","解码线","训练器","试听课","试用装","课","贴","赠品","足浴粉","车漆","车篓子","车轮","车锁","轨道","转换","转换器","转接","轮胎","轮胎专用胶水","软膏","辅食","运费专拍","连衣裙","适配","适配器","遮挡布","避光垫","避孕套","酒","金属探测","金属探测器","钉子","钙咀嚼片","钢化膜","钢化蛋","钳","铆管","锁精环","镜片","镰刀","长筒袜","门帘","门把手","门槛条","门锁","防撞条","防静电","阴囊","阴部","雨刮","雨披","雨衣","霜","露","青春痘","静电","静脉曲张","非卖品","面膜","鞋垫","鞋带","领结","额头贴","飞机","飞机杯","香薰精油","鱼线","鸭肠","鹿鞭","黄膏贴","鼠标垫","鼻影","鼻毛","鼻毛器","龟头","锯片","单拍不发货","火花塞","红花手套","温度计"], + // 试用价格(中了要花多少钱),高于这个价格都不会试用,小于等于才会试用 + trialPrice: 0, + /* + * 最小提供数量,例如试用商品只提供2份试用资格,当前设置为1,则会进行申请 + * 若只提供5分试用资格,当前设置为10,则不会申请 + * 可设置环境变量:JD_TRY_MINSUPPLYNUM + * */ + minSupplyNum:20, + /* + * 过滤大于设定值的已申请人数,例如下面设置的1000,A商品已经有1001人申请了,则A商品不会进行申请,会被跳过 + * 可设置环境变量:JD_TRY_APPLYNUMFILTER + * */ + applyNumFilter: process.env.JD_TRY_APPLYNUMFILTER || 99999, + /* + * 商品试用之间和获取商品之间的间隔, 单位:毫秒(1秒=1000毫秒) + * 可设置环境变量:JD_TRY_APPLYINTERVAL + * */ + applyInterval: process.env.JD_TRY_APPLYINTERVAL || 5000, + /* + * 商品数组的最大长度,通俗来说就是即将申请的商品队列长度 + * 例如设置为20,当第一次获取后获得12件,过滤后剩下5件,将会进行第二次获取,过滤后加上第一次剩余件数 + * 例如是18件,将会进行第三次获取,直到过滤完毕后为20件才会停止,不建议设置太大 + * 可设置环境变量:JD_TRY_MAXLENGTH + * */ + maxLength: 10 + } + + !(async() => { + // console.log(`\n本脚本默认不运行,也不建议运行\n如需运行请自行添加环境变量:JD_TRY,值填:true\n`) + await $.wait(1000) + if(process.env.JD_TRY && process.env.JD_TRY === 'true'){ + await requireConfig() + if(!$.cookiesArr[0]){ + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/', { + "open-url": "https://bean.m.jd.com/" + }) + return + } + for(let i = 0; i < $.cookiesArr.length; i++){ + message += "[通知] 闪电试用 \n\n --- \n\n" + if($.cookiesArr[i]){ + $.cookie = $.cookiesArr[i]; + $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await totalBean(); + console.log(`\n开始【京东账号${$.index}】${$.nickName || $.UserName}\n`); + if(!$.isLogin){ + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, { + "open-url": "https://bean.m.jd.com/bean/signIndex.action" + }); + await $.notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + continue + } + + username = $.UserName + if ($.UserName == "jd_4521b375ebb5d"){ + username = "锟子" + } + if ($.UserName == "jd_542c10c0222bc"){ + username = "康子" + } + if($.UserName == "jd_66dcb31363ef6"){ + username = "涛子" + } + if($.UserName == "18070420956_p"){ + username = "奇怪子" + } + if($.UserName == "jd_45d917547c763"){ + username = "跑腿小弟子" + } + if ($.UserName == "jd_66ea783827d30"){ + username = "军子" + } + if ($.UserName == "jd_4311ac0ff4456"){ + username = "居子" + } + maxSize = Math.floor(Math.random() * (10) + 8) + args_xh.maxLength = Math.floor(Math.random() * (10) + 8) + let list = maped[Math.floor(Math.random() * (6) + 0)] + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + message = message + "最大页数:" + maxSize + "最大长度:"+ args_xh.maxLength +"申请列表:" + list +" \n\n " + + $.totalTry = 0 + $.totalSuccess = 0 + let size = 1; + + for (let i =0;i { + postToDingTalk(e) + console.log(`❗️ ${$.name} 运行错误!\n${e}`) + }).finally(() => { + $.done() + }) + + function requireConfig(){ + return new Promise(resolve => { + console.log('开始获取配置文件\n') + $.notify = $.isNode() ? require('./sendNotify') : { sendNotify: async() => { } } + //获取 Cookies + $.cookiesArr = [] + if($.isNode()){ + //Node.js用户请在jdCookie.js处填写京东ck; + const jdCookieNode = require('./jdCookie.js'); + Object.keys(jdCookieNode).forEach((item) => { + if(jdCookieNode[item]){ + $.cookiesArr.push(jdCookieNode[item]) + } + }) + if(process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { }; + } else { + //IOS等用户直接用NobyDa的jd $.cookie + $.cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + console.log(`共${$.cookiesArr.length}个京东账号\n`) + for (const key in args_xh) { + if(typeof args_xh[key] == 'string') { + args_xh[key] = Number(args_xh[key]) + } + } + // console.debug(args_xh) + resolve() + }) + } + + //获取商品列表并且过滤 By X1a0He + function try_feedsList(tabId, page){ + return new Promise((resolve, reject) => { + const body = JSON.stringify({ + "tabId": `${tabId}`, + "page": page, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_feedsList', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.debug(data) + // return + data = JSON.parse(data) + if(data.success){ + $.totalPages = data.data.pages + totalPages = data.data.pages + console.log(`获取到商品 ${data.data.feedList.length} 条\n`) + for(let i = 0; i < data.data.feedList.length; i++){ + if(trialActivityIdList.length > args_xh.maxLength){ + console.log('商品列表长度已满.结束获取') + }else + if(data.data.feedList[i].applyState === 1){ + console.log(`商品已申请试用:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].applyState !== null){ + console.log(`商品状态异常,跳过:${data.data.feedList[i].skuTitle}`) + continue + }else + if(data.data.feedList[i].skuTitle){ + console.log(`检测第 ${page} 页 第 ${i + 1} 个商品\n${data.data.feedList[i].skuTitle}`) + if(parseFloat(data.data.feedList[i].jdPrice) <= args_xh.jdPrice){ + console.log(`商品被过滤,${data.data.feedList[i].jdPrice} < ${args_xh.jdPrice} \n`) + }else if(parseFloat(data.data.feedList[i].supplyNum) > args_xh.minSupplyNum && data.data.feedList[i].supplyNum !== null){ + console.log(`商品被过滤,提供申请的份数大于预设申请的份数 \n`) + }else if(parseFloat(data.data.feedList[i].applyNum) > args_xh.applyNumFilter && data.data.feedList[i].applyNum !== null){ + console.log(`商品被过滤,已申请试用人数大于预设人数 \n`) + }else if(parseFloat(data.data.feedList[i].trialPrice) > args_xh.trialPrice){ + console.log(`商品被过滤,期待价格高于预设价格 \n`) + }else if(args_xh.titleFilters.some(fileter_word => data.data.feedList[i].skuTitle.includes(fileter_word))){ + console.log('商品被过滤,含有关键词 \n') + }else{ + console.log(`商品通过,将加入试用组,trialActivityId为${data.data.feedList[i].trialActivityId}\n`) + trialActivityIdList.push(data.data.feedList[i].trialActivityId) + trialActivityTitleList.push(data.data.feedList[i].skuTitle) + } + }else{ + console.log('skuTitle解析异常') + return + } + } + console.log(`当前试用组id如下,长度为:${trialActivityIdList.length}\n${trialActivityIdList}\n`) + } else { + console.log(`💩 获得试用列表失败: ${data.message}`) + } + } + } catch(e){ + console.log(e); + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + console.log(`${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_apply(title, activityId){ + return new Promise((resolve, reject) => { + console.log(`申请试用商品中...`) + console.log(`商品:${title}`) + console.log(`id为:${activityId}`) + const body = JSON.stringify({ + "activityId": activityId, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_apply', body) + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + $.totalTry++ + data = JSON.parse(data) + if(data.success && data.code === "1"){ // 申请成功 + message += "" + title + "\n\n" + message += "" + `-------\n\n` + "\n\n" + console.log(data.message) + $.totalSuccess++ + } else if(data.code === "-106"){ + console.log(data.message) // 未在申请时间内! + } else if(data.code === "-110"){ + console.log(data.message) // 您的申请已成功提交,请勿重复申请… + } else if(data.code === "-120"){ + console.log(data.message) // 您还不是会员,本品只限会员申请试用,请注册会员后申请! + } else if(data.code === "-167"){ + console.log(data.message) // 抱歉,此试用需为种草官才能申请。查看下方详情了解更多。 + } else { + console.log("申请失败", JSON.stringify(data)) + message += "" + JSON.stringify(data) + "\n\n" + message += "" + `-------\n\n` + "\n\n" + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function try_MyTrials(page, selected){ + return new Promise((resolve, reject) => { + switch(selected){ + case 1: + console.log('正在获取已申请的商品...') + break; + case 2: + console.log('正在获取申请成功的商品...') + break; + case 3: + console.log('正在获取申请失败的商品...') + break; + default: + console.log('selected错误') + } + const body = JSON.stringify({ + "page": page, + "selected": selected, // 1 - 已申请 2 - 成功列表,3 - 失败列表 + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_MyTrials', body) + option.headers.Referer = 'https://pro.m.jd.com/' + $.get(option, (err, resp, data) => { + try{ + if(err){ + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.log(data) + // return + data = JSON.parse(data) + if(data.success){ + //temp adjustment + if(selected == 2){ + if (data.success && data.data) { + $.successList = data.data.list.filter(item => { + return item.text.text.includes('试用资格将保留10天') + }) + console.log(`待领取: ${$.successList.length}个`) + } else { + console.log(`获得成功列表失败: ${data.message}`) + } + } + if(data.data.list.length > 0){ + let count = 0 + for(let item of data.data.list){ + console.log(`申请时间:${new Date(parseInt(item.applyTime)).toLocaleString()}`) + console.log(`申请商品:${item.trialName}`) + console.log(`当前状态:${item.text.text}`) + console.log(`剩余时间:${remaining(item.leftTime)}`) + + if (count < 3){ + message += "" + `申请商品:${item.trialName}` + "\n\n" + message += "" + `当前状态:${item.text.text}` + "\n\n" + message += "" + `-----\n\n` + "\n\n" + count ++ + } + + console.log() + } + } + // else { + // switch(selected){ + // case 1: + // console.log('无已申请的商品\n') + // break; + // case 2: + // console.log('无申请成功的商品\n') + // break; + // case 3: + // console.log('无申请失败的商品\n') + // break; + // default: + // console.log('selected错误') + // } + // } + } else { + console.log(`ERROR:try_MyTrials`) + } + } + } catch(e){ + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally{ + resolve() + } + }) + }) + } + + function remaining(time){ + let days = parseInt(time / (1000 * 60 * 60 * 24)); + let hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + let minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60)); + return `${days} 天 ${hours} 小时 ${minutes} 分` + } + + function taskurl_xh(appid, functionId, body = JSON.stringify({})){ + return { + "url": `${URL}?appid=${appid}&functionId=${functionId}&clientVersion=10.1.2&client=wh5&body=${encodeURIComponent(body)}`, + 'headers': { + 'Host': 'api.m.jd.com', + 'Accept-Encoding': 'gzip, deflate, br', + 'Cookie': $.cookie, + 'Connection': 'keep-alive', + 'UserAgent': 'jdapp;iPhone;10.1.2;15.0;ff2caa92a8529e4788a34b3d8d4df66d9573f499;network/wifi;model/iPhone13,4;addressid/2074196292;appBuild/167802;jdSupportDarkMode/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://prodev.m.jd.com/' + }, + } + } + + async function showMsg(){ + let message1 = `京东账号${$.index} ${$.nickName || $.UserName}\n🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + message += "" + `🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + "\n\n" + if(!args_xh.jdNotify || args_xh.jdNotify === 'false'){ + $.msg($.name, ``, message1, { + "open-url": 'https://try.m.jd.com/user' + }) + if($.isNode()) + notifyMsg += `${message1}\n\n` + } else { + console.log(message1) + } + } + + function totalBean(){ + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": $.cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try{ + if(err){ + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if(data){ + data = JSON.parse(data); + if(data['retcode'] === 13){ + $.isLogin = false; //cookie过期 + return + } + if(data['retcode'] === 0){ + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch(e){ + $.logErr(e, resp) + } finally{ + resolve(); + } + }) + }) + } + + function jsonParse(str){ + if(typeof str == "string"){ + try{ + return JSON.parse(str); + } catch(e){ + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } + } + + // 来自 @chavyleung 大佬 + // https://raw.githubusercontent.com/chavyleung/scripts/master/Env.js + 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 + } + + 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 = () => { }){ + // 如果指定了请求体, 但没指定`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.post(opts, (err, resp, body) => { + if(!err && resp){ + resp.body = body + resp.statusCode = resp.status + } + callback(err, resp, body) + }) + } else if(this.isQuanX()){ + opts.method = 'POST' + 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.post(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 {*} fmt 格式化参数 + * + */ + time(fmt){ + let o = { + 'M+': new Date().getMonth() + 1, + 'd+': new Date().getDate(), + 'H+': new Date().getHours(), + 'm+': new Date().getMinutes(), + 's+': new Date().getSeconds(), + 'q+': Math.floor((new Date().getMonth() + 3) / 3), + 'S': new Date().getMilliseconds() + } + if(/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (new 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) + } + + + //我加的函数 + function postToDingTalk(messgae) { + const message1 = "" + messgae + // that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title":"闪电试用", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": true + } + } + + + $.post(toDingtalk(dingtalk,JSON.stringify(body)), (data,status,xhr)=>{ + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + },"json") + } + + + function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body:bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } + } + + function getPic(){ + let code = ["1.gif","2.png","3.png","4.png","5.gif","6.gif","7.gif","8.gif","9.gif","10.png","11.png"] + let address = "\n\n ![screenshot](https://cdn.jsdelivr.net/gh/selfImprHuang/Go-Tool@v1.2/test/emptyDirTest/3/" + + pos = parseInt(11*Math.random()) + address = address + code[pos] + ")" + return address + } \ No newline at end of file diff --git a/src/main/resources/test_trytryOne.js b/src/main/resources/test_trytryOne.js new file mode 100644 index 0000000..de67631 --- /dev/null +++ b/src/main/resources/test_trytryOne.js @@ -0,0 +1,1226 @@ +/* + * 由ZCY01二次修改:脚本默认不运行 + * 由 X1a0He 修复:依然保持脚本默认不运行 + * 如需运行请自行添加环境变量:JD_TRY,值填 true 即可运行 + * TG交流群:https://t.me/jd_zero205 + * TG通知频道:https://t.me/jd_zero205_tz + * + update 2021/09/05 + 京东试用:脚本更新地址 https://github.com/zero205/JD_tencent_scf/raw/main/jd_try.js + 脚本兼容: Node.js + 每天最多关注300个商店,但用户商店关注上限为500个。 + 请配合取关脚本试用,使用 jd_unsubscribe.js 提前取关至少250个商店确保京东试用脚本正常运行。 + * + * X1a0He留 + * 由于没有兼容Qx,原脚本已失效,建议原脚本的兼容Qx注释删了 + * 脚本是否耗时只看args_xh.maxLength的大小 + * 上一作者说了每天最多300个商店,总上限为500个,jd_unsubscribe.js我已更新为批量取关版 + * 请提前取关至少250个商店确保京东试用脚本正常运行 + * 没有写通知,是否申请成功没有进行通知,但脚本会把状态log出日志 + */ + + let dingtalk = "https://oapi.dingtalk.com/robot/send?access_token=d2b6042cb38f0df63e20797c002208d2710104750c18a1dc84d54106a859a3f0" + let dingtalk1 = "https://oapi.dingtalk.com/robot/send?access_token=a3e80da6f064321881fc38e43a07bfde7a61b6f18245454520fb749556cebfcd" + let totalPages = 999999 //总页数 + const $ = new Env('京东试用') + const URL = 'https://api.m.jd.com/client.action' + let trialActivityIdList = [] + let sensMessage = "试用\n\n" + let trialActivityTitleList = [] + let notifyMsg = '' + let message = "" + let minItemValue = 500 + let wordLength = 1000 + let process = { + env: { + "JD_TRY": "true" + } + } + // default params + let args_xh = { + channelEnd: Math.floor(Math.random() * (4) + 3), + channel: [1,2,3,4,5,10,12,15], + maxSize: 15, + listCount: 0, + /* + * 是否进行通知 + * 可设置环境变量:JD_TRY_NOTIFY + * */ + // isNotify: process.env.JD_TRY_NOTIFY || true, + // 商品原价,低于这个价格都不会试用 + jdPrice: process.env.JD_TRY_PRICE || 0, + /* + * 获取试用商品类型,默认为1 + * 1 - 精选 + * 2 - 闪电试用 + * 3 - 家用电器(可能会有变化) + * 4 - 手机数码(可能会有变化) + * 5 - 电脑办公(可能会有变化) + * 可设置环境变量:JD_TRY_TABID + * */ + // TODO: tab ids as array(support multi tabIds) + // tabId: process.env.JD_TRY_TABID && process.env.JD_TRY_TABID.split('@').map(Number) || [1], + tabId: process.env.JD_TRY_TABID || 1, + /* + * 试用商品标题过滤 + * 可设置环境变量:JD_TRY_TITLEFILTERS,关键词与关键词之间用@分隔 + * */ + titleFilters: ["玻璃","清洁球","钢丝球","消毒液","泡澡球","隔音耳塞","翻分器","眼罩","乒乓球","布袋","枕头套","仓鼠零食","胸包","书包","周岁","抓周","干眼症","密码锁","防滑垫","椅背置物袋","艾脐贴","车内清洁","清洁刷","香薰","防疫","密封袋","早教","保鲜膜","底座","万向滑轮","高升专","专升本","学历","床头台灯","收敛水","鸡毛掸子","中国结","匙扣","糖糖粉","灭蝇","苍蝇药","苍蝇拍","假发","补发","陶瓷瓶","冷兵器","汽车椅背","擦玻璃","垃圾袋","擦窗","平光镜","眼镜","气垫霜","球帽","食盐","彩铅","手动幕","玻珠幕","玻珠","电脑电源","切菜板","隔热棉","过滤棉","园艺工具","砍菜刀","枇杷秋梨膏","唑溶液","滑块袋","育苗盘","隔热板","碟子","酵素","儿童吸管","体温计","茗杯","砂锅","呼噜","湿粮","膝盖贴","面酱","切菜板","油罐","油壶","茶具","茶宠","眼药水","体温计","儿童乐园","热敷包","茶壶","保温棉","双面板","消防水带","摄像头","除菌洗地液","地面清洁液","清洁配件","洗地专用","鱼缸","鱼竿","挂篓","茶壶","沉香","盘香","启动电源","摆件车模","摄像头","咖啡豆","投屏器","声卡套装","靠背收纳袋","切菜板","趴趴枕","洗地液","刹车油","提示牌","告知牌","警示牌","静音阻尼","信纸","信封","PVC板","标识牌","标志牌","锯条","摇步器","圣杯","撑衣杆","梳子","马桶刷","鱼缸","刨木","改光膜","手推车","电钻","行车记录仪","垃圾处理器","拉柳枪","花洒","自拍杆","百日宴","存储卡","艾绒贴","艾灸贴","清洁软胶","保护镜","uv镜","枇杷雪梨膏","枇杷膏","皮套","保护壳","徽墨","SUP掌机","台账本","墨条","墨块","去毛器","高清配件" ,"拾音器" ,"麦克风","类纸膜", "坐骨膏", "神经痛贴", "专用贴", "鸳鸯锅", "4/3膜", "镜头贴","后膜","摄像头膜", "镜头膜","去角质","死皮","U盘","接线式直管","香囊袋","防疫香包","炖盅","如意碗","汽车头枕腰靠套装","湿手器","汤盅","面碗","风水鱼","打印机碳带", "标签纸", "不干胶标签带:","清洁液","提词器", "卡针", "儿童电话手表", "绷带","短裙","护具","卡册","黄金卡","贴布","护腕","鼠标手","儿童牙膏","锁头","闹钟","储奶袋","母乳","儿童电动牙刷","涂鸦贴纸","贴纸","抚奶嘴","牙套","戒奶嘴","断奶","饭盒","水凝膜","覆盖膜","背膜","百褶","半身裙","牙膏","风湿贴","刺激贴","冷敷贴","腰肌劳损","键盘垫","扭扭车","孩儿乐","儿童沐浴露","眼线笔","贴膜","笔","屏幕膜","修正带","封口机","对接头","网线","少儿读物","遮瑕","惯性小汽车","皮筋枪","身体乳","救生衣","裤","鞋","三轮车","起雾棒","干洗剂","白酒", "口罩","碳粉","私处","创可贴", "脖套" ,"牵引器" ,"木糖醇","富贵包","延长器","网卡","泡泡纸","戒烟","喷壶","刷头","面霜","宝宝霜","黑头","眼袋","防晒霜","护手霜","精华露","鼻头","细纹霜","抬头纹","美肌霜","素颜霜","儿童保温水杯","滋养霜","帽子","护膝","领带","露指","飞机杯","打飞机","保护膜","大头围","儿童随身","马丁靴","爸爸鞋","理发推","理发器","刀头","幕布","挡风玻璃","挡风板","乳液","测电笔", "测试", "请勿下单", "牛舌", "儿童玩具枪", "宣纸", "洋娃娃", "口琴", "磨砂壳", "亲子互动", "防卫尖刺", "折叠锯子", "牙签防水", "购物券", "材料包", "水勺", "碎发", "整理棒", "内裤", "莆田官网", "蚊香", "空调遥控器", "电视遥控器", "马桶垫", "锅铲", "电容笔", "茶勺", "瓜刨", "耳钉", "茶杯", "滤杯", "红绳", "装修", "钥匙扣", "美容院", "芦荟", "仿真小蛋糕", "儿童便捷", "遮瑕膏", "汽车摆件", "水枪", "润唇膏", "衬衫", "中老年", "拐杖", "牙签盒", "电风扇罩", "茶杯", "袜子", "掏耳", "爬爬垫", "滑板车", "格子长袖", "牙线", "粉扑", "粉扑盒子", "停车牌", "小勺子", "爽肤水", "防蚊裤", "0-12岁", "宝宝牙刷", "玩具女孩", "固定器", "润唇膏", "商务休闲", "儿童背包", "塑料士兵小军人玩具", "串珠玩具", "儿童串珠玩具", "运势书", "背心马甲", "示宽灯", "收银机", "收钱码", "空调罩", "效果图", "米小芽", "抵用券", "手工黏土", "儿童拌饭", "伊威", "菲妮小熊", "刀片", "割草机", "儿童n95", "儿童口罩", "音频线", "土工布", "抑菌膏", "win10", "日历", "玻璃吊", "竖笛", "角阀", "三角阀", "反光镜", "倒车", "童装", "童装男女童", "女童裤子", "八倍镜", "手提秤", "电子秤", "钓鱼手竿", "鱼饵", "护栏", "栅网", "狗链", "切割片", "汽油锯", "滤芯", "饲料", "九九乘法", "铁丝", "监狱", "隔离网", "宝宝玩具车", "成长裤", "女士内裤", "小兔女士", "浮漂", "儿童磨牙饼", "墙纸", "壁纸", "传菜铃", "红包封", "光驱", "挂绳", "增高", "宝宝鞋子", "女童裤子", "宝宝牙刷", "童装", "宝宝灯笼裤", "吃饭衣", "围兜", "牙刷收纳盒", "安全锤", "抛光机", "机油", "合成机油", "铅笔", "吸奶器", "鱼钩", "翻板钩", "口罩盒", "九九乘除", "耐火泥", "尼龙网", "侧挂式", "手术刀", "喷雾器", "注射器", "驱虫", "女士内裤,少女内裤", "树苗", "塑身裤", "笼子", "捆扎绳", "打包绳", "捆绑绳", "插销", "水乳", "光和青春", "测评", "在线直播", "HDMI", "LED", "SD", "SD卡", "VGA", "hdmi", "hpv", "led开关电源", "windows", "一次性", "一片装", "一盒", "万用表", "万藓灵", "丝袜", "中国电信", "丰胸", "丸", "乳液", "乳腺", "交换", "交换机", "享底价", "亿优信", "会员", "会员卡", "会议杯子", "便秘", "保健", "保护套", "保暖女裤", "保暖裤", "修护", "修眉", "修眉剪", "倒车镜", "假睫毛", "儿童奶粉", "儿童口罩", "儿童成长", "充电头", "充电桩", "免钉胶水", "养芝堂", "内衣", "冻干粉", "净水剂", "减肥", "分流", "分流器", "别针", "刮痧", "刮痧板", "刷牙头", "剂", "剃须刀配件", "削皮刀", "前列腺", "剥虾", "剪", "剪钳", "办公会议茶杯", "办公杯", "加温器", "包皮", "化妆", "半身不遂", "卡套", "卡尺", "卡托", "卧铺垫", "卸妆", "卸妆水", "压片", "参肽片", "反光条贴", "反光板", "反光贴", "口红", "口腔", "口腔抑菌", "号码卡", "同仁堂", "吸顶灯", "咬钩", "咽炎", "哑光", "哨", "哺乳", "哺乳套装", "唇釉", "啪啪", "嚼片", "围裙", "图钉", "地漏", "坐垫", "培训", "增生贴", "墨水", "墨盒", "墨粉", "复合肥", "外用", "多功能尺子", "天线", "夹", "奶瓶", "奶粉", "妆", "妇女", "婴幼儿", "婴儿", "孕妇装", "学习卡", "安全帽", "安全裤", "定做", "定做榻榻米", "定制", "宝宝奶粉", "宝宝口罩", "宝宝成长", "实验课", "宠物", "密封条", "小学", "尤尖锐湿疣", "尺", "尼龙管", "尿", "尿素", "尿素霜", "屏蔽袋", "屏风", "工作手册", "工作服", "巾", "平衡线", "幼儿", "幼儿园", "幼儿配方", "座垫", "座套", "康复", "延时", "延迟", "延迟喷雾", "开果器", "彩带", "情趣", "成人票", "手册", "手套", "手机卡", "手机壳", "手机维修", "打底", "打草绳", "打钉枪", "扩音器", "把手", "护理", "护肤", "护腿套", "护踝", "报警器", "抽屉轨道", "拔毒膏", "挂钩", "指套", "挑逗", "挤奶器", "掏耳朵", "插座", "摄像头镜片", "敏感", "敏肌", "教学","教育", "教学视频", "教材", "数据线", "文胸", "替换头", "月子", "有机肥", "机顶盒", "条码", "架", "染发剂", "柔肤水", "框", "梯", "梯子", "模具", "止痒", "毛囊", "毛孔", "水平仪", "水晶头", "水龙头", "汤勺", "汽车脚垫", "油漆", "泡沫", "泡沫胶", "泥灸", "注射针", "泳衣", "洁面", "洗面", "流量卡", "浮标", "润滑", "润颜乳", "清水剂", "渔具", "滤网", "漆", "漱口水", "灯泡", "灶台贴纸", "烧水棒", "热熔胶枪", "煤油", "燃气报警器", "爸爸装", "牙刷头", "牙刷替换头", "牛仔裤", "犬粮", "狗狗沐浴露", "狗粮", "猪油", "猫咪", "猫咪玩具", "猫玩具", "猫砂", "猫粮", "玛咖片", "玻尿酸", "玻璃镜片", "玻璃防雾剂", "用友", "甲醛", "电池", "电缆剪", "电话卡", "电话牌", "男士用品", "男童", "疣", "疮", "痉挛", "痔疮", "瘙痒", "皮带", "眉笔", "眼影", "眼镜", "眼霜", "睡裤", "睫毛", "矫正", "矫正器", "矫正带", "砂盆", "砂纸", "硅胶", "磨脚", "磨脚石", "祛斑霜", "神露", "福来油", "空气滤芯", "空调滤", "窗帘", "筒灯", "筷子", "粉刺", "粉底", "粉饼", "精华", "精华乳", "精油", "纱窗", "纱网", "纳米砖", "纸尿裤", "纹眉", "纹眉色料", "线上", "线上课程", "绑带", "维修", "维生素", "绿幕", "绿草皮", "美容棒", "美工刀", "美甲", "美缝", "美胸", "翻身", "老人用品", "老爷车", "老花", "考", "耳罩", "职业装", "肥佬", "肥料", "胖子", "胶囊", "胶带", "脚垫", "腋毛", "腋毛神器", "腮红", "腰带", "自慰", "舒缓水", "色料", "艾条", "花萃", "葛根", "虾青素", "蚊帐", "蚯蚓粪", "蟑螂药", "补墙", "补水", "表带", "袖套", "裁纸刀", "裤头", "裸妆", "视线盲区贴纸", "解码线", "训练器", "试听课", "试用装", "课", "赠品", "足浴粉", "车漆", "车篓子", "车轮", "车锁", "轨道", "转换", "转换器", "转接", "轮胎", "轮胎专用胶水", "软膏", "辅食", "运费专拍", "连衣裙", "适配", "适配器", "遮挡布", "避光垫", "避孕套", "酒", "金属探测", "金属探测器", "钉子", "钙咀嚼片", "钢化膜", "钢化蛋", "钳", "铆管", "锁精环", "镜片", "镰刀", "长筒袜", "门帘", "门把手", "门槛条", "门锁", "防撞条", "防静电", "阴囊", "阴部", "雨刮", "雨披", "雨衣", "青春痘", "静电", "静脉曲张", "非卖品", "面膜", "鞋垫", "鞋带", "领结", "额头贴", "飞机杯", "香薰精油", "鱼线", "鸭肠", "鹿鞭", "黄膏贴", "鼠标垫", "鼻影", "鼻毛", "鼻毛器", "龟头", "锯片", "单拍不发货", "火花塞", "红花手套", "温度计"], + // 试用价格(中了要花多少钱),高于这个价格都不会试用,小于等于才会试用 + trialPrice: 0, + /* + * 最小提供数量,例如试用商品只提供2份试用资格,当前设置为1,则会进行申请 + * 若只提供5分试用资格,当前设置为10,则不会申请 + * 可设置环境变量:JD_TRY_MINSUPPLYNUM + * */ + minSupplyNum: 20, + /* + * 过滤大于设定值的已申请人数,例如下面设置的1000,A商品已经有1001人申请了,则A商品不会进行申请,会被跳过 + * 可设置环境变量:JD_TRY_APPLYNUMFILTER + * */ + applyNumFilter: process.env.JD_TRY_APPLYNUMFILTER || 99999, + /* + * 商品试用之间和获取商品之间的间隔, 单位:毫秒(1秒=1000毫秒) + * 可设置环境变量:JD_TRY_APPLYINTERVAL + * */ + applyInterval: process.env.JD_TRY_APPLYINTERVAL || 5000, + /* + * 商品数组的最大长度,通俗来说就是即将申请的商品队列长度 + * 例如设置为20,当第一次获取后获得12件,过滤后剩下5件,将会进行第二次获取,过滤后加上第一次剩余件数 + * 例如是18件,将会进行第三次获取,直到过滤完毕后为20件才会停止,不建议设置太大 + * 可设置环境变量:JD_TRY_MAXLENGTH + * */ + maxLength: 10 + + } + + !(async () => { + // console.log(`\n本脚本默认不运行,也不建议运行\n如需运行请自行添加环境变量:JD_TRY,值填:true\n`) + await $.wait(1000) + if (process.env.JD_TRY && process.env.JD_TRY === 'true') { + await requireConfig() + if (!$.cookiesArr[0]) { + $.msg($.name, '【提示】请先获取京东账号一cookie\n直接使用NobyDa的京东签到获取', 'https://bean.m.jd.com/', { + "open-url": "https://bean.m.jd.com/" + }) + return + } + for (let i = 0; i < $.cookiesArr.length; i++) { + message += "[通知] 随机试用 \n\n --- \n\n" + await $.wait(Math.floor(Math.random() * (10000) + 5000)); + if ($.cookiesArr[i]) { + $.cookie = $.cookiesArr[i]; + $.UserName = decodeURIComponent($.cookie.match(/pt_pin=(.+?);/) && $.cookie.match(/pt_pin=(.+?);/)[1]) + $.index = i + 1; + $.isLogin = true; + $.nickName = ''; + await totalBean(); + console.log(`\n开始【京东账号${$.index}】${$.nickName || $.UserName}\n`); + if (!$.isLogin) { + $.msg($.name, `【提示】cookie已失效`, `京东账号${$.index} ${$.nickName || $.UserName}\n请重新登录获取\nhttps://bean.m.jd.com/bean/signIndex.action`, { + "open-url": "https://bean.m.jd.com/bean/signIndex.action" + }); + await $.notify.sendNotify(`${$.name}cookie已失效 - ${$.UserName}`, `京东账号${$.index} ${$.UserName}\n请重新登录获取cookie`); + continue + } + + username = $.UserName + if ($.UserName == "jd_4521b375ebb5d") { + username = "锟子" + } + if ($.UserName == "jd_542c10c0222bc") { + username = "康子" + } + if ($.UserName == "jd_66dcb31363ef6") { + username = "涛子" + } + if ($.UserName == "18070420956_p") { + username = "奇怪子" + } + if ($.UserName == "jd_45d917547c763") { + username = "跑腿小弟子" + } + if ($.UserName == "jd_66ea783827d30") { + username = "军子" + } + if ($.UserName == "jd_4311ac0ff4456") { + username = "居子" + } + args_xh.maxLength = Math.floor(Math.random() * (20) + 10) + let list = getList() + //加上名称 + message = message + "【羊毛姐妹】" + username + " \n\n " + message = message + "" + "数量大小:" + args_xh.maxLength + "申请列表:" + list + " \n\n " + + $.totalTry = 0 + $.totalSuccess = 0 + let size = 1; + + m = i + for (let i = 0; i < list.length; i++) { + args_xh.maxSize = Math.floor(Math.random() * (30) + 10) + message = message + "" + "最大列表长度:" + args_xh.maxSize + " 申请列表:" + list[i] + " \n\n" + while (args_xh.listCount + trialActivityIdList.length < args_xh.maxLength && size < args_xh.maxSize && size < totalPages - 1) { + console.log(`\n正在进行第 ${size} 次获取试用商品\n`) + console.log(`\n当前产品页面总长度为${totalPages} 页\n`) + await try_feedsList(list[i], size++) + if (m == 0 && sensMessage.length > wordLength) { + console.log("-----------------------------------") + console.log("-----------------------------------") + console.log("-----------------------------------") + console.log("-----------------------------------") + console.log("-----------------------------------") + console.log("-----------------------------------") + console.log("-----------------------------------") + postToDingTalk1(sensMessage) + sensMessage = "试用\n\n" + }else{ + console.log("------------清空------------") + console.log("------------清空------------") + sensMessage = "试用\n\n" + } + if (args_xh.listCount + trialActivityIdList.length < args_xh.maxLength) { + args_xh.applyInterval = Math.floor(Math.random() * (4000) + 5000) + console.log(`间隔延时中,请等待 ${args_xh.applyInterval} ms`) + await $.wait(args_xh.applyInterval); + } + } + args_xh.listCount += trialActivityIdList.length + console.log("正在执行试用申请...") + await $.wait(args_xh.applyInterval); + for (let i = 0; i < trialActivityIdList.length; i++) { + args_xh.applyInterval = Math.floor(Math.random() * (4000) + 5000) + await try_apply(trialActivityTitleList[i], trialActivityIdList[i]) + console.log(`间隔延时中,请等待 ${args_xh.applyInterval} ms\n`) + await $.wait(args_xh.applyInterval); + } + message = message + "" + "本循环申请数量:" + trialActivityIdList.length + "总量限制为:" + args_xh.listCount + " \n\n " + trialActivityIdList = [] + trialActivityTitleList = [] + size = 1 + totalPages == 999999 + } + + + console.log("试用申请执行完毕...") + + // await try_MyTrials(1, 1) //申请中的商品 + await try_MyTrials(1, 2) //申请成功的商品 + // await try_MyTrials(1, 3) //申请失败的商品 + await showMsg() + //下一个要重新去拉列表 + trialActivityIdList = [] + trialActivityTitleList = [] + await $.wait(Math.floor(Math.random() * (15000) + 5000)); + } + + args_xh.listCount = 0 + postToDingTalk(message) + message = "" + totalPages == 999999 + } + await $.notify.sendNotify(`${$.name}`, notifyMsg); + } else { + console.log(`\n您未设置运行【京东试用】脚本,结束运行!\n`) + } + })().catch((e) => { + postToDingTalk(e + message) + console.log(`❗️ ${$.name} 运行错误!\n${e}`) + }).finally(() => { + $.done() + }) + + + function getList() { + for (i = 0; i < Math.floor(Math.random() * (5001) + 500); i++) { + index1 = Math.floor(Math.random() * (args_xh.channel.length) + 0) + index2 = Math.floor(Math.random() * (args_xh.channel.length) + 0) + temp = args_xh.channel[index1] + args_xh.channel[index1] = args_xh.channel[index2] + args_xh.channel[index2] = temp + } + + return args_xh.channel.slice(0, args_xh.channelEnd) + } + + function requireConfig() { + return new Promise(resolve => { + console.log('开始获取配置文件\n') + $.notify = $.isNode() ? require('./sendNotify') : { sendNotify: async () => { } } + //获取 Cookies + $.cookiesArr = [] + if ($.isNode()) { + //Node.js用户请在jdCookie.js处填写京东ck; + const jdCookieNode = require('./jdCookie.js'); + Object.keys(jdCookieNode).forEach((item) => { + if (jdCookieNode[item]) { + $.cookiesArr.push(jdCookieNode[item]) + } + }) + if (process.env.JD_DEBUG && process.env.JD_DEBUG === 'false') console.log = () => { }; + } else { + //IOS等用户直接用NobyDa的jd $.cookie + $.cookiesArr = [$.getdata('CookieJD'), $.getdata('CookieJD2'), ...jsonParse($.getdata('CookiesJD') || "[]").map(item => item.cookie)].filter(item => !!item); + } + console.log(`共${$.cookiesArr.length}个京东账号\n`) + for (const key in args_xh) { + if (typeof args_xh[key] == 'string') { + args_xh[key] = Number(args_xh[key]) + } + } + // console.debug(args_xh) + resolve() + }) + } + + //获取商品列表并且过滤 By X1a0He + function try_feedsList(tabId, page) { + return new Promise((resolve, reject) => { + + const body = JSON.stringify({ + "tabId": `${tabId}`, + "page": page, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_feedsList', body) + $.get(option, (err, resp, data) => { + try { + if (err) { + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.debug(data) + // return + data = JSON.parse(data) + if (totalPages == 999999) { + message = message + "" + " 当前最大页数为:" + data.data.pages + " \n\n" + } + if (data.success) { + $.totalPages = data.data.pages + totalPages = data.data.pages + console.log(`获取到商品 ${data.data.feedList.length} 条\n`) + for (let i = 0; i < data.data.feedList.length; i++) { + if (args_xh.listCount + trialActivityIdList.length >= args_xh.maxLength) { + console.log('商品列表长度已满.结束获取') + } else + if (data.data.feedList[i].applyState === 1) { + console.log(`商品已申请试用:${data.data.feedList[i].skuTitle}`) + continue + } else + if (data.data.feedList[i].applyState !== null) { + console.log(`商品状态异常,跳过:${data.data.feedList[i].skuTitle}`) + continue + } else + if (data.data.feedList[i].skuTitle) { + console.log(`检测第 ${page} 页 第 ${i + 1} 个商品\n${data.data.feedList[i].skuTitle}`) + if (parseFloat(data.data.feedList[i].jdPrice) <= args_xh.jdPrice) { + console.log(`商品被过滤,${data.data.feedList[i].jdPrice} < ${args_xh.jdPrice} \n`) + } else if (parseFloat(data.data.feedList[i].supplyNum) > args_xh.minSupplyNum && data.data.feedList[i].supplyNum !== null) { + console.log(`商品被过滤,提供申请的份数大于预设申请的份数 \n`) + } else if (parseFloat(data.data.feedList[i].applyNum) > args_xh.applyNumFilter && data.data.feedList[i].applyNum !== null) { + console.log(`商品被过滤,已申请试用人数大于预设人数 \n`) + } else if (parseFloat(data.data.feedList[i].trialPrice) > args_xh.trialPrice && data.data.feedList[i].jdPrice < minItemValue) { + console.log(`商品被过滤,期待价格高于预设价格 \n`) + } else if (args_xh.titleFilters.some(fileter_word => data.data.feedList[i].skuTitle.includes(fileter_word))) { + sensMessage += "" + data.data.feedList[i].skuTitle + " \n\n" + args_xh.titleFilters.some(fileter_word =>{ + if (data.data.feedList[i].skuTitle.includes(fileter_word)){ + sensMessage += "" + "敏感词汇:" + fileter_word + " \n\n" + } + }) + console.log('商品被过滤,含有关键词 \n') + } else { + console.log(`商品通过,将加入试用组,trialActivityId为${data.data.feedList[i].trialActivityId}\n`) + trialActivityIdList.push(data.data.feedList[i].trialActivityId) + trialActivityTitleList.push(data.data.feedList[i].skuTitle) + } + } else { + console.log('skuTitle解析异常') + return + } + } + console.log(`当前试用组id如下,长度为:${trialActivityIdList.length}\n${trialActivityIdList}\n`) + } else { + console.log(`💩 获得试用列表失败: ${data.message}`) + } + } + } catch (e) { + console.log(e); + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + console.log(`${JSON.stringify(data)}`) + } finally { + resolve() + } + }) + }) + } + + function try_apply(title, activityId) { + return new Promise((resolve, reject) => { + console.log(`申请试用商品中...`) + console.log(`商品:${title}`) + console.log(`id为:${activityId}`) + const body = JSON.stringify({ + "activityId": activityId, + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_apply', body) + $.get(option, (err, resp, data) => { + try { + if (err) { + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + $.totalTry++ + data = JSON.parse(data) + if (data.success && data.code === "1") { // 申请成功 + message += "" + title + "\n\n" + message += "" + `-------\n\n` + "\n\n" + console.log(data.message) + $.totalSuccess++ + } else if (data.code === "-106") { + console.log(data.message) // 未在申请时间内! + } else if (data.code === "-110") { + console.log(data.message) // 您的申请已成功提交,请勿重复申请… + } else if (data.code === "-120") { + console.log(data.message) // 您还不是会员,本品只限会员申请试用,请注册会员后申请! + } else if (data.code === "-167") { + console.log(data.message) // 抱歉,此试用需为种草官才能申请。查看下方详情了解更多。 + } else { + console.log("申请失败", JSON.stringify(data)) + message += "" + JSON.stringify(data) + "\n\n" + message += "" + `-------\n\n` + "\n\n" + } + } + } catch (e) { + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally { + resolve() + } + }) + }) + } + + function try_MyTrials(page, selected) { + return new Promise((resolve, reject) => { + switch (selected) { + case 1: + console.log('正在获取已申请的商品...') + break; + case 2: + console.log('正在获取申请成功的商品...') + break; + case 3: + console.log('正在获取申请失败的商品...') + break; + default: + console.log('selected错误') + } + const body = JSON.stringify({ + "page": page, + "selected": selected, // 1 - 已申请 2 - 成功列表,3 - 失败列表 + "previewTime": "" + }); + let option = taskurl_xh('newtry', 'try_MyTrials', body) + option.headers.Referer = 'https://pro.m.jd.com/' + $.get(option, (err, resp, data) => { + try { + if (err) { + console.log(`🚫 ${arguments.callee.name.toString()} API请求失败,请检查网路\n${JSON.stringify(err)}`) + } else { + // console.log(data) + // return + data = JSON.parse(data) + if (data.success) { + //temp adjustment + if (selected == 2) { + if (data.success && data.data) { + $.successList = data.data.list.filter(item => { + return item.text.text.includes('试用资格将保留10天') + }) + console.log(`待领取: ${$.successList.length}个`) + } else { + console.log(`获得成功列表失败: ${data.message}`) + } + } + if (data.data.list.length > 0) { + let count = 0 + for (let item of data.data.list) { + console.log(`申请时间:${new Date(parseInt(item.applyTime)).toLocaleString()}`) + console.log(`申请商品:${item.trialName}`) + console.log(`当前状态:${item.text.text}`) + console.log(`剩余时间:${remaining(item.leftTime)}`) + + if (count < 3) { + message += "" + `申请商品:${item.trialName}` + "\n\n" + message += "" + `当前状态:${item.text.text}` + "\n\n" + message += "" + `-----\n\n` + "\n\n" + count++ + } + + console.log() + } + } + // else { + // switch(selected){ + // case 1: + // console.log('无已申请的商品\n') + // break; + // case 2: + // console.log('无申请成功的商品\n') + // break; + // case 3: + // console.log('无申请失败的商品\n') + // break; + // default: + // console.log('selected错误') + // } + // } + } else { + console.log(`ERROR:try_MyTrials`) + } + } + } catch (e) { + reject(`⚠️ ${arguments.callee.name.toString()} API返回结果解析出错\n${e}\n${JSON.stringify(data)}`) + } finally { + resolve() + } + }) + }) + } + + function remaining(time) { + let days = parseInt(time / (1000 * 60 * 60 * 24)); + let hours = parseInt((time % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); + let minutes = parseInt((time % (1000 * 60 * 60)) / (1000 * 60)); + return `${days} 天 ${hours} 小时 ${minutes} 分` + } + + function taskurl_xh(appid, functionId, body = JSON.stringify({})) { + return { + "url": `${URL}?appid=${appid}&functionId=${functionId}&clientVersion=10.1.2&client=wh5&body=${encodeURIComponent(body)}`, + 'headers': { + 'Host': 'api.m.jd.com', + 'Accept-Encoding': 'gzip, deflate, br', + 'Cookie': $.cookie, + 'Connection': 'keep-alive', + 'UserAgent': 'jdapp;iPhone;10.1.2;15.0;ff2caa92a8529e4788a34b3d8d4df66d9573f499;network/wifi;model/iPhone13,4;addressid/2074196292;appBuild/167802;jdSupportDarkMode/1;Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1', + 'Accept-Language': 'zh-cn', + 'Referer': 'https://prodev.m.jd.com/' + }, + } + } + + async function showMsg() { + let message1 = `京东账号${$.index} ${$.nickName || $.UserName}\n🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + message += "" + `🎉 本次申请:${$.totalSuccess}/${$.totalTry}个商品🛒\n🎉 ${$.successList.length}个商品待领取` + "\n\n" + if (!args_xh.jdNotify || args_xh.jdNotify === 'false') { + $.msg($.name, ``, message1, { + "open-url": 'https://try.m.jd.com/user' + }) + if ($.isNode()) + notifyMsg += `${message1}\n\n` + } else { + console.log(message1) + } + } + + function totalBean() { + return new Promise(async resolve => { + const options = { + "url": `https://wq.jd.com/user/info/QueryJDUserInfo?sceneval=2`, + "headers": { + "Accept": "application/json,text/plain, */*", + "Content-Type": "application/x-www-form-urlencoded", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-cn", + "Connection": "keep-alive", + "Cookie": $.cookie, + "Referer": "https://wqs.jd.com/my/jingdou/my.shtml?sceneval=2", + "User-Agent": $.isNode() ? (process.env.JD_USER_AGENT ? process.env.JD_USER_AGENT : (require('./USER_AGENTS').USER_AGENT)) : ($.getdata('JDUA') ? $.getdata('JDUA') : "jdapp;iPhone;9.4.4;14.3;network/4g;Mozilla/5.0 (iPhone; CPU iPhone OS 14_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148;supportJDSHWK/1") + }, + "timeout": 10000, + } + $.post(options, (err, resp, data) => { + try { + if (err) { + console.log(`${JSON.stringify(err)}`) + console.log(`${$.name} API请求失败,请检查网路重试`) + } else { + if (data) { + data = JSON.parse(data); + if (data['retcode'] === 13) { + $.isLogin = false; //cookie过期 + return + } + if (data['retcode'] === 0) { + $.nickName = (data['base'] && data['base'].nickname) || $.UserName; + } else { + $.nickName = $.UserName + } + } else { + console.log(`京东服务器返回空数据`) + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }) + }) + } + + function jsonParse(str) { + if (typeof str == "string") { + try { + return JSON.parse(str); + } catch (e) { + console.log(e); + $.msg($.name, '', '请勿随意在BoxJs输入框修改内容\n建议通过脚本去获取cookie') + return []; + } + } + } + + // 来自 @chavyleung 大佬 + // https://raw.githubusercontent.com/chavyleung/scripts/master/Env.js + 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 + } + + 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 = () => { }) { + // 如果指定了请求体, 但没指定`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.post(opts, (err, resp, body) => { + if (!err && resp) { + resp.body = body + resp.statusCode = resp.status + } + callback(err, resp, body) + }) + } else if (this.isQuanX()) { + opts.method = 'POST' + 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.post(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 {*} fmt 格式化参数 + * + */ + time(fmt) { + let o = { + 'M+': new Date().getMonth() + 1, + 'd+': new Date().getDate(), + 'H+': new Date().getHours(), + 'm+': new Date().getMinutes(), + 's+': new Date().getSeconds(), + 'q+': Math.floor((new Date().getMonth() + 3) / 3), + 'S': new Date().getMilliseconds() + } + if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (new 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) + } + + + //我加的函数 + function postToDingTalk(messgae) { + const message1 = "" + messgae + // that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title": "随机试用", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": true + } + } + + + $.post(toDingtalk(dingtalk, JSON.stringify(body)), (data, status, xhr) => { + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }, "json") + } + + + function toDingtalk(urlmain, bodyMain) { + return { + url: urlmain, + body: bodyMain, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, + timeout: 10000, + } + } + + + function postToDingTalk1(messgae) { + const message1 = "" + messgae + // that.log(messgae) + + const body = { + "msgtype": "markdown", + "markdown": { + "title": "错误筛选", + "text": message1 + }, + "at": { + "atMobiles": [], + "isAtAll": false + } + } + + $.post(toDingtalk(dingtalk1, JSON.stringify(body)), (data, status, xhr) => { + try { + that.log(resp) + that.log(data) + if (err) { + that.log(JSON.stringify(err)); + $.logErr(err); + } else { + if (safeGet(data)) { + $.duckRes = JSON.parse(data); + } + } + } catch (e) { + $.logErr(e, resp) + } finally { + resolve(); + } + }, "json") +} \ No newline at end of file diff --git a/src/main/test/emptyDirTest/1/11.txt b/src/main/test/emptyDirTest/1/11.txt new file mode 100644 index 0000000..344c56e --- /dev/null +++ b/src/main/test/emptyDirTest/1/11.txt @@ -0,0 +1,10 @@ +12321321 +3213 + +3213213 +321321 +321321 +3 + +32132131 +321321321 diff --git a/src/main/test/emptyDirTest/1/222.png b/src/main/test/emptyDirTest/1/222.png new file mode 100644 index 0000000..483a711 Binary files /dev/null and b/src/main/test/emptyDirTest/1/222.png differ diff --git a/src/main/test/emptyDirTest/1/233.png b/src/main/test/emptyDirTest/1/233.png new file mode 100644 index 0000000..f2b32f2 Binary files /dev/null and b/src/main/test/emptyDirTest/1/233.png differ diff --git a/src/main/test/emptyDirTest/1/mmm.png b/src/main/test/emptyDirTest/1/mmm.png new file mode 100644 index 0000000..6053a6e Binary files /dev/null and b/src/main/test/emptyDirTest/1/mmm.png differ diff --git a/src/main/test/emptyDirTest/2/1/11.txt b/src/main/test/emptyDirTest/2/1/11.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main/test/emptyDirTest/2/2222/4/4/111.txt b/src/main/test/emptyDirTest/2/2222/4/4/111.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main/test/emptyDirTest/2/2222/4/4/4/4/1211.txt b/src/main/test/emptyDirTest/2/2222/4/4/4/4/1211.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main/test/emptyDirTest/3/11.txt b/src/main/test/emptyDirTest/3/11.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/main/test/util/FileUtilTest.java b/src/main/test/util/FileUtilTest.java new file mode 100644 index 0000000..14cf865 --- /dev/null +++ b/src/main/test/util/FileUtilTest.java @@ -0,0 +1,30 @@ +package util; + +import java.io.File; + +public class FileUtilTest { + + public static void main(String[] args) { + System.out.println(FileUtil.isFile("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\emptyDirTest\\1\\11.txt")); + System.out.println(FileUtil.isDir("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\emptyDirTest")); +// for(File file:FileUtil.findAllDirFromDir("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\emptyDirTest")){ +// System.out.println(file.getName()); +// } + + System.out.println("==================================="); + for(File file:FileUtil.findAllEmptyDirFromDir("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\emptyDirTest")){ + System.out.println(file.getName()); + } +// +// System.out.println("==================================="); +// for(File file:FileUtil.findAllFile(new File("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\emptyDirTest"))){ +// System.out.println(file.getName()); +// } +// +// + System.out.println("==================================="); + for(File file:FileUtil.findAllNotEmptyDirFromDir("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\emptyDirTest")){ + System.out.println(file.getName()); + } + } +} diff --git a/src/main/test/util/FullFillTimeValueTest.java b/src/main/test/util/FullFillTimeValueTest.java new file mode 100644 index 0000000..c86d920 --- /dev/null +++ b/src/main/test/util/FullFillTimeValueTest.java @@ -0,0 +1,52 @@ +package util; + +import com.google.common.collect.Lists; +import entity.OriginTimeValue; +import entity.TargetTimeValue; +import util.time.FillFullTimeValueUtil; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.TimeZone; + +public class FullFillTimeValueTest { + + + public static void main(String[] args) { + List originTimeValueList = Lists.newArrayList(); + originTimeValueList.add(new OriginTimeValue(1542995383, 109991)); + + List targetTimeValues1 = FillFullTimeValueUtil.MINUTE.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now() + .plusDays(1), 1, originTimeValueList, + TimeZone.getDefault()); + + + List targetTimeValues2 = FillFullTimeValueUtil.HOUR.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now() + .plusDays(1), 2, originTimeValueList, + TimeZone.getDefault()); + + List targetTimeValues3 = FillFullTimeValueUtil.DAY.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now() + .plusDays(100), 10, originTimeValueList, + TimeZone.getDefault()); + + List targetTimeValues4 = FillFullTimeValueUtil.MINUTE.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now() + .plusDays(1), 1, null, + TimeZone.getDefault()); + + + targetTimeValues1.forEach(targetTimeValue -> System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue())); + + System.out.println("---------------------------------------------------------------------"); + + targetTimeValues2.forEach(targetTimeValue -> System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue())); + + System.out.println("---------------------------------------------------------------------"); + + targetTimeValues3.forEach(targetTimeValue -> System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue())); + + System.out.println("---------------------------------------------------------------------"); + + targetTimeValues4.forEach(targetTimeValue -> System.out.println(targetTimeValue.getTime() + " , " + targetTimeValue.getValue())); + + } +} diff --git a/src/main/test/util/MessageUtilsTest.java b/src/main/test/util/MessageUtilsTest.java new file mode 100644 index 0000000..3d0e1f0 --- /dev/null +++ b/src/main/test/util/MessageUtilsTest.java @@ -0,0 +1,29 @@ +package util; + +public class MessageUtilsTest { + + + public static void main(String[] args) { + String pattern = "{0}----{1}======={2}_______{3}"; + System.out.println(MessageUtils.format(pattern,"我是零","我是一","我是2","我是三")); + System.out.println(MessageUtils.format(pattern,"我是零","我是一")); + System.out.println(MessageUtils.format(pattern,"我是零","我是一","我是2","我是三","我是多的","我又多了")); + xxx[] a = new xxx[] {new xxx("123",222),new xxx("123",555),new xxx("999",222)}; + System.out.println(MessageUtils.format(pattern,a)); + + String i = "{ --},{}"; + System.out.println(MessageUtils.format(i,"我是零","我是一")); + System.out.println(MessageUtils.format(i,a)); + + } +} + +class xxx{ + String a; + int b; + + public xxx(String a, int b) { + this.a = a; + this.b = b; + } +} diff --git a/src/main/test/util/PageUtilTest.java b/src/main/test/util/PageUtilTest.java new file mode 100644 index 0000000..cc7d0ef --- /dev/null +++ b/src/main/test/util/PageUtilTest.java @@ -0,0 +1,49 @@ +package util; + + +import entity.CommonPageResp; + +import java.util.ArrayList; +import java.util.List; + + +public class PageUtilTest { + + + private static List valueList = new ArrayList<>(); + private static List emptyList = new ArrayList<>(); + private static List nullList =null; + + public static void dataMake(){ + valueList.add("1"); + valueList.add("2"); + valueList.add("3"); + valueList.add("4"); + valueList.add("5"); + valueList.add("6"); + valueList.add("7"); + valueList.add("8"); + valueList.add("9"); + valueList.add("10"); + } + + public static void main(String[] args) { + dataMake(); + +// CommonPageResp result = PageUtil.pagingListFromZero(valueList,-1,100); + CommonPageResp result1 = PageUtil.pagingListFromZero(valueList,1,2); + CommonPageResp result2 = PageUtil.pagingListFromZero(valueList,0,2); + CommonPageResp result3 = PageUtil.pagingListFromZero(valueList,100,2); + CommonPageResp result5 = PageUtil.pagingListFromZero(emptyList,100,3); + CommonPageResp result6 = PageUtil.pagingListFromZero(nullList,100,2); + + +// CommonPageResp result = PageUtil.pagingListFromOne(valueList,-1,100); + CommonPageResp result7 = PageUtil.pagingListFromOne(valueList,1,2); + CommonPageResp result8 = PageUtil.pagingListFromOne(valueList,2,2); + CommonPageResp result9 = PageUtil.pagingListFromOne(valueList,100,2); + CommonPageResp result10 = PageUtil.pagingListFromOne(emptyList,100,3); + CommonPageResp result11 = PageUtil.pagingListFromOne(nullList,100,2); + System.out.println("直接断点查看结果"); + } +} \ No newline at end of file diff --git a/src/main/test/util/StringUtilsTest.java b/src/main/test/util/StringUtilsTest.java new file mode 100644 index 0000000..a64db1c --- /dev/null +++ b/src/main/test/util/StringUtilsTest.java @@ -0,0 +1,82 @@ +package util; + +import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; + +public class StringUtilsTest { + + + public static void main(String[] args) throws BadHanyuPinyinOutputFormatCombination { + System.out.println( StringUtils.upperFirstLetter("abx123")); + System.out.println( StringUtils.upperFirstLetter("123abx123")); + System.out.println( StringUtils.upperFirstLetter("%%#@abx123")); + + + System.out.println( StringUtils.lowerFirstLetter("Abx123")); + System.out.println( StringUtils.lowerFirstLetter("123abx123")); + System.out.println( StringUtils.lowerFirstLetter("%%#@abx123")); + + System.out.println( StringUtils.upperAllLetter("Abx123")); + System.out.println( StringUtils.upperAllLetter("123abx123")); + System.out.println( StringUtils.upperAllLetter("%%#@abx123")); + + + System.out.println( StringUtils.lowerAllLetter("Abx123")); + System.out.println( StringUtils.lowerAllLetter("123abx123")); + System.out.println( StringUtils.lowerAllLetter("%%#@abx123")); + + + System.out.println( StringUtils.appendAll("%%#@abx123","dsadasdsad")); + System.out.println( StringUtils.appendAll("%%#@abx123")); + System.out.println( StringUtils.appendAll()); + System.out.println( StringUtils.appendAll("%%#@abx123","dasde2weqwewq","d dasdsa dasdas da dsa")); + + + System.out.println( StringUtils.isContainChinese("%%#@abx123")); + System.out.println( StringUtils.isContainChinese("%%#@哈哈哈哈的撒娇低价十九大uiyhuids")); + System.out.println( StringUtils.isContainChinese("")); + System.out.println( StringUtils.isContainChinese("大数99092jkjj大声道")); + System.out.println( StringUtils.isContainChinese("大数99092jkjj")); + + System.out.println( StringUtils.isChineseChar('1')); + System.out.println( StringUtils.isChineseChar('我')); + + System.out.println( StringUtils.toPinyinUpper("我爱中国")); + System.out.println( StringUtils.toPinyinUpper("%%#@我爱中国")); + System.out.println( StringUtils.toPinyinUpper("")); + System.out.println( StringUtils.toPinyinUpper("我爱中国12321dsad")); + System.out.println( StringUtils.toPinyinUpper("12321dsad")); + + + System.out.println( StringUtils.toPinyinLower("我爱中国")); + System.out.println( StringUtils.toPinyinLower("%%#@我爱中国")); + System.out.println( StringUtils.toPinyinLower("")); + System.out.println( StringUtils.toPinyinLower("我爱中国12321dsad")); + System.out.println( StringUtils.toPinyinLower("12321dsad")); + + + + System.out.println( StringUtils.toPinyinPhoneticSignUpper("我爱中国")); + System.out.println( StringUtils.toPinyinPhoneticSignUpper("%%#@我爱中国")); + System.out.println( StringUtils.toPinyinPhoneticSignUpper("")); + System.out.println( StringUtils.toPinyinPhoneticSignUpper("我爱中国12321dsad")); + System.out.println( StringUtils.toPinyinPhoneticSignUpper("12321dsad")); + + + + System.out.println( StringUtils.toPinyinPhoneticSignLower("我爱中国")); + System.out.println( StringUtils.toPinyinPhoneticSignLower("%%#@我爱中国")); + System.out.println( StringUtils.toPinyinPhoneticSignLower("")); + System.out.println( StringUtils.toPinyinPhoneticSignLower("我爱中国12321dsad")); + System.out.println( StringUtils.toPinyinPhoneticSignLower("12321dsad")); + + System.out.println(StringUtils.replacePattern("ABCDEFG","[A-C]")); + System.out.println(StringUtils.replacePattern("ABCDEFG12333","[A-C1-3]")); + System.out.println(StringUtils.replacePattern("X432432^&*(DSAD","[A-C1-2]")); + + System.out.println(StringUtils.replacePattern("ABCDEFG","XYZ","[A-C]")); + System.out.println(StringUtils.replacePattern("ABCDEFG12333","YYYM","[A-C1-3]")); + System.out.println(StringUtils.replacePattern("X432432^&*(DSAD","中文,213321sdadsa","[A-C1-2]")); + } + + +} diff --git a/src/main/test/util/image/CaptchaUtilTest.java b/src/main/test/util/image/CaptchaUtilTest.java new file mode 100644 index 0000000..3f4bf6f --- /dev/null +++ b/src/main/test/util/image/CaptchaUtilTest.java @@ -0,0 +1,13 @@ +package util.image; + +public class CaptchaUtilTest { + + + public static void main(String[] args) { + CaptchaUtil captchaUtil = new CaptchaUtil(); + System.out.println(captchaUtil.generalCode()); + captchaUtil.generateCaptchaImage("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\captcha\\test.jpg"); + //自定义code的处理 + captchaUtil.generateCaptchaImage("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\captcha\\test1.jpg","xy2312sa"); + } +} diff --git a/src/main/test/util/image/JpegImager/2002013.jpg b/src/main/test/util/image/JpegImager/2002013.jpg new file mode 100644 index 0000000..d1c873f Binary files /dev/null and b/src/main/test/util/image/JpegImager/2002013.jpg differ diff --git a/src/main/test/util/image/JpegImagerUtilTest.java b/src/main/test/util/image/JpegImagerUtilTest.java new file mode 100644 index 0000000..7cbd123 --- /dev/null +++ b/src/main/test/util/image/JpegImagerUtilTest.java @@ -0,0 +1,17 @@ +package util.image; + +import util.FileUtil; + +import java.io.IOException; + +public class JpegImagerUtilTest { + + public static void main(String[] args) throws IOException { + PicturesCompressUtil picturesCompressUtil = new PicturesCompressUtil(); + picturesCompressUtil.compress("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\JpegImager\\2002013.jpg","F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\JpegImager\\2002013_copy.jpg"); + System.out.println("压缩之后的大小差别为"); + byte[] b1 = FileUtil.fileToByte("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\JpegImager\\2002013.jpg"); + byte[] b2 = FileUtil.fileToByte("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\JpegImager\\2002013_copy.jpg"); + System.out.println("压缩前后字节差:" + (b1.length - b2.length+ " byte")); + } +} diff --git a/src/main/test/util/image/QRCode/log.png b/src/main/test/util/image/QRCode/log.png new file mode 100644 index 0000000..65fe8e6 Binary files /dev/null and b/src/main/test/util/image/QRCode/log.png differ diff --git a/src/main/test/util/image/QRCodeUtilTest.java b/src/main/test/util/image/QRCodeUtilTest.java new file mode 100644 index 0000000..21767fa --- /dev/null +++ b/src/main/test/util/image/QRCodeUtilTest.java @@ -0,0 +1,32 @@ +package util.image; + +import java.awt.*; +import java.awt.image.BufferedImage; + +public class QRCodeUtilTest { + + public static void main(String[] args) { + QRCodeUtil qrCodeUtil = new QRCodeUtil(); + qrCodeUtil.getQrCodeItem().setContent("我测试一下"); + qrCodeUtil.getQrCodeItem().setContentFont(new Font("宋体",Font.BOLD, 12)); + qrCodeUtil.getQrCodeItem().setContentColor(Color.RED); + BufferedImage bufferedImage = qrCodeUtil.createQrCodeImage(); + qrCodeUtil.createQrCodeWithImage("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\QRCode\\default.jpg",bufferedImage); + + BufferedImage bufferedImage1 = qrCodeUtil.createQrCodeImage(); + bufferedImage1 = qrCodeUtil.drawContent(bufferedImage1); + qrCodeUtil.createQrCodeWithImage("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\QRCode\\content.jpg",bufferedImage1); + + BufferedImage bufferedImage2 = qrCodeUtil.createQrCodeImage(); + bufferedImage2 = qrCodeUtil.drawLogo(bufferedImage2); + qrCodeUtil.createQrCodeWithImage("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\QRCode\\logo1.jpg",bufferedImage2); + + BufferedImage bufferedImage3 = qrCodeUtil.createQrCodeImage(); + bufferedImage3 = qrCodeUtil.drawLogo(bufferedImage3); + bufferedImage3 = qrCodeUtil.drawContent(bufferedImage3); + qrCodeUtil.createQrCodeWithImage("F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\image\\QRCode\\logoContent.jpg",bufferedImage3); + + + } + +} diff --git a/src/main/test/util/transform/TransformTest.java b/src/main/test/util/transform/TransformTest.java new file mode 100644 index 0000000..571f00c --- /dev/null +++ b/src/main/test/util/transform/TransformTest.java @@ -0,0 +1,63 @@ +package util.transform; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +public class TransformTest { + + public static void main(String[] args) { + System.out.println("测试JsonBinder"); + + JsonObject jsonObject = new JsonObject(); + jsonObject.setX1(123); + jsonObject.setX2("123"); + jsonObject.setX3(new JsonObject()); + String jsonString = JsonBinder.toJson(jsonObject); + System.out.println(jsonString); + System.out.println(JsonBinder.fromJson(jsonString, JsonObject.class).getX2()); + + System.out.println("测试XmlBinder"); + String xmlString = XmlBinder.convertToXml(jsonObject); + System.out.println(xmlString); + + System.out.println(XmlBinder.convertXmlStrToObject(xmlString,JsonObject.class).getX2()); + XmlBinder.convertToXml(jsonObject,"F:\\Java个人代码\\Java_Utils\\src\\main\\test\\util\\transform\\transform.xml"); + } + + @XmlRootElement(name = "xml") + @XmlAccessorType(XmlAccessType.FIELD) + static class JsonObject { + @XmlElement(name = "x1") + int x1; + @XmlElement(name = "x2") + String x2; + @XmlElement(name = "x3") + JsonObject x3; + + public int getX1() { + return x1; + } + + public void setX1(int x1) { + this.x1 = x1; + } + + public String getX2() { + return x2; + } + + public void setX2(String x2) { + this.x2 = x2; + } + + public JsonObject getX3() { + return x3; + } + + public void setX3(JsonObject x3) { + this.x3 = x3; + } + } +} diff --git a/src/main/test/util/tree/TreeUtilTest.java b/src/main/test/util/tree/TreeUtilTest.java new file mode 100644 index 0000000..2fad8cb --- /dev/null +++ b/src/main/test/util/tree/TreeUtilTest.java @@ -0,0 +1,19 @@ +package util.tree; + +import com.alibaba.fastjson.JSON; + +public class TreeUtilTest { + public static void main(String[] args) { + String treeNodeString = "[{\"code\":\"aa\",\"parentCode\":\"a\"},{\"code\":\"aaa\",\"parentCode\":\"aa\"},{\"code\":\"aaaa\"," + + "\"parentCode\":\"aaa\"},{\"code\":\"bbbb\",\"parentCode\":\"aaa\"},{\"code\":\"XXX\",\"parentCode\":\"aaaa\"}," + + "{\"code\":\"22121\",\"parentCode\":\"XXX\"},{\"code\":\"a\",\"parentCode\":\"0\"},{\"code\":\"222\",\"parentCode\":\"a\"}," + + "{\"code\":\"AXMW\",\"parentCode\":\"222\"}]"; + System.out.println(TreeUtils.getCodePath(JSON.parseArray(treeNodeString, TreeNode.class),"aa")); + System.out.println(TreeUtils.getCodePath(JSON.parseArray(treeNodeString, TreeNode.class),"mmmm")); + + TreeNode2 t2 = TreeUtils.getTreeWithChildNodeList(JSON.parseArray(treeNodeString, TreeNode2.class),"a"); + TreeNode2 t3 = TreeUtils.getTreeWithChildNodeList(JSON.parseArray(treeNodeString, TreeNode2.class),"mmmm"); + TreeNode2 t4 = TreeUtils.getTreeWithChildNodeList(JSON.parseArray(treeNodeString, TreeNode2.class),"AXMW"); + System.out.println(""); + } +} diff --git a/src/main/test/util/zip/ZipTest.java b/src/main/test/util/zip/ZipTest.java new file mode 100644 index 0000000..22578c8 --- /dev/null +++ b/src/main/test/util/zip/ZipTest.java @@ -0,0 +1,134 @@ +/* + * @(#) TestGzip + * 版权声明 网宿科技, 版权所有 违者必究 + * + *
Copyright: Copyright (c) 2018 + *
Company:网宿科技 + *
@author Administrator + *
@description 功能描述 + *
2018-11-09 20:30:59 + */ + +package util.zip; + +import com.google.common.collect.Lists; +import entity.FileItem; +import org.springframework.util.StopWatch; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import util.FileUtil; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.UUID; + + +/** + * 关联WS业务--日志下载 + * 参考地址:https://www.cnblogs.com/guochunyi/p/5311261.html + */ +public class ZipTest { + + + public static void main(String[] args) throws IOException { + //这边的测试我没有放入对应的文件,因为太大了,所以如果想要测试,需要在相应的目录放入对应带下的文件才能进行测试... + testGzip(); + } + + public static void testGzip() throws IOException { + String Path1M = ZipTest.class.getClassLoader().getResource("/test/testDownload").getPath(); + String path10M = ZipTest.class.getClassLoader().getResource("/test/test10M").getPath(); + String path100M = ZipTest.class.getClassLoader().getResource("/test/test100M").getPath(); + String path1000M = ZipTest.class.getClassLoader().getResource("/test/test1000M").getPath(); + System.out.println("测试1M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testGzipOnce(Path1M); + } + System.out.println("测试10M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testGzipOnce(path10M); + } + System.out.println("测试100M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testGzipOnce(path100M); + } + System.out.println("测试1000M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testGzipOnce(path1000M); + } + + System.out.println("测试1M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testZipOnce(Path1M); + } + System.out.println("测试10M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testZipOnce(path10M); + } + System.out.println("测试100M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testZipOnce(path100M); + } + System.out.println("测试1000M数据的压缩时间"); + for (int i = 0; i < 3; i++) { + testZipOnce(path1000M); + } + } + + + private static void testZipOnce(String path) throws IOException { + String filePath = ZipTest.class.getClassLoader().getResource("/test").getPath(); + File packageFile = new File(filePath + UUID.randomUUID().toString().replaceAll("-", "")); + packageFile.mkdir(); + String zPath = packageFile.getPath() + File.separator + UUID.randomUUID().toString().replaceAll("-", "") + ".zip"; + new File(zPath).createNewFile(); + + File file = ZipOutputUtil.compress(path, zPath); + System.out.println(file.getName()); + } + + private static void testGzipOnce(String path) throws IOException { + String filePath = ZipTest.class.getClassLoader().getResource("/test").getPath(); + File packageFile = new File(filePath + UUID.randomUUID().toString().replaceAll("-", "")); + packageFile.mkdir(); + String tarPath = packageFile.getPath() + File.separator + UUID.randomUUID().toString().replaceAll("-", "") + ".tar"; + String gzPath = packageFile.getPath() + File.separator + UUID.randomUUID().toString().replaceAll("-", "") + ".gz"; + new File(gzPath).createNewFile(); + List files = Lists.newArrayList(); + File file = new File(path); + File[] file1 = file.listFiles(); + for (File file2 : file1) { + files.add(file2); + } + File filex = TarArchiveGZIPOutputUtil.compress(files, tarPath); + System.out.println(filex.getName()); + } + + @RequestMapping(value = "/testFile1", method = RequestMethod.POST) + public void testFile1() throws FileNotFoundException { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + String filePath = ZipTest.class.getClassLoader().getResource("/test").getPath(); + File packageFile = new File(filePath + UUID.randomUUID().toString().replaceAll("-", "")); + packageFile.mkdir(); + + String path = ZipTest.class.getClassLoader().getResource("/test/testgzip").getPath(); + File file = new File(path); + File[] files = file.listFiles(); + List fileItems = Lists.newArrayList(); + + for (File file1 : files) { + FileItem fileItem = new FileItem(); + fileItem.setInputStream(new FileInputStream(file1)); + fileItem.setFileName(file1.getName()); + fileItems.add(fileItem); + } + + FileUtil.storeFiles(fileItems, packageFile.getPath()); + stopWatch.stop(); + System.out.println(stopWatch.getTotalTimeMillis() / 1000.0000 + " s"); + } +}