diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java index c6feb57b86..7c407e1b6b 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java @@ -544,4 +544,17 @@ public class RedisKeys { public static String getGridInfoKey(String gridId) { return rootPrefix.concat("gov:grid:").concat(gridId); } + + /** + * @description 调查问卷accessKey + * + * @param userId + * @param qKey + * @return + * @author wxz + * @date 2021.09.23 17:38:37 + */ + public static String getQuestionnaireAccessKey(String userId, String qKey) { + return rootPrefix.concat("questionnaire:accesskey:").concat(userId).concat(":").concat(qKey); + } } diff --git a/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/form/TDuckDetailFormDTO.java b/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/form/TDuckDetailFormDTO.java index 8796d3291b..3a9b934b69 100644 --- a/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/form/TDuckDetailFormDTO.java +++ b/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/form/TDuckDetailFormDTO.java @@ -17,15 +17,22 @@ public class TDuckDetailFormDTO implements Serializable { private static final long serialVersionUID = 3793280475377993346L; public interface TDuckDetailForm{} + public interface PermissionValidate{} /** * 项目key */ - @NotBlank(message = "项目key不能为空",groups = TDuckDetailForm.class) + @NotBlank(message = "项目key不能为空",groups = { TDuckDetailForm.class, PermissionValidate.class }) private String key; /** * 是否显示类型 */ @NotNull(message = "是否显示类型不能为空",groups = TDuckDetailForm.class) private Boolean displayType; + + /** 当前操作人所在的组织的类型(grid:网格,agency:单位) */ + private String orgType; + + /** 当前操作人所在的组织的ID(当orgType为grid的时候必填,为agency的时候留空) */ + private String orgId; } diff --git a/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/result/PermissionValidateResultDTO.java b/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/result/PermissionValidateResultDTO.java new file mode 100644 index 0000000000..45897428d9 --- /dev/null +++ b/epmet-module/data-aggregator/data-aggregator-client/src/main/java/com/epmet/dataaggre/dto/epmettduck/result/PermissionValidateResultDTO.java @@ -0,0 +1,9 @@ +package com.epmet.dataaggre.dto.epmettduck.result; + +import lombok.Data; + +@Data +public class PermissionValidateResultDTO { + private Boolean permitted; + private String accessKey; +} diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/controller/EpmetTDuckController.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/controller/EpmetTDuckController.java index 5a34f9d7a8..bcffe238d4 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/controller/EpmetTDuckController.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/controller/EpmetTDuckController.java @@ -1,6 +1,10 @@ package com.epmet.dataaggre.controller; import com.epmet.commons.tools.annotation.LoginUser; +import com.epmet.commons.tools.constant.AppClientConstant; +import com.epmet.commons.tools.exception.EpmetErrorCode; +import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.exception.ValidateException; import com.epmet.commons.tools.security.dto.TokenDto; import com.epmet.commons.tools.utils.Result; import com.epmet.commons.tools.validator.ValidatorUtils; @@ -9,14 +13,15 @@ import com.epmet.dataaggre.dto.epmettduck.form.*; import com.epmet.dataaggre.dto.epmettduck.result.*; import com.epmet.dataaggre.entity.epmettduck.PrUserProjectEntity; import com.epmet.dataaggre.entity.epmettduck.PrUserProjectItemEntity; +import com.epmet.dataaggre.service.QuestionnaireService; import com.epmet.dataaggre.service.epmettduck.PrUserProjectItemService; import com.epmet.dataaggre.service.epmettduck.PrUserProjectService; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; -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.RestController; +import org.springframework.web.bind.annotation.*; +import sun.tools.jstat.Token; +import javax.validation.constraints.NotBlank; import java.util.List; /** @@ -31,6 +36,8 @@ public class EpmetTDuckController { private PrUserProjectService prUserProjectService; @Autowired private PrUserProjectItemService projectItemService; + @Autowired + private QuestionnaireService questionnaireService; /** @@ -143,4 +150,36 @@ public class EpmetTDuckController { public Result redPoint(@LoginUser TokenDto tokenDto) { return new Result().ok(prUserProjectService.redPoint(tokenDto)); } + + /** + * @description 校验权限,并且获取accesskey + * + * @param input + * @return + * @author wxz + * @date 2021.09.23 15:13:53 + */ + @PostMapping("/permission-validate") + public Result permissionValidate(@RequestBody TDuckDetailFormDTO input, @LoginUser TokenDto loginUserInfo, @RequestHeader("customerId") String customerId) { + ValidatorUtils.validateEntity(input, TDuckDetailFormDTO.PermissionValidate.class); + // 所用端的类型:gov:工作端,resi居民端 + String app = loginUserInfo.getApp(); + String orgId = input.getOrgId(); + String projectKey = input.getKey(); + String userId = loginUserInfo.getUserId(); + + PermissionValidateResultDTO r = null; + if (AppClientConstant.APP_RESI.equals(app)) { + if (StringUtils.isBlank(orgId) || !"grid".equals(input.getOrgType())) { + // 居民端,orgId是网格id,必填 + throw new ValidateException(EpmetErrorCode.INTERNAL_VALIDATE_ERROR.getCode(), "【调查问卷】校验访问权限-居民端 orgId不能为空,且orgType需要为[grid]"); + } + r = questionnaireService.resiPermissionValidate(projectKey, userId, orgId); + } else if (AppClientConstant.APP_GOV.equals(app)) { + // 工作端 + r = questionnaireService.govPermissionValidate(projectKey, userId, customerId); + } + + return new Result().ok(r); + } } diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/QuestionnaireService.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/QuestionnaireService.java new file mode 100644 index 0000000000..c23f7f1245 --- /dev/null +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/QuestionnaireService.java @@ -0,0 +1,9 @@ +package com.epmet.dataaggre.service; + +import com.epmet.dataaggre.dto.epmettduck.result.PermissionValidateResultDTO; + +public interface QuestionnaireService { + PermissionValidateResultDTO resiPermissionValidate(String projectKey, String userId, String gridId); + + PermissionValidateResultDTO govPermissionValidate(String projectKey, String staffId, String customerId); +} diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrPublishRangeService.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrPublishRangeService.java index d238150f46..66a2dbb79e 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrPublishRangeService.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrPublishRangeService.java @@ -102,6 +102,16 @@ public interface PrPublishRangeService extends BaseService */ List getRangeOrgList(String projectKey); + /** + * @description 使用projectKey查询发布范围entity + * + * @param projectKey + * @return + * @author wxz + * @date 2021.09.23 23:04:23 + */ + List getPublishRangeEntity(String projectKey); + /** * @Description 获取组织范围内的问卷 * @Param orgList diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrUserProjectService.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrUserProjectService.java index 2a35aa5ac1..93e437a043 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrUserProjectService.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/PrUserProjectService.java @@ -174,4 +174,14 @@ public interface PrUserProjectService extends BaseService { * @Date 2021/9/23 10:05 */ RedPointResultDTO redPoint(TokenDto tokenDto); + + /** + * @description 根据key查询问卷 + * + * @param key + * @return + * @author wxz + * @date 2021.09.23 22:25:57 + */ + PrUserProjectEntity getProjectEntityBykey(String key); } \ No newline at end of file diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrPublishRangeServiceImpl.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrPublishRangeServiceImpl.java index d669cc59c8..6865f8764e 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrPublishRangeServiceImpl.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrPublishRangeServiceImpl.java @@ -125,6 +125,13 @@ public class PrPublishRangeServiceImpl extends BaseServiceImpl getPublishRangeEntity(String projectKey) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(PrPublishRangeEntity::getProjectKey, projectKey); + return baseDao.selectList(wrapper); + } + /** * @param orgList * @Description 获取组织范围内的问卷 diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrUserProjectServiceImpl.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrUserProjectServiceImpl.java index 19815e12b1..89f03e8545 100644 --- a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrUserProjectServiceImpl.java +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/epmettduck/impl/PrUserProjectServiceImpl.java @@ -791,4 +791,11 @@ public class PrUserProjectServiceImpl extends BaseServiceImpl query = new LambdaQueryWrapper<>(); + query.eq(PrUserProjectEntity::getKey, key); + return baseDao.selectOne(query); + } } \ No newline at end of file diff --git a/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/impl/QuestionnaireServiceImpl.java b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/impl/QuestionnaireServiceImpl.java new file mode 100644 index 0000000000..1c6aab452d --- /dev/null +++ b/epmet-module/data-aggregator/data-aggregator-server/src/main/java/com/epmet/dataaggre/service/impl/QuestionnaireServiceImpl.java @@ -0,0 +1,193 @@ +package com.epmet.dataaggre.service.impl; + +import com.epmet.commons.tools.constant.AppClientConstant; +import com.epmet.commons.tools.constant.ServiceConstant; +import com.epmet.commons.tools.dto.form.IdAndNameDTO; +import com.epmet.commons.tools.dto.result.CustomerStaffInfoCacheResult; +import com.epmet.commons.tools.exception.EpmetErrorCode; +import com.epmet.commons.tools.exception.RenException; +import com.epmet.commons.tools.feign.ResultDataResolver; +import com.epmet.commons.tools.redis.RedisKeys; +import com.epmet.commons.tools.redis.RedisUtils; +import com.epmet.commons.tools.redis.common.CustomerStaffRedis; +import com.epmet.commons.tools.utils.Result; +import com.epmet.dataaggre.dto.epmettduck.result.PermissionValidateResultDTO; +import com.epmet.dataaggre.entity.epmettduck.PrPublishRangeEntity; +import com.epmet.dataaggre.entity.epmettduck.PrUserProjectEntity; +import com.epmet.dataaggre.service.QuestionnaireService; +import com.epmet.dataaggre.service.epmettduck.PrPublishRangeService; +import com.epmet.dataaggre.service.epmettduck.PrUserProjectService; +import com.epmet.dto.CustomerGridDTO; +import com.epmet.dto.form.CustomerGridFormDTO; +import com.epmet.feign.GovOrgOpenFeignClient; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Service +@Slf4j +public class QuestionnaireServiceImpl implements QuestionnaireService, ResultDataResolver { + + /** 调查问卷有效期 15min */ + public static final long QUESTIONNAIRE_EXPIRE_SECONDS = 15 * 60; + + @Autowired + private PrUserProjectService prUserProjectService; + + @Autowired + private PrPublishRangeService prPublishRangeService; + + @Autowired + private GovOrgOpenFeignClient govOrgOpenFeignClient; + + @Autowired + private RedisUtils redisUtils; + + @Autowired + private CustomerStaffRedis customerStaffRedis; + + /** + * @description 居民端调查问卷权限校验 + * + * @param projectKey + * @param userId + * @param gridId + * @return + * @author wxz + * @date 2021.09.23 17:45:25 + */ + public PermissionValidateResultDTO resiPermissionValidate(String projectKey, String userId, String gridId) { + + PrUserProjectEntity project = prUserProjectService.getProjectEntityBykey(projectKey); + if (project == null || !AppClientConstant.APP_RESI.equals(project.getClient())) { + // 工作端只能看到发布到居民端的 + log.warn("【调查问卷】居民端无法查看发布到工作端的调查问卷,staffId:{}, projectKey:{}", userId, projectKey); + return generateValidateResult(userId, projectKey, false); + } + + CustomerGridFormDTO form = new CustomerGridFormDTO(); + form.setGridId(gridId); + Result gridInfoResult = govOrgOpenFeignClient.getGridBaseInfoByGridId(form); + CustomerGridDTO gridInfo = getResultDataOrThrowsException(gridInfoResult, ServiceConstant.GOV_ORG_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【调查问卷】校验访问权限,查询网格信息失败"); + // 网格父级ID列表:网格ID(拼接起来,冒号分割) + String gridIdPath = gridInfo.getPids().concat(":").concat(gridInfo.getId()); + List publishRangeEntity = prPublishRangeService.getPublishRangeEntity(projectKey); + PermissionValidateResultDTO r = new PermissionValidateResultDTO(); + for (PrPublishRangeEntity rangeEntity : publishRangeEntity) { + if (gridIdPath.contains(rangeEntity.getOrgIds())) { + return generateValidateResult(userId, projectKey, true); + } + } + r.setPermitted(false); + return r; + } + + @Override + public PermissionValidateResultDTO govPermissionValidate(String projectKey, String staffId, String customerId) { + PrUserProjectEntity project = prUserProjectService.getProjectEntityBykey(projectKey); + if (project == null || !"gov".equals(project.getClient())) { + // 工作端只能看到发布到工作端的 + log.warn("【调查问卷】工作端无法查看发布到居民端的调查问卷,staffId:{}, projectKey:{}", staffId, projectKey); + return generateValidateResult(staffId, projectKey, false); + } + + List gridRangeOrgIds = new ArrayList<>(); + List agencyRangeOrgIds = new ArrayList<>(); + List deptRangeOrgIds = new ArrayList<>(); + + // 将发布范围分别放到3个不同的列表中 + List publishRangeEntitys = prPublishRangeService.getPublishRangeEntity(projectKey); + publishRangeEntitys.forEach(rangeEntity -> { + if ("grid".equals(rangeEntity.getOrgType())) { + gridRangeOrgIds.add(rangeEntity.getOrgIds()); + } else if ("agency".equals(rangeEntity.getOrgType())) { + agencyRangeOrgIds.add(rangeEntity.getOrgIds()); + } else if ("dept".equals(rangeEntity.getOrgType())) { + deptRangeOrgIds.add(rangeEntity.getOrgIds()); + } else { + throw new RenException(EpmetErrorCode.SERVER_ERROR.getCode(), String.format("【调查问卷】未知的发布范围类型:%s", rangeEntity.getOrgType())); + } + }); + + CustomerStaffInfoCacheResult staffInfo = customerStaffRedis.getStaffInfo(customerId, staffId); + PermissionValidateResultDTO r = null; + //if ("agency".equals(staffInfo.getFromOrgType())) { + // // 来自agency + // + //} else if ("grid".equals(staffInfo.getFromOrgType())) { + // List belongGridList = staffInfo.getGridList(); + // + //} else if ("dept".equals(staffInfo.getFromOrgType())) { + // + //} + + String agencyId = staffInfo.getAgencyId(); + String agencyPIds = staffInfo.getAgencyPIds(); + + // 网格范围内的权限判断 + List staffGridList = staffInfo.getGridList(); + for (IdAndNameDTO gridIdAndName : staffGridList) { + // 工作人员所属的 父orgId路径:网格id + String staffGridIdPath = (StringUtils.isEmpty(agencyPIds) ? "" : agencyPIds.concat(":")).concat(agencyId).concat(":").concat(gridIdAndName.getId()); + for (String gridRangeOrgId : gridRangeOrgIds) { + if (staffGridIdPath.contains(gridRangeOrgId)) { + r = generateValidateResult(staffId, projectKey, true); + return r; + } + } + } + + // dept范围内的权限判断 + List staffDeptList = staffInfo.getDeptList(); + for (IdAndNameDTO deptIdAndName : staffDeptList) { + // 工作人员所属的 父orgId路径:网格id + String staffDeptIdPath = (StringUtils.isEmpty(agencyPIds) ? "" : agencyPIds.concat(":")).concat(agencyId).concat(":").concat(deptIdAndName.getId()); + for (String deptRangeOrgIdPath : deptRangeOrgIds) { + if (staffDeptIdPath.contains(deptRangeOrgIdPath)) { + r = generateValidateResult(staffId, projectKey, true); + return r; + } + } + } + + // agency范围内的权限判断 + String staffAgencyIdPath = (StringUtils.isEmpty(agencyPIds) ? "" : agencyPIds.concat(":")).concat(agencyId); + for (String agencyRangeOrgId : agencyRangeOrgIds) { + if (staffAgencyIdPath.contains(agencyRangeOrgId)) { + r = generateValidateResult(staffId, projectKey, true); + return r; + } + } + + // 如果上述范围中都不能判断通过,那么返回一个不通过的结果给到前端 + r = generateValidateResult(staffId, projectKey, false); + return r; + } + + /** + * @description 生成权限允许的返回结果 + * + * @param userId + * @param projectKey + * @param permitted 是否允许访问 + * @return + * @author wxz + * @date 2021.09.23 23:19:17 + */ + private PermissionValidateResultDTO generateValidateResult(String userId, String projectKey, Boolean permitted) { + PermissionValidateResultDTO d = new PermissionValidateResultDTO(); + d.setPermitted(permitted); + if (permitted) { + String accessKey = UUID.randomUUID().toString().replace("-", ""); + redisUtils.set(RedisKeys.getQuestionnaireAccessKey(userId, projectKey), accessKey, QUESTIONNAIRE_EXPIRE_SECONDS); + d.setAccessKey(accessKey); + } + return d; + } + +}