diff --git a/pom.xml b/pom.xml index 4b4784c..8ebccb8 100644 --- a/pom.xml +++ b/pom.xml @@ -230,6 +230,29 @@ 3.0.1 + + + org.projectlombok + lombok + true + + + + + org.mapstruct + mapstruct + 1.5.5.Final + + + + + org.mapstruct + mapstruct-processor + 1.5.5.Final + provided + + + diff --git a/src/main/java/com/biutag/supervision/aop/CheckInterceptor.java b/src/main/java/com/biutag/supervision/aop/CheckInterceptor.java new file mode 100644 index 0000000..5f05c69 --- /dev/null +++ b/src/main/java/com/biutag/supervision/aop/CheckInterceptor.java @@ -0,0 +1,50 @@ +package com.biutag.supervision.aop; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.stereotype.Component; + +/** + * @ClassName CheckInterceptor + * @Description 参数规范 + * @Author shihao + * @Date 2025/12/9 9:14 + */ +@Component +@Aspect +@Slf4j +public class CheckInterceptor { + + + @Pointcut("execution(* com.biutag.supervision.controller..*(..)) || execution(* com.biutag.supervision.service..*(..))") + public void pointCut() { + } + + + @Before("pointCut()") + public void check(JoinPoint joinPoint) { + Object[] args = joinPoint.getArgs(); + for (Object arg : args) { + if (arg instanceof ParamChecked) { + ((ParamChecked) arg).check(); + } + } + } + + + /** + * 只校验 com.biutag.supervision.pojo 包下面的类 + */ + private boolean inPojoPackage(Object arg) { + Package p = arg.getClass().getPackage(); + if (p == null) { + return false; + } + String pkg = p.getName(); + return pkg.startsWith("com.biutag.supervision.pojo"); + } + +} diff --git a/src/main/java/com/biutag/supervision/aop/ParamChecked.java b/src/main/java/com/biutag/supervision/aop/ParamChecked.java new file mode 100644 index 0000000..fba4cc3 --- /dev/null +++ b/src/main/java/com/biutag/supervision/aop/ParamChecked.java @@ -0,0 +1,8 @@ +package com.biutag.supervision.aop; + +import java.io.Serializable; + +public interface ParamChecked extends Serializable { + + void check(); +} diff --git a/src/main/java/com/biutag/supervision/common/UserContextHolder.java b/src/main/java/com/biutag/supervision/common/UserContextHolder.java index e24e9f5..9a9b26e 100644 --- a/src/main/java/com/biutag/supervision/common/UserContextHolder.java +++ b/src/main/java/com/biutag/supervision/common/UserContextHolder.java @@ -2,6 +2,7 @@ package com.biutag.supervision.common; import cn.hutool.core.util.StrUtil; import cn.hutool.http.Header; +import com.biutag.supervision.constants.AppConstants; import com.biutag.supervision.constants.RedisKeyConstants; import com.biutag.supervision.exception.AuthException; import com.biutag.supervision.pojo.model.UserAuth; @@ -31,4 +32,10 @@ public class UserContextHolder { return getCurrentUser().getUserId(); } + + public static boolean isSuperUser() { + return AppConstants.USER_TYPE_SUPER.equals(getCurrentUser().getUserType()); + } + + } \ No newline at end of file diff --git a/src/main/java/com/biutag/supervision/controller/report/ReportProjectController.java b/src/main/java/com/biutag/supervision/controller/report/ReportProjectController.java index 0c80e67..7e0f5f7 100644 --- a/src/main/java/com/biutag/supervision/controller/report/ReportProjectController.java +++ b/src/main/java/com/biutag/supervision/controller/report/ReportProjectController.java @@ -7,8 +7,6 @@ import cn.hutool.core.util.StrUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.excel.write.handler.CellWriteHandler; -import com.alibaba.excel.write.handler.context.CellWriteHandlerContext; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.fill.FillConfig; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -18,22 +16,19 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.biutag.supervision.common.UserContextHolder; import com.biutag.supervision.constants.AppConstants; import com.biutag.supervision.constants.enums.DeleteStatusEnum; -import com.biutag.supervision.constants.enums.FlowNodeEnum; import com.biutag.supervision.constants.enums.RoleCodeEnum; import com.biutag.supervision.mapper.Recessed.RecessedLogMapper; import com.biutag.supervision.pojo.Result; import com.biutag.supervision.pojo.entity.InformMessage; import com.biutag.supervision.pojo.entity.recessed.RecessedLog; -import com.biutag.supervision.pojo.entity.report.ReportFlow; import com.biutag.supervision.pojo.entity.report.ReportProject; -import com.biutag.supervision.pojo.entity.report.ReportReview; import com.biutag.supervision.pojo.enums.FlowEnum; import com.biutag.supervision.pojo.model.UserAuth; import com.biutag.supervision.pojo.param.Recessed.RecessedParam; -import com.biutag.supervision.pojo.param.Report.ReportDeleteParam; import com.biutag.supervision.pojo.param.Report.ReportProjectQueryParam; import com.biutag.supervision.pojo.param.entryWindow.EntryWindowQueryParam; import com.biutag.supervision.pojo.param.statement.StatementQueryParam; +import com.biutag.supervision.pojo.request.reportProject.ReportProjectDeleteRequest; import com.biutag.supervision.pojo.vo.entryWindow.EntryWindowVo; import com.biutag.supervision.pojo.vo.excel.ExcelControlPriceVo; import com.biutag.supervision.pojo.vo.report.ReportHomeVo; @@ -42,24 +37,18 @@ import com.biutag.supervision.pojo.vo.statement.ConditionExcelVo; import com.biutag.supervision.pojo.vo.statement.ConditionVo; import com.biutag.supervision.service.InformMessageService; import com.biutag.supervision.service.Report.ReportProjectService; -import com.biutag.supervision.service.Report.ReportReviewService; import com.biutag.supervision.service.SupDepartService; import com.biutag.supervision.util.BigDecimalUtils; -import com.biutag.supervision.util.CustomFontLoader; import jakarta.servlet.ServletOutputStream; import jakarta.servlet.http.HttpServletResponse; -import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.IOUtils; import org.springframework.core.io.ClassPathResource; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; -import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; @@ -67,7 +56,9 @@ import java.math.RoundingMode; import java.net.URLEncoder; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; /** * @author weipeng @@ -151,6 +142,7 @@ public class ReportProjectController { orgIds = departService.getAllNodeIds(user.getDepartId()); wrapper.in("p.project_unit_id", orgIds); } + wrapper.eq("p.delete_flag", DeleteStatusEnum.NO.getCode()); } wrapper.orderByDesc("p.crt_time"); wrapper.groupBy("p.id"); @@ -188,9 +180,8 @@ public class ReportProjectController { wrapper.ge("p.report_money",new BigDecimal(200000)); } } - - wrapper.groupBy("p.id"); + wrapper.eq("p.delete_flag", DeleteStatusEnum.NO.getCode()); return Result.success(reportProjectService.getConditionPage(new Page<>(queryParam.getCurrent(),queryParam.getSize()),wrapper)); } @@ -329,14 +320,18 @@ public class ReportProjectController { } - @DeleteMapping("/{id}") - public Result delDetail(@PathVariable("id")String id){ - ReportDeleteParam reportDeleteParam = new ReportDeleteParam(); - reportDeleteParam.setId(id); - reportDeleteParam.setIsDel(DeleteStatusEnum.YES.getCode()); - return reportProjectService.delete(reportDeleteParam); +// @DeleteMapping("/{id}") +// public Result delDetail(@PathVariable("id")String id){ +//// ReportDeleteParam reportDeleteParam = new ReportDeleteParam(); +//// reportDeleteParam.setId(id); +//// return reportProjectService.delete(reportDeleteParam); // reportProjectService.removeById(id); // return Result.success(); +// } + + @PostMapping("/deleteReportProject") + public Result deleteReportProject(@RequestBody ReportProjectDeleteRequest request){ + return reportProjectService.deleteReportProject(request); } diff --git a/src/main/java/com/biutag/supervision/controller/warning/WarningController.java b/src/main/java/com/biutag/supervision/controller/warning/WarningController.java index 7fdcbd5..0df1525 100644 --- a/src/main/java/com/biutag/supervision/controller/warning/WarningController.java +++ b/src/main/java/com/biutag/supervision/controller/warning/WarningController.java @@ -3,22 +3,18 @@ package com.biutag.supervision.controller.warning; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; - -import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.biutag.supervision.common.UserContextHolder; import com.biutag.supervision.constants.AppConstants; +import com.biutag.supervision.constants.enums.DeleteStatusEnum; import com.biutag.supervision.constants.enums.RoleCodeEnum; import com.biutag.supervision.pojo.Result; -import com.biutag.supervision.pojo.entity.InvertRecord; import com.biutag.supervision.pojo.entity.report.ReportFlow; import com.biutag.supervision.pojo.entity.report.ReportProject; -import com.biutag.supervision.pojo.entity.report.ReportReview; import com.biutag.supervision.pojo.entity.warning.WarningContent; import com.biutag.supervision.pojo.entity.warning.WarningRecord; -import com.biutag.supervision.pojo.enums.FlowEnum; import com.biutag.supervision.pojo.enums.FlowStateEnum; import com.biutag.supervision.pojo.enums.FlowWarningEnum; import com.biutag.supervision.pojo.model.UserAuth; @@ -32,14 +28,12 @@ import com.biutag.supervision.service.Report.ReportProjectService; import com.biutag.supervision.service.SupDepartService; import com.biutag.supervision.service.Warning.WarningContentService; import com.biutag.supervision.service.Warning.WarningRecordService; -import io.lettuce.core.dynamic.annotation.Param; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -66,7 +60,8 @@ public class WarningController { .eq("f.report_link","end") .eq("f.approver_state","end") .eq(StrUtil.isNotBlank(queryParam.getWarningState()),"p.warning_state",queryParam.getWarningState()) - .eq("p.node",FlowStateEnum.End.getLabel()); + .eq("p.node",FlowStateEnum.End.getLabel()) + .eq("p.delete_flag", DeleteStatusEnum.NO.getCode()); if (!AppConstants.USER_TYPE_SUPER.equals(user.getUserType()) && !user.getRoleCodes().contains(RoleCodeEnum.FIRST_ADMIN.getCode())) { List orgIds =new ArrayList<>(); if(!user.getAuthDepartIds().isEmpty()){ diff --git a/src/main/java/com/biutag/supervision/mapper/Report/ReportProjectMapper.java b/src/main/java/com/biutag/supervision/mapper/Report/ReportProjectMapper.java index f8fd2a1..5e3bf7d 100644 --- a/src/main/java/com/biutag/supervision/mapper/Report/ReportProjectMapper.java +++ b/src/main/java/com/biutag/supervision/mapper/Report/ReportProjectMapper.java @@ -30,4 +30,9 @@ public interface ReportProjectMapper extends BaseMapper { List getProjectWorkVoList(ProjectWorkQueryParam queryParam); ProjectTabWorkVo getProjectTabWorkVo(ProjectWorkQueryParam queryParam); + + /** + * 管理员专用:根据 id 查询,包括逻辑删除的数据 + */ + ReportProject selectByIdIncludeDeleted(@Param("id") String id); } diff --git a/src/main/java/com/biutag/supervision/pojo/entity/report/ReportProject.java b/src/main/java/com/biutag/supervision/pojo/entity/report/ReportProject.java index de9a774..dacf084 100644 --- a/src/main/java/com/biutag/supervision/pojo/entity/report/ReportProject.java +++ b/src/main/java/com/biutag/supervision/pojo/entity/report/ReportProject.java @@ -2,7 +2,9 @@ package com.biutag.supervision.pojo.entity.report; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableName; +import com.biutag.supervision.constants.AppConstants; import com.biutag.supervision.constants.enums.DeleteStatusEnum; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.v3.oas.annotations.media.Schema; @@ -160,4 +162,16 @@ public class ReportProject { private int isRecessed; + /** + * @see AppConstants + */ + @Schema(description = "是否逻辑删除:0-未删除,1-已删除") + @TableLogic(value = AppConstants.UN_DEL, delval = AppConstants.DEL) + @TableField("delete_flag") + private Integer deleteFlag; + + @TableField("delete_reason") + @Schema(description = "删除原因") + private String deleteReason; + } diff --git a/src/main/java/com/biutag/supervision/pojo/param/Report/ReportDeleteParam.java b/src/main/java/com/biutag/supervision/pojo/param/Report/ReportDeleteParam.java index 4db668a..1a2b3ec 100644 --- a/src/main/java/com/biutag/supervision/pojo/param/Report/ReportDeleteParam.java +++ b/src/main/java/com/biutag/supervision/pojo/param/Report/ReportDeleteParam.java @@ -11,13 +11,11 @@ import lombok.Data; @Data public class ReportDeleteParam { - //项目id + @Schema(description = "项目id") private String id; - /** - * @see com.biutag.supervision.constants.enums.DeleteStatusEnum - */ - @Schema(description = "是否删除") - private int isDel; + + @Schema(description = "删除原因") + private String deleteReason; } diff --git a/src/main/java/com/biutag/supervision/pojo/request/reportProject/ReportProjectDeleteRequest.java b/src/main/java/com/biutag/supervision/pojo/request/reportProject/ReportProjectDeleteRequest.java new file mode 100644 index 0000000..8255754 --- /dev/null +++ b/src/main/java/com/biutag/supervision/pojo/request/reportProject/ReportProjectDeleteRequest.java @@ -0,0 +1,32 @@ +package com.biutag.supervision.pojo.request.reportProject; + +import com.biutag.supervision.aop.ParamChecked; +import dm.jdbc.util.StringUtil; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * @ClassName ProjectDeleteRequest + * @Description 项目删除请求 + * @Author shihao + * @Date 2025/12/8 18:48 + */ +@Setter +@Getter +@Schema(description = "项目删除请求") +public class ReportProjectDeleteRequest implements ParamChecked { + + @Schema(description = "项目id") + private String id; + + @Schema(description = "删除原因") + private String deleteReason; + + @Override + public void check() { + if (StringUtil.isEmpty(id)){ + throw new IllegalArgumentException("删除id不能为空!"); + } + } +} diff --git a/src/main/java/com/biutag/supervision/pojo/transfer/ProjectTransfer.java b/src/main/java/com/biutag/supervision/pojo/transfer/ProjectTransfer.java new file mode 100644 index 0000000..3201f51 --- /dev/null +++ b/src/main/java/com/biutag/supervision/pojo/transfer/ProjectTransfer.java @@ -0,0 +1,20 @@ +package com.biutag.supervision.pojo.transfer; + +import com.biutag.supervision.pojo.param.Report.ReportDeleteParam; +import com.biutag.supervision.pojo.request.reportProject.ReportProjectDeleteRequest; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @ClassName ProjectTransfer + * @Description ProjectTransfer + * @Author shihao + * @Date 2025/12/8 18:55 + */ +@Mapper +public interface ProjectTransfer { + + ProjectTransfer INSTANCE = Mappers.getMapper(ProjectTransfer.class); + + ReportDeleteParam delRequestToDelParam(ReportProjectDeleteRequest request); +} diff --git a/src/main/java/com/biutag/supervision/service/Report/ReportProjectService.java b/src/main/java/com/biutag/supervision/service/Report/ReportProjectService.java index 7a8fc7a..528c6d9 100644 --- a/src/main/java/com/biutag/supervision/service/Report/ReportProjectService.java +++ b/src/main/java/com/biutag/supervision/service/Report/ReportProjectService.java @@ -4,15 +4,11 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; -import com.alibaba.excel.util.StringUtils; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; -import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.biutag.supervision.common.UserContextHolder; @@ -27,20 +23,18 @@ import com.biutag.supervision.mapper.Report.ReportReviewMapper; import com.biutag.supervision.mapper.Warning.WarningContentMapper; import com.biutag.supervision.mapper.Warning.WarningRecordMapper; import com.biutag.supervision.pojo.Result; -import com.biutag.supervision.pojo.entity.InformMessage; -import com.biutag.supervision.pojo.entity.InvertRecord; import com.biutag.supervision.pojo.entity.report.ReportFile; import com.biutag.supervision.pojo.entity.report.ReportFlow; import com.biutag.supervision.pojo.entity.report.ReportProject; import com.biutag.supervision.pojo.entity.report.ReportReview; -import com.biutag.supervision.pojo.entity.warning.WarningContent; -import com.biutag.supervision.pojo.entity.warning.WarningRecord; import com.biutag.supervision.pojo.enums.FlowEnum; import com.biutag.supervision.pojo.enums.FlowStateEnum; import com.biutag.supervision.pojo.model.UserAuth; import com.biutag.supervision.pojo.param.Report.ReportDeleteParam; import com.biutag.supervision.pojo.param.Report.ReportProjectQueryParam; import com.biutag.supervision.pojo.param.Work.ProjectWorkQueryParam; +import com.biutag.supervision.pojo.request.reportProject.ReportProjectDeleteRequest; +import com.biutag.supervision.pojo.transfer.ProjectTransfer; import com.biutag.supervision.pojo.vo.FileVo; import com.biutag.supervision.pojo.vo.entryWindow.EntryWindowVo; import com.biutag.supervision.pojo.vo.report.ReportFileVo; @@ -135,7 +129,12 @@ public class ReportProjectService extends ServiceImpl dateTimes = new ArrayList<>(); dateTimes.add(project.getServiceStartTime()); @@ -169,8 +168,9 @@ public class ReportProjectService extends ServiceImpl flows = reportFlowService.list(new LambdaQueryWrapper().eq(ReportFlow::getReportId, id).eq(ReportFlow::getType, "report")); - flows = flows.stream().filter(s -> !s.getApproverState().equals(FlowStateEnum.Reject.getLabel()) && isFileFlow(project.getNode()).contains(s.getReportLink())) + flows = flows.stream().filter(s -> !s.getApproverState().equals(FlowStateEnum.Reject.getLabel()) && isFileFlow(finalReport.getNode()).contains(s.getReportLink())) .collect(Collectors.toMap( ReportFlow::getReportCode, Function.identity(), @@ -303,27 +303,40 @@ public class ReportProjectService extends ServiceImpl delete(ReportDeleteParam reportDeleteParam) { +// String id = reportDeleteParam.getId(); +// if (StringUtils.isBlank(id)) { +// return Result.failed("项目id不能为空"); +// } +// this.removeById(id); +// deleteByColumn(reviewMapper, ReportReview::getReportId, id); +// deleteByColumn(reportFileMapper, ReportFile::getReportId, id); +// deleteByColumn(reportFlowMapper, ReportFlow::getReportId, id); +// deleteByColumn(informMessageMapper, InformMessage::getReportId, id); +// deleteByColumn(warningContentMapper, WarningContent::getWarningId, id); +// deleteByColumn(warningRecordMapper, WarningRecord::getReportId, id); +// deleteByColumn(invertRecordMapper, InvertRecord::getReportId, id); +// return Result.success(); +// } +// +// +// private void deleteByColumn (BaseMapper mapper, SFunction column, String id ){ +// LambdaQueryWrapper wrapper = Wrappers.lambdaQuery().eq(column, id); +// mapper.delete(wrapper); +// } + @Transactional(rollbackFor = Exception.class) - public Result delete(ReportDeleteParam reportDeleteParam) { - String id = reportDeleteParam.getId(); - if (StringUtils.isBlank(id)) { - return Result.failed("项目id不能为空"); + public Result deleteReportProject(ReportProjectDeleteRequest request) { + ReportDeleteParam reportDeleteParam = ProjectTransfer.INSTANCE.delRequestToDelParam(request); + ReportProject reportProject = this.getById(reportDeleteParam.getId()); + if (ObjectUtil.isNull(reportProject)){ + throw new RuntimeException("项目数据不存在!"); } - this.removeById(id); - deleteByColumn(reviewMapper, ReportReview::getReportId, id); - deleteByColumn(reportFileMapper, ReportFile::getReportId, id); - deleteByColumn(reportFlowMapper, ReportFlow::getReportId, id); - deleteByColumn(informMessageMapper, InformMessage::getReportId, id); - deleteByColumn(warningContentMapper, WarningContent::getWarningId, id); - deleteByColumn(warningRecordMapper, WarningRecord::getReportId, id); - deleteByColumn(invertRecordMapper, InvertRecord::getReportId, id); - return Result.success(); - } - - - private void deleteByColumn (BaseMapper mapper, SFunction column, String id ){ - LambdaQueryWrapper wrapper = Wrappers.lambdaQuery().eq(column, id); - mapper.delete(wrapper); + reportProject.setDeleteReason(reportDeleteParam.getDeleteReason()); + this.updateById(reportProject); + this.removeById(reportProject); + return Result.success(); } diff --git a/src/main/resources/mapper/ReportProjectMapper.xml b/src/main/resources/mapper/ReportProjectMapper.xml index a199e91..07818ea 100644 --- a/src/main/resources/mapper/ReportProjectMapper.xml +++ b/src/main/resources/mapper/ReportProjectMapper.xml @@ -23,6 +23,10 @@ LEFT JOIN report_project as p2 on p2.id = w.report_id flow.is_init is null + AND ( + (w.id IS NULL AND project.delete_flag = 0) + OR (w.id IS NOT NULL AND p2.delete_flag = 0) + ) and flow.approver_id = #{userId} @@ -46,7 +50,7 @@ report_flow flow LEFT JOIN report_project as project on project.id = flow.report_id - flow.is_init is null and project.is_recessed = 0 + flow.is_init is null and project.is_recessed = 0 AND project.delete_flag = 0 and flow.approver_id = #{userId} @@ -85,4 +89,9 @@ left join report_review rv on p.id = rv.report_id ${ew.getCustomSqlSegment} +