diff --git a/.gitignore b/.gitignore
index 75efa76..d5119de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
# ---> Maven
target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
@@ -11,9 +14,25 @@ buildNumber.properties
# https://github.com/takari/maven-wrapper#usage-without-binary-jar
.mvn/wrapper/maven-wrapper.jar
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
# Eclipse m2e generated files
# Eclipse Core
.project
+.settings
+.springBeans
+.sts4-cache
# JDT-specific (Eclipse Java Development Tools)
.classpath
@@ -42,4 +61,18 @@ buildNumber.properties
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..79523bd
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,83 @@
+
+
+ 4.0.0
+
+ com.dx.union
+ UnionPaySigner
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+ UTF-8
+
+
+
+
+ cn.hutool
+ hutool-http
+ 5.8.34
+
+
+ cn.hutool
+ hutool-json
+ 5.8.34
+
+
+ cn.hutool
+ hutool-poi
+ 5.8.34
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.23.1
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.23.1
+
+
+
+
+ ${project.artifactId}
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.3
+
+
+ false
+
+ jar-with-dependencies
+
+
+
+
+
+
+
+
+ com.dx.union.CheckLogin
+
+
+
+
+
+ make-assembly
+
+ package
+
+ assembly
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/dx/union/CheckLogin.java b/src/main/java/com/dx/union/CheckLogin.java
new file mode 100644
index 0000000..b593226
--- /dev/null
+++ b/src/main/java/com/dx/union/CheckLogin.java
@@ -0,0 +1,109 @@
+package com.dx.union;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.text.csv.CsvReader;
+import cn.hutool.core.text.csv.CsvUtil;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ *
+ */
+public class CheckLogin {
+
+ private static final Logger log = LogManager.getLogger(Main.class);
+ private static final char[] HEX_CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+ public static void main(String[] args) {
+ try {
+ final CsvReader reader = CsvUtil.getReader();
+ // Properties properties = getProperties();
+ // String csv_file_path = properties.getProperty("csv_file_path");
+ // log.info("csv_file_path:{}", csv_file_path);
+ //假设csv文件在classpath目录下
+ final List userList = reader.read(
+ ResourceUtil.getUtf8Reader("users.csv"), User.class);
+ log.info("读取到 {} 个需打卡账号", userList.size());
+ userList.forEach(user -> {
+ log.info("开始打卡 {} 的账号,密码为:{}", user.getUsername(), user.getPassword());
+ boolean isSignSuccess = sign(user);
+ });
+ } catch (Exception e) {
+ log.error(e);
+ }
+
+ }
+
+ public static boolean sign(User user) {
+ boolean result = false;
+ try {
+ String password = encrypt2ToMD5("weaver@2024");
+ System.out.println(password);
+ String username = "WBzhangmiao";
+ String body = HttpRequest.post("https://login.oa.unionpay.com/idsapi/portal/Login")
+ .form("username", username)
+ .form("password", password)
+ .form("saveUsername", "false")
+ .form("savePassword", "false")
+ .form("loginType", "normal")
+ .form("code", "")
+ .execute().body();
+ JSONObject bodyJson = JSONUtil.parseObj(body);
+ String token = bodyJson.getJSONObject("data").getStr("token");
+ String thirdBody = HttpRequest.get("http://oms.oa.unionpay.com/prod-api/checkTokenThenLogin?personType=0&token=" + token).execute().body();
+ JSONObject thirdBodyJson = JSONUtil.parseObj(thirdBody);
+ String thirdToken = thirdBodyJson.getStr("localToken");
+ String resultBody = HttpRequest.post("http://oms.oa.unionpay.com/prod-api/atds/ds/1").header("Authorization", "Bearer " + thirdToken).execute().body();
+ System.out.println(resultBody);
+ result = true;
+ } catch (Exception e) {
+ log.error("sign error", e);
+ }
+ return result;
+ }
+
+ /**
+ * MD5 加密
+ * @param str 待加密字符串
+ * @return MD5加密后字符串
+ */
+ public static String encrypt2ToMD5(String str) {
+ // 加密后的16进制字符串
+ String hexStr = "";
+ try {
+ // 此 MessageDigest 类为应用程序提供信息摘要算法的功能
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ // 转换为MD5码
+ byte[] digest = md5.digest(str.getBytes(StandardCharsets.UTF_8));
+ hexStr = toHexString(digest);
+ } catch (Exception e) {
+ log.error("encrypt2ToMD5 error", e);
+ }
+ return hexStr;
+ }
+
+ public static String toHexString(byte[] input) {
+ StringBuilder result = new StringBuilder();
+ for (byte b : input) {
+ result.append(HEX_CHARS[b >>> 4 & 15]);
+ result.append(HEX_CHARS[b & 15]);
+ }
+ return result.toString();
+ }
+
+ public static Properties getProperties() throws IOException {
+ Properties properties = new Properties();
+ properties.load(ResourceUtil.getStream("config.properties"));
+ return properties;
+ }
+
+}
diff --git a/src/main/java/com/dx/union/Main.java b/src/main/java/com/dx/union/Main.java
new file mode 100644
index 0000000..27a3c4d
--- /dev/null
+++ b/src/main/java/com/dx/union/Main.java
@@ -0,0 +1,7 @@
+package com.dx.union;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello world!");
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/dx/union/User.java b/src/main/java/com/dx/union/User.java
new file mode 100644
index 0000000..366b991
--- /dev/null
+++ b/src/main/java/com/dx/union/User.java
@@ -0,0 +1,35 @@
+package com.dx.union;
+
+
+import cn.hutool.core.annotation.Alias;
+
+public class User {
+ @Alias("用户名")
+ private String username;
+ @Alias("密码")
+ private String password;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return "User{" +
+ "username='" + username + '\'' +
+ ", password='" + password + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/resources/config.properties b/src/main/resources/config.properties
new file mode 100755
index 0000000..7d39b98
--- /dev/null
+++ b/src/main/resources/config.properties
@@ -0,0 +1 @@
+csv_file_path=D:/file/source/
diff --git a/src/main/resources/log4j2.properties b/src/main/resources/log4j2.properties
new file mode 100755
index 0000000..e1f4c15
--- /dev/null
+++ b/src/main/resources/log4j2.properties
@@ -0,0 +1,42 @@
+# log4j2.properties
+name= RollingFileLogConfigDemo
+# Log files location
+property.basePath = ./
+# Console appender configuration
+appender.console.type = Console
+appender.console.name = consoleLogger
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
+
+# Root logger referring to console appender
+rootLogger.appenderRef.stdout.ref = consoleLogger
+
+status = warn
+
+# RollingFileAppender name, pattern, path and rollover policy
+appender.rolling.type = RollingFile
+appender.rolling.name = fileLogger
+appender.rolling.fileName= ${basePath}/app.log
+appender.rolling.filePattern= ${basePath}/app_%d{yyyyMMdd}.log.gz
+appender.rolling.layout.type = PatternLayout
+appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss.SSS} %level [%t] [%l] - %msg%n
+appender.rolling.policies.type = Policies
+
+# RollingFileAppender rotation policy
+appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
+appender.rolling.policies.size.size = 10MB
+appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
+appender.rolling.policies.time.interval = 1
+appender.rolling.policies.time.modulate = true
+appender.rolling.strategy.type = DefaultRolloverStrategy
+appender.rolling.strategy.delete.type = Delete
+appender.rolling.strategy.delete.basePath = ${basePath}
+appender.rolling.strategy.delete.maxDepth = 10
+appender.rolling.strategy.delete.ifLastModified.type = IfLastModified
+
+# Delete all files older than 30 days
+appender.rolling.strategy.delete.ifLastModified.age = 30d
+
+# Configure root logger
+rootLogger.level = debug
+rootLogger.appenderRef.rolling.ref = fileLogger
diff --git a/src/main/resources/users.csv b/src/main/resources/users.csv
new file mode 100644
index 0000000..73f732d
--- /dev/null
+++ b/src/main/resources/users.csv
@@ -0,0 +1,3 @@
+用户名,密码
+111,222
+1111,2222