初始化代码
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
@@ -0,0 +1,204 @@
|
|||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>Java_Utils</groupId>
|
||||||
|
<artifactId>Java_Utils</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<powermock.version>1.4.9</powermock.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>1.7</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.7</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.build.jdk.version>1.8</project.build.jdk.version>
|
||||||
|
<javax.version>7.0</javax.version>
|
||||||
|
<javax.servlet.version>3.0</javax.servlet.version>
|
||||||
|
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
<!--javax依赖-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>jstl</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax</groupId>
|
||||||
|
<artifactId>javaee-web-api</artifactId>
|
||||||
|
<version>${javax.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.belerweb</groupId>
|
||||||
|
<artifactId>pinyin4j</artifactId>
|
||||||
|
<version>2.5.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>1.7.25</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>19.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.google-collections</groupId>
|
||||||
|
<artifactId>google-collect</artifactId>
|
||||||
|
<version>snapshot-20080530</version>
|
||||||
|
</dependency>
|
||||||
|
<!--引入Spring的CollectionUtils类,这边主要使用Spring的类代替apache-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>4.3.1.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--添加Itext依赖-->
|
||||||
|
<!--iText 用于html生成pdf-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itextpdf</artifactId>
|
||||||
|
<version>5.5.11</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf</groupId>
|
||||||
|
<artifactId>itext-asian</artifactId>
|
||||||
|
<version>5.2.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.itextpdf.tool</groupId>
|
||||||
|
<artifactId>xmlworker</artifactId>
|
||||||
|
<version>5.5.11</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!--for transform-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.7.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 图片缩略图 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.coobird</groupId>
|
||||||
|
<artifactId>thumbnailator</artifactId>
|
||||||
|
<version>0.4.8</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!--二维码处理-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.zxing</groupId>
|
||||||
|
<artifactId>core</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-configuration2 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-configuration2</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-compress</artifactId>
|
||||||
|
<version>1.18</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>1.2.54</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--redis数据库相关的依赖-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>redis.clients</groupId>
|
||||||
|
<artifactId>jedis</artifactId>
|
||||||
|
<version>2.7.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-redis</artifactId>
|
||||||
|
<version>1.6.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
<version>4.3.7.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>Java_Utils</finalName>
|
||||||
|
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-clean-plugin</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</plugin>
|
||||||
|
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.7.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.20.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>3.2.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
|
<version>2.5.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.8.2</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/java</directory>
|
||||||
|
<includes>
|
||||||
|
<include>**/*.properties</include>
|
||||||
|
<include>**/*.xml</include>
|
||||||
|
</includes>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# 我的公众号
|
||||||
|

|
||||||
|
|
||||||
|
# 作用
|
||||||
|
保存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获取文件夹文件、单测
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package additive;
|
||||||
|
|
||||||
|
public class ValidTool {
|
||||||
|
|
||||||
|
public static void assertIsTrue(boolean expression, String message) {
|
||||||
|
if (!expression) {
|
||||||
|
throw new IllegalArgumentException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* @(#) PagingQueryResp
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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<T> {
|
||||||
|
/**
|
||||||
|
* 页数
|
||||||
|
*/
|
||||||
|
@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<T> resultList;
|
||||||
|
|
||||||
|
public Integer getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(Integer total) {
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> getResultList() {
|
||||||
|
return resultList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResultList(List<T> resultList) {
|
||||||
|
this.resultList = resultList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<EncodeHintType,Object> 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<EncodeHintType,Object> getHints() {
|
||||||
|
return hints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHints(Map<EncodeHintType,Object> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* @(#) BeanCloneException
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* @(#) BeanPropertiesCopyException
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* @(#) SerializableDeepCloneException
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* @(#) CloneType
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 2018-10-07 17:13:13
|
||||||
|
*/
|
||||||
|
|
||||||
|
package type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author selfImpr
|
||||||
|
*/
|
||||||
|
public enum CloneType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基本类型和final的不需要复制的类型
|
||||||
|
*/
|
||||||
|
SIMPLE_TYPE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数组
|
||||||
|
*/
|
||||||
|
ARRAY,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要深度克隆的类
|
||||||
|
*/
|
||||||
|
DEEP_CLONE_CLASS
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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<FileItem> 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<File> findAllDirFromDir(String dirPath){
|
||||||
|
File dir = new File(dirPath);
|
||||||
|
if(!dir.exists() || !dir.isDirectory()){
|
||||||
|
throw new RuntimeException("非文件夹或者文件夹位置错误");
|
||||||
|
}
|
||||||
|
List<File> result = findDir(dir);
|
||||||
|
result.add(dir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<File> findDir(File file ){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
for(File child : Objects.requireNonNull(file.listFiles())){
|
||||||
|
if(child.isDirectory()){
|
||||||
|
list.add(child);
|
||||||
|
List<File> tempList = findDir(child);
|
||||||
|
if(!CollectionUtils.isEmpty(tempList)){
|
||||||
|
list.addAll(tempList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拿到文件夹下面的所有空文件夹
|
||||||
|
*/
|
||||||
|
public static List<File> findAllEmptyDirFromDir( String dirPath){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
File dir = new File(dirPath);
|
||||||
|
if(!dir.exists() || !dir.isDirectory()){
|
||||||
|
throw new RuntimeException("非文件夹或者文件夹位置错误");
|
||||||
|
}
|
||||||
|
List<File> allList = findAllDirFromDir(dirPath);
|
||||||
|
for(File dirFile:allList){
|
||||||
|
if(isEmptyFile(dirFile)){
|
||||||
|
list.add(dirFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过目录获取目录下所有的文件
|
||||||
|
*/
|
||||||
|
public static List<File> findAllFile(File dir){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
for (File file : Objects.requireNonNull(dir.listFiles())){
|
||||||
|
if(file.isFile()){
|
||||||
|
list.add(file);
|
||||||
|
}else{
|
||||||
|
List<File> tempList = findAllFile(file);
|
||||||
|
if(!CollectionUtils.isEmpty(tempList)){
|
||||||
|
list.addAll(tempList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isEmptyFile(File dir) {
|
||||||
|
List<File> child = findAllFile(dir);
|
||||||
|
return CollectionUtils.isEmpty(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拿到文件夹下面的所有非空文件夹
|
||||||
|
*/
|
||||||
|
public static List<File> findAllNotEmptyDirFromDir( String dirPath){
|
||||||
|
List<File> list = Lists.newArrayList();
|
||||||
|
File dir = new File(dirPath);
|
||||||
|
if(!dir.exists() || !dir.isDirectory()){
|
||||||
|
throw new RuntimeException("非文件夹或者文件夹位置错误");
|
||||||
|
}
|
||||||
|
List<File> allList = findAllDirFromDir(dirPath);
|
||||||
|
for(File dirFile:allList){
|
||||||
|
if(!isEmptyFile(dir)){
|
||||||
|
list.add(dirFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* @(#) PageUtil
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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> T
|
||||||
|
* @return 分页通用对象
|
||||||
|
*/
|
||||||
|
public static <T> CommonPageResp<T> pagingListFromZero(List<T> list, int pageIndex, int pageSize) {
|
||||||
|
assertIsTrue(pageIndex >= 0, "pageIndex必需大于等于0");
|
||||||
|
|
||||||
|
if (list == null ) {
|
||||||
|
return nullPage(pageSize);
|
||||||
|
}
|
||||||
|
CommonPageResp<T> 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> T
|
||||||
|
* @return 分页通用对象
|
||||||
|
*/
|
||||||
|
static <T> CommonPageResp<T> pagingListFromOne(List<T> list, int pageIndex, int pageSize) {
|
||||||
|
if ( pageIndex<1){
|
||||||
|
pageIndex = 1;
|
||||||
|
}
|
||||||
|
CommonPageResp<T> 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 <T> CommonPageResp<T> nullPage(int pageSize) {
|
||||||
|
CommonPageResp<T> pagingQueryResp = new CommonPageResp<>();
|
||||||
|
pagingQueryResp.setResultList(Collections.emptyList());
|
||||||
|
pagingQueryResp.setTotal(ZERO);
|
||||||
|
pagingQueryResp.setPageIndex(ZERO);
|
||||||
|
pagingQueryResp.setPageSize(pageSize);
|
||||||
|
return pagingQueryResp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* @(#) StringUtils
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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<chars.length;i++){
|
||||||
|
if (chars[0] >= 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<chars.length;i++){
|
||||||
|
if (chars[0] >= 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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<Class> 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<Field> getAllField(Object object) {
|
||||||
|
List<Field> fields = new ArrayList<>();
|
||||||
|
if (object == null) {
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO 这边的这个类型会不会有问题
|
||||||
|
return Arrays.asList(object.getClass().getDeclaredFields());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> getAllFieldName(Object object) {
|
||||||
|
List<String> 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
|
||||||
|
* <p>
|
||||||
|
* <p>
|
||||||
|
* 并且还不能判断自定义的泛型类型。
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
*/
|
||||||
|
public static List<Class> getGenericParamType(Object object) {
|
||||||
|
List<Class> 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<Class> getGenericParamTypeInField(Field field) {
|
||||||
|
List<Class> 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<Class> getClassesByInterface(String[] filePath, Class interfaceClass) {
|
||||||
|
Set<Class> interfaceImpClasses = new HashSet<>();
|
||||||
|
Set<Class> classes = new HashSet<>();
|
||||||
|
|
||||||
|
for (String path : filePath) {
|
||||||
|
//把前面那个"/"去掉
|
||||||
|
Set<Class> 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<Class> getAllClass(File file, String packageName) {
|
||||||
|
Set<Class> 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<Method> getSuperClassMethod(Class clazz) {
|
||||||
|
List<Method> 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<Method> 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> T newInstance(String className,Class<T> 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<T> classes = (Class<T>) classType;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return classes.newInstance();
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
throw new RuntimeException("类实例化出错"+e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
throw new RuntimeException("类实例化出错了" + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* @(#) ClassVisitorUtils
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* @(#) MethodVisitorUtils
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
/*
|
||||||
|
* @(#) FillTemplateHelper
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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("<html>");
|
||||||
|
sb.append("<head>");
|
||||||
|
sb.append("<meta charset=\"UTF-8\" />");
|
||||||
|
sb.append("</head>");
|
||||||
|
sb.append("<body style='font-family:SimSun;'>");
|
||||||
|
sb.append("<div class=\"executed-report\">");
|
||||||
|
sb.append("<div class=\"report-box clearfix\">");
|
||||||
|
sb.append(content);
|
||||||
|
sb.append("</div>");
|
||||||
|
sb.append("</div>");
|
||||||
|
sb.append("</body>");
|
||||||
|
sb.append("</html>");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
public void setRedisTemplate(RedisTemplate<String, Object> 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<Object, Object> hmget(String key) {
|
||||||
|
return redisTemplate.opsForHash().entries(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HashSet
|
||||||
|
* @param key 键
|
||||||
|
* @param map 对应多个键值
|
||||||
|
* @return true 成功 false 失败
|
||||||
|
*/
|
||||||
|
public boolean hmset(String key, Map<String, Object> 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<String, Object> 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<Object> 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<Object> 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<Object> 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<Object> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval,
|
||||||
|
List<OriginTimeValue> 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<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval,
|
||||||
|
List<OriginTimeValue> 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<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate, int timeInterval,
|
||||||
|
List<OriginTimeValue> 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<TargetTimeValue> fullFillTimeValue(LocalDateTime startDate, LocalDateTime endDate,
|
||||||
|
int timeInterval, List<OriginTimeValue> 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<TargetTimeValue> fullFillRule(List<OriginTimeValue> originTimeValues, Instant firstInstant, Instant finalInstant,
|
||||||
|
int seconds) {
|
||||||
|
//转换为Time-value形式的map
|
||||||
|
if (CollectionUtils.isEmpty(originTimeValues)) {
|
||||||
|
originTimeValues = Lists.newArrayList();
|
||||||
|
}
|
||||||
|
Map<Long, Long> timeValueMap = originTimeValues.stream().collect(Collectors.toMap(OriginTimeValue::getTime,
|
||||||
|
OriginTimeValue::getValue));
|
||||||
|
final List<TargetTimeValue> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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> T fromJson(String json, Class<T> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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> T convertXmlStrToObject(String xml, Class<T> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* @(#) TreeNode
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2019
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package util.tree;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这个对象主要用于处理从父推子的一条链路的处理
|
||||||
|
* @author 黄志军
|
||||||
|
*/
|
||||||
|
public class TreeNode2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前节点的标识,code
|
||||||
|
*/
|
||||||
|
private String code;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 父节点标识
|
||||||
|
*/
|
||||||
|
private String parentCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 子节点对象数组
|
||||||
|
*/
|
||||||
|
private List<TreeNode2> 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<TreeNode2> getChildNodeList() {
|
||||||
|
return childNodeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setChildNodeList(List<TreeNode2> childNodeList) {
|
||||||
|
this.childNodeList = childNodeList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* @(#) TreeUtils
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2019
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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<TreeNode> treeNodeList, String code) {
|
||||||
|
//对所有的节点进行校验,校验规则是不能存在两个code一样的节点
|
||||||
|
validTreeNodeList(treeNodeList);
|
||||||
|
Map<String, TreeNode> 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<String, TreeNode> 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<TreeNode2> treeNodeList ,String code){
|
||||||
|
TreeNode2 destNode = validTreeNode2List(treeNodeList,code);
|
||||||
|
if (destNode == null ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, List<TreeNode2>> treeNodeMap = Maps.newHashMap();
|
||||||
|
//创建 父code-节点的键值对关系
|
||||||
|
treeNodeList.forEach(treeNode -> {
|
||||||
|
List<TreeNode2> 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<TreeNode2> getChildNodeList( Map<String, List<TreeNode2>> treeNodeMap, String code) {
|
||||||
|
List<TreeNode2> 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<TreeNode> treeNodeList){
|
||||||
|
List<String> codeList = treeNodeList.stream().map(TreeNode::getCode).distinct().collect(Collectors.toList());
|
||||||
|
if(codeList.size() != treeNodeList.size()){
|
||||||
|
throw new RuntimeException("存在相同的code");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TreeNode2 validTreeNode2List(List<TreeNode2> treeNodeList,String code){
|
||||||
|
List<String> codeList = treeNodeList.stream().map(TreeNode2::getCode).distinct().collect(Collectors.toList());
|
||||||
|
if(codeList.size() != treeNodeList.size()){
|
||||||
|
throw new RuntimeException("存在相同的code");
|
||||||
|
}
|
||||||
|
List<TreeNode2> list = treeNodeList.stream().filter(item->item.getCode().equals(code)).collect(Collectors.toList());
|
||||||
|
return CollectionUtils.isEmpty(list) ?null:list.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<File> 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<File> 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<File> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ @(#) log4j2.xml
|
||||||
|
~ log4j的配置文件
|
||||||
|
~ <br> Copyright: Copyright (c) 2018
|
||||||
|
~ <br> Company:黄志军
|
||||||
|
~ <br> @author selfImpr
|
||||||
|
~ <br> 2018-05-21 16:20:42
|
||||||
|
~ <br> @description
|
||||||
|
~
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<Configuration status="WARN">
|
||||||
|
<Properties>
|
||||||
|
|
||||||
|
<Property name="appId" value="Spring"/>
|
||||||
|
|
||||||
|
<Property name="moduleId" value="Spring"/>
|
||||||
|
|
||||||
|
<!--<Property name="logDir" value="/opt/logs/"/>-->
|
||||||
|
<Property name="logDir" value="F:/sunsharing-program-code/运行日志/sunsharing/logs/"/><!-- windows use this-->
|
||||||
|
<Property name="logFilePrefix" value="${logDir}/${appId}/${appId}-${moduleId}"/>
|
||||||
|
<Property name="commonPath" value="${logFilePrefix}.log"/>
|
||||||
|
<Property name="exceptionPath" value="${logFilePrefix}-exception.log"/>
|
||||||
|
<Property name="accessPath" value="${logFilePrefix}-access.log"/>
|
||||||
|
<Property name="commonPattern" value="%d{MM-dd HH:mm:ss.SSS} %p %thread %X{invokeNo} %logger{40} %line %msg%n"/>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Appenders>
|
||||||
|
|
||||||
|
<Console name="Console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout pattern="${commonPattern}"/>
|
||||||
|
</Console>
|
||||||
|
|
||||||
|
<RollingFile name="fileAppender" fileName="${commonPath}" filePattern="${commonPath}.%d{yyyy-MM-dd}" append="true">
|
||||||
|
<PatternLayout pattern="${commonPattern}"/>
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
|
||||||
|
</Policies>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
<RollingFile name="errorAppender" fileName="${exceptionPath}" filePattern="${exceptionPath}.%d{yyyy-MM-dd}" append="true">
|
||||||
|
<PatternLayout pattern="${commonPattern}"/>
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
|
||||||
|
</Policies>
|
||||||
|
<Filters>
|
||||||
|
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/>
|
||||||
|
</Filters>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
<RollingFile name="accessAppender" fileName="${accessPath}" filePattern="${accessPath}.%d{yyyy-MM-dd}" append="true">
|
||||||
|
<PatternLayout pattern="${commonPattern}"/>
|
||||||
|
<Policies>
|
||||||
|
<TimeBasedTriggeringPolicy modulate="true" interval="1"/>
|
||||||
|
</Policies>
|
||||||
|
</RollingFile>
|
||||||
|
|
||||||
|
</Appenders>
|
||||||
|
|
||||||
|
<Loggers>
|
||||||
|
<Logger name="com.sunsharing" level="DEBUG"/>
|
||||||
|
<Logger name="jdbc.sqltiming" level="INFO"/>
|
||||||
|
|
||||||
|
<Root level="WARN">
|
||||||
|
<AppenderRef ref="Console"/>
|
||||||
|
<AppenderRef ref="fileAppender"/>
|
||||||
|
<AppenderRef ref="errorAppender"/>
|
||||||
|
</Root>
|
||||||
|
</Loggers>
|
||||||
|
|
||||||
|
</Configuration>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>天天提鹅</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 += "<font color=\'#778899\' size=2>" + `兑换金币:${data.resultData.data.cnumber}` + "</font>\n\n"
|
||||||
|
that.log(`当前总金币:${data.resultData.data.goldTotal}`);
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `当前总金币:${data.resultData.data.goldTotal}` +"</font>\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 += "<font color=\'#778899\' size=2>" +`收取鹅蛋:${data.resultData.data.eggTotal}个成功` + "</font>\n\n"
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `当前总鹅蛋数量:${data.resultData.data.userLevelDto.userHaveEggNum}` + "</font>\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 += "<font color=\'#778899\' size=2>" + `收取鹅蛋失败:${data.resultData.msg}` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>动动国创</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 + "<font color=\'#778899\' size=2>" + `共获得${$.beans} 京豆\n` + "</font>\n\n"
|
||||||
|
}
|
||||||
|
message = message +"----\n\n"
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
.catch((e) => {
|
||||||
|
$.logErr(e)
|
||||||
|
message = message + "<font color=\'#778899\' size=2>" + e + "</font>\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 += "<font color=\'#778899\' size=2>" + `获得 你猜获得了啥🐶 ${data.data.bizMsg}` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>动动赚赚</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 += "<font color=\'#778899\' size=2>" + `本次获得${parseInt($.totalBeanNum) - $.nowBean}京豆,${parseInt($.totalNum) - $.nowNum}金币\n` + "</font>\n\n"
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `累计获得${$.totalBeanNum}京豆,${$.totalNum}金币\n可兑换${$.totalNum / 10000}元无门槛红包` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>动动摇钱树</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 += "<font color=\'#778899\' size=2>" + `【我的金果数量】${userInfo.treeInfo.fruit}\n` + "</font>\n\n";
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `【我的金币数量】${userInfo.treeInfo.coin}\n` + "</font>\n\n";
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `【距离${userInfo.treeInfo.level + 1}级摇钱树还差】${userInfo.treeInfo.progressLeft}\n` + "</font>\n\n";
|
||||||
|
} else {
|
||||||
|
$.log(`京东账号${$.index}${$.UserName}运行失败\n此账号未实名认证或者未参与过此活动\n①如未参与活动,请先去京东app参加摇钱树活动\n入口:我的->游戏与互动->查看更多\n②如未实名认证,请进行实名认证`)
|
||||||
|
// $.msg($.name, `【提示】京东账号${$.index}${$.UserName}运行失败`, '此账号未实名认证或者未参与过此活动\n①如未参与活动,请先去京东app参加摇钱树活动\n入口:我的->游戏与互动->查看更多\n②如未实名认证,请进行实名认证', {"open-url": "openApp.jdMobile://"});
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `运行失败\n此账号未实名认证或者未参与过此活动\n①如未参与活动,请先去京东app参加摇钱树活动\n入口:我的->游戏与互动->查看更多\n②如未实名认证,请进行实名认证` + "</font>\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 +="<font color=\'#778899\' size=2>" + `【距离${data.treeInfo.level + 1}级摇钱树还差】${data.treeInfo.progressLeft}\n` + "</font>\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 += "<font color=\'#778899\' size=2>" + `【我的金果数量】${res.resultData.data.gaAmount}\n` + "</font>\n\n";
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `【我的金贴数量】${res.resultData.data.gcAmount / 100}\n` + "</font>\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 += "<font color=\'#778899\' size=2>" + `【7日签到奖励领取】${getSignAwardRes.datamessage}\n` + "</font>\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 +="<font color=\'#778899\' size=2>" + `【偷取好友金果】共${$.amount}个\n` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>动动萌宠</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 + "<font color=\'#778899\' size=2>"+ "动动萌宠未开启\n请手动去动动APP开启活动\n入口:我的->游戏与互动->查看更多开启</font>\n\n"
|
||||||
|
$.log($.name, '', `【提示】动动账号${$.index}${$.nickName}\n萌宠活动未开启\n请手动去动动APP开启活动\n入口:我的->游戏与互动->查看更多开启`);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!$.petInfo.goodsInfo) {
|
||||||
|
message = message + "<font color=\'#778899\' size=2>"+ "暂未选购新的商品</font>\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 + "<font color=\'#778899\' size=2>"+ `【提醒⏰】${$.petInfo.goodsInfo.goodsName}已可领取`, '请去动动APP或微信小程序查看' +"</font>\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 + "<font color=\'#778899\' size=2>"+ `【提醒⏰】已领取红包,但未继续领养新的物品`, '请去动动APP或微信小程序继续领养' + "</font>\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 + "<font color=\'#778899\' size=2>"+ `【第${response.result.medalNum + 1}块勋章完成进度】${response.result.medalPercent}%,还需收集${response.result.needCollectEnergy}好感\n` + "</font>\n\n";
|
||||||
|
message = message + "<font color=\'#778899\' size=2>"+ `【已获得勋章】${response.result.medalNum}块,还需收集${response.result.needCollectMedalNum}块即可兑换奖品“${$.petInfo.goodsInfo.goodsName}”\n` + "</font>\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 += "<font color=\'#778899\' size=2>"+ `【额外奖励${getHelpAddedBonusResult.result.reward}领取】${getHelpAddedBonusResult.message}\n` + "</font>\n\n";
|
||||||
|
}
|
||||||
|
that.log(`领取30g额外奖励结果:【${getHelpAddedBonusResult.message}】`);
|
||||||
|
} else {
|
||||||
|
that.log("已经领取过5好友助力额外奖励");
|
||||||
|
message += "<font color=\'#778899\' size=2>"+ `【额外奖励】已领取\n` + "</font>\n\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
that.log("助力好友未达到5个")
|
||||||
|
message += "<font color=\'#778899\' size=2>"+ `【额外奖励】领取失败,原因:给您助力的人未达5个\n` + "</font>\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 += "<font color=\'#778899\' size=2>"+ `【助力您的好友】${str}\n` + "</font>\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 + "<font color=\'#778899\' size=2>"+ `【您助力的好友】${helpPeoples.substr(0, helpPeoples.length - 1)}\n` +"</font>\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 += "<font color=\'#778899\' size=2>"+ `【邀请新用户】获取狗粮${$.taskInfo.inviteFriendsInit.reward}g\n` +"</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>动动超市</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 + "<font color=\'#778899\' size=2>" +`❌ ${$.name}, 失败! 原因: ${e}!` + "</font>\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 += "<font color=\'#778899\' size=2>" + `${taskData.data.taskErrorTips}` + "</font>\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 += "<font color=\'#778899\' size=2>" + `成功领取${beanCount}京豆` + "</font>\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 += "<font color=\'#778899\' size=2>" + `成功领取${beanCount}京豆` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>极速签到领红包</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 + "<font color=\'#778899\' size=2>" + "获得优惠券:" + $.reward.prizeDesc + ',面值:' + $.reward.amount + ",满" + $.reward.useLimit + "可用" + "</font>\n\n"
|
||||||
|
that.log("获得优惠券:" + $.reward.prizeDesc + ',面值:' + $.reward.amount + ",满" + $.reward.useLimit + "可用");
|
||||||
|
} else if ($.reward.prizeType == 4) {
|
||||||
|
message = message + "<font color=\'#778899\' size=2>" + "获得现金:" + $.reward.amount + ',描述:' + $.reward.prizeDesc + "</font>\n\n"
|
||||||
|
that.log("获得现金:" + $.reward.amount + ',描述:' + $.reward.prizeDesc);
|
||||||
|
} else {
|
||||||
|
message = message + "<font color=\'#778899\' size=2>" + "获得" + $.reward.prizeDesc + ",面值:" + $.reward.amount + "</font>\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 + "<font color=\'#778899\' size=2>" + "有" + item.amount + "现金没有提现,尝试提现中" + "</font>\n\n"
|
||||||
|
that.log("有" + item.amount + "现金没有提现,尝试提现中");
|
||||||
|
await apCashWithDraw(item);
|
||||||
|
await $.wait(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})()
|
||||||
|
.catch((e) => {
|
||||||
|
message = message + "<font color=\'#778899\' size=2>" + `❌ ${$.name}, 失败! 原因: ${e}!` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
@@ -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 += "<font color=\'#FFA500\'>[通知] </font><font color=\'#006400\' size='3'>极速签到挣金币</font> \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 + "<font color=\'#778899\' size=2>【羊毛姐妹】<font color=\'#FFA500\' size=3>" + username + " </font> </font> \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 += "<font color=\'#778899\' size=2>" + `本次运行获得${$.score}金币,共计${$.total}金币` + "</font>\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 += "<font color=\'#778899\' size=2>" + `极速版签到提现:签到异常:${JSON.stringify(data)}\n` + "</font>\n\n"
|
||||||
|
console.log(`极速版签到提现:签到失败:${data.data.retMessage}\n`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message += "<font color=\'#778899\' size=2>" + `极速版签到提现:签到异常:${JSON.stringify(data)}\n` + "</font>\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 +="<font color=\'#778899\' size=2>" + `${data.data.taskInfo.mainTitle}任务完成成功,预计获得${data.data.reward}金币` + "</font>\n\n"
|
||||||
|
that.log(`${data.data.taskInfo.mainTitle}任务完成成功,预计获得${data.data.reward}金币`)
|
||||||
|
} else {
|
||||||
|
message +="<font color=\'#778899\' size=2>" + `${data.data.taskInfo.mainTitle}任务发生异常${data.errMsg}` + "</font>\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 +="<font color=\'#778899\' size=2>" + `提现${item.amount}微信现金,` + "</font>\n\n"
|
||||||
|
await cashOut(item.id,item.poolBaseId,item.prizeGroupId,item.prizeBaseId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message +="<font color=\'#778899\' size=2>" + `提现发生异常:${data.errMsg}` + "</font>\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 += "<font color=\'#778899\' size=2>" + `极速版签到提现,去提现${code['prizeValue']}微信现金,` + "</font>\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 +="<font color=\'#778899\' size=2>" + `极速版签到提现现金:失败:${JSON.stringify(data)}\n` + "</font>\n\n"
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message +="<font color=\'#778899\' size=2>" + `极速版签到提现现金:失败:${JSON.stringify(data)}\n` + "</font>\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 +="<font color=\'#778899\' size=2>" + `提现失败:${data['data']['message']}` + "</font>\n\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message +="<font color=\'#778899\' size=2>" + `提现失败:${data['data']['message']}` + "</font>\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 )
|
||||||
|
address = address + code[pos] + ")"
|
||||||
|
return address
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,10 @@
|
|||||||
|
12321321
|
||||||
|
3213
|
||||||
|
|
||||||
|
3213213
|
||||||
|
321321
|
||||||
|
321321
|
||||||
|
3
|
||||||
|
|
||||||
|
32132131
|
||||||
|
321321321
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 132 KiB |
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<OriginTimeValue> originTimeValueList = Lists.newArrayList();
|
||||||
|
originTimeValueList.add(new OriginTimeValue(1542995383, 109991));
|
||||||
|
|
||||||
|
List<TargetTimeValue> targetTimeValues1 = FillFullTimeValueUtil.MINUTE.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||||
|
.plusDays(1), 1, originTimeValueList,
|
||||||
|
TimeZone.getDefault());
|
||||||
|
|
||||||
|
|
||||||
|
List<TargetTimeValue> targetTimeValues2 = FillFullTimeValueUtil.HOUR.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||||
|
.plusDays(1), 2, originTimeValueList,
|
||||||
|
TimeZone.getDefault());
|
||||||
|
|
||||||
|
List<TargetTimeValue> targetTimeValues3 = FillFullTimeValueUtil.DAY.fullFillTimeValue(LocalDateTime.now(), LocalDateTime.now()
|
||||||
|
.plusDays(100), 10, originTimeValueList,
|
||||||
|
TimeZone.getDefault());
|
||||||
|
|
||||||
|
List<TargetTimeValue> 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()));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package util;
|
||||||
|
|
||||||
|
|
||||||
|
import entity.CommonPageResp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
public class PageUtilTest {
|
||||||
|
|
||||||
|
|
||||||
|
private static List<String> valueList = new ArrayList<>();
|
||||||
|
private static List<String> emptyList = new ArrayList<>();
|
||||||
|
private static List<String> 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<String> result = PageUtil.pagingListFromZero(valueList,-1,100);
|
||||||
|
CommonPageResp<String> result1 = PageUtil.pagingListFromZero(valueList,1,2);
|
||||||
|
CommonPageResp<String> result2 = PageUtil.pagingListFromZero(valueList,0,2);
|
||||||
|
CommonPageResp<String> result3 = PageUtil.pagingListFromZero(valueList,100,2);
|
||||||
|
CommonPageResp<String> result5 = PageUtil.pagingListFromZero(emptyList,100,3);
|
||||||
|
CommonPageResp<String> result6 = PageUtil.pagingListFromZero(nullList,100,2);
|
||||||
|
|
||||||
|
|
||||||
|
// CommonPageResp<String> result = PageUtil.pagingListFromOne(valueList,-1,100);
|
||||||
|
CommonPageResp<String> result7 = PageUtil.pagingListFromOne(valueList,1,2);
|
||||||
|
CommonPageResp<String> result8 = PageUtil.pagingListFromOne(valueList,2,2);
|
||||||
|
CommonPageResp<String> result9 = PageUtil.pagingListFromOne(valueList,100,2);
|
||||||
|
CommonPageResp<String> result10 = PageUtil.pagingListFromOne(emptyList,100,3);
|
||||||
|
CommonPageResp<String> result11 = PageUtil.pagingListFromOne(nullList,100,2);
|
||||||
|
System.out.println("直接断点查看结果");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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]"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 829 KiB |
@@ -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"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 388 KiB |
@@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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("");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* @(#) TestGzip
|
||||||
|
* 版权声明 网宿科技, 版权所有 违者必究
|
||||||
|
*
|
||||||
|
* <br> Copyright: Copyright (c) 2018
|
||||||
|
* <br> Company:网宿科技
|
||||||
|
* <br> @author Administrator
|
||||||
|
* <br> @description 功能描述
|
||||||
|
* <br> 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<File> 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<FileItem> 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user