• 欢迎光临~

学工云 - 蘑菇云 自动打卡脚本

开发技术 开发技术 2022-08-02 次浏览

先上代码

主方法

package com;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.*;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author xiao_rao
* @date 2022-07-31 21:13:22
* @description
*/
public class Start {

static URL loginURL;
static URL signInURL;
static URL planIdURL;

static String Json;


//http请求头部信息。
public final static String Accept_Language = "zh-CN,zh;q=0.8";
public final static String user_agent_value = "Mozilla/5.0 (Linux; Android 7.0; HTC M9e Build/EZG0TF) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.1566.54 Mobile Safari/537.36";
public final static String Content_Type = "application/json; charset=UTF-8";
public final static String Host = "api.moguding.net:9000";
public final static String Accept_Encoding = "";
public final static String Cache_Control = "no-cache";

//用于将程序运行过程中的信息输出到RunTimeLog.txt文件中 方便对异常就行追查
static StringBuffer s = new StringBuffer();

public static void main(String[] args) throws IOException {
List<UserPO> userList = new ArrayList<>();
UserPO userPO = new UserPO();
init();
BufferedReader in = null;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream("src/MoGuDing.txt"), "UTF-8");
in = new BufferedReader(isr);
String str = "";
//将读取到的json信息转换user对象
while ((str = in.readLine()) != null) {
userPO = JSON.parseObject(str, UserPO.class);
if (null != userPO.getStatus() && userPO.getStatus() == 1) {
userPO.setCardType("END");
} else {
userPO.setCardType("START");
}
if (null != userPO.getToken() && !userPO.getToken().equals("")) {
getSign(userPO);
SignIn(userPO);
}
userList.add(userPO);
}
in.close();
doCard(userList);
} catch (IOException e) {
e.printStackTrace();
}
}


/**
* 初始化数据
**/
static Integer day = 0;

public static void init() throws MalformedURLException {
loginURL = new URL("https://api.moguding.net:9000/session/user/v1/login");
signInURL = new URL("https://api.moguding.net:9000/attendence/clock/v2/save");
planIdURL = new URL("https://api.moguding.net:9000/practice/plan/v3/getPlanByStu");
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("dd");
day = Integer.valueOf(format.format(date));
}

public static void doCard(List<UserPO> userPOS) {
/**
* 这个try代码块用于捕捉打卡时候的异常,并且可以让程序继续执行
*/
try {
userPOS.forEach(item -> {
if (null != item.getToken() && !item.getToken().equals(" ")) {
return;
}
//登陆
login(item);
//计算获取planId的sign
getPlanIdSign(item);
// 获取planId
getPlanId(item);
// 获取签到需要的sign
getSign(item);
//打卡
SignIn(item);
});
inputRecord(userPOS);
} catch (
Exception e) {
e.printStackTrace();
}
}


public static String PostRequest(URL Url, String token, String sign, String roleKey, String jsonStr) {
OutputStreamWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) Url.openConnection();
conn.setRequestMethod("POST");

//发送POST请求必须设置为true
conn.setDoOutput(true);
conn.setDoInput(true);
//设置连接超时时间和读取超时时间
conn.setConnectTimeout(30000);
conn.setReadTimeout(10000);

conn.setRequestProperty("Host", Host);
conn.setRequestProperty("Accept-Language", Accept_Language);
conn.setRequestProperty("User-Agent", user_agent_value);
conn.setRequestProperty("Sign", sign);
conn.setRequestProperty("Authorization", token);
conn.setRequestProperty("roleKey", roleKey);
conn.setRequestProperty("Content-Type", Content_Type);
conn.setRequestProperty("Accept-Encoding", Accept_Encoding);
conn.setRequestProperty("Cache-Control", Cache_Control);
//获取输出流
out = new OutputStreamWriter(conn.getOutputStream());

