考勤设备模块
This commit is contained in:
parent
0c7e9dc026
commit
afa1689cb6
@ -81,6 +81,11 @@
|
||||
<artifactId>yudao-spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
<artifactId>yudao-spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- DB 相关 -->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.cloud</groupId>
|
||||
|
@ -1,10 +1,18 @@
|
||||
package cn.iocoder.yudao.module.system.api.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.system.api.equipment.dto.AttendanceUpdateDTO;
|
||||
import cn.iocoder.yudao.module.system.api.equipment.dto.DistributeRecordDTO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.attendancemachine.AddUserToAttendanceMachineVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.attendancemachine.AttendanceMachinePasswordVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.AttendanceMachineService;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.DistributeRecordService;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@RestController // 提供 RESTful API 接口,给 Feign 调用
|
||||
@Validated
|
||||
@ -13,9 +21,37 @@ public class AttendanceMachineApiImpl implements AttendanceMachineApi{
|
||||
@Resource
|
||||
private AttendanceMachineService attendanceMachineService;
|
||||
|
||||
@Override
|
||||
public void updateAttendanceMachineStatus(String deviceNo) {
|
||||
@Resource
|
||||
private DistributeRecordService distributeRecordService;
|
||||
|
||||
attendanceMachineService.updateAttendanceMachineStatus(deviceNo);
|
||||
@Override
|
||||
public void createDistributeRecord(List<DistributeRecordDTO> recordDTO) {
|
||||
|
||||
List<DistributeRecordDO> distributeRecordDO = BeanUtils.toBean(recordDTO, DistributeRecordDO.class);
|
||||
|
||||
distributeRecordService.createDistributeRecord(distributeRecordDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDistributeRecord(List<DistributeRecordDTO> recordDTO) {
|
||||
|
||||
distributeRecordService.updateDistributeRecord(BeanUtils.toBean(recordDTO, DistributeRecordDO.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAttendance(AttendanceUpdateDTO updateDTO) {
|
||||
|
||||
AddUserToAttendanceMachineVO updateVO = BeanUtils.toBean(updateDTO, AddUserToAttendanceMachineVO.class);
|
||||
attendanceMachineService.addUserToAttendanceMachine(updateVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDevicePassword(String deviceNo, String oldPassword, String newPassword) {
|
||||
|
||||
AttendanceMachinePasswordVO passwordVO = new AttendanceMachinePasswordVO();
|
||||
passwordVO.setDeviceNo(deviceNo);
|
||||
passwordVO.setOldPassword(oldPassword);
|
||||
passwordVO.setNewPassword(newPassword);
|
||||
attendanceMachineService.updatePassword(passwordVO);
|
||||
}
|
||||
}
|
||||
|
@ -2,20 +2,34 @@ package cn.iocoder.yudao.module.system.controller.admin.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
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;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.attendancemachine.*;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket.UpdatePasswordVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket.WebsocketBaseVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.AttendanceMachineService;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.DistributeRecordService;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collections;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.REQUEST_FAILURE;
|
||||
|
||||
|
||||
@Tag(name = "管理后台 - 考勤设备")
|
||||
@ -27,6 +41,15 @@ public class AttendanceMachineController {
|
||||
@Resource
|
||||
private AttendanceMachineService attendanceMachineService;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Resource
|
||||
private WebSocketSenderApi webSocketSenderApi;
|
||||
|
||||
@Resource
|
||||
private DistributeRecordService recordService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建考勤设备")
|
||||
@PreAuthorize("@ss.hasPermission('system:attendance-machine:create')")
|
||||
@ -48,8 +71,58 @@ public class AttendanceMachineController {
|
||||
@PreAuthorize("@ss.hasPermission('system:attendance-machine:update')")
|
||||
public CommonResult<Boolean> updateAttendanceMachine(@Valid @RequestBody AttendanceMachinePasswordVO updateReqVO) {
|
||||
|
||||
attendanceMachineService.updatePassword(updateReqVO);
|
||||
return success(true);
|
||||
// 将密码信息 储存在redis中
|
||||
stringRedisTemplate.opsForValue().set(updateReqVO.getDeviceNo(), updateReqVO.getOldPassword() + "-" + updateReqVO.getNewPassword());
|
||||
|
||||
String requestId = IdWorker.get32UUID();
|
||||
// 设备修改密码命令信息
|
||||
UpdatePasswordVO passwordVO = new UpdatePasswordVO().setOld_password(updateReqVO.getOldPassword())
|
||||
.setNew_password(updateReqVO.getNewPassword());
|
||||
WebsocketBaseVO data = new WebsocketBaseVO()
|
||||
.setFrom("")
|
||||
.setTo(updateReqVO.getDeviceNo())
|
||||
.setExtra(requestId + "_" + getLoginUserId())
|
||||
.setData(passwordVO);
|
||||
|
||||
// 设置 设备下发记录
|
||||
DistributeRecordDO recordDO = new DistributeRecordDO();
|
||||
recordDO.setRequestId(requestId);
|
||||
recordDO.setDeviceNo(updateReqVO.getDeviceNo());
|
||||
recordDO.setUserId(getLoginUserId());
|
||||
recordDO.setType(3);
|
||||
recordDO.setResult("通讯失败");
|
||||
|
||||
// 更新下发记录信息
|
||||
recordService.createDistributeRecord(Collections.singletonList(recordDO));
|
||||
|
||||
// 设备租户ID
|
||||
TenantContextHolder.setTenantId(1L);
|
||||
// 发送修改密码命令给设备
|
||||
webSocketSenderApi.sendSN(updateReqVO.getDeviceNo(), "attendance-message-send", JsonUtils.toJsonString(data));
|
||||
|
||||
Long startTime = System.currentTimeMillis();
|
||||
while (true) {
|
||||
|
||||
if (stringRedisTemplate.opsForValue().get(updateReqVO.getDeviceNo()) == null) {
|
||||
|
||||
return success(true);
|
||||
}else if ("false".equals(stringRedisTemplate.opsForValue().get(updateReqVO.getDeviceNo()))) {
|
||||
|
||||
Integer code = Integer.valueOf(stringRedisTemplate.opsForValue().get(updateReqVO.getDeviceNo() + "msg").split("_")[0]);
|
||||
String msg = stringRedisTemplate.opsForValue().get(updateReqVO.getDeviceNo() + "msg").split("_")[1];
|
||||
|
||||
// 清楚 redis缓存
|
||||
stringRedisTemplate.delete(updateReqVO.getDeviceNo());
|
||||
stringRedisTemplate.delete(updateReqVO.getDeviceNo() + "msg");
|
||||
return error(code, msg);
|
||||
}
|
||||
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - startTime > 3000) {
|
||||
|
||||
throw exception(REQUEST_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/update-user")
|
||||
|
@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||
@ -14,12 +13,15 @@ import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.User
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
|
||||
import cn.iocoder.yudao.module.system.convert.equipment.AttendanceMachineConvert;
|
||||
import cn.iocoder.yudao.module.system.convert.equipment.UsersExtConvert;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.AttendanceMachineDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.UsersExtDO;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.AttendanceMachineService;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.DistributeRecordService;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.UsersExtService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@ -39,11 +41,15 @@ import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@ -62,6 +68,9 @@ public class UsersExtController {
|
||||
@Resource
|
||||
private AttendanceMachineService attendanceMachineService;
|
||||
|
||||
@Resource
|
||||
private DistributeRecordService recordService;
|
||||
|
||||
@RequestMapping(value = "/create",
|
||||
method = {RequestMethod.POST, RequestMethod.PUT}) // 解决 uni-app 不支持 Put 上传文件的问题)
|
||||
@Operation(summary = "上传照片")
|
||||
@ -102,9 +111,7 @@ public class UsersExtController {
|
||||
// 获得部门信息Map
|
||||
Map<Long, DeptDO> deptDOMap = deptService.getDeptMap(convertList(attendanceMachineDO, AttendanceMachineDO::getDeptId));
|
||||
|
||||
List<AttendanceMachineRespVO> respVOS = BeanUtils.toBean(attendanceMachineDO, AttendanceMachineRespVO.class);
|
||||
|
||||
return success(CollectionUtils.convertList(respVOS, respVO -> respVO.setDeptName(deptDOMap.get(respVO.getDeptId()).getName())));
|
||||
return success(AttendanceMachineConvert.INSTANCE.convertList(attendanceMachineDO, deptDOMap));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@ -119,8 +126,23 @@ public class UsersExtController {
|
||||
//获得部门Map
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(pageResult.getList(), UsersExtRespVO::getDeptId));
|
||||
|
||||
return success(new PageResult<>(UsersExtConvert.INSTANCE.convertList(pageResult.getList(), deptMap)
|
||||
, pageResult.getTotal()));
|
||||
// 获得 下发或修改状态信息
|
||||
List<Integer> type = Arrays.asList(1,2);
|
||||
List<DistributeRecordDO> recordDOs = recordService.getDistributeRecord(convertList(pageResult.getList(), UsersExtRespVO::getUserId), type);
|
||||
Map<Long, DistributeRecordDO> recordDOMap = convertMap(recordDOs, DistributeRecordDO::getUserId);
|
||||
|
||||
List<UsersExtRespVO> respVOS = UsersExtConvert.INSTANCE.convertList(pageResult.getList(), deptMap, recordDOMap);
|
||||
|
||||
// 判断是否已下发
|
||||
if (pageReqVO.getIsIssued() != null && pageReqVO.getIsIssued() == 0) {
|
||||
|
||||
respVOS = respVOS.stream().filter(data -> data.getDevices() == null || !new HashSet<>(data.getDevices()).containsAll(pageReqVO.getDeviceNos())).collect(Collectors.toList());
|
||||
}else if (pageReqVO.getIsIssued() != null && pageReqVO.getIsIssued() == 1) {
|
||||
|
||||
respVOS = respVOS.stream().filter(data -> data.getDevices() != null && new HashSet<>(data.getDevices()).containsAll(pageReqVO.getDeviceNos())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return success(new PageResult<>(respVOS, pageResult.getTotal()));
|
||||
}
|
||||
|
||||
return success(BeanUtils.toBean(pageResult, UsersExtRespVO.class));
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.equipment.vo.attendancemachine;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtRespVO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@ -11,13 +10,13 @@ import java.util.List;
|
||||
@Data
|
||||
public class AddUserToAttendanceMachineVO {
|
||||
|
||||
@Schema(description = "下发用户列表")
|
||||
@NotNull(message = "下发用户不能为空")
|
||||
private List<UsersExtRespVO> userInfo;
|
||||
@Schema(description = "下发用户编号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "下发用户编号不能为空")
|
||||
private List<Long> userId;
|
||||
|
||||
@Schema(description = "设备号列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "设备号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "设备号不能为空")
|
||||
private List<String> deviceNos;
|
||||
private String deviceNo;
|
||||
|
||||
@Schema(description = "下发或删除 | 0下发, 1删除")
|
||||
private Integer method;
|
||||
|
@ -11,9 +11,9 @@ import javax.validation.constraints.NotNull;
|
||||
@Data
|
||||
public class AttendanceMachinePasswordVO {
|
||||
|
||||
@Schema(description = "设备ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "设备ID不能为空")
|
||||
private Long id;
|
||||
@Schema(description = "设备号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "设备号不能为空")
|
||||
private String deviceNo;
|
||||
|
||||
@Schema(description = "旧密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
@NotEmpty(message = "旧密码不能为空")
|
||||
|
@ -36,6 +36,6 @@ public class AttendanceMachineRespVO {
|
||||
@ExcelProperty("设备名称")
|
||||
private String deviceName;
|
||||
|
||||
@Schema(description = "是否在线 | 0否 1是")
|
||||
@Schema(description = "是否在线 | 0离线 1在线")
|
||||
private Integer isOnLine;
|
||||
}
|
@ -30,6 +30,15 @@ public class UsersExtPageReqVO extends PageParam {
|
||||
@Schema(description = "是否录入人脸 | 0:未录入 1:已录入")
|
||||
private Integer isEnter;
|
||||
|
||||
@Schema(description = "用户类型")
|
||||
private Integer userType;
|
||||
|
||||
@Schema(description = "是否下发 | 0否 1是")
|
||||
private Integer isIssued;
|
||||
|
||||
@Schema(description = "设备号集合")
|
||||
private List<String> deviceNos;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt;
|
||||
|
||||
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.upload.UploadUserFile;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
@ -36,8 +35,14 @@ public class UsersExtRespVO {
|
||||
@ExcelProperty("人脸图片")
|
||||
private String faceImg;
|
||||
|
||||
@Schema(description = "绑定的考勤机设备号")
|
||||
private String attendanceMachineNos;
|
||||
|
||||
@Schema(description = "绑定的考勤机设备号集合")
|
||||
private List<String> attendanceMachineNos;
|
||||
private List<String> devices;
|
||||
|
||||
@Schema(description = "下发结果")
|
||||
private String result;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "修改人看图片命令 VO")
|
||||
@Data
|
||||
public class UpdateFaceImgVO {
|
||||
|
||||
@Schema(description = "指令")
|
||||
private String cmd = "editUser";
|
||||
|
||||
@Schema(description = "用户id")
|
||||
private String user_id;
|
||||
|
||||
@Schema(description = "修改类型")
|
||||
private Integer edit_mode = 1;
|
||||
|
||||
@Schema(description = "人脸图片url")
|
||||
private String face_template;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "修改设备密码 VO")
|
||||
@Data
|
||||
public class UpdatePasswordVO {
|
||||
|
||||
@Schema(description = "指令号,此处固定为 setPassword")
|
||||
private String cmd = "setPassword";
|
||||
|
||||
@Schema(description = "设备当前密码")
|
||||
private String old_password;
|
||||
|
||||
@Schema(description = "新密码")
|
||||
private String new_password;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class WebsocketBaseVO {
|
||||
|
||||
@Schema(description = "固定为 to_device")
|
||||
private String cmd = "to_device";
|
||||
|
||||
private String from;
|
||||
|
||||
private String extra;
|
||||
|
||||
@Schema(description = "目标设备号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String to;
|
||||
|
||||
@Schema(description = "具体指令中的数据格式")
|
||||
private Object data;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package cn.iocoder.yudao.module.system.convert.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.attendancemachine.AttendanceMachineRespVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.AttendanceMachineDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Mapper
|
||||
public interface AttendanceMachineConvert {
|
||||
|
||||
AttendanceMachineConvert INSTANCE = Mappers.getMapper(AttendanceMachineConvert.class);
|
||||
|
||||
default List<AttendanceMachineRespVO> convertList(List<AttendanceMachineDO> list, Map<Long, DeptDO> deptMap) {
|
||||
|
||||
return CollectionUtils.convertList(list, data -> convert(data, deptMap.get(data.getDeptId())));
|
||||
}
|
||||
|
||||
default AttendanceMachineRespVO convert(AttendanceMachineDO attendanceMachineDO, DeptDO deptDO) {
|
||||
|
||||
AttendanceMachineRespVO respVO = new AttendanceMachineRespVO();
|
||||
if (attendanceMachineDO != null) {
|
||||
|
||||
respVO = BeanUtils.toBean(attendanceMachineDO, AttendanceMachineRespVO.class);
|
||||
respVO.setIsOnLine(attendanceMachineDO.getStatus());
|
||||
|
||||
if (deptDO != null) {
|
||||
respVO.setDeptName(deptDO.getName());
|
||||
}
|
||||
}
|
||||
|
||||
return respVO;
|
||||
}
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
package cn.iocoder.yudao.module.system.convert.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtRespVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -15,18 +16,32 @@ public interface UsersExtConvert {
|
||||
|
||||
UsersExtConvert INSTANCE = Mappers.getMapper(UsersExtConvert.class);
|
||||
|
||||
default List<UsersExtRespVO> convertList(List<UsersExtRespVO> list, Map<Long, DeptDO> deptMap) {
|
||||
default List<UsersExtRespVO> convertList(List<UsersExtRespVO> list, Map<Long, DeptDO> deptMap, Map<Long, DistributeRecordDO> recordDOMap) {
|
||||
|
||||
return CollectionUtils.convertList(list, user -> convert(user, deptMap.get(user.getDeptId())));
|
||||
return CollectionUtils.convertList(list, user -> convert(user, deptMap.get(user.getDeptId()), recordDOMap.get(user.getUserId())));
|
||||
}
|
||||
|
||||
default UsersExtRespVO convert(UsersExtRespVO usersExtDO, DeptDO dept) {
|
||||
default UsersExtRespVO convert(UsersExtRespVO usersExtDO, DeptDO dept, DistributeRecordDO recordDO) {
|
||||
|
||||
if (dept != null) {
|
||||
usersExtDO.setDeptName(dept.getName());
|
||||
}
|
||||
|
||||
usersExtDO.setFaceImg(usersExtDO.getFaceImg() + "?time=" + LocalDateTime.now().getSecond());
|
||||
if (usersExtDO.getFaceImg() != null) {
|
||||
|
||||
usersExtDO.setFaceImg(usersExtDO.getFaceImg() + "?time=" + System.currentTimeMillis());
|
||||
}
|
||||
|
||||
if (usersExtDO.getAttendanceMachineNos() != null) {
|
||||
|
||||
usersExtDO.setDevices(JsonUtils.parseArray(usersExtDO.getAttendanceMachineNos(), String.class));
|
||||
}
|
||||
|
||||
if (recordDO != null) {
|
||||
|
||||
usersExtDO.setResult(recordDO.getResult());
|
||||
usersExtDO.setCreateTime(recordDO.getCreateTime());
|
||||
}
|
||||
|
||||
return usersExtDO;
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ public class DistributeRecordDO extends BaseDO {
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
/**
|
||||
* 记录编号
|
||||
*/
|
||||
private String requestId;
|
||||
/**
|
||||
* 设备编号
|
||||
*/
|
||||
@ -34,9 +38,13 @@ public class DistributeRecordDO extends BaseDO {
|
||||
private Long userId;
|
||||
/**
|
||||
* 记录类型
|
||||
* 0删除 1下发
|
||||
* 0删除 1下发 2修改
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private Integer code;
|
||||
/**
|
||||
* 下发结果
|
||||
*/
|
||||
|
@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.system.dal.dataobject.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.worklog.vo.upload.UploadUserFile;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@ -15,7 +14,7 @@ import java.util.List;
|
||||
*
|
||||
* @author 符溶馨
|
||||
*/
|
||||
@TableName("system_users_ext")
|
||||
@TableName(value = "system_users_ext", autoResultMap = true)
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
|
@ -20,7 +20,6 @@ public interface AttendanceMachineMapper extends BaseMapperX<AttendanceMachineDO
|
||||
|
||||
IPage<AttendanceMachineRespVO> selectAttendancePage(@Param("page") IPage<AttendanceMachineRespVO> mpPage,
|
||||
@Param("reqVO") AttendanceMachinePageReqVO pageReqVO);
|
||||
// @Param("deviceNos")List<String> deviceNos);
|
||||
|
||||
AttendanceMachineRespVO selectAttendanceByAssetsNo(@Param("assetsNo") String assetsNo);
|
||||
|
||||
|
@ -3,6 +3,10 @@ package cn.iocoder.yudao.module.system.dal.mysql.equipment;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考勤机下发记录 Mapper
|
||||
@ -12,4 +16,5 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
@Mapper
|
||||
public interface DistributeRecordMapper extends BaseMapperX<DistributeRecordDO> {
|
||||
|
||||
List<DistributeRecordDO> selectListByUserIdAndType(@Param("userId") List<Long> userId, @Param("type") Collection<Integer> type);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package cn.iocoder.yudao.module.system.job.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||
import cn.iocoder.yudao.framework.websocket.core.session.WebSocketSessionManager;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.AttendanceMachineDO;
|
||||
import cn.iocoder.yudao.module.system.service.equipment.AttendanceMachineService;
|
||||
import com.github.yulichang.toolkit.SpringContentUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
@EnableScheduling
|
||||
public class AttendanceMachineJob {
|
||||
|
||||
@Resource
|
||||
private AttendanceMachineService attendanceMachineService;
|
||||
|
||||
@Resource
|
||||
private StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
@Scheduled(initialDelay = 5000, fixedRate = 30000)
|
||||
@TenantJob
|
||||
public void updateAttendanceMachineStatus() {
|
||||
|
||||
// 获得所有在线的设备
|
||||
List<AttendanceMachineDO> attendanceMachineDOS = attendanceMachineService.getListByStatus();
|
||||
for (AttendanceMachineDO reqDO : attendanceMachineDOS) {
|
||||
|
||||
// redis数据不存在,则为离线状态
|
||||
if (stringRedisTemplate.opsForValue().get(reqDO.getDeviceNo()) == null) {
|
||||
|
||||
attendanceMachineService.updateAttendanceMachineStatus(reqDO.getDeviceNo(), 0, null);
|
||||
|
||||
//同步 删除对应sessionId
|
||||
WebSocketSessionManager webSocketSessionManager = SpringContentUtils.getBean(WebSocketSessionManager.class);
|
||||
webSocketSessionManager.removeSession(webSocketSessionManager.getSessionByDeviceNum(reqDO.getDeviceNo()));
|
||||
}else {
|
||||
|
||||
attendanceMachineService.updateAttendanceMachineStatus(reqDO.getDeviceNo(), 1, stringRedisTemplate.opsForValue().get(reqDO.getDeviceNo()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ public interface AttendanceMachineService {
|
||||
* 更新考勤设备 状态
|
||||
* @param deviceNo 设备号
|
||||
*/
|
||||
void updateAttendanceMachineStatus(String deviceNo);
|
||||
void updateAttendanceMachineStatus(String deviceNo, Integer status, String dateTime);
|
||||
|
||||
/**
|
||||
* 考勤设备密码修改
|
||||
@ -78,4 +78,10 @@ public interface AttendanceMachineService {
|
||||
* @param addReqVO 下发信息
|
||||
*/
|
||||
void addUserToAttendanceMachine(AddUserToAttendanceMachineVO addReqVO);
|
||||
|
||||
/**
|
||||
* 获得所有在线的设备
|
||||
* @return 设备列表
|
||||
*/
|
||||
List<AttendanceMachineDO> getListByStatus();
|
||||
}
|
@ -10,7 +10,7 @@ import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.User
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.assets.AssetsTypeDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.AttendanceMachineDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.UsersExtDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.equipment.AttendanceMachineMapper;
|
||||
import cn.iocoder.yudao.module.system.service.assets.AssetsTypeService;
|
||||
import cn.iocoder.yudao.module.system.service.assets.DeptAssetsInOutStockService;
|
||||
@ -24,14 +24,15 @@ import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ATTENDANCE_MACHINE_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ATTENDANCE_PASSWORD_NOT_EQUAL;
|
||||
|
||||
@ -110,9 +111,15 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAttendanceMachineStatus(String deviceNo) {
|
||||
public void updateAttendanceMachineStatus(String deviceNo, Integer status, String dateTime) {
|
||||
|
||||
attendanceMachineMapper.update(new AttendanceMachineDO().setStatus(1).setRequestTime(LocalDateTime.now()),
|
||||
AttendanceMachineDO updateDO = new AttendanceMachineDO();
|
||||
updateDO.setStatus(status);
|
||||
updateDO.setUpdater(getLoginUserId().toString());
|
||||
if (status == 1) {
|
||||
updateDO.setRequestTime(LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
}
|
||||
attendanceMachineMapper.update(updateDO,
|
||||
new LambdaUpdateWrapper<AttendanceMachineDO>().eq(AttendanceMachineDO::getDeviceNo, deviceNo));
|
||||
}
|
||||
|
||||
@ -120,7 +127,7 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
public void updatePassword(AttendanceMachinePasswordVO updateReqVO) {
|
||||
|
||||
//校验 旧密码
|
||||
AttendanceMachineDO attendanceMachineDO = attendanceMachineMapper.selectById(updateReqVO.getId());
|
||||
AttendanceMachineDO attendanceMachineDO = attendanceMachineMapper.selectOne(AttendanceMachineDO::getDeviceNo, updateReqVO.getDeviceNo());
|
||||
if (attendanceMachineDO == null) {
|
||||
|
||||
throw exception(ATTENDANCE_MACHINE_NOT_EXISTS);
|
||||
@ -134,10 +141,9 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
|
||||
//更新
|
||||
attendanceMachineDO = new AttendanceMachineDO()
|
||||
.setId(updateReqVO.getId())
|
||||
.setPassword(passwordEncoder.encode(updateReqVO.getNewPassword()));
|
||||
|
||||
attendanceMachineMapper.updateById(attendanceMachineDO);
|
||||
attendanceMachineMapper.update(attendanceMachineDO, new LambdaUpdateWrapper<AttendanceMachineDO>().eq(AttendanceMachineDO::getDeviceNo, updateReqVO.getDeviceNo()));
|
||||
}
|
||||
|
||||
private void validateAttendanceMachineExists(Long id) {
|
||||
@ -196,29 +202,39 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
@Override
|
||||
public void addUserToAttendanceMachine(AddUserToAttendanceMachineVO addReqVO) {
|
||||
|
||||
List<DistributeRecordDO> recordDOS = new ArrayList<>();
|
||||
//获得 用户已绑定设备信息
|
||||
List<UsersExtDO> usersExtDO = usersExtService.getListByUserId(addReqVO.getUserId());
|
||||
|
||||
// 更新用户已下发设备列表
|
||||
List<UsersExtRespVO> userInfo = addReqVO.getUserInfo();
|
||||
if (addReqVO.getMethod() == 0) {
|
||||
|
||||
userInfo.forEach(data -> {
|
||||
usersExtDO.forEach(data -> {
|
||||
|
||||
List<String> deviceNo = data.getAttendanceMachineNos();
|
||||
|
||||
// 添加不重复的设备号
|
||||
deviceNo.addAll(addReqVO.getDeviceNos().stream().filter(var -> !deviceNo.contains(var)).collect(Collectors.toList()));
|
||||
if (deviceNo == null || deviceNo.isEmpty()) {
|
||||
|
||||
deviceNo = new ArrayList<>();
|
||||
deviceNo.add(addReqVO.getDeviceNo());
|
||||
}else {
|
||||
|
||||
if (!deviceNo.contains(addReqVO.getDeviceNo())) {
|
||||
|
||||
deviceNo.add(addReqVO.getDeviceNo());
|
||||
}
|
||||
}
|
||||
|
||||
//设备 用户绑定设备
|
||||
data.setAttendanceMachineNos(deviceNo);
|
||||
});
|
||||
}else if (addReqVO.getMethod() == 1) {
|
||||
|
||||
userInfo.forEach(data -> {
|
||||
usersExtDO.forEach(data -> {
|
||||
|
||||
List<String> deviceNo = data.getAttendanceMachineNos();
|
||||
// 添加设备号
|
||||
deviceNo.removeAll(addReqVO.getDeviceNos());
|
||||
deviceNo.remove(addReqVO.getDeviceNo());
|
||||
|
||||
//设备 用户绑定设备
|
||||
data.setAttendanceMachineNos(deviceNo);
|
||||
@ -226,9 +242,12 @@ public class AttendanceMachineServiceImpl implements AttendanceMachineService {
|
||||
}
|
||||
|
||||
// 更新 用户信息
|
||||
usersExtService.updateListUsersExt(userInfo);
|
||||
usersExtService.updateListUsersExt(usersExtDO);
|
||||
}
|
||||
|
||||
//同步 插入 下发记录
|
||||
@Override
|
||||
public List<AttendanceMachineDO> getListByStatus() {
|
||||
|
||||
return attendanceMachineMapper.selectList();
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.service.equipment;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考勤机下发记录 Service 接口
|
||||
@ -15,15 +17,20 @@ public interface DistributeRecordService {
|
||||
* 创建考勤机下发记录
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createDistributeRecord(@Valid DistributeRecordDO createReqVO);
|
||||
void createDistributeRecord(@Valid List<DistributeRecordDO> createReqVO);
|
||||
|
||||
/**
|
||||
* 获得考勤机下发记录
|
||||
* 更新 考勤机下发记录
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateDistributeRecord(@Valid List<DistributeRecordDO> updateReqVO);
|
||||
|
||||
/**
|
||||
* 获得最新的 下发或修改的考勤机下发记录
|
||||
*
|
||||
* @param id 编号
|
||||
* @param userId 用户编号编号
|
||||
* @return 考勤机下发记录
|
||||
*/
|
||||
DistributeRecordDO getDistributeRecord(Long id);
|
||||
List<DistributeRecordDO> getDistributeRecord(List<Long> userId, Collection<Integer> type);
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
package cn.iocoder.yudao.module.system.service.equipment;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.equipment.DistributeRecordMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 考勤机下发记录 Service 实现类
|
||||
@ -20,17 +23,27 @@ public class DistributeRecordServiceImpl implements DistributeRecordService {
|
||||
private DistributeRecordMapper distributeRecordMapper;
|
||||
|
||||
@Override
|
||||
public Long createDistributeRecord(DistributeRecordDO createReqVO) {
|
||||
public void createDistributeRecord(List<DistributeRecordDO> createReqVO) {
|
||||
|
||||
// 插入
|
||||
distributeRecordMapper.insert(createReqVO);
|
||||
// 返回
|
||||
return createReqVO.getId();
|
||||
distributeRecordMapper.insertBatch(createReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DistributeRecordDO getDistributeRecord(Long id) {
|
||||
return distributeRecordMapper.selectById(id);
|
||||
public void updateDistributeRecord(List<DistributeRecordDO> updateReqVO) {
|
||||
|
||||
for (DistributeRecordDO updateDO : updateReqVO) {
|
||||
|
||||
distributeRecordMapper.update(updateDO,
|
||||
new LambdaQueryWrapperX<DistributeRecordDO>()
|
||||
.eq(DistributeRecordDO::getUserId, updateDO.getUserId())
|
||||
.eq(DistributeRecordDO::getRequestId, updateDO.getRequestId()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DistributeRecordDO> getDistributeRecord(List<Long> userId, Collection<Integer> type) {
|
||||
|
||||
return distributeRecordMapper.selectListByUserIdAndType(userId, type);
|
||||
}
|
||||
}
|
@ -40,7 +40,7 @@ public interface UsersExtService {
|
||||
*
|
||||
* @param updateDo 更新信息
|
||||
*/
|
||||
void updateListUsersExt(@Valid List<UsersExtRespVO> updateDo);
|
||||
void updateListUsersExt(@Valid List<UsersExtDO> updateDo);
|
||||
|
||||
/**
|
||||
* 删除用户人脸信息
|
||||
@ -55,6 +55,13 @@ public interface UsersExtService {
|
||||
*/
|
||||
UsersExtDO getUsersExt(Long id);
|
||||
|
||||
/**
|
||||
* 获得指定得用户信息列表
|
||||
* @param userId 用户编号
|
||||
* @return
|
||||
*/
|
||||
List<UsersExtDO> getListByUserId(List<Long> userId);
|
||||
|
||||
/**
|
||||
* 获得用户信息拓展分页
|
||||
*
|
||||
|
@ -3,21 +3,28 @@ package cn.iocoder.yudao.module.system.service.equipment;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
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;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||
import cn.iocoder.yudao.module.infra.api.file.FileApi;
|
||||
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UserExtImportVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtPageReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtRespVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.userExt.UsersExtSaveReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket.UpdateFaceImgVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.equipment.vo.websocket.WebsocketBaseVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.equipment.UsersExtDO;
|
||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import cn.iocoder.yudao.module.system.dal.mysql.equipment.UsersExtMapper;
|
||||
import cn.iocoder.yudao.module.system.service.dept.DeptService;
|
||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@ -26,13 +33,11 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
@ -58,6 +63,12 @@ public class UsersExtServiceImpl implements UsersExtService {
|
||||
@Resource
|
||||
private AdminUserService userService;
|
||||
|
||||
@Resource
|
||||
private WebSocketSenderApi webSocketSenderApi;
|
||||
|
||||
@Resource
|
||||
private DistributeRecordService recordService;
|
||||
|
||||
@Override
|
||||
public Long createUsersExt(UsersExtDO updateDO, MultipartFile file) throws IOException {
|
||||
|
||||
@ -96,6 +107,41 @@ public class UsersExtServiceImpl implements UsersExtService {
|
||||
updateDO.setFaceImg(url);
|
||||
usersExtMapper.updateById(usersExtDO);
|
||||
}
|
||||
|
||||
// 判断用户是否已下发至考勤设备
|
||||
if (usersExtDO.getAttendanceMachineNos() != null) {
|
||||
|
||||
String requestId = IdWorker.get32UUID();
|
||||
WebsocketBaseVO baseVO = new WebsocketBaseVO()
|
||||
.setFrom("")
|
||||
.setExtra(requestId + "_" + getLoginUserId());
|
||||
for (String deviceNo : usersExtDO.getAttendanceMachineNos()) {
|
||||
|
||||
// 设备指令信息
|
||||
UpdateFaceImgVO faceImgVO = new UpdateFaceImgVO();
|
||||
faceImgVO.setUser_id(String.valueOf(usersExtDO.getUserId()));
|
||||
faceImgVO.setFace_template(url);
|
||||
|
||||
baseVO.setTo(deviceNo);
|
||||
baseVO.setData(faceImgVO);
|
||||
|
||||
// 设置 设备下发记录
|
||||
DistributeRecordDO recordDO = new DistributeRecordDO();
|
||||
recordDO.setRequestId(requestId);
|
||||
recordDO.setDeviceNo(deviceNo);
|
||||
recordDO.setUserId(usersExtDO.getUserId());
|
||||
recordDO.setType(2);
|
||||
recordDO.setResult("通讯失败");
|
||||
|
||||
// 更新下发记录信息
|
||||
recordService.createDistributeRecord(Collections.singletonList(recordDO));
|
||||
|
||||
// 设备租户ID
|
||||
TenantContextHolder.setTenantId(1L);
|
||||
// 发送指令至设备 更新设备上人脸图片
|
||||
webSocketSenderApi.sendSN(deviceNo, "attendance-message-send", JsonUtils.toJsonString(baseVO));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回
|
||||
@ -113,12 +159,10 @@ public class UsersExtServiceImpl implements UsersExtService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateListUsersExt(List<UsersExtRespVO> updateDo) {
|
||||
public void updateListUsersExt(List<UsersExtDO> updateDo) {
|
||||
|
||||
// 更新
|
||||
List<UsersExtDO> update = BeanUtils.toBean(updateDo, UsersExtDO.class);
|
||||
|
||||
usersExtMapper.updateBatch(update);
|
||||
usersExtMapper.updateBatch(updateDo);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -145,9 +189,16 @@ public class UsersExtServiceImpl implements UsersExtService {
|
||||
|
||||
@Override
|
||||
public UsersExtDO getUsersExt(Long id) {
|
||||
|
||||
return usersExtMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UsersExtDO> getListByUserId(List<Long> userId) {
|
||||
|
||||
return usersExtMapper.selectList(UsersExtDO::getUserId, userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<UsersExtRespVO> getUsersExtPage(UsersExtPageReqVO pageReqVO) {
|
||||
|
||||
|
@ -135,6 +135,19 @@ yudao:
|
||||
web:
|
||||
admin-ui:
|
||||
url: http://sys.znkjfw.com # Admin 管理后台 UI 的地址
|
||||
websocket:
|
||||
enable: true # websocket的开关
|
||||
path: /infra/ws # 路径
|
||||
sender-type: local # 消息发送的类型,可选值为 local、redis、rocketmq、kafka、rabbitmq
|
||||
sender-rocketmq:
|
||||
topic: ${spring.application.name}-websocket # 消息发送的 RocketMQ Topic
|
||||
consumer-group: ${spring.application.name}-websocket-consumer # 消息发送的 RocketMQ Consumer Group
|
||||
sender-rabbitmq:
|
||||
exchange: ${spring.application.name}-websocket-exchange # 消息发送的 RabbitMQ Exchange
|
||||
queue: ${spring.application.name}-websocket-queue # 消息发送的 RabbitMQ Queue
|
||||
sender-kafka:
|
||||
topic: ${spring.application.name}-websocket # 消息发送的 Kafka Topic
|
||||
consumer-group: ${spring.application.name}-websocket-consumer # 消息发送的 Kafka Consumer Group
|
||||
swagger:
|
||||
title: 管理后台
|
||||
description: 提供管理员管理的所有功能
|
||||
|
@ -15,7 +15,8 @@
|
||||
a.assets_no AS assetsNo,
|
||||
b.device_no AS deviceNo,
|
||||
c.dept_id AS deptId,
|
||||
b.device_name AS deviceName
|
||||
b.device_name AS deviceName,
|
||||
b.status AS isOnLine
|
||||
FROM
|
||||
zc_assets a
|
||||
LEFT JOIN kq_attendance_machine b ON a.assets_no = b.assets_no
|
||||
@ -29,12 +30,9 @@
|
||||
<if test="reqVO.deviceName != null and reqVO.deviceName != ''">
|
||||
AND b.device_name LIKE CONCAT('%', #{reqVO.deviceName}, '%')
|
||||
</if>
|
||||
<!-- <if test="deviceNos != null and deviceNos.size() > 0">-->
|
||||
<!-- AND b.device_no IN-->
|
||||
<!-- <foreach collection="deviceNos" item="deviceNos" open="(" separator="," close=")">-->
|
||||
<!-- #{deviceNos}-->
|
||||
<!-- </foreach>-->
|
||||
<!-- </if>-->
|
||||
<if test="reqVO.isOnLine != null">
|
||||
AND b.status = #{reqVO.isOnLine}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectAttendanceByAssetsNo" resultType="cn.iocoder.yudao.module.system.controller.admin.equipment.vo.attendancemachine.AttendanceMachineRespVO">
|
||||
@ -61,12 +59,24 @@
|
||||
a.face_img AS faceImg,
|
||||
c.create_time AS createTime
|
||||
FROM
|
||||
( system_users_ext a, kq_attendance_machine b )
|
||||
LEFT JOIN kq_distribute_record c ON c.device_no = b.device_no AND c.user_id = a.user_id
|
||||
LEFT JOIN system_users d ON a.user_id = d.id
|
||||
( system_users_ext a, kq_attendance_machine b, system_users d )
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
user_id,
|
||||
max( create_time ) AS create_time
|
||||
FROM
|
||||
kq_distribute_record
|
||||
WHERE
|
||||
code = 0
|
||||
AND ( type = 1 OR type = 2 )
|
||||
AND device_no = #{reqVO.deviceNo}
|
||||
GROUP BY
|
||||
user_id
|
||||
) c ON c.user_id = a.user_id
|
||||
WHERE
|
||||
a.attendance_machine_nos LIKE CONCAT( '%', b.device_no, '%' )
|
||||
AND b.device_no = #{reqVO.deviceNo}
|
||||
AND a.user_id = d.id
|
||||
<if test="reqVO.userName != null and reqVO.userName != ''">
|
||||
AND d.nickname LIKE CONCAT( '%', #{reqVO.userName}, '%' )
|
||||
</if>
|
||||
|
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.equipment.DistributeRecordMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
|
||||
<select id="selectListByUserIdAndType" resultType="cn.iocoder.yudao.module.system.dal.dataobject.equipment.DistributeRecordDO">
|
||||
SELECT
|
||||
a.user_id,
|
||||
a.result,
|
||||
b.create_time
|
||||
FROM
|
||||
kq_distribute_record a,
|
||||
(
|
||||
SELECT
|
||||
user_id,
|
||||
MAX( create_time ) AS create_time
|
||||
FROM
|
||||
kq_distribute_record
|
||||
WHERE
|
||||
type IN
|
||||
<foreach collection="type" item="type" open="(" separator="," close=")">
|
||||
#{type}
|
||||
</foreach>
|
||||
AND user_id IN
|
||||
<foreach collection="userId" item="userId" open="(" separator="," close=")">
|
||||
#{userId}
|
||||
</foreach>
|
||||
GROUP BY
|
||||
user_id
|
||||
) b
|
||||
WHERE
|
||||
a.user_id = b.user_id
|
||||
AND a.create_time = b.create_time
|
||||
</select>
|
||||
</mapper>
|
@ -45,12 +45,15 @@
|
||||
</if>
|
||||
<if test="reqVO.createTime != null and reqVO.createTime.length > 0">
|
||||
<if test="reqVO.createTime[0] != null">
|
||||
and b.create_time >= #{reqVO.createTime[0]}
|
||||
AND b.create_time >= #{reqVO.createTime[0]}
|
||||
</if>
|
||||
<if test="reqVO.createTime[1] != null">
|
||||
and b.create_time <= #{reqVO.createTime[1]}
|
||||
AND b.create_time <= #{reqVO.createTime[1]}
|
||||
</if>
|
||||
</if>
|
||||
<if test="reqVO.userType != null">
|
||||
AND a.user_type = #{reqVO.userType}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
</mapper>
|
Loading…
Reference in New Issue
Block a user