Commit b06c404d by 涂亚平

人社局测试

1 parent 27a4934c
......@@ -11,9 +11,11 @@ import com.subsidy.common.exception.HttpException;
import com.subsidy.mapper.AdministerMapper;
import com.subsidy.mapper.MemberMapper;
import com.subsidy.mapper.MemberTokensMapper;
import com.subsidy.mapper.OprMemDictMapper;
import com.subsidy.model.AdministerDO;
import com.subsidy.model.MemberDO;
import com.subsidy.model.MemberTokensDO;
import com.subsidy.model.OprMemDictDO;
import com.subsidy.util.ConstantUtils;
import com.subsidy.util.JwtUtil;
import com.subsidy.util.Localstorage;
......@@ -55,6 +57,9 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired
private MemberTokensMapper memberTokensMapper;
@Autowired
private OprMemDictMapper oprMemDictMapper;
@Override
@CrossOrigin()
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
......@@ -67,13 +72,6 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
Method method = handlerMethod.getMethod();
TimeRequired timeRequired = method.getAnnotation(TimeRequired.class);
if (timeRequired !=null){
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour<6){
throw new HttpException(17001);
}
}
LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class);
if (methodAnnotation != null) {
......@@ -100,6 +98,19 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
}
} else if(ConstantUtils.MOBILE_TERMINATE.equals(type)) {
MemberDO memberDO = memberMapper.selectById(claimMap.get("id").asLong());
if (timeRequired !=null){
Calendar calendar = Calendar.getInstance();
int hour = calendar.get(Calendar.HOUR_OF_DAY);
if (hour<6){
OprMemDictDO oprMemDictDO = new OprMemDictDO();
oprMemDictDO.setUserId(memberDO.getId());
oprMemDictDO.setOprType("登出");
oprMemDictDO.setResult(1);
oprMemDictMapper.insert(oprMemDictDO);
throw new HttpException(17001);
}
}
if(memberDO != null) {
Localstorage.setUser(memberDO);
return true;
......
package com.subsidy.jobs;
import com.alibaba.fastjson.JSONObject;
import com.subsidy.common.ResponseData;
import com.subsidy.service.RenSheJuService;
import com.subsidy.service.RenshejuHistoryService;
import com.subsidy.service.impl.RenshejuHistoryServiceImpl;
import com.subsidy.util.websocket.WebSocketUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
/**
* 人社局数据对接
......@@ -83,5 +89,12 @@ public class RenSheJuJob {
// renSheJuService.getErrorClass();
// }
@Scheduled(cron = "00 58 23 * * ?")
public void cancelLogin()throws IOException{
ConcurrentHashMap<Long, WebSocketSession> webSocketMap = WebSocketUtil.webSocketMap;
for (Long key : webSocketMap.keySet()){
webSocketMap.get(key).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(17001))));
}
}
}
......@@ -98,7 +98,7 @@ public interface RenSheJuMapper {
List<Long> checkClassIds();
/**
* 查看某个班级的成员做过的人脸识别记录
* 查看某个班级的成员做过的人脸识别记录 弃用
*/
List<ClassImageChecksVO> classImageChecks(Long classId);
......@@ -107,5 +107,9 @@ public interface RenSheJuMapper {
*/
List<ClassImageChecksVO> passExamCheck(Long classId);
/**
* 进入到课程第二次做人脸识别
*/
List<ClassImageChecksVO> studyCheck(Long classId);
}
......@@ -1157,6 +1157,7 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
return polyvInfoVO;
}
@Transactional(rollbackFor = Exception.class)
public String logout(MemberDO memberDO) {
memberTokensMapper.delete(new QueryWrapper<MemberTokensDO>()
.lambda()
......
......@@ -47,5 +47,23 @@ public class RenSheJuConstant {
*/
public static final String POST_10 = "POST_10_clear";
/**
* 调取失败
*/
public static final String API_ERROR = "调取失败";
/**
* 当天没数据
*/
public static final String NO_DATA = "NO_DATA";
/**
* 推送失败
*/
public static final String PUSH_FAIL = "推送失败";
/**
* 推送成功
*/
public static final String PUSH_SUCCESS = "推送成功";
}
package com.subsidy.util.websocket;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.framing.Framedata;
import org.java_websocket.handshake.ServerHandshake;
import javax.net.ssl.*;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/** @Author huyi @Date 2021/10/15 20:03 @Description: 重连websocket客户端 */
@Slf4j
public class ReConnectWebSocketClient {
/** 字符串消息回调 */
private Consumer<String> msgStr;
/** 字节流消息回调 */
private Consumer<ByteBuffer> msgByte;
/** 异常回调 */
private Consumer<Exception> error;
/** 连接标识 */
private String key;
/** ws服务端连接 */
private URI serverUri;
/** 尝试重连标识 */
private AtomicBoolean tryReconnect;
/** 需要ping标识 */
private AtomicBoolean needPing;
/** websocket连接实体 */
private WebSocketClient webSocketClient;
/** 重连次数 */
private AtomicInteger reConnectTimes;
/** 连接结束标识 */
private AtomicBoolean end;
/** 连接后初始发送报文,这里也可以不需要,如果服务端主动断开连接,重连后可以继续推送报文的话。 */
private String initReConnectReq;
/** 结束回调 */
private Consumer<String> endConsumer;
public ReConnectWebSocketClient(
URI serverUri,
String key,
Consumer<String> msgStr,
Consumer<ByteBuffer> msgByte,
Consumer<Exception> error) {
this.msgStr = msgStr;
this.msgByte = msgByte;
this.error = error;
this.key = key;
this.serverUri = serverUri;
this.tryReconnect = new AtomicBoolean(false);
this.needPing = new AtomicBoolean(true);
this.reConnectTimes = new AtomicInteger(0);
this.end = new AtomicBoolean(false);
this.endConsumer = this::close;
init();
}
/** 初始化连接 */
public void init() {
// 创建连接
createWebSocketClient();
// ping线程
circlePing();
}
private void needReconnect() throws Exception {
ThreadUtil.sleep(10, TimeUnit.SECONDS);
int cul = reConnectTimes.incrementAndGet();
if (cul > 3) {
close("real stop");
throw new Exception("服务端断连,3次重连均失败");
}
log.warn("[{}]第[{}]次断开重连", key, cul);
if (tryReconnect.get()) {
log.error("[{}]第[{}]次断开重连结果 -> 连接正在重连,本次重连请求放弃", key, cul);
needReconnect();
return;
}
try {
tryReconnect.set(true);
if (webSocketClient.isOpen()) {
log.warn("[{}]第[{}]次断开重连,关闭旧连接", key, cul);
webSocketClient.closeConnection(2, "reconnect stop");
}
webSocketClient = null;
createWebSocketClient();
connect();
if (!StrUtil.hasBlank(initReConnectReq)) {
send(initReConnectReq);
}
} catch (Exception exception) {
log.error("[{}]第[{}]次断开重连结果 -> 连接正在重连,重连异常:[{}]", key, cul, exception.getMessage());
needReconnect();
} finally {
tryReconnect.set(false);
}
}
private void createWebSocketClient() {
webSocketClient =
new WebSocketClient(serverUri) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
log.info("[{}]ReConnectWebSocketClient [onOpen]连接成功{}", key, getRemoteSocketAddress());
tryReconnect.set(false);
}
@Override
public void onMessage(String text) {
log.info("[{}]ReConnectWebSocketClient [onMessage]接收到服务端数据:text={}", key, text);
msgStr.accept(text);
}
@Override
public void onMessage(ByteBuffer bytes) {
log.info("[{}]ReConnectWebSocketClient [onMessage]接收到服务端数据:bytes={}", key, bytes);
msgByte.accept(bytes);
}
@Override
public void onWebsocketPong(WebSocket conn, Framedata f) {
log.info(
"[{}]ReConnectWebSocketClient [onWebsocketPong]接收到服务端数据:opcode={}",
key,
f.getOpcode());
}
@Override
public void onClose(int i, String s, boolean b) {
log.info("[{}]ReConnectWebSocketClient [onClose]关闭,s={},b={}", key, s, b);
if (StrUtil.hasBlank(s) || s.contains("https")) {
if (end.get()) {
return;
}
try {
needReconnect();
} catch (Exception exception) {
endConsumer.accept("reconnect error");
error.accept(exception);
}
}
}
@Override
public void onError(Exception e) {
log.info("[{}]ReConnectWebSocketClient [onError]异常,e={}", key, e);
endConsumer.accept("error close");
error.accept(e);
}
};
if (serverUri.toString().contains("wss://")) {
trustAllHosts(webSocketClient);
}
}
public void circlePing() {
new Thread(
() -> {
while (needPing.get()) {
if (webSocketClient.isOpen()) {
webSocketClient.sendPing();
}
ThreadUtil.sleep(5, TimeUnit.SECONDS);
}
log.warn("[{}]Ping循环关闭", key);
})
.start();
}
/**
* 连接
*
* @throws Exception 异常
*/
public void connect() throws Exception {
webSocketClient.connectBlocking(10, TimeUnit.SECONDS);
}
/**
* 发送
*
* @param msg 消息
* @throws Exception 异常
*/
public void send(String msg) throws Exception {
this.initReConnectReq = msg;
if (webSocketClient.isOpen()) {
webSocketClient.send(msg);
}
}
/**
* 关闭
*
* @param msg 关闭消息
*/
public void close(String msg) {
needPing.set(false);
end.set(true);
if (webSocketClient != null) {
webSocketClient.closeConnection(3, msg);
}
}
/**
* 忽略证书
*
* @param client
*/
public void trustAllHosts(WebSocketClient client) {
TrustManager[] trustAllCerts =
new TrustManager[] {
new X509ExtendedTrustManager() {
@Override
public void checkClientTrusted(
X509Certificate[] x509Certificates, String s, Socket socket)
throws CertificateException {}
@Override
public void checkServerTrusted(
X509Certificate[] x509Certificates, String s, Socket socket)
throws CertificateException {}
@Override
public void checkClientTrusted(
X509Certificate[] x509Certificates, String s, SSLEngine sslEngine)
throws CertificateException {}
@Override
public void checkServerTrusted(
X509Certificate[] x509Certificates, String s, SSLEngine sslEngine)
throws CertificateException {}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s)
throws CertificateException {}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};
try {
SSLContext ssl = SSLContext.getInstance("SSL");
ssl.init(null, trustAllCerts, new java.security.SecureRandom());
SSLSocketFactory socketFactory = ssl.getSocketFactory();
client.setSocketFactory(socketFactory);
} catch (Exception e) {
log.error("ReConnectWebSocketClient trustAllHosts 异常,e={0}", e);
}
}
}
\ No newline at end of file
......@@ -5,6 +5,10 @@ import lombok.Data;
@Data
public class ClassImageChecksVO {
Long classId;
Long memberId;
/**
* 检测时间,【13位时间戳】【精确到毫秒】如检测类型为活跃度检测则与【学时信息采集接口】、【考试信息采集接口】activityTime时间保持一致
*/
......
......@@ -9,5 +9,6 @@ public class DailyActivitiesVO {
private Long activityTime;
private Integer checkType;
}
......@@ -168,7 +168,8 @@
<select id="dailyActivities" resultType="com.subsidy.vo.renshe.DailyActivitiesVO">
SELECT
t1.`status` as access,
unix_timestamp( t1.create_date )*1000 as activityTime
unix_timestamp( t1.create_date )*1000 as activityTime,
t1.check_type
FROM
activity_detection t1
WHERE
......@@ -176,7 +177,6 @@
AND t1.delete_date IS NULL
AND t1.member_id = #{memberId}
AND t1.class_id = #{classId}
and t1.check_type= 0
</select>
<select id="examActivities" resultType="com.subsidy.vo.renshe.ExamActivitiesVO">
......@@ -353,7 +353,7 @@
SELECT
distinct class_id
FROM
class_member_mapping
image_check_record
WHERE
delete_date IS NULL
AND DATE_FORMAT( DATE_ADD( update_date, INTERVAL 1 DAY ), '%Y-%m-%d' ) = DATE_FORMAT(
......@@ -401,4 +401,27 @@
AND t1.result = 1
</select>
<select id="studyCheck" parameterType="long" resultType="com.subsidy.vo.renshe.ClassImageChecksVO">
SELECT
t1.class_id,
t1.member_id,
t1.photo AS image,
t2.user_name AS studentName,
t2.id_card AS identity,
t2.telephone AS phone,
UNIX_TIMESTAMP( t1.create_date )* 1000 AS activityTime
FROM
image_check_record t1
LEFT JOIN member t2 ON t1.member_id = t2.id
WHERE
class_id = #{classId}
AND DATE_FORMAT( DATE_ADD( t1.create_date, INTERVAL 1 DAY ), '%Y-%m-%d' ) = DATE_FORMAT( NOW(), '%Y-%m-%d' )
AND t1.paper_id IS NULL
AND t1.result = 1
and t1.member_id
GROUP BY t1.class_id,t1.member_id
ORDER BY t1.create_date desc
</select>
</mapper>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!