26
26
27
27
import org .apache .http .NameValuePair ;
28
28
import org .apache .http .message .BasicNameValuePair ;
29
+ import org .gcszhn .autocard .AppConfig ;
30
+ import org .gcszhn .autocard .utils .DigestUtils ;
29
31
import org .gcszhn .autocard .utils .LogUtils ;
30
32
import org .gcszhn .autocard .utils .StatusCode ;
33
+ import org .jsoup .Jsoup ;
34
+ import org .jsoup .nodes .Document ;
35
+ import org .jsoup .nodes .Element ;
31
36
import org .springframework .beans .factory .annotation .Autowired ;
32
37
import org .springframework .beans .factory .annotation .Value ;
33
38
import org .springframework .context .annotation .Scope ;
41
46
@ Scope ("prototype" )
42
47
@ Service
43
48
public class ClockinService implements Closeable {
49
+ /**时间格式化 */
50
+ private static final SimpleDateFormat SDF = new SimpleDateFormat ("yyyyMMdd" );
51
+ /**表达校验数据缓存关键字 */
52
+ private static final String FORM_MD5_VALUE = "FORM_MD5_VALUE" ;
44
53
/**打卡信息网址 */
45
54
@ Value ("${app.autoCard.reportUrl}" )
46
55
/**打卡提交网址 */
@@ -50,8 +59,9 @@ public class ClockinService implements Closeable {
50
59
/**浙大通行证客户端 */
51
60
@ Autowired
52
61
private ZJUClientService client ;
53
- /**时间格式化 */
54
- private SimpleDateFormat sdf = new SimpleDateFormat ("yyyyMMdd" );
62
+ /**应用配置实例 */
63
+ @ Autowired
64
+ private AppConfig appConfig ;
55
65
/**
56
66
* 用于访问打卡页面
57
67
* @param username 用户名
@@ -60,10 +70,55 @@ public class ClockinService implements Closeable {
60
70
*/
61
71
public String getPage (String username , String password ) {
62
72
if (client .login (username , password )) {
63
- return client .doGetText (reportUrl );
73
+ String page1 = client .doGetText (reportUrl );
74
+ Boolean formvalidation = appConfig .getConfigItem ("formvalidation" , Boolean .class );
75
+ if (formvalidation !=null && !formvalidation ) {
76
+ return page1 ;
77
+ }
78
+ String page2 = client .doGetText (reportUrl );
79
+ boolean page1Flag = formValidation (page1 );
80
+ boolean page2Flag = formValidation (page2 );
81
+ if ( page1Flag == (page1 !=null ) && page2Flag == (page2 !=null )) {
82
+ LogUtils .printMessage ("表单校验通过" , LogUtils .Level .INFO );
83
+ return page1 ;
84
+ } else if (page1 != null && page2 != null && page1Flag != page2Flag ) {
85
+ // 意味着两次获取的页面表单是变化的,无法作为校验依据
86
+ LogUtils .printMessage ("表单校验功能失效,已忽略校验,请联系作者" , LogUtils .Level .ERROR );
87
+ return page1 ;
88
+ } else {
89
+ LogUtils .printMessage ("表单校验失败,请检查健康打卡页面是否更新或等待一会再次尝试,若更新请删除缓存文件并重启打卡程序" , LogUtils .Level .ERROR );
90
+ }
64
91
}
65
92
return null ;
66
93
}
94
+ /**
95
+ * 表单数据的MD5校验,浙大健康打卡时常更新,但后端验证不够及时,因此进行前端验证
96
+ * @param html 表单的html页面
97
+ * @return true为验证通过
98
+ */
99
+ public boolean formValidation (String html ) {
100
+ try {
101
+ if (html != null ) {
102
+ Document document = Jsoup .parse (html );
103
+ Element form = document .getElementsByClass ("form-detail2" ).last ();
104
+ if (form != null ) {
105
+ String digest = DigestUtils .digest (form .html (), "MD5" );
106
+ if (appConfig .getCacheItem (FORM_MD5_VALUE ) == null ) {
107
+ appConfig .addCacheItem (FORM_MD5_VALUE , digest );
108
+ }
109
+ if (appConfig .getCacheItem (FORM_MD5_VALUE ).equals (digest )) {
110
+ return true ;
111
+ }
112
+ } else {
113
+ LogUtils .printMessage ("未捕获表单信息,捕获信息如下" , LogUtils .Level .ERROR );
114
+ System .out .println (html );
115
+ }
116
+ }
117
+ } catch (Exception e ) {
118
+ LogUtils .printMessage (e .getMessage (), e , LogUtils .Level .ERROR );
119
+ }
120
+ return false ;
121
+ }
67
122
/**
68
123
* 用于提取已有提交信息
69
124
* @param username 用户名
@@ -107,7 +162,7 @@ public ArrayList<NameValuePair> getOldInfo(String username, String password) {
107
162
infoJsonObject1 .putAll (oldInfoJson );
108
163
infoJsonObject1 .forEach ((String name , Object value )->{
109
164
switch (name ) {
110
- case "date" : value =sdf .format (new Date ());break ;
165
+ case "date" : value =SDF .format (new Date ());break ;
111
166
case "bztcyy" : value ="" ;break ; //地区变更需要手动打卡一次,过滤上一次的地区变更原因
112
167
}
113
168
// fix bug for "是否从下列地区返回浙江错误"
@@ -135,7 +190,7 @@ public StatusCode submit(String username, String password) {
135
190
ArrayList <NameValuePair > info = getOldInfo (username , password );
136
191
if (info ==null ) {
137
192
LogUtils .printMessage ("打卡信息获取失败" , LogUtils .Level .ERROR );
138
- statusCode .setMessage (username +", 打卡信息获取失败 " );
193
+ statusCode .setMessage (username +"的打卡信息获取失败,可能是打卡更新了或网络不稳定,请查看后台打卡日志输出 " );
139
194
statusCode .setStatus (-1 );
140
195
return statusCode ;
141
196
}
@@ -163,6 +218,7 @@ public StatusCode submit(String username, String password) {
163
218
public void close () {
164
219
try {
165
220
client .close ();
221
+
166
222
} catch (Exception e ) {
167
223
LogUtils .printMessage (null , e , LogUtils .Level .ERROR );
168
224
}
0 commit comments