Commit 71f218a5ba059e5580ca7ccaaa454801d9ac16fc

Authored by 2c
1 parent 509f3d2e

新增管理员取钥匙类型

优化推送酒精异常数据逻辑
Bsth-admin/src/main/java/com/ruoyi/common/SignStatusEnum.java
... ... @@ -11,7 +11,8 @@ public enum SignStatusEnum {
11 11 SIGN_STATUS_ZONE_ENUM(0, "正常"),
12 12 SIGN_STATUS_EMPTY_ENUM(1, "未签"),
13 13 SIGN_STATUS_DELAY_ENUM(2, ""),
14   - SIGN_STATUS_WINE_ENUM(3, "酒精测试超标");
  14 + SIGN_STATUS_WINE_ENUM(3, "酒精测试超标"),
  15 + SIGN_STATUS_FOUR_ENUM(4, "管理员代领");
15 16  
16 17  
17 18 SignStatusEnum(Integer status, String description) {
... ...
Bsth-admin/src/main/java/com/ruoyi/controller/dss/KeyBoxController.java
... ... @@ -260,30 +260,36 @@ public class KeyBoxController extends BaseController {
260 260 return ResponseResult.success(vo);
261 261 }
262 262  
  263 + /**
  264 + * 人员领取钥匙的接口方法
  265 + *
  266 + * @param dto 经过验证的请求体,包含领取钥匙所需的信息
  267 + * @param bindingResult 用于存储校验结果的对象
  268 + * @return 返回包含领取钥匙结果的响应对象
  269 + */
263 270 @PostMapping(value = "Driver/TakeKey")
264 271 @ApiOperation(value = "20.人员领取钥匙")
265 272 public ResponseResult<TakeKeyVo> takeKey(@Valid @RequestBody TakeKeyDTO dto, BindingResult bindingResult) {
  273 + // 检查是否有校验错误,如果有,则返回错误信息
266 274 if (bindingResult.hasErrors()) {
267 275 return ResponseResult.error(bindingResult.getFieldError().getDefaultMessage());
268 276 }
269 277  
  278 + // 验证设备信息,如果验证失败,则返回错误响应
270 279 String msg = JwtAuthenticationTokenFilter.validateDevice(dto.getDevice());
271 280 if (StringUtils.isNotEmpty(msg)) {
272 281 log.info(msg);
273 282 return ResponseResult.error(TipEnum.TIP_401.getCode(), TipEnum.TIP_401.getMsg());
274 283 }
275 284  
276   -
  285 + // 查询工作地点信息
277 286 LinggangKeyWorkLocation entity = new LinggangKeyWorkLocation();
278 287 entity.setDevice(dto.getDevice());
279 288 List<LinggangKeyWorkLocation> schedulings = linggangKeyWorkLocationService.list(entity);
280 289  
  290 + // 初始化钥匙信息列表
281 291 List<KeyInfo> keyInfos = null;
282   -// if (CollectionUtils.isNotEmpty(dto.getKeyItem())) {
283   -// Set<String> codes = dto.getKeyItem().stream().map(TakeKeyKeyItemDTO::getKeyCode).filter(obj -> Objects.nonNull(obj)).collect(Collectors.toSet());
284   -// keyInfos = keyInfoService.list(codes);
285   -// }
286   -
  292 + // 根据车牌号码获取车辆信息,并关联钥匙信息
287 293 Set<String> nbbms = dto.getKeyItem().stream().map(TakeKeyKeyItemDTO::getPlate).filter(obj -> StringUtils.isNotEmpty(obj)).collect(Collectors.toSet());
288 294 if (CollectionUtils.isNotEmpty(nbbms)) {
289 295 List<CarInfo> carInfos = carInfoService.list(nbbms);
... ... @@ -303,29 +309,42 @@ public class KeyBoxController extends BaseController {
303 309 }
304 310 }
305 311  
  312 + // 获取设备信息
306 313 Equipment equipment = equipmentService.getOneByDeviceId(dto.getDevice());
307 314 LinggangVenueInfo venueInfo = null;
308 315 if (Objects.nonNull(equipment)) {
309 316 venueInfo = venueInfoService.getById(equipment.getYardId());
310 317 }
311 318  
  319 + // 获取驾驶员信息
312 320 NewDriver driver = newDriverService.getOne(dto.getStaffCode());
313 321 // if (Objects.isNull(driver)) {
314 322 // logger.info("[{}]没有找到driver", dto);
315 323 // return ResponseResult.error404();
316 324 // }
317 325  
  326 + // 转换并处理领取钥匙的位置信息
318 327 List<LinggangKeyWorkLocation> locations = convert(dto, schedulings, driver, keyInfos, 1, venueInfo);
  328 +
  329 + //如果是管理员操作改变排班表的exType=3
  330 + if (dto.getOpeType()==16) {
  331 + LinggangScheduling scheduling = schedulingService.getById(locations.get(0).getSchedulingId());
  332 + scheduling.setExType(4);
  333 + schedulingService.updateById(scheduling);
  334 + }
  335 +
319 336 ResponseResult<Boolean> responseResult = linggangKeyWorkLocationService.saveAndDel(locations);
320 337 if (Objects.isNull(responseResult)) {
321 338 return ResponseResult.error();
322 339 }
323 340  
  341 + // 构建并返回响应结果
324 342 TakeKeyVo vo = convertTakeKeyVo(dto, responseResult, equipment);
325 343  
326 344 return new ResponseResult<>(responseResult.getCode(), responseResult.getMsg(), vo);
327 345 }
328 346  
  347 +
329 348 @PostMapping(value = "Driver/TurnKey")
330 349 @ApiOperation(value = "21.人员归还钥匙")
331 350 public ResponseResult<TakeKeyVo> turnKey(@Valid @RequestBody TakeKeyDTO dto, BindingResult bindingResult) {
... ... @@ -948,11 +967,26 @@ public class KeyBoxController extends BaseController {
948 967 return vo;
949 968 }
950 969  
  970 + /**
  971 + * 将取钥匙请求数据转换为领岗钥匙工作位置信息列表
  972 + * 此方法主要用于处理取钥匙请求,将请求中的关键信息转换并封装到领岗钥匙工作位置对象中,
  973 + * 以便于后续的处理和存储
  974 + *
  975 + * @param dto 取钥匙请求数据传输对象,包含请求的相关信息
  976 + * @param schedulings 已调度的领岗钥匙工作位置信息列表,用于关联调度信息
  977 + * @param driver 司机信息对象,提供司机相关数据
  978 + * @param keyInfos 钥匙信息列表,用于匹配和获取钥匙详细信息
  979 + * @param ty 类型标识,用于区分不同的处理场景
  980 + * @param venueInfo 场地信息对象,提供场地相关数据
  981 + * @return 返回转换后的领岗钥匙工作位置信息列表
  982 + */
951 983 private List<LinggangKeyWorkLocation> convert(TakeKeyDTO dto, List<LinggangKeyWorkLocation> schedulings, NewDriver driver, List<KeyInfo> keyInfos, int ty, LinggangVenueInfo venueInfo) {
  984 + // 检查请求中的钥匙项目是否为空,如果为空则直接返回空列表
952 985 if (CollectionUtils.isEmpty(dto.getKeyItem())) {
953 986 return Collections.emptyList();
954 987 }
955 988  
  989 + // 遍历请求中的每个钥匙项目,转换为领岗钥匙工作位置信息
956 990 return dto.getKeyItem().stream().map(item -> {
957 991 LinggangKeyWorkLocation location = new LinggangKeyWorkLocation();
958 992 location.setDevice(item.getDevice());
... ... @@ -965,6 +999,8 @@ public class KeyBoxController extends BaseController {
965 999 location.setType1(ty);
966 1000 location.setCabinetNo(item.getParkCode());
967 1001 location.setJobCode(dto.getStaffCode());
  1002 +
  1003 + // 如果已调度信息不为空,尝试匹配并关联调度信息
968 1004 if (CollectionUtils.isNotEmpty(schedulings)) {
969 1005 Optional<LinggangKeyWorkLocation> opt = schedulings.stream().filter(s -> Objects.equals(item.getKey(), s.getCabinetNo())).findFirst();
970 1006 if (opt.isPresent()) {
... ... @@ -972,6 +1008,8 @@ public class KeyBoxController extends BaseController {
972 1008 location.setSchedulingId(opt.get().getId());
973 1009 }
974 1010 }
  1011 +
  1012 + // 如果钥匙信息不为空,尝试匹配并关联钥匙信息
975 1013 if (Objects.nonNull(keyInfos)) {
976 1014 Optional<KeyInfo> optional = keyInfos.stream().filter(k -> Objects.equals(k.getKeyCode(), item.getKeyCode())).findFirst();
977 1015 if (optional.isPresent()) {
... ... @@ -984,10 +1022,12 @@ public class KeyBoxController extends BaseController {
984 1022 }
985 1023 }
986 1024  
  1025 + // 如果司机信息不为空,关联司机信息
987 1026 if (Objects.nonNull(driver)) {
988 1027 location.setCreateBy(Convert.toLong(driver.getId()));
989 1028 }
990 1029  
  1030 + // 如果场地信息不为空,关联场地信息
991 1031 if (Objects.nonNull(venueInfo)) {
992 1032 location.setYardId(venueInfo.getId());
993 1033 location.setYardName(venueInfo.getName());
... ... @@ -1140,4 +1180,16 @@ public class KeyBoxController extends BaseController {
1140 1180 return target;
1141 1181 }).orElseGet(null);
1142 1182 }
  1183 +
  1184 + /**
  1185 + * 判断是否是管理员
  1186 + *
  1187 + * @param staffCode 员工编号
  1188 + * @return 是否是管理员
  1189 + */
  1190 + private boolean isAdmin(String staffCode) {
  1191 + // 这里可以根据实际情况实现管理员判断逻辑
  1192 + // 例如:return adminList.contains(staffCode);
  1193 + return "admin".equals(staffCode); // 示例逻辑
  1194 + }
1143 1195 }
... ...
Bsth-admin/src/main/java/com/ruoyi/controller/dss/RemindDriverKeyLocalController.java
... ... @@ -59,50 +59,61 @@ public class RemindDriverKeyLocalController extends BaseController {
59 59 @ApiOperation("司机提醒信息")
60 60 @PostMapping(value = "/remind/driver/key/local/report")
61 61 public ResponseResult<RemindDriverReportVo> remindDriverKeyLocalReport(@Valid @RequestBody RemindDriverReportDTO request, BindingResult bindingResult) {
  62 + // 检查参数绑定结果,如果有错误则返回错误信息
62 63 if (bindingResult.hasErrors()) {
63 64 return ResponseResult.error(bindingResult.getFieldError().getDefaultMessage());
64 65 }
65 66  
  67 + // 创建并初始化冷柜调度对象
66 68 LinggangScheduling scheduling = new LinggangScheduling();
67 69 scheduling.setJobCode(request.getJobCode());
68 70 scheduling.setScheduleDate(request.getDate());
69 71 scheduling.setStartScheduleDate(request.getDate());
70 72 scheduling.setEndScheduleDate(DateUtils.addDays(request.getDate(), 1));
71 73  
72   -
  74 + // 创建并初始化订单实体对象,用于排序
73 75 OrderEntity orderEntity = new OrderEntity();
74 76 orderEntity.setOrder("ascending");
75 77 orderEntity.setProp("fcsjT");
76 78  
  79 + // 查询符合条件的冷柜调度列表
77 80 List<LinggangScheduling> linggangSchedulings = linggangSchedulingService.list(scheduling, orderEntity);
78 81 int size = CollectionUtils.size(linggangSchedulings);
79 82  
  83 + // 初始化钥匙信息和车辆信息列表
80 84 List<KeyInfo> keyInfos = null;
81 85 List<CarInfo> carInfos = null;
  86 +
  87 + // 如果调度列表不为空,根据调度信息获取车辆信息
82 88 if (0 < size) {
83 89 Set<String> nbbms = linggangSchedulings.stream().map(LinggangScheduling::getNbbm).collect(Collectors.toSet());
84 90 carInfos = carInfoService.list(nbbms);
85 91 }
86 92  
  93 + // 如果车辆信息不为空,根据车辆信息获取钥匙信息
87 94 if (CollectionUtils.isNotEmpty(carInfos)) {
88 95 Set<String> plateNums = carInfos.stream().map(CarInfo::getPlateNum).collect(Collectors.toSet());
89 96 keyInfos = keyInfoService.listPlateNums(plateNums);
90 97 }
91 98  
  99 + // 计算车辆和钥匙信息的大小
92 100 int carSize = CollectionUtils.size(carInfos);
93 101 int keyInfoSize = CollectionUtils.size(keyInfos);
94 102  
  103 + // 创建并初始化提醒司机报告视图对象
95 104 RemindDriverReportVo reportVo = new RemindDriverReportVo();
96 105 List<LinggangScheduling> values = linggangSchedulings.stream().filter(ls -> StringUtils.equalsAnyIgnoreCase(ls.getBcType(), "out")).collect(Collectors.toList());
97 106 size = CollectionUtils.size(values);
98 107 reportVo.setCount(Convert.toLong(size));
99 108  
  109 + // 如果调度列表不为空,处理每个调度信息,生成提醒信息列表
100 110 if (size > 0) {
101 111 List<RemindKeyInfoLocalVo> remindKeyInfoLocalVoList = new ArrayList<>();
102 112 for (int i = 0; i < size; i++) {
103 113 RemindKeyInfoLocalVo localVo = new RemindKeyInfoLocalVo();
104 114 localVo.setNbbm(values.get(i).getNbbm());
105 115  
  116 + // 初始化工作位置对象
106 117 LinggangKeyWorkLocation workLocation = new LinggangKeyWorkLocation();
107 118 if (carSize > 0 && keyInfoSize > 0) {
108 119 int index = i;
... ... @@ -112,11 +123,15 @@ public class RemindDriverKeyLocalController extends BaseController {
112 123 optional.ifPresent(k -> workLocation.setKeyInfoId(k.getId()));
113 124 }
114 125 }
  126 +
  127 + // 根据钥匙ID和时间获取工作位置信息
115 128 List<LinggangKeyWorkLocation> keyWorkLocations = null;
116 129 if (Objects.nonNull(workLocation.getKeyInfoId())) {
117 130 workLocation.setMaxCreateDate(new Date());
118 131 keyWorkLocations = linggangKeyWorkLocationService.getTenByKeyIdAndTime(workLocation);
119 132 }
  133 +
  134 + // 处理工作位置信息,确定钥匙状态和相关设备信息
120 135 if (CollectionUtils.isNotEmpty(keyWorkLocations)) {
121 136 int klSize = CollectionUtils.size(keyWorkLocations);
122 137 LinggangKeyWorkLocation sourceKL200 = null;
... ... @@ -137,6 +152,7 @@ public class RemindDriverKeyLocalController extends BaseController {
137 152 }
138 153 }
139 154  
  155 + // 根据工作位置信息设置提醒信息
140 156 if (Objects.nonNull(sourceKL0) && Objects.nonNull(sourceKL1) && Objects.nonNull(sourceKL0.getIndex()) && Objects.nonNull(sourceKL1.getIndex())) {
141 157 if (sourceKL0.getIndex() > sourceKL1.getIndex()) {
142 158 localVo.setKeyInfoStatus(0);
... ... @@ -168,24 +184,43 @@ public class RemindDriverKeyLocalController extends BaseController {
168 184 remindKeyInfoLocalVoList.add(localVo);
169 185 }
170 186 }
  187 +
  188 + // 设置报告视图对象的提醒信息列表和当前位置信息
171 189 if(CollectionUtils.isNotEmpty(remindKeyInfoLocalVoList)) {
172 190 reportVo.setRemindKeyInfoLocalVoList(remindKeyInfoLocalVoList);
173 191 reportVo.setCurrentKeyLocaltion(remindKeyInfoLocalVoList.get(0).getEquipmentName());
174 192 }
175 193 }
176 194  
  195 + // 返回成功响应结果
177 196 return ResponseResult.success(reportVo);
178 197 }
179 198  
  199 + /**
  200 + * 设置返回信息
  201 + * 此方法用于将设备信息和场地名称设置到本地提醒信息对象中
  202 + *
  203 + * @param sourceKL200 来自KL200的源数据对象,包含设备ID和场地名称等信息
  204 + * @param localVo 本地提醒信息对象,用于存储返回的设备名称和场地名称
  205 + */
180 206 private void setReturnInfo(LinggangKeyWorkLocation sourceKL200, RemindKeyInfoLocalVo localVo) {
  207 + // 检查输入对象是否为空,如果任一对象为空,则不执行后续操作
181 208 if (Objects.isNull(sourceKL200) || Objects.isNull(localVo)) {
182 209 return;
183 210 }
  211 +
  212 + // 根据设备ID获取设备信息
184 213 Equipment equipment = equipmentService.getOneByDeviceId(sourceKL200.getDevice());
  214 +
  215 + // 检查是否找到对应的设备信息,如果未找到,则不执行后续操作
185 216 if (Objects.isNull(equipment)) {
186 217 return;
187 218 }
  219 +
  220 + // 设置本地提醒信息对象的返回设备名称
188 221 localVo.setReturnEquipmentName(equipment.getName());
  222 +
  223 + // 设置本地提醒信息对象的返回场地名称
189 224 localVo.setReturnYardName(sourceKL200.getYardName());
190 225 }
191 226 }
... ...
Bsth-admin/src/main/java/com/ruoyi/controller/dss2/DssDriverV2Controller.java
... ... @@ -54,23 +54,35 @@ public class DssDriverV2Controller {
54 54 @Autowired
55 55 private NewDriverService newDriverService;
56 56  
  57 + /**
  58 + * 线下签到接口
  59 + *
  60 + * @param signV2DTO 签到请求数据传输对象
  61 + * @param bindingResult 数据校验结果
  62 + * @return 返回签到结果封装对象
  63 + */
57 64 @ApiOperation("线下签到")
58 65 @PostMapping("/offline/sign/in/add")
59 66 public ResponseResult<DssSignVo> addSign(@RequestBody DssSignV2DTO signV2DTO, BindingResult bindingResult) {
  67 + // 数据校验,如果有错误则返回错误信息
60 68 if (bindingResult.hasErrors()) {
61 69 return ResponseResult.error(bindingResult.getFieldError().getDefaultMessage());
62 70 }
63 71  
  72 + // 获取审核人员信息,如果找不到则返回错误信息
64 73 NewDriver driver = newDriverService.getOne(signV2DTO.getAuditJobCode());
65 74 if (Objects.isNull(driver)) {
66 75 return ResponseResult.error("无法查找到审核人员");
67 76 }
68 77  
69   -
  78 + // 将请求DTO转换为签到实体对象,并设置创建者信息
70 79 SignIn signIn = convertSignIn(signV2DTO);
71 80 signIn.setCreateBy(Convert.toStr(driver.getId()));
  81 +
  82 + // 调用服务添加签到信息,并处理结果
72 83 AjaxResult ajaxResult = signInServiceV1.addSignInOffice(signIn);
73 84  
  85 + // 如果添加成功,则进行后续处理,包括获取字典数据、复制属性等
74 86 if (Objects.nonNull(ajaxResult) && ajaxResult.isSuccess()) {
75 87 SysDictData sysDictData = new SysDictData();
76 88 sysDictData.setDictType("drinking");
... ... @@ -86,12 +98,14 @@ public class DssDriverV2Controller {
86 98  
87 99 vo.setName(signInV1.getDriver().getPersonnelName());
88 100 vo.setPosts(signInV1.getPosts());
  101 + // 将处理后的数据转换为响应结果并返回
89 102 ResponseResult<DssSignVo> responseResult = ResponseResult.success(convertSignInVo(vo, signV2DTO, dictData, signInV1));
90 103 responseResult.setMsg(Convert.toStr(ajaxResult.get(AjaxResult.MSG_TAG)));
91 104 return responseResult;
92 105 }
93 106 }
94 107  
  108 + // 如果添加失败,则根据AjaxResult中的信息返回相应的错误结果
95 109 return ResponseResult.error(Convert.toInt(ajaxResult.get(AjaxResult.CODE_TAG)), Convert.toStr(ajaxResult.get(AjaxResult.MSG_TAG)));
96 110 }
97 111  
... ... @@ -141,6 +155,7 @@ public class DssDriverV2Controller {
141 155 signIn.setImage(dto.getImageContent());
142 156 signIn.setResourceType(2);
143 157 }
  158 + signIn.setExceptionId(dto.getExceptionId());
144 159  
145 160 // SysDictData sysDictData = querySystData(null,"drunkenness");
146 161 // if(Objects.nonNull(sysDictData)){
... ... @@ -151,20 +166,34 @@ public class DssDriverV2Controller {
151 166 }
152 167  
153 168  
  169 + /**
  170 + * 将登录响应信息、签到信息、字典数据和签到记录转换为DSS签到视图对象
  171 + *
  172 + * @param responseVo 登录响应视图对象,包含登录相关信息
  173 + * @param dto 签到信息DTO,包含签到相关数据
  174 + * @param dictData 字典数据,用于参考测试值的阈值
  175 + * @param signInV1 签到记录,包含用户的签到详情
  176 + * @return 返回一个转换后的DSS签到视图对象
  177 + */
154 178 private DssSignVo convertSignInVo(SignInResponseVo responseVo, DssSignV2DTO dto, SysDictData dictData, SignInV1 signInV1) {
  179 + // 初始化DSS签到视图对象
155 180 DssSignVo vo = new DssSignVo();
  181 + // 设置测试ID,即登录响应中的ID
156 182 vo.setTestId(Convert.toStr(responseVo.getId()));
157 183  
158   -
  184 + // 根据签到状态判断测试结果,如果是签到状态区内,则测试结果为2,否则为0
159 185 Integer testResult = bigViewServiceV1.isSignStatusZoneEnum(signInV1.getSignIn()) ? 2 : 0;
160 186 vo.setTestResult(testResult);
  187 + // 如果字典数据为空或测试结果为0且测试值大于字典数据的阈值,则设置测试结果为1
161 188 if (Objects.isNull(dictData) || Objects.equals(testResult, 0) && dto.getTestValue() > Convert.toLong(dictData.getDictValue())) {
162 189 vo.setTestResult(1);
163 190 }
164 191  
  192 + // 根据签到状态设置结果,如果签到状态为1,则结果为0,否则为1
165 193 Integer result = Objects.equals(1, signInV1.getSignIn().getStatus()) ? 0 : 1;
166 194 vo.setResult(result);
167 195  
  196 + // 返回转换后的DSS签到视图对象
168 197 return vo;
169 198 }
170 199  
... ...
Bsth-admin/src/main/java/com/ruoyi/in/service/impl/SignInServiceV1Impl.java
... ... @@ -93,6 +93,7 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
93 93 @Autowired
94 94 private ISignInService signInService;
95 95  
  96 + @Autowired
96 97 private EquipmentExceptionReportService equipmentExceptionReportService;
97 98  
98 99 private static final FastDateFormat HHMM = FastDateFormat.getInstance("HH:mm");
... ... @@ -180,53 +181,71 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
180 181 return saveData(signIn, scheduling, calDriverScheduling, driver, signInV1);
181 182 }
182 183  
  184 + /**
  185 + * 添加员工签到信息
  186 + *
  187 + * @param signIn 员工签到对象,包含签到的相关信息
  188 + * @return 返回AjaxResult对象,包含签到操作的结果
  189 + */
183 190 @Override
184 191 public AjaxResult addSignInOffice(SignIn signIn) {
  192 + // 创建SignInV1对象,并设置签到信息
185 193 SignInV1 signInV1 = new SignInV1();
186 194 signInV1.setSignIn(signIn);
187 195  
188 196 // 查询员工信息
189 197 Driver driver = driverMapper.getDriverInfoByJobCode(signIn.getJobCode());
  198 + // 如果员工不存在,记录日志并返回警告信息
190 199 if (Objects.isNull(driver)) {
191 200 log.info("这个工号的员工不存在:[{}]", signIn);
192 201 return AjaxResult.warn("这个工号的员工不存在!");
193 202 }
  203 + // 设置员工信息
194 204 signInV1.setDriver(driver);
195 205  
  206 + // 如果签到时间未设置,则设置为当前时间
196 207 if (Objects.isNull(signIn.getCreateTime())) {
197 208 signIn.setCreateTime(DateUtils.getNowDate());
198 209 }
199 210  
  211 + // 获取签到时间的日期部分
200 212 long dateTime = signIn.getCreateTime().getTime();
201 213 Date date = DateUtils.shortDate(new Date(dateTime));
202 214 DriverScheduling scheduling = null;
203 215 CalDriverScheduling calDriverScheduling = null;
204 216  
  217 + // 查询员工的排班信息
205 218 List<DriverSchedulingV1> schedulings = schedulingServiceV1.queryByJobCodeAndSchedulingDate(signIn.getJobCode(), date);
  219 + // 如果没有排班信息,保存签到信息并返回成功
206 220 if (CollectionUtils.isEmpty(schedulings)) {
207 221 saveSignOfNoScheduling(signIn, ErrorTypeProperties.WORK_DAY_ERROR);
208 222 switchAndChooseAlcohol(signIn, driver, null);
209 223 return saveData(signIn, null, null, driver, signInV1);
210 224 } else if (Objects.equals(2, signIn.getType())) {
  225 + // 根据签到类型查找对应的排班信息
211 226 calDriverScheduling = findSchedulingByDateTime(schedulings, dateTime, ConstDriverProperties.BC_TYPE_IN);
212 227 } else {
213 228 calDriverScheduling = findSchedulingByDateTime(schedulings, dateTime, ConstDriverProperties.BC_TYPE_OUT);
214 229 }
215 230  
  231 + // 如果没有找到合适的排班信息,记录日志,保存签到信息并返回成功
216 232 if (Objects.isNull(calDriverScheduling.getDriverScheduling())) {
217 233 log.info("当天没有满足要求的数据:dateTime:[{}],signIn:[{}],scheduling:[{}]", dateTime, signIn, JSON.toJSONString(scheduling));
218 234 saveSignOfNoScheduling(signIn, ErrorTypeProperties.WORK_DAY_ERROR);
219 235 return AjaxResult.success(ErrorTypeProperties.WORK_DAY_ERROR);
220 236 }
221 237  
  238 + // 设置排班信息
222 239 scheduling = calDriverScheduling.getDriverScheduling();
223 240 signInV1.setDriverScheduling(calDriverScheduling.getDriverScheduling());
224 241  
  242 + // 如果排班信息中没有签到ID,执行签到逻辑
225 243 if (Objects.isNull(scheduling.getSignInId())) {
226 244 switchAndChooseTime(signIn, scheduling, dateTime);
227 245 switchAndChooseAlcohol(signIn, driver, scheduling);
228 246  
229 247 } else {
  248 + // 如果排班信息中已有签到ID,更新签到逻辑
230 249 log.info("签到的数据为:[{}]", scheduling);
231 250 SignInV1 sourceSign = getById(scheduling.getSignInId());
232 251 if (Objects.nonNull(sourceSign)) {
... ... @@ -235,9 +254,10 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
235 254 }
236 255 }
237 256  
  257 + // 更新签到信息
238 258 signInV1.setSignIn(signIn);
239 259  
240   -
  260 + // 保存签到数据并返回结果
241 261 return saveData(signIn, scheduling, calDriverScheduling, driver, signInV1);
242 262 }
243 263  
... ... @@ -262,26 +282,39 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
262 282 return wrapper.update();
263 283 }
264 284  
  285 + /**
  286 + * 保存签到数据
  287 + *
  288 + * @param signIn 签到信息对象
  289 + * @param scheduling 司机排班信息对象
  290 + * @param calDriverScheduling 计划司机排班信息对象
  291 + * @param driver 司机信息对象
  292 + * @param signInV1 签到信息V1对象
  293 + * @return 返回Ajax结果对象
  294 + */
265 295 private AjaxResult saveData(SignIn signIn, DriverScheduling scheduling, CalDriverScheduling calDriverScheduling, Driver driver, SignInV1 signInV1) {
  296 + // 提取视频内容,并将图片内容设置为null以进行后续处理
266 297 String videoContent = signIn.getImage();
267 298 signIn.setImage(null);
268 299  
  300 + // 处理扩展类型字段
269 301 signIn.setExType1(signIn.getExType());
270 302 Integer type = Objects.isNull(signIn.getExType()) ? 0 : bigViewServiceV1.isSignStatusWineEnum(signIn) ? 3 : signIn.getExType() > 0 ? 1 : 0;
271 303 signIn.setExType(type);
272 304  
  305 + // 插入签到数据到数据库
273 306 signInMapper.insertSignIn(signIn);
274 307  
  308 + // 如果签到图片内容非空,进行处理
275 309 if (org.apache.commons.lang3.StringUtils.isNotEmpty(signIn.getImage())) {
276   -
277 310 signIn.setImage(null);
278 311 }
  312 + // 处理视频内容并上传
279 313 if (org.apache.commons.lang3.StringUtils.isNotEmpty(videoContent) && Objects.equals(signIn.getResourceType(), 2)) {
280 314 StringBuilder builder = new StringBuilder();
281 315 builder.append("sign/video/offline/");
282 316 builder.append(DateUtil.shortNowStr());
283 317 builder.append("/");
284   - builder.append("/");
285 318 builder.append(signIn.getId());
286 319 builder.append("/");
287 320 builder.append(java.util.UUID.randomUUID().toString().replace("-", ""));
... ... @@ -299,6 +332,7 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
299 332 signInResource.setCreateBy(Convert.toLong(signIn.getCreateBy()));
300 333 signInResourceService.save(signInResource);
301 334 } else if (org.apache.commons.lang3.StringUtils.isNotEmpty(videoContent)) {
  335 + // 处理图片内容并上传
302 336 StringBuilder builder = new StringBuilder();
303 337 builder.append("sign/images/offline/");
304 338 builder.append(DateUtil.shortNowStr());
... ... @@ -308,7 +342,7 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
308 342 builder.append(java.util.UUID.randomUUID().toString().replace("-", ""));
309 343 builder.append(".jpg");
310 344  
311   - uploadUtil.uploadImageOfBase64(videoContent, builder.toString(),"jpg");
  345 +// uploadUtil.uploadImageOfBase64(videoContent, builder.toString(),"jpg");
312 346  
313 347 LinggangSignInResource signInResource = new LinggangSignInResource();
314 348 signInResource.setSignId(signIn.getId());
... ... @@ -320,16 +354,19 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
320 354 signInResource.setCreateBy(Convert.toLong(signIn.getCreateBy()));
321 355 signInResourceService.save(signInResource);
322 356 }
  357 + // 更新签到V1对象ID
323 358 signInV1.setId(signIn.getId());
324 359 // 更新考勤
325 360 if (Objects.nonNull(calDriverScheduling)) {
326 361 schedulingService.computedSignInBySignIn(scheduling, calDriverScheduling.getIndex(), signIn, true, signInService);
327 362 }
328 363  
  364 + // 更新临时缓存中的签到状态
329 365 if (TempCache.checkJobCodeExist(signIn.getJobCode())) {
330 366 TempCache.updateSignStatus(signIn.getJobCode());
331 367 }
332 368  
  369 + // 更新签到记录中的排班ID
333 370 if (Objects.nonNull(scheduling)) {
334 371 LambdaUpdateWrapper<SignInV1> updateWrapper = new LambdaUpdateWrapper<>();
335 372  
... ... @@ -340,6 +377,7 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
340 377 // 异常保存到异常异常中
341 378 threadJobService.asyncInsertExceptionRecord(signIn, driver, scheduling);
342 379  
  380 + // 更新设备异常报告状态
343 381 if (Objects.nonNull(signIn.getExceptionId())) {
344 382 LambdaUpdateWrapper<EquipmentExceptionReport> reportLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
345 383 reportLambdaUpdateWrapper.set(EquipmentExceptionReport::getStatus, 3).set(EquipmentExceptionReport::getUpdateTime, new Date())
... ... @@ -347,6 +385,7 @@ public class SignInServiceV1Impl extends ServiceImpl&lt;SignInMapperV1, SignInV1&gt; i
347 385 equipmentExceptionReportService.update(reportLambdaUpdateWrapper);
348 386 }
349 387  
  388 + // 处理Ajax结果并返回
350 389 return handleAjaxResult(signIn, signInV1);
351 390 }
352 391  
... ...
Bsth-admin/src/main/java/com/ruoyi/service/ThreadJobService.java
... ... @@ -201,7 +201,8 @@ public class ThreadJobService {
201 201  
202 202 @Async
203 203 public void asyncInsertExceptionRecord(SignIn signIn, Driver driver, DriverScheduling scheduling) {
204   - if (!SIGN_NO_EX_NUM.equals(signIn.getExType())) {
  204 + // 异常处理,如果签到异常,则插入异常记录
  205 + if (!SIGN_NO_EX_NUM.equals(signIn.getExType()) && Objects.isNull(signIn.getExceptionId())) {
205 206 EquipmentException exception = new EquipmentException();
206 207 exception.setExType(signIn.getExType());
207 208 exception.setDeviceId(signIn.getDeviceId());
... ... @@ -374,6 +375,7 @@ public class ThreadJobService {
374 375 map.put("noticeIssuer", "运控中心");
375 376 map.put("noticeRecipient", "05-" + newDriver.getJobCode());
376 377 map.put("noticeTitle", "异常通知");
  378 + map.put("noticeTime", ConstDateUtil.formatDate("yyyy-MM-dd HH:mm:ss", signIn.getCreateTime()));
377 379 // map.put("noticeSubtitle", "");
378 380  
379 381 StringBuilder builder = new StringBuilder();
... ... @@ -410,6 +412,7 @@ public class ThreadJobService {
410 412 map.put("noticeIssuer", "运控中心");
411 413 map.put("noticeRecipient", "05-006154");
412 414 map.put("noticeTitle", "异常通知");
  415 + map.put("noticeTime", "2025-02-26 10:01:52");
413 416 map.put("noticeContent", "工号:1700003,姓名:测试,工种:驾驶员,排班:有排班,打卡时间:2025-01-07 03:29:20,酒精测试超标,当前测试值达到50mg/100ml。属于饮酒后驾驶机动车");
414 417 map.put("phone", "13681905733");
415 418 map.put("smsContent", "工号:1700003,姓名:测试,工种:驾驶员,排班:有排班,打卡时间:2025-01-07 03:29:20,酒精测试超标,当前测试值达到50mg/100ml。属于饮酒后驾驶机动车");
... ... @@ -419,7 +422,7 @@ public class ThreadJobService {
419 422 map.put("signature", key);
420 423 String result = null;
421 424 try {
422   - result = HttpUtil.get("http://10.10.200.142:9103/commonOpenDataApi/sendAppAndSmsNotice", (Map<String, Object>) JSON.toJSON((map)), 10000);
  425 + result = HttpUtil.get("http://192.168.168.27:9103/commonOpenDataApi/sendAppAndSmsNotice", (Map<String, Object>) JSON.toJSON((map)), 10000);
423 426 System.out.println(result);
424 427 } catch (Exception e) {
425 428 e.printStackTrace();
... ...
Bsth-admin/src/main/java/com/ruoyi/service/impl/BigViewServiceImpl.java
... ... @@ -406,26 +406,35 @@ public class BigViewServiceImpl implements BigViewService {
406 406 /**
407 407 * 自编号为key 存储人员信息
408 408 *
409   - * @param map
410   - * @return
  409 + * @param map 原始映射,键为字符串,值为DriverScheduling对象列表
  410 + * @return 返回一个新的映射,键为字符串,值为LineInfo对象
411 411 */
412 412 private Map<String, LineInfo> transformMapByMacheList(Map<String, List<DriverScheduling>> map) {
  413 + // 初始化一个新的映射,用于存储转换后的人员信息
413 414 Map<String, LineInfo> matchMap = new HashMap<>();
  415 + // 检查输入映射是否为空,如果为空则直接返回新的空映射
414 416 if (CollectionUtil.isEmpty(map)){
415 417 return matchMap;
416 418 }
  419 + // 遍历输入映射的每个条目
417 420 for (Map.Entry<String, List<DriverScheduling>> entry : map.entrySet()) {
  421 + // 获取当前条目的值,即DriverScheduling对象列表
418 422 List<DriverScheduling> value = entry.getValue();
  423 + // 过滤出符合特定条件(出库类型为OUT且自编号不为空)的DriverScheduling对象,并按发车时间排序
419 424 List<DriverScheduling> list = value.stream().filter(item -> BC_TYPE_OUT.equals(item.getBcType()) && !Objects.isNull(item.getNbbm())).sorted(Comparator.comparing(DriverScheduling::getFcsjT)).collect(Collectors.toList());
  425 + // 遍历过滤并排序后的DriverScheduling对象列表
420 426 for (DriverScheduling scheduling : list) {
421 427 // 把每辆车的人员信息收集起来
422 428 String nbbm = scheduling.getNbbm();
  429 + // 尝试从新映射中获取当前自编号对应的LineInfo对象
423 430 LineInfo lineInfoList = matchMap.get(nbbm);
  431 + // 如果新映射中不存在当前自编号对应的LineInfo对象,则创建新的LineInfo对象并添加到新映射中
424 432 if (Objects.isNull(lineInfoList)) {
425 433 LineInfo lineInfo = new LineInfo();
426 434 lineInfo.setNbbm(nbbm);
427 435 lineInfo.setLineName(scheduling.getLineName());
428 436 lineInfo.setFleetName(scheduling.getFleetName());
  437 + // 根据调度信息获取人员信息并设置到LineInfo对象中
429 438 LineInfo.PersonInfoVo personInfoVo = getPersonInfoVo(scheduling);
430 439 if (DRIVER_STRING.equals(scheduling.getPosts())) {
431 440 lineInfo.setDriverInfoVo(personInfoVo);
... ... @@ -434,11 +443,13 @@ public class BigViewServiceImpl implements BigViewService {
434 443 }
435 444 matchMap.put(nbbm, lineInfo);
436 445 } else {
  446 + // 如果新映射中已存在当前自编号对应的LineInfo对象,则更新其人员信息
437 447 LineInfo.PersonInfoVo personInfoVo = getPersonInfoVo(scheduling);
438 448 handleMoreStatus(matchMap, scheduling, nbbm, personInfoVo, scheduling);
439 449 }
440 450 }
441 451 }
  452 + // 返回转换后的新映射
442 453 return matchMap;
443 454 }
444 455  
... ... @@ -482,8 +493,17 @@ public class BigViewServiceImpl implements BigViewService {
482 493 }
483 494 }
484 495  
  496 + /**
  497 + * 根据司机排班信息获取个人信息服务对象
  498 + * 此方法用于将司机排班信息转换为个人信息服务对象,以便在 lineage 模块中使用
  499 + * 它根据排班信息中的例外类型和备注来确定签到状态,并设置工作编号和姓名
  500 + *
  501 + * @param scheduling 司机排班信息,包含例外类型、备注、工作编号和姓名
  502 + * @return 返回一个填充了签到状态、工作编号和姓名的个人信息服务对象
  503 + */
485 504 private LineInfo.PersonInfoVo getPersonInfoVo(DriverScheduling scheduling) {
486 505 LineInfo.PersonInfoVo personInfoVo = new LineInfo.PersonInfoVo();
  506 + // 根据排班信息中的例外类型设置签到状态
487 507 if (Objects.isNull(scheduling.getExType())) {
488 508 personInfoVo.setSignStatus(SIGN_STATUS_EMPTY_ENUM);
489 509 } else {
... ... @@ -502,8 +522,11 @@ public class BigViewServiceImpl implements BigViewService {
502 522 case 3:
503 523 personInfoVo.setSignStatus(SIGN_STATUS_WINE_ENUM);
504 524 break;
  525 + case 4:
  526 + personInfoVo.setSignStatus(SIGN_STATUS_FOUR_ENUM);
505 527 }
506 528 }
  529 + // 设置工作编号和姓名
507 530 personInfoVo.setJobCode(scheduling.getJobCode());
508 531 personInfoVo.setName(scheduling.getName());
509 532 return personInfoVo;
... ...
Bsth-admin/src/main/java/com/ruoyi/service/impl/dss/FaceServiceImpl.java
... ... @@ -203,10 +203,10 @@ public class FaceServiceImpl implements FaceService {
203 203 StringBuilder builder = new StringBuilder();
204 204 builder.append(RuoYiConfig.getDownloadPath1());
205 205 if (!StringUtils.startsWith(dr.getImage(), "/")) {
206   - dr.setImage("/"+dr.getImage()) ;
  206 + dr.setImage("/" + dr.getImage());
207 207 }
208   - if(!StringUtils.startsWith(dr.getImage(),"/head")){
209   - dr.setImage("/head"+dr.getImage()) ;
  208 + if (!StringUtils.startsWith(dr.getImage(), "/head")) {
  209 + dr.setImage("/head" + dr.getImage());
210 210 }
211 211 builder.append(dr.getImage());
212 212  
... ...
Bsth-admin/src/main/resources/application-druid-dev.yml
... ... @@ -138,7 +138,7 @@ ruoyi:
138 138 # 实例演示开关
139 139 demoEnabled: true
140 140 # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
141   - profile: D:/temp/temp/bsth
  141 + profile: D:/work/project/Documents/sign/lingang/uploadPath
142 142 # 获取ip地址开关
143 143 addressEnabled: false
144 144 # 验证码类型 math 数字计算 char 字符验证
... ... @@ -190,7 +190,7 @@ api:
190 190 people:
191 191 url: https://api.dingtalk.com/v1.0/yida/forms/instances/search
192 192 log:
193   - path: D:/ruoyi/logs
  193 + path: D:/work/project/Documents/sign/lingang/logs
194 194 server:
195 195 port: 8100
196 196 netty:
... ... @@ -225,7 +225,7 @@ bsth:
225 225 sdk:
226 226 key: C21s5J1n1rHwXPkvVjubKshtofV5sHXvyUQqSWYxHp2b
227 227 lib:
228   - path: D:/work/code/jienengjiancha/bsth-alcohol-sign/Bsth-admin/src/main/resources/libs/WIN64
  228 + path: D:/work/project/java/bsth-alcohol-sign/Bsth-admin/src/main/resources/libs/WIN64
229 229 faceFeature:
230 230 url: http://222.76.217.238:8880/fcgi-bin/entry.fcgi/system
231 231 process:
... ...
Bsth-admin/src/main/resources/mapper/driver_scheduling/DriverSchedulingMapper.xml
... ... @@ -74,7 +74,7 @@
74 74 and scheduling.job_code = #{jobCode}
75 75 </if>
76 76 <if test="name !=null and name != ''">
77   - and `name` = #{name}
  77 + and scheduling.`name` = #{name}
78 78 </if>
79 79 <if test="lineName !=null and lineName != ''">
80 80 and scheduling.line_name like concat('%', #{lineName}, '%')
... ...
Bsth-admin/src/main/resources/mybatis/mybatis-config.xml
... ... @@ -15,6 +15,7 @@ PUBLIC &quot;-//mybatis.org//DTD Config 3.0//EN&quot;
15 15 <setting name="logImpl" value="SLF4J" />
16 16 <!-- 使用驼峰命名法转换字段 -->
17 17 <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
  18 +<!-- <setting name="logImpl" value="STDOUT_LOGGING"/>-->
18 19 </settings>
19 20  
20 21 </configuration>
... ...