Merge branch 'main' of http://121.37.111.42:3000/zhengsl/WholeProcessPlatform
This commit is contained in:
commit
b708a53b46
@ -1,5 +1,8 @@
|
||||
package com.yfd.platform.config;
|
||||
|
||||
import io.swagger.v3.oas.models.Components;
|
||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springdoc.core.models.GroupedOpenApi;
|
||||
@ -10,15 +13,55 @@ import io.swagger.v3.oas.models.info.Contact;
|
||||
@Configuration
|
||||
public class SwaggerConfig {
|
||||
|
||||
|
||||
// @Bean
|
||||
// public OpenAPI projectOpenAPI() {
|
||||
// return new OpenAPI()
|
||||
// .info(new Info()
|
||||
// .title("项目API 接口文档")
|
||||
// .version("3.0")
|
||||
// .description("")
|
||||
// .contact(new Contact().name("郑顺利").email("13910913995@163.com"))
|
||||
// );
|
||||
// }
|
||||
|
||||
|
||||
@Bean
|
||||
public OpenAPI projectOpenAPI() {
|
||||
// 1. 定义第一个 Header:token
|
||||
SecurityScheme tokenScheme = new SecurityScheme()
|
||||
.type(SecurityScheme.Type.APIKEY)
|
||||
.in(SecurityScheme.In.HEADER)
|
||||
.name("token")
|
||||
.description("用户认证 Token");
|
||||
|
||||
// 2. 定义第二个 Header:租户ID(示例)
|
||||
SecurityScheme tenantScheme = new SecurityScheme()
|
||||
.type(SecurityScheme.Type.APIKEY)
|
||||
.in(SecurityScheme.In.HEADER)
|
||||
.name("Tenant_Id")
|
||||
.description("租户标识");
|
||||
|
||||
// 3. 将两个安全方案注册到 Components
|
||||
Components components = new Components()
|
||||
.addSecuritySchemes("tokenAuth", tokenScheme)
|
||||
.addSecuritySchemes("tenantAuth", tenantScheme);
|
||||
|
||||
// 4. 创建 SecurityRequirement,同时要求两个 Header 都必须提供
|
||||
SecurityRequirement securityRequirement = new SecurityRequirement()
|
||||
.addList("tokenAuth") // 引用 token 方案
|
||||
.addList("tenantAuth"); // 引用 tenant 方案
|
||||
|
||||
|
||||
return new OpenAPI()
|
||||
.info(new Info()
|
||||
.title("项目API 接口文档")
|
||||
.version("3.0")
|
||||
.description("")
|
||||
.contact(new Contact().name("郑顺利").email("13910913995@163.com"))
|
||||
);
|
||||
)
|
||||
.components(components)
|
||||
.addSecurityItem(securityRequirement); // 一次性添加
|
||||
}
|
||||
|
||||
// @Bean
|
||||
|
||||
@ -52,9 +52,27 @@ public class SdEngMonitorController {
|
||||
return ResponseResult.successData(engInfoBHService.getEngPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/alarmPoint/GetKendoListCust")
|
||||
@Operation(summary = "电站告警描点列表")
|
||||
public ResponseResult getAlarmPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(engInfoBHService.getAlarmPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/rsvrcscdb/GetKendoList")
|
||||
@Operation(summary = "条件过滤数据列表")
|
||||
public ResponseResult getRsvrcscdBKendoList(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(engInfoBHService.getRsvrcscdBKendoList(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/rsvrcscdb/rvcd")
|
||||
@Operation(summary = "查询梯级流域")
|
||||
public ResponseResult getRsvrcscdBRvcdList(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(engInfoBHService.getRsvrcscdBRvcdList(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/rsvrcscdb/getQgcRvcd")
|
||||
@Operation(summary = "查询梯级流域图流域")
|
||||
public ResponseResult getQgcRvcdList(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(engInfoBHService.getQgcRvcdList(dataSourceRequest));
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package com.yfd.platform.qgc_base.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 当前登录用户的数据权限范围
|
||||
*/
|
||||
@Data
|
||||
public class CurrentUserDataScopeVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 是否为统一管理的超级管理员
|
||||
*/
|
||||
private boolean managedAdmin;
|
||||
|
||||
/**
|
||||
* 当前用户有权限的电站编码
|
||||
*/
|
||||
private Set<String> stationCodes = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* 当前用户有权限的流域编码
|
||||
*/
|
||||
private Set<String> rvcdCodes = new LinkedHashSet<>();
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.yfd.platform.qgc_base.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 数据权限条件应用结果
|
||||
*/
|
||||
@Data
|
||||
public class DataScopeApplyResult implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 当前用户是否为管理员
|
||||
*/
|
||||
private boolean managedAdmin;
|
||||
|
||||
/**
|
||||
* 当前权限是否命中空结果
|
||||
*/
|
||||
private boolean emptyResult;
|
||||
|
||||
/**
|
||||
* 是否已向查询中追加权限条件
|
||||
*/
|
||||
private boolean conditionApplied;
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
package com.yfd.platform.qgc_base.domain.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Schema(description = "电站告警描点")
|
||||
public class EngAlarmPointVo {
|
||||
|
||||
@Schema(description = "站点类型")
|
||||
private String sttp;
|
||||
|
||||
@Schema(description = "站点编码")
|
||||
private String stcd;
|
||||
|
||||
@Schema(description = "经度")
|
||||
private BigDecimal lgtd;
|
||||
|
||||
@Schema(description = "纬度")
|
||||
private BigDecimal lttd;
|
||||
|
||||
@Schema(description = "高程")
|
||||
private BigDecimal dtmel;
|
||||
|
||||
@Schema(description = "描点状态")
|
||||
private String anchoPointState;
|
||||
|
||||
@Schema(description = "锚点类型")
|
||||
private String sttpMap;
|
||||
|
||||
@Schema(description = "弹框站点名称")
|
||||
private String titleName;
|
||||
|
||||
@Schema(description = "地图避让")
|
||||
private Integer distance;
|
||||
|
||||
@Schema(description = "流域编码")
|
||||
private String rvcd;
|
||||
|
||||
@Schema(description = "行政编码")
|
||||
private String addvcd;
|
||||
|
||||
@Schema(description = "基地编码")
|
||||
private String baseId;
|
||||
|
||||
@Schema(description = "关联电站编码")
|
||||
private String rstcds;
|
||||
|
||||
@Schema(description = "设施类型")
|
||||
private String sttpCode;
|
||||
|
||||
@Schema(description = "电站名称")
|
||||
private String ennm;
|
||||
|
||||
@Schema(description = "流域名称")
|
||||
private String rvnm;
|
||||
|
||||
@Schema(description = "电站装机类型")
|
||||
private Integer endInstalledType;
|
||||
|
||||
@Schema(description = "生态流量告警数")
|
||||
private Integer stqCount;
|
||||
|
||||
@Schema(description = "水质告警数")
|
||||
private Integer wqCount;
|
||||
|
||||
@Schema(description = "水位告警数")
|
||||
private Integer zCount;
|
||||
|
||||
@Schema(description = "水温告警数")
|
||||
private Integer wtCount;
|
||||
|
||||
@Schema(description = "年份")
|
||||
private String yyyy;
|
||||
|
||||
@Schema(description = "告警区间范围")
|
||||
private String range;
|
||||
|
||||
@Schema(description = "装机容量")
|
||||
private BigDecimal ttpwr;
|
||||
|
||||
@Schema(description = "基地名称")
|
||||
private String baseName;
|
||||
|
||||
@Schema(description = "电站编码")
|
||||
private String rstcd;
|
||||
|
||||
@Schema(description = "流域沿程")
|
||||
private Integer rvcdStepSort;
|
||||
|
||||
@Schema(description = "电站沿程")
|
||||
private Integer rstcdStepSort;
|
||||
|
||||
@Schema(description = "站点沿程")
|
||||
private Integer siteStepSort;
|
||||
|
||||
@Schema(description = "电站图片")
|
||||
private String logo;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.yfd.platform.qgc_base.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EngQgcRvcdVo {
|
||||
|
||||
private String rvcd;
|
||||
|
||||
private String rvnm;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.yfd.platform.qgc_base.domain.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EngRsvrcscdRvcdVo {
|
||||
|
||||
private String wbsCode;
|
||||
|
||||
private String wbsName;
|
||||
|
||||
/**
|
||||
* 旧口径对应上级/关联对象编码,新库这里映射为基地编码。
|
||||
*/
|
||||
private String objId;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.yfd.platform.qgc_base.service;
|
||||
|
||||
import com.yfd.platform.qgc_base.domain.vo.CurrentUserDataScopeVo;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 当前登录用户数据权限公共服务
|
||||
*/
|
||||
public interface ICurrentUserDataScopeService {
|
||||
|
||||
/**
|
||||
* 获取当前用户完整的数据权限范围
|
||||
*/
|
||||
CurrentUserDataScopeVo getCurrentUserDataScope();
|
||||
|
||||
/**
|
||||
* 获取当前用户有权限的电站编码
|
||||
*/
|
||||
Set<String> getCurrentUserAuthorizedStationCodes();
|
||||
|
||||
/**
|
||||
* 获取当前用户有权限的流域编码
|
||||
*/
|
||||
Set<String> getCurrentUserAuthorizedRvcdCodes();
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.yfd.platform.qgc_base.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 当前用户数据权限过滤公共服务
|
||||
*/
|
||||
public interface IDataScopeFilterService {
|
||||
|
||||
/**
|
||||
* 追加当前用户电站权限 SQL 条件
|
||||
*/
|
||||
DataScopeApplyResult appendCurrentUserStationScope(StringBuilder sql, Map<String, Object> paramMap, String columnName);
|
||||
|
||||
/**
|
||||
* 追加当前用户流域权限 SQL 条件
|
||||
*/
|
||||
DataScopeApplyResult appendCurrentUserRvcdScope(StringBuilder sql, Map<String, Object> paramMap, String columnName);
|
||||
|
||||
/**
|
||||
* 追加当前用户电站权限 Wrapper 条件
|
||||
*/
|
||||
<T> DataScopeApplyResult applyCurrentUserStationScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column);
|
||||
|
||||
/**
|
||||
* 追加当前用户流域权限 Wrapper 条件
|
||||
*/
|
||||
<T> DataScopeApplyResult applyCurrentUserRvcdScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column);
|
||||
}
|
||||
@ -7,9 +7,12 @@ import com.yfd.platform.common.DataSourceResult;
|
||||
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
|
||||
import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngAlarmPointVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngOperatVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngQgcRvcdVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngRsvrcscdBVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngRsvrcscdRvcdVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngPointVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngStInfoResultVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo;
|
||||
@ -91,5 +94,11 @@ public interface ISdEngInfoBHService extends IService<SdEngInfoBH> {
|
||||
|
||||
DataSourceResult<EngPointVo> getEngPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<EngAlarmPointVo> getAlarmPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<EngRsvrcscdBVo> getRsvrcscdBKendoList(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<EngRsvrcscdRvcdVo> getRsvrcscdBRvcdList(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<EngQgcRvcdVo> getQgcRvcdList(DataSourceRequest dataSourceRequest);
|
||||
}
|
||||
|
||||
@ -0,0 +1,161 @@
|
||||
package com.yfd.platform.qgc_base.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
|
||||
import com.yfd.platform.qgc_base.domain.vo.CurrentUserDataScopeVo;
|
||||
import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper;
|
||||
import com.yfd.platform.qgc_base.service.ICurrentUserDataScopeService;
|
||||
import com.yfd.platform.qgc_data.domain.SysUserDataScope;
|
||||
import com.yfd.platform.qgc_data.mapper.SysUserDataScopeMapper;
|
||||
import com.yfd.platform.system.service.IAdminAuthService;
|
||||
import com.yfd.platform.utils.SecurityUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 当前登录用户数据权限公共服务实现
|
||||
*/
|
||||
@Service
|
||||
public class CurrentUserDataScopeServiceImpl implements ICurrentUserDataScopeService {
|
||||
|
||||
private static final int QUERY_BATCH_SIZE = 500;
|
||||
|
||||
@Resource
|
||||
private SysUserDataScopeMapper sysUserDataScopeMapper;
|
||||
|
||||
@Resource
|
||||
private SdEngInfoBHMapper sdEngInfoBHMapper;
|
||||
|
||||
@Resource
|
||||
private IAdminAuthService adminAuthService;
|
||||
|
||||
@Override
|
||||
public CurrentUserDataScopeVo getCurrentUserDataScope() {
|
||||
CurrentUserDataScopeVo scopeVo = new CurrentUserDataScopeVo();
|
||||
if (adminAuthService.isCurrentManagedAdmin()) {
|
||||
scopeVo.setManagedAdmin(true);
|
||||
return scopeVo;
|
||||
}
|
||||
|
||||
String userId = SecurityUtils.getUserId();
|
||||
if (!StringUtils.hasText(userId)) {
|
||||
return scopeVo;
|
||||
}
|
||||
|
||||
List<SysUserDataScope> validPermissions = sysUserDataScopeMapper.selectValidPermissions(userId);
|
||||
if (validPermissions == null || validPermissions.isEmpty()) {
|
||||
return scopeVo;
|
||||
}
|
||||
|
||||
Set<String> directStationCodes = collectOrgIdsByType(validPermissions, "STATION");
|
||||
Set<String> directRvcdCodes = collectOrgIdsByType(validPermissions, "RVCD");
|
||||
Set<String> stationCodes = new LinkedHashSet<>();
|
||||
Set<String> rvcdCodes = new LinkedHashSet<>();
|
||||
|
||||
if (!directStationCodes.isEmpty()) {
|
||||
List<SdEngInfoBH> stationList = listStationsByStcds(directStationCodes);
|
||||
stationCodes.addAll(extractStationCodes(stationList));
|
||||
rvcdCodes.addAll(extractLegacyBasinCodes(stationList));
|
||||
}
|
||||
|
||||
if (!directRvcdCodes.isEmpty()) {
|
||||
List<SdEngInfoBH> stationList = listStationsByReachcds(directRvcdCodes);
|
||||
stationCodes.addAll(extractStationCodes(stationList));
|
||||
rvcdCodes.addAll(extractLegacyBasinCodes(stationList));
|
||||
}
|
||||
|
||||
scopeVo.setStationCodes(stationCodes);
|
||||
scopeVo.setRvcdCodes(rvcdCodes);
|
||||
return scopeVo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getCurrentUserAuthorizedStationCodes() {
|
||||
return getCurrentUserDataScope().getStationCodes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getCurrentUserAuthorizedRvcdCodes() {
|
||||
return getCurrentUserDataScope().getRvcdCodes();
|
||||
}
|
||||
|
||||
private Set<String> collectOrgIdsByType(List<SysUserDataScope> scopes, String orgType) {
|
||||
Set<String> orgIds = new LinkedHashSet<>();
|
||||
for (SysUserDataScope scope : scopes) {
|
||||
if (scope == null || !orgType.equalsIgnoreCase(scope.getOrgType())) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.hasText(scope.getOrgId())) {
|
||||
orgIds.add(scope.getOrgId());
|
||||
}
|
||||
}
|
||||
return orgIds;
|
||||
}
|
||||
|
||||
private List<SdEngInfoBH> listStationsByStcds(Set<String> stationCodes) {
|
||||
return listStationsByColumn(stationCodes, QueryDimension.STATION);
|
||||
}
|
||||
|
||||
private List<SdEngInfoBH> listStationsByReachcds(Set<String> rvcdCodes) {
|
||||
return listStationsByColumn(rvcdCodes, QueryDimension.REACH);
|
||||
}
|
||||
|
||||
private List<SdEngInfoBH> listStationsByColumn(Set<String> codes, QueryDimension queryDimension) {
|
||||
List<SdEngInfoBH> result = new ArrayList<>();
|
||||
if (codes == null || codes.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<String> codeList = new ArrayList<>(codes);
|
||||
for (int i = 0; i < codeList.size(); i += QUERY_BATCH_SIZE) {
|
||||
int end = Math.min(i + QUERY_BATCH_SIZE, codeList.size());
|
||||
List<String> batchCodes = codeList.subList(i, end);
|
||||
LambdaQueryWrapper<SdEngInfoBH> wrapper = new LambdaQueryWrapper<SdEngInfoBH>()
|
||||
.select(SdEngInfoBH::getStcd, SdEngInfoBH::getReachcd, SdEngInfoBH::getEnnm);
|
||||
if (queryDimension == QueryDimension.STATION) {
|
||||
wrapper.in(SdEngInfoBH::getStcd, batchCodes);
|
||||
} else {
|
||||
wrapper.in(SdEngInfoBH::getReachcd, batchCodes);
|
||||
}
|
||||
result.addAll(sdEngInfoBHMapper.selectList(wrapper));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Set<String> extractStationCodes(List<SdEngInfoBH> stationList) {
|
||||
Set<String> stationCodes = new LinkedHashSet<>();
|
||||
if (stationList == null || stationList.isEmpty()) {
|
||||
return stationCodes;
|
||||
}
|
||||
for (SdEngInfoBH station : stationList) {
|
||||
if (station != null && StringUtils.hasText(station.getStcd())) {
|
||||
stationCodes.add(station.getStcd());
|
||||
}
|
||||
}
|
||||
return stationCodes;
|
||||
}
|
||||
|
||||
private Set<String> extractLegacyBasinCodes(List<SdEngInfoBH> stationList) {
|
||||
Set<String> rvcdCodes = new LinkedHashSet<>();
|
||||
if (stationList == null || stationList.isEmpty()) {
|
||||
return rvcdCodes;
|
||||
}
|
||||
for (SdEngInfoBH station : stationList) {
|
||||
if (station != null && StringUtils.hasText(station.getEnnm()) && StringUtils.hasText(station.getReachcd())) {
|
||||
rvcdCodes.add(station.getReachcd());
|
||||
}
|
||||
}
|
||||
return rvcdCodes;
|
||||
}
|
||||
|
||||
private enum QueryDimension {
|
||||
STATION,
|
||||
REACH
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,154 @@
|
||||
package com.yfd.platform.qgc_base.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.yfd.platform.qgc_base.domain.vo.CurrentUserDataScopeVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
|
||||
import com.yfd.platform.qgc_base.service.ICurrentUserDataScopeService;
|
||||
import com.yfd.platform.qgc_base.service.IDataScopeFilterService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 当前用户数据权限过滤公共服务实现
|
||||
*/
|
||||
@Service
|
||||
public class DataScopeFilterServiceImpl implements IDataScopeFilterService {
|
||||
|
||||
private static final int IN_BATCH_SIZE = 900;
|
||||
|
||||
@Resource
|
||||
private ICurrentUserDataScopeService currentUserDataScopeService;
|
||||
|
||||
@Override
|
||||
public DataScopeApplyResult appendCurrentUserStationScope(StringBuilder sql, Map<String, Object> paramMap, String columnName) {
|
||||
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
|
||||
return appendScopeCondition(sql, paramMap, columnName, scopeVo, scopeVo.getStationCodes(), "stationScope");
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataScopeApplyResult appendCurrentUserRvcdScope(StringBuilder sql, Map<String, Object> paramMap, String columnName) {
|
||||
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
|
||||
return appendScopeCondition(sql, paramMap, columnName, scopeVo, scopeVo.getRvcdCodes(), "rvcdScope");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DataScopeApplyResult applyCurrentUserStationScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column) {
|
||||
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
|
||||
return applyScopeCondition(wrapper, column, scopeVo, scopeVo.getStationCodes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> DataScopeApplyResult applyCurrentUserRvcdScope(LambdaQueryWrapper<T> wrapper, SFunction<T, ?> column) {
|
||||
CurrentUserDataScopeVo scopeVo = currentUserDataScopeService.getCurrentUserDataScope();
|
||||
return applyScopeCondition(wrapper, column, scopeVo, scopeVo.getRvcdCodes());
|
||||
}
|
||||
|
||||
private DataScopeApplyResult appendScopeCondition(StringBuilder sql,
|
||||
Map<String, Object> paramMap,
|
||||
String columnName,
|
||||
CurrentUserDataScopeVo scopeVo,
|
||||
Set<String> scopeValues,
|
||||
String paramPrefix) {
|
||||
DataScopeApplyResult result = initResult(scopeVo, scopeValues);
|
||||
if (result.isManagedAdmin() || result.isEmptyResult()) {
|
||||
return result;
|
||||
}
|
||||
if (!StringUtils.hasText(columnName)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<List<String>> batches = splitValues(scopeValues);
|
||||
if (batches.isEmpty()) {
|
||||
result.setEmptyResult(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
sql.append(" AND (");
|
||||
for (int i = 0; i < batches.size(); i++) {
|
||||
if (i > 0) {
|
||||
sql.append(" OR ");
|
||||
}
|
||||
List<String> batch = batches.get(i);
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
for (int j = 0; j < batch.size(); j++) {
|
||||
String key = buildParamKey(paramMap, paramPrefix, i, j);
|
||||
paramMap.put(key, batch.get(j));
|
||||
placeholders.add("#{map." + key + "}");
|
||||
}
|
||||
sql.append(columnName).append(" IN (").append(String.join(", ", placeholders)).append(")");
|
||||
}
|
||||
sql.append(") ");
|
||||
result.setConditionApplied(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T> DataScopeApplyResult applyScopeCondition(LambdaQueryWrapper<T> wrapper,
|
||||
SFunction<T, ?> column,
|
||||
CurrentUserDataScopeVo scopeVo,
|
||||
Set<String> scopeValues) {
|
||||
DataScopeApplyResult result = initResult(scopeVo, scopeValues);
|
||||
if (result.isManagedAdmin() || result.isEmptyResult()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<List<String>> batches = splitValues(scopeValues);
|
||||
if (batches.isEmpty()) {
|
||||
result.setEmptyResult(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
wrapper.and(innerWrapper -> {
|
||||
for (int i = 0; i < batches.size(); i++) {
|
||||
if (i > 0) {
|
||||
innerWrapper.or();
|
||||
}
|
||||
innerWrapper.in(column, batches.get(i));
|
||||
}
|
||||
});
|
||||
result.setConditionApplied(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
private DataScopeApplyResult initResult(CurrentUserDataScopeVo scopeVo, Collection<String> scopeValues) {
|
||||
DataScopeApplyResult result = new DataScopeApplyResult();
|
||||
if (scopeVo != null && scopeVo.isManagedAdmin()) {
|
||||
result.setManagedAdmin(true);
|
||||
return result;
|
||||
}
|
||||
if (CollectionUtils.isEmpty(scopeValues)) {
|
||||
result.setEmptyResult(true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<List<String>> splitValues(Collection<String> values) {
|
||||
List<List<String>> batches = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(values)) {
|
||||
return batches;
|
||||
}
|
||||
|
||||
List<String> valueList = new ArrayList<>(values);
|
||||
for (int i = 0; i < valueList.size(); i += IN_BATCH_SIZE) {
|
||||
int end = Math.min(i + IN_BATCH_SIZE, valueList.size());
|
||||
batches.add(valueList.subList(i, end));
|
||||
}
|
||||
return batches;
|
||||
}
|
||||
|
||||
private String buildParamKey(Map<String, Object> paramMap, String paramPrefix, int batchIndex, int itemIndex) {
|
||||
String key = paramPrefix + "_" + batchIndex + "_" + itemIndex;
|
||||
while (paramMap.containsKey(key)) {
|
||||
key = key + "_n";
|
||||
}
|
||||
return key;
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.yfd.platform.qgc_base.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@ -23,17 +24,22 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper;
|
||||
import com.yfd.platform.qgc_data.domain.SysUserDataScope;
|
||||
import com.yfd.platform.qgc_data.mapper.SysUserDataScopeMapper;
|
||||
import com.yfd.platform.qgc_base.domain.SdEngInfoBH;
|
||||
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
|
||||
import com.yfd.platform.qgc_base.domain.SdEngInfoBHRequest;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngAlarmPointVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngBaseInfoVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngEiaapprovalVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngOperatVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngQgcRvcdVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngRsvrcscdBVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngRsvrcscdRvcdVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngPointVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngStbprpDataVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngStBaseInfoVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngStInfoResultVo;
|
||||
import com.yfd.platform.qgc_base.domain.vo.EngVmsstbprptVo;
|
||||
import com.yfd.platform.qgc_base.mapper.SdEngInfoBHMapper;
|
||||
import com.yfd.platform.qgc_base.service.IDataScopeFilterService;
|
||||
import com.yfd.platform.qgc_base.service.IMsOperationLogService;
|
||||
import com.yfd.platform.qgc_base.service.ISdEngInfoBHService;
|
||||
import com.yfd.platform.system.service.IAdminAuthService;
|
||||
@ -60,6 +66,9 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
|
||||
private static final Map<String, String> ENG_CODE_NAME_FIELD_MAP = new LinkedHashMap<>();
|
||||
|
||||
@Resource
|
||||
private IDataScopeFilterService dataScopeFilterService;
|
||||
|
||||
static {
|
||||
ENG_CODE_NAME_FIELD_MAP.put("baseId", "baseName");
|
||||
ENG_CODE_NAME_FIELD_MAP.put("hbrvcd", "hbrvcdName");
|
||||
@ -126,8 +135,26 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = "engInfoCache#3600", keyGenerator = "cacheKeyGenerator")
|
||||
public List<SdEngInfoBH> selectForDropdown(SdEngInfoBHRequest sdEngInfoBHRequest) {
|
||||
List<SdEngInfoBH> allData = this.selectForDropdownCached(sdEngInfoBHRequest);
|
||||
|
||||
if (adminAuthService.isCurrentManagedAdmin()) {
|
||||
return allData;
|
||||
}
|
||||
Set<String> authorizedStations = getUserAuthorizedStationCodes();
|
||||
if (authorizedStations != null && !authorizedStations.isEmpty()) {
|
||||
return allData.stream()
|
||||
.filter(item -> authorizedStations.contains(item.getStcd()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* 纯数据库查询(可缓存),不包含权限过滤逻辑
|
||||
*/
|
||||
@Cacheable(cacheNames = "engInfoCache#3600", keyGenerator = "cacheKeyGenerator")
|
||||
public List<SdEngInfoBH> selectForDropdownCached(SdEngInfoBHRequest sdEngInfoBHRequest) {
|
||||
String baseId = sdEngInfoBHRequest.getBaseId();
|
||||
String hbrvcd = sdEngInfoBHRequest.getHbrvcd();
|
||||
String ennm = sdEngInfoBHRequest.getEnnm();
|
||||
@ -138,28 +165,15 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
LambdaQueryWrapper<SdEngInfoBH> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(StringUtils.hasText(baseId), SdEngInfoBH::getBaseId, baseId)
|
||||
.eq(StringUtils.hasText(hbrvcd), SdEngInfoBH::getHbrvcd, hbrvcd)
|
||||
.eq(StrUtil.isNotBlank(reachcd), SdEngInfoBH::getRvcd, reachcd)
|
||||
.eq(StrUtil.isNotBlank(rvcd), SdEngInfoBH::getReachcd, rvcd)
|
||||
.eq(StrUtil.isNotBlank(rvcd), SdEngInfoBH::getReachcd, rvcd)
|
||||
.eq(StrUtil.isNotBlank(reachcd), SdEngInfoBH::getReachcd, reachcd)
|
||||
.eq(StrUtil.isNotBlank(rvcd), SdEngInfoBH::getRvcd, rvcd)
|
||||
.in(rvcds != null && !rvcds.isEmpty(), SdEngInfoBH::getReachcd, rvcds)
|
||||
.in(hbrvcds != null && !hbrvcds.isEmpty(), SdEngInfoBH::getHbrvcd, hbrvcds)
|
||||
.like(StringUtils.hasText(ennm), SdEngInfoBH::getEnnm, ennm)
|
||||
.select(SdEngInfoBH::getStcd, SdEngInfoBH::getEnnm, SdEngInfoBH::getReachcdName, SdEngInfoBH::getYrgeb, SdEngInfoBH::getBaseId)
|
||||
.orderByAsc(SdEngInfoBH::getBaseId,SdEngInfoBH::getOrderIndex);
|
||||
|
||||
if(adminAuthService.isCurrentManagedAdmin()){
|
||||
.orderByAsc(SdEngInfoBH::getBaseId, SdEngInfoBH::getOrderIndex);
|
||||
return this.list(wrapper);
|
||||
}
|
||||
Set<String> authorizedStations = getUserAuthorizedStationCodes();
|
||||
if (authorizedStations != null && !authorizedStations.isEmpty()) {
|
||||
List<SdEngInfoBH> list = this.list(wrapper);
|
||||
return list.stream()
|
||||
.filter(item -> authorizedStations.contains(item.getStcd()))
|
||||
.collect(Collectors.toList());
|
||||
}else{
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Set<String> getUserAuthorizedStationCodes() {
|
||||
String userId = SecurityUtils.getUserId();
|
||||
@ -2754,8 +2768,13 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
.append("AND NVL(t.USFL, 1) = 1 ")
|
||||
.append("AND t.LGTD IS NOT NULL ")
|
||||
.append("AND t.LTTD IS NOT NULL ");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.STCD");
|
||||
if (scopeApplyResult.isEmptyResult()) {
|
||||
result.setData(new ArrayList<>());
|
||||
result.setTotal(0L);
|
||||
return result;
|
||||
}
|
||||
String filterSql = buildEngPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql);
|
||||
@ -2772,6 +2791,353 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<EngAlarmPointVo> getAlarmPointKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||
String startTimeText = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime");
|
||||
String endTimeText = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime");
|
||||
|
||||
Date startTime;
|
||||
Date endTime;
|
||||
String yyyy = null;
|
||||
if (StrUtil.isNotBlank(startTimeText) && StrUtil.isNotBlank(endTimeText)) {
|
||||
startTime = parseAlarmPointTime(startTimeText);
|
||||
endTime = parseAlarmPointTime(endTimeText);
|
||||
} else {
|
||||
yyyy = String.valueOf(DateUtil.year(new Date()));
|
||||
Map<String, Date> yearRange = buildAlarmPointYearRange(yyyy);
|
||||
startTime = yearRange.get("startTime");
|
||||
endTime = yearRange.get("endTime");
|
||||
}
|
||||
|
||||
Map<String, Object> pointParamMap = new HashMap<>();
|
||||
StringBuilder pointSql = new StringBuilder(buildAlarmPointBaseSql());
|
||||
// DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(pointSql, pointParamMap, "eng.STCD");
|
||||
List<EngAlarmPointVo> points= microservicDynamicSQLMapper.getAllListWithResultType(
|
||||
pointSql.toString(),
|
||||
pointParamMap,
|
||||
EngAlarmPointVo.class
|
||||
);
|
||||
// if (scopeApplyResult.isEmptyResult()) {
|
||||
// points = new ArrayList<>();
|
||||
// } else {
|
||||
// points = microservicDynamicSQLMapper.getAllListWithResultType(
|
||||
// pointSql.toString(),
|
||||
// pointParamMap,
|
||||
// EngAlarmPointVo.class
|
||||
// );
|
||||
// }
|
||||
|
||||
Map<String, Object> countParamMap = new HashMap<>();
|
||||
countParamMap.put("alarmPointStartTime", startTime);
|
||||
countParamMap.put("alarmPointEndTime", endTime);
|
||||
List<Map<String, Object>> countRows = microservicDynamicSQLMapper.getAllList(buildAlarmPointCountSql(), countParamMap);
|
||||
Map<String, Integer> qecCountMap = buildAlarmPointQecCountMap(countRows);
|
||||
Map<String, Integer> wqCountMap = buildAlarmPointWqCountMap(countRows);
|
||||
|
||||
List<Map<String, Object>> expressionRows = microservicDynamicSQLMapper.getAllList(buildAlarmPointLegendSql(), new HashMap<>());
|
||||
List<EngAlarmPointVo> resultList = mergeAlarmPointData(points, qecCountMap, wqCountMap, expressionRows, yyyy);
|
||||
|
||||
DataSourceResult<EngAlarmPointVo> result = new DataSourceResult<>();
|
||||
result.setData(resultList);
|
||||
result.setTotal(resultList.size());
|
||||
result.setAggregates(new HashMap<>());
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildAlarmPointBaseSql() {
|
||||
return "SELECT " +
|
||||
"eng.STCD AS stcd, " +
|
||||
"'ENG' AS sttp, " +
|
||||
"eng.ENNM AS ennm, " +
|
||||
"eng.ENNM AS titleName, " +
|
||||
"eng.LOGO AS logo, " +
|
||||
"eng.RVCD AS rvcd, " +
|
||||
"eng.RVCD_NAME AS rvnm, " +
|
||||
"eng.ADDVCD AS addvcd, " +
|
||||
"eng.BASE_ID AS baseId, " +
|
||||
"NVL(eng.BASE_NAME, hb.BASENAME) AS baseName, " +
|
||||
"eng.LGTD AS lgtd, " +
|
||||
"eng.LTTD AS lttd, " +
|
||||
"eng.ELEV AS dtmel, " +
|
||||
"eng.YRGEB AS ttpwr, " +
|
||||
"'ENG' AS sttpMap, " +
|
||||
"CASE WHEN eng.PRSC IN (1, 2) THEN 1 WHEN eng.PRSC = 3 THEN 2 END AS endInstalledType, " +
|
||||
"CASE " +
|
||||
" WHEN eng.PRSC IN (1, 2) AND NVL(eng.BLDSTT_CODE, 0) = 2 THEN 'large_eng_built' " +
|
||||
" WHEN eng.PRSC IN (1, 2) AND NVL(eng.BLDSTT_CODE, 0) = 1 THEN 'large_eng_ubuilt' " +
|
||||
" WHEN eng.PRSC IN (1, 2) THEN 'large_eng_nbuilt' " +
|
||||
" WHEN eng.PRSC = 3 AND NVL(eng.BLDSTT_CODE, 0) = 2 THEN 'mid_eng_built' " +
|
||||
" WHEN eng.PRSC = 3 AND NVL(eng.BLDSTT_CODE, 0) = 1 THEN 'mid_eng_ubuilt' " +
|
||||
" WHEN eng.PRSC = 3 THEN 'mid_eng_nbuilt' " +
|
||||
" ELSE NULL END AS anchoPointState, " +
|
||||
"eng.STCD AS rstcd, " +
|
||||
"eng.STCD AS rstcds, " +
|
||||
"'ENG' AS sttpCode, " +
|
||||
"NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " +
|
||||
"NVL(rstSort.SORT, 999999) AS rstcdStepSort, " +
|
||||
"NVL(siteSort.SORT, 999999) AS siteStepSort " +
|
||||
"FROM SD_ENGINFO_B_H eng " +
|
||||
"LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " +
|
||||
"LEFT JOIN MS_ALONG_B along ON along.RVCD = eng.HBRVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " +
|
||||
"LEFT JOIN ( " +
|
||||
" SELECT det.SORT, cfg.RVCD, det.STCD " +
|
||||
" FROM MS_ALONGDET_B det " +
|
||||
" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
|
||||
" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " +
|
||||
") rstSort ON rstSort.RVCD = eng.HBRVCD AND rstSort.STCD = eng.STCD " +
|
||||
"LEFT JOIN ( " +
|
||||
" SELECT det.SORT, cfg.RVCD, det.STCD " +
|
||||
" FROM MS_ALONGDET_B det " +
|
||||
" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
|
||||
" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " +
|
||||
") siteSort ON siteSort.RVCD = eng.HBRVCD AND siteSort.STCD = eng.STCD " +
|
||||
"WHERE NVL(eng.IS_DELETED, 0) = 0 " +
|
||||
"AND NVL(eng.USFL, 0) = 1 " +
|
||||
"AND eng.LGTD IS NOT NULL " +
|
||||
"AND eng.LTTD IS NOT NULL ";
|
||||
}
|
||||
|
||||
private String buildAlarmPointCountSql() {
|
||||
return "SELECT wr.STCD AS stcd, wr.STCD AS rstcd, COUNT(wr.STCD) AS count, 'QEC' AS ys " +
|
||||
"FROM MS_WARN_RECORD_W wr " +
|
||||
"WHERE NVL(wr.IS_DELETED, 0) = 0 " +
|
||||
"AND wr.TB_ID IN (SELECT tb.ID FROM ST_TB_B tb WHERE tb.TB_CODE = 'QEC_R' AND NVL(tb.IS_DELETED, 0) = 0) " +
|
||||
"AND wr.YS = 'QEC' " +
|
||||
"AND wr.SFGB = 'N' " +
|
||||
"AND wr.BTM BETWEEN #{map.alarmPointStartTime} AND #{map.alarmPointEndTime} " +
|
||||
"GROUP BY wr.STCD " +
|
||||
"UNION ALL " +
|
||||
"SELECT wr.STCD AS stcd, wq.RSTCD AS rstcd, COUNT(wr.STCD) AS count, 'WQ' AS ys " +
|
||||
"FROM MS_WARN_RECORD_W wr " +
|
||||
"LEFT JOIN SD_WQ_B_H wq ON wr.STCD = wq.STCD AND NVL(wq.IS_DELETED, 0) = 0 " +
|
||||
"WHERE NVL(wr.IS_DELETED, 0) = 0 " +
|
||||
"AND wr.TB_ID IN (SELECT tb.ID FROM ST_TB_B tb WHERE tb.TB_CODE = 'WQ_R' AND NVL(tb.IS_DELETED, 0) = 0) " +
|
||||
"AND wr.SFGB = 'N' " +
|
||||
"AND wr.BTM BETWEEN #{map.alarmPointStartTime} AND #{map.alarmPointEndTime} " +
|
||||
"AND wq.RSTCD IS NOT NULL " +
|
||||
"GROUP BY wr.STCD, wq.RSTCD";
|
||||
}
|
||||
|
||||
private String buildAlarmPointLegendSql() {
|
||||
return "SELECT EXPRESSION AS expression, NAME_EN AS nameEn " +
|
||||
"FROM MS_MAPLEGEND_B " +
|
||||
"WHERE LAYER_CODE = 'eng_alarm_point' " +
|
||||
"AND IF_SHOW = 1 " +
|
||||
"AND NVL(IS_DELETED, 0) = 0 " +
|
||||
"AND EXPRESSION IS NOT NULL " +
|
||||
"ORDER BY NVL(ORDER_INDEX, 999999), ID";
|
||||
}
|
||||
|
||||
private Map<String, Date> buildAlarmPointYearRange(String yearText) {
|
||||
Date endTime = new Date();
|
||||
String currentYear = String.valueOf(DateUtil.year(endTime));
|
||||
Date startTime = DateUtil.parse(currentYear + "-01-01");
|
||||
if (StrUtil.isNotBlank(yearText) && !currentYear.equals(yearText)) {
|
||||
startTime = DateUtil.parse(yearText + "-01-01");
|
||||
endTime = DateUtil.parse(yearText + "-12-31");
|
||||
}
|
||||
Map<String, Date> result = new HashMap<>();
|
||||
result.put("startTime", startTime);
|
||||
result.put("endTime", endTime);
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Integer> buildAlarmPointQecCountMap(List<Map<String, Object>> countRows) {
|
||||
Map<String, Integer> result = new HashMap<>();
|
||||
if (CollUtil.isEmpty(countRows)) {
|
||||
return result;
|
||||
}
|
||||
for (Map<String, Object> row : countRows) {
|
||||
if (!"QEC".equalsIgnoreCase(safeAlarmValue(firstPresentAlarmValue(row, "YS", "ys")))) {
|
||||
continue;
|
||||
}
|
||||
String stcd = safeAlarmValue(firstPresentAlarmValue(row, "RSTCD", "rstcd", "STCD", "stcd"));
|
||||
if (StrUtil.isBlank(stcd)) {
|
||||
continue;
|
||||
}
|
||||
result.put(stcd, toAlarmIntegerValue(firstPresentAlarmValue(row, "COUNT", "count")));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, Integer> buildAlarmPointWqCountMap(List<Map<String, Object>> countRows) {
|
||||
Map<String, Integer> result = new HashMap<>();
|
||||
if (CollUtil.isEmpty(countRows)) {
|
||||
return result;
|
||||
}
|
||||
for (Map<String, Object> row : countRows) {
|
||||
if (!"WQ".equalsIgnoreCase(safeAlarmValue(firstPresentAlarmValue(row, "YS", "ys")))) {
|
||||
continue;
|
||||
}
|
||||
Integer count = toAlarmIntegerValue(firstPresentAlarmValue(row, "COUNT", "count"));
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
String rstcdText = safeAlarmValue(firstPresentAlarmValue(row, "RSTCD", "rstcd"));
|
||||
if (StrUtil.isBlank(rstcdText)) {
|
||||
continue;
|
||||
}
|
||||
for (String rstcd : rstcdText.split(",")) {
|
||||
String trimmed = StrUtil.trim(rstcd);
|
||||
if (StrUtil.isBlank(trimmed)) {
|
||||
continue;
|
||||
}
|
||||
result.put(trimmed, result.getOrDefault(trimmed, 0) + count);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<EngAlarmPointVo> mergeAlarmPointData(List<EngAlarmPointVo> points,
|
||||
Map<String, Integer> qecCountMap,
|
||||
Map<String, Integer> wqCountMap,
|
||||
List<Map<String, Object>> expressionRows,
|
||||
String yyyy) {
|
||||
List<EngAlarmPointVo> result = new ArrayList<>();
|
||||
if (CollUtil.isEmpty(points)) {
|
||||
return result;
|
||||
}
|
||||
for (EngAlarmPointVo point : points) {
|
||||
if (point == null || !isAlarmPointVisible(point.getAnchoPointState())) {
|
||||
continue;
|
||||
}
|
||||
point.setAnchoPointState(normalizeAlarmPointState(point.getAnchoPointState()) + "_ALARM");
|
||||
point.setStqCount(qecCountMap.getOrDefault(point.getStcd(), 0));
|
||||
point.setWqCount(wqCountMap.getOrDefault(point.getStcd(), 0));
|
||||
point.setZCount(0);
|
||||
point.setWtCount(0);
|
||||
point.setYyyy(yyyy);
|
||||
point.setSttpCode("ENG");
|
||||
int total = point.getStqCount() + point.getWqCount();
|
||||
applyAlarmPointRange(point, total, expressionRows);
|
||||
result.add(point);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isAlarmPointVisible(String state) {
|
||||
return "large_eng_built".equals(state)
|
||||
|| "mid_eng_built".equals(state)
|
||||
|| "large_eng_ubuilt".equals(state)
|
||||
|| "mid_eng_ubuilt".equals(state);
|
||||
}
|
||||
|
||||
private String normalizeAlarmPointState(String state) {
|
||||
if ("large_eng_ubuilt".equals(state)) {
|
||||
return "large_eng_built";
|
||||
}
|
||||
if ("mid_eng_ubuilt".equals(state)) {
|
||||
return "mid_eng_built";
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
private void applyAlarmPointRange(EngAlarmPointVo point, int total, List<Map<String, Object>> expressionRows) {
|
||||
if (point == null || CollUtil.isEmpty(expressionRows)) {
|
||||
return;
|
||||
}
|
||||
for (Map<String, Object> row : expressionRows) {
|
||||
String expression = safeAlarmValue(firstPresentAlarmValue(row, "EXPRESSION", "expression"));
|
||||
if (!matchesAlarmExpression(expression, total)) {
|
||||
continue;
|
||||
}
|
||||
String nameEn = safeAlarmValue(firstPresentAlarmValue(row, "NAMEEN", "nameEn", "NAME_EN"));
|
||||
if (StrUtil.isNotBlank(nameEn)) {
|
||||
point.setAnchoPointState(point.getAnchoPointState() + "_" + nameEn);
|
||||
point.setRange(nameEn);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean matchesAlarmExpression(String range, int value) {
|
||||
if (StrUtil.isBlank(range)) {
|
||||
return false;
|
||||
}
|
||||
if (range.matches("x=\\d+")) {
|
||||
return value == Integer.parseInt(range.substring(2));
|
||||
}
|
||||
if (range.matches("x>\\d+")) {
|
||||
return value > Integer.parseInt(range.substring(2));
|
||||
}
|
||||
if (range.matches("x>=\\d+")) {
|
||||
return value >= Integer.parseInt(range.substring(3));
|
||||
}
|
||||
if (range.matches("x<\\d+")) {
|
||||
return value < Integer.parseInt(range.substring(2));
|
||||
}
|
||||
if (range.matches("x<=\\d+")) {
|
||||
return value <= Integer.parseInt(range.substring(3));
|
||||
}
|
||||
if (range.matches("\\d+<x<\\d+")) {
|
||||
String[] split = range.split("<x<");
|
||||
return value > Integer.parseInt(split[0]) && value < Integer.parseInt(split[1]);
|
||||
}
|
||||
if (range.matches("\\d+<=x<=\\d+")) {
|
||||
String[] split = range.split("<=x<=");
|
||||
return value >= Integer.parseInt(split[0]) && value <= Integer.parseInt(split[1]);
|
||||
}
|
||||
if (range.matches("\\d+<x<=\\d+")) {
|
||||
String[] split = range.split("<x<=");
|
||||
return value > Integer.parseInt(split[0]) && value <= Integer.parseInt(split[1]);
|
||||
}
|
||||
if (range.matches("\\d+<=x<\\d+")) {
|
||||
String[] split = range.split("<=x<");
|
||||
return value >= Integer.parseInt(split[0]) && value < Integer.parseInt(split[1]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Date parseAlarmPointTime(String timeText) {
|
||||
if (StrUtil.isBlank(timeText)) {
|
||||
return null;
|
||||
}
|
||||
String value = timeText.trim();
|
||||
if (value.length() <= 10) {
|
||||
return DateUtil.parse(value, "yyyy-MM-dd");
|
||||
}
|
||||
return DateUtil.parse(value, "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
private Object firstPresentAlarmValue(Map<String, Object> row, String... keys) {
|
||||
if (row == null || keys == null) {
|
||||
return null;
|
||||
}
|
||||
for (String key : keys) {
|
||||
if (row.containsKey(key)) {
|
||||
return row.get(key);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Integer toAlarmIntegerValue(Object value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
if (value instanceof Number number) {
|
||||
return number.intValue();
|
||||
}
|
||||
String text = String.valueOf(value).trim();
|
||||
if (StrUtil.isBlank(text)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(text);
|
||||
} catch (NumberFormatException ex) {
|
||||
try {
|
||||
return Double.valueOf(text).intValue();
|
||||
} catch (NumberFormatException ignore) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String safeAlarmValue(Object value) {
|
||||
return value == null ? "" : String.valueOf(value).trim();
|
||||
}
|
||||
|
||||
private String buildEngPointFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
@ -2983,6 +3349,60 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<EngRsvrcscdRvcdVo> getRsvrcscdBRvcdList(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceResult<EngRsvrcscdRvcdVo> result = new DataSourceResult<>();
|
||||
result.setAggregates(new HashMap<>());
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT DISTINCT ")
|
||||
.append("dic.HBRVCD AS wbsCode, ")
|
||||
.append("dic.HBRVNM AS wbsName, ")
|
||||
.append("dic.BASEID AS objId, ")
|
||||
.append("NVL(dic.BASEID, 'ZZZZZZZZ') AS baseOrder, ")
|
||||
.append("NVL(dic.ORDER_INDEX, 999999) AS orderIndex ")
|
||||
.append("FROM SD_HBRV_DIC dic ")
|
||||
.append("INNER JOIN SD_RSVRCSCD_B r ON r.RVCD = dic.HBRVCD AND NVL(r.IS_DELETED, 0) = 0 ")
|
||||
.append("WHERE NVL(dic.IS_DELETED, 0) = 0 ")
|
||||
.append("AND NVL(dic.ENABLED, 1) = 1 ");
|
||||
|
||||
// 动态过滤条件(原有代码)
|
||||
appendRsvrcscdRvcdPresetFilters(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), sql, paramMap, new int[]{0});
|
||||
|
||||
// 使用别名排序
|
||||
sql.append(" ORDER BY baseOrder ASC, orderIndex ASC, wbsCode ASC");
|
||||
|
||||
List<EngRsvrcscdRvcdVo> list = microservicDynamicSQLMapper.getAllListWithResultType(
|
||||
sql.toString(), paramMap, EngRsvrcscdRvcdVo.class);
|
||||
result.setData(list);
|
||||
result.setTotal(list.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<EngQgcRvcdVo> getQgcRvcdList(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceResult<EngQgcRvcdVo> result = new DataSourceResult<>();
|
||||
result.setAggregates(new HashMap<>());
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT DISTINCT ")
|
||||
.append("rv.RVCD AS rvcd, ")
|
||||
.append("rv.RVNM AS rvnm, ")
|
||||
.append("NVL(rv.ORDER_INDEX, 999999) AS order_index ")
|
||||
.append("FROM SD_RVCD_DIC rv ")
|
||||
.append("INNER JOIN MS_LYSXJGX_B rel ON rel.QGC_RVCD = rv.RVCD AND NVL(rel.IS_DELETED, 0) = 0 ")
|
||||
.append("WHERE NVL(rv.IS_DELETED, 0) = 0 ")
|
||||
.append("AND NVL(rv.ENABLED, 1) = 1 ")
|
||||
.append("ORDER BY order_index ASC, rv.RVCD ASC");
|
||||
|
||||
List<EngQgcRvcdVo> list = microservicDynamicSQLMapper.getAllListWithResultType(
|
||||
sql.toString(), new HashMap<>(), EngQgcRvcdVo.class);
|
||||
result.setData(list);
|
||||
result.setTotal(list.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
private String buildRsvrcscdBFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
@ -3123,4 +3543,125 @@ public class SdEngInfoBHServiceImpl extends ServiceImpl<SdEngInfoBHMapper, SdEng
|
||||
}
|
||||
return " ORDER BY " + String.join(", ", orderItems);
|
||||
}
|
||||
|
||||
private void appendRsvrcscdRvcdPresetFilters(DataSourceRequest.FilterDescriptor filter,
|
||||
StringBuilder sql,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
if (filter == null) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.hasText(filter.getField())) {
|
||||
String field = filter.getField();
|
||||
String operator = filter.getOperator() == null ? "eq" : filter.getOperator().toLowerCase();
|
||||
Object value = filter.getValue();
|
||||
if (!StringUtils.hasText(operator)) {
|
||||
operator = "eq";
|
||||
}
|
||||
if ("baseId".equals(field)) {
|
||||
appendRsvrcscdRvcdLeafCondition(sql, "dic.BASEID", operator, value, paramMap, indexHolder);
|
||||
return;
|
||||
}
|
||||
if ("treeLevel".equals(field)) {
|
||||
appendRsvrcscdRvcdLeafCondition(sql, "dic.GRD", operator, value, paramMap, indexHolder);
|
||||
return;
|
||||
}
|
||||
if ("wbsType".equals(field)) {
|
||||
// 旧口径走 SD_WBS_B.WBS_TYPE,这里已固定替换成 SD_HBRV_DIC,保留参数但不参与过滤。
|
||||
return;
|
||||
}
|
||||
if ("wbsCode".equals(field)) {
|
||||
appendRsvrcscdRvcdLeafCondition(sql, "dic.HBRVCD", operator, value, paramMap, indexHolder);
|
||||
return;
|
||||
}
|
||||
if ("wbsName".equals(field)) {
|
||||
appendRsvrcscdRvcdLeafCondition(sql, "dic.HBRVNM", operator, value, paramMap, indexHolder);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (filter.getFilters() == null || filter.getFilters().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) {
|
||||
appendRsvrcscdRvcdPresetFilters(child, sql, paramMap, indexHolder);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendRsvrcscdRvcdLeafCondition(StringBuilder sql,
|
||||
String column,
|
||||
String operator,
|
||||
Object value,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
if (!StringUtils.hasText(column)) {
|
||||
return;
|
||||
}
|
||||
if ("isnull".equals(operator)) {
|
||||
sql.append(" AND ").append(column).append(" IS NULL ");
|
||||
return;
|
||||
}
|
||||
if ("isnotnull".equals(operator)) {
|
||||
sql.append(" AND ").append(column).append(" IS NOT NULL ");
|
||||
return;
|
||||
}
|
||||
if ("in".equals(operator)) {
|
||||
List<Object> values = normalizeFilterValues(value);
|
||||
if (values.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
for (Object item : values) {
|
||||
String key = "rsvrcdRvcdParam" + indexHolder[0]++;
|
||||
paramMap.put(key, item);
|
||||
placeholders.add("#{map." + key + "}");
|
||||
}
|
||||
sql.append(" AND ").append(column).append(" IN (").append(String.join(", ", placeholders)).append(") ");
|
||||
return;
|
||||
}
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
String key = "rsvrcdRvcdParam" + indexHolder[0]++;
|
||||
switch (operator) {
|
||||
case "eq" -> {
|
||||
paramMap.put(key, value);
|
||||
sql.append(" AND ").append(column).append(" = #{map.").append(key).append("} ");
|
||||
}
|
||||
case "neq" -> {
|
||||
paramMap.put(key, value);
|
||||
sql.append(" AND ").append(column).append(" <> #{map.").append(key).append("} ");
|
||||
}
|
||||
case "contains" -> {
|
||||
paramMap.put(key, "%" + value + "%");
|
||||
sql.append(" AND ").append(column).append(" LIKE #{map.").append(key).append("} ");
|
||||
}
|
||||
case "startswith" -> {
|
||||
paramMap.put(key, value + "%");
|
||||
sql.append(" AND ").append(column).append(" LIKE #{map.").append(key).append("} ");
|
||||
}
|
||||
case "endswith" -> {
|
||||
paramMap.put(key, "%" + value);
|
||||
sql.append(" AND ").append(column).append(" LIKE #{map.").append(key).append("} ");
|
||||
}
|
||||
case "gt" -> {
|
||||
paramMap.put(key, value);
|
||||
sql.append(" AND ").append(column).append(" > #{map.").append(key).append("} ");
|
||||
}
|
||||
case "gte" -> {
|
||||
paramMap.put(key, value);
|
||||
sql.append(" AND ").append(column).append(" >= #{map.").append(key).append("} ");
|
||||
}
|
||||
case "lt" -> {
|
||||
paramMap.put(key, value);
|
||||
sql.append(" AND ").append(column).append(" < #{map.").append(key).append("} ");
|
||||
}
|
||||
case "lte" -> {
|
||||
paramMap.put(key, value);
|
||||
sql.append(" AND ").append(column).append(" <= #{map.").append(key).append("} ");
|
||||
}
|
||||
default -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5939,7 +5939,7 @@ public class EngEqDataServiceImpl implements EngEqDataService {
|
||||
.append(" WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' ")
|
||||
.append(") siteSort ON siteSort.RVCD = eng.HBRVCD AND siteSort.STCD = a.STCD ")
|
||||
.append("WHERE NVL(a.IS_DELETED, 0) = 0 ")
|
||||
.append("AND NVL(a.USFL, 1) = 1 ")
|
||||
// .append("AND NVL(a.USFL, 1) = 1 ")
|
||||
.append("AND a.LGTD IS NOT NULL ")
|
||||
.append("AND a.LTTD IS NOT NULL ")
|
||||
.append("AND a.STTP IN (SELECT STTP_CODE FROM SD_STTP_B WHERE DESCRIPTION = 'EQ') ")
|
||||
|
||||
@ -152,4 +152,10 @@ public class FbStationController {
|
||||
public ResponseResult getFbPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(fbStationService.getFbPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/point/built/GetKendoListCust")
|
||||
@Operation(summary = "增殖站地图描点接口(仅查询在建状态的)")
|
||||
public ResponseResult getFbBuiltPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(fbStationService.getFbBuiltPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
}
|
||||
|
||||
@ -65,4 +65,6 @@ public interface FbStationService {
|
||||
DataSourceResult<TableVo> getFishbreedrFishKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<FbTracingPointVo> getFbPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<FbTracingPointVo> getFbBuiltPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
}
|
||||
|
||||
@ -4577,6 +4577,15 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
|
||||
@Override
|
||||
public DataSourceResult<FbTracingPointVo> getFbPointKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||
return queryFbPointKendoListCust(dataSourceRequest, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<FbTracingPointVo> getFbBuiltPointKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||
return queryFbPointKendoListCust(dataSourceRequest, true);
|
||||
}
|
||||
|
||||
private DataSourceResult<FbTracingPointVo> queryFbPointKendoListCust(DataSourceRequest dataSourceRequest, boolean builtMode) {
|
||||
DataSourceResult<FbTracingPointVo> dataSourceResult = new DataSourceResult<>();
|
||||
dataSourceResult.setAggregates(new HashMap<>());
|
||||
|
||||
@ -4589,6 +4598,9 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
DataSourceLoadOptionsBase devRequest = dataSourceRequest.toDevRequest();
|
||||
String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(devRequest, "rstcd");
|
||||
String sttp = QgcQueryWrapperUtil.getFilterFieldValue(devRequest, "sttp");
|
||||
if(StrUtil.isBlank(sttp)){
|
||||
sttp= QgcQueryWrapperUtil.getFilterFieldValue(devRequest, "sttpCode");
|
||||
}
|
||||
String bldsttCcode = QgcQueryWrapperUtil.getFilterFieldValue(devRequest, "bldsttCcode");
|
||||
|
||||
if (StrUtil.isEmpty(sttp)) {
|
||||
@ -4648,7 +4660,7 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
.append(" AND t.TM BETWEEN ADD_MONTHS(SYSDATE, -12) AND SYSDATE ")
|
||||
.append(" GROUP BY t.RSTCD ")
|
||||
.append(") b ON a.STCD = b.stcd ")
|
||||
.append("WHERE NVL(a.USFL, 1) = 1 ")
|
||||
.append("WHERE 1 = 1 ")
|
||||
.append("AND a.LGTD IS NOT NULL ")
|
||||
.append("AND a.LTTD IS NOT NULL ");
|
||||
|
||||
@ -4670,7 +4682,7 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
|
||||
|
||||
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
|
||||
dataSourceRequest == null ? null : dataSourceRequest.getFilter(),
|
||||
dataSourceRequest.getFilter(),
|
||||
paramMap,
|
||||
new int[]{0},
|
||||
this::mapWeFvColumn
|
||||
@ -4683,7 +4695,12 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
Page<?> page = devRequest == null ? null : QgcQueryWrapperUtil.buildPage(devRequest, devRequest.getSkip(), devRequest.getTake());
|
||||
List<FbTracingPointVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, FbTracingPointVo.class);
|
||||
|
||||
if (builtMode) {
|
||||
enrichFbBuiltPointYearStatistics(list, sttp);
|
||||
list = getBuiltPointLegend(list);
|
||||
} else {
|
||||
list = getPointLegend(list);
|
||||
}
|
||||
|
||||
SiteAvoidanceUtils.calcSiteMapLev(list,
|
||||
FbTracingPointVo::getStcd,
|
||||
@ -4697,6 +4714,53 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
private void enrichFbBuiltPointYearStatistics(List<FbTracingPointVo> list, String sttp) {
|
||||
if (CollUtil.isEmpty(list) || !"FB".equalsIgnoreCase(sttp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String currentYear = String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
|
||||
Map<String, Object> planParamMap = new HashMap<>();
|
||||
planParamMap.put("yr", currentYear);
|
||||
String planSql = "SELECT plan.RSTCD AS stcd, SUM(det.FCNT) AS fcnt "
|
||||
+ "FROM SD_ENGFRPLAN_B plan "
|
||||
+ "INNER JOIN SD_ENGFRPLANDET_B det ON plan.ID = det.RPJH_ID "
|
||||
+ "WHERE NVL(plan.IS_DELETED, 0) = 0 "
|
||||
+ "AND NVL(det.IS_DELETED, 0) = 0 "
|
||||
+ "AND TO_CHAR(plan.PLANSD, 'YYYY') = #{map.yr} "
|
||||
+ "GROUP BY plan.RSTCD";
|
||||
List<FbPointCountVo> planList = microservicDynamicSQLMapper.getAllListWithResultType(planSql, planParamMap, FbPointCountVo.class);
|
||||
|
||||
Map<String, Object> actualParamMap = new HashMap<>();
|
||||
actualParamMap.put("yr", currentYear);
|
||||
String actualSql = "SELECT run.RSTCD AS stcd, SUM(det.FCNT) AS fcnt "
|
||||
+ "FROM SD_ENGFR_R run "
|
||||
+ "INNER JOIN SD_RPIMNFISH_R det ON run.ID = det.RPIMN_ID "
|
||||
+ "WHERE NVL(run.IS_DELETED, 0) = 0 "
|
||||
+ "AND NVL(det.IS_DELETED, 0) = 0 "
|
||||
+ "AND TO_CHAR(run.TM, 'YYYY') = #{map.yr} "
|
||||
+ "GROUP BY run.RSTCD";
|
||||
List<FbPointCountVo> actualList = microservicDynamicSQLMapper.getAllListWithResultType(actualSql, actualParamMap, FbPointCountVo.class);
|
||||
|
||||
Map<String, Long> planMap = planList.stream()
|
||||
.filter(item -> StrUtil.isNotBlank(item.getStcd()))
|
||||
.collect(Collectors.toMap(FbPointCountVo::getStcd, FbPointCountVo::getFcnt, (left, right) -> left));
|
||||
Map<String, Long> actualMap = actualList.stream()
|
||||
.filter(item -> StrUtil.isNotBlank(item.getStcd()))
|
||||
.collect(Collectors.toMap(FbPointCountVo::getStcd, FbPointCountVo::getFcnt, (left, right) -> left));
|
||||
|
||||
list.forEach(item -> {
|
||||
Long planCount = planMap.get(item.getStcd());
|
||||
Long actualCount = actualMap.get(item.getStcd());
|
||||
item.setYr(currentYear);
|
||||
item.setJhCnt(planCount);
|
||||
item.setFished(actualCount);
|
||||
if (planCount != null) {
|
||||
item.setUnfished(actualCount == null ? planCount : Math.max(planCount - actualCount, 0L));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String mapWeFvColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
@ -4705,6 +4769,7 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
case "rstcd" -> "a.RSTCD";
|
||||
case "stcd" -> "a.STCD";
|
||||
case "sttp" -> "a.STTP";
|
||||
case "sttpcode" -> "a.STTP";
|
||||
case "bldsttccode" -> "a.BLDSTT_CODE";
|
||||
case "lgtd" -> "a.LGTD";
|
||||
default -> null;
|
||||
@ -4727,4 +4792,41 @@ public class FbStationServiceImpl implements FbStationService {
|
||||
}
|
||||
return voList;
|
||||
}
|
||||
|
||||
private List<FbTracingPointVo> getBuiltPointLegend(List<FbTracingPointVo> voList) {
|
||||
for (FbTracingPointVo pointVo : voList) {
|
||||
Integer bldstt = pointVo.getBldstt();
|
||||
String sttp = pointVo.getSttp();
|
||||
if (bldstt != null && bldstt == 1) {
|
||||
if ("FB".equals(sttp)) {
|
||||
pointVo.setAnchoPointState("fb_built");
|
||||
}
|
||||
if ("SG".equals(sttp)) {
|
||||
pointVo.setAnchoPointState("sg_built");
|
||||
}
|
||||
}
|
||||
}
|
||||
return voList;
|
||||
}
|
||||
|
||||
private static class FbPointCountVo {
|
||||
private String stcd;
|
||||
private Long fcnt;
|
||||
|
||||
public String getStcd() {
|
||||
return stcd;
|
||||
}
|
||||
|
||||
public void setStcd(String stcd) {
|
||||
this.stcd = stcd;
|
||||
}
|
||||
|
||||
public Long getFcnt() {
|
||||
return fcnt;
|
||||
}
|
||||
|
||||
public void setFcnt(Long fcnt) {
|
||||
this.fcnt = fcnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1955,13 +1955,13 @@ public class FhHabitatServiceImpl implements FhHabitatService {
|
||||
.append("t.DTIN AS dtin ")
|
||||
.append("FROM ( ")
|
||||
.append(" SELECT STCD, STNM, 'FH' AS STTP_CODE, RSTCD, BASE_ID, HBRVCD, LGTD, LTTD, BLPRD AS BLDSTT_CCODE, ELEV, DTIN ")
|
||||
.append(" FROM SD_FHBT_B_H WHERE NVL(IS_DELETED, 0) = 0 AND USFL = 1 ")
|
||||
.append(" FROM SD_FHBT_B_H WHERE NVL(IS_DELETED, 0) = 0 ")
|
||||
.append(" UNION ALL ")
|
||||
.append(" SELECT STCD, STNM, STTP AS STTP_CODE, RSTCD, BASE_ID, HBRVCD, LGTD, LTTD, BLDSTT_CODE AS BLDSTT_CCODE, ELEV, DTIN ")
|
||||
.append(" FROM SD_VA_B_H WHERE NVL(IS_DELETED, 0) = 0 AND USFL = 1 ")
|
||||
.append(" FROM SD_VA_B_H WHERE NVL(IS_DELETED, 0) = 0 ")
|
||||
.append(" UNION ALL ")
|
||||
.append(" SELECT STCD, STNM, STTP AS STTP_CODE, RSTCD, BASE_ID, HBRVCD, LGTD, LTTD, BLDSTT_CODE AS BLDSTT_CCODE, ELEV, DTIN ")
|
||||
.append(" FROM SD_VP_B_H WHERE NVL(IS_DELETED, 0) = 0 AND USFL = 1 ")
|
||||
.append(" FROM SD_VP_B_H WHERE NVL(IS_DELETED, 0) = 0 ")
|
||||
.append(") t ")
|
||||
.append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = t.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ")
|
||||
.append("LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(t.BASE_ID, eng.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 ")
|
||||
|
||||
@ -106,6 +106,12 @@ public class FishPassageController {
|
||||
return ResponseResult.successData(fpBuildService.getStInfoByStcd(stcd));
|
||||
}
|
||||
|
||||
@PostMapping("/point/qgc/GetKendoListCust")
|
||||
@Operation(summary = "环保部-过鱼设施描点接口")
|
||||
public ResponseResult getQgcFpPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(fpBuildService.getQgcFpPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/point/built/GetKendoListCust")
|
||||
@Operation(summary = "过鱼设施地图描点接口(仅查询在建状态的)")
|
||||
public ResponseResult getFpBuiltPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
|
||||
@ -15,6 +15,9 @@ public class FpAnchoPointVo {
|
||||
@Schema(description = "站名")
|
||||
private String stnm;
|
||||
|
||||
@Schema(description = "站点图片")
|
||||
private String logo;
|
||||
|
||||
@Schema(description = "弹框站点名称")
|
||||
private String titleName;
|
||||
|
||||
@ -45,6 +48,9 @@ public class FpAnchoPointVo {
|
||||
@Schema(description = "运行状态")
|
||||
private String run;
|
||||
|
||||
@Schema(description = "运行状态名称")
|
||||
private String runName;
|
||||
|
||||
@Schema(description = "设施类型")
|
||||
private String dwtp;
|
||||
|
||||
@ -78,9 +84,21 @@ public class FpAnchoPointVo {
|
||||
@Schema(description = "达标状态子类型")
|
||||
private Integer stdSstate;
|
||||
|
||||
@Schema(description = "达标状态子类型名称")
|
||||
private String stdSstateName;
|
||||
|
||||
@Schema(description = "地图避让")
|
||||
private Integer distance;
|
||||
|
||||
@Schema(description = "澜沧江运行状态")
|
||||
private Integer lcjStatus;
|
||||
|
||||
@Schema(description = "澜沧江运行状态名称")
|
||||
private String lcjStatusName;
|
||||
|
||||
@Schema(description = "年份")
|
||||
private String yr;
|
||||
|
||||
@Schema(description = "过鱼种类")
|
||||
private Integer ftpTypeCount;
|
||||
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.yfd.platform.qgc_env.fp.entity.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "过鱼设施鱼类统计")
|
||||
public class FpFishStatisticsVo {
|
||||
|
||||
@Schema(description = "站点编码")
|
||||
private String stcd;
|
||||
|
||||
@Schema(description = "鱼类名称")
|
||||
private String ftp;
|
||||
|
||||
@Schema(description = "鱼编码")
|
||||
private String fishId;
|
||||
|
||||
@Schema(description = "数量")
|
||||
private Integer count;
|
||||
}
|
||||
@ -21,5 +21,7 @@ public interface FpBuildService {
|
||||
|
||||
FpVmsstbprptVo getStInfoByStcd(String stcd);
|
||||
|
||||
DataSourceResult<FpAnchoPointVo> getQgcFpPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<FpAnchoPointVo> getFpBuiltPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import com.yfd.platform.common.exception.BizException;
|
||||
import com.yfd.platform.qgc_env.fp.entity.vo.FpAnchoPointVo;
|
||||
import com.yfd.platform.qgc_env.fp.entity.vo.FpConstructionSituationVo;
|
||||
import com.yfd.platform.qgc_env.fp.entity.vo.FpFishDicVo;
|
||||
import com.yfd.platform.qgc_env.fp.entity.vo.FpFishStatisticsVo;
|
||||
import com.yfd.platform.qgc_env.fp.entity.vo.FpVmsstbprptVo;
|
||||
import com.yfd.platform.qgc_env.wt.utils.SiteAvoidanceUtils;
|
||||
import com.yfd.platform.qgc_env.fp.service.FpBuildService;
|
||||
@ -28,6 +29,8 @@ import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class FpBuildServiceImpl implements FpBuildService {
|
||||
@ -214,6 +217,99 @@ public class FpBuildServiceImpl implements FpBuildService {
|
||||
return list.getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<FpAnchoPointVo> getQgcFpPointKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceResult<FpAnchoPointVo> dataSourceResult = new DataSourceResult<>();
|
||||
dataSourceResult.setAggregates(new HashMap<>());
|
||||
if (dataSourceRequest == null) {
|
||||
dataSourceResult.setData(new ArrayList<>());
|
||||
dataSourceResult.setTotal(0L);
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
StringBuilder sql = new StringBuilder("SELECT " +
|
||||
"fp.STCD AS stcd, " +
|
||||
"fp.STNM AS stnm, " +
|
||||
"fp.LOGO AS logo, " +
|
||||
"fp.STNM AS titleName, " +
|
||||
"fp.BLDSTT_CODE AS bldsttCcode, " +
|
||||
"fp.BLDSTT_CODE AS bldstt, " +
|
||||
"fp.LTTD AS lttd, " +
|
||||
"fp.LGTD AS lgtd, " +
|
||||
"fp.ELEV AS dtmel, " +
|
||||
"fp.RSTCD AS rstcds, " +
|
||||
"eng.ENNM AS ennm, " +
|
||||
"'FP' AS sttpCode, " +
|
||||
"state.RUN_STATE AS run, " +
|
||||
"CASE WHEN state.RUN_STATE = 1 THEN '运行中' WHEN state.RUN_STATE IN (0, 2) THEN '未运行' ELSE NULL END AS runName, " +
|
||||
"fp.STTP AS dwtp, " +
|
||||
"CASE " +
|
||||
"WHEN fp.STTP = 'FP_1' THEN '鱼道' " +
|
||||
"WHEN fp.STTP = 'FP_2' THEN '仿自然通道' " +
|
||||
"WHEN fp.STTP = 'FP_3' THEN '集运鱼系统' " +
|
||||
"WHEN fp.STTP = 'FP_4' THEN '升鱼机' " +
|
||||
"ELSE '其它' END AS dwtpName, " +
|
||||
"fp.STTP AS sttpMap, " +
|
||||
"eng.RVCD AS rvcd, " +
|
||||
"eng.ADDVCD AS addvcd, " +
|
||||
"eng.BASE_ID AS baseId, " +
|
||||
"fp.STTP AS sttp, " +
|
||||
"CASE " +
|
||||
"WHEN fp.STTP = 'FP_1' THEN 'GY_1' " +
|
||||
"WHEN fp.STTP = 'FP_2' THEN 'GY_2' " +
|
||||
"WHEN fp.STTP = 'FP_3' THEN 'GY_3' " +
|
||||
"WHEN fp.STTP = 'FP_4' THEN 'GY_4' " +
|
||||
"ELSE 'GY_5' END AS anchoPointState, " +
|
||||
"fp.MWAY AS mway, " +
|
||||
"fp.DTIN AS dtin, " +
|
||||
"state.STD_SSTATE AS stdSstate, " +
|
||||
"CASE WHEN state.STD_SSTATE = 1 THEN '正常运行' " +
|
||||
"WHEN state.STD_SSTATE IN (0, 2) THEN '暂无数据' " +
|
||||
"WHEN state.STD_SSTATE = 3 THEN '未正常运行' ELSE NULL END AS stdSstateName, " +
|
||||
"CASE WHEN recent.STCD IS NULL THEN 2 ELSE 1 END AS lcjStatus, " +
|
||||
"CASE WHEN recent.STCD IS NULL THEN '暂无数据' ELSE '正常运行' END AS lcjStatusName, " +
|
||||
"fp.ORDER_INDEX AS orderIndex " +
|
||||
"FROM SD_FPSS_B_H fp " +
|
||||
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
|
||||
"LEFT JOIN (SELECT s.STCD, s.RUN_STATE, s.STD_SSTATE " +
|
||||
" FROM MS_STSTATE_T s " +
|
||||
" INNER JOIN (SELECT STCD, MAX(YR) AS YR FROM MS_STSTATE_T WHERE NVL(IS_DELETED, 0) = 0 GROUP BY STCD) latest " +
|
||||
" ON latest.STCD = s.STCD AND latest.YR = s.YR " +
|
||||
" WHERE NVL(s.IS_DELETED, 0) = 0) state ON state.STCD = fp.STCD " +
|
||||
"LEFT JOIN (SELECT STCD FROM SD_FPSSRL_R WHERE NVL(IS_DELETED, 0) = 0 AND TM BETWEEN ADD_MONTHS(SYSDATE, -12) AND SYSDATE GROUP BY STCD " +
|
||||
" UNION " +
|
||||
" SELECT STCD FROM SD_FPSS_R WHERE NVL(IS_DELETED, 0) = 0 AND STRDT >= ADD_MONTHS(SYSDATE, -12) AND NVL(ENDDT, STRDT) <= SYSDATE GROUP BY STCD) recent " +
|
||||
"ON recent.STCD = fp.STCD " +
|
||||
"WHERE NVL(fp.IS_DELETED, 0) = 0 AND fp.STTP !='FPQ'");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
|
||||
String filterSql = buildFpPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql).append(" ");
|
||||
}
|
||||
sql.append(buildFpPointOrderBySql(dataSourceRequest.getSort()));
|
||||
|
||||
Page<?> page = QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
|
||||
List<FpAnchoPointVo> resultList = microservicDynamicSQLMapper.pageAllListWithResultType(
|
||||
page, sql.toString(), paramMap, FpAnchoPointVo.class);
|
||||
|
||||
if (CollUtil.isNotEmpty(resultList)) {
|
||||
fillQgcFpPointStatistics(resultList);
|
||||
applyFpPointLegend(resultList);
|
||||
SiteAvoidanceUtils.calcSiteMapLev(resultList,
|
||||
FpAnchoPointVo::getStcd,
|
||||
FpAnchoPointVo::getLgtd,
|
||||
FpAnchoPointVo::getLttd,
|
||||
FpAnchoPointVo::getAnchoPointState,
|
||||
FpAnchoPointVo::setDistance);
|
||||
}
|
||||
|
||||
dataSourceResult.setData(resultList);
|
||||
dataSourceResult.setTotal(page == null ? resultList.size() : page.getTotal());
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
private String buildFishDicBaseSql() {
|
||||
return "SELECT " +
|
||||
"src.ID AS id, " +
|
||||
@ -1185,12 +1281,17 @@ public class FpBuildServiceImpl implements FpBuildService {
|
||||
" fp.DTIN AS dtin\n" +
|
||||
"FROM SD_FPSS_B_H fp\n" +
|
||||
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0\n" +
|
||||
"WHERE NVL(fp.IS_DELETED, 0) = 0 AND fp.BLDSTT_CODE = 1 AND fp.LGTD IS NOT NULL AND fp.LTTD IS NOT NULL ");
|
||||
"WHERE NVL(fp.IS_DELETED, 0) = 0 ");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
|
||||
String filterSql = buildFpPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
|
||||
dataSourceRequest.getFilter(),
|
||||
paramMap,
|
||||
new int[]{0},
|
||||
this::mapFpColumn
|
||||
);
|
||||
// String filterSql = buildFpPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql).append(" ");
|
||||
}
|
||||
@ -1227,6 +1328,205 @@ public class FpBuildServiceImpl implements FpBuildService {
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
private void fillQgcFpPointStatistics(List<FpAnchoPointVo> pointList) {
|
||||
List<String> stcdList = pointList.stream()
|
||||
.map(FpAnchoPointVo::getStcd)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isEmpty(stcdList)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String year = queryLatestFpYear(stcdList);
|
||||
List<FpFishStatisticsVo> manualList = queryQgcFpManualFishStatistics(stcdList, year);
|
||||
Set<String> manualStcdSet = manualList.stream()
|
||||
.map(FpFishStatisticsVo::getStcd)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
List<String> autoQueryStcdList = stcdList.stream()
|
||||
.filter(stcd -> !manualStcdSet.contains(stcd))
|
||||
.collect(Collectors.toList());
|
||||
List<FpFishStatisticsVo> autoList = queryQgcFpAutoFishStatistics(autoQueryStcdList, year);
|
||||
if (CollUtil.isNotEmpty(autoList)) {
|
||||
manualList.addAll(autoList);
|
||||
}
|
||||
Map<String, List<FpFishStatisticsVo>> stcdDataMap = manualList.stream()
|
||||
.collect(Collectors.groupingBy(FpFishStatisticsVo::getStcd));
|
||||
for (FpAnchoPointVo vo : pointList) {
|
||||
vo.setYr(year);
|
||||
List<FpFishStatisticsVo> fishStatistics = stcdDataMap.get(vo.getStcd());
|
||||
if (CollUtil.isEmpty(fishStatistics)) {
|
||||
continue;
|
||||
}
|
||||
vo.setFtpTypeCount(fishStatistics.size());
|
||||
vo.setFtpCount(fishStatistics.stream()
|
||||
.filter(item -> item.getCount() != null)
|
||||
.mapToInt(FpFishStatisticsVo::getCount)
|
||||
.sum());
|
||||
}
|
||||
}
|
||||
|
||||
private String queryLatestFpYear(List<String> stcdList) {
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
StringBuilder sql = new StringBuilder("SELECT MAX(t.YR) AS yr FROM (" +
|
||||
"SELECT TO_CHAR(STRDT, 'yyyy') AS YR, STCD FROM SD_FPSS_R WHERE NVL(IS_DELETED, 0) = 0 " +
|
||||
"UNION ALL " +
|
||||
"SELECT TO_CHAR(TM, 'yyyy') AS YR, STCD FROM SD_FPSSRL_R WHERE NVL(IS_DELETED, 0) = 0) t WHERE 1 = 1 ");
|
||||
appendInCondition(sql, paramMap, "t.STCD", stcdList, "fpYear");
|
||||
List<FpAnchoPointVo> list = microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, FpAnchoPointVo.class);
|
||||
if (CollUtil.isEmpty(list) || StrUtil.isBlank(list.getFirst().getYr())) {
|
||||
return String.valueOf(java.time.LocalDate.now().getYear());
|
||||
}
|
||||
return list.getFirst().getYr();
|
||||
}
|
||||
|
||||
private List<FpFishStatisticsVo> queryQgcFpManualFishStatistics(List<String> stcdList, String year) {
|
||||
if (CollUtil.isEmpty(stcdList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
StringBuilder sql = new StringBuilder("SELECT data.STCD AS stcd, data.FTP AS fishId, dict.NAME AS ftp, SUM(data.FCNT) AS count " +
|
||||
"FROM (SELECT t.STCD, t.FTP, t.FCNT, eng.HBRVCD " +
|
||||
" FROM SD_FPSS_R t " +
|
||||
" INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD AND NVL(fp.IS_DELETED, 0) = 0 " +
|
||||
" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
|
||||
" WHERE NVL(t.IS_DELETED, 0) = 0 ");
|
||||
paramMap.put("manualYear", year);
|
||||
sql.append(" AND TO_CHAR(t.STRDT, 'yyyy') = #{map.manualYear}) data ")
|
||||
.append("INNER JOIN (SELECT DISTINCT rel.FISH_ID, rel.RVCD, dic.NAME " +
|
||||
" FROM SD_FISHDICTORY_RLTN_B rel " +
|
||||
" LEFT JOIN SD_FISHDICTORY_B dic ON dic.ID = rel.ZY_FISH_ID " +
|
||||
" WHERE NVL(rel.IS_DELETED, 0) = 0 AND NVL(dic.IS_DELETED, 0) = 0 " +
|
||||
" AND (rel.FISH_ID <> rel.ZY_FISH_ID OR rel.RVCD = 'ZY')) dict " +
|
||||
"ON dict.FISH_ID = data.FTP AND (dict.RVCD = data.HBRVCD OR dict.RVCD = 'ZY') WHERE 1 = 1 ");
|
||||
appendInCondition(sql, paramMap, "data.STCD", stcdList, "fpManual");
|
||||
sql.append(" GROUP BY data.STCD, data.FTP, dict.NAME");
|
||||
return microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, FpFishStatisticsVo.class);
|
||||
}
|
||||
|
||||
private List<FpFishStatisticsVo> queryQgcFpAutoFishStatistics(List<String> stcdList, String year) {
|
||||
if (CollUtil.isEmpty(stcdList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
StringBuilder sql = new StringBuilder("SELECT data.STCD AS stcd, data.FTP AS fishId, dict.NAME AS ftp, SUM(data.FCNT) AS count " +
|
||||
"FROM (SELECT t.STCD, t.FTP, t.FCNT, eng.HBRVCD " +
|
||||
" FROM SD_FPSSRL_R t " +
|
||||
" INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD AND NVL(fp.IS_DELETED, 0) = 0 " +
|
||||
" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
|
||||
" WHERE NVL(t.IS_DELETED, 0) = 0 ");
|
||||
paramMap.put("autoYear", year);
|
||||
sql.append(" AND TO_CHAR(t.TM, 'yyyy') = #{map.autoYear}) data ")
|
||||
.append("INNER JOIN (SELECT DISTINCT rel.FISH_ID, rel.RVCD, dic.NAME " +
|
||||
" FROM SD_FISHDICTORY_RLTN_B rel " +
|
||||
" LEFT JOIN SD_FISHDICTORY_B dic ON dic.ID = rel.ZY_FISH_ID " +
|
||||
" WHERE NVL(rel.IS_DELETED, 0) = 0 AND NVL(dic.IS_DELETED, 0) = 0 " +
|
||||
" AND (rel.FISH_ID <> rel.ZY_FISH_ID OR rel.RVCD = 'ZY')) dict " +
|
||||
"ON dict.FISH_ID = data.FTP AND (dict.RVCD = data.HBRVCD OR dict.RVCD = 'ZY') WHERE 1 = 1 ");
|
||||
appendInCondition(sql, paramMap, "data.STCD", stcdList, "fpAuto");
|
||||
sql.append(" GROUP BY data.STCD, data.FTP, dict.NAME");
|
||||
return microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, FpFishStatisticsVo.class);
|
||||
}
|
||||
|
||||
private void applyFpPointLegend(List<FpAnchoPointVo> voList) {
|
||||
for (FpAnchoPointVo pointVo : voList) {
|
||||
if (!"2".equals(pointVo.getBldstt())) {
|
||||
if ("FP_1".equals(pointVo.getSttp())) {
|
||||
pointVo.setAnchoPointState("GY_1_INCOMPLETE");
|
||||
} else if ("FP_2".equals(pointVo.getSttp())) {
|
||||
pointVo.setAnchoPointState("GY_2_INCOMPLETE");
|
||||
} else if ("FP_3".equals(pointVo.getSttp())) {
|
||||
pointVo.setAnchoPointState("GY_3_INCOMPLETE");
|
||||
} else if ("FP_4".equals(pointVo.getSttp())) {
|
||||
pointVo.setAnchoPointState("GY_4_INCOMPLETE");
|
||||
} else {
|
||||
pointVo.setAnchoPointState("GY_5_INCOMPLETE");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void appendInCondition(StringBuilder sql,
|
||||
Map<String, Object> paramMap,
|
||||
String column,
|
||||
List<String> values,
|
||||
String prefix) {
|
||||
if (CollUtil.isEmpty(values)) {
|
||||
return;
|
||||
}
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
int index = 0;
|
||||
for (String value : values) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
String key = prefix + index++;
|
||||
paramMap.put(key, value);
|
||||
placeholders.add("#{map." + key + "}");
|
||||
}
|
||||
if (CollUtil.isEmpty(placeholders)) {
|
||||
return;
|
||||
}
|
||||
sql.append(" AND ").append(column).append(" IN (")
|
||||
.append(String.join(", ", placeholders))
|
||||
.append(") ");
|
||||
}
|
||||
|
||||
private String buildFpPointOrderBySql(List<DataSourceRequest.SortDescriptor> sorts) {
|
||||
if (CollUtil.isEmpty(sorts)) {
|
||||
return " ORDER BY fp.ORDER_INDEX ASC NULLS LAST, fp.STCD ASC";
|
||||
}
|
||||
List<String> orderItems = new ArrayList<>();
|
||||
for (DataSourceRequest.SortDescriptor sort : sorts) {
|
||||
if (sort == null || StrUtil.isBlank(sort.getField())) {
|
||||
continue;
|
||||
}
|
||||
String column = mapFpPointOrderColumn(sort.getField());
|
||||
if (StrUtil.isBlank(column)) {
|
||||
continue;
|
||||
}
|
||||
String direction = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC";
|
||||
orderItems.add(column + " " + direction + " NULLS LAST");
|
||||
}
|
||||
if (orderItems.isEmpty()) {
|
||||
return " ORDER BY fp.ORDER_INDEX ASC NULLS LAST, fp.STCD ASC";
|
||||
}
|
||||
return " ORDER BY " + String.join(", ", orderItems);
|
||||
}
|
||||
|
||||
private String mapFpPointOrderColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
return switch (field) {
|
||||
case "stcd" -> "fp.STCD";
|
||||
case "stnm", "titleName" -> "fp.STNM";
|
||||
case "bldsttCcode", "bldstt" -> "fp.BLDSTT_CODE";
|
||||
case "lgtd" -> "fp.LGTD";
|
||||
case "lttd" -> "fp.LTTD";
|
||||
case "ennm" -> "eng.ENNM";
|
||||
case "baseId" -> "eng.BASE_ID";
|
||||
case "rvcd" -> "eng.RVCD";
|
||||
case "addvcd" -> "eng.ADDVCD";
|
||||
case "run" -> "state.RUN_STATE";
|
||||
case "stdSstate" -> "state.STD_SSTATE";
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String mapFpColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
return switch (field.toLowerCase()) {
|
||||
case "bldsttccode" -> "fp.BLDSTT_CODE";
|
||||
case "lgtd" -> "fp.LGTD";
|
||||
case "lttd" -> "fp.LTTD";
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String buildFpPointFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
@ -1267,6 +1567,12 @@ public class FpBuildServiceImpl implements FpBuildService {
|
||||
case "rvcd" -> "eng.RVCD";
|
||||
case "addvcd" -> "eng.ADDVCD";
|
||||
case "sttp" -> "fp.STTP";
|
||||
case "bldsttCcode", "bldstt" -> "fp.BLDSTT_CODE";
|
||||
case "lgtd" -> "fp.LGTD";
|
||||
case "lttd" -> "fp.LTTD";
|
||||
case "run" -> "state.RUN_STATE";
|
||||
case "stdSstate" -> "state.STD_SSTATE";
|
||||
case "lcjStatus" -> "CASE WHEN recent.STCD IS NULL THEN 2 ELSE 1 END";
|
||||
default -> null;
|
||||
};
|
||||
if (column == null) {
|
||||
|
||||
@ -89,8 +89,15 @@ public class FprMonitorController {
|
||||
|
||||
@PostMapping("/sdFprdR/point/getFprdPointList")
|
||||
@Operation(summary = "鱼类调查装置锚点信息")
|
||||
public ResponseResult getFprdPointList(@RequestBody FprdRunDataAo ao) {
|
||||
List<FprdPointInfoVo> result = fprMonitorService.getFprdInfoList(ao);
|
||||
public ResponseResult getFprdPointList(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
List<FprdPointInfoVo> result = fprMonitorService.getFprdPointList(dataSourceRequest);
|
||||
return ResponseResult.successData(result);
|
||||
}
|
||||
|
||||
@PostMapping("/point/getFprdPointList")
|
||||
@Operation(summary = "鱼类调查装置锚点信息(AO入参)")
|
||||
public ResponseResult getFprdPointListByAo(@RequestBody FprdRunDataAo ao) {
|
||||
List<FprdPointInfoVo> result = fprMonitorService.getFprdPointList(ao);
|
||||
return ResponseResult.successData(result);
|
||||
}
|
||||
|
||||
|
||||
@ -31,5 +31,7 @@ public interface FprMonitorService {
|
||||
|
||||
List<String> getFishInfo();
|
||||
|
||||
List<FprdPointInfoVo> getFprdInfoList(FprdRunDataAo ao);
|
||||
List<FprdPointInfoVo> getFprdPointList(FprdRunDataAo ao);
|
||||
|
||||
List<FprdPointInfoVo> getFprdPointList(DataSourceRequest dataSourceRequest);
|
||||
}
|
||||
|
||||
@ -129,11 +129,24 @@ public class FprMonitorServiceImpl implements FprMonitorService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FprdPointInfoVo> getFprdInfoList(FprdRunDataAo ao) {
|
||||
validateFprdRunDataAo(ao);
|
||||
public List<FprdPointInfoVo> getFprdPointList(FprdRunDataAo ao) {
|
||||
validateFprdPointAo(ao);
|
||||
return listFprdPointInfo(ao.getBaseId(), ao.getHbrvcd(), ao.getStcd());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FprdPointInfoVo> getFprdPointList(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||
String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId");
|
||||
String hbrvcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "hbrvcd");
|
||||
String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd");
|
||||
validateFprdPointRequest(baseId);
|
||||
return listFprdPointInfo(baseId, hbrvcd, stcd);
|
||||
}
|
||||
|
||||
private List<FprdPointInfoVo> listFprdPointInfo(String baseId, String hbrvcd, String stcd) {
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
paramMap.put("baseId", ao.getBaseId());
|
||||
|
||||
|
||||
StringBuilder sql = new StringBuilder("SELECT ")
|
||||
.append("aim.STCD AS stcd, ")
|
||||
@ -143,17 +156,17 @@ public class FprMonitorServiceImpl implements FprMonitorService {
|
||||
.append("TO_CHAR(aim.BLDSTT_CODE) AS bldstt, ")
|
||||
.append("aim.LTTD AS lttd, ")
|
||||
.append("aim.LGTD AS lgtd, ")
|
||||
.append("aim.DTMEL AS dtmel, ")
|
||||
// .append("aim.DTMEL AS dtmel, ")
|
||||
.append("aim.RSTCD AS rstcds, ")
|
||||
.append("eng.ENNM AS ennm, ")
|
||||
.append("aim.STTP AS sttpCode, ")
|
||||
.append("aim.DWTP AS dwtp, ")
|
||||
.append("aim.DWTP AS dwtpName, ")
|
||||
// .append("aim.DWTP AS dwtp, ")
|
||||
// .append("aim.DWTP AS dwtpName, ")
|
||||
.append("aim.STTP AS sttpMap, ")
|
||||
.append("aim.RVCD AS rvcd, ")
|
||||
.append("rv.RVNM AS rvcdName, ")
|
||||
.append("aim.ADDVCD AS addvcd, ")
|
||||
.append("addv.ADDVCD_NAME AS addvcdName, ")
|
||||
// .append("aim.ADDVCD AS addvcd, ")
|
||||
// .append("addv.ADDVCD_NAME AS addvcdName, ")
|
||||
.append("aim.HBRVCD AS hbrvcd, ")
|
||||
.append("hbrv.HBRVNM AS hbrvcdName, ")
|
||||
.append("aim.BASE_ID AS baseId, ")
|
||||
@ -163,7 +176,7 @@ public class FprMonitorServiceImpl implements FprMonitorService {
|
||||
.append("'' AS anchoPointState, ")
|
||||
.append("aim.MWAY AS mway, ")
|
||||
.append("aim.DTIN AS dtin, ")
|
||||
.append("aim.STDSSTATE AS stdSstate, ")
|
||||
// .append("aim.STDSSTATE AS stdSstate, ")
|
||||
.append("aim.STLC AS stlc ")
|
||||
.append("FROM SD_AIMONITOR_B_H aim ")
|
||||
.append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = aim.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ")
|
||||
@ -173,23 +186,26 @@ public class FprMonitorServiceImpl implements FprMonitorService {
|
||||
.append(" AND NVL(hbrv.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND NVL(hbrv.ENABLED, 1) = 1 ")
|
||||
.append("LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = aim.RVCD ")
|
||||
.append("LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = aim.ADDVCD ")
|
||||
// .append("LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = aim.ADDVCD ")
|
||||
.append("LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = aim.STTP ")
|
||||
.append(" AND NVL(sttp.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND NVL(sttp.ENABLE, 1) = 1 ")
|
||||
.append("WHERE NVL(aim.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND aim.STTP = 'FPRD' ")
|
||||
.append(" AND aim.LGTD IS NOT NULL ")
|
||||
.append(" AND aim.BASE_ID = #{map.baseId}");
|
||||
.append(" AND aim.LGTD IS NOT NULL ");
|
||||
|
||||
if (StrUtil.isNotBlank(ao.getHbrvcd())) {
|
||||
if (StrUtil.isNotBlank(baseId)) {
|
||||
sql.append(" AND aim.BASE_ID = #{map.baseId}");
|
||||
}
|
||||
paramMap.put("baseId", baseId);
|
||||
if (StrUtil.isNotBlank(hbrvcd)) {
|
||||
sql.append(" AND aim.HBRVCD = #{map.hbrvcd}");
|
||||
paramMap.put("hbrvcd", ao.getHbrvcd());
|
||||
paramMap.put("hbrvcd", hbrvcd);
|
||||
}
|
||||
|
||||
if (StrUtil.isNotBlank(ao.getStcd())) {
|
||||
if (StrUtil.isNotBlank(stcd)) {
|
||||
sql.append(" AND aim.STCD = #{map.stcd}");
|
||||
paramMap.put("stcd", ao.getStcd());
|
||||
paramMap.put("stcd", stcd);
|
||||
}
|
||||
|
||||
List<FprdPointInfoVo> resultList = microservicDynamicSQLMapper.getAllListWithResultType(
|
||||
@ -691,6 +707,19 @@ public class FprMonitorServiceImpl implements FprMonitorService {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateFprdPointRequest(String baseId) {
|
||||
// if (StrUtil.isBlank(baseId)) {
|
||||
// throw new BizException("基地编码(baseId)不能为空.");
|
||||
// }
|
||||
}
|
||||
|
||||
private void validateFprdPointAo(FprdRunDataAo ao) {
|
||||
if (ao == null) {
|
||||
throw new BizException("请求参数不能为空.");
|
||||
}
|
||||
validateFprdPointRequest(ao.getBaseId());
|
||||
}
|
||||
|
||||
private String buildFishDicBaseSql() {
|
||||
return "SELECT " +
|
||||
"src.ID AS id, " +
|
||||
|
||||
@ -1948,7 +1948,7 @@ public class VpConstructionServiceImpl implements VpConstructionService {
|
||||
" t.STTP AS sttp,\n" +
|
||||
" t.DTIN AS dtin\n" +
|
||||
"FROM (\n" +
|
||||
" SELECT STCD, STNM, STTP, LGTD, LTTD, ELEV, RSTCD, BASE_ID, RVCD, ADDVCD, BLDSTT_CODE, DTIN\n" +
|
||||
" SELECT STCD, STNM, STTP, LGTD, LTTD, ELEV, RSTCD, BASE_ID,NULL RVCD,NULL ADDVCD, BLDSTT_CODE, DTIN\n" +
|
||||
" FROM SD_VP_B_H\n" +
|
||||
" WHERE NVL(IS_DELETED, 0) = 0 AND BLDSTT_CODE = 1 AND LGTD IS NOT NULL AND LTTD IS NOT NULL\n" +
|
||||
" UNION ALL\n" +
|
||||
@ -1960,10 +1960,16 @@ public class VpConstructionServiceImpl implements VpConstructionService {
|
||||
" FROM SD_FHBT_B_H\n" +
|
||||
" WHERE NVL(IS_DELETED, 0) = 0 AND LGTD IS NOT NULL AND LTTD IS NOT NULL\n" +
|
||||
") t\n" +
|
||||
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = t.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ");
|
||||
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = t.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 WHERE 1=1");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
String filterSql = buildFhvapPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
|
||||
dataSourceRequest.getFilter(),
|
||||
paramMap,
|
||||
new int[]{0},
|
||||
this::mapVpColumn
|
||||
);
|
||||
// String filterSql = buildFhvapPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql);
|
||||
}
|
||||
@ -1991,6 +1997,26 @@ public class VpConstructionServiceImpl implements VpConstructionService {
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
private String mapVpColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> columnMap = new HashMap<>();
|
||||
columnMap.put("stcd", "t.STCD");
|
||||
columnMap.put("stnm", "t.STNM");
|
||||
columnMap.put("sttpcode", "t.STTP");
|
||||
columnMap.put("bldsttccode", "t.BLDSTT_CODE");
|
||||
columnMap.put("lgtd", "t.LGTD");
|
||||
columnMap.put("lttd", "t.LTTD");
|
||||
columnMap.put("baseId", "t.BASE_ID");
|
||||
columnMap.put("rvcd", "t.RVCD");
|
||||
columnMap.put("addvcd", "t.ADDVCD");
|
||||
columnMap.put("rstcds", "t.RSTCD");
|
||||
columnMap.put("ennm", "eng.ENNM");
|
||||
return columnMap.get(field.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
private String buildFhvapPointFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
@ -2149,19 +2175,25 @@ public class VpConstructionServiceImpl implements VpConstructionService {
|
||||
" we.ELEV AS dtmel,\n" +
|
||||
" we.RSTCD AS rstcds,\n" +
|
||||
" eng.ENNM AS ennm,\n" +
|
||||
" 'WVA' AS sttpMap,\n" +
|
||||
" we.STTP AS sttpMap,\n" +
|
||||
" we.RVCD AS rvcd,\n" +
|
||||
" we.ADDVCD AS addvcd,\n" +
|
||||
// " we.ADDVCD AS addvcd,\n" +
|
||||
" we.BASE_ID AS baseId,\n" +
|
||||
" 'WVA' AS sttp,\n" +
|
||||
" we.STTP AS sttp,\n" +
|
||||
" 'wild_animal_legend' AS anchoPointState,\n" +
|
||||
" 'WVA' AS sttpCode\n" +
|
||||
"FROM SD_WE_B_H we\n" +
|
||||
" we.STTP AS sttpCode\n" +
|
||||
"FROM SD_AIMONITOR_B_H we\n" +
|
||||
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = we.RSTCD AND NVL(eng.IS_DELETED, 0) = 0\n" +
|
||||
"WHERE we.LGTD IS NOT NULL AND we.LTTD IS NOT NULL ");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
String filterSql = buildWvaPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
|
||||
dataSourceRequest.getFilter(),
|
||||
paramMap,
|
||||
new int[]{0},
|
||||
this::mapVapWvaColumn
|
||||
);
|
||||
// String filterSql = buildWvaPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql);
|
||||
}
|
||||
@ -2176,6 +2208,26 @@ public class VpConstructionServiceImpl implements VpConstructionService {
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
private String mapVapWvaColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
Map<String, String> columnMap = new HashMap<>();
|
||||
columnMap.put("stcd", "we.STCD");
|
||||
columnMap.put("stnm", "we.STNM");
|
||||
columnMap.put("sttpcode", "we.STTP");
|
||||
columnMap.put("bldsttccode", "we.BLDSTT_CODE");
|
||||
columnMap.put("lgtd", "we.LGTD");
|
||||
columnMap.put("lttd", "we.LTTD");
|
||||
columnMap.put("baseId", "we.BASE_ID");
|
||||
columnMap.put("rvcd", "we.RVCD");
|
||||
columnMap.put("addvcd", "we.ADDVCD");
|
||||
columnMap.put("rstcds", "weRSTCD");
|
||||
columnMap.put("ennm", "eng.ENNM");
|
||||
return columnMap.get(field.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
private String buildWvaPointFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
|
||||
@ -65,6 +65,12 @@ public class VdMonitorController {
|
||||
return ResponseResult.successData(vdMonitorService.getVdPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/aiPoint/GetKendoListCust")
|
||||
@Operation(summary = "视频站AI设施锚点")
|
||||
public ResponseResult getVdAiPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(vdMonitorService.getVdAiPointKendoListCust(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/runData/GetKendoListCust")
|
||||
@Operation(summary = "查询视频监控运行数据")
|
||||
public ResponseResult getRunDataKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
|
||||
@ -0,0 +1,107 @@
|
||||
package com.yfd.platform.qgc_env.vd.entity.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@Data
|
||||
@Schema(description = "视频站AI设施锚点信息")
|
||||
public class VdAiPointVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "锚点状态")
|
||||
private String anchoPointState;
|
||||
|
||||
@Schema(description = "地图站类标识")
|
||||
private String sttpMap;
|
||||
|
||||
@Schema(description = "锚点站类")
|
||||
private String sttp;
|
||||
|
||||
@Schema(description = "视频站编码")
|
||||
private String stcd;
|
||||
|
||||
@Schema(description = "视频站名称")
|
||||
private String stnm;
|
||||
|
||||
@Schema(description = "经度")
|
||||
private BigDecimal lgtd;
|
||||
|
||||
@Schema(description = "纬度")
|
||||
private BigDecimal lttd;
|
||||
|
||||
@Schema(description = "流域编码")
|
||||
private String rvcd;
|
||||
|
||||
@Schema(description = "行政区编码")
|
||||
private String addvcd;
|
||||
|
||||
@Schema(description = "流域名称")
|
||||
private String rvnm;
|
||||
|
||||
@Schema(description = "基地编码")
|
||||
private String baseId;
|
||||
|
||||
@Schema(description = "所属电站编码")
|
||||
private String rstcds;
|
||||
|
||||
@Schema(description = "所属电站编码")
|
||||
private String rstcd;
|
||||
|
||||
@Schema(description = "高程")
|
||||
private BigDecimal dtmel;
|
||||
|
||||
@Schema(description = "标题")
|
||||
private String titleName;
|
||||
|
||||
@Schema(description = "电站名称")
|
||||
private String ennm;
|
||||
|
||||
@Schema(description = "站类名称")
|
||||
private String sttpName;
|
||||
|
||||
@Schema(description = "站点排序")
|
||||
private Integer siteStepSort;
|
||||
|
||||
@Schema(description = "站类编码")
|
||||
private String sttpCode;
|
||||
|
||||
@Schema(description = "栖息地编码")
|
||||
private String fhstcd;
|
||||
|
||||
@Schema(description = "栖息地名称")
|
||||
private String fhstnm;
|
||||
|
||||
@Schema(description = "基地流域编码")
|
||||
private String hbrvcd;
|
||||
|
||||
@Schema(description = "基地流域名称")
|
||||
private String hbrvcdName;
|
||||
|
||||
@Schema(description = "播放地址")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "站址")
|
||||
private String stlc;
|
||||
|
||||
@Schema(description = "AI是否启用")
|
||||
private Integer aiEnabled;
|
||||
|
||||
@Schema(description = "AI外部站码")
|
||||
private String aiExtCode;
|
||||
|
||||
@Schema(description = "AI外部站名")
|
||||
private String aiExtName;
|
||||
|
||||
@Schema(description = "AI频率")
|
||||
private String aiFrequency;
|
||||
|
||||
@Schema(description = "AI站类编码")
|
||||
private String aiSttpCode;
|
||||
|
||||
@Schema(description = "AI站类名称")
|
||||
private String aiSttpName;
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.vd.service;
|
||||
|
||||
import com.yfd.platform.common.DataSourceRequest;
|
||||
import com.yfd.platform.common.DataSourceResult;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdAiPointVo;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdTreeNodeVo;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdRunDataVo;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdVmsstbprptVo;
|
||||
@ -20,5 +21,7 @@ public interface VdMonitorService {
|
||||
|
||||
DataSourceResult<?> getVdPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<VdAiPointVo> getVdAiPointKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<VdRunDataVo> getRunDataKendoListCust(DataSourceRequest dataSourceRequest);
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import com.yfd.platform.common.DataSourceResult;
|
||||
import com.yfd.platform.common.GroupHelper;
|
||||
import com.yfd.platform.common.GroupingInfo;
|
||||
import com.yfd.platform.common.MicroservicDynamicSQLMapper;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdAiPointVo;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdPointVo;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdRunDataVo;
|
||||
import com.yfd.platform.qgc_env.vd.entity.vo.VdTreeNodeVo;
|
||||
@ -229,6 +230,72 @@ public class VdMonitorServiceImpl implements VdMonitorService {
|
||||
return queryVdPointDetailList(dataSourceRequest, loadOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<VdAiPointVo> getVdAiPointKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||
Page<?> page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
|
||||
String baseId = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId");
|
||||
String rstcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd");
|
||||
String hbrvcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "hbrvcd");
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT ")
|
||||
.append("t.stcd AS stcd, ")
|
||||
.append("t.stnm AS stnm, ")
|
||||
.append("t.anchoPointState AS anchoPointState, ")
|
||||
.append("t.sttpMap AS sttpMap, ")
|
||||
.append("t.sttp AS sttp, ")
|
||||
.append("t.lgtd AS lgtd, ")
|
||||
.append("t.lttd AS lttd, ")
|
||||
.append("t.rvcd AS rvcd, ")
|
||||
.append("t.addvcd AS addvcd, ")
|
||||
.append("t.rvnm AS rvnm, ")
|
||||
.append("t.baseId AS baseId, ")
|
||||
.append("t.rstcds AS rstcds, ")
|
||||
.append("t.rstcd AS rstcd, ")
|
||||
.append("t.dtmel AS dtmel, ")
|
||||
.append("t.titleName AS titleName, ")
|
||||
.append("t.ennm AS ennm, ")
|
||||
.append("t.sttpName AS sttpName, ")
|
||||
.append("t.siteStepSort AS siteStepSort, ")
|
||||
.append("t.sttpCode AS sttpCode, ")
|
||||
.append("t.fhstcd AS fhstcd, ")
|
||||
.append("t.fhstnm AS fhstnm, ")
|
||||
.append("t.hbrvcd AS hbrvcd, ")
|
||||
.append("t.hbrvcdName AS hbrvcdName, ")
|
||||
.append("t.url AS url, ")
|
||||
.append("t.stlc AS stlc, ")
|
||||
.append("t.aiEnabled AS aiEnabled, ")
|
||||
.append("t.aiExtCode AS aiExtCode, ")
|
||||
.append("t.aiExtName AS aiExtName, ")
|
||||
.append("t.aiFrequency AS aiFrequency, ")
|
||||
.append("t.aiSttpCode AS aiSttpCode, ")
|
||||
.append("t.aiSttpName AS aiSttpName ")
|
||||
.append("FROM (")
|
||||
.append(buildVdAiPointCoreSql())
|
||||
.append(") t WHERE 1 = 1 ");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
if (StrUtil.isNotBlank(baseId)) {
|
||||
paramMap.put("vdAiBaseId", baseId);
|
||||
sql.append(" AND t.baseId = #{map.vdAiBaseId} ");
|
||||
}
|
||||
if (StrUtil.isNotBlank(hbrvcd)) {
|
||||
paramMap.put("vdAiHbrvcd", hbrvcd);
|
||||
sql.append(" AND t.hbrvcd = #{map.vdAiHbrvcd} ");
|
||||
}
|
||||
appendVdAiRstcdCondition(sql, paramMap, parseArrayLikeValues(rstcd));
|
||||
sql.append(" ORDER BY t.siteStepSort ASC NULLS LAST, t.stcd ASC");
|
||||
|
||||
List<VdAiPointVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
|
||||
page, sql.toString(), paramMap, VdAiPointVo.class);
|
||||
DataSourceResult<VdAiPointVo> result = new DataSourceResult<>();
|
||||
result.setData(list);
|
||||
result.setTotal(page != null ? page.getTotal() : list.size());
|
||||
result.setAggregates(new HashMap<>());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<VdRunDataVo> getRunDataKendoListCust(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||
@ -703,6 +770,68 @@ public class VdMonitorServiceImpl implements VdMonitorService {
|
||||
" AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 ";
|
||||
}
|
||||
|
||||
private String buildVdAiPointCoreSql() {
|
||||
return "SELECT " +
|
||||
"src.STCD AS stcd, " +
|
||||
"src.STNM AS stnm, " +
|
||||
"'aispjk' AS anchoPointState, " +
|
||||
"'AIVD' AS sttpMap, " +
|
||||
"src.STTP AS sttp, " +
|
||||
"src.LGTD AS lgtd, " +
|
||||
"src.LTTD AS lttd, " +
|
||||
"NVL(eng.RVCD, src.RVCD) AS rvcd, " +
|
||||
"NVL(eng.ADDVCD, src.ADDVCD) AS addvcd, " +
|
||||
"rv.RVNM AS rvnm, " +
|
||||
"NVL(eng.BASE_ID, src.BASE_ID) AS baseId, " +
|
||||
"src.RSTCD AS rstcds, " +
|
||||
"src.RSTCD AS rstcd, " +
|
||||
"src.ELEV AS dtmel, " +
|
||||
"src.STNM AS titleName, " +
|
||||
"eng.ENNM AS ennm, " +
|
||||
"vdSttp.STTP_NAME AS sttpName, " +
|
||||
"NVL(siteSort.SORT, 999999) AS siteStepSort, " +
|
||||
"'AIVD' AS sttpCode, " +
|
||||
"src.FHSTCD AS fhstcd, " +
|
||||
"fh.STNM AS fhstnm, " +
|
||||
"NVL(eng.HBRVCD, src.HBRVCD) AS hbrvcd, " +
|
||||
"hbrv.HBRVNM AS hbrvcdName, " +
|
||||
"src.URL AS url, " +
|
||||
"src.STLC AS stlc, " +
|
||||
"src.AI_ENABLED AS aiEnabled, " +
|
||||
"src.AI_EXT_CODE AS aiExtCode, " +
|
||||
"src.AI_EXT_NAME AS aiExtName, " +
|
||||
"src.AI_FREQUENCY AS aiFrequency, " +
|
||||
"(SELECT LISTAGG(ai.STTP, ',') WITHIN GROUP (ORDER BY ai.STTP) " +
|
||||
" FROM SD_AIMONITOR_B_H ai " +
|
||||
" WHERE NVL(ai.IS_DELETED, 0) = 0 " +
|
||||
" AND ai.STTP LIKE 'AI_%' " +
|
||||
" AND INSTR(',' || src.AI_EXT_CODE || ',', ',' || ai.STCD || ',') > 0) AS aiSttpCode, " +
|
||||
"(SELECT LISTAGG(sttp.STTP_NAME, ',') WITHIN GROUP (ORDER BY ai.STTP) " +
|
||||
" FROM SD_AIMONITOR_B_H ai " +
|
||||
" LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = ai.STTP " +
|
||||
" AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " +
|
||||
" WHERE NVL(ai.IS_DELETED, 0) = 0 " +
|
||||
" AND ai.STTP LIKE 'AI_%' " +
|
||||
" AND INSTR(',' || src.AI_EXT_CODE || ',', ',' || ai.STCD || ',') > 0) AS aiSttpName " +
|
||||
"FROM SD_VDINFO_B src " +
|
||||
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = src.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
|
||||
"LEFT JOIN SD_FHBT_B_H fh ON fh.STCD = src.FHSTCD AND NVL(fh.IS_DELETED, 0) = 0 " +
|
||||
"LEFT JOIN SD_RVCD_DIC rv ON rv.RVCD = NVL(eng.RVCD, src.RVCD) " +
|
||||
"LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(eng.HBRVCD, src.HBRVCD) " +
|
||||
" AND hbrv.BASEID = NVL(eng.BASE_ID, src.BASE_ID) " +
|
||||
" AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " +
|
||||
"LEFT JOIN SD_STTP_B vdSttp ON vdSttp.STTP_CODE = src.STTP " +
|
||||
" AND NVL(vdSttp.IS_DELETED, 0) = 0 AND NVL(vdSttp.ENABLE, 1) = 1 " +
|
||||
"LEFT JOIN (SELECT det.SORT, cfg.RVCD, det.STCD FROM MS_ALONGDET_B det " +
|
||||
"INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " +
|
||||
"WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common') siteSort " +
|
||||
"ON siteSort.RVCD = NVL(eng.HBRVCD, src.HBRVCD) AND siteSort.STCD = src.STCD " +
|
||||
"WHERE src.STTP LIKE 'VD%' " +
|
||||
"AND src.AI_EXT_CODE IS NOT NULL " +
|
||||
"AND src.LGTD IS NOT NULL " +
|
||||
"AND src.LTTD IS NOT NULL ";
|
||||
}
|
||||
|
||||
private String buildRunDataCoreSql() {
|
||||
return "SELECT " +
|
||||
"run.ID AS id, " +
|
||||
@ -1183,6 +1312,44 @@ public class VdMonitorServiceImpl implements VdMonitorService {
|
||||
return values;
|
||||
}
|
||||
|
||||
private List<String> parseArrayLikeValues(String value) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return values;
|
||||
}
|
||||
String trimmed = value.trim();
|
||||
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
||||
trimmed = trimmed.substring(1, trimmed.length() - 1);
|
||||
}
|
||||
if (StrUtil.isBlank(trimmed)) {
|
||||
return values;
|
||||
}
|
||||
for (String item : trimmed.split(",")) {
|
||||
String normalized = StrUtil.trim(item.replace("\"", "").replace("'", ""));
|
||||
if (StrUtil.isNotBlank(normalized)) {
|
||||
values.add(normalized);
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private void appendVdAiRstcdCondition(StringBuilder sql,
|
||||
Map<String, Object> paramMap,
|
||||
List<String> rstcdList) {
|
||||
if (CollUtil.isEmpty(rstcdList)) {
|
||||
return;
|
||||
}
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
for (int i = 0; i < rstcdList.size(); i++) {
|
||||
String key = "vdAiRstcd" + i;
|
||||
paramMap.put(key, rstcdList.get(i));
|
||||
placeholders.add("#{map." + key + "}");
|
||||
}
|
||||
sql.append(" AND t.rstcds IN (")
|
||||
.append(String.join(", ", placeholders))
|
||||
.append(") ");
|
||||
}
|
||||
|
||||
private void appendNormalizedValues(List<Object> values, Object value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
|
||||
@ -9,10 +9,12 @@ import com.yfd.platform.common.*;
|
||||
import com.yfd.platform.common.exception.BizException;
|
||||
import com.yfd.platform.qgc_base.domain.MsOperationLog;
|
||||
import com.yfd.platform.qgc_base.domain.MsOperationLogDetail;
|
||||
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
|
||||
import com.yfd.platform.qgc_base.entity.vo.BatchDeleteAo;
|
||||
import com.yfd.platform.qgc_base.entity.vo.DataParam;
|
||||
import com.yfd.platform.qgc_base.mapper.MsOperationLogDetailMapper;
|
||||
import com.yfd.platform.qgc_base.mapper.MsOperationLogMapper;
|
||||
import com.yfd.platform.qgc_base.service.IDataScopeFilterService;
|
||||
import com.yfd.platform.qgc_env.wq.entity.vo.*;
|
||||
import com.yfd.platform.qgc_env.wq.service.EnvWqDataService;
|
||||
import com.yfd.platform.qgc_env.wt.entity.vo.WbsbVo;
|
||||
@ -45,6 +47,9 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
@Service
|
||||
public class EnvWqDataServiceImpl implements EnvWqDataService {
|
||||
|
||||
@Resource
|
||||
private IDataScopeFilterService dataScopeFilterService;
|
||||
|
||||
private static final String WQ_HOUR_TABLE_NAME = "SD_WQ_R";
|
||||
private static final String WQ_DAY_TABLE_NAME = "SD_WQDAY_S";
|
||||
private static final String WQ_MONTH_TABLE_NAME = "SD_WQDRTP_S";
|
||||
@ -4610,6 +4615,13 @@ public class EnvWqDataServiceImpl implements EnvWqDataService {
|
||||
.append("AND NVL(t.USFL, 1) = 1 ");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
|
||||
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.RSTCD");
|
||||
if (scopeApplyResult.isEmptyResult()) {
|
||||
dataSourceResult.setData(new ArrayList<>());
|
||||
dataSourceResult.setTotal(0L);
|
||||
return dataSourceResult;
|
||||
}
|
||||
String filterSql = buildWqPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql);
|
||||
|
||||
@ -5,6 +5,8 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.yfd.platform.common.*;
|
||||
import com.yfd.platform.common.exception.BizException;
|
||||
import com.yfd.platform.qgc_base.domain.vo.DataScopeApplyResult;
|
||||
import com.yfd.platform.qgc_base.service.IDataScopeFilterService;
|
||||
import com.yfd.platform.qgc_env.wt.entity.vo.DfltkwFacilityCountVo;
|
||||
import com.yfd.platform.qgc_env.wt.entity.vo.FishSpawnVo;
|
||||
import com.yfd.platform.qgc_env.wt.entity.vo.RstcdTreeInfoVo;
|
||||
@ -58,6 +60,9 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService {
|
||||
@Resource
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Resource
|
||||
private IDataScopeFilterService dataScopeFilterService;
|
||||
|
||||
@Override
|
||||
public DataSourceResult getEvnmAutoMonitorList(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||
@ -2886,6 +2891,14 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService {
|
||||
}
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
DataScopeApplyResult scopeApplyResult = dataScopeFilterService.appendCurrentUserStationScope(sql, paramMap, "t.RSTCD");
|
||||
if (scopeApplyResult.isEmptyResult()) {
|
||||
dataSourceResult.setData(new ArrayList<>());
|
||||
dataSourceResult.setTotal(0L);
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
// Map<String, Object> paramMap = new HashMap<>();
|
||||
if (StrUtil.isNotEmpty(bldsttCcode)) {
|
||||
paramMap.put("bldsttCcode", bldsttCcode);
|
||||
}
|
||||
|
||||
@ -150,6 +150,12 @@ public class WeFishController {
|
||||
return ResponseResult.successData(weFishService.getQgcWeFishPoint(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/we/point/qgc/GetKendoListCust")
|
||||
@Operation(summary = "环保部-水生生态调查-地图锚点")
|
||||
public ResponseResult getQgcWePoint(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
return ResponseResult.successData(weFishService.getQgcWePoint(dataSourceRequest));
|
||||
}
|
||||
|
||||
@PostMapping("/te/tet/spec/GetKendoListCust")
|
||||
@Operation(summary = "重点陆生动物二级页面")
|
||||
public ResponseResult getTeSpecialAnimalList(@RequestBody DataSourceRequest dataSourceRequest) {
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
package com.yfd.platform.qgc_env.wte.entity.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(description = "水生生态调查锚点鱼类统计")
|
||||
public class WePointFishStatVo {
|
||||
|
||||
@Schema(description = "断面编码")
|
||||
private String stcd;
|
||||
|
||||
@Schema(description = "鱼类名称")
|
||||
private String fishName;
|
||||
|
||||
@Schema(description = "数量")
|
||||
private Integer count;
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
package com.yfd.platform.qgc_env.wte.entity.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Schema(description = "环保部-水生生态调查-锚点")
|
||||
public class WePointQgcVo {
|
||||
|
||||
@Schema(description = "站点编码")
|
||||
private String stcd;
|
||||
|
||||
@Schema(description = "断面名称")
|
||||
private String stnm;
|
||||
|
||||
@Schema(description = "经度")
|
||||
private BigDecimal lgtd;
|
||||
|
||||
@Schema(description = "纬度")
|
||||
private BigDecimal lttd;
|
||||
|
||||
@Schema(description = "高程")
|
||||
private BigDecimal dtmel;
|
||||
|
||||
@Schema(description = "关联电站编码冗余")
|
||||
private String rstcds;
|
||||
|
||||
@Schema(description = "电站名称")
|
||||
private String ennm;
|
||||
|
||||
@Schema(description = "最新调查时间")
|
||||
private String tm;
|
||||
|
||||
@Schema(description = "描点状态")
|
||||
private String anchoPointState;
|
||||
|
||||
@Schema(description = "锚点类型")
|
||||
private String sttpMap;
|
||||
|
||||
@Schema(description = "站点类型")
|
||||
private String sttp;
|
||||
|
||||
@Schema(description = "设施类型")
|
||||
private String sttpCode;
|
||||
|
||||
@Schema(description = "弹框标题")
|
||||
private String titleName;
|
||||
|
||||
@Schema(description = "流域编码")
|
||||
private String rvcd;
|
||||
|
||||
@Schema(description = "行政编码")
|
||||
private String addvcd;
|
||||
|
||||
@Schema(description = "基地编码")
|
||||
private String baseId;
|
||||
|
||||
@Schema(description = "关联电站编码")
|
||||
private String rstcd;
|
||||
|
||||
@Schema(description = "沿程排序")
|
||||
private Integer siteStepSort;
|
||||
|
||||
@Schema(description = "地图避让")
|
||||
private Integer distance;
|
||||
|
||||
@Schema(description = "调查鱼类列表")
|
||||
private List<WePointFishStatVo> fishList;
|
||||
}
|
||||
@ -53,6 +53,8 @@ public interface WeFishService {
|
||||
|
||||
DataSourceResult<WeFishPointQgcVo> getQgcWeFishPoint(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<WePointQgcVo> getQgcWePoint(DataSourceRequest dataSourceRequest);
|
||||
|
||||
DataSourceResult<WeTeSpecialAnimalVo> getTeSpecialAnimalList(DataSourceRequest dataSourceRequest);
|
||||
|
||||
List<WeDefaultDataVo> getWeDefaultData(String stcd);
|
||||
|
||||
@ -10,6 +10,7 @@ import com.yfd.platform.common.DataSourceResult;
|
||||
import com.yfd.platform.common.GroupHelper;
|
||||
import com.yfd.platform.common.GroupingInfo;
|
||||
import com.yfd.platform.common.MicroservicDynamicSQLMapper;
|
||||
import com.yfd.platform.qgc_env.wt.utils.SiteAvoidanceUtils;
|
||||
import com.yfd.platform.qgc_env.wte.entity.vo.*;
|
||||
import com.yfd.platform.qgc_env.wte.service.WeFishService;
|
||||
import com.yfd.platform.utils.KendoUtil;
|
||||
@ -1065,6 +1066,170 @@ public class WeFishServiceImpl implements WeFishService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<WePointQgcVo> getQgcWePoint(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceResult<WePointQgcVo> result = new DataSourceResult<>();
|
||||
result.setAggregates(new HashMap<>());
|
||||
if (dataSourceRequest == null) {
|
||||
result.setData(new ArrayList<>());
|
||||
result.setTotal(0L);
|
||||
return result;
|
||||
}
|
||||
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
|
||||
String stcd = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "stcd");
|
||||
String startTime = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "startTime");
|
||||
String endTime = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "endTime");
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT ")
|
||||
.append("section.STCD AS stcd, ")
|
||||
.append("section.STNM AS stnm, ")
|
||||
.append("section.LGTD AS lgtd, ")
|
||||
.append("section.LTTD AS lttd, ")
|
||||
.append("section.ELEV AS dtmel, ")
|
||||
.append("section.RSTCD AS rstcds, ")
|
||||
.append("eng.ENNM AS ennm, ")
|
||||
.append("TO_CHAR(latest.TM, 'yyyy-mm-dd hh24:mi:ss') AS tm, ")
|
||||
.append("'WE' AS anchoPointState, ")
|
||||
.append("'WE' AS sttpMap, ")
|
||||
.append("'WE' AS sttp, ")
|
||||
.append("'WE' AS sttpCode, ")
|
||||
.append("section.STNM AS titleName, ")
|
||||
.append("section.RVCD AS rvcd, ")
|
||||
.append("section.ADDVCD AS addvcd, ")
|
||||
.append("section.BASE_ID AS baseId, ")
|
||||
.append("section.RSTCD AS rstcd, ")
|
||||
.append("siteSort.SORT AS siteStepSort ")
|
||||
.append("FROM SD_WE_B_H section ")
|
||||
.append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = section.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ")
|
||||
.append("LEFT JOIN ( ")
|
||||
.append(" SELECT STCD, MAX(TM) AS TM ")
|
||||
.append(" FROM SD_WE_R ")
|
||||
.append(" WHERE NVL(IS_DELETED, 0) = 0 AND STATUS = 1 ")
|
||||
.append(" GROUP BY STCD ")
|
||||
.append(") latest ON latest.STCD = section.STCD ")
|
||||
.append("LEFT JOIN MS_ALONG_B along ON along.RVCD = section.HBRVCD ")
|
||||
.append(" AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 ")
|
||||
.append("LEFT JOIN ( ")
|
||||
.append(" SELECT det.SORT, cfg.RVCD, det.STCD ")
|
||||
.append(" FROM MS_ALONGDET_B det ")
|
||||
.append(" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID ")
|
||||
.append(" WHERE NVL(det.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND NVL(cfg.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND cfg.CODE = 'common' ")
|
||||
.append(") siteSort ON siteSort.RVCD = section.HBRVCD AND siteSort.STCD = section.STCD ")
|
||||
.append("WHERE NVL(section.USFL, 1) = 1 ");
|
||||
|
||||
String filterSql = buildWePointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append("AND ").append(filterSql).append(" ");
|
||||
}
|
||||
sql.append(buildWePointOrderBySql(dataSourceRequest.getSort()));
|
||||
|
||||
Page<?> page = loadOptions == null ? null
|
||||
: QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
|
||||
List<WePointQgcVo> list = microservicDynamicSQLMapper.pageAllListWithResultType(
|
||||
page,
|
||||
sql.toString(),
|
||||
paramMap,
|
||||
WePointQgcVo.class
|
||||
);
|
||||
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
result.setData(list);
|
||||
result.setTotal(page != null ? page.getTotal() : 0L);
|
||||
return result;
|
||||
}
|
||||
|
||||
Map<String, List<WePointFishStatVo>> fishMap = queryWePointFishMap(
|
||||
list.stream().map(WePointQgcVo::getStcd).filter(StrUtil::isNotBlank).distinct().toList(),
|
||||
stcd,
|
||||
startTime,
|
||||
endTime
|
||||
);
|
||||
for (WePointQgcVo vo : list) {
|
||||
vo.setFishList(fishMap.get(vo.getStcd()));
|
||||
}
|
||||
|
||||
SiteAvoidanceUtils.calcSiteMapLev(list,
|
||||
WePointQgcVo::getStcd,
|
||||
WePointQgcVo::getLgtd,
|
||||
WePointQgcVo::getLttd,
|
||||
WePointQgcVo::getAnchoPointState,
|
||||
WePointQgcVo::setDistance);
|
||||
|
||||
result.setData(list);
|
||||
result.setTotal(page != null ? page.getTotal() : list.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
private Map<String, List<WePointFishStatVo>> queryWePointFishMap(List<String> stcdList,
|
||||
String stcd,
|
||||
String startTime,
|
||||
String endTime) {
|
||||
Map<String, List<WePointFishStatVo>> result = new LinkedHashMap<>();
|
||||
if (CollUtil.isEmpty(stcdList)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT ")
|
||||
.append("we.STCD AS stcd, ")
|
||||
.append("dict.NAME AS fishName, ")
|
||||
.append("SUM(fish.FCNT) AS count ")
|
||||
.append("FROM SD_WE_R we ")
|
||||
.append("INNER JOIN SD_WEFISH_R fish ON fish.WER_ID = we.ID ")
|
||||
.append(" AND NVL(fish.IS_DELETED, 0) = 0 ")
|
||||
.append("INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD ")
|
||||
.append(" AND NVL(section.USFL, 1) = 1 ")
|
||||
.append("INNER JOIN ( ")
|
||||
.append(" SELECT STCD, MAX(TM) AS TM ")
|
||||
.append(" FROM SD_WE_R ")
|
||||
.append(" WHERE NVL(IS_DELETED, 0) = 0 AND STATUS = 1 ")
|
||||
.append(" GROUP BY STCD ")
|
||||
.append(") latest ON latest.STCD = we.STCD AND latest.TM = we.TM ")
|
||||
.append("LEFT JOIN ( ")
|
||||
.append(" SELECT DISTINCT rel.FISH_ID, rel.RVCD, dic.NAME ")
|
||||
.append(" FROM SD_FISHDICTORY_RLTN_B rel ")
|
||||
.append(" LEFT JOIN SD_FISHDICTORY_B dic ON rel.ZY_FISH_ID = dic.ID ")
|
||||
.append(" WHERE NVL(rel.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND NVL(dic.IS_DELETED, 0) = 0 ")
|
||||
.append(" AND (rel.FISH_ID <> rel.ZY_FISH_ID OR rel.RVCD = 'ZY') ")
|
||||
.append(") dict ON fish.FTP = dict.FISH_ID AND (section.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') ")
|
||||
.append("WHERE fish.FCNT IS NOT NULL ")
|
||||
.append("AND NVL(we.IS_DELETED, 0) = 0 ")
|
||||
.append("AND NVL(we.STATUS, 1) = 1 ");
|
||||
|
||||
appendWePointInCondition(sql, paramMap, "we.STCD", stcdList, "stcdList");
|
||||
if (StrUtil.isNotBlank(stcd)) {
|
||||
paramMap.put("filterStcd", stcd);
|
||||
sql.append("AND we.STCD = #{map.filterStcd} ");
|
||||
}
|
||||
if (StrUtil.isNotBlank(startTime) && StrUtil.isNotBlank(endTime)) {
|
||||
paramMap.put("startTime", startTime);
|
||||
paramMap.put("endTime", endTime);
|
||||
sql.append("AND we.TM BETWEEN TO_DATE(#{map.startTime}, 'yyyy-mm-dd hh24:mi:ss') ")
|
||||
.append("AND TO_DATE(#{map.endTime}, 'yyyy-mm-dd hh24:mi:ss') ");
|
||||
}
|
||||
sql.append("GROUP BY we.STCD, dict.NAME ORDER BY SUM(fish.FCNT)");
|
||||
|
||||
List<WePointFishStatVo> rows = microservicDynamicSQLMapper.getAllListWithResultType(
|
||||
sql.toString(),
|
||||
paramMap,
|
||||
WePointFishStatVo.class
|
||||
);
|
||||
for (WePointFishStatVo row : rows) {
|
||||
if (row == null || StrUtil.isBlank(row.getStcd())) {
|
||||
continue;
|
||||
}
|
||||
result.computeIfAbsent(row.getStcd(), key -> new ArrayList<>()).add(row);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceResult<WeTeSpecialAnimalVo> getTeSpecialAnimalList(DataSourceRequest dataSourceRequest) {
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();
|
||||
@ -2489,6 +2654,96 @@ public class WeFishServiceImpl implements WeFishService {
|
||||
return sql.toString();
|
||||
}
|
||||
|
||||
private String buildWePointFilterCondition(DataSourceRequest.FilterDescriptor filter,
|
||||
Map<String, Object> paramMap,
|
||||
int[] indexHolder) {
|
||||
return QgcQueryWrapperUtil.buildFilterCondition(filter, paramMap, indexHolder, this::mapWePointColumn);
|
||||
}
|
||||
|
||||
private String mapWePointColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return switch (field) {
|
||||
case "stcd" -> "section.STCD";
|
||||
case "lgtd" -> "section.LGTD";
|
||||
case "stnm", "titleName" -> "section.STNM";
|
||||
case "ennm" -> "eng.ENNM";
|
||||
case "rvcd" -> "section.RVCD";
|
||||
case "addvcd" -> "section.ADDVCD";
|
||||
case "baseId" -> "section.BASE_ID";
|
||||
case "rstcd", "rstcds" -> "section.RSTCD";
|
||||
case "tm" -> "latest.TM";
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String buildWePointOrderBySql(List<DataSourceRequest.SortDescriptor> sorts) {
|
||||
if (CollUtil.isEmpty(sorts)) {
|
||||
return " ORDER BY siteSort.SORT NULLS LAST";
|
||||
}
|
||||
List<String> orderByParts = new ArrayList<>();
|
||||
for (DataSourceRequest.SortDescriptor sort : sorts) {
|
||||
if (sort == null || StrUtil.isBlank(sort.getField())) {
|
||||
continue;
|
||||
}
|
||||
String column = mapWePointSortColumn(sort.getField());
|
||||
if (StrUtil.isBlank(column)) {
|
||||
continue;
|
||||
}
|
||||
String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC";
|
||||
orderByParts.add(column + " " + direction + " NULLS LAST");
|
||||
}
|
||||
if (orderByParts.isEmpty()) {
|
||||
return " ORDER BY siteSort.SORT NULLS LAST";
|
||||
}
|
||||
return " ORDER BY " + String.join(", ", orderByParts);
|
||||
}
|
||||
|
||||
private String mapWePointSortColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
return switch (field) {
|
||||
case "stcd" -> "section.STCD";
|
||||
case "stnm", "titleName" -> "section.STNM";
|
||||
case "ennm" -> "eng.ENNM";
|
||||
case "tm" -> "latest.TM";
|
||||
case "rvcd" -> "section.RVCD";
|
||||
case "addvcd" -> "section.ADDVCD";
|
||||
case "baseId" -> "section.BASE_ID";
|
||||
case "siteStepSort" -> "siteSort.SORT";
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private void appendWePointInCondition(StringBuilder sql,
|
||||
Map<String, Object> paramMap,
|
||||
String column,
|
||||
List<String> values,
|
||||
String paramPrefix) {
|
||||
if (CollUtil.isEmpty(values) || StrUtil.isBlank(column)) {
|
||||
return;
|
||||
}
|
||||
List<String> placeholders = new ArrayList<>();
|
||||
int index = 0;
|
||||
for (String value : values) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
continue;
|
||||
}
|
||||
String key = paramPrefix + "_" + index++;
|
||||
paramMap.put(key, value);
|
||||
placeholders.add("#{map." + key + "}");
|
||||
}
|
||||
if (CollUtil.isEmpty(placeholders)) {
|
||||
return;
|
||||
}
|
||||
sql.append("AND ").append(column).append(" IN (")
|
||||
.append(String.join(", ", placeholders))
|
||||
.append(") ");
|
||||
}
|
||||
|
||||
private String buildTeSpecialAnimalDetailSql() {
|
||||
return "SELECT DISTINCT " +
|
||||
"b.ID AS id, " +
|
||||
|
||||
@ -2425,7 +2425,13 @@ public class ZqMonitorServiceImpl implements ZqMonitorService {
|
||||
Map<String, Object> paramMap = new HashMap<>();
|
||||
|
||||
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
|
||||
String filterSql = buildMsstbprptFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
String filterSql = QgcQueryWrapperUtil.buildFilterCondition(
|
||||
dataSourceRequest.getFilter(),
|
||||
paramMap,
|
||||
new int[]{0},
|
||||
this::mapZqColumn
|
||||
);
|
||||
// String filterSql = buildMsstbprptFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0});
|
||||
if (StrUtil.isNotBlank(filterSql)) {
|
||||
sql.append(" AND ").append(filterSql).append(" ");
|
||||
}
|
||||
@ -2446,4 +2452,16 @@ public class ZqMonitorServiceImpl implements ZqMonitorService {
|
||||
dataSourceResult.setTotal(page == null ? resultList.size() : page.getTotal());
|
||||
return dataSourceResult;
|
||||
}
|
||||
|
||||
|
||||
private String mapZqColumn(String field) {
|
||||
if (StrUtil.isBlank(field)) {
|
||||
return null;
|
||||
}
|
||||
return switch (field.toLowerCase()) {
|
||||
case "dtintype" -> "rb.DTIN_TYPE";
|
||||
case "lgtd" -> "rb.LGTD";
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,6 +41,34 @@ public interface MsMapmoduleBMapper extends BaseMapper<MsMapmoduleB> {
|
||||
List<MapLayerVo> getMapLayerTree(@Param("moduleId") String moduleId, @Param("sid") String sid,
|
||||
@Param("templateId") String templateId);
|
||||
|
||||
/**
|
||||
* 按模块ID集合查询地图图层树(用于非管理员按用户菜单权限取图层)
|
||||
*/
|
||||
@Select("<script>"
|
||||
+ "SELECT DISTINCT BML.ID,BML.ANCHOR_PARAM_JSON, BML.PARENT_ID AS parentId, BML.TITLE, BML.CODE, BML.LABEL_LEVEL AS labelLevel, "
|
||||
+ "BML.CHECKABLE, BML.TYPE, BML.Z_INDEX AS zIndex, BML.STTP_TYPE AS sttpType, BML.LAYERS, "
|
||||
+ "BML.PARAMJSON AS paramJson, BML.URL, BML.URL_THD AS urlThd, BML.OPACITY, BML.SYSTEM_ID AS systemId, "
|
||||
+ "BML.OPTIONS, BMM.MULTI_SELECT AS multiSelect, BMM.CAN_BE_CHECKED AS canBeChecked, "
|
||||
+ "CASE WHEN BMM.CHECKED IS NULL THEN 0 ELSE BMM.CHECKED END AS checked, BML.ORDER_INDEX "
|
||||
+ "FROM MS_MAPLAYER_B BML INNER JOIN MS_MAPMODULE_B BMM ON BML.ID = BMM.RES_ID "
|
||||
+ "WHERE BMM.IS_DELETED = 0 AND BMM.RES_TYPE = 'layer' "
|
||||
+ "<if test=\"moduleIds != null and moduleIds.size() > 0\">"
|
||||
+ " AND BMM.MODULE_ID IN "
|
||||
+ "<foreach collection=\"moduleIds\" item=\"moduleId\" open=\"(\" separator=\",\" close=\")\">"
|
||||
+ "#{moduleId}"
|
||||
+ "</foreach>"
|
||||
+ "</if>"
|
||||
+ "<if test=\"sid != null and sid != ''\"> AND BMM.SYSTEM_ID = #{sid}</if>"
|
||||
+ "<choose>"
|
||||
+ "<when test=\"templateId != null and templateId != ''\"> AND BMM.TEMPLATE_ID = #{templateId}</when>"
|
||||
+ "<otherwise> AND (BMM.TEMPLATE_ID IS NULL OR BMM.TEMPLATE_ID = '00000000-0000-0000-0000-000000000000')</otherwise>"
|
||||
+ "</choose>"
|
||||
+ " AND BML.ENABLE = 1 AND BML.IS_DELETED = 0 AND (BML.TYPE NOT IN ('YXDT','DXDT','SLDT') OR BML.TYPE IS NULL) "
|
||||
+ "ORDER BY BML.ORDER_INDEX"
|
||||
+ "</script>")
|
||||
List<MapLayerVo> getMapLayerTreeByModuleIds(@Param("moduleIds") List<String> moduleIds, @Param("sid") String sid,
|
||||
@Param("templateId") String templateId);
|
||||
|
||||
/**
|
||||
* 查询地图工具箱(关联MS_MAPMODULE_B与MS_MAPTOOLBOX_B)
|
||||
*/
|
||||
|
||||
@ -2,18 +2,23 @@ package com.yfd.platform.qgc_sys.mapLayer.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.domain.MsMapmoduleB;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.domain.MsMaplayerB;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerAo;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.entity.vo.MapLayerVo;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMaplayerBMapper;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.mapper.MsMapmoduleBMapper;
|
||||
import com.yfd.platform.qgc_sys.mapLayer.service.IMapLayerBizService;
|
||||
import com.yfd.platform.system.domain.SysMenu;
|
||||
import com.yfd.platform.system.domain.SysDictionary;
|
||||
import com.yfd.platform.system.domain.SysDictionaryItems;
|
||||
import com.yfd.platform.system.domain.SysUser;
|
||||
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
|
||||
import com.yfd.platform.system.mapper.SysDictionaryMapper;
|
||||
import com.yfd.platform.system.mapper.SysMenuMapper;
|
||||
import com.yfd.platform.system.mapper.SysUserMapper;
|
||||
import com.yfd.platform.system.service.IAdminAuthService;
|
||||
import com.yfd.platform.utils.SecurityUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@ -43,6 +48,12 @@ public class MapLayerBizServiceImpl implements IMapLayerBizService {
|
||||
@Resource
|
||||
private MsMapmoduleBMapper msMapmoduleBMapper;
|
||||
|
||||
@Resource
|
||||
private SysMenuMapper sysMenuMapper;
|
||||
|
||||
@Resource
|
||||
private IAdminAuthService adminAuthService;
|
||||
|
||||
@Override
|
||||
public List<MsMaplayerB> getMapLayerTree(MapLayerAo flag) {
|
||||
// 1. 查询字典 "DTZJLX" 获取需要排除的图层类型
|
||||
@ -173,12 +184,27 @@ public class MapLayerBizServiceImpl implements IMapLayerBizService {
|
||||
|
||||
@Override
|
||||
public List<MapLayerVo> getMapLayerTree(String moduleId, String systemId, String templateId) {
|
||||
// 通过 JOIN 查询 MS_MAPLAYER_B 和 MS_MAPMODULE_B
|
||||
List<MapLayerVo> allLayers = msMapmoduleBMapper.getMapLayerTree(moduleId, systemId, templateId);
|
||||
|
||||
if (allLayers == null || allLayers.isEmpty()) {
|
||||
List<MapLayerVo> allLayers;
|
||||
boolean currentManagedAdmin = adminAuthService.isCurrentManagedAdmin();
|
||||
if (currentManagedAdmin) {
|
||||
allLayers = msMapmoduleBMapper.getMapLayerTree(moduleId, systemId, templateId);
|
||||
} else {
|
||||
List<String> currentUserModuleIds = getCurrentUserModuleIds();
|
||||
if (currentUserModuleIds.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
allLayers = msMapmoduleBMapper.getMapLayerTreeByModuleIds(currentUserModuleIds, systemId, templateId);
|
||||
allLayers = supplementMissingParentLayers(allLayers);
|
||||
allLayers = deduplicateMapLayers(allLayers);
|
||||
}
|
||||
if (allLayers.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if (!currentManagedAdmin) {
|
||||
Set<String> checkedLayerIds = getCurrentModuleCheckedLayerIds(moduleId, systemId, templateId);
|
||||
resetCheckedStatus(allLayers, checkedLayerIds);
|
||||
}
|
||||
allLayers = sortMapLayerVos(allLayers);
|
||||
|
||||
// 取第一级
|
||||
List<MapLayerVo> parents = allLayers.stream()
|
||||
@ -211,4 +237,177 @@ public class MapLayerBizServiceImpl implements IMapLayerBizService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> getCurrentUserModuleIds() {
|
||||
String userId = SecurityUtils.getUserId();
|
||||
if (StrUtil.isBlank(userId)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<SysMenu> userMenus = sysMenuMapper.selectMenuByUserId(userId, null);
|
||||
if (userMenus == null || userMenus.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return userMenus.stream()
|
||||
.map(SysMenu::getId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private List<MapLayerVo> supplementMissingParentLayers(List<MapLayerVo> layers) {
|
||||
if (layers == null || layers.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<MapLayerVo> result = new ArrayList<>(layers);
|
||||
Set<String> existingIds = result.stream()
|
||||
.map(MapLayerVo::getId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
Set<String> pendingParentIds = result.stream()
|
||||
.map(MapLayerVo::getParentId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.filter(parentId -> !existingIds.contains(parentId))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
while (!pendingParentIds.isEmpty()) {
|
||||
LambdaQueryWrapper<MsMaplayerB> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.in(MsMaplayerB::getId, pendingParentIds)
|
||||
.eq(MsMaplayerB::getIsDeleted, 0)
|
||||
.eq(MsMaplayerB::getEnable, 1)
|
||||
.and(w -> w.notIn(MsMaplayerB::getType, "YXDT", "DXDT", "SLDT").or().isNull(MsMaplayerB::getType))
|
||||
.orderByAsc(MsMaplayerB::getOrderIndex);
|
||||
List<MsMaplayerB> parentLayers = msMaplayerBMapper.selectList(wrapper);
|
||||
if (parentLayers == null || parentLayers.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Set<String> nextParentIds = new LinkedHashSet<>();
|
||||
for (MsMaplayerB parentLayer : parentLayers) {
|
||||
if (parentLayer == null || StrUtil.isBlank(parentLayer.getId()) || existingIds.contains(parentLayer.getId())) {
|
||||
continue;
|
||||
}
|
||||
result.add(toMapLayerVo(parentLayer));
|
||||
existingIds.add(parentLayer.getId());
|
||||
if (StrUtil.isNotBlank(parentLayer.getParentId()) && !existingIds.contains(parentLayer.getParentId())) {
|
||||
nextParentIds.add(parentLayer.getParentId());
|
||||
}
|
||||
}
|
||||
pendingParentIds = nextParentIds;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<MapLayerVo> sortMapLayerVos(List<MapLayerVo> layers) {
|
||||
return layers.stream()
|
||||
.sorted(Comparator
|
||||
.comparingInt((MapLayerVo item) -> parseOrderIndex(item.getOrderIndex()))
|
||||
.thenComparing(item -> StrUtil.nullToDefault(item.getId(), "")))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private int parseOrderIndex(String orderIndex) {
|
||||
if (StrUtil.isBlank(orderIndex)) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(orderIndex);
|
||||
} catch (NumberFormatException ex) {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
private MapLayerVo toMapLayerVo(MsMaplayerB layer) {
|
||||
MapLayerVo vo = new MapLayerVo();
|
||||
vo.setId(layer.getId());
|
||||
vo.setParentId(layer.getParentId());
|
||||
vo.setTitle(layer.getTitle());
|
||||
vo.setCode(layer.getCode());
|
||||
vo.setLabelLevel(layer.getLabelLevel());
|
||||
vo.setCheckable(layer.getCheckable());
|
||||
vo.setType(layer.getType());
|
||||
vo.setZIndex(layer.getZIndex());
|
||||
vo.setSttpType(layer.getSttpType());
|
||||
vo.setLayers(layer.getLayers());
|
||||
vo.setUrl(layer.getUrl());
|
||||
vo.setUrlThd(layer.getUrlThd());
|
||||
vo.setOpacity(layer.getOpacity());
|
||||
vo.setParamJson(layer.getParamJson());
|
||||
vo.setAnchorParamJson(layer.getAnchorParamJson());
|
||||
vo.setOptions(layer.getOptions());
|
||||
vo.setOrderIndex(layer.getOrderIndex() == null ? null : String.valueOf(layer.getOrderIndex()));
|
||||
vo.setChecked(0);
|
||||
vo.setCanBeChecked(0);
|
||||
vo.setMultiSelect(1);
|
||||
return vo;
|
||||
}
|
||||
|
||||
private List<MapLayerVo> deduplicateMapLayers(List<MapLayerVo> layers) {
|
||||
Map<String, MapLayerVo> uniqueMap = new LinkedHashMap<>();
|
||||
for (MapLayerVo layer : layers) {
|
||||
if (layer == null || StrUtil.isBlank(layer.getId())) {
|
||||
continue;
|
||||
}
|
||||
uniqueMap.putIfAbsent(layer.getId(), layer);
|
||||
}
|
||||
return new ArrayList<>(uniqueMap.values());
|
||||
}
|
||||
|
||||
private Set<String> getCurrentModuleCheckedLayerIds(String moduleId, String systemId, String templateId) {
|
||||
if (StrUtil.isBlank(moduleId)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
LambdaQueryWrapper<MsMapmoduleB> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(MsMapmoduleB::getModuleId, moduleId)
|
||||
.eq(MsMapmoduleB::getResType, "layer")
|
||||
.eq(MsMapmoduleB::getIsDeleted, 0)
|
||||
.select(MsMapmoduleB::getResId);
|
||||
if (StrUtil.isNotBlank(systemId)) {
|
||||
wrapper.eq(MsMapmoduleB::getSystemId, systemId);
|
||||
}
|
||||
if (StrUtil.isNotBlank(templateId)) {
|
||||
wrapper.eq(MsMapmoduleB::getTemplateId, templateId);
|
||||
} else {
|
||||
wrapper.and(w -> w.isNull(MsMapmoduleB::getTemplateId)
|
||||
.or()
|
||||
.eq(MsMapmoduleB::getTemplateId, "00000000-0000-0000-0000-000000000000"));
|
||||
}
|
||||
List<MsMapmoduleB> moduleLayers = msMapmoduleBMapper.selectList(wrapper);
|
||||
if (moduleLayers == null || moduleLayers.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> checkedIds = moduleLayers.stream()
|
||||
.map(MsMapmoduleB::getResId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new));
|
||||
if (checkedIds.isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> pendingParentIds = new LinkedHashSet<>(checkedIds);
|
||||
while (!pendingParentIds.isEmpty()) {
|
||||
LambdaQueryWrapper<MsMaplayerB> wrapperParent = new LambdaQueryWrapper<>();
|
||||
wrapperParent.in(MsMaplayerB::getId, pendingParentIds)
|
||||
.eq(MsMaplayerB::getIsDeleted, 0)
|
||||
.select(MsMaplayerB::getId, MsMaplayerB::getParentId);
|
||||
List<MsMaplayerB> currentLayers = msMaplayerBMapper.selectList(wrapperParent);
|
||||
if (currentLayers == null || currentLayers.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
Set<String> nextParentIds = new LinkedHashSet<>();
|
||||
for (MsMaplayerB currentLayer : currentLayers) {
|
||||
if (StrUtil.isNotBlank(currentLayer.getParentId()) && checkedIds.add(currentLayer.getParentId())) {
|
||||
nextParentIds.add(currentLayer.getParentId());
|
||||
}
|
||||
}
|
||||
pendingParentIds = nextParentIds;
|
||||
}
|
||||
return checkedIds;
|
||||
}
|
||||
|
||||
private void resetCheckedStatus(List<MapLayerVo> layers, Set<String> checkedLayerIds) {
|
||||
if (layers == null || layers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<String> normalizedCheckedIds = checkedLayerIds == null ? Collections.emptySet() : checkedLayerIds;
|
||||
for (MapLayerVo layer : layers) {
|
||||
layer.setChecked(normalizedCheckedIds.contains(layer.getId()) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,9 +19,12 @@ import com.yfd.platform.utils.SecurityUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -134,7 +137,8 @@ public class MapmoduleBServiceImpl extends ServiceImpl<MsMapmoduleBMapper, MsMap
|
||||
|
||||
// 1. GIS图层区
|
||||
List<MapLayerVo> layer = mapLayerBizService.getMapLayerTree(
|
||||
mapmoduleB.getModuleId(), mapmoduleB.getSystemId(), templateId);
|
||||
mapmoduleB.getModuleId(), mapmoduleB.getSystemId(), templateId);;
|
||||
|
||||
mapmoduleVo.setMapLayerVos(layer);
|
||||
|
||||
// 2. 地图图例
|
||||
@ -182,4 +186,23 @@ public class MapmoduleBServiceImpl extends ServiceImpl<MsMapmoduleBMapper, MsMap
|
||||
}
|
||||
return msMaptoolboxBList;
|
||||
}
|
||||
|
||||
private boolean hasCurrentUserModulePermission(String moduleId) {
|
||||
if (StrUtil.isBlank(moduleId) || StrUtil.equalsIgnoreCase(moduleId, "common")) {
|
||||
return true;
|
||||
}
|
||||
String userId = SecurityUtils.getUserId();
|
||||
if (StrUtil.isBlank(userId)) {
|
||||
return false;
|
||||
}
|
||||
List<SysMenu> userMenus = sysMenuMapper.selectMenuByUserId(userId, null);
|
||||
if (userMenus == null || userMenus.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Set<String> menuIds = userMenus.stream()
|
||||
.map(SysMenu::getId)
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
return menuIds.contains(moduleId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package com.yfd.platform.system.controller;
|
||||
|
||||
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.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 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 java.util.Date;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/system/pushConfig")
|
||||
@Tag(name = "推送配置")
|
||||
public class PushConfigController {
|
||||
|
||||
@Resource
|
||||
private IPushConfigService pushConfigService;
|
||||
|
||||
@Operation(summary = "查询推送配置列表")
|
||||
@GetMapping("/getPushConfigList")
|
||||
public ResponseResult getPushConfigList(Page<PushConfig> page,
|
||||
String categoryName,
|
||||
String messageType,
|
||||
Integer targetType,
|
||||
Integer status) {
|
||||
return ResponseResult.successData(pushConfigService.getPushConfigPage(page, categoryName, messageType, targetType, status));
|
||||
}
|
||||
|
||||
@Operation(summary = "根据ID查询推送配置")
|
||||
@GetMapping("/getPushConfigById")
|
||||
public ResponseResult getPushConfigById(@RequestParam String id) {
|
||||
return ResponseResult.successData(pushConfigService.getById(id));
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "新增推送配置")
|
||||
@Operation(summary = "新增推送配置")
|
||||
@PostMapping("/addPushConfig")
|
||||
public ResponseResult addPushConfig(@RequestBody PushConfig pushConfig) {
|
||||
return pushConfigService.addPushConfig(pushConfig) ? ResponseResult.success() : ResponseResult.error("新增失败");
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "修改推送配置")
|
||||
@Operation(summary = "修改推送配置")
|
||||
@PostMapping("/updatePushConfig")
|
||||
public ResponseResult updatePushConfig(@RequestBody PushConfig pushConfig) {
|
||||
return pushConfigService.updatePushConfig(pushConfig) ? ResponseResult.success() : ResponseResult.error("修改失败");
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "删除推送配置")
|
||||
@Operation(summary = "删除推送配置")
|
||||
@PostMapping("/deletePushConfig")
|
||||
public ResponseResult deletePushConfig(@RequestParam String ids) {
|
||||
return pushConfigService.deletePushConfig(ids) ? ResponseResult.success() : ResponseResult.error("删除失败");
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "设置推送配置状态")
|
||||
@Operation(summary = "设置推送配置状态")
|
||||
@PostMapping("/setPushConfigStatus")
|
||||
public ResponseResult setPushConfigStatus(@RequestParam String id, @RequestParam Integer status) {
|
||||
return pushConfigService.setPushConfigStatus(id, status) ? ResponseResult.success() : ResponseResult.error("设置失败");
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "设置短信推送开关")
|
||||
@Operation(summary = "设置短信推送开关")
|
||||
@PostMapping("/setPushConfigSmsSwitch")
|
||||
public ResponseResult setPushConfigSmsSwitch(@RequestParam String id, @RequestParam Integer isSms) {
|
||||
return pushConfigService.setPushConfigSmsSwitch(id, isSms) ? ResponseResult.success() : ResponseResult.error("设置失败");
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "保存推送目标")
|
||||
@Operation(summary = "保存推送目标")
|
||||
@PostMapping("/savePushTargets")
|
||||
public ResponseResult savePushTargets(@RequestBody PushConfigTargetRequest request) {
|
||||
return pushConfigService.savePushTargets(request) ? ResponseResult.success() : ResponseResult.error("保存失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "查询推送目标")
|
||||
@GetMapping("/getPushTargets")
|
||||
public ResponseResult getPushTargets(@RequestParam String configId) {
|
||||
return ResponseResult.successData(pushConfigService.getPushTargets(configId));
|
||||
}
|
||||
|
||||
@Log(module = "推送配置", value = "立即执行推送配置")
|
||||
@Operation(summary = "立即执行推送配置")
|
||||
@PostMapping("/execution")
|
||||
public ResponseResult execution(@RequestParam String configId) {
|
||||
return pushConfigService.executeNow(configId) ? ResponseResult.success() : ResponseResult.error("执行失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "查询推送历史主表")
|
||||
@GetMapping("/getPushHistoryList")
|
||||
public ResponseResult getPushHistoryList(Page<PushHistory> 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));
|
||||
}
|
||||
|
||||
@Operation(summary = "查询推送历史明细")
|
||||
@GetMapping("/getPushHistoryDetailList")
|
||||
public ResponseResult getPushHistoryDetailList(Page<PushHistoryDetail> page,
|
||||
String historyId,
|
||||
Integer status) {
|
||||
return ResponseResult.successData(pushConfigService.getPushHistoryDetailPage(page, historyId, status));
|
||||
}
|
||||
}
|
||||
@ -78,7 +78,7 @@ public class SmsVerifyCodeController {
|
||||
*/
|
||||
@PostMapping("/sendCode")
|
||||
@Operation(summary = "发送验证码")
|
||||
public ResponseResult sendVerifyCode(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult sendVerifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
String phone = smsVerifyCodeRequest.getPhone();
|
||||
Integer type = smsVerifyCodeRequest.getType();
|
||||
|
||||
@ -91,21 +91,21 @@ public class SmsVerifyCodeController {
|
||||
|
||||
// 1. 注册验证码校验
|
||||
if (type.equals(SmsVerifyCode.TYPE_REGISTER)) {
|
||||
SysUser existUser = userService.getUserByPhone(phone);
|
||||
SysUser existUser = userService.getUserByPhone(phone,tenantId);
|
||||
if (existUser != null) {
|
||||
return ResponseResult.error("该手机号已注册");
|
||||
}
|
||||
}
|
||||
// 2. 找回密码验证码校验
|
||||
else if (type.equals(SmsVerifyCode.TYPE_FIND_PASSWORD)) {
|
||||
SysUser existUser = userService.getUserByPhone(phone);
|
||||
SysUser existUser = userService.getUserByPhone(phone,tenantId);
|
||||
if (existUser == null) {
|
||||
return ResponseResult.error("该手机号未注册");
|
||||
}
|
||||
}
|
||||
// 3. 登录验证码校验(新增)
|
||||
else if (type.equals(SmsVerifyCode.TYPE_LOGIN)) {
|
||||
SysUser existUser = userService.getUserByPhone(phone);
|
||||
SysUser existUser = userService.getUserByPhone(phone,tenantId);
|
||||
if (existUser == null) {
|
||||
return ResponseResult.error("该手机号未注册,请先注册");
|
||||
}
|
||||
@ -118,7 +118,7 @@ public class SmsVerifyCodeController {
|
||||
return ResponseResult.error("类型错误:1-注册 2-找回密码 3-登录");
|
||||
}
|
||||
|
||||
String code = smsVerifyCodeService.sendVerifyCode(phone, type);
|
||||
String code = smsVerifyCodeService.sendVerifyCode(phone, type,tenantId);
|
||||
if (code == null) {
|
||||
return ResponseResult.error("验证码发送失败,请稍后重试");
|
||||
}
|
||||
@ -132,7 +132,7 @@ public class SmsVerifyCodeController {
|
||||
*/
|
||||
@PostMapping("/batchSendContent")
|
||||
@Operation(summary = "批量发送短信")
|
||||
public ResponseResult batchSendContent(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult batchSendContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
|
||||
List<String> phoneList = smsVerifyCodeRequest.getPhoneList();
|
||||
if(phoneList==null){
|
||||
@ -148,7 +148,7 @@ public class SmsVerifyCodeController {
|
||||
*/
|
||||
@PostMapping("/batchUrgeContent")
|
||||
@Operation(summary = "催促")
|
||||
public ResponseResult batchUrgeContent(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult batchUrgeContent(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
List<String> userIds = smsVerifyCodeRequest.getUserIds();
|
||||
String content = smsVerifyCodeRequest.getContent();
|
||||
|
||||
@ -161,7 +161,7 @@ public class SmsVerifyCodeController {
|
||||
}
|
||||
|
||||
try {
|
||||
int successCount = smsVerifyCodeService.urgeByUserIds(userIds, content);
|
||||
int successCount = smsVerifyCodeService.urgeByUserIds(tenantId,userIds, content);
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
// result.put("successCount", successCount);
|
||||
result.put("totalCount", userIds.size());
|
||||
@ -180,7 +180,7 @@ public class SmsVerifyCodeController {
|
||||
@PostMapping("/register")
|
||||
@Operation(summary = "注册用户")
|
||||
@Transactional
|
||||
public ResponseResult register(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult register(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
String code = smsVerifyCodeRequest.getCode();
|
||||
if (smsVerifyCodeRequest.getPhone() == null || smsVerifyCodeRequest.getPhone().isEmpty()) {
|
||||
return ResponseResult.error("手机号不能为空");
|
||||
@ -195,12 +195,12 @@ public class SmsVerifyCodeController {
|
||||
return ResponseResult.error("验证码不能为空");
|
||||
}
|
||||
|
||||
boolean verified = smsVerifyCodeService.verifyCode(smsVerifyCodeRequest.getPhone(), code, SmsVerifyCode.TYPE_REGISTER);
|
||||
boolean verified = smsVerifyCodeService.verifyCode(smsVerifyCodeRequest.getPhone(), code, SmsVerifyCode.TYPE_REGISTER,tenantId);
|
||||
if (!verified) {
|
||||
return ResponseResult.error("验证码错误或已过期");
|
||||
}
|
||||
|
||||
SysUser existUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone());
|
||||
SysUser existUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId);
|
||||
if (existUser != null) {
|
||||
return ResponseResult.error("该手机号已注册");
|
||||
}
|
||||
@ -225,7 +225,7 @@ public class SmsVerifyCodeController {
|
||||
user.setCompanyCode(smsVerifyCodeRequest.getCompanyCode());
|
||||
boolean success = userService.save(user);
|
||||
// 给注册用户加上默认权限
|
||||
SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone());
|
||||
SysUser savedUser = userService.getUserByPhone(smsVerifyCodeRequest.getPhone(),tenantId);
|
||||
if (savedUser != null) {
|
||||
this.addDefaultRole(savedUser.getId(), smsVerifyCodeRequest);
|
||||
}
|
||||
@ -338,7 +338,7 @@ public class SmsVerifyCodeController {
|
||||
*/
|
||||
@PostMapping("/resetPassword")
|
||||
@Operation(summary = "找回密码")
|
||||
public ResponseResult resetPassword(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult resetPassword(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
String password = smsVerifyCodeRequest.getPassword();
|
||||
String phone = smsVerifyCodeRequest.getPhone();
|
||||
String code = smsVerifyCodeRequest.getCode();
|
||||
@ -352,12 +352,12 @@ public class SmsVerifyCodeController {
|
||||
return ResponseResult.error("新密码不能为空");
|
||||
}
|
||||
|
||||
boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD);
|
||||
boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_FIND_PASSWORD,tenantId);
|
||||
if (!verified) {
|
||||
return ResponseResult.error("验证码错误或已过期");
|
||||
}
|
||||
|
||||
SysUser existUser = userService.getUserByPhone(phone);
|
||||
SysUser existUser = userService.getUserByPhone(phone,tenantId);
|
||||
if (existUser == null) {
|
||||
return ResponseResult.error("该手机号未注册");
|
||||
}
|
||||
@ -382,11 +382,11 @@ public class SmsVerifyCodeController {
|
||||
*/
|
||||
@PostMapping("/verifyCode")
|
||||
@Operation(summary = "验证验证码")
|
||||
public ResponseResult verifyCode(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult verifyCode(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
String phone = smsVerifyCodeRequest.getPhone();
|
||||
String code = smsVerifyCodeRequest.getCode();
|
||||
Integer type = smsVerifyCodeRequest.getType();
|
||||
boolean valid = smsVerifyCodeService.verifyCode(phone, code, type);
|
||||
boolean valid = smsVerifyCodeService.verifyCode(phone, code, type,tenantId);
|
||||
if (valid) {
|
||||
return ResponseResult.success();
|
||||
} else {
|
||||
@ -399,7 +399,7 @@ public class SmsVerifyCodeController {
|
||||
*/
|
||||
@PostMapping("/login")
|
||||
@Operation(summary = "短信验证码登录")
|
||||
public ResponseResult smsLogin(@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
public ResponseResult smsLogin(@RequestHeader(value = "Tenant_id", required = false) String tenantId,@RequestBody SmsVerifyCodeRequest smsVerifyCodeRequest) {
|
||||
String phone = smsVerifyCodeRequest.getPhone();
|
||||
String code = smsVerifyCodeRequest.getCode();
|
||||
if (phone == null || phone.isEmpty()) {
|
||||
@ -409,12 +409,12 @@ public class SmsVerifyCodeController {
|
||||
return ResponseResult.error("验证码不能为空");
|
||||
}
|
||||
|
||||
boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_LOGIN);
|
||||
boolean verified = smsVerifyCodeService.verifyCode(phone, code, SmsVerifyCode.TYPE_LOGIN,tenantId);
|
||||
if (!verified) {
|
||||
return ResponseResult.error("验证码错误或已过期");
|
||||
}
|
||||
|
||||
SysUser user = userService.getUserByPhone(phone);
|
||||
SysUser user = userService.getUserByPhone(phone,tenantId);
|
||||
if (user == null) {
|
||||
return ResponseResult.error("该手机号未注册");
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
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 lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("PUSH_CONFIG")
|
||||
public class PushConfig implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
private String categoryCode;
|
||||
|
||||
private String categoryName;
|
||||
|
||||
private String baseIdList;
|
||||
|
||||
private String baseNameList;
|
||||
|
||||
private String messageType;
|
||||
|
||||
private String cronExpression;
|
||||
|
||||
private Integer targetType;
|
||||
|
||||
private Integer isSms;
|
||||
|
||||
private Long pushCount;
|
||||
|
||||
private Long dailyPushCount;
|
||||
|
||||
private Date finishTime;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private Date updatedAt;
|
||||
|
||||
private String recordUser;
|
||||
|
||||
private String modifyUser;
|
||||
|
||||
private Date modifyTime;
|
||||
|
||||
private Integer isDeleted;
|
||||
|
||||
private String deleteUser;
|
||||
|
||||
private Date deleteTime;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.yfd.platform.system.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class PushConfigTargetRequest implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String configId;
|
||||
|
||||
/**
|
||||
* 0-用户,1-角色
|
||||
*/
|
||||
private Integer type;
|
||||
|
||||
private List<String> userRoleIds;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.yfd.platform.system.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class PushConfigTargetVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String id;
|
||||
|
||||
private String configId;
|
||||
|
||||
private Integer type;
|
||||
|
||||
private String userRoleId;
|
||||
|
||||
private String targetName;
|
||||
|
||||
private String targetPhone;
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
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 lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("PUSH_CONFIG_USER")
|
||||
public class PushConfigUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
private String configId;
|
||||
|
||||
private Integer type;
|
||||
|
||||
private String userRoleId;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private String recordUser;
|
||||
|
||||
private String modifyUser;
|
||||
|
||||
private Date modifyTime;
|
||||
|
||||
private Integer isDeleted;
|
||||
|
||||
private String deleteUser;
|
||||
|
||||
private Date deleteTime;
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
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 lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("PUSH_HISTORY")
|
||||
public class PushHistory implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
private String configId;
|
||||
|
||||
private Date planTime;
|
||||
|
||||
private String messageTypeCode;
|
||||
|
||||
private String messageTypeName;
|
||||
|
||||
private String title;
|
||||
|
||||
private String content;
|
||||
|
||||
private Long pushedCount;
|
||||
|
||||
private Long successCount;
|
||||
|
||||
private Long failCount;
|
||||
|
||||
private Long pendingCount;
|
||||
|
||||
private String sendChannel;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String source;
|
||||
|
||||
private String relation;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private Date updatedAt;
|
||||
|
||||
private String recordUser;
|
||||
|
||||
private String modifyUser;
|
||||
|
||||
private Date modifyTime;
|
||||
|
||||
private Integer isDeleted;
|
||||
|
||||
private String deleteUser;
|
||||
|
||||
private Date deleteTime;
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
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 lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@TableName("PUSH_HISTORY_DETAIL")
|
||||
public class PushHistoryDetail implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String id;
|
||||
|
||||
private String historyId;
|
||||
|
||||
private String targetName;
|
||||
|
||||
private String targetPhone;
|
||||
|
||||
private Integer status;
|
||||
|
||||
private String sendChannel;
|
||||
|
||||
private Date sendTime;
|
||||
|
||||
private String errorMsg;
|
||||
|
||||
private Date createdAt;
|
||||
|
||||
private String recordUser;
|
||||
|
||||
private String modifyUser;
|
||||
|
||||
private Date modifyTime;
|
||||
|
||||
private Integer isDeleted;
|
||||
|
||||
private String deleteUser;
|
||||
|
||||
private Date deleteTime;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.yfd.platform.system.domain;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class PushTargetUserVo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String userId;
|
||||
|
||||
private String targetName;
|
||||
|
||||
private String targetPhone;
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
package com.yfd.platform.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
@ -115,4 +116,18 @@ public class QuartzJob implements Serializable {
|
||||
@Schema(description = "备用3")
|
||||
private String custom3;
|
||||
|
||||
/**
|
||||
* 业务模块编码(如:PUSH-推送配置,SYNC-数据同步,REPORT-报表生成)
|
||||
*/
|
||||
@Schema(description = "业务模块编码")
|
||||
@TableField("BIZ_MODULE")
|
||||
private String bizModule;
|
||||
|
||||
/**
|
||||
* 关联业务表的主键ID(如 PUSH_CONFIG.ID)
|
||||
*/
|
||||
@Schema(description = "关联业务主键ID")
|
||||
@TableField("BIZ_ID")
|
||||
private String bizId;
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.yfd.platform.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
@ -63,4 +64,10 @@ public class SmsVerifyCode implements Serializable {
|
||||
* 0-未使用 1-已使用
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@TableField("TENANT_ID")
|
||||
private String tenantId;
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.yfd.platform.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yfd.platform.system.domain.PushConfig;
|
||||
|
||||
public interface PushConfigMapper extends BaseMapper<PushConfig> {
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.yfd.platform.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yfd.platform.system.domain.PushConfigTargetVo;
|
||||
import com.yfd.platform.system.domain.PushConfigUser;
|
||||
import com.yfd.platform.system.domain.PushTargetUserVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface PushConfigUserMapper extends BaseMapper<PushConfigUser> {
|
||||
|
||||
List<PushTargetUserVo> selectAllActiveUsers();
|
||||
|
||||
List<PushTargetUserVo> selectTargetUsersByConfigId(@Param("configId") String configId);
|
||||
|
||||
List<PushConfigTargetVo> selectConfigTargets(@Param("configId") String configId);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.yfd.platform.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yfd.platform.system.domain.PushHistoryDetail;
|
||||
|
||||
public interface PushHistoryDetailMapper extends BaseMapper<PushHistoryDetail> {
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.yfd.platform.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.yfd.platform.system.domain.PushHistory;
|
||||
|
||||
public interface PushHistoryMapper extends BaseMapper<PushHistory> {
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
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 java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface IPushConfigService extends IService<PushConfig> {
|
||||
|
||||
Page<PushConfig> getPushConfigPage(Page<PushConfig> page,
|
||||
String categoryName,
|
||||
String messageType,
|
||||
Integer targetType,
|
||||
Integer status);
|
||||
|
||||
boolean addPushConfig(PushConfig pushConfig);
|
||||
|
||||
boolean updatePushConfig(PushConfig pushConfig);
|
||||
|
||||
boolean deletePushConfig(String ids);
|
||||
|
||||
boolean setPushConfigStatus(String id, Integer status);
|
||||
|
||||
boolean setPushConfigSmsSwitch(String id, Integer isSms);
|
||||
|
||||
boolean savePushTargets(PushConfigTargetRequest request);
|
||||
|
||||
List<PushConfigTargetVo> getPushTargets(String configId);
|
||||
|
||||
Page<PushHistory> getPushHistoryPage(Page<PushHistory> page,
|
||||
String configId,
|
||||
Integer status,
|
||||
String messageTypeCode,
|
||||
Date startTime,
|
||||
Date endTime);
|
||||
|
||||
Page<PushHistoryDetail> getPushHistoryDetailPage(Page<PushHistoryDetail> page,
|
||||
String historyId,
|
||||
Integer status);
|
||||
|
||||
boolean executeNow(String configId);
|
||||
|
||||
void executePushConfig(String configId);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.yfd.platform.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yfd.platform.system.domain.PushConfigUser;
|
||||
|
||||
public interface IPushConfigUserService extends IService<PushConfigUser> {
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.yfd.platform.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yfd.platform.system.domain.PushHistoryDetail;
|
||||
|
||||
public interface IPushHistoryDetailService extends IService<PushHistoryDetail> {
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.yfd.platform.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.yfd.platform.system.domain.PushHistory;
|
||||
|
||||
public interface IPushHistoryService extends IService<PushHistory> {
|
||||
}
|
||||
@ -18,7 +18,7 @@ public interface ISmsVerifyCodeService extends IService<SmsVerifyCode> {
|
||||
* @param type 1-注册 2-找回密码
|
||||
* @return 验证码
|
||||
*/
|
||||
String sendVerifyCode(String phone, Integer type);
|
||||
String sendVerifyCode(String phone, Integer type,String tenantId);
|
||||
|
||||
/**
|
||||
* 验证验证码
|
||||
@ -27,7 +27,7 @@ public interface ISmsVerifyCodeService extends IService<SmsVerifyCode> {
|
||||
* @param type 类型 1-注册 2-找回密码
|
||||
* @return 是否验证通过
|
||||
*/
|
||||
boolean verifyCode(String phone, String code, Integer type);
|
||||
boolean verifyCode(String phone, String code, Integer type,String tenantId);
|
||||
|
||||
/**
|
||||
* 标记验证码已使用
|
||||
@ -50,5 +50,5 @@ public interface ISmsVerifyCodeService extends IService<SmsVerifyCode> {
|
||||
boolean sendAuditNotify(String phone, String auditStatus, String reason);
|
||||
|
||||
void batchSendContent(List<String> phoneList, String content);
|
||||
int urgeByUserIds(List<String> userIds, String content);
|
||||
int urgeByUserIds(String tenantId,List<String> userIds, String content);
|
||||
}
|
||||
@ -155,7 +155,7 @@ public interface IUserService extends IService<SysUser> {
|
||||
*phone 手机号
|
||||
* 返回值说明: 用户对象
|
||||
************************************/
|
||||
SysUser getUserByPhone(String phone);
|
||||
SysUser getUserByPhone(String phone,String tenantId);
|
||||
|
||||
/***********************************
|
||||
* 用途说明:根据手机号修改密码
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package com.yfd.platform.system.service.impl;
|
||||
|
||||
import com.yfd.platform.system.service.IPushConfigService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service("pushConfigQuartzExecutor")
|
||||
public class PushConfigQuartzExecutor {
|
||||
|
||||
@Resource
|
||||
private IPushConfigService pushConfigService;
|
||||
|
||||
public void execute(String configId) {
|
||||
pushConfigService.executePushConfig(configId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,511 @@
|
||||
package com.yfd.platform.system.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
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.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.mapper.PushConfigMapper;
|
||||
import com.yfd.platform.system.mapper.PushConfigUserMapper;
|
||||
import com.yfd.platform.system.service.IPushConfigService;
|
||||
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.QuartzManage;
|
||||
import com.yfd.platform.utils.SecurityUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
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;
|
||||
|
||||
@Service
|
||||
public class PushConfigServiceImpl extends ServiceImpl<PushConfigMapper, PushConfig> implements IPushConfigService {
|
||||
|
||||
private static final String QUARTZ_BIZ_TYPE = "PUSH_CONFIG";
|
||||
private static final String DEFAULT_SEND_CHANNEL = "SMS";
|
||||
private static final String DEFAULT_SOURCE = "PUSH_CONFIG";
|
||||
|
||||
@Resource
|
||||
private PushConfigUserMapper pushConfigUserMapper;
|
||||
|
||||
@Resource
|
||||
private IPushConfigUserService pushConfigUserService;
|
||||
|
||||
@Resource
|
||||
private IPushHistoryService pushHistoryService;
|
||||
|
||||
@Resource
|
||||
private IPushHistoryDetailService pushHistoryDetailService;
|
||||
|
||||
@Resource
|
||||
private IQuartzJobService quartzJobService;
|
||||
|
||||
@Resource
|
||||
private QuartzManage quartzManage;
|
||||
|
||||
@Override
|
||||
public Page<PushConfig> getPushConfigPage(Page<PushConfig> page,
|
||||
String categoryName,
|
||||
String messageType,
|
||||
Integer targetType,
|
||||
Integer status) {
|
||||
LambdaQueryWrapper<PushConfig> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(PushConfig::getIsDeleted, 0)
|
||||
.like(StrUtil.isNotBlank(categoryName), PushConfig::getCategoryName, categoryName)
|
||||
.like(StrUtil.isNotBlank(messageType), PushConfig::getMessageType, messageType)
|
||||
.eq(targetType != null, PushConfig::getTargetType, targetType)
|
||||
.eq(status != null, PushConfig::getStatus, status)
|
||||
.orderByDesc(PushConfig::getUpdatedAt, PushConfig::getCreatedAt);
|
||||
return this.page(page, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean addPushConfig(PushConfig pushConfig) {
|
||||
validatePushConfig(pushConfig, false);
|
||||
Date now = new Date();
|
||||
pushConfig.setCreatedAt(now);
|
||||
pushConfig.setUpdatedAt(now);
|
||||
pushConfig.setModifyTime(now);
|
||||
pushConfig.setRecordUser(currentUserIdOrSystem());
|
||||
pushConfig.setModifyUser(currentUserIdOrSystem());
|
||||
pushConfig.setIsDeleted(0);
|
||||
pushConfig.setStatus(pushConfig.getStatus() == null ? 1 : pushConfig.getStatus());
|
||||
pushConfig.setIsSms(pushConfig.getIsSms() == null ? 0 : pushConfig.getIsSms());
|
||||
pushConfig.setPushCount(pushConfig.getPushCount() == null ? 0L : pushConfig.getPushCount());
|
||||
pushConfig.setDailyPushCount(pushConfig.getDailyPushCount() == null ? 0L : pushConfig.getDailyPushCount());
|
||||
return this.save(pushConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updatePushConfig(PushConfig pushConfig) {
|
||||
validatePushConfig(pushConfig, true);
|
||||
PushConfig dbConfig = getAvailableConfig(pushConfig.getId());
|
||||
dbConfig.setCategoryCode(pushConfig.getCategoryCode());
|
||||
dbConfig.setCategoryName(pushConfig.getCategoryName());
|
||||
dbConfig.setBaseIdList(pushConfig.getBaseIdList());
|
||||
dbConfig.setBaseNameList(pushConfig.getBaseNameList());
|
||||
dbConfig.setMessageType(pushConfig.getMessageType());
|
||||
dbConfig.setCronExpression(pushConfig.getCronExpression());
|
||||
dbConfig.setTargetType(pushConfig.getTargetType());
|
||||
// dbConfig.setIsSms(pushConfig.getIsSms() == null ? 0 : pushConfig.getIsSms());
|
||||
// dbConfig.setStatus(pushConfig.getStatus() == null ? dbConfig.getStatus() : pushConfig.getStatus());
|
||||
dbConfig.setUpdatedAt(new Date());
|
||||
dbConfig.setModifyTime(new Date());
|
||||
dbConfig.setModifyUser(currentUserIdOrSystem());
|
||||
boolean updated = this.updateById(dbConfig);
|
||||
if (updated) {
|
||||
if (Objects.equals(dbConfig.getTargetType(), 1)) {
|
||||
softDeleteTargets(dbConfig.getId(), currentUserIdOrSystem(), new Date());
|
||||
}
|
||||
refreshQuartzJobIfExists(dbConfig);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean deletePushConfig(String ids) {
|
||||
if (StrUtil.isBlank(ids)) {
|
||||
throw new BizException("参数不能为空.");
|
||||
}
|
||||
Date now = new Date();
|
||||
String userId = currentUserIdOrSystem();
|
||||
for (String id : ids.split(",")) {
|
||||
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);
|
||||
softDeleteTargets(configId, userId, now);
|
||||
deleteQuartzJob(configId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean setPushConfigStatus(String id, Integer status) {
|
||||
if (StrUtil.isBlank(id) || status == null) {
|
||||
throw new BizException("参数不能为空.");
|
||||
}
|
||||
PushConfig config = getAvailableConfig(id);
|
||||
config.setStatus(status);
|
||||
if (Objects.equals(status, 0)) {
|
||||
config.setIsSms(0);
|
||||
}
|
||||
config.setUpdatedAt(new Date());
|
||||
config.setModifyTime(new Date());
|
||||
config.setModifyUser(currentUserIdOrSystem());
|
||||
boolean updated = this.updateById(config);
|
||||
// if (updated) {
|
||||
// syncQuartzJobBySwitch(config);
|
||||
// }
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean setPushConfigSmsSwitch(String id, Integer isSms) {
|
||||
if (StrUtil.isBlank(id) || isSms == null) {
|
||||
throw new BizException("参数不能为空.");
|
||||
}
|
||||
if (!Objects.equals(isSms, 0) && !Objects.equals(isSms, 1)) {
|
||||
throw new BizException("短信推送开关值不正确.");
|
||||
}
|
||||
PushConfig config = getAvailableConfig(id);
|
||||
config.setIsSms(isSms);
|
||||
config.setUpdatedAt(new Date());
|
||||
config.setModifyTime(new Date());
|
||||
config.setModifyUser(currentUserIdOrSystem());
|
||||
boolean updated = this.updateById(config);
|
||||
if (updated) {
|
||||
syncQuartzJobBySwitch(config);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean savePushTargets(PushConfigTargetRequest request) {
|
||||
validatePushTargetRequest(request);
|
||||
PushConfig config = getAvailableConfig(request.getConfigId());
|
||||
validateTargetTypeMatch(config.getTargetType(), request.getType());
|
||||
Date now = new Date();
|
||||
String userId = currentUserIdOrSystem();
|
||||
softDeleteTargets(config.getId(), userId, now);
|
||||
if (request.getUserRoleIds() == null || request.getUserRoleIds().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
List<PushConfigUser> list = new ArrayList<>();
|
||||
for (String userRoleId : request.getUserRoleIds()) {
|
||||
String targetId = StrUtil.trim(userRoleId);
|
||||
if (StrUtil.isBlank(targetId)) {
|
||||
continue;
|
||||
}
|
||||
PushConfigUser relation = new PushConfigUser();
|
||||
relation.setConfigId(config.getId());
|
||||
relation.setType(request.getType());
|
||||
relation.setUserRoleId(targetId);
|
||||
relation.setCreatedAt(now);
|
||||
relation.setRecordUser(userId);
|
||||
relation.setModifyUser(userId);
|
||||
relation.setModifyTime(now);
|
||||
relation.setIsDeleted(0);
|
||||
list.add(relation);
|
||||
}
|
||||
return list.isEmpty() || pushConfigUserService.saveBatch(list);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PushConfigTargetVo> getPushTargets(String configId) {
|
||||
if (StrUtil.isBlank(configId)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return pushConfigUserMapper.selectConfigTargets(configId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<PushHistory> getPushHistoryPage(Page<PushHistory> page,
|
||||
String configId,
|
||||
Integer status,
|
||||
String messageTypeCode,
|
||||
Date startTime,
|
||||
Date endTime) {
|
||||
LambdaQueryWrapper<PushHistory> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(PushHistory::getIsDeleted, 0)
|
||||
.eq(StrUtil.isNotBlank(configId), PushHistory::getConfigId, configId)
|
||||
.eq(status != null, PushHistory::getStatus, status)
|
||||
.eq(StrUtil.isNotBlank(messageTypeCode), PushHistory::getMessageTypeCode, messageTypeCode)
|
||||
.ge(startTime != null, PushHistory::getPlanTime, startTime)
|
||||
.le(endTime != null, PushHistory::getPlanTime, endTime)
|
||||
.orderByDesc(PushHistory::getPlanTime, PushHistory::getCreatedAt);
|
||||
return pushHistoryService.page(page, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<PushHistoryDetail> getPushHistoryDetailPage(Page<PushHistoryDetail> page,
|
||||
String historyId,
|
||||
Integer status) {
|
||||
LambdaQueryWrapper<PushHistoryDetail> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(PushHistoryDetail::getIsDeleted, 0)
|
||||
.eq(StrUtil.isNotBlank(historyId), PushHistoryDetail::getHistoryId, historyId)
|
||||
.eq(status != null, PushHistoryDetail::getStatus, status)
|
||||
.orderByDesc(PushHistoryDetail::getCreatedAt, PushHistoryDetail::getSendTime);
|
||||
return pushHistoryDetailService.page(page, wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean executeNow(String configId) {
|
||||
executePushConfig(configId);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void executePushConfig(String configId) {
|
||||
PushConfig config = getAvailableConfig(configId);
|
||||
List<PushTargetUserVo> targets = resolveTargets(config);
|
||||
Date now = new Date();
|
||||
String operator = currentUserIdOrSystem();
|
||||
|
||||
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.setPushedCount(0L);
|
||||
history.setSuccessCount(0L);
|
||||
history.setFailCount(0L);
|
||||
history.setPendingCount((long) targets.size());
|
||||
history.setSendChannel(DEFAULT_SEND_CHANNEL);
|
||||
history.setStatus(0);
|
||||
history.setSource(DEFAULT_SOURCE);
|
||||
history.setRelation(StrUtil.blankToDefault(config.getBaseNameList(), config.getCategoryName()));
|
||||
history.setCreatedAt(now);
|
||||
history.setUpdatedAt(now);
|
||||
history.setRecordUser(operator);
|
||||
history.setModifyUser(operator);
|
||||
history.setModifyTime(now);
|
||||
history.setIsDeleted(0);
|
||||
pushHistoryService.save(history);
|
||||
|
||||
if (!targets.isEmpty()) {
|
||||
List<PushHistoryDetail> 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(0);
|
||||
detail.setSendChannel(DEFAULT_SEND_CHANNEL);
|
||||
detail.setCreatedAt(now);
|
||||
detail.setRecordUser(operator);
|
||||
detail.setModifyUser(operator);
|
||||
detail.setModifyTime(now);
|
||||
detail.setIsDeleted(0);
|
||||
detailList.add(detail);
|
||||
}
|
||||
pushHistoryDetailService.saveBatch(detailList);
|
||||
}
|
||||
}
|
||||
|
||||
private void validatePushConfig(PushConfig pushConfig, boolean requireId) {
|
||||
if (pushConfig == null) {
|
||||
throw new BizException("参数不能为空.");
|
||||
}
|
||||
if (requireId && StrUtil.isBlank(pushConfig.getId())) {
|
||||
throw new BizException("配置ID不能为空.");
|
||||
}
|
||||
if (StrUtil.isBlank(pushConfig.getCategoryCode())) {
|
||||
throw new BizException("消息类别编码不能为空.");
|
||||
}
|
||||
if (StrUtil.isBlank(pushConfig.getCategoryName())) {
|
||||
throw new BizException("消息类别名称不能为空.");
|
||||
}
|
||||
if (StrUtil.isBlank(pushConfig.getMessageType())) {
|
||||
throw new BizException("消息类型不能为空.");
|
||||
}
|
||||
if (StrUtil.isBlank(pushConfig.getCronExpression()) || !CronExpression.isValidExpression(pushConfig.getCronExpression())) {
|
||||
throw new BizException("cron表达式格式错误.");
|
||||
}
|
||||
if (pushConfig.getTargetType() == null || (pushConfig.getTargetType() != 1 && pushConfig.getTargetType() != 2 && pushConfig.getTargetType() != 3)) {
|
||||
throw new BizException("推送目标类型不正确.");
|
||||
}
|
||||
}
|
||||
|
||||
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("绑定类型不正确.");
|
||||
}
|
||||
}
|
||||
|
||||
private void validateTargetTypeMatch(Integer targetType, Integer relationType) {
|
||||
if (targetType == null) {
|
||||
return;
|
||||
}
|
||||
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("按角色推送只能绑定角色.");
|
||||
}
|
||||
}
|
||||
|
||||
private PushConfig getAvailableConfig(String id) {
|
||||
List<PushConfig> list = this.list(new LambdaQueryWrapper<PushConfig>()
|
||||
.eq(PushConfig::getId, id)
|
||||
.eq(PushConfig::getIsDeleted, 0));
|
||||
PushConfig config = list.isEmpty() ? null : list.get(0);
|
||||
if (config == null) {
|
||||
throw new BizException("推送配置不存在.");
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
private void softDeleteTargets(String configId, String userId, Date now) {
|
||||
LambdaUpdateWrapper<PushConfigUser> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(PushConfigUser::getConfigId, configId)
|
||||
.eq(PushConfigUser::getIsDeleted, 0)
|
||||
.set(PushConfigUser::getIsDeleted, 1)
|
||||
.set(PushConfigUser::getDeleteUser, userId)
|
||||
.set(PushConfigUser::getDeleteTime, now)
|
||||
.set(PushConfigUser::getModifyUser, userId)
|
||||
.set(PushConfigUser::getModifyTime, now);
|
||||
pushConfigUserService.update(updateWrapper);
|
||||
}
|
||||
|
||||
private void syncQuartzJob(PushConfig config) {
|
||||
QuartzJob quartzJob = getPushQuartzJob(config.getId());
|
||||
Date now = new Date();
|
||||
if (quartzJob == null) {
|
||||
quartzJob = new QuartzJob();
|
||||
quartzJob.setBizModule(QUARTZ_BIZ_TYPE);
|
||||
quartzJob.setBizId(config.getId());
|
||||
}
|
||||
quartzJob.setJobName("推送配置-" + config.getCategoryName());
|
||||
quartzJob.setJobClass("pushConfigQuartzExecutor");
|
||||
quartzJob.setJobMethod("execute");
|
||||
quartzJob.setJobCron(config.getCronExpression());
|
||||
quartzJob.setJobParams(config.getId());
|
||||
quartzJob.setDescription("推送配置定时任务-" + config.getMessageType());
|
||||
quartzJob.setStatus(Objects.equals(config.getStatus(), 1) ? "1" : "0");
|
||||
quartzJob.setLastmodifier(currentUsernameOrSystem());
|
||||
quartzJob.setLastmodifydate(new Timestamp(now.getTime()));
|
||||
quartzJob.setOrderno(0);
|
||||
if (StrUtil.isBlank(quartzJob.getId())) {
|
||||
quartzJobService.save(quartzJob);
|
||||
quartzManage.addJob(quartzJob);
|
||||
} else {
|
||||
quartzJobService.updateById(quartzJob);
|
||||
quartzManage.updateJobCron(quartzJob);
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshQuartzJobIfExists(PushConfig config) {
|
||||
QuartzJob quartzJob = getPushQuartzJob(config.getId());
|
||||
if (quartzJob == null) {
|
||||
return;
|
||||
}
|
||||
if (canCreateQuartzJob(config)) {
|
||||
syncQuartzJob(config);
|
||||
} else {
|
||||
deleteQuartzJob(config.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void syncQuartzJobBySwitch(PushConfig config) {
|
||||
if (canCreateQuartzJob(config)) {
|
||||
syncQuartzJob(config);
|
||||
} else {
|
||||
deleteQuartzJob(config.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canCreateQuartzJob(PushConfig config) {
|
||||
return config != null
|
||||
&& Objects.equals(config.getStatus(), 1)
|
||||
&& Objects.equals(config.getIsSms(), 1);
|
||||
}
|
||||
|
||||
private void deleteQuartzJob(String configId) {
|
||||
QuartzJob quartzJob = getPushQuartzJob(configId);
|
||||
if (quartzJob != null) {
|
||||
quartzManage.deleteJob(quartzJob);
|
||||
quartzJobService.removeById(quartzJob.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private QuartzJob getPushQuartzJob(String configId) {
|
||||
List<QuartzJob> list = quartzJobService.list(new LambdaQueryWrapper<QuartzJob>()
|
||||
.eq(QuartzJob::getBizModule, QUARTZ_BIZ_TYPE)
|
||||
.eq(QuartzJob::getBizId, configId));
|
||||
return list.isEmpty() ? null : list.getFirst();
|
||||
}
|
||||
|
||||
private List<PushTargetUserVo> resolveTargets(PushConfig config) {
|
||||
List<PushTargetUserVo> rawTargets;
|
||||
if (Objects.equals(config.getTargetType(), 1)) {
|
||||
rawTargets = pushConfigUserMapper.selectAllActiveUsers();
|
||||
} else {
|
||||
rawTargets = pushConfigUserMapper.selectTargetUsersByConfigId(config.getId());
|
||||
}
|
||||
if (rawTargets == null || rawTargets.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<String, PushTargetUserVo> targetMap = new LinkedHashMap<>();
|
||||
for (PushTargetUserVo target : rawTargets) {
|
||||
if (target == null || StrUtil.isBlank(target.getUserId()) || StrUtil.isBlank(target.getTargetPhone())) {
|
||||
continue;
|
||||
}
|
||||
targetMap.putIfAbsent(target.getUserId(), target);
|
||||
}
|
||||
return new ArrayList<>(targetMap.values());
|
||||
}
|
||||
|
||||
private String buildDefaultTitle(PushConfig config) {
|
||||
return StrUtil.format("【{}】默认推送标题", StrUtil.blankToDefault(config.getCategoryName(), "消息通知"));
|
||||
}
|
||||
|
||||
private String buildDefaultContent(PushConfig config) {
|
||||
return StrUtil.format("【{}】默认推送内容,消息类型:{},执行时间:{}",
|
||||
StrUtil.blankToDefault(config.getCategoryName(), "消息通知"),
|
||||
StrUtil.blankToDefault(config.getMessageType(), "未配置"),
|
||||
DateUtil.formatDateTime(new Date()));
|
||||
}
|
||||
|
||||
private String currentUserIdOrSystem() {
|
||||
try {
|
||||
return SecurityUtils.getUserId();
|
||||
} catch (Exception ex) {
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
|
||||
private String currentUsernameOrSystem() {
|
||||
try {
|
||||
return SecurityUtils.getCurrentUsername();
|
||||
} catch (Exception ex) {
|
||||
return "system";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.yfd.platform.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.system.domain.PushConfigUser;
|
||||
import com.yfd.platform.system.mapper.PushConfigUserMapper;
|
||||
import com.yfd.platform.system.service.IPushConfigUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PushConfigUserServiceImpl extends ServiceImpl<PushConfigUserMapper, PushConfigUser> implements IPushConfigUserService {
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.yfd.platform.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.system.domain.PushHistoryDetail;
|
||||
import com.yfd.platform.system.mapper.PushHistoryDetailMapper;
|
||||
import com.yfd.platform.system.service.IPushHistoryDetailService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PushHistoryDetailServiceImpl extends ServiceImpl<PushHistoryDetailMapper, PushHistoryDetail> implements IPushHistoryDetailService {
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.yfd.platform.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.yfd.platform.system.domain.PushHistory;
|
||||
import com.yfd.platform.system.mapper.PushHistoryMapper;
|
||||
import com.yfd.platform.system.service.IPushHistoryService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class PushHistoryServiceImpl extends ServiceImpl<PushHistoryMapper, PushHistory> implements IPushHistoryService {
|
||||
}
|
||||
@ -42,13 +42,15 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String sendVerifyCode(String phone, Integer type) {
|
||||
public String sendVerifyCode(String phone, Integer type,String tenantId) {
|
||||
String code = generateCode();
|
||||
|
||||
LambdaQueryWrapper<SmsVerifyCode> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SmsVerifyCode::getPhone, phone)
|
||||
.eq(SmsVerifyCode::getType, type)
|
||||
.gt(SmsVerifyCode::getTenantId, tenantId)
|
||||
.eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED);
|
||||
|
||||
this.remove(queryWrapper);
|
||||
|
||||
SmsVerifyCode verifyCode = new SmsVerifyCode();
|
||||
@ -58,6 +60,7 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
|
||||
verifyCode.setType(type);
|
||||
verifyCode.setStatus(SmsVerifyCode.STATUS_UNUSED);
|
||||
verifyCode.setCreateTime(new Date());
|
||||
verifyCode.setTenantId(tenantId);
|
||||
|
||||
Date expireTime = new Date(System.currentTimeMillis() + CODE_VALID_MINUTES * 60 * 1000L);
|
||||
verifyCode.setExpireTime(expireTime);
|
||||
@ -75,11 +78,12 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifyCode(String phone, String code, Integer type) {
|
||||
public boolean verifyCode(String phone, String code, Integer type,String tenantId) {
|
||||
LambdaQueryWrapper<SmsVerifyCode> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SmsVerifyCode::getPhone, phone)
|
||||
.eq(SmsVerifyCode::getCode, code)
|
||||
.eq(SmsVerifyCode::getType, type)
|
||||
.eq(SmsVerifyCode::getTenantId, tenantId)
|
||||
.eq(SmsVerifyCode::getStatus, SmsVerifyCode.STATUS_UNUSED)
|
||||
.gt(SmsVerifyCode::getExpireTime, new Date());
|
||||
|
||||
@ -150,14 +154,14 @@ public class SmsVerifyCodeServiceImpl extends ServiceImpl<SmsVerifyCodeMapper, S
|
||||
|
||||
|
||||
@Override
|
||||
public int urgeByUserIds(List<String> userIds, String content) {
|
||||
public int urgeByUserIds(String tenantId,List<String> userIds, String content) {
|
||||
if (userIds == null || userIds.isEmpty()) {
|
||||
log.warn("催促短信发送失败:用户ID列表为空");
|
||||
return 0;
|
||||
}
|
||||
List<String> ids = userIds.stream().distinct().toList();
|
||||
List<SysUser> sysUsers = sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, ids)
|
||||
.eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getStatus,1).select(SysUser::getPhone));
|
||||
.eq(SysUser::getRegStatus, "APPROVED").eq(SysUser::getTenantId, tenantId).eq(SysUser::getStatus,1).select(SysUser::getPhone));
|
||||
|
||||
if (sysUsers.isEmpty()) {
|
||||
log.warn("催促短信发送失败:未找到有效的手机号,userIds: {}", ids);
|
||||
|
||||
@ -648,9 +648,10 @@ public class UserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public SysUser getUserByPhone(String phone) {
|
||||
public SysUser getUserByPhone(String phone,String tenantId) {
|
||||
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(SysUser::getPhone, phone);
|
||||
queryWrapper.eq(SysUser::getTenantId, tenantId);
|
||||
return this.getOne(queryWrapper);
|
||||
}
|
||||
|
||||
|
||||
@ -19,12 +19,12 @@ import com.yfd.platform.config.MessageConfig;
|
||||
import com.yfd.platform.config.thread.ThreadPoolExecutorUtil;
|
||||
import com.yfd.platform.system.domain.Message;
|
||||
import com.yfd.platform.system.domain.QuartzJob;
|
||||
import com.yfd.platform.system.service.IMessageService;
|
||||
import com.yfd.platform.system.service.IQuartzJobService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.DisallowConcurrentExecution;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.quartz.PersistJobDataAfterExecution;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.sql.Timestamp;
|
||||
@ -32,48 +32,72 @@ import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* 参考人人开源,https://gitee.com/renrenio/renren-security
|
||||
* 定时任务执行器(禁止同一Job并发执行)
|
||||
*
|
||||
* @author /
|
||||
* @date 2019-01-07
|
||||
*/
|
||||
@Async
|
||||
@DisallowConcurrentExecution
|
||||
@PersistJobDataAfterExecution
|
||||
@SuppressWarnings({"unchecked", "all"})
|
||||
@Slf4j
|
||||
public class ExecutionJob extends QuartzJobBean {
|
||||
|
||||
/**
|
||||
* 该处仅供参考
|
||||
*/
|
||||
private final static ThreadPoolExecutor EXECUTOR =
|
||||
ThreadPoolExecutorUtil.getPoll();
|
||||
private static final ThreadPoolExecutor EXECUTOR = ThreadPoolExecutorUtil.getPoll();
|
||||
|
||||
@Resource
|
||||
private IMessageService messageService;
|
||||
|
||||
@Resource
|
||||
private MessageConfig messageConfig;
|
||||
|
||||
@Override
|
||||
public void executeInternal(JobExecutionContext context) {
|
||||
protected void executeInternal(JobExecutionContext context) {
|
||||
QuartzJob quartzJob =
|
||||
(QuartzJob) context.getMergedJobDataMap().get(QuartzJob.JOB_KEY);
|
||||
// 获取spring bean
|
||||
|
||||
IQuartzJobService quartzJobService =
|
||||
SpringContextHolder.getBean(IQuartzJobService.class);
|
||||
String uuid = quartzJob.getId();
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
String jobName = quartzJob.getJobName();
|
||||
String bizModule = quartzJob.getBizModule();
|
||||
String bizId = quartzJob.getBizId();
|
||||
|
||||
try {
|
||||
// 执行任务
|
||||
System.out.println(
|
||||
"--------------------------------------------------------------");
|
||||
System.out.println("任务开始执行,任务名称:" + jobName);
|
||||
QuartzRunnable task = new QuartzRunnable(quartzJob.getJobClass(),
|
||||
logExecutionStart(jobName, bizModule, bizId);
|
||||
|
||||
QuartzRunnable task = new QuartzRunnable(
|
||||
quartzJob.getJobClass(),
|
||||
quartzJob.getJobMethod(),
|
||||
quartzJob.getJobParams());
|
||||
Future<?> future = EXECUTOR.submit(task);
|
||||
future.get();
|
||||
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
logExecutionEnd(jobName, bizModule, bizId, times);
|
||||
|
||||
// sendCompletionMessage(quartzJob);
|
||||
} catch (Exception e) {
|
||||
log.error("任务执行失败: jobName={}, module={}, bizId={}", jobName, bizModule, bizId, e);
|
||||
quartzJob.setStatus("0");
|
||||
quartzJobService.updateById(quartzJob);
|
||||
}
|
||||
}
|
||||
|
||||
private void logExecutionStart(String jobName, String bizModule, String bizId) {
|
||||
log.info("--------------------------------------------------------------");
|
||||
log.info("任务开始执行,任务名称:" + jobName +
|
||||
(bizModule != null ? ",模块:" + bizModule : "") +
|
||||
(bizId != null ? ",业务ID:" + bizId : ""));
|
||||
}
|
||||
|
||||
private void logExecutionEnd(String jobName, String bizModule, String bizId, long times) {
|
||||
log.info("任务执行完毕,任务名称:" + jobName +
|
||||
(bizModule != null ? ",模块:" + bizModule : "") +
|
||||
",执行时间:" + times + "毫秒");
|
||||
log.info("--------------------------------------------------------------");
|
||||
}
|
||||
|
||||
private void sendCompletionMessage(QuartzJob quartzJob) {
|
||||
Message message = new Message();
|
||||
message.setCreatetime(new Timestamp(System.currentTimeMillis()));
|
||||
message.setType("1");
|
||||
@ -85,19 +109,5 @@ public class ExecutionJob extends QuartzJobBean {
|
||||
message.setStatus("1");
|
||||
message.setValidperiod(24);
|
||||
messageConfig.addMessage(message);
|
||||
// 任务状态
|
||||
System.out.println("任务执行完毕,任务名称:" + jobName + ", " +
|
||||
"执行时间:" + times + "毫秒");
|
||||
System.out.println(
|
||||
"--------------------------------------------------------------");
|
||||
} catch (Exception e) {
|
||||
System.out.println("任务执行失败,任务名称:" + jobName);
|
||||
System.out.println(
|
||||
"--------------------------------------------------------------");
|
||||
quartzJob.setStatus("0");
|
||||
//更新状态
|
||||
quartzJobService.updateById(quartzJob);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -18,15 +18,21 @@ package com.yfd.platform.utils;
|
||||
import com.yfd.platform.system.domain.QuartzJob;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.*;
|
||||
import org.quartz.impl.matchers.GroupMatcher;
|
||||
import org.quartz.impl.triggers.CronTriggerImpl;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static org.quartz.TriggerBuilder.newTrigger;
|
||||
|
||||
/**
|
||||
* 定时任务管理器(线程安全,支持多模块)
|
||||
*
|
||||
* @author
|
||||
* @date 2019-01-07
|
||||
*/
|
||||
@ -34,154 +40,267 @@ import static org.quartz.TriggerBuilder.newTrigger;
|
||||
@Component
|
||||
public class QuartzManage {
|
||||
|
||||
private static final String JOB_NAME = "TASK_";
|
||||
private static final String JOB_NAME_PREFIX = "TASK_";
|
||||
private static final String GROUP_SEPARATOR = "_";
|
||||
|
||||
@Resource(name = "scheduler")
|
||||
private Scheduler scheduler;
|
||||
|
||||
public void addJob(QuartzJob quartzJob) {
|
||||
try {
|
||||
// 构建job信息
|
||||
JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class).
|
||||
withIdentity(JOB_NAME + quartzJob.getId()).build();
|
||||
/** 按任务ID粒度的锁,避免全局锁竞争 */
|
||||
private static final ReentrantLock GLOBAL_LOCK = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* 构建 JobKey(包含 bizModule 用于分组隔离)
|
||||
*/
|
||||
private JobKey buildJobKey(QuartzJob quartzJob) {
|
||||
String group = resolveGroup(quartzJob);
|
||||
return JobKey.jobKey(JOB_NAME_PREFIX + quartzJob.getId(), group);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 TriggerKey
|
||||
*/
|
||||
private TriggerKey buildTriggerKey(QuartzJob quartzJob) {
|
||||
String group = resolveGroup(quartzJob);
|
||||
return TriggerKey.triggerKey(JOB_NAME_PREFIX + quartzJob.getId(), group);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 Quartz 分组名:有 bizModule 则按模块分组,否则默认分组
|
||||
*/
|
||||
private String resolveGroup(QuartzJob quartzJob) {
|
||||
if (quartzJob.getBizModule() != null && !quartzJob.getBizModule().isBlank()) {
|
||||
return quartzJob.getBizModule();
|
||||
}
|
||||
return "DEFAULT";
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加定时任务(线程安全)
|
||||
*/
|
||||
public void addJob(QuartzJob quartzJob) {
|
||||
GLOBAL_LOCK.lock();
|
||||
try {
|
||||
JobDetail jobDetail = JobBuilder.newJob(ExecutionJob.class)
|
||||
.withIdentity(buildJobKey(quartzJob))
|
||||
.storeDurably()
|
||||
.build();
|
||||
|
||||
//通过触发器名和cron 表达式创建 Trigger
|
||||
Trigger cronTrigger = newTrigger()
|
||||
.withIdentity(JOB_NAME + quartzJob.getId())
|
||||
.withIdentity(buildTriggerKey(quartzJob))
|
||||
.startNow()
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getJobCron()))
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(quartzJob.getJobCron())
|
||||
.withMisfireHandlingInstructionDoNothing())
|
||||
.build();
|
||||
|
||||
cronTrigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob);
|
||||
|
||||
//重置启动时间
|
||||
((CronTriggerImpl) cronTrigger).setStartTime(new Date());
|
||||
|
||||
//执行定时任务
|
||||
scheduler.scheduleJob(jobDetail, cronTrigger);
|
||||
|
||||
// 暂停任务
|
||||
if ("0".equals(quartzJob.getStatus())) {
|
||||
pauseJob(quartzJob);
|
||||
scheduler.pauseJob(buildJobKey(quartzJob));
|
||||
}
|
||||
log.info("创建定时任务成功: module={}, bizId={}, jobName={}",
|
||||
quartzJob.getBizModule(), quartzJob.getBizId(), quartzJob.getJobName());
|
||||
} catch (Exception e) {
|
||||
log.error("创建定时任务失败", e);
|
||||
throw new RuntimeException("创建定时任务失败");
|
||||
log.error("创建定时任务失败: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId(), e);
|
||||
throw new RuntimeException("创建定时任务失败", e);
|
||||
} finally {
|
||||
GLOBAL_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新job cron表达式
|
||||
*
|
||||
* @param quartzJob /
|
||||
* 更新任务 Cron 表达式(线程安全,check-then-act 原子化)
|
||||
*/
|
||||
public void updateJobCron(QuartzJob quartzJob) {
|
||||
GLOBAL_LOCK.lock();
|
||||
try {
|
||||
TriggerKey triggerKey =
|
||||
TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger =
|
||||
(CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
TriggerKey triggerKey = buildTriggerKey(quartzJob);
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
return;
|
||||
}
|
||||
|
||||
CronScheduleBuilder scheduleBuilder =
|
||||
CronScheduleBuilder.cronSchedule(quartzJob.getJobCron());
|
||||
trigger =
|
||||
trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
|
||||
//重置启动时间
|
||||
CronScheduleBuilder.cronSchedule(quartzJob.getJobCron())
|
||||
.withMisfireHandlingInstructionDoNothing();
|
||||
trigger = trigger.getTriggerBuilder()
|
||||
.withIdentity(triggerKey)
|
||||
.withSchedule(scheduleBuilder)
|
||||
.build();
|
||||
((CronTriggerImpl) trigger).setStartTime(new Date());
|
||||
trigger.getJobDataMap().put(QuartzJob.JOB_KEY, quartzJob);
|
||||
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
// 暂停任务
|
||||
if ("0".equals(quartzJob.getStatus())) {
|
||||
pauseJob(quartzJob);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("更新定时任务失败", e);
|
||||
throw new RuntimeException("更新定时任务失败");
|
||||
}
|
||||
|
||||
if ("0".equals(quartzJob.getStatus())) {
|
||||
scheduler.pauseJob(buildJobKey(quartzJob));
|
||||
} else {
|
||||
scheduler.resumeJob(buildJobKey(quartzJob));
|
||||
}
|
||||
log.info("更新定时任务成功: module={}, bizId={}, jobName={}",
|
||||
quartzJob.getBizModule(), quartzJob.getBizId(), quartzJob.getJobName());
|
||||
} catch (Exception e) {
|
||||
log.error("更新定时任务失败: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId(), e);
|
||||
throw new RuntimeException("更新定时任务失败", e);
|
||||
} finally {
|
||||
GLOBAL_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
* 删除任务
|
||||
*/
|
||||
public void deleteJob(QuartzJob quartzJob) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
JobKey jobKey = buildJobKey(quartzJob);
|
||||
scheduler.pauseJob(jobKey);
|
||||
scheduler.deleteJob(jobKey);
|
||||
log.info("删除定时任务成功: module={}, bizId={}, jobName={}",
|
||||
quartzJob.getBizModule(), quartzJob.getBizId(), quartzJob.getJobName());
|
||||
} catch (Exception e) {
|
||||
log.error("删除定时任务失败", e);
|
||||
throw new RuntimeException("删除定时任务失败");
|
||||
log.error("删除定时任务失败: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId(), e);
|
||||
throw new RuntimeException("删除定时任务失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
* 恢复任务
|
||||
*/
|
||||
public void resumeJob(QuartzJob quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey =
|
||||
TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger =
|
||||
(CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
TriggerKey triggerKey = buildTriggerKey(quartzJob);
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
if (trigger == null) {
|
||||
addJob(quartzJob);
|
||||
return;
|
||||
}
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.resumeJob(jobKey);
|
||||
scheduler.resumeJob(buildJobKey(quartzJob));
|
||||
log.info("恢复定时任务成功: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId());
|
||||
} catch (Exception e) {
|
||||
log.error("恢复定时任务失败", e);
|
||||
throw new RuntimeException("恢复定时任务失败");
|
||||
log.error("恢复定时任务失败: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId(), e);
|
||||
throw new RuntimeException("恢复定时任务失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行job
|
||||
*
|
||||
* @param quartzJob /
|
||||
* 立即执行任务(保留已有 JobDataMap,追加最新 quartzJob 数据)
|
||||
*/
|
||||
public void runJobNow(QuartzJob quartzJob) {
|
||||
try {
|
||||
TriggerKey triggerKey =
|
||||
TriggerKey.triggerKey(JOB_NAME + quartzJob.getId());
|
||||
CronTrigger trigger =
|
||||
(CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
// 如果不存在则创建一个定时任务
|
||||
TriggerKey triggerKey = buildTriggerKey(quartzJob);
|
||||
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
|
||||
if (trigger == null) {
|
||||
log.warn("任务不存在,先创建再执行: jobName={}", quartzJob.getJobName());
|
||||
addJob(quartzJob);
|
||||
trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
}
|
||||
JobDataMap dataMap = new JobDataMap();
|
||||
|
||||
JobDataMap dataMap = trigger.getJobDataMap();
|
||||
dataMap.put(QuartzJob.JOB_KEY, quartzJob);
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
|
||||
JobKey jobKey = buildJobKey(quartzJob);
|
||||
scheduler.triggerJob(jobKey, dataMap);
|
||||
log.info("手动触发任务执行: module={}, bizId={}, jobName={}",
|
||||
quartzJob.getBizModule(), quartzJob.getBizId(), quartzJob.getJobName());
|
||||
} catch (Exception e) {
|
||||
log.error("定时任务执行失败", e);
|
||||
throw new RuntimeException("定时任务执行失败");
|
||||
log.error("手动触发任务失败: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId(), e);
|
||||
throw new RuntimeException("定时任务执行失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停一个job
|
||||
*
|
||||
* @param quartzJob /
|
||||
* 暂停任务
|
||||
*/
|
||||
public void pauseJob(QuartzJob quartzJob) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(JOB_NAME + quartzJob.getId());
|
||||
scheduler.pauseJob(jobKey);
|
||||
scheduler.pauseJob(buildJobKey(quartzJob));
|
||||
log.info("暂停定时任务成功: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId());
|
||||
} catch (Exception e) {
|
||||
log.error("定时任务暂停失败", e);
|
||||
throw new RuntimeException("定时任务暂停失败");
|
||||
log.error("定时任务暂停失败: module={}, bizId={}", quartzJob.getBizModule(), quartzJob.getBizId(), e);
|
||||
throw new RuntimeException("定时任务暂停失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 多模块支持方法 ====================
|
||||
|
||||
/**
|
||||
* 根据业务模块和业务ID查找已存在的任务
|
||||
*
|
||||
* @param bizModule 业务模块编码
|
||||
* @param bizId 业务主键ID
|
||||
* @return 是否存在
|
||||
*/
|
||||
public boolean existsByBiz(String bizModule, String bizId) {
|
||||
if (bizModule == null || bizModule.isBlank() || bizId == null || bizId.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.groupEquals(bizModule));
|
||||
for (JobKey jobKey : jobKeys) {
|
||||
JobDetail detail = scheduler.getJobDetail(jobKey);
|
||||
if (detail != null) {
|
||||
QuartzJob job = (QuartzJob) detail.getJobDataMap().get(QuartzJob.JOB_KEY);
|
||||
if (job != null && bizId.equals(job.getBizId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SchedulerException e) {
|
||||
log.error("查询任务失败: module={}, bizId={}", bizModule, bizId, e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按模块暂停该模块下所有任务
|
||||
*/
|
||||
public void pauseAllByModule(String bizModule) {
|
||||
if (bizModule == null || bizModule.isBlank()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.groupEquals(bizModule));
|
||||
scheduler.pauseJobs(org.quartz.impl.matchers.GroupMatcher.groupEquals(bizModule));
|
||||
log.info("暂停模块[{}]下所有任务,共{}个", bizModule, jobKeys.size());
|
||||
} catch (SchedulerException e) {
|
||||
log.error("暂停模块任务失败: module={}", bizModule, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按模块恢复该模块下所有任务
|
||||
*/
|
||||
public void resumeAllByModule(String bizModule) {
|
||||
if (bizModule == null || bizModule.isBlank()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
scheduler.resumeJobs(org.quartz.impl.matchers.GroupMatcher.groupEquals(bizModule));
|
||||
log.info("恢复模块[{}]下所有任务", bizModule);
|
||||
} catch (SchedulerException e) {
|
||||
log.error("恢复模块任务失败: module={}", bizModule, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按模块删除该模块下所有任务
|
||||
*/
|
||||
public void deleteAllByModule(String bizModule) {
|
||||
if (bizModule == null || bizModule.isBlank()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
Set<JobKey> jobKeys = scheduler.getJobKeys(GroupMatcher.groupEquals(bizModule));
|
||||
scheduler.deleteJobs(new java.util.ArrayList<>(jobKeys));
|
||||
log.info("删除模块[{}]下所有任务,共{}个", bizModule, jobKeys.size());
|
||||
} catch (SchedulerException e) {
|
||||
log.error("删除模块任务失败: module={}", bizModule, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,9 +111,11 @@ spring:
|
||||
matching-strategy: ant_path_matcher
|
||||
data:
|
||||
redis:
|
||||
host: "${REDIS_HOST:172.16.21.142}"
|
||||
# host: "${REDIS_HOST:172.16.21.142}"
|
||||
host: "${REDIS_HOST:localhost}"
|
||||
port: "${REDIS_PORT:6379}"
|
||||
password: "${REDIS_PASSWORD:zny5678}"
|
||||
password: "${REDIS_PASSWORD:}"
|
||||
# password: "${REDIS_PASSWORD:zny5678}"
|
||||
database: "${REDIS_DATABASE:15}"
|
||||
timeout: 10000ms
|
||||
lettuce:
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.yfd.platform.system.mapper.PushConfigUserMapper">
|
||||
|
||||
<select id="selectAllActiveUsers" resultType="com.yfd.platform.system.domain.PushTargetUserVo">
|
||||
SELECT
|
||||
u.ID AS userId,
|
||||
NVL(u.REAL_NAME, NVL(u.NICKNAME, u.USERNAME)) AS targetName,
|
||||
u.PHONE AS targetPhone
|
||||
FROM SYS_USER u
|
||||
WHERE u.STATUS = 1
|
||||
AND u.PHONE IS NOT NULL
|
||||
AND TRIM(u.PHONE) IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="selectTargetUsersByConfigId" resultType="com.yfd.platform.system.domain.PushTargetUserVo">
|
||||
SELECT DISTINCT
|
||||
t.userId,
|
||||
t.targetName,
|
||||
t.targetPhone
|
||||
FROM (
|
||||
SELECT
|
||||
u.ID AS userId,
|
||||
NVL(u.REAL_NAME, NVL(u.NICKNAME, u.USERNAME)) AS targetName,
|
||||
u.PHONE AS targetPhone
|
||||
FROM PUSH_CONFIG_USER pcu
|
||||
INNER JOIN SYS_USER u ON u.ID = pcu.USER_ROLE_ID
|
||||
WHERE pcu.CONFIG_ID = #{configId}
|
||||
AND pcu.TYPE = 0
|
||||
AND NVL(pcu.IS_DELETED, 0) = 0
|
||||
AND u.STATUS = 1
|
||||
AND u.PHONE IS NOT NULL
|
||||
AND TRIM(u.PHONE) IS NOT NULL
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
u.ID AS userId,
|
||||
NVL(u.REAL_NAME, NVL(u.NICKNAME, u.USERNAME)) AS targetName,
|
||||
u.PHONE AS targetPhone
|
||||
FROM PUSH_CONFIG_USER pcu
|
||||
INNER JOIN SYS_ROLE_USERS sru ON sru.ROLEID = pcu.USER_ROLE_ID
|
||||
INNER JOIN SYS_USER u ON u.ID = sru.USERID
|
||||
WHERE pcu.CONFIG_ID = #{configId}
|
||||
AND pcu.TYPE = 1
|
||||
AND NVL(pcu.IS_DELETED, 0) = 0
|
||||
AND u.STATUS = 1
|
||||
AND u.PHONE IS NOT NULL
|
||||
AND TRIM(u.PHONE) IS NOT NULL
|
||||
) t
|
||||
</select>
|
||||
|
||||
<select id="selectConfigTargets" resultType="com.yfd.platform.system.domain.PushConfigTargetVo">
|
||||
SELECT
|
||||
pcu.ID AS id,
|
||||
pcu.CONFIG_ID AS configId,
|
||||
pcu.TYPE AS type,
|
||||
pcu.USER_ROLE_ID AS userRoleId,
|
||||
CASE
|
||||
WHEN pcu.TYPE = 0 THEN NVL(u.REAL_NAME, NVL(u.NICKNAME, u.USERNAME))
|
||||
ELSE r.ROLENAME
|
||||
END AS targetName,
|
||||
CASE
|
||||
WHEN pcu.TYPE = 0 THEN u.PHONE
|
||||
ELSE NULL
|
||||
END AS targetPhone
|
||||
FROM PUSH_CONFIG_USER pcu
|
||||
LEFT JOIN SYS_USER u ON pcu.TYPE = 0 AND u.ID = pcu.USER_ROLE_ID
|
||||
LEFT JOIN SYS_ROLE r ON pcu.TYPE = 1 AND r.ID = pcu.USER_ROLE_ID
|
||||
WHERE pcu.CONFIG_ID = #{configId}
|
||||
AND NVL(pcu.IS_DELETED, 0) = 0
|
||||
ORDER BY pcu.CREATED_AT DESC, pcu.ID DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue
Block a user