From 8a4374ed5d4ae84ddd9b578fb0ddf79e4efa4ad3 Mon Sep 17 00:00:00 2001 From: lilin <18811154576@163.com> Date: Mon, 13 Jul 2026 13:46:48 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8E=A8=E9=80=81=E9=85=8D=E7=BD=AE=E6=8E=A8?= =?UTF-8?q?=E9=80=81=E5=8E=86=E5=8F=B2=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../platform/config/MyMetaObjectHandler.java | 31 +- .../controller/PushConfigController.java | 142 ++- .../platform/system/domain/PushConfig.java | 13 +- .../domain/PushConfigTargetRequest.java | 10 +- .../domain/PushHistoryDetailStatistics.java | 10 + .../platform/system/domain/PushTargetVo.java | 15 + .../yfd/platform/system/domain/SdWtbhVo.java | 28 + .../mapper/PushHistoryDetailMapper.java | 14 + .../system/service/IPushConfigService.java | 10 +- .../service/IPushHistoryDetailService.java | 1 + .../system/service/ISysRoleService.java | 2 + .../platform/system/service/IUserService.java | 1 + .../service/impl/PushConfigServiceImpl.java | 863 ++++++++++++++++-- .../impl/PushHistoryDetailServiceImpl.java | 13 + .../service/impl/SysRoleServiceImpl.java | 13 + .../system/service/impl/UserServiceImpl.java | 16 + .../java/com/yfd/platform/utils/CronUtil.java | 28 + 17 files changed, 1067 insertions(+), 143 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/system/domain/PushHistoryDetailStatistics.java create mode 100644 backend/src/main/java/com/yfd/platform/system/domain/PushTargetVo.java create mode 100644 backend/src/main/java/com/yfd/platform/system/domain/SdWtbhVo.java create mode 100644 backend/src/main/java/com/yfd/platform/utils/CronUtil.java diff --git a/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java b/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java index 2459da8d..63de20da 100644 --- a/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java +++ b/backend/src/main/java/com/yfd/platform/config/MyMetaObjectHandler.java @@ -24,17 +24,23 @@ public class MyMetaObjectHandler implements MetaObjectHandler { public void insertFill(MetaObject metaObject) { Date now = new Date(); - // 自动填充创建时间 + // 创建时间 this.strictInsertFill(metaObject, "createdAt", Date.class, now); - // 自动填充更新时间 + // 更新时间 this.strictInsertFill(metaObject, "updatedAt", Date.class, now); + // 更新时间 + this.strictInsertFill(metaObject, "modifyTime", Date.class, now); + try { String userId = SecurityUtils.getUserId(); - // 自动填充更新时间 + // 创建人 this.strictInsertFill(metaObject, "createdBy", String.class, userId ); - - // 自动填充更新时间 + //创建人 + this.strictInsertFill(metaObject, "recordUser", String.class, userId ); + // 更新人 + this.strictInsertFill(metaObject, "modifyUser", String.class, userId); + // 更新人 this.strictInsertFill(metaObject, "updatedBy", String.class, userId); } catch (Exception e) { log.info("message{}",e.getMessage()); @@ -47,12 +53,21 @@ public class MyMetaObjectHandler implements MetaObjectHandler { */ @Override public void updateFill(MetaObject metaObject) { - // 自动填充更新时间 - this.strictUpdateFill(metaObject, "updatedAt", Date.class, new Date()); + Date date = new Date(); + // 更新时间 + this.strictUpdateFill(metaObject, "updatedAt", Date.class, date); + // 删除时间 + this.strictUpdateFill(metaObject, "deleteTime", Date.class, date); + // 跟新时间 + this.strictInsertFill(metaObject, "modifyTime", Date.class, date); try { String userId = SecurityUtils.getUserId(); - // 自动填充更新人 + // 更新人 this.strictInsertFill(metaObject, "updatedBy", String.class, userId); + // 删除人 + this.strictInsertFill(metaObject, "deleteUser", String.class, userId); + // 更新人 + this.strictInsertFill(metaObject, "modifyUser", String.class, userId); } catch (Exception e) { log.info("message{}",e.getMessage()); } diff --git a/backend/src/main/java/com/yfd/platform/system/controller/PushConfigController.java b/backend/src/main/java/com/yfd/platform/system/controller/PushConfigController.java index 06a1e4c9..8941aece 100644 --- a/backend/src/main/java/com/yfd/platform/system/controller/PushConfigController.java +++ b/backend/src/main/java/com/yfd/platform/system/controller/PushConfigController.java @@ -4,23 +4,24 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.annotation.Log; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.exception.BizException; import com.yfd.platform.config.ResponseResult; -import com.yfd.platform.system.domain.PushConfig; -import com.yfd.platform.system.domain.PushConfigTargetRequest; -import com.yfd.platform.system.domain.PushHistory; -import com.yfd.platform.system.domain.PushHistoryDetail; -import com.yfd.platform.system.service.IPushConfigService; +import com.yfd.platform.qgc_data.domain.ApprovalMain; +import com.yfd.platform.system.domain.*; +import com.yfd.platform.system.service.*; +import com.yfd.platform.utils.DataSourceRequestUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; + +import static cn.hutool.core.date.DateUtil.parseDate; @RestController @RequestMapping("/system/pushConfig") @@ -30,14 +31,32 @@ public class PushConfigController { @Resource private IPushConfigService pushConfigService; + @Resource + private IUserService userService; + + @Resource + private ISysRoleService roleService; + + @Resource + private IPushHistoryService pushHistoryService; + + @Resource + private IPushHistoryDetailService pushHistoryDetailService; + + + @Operation(summary = "查询推送配置列表") - @GetMapping("/getPushConfigList") - public ResponseResult getPushConfigList(Page page, - String categoryName, - String messageType, - Integer targetType, - Integer status) { - return ResponseResult.successData(pushConfigService.getPushConfigPage(page, categoryName, messageType, targetType, status)); + @PostMapping("/getPushConfigList") + public ResponseResult getPushConfigList(@RequestBody DataSourceRequest request) { + + Page pushConfigPage = DataSourceRequestUtil.executeQuery(request, PushConfig.class, pushConfigService); + return ResponseResult.successData(pushConfigPage); + +// String categoryName = null; +// String messageType = null; +// Integer targetType = null; +// Integer status = null; +// return ResponseResult.successData(pushConfigService.getPushConfigPage(page, categoryName, messageType, targetType, status)); } @Operation(summary = "根据ID查询推送配置") @@ -63,7 +82,7 @@ public class PushConfigController { @Log(module = "推送配置", value = "删除推送配置") @Operation(summary = "删除推送配置") @PostMapping("/deletePushConfig") - public ResponseResult deletePushConfig(@RequestParam String ids) { + public ResponseResult deletePushConfig(@RequestBody List ids) { return pushConfigService.deletePushConfig(ids) ? ResponseResult.success() : ResponseResult.error("删除失败"); } @@ -102,23 +121,78 @@ public class PushConfigController { } @Operation(summary = "查询推送历史主表") - @GetMapping("/getPushHistoryList") - public ResponseResult getPushHistoryList(Page page, - String configId, - Integer status, - String messageTypeCode, - String startTime, - String endTime) { - Date start = StrUtil.isBlank(startTime) ? null : DateUtil.parse(startTime); - Date end = StrUtil.isBlank(endTime) ? null : DateUtil.parse(endTime); - return ResponseResult.successData(pushConfigService.getPushHistoryPage(page, configId, status, messageTypeCode, start, end)); + @PostMapping("/postPushHistoryList") + public ResponseResult getPushHistoryList(@RequestBody DataSourceRequest request) { + // 1. 预处理日期过滤器 + List filters = request.getFilter().getFilters(); + for (DataSourceRequest.FilterDescriptor filter : filters) { + String field = filter.getField(); + // 判断是否为日期字段(根据你的实体字段名) + if (isDateField(field)) { + Object value = filter.getValue(); + if (value != null) { + String strValue = value.toString(); + if (StrUtil.isNotBlank(strValue)) { + Date dateValue = parseDate(strValue); + // 关键:将转换后的 Date 对象重新设置回 filter + filter.setValue(dateValue); + } + } + } + } + + // 2. 调用通用查询 + Page pushHistoryPage = DataSourceRequestUtil.executeQuery(request, PushHistory.class, pushHistoryService); + return ResponseResult.successData(pushHistoryPage); + } + + // 辅助方法:判断字段是否为日期类型(根据你的实体类字段名) + private boolean isDateField(String field) { + // 这些字段在 PushHistory 中都是 Date 类型 + return "planTime".equals(field) + || "createdAt".equals(field) + || "updatedAt".equals(field) + || "modifyTime".equals(field) + || "deleteTime".equals(field); + } + + // 辅助方法:解析日期字符串 + private Date parseDate(String dateStr) { + try { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr); + } catch (ParseException e) { + throw new BizException("日期格式错误,请使用 yyyy-MM-dd HH:mm:ss 格式: " + dateStr); + } } @Operation(summary = "查询推送历史明细") - @GetMapping("/getPushHistoryDetailList") - public ResponseResult getPushHistoryDetailList(Page page, - String historyId, - Integer status) { - return ResponseResult.successData(pushConfigService.getPushHistoryDetailPage(page, historyId, status)); + @PostMapping("/getPushHistoryDetailList") + public ResponseResult getPushHistoryDetailList(@RequestBody DataSourceRequest request) { + Page pushHistoryDetailPage = DataSourceRequestUtil.executeQuery(request, PushHistoryDetail.class, pushHistoryDetailService); + return ResponseResult.successData(pushHistoryDetailPage); + } + + @GetMapping("/queryUsersList") + @Operation(summary = "查询状态正常的用户列表") + @ResponseBody + public ResponseResult queryUsersList( @RequestParam(value = "name", required = false) String name,@RequestHeader(value = "Tenant_id", required = false) String tenantId) { + + List sysUserList = userService.queryUsersList(name,StrUtil.trimToNull(tenantId)); + return ResponseResult.successData(sysUserList); + } + + + @Operation(summary = "根据historyId查推送历史明细详情") + @GetMapping("/getPushHistoryDetailById") + public ResponseResult getPushHistoryDetailById(@RequestParam String historyId) { + return ResponseResult.successData(pushHistoryDetailService.getPushHistoryDetailById(historyId)); + } + + @GetMapping("/queryRolesList") + @Operation(summary = "查询角色类型列表") + @ResponseBody + public ResponseResult queryRolesList( @RequestParam(value = "roleName", required = false) String roleName,@RequestHeader(value = "Tenant_id", required = false) String tenantId) { + List sysRoleList = roleService.queryRolesList(roleName,StrUtil.trimToNull(tenantId)); + return ResponseResult.successData(sysRoleList); } } diff --git a/backend/src/main/java/com/yfd/platform/system/domain/PushConfig.java b/backend/src/main/java/com/yfd/platform/system/domain/PushConfig.java index 5c4bd18a..93cbb56e 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/PushConfig.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/PushConfig.java @@ -1,8 +1,6 @@ package com.yfd.platform.system.domain; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.io.Serializable; @@ -15,6 +13,7 @@ public class PushConfig implements Serializable { private static final long serialVersionUID = 1L; @TableId(type = IdType.ASSIGN_UUID) + @TableField("ID") private String id; private String categoryCode; @@ -41,16 +40,20 @@ public class PushConfig implements Serializable { private Integer status; + @TableField(fill = FieldFill.INSERT) private Date createdAt; - private Date updatedAt; - + @TableField(fill = FieldFill.INSERT) private String recordUser; + @TableField(fill = FieldFill.UPDATE) private String modifyUser; + @TableField(fill = FieldFill.INSERT_UPDATE) private Date modifyTime; + /** 是否已删除:0=未删除 1=已删除 */ + @TableField("IS_DELETED") private Integer isDeleted; private String deleteUser; diff --git a/backend/src/main/java/com/yfd/platform/system/domain/PushConfigTargetRequest.java b/backend/src/main/java/com/yfd/platform/system/domain/PushConfigTargetRequest.java index 9f4adf4f..62beac83 100644 --- a/backend/src/main/java/com/yfd/platform/system/domain/PushConfigTargetRequest.java +++ b/backend/src/main/java/com/yfd/platform/system/domain/PushConfigTargetRequest.java @@ -12,10 +12,16 @@ public class PushConfigTargetRequest implements Serializable { private String configId; +// /** +// * 0-用户,1-角色 +// */ +// private Integer type; + /** - * 0-用户,1-角色 + * 1-所有人,2-按人,3-按角色 */ - private Integer type; + private Integer targetType; + private List userRoleIds; } diff --git a/backend/src/main/java/com/yfd/platform/system/domain/PushHistoryDetailStatistics.java b/backend/src/main/java/com/yfd/platform/system/domain/PushHistoryDetailStatistics.java new file mode 100644 index 00000000..1797d0bf --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/PushHistoryDetailStatistics.java @@ -0,0 +1,10 @@ +package com.yfd.platform.system.domain; + +import lombok.Data; + +@Data +public class PushHistoryDetailStatistics { + private Integer pendingCount; // 待推送(0) + private Integer successCount; // 成功(1) + private Integer failCount; // 失败(2) +} diff --git a/backend/src/main/java/com/yfd/platform/system/domain/PushTargetVo.java b/backend/src/main/java/com/yfd/platform/system/domain/PushTargetVo.java new file mode 100644 index 00000000..268e1aa9 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/PushTargetVo.java @@ -0,0 +1,15 @@ +package com.yfd.platform.system.domain; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class PushTargetVo implements Serializable { + + private Integer targetType; + + private List userRoleIds; + private List pushConfigTargetVoList; +} diff --git a/backend/src/main/java/com/yfd/platform/system/domain/SdWtbhVo.java b/backend/src/main/java/com/yfd/platform/system/domain/SdWtbhVo.java new file mode 100644 index 00000000..88b92a7e --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/system/domain/SdWtbhVo.java @@ -0,0 +1,28 @@ +package com.yfd.platform.system.domain; + +import lombok.Data; + +import java.io.Serializable; +@Data +public class SdWtbhVo implements Serializable{ + + + + private static final long serialVersionUID = 1L; + + private String stcd; + + private String stnm; + + private String baseId; + + private String baseName; + + private String sttpCode; + + private String sttpName; + + private String rstcd; + + private String warnState; + } diff --git a/backend/src/main/java/com/yfd/platform/system/mapper/PushHistoryDetailMapper.java b/backend/src/main/java/com/yfd/platform/system/mapper/PushHistoryDetailMapper.java index 9ac4f8ca..f899cfd3 100644 --- a/backend/src/main/java/com/yfd/platform/system/mapper/PushHistoryDetailMapper.java +++ b/backend/src/main/java/com/yfd/platform/system/mapper/PushHistoryDetailMapper.java @@ -2,6 +2,20 @@ package com.yfd.platform.system.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.yfd.platform.system.domain.PushHistoryDetail; +import com.yfd.platform.system.domain.PushHistoryDetailStatistics; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import java.util.List; +import java.util.Map; +@Mapper public interface PushHistoryDetailMapper extends BaseMapper { + @Select("SELECT " + + "COUNT(CASE WHEN STATUS = 0 THEN 1 END) AS pendingCount, " + + "COUNT(CASE WHEN STATUS = 1 THEN 1 END) AS successCount, " + + "COUNT(CASE WHEN STATUS = 2 THEN 1 END) AS failCount " + + "FROM PUSH_HISTORY_DETAIL " + + "WHERE HISTORY_ID = #{historyId}") + PushHistoryDetailStatistics countByHistoryId(@Param("historyId") String historyId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/IPushConfigService.java b/backend/src/main/java/com/yfd/platform/system/service/IPushConfigService.java index d103ee2d..7e9b513e 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IPushConfigService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IPushConfigService.java @@ -2,11 +2,7 @@ package com.yfd.platform.system.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; -import com.yfd.platform.system.domain.PushConfig; -import com.yfd.platform.system.domain.PushConfigTargetRequest; -import com.yfd.platform.system.domain.PushConfigTargetVo; -import com.yfd.platform.system.domain.PushHistory; -import com.yfd.platform.system.domain.PushHistoryDetail; +import com.yfd.platform.system.domain.*; import java.util.Date; import java.util.List; @@ -23,7 +19,7 @@ public interface IPushConfigService extends IService { boolean updatePushConfig(PushConfig pushConfig); - boolean deletePushConfig(String ids); + boolean deletePushConfig(List ids); boolean setPushConfigStatus(String id, Integer status); @@ -31,7 +27,7 @@ public interface IPushConfigService extends IService { boolean savePushTargets(PushConfigTargetRequest request); - List getPushTargets(String configId); + PushTargetVo getPushTargets(String configId); Page getPushHistoryPage(Page page, String configId, diff --git a/backend/src/main/java/com/yfd/platform/system/service/IPushHistoryDetailService.java b/backend/src/main/java/com/yfd/platform/system/service/IPushHistoryDetailService.java index dfc002a4..7152220d 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IPushHistoryDetailService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IPushHistoryDetailService.java @@ -4,4 +4,5 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.yfd.platform.system.domain.PushHistoryDetail; public interface IPushHistoryDetailService extends IService { + Object getPushHistoryDetailById(String historyId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java b/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java index 36f25dec..244983bf 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/ISysRoleService.java @@ -65,4 +65,6 @@ public interface ISysRoleService extends IService { boolean setMenuById(String id, String menuIds); List selectRoleList(String rolename, String tenantId); + + List queryRolesList(String roleName, String tenantId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java index d9f12b89..863fa04c 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/IUserService.java +++ b/backend/src/main/java/com/yfd/platform/system/service/IUserService.java @@ -183,4 +183,5 @@ public interface IUserService extends IService { ************************************/ Page queryPendingAuditUsers(Page page, String name, String regStatus, String tenantId); + List queryUsersList(String name, String tenantId); } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/PushConfigServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/PushConfigServiceImpl.java index bdc51b55..1932cdaa 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/PushConfigServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/PushConfigServiceImpl.java @@ -6,15 +6,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.exception.BizException; -import com.yfd.platform.system.domain.PushConfig; -import com.yfd.platform.system.domain.PushConfigTargetRequest; -import com.yfd.platform.system.domain.PushConfigTargetVo; -import com.yfd.platform.system.domain.PushConfigUser; -import com.yfd.platform.system.domain.PushHistory; -import com.yfd.platform.system.domain.PushHistoryDetail; -import com.yfd.platform.system.domain.PushTargetUserVo; -import com.yfd.platform.system.domain.QuartzJob; +import com.yfd.platform.system.domain.*; import com.yfd.platform.system.mapper.PushConfigMapper; import com.yfd.platform.system.mapper.PushConfigUserMapper; import com.yfd.platform.system.service.IPushConfigService; @@ -22,27 +16,27 @@ import com.yfd.platform.system.service.IPushConfigUserService; import com.yfd.platform.system.service.IPushHistoryDetailService; import com.yfd.platform.system.service.IPushHistoryService; import com.yfd.platform.system.service.IQuartzJobService; +import com.yfd.platform.utils.CronUtil; import com.yfd.platform.utils.QuartzManage; import com.yfd.platform.utils.SecurityUtils; +import com.yfd.platform.utils.SmsSender; import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.annotations.Param; import org.quartz.CronExpression; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; +import java.util.stream.Collectors; @Service +@Slf4j public class PushConfigServiceImpl extends ServiceImpl implements IPushConfigService { private static final String QUARTZ_BIZ_TYPE = "PUSH_CONFIG"; - private static final String DEFAULT_SEND_CHANNEL = "SMS"; + private static final String DEFAULT_SEND_CHANNEL = "短信推送"; private static final String DEFAULT_SOURCE = "PUSH_CONFIG"; @Resource @@ -63,6 +57,12 @@ public class PushConfigServiceImpl extends ServiceImpl getPushConfigPage(Page page, String categoryName, @@ -75,7 +75,7 @@ public class PushConfigServiceImpl extends ServiceImpl ids) { + if (ids.isEmpty()) { throw new BizException("参数不能为空."); } Date now = new Date(); String userId = currentUserIdOrSystem(); - for (String id : ids.split(",")) { + for (String id : ids) { String configId = StrUtil.trim(id); if (StrUtil.isBlank(configId)) { continue; } - PushConfig config = getAvailableConfig(configId); - config.setIsDeleted(1); - config.setDeleteUser(userId); - config.setDeleteTime(now); - config.setModifyUser(userId); - config.setModifyTime(now); - config.setUpdatedAt(now); - this.updateById(config); + this.removeById(configId); softDeleteTargets(configId, userId, now); deleteQuartzJob(configId); } @@ -162,9 +154,9 @@ public class PushConfigServiceImpl extends ServiceImpl updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(PushConfig::getTargetType,request.getTargetType()); + updateWrapper.eq(PushConfig::getId,request.getConfigId()); + Boolean update = this.update(updateWrapper); if (request.getUserRoleIds() == null || request.getUserRoleIds().isEmpty()) { return true; } + int type = 0; + //如果是所有人或者按人 + if(request.getTargetType() ==3 ){ + type = 1; + } List list = new ArrayList<>(); for (String userRoleId : request.getUserRoleIds()) { String targetId = StrUtil.trim(userRoleId); @@ -213,12 +215,12 @@ public class PushConfigServiceImpl extends ServiceImpl getPushTargets(String configId) { + public PushTargetVo getPushTargets(String configId) { if (StrUtil.isBlank(configId)) { - return Collections.emptyList(); + return (PushTargetVo) Collections.emptyList(); } - return pushConfigUserMapper.selectConfigTargets(configId); + PushConfig config = getAvailableConfig(configId); + + PushTargetVo pushTargetVo = new PushTargetVo(); + List pushConfigTargetVoList = pushConfigUserMapper.selectConfigTargets(configId); + List userRoleIds = new ArrayList<>(); + + if(pushConfigTargetVoList.size()>0){ + + for (PushConfigTargetVo pushConfigTargetVo : pushConfigTargetVoList) { + userRoleIds.add(pushConfigTargetVo.getUserRoleId()); + } + + } + pushTargetVo.setTargetType(config.getTargetType()); + pushTargetVo.setUserRoleIds(userRoleIds); + //pushTargetVo.setPushConfigTargetVoList(pushConfigTargetVoList); + return pushTargetVo; } @Override @@ -273,17 +291,24 @@ public class PushConfigServiceImpl extends ServiceImpl targets = resolveTargets(config); Date now = new Date(); String operator = currentUserIdOrSystem(); + // 1. 生成推送内容 + String content = generatePushContent(config); + boolean contentSuccess = StrUtil.isNotBlank(content); + + // 2. 解析推送目标 + List targets = resolveTargets(config); + + // 3. 创建推送历史主表 PushHistory history = new PushHistory(); history.setConfigId(config.getId()); history.setPlanTime(now); history.setMessageTypeCode(config.getCategoryCode()); history.setMessageTypeName(config.getCategoryName()); history.setTitle(buildDefaultTitle(config)); - history.setContent(buildDefaultContent(config)); + history.setContent(contentSuccess ? content : "内容生成失败"); history.setPushedCount(0L); history.setSuccessCount(0L); history.setFailCount(0L); @@ -300,6 +325,34 @@ public class PushConfigServiceImpl extends ServiceImpl detailList = new ArrayList<>(); + for (PushTargetUserVo target : targets) { + PushHistoryDetail detail = new PushHistoryDetail(); + detail.setHistoryId(history.getId()); + detail.setTargetName(target.getTargetName()); + detail.setTargetPhone(target.getTargetPhone()); + detail.setStatus(2); + detail.setSendChannel(DEFAULT_SEND_CHANNEL); + detail.setErrorMsg("推送内容生成失败"); + detail.setCreatedAt(now); + detail.setRecordUser(operator); + detail.setModifyUser(operator); + detail.setModifyTime(now); + detail.setIsDeleted(0); + detailList.add(detail); + } + pushHistoryDetailService.saveBatch(detailList); + } + history.setStatus(3); + history.setFailCount((long) targets.size()); + pushHistoryService.updateById(history); + return; + } + + // 5. 创建推送明细(初始状态为待推送) if (!targets.isEmpty()) { List detailList = new ArrayList<>(); for (PushTargetUserVo target : targets) { @@ -317,60 +370,642 @@ public class PushConfigServiceImpl extends ServiceImpl + * 示例:
+ * 【大渡河干流】:监测站共37个,16个数据正常,21个数据中断超3天,0个无数据;
+ * 视频监控站共92个,22个在线,70个离线; + * + * @param config 推送配置 + * @return 推送内容文本,失败返回 null + */ + private String generatePushContent(PushConfig config) { + try { + // ----- 1. 解析普通基地列表 ----- + String baseIdStr = config.getBaseIdList(); + String baseNameStr = config.getBaseNameList(); + if (StrUtil.isBlank(baseIdStr) || StrUtil.isBlank(baseNameStr)) { + log.warn("基地ID或名称列表为空,无法生成推送内容"); + return null; + } + + List baseIdList = Arrays.stream(baseIdStr.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toList()); + List baseNameList = Arrays.stream(baseNameStr.split(",")) + .map(String::trim) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toList()); + + if (baseIdList.size() != baseNameList.size()) { + log.error("基地ID和名称数量不一致,ID数量={}, 名称数量={}", baseIdList.size(), baseNameList.size()); + return null; + } + + // 构建有序映射 + List baseInfoList = new ArrayList<>(); + for (int i = 0; i < baseIdList.size(); i++) { + baseInfoList.add(new BaseInfo(baseIdList.get(i), baseNameList.get(i))); + } + + // ----- 2. 查询普通基地数据(所有 baseId) ----- + Map normalParam = new HashMap<>(); + // 监测站数据(WT+WQ+ZQ) + List normalMonitor = new ArrayList<>(); + if (!baseIdList.isEmpty()) { + normalMonitor.addAll(queryList(buildWTSql(baseIdList, normalParam), normalParam)); + normalMonitor.addAll(queryList(buildWQSql(baseIdList, normalParam), normalParam)); + //normalMonitor.addAll(queryList(buildZQSql(baseIdList, normalParam), normalParam)); + } + // 视频监控数据(VD) + List normalVideo = new ArrayList<>(); + if (!baseIdList.isEmpty()) { + normalVideo.addAll(queryList(buildVDSql(baseIdList, normalParam), normalParam)); + } + + // ----- 3. 查询特殊基地数据(丰满、DB)----- + // 丰满 + Map fmParam = new HashMap<>(); + List fmMonitor = querySpecialMonitor("008610902100000001", fmParam); + List fmVideo = querySpecialVideo("008610902100000001", fmParam); + + // DB + Map dbParam = new HashMap<>(); + List dbMonitor = querySpecialMonitor("008690900800000001", dbParam); + List dbVideo = querySpecialVideo("008690900800000001", dbParam); + + // ----- 4. 构建最终文本 ----- + StringBuilder content = new StringBuilder(); + // 头部 实际已经自带了 + // content.append("【水电水利规划设计总院】\n"); + + // 4.1 普通基地(按 baseInfoList 顺序) + for (BaseInfo baseInfo : baseInfoList) { + String baseId = baseInfo.baseId; + String baseName = baseInfo.baseName; + // 生成该基地的文本,从普通数据中按 baseId 过滤 + String text = buildStationText(baseName, normalMonitor, normalVideo, baseId); + content.append(text); + } + + // 4.2 特殊基地(丰满、DB,固定顺序) + content.append(buildStationText("丰满", fmMonitor, fmVideo, null)); + content.append(buildStationText("DB", dbMonitor, dbVideo, null)); + + return content.toString(); + + } catch (Exception e) { + log.error("生成推送内容失败,configId={}", config.getId(), e); + return null; } } - private void validatePushTargetRequest(PushConfigTargetRequest request) { - if (request == null) { - throw new BizException("参数不能为空."); - } - if (StrUtil.isBlank(request.getConfigId())) { - throw new BizException("推送配置ID不能为空."); - } - if (request.getType() == null || (request.getType() != 0 && request.getType() != 1)) { - throw new BizException("绑定类型不正确."); +// ---------- 辅助方法 ---------- + + /** + * 查询特殊基地的监测站(WT+WQ,若有需要可加ZQ) + */ + private List querySpecialMonitor(String rstcd, Map paramMap) { + List list = new ArrayList<>(); + list.addAll(queryList(buildWTSqlByRstcd(rstcd, paramMap), paramMap)); + list.addAll(queryList(buildWQSqlByRstcd(rstcd, paramMap), paramMap)); + // 如果特殊基地也有ZQ,可取消注释下面一行 + // list.addAll(queryList(buildZQSqlByRstcd(rstcd, paramMap), paramMap)); + return list; + } + + /** + * 查询特殊基地的视频监控(VD) + */ + private List querySpecialVideo(String rstcd, Map paramMap) { + return queryList(buildVDSqlByRstcd(rstcd, paramMap), paramMap); + } + + /** + * 执行查询,返回列表(异常时返回空列表) + */ + private List queryList(String sql, Map paramMap) { + try { + return microservicDynamicSQLMapper.pageAllListWithResultType( + null, sql, paramMap, SdWtbhVo.class + ); + } catch (Exception e) { + log.error("执行SQL查询失败,sql={}", sql, e); + return Collections.emptyList(); } } - private void validateTargetTypeMatch(Integer targetType, Integer relationType) { - if (targetType == null) { - return; + /** + * 统计并生成单个基地的文本(监测站+视频监控) + * @param baseName 基地名称 + * @param monitorList 该基地所在的所有监测站数据(可能包含多个基地) + * @param videoList 该基地所在的所有视频监控数据(可能包含多个基地) + * @param baseId 若不为空,则从列表中过滤该 baseId;若为空,则使用整个列表(用于特殊基地) + */ + private String buildStationText(String baseName, List monitorList, + List videoList, String baseId) { + // 过滤 baseId(如果指定) + List filteredMonitor = filterByBaseId(monitorList, baseId); + List filteredVideo = filterByBaseId(videoList, baseId); + + // 统计监测站 + Map monitorStats = countByWarnState(filteredMonitor); + long totalMonitor = filteredMonitor.size(); + long normalMonitor = monitorStats.getOrDefault(1, 0L); + long abnormalMonitor = monitorStats.getOrDefault(2, 0L); + long noDataMonitor = monitorStats.getOrDefault(0, 0L); + + // 统计视频监控(在线=1,离线=0+2 或其它非在线状态) + Map videoStats = countByWarnState(filteredVideo); + long totalVideo = filteredVideo.size(); + long onlineVideo = videoStats.getOrDefault(1, 0L); + long offlineVideo = totalVideo - onlineVideo; // 离线 = 总 - 在线 + + return StrUtil.format("[{}]:监测站共{}个,{}个数据正常,{}个数据中断超3天,{}个无数据;视频监控站共{}个,{}个在线,{}个离线;\n", + baseName, totalMonitor, normalMonitor, abnormalMonitor, noDataMonitor, + totalVideo, onlineVideo, offlineVideo); + } + + /** + * 按 baseId 过滤列表(若 baseId 为空,则返回原列表) + */ + private List filterByBaseId(List list, String baseId) { + if (StrUtil.isBlank(baseId)) { + return list; } - if (targetType == 1) { - throw new BizException("当前配置为所有人推送,无需绑定目标."); - } - if (targetType == 2 && !Objects.equals(relationType, 0)) { - throw new BizException("按人推送只能绑定用户."); - } - if (targetType == 3 && !Objects.equals(relationType, 1)) { - throw new BizException("按角色推送只能绑定角色."); + return list.stream() + .filter(vo -> baseId.equals(vo.getBaseId())) + .collect(Collectors.toList()); + } + + /** + * 统计各 warnState 的数量(0=无数据,1=正常,2=异常) + */ + private Map countByWarnState(List list) { + return list.stream() + .collect(Collectors.groupingBy( + vo -> { + String state = vo.getWarnState(); + if (StrUtil.isBlank(state)) { + return 0; // 默认当作无数据 + } + try { + return Integer.parseInt(state); + } catch (NumberFormatException e) { + return 0; + } + }, + Collectors.counting() + )); + } + + // ---------- 内部类 ---------- + private static class BaseInfo { + String baseId; + String baseName; + BaseInfo(String baseId, String baseName) { + this.baseId = baseId; + this.baseName = baseName; } } + /** + * 拼接 LIKE 模糊查询条件(自动加 %) + * @param sql SQL 构建器 + * @param paramMap 参数容器 + * @param column 列名(如 "sd.RSTCD") + * @param value 查询值(如 "008610902100000001"),可为空 + * @param paramKey 参数键名(如 "rstcd") + */ + private void appendLikeCondition(StringBuilder sql, Map paramMap, + String column, String value, String paramKey) { + if (StrUtil.isBlank(value)) { + return; // 不拼接条件 + } + paramMap.put(paramKey, "%" + value.trim() + "%"); + sql.append("AND ").append(column).append(" LIKE #{map.").append(paramKey).append("} "); + } + + /** + * 拼接 IN 条件,支持动态参数列表 + * @param sql SQL 构建器 + * @param paramMap 参数容器(用于 MyBatis 预编译) + * @param column 列名(如 "sd.BASE_ID") + * @param values 参数值列表(不能为 null,但可为空) + * @param paramPrefix 参数前缀(如 "baseId"),用于生成占位符名称 + */ + private void appendInCondition(StringBuilder sql, Map paramMap, + String column, List values, String paramPrefix) { + if (values == null || values.isEmpty()) { + return; // 不拼接任何条件 + } + sql.append("AND ").append(column).append(" IN ("); + for (int i = 0; i < values.size(); i++) { + String paramKey = paramPrefix + i; + paramMap.put(paramKey, values.get(i).trim()); + sql.append("#{map.").append(paramKey).append("}"); + if (i < values.size() - 1) { + sql.append(", "); + } + } + sql.append(") "); + } + + /** + * 构建 WT 类型(水文站)查询 SQL + * @param baseIdList 基地ID,可为空 + * @param paramMap 参数容器 + * @return SQL 字符串 + */ + private String buildWTSql(List baseIdList, Map paramMap) { + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'WT' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_WT_B_H sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + // 动态 IN 条件(若列表为空,则不拼接) + appendInCondition(sql, paramMap, "sd.BASE_ID", baseIdList, "baseId"); + + // 固定条件 + sql.append("AND sd.STTP IN ('WTRV', 'WTVT') ") + .append("AND sd.MWAY = 2 ") + .append("AND sd.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY sd.BASE_ID"); + + return sql.toString(); + } + + /** + * 构建 WQ 类型(水质站)查询 SQL + */ + private String buildWQSql(List baseIdList, Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'WQ' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_WQ_B_H sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + appendInCondition(sql, paramMap, "sd.BASE_ID", baseIdList, "baseId"); + + sql.append("AND sd.STTP IN ('WQFB', 'WQ') ") + .append("AND sd.DTIN_TYPE = 0 ") + .append("AND sd.MWAY = 2 ") + .append("AND sd.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY sd.BASE_ID"); + + return sql.toString(); + } + + /** + * 构建 VD 类型(视频监控 + 声纳)查询 SQL,包含 UNION ALL + *

注意:第二部分原SQL中错误地使用了 sd.WARN_STATE,现修正为 sn.WARN_STATE

+ */ + private String buildVDSql(List baseIdList, Map paramMap) { + StringBuilder sql = new StringBuilder(); + + // ------ 第一部分:视频监控表 SD_VDINFO_B ------ + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'VD' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_VDINFO_B sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + // 使用不同前缀避免与第二部分冲突 + appendInCondition(sql, paramMap, "sd.BASE_ID", baseIdList, "vdBaseId"); + + sql.append("AND sd.STTP LIKE 'VD%' ") + .append("AND sd.DTIN = 1 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 "); + + // ------ UNION ALL ------ + sql.append("UNION ALL "); + + // ------ 第二部分:声纳表 SD_SONAR_B_H ------ + sql.append("SELECT sn.STCD AS stcd, ") + .append("sn.STNM AS stnm, ") + .append("sn.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'VD' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sn.RSTCD AS rstcd, ") + .append("sn.WARN_STATE AS warnState ") // 修正:原为 sd.WARN_STATE → sn.WARN_STATE + .append("FROM SD_SONAR_B_H sn ") + .append("LEFT JOIN SD_HYDROBASE sh ON sn.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sn.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + // 使用不同前缀,与第一部分区分 + appendInCondition(sql, paramMap, "sn.BASE_ID", baseIdList, "snBaseId"); + + sql.append("AND sn.STTP LIKE 'VD%' ") + .append("AND sn.MWAY = 2 ") + .append("AND sn.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY baseId"); // 整个 UNION 结果排序 + + return sql.toString(); + } + + /** + * 构建 ZQ 类型(流量/水情站)查询 SQL + */ + private String buildZQSql(List baseIdList, Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'ZQ' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_RIVER_B_H sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + appendInCondition(sql, paramMap, "sd.BASE_ID", baseIdList, "baseId"); + + sql.append("AND sd.STTP IN ('ZQ') ") + .append("AND sd.DTIN_TYPE = 0 ") + .append("AND sd.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY sd.BASE_ID"); + + return sql.toString(); + } + + + + + /** + * 构建 WT 类型(水文站)查询 SQL,按 RSTCD 模糊查询 + * @param rstcd RSTCD 值(如 "008610902100000001") + * @param paramMap 参数容器 + * @return SQL 字符串 + */ + private String buildWTSqlByRstcd(String rstcd, Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'WT' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_WT_B_H sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + // 动态 LIKE 条件 + appendLikeCondition(sql, paramMap, "sd.RSTCD", rstcd, "rstcd"); + + // 固定条件 + sql.append("AND sd.STTP IN ('WTRV', 'WTVT') ") + .append("AND sd.MWAY = 2 ") + .append("AND sd.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY sd.BASE_ID"); + + return sql.toString(); + } + + /** + * 构建 WQ 类型(水质站)查询 SQL,按 RSTCD 模糊查询 + */ + private String buildWQSqlByRstcd(String rstcd, Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'WQ' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_WQ_B_H sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + appendLikeCondition(sql, paramMap, "sd.RSTCD", rstcd, "rstcd"); + + sql.append("AND sd.STTP IN ('WQFB', 'WQ') ") + .append("AND sd.DTIN_TYPE = 0 ") + .append("AND sd.MWAY = 2 ") + .append("AND sd.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY sd.BASE_ID"); + + return sql.toString(); + } + + /** + * 构建 VD 类型(视频监控 + 声纳)查询 SQL,按 RSTCD 模糊查询,包含 UNION ALL + */ + private String buildVDSqlByRstcd(String rstcd, Map paramMap) { + StringBuilder sql = new StringBuilder(); + + // ------ 第一部分:视频监控表 SD_VDINFO_B ------ + sql.append("SELECT sd.STCD AS stcd, ") + .append("sd.STNM AS stnm, ") + .append("sd.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'VD' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sd.RSTCD AS rstcd, ") + .append("sd.WARN_STATE AS warnState ") + .append("FROM SD_VDINFO_B sd ") + .append("LEFT JOIN SD_HYDROBASE sh ON sd.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sd.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + // 使用不同参数键,避免冲突 + appendLikeCondition(sql, paramMap, "sd.RSTCD", rstcd, "vdRstcd"); + + sql.append("AND sd.STTP LIKE 'VD%' ") + .append("AND sd.DTIN = 1 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 "); + + // ------ UNION ALL ------ + sql.append("UNION ALL "); + + // ------ 第二部分:声纳表 SD_SONAR_B_H ------ + sql.append("SELECT sn.STCD AS stcd, ") + .append("sn.STNM AS stnm, ") + .append("sn.BASE_ID AS baseId, ") + .append("sh.BASENAME AS baseName, ") + .append("'VD' AS sttpCode, ") + .append("ss.STTP_NAME AS sttpName, ") + .append("sn.RSTCD AS rstcd, ") + .append("sn.WARN_STATE AS warnState ") + .append("FROM SD_SONAR_B_H sn ") + .append("LEFT JOIN SD_HYDROBASE sh ON sn.BASE_ID = sh.BASEID ") + .append("LEFT JOIN SD_STTP_B ss ON sn.STTP = ss.STTP_CODE ") + .append("WHERE 1=1 "); + + // 使用不同参数键 + appendLikeCondition(sql, paramMap, "sn.RSTCD", rstcd, "snRstcd"); + + sql.append("AND sn.STTP LIKE 'VD%' ") + .append("AND sn.MWAY = 2 ") + .append("AND sn.IS_DELETED = 0 ") + .append("AND sh.IS_DELETED = 0 ") + .append("AND ss.IS_DELETED = 0 ") + .append("ORDER BY baseId"); + + return sql.toString(); + } + + + + + + + + + + + + + + + + + /** + * 发送短信(占位,后续接入真实短信服务) + * + * @param phone 手机号 + * @param content 短信内容 + * @return true=成功 false=失败 + */ + private boolean sendSms(String phone, String content) { + // TODO: 后续接入真实短信服务(如阿里云短信、腾讯云短信等) + // 暂时模拟发送,后续替换为真实调用 + try { + return true; + } catch (Exception e) { + return false; + } + } + + + /** + * 更新推送配置的推送次数 + *

+ * dailyPushCount:当日推送成功次数(按人去重后的成功人数) + * pushCount:累计推送成功次数 + * finishTime:当日时间(年月日) + * + * @param config 推送配置 + * @param successCount 本次成功推送人数 + * @param now 当前时间 + */ + private void updatePushConfigCount(PushConfig config, long successCount, Date now) { + String today = DateUtil.formatDate(now); + Date finishTime = config.getFinishTime(); + String lastFinishDate = finishTime == null ? null : DateUtil.formatDate(finishTime); + + Long dailyCount; + if (today.equals(lastFinishDate)) { + // 同一天,累加 + dailyCount = (config.getDailyPushCount() == null ? 0L : config.getDailyPushCount()) + successCount; + } else { + // 新的一天,重置 + dailyCount = successCount; + } + + Long totalCount = (config.getPushCount() == null ? 0L : config.getPushCount()) + successCount; + + config.setDailyPushCount(dailyCount); + config.setPushCount(totalCount); + config.setFinishTime(now); + config.setModifyTime(now); + this.updateById(config); + } + + private PushConfig getAvailableConfig(String id) { List list = this.list(new LambdaQueryWrapper() .eq(PushConfig::getId, id) @@ -508,4 +1143,58 @@ public class PushConfigServiceImpl extends ServiceImpl implements IPushHistoryDetailService { + @Autowired + private PushHistoryDetailMapper pushHistoryDetailMapper; + + @Override + public Object getPushHistoryDetailById(String historyId) { + return pushHistoryDetailMapper.countByHistoryId(historyId); + } + } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java index 6b14175b..97908d08 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/SysRoleServiceImpl.java @@ -1,6 +1,8 @@ package com.yfd.platform.system.service.impl; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.yfd.platform.config.ResponseResult; @@ -172,4 +174,15 @@ public class SysRoleServiceImpl extends ServiceImpl impl return roleMapper.selectRoleList(rolename, tenantId); } + @Override + public List queryRolesList(String roleName, String tenantId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysRole::getTenantId, tenantId); + queryWrapper.like(StrUtil.isNotBlank(roleName),SysRole::getRolename, roleName); + queryWrapper.ne(SysRole::getLevel, 1); + queryWrapper.orderByDesc(SysRole::getLevel); + List sysRoleList = this.list( queryWrapper); + return sysRoleList; + } + } diff --git a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java index 73b12b45..cc11fb14 100644 --- a/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/system/service/impl/UserServiceImpl.java @@ -904,4 +904,20 @@ public class UserServiceImpl extends ServiceImpl impleme return true; } } + + + @Override + public List queryUsersList(String name, String tenantId) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StrUtil.isNotBlank(tenantId), SysUser::getTenantId, tenantId); + queryWrapper.eq(SysUser::getStatus, 1); + queryWrapper.and(StrUtil.isNotBlank(name), wrapper -> + wrapper.like(SysUser::getNickname, name) + .or() + .like(SysUser::getRealName, name) + ); + queryWrapper.orderByDesc(SysUser::getRegTime); + List sysUserList = this.list( queryWrapper); + return sysUserList; + } } diff --git a/backend/src/main/java/com/yfd/platform/utils/CronUtil.java b/backend/src/main/java/com/yfd/platform/utils/CronUtil.java new file mode 100644 index 00000000..c757814d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/utils/CronUtil.java @@ -0,0 +1,28 @@ +package com.yfd.platform.utils; + +import cn.hutool.cron.pattern.CronPattern; +import cn.hutool.cron.pattern.CronPatternUtil; +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.date.DateField; +import java.util.Date; + +/** + * Cron 表达式工具类(基于 Hutool 6.x) + * 支持 6 位或 7 位表达式(秒 分 时 日 月 星期 [年]) + */ +public class CronUtil { + + /** + * 校验 Cron 表达式是否合法 + * @param expression Cron 表达式(支持 6 或 7 个字段) + * @return true-合法,false-非法 + */ + public static boolean isValid(String expression) { + try { + CronPattern.of(expression); + return true; + } catch (Exception e) { + return false; + } + } +} \ No newline at end of file