out.write(jsonStr);
out.flush();
out.close();
//取得输入流,并使用Reader读取
if (200 == conn.getResponseCode()) {
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
} else {

s.append("ResponseCode is an error code:" + conn.getResponseCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return result.toString();
}

//登陆
public static void login(UserPO userPOs) {
LoginDTO loginDTO = new LoginDTO();
loginDTO.setPassword(userPOs.getPassword());
loginDTO.setPhone(userPOs.getAccont());
loginDTO.setLoginType("android");
String loginJson = JSON.toJSONString(loginDTO);
//登陆 获得响应信息
Json = PostRequest(loginURL, "", "", "", loginJson);
JSONObject jsonObject = JSONObject.parseObject(Json);
Integer code = jsonObject.getInteger("code");
if (code != 200) {
System.out.println("账号;" + loginDTO.getPhone() + "登陆失败! 原因====>" + jsonObject.getString("msg"));
} else {
//将获得的信息给到user对象
JSONObject data = jsonObject.getJSONObject("data");
userPOs.setToken(data.getString("token"));
userPOs.setUserId(data.getString("userId"));
userPOs.setMoguNo(data.getString("moguNo"));
}
}

public static void getPlanIdSign(UserPO userPOs) {
String str = userPOs.getUserId() + "student" + "3478cbbc33f84bd00d75d7dfa69e0daa";
try {
// 生成一个MD5加密计算摘要
MessageDigest md = MessageDigest.getInstance("MD5");
// 计算md5函数
md.update(str.getBytes());
// digest()最后确定返回md5 hash值,返回值为8位字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
// BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
// 一个byte是八位二进制,也就是2位十六进制字符(2的8次方等于16的2次方)
userPOs.setPlanIdSign(new BigInteger(1, md.digest()).toString(16));
} catch (Exception e) {
e.printStackTrace();
}
}

//获取planid
public static void getPlanId(UserPO userPOs) {
Json = PostRequest(planIdURL, userPOs.getToken(), userPOs.getPlanIdSign(), "student", "{"state":""}");
JSONObject jsonObject = JSONObject.parseObject(Json);
JSONArray data = jsonObject.getJSONArray("data");
userPOs.setPlanId(data.getJSONObject(0).getString("planId"));
}

public static void getSign(UserPO userPOs) {
String str = "Android" + userPOs.getCardType() + userPOs.getPlanId() + userPOs.getUserId() + userPOs.getAddress() + "3478cbbc33f84bd00d75d7dfa69e0daa";
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(str.getBytes());
userPOs.setSign(new BigInteger(1, md.digest()).toString(16));
// s.append("sign = " + sign + "n");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void SignIn(UserPO userPOs) {
int num = 0;
/**这条JSON是登陆时返回的JSON,用于初始化用户信息,例如:UserID PlanID Token*/
//生成签到命令
DoCardCommand doCardCommand = new DoCardCommand();
doCardCommand.setCountry(userPOs.getCountry());
doCardCommand.setAddress(userPOs.getAddress());
doCardCommand.setProvince(userPOs.getProvince());
doCardCommand.setCity(userPOs.getCity());
doCardCommand.setLatitude(userPOs.getLatitude());
doCardCommand.setDescription("");
doCardCommand.setPlanId(userPOs.getPlanId());
doCardCommand.setType(userPOs.getCardType());
doCardCommand.setDevice("Android");
doCardCommand.setLongitude(userPOs.getLongitude());
String doCard = JSON.toJSONString(doCardCommand);
String cardResult = "";
try {
cardResult = PostRequest(signInURL, userPOs.getToken(), userPOs.getSign(), "student", doCard);
JSONObject result = JSONObject.parseObject(cardResult);
Integer code = result.getInteger("code");
//token失效
if (code == 401) {
System.out.println(userPOs.getAccont() + "token失效!");
//更新值
userPOs.setToken(null);
login(userPOs);
getPlanIdSign(userPOs);
getPlanId(userPOs);
getSign(userPOs);
SignIn(userPOs);
} else if (code == 200) {
System.out.println("账号;" + userPOs.getAccont() + userPOs.getCardType() + "打卡成功!");
} else {
System.out.println("账号;" + userPOs.getAccont() + userPOs.getCardType() + "打卡失败!!");
}
// JSONObject resultJSONObject = result.getJSONObject("data");
// System.out.println(resultJSONObject);
//修改状态
if (userPOs.getStatus() == 1) {
userPOs.setStatus(0);
} else {
userPOs.setStatus(1);
}

} catch (Exception e) {
e.printStackTrace();
}
}

//写入数据
public static void inputRecord(List<UserPO> userPOList) throws IOException {
FileOutputStream outputStream = new FileOutputStream("src/MoGuDing.txt");
userPOList.forEach(item -> {
try {
outputStream.write(JSON.toJSONString(item).getBytes());
} catch (IOException e) {
e.printStackTrace();
}
});
outputStream.flush();
outputStream.close(); }}
使用到的实体类
package com;

