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 ebf0c6d8..c4c89144 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 @@ -14,6 +14,9 @@ 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.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionSynchronization; +import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.web.socket.WebSocketSession; import javax.annotation.Resource; @@ -40,6 +43,7 @@ public class AttendanceWebSocketMessageListener implements WebSocketMessageListe private AttendanceMachineApi attendanceMachineApi; @Override + @Transactional(rollbackFor = Exception.class) public void onMessage(WebSocketSession session, AttendanceSendMessage message) { StringRedisTemplate redisTemplate = SpringContentUtils.getBean(StringRedisTemplate.class); @@ -91,46 +95,55 @@ public class AttendanceWebSocketMessageListener implements WebSocketMessageListe } if (object1.get("cmd").equals(AttendanceConstants.CMD_TO_CLIENT)) { - System.out.println("进来了"+ System.currentTimeMillis()); // 获取响应数据 DeviceResponseDTO dto = JsonUtils.parseObject2(object1.get("data").toString(), DeviceResponseDTO.class); + // 获取设备号 + String deviceNo = object1.get("from").toString(); 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) { + // 在事务提交后,更新下发记录, + TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() { + @Override + public void afterCommit() { - 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 { + List recordDTOs = new ArrayList<>(); - // 更新下发记录表 - for (DeviceResponseDTO.DeleteUser info : dto.getDelFailed()) { + // 更新下发记录表 + if (dto.getDelFailed() == null) { - 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); + 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); } - } - - // 更新下发记录表 - attendanceMachineApi.updateDistributeRecord(recordDTOs); + }); // 响应失败的情况 if (dto.getCode() != 0) { @@ -139,8 +152,8 @@ public class AttendanceWebSocketMessageListener implements WebSocketMessageListe webSocketMessageSender.sendObject(object1.get("to").toString(), "attendance-message-send", object1); }else { - redisTemplate.opsForValue().set(object1.get("from").toString() + "msg", dto.getCode() + "_" + dto.getMsg(), 30, TimeUnit.SECONDS); - redisTemplate.opsForValue().set(object1.get("from").toString(), "false", 30, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(deviceNo + "msg", dto.getCode() + "_" + dto.getMsg(), 30, TimeUnit.SECONDS); + redisTemplate.opsForValue().set(deviceNo, "false", 30, TimeUnit.SECONDS); } return; @@ -151,20 +164,20 @@ public class AttendanceWebSocketMessageListener implements WebSocketMessageListe case "addUserRet": // 更新设备绑定用户信息 attendanceUpdateDTO.setUserId(Collections.singletonList(Long.valueOf(dto.getUserId()))); - attendanceUpdateDTO.setDeviceNo(object1.get("from").toString()); + attendanceUpdateDTO.setDeviceNo(deviceNo); attendanceUpdateDTO.setMethod(0); // 更新设备绑定用户信息 attendanceMachineApi.updateAttendance(attendanceUpdateDTO); break; case "delMultiUserRet": - List userIds = JsonUtils.parseArray(redisTemplate.opsForValue().get(object1.get("from").toString()), String.class); + List userIds = JsonUtils.parseArray(redisTemplate.opsForValue().get(deviceNo), 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.setDeviceNo(deviceNo); attendanceUpdateDTO.setMethod(1); // 更新设备绑定用户信息 @@ -172,20 +185,24 @@ public class AttendanceWebSocketMessageListener implements WebSocketMessageListe break; case "setPasswordRet": // 更新设备密码 - String value = redisTemplate.opsForValue().get(object1.get("from").toString()); + String value = redisTemplate.opsForValue().get(deviceNo); if (value != null) { String oldPassword = value.split("-")[0]; String newPassword = value.split("-")[1]; - attendanceMachineApi.updateDevicePassword(object1.get("from").toString(), oldPassword, newPassword); + attendanceMachineApi.updateDevicePassword(deviceNo, oldPassword, newPassword); } break; } - redisTemplate.delete(object1.get("from").toString()); + redisTemplate.delete(deviceNo); + + } if (!object1.get("to").toString().isEmpty()) { webSocketMessageSender.sendObject(object1.get("to").toString(), "attendance-message-send", object1); } + + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/DistributeRecordServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/DistributeRecordServiceImpl.java index 98fcb565..2ebf49ed 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/DistributeRecordServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/DistributeRecordServiceImpl.java @@ -1,8 +1,9 @@ package cn.iocoder.yudao.module.system.service.equipment; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO; import cn.iocoder.yudao.module.system.dal.mysql.equipment.DistributeRecordMapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -34,8 +35,11 @@ public class DistributeRecordServiceImpl implements DistributeRecordService { for (DistributeRecordDO updateDO : updateReqVO) { - distributeRecordMapper.update(updateDO, - new LambdaQueryWrapperX() + DistributeRecordDO updateVO = BeanUtils.toBean(updateDO, DistributeRecordDO.class); + updateVO.setRequestId(null); + updateVO.setUserId(null); + distributeRecordMapper.update(updateVO, + new LambdaUpdateWrapper() .eq(DistributeRecordDO::getUserId, updateDO.getUserId()) .eq(DistributeRecordDO::getRequestId, updateDO.getRequestId())); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtService.java index 38febe07..40561f58 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtService.java @@ -57,7 +57,7 @@ public interface UsersExtService { /** * 删除用户人脸信息 */ - String deleteUser(Long userId); + void deleteUser(Long userId); /** * 获得用户信息拓展 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtServiceImpl.java index 2042cfa3..8f76ae59 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/equipment/UsersExtServiceImpl.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.equipment; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.IoUtil; +import cn.hutool.json.JSONObject; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -28,7 +29,9 @@ import cn.iocoder.yudao.module.system.service.user.AdminUserService; import cn.iocoder.yudao.module.system.service.websocket.WebsocketService; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.github.yulichang.toolkit.SpringContentUtils; import org.springframework.context.annotation.Lazy; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -197,7 +200,7 @@ public class UsersExtServiceImpl implements UsersExtService { } @Override - public String deleteUser(Long userId) { + public void deleteUser(Long userId) { //校验 当前用户人脸信息是否已存在 UsersExtDO usersExtDO = usersExtMapper.selectOne(UsersExtDO::getUserId, userId); @@ -214,17 +217,14 @@ public class UsersExtServiceImpl implements UsersExtService { .setCmd("delMultiUser") .setUser_ids(new String[]{String.valueOf(usersExtDO.getUserId())}); - try { - for (String deviceNo : deviceNos) { + // 删除的用户Id 存在redis中 + StringRedisTemplate redisTemplate = SpringContentUtils.getBean(StringRedisTemplate.class); + for (String deviceNo : deviceNos) { - websocketService.sendSn(deviceNo, userVO, 0); - } - } catch (RuntimeException ex) { - - return ex.getMessage(); + redisTemplate.opsForValue().set(deviceNo, new JSONObject(userVO).get("user_ids").toString()); + websocketService.sendSn(deviceNo, userVO, 0); } } - return null; } private void validateUsersExtExists(Long userId) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/FactoryUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/FactoryUserServiceImpl.java index e3570280..ce778660 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/FactoryUserServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/FactoryUserServiceImpl.java @@ -21,6 +21,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; import javax.annotation.Resource; import java.util.List; @@ -85,7 +86,7 @@ public class FactoryUserServiceImpl implements FactoryUserService{ AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class); user.setDeptId(deptDO.getId()); user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启 - user.setPassword(encodePassword("123456")); // 设置默认密码 + user.setPassword(encodePassword()); // 设置默认密码 user.setUserType(2); // 设置用户类型为 工厂用户 userMapper.insert(user); @@ -114,8 +115,10 @@ public class FactoryUserServiceImpl implements FactoryUserService{ // 发送指令至 考勤设备 下发员工 websocketService.sendSn(machineDO.getDeviceNo(), addUserVO, 1); } - } catch (RuntimeException ex) { + } catch (Exception ex) { + // 手动回滚 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return ex.getMessage(); } @@ -183,8 +186,10 @@ public class FactoryUserServiceImpl implements FactoryUserService{ // 发送指令至 考勤设备 修改员工信息 websocketService.sendSn(machineDO.getDeviceNo(), addUserVO, 1); } - }catch (RuntimeException ex) { + }catch (Exception ex) { + // 手动回滚 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return ex.getMessage(); } @@ -202,7 +207,16 @@ public class FactoryUserServiceImpl implements FactoryUserService{ userMapper.deleteById(id); // 同步删除用户拓展信息 - return usersExtService.deleteUser(id); + try { + + usersExtService.deleteUser(id); + } catch (Exception ex) { + + // 手动回滚 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return ex.getMessage(); + } + return null; } private void validateId(Long id) { @@ -215,10 +229,9 @@ public class FactoryUserServiceImpl implements FactoryUserService{ /** * 对密码进行加密 * - * @param password 密码 * @return 加密后的密码 */ - private String encodePassword(String password) { - return passwordEncoder.encode(password); + private String encodePassword() { + return passwordEncoder.encode("123456"); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/websocket/WebsocketServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/websocket/WebsocketServiceImpl.java index 48fccf12..5988834f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/websocket/WebsocketServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/websocket/WebsocketServiceImpl.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.service.websocket; +import cn.hutool.json.JSONObject; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; @@ -11,7 +12,6 @@ import com.xingyuv.http.util.StringUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; -import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.util.Collections; @@ -47,11 +47,13 @@ public class WebsocketServiceImpl implements WebsocketService{ .setExtra(requestId + "_" + getLoginUserId()) .setData(data); + JSONObject dataJson = new JSONObject(data); + // 设置 设备下发记录 DistributeRecordDO recordDO = new DistributeRecordDO(); recordDO.setRequestId(requestId); recordDO.setDeviceNo(deviceNo); - recordDO.setUserId(getLoginUserId()); + recordDO.setUserId(dataJson.get("user_id") == null ? getLoginUserId() : Long.valueOf(dataJson.get("user_id").toString())); recordDO.setType(type); recordDO.setResult("通讯失败"); @@ -60,7 +62,10 @@ public class WebsocketServiceImpl implements WebsocketService{ // 设备租户ID TenantContextHolder.setTenantId(1L); - stringRedisTemplate.opsForValue().set(deviceNo, "true"); + + if (StringUtil.isEmpty(stringRedisTemplate.opsForValue().get(deviceNo))) { + stringRedisTemplate.opsForValue().set(deviceNo, "true"); + } // 发送修改密码命令给设备 webSocketSenderApi.sendSN(deviceNo, "attendance-message-send", JsonUtils.toJsonString(baseVO)); @@ -88,6 +93,7 @@ public class WebsocketServiceImpl implements WebsocketService{ } Long currentTime = System.currentTimeMillis(); if (currentTime - startTime > 30000) { + throw exception(REQUEST_FAILURE); } }