diff --git a/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java b/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java index 046b48d1..77c8887e 100644 --- a/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java +++ b/xinnengyuan/ruoyi-admin/src/main/java/org/dromara/web/controller/CaptchaController.java @@ -5,6 +5,8 @@ import cn.hutool.captcha.AbstractCaptcha; import cn.hutool.captcha.generator.CodeGenerator; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -76,7 +78,7 @@ public class CaptchaController { SmsResponse smsResponse = smsBlend.sendMessage(phonenumber, map); if (!smsResponse.isSuccess()) { log.error("验证码短信发送异常 => {}", smsResponse); - return R.fail(smsResponse.getData().toString()); + return R.fail(parseData(smsResponse)); } return R.ok(); } @@ -140,4 +142,35 @@ public class CaptchaController { return R.ok(captchaVo); } + + + + public static String parseData(SmsResponse smsResponse ) { + try { + JSONObject json = JSONUtil.parseObj(smsResponse.getData()); + // 核心:用 JsonUtil 解析 data,通过键路径 "Response.SendStatusSet[0].Code" 提取字段 + // 键路径规则:层级用 "." 分隔,列表索引用 "[0]" 表示(第 1 个元素) + String code = json.getByPath("Response.SendStatusSet[0].Code", String.class); + System.out.println("错误码:" + code); // 输出:FailedOperation.InsufficientBalanceInSmsPackage + return convert(code); + } catch (Exception e) { + return "短信发送未知错误"; + } + } + + + public static String convert(String code) { + return switch (code) { + case "FailedOperation.InsufficientBalanceInSmsPackage" -> "套餐包余量不足,请购买套餐包"; + case "InternalError.SendAndRecvFail" -> "短信收发超时,请检查您的网络是否有波动"; + case "InvalidParameterValue.IncorrectPhoneNumber" -> "手机号格式错误"; + case "LimitExceeded.AppCountryOrRegionDailyLimit" -> "业务短信国家/地区日下发条数超过设定的上限"; + case "LimitExceeded.AppDailyLimit" -> "业务短信日下发条数超过设定的上限"; + case "LimitExceeded.PhoneNumberDailyLimit" -> "单个手机号日下发短信条数超过设定的上限"; + case "UnauthorizedOperation.ServiceSuspendDueToArrears" -> "欠费被停止服务"; + case "UnsupportedOperation.UnsupportedRegion" -> "不支持该地区短信下发"; + default -> "短信发送未知错误"; + }; + } + } diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application-local.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application-local.yml index 4106a417..64b0ccdc 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application-local.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application-local.yml @@ -41,10 +41,10 @@ snail-job: spring: ai: dashscope: - api-key: xxx + api-key: sk-8d8df92fcbac4bd2922edba30b0bb8fa chat: options: - model: qwen-plus + model: qwen3-max datasource: type: com.zaxxer.hikari.HikariDataSource # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content diff --git a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml index a69eabd8..9b5259f3 100644 --- a/xinnengyuan/ruoyi-admin/src/main/resources/application.yml +++ b/xinnengyuan/ruoyi-admin/src/main/resources/application.yml @@ -76,9 +76,9 @@ spring: servlet: multipart: # 单个文件大小 - max-file-size: 200MB + max-file-size: 1024MB # 设置总上传的文件大小 - max-request-size: 200MB + max-request-size: 1024MB mvc: # 设置静态资源路径 防止所有请求都去查静态资源 static-path-pattern: /static/** diff --git a/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/RecognizerTest.java b/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/RecognizerTest.java index 6706007f..25691018 100644 --- a/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/RecognizerTest.java +++ b/xinnengyuan/ruoyi-admin/src/test/java/org/dromara/test/RecognizerTest.java @@ -1,14 +1,23 @@ package org.dromara.test; +import cn.hutool.json.JSONUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.StringUtils; import org.dromara.manager.recognizermanager.RecognizerManager; import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum; import org.dromara.manager.recognizermanager.vo.RecognizeVo; +import org.dromara.progress.domain.PgsProgressPlanDetail; +import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailFinishedVo; +import org.dromara.progress.service.IPgsProgressPlanDetailService; +import org.dromara.progress.service.IPgsProgressPlanService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; +import java.math.BigDecimal; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; /** * @author lilemy @@ -21,6 +30,12 @@ public class RecognizerTest { @Resource private RecognizerManager recognizerManager; + @Resource + private IPgsProgressPlanDetailService progressPlanDetailService; + + @Resource + private IPgsProgressPlanService progressPlanService; + @Test void test() { RecognizeVo recognize = recognizerManager.recognize("http://xny.yj-3d.com:7363/file/tif/20250625160218orthophoto.png", List.of(RecognizerTypeEnum.PANEL)); @@ -31,4 +46,39 @@ public class RecognizerTest { void testChange() { recognizerManager.convertCoordinate("http://xny.yj-3d.com:9000/xinnengyuan-dev/2025/11/11/d48767a62bc04867a552e06ba6712004.tif", List.of()); } + + @Test + void checkNumber() { + List detailList = progressPlanDetailService.list(); + List planDetailList = detailList.stream() + .filter(detail -> StringUtils.isNotBlank(detail.getFinishedDetail())) + .toList(); + Map> collect = planDetailList.stream() + .collect(Collectors.groupingBy(PgsProgressPlanDetail::getFinishedDetail)); + // 遍历分组结果,输出重复项 + for (Map.Entry> entry : collect.entrySet()) { + String fieldValue = entry.getKey(); + List duplicates = entry.getValue(); + if (duplicates.size() > 1) { // 筛选出有重复的字段值 + PgsProgressPlanDetail first = duplicates.getFirst(); + Long id = first.getId(); + Long planId = first.getProgressPlanId(); + progressPlanService.removeById(planId); + progressPlanDetailService.removeById(id); + System.out.println("重复对象的对象:" + duplicates.stream().map(PgsProgressPlanDetail::getId).toList()); + } + } + for (PgsProgressPlanDetail detail : detailList) { + BigDecimal aiFill = detail.getFinishedNumber(); + String finishedDetail = detail.getFinishedDetail(); + if (StringUtils.isBlank(finishedDetail)) { + continue; + } +// log.info("id: {}, finishedDetail: {}", detail.getId(), finishedDetail); + List finishedVos = JSONUtil.toList(finishedDetail, PgsProgressPlanDetailFinishedVo.class); + if (aiFill.compareTo(BigDecimal.valueOf(finishedVos.size())) != 0) { + log.info("数量异常:{}:{}", detail.getId(), detail.getProgressCategoryId()); + } + } + } } diff --git a/xinnengyuan/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java b/xinnengyuan/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java index d39652a0..5e5f8dab 100644 --- a/xinnengyuan/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java +++ b/xinnengyuan/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/config/AsyncConfig.java @@ -59,6 +59,18 @@ public class AsyncConfig implements AsyncConfigurer { return executor; } + // 解压线程池(大文件操作,不需要太多线程) + @Bean("unzipExecutor") + public Executor unzipExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setCorePoolSize(2); + executor.setMaxPoolSize(4); + executor.setQueueCapacity(10); + executor.setThreadNamePrefix("unzip-"); + executor.initialize(); + return executor; + } + /** * 异步执行异常处理 */ diff --git a/xinnengyuan/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java b/xinnengyuan/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java index a3547075..f69f0423 100644 --- a/xinnengyuan/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java +++ b/xinnengyuan/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/handler/PlusDataPermissionHandler.java @@ -91,7 +91,7 @@ public class PlusDataPermissionHandler { DataPermissionHelper.setVariable("user", currentUser); } // 如果是超级管理员或租户管理员,则不过滤数据 - if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) { + if (LoginHelper.isSuperAdmin()) { return where; } // 构造数据过滤条件的 SQL 片段 diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/AsyncUtil.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/AsyncUtil.java index 9671d607..2c501a3b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/AsyncUtil.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/AsyncUtil.java @@ -1,5 +1,6 @@ package org.dromara.common.utils; +import cn.hutool.core.collection.CollectionUtil; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.utils.MessageUtils; @@ -9,6 +10,8 @@ import org.dromara.contractor.domain.SubConstructionUser; import org.dromara.mobileAttendanceMachine.DeviceMessageSender; import org.dromara.mobileAttendanceMachine.KqjEntity; import org.dromara.project.domain.BusAttendanceMachine; +import org.dromara.project.domain.BusAttendanceMachineRepeat; +import org.dromara.project.service.IBusAttendanceMachineRepeatService; import org.dromara.project.service.IBusAttendanceMachineService; import org.dromara.sms4j.api.SmsBlend; import org.dromara.sms4j.api.entity.SmsResponse; @@ -19,6 +22,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -36,6 +40,9 @@ public class AsyncUtil { @Lazy private IBusAttendanceMachineService attendanceMachineService; + @Resource + private IBusAttendanceMachineRepeatService busAttendanceMachineRepeatService; + //发送短信 @Async public void sendSms(List mobileList, String config) { @@ -63,22 +70,107 @@ public class AsyncUtil { public void sendPersonnel(Long teamId, SubConstructionUser constructionUser) { SysOssVo byId = ossService.getById(Long.valueOf(constructionUser.getFacePic())); List list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", teamId).list(); + + ArrayList repeats = new ArrayList<>(); for (BusAttendanceMachine machine : list) { - deviceMessageSender.sendPersonnelInformation(machine.getSn(), constructionUser.getSysUserId().toString(), constructionUser.getUserName(), byId.getUrl()); + Boolean b = deviceMessageSender.sendPersonnelInformation(machine.getSn(), + constructionUser.getSysUserId().toString(), constructionUser.getUserName(), byId.getUrl()); + if (!b) { + //记录下来重连时下发 + BusAttendanceMachineRepeat repeat = new BusAttendanceMachineRepeat(); + repeat.setSn(machine.getSn()); + repeat.setUserId(constructionUser.getSysUserId().toString()); + repeat.setUserName(constructionUser.getUserName()); + repeat.setUrl(byId.getUrl()); + repeat.setType("1"); + repeats.add(repeat); + } + } + if (CollectionUtil.isNotEmpty(repeats)) { + busAttendanceMachineRepeatService.saveBatch(repeats); } } //删除考勤人员 @Async public void deletePersonnel(SubConstructionUser constructionUser) { + ArrayList repeats = new ArrayList<>(); List list = attendanceMachineService.lambdaQuery().apply("FIND_IN_SET({0}, teams)", constructionUser.getTeamId()).list(); for (BusAttendanceMachine machine : list) { try { - deviceMessageSender.deleteUser(machine.getSn(), constructionUser.getSysUserId().toString()); + KqjEntity.CommonResponse commonResponse = deviceMessageSender.deleteUser(machine.getSn(), constructionUser.getSysUserId().toString()); + int code = commonResponse.getData().getCode(); + if (code != 0) { + //记录下来重连时下发 + BusAttendanceMachineRepeat repeat = new BusAttendanceMachineRepeat(); + repeat.setSn(machine.getSn()); + repeat.setUserId(constructionUser.getSysUserId().toString()); + repeat.setUserName(constructionUser.getUserName()); + repeat.setUrl(null); + repeat.setType("2"); + repeats.add(repeat); + } + } catch (Exception e) { + log.error("删除考勤人员异常", e); + BusAttendanceMachineRepeat repeat = new BusAttendanceMachineRepeat(); + repeat.setSn(machine.getSn()); + repeat.setUserId(constructionUser.getSysUserId().toString()); + repeat.setUserName(constructionUser.getUserName()); + repeat.setUrl(null); + repeat.setType("2"); + repeats.add(repeat); + } + } + if (CollectionUtil.isNotEmpty(repeats)) { + busAttendanceMachineRepeatService.saveBatch(repeats); + } + } + + + //重新下发人员 + @Async + public void repeatSend(String sn) { + List list = busAttendanceMachineRepeatService.lambdaQuery() + .eq(BusAttendanceMachineRepeat::getSn, sn) + .eq(BusAttendanceMachineRepeat::getType, "1") + .list(); + List repeatIds = new ArrayList<>(); + for (BusAttendanceMachineRepeat repeat : list) { + Boolean b = deviceMessageSender.sendPersonnelInformation(repeat.getSn(), repeat.getUserId(), repeat.getUserName(), repeat.getUrl()); + if (b) { + //成功删除记录 + repeatIds.add(repeat.getId()); + } + } + if (CollectionUtil.isNotEmpty(repeatIds)) { + busAttendanceMachineRepeatService.removeByIds(repeatIds); + } + } + + //重新删除人员 + @Async + public void repeatDelete(String sn) { + List list = busAttendanceMachineRepeatService.lambdaQuery() + .eq(BusAttendanceMachineRepeat::getSn, sn) + .eq(BusAttendanceMachineRepeat::getType, "2") + .list(); + List repeatIds = new ArrayList<>(); + for (BusAttendanceMachineRepeat repeat : list) { + try { + KqjEntity.CommonResponse commonResponse = deviceMessageSender.deleteUser(repeat.getSn(), repeat.getUserId()); + int code = commonResponse.getData().getCode(); + if (code == 0) { + //成功删除记录 + repeatIds.add(repeat.getId()); + } } catch (Exception e) { log.error("删除考勤人员异常", e); } } + if (CollectionUtil.isNotEmpty(repeatIds)) { + busAttendanceMachineRepeatService.removeByIds(repeatIds); + } } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java index 61248467..d47abcb0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/common/utils/JSTUtil.java @@ -8,6 +8,7 @@ import org.dromara.common.constant.GeoJsonConstant; import org.dromara.common.core.constant.HttpStatus; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.domain.GeoPoint; +import org.dromara.facility.domain.FacMatrix; import org.dromara.facility.domain.FacPhotovoltaicPanel; import org.dromara.facility.domain.dto.geojson.FacFeatureByPlane; import org.dromara.facility.domain.dto.geojson.FacFeatureByPoint; @@ -338,6 +339,29 @@ public class JSTUtil { return null; } + /** + * 匹配最近方阵,获取该方阵的信息 + * + * @param pointEntity 点位 + * @param matrices 方阵列表 + * @return 最近方阵的信息 + */ + public static FacMatrix findContainingMatrix( + RecognizeConvertCoordinateResult pointEntity, + List matrices + ) { + double lng = Double.parseDouble(pointEntity.getLng()); + double lat = Double.parseDouble(pointEntity.getLat()); + Point point = geometryFactory.createPoint(new Coordinate(lng, lat)); + for (FacMatrix matrix : matrices) { + Polygon polygon = parsePolygon(matrix.getPositions()); + if (polygon.covers(point)) { // covers 包含边界} + return matrix; + } + } + return null; + } + /** * 将 FacPhotovoltaicPanel.positions 转成 Polygon */ @@ -376,7 +400,7 @@ public class JSTUtil { List list = new ArrayList<>(); list.add(s); List matchingRange = findMatchingRange("30.247348", "105.729797", list); - System.out.println(matchingRange==null); + System.out.println(matchingRange == null); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubAttendanceMachineUserServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubAttendanceMachineUserServiceImpl.java index 975f7cb8..81223805 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubAttendanceMachineUserServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubAttendanceMachineUserServiceImpl.java @@ -92,7 +92,7 @@ public class SubAttendanceMachineUserServiceImpl implements ISubAttendanceMachin vo.setMachineId(req.getMachineId()); vo.setContractorId(req.getContractorId()); vo.setUserId(userVo.getUserId()); - vo.setUserName(userVo.getUserName()); + vo.setUserName(userVo.getNickName()); if (CollUtil.isEmpty(finalUserIdList)) { vo.setIdentifying(0); } else if (finalUserIdList.contains(userVo.getUserId().toString())) { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java index 77aff5fd..1ae52ec8 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/contractor/service/impl/SubConstructionUserServiceImpl.java @@ -257,6 +257,7 @@ public class SubConstructionUserServiceImpl extends ServiceImpl uploadZip(@RequestPart("file") MultipartFile file, @Validated(AddGroup.class) DroDroneBigPictureBo bo) { + return R.ok(droDroneBigPictureService.uploadZip(file, bo)); + } + /** * 获取无人机大图信息详细信息 * @@ -77,7 +88,7 @@ public class DroDroneBigPictureController extends BaseController { @RepeatSubmit() @PostMapping() public R add(@Validated(AddGroup.class) @RequestBody DroDroneBigPictureBo bo) { - return toAjax(droDroneBigPictureService.insertByBo(bo)); + return toAjax(droDroneBigPictureService.insertByBo(bo, true)); } /** diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/DroDroneBigPicture.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/DroDroneBigPicture.java index 3771c88d..a60cbb34 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/DroDroneBigPicture.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/DroDroneBigPicture.java @@ -73,6 +73,11 @@ public class DroDroneBigPicture extends BaseEntity { */ private String tifFile; + /** + * 来源类型 + */ + private String sourceType; + /** * 状态 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/bo/DroDroneBigPictureBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/bo/DroDroneBigPictureBo.java index 1af484c9..464f462c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/bo/DroDroneBigPictureBo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/bo/DroDroneBigPictureBo.java @@ -74,6 +74,11 @@ public class DroDroneBigPictureBo extends BaseEntity { */ private String tifFile; + /** + * 来源类型 + */ + private String sourceType; + /** * 状态 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/vo/DroDroneBigPictureVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/vo/DroDroneBigPictureVo.java index 3db3df83..e3f319e0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/vo/DroDroneBigPictureVo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/domain/vo/DroDroneBigPictureVo.java @@ -91,12 +91,23 @@ public class DroDroneBigPictureVo implements Serializable { */ private String recognizeResult; + /** + * 识别结果列表 + */ + private String recognizeResultStr; + /** * tif文件 */ @ExcelProperty(value = "tif文件") private String tifFile; + /** + * 来源类型 + */ + @ExcelProperty(value = "来源类型") + private String sourceType; + /** * 状态 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/IDroDroneBigPictureService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/IDroDroneBigPictureService.java index d63e474e..0a2240f0 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/IDroDroneBigPictureService.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/IDroDroneBigPictureService.java @@ -7,7 +7,9 @@ import org.dromara.drone.domain.DroDroneBigPicture; import org.dromara.drone.domain.bo.DroDroneBigPictureBo; import org.dromara.drone.domain.bo.DroDroneBigPictureProgressVo; import org.dromara.drone.domain.vo.DroDroneBigPictureVo; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.util.Collection; import java.util.List; import java.util.concurrent.CompletableFuture; @@ -48,10 +50,11 @@ public interface IDroDroneBigPictureService extends IService /** * 新增无人机大图信息 * - * @param bo 无人机大图信息 + * @param bo 无人机大图信息 + * @param isNew 是否创建新记录 * @return 是否新增成功 */ - Boolean insertByBo(DroDroneBigPictureBo bo); + Boolean insertByBo(DroDroneBigPictureBo bo, Boolean isNew); /** * 修改无人机大图信息 @@ -100,6 +103,15 @@ public interface IDroDroneBigPictureService extends IService */ Boolean compressPicture(String ossIds, List compressPicIds); + /** + * 异步合成大图 + * + * @param businessName 业务名称 + * @param imageUrls 图片URL列表 + * @return 任务id + */ + CompletableFuture asyncAddBigPicture(String businessName, List imageUrls); + /** * 异步添加压缩图片 * @@ -116,4 +128,22 @@ public interface IDroDroneBigPictureService extends IService * @return 是否成功 */ CompletableFuture asyncUpdateCompressPicture(DroDroneBigPicture pic, DroDroneBigPicture oldPic); + + /** + * 上传zip文件 + * + * @param file zip文件 + * @param bo 无人机大图信息 + * @return 是否成功 + */ + Boolean uploadZip(MultipartFile file, DroDroneBigPictureBo bo); + + /** + * 解压zip文件 + * + * @param zipFile zip文件 + * @param tempDir 临时目录 + * @return 解压后的文件的对象存储Ids + */ + CompletableFuture> unzipAsync(File zipFile, File tempDir); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/impl/DroDroneBigPictureServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/impl/DroDroneBigPictureServiceImpl.java index ae484fab..d8517aa2 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/impl/DroDroneBigPictureServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/drone/service/impl/DroDroneBigPictureServiceImpl.java @@ -2,6 +2,10 @@ package org.dromara.drone.service.impl; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; +import cn.hutool.core.io.FileTypeUtil; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.ZipUtil; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -27,7 +31,9 @@ import org.dromara.drone.service.IDroDroneBigPictureService; import org.dromara.manager.dronemanager.DroneManager; import org.dromara.manager.dronemanager.vo.DroneImgMergeProgressVo; import org.dromara.manager.dronemanager.vo.DroneImgMergeUrlVo; +import org.dromara.manager.recognizermanager.enums.RecognizerTypeEnum; import org.dromara.progress.domain.dto.progressplandetail.PgsProgressPlanDetailAINumberReq; +import org.dromara.progress.domain.vo.progressplandetail.PgsProgressPlanDetailRecognizerVo; import org.dromara.progress.service.IPgsProgressPlanDetailService; import org.dromara.system.domain.vo.SysOssVo; import org.dromara.system.service.ISysOssService; @@ -36,7 +42,9 @@ import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; @@ -54,7 +62,8 @@ import java.util.stream.Collectors; @Slf4j @RequiredArgsConstructor @Service -public class DroDroneBigPictureServiceImpl extends ServiceImpl +public +class DroDroneBigPictureServiceImpl extends ServiceImpl implements IDroDroneBigPictureService { @Lazy @@ -90,11 +99,34 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl recognizerList = + JSONUtil.toList(pictureVo.getRecognizeResult(), PgsProgressPlanDetailRecognizerVo.class); + if (CollUtil.isNotEmpty(recognizerList)) { + // 1. 按类型名称分组 + Map> groupMap = recognizerList.stream() + .collect(Collectors.groupingBy(r -> { + RecognizerTypeEnum typeEnum = RecognizerTypeEnum.fromValue(r.getType()); + return typeEnum != null ? typeEnum.getText() : "未知类型"; + })); + // 2. 将每组转换为 “类型:name1, name2” + String recognizerStr = groupMap.entrySet().stream() + .map(entry -> { + String type = entry.getKey(); + String names = entry.getValue().stream() + .map(PgsProgressPlanDetailRecognizerVo::getName) + .collect(Collectors.joining(", ")); + return type + ":" + names; + }) + .collect(Collectors.joining(";")); // 组之间用分号分隔 + pictureVo.setRecognizeResultStr(recognizerStr); + } + } } return pictureVo; } @@ -123,13 +155,36 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl recognizerList = + JSONUtil.toList(pictureVo.getRecognizeResult(), PgsProgressPlanDetailRecognizerVo.class); + if (CollUtil.isNotEmpty(recognizerList)) { + // 1. 按类型名称分组 + Map> groupMap = recognizerList.stream() + .collect(Collectors.groupingBy(r -> { + RecognizerTypeEnum typeEnum = RecognizerTypeEnum.fromValue(r.getType()); + return typeEnum != null ? typeEnum.getText() : "未知类型"; + })); + // 2. 将每组转换为 “类型:name1, name2” + String recognizerStr = groupMap.entrySet().stream() + .map(entry -> { + String type = entry.getKey(); + String names = entry.getValue().stream() + .map(PgsProgressPlanDetailRecognizerVo::getName) + .collect(Collectors.joining(", ")); + return type + ":" + names; + }) + .collect(Collectors.joining(";")); // 组之间用分号分隔 + pictureVo.setRecognizeResultStr(recognizerStr); + } + } } } result.setRecords(records); @@ -157,6 +212,7 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl { @@ -196,6 +260,30 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl picIds = StringUtils.splitTo(smallPic, Convert::toLong); + List ossVos = ossService.listByIds(picIds); + List picUrls = ossVos.stream().map(SysOssVo::getUrl).toList(); + // 异步执行大图合并 + self.asyncAddBigPicture(add.getTaskName(), picUrls) + .thenAccept(result -> { + DroDroneBigPicture update = new DroDroneBigPicture(); + update.setId(id); + update.setStatus("2"); + update.setTaskId(result); + this.updateById(update); + }).exceptionally(ex -> { + log.error("无人机大图信息[{}]异步执行合成图片失败", add.getTaskName(), ex); + DroDroneBigPicture update = new DroDroneBigPicture(); + update.setId(id); + update.setStatus("4"); + this.updateById(update); + return null; + }); + } + if (StringUtils.isNotBlank(add.getBigPic()) && StringUtils.isNotBlank(add.getTifFile())) { + return this.createProgressRecognize(id); + } return true; } @@ -254,8 +342,26 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl= 0 && msg.compareTo(BigDecimal.ONE) < 0) { return vo; } else { + vo.setProgress(BigDecimal.ZERO); newStatus = "4"; picture.setStatus(newStatus); } @@ -413,6 +551,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl asyncAddBigPicture(String businessName, List imageUrls) { + return CompletableFuture.completedFuture(droneManager.createImageMergeTask(businessName, imageUrls)); + } + /** * 异步添加压缩图片 * @@ -498,6 +649,136 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl { + String fileStr = result.stream() + .map(String::valueOf) + .collect(Collectors.joining(",")); + bo.setId(id); + bo.setSmallPic(fileStr); + this.insertByBo(bo, false); + }) + .exceptionally(ex -> { + // 统一处理解压失败(包括 ZipUtil 等异常) + log.error("压缩包处理失败: {}", ex.getMessage(), ex); + // 保存数据 + DroDroneBigPicture update = new DroDroneBigPicture(); + update.setId(id); + update.setStatus("8"); + update.setRemark(ex.getMessage()); + this.updateById(picture); + return null; + }).whenComplete((r, ex) -> { + // 不管成功失败,都删除临时文件 + FileUtil.del(tempDir); + }); + return true; + } + + /** + * 解压zip文件 + * + * @param zipFile zip文件 + * @param tempDir 临时目录 + * @return 解压后的文件的对象存储Ids + */ + @Async("unzipExecutor") + @Override + public CompletableFuture> unzipAsync(File zipFile, File tempDir) { + File unzipDir; + try { + unzipDir = ZipUtil.unzip(zipFile); + } catch (Exception e) { + // 记录错误日志 + log.error("解压失败:{}", zipFile.getAbsolutePath(), e); + // 抛出异常到上层 thenCompose,便于处理 + CompletableFuture> future = new CompletableFuture<>(); + future.completeExceptionally(new ServiceException("压缩包解压失败")); + return future; + } + // 找图片 + List imageFiles = FileUtil.loopFiles(unzipDir).stream() + .filter(this::isImage) + .toList(); + if (CollUtil.isEmpty(imageFiles)) { + // 抛出异常到上层 thenCompose,便于处理 + CompletableFuture> future = new CompletableFuture<>(); + future.completeExceptionally(new ServiceException("压缩包中没有图片")); + return future; + } + // 异步上传任务 + List> uploadFutures = new ArrayList<>(); + for (File img : imageFiles) { + SysOssVo upload = ossService.upload(img); + uploadFutures.add(CompletableFuture.completedFuture(upload.getOssId())); + } + return CompletableFuture.allOf(uploadFutures.toArray(new CompletableFuture[0])) + .thenApply(v -> uploadFutures.stream() + .map(CompletableFuture::join) + .toList()); + } + + /** + * 判断文件是否是图片 + * + * @param file 文件 + * @return 是否是图片 + */ + private boolean isImage(File file) { + // 方式 1:判断扩展名 + String ext = FileUtil.extName(file).toLowerCase(); + List imageExt = Arrays.asList("jpg", "jpeg", "png", "bmp", "gif", "webp"); + if (imageExt.contains(ext)) { + return true; + } + + // 方式 2:判断真实文件类型(更安全) + String type = FileTypeUtil.getType(file); + return type != null && (type.equals("jpg") || type.equals("png") + || type.equals("jpeg") || type.equals("gif") || type.equals("bmp")); + } + /** * 判断两个Ids是否相同 * @@ -516,4 +797,19 @@ public class DroDroneBigPictureServiceImpl extends ServiceImpl panelList = this.lambdaQuery() .in(FacPhotovoltaicPanel::getProjectId, projectIds) - .ne(FacPhotovoltaicPanel::getStatus, FacFinishStatusEnum.FINISH.getValue()) .eq(type.equals(RecognizerTypeEnum.BRACKET.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "支架安装") .eq(type.equals(RecognizerTypeEnum.PANEL.getValue()), FacPhotovoltaicPanel::getProgressCategoryName, "组件安装") .list(); if (CollUtil.isEmpty(panelList)) { + log.info("没有需要更新的光伏板"); return recognizeVoList; } // 判断识别出来的坐标是否包含在某个面内 @@ -792,7 +792,9 @@ public class FacPhotovoltaicPanelServiceImpl extends ServiceImpl list(GpsSafetyUserRecordBo bo, PageQuery pageQuery) { + return gpsSafetyUserRecordService.queryPageList(bo, pageQuery); + } + + /** + * 导出安全员轨迹信息列表 + */ + @SaCheckPermission("gps:safetyUserRecord:export") + @Log(title = "安全员轨迹信息", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(GpsSafetyUserRecordBo bo, HttpServletResponse response) { + List list = gpsSafetyUserRecordService.queryList(bo); + ExcelUtil.exportExcel(list, "安全员轨迹信息", GpsSafetyUserRecordVo.class, response); + } + + /** + * 获取安全员轨迹信息详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("gps:safetyUserRecord:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(gpsSafetyUserRecordService.queryById(id)); + } + + /** + * 新增安全员轨迹信息 + */ + @SaCheckPermission("gps:safetyUserRecord:add") + @Log(title = "安全员轨迹信息", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody GpsSafetyUserRecordBo bo) { + return toAjax(gpsSafetyUserRecordService.insertByBo(bo)); + } + + /** + * 修改安全员轨迹信息 + */ + @SaCheckPermission("gps:safetyUserRecord:edit") + @Log(title = "安全员轨迹信息", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody GpsSafetyUserRecordBo bo) { + return toAjax(gpsSafetyUserRecordService.updateByBo(bo)); + } + + /** + * 删除安全员轨迹信息 + * + * @param ids 主键串 + */ + @SaCheckPermission("gps:safetyUserRecord:remove") + @Log(title = "安全员轨迹信息", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(gpsSafetyUserRecordService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsManmachine.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsManmachine.java index c3b808e7..d7c83ab5 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsManmachine.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsManmachine.java @@ -1,9 +1,8 @@ package org.dromara.gps.domain; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; -import lombok.EqualsAndHashCode; import java.io.Serial; import java.io.Serializable; @@ -29,12 +28,12 @@ public class GpsManmachine implements Serializable { private String clientId; /** - * 绑定id + * 绑定id */ private Long userId; /** - * 类型(绑定id类型,1、车辆,2人员) + * 类型(绑定id类型,1车辆 2人员 3安全员) */ private Integer type; diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsSafetyUserRecord.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsSafetyUserRecord.java new file mode 100644 index 00000000..6c8ba078 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/GpsSafetyUserRecord.java @@ -0,0 +1,73 @@ +package org.dromara.gps.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.mybatis.core.domain.BaseEntity; + +import java.io.Serial; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 安全员轨迹信息对象 gps_safety_user_record + * + * @author lilemy + * @date 2025-11-26 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("gps_safety_user_record") +public class GpsSafetyUserRecord extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(value = "id") + private Long id; + + /** + * 项目id + */ + private Long projectId; + + /** + * 人员id + */ + private Long userId; + + /** + * 设备id + */ + private String clientId; + + /** + * 人员名称 + */ + private String userName; + + /** + * 记录时间 + */ + private LocalDate recordDate; + + /** + * 入场时间 + */ + private LocalDateTime entryTime; + + /** + * 退场时间 + */ + private LocalDateTime exitTime; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsEquipmentBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsEquipmentBo.java index f00161c0..b7390eca 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsEquipmentBo.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsEquipmentBo.java @@ -1,13 +1,12 @@ package org.dromara.gps.domain.bo; -import org.dromara.gps.domain.GpsEquipment; -import org.dromara.common.mybatis.core.domain.BaseEntity; -import org.dromara.common.core.validate.AddGroup; -import org.dromara.common.core.validate.EditGroup; import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; -import jakarta.validation.constraints.*; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.gps.domain.GpsEquipment; import java.util.List; @@ -25,7 +24,7 @@ public class GpsEquipmentBo extends BaseEntity { /** * 主键ID */ - @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + @NotNull(message = "主键ID不能为空", groups = {EditGroup.class}) private Long id; /** @@ -88,7 +87,7 @@ public class GpsEquipmentBo extends BaseEntity { private Integer gpsType; /** - * 设备类型(0、人员设备,1、车辆设备) + * 设备类型(0人员设备 1车辆设备 2安全员设备) */ private Integer clientType; diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsSafetyUserRecordBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsSafetyUserRecordBo.java new file mode 100644 index 00000000..b93f6c07 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/bo/GpsSafetyUserRecordBo.java @@ -0,0 +1,81 @@ +package org.dromara.gps.domain.bo; + +import io.github.linpeilie.annotations.AutoMapper; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.gps.domain.GpsSafetyUserRecord; + +import java.io.Serial; +import java.time.LocalDate; +import java.time.LocalDateTime; + +/** + * 安全员轨迹信息业务对象 gps_safety_user_record + * + * @author lilemy + * @date 2025-11-26 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = GpsSafetyUserRecord.class, reverseConvertGenerate = false) +public class GpsSafetyUserRecordBo extends BaseEntity { + + @Serial + private static final long serialVersionUID = 70132320796943002L; + + /** + * 主键 + */ + @NotNull(message = "主键不能为空", groups = {EditGroup.class}) + private Long id; + + /** + * 项目id + */ + @NotNull(message = "项目id不能为空", groups = {AddGroup.class, EditGroup.class}) + private Long projectId; + + /** + * 人员id + */ + @NotNull(message = "人员id不能为空", groups = {AddGroup.class, EditGroup.class}) + private Long userId; + + /** + * 设备id + */ + @NotBlank(message = "设备id不能为空", groups = {AddGroup.class, EditGroup.class}) + private String clientId; + + /** + * 人员名称 + */ + private String userName; + + /** + * 记录时间 + */ + @NotNull(message = "记录时间不能为空", groups = {AddGroup.class, EditGroup.class}) + private LocalDate recordDate; + + /** + * 入场时间 + */ + private LocalDateTime entryTime; + + /** + * 退场时间 + */ + private LocalDateTime exitTime; + + /** + * 备注 + */ + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/GpsSafetyUserRecordVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/GpsSafetyUserRecordVo.java new file mode 100644 index 00000000..99f53244 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/domain/vo/GpsSafetyUserRecordVo.java @@ -0,0 +1,83 @@ +package org.dromara.gps.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import org.dromara.gps.domain.GpsSafetyUserRecord; + +import java.io.Serial; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.LocalDateTime; + + +/** + * 安全员轨迹信息视图对象 gps_safety_user_record + * + * @author lilemy + * @date 2025-11-26 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = GpsSafetyUserRecord.class) +public class GpsSafetyUserRecordVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long id; + + /** + * 项目id + */ + @ExcelProperty(value = "项目id") + private Long projectId; + + /** + * 人员id + */ + @ExcelProperty(value = "人员id") + private Long userId; + + /** + * 设备id + */ + @ExcelProperty(value = "设备id") + private String clientId; + + /** + * 人员名称 + */ + @ExcelProperty(value = "人员名称") + private String userName; + + /** + * 记录时间 + */ + @ExcelProperty(value = "记录时间") + private LocalDate recordDate; + + /** + * 入场时间 + */ + @ExcelProperty(value = "入场时间") + private LocalDateTime entryTime; + + /** + * 退场时间 + */ + @ExcelProperty(value = "退场时间") + private LocalDateTime exitTime; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/GpsEquipmentMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/GpsEquipmentMapper.java index 9478673c..e1f2a8a3 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/GpsEquipmentMapper.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/mapper/GpsEquipmentMapper.java @@ -1,12 +1,10 @@ package org.dromara.gps.mapper; -import jakarta.validation.constraints.NotNull; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; -import org.apache.ibatis.annotations.Update; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.gps.domain.GpsEquipment; import org.dromara.gps.domain.vo.GpsEquipmentVo; -import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.gps.domain.vo.GpsUserVo; import java.util.List; @@ -21,7 +19,7 @@ public interface GpsEquipmentMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsSafetyUserRecordService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsSafetyUserRecordService.java new file mode 100644 index 00000000..0dad301f --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/IGpsSafetyUserRecordService.java @@ -0,0 +1,82 @@ +package org.dromara.gps.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.gps.domain.GpsSafetyUserRecord; +import org.dromara.gps.domain.bo.GpsSafetyUserRecordBo; +import org.dromara.gps.domain.vo.GpsSafetyUserRecordVo; + +import java.util.Collection; +import java.util.List; + +/** + * 安全员轨迹信息Service接口 + * + * @author lilemy + * @date 2025-11-26 + */ +public interface IGpsSafetyUserRecordService extends IService { + + /** + * 查询安全员轨迹信息 + * + * @param id 主键 + * @return 安全员轨迹信息 + */ + GpsSafetyUserRecordVo queryById(Long id); + + /** + * 分页查询安全员轨迹信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 安全员轨迹信息分页列表 + */ + TableDataInfo queryPageList(GpsSafetyUserRecordBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的安全员轨迹信息列表 + * + * @param bo 查询条件 + * @return 安全员轨迹信息列表 + */ + List queryList(GpsSafetyUserRecordBo bo); + + /** + * 新增安全员轨迹信息 + * + * @param bo 安全员轨迹信息 + * @return 是否新增成功 + */ + Boolean insertByBo(GpsSafetyUserRecordBo bo); + + /** + * 修改安全员轨迹信息 + * + * @param bo 安全员轨迹信息 + * @return 是否修改成功 + */ + Boolean updateByBo(GpsSafetyUserRecordBo bo); + + /** + * 校验并批量删除安全员轨迹信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 校验并保存轨迹信息 + * 核心逻辑:根据用户当前坐标判断是否在项目区域内,更新或创建轨迹记录(进入/离开区域) + * + * @param clientId 设备id,非空 + * @param projectId 项目id,非空 + * @param userId 用户id,非空 + * @param longitude 经度,非空 + * @param latitude 纬度,非空 + */ + void validTrackByEquipment(String clientId, Long projectId, Long userId, String longitude, String latitude); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java index 507c02a6..0601fd4d 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsEquipmentServiceImpl.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.exception.ServiceException; @@ -31,6 +32,7 @@ import org.dromara.gps.mapper.GpsEquipmentMapper; import org.dromara.gps.mapper.GpsManmachineMapper; import org.dromara.gps.service.IGpsEquipmentService; import org.dromara.gps.service.IGpsEquipmentSonService; +import org.dromara.gps.service.IGpsSafetyUserRecordService; import org.dromara.project.domain.vo.project.BusProjectVo; import org.dromara.project.service.IBusProjectService; import org.dromara.system.domain.vo.SysUserVo; @@ -81,6 +83,9 @@ public class GpsEquipmentServiceImpl extends ServiceImpl 1; // 车辆 + case 0 -> 2; // 人员 + case 2 -> 3; // 安全员 + default -> throw new ServiceException("未知设备类型"); + }; + gpsManmachine.setType(type); if (bo.getClientType() == 1) { iVehVehicleInfoService.update(new LambdaUpdateWrapper().set(VehVehicleInfo::getClientId, bo.getClientId()).eq(VehVehicleInfo::getId, bo.getUserId())); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsSafetyUserRecordServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsSafetyUserRecordServiceImpl.java new file mode 100644 index 00000000..3bae7b17 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/gps/service/impl/GpsSafetyUserRecordServiceImpl.java @@ -0,0 +1,266 @@ +package org.dromara.gps.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.PageQuery; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.utils.JSTUtil; +import org.dromara.facility.domain.FacMatrix; +import org.dromara.facility.service.IFacMatrixService; +import org.dromara.gps.domain.GpsSafetyUserRecord; +import org.dromara.gps.domain.bo.GpsSafetyUserRecordBo; +import org.dromara.gps.domain.vo.GpsSafetyUserRecordVo; +import org.dromara.gps.mapper.GpsSafetyUserRecordMapper; +import org.dromara.gps.service.IGpsSafetyUserRecordService; +import org.dromara.manager.recognizermanager.vo.RecognizeConvertCoordinateResult; +import org.dromara.system.domain.vo.SysUserVo; +import org.dromara.system.service.ISysUserService; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * 安全员轨迹信息Service业务层处理 + * + * @author lilemy + * @date 2025-11-26 + */ +@Slf4j +@RequiredArgsConstructor +@Service +public class GpsSafetyUserRecordServiceImpl extends ServiceImpl + implements IGpsSafetyUserRecordService { + + @Resource + private IFacMatrixService matrixService; + + @Resource + private ISysUserService userService; + + /** + * 查询安全员轨迹信息 + * + * @param id 主键 + * @return 安全员轨迹信息 + */ + @Override + public GpsSafetyUserRecordVo queryById(Long id) { + return baseMapper.selectVoById(id); + } + + /** + * 分页查询安全员轨迹信息列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 安全员轨迹信息分页列表 + */ + @Override + public TableDataInfo queryPageList(GpsSafetyUserRecordBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的安全员轨迹信息列表 + * + * @param bo 查询条件 + * @return 安全员轨迹信息列表 + */ + @Override + public List queryList(GpsSafetyUserRecordBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(GpsSafetyUserRecordBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(GpsSafetyUserRecord::getId); + lqw.eq(bo.getProjectId() != null, GpsSafetyUserRecord::getProjectId, bo.getProjectId()); + lqw.eq(bo.getUserId() != null, GpsSafetyUserRecord::getUserId, bo.getUserId()); + lqw.eq(StringUtils.isNotBlank(bo.getClientId()), GpsSafetyUserRecord::getClientId, bo.getClientId()); + lqw.like(StringUtils.isNotBlank(bo.getUserName()), GpsSafetyUserRecord::getUserName, bo.getUserName()); + lqw.eq(bo.getRecordDate() != null, GpsSafetyUserRecord::getRecordDate, bo.getRecordDate()); + lqw.eq(bo.getEntryTime() != null, GpsSafetyUserRecord::getEntryTime, bo.getEntryTime()); + lqw.eq(bo.getExitTime() != null, GpsSafetyUserRecord::getExitTime, bo.getExitTime()); + return lqw; + } + + /** + * 新增安全员轨迹信息 + * + * @param bo 安全员轨迹信息 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(GpsSafetyUserRecordBo bo) { + GpsSafetyUserRecord add = MapstructUtils.convert(bo, GpsSafetyUserRecord.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改安全员轨迹信息 + * + * @param bo 安全员轨迹信息 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(GpsSafetyUserRecordBo bo) { + GpsSafetyUserRecord update = MapstructUtils.convert(bo, GpsSafetyUserRecord.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(GpsSafetyUserRecord entity) { + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除安全员轨迹信息信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if (isValid) { + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } + + /** + * 校验并保存轨迹信息 + * 核心逻辑:根据用户当前坐标判断是否在项目区域内,更新或创建轨迹记录(进入/离开区域) + * + * @param clientId 设备id,非空 + * @param projectId 项目id,非空 + * @param userId 用户id,非空 + * @param longitude 经度,非空 + * @param latitude 纬度,非空 + */ + @Override + public void validTrackByEquipment(String clientId, Long projectId, Long userId, String longitude, String latitude) { + // 1. 参数校验:任一参数为空则记录错误日志并终止流程 + if (StringUtils.isBlank(clientId) || Objects.isNull(projectId) + || Objects.isNull(userId) || StringUtils.isBlank(longitude) + || StringUtils.isBlank(latitude)) { + log.error("同步安全员轨迹参数异常 clientId: {}, projectId: {}, userId: {}, longitude: {}, latitude: {}", + clientId, projectId, userId, longitude, latitude); + return; // 提前返回,避免无效执行 + } + + LocalDateTime currentTime = LocalDateTime.now(); + LocalDate currentDate = LocalDate.now(); + + // 2. 查询当前项目的地理范围配置 + List matrixList = matrixService.lambdaQuery() + .eq(FacMatrix::getProjectId, projectId) + .list(); + if (CollUtil.isEmpty(matrixList)) { + log.error("同步安全员轨迹项目范围不存在 projectId: {}", projectId); + return; // 无地理范围配置,终止流程 + } + + // 3. 解析坐标并判断是否在项目区域内 + RecognizeConvertCoordinateResult coordinateResult = new RecognizeConvertCoordinateResult(); + coordinateResult.setLng(longitude); + coordinateResult.setLat(latitude); + FacMatrix currentMatrix = JSTUtil.findContainingMatrix(coordinateResult, matrixList); // 命中的地理范围 + + // 4. 查询用户当天最新轨迹记录 + GpsSafetyUserRecord latestRecord = lambdaQuery() + .eq(GpsSafetyUserRecord::getClientId, clientId) + .eq(GpsSafetyUserRecord::getProjectId, projectId) + .eq(GpsSafetyUserRecord::getUserId, userId) + .eq(GpsSafetyUserRecord::getRecordDate, currentDate) + .orderByDesc(GpsSafetyUserRecord::getId) + .last("limit 1") + .one(); + + // 5. 获取用户信息(用于轨迹记录) + SysUserVo userVo = userService.selectUserById(userId); + + // 6. 轨迹记录逻辑处理:根据是否在区域内+是否已有记录,分支处理 + handleTrackRecord(currentMatrix, latestRecord, userVo, clientId, projectId, userId, currentDate, currentTime); + } + + /** + * 处理轨迹记录的创建或更新逻辑 + * 封装核心业务逻辑,减少主方法嵌套 + * + * @param currentMatrix 当前命中的地理范围(null表示不在区域内) + * @param latestRecord 用户当天最新轨迹记录 + * @param userVo 用户信息 + * @param clientId 设备ID + * @param projectId 项目ID + * @param userId 用户ID + * @param currentDate 当前日期 + * @param currentTime 当前时间 + */ + private void handleTrackRecord(FacMatrix currentMatrix, GpsSafetyUserRecord latestRecord, + SysUserVo userVo, String clientId, Long projectId, + Long userId, LocalDate currentDate, LocalDateTime currentTime) { + // 场景1:用户当天已有轨迹记录 + if (Objects.nonNull(latestRecord)) { + LocalDateTime exitTime = latestRecord.getExitTime(); + + // 子场景1.1:当前在区域内,且上次记录已标记离开 → 创建新的进入记录 + if (Objects.nonNull(currentMatrix) && Objects.nonNull(exitTime)) { + createNewTrackRecord(userVo, clientId, projectId, userId, currentDate, currentTime); + } + // 子场景1.2:当前不在区域内,且上次记录未标记离开 → 更新离开时间 + else if (Objects.isNull(currentMatrix) && Objects.isNull(exitTime)) { + latestRecord.setExitTime(currentTime); + this.updateById(latestRecord); + } + // 其他情况(如在区域内但未离开/不在区域内但已离开)无需处理 + return; + } + + // 场景2:用户当天无轨迹记录,且当前在区域内 → 创建首次进入记录 + if (Objects.nonNull(currentMatrix)) { + createNewTrackRecord(userVo, clientId, projectId, userId, currentDate, currentTime); + } + } + + /** + * 创建新的轨迹记录(进入区域) + * 封装重复的对象创建逻辑,提升代码复用性 + */ + private void createNewTrackRecord(SysUserVo userVo, String clientId, Long projectId, + Long userId, LocalDate currentDate, LocalDateTime currentTime) { + GpsSafetyUserRecord newRecord = new GpsSafetyUserRecord(); + newRecord.setProjectId(projectId); + newRecord.setUserId(userId); + newRecord.setClientId(clientId); + newRecord.setUserName(Objects.nonNull(userVo) ? userVo.getNickName() : "未知用户"); // 空值保护 + newRecord.setRecordDate(currentDate); + newRecord.setEntryTime(currentTime); + this.save(newRecord); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneManager.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneManager.java index 9967704f..38fd0596 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneManager.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneManager.java @@ -34,6 +34,7 @@ public class DroneManager { * * @param businessName 业务名称 * @param imageUrls 图片URL列表 + * @return 任务ID */ public String createImageMergeTask(String businessName, List imageUrls) { return DroneRequestUtils.createImgMergeTask(droneProperties.getUrl(), businessName, imageUrls); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java index 4c5c9f07..fe17682b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/manager/dronemanager/DroneRequestUtils.java @@ -67,6 +67,7 @@ public class DroneRequestUtils { * * @param businessName 业务名称 * @param imageUrls 图片URL列表 + * @return 任务ID */ public static String createImgMergeTask(String url, String businessName, List imageUrls) { if (StringUtils.isBlank(businessName) || CollUtil.isEmpty(imageUrls)) { @@ -97,17 +98,17 @@ public class DroneRequestUtils { } /** - * 下载图片合成结果 + * 获取图片合成结果 * * @param taskId 任务ID */ public static DroneImgMergeUrlVo getMergedFileUrl(String url, String taskId) { if (StringUtils.isAnyBlank(taskId)) { - throw new ServiceException("下载图片合成结果请求参数错误", HttpStatus.BAD_REQUEST); + throw new ServiceException("获取图片合成结果请求参数错误", HttpStatus.BAD_REQUEST); } // 完整 URL String fullUrl = url + DroneConstant.GET_MERGED_FILE_URL + "/" + taskId; - String errorMsg = "下载图片合成结果请求失败"; + String errorMsg = "获取图片合成结果请求失败"; try (HttpResponse response = HttpRequest.get(fullUrl).execute()) { if (!response.isOk()) { log.error("{}:{}", errorMsg, response.getStatus()); @@ -121,7 +122,7 @@ public class DroneRequestUtils { } String data = obj.getStr("data"); DroneImgMergeUrlVo mergeUrlVo = JSONUtil.toBean(data, DroneImgMergeUrlVo.class); - log.info("下载图片合成结果请求成功:{}", mergeUrlVo); + log.info("获取图片合成结果请求成功:{}", mergeUrlVo); return mergeUrlVo; } } @@ -148,7 +149,14 @@ public class DroneRequestUtils { JSONObject obj = JSONUtil.parseObj(body); if (!obj.getStr("code").equals("200")) { log.error("{},状态码:{},错误信息:{}", errorMsg, obj.get("code"), obj.get("msg")); - throw new ServiceException(errorMsg + ":" + obj.get("msg")); + if (obj.getStr("code").equals("500")) { + DroneImgMergeProgressVo vo = new DroneImgMergeProgressVo(); + vo.setCode("404"); + vo.setMsg(null); + return vo; + } else { + throw new ServiceException(errorMsg + ":" + obj.get("msg")); + } } DroneImgMergeProgressVo progress = JSONUtil.toBean(obj, DroneImgMergeProgressVo.class); if (progress == null) { diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/out/controller/OutTableController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/out/controller/OutTableController.java index af4ba338..a6396ff1 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/out/controller/OutTableController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/out/controller/OutTableController.java @@ -453,7 +453,7 @@ public class OutTableController extends BaseController { BigDecimal monthCompletionValue = BigDecimal.ZERO; for (BusProcurement busProcurement : busProcurements1) { - if(busProcurement.getAcceptedQuantity()!=null){ + if (busProcurement.getAcceptedQuantity() != null && busProcurement.getUnitPrice() != null) { monthCompletionValue = monthCompletionValue.add(busProcurement.getAcceptedQuantity().multiply(busProcurement.getUnitPrice()).setScale(4, RoundingMode.HALF_UP)); } } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressPlanDetailServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressPlanDetailServiceImpl.java index f806970d..3af2de33 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressPlanDetailServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/progress/service/impl/PgsProgressPlanDetailServiceImpl.java @@ -1184,6 +1184,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl targets = recognizeVo.getTargets(); @@ -1281,6 +1287,7 @@ public class PgsProgressPlanDetailServiceImpl extends ServiceImpl list(BusAttendanceMachineRepeatBo bo, PageQuery pageQuery) { + return busAttendanceMachineRepeatService.queryPageList(bo, pageQuery); + } + + /** + * 导出考勤重新下发列表 + */ + @SaCheckPermission("project:attendanceMachineRepeat:export") + @Log(title = "考勤重新下发", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(BusAttendanceMachineRepeatBo bo, HttpServletResponse response) { + List list = busAttendanceMachineRepeatService.queryList(bo); + ExcelUtil.exportExcel(list, "考勤重新下发", BusAttendanceMachineRepeatVo.class, response); + } + + /** + * 获取考勤重新下发详细信息 + * + * @param id 主键 + */ + @SaCheckPermission("project:attendanceMachineRepeat:query") + @GetMapping("/{id}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long id) { + return R.ok(busAttendanceMachineRepeatService.queryById(id)); + } + + /** + * 新增考勤重新下发 + */ + @SaCheckPermission("project:attendanceMachineRepeat:add") + @Log(title = "考勤重新下发", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody BusAttendanceMachineRepeatBo bo) { + return toAjax(busAttendanceMachineRepeatService.insertByBo(bo)); + } + + /** + * 修改考勤重新下发 + */ + @SaCheckPermission("project:attendanceMachineRepeat:edit") + @Log(title = "考勤重新下发", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody BusAttendanceMachineRepeatBo bo) { + return toAjax(busAttendanceMachineRepeatService.updateByBo(bo)); + } + + /** + * 删除考勤重新下发 + * + * @param ids 主键串 + */ + @SaCheckPermission("project:attendanceMachineRepeat:remove") + @Log(title = "考勤重新下发", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] ids) { + return toAjax(busAttendanceMachineRepeatService.deleteWithValidByIds(List.of(ids), true)); + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceMachineRepeat.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceMachineRepeat.java new file mode 100644 index 00000000..2b53e3e5 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/BusAttendanceMachineRepeat.java @@ -0,0 +1,61 @@ +package org.dromara.project.domain; + +import org.dromara.common.mybatis.core.domain.BaseEntity; +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; + +/** + * 考勤重新下发对象 bus_attendance_machine_repeat + * + * @author Lion Li + * @date 2025-11-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("bus_attendance_machine_repeat") +public class BusAttendanceMachineRepeat extends BaseEntity { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @TableId(value = "id") + private Long id; + + /** + * 设备sn + */ + private String sn; + + /** + * 用户id + */ + private String userId; + + /** + * 用户名 + */ + private String userName; + + /** + * 人脸地址 + */ + private String url; + + /** + * (1-新增 2-删除) + */ + private String type; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/bo/BusAttendanceMachineRepeatBo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/bo/BusAttendanceMachineRepeatBo.java new file mode 100644 index 00000000..27a9793e --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/bo/BusAttendanceMachineRepeatBo.java @@ -0,0 +1,61 @@ +package org.dromara.project.domain.bo; + +import org.dromara.project.domain.BusAttendanceMachineRepeat; +import org.dromara.common.mybatis.core.domain.BaseEntity; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; +import lombok.EqualsAndHashCode; +import jakarta.validation.constraints.*; + +/** + * 考勤重新下发业务对象 bus_attendance_machine_repeat + * + * @author Lion Li + * @date 2025-11-24 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = BusAttendanceMachineRepeat.class, reverseConvertGenerate = false) +public class BusAttendanceMachineRepeatBo extends BaseEntity { + + /** + * 主键ID + */ + @NotNull(message = "主键ID不能为空", groups = { EditGroup.class }) + private Long id; + + /** + * 设备sn + */ + @NotBlank(message = "设备sn不能为空", groups = { AddGroup.class, EditGroup.class }) + private String sn; + + /** + * 用户id + */ + private String userId; + + /** + * 用户名 + */ + private String userName; + + /** + * 人脸地址 + */ + private String url; + + /** + * (1-新增 2-删除) + */ + private String type; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/BusAttendanceMachineRepeatVo.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/BusAttendanceMachineRepeatVo.java new file mode 100644 index 00000000..0a5a8eae --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/domain/vo/BusAttendanceMachineRepeatVo.java @@ -0,0 +1,75 @@ +package org.dromara.project.domain.vo; + +import org.dromara.project.domain.BusAttendanceMachineRepeat; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import org.dromara.common.excel.annotation.ExcelDictFormat; +import org.dromara.common.excel.convert.ExcelDictConvert; +import io.github.linpeilie.annotations.AutoMapper; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.util.Date; + + + +/** + * 考勤重新下发视图对象 bus_attendance_machine_repeat + * + * @author Lion Li + * @date 2025-11-24 + */ +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = BusAttendanceMachineRepeat.class) +public class BusAttendanceMachineRepeatVo implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty(value = "主键ID") + private Long id; + + /** + * 设备sn + */ + @ExcelProperty(value = "设备sn") + private String sn; + + /** + * 用户id + */ + @ExcelProperty(value = "用户id") + private String userId; + + /** + * 用户名 + */ + @ExcelProperty(value = "用户名") + private String userName; + + /** + * 人脸地址 + */ + @ExcelProperty(value = "人脸地址") + private String url; + + /** + * (1-新增 2-删除) + */ + @ExcelProperty(value = "", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "1=-新增,2=-删除") + private String type; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/mapper/BusAttendanceMachineRepeatMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/mapper/BusAttendanceMachineRepeatMapper.java new file mode 100644 index 00000000..013957e8 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/mapper/BusAttendanceMachineRepeatMapper.java @@ -0,0 +1,15 @@ +package org.dromara.project.mapper; + +import org.dromara.project.domain.BusAttendanceMachineRepeat; +import org.dromara.project.domain.vo.BusAttendanceMachineRepeatVo; +import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; + +/** + * 考勤重新下发Mapper接口 + * + * @author Lion Li + * @date 2025-11-24 + */ +public interface BusAttendanceMachineRepeatMapper extends BaseMapperPlus { + +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceMachineRepeatService.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceMachineRepeatService.java new file mode 100644 index 00000000..47624197 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/IBusAttendanceMachineRepeatService.java @@ -0,0 +1,70 @@ +package org.dromara.project.service; + +import org.dromara.project.domain.vo.BusAttendanceMachineRepeatVo; +import org.dromara.project.domain.bo.BusAttendanceMachineRepeatBo; +import org.dromara.project.domain.BusAttendanceMachineRepeat; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; + +import com.baomidou.mybatisplus.extension.service.IService; +import java.util.Collection; +import java.util.List; + +/** + * 考勤重新下发Service接口 + * + * @author Lion Li + * @date 2025-11-24 + */ +public interface IBusAttendanceMachineRepeatService extends IService{ + + /** + * 查询考勤重新下发 + * + * @param id 主键 + * @return 考勤重新下发 + */ + BusAttendanceMachineRepeatVo queryById(Long id); + + /** + * 分页查询考勤重新下发列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 考勤重新下发分页列表 + */ + TableDataInfo queryPageList(BusAttendanceMachineRepeatBo bo, PageQuery pageQuery); + + /** + * 查询符合条件的考勤重新下发列表 + * + * @param bo 查询条件 + * @return 考勤重新下发列表 + */ + List queryList(BusAttendanceMachineRepeatBo bo); + + /** + * 新增考勤重新下发 + * + * @param bo 考勤重新下发 + * @return 是否新增成功 + */ + Boolean insertByBo(BusAttendanceMachineRepeatBo bo); + + /** + * 修改考勤重新下发 + * + * @param bo 考勤重新下发 + * @return 是否修改成功 + */ + Boolean updateByBo(BusAttendanceMachineRepeatBo bo); + + /** + * 校验并批量删除考勤重新下发信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceMachineRepeatServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceMachineRepeatServiceImpl.java new file mode 100644 index 00000000..c5e9e859 --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceMachineRepeatServiceImpl.java @@ -0,0 +1,136 @@ +package org.dromara.project.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.dromara.common.core.utils.MapstructUtils; +import org.dromara.common.core.utils.StringUtils; +import org.dromara.common.mybatis.core.page.TableDataInfo; +import org.dromara.common.mybatis.core.page.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.dromara.project.domain.bo.BusAttendanceMachineRepeatBo; +import org.dromara.project.domain.vo.BusAttendanceMachineRepeatVo; +import org.dromara.project.domain.BusAttendanceMachineRepeat; +import org.dromara.project.mapper.BusAttendanceMachineRepeatMapper; +import org.dromara.project.service.IBusAttendanceMachineRepeatService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 考勤重新下发Service业务层处理 + * + * @author Lion Li + * @date 2025-11-24 + */ +@RequiredArgsConstructor +@Service +public class BusAttendanceMachineRepeatServiceImpl extends ServiceImpl + implements IBusAttendanceMachineRepeatService { + + private final BusAttendanceMachineRepeatMapper baseMapper; + + /** + * 查询考勤重新下发 + * + * @param id 主键 + * @return 考勤重新下发 + */ + @Override + public BusAttendanceMachineRepeatVo queryById(Long id){ + return baseMapper.selectVoById(id); + } + + /** + * 分页查询考勤重新下发列表 + * + * @param bo 查询条件 + * @param pageQuery 分页参数 + * @return 考勤重新下发分页列表 + */ + @Override + public TableDataInfo queryPageList(BusAttendanceMachineRepeatBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询符合条件的考勤重新下发列表 + * + * @param bo 查询条件 + * @return 考勤重新下发列表 + */ + @Override + public List queryList(BusAttendanceMachineRepeatBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(BusAttendanceMachineRepeatBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.orderByDesc(BusAttendanceMachineRepeat::getId); + lqw.eq(StringUtils.isNotBlank(bo.getSn()), BusAttendanceMachineRepeat::getSn, bo.getSn()); + lqw.eq(StringUtils.isNotBlank(bo.getUserId()), BusAttendanceMachineRepeat::getUserId, bo.getUserId()); + lqw.like(StringUtils.isNotBlank(bo.getUserName()), BusAttendanceMachineRepeat::getUserName, bo.getUserName()); + lqw.eq(StringUtils.isNotBlank(bo.getUrl()), BusAttendanceMachineRepeat::getUrl, bo.getUrl()); + lqw.eq(StringUtils.isNotBlank(bo.getType()), BusAttendanceMachineRepeat::getType, bo.getType()); + return lqw; + } + + /** + * 新增考勤重新下发 + * + * @param bo 考勤重新下发 + * @return 是否新增成功 + */ + @Override + public Boolean insertByBo(BusAttendanceMachineRepeatBo bo) { + BusAttendanceMachineRepeat add = MapstructUtils.convert(bo, BusAttendanceMachineRepeat.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setId(add.getId()); + } + return flag; + } + + /** + * 修改考勤重新下发 + * + * @param bo 考勤重新下发 + * @return 是否修改成功 + */ + @Override + public Boolean updateByBo(BusAttendanceMachineRepeatBo bo) { + BusAttendanceMachineRepeat update = MapstructUtils.convert(bo, BusAttendanceMachineRepeat.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(BusAttendanceMachineRepeat entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 校验并批量删除考勤重新下发信息 + * + * @param ids 待删除的主键集合 + * @param isValid 是否进行有效性校验 + * @return 是否删除成功 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteByIds(ids) > 0; + } +} diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java index bd9d6e2a..3bf263af 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusAttendanceServiceImpl.java @@ -409,6 +409,7 @@ public class BusAttendanceServiceImpl extends ServiceImpl constructionUserLuw = Wrappers.lambdaUpdate(SubConstructionUser.class) .eq(SubConstructionUser::getId, constructionUser.getId()) .set(SubConstructionUser::getTeamId, null) + .set(SubConstructionUser::getStatus, "1") .set(SubConstructionUser::getLeaveDate, new Date()); if (StringUtils.isNotBlank(salaryVoucherFile) && StringUtils.isNotBlank(salaryConfirmationFile)) { constructionUserLuw.set(SubConstructionUser::getExitStatus, "2"); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java index b5b70347..ef5bf1d5 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/project/service/impl/BusProjectTeamMemberServiceImpl.java @@ -190,6 +190,7 @@ public class BusProjectTeamMemberServiceImpl extends ServiceImpl getReplacementMap(QltQualityConstructionLog qualityConstructionLog) { Map replacementMap = new HashMap<>(); - String createName = userService.selectUserById(qualityConstructionLog.getCreateBy()).getNickName(); + Long createBy = qualityConstructionLog.getCreateBy(); + String createName = ""; + if (createBy != null) { + SysUserVo userVo = userService.selectUserById(createBy); + if (userVo != null) { + createName = userVo.getNickName(); + } + } replacementMap.put("${createName}", createName); Date createTime = qualityConstructionLog.getCreateTime(); replacementMap.put("${createTime}", createTime != null ? DateUtils.formatDateTime(createTime) : ""); - String projectName = projectService.getById(qualityConstructionLog.getProjectId()).getProjectName(); + Long projectId = qualityConstructionLog.getProjectId(); + String projectName = ""; + if (projectId != null) { + BusProject project = projectService.getById(projectId); + if (project != null) { + projectName = project.getProjectName(); + } + } replacementMap.put("${projectName}", projectName); LocalDate happenDate = qualityConstructionLog.getHappenDate(); replacementMap.put("${happenDate}", happenDate != null ? happenDate.toString() : ""); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseSafetyWeeklyReportServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseSafetyWeeklyReportServiceImpl.java index 963912de..3d7a9be1 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseSafetyWeeklyReportServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/safety/service/impl/HseSafetyWeeklyReportServiceImpl.java @@ -391,51 +391,33 @@ public class HseSafetyWeeklyReportServiceImpl extends ServiceImpl=0" // 简单的条件 + ); + + // 设置填充颜色 + PatternFormatting fill = rule.createPatternFormatting(); + fill.setFillBackgroundColor(IndexedColors.LIGHT_BLUE.getIndex()); + fill.setFillPattern(PatternFormatting.SOLID_FOREGROUND); + + // 应用规则 + CellRangeAddress[] regions = { + CellRangeAddress.valueOf("I12:I18"), + CellRangeAddress.valueOf("I20:I23") + }; + + sheetCF.addConditionalFormatting(regions, rule); + System.out.println("最简化条件格式设置成功"); + + } catch (Exception e) { + System.err.println("最简化条件格式设置失败: " + e.getMessage()); + // 如果连这个都失败,可能是POI版本问题,跳过条件格式 + System.out.println("跳过条件格式设置"); + } + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/DeviceWebSocketServer.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/DeviceWebSocketServer.java index 2845b421..ec19766b 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/DeviceWebSocketServer.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/websocket/websocket/service/DeviceWebSocketServer.java @@ -2,11 +2,13 @@ package org.dromara.websocket.websocket.service; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.annotation.Resource; import jakarta.websocket.*; import jakarta.websocket.server.ServerEndpoint; import lombok.extern.log4j.Log4j2; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.SpringUtils; +import org.dromara.common.utils.AsyncUtil; import org.dromara.mobileAttendanceMachine.KqjEntity; import org.dromara.project.service.IBusAttendanceMachineService; import org.springframework.stereotype.Component; @@ -33,6 +35,9 @@ public class DeviceWebSocketServer { private final static IBusAttendanceMachineService attendanceMachineService = SpringUtils.getBean(IBusAttendanceMachineService.class); + private final static AsyncUtil asyncUtil = SpringUtils.getBean(AsyncUtil.class); + + // ------------------------------ 常量定义 ------------------------------ public static final String DECLARE = "declare"; // 设备注册消息 public static final String PING = "ping"; // 心跳消息 @@ -388,6 +393,8 @@ public class DeviceWebSocketServer { // 示例:BusAttendanceMachineService.register(sn); if (attendanceMachineService != null) { attendanceMachineService.insertBySn(sn); + asyncUtil.repeatSend(sn); + asyncUtil.repeatDelete(sn); } else { log.error("IBusAttendanceMachineService 为空,无法进行设备注册"); } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/controller/XzdBxBxsqController.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/controller/XzdBxBxsqController.java index c8d559cc..1624de8f 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/controller/XzdBxBxsqController.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/controller/XzdBxBxsqController.java @@ -52,6 +52,9 @@ public class XzdBxBxsqController extends BaseController { private final IXzdProjectService xzdProjectService; private final IXzdSupplierOpenBankService xzdSupplierOpenBankService; private final IXzdBxBxsqBxlxService xzdBxBxsqBxlxService; + private final IXzdYhxxService xzdYhxxService; + + /** * 查询报销-报销申请列表 */ @@ -61,8 +64,6 @@ public class XzdBxBxsqController extends BaseController { return xzdBxBxsqService.queryPageList(bo, pageQuery); } - private final IXzdYhxxService xzdYhxxService; - /** * 查询银行数据关联列表 */ diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/mapper/XzdBxBxsqMapper.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/mapper/XzdBxBxsqMapper.java index ac25edd7..8dc296cf 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/mapper/XzdBxBxsqMapper.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/mapper/XzdBxBxsqMapper.java @@ -1,5 +1,10 @@ package org.dromara.xzd.bx.bxsq.mapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import org.dromara.common.mybatis.annotation.DataColumn; +import org.dromara.common.mybatis.annotation.DataPermission; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.xzd.bx.bxsq.domain.XzdBxBxsq; import org.dromara.xzd.bx.bxsq.domain.vo.XzdBxBxsqVo; @@ -12,4 +17,13 @@ import org.dromara.xzd.bx.bxsq.domain.vo.XzdBxBxsqVo; */ public interface XzdBxBxsqMapper extends BaseMapperPlus { + + @DataPermission({ + @DataColumn(key = "deptName", value = "dept_id"), + @DataColumn(key = "userName", value = "bxr") + }) + default Page selectPage(IPage page, LambdaQueryWrapper wrapper) { + return this.selectVoPage(page, wrapper); + } + } diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/service/impl/XzdBxBxsqServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/service/impl/XzdBxBxsqServiceImpl.java index 1f6ab91f..bb6fde13 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/service/impl/XzdBxBxsqServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/bx/bxsq/service/impl/XzdBxBxsqServiceImpl.java @@ -29,9 +29,7 @@ import org.dromara.xzd.bx.bxsq.fymx.service.impl.XzdBxBxsqFymxServiceImpl; import org.dromara.xzd.bx.bxsq.mapper.XzdBxBxsqMapper; import org.dromara.xzd.bx.bxsq.service.IXzdBxBxsqService; import org.dromara.xzd.domain.XzdProject; -import org.dromara.xzd.domain.XzdSupplierOpenBank; import org.dromara.xzd.domain.XzdYhxx; -import org.dromara.xzd.domain.bo.XzdYhxxBo; import org.dromara.xzd.service.impl.XzdProjectServiceImpl; import org.dromara.xzd.service.impl.XzdSupplierOpenBankServiceImpl; import org.dromara.xzd.service.impl.XzdYhxxServiceImpl; @@ -81,7 +79,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl xzdBxBxsqVo1 = List.of(xzdBxBxsqVo); setValue(xzdBxBxsqVo1); @@ -97,6 +95,11 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl queryPageList(XzdBxBxsqBo bo, PageQuery pageQuery) { + //暂时定为只能看见自己的报销 + if (bo.getBxr() == null && !LoginHelper.isSuperAdmin()) { + bo.setBxr(LoginHelper.getUserId()); + } + LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); setValue(result.getRecords()); @@ -164,12 +167,12 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl 0; @@ -177,7 +180,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl ids, Boolean isValid) { - if(isValid){ + if (isValid) { //TODO 做一些业务上的校验,判断是否需要校验 } @@ -300,7 +303,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl 0; } - public void setValue(List vos){ + public void setValue(List vos) { for (XzdBxBxsqVo vo : vos) { //费用明细 LambdaQueryWrapper lqw = new LambdaQueryWrapper<>(); @@ -308,7 +311,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl list = xzdBxBxsqFymxService.list(lqw); //费用明细处理 List voList = new ArrayList<>(); - if (list != null && !list.isEmpty()){ + if (list != null && !list.isEmpty()) { for (XzdBxBxsqFymx fymx : list) { XzdBxBxsqFymxVo fymxVo = new XzdBxBxsqFymxVo(); BeanUtils.copyProperties(fymx, fymxVo); @@ -327,7 +330,7 @@ public class XzdBxBxsqServiceImpl extends ServiceImpl buildQueryWrapper(XzdContractAgreementBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); - lqw.orderByDesc(XzdContractAgreement::getId); + lqw.orderByDesc(XzdContractAgreement::getCreateTime); + lqw.eq(bo.getCompanyId() != null, XzdContractAgreement::getCompanyId, bo.getCompanyId()); lqw.eq(StringUtils.isNotBlank(bo.getContractCode()), XzdContractAgreement::getContractCode, bo.getContractCode()); lqw.like(StringUtils.isNotBlank(bo.getContractName()), XzdContractAgreement::getContractName, bo.getContractName()); lqw.eq(bo.getDocumentDate() != null, XzdContractAgreement::getDocumentDate, bo.getDocumentDate()); diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdContractDetailsServiceImpl.java b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdContractDetailsServiceImpl.java index 850c57af..dde1ca97 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdContractDetailsServiceImpl.java +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/xzd/service/impl/XzdContractDetailsServiceImpl.java @@ -185,6 +185,17 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl 0; if (!flag) { return false; @@ -251,24 +262,6 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl old1 = List.of(old); -// setValue(old1); -// old = old1.getFirst(); - -// if (bo.getSealInfo() != null && !bo.getSealInfo().isEmpty()){ -// if (old.getSealInfo() != null && !old.getSealInfo().isEmpty()){ -// xzdBusinessChangeService.removeByIds(old.getSealInfo()); -// } -// for (XzdBusinessChange businessChange : bo.getSealInfo()) { -// businessChange.setContractChangeId(update.getId()); -// } -// xzdBusinessChangeService.saveBatch(bo.getSealInfo()); -// }else { -// if (old.getSealInfo() != null && !old.getSealInfo().isEmpty()){ -// xzdBusinessChangeService.removeByIds(old.getSealInfo()); -// } -// } - //合同文本-预收款项 if (bo.getYskx() != null && !bo.getYskx().isEmpty()){ if (old.getYskx() != null && !old.getYskx().isEmpty()){ @@ -286,15 +279,6 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); - List nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList(); - for (Long l : oldFileId) { - if (!nowFileId.contains(l)) { - sysOssService.deleteWithValidByIds(List.of(l), false); - } - } - } - }else { - if (old.getFileId()!= null && !old.getFileId().isEmpty()){ - List deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); - sysOssService.deleteWithValidByIds(deleteIds, false); - } - } +// if (bo.getFileId() != null && !bo.getFileId().isEmpty()){ +// if (old.getFileId() != null && !old.getFileId().isEmpty()) { +// List oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); +// List nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList(); +// for (Long l : oldFileId) { +// if (!nowFileId.contains(l)) { +// sysOssService.deleteWithValidByIds(List.of(l), false); +// } +// } +// } +// }else { +// if (old.getFileId()!= null && !old.getFileId().isEmpty()){ +// List deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); +// sysOssService.deleteWithValidByIds(deleteIds, false); +// } +// } validEntityBeforeSave(update); @@ -565,6 +536,11 @@ public class XzdContractDetailsServiceImpl extends ServiceImpl implements IXzdSpykpSpdjService { private final XzdSpykpSpdjMapper baseMapper; @@ -173,44 +178,44 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); - List nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList(); - for (Long l : oldFileId) { - if (!nowFileId.contains(l)) { - sysOssService.deleteWithValidByIds(List.of(l), false); - } - } - } - }else { - if (old.getFileId()!= null && !old.getFileId().isEmpty()){ - List deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); - sysOssService.deleteWithValidByIds(deleteIds, false); - } - } - //发票图片 - if (bo.getFptp() != null){ - if (!bo.getFptp().equals(old.getFptp())){ - sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false); - } - }else { - if (old.getFptp()!= null){ - sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false); - } - } - //证明信息文件 - if (bo.getZmxxwj() != null){ - if (!bo.getZmxxwj().equals(old.getZmxxwj())){ - sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false); - } - }else { - if (old.getZmxxwj()!= null){ - sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false); - } - } +// if (bo.getFileId() != null && !bo.getFileId().isEmpty()){ +// if (old.getFileId() != null && !old.getFileId().isEmpty()) { +// List oldFileId = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); +// List nowFileId = Arrays.stream(bo.getFileId().split(",")).map(Long::valueOf).toList(); +// for (Long l : oldFileId) { +// if (!nowFileId.contains(l)) { +// sysOssService.deleteWithValidByIds(List.of(l), false); +// } +// } +// } +// }else { +// if (old.getFileId()!= null && !old.getFileId().isEmpty()){ +// List deleteIds = Arrays.stream(old.getFileId().split(",")).map(Long::valueOf).toList(); +// sysOssService.deleteWithValidByIds(deleteIds, false); +// } +// } +// //发票图片 +// if (bo.getFptp() != null){ +// if (!bo.getFptp().equals(old.getFptp())){ +// sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false); +// } +// }else { +// if (old.getFptp()!= null){ +// sysOssService.deleteWithValidByIds(List.of(old.getFptp()), false); +// } +// } +// //证明信息文件 +// if (bo.getZmxxwj() != null){ +// if (!bo.getZmxxwj().equals(old.getZmxxwj())){ +// sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false); +// } +// }else { +// if (old.getZmxxwj()!= null){ +// sysOssService.deleteWithValidByIds(List.of(old.getZmxxwj()), false); +// } +// } return baseMapper.updateById(update) > 0; } @@ -269,14 +274,14 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl byid2 = iXzdCorrespondentList.getCustomerByid(vo.getXfId()); - if (byid2 != null) { - if (byid2.getData().getXzdCustomerinformation() != null) { - vo.setXfmc(byid2.getData().getXzdCustomerinformation().getUnitName()); - } - } - } +// if (vo.getXfId() != null){ +// R byid2 = iXzdCorrespondentList.getCustomerByid(vo.getXfId()); +// if (byid2 != null) { +// if (byid2.getData().getXzdCustomerinformation() != null) { +// vo.setXfmc(byid2.getData().getXzdCustomerinformation().getUnitName()); +// } +// } +// } //经办人 if (vo.getJbrId() != null){ SysUserVo sysUserVo = sysUserService.selectUserById(vo.getJbrId()); @@ -308,4 +313,51 @@ public class XzdSpykpSpdjServiceImpl extends ServiceImpl + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/project/BusAttendanceMachineRepeatMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/project/BusAttendanceMachineRepeatMapper.xml new file mode 100644 index 00000000..ec91da9c --- /dev/null +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/project/BusAttendanceMachineRepeatMapper.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdSupplierInfoMapper.xml b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdSupplierInfoMapper.xml index 452d1682..e518752c 100644 --- a/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdSupplierInfoMapper.xml +++ b/xinnengyuan/ruoyi-modules/ruoyi-system/src/main/resources/mapper/xzd/XzdSupplierInfoMapper.xml @@ -8,8 +8,6 @@ SELECT info.id,info.unit_code,info.unit_name,info.unified_social_credit_code, supplement.belonging_organization as sszz, -# settlement.opening_bank as khyh, -# settlement.account_number as khhzh, info.city_code as cityCode, info.shzt as shzt, yhxx.open_bank as khyh, @@ -23,7 +21,6 @@ supplement.responsible_salesman as fgywy, supplement.supplier_status as gyszt, (select ct.customer_type from (select info.id,ti.type,ti.primary_class,ti.customertype_id,info.unit_code from xzd_customertype_info ti left join xzd_supplier_info info on ti.customerinformation_id = info.id and ti.type like '2' where info.id is not NULL) as temp left join xzd_customertype ct on temp.customertype_id = ct.id where temp.id = info.id and temp.primary_class like '1') as gyslx, - # type.customer_type as gyslx, supplement.supplier_level as gysdj, info.is_group_supplier as isGroupSupplier, info.is_blacklist as isBlacklist, @@ -104,9 +101,6 @@ ORDER BY info.create_time DESC - - - diff --git a/xinnengyuan/script/sql/xinnengyuan.sql b/xinnengyuan/script/sql/xinnengyuan.sql index 19c7b5a6..0d6c75df 100644 --- a/xinnengyuan/script/sql/xinnengyuan.sql +++ b/xinnengyuan/script/sql/xinnengyuan.sql @@ -1953,3 +1953,24 @@ CREATE TABLE `ai_chat_memory` INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id' ) comment = 'AI 对话记录信息'; + +DROP TABLE IF EXISTS gps_safety_user_record; +CREATE TABLE `gps_safety_user_record` +( + `id` bigint not null auto_increment comment '主键', + `project_id` bigint not null comment '项目id', + `user_id` bigint not null comment '人员id', + `client_id` varchar(20) not null comment '设备id', + `user_name` varchar(64) null comment '人员名称', + `record_date` date not null comment '记录时间', + `entry_time` datetime null comment '入场时间', + `exit_time` datetime null comment '退场时间', + `remark` varchar(512) null comment '备注', + `create_by` bigint null comment '创建者', + `update_by` bigint null comment '更新者', + `create_dept` bigint null comment '创建部门', + `create_time` datetime default CURRENT_TIMESTAMP null comment '创建时间', + `update_time` datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_user_id` (`user_id` ASC) USING BTREE comment '用户id' +) comment '安全员轨迹信息';