/**
* @author xiao_rao
* @date 2022-08-01 18:38:30
* @description 账户基本信息
*/
public class UserPO {

/**
* 索引
*/
private Integer index;
/**
* 账号
*/
private String accont;
/**
* 密码
*/
private String password;
/**
* 打卡类型
*/
private String cardType;
/**
* 详细地址
*/
private String address;
/**
* 国家
*/
private String country;
/**
* 省份
*/
private String province;
/**
* 城市
*/
private String city;
/**
* 经度
*/
private String longitude;
/**
* 维度
*/
private String latitude;
/**
* token
*/
private String token;
/**
* uuid
*/
private String userId;
/**
* moguNo
*/
private String moguNo;

/**
* 获取planId的sign
*/
private String planIdSign;
/**
* planId
*/
private String planId;
/**
* 签到sign
*/
private String sign;

/**
* 上班打卡状态 1;已打卡
*/
private Integer status;
}


/**
* @author xiao_rao
* @date 2022-08-01 20:19:48
* @description 登陆命令
*/
public class LoginDTO {
/**
* 密码
*/
private String password;
/**
* 账号
*/
private String phone;

/**
* 登陆类型
*/
private String loginType;

private String uuid;

/**
* @author xiao_rao
* @date 2022-08-01 19:59:48
* @description 打卡命令
*/
public class DoCardCommand implements Serializable {
/**
* 国家
*/
// @JSONField(ordinal = 1)
private String country;
/**
* 详细地址
*/
// @JSONField(ordinal = 2)
private String address;
/**
* 省份
*/
// @JSONField(ordinal = 3)
private String province;
/**
* 城市
*/
// @JSONField(ordinal = 4)
private String city;
/**
* 维度
*/
// @JSONField(ordinal = 5)
private String latitude;
/**
* 打卡描述
*/
// @JSONField(ordinal = 6)
private String description;
/**
* planid
*/
// @JSONField(ordinal = 7)
private String planId;
/**
* 打卡类型
*/
// @JSONField(ordinal = 8)
private String type;
/**
* 设备
*/
private String device;
/**
* 经度
*/
private String longitude;
}

在src的包下 会创建一个文本文件 用来存放登陆的账号信息 格式如下;
{
    "accont":"你登陆的账号",
    "address":"详细地址  例如陕西省-西安市-雁塔区-唐延路xx号",
    "city":"xx市 例如 西安市",
    "country":"中国",
    "latitude":"纬度",
    "longitude":"经度",
    "password":"密码",
    "province":"xx省 例陕西省"
}

这些是必填项 打卡需要的重要数据

关于经纬度如何获取 百度搜索高德地图经纬度获取 搜索地区 获取 然后执行main方法即可 这个脚本需要借助其他工具实行定时执行 一天定时执行两次  无需在代码上面修改

到现在实现自动打卡的功能已经实现了80% ,关于如何定时执行这个任务 稍等会在评论区补充 

程序员灯塔
转载请注明原文链接:学工云 - 蘑菇云 自动打卡脚本
喜欢 (0)