diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/rpc/config/RpcConfiguration.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/rpc/config/RpcConfiguration.java index f0ac5a6c..a47ca94d 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/rpc/config/RpcConfiguration.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/rpc/config/RpcConfiguration.java @@ -1,10 +1,11 @@ package cn.iocoder.yudao.module.infra.framework.rpc.config; +import cn.iocoder.yudao.module.system.api.equipment.AttendanceMachineApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.context.annotation.Configuration; @Configuration(proxyBeanMethods = false) -@EnableFeignClients(clients = AdminUserApi.class) +@EnableFeignClients(clients = { AdminUserApi.class, AttendanceMachineApi.class }) public class RpcConfiguration { } diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/AttendanceWebSocketMessageListener.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/AttendanceWebSocketMessageListener.java index 38f03184..d9d3c579 100644 --- a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/AttendanceWebSocketMessageListener.java +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/AttendanceWebSocketMessageListener.java @@ -1,17 +1,28 @@ package cn.iocoder.yudao.module.infra.websocket; -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.hutool.json.JSONObject; +import cn.iocoder.yudao.framework.common.util.json.JsonUtils; +import cn.iocoder.yudao.framework.websocket.core.attendance.AttendanceConstants; import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener; import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; -import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils; -import cn.iocoder.yudao.module.infra.websocket.message.AttendanceReceiveMessage; +import cn.iocoder.yudao.module.infra.websocket.dto.DeviceResponseDTO; import cn.iocoder.yudao.module.infra.websocket.message.AttendanceSendMessage; -import cn.iocoder.yudao.module.infra.websocket.message.DemoReceiveMessage; -import cn.iocoder.yudao.module.infra.websocket.message.DemoSendMessage; +import cn.iocoder.yudao.module.system.api.equipment.AttendanceMachineApi; +import cn.iocoder.yudao.module.system.api.equipment.dto.AttendanceUpdateDTO; +import cn.iocoder.yudao.module.system.api.equipment.dto.DistributeRecordDTO; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.github.yulichang.toolkit.SpringContentUtils; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; /** * 考勤仪设备 WebSocket 数据通信 @@ -24,12 +35,154 @@ public class AttendanceWebSocketMessageListener implements WebSocketMessageListe @Resource private WebSocketMessageSender webSocketMessageSender; + @Resource + private AttendanceMachineApi attendanceMachineApi; + @Override public void onMessage(WebSocketSession session, AttendanceSendMessage message) { - String sn = session.getId() ; - AttendanceReceiveMessage toMessage = new AttendanceReceiveMessage().setFrom("system") - .setData(message.getData()); - webSocketMessageSender.sendSNObject(sn, "attendance-message-send", toMessage); + + StringRedisTemplate redisTemplate = SpringContentUtils.getBean(StringRedisTemplate.class); + + JSONObject object1 = new JSONObject(message.getData()); + if (object1.get("cmd").equals(AttendanceConstants.CMD_TO_DEVICE)) { + + String requestId = IdWorker.get32UUID(); + object1.set("from", session.getId()); + object1.set("extra", requestId + "_" + message.getTo()); + + JSONObject data = new JSONObject(object1.get("data")); + // 插入设备请求记录 + List recordDTOs = new ArrayList<>(); + DistributeRecordDTO recordDTO = new DistributeRecordDTO(); + + switch (data.get("cmd").toString()) { + + case "addUser": + recordDTO.setRequestId(requestId); + recordDTO.setDeviceNo(object1.get("to").toString()); + recordDTO.setUserId(Long.valueOf(data.get("user_id").toString())); + recordDTO.setType(1); + recordDTO.setResult("通讯失败"); + recordDTO.setCreator(message.getTo()); + recordDTOs.add(recordDTO); + break; + case "delMultiUser": + List userIds = JsonUtils.parseArray(data.get("user_ids").toString(), String.class); + // 删除的用户Id 存在redis中 + redisTemplate.opsForValue().set(object1.get("to").toString(), data.get("user_ids").toString()); + for (String userId : userIds) { + + DistributeRecordDTO deleteRecord = new DistributeRecordDTO(); + deleteRecord.setRequestId(requestId); + deleteRecord.setDeviceNo(object1.get("to").toString()); + deleteRecord.setUserId(Long.valueOf(userId)); + deleteRecord.setType(0); + deleteRecord.setResult("通讯失败"); + deleteRecord.setCreator(message.getTo()); + recordDTOs.add(deleteRecord); + } + break; + } + attendanceMachineApi.createDistributeRecord(recordDTOs); + + // 发送命令至设备 + webSocketMessageSender.sendSNObject(object1.get("to").toString(), "attendance-message-send", object1); + } + + if (object1.get("cmd").equals(AttendanceConstants.CMD_TO_CLIENT)) { + + // 获取响应数据 + DeviceResponseDTO dto = JsonUtils.parseObject2(object1.get("data").toString(), DeviceResponseDTO.class); + + String requestId = object1.get("extra").toString().split("_")[0]; + String userId = object1.get("extra").toString().split("_")[1]; + if (dto != null) { + + // 更新下发数据 + AttendanceUpdateDTO attendanceUpdateDTO = new AttendanceUpdateDTO(); + List recordDTOs = new ArrayList<>(); + + // 更新下发记录表 + if (dto.getDelFailed() == null) { + + DistributeRecordDTO recordDTO = new DistributeRecordDTO(); + recordDTO.setCode(dto.getCode()); + recordDTO.setResult(dto.getMsg()); + recordDTO.setUserId(dto.getUserId() == null ? Long.valueOf(userId) : Long.valueOf(dto.getUserId())); + recordDTO.setRequestId(requestId); + recordDTO.setUpdater(userId); + recordDTOs.add(recordDTO); + }else { + + // 更新下发记录表 + for (DeviceResponseDTO.DeleteUser info : dto.getDelFailed()) { + + DistributeRecordDTO deleteRecord = new DistributeRecordDTO(); + deleteRecord.setCode(info.getCode()); + deleteRecord.setResult(info.getMsg()); + deleteRecord.setUserId(Long.valueOf(info.getUserId())); + deleteRecord.setRequestId(requestId); + deleteRecord.setUpdater(userId); + recordDTOs.add(deleteRecord); + } + } + + // 更新下发记录表 + attendanceMachineApi.updateDistributeRecord(recordDTOs); + + // 响应失败的情况 + if (dto.getCode() != 0) { + + if ("setPasswordRet".equals(dto.getCmd())) { + + redisTemplate.opsForValue().set(object1.get("from").toString() + "msg", dto.getCode() + "_" + dto.getMsg()); + redisTemplate.opsForValue().set(object1.get("from").toString(), "false"); + } + return; + } + + switch (dto.getCmd()) { + + case "addUserRet": + // 更新设备绑定用户信息 + attendanceUpdateDTO.setUserId(Collections.singletonList(Long.valueOf(dto.getUserId()))); + attendanceUpdateDTO.setDeviceNo(object1.get("from").toString()); + attendanceUpdateDTO.setMethod(0); + + // 更新设备绑定用户信息 + attendanceMachineApi.updateAttendance(attendanceUpdateDTO); + break; + case "delMultiUserRet": + List userIds = JsonUtils.parseArray(redisTemplate.opsForValue().get(object1.get("from").toString()), String.class); + if (dto.getDelFailed() != null) { + userIds.removeAll(convertList(dto.getDelFailed(), DeviceResponseDTO.DeleteUser::getUserId)); + } + // 更新设备绑定用户信息 + attendanceUpdateDTO.setUserId(userIds.stream().map(Long::valueOf).collect(Collectors.toList())); + attendanceUpdateDTO.setDeviceNo(object1.get("from").toString()); + attendanceUpdateDTO.setMethod(1); + + // 更新设备绑定用户信息 + attendanceMachineApi.updateAttendance(attendanceUpdateDTO); + break; + case "setPasswordRet": + // 更新设备密码 + String value = redisTemplate.opsForValue().get(object1.get("from").toString()); + if (value != null) { + String oldPassword = value.split("-")[0]; + String newPassword = value.split("-")[1]; + attendanceMachineApi.updateDevicePassword(object1.get("from").toString(), oldPassword, newPassword); + + redisTemplate.delete(object1.get("from").toString()); + } + break; + } + } + + if (!object1.get("to").toString().isEmpty()) { + webSocketMessageSender.sendObject(object1.get("to").toString(), "attendance-message-send", object1); + } + } } @Override diff --git a/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/dto/DeviceResponseDTO.java b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/dto/DeviceResponseDTO.java new file mode 100644 index 00000000..f4e8728a --- /dev/null +++ b/yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/websocket/dto/DeviceResponseDTO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.infra.websocket.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Schema(description = "设备响应 Response DTO") +@Data +public class DeviceResponseDTO { + + @Schema(description = "指令号") + private String cmd; + + @Schema(description = "错误码") + private Integer code; + + @Schema(description = "返回说明") + private String msg; + + @Schema(description = "用户编号") + private String userId; + + private List delFailed; + + @Schema(description = "批量删除用户,响应data") + @Data + public static class DeleteUser { + + @Schema(description = "用户编号") + private String userId; + + @Schema(description = "错误码") + private Integer code; + + @Schema(description = "返回说明") + private String msg; + } +}