From 809aaae720da8c82b407e9e1d1561e671a56c81f Mon Sep 17 00:00:00 2001 From: renhao02 Date: Fri, 7 Mar 2025 17:33:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=A6=96=E9=A1=B5=E3=80=81?= =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E5=B7=A1=E6=9F=A5=E3=80=81=E6=89=A7=E6=B3=95?= =?UTF-8?q?=E5=A4=84=E7=BD=9A=E7=BB=9F=E8=AE=A1=E3=80=81=E6=B3=95=E6=B2=BB?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E7=AD=89=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ExampleService.java | 19 + .../service/HikVisionService.java | 172 +++++++ .../service/HomePageService.java | 446 ++++++++++++++++++ .../service/InsEnterprseService.java | 38 ++ .../service/LawEnfPenaltyStatService.java | 90 ++++ .../service/LegalReviewService.java | 220 +++++++++ .../service/MessageService.java | 241 ++++++++++ 7 files changed, 1226 insertions(+) create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/ExampleService.java create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/HikVisionService.java create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/HomePageService.java create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/InsEnterprseService.java create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/LawEnfPenaltyStatService.java create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/LegalReviewService.java create mode 100644 server/src/main/java/com/aisino/iles/lawenforcement/service/MessageService.java diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/ExampleService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/ExampleService.java new file mode 100644 index 0000000..8b74852 --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/ExampleService.java @@ -0,0 +1,19 @@ +package com.aisino.iles.lawenforcement.service; + +import com.aisino.iles.lawenforcement.model.Example; +import com.aisino.iles.lawenforcement.repository.ExampleRepository; +import org.springframework.stereotype.Service; + +@Service +public class ExampleService { + private final ExampleRepository exampleRepository; + + public ExampleService(ExampleRepository exampleRepository) { + this.exampleRepository = exampleRepository; + } + + public Example getExample() { + return exampleRepository.findAll().stream().findFirst().orElseGet(Example::new); + } + +} diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/HikVisionService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/HikVisionService.java new file mode 100644 index 0000000..e35a66a --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/HikVisionService.java @@ -0,0 +1,172 @@ +package com.aisino.iles.lawenforcement.service; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.aisino.iles.lawenforcement.model.query.HikVisionQuery; +import com.hikvision.artemis.sdk.ArtemisHttpUtil; +import com.hikvision.artemis.sdk.config.ArtemisConfig; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +@Slf4j +@Service +public class HikVisionService { + + private void initHikInterfaceInfo() { + ArtemisConfig.host = "10.22.245.160:10443"; + ArtemisConfig.appKey = "20976813"; + ArtemisConfig.appSecret = "KCCXzxhyTFCelIg4SRIz"; + } + + public String getRegionsRoot(String treeCode) { + // 设置平台参数 + initHikInterfaceInfo(); + // 设置调用接口地址 + Map path = new HashMap(2) { + { + put("https://", "/artemis/api/resource/v1/regions/root"); + } + }; + // 组装请求参数 + JSONObject jsonBody = JSONUtil.createObj().putOpt("treeCode", treeCode); + String body = JSONUtil.toJsonStr(jsonBody); + // 设置参数提交方式 + String contentType = "application/json"; + // 调用接口 + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + log.debug("获取根区域信息:{}", result); + return result; + } + + public String getSubRegions(String parentIndexCode, String treeCode) { + // 设置平台参数 + initHikInterfaceInfo(); + // 设置调用接口地址 + Map path = new HashMap(2) { + { + put("https://", "/artemis/api/resource/v1/regions/subRegions"); + } + }; + // 组装请求参数 + JSONObject jsonBody = JSONUtil.createObj() + .putOpt("parentIndexCode", parentIndexCode) + .putOpt("treeCode", treeCode); + String body = JSONUtil.toJsonStr(jsonBody); + // 设置参数提交方式 + String contentType = "application/json"; + // 调用接口 + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + log.debug("下一级区域信息:{}", result); + return result; + } + + public String getRegionsCameras(HikVisionQuery hikVisionQuery) { + // 设置平台参数 + initHikInterfaceInfo(); + // 设置调用接口地址 + Map path = new HashMap(2) { + { + put("https://", "/artemis/api/resource/v1/regions/regionIndexCode/cameras"); + } + }; + // 组装请求参数 + JSONObject jsonBody = JSONUtil.createObj() + .putOpt("pageNo", hikVisionQuery.getPageNo()) + .putOpt("pageSize", hikVisionQuery.getPageSize()) + .putOpt("regionIndexCode", hikVisionQuery.getRegionIndexCode()) + .putOpt("treeCode", hikVisionQuery.getTreeCode()); + String body = JSONUtil.toJsonStr(jsonBody); + // 设置参数提交方式 + String contentType = "application/json"; + // 调用接口 + String result; + result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + log.debug("区域摄像头信息:{}", result); + return result; + } + + public String getRegionsCamerasDetail(String cameraIndexCode) { + // 设置平台参数 + initHikInterfaceInfo(); + // 设置调用接口地址 + Map path = new HashMap(2) { + { + put("https://", "/artemis/api/resource/v1/cameras/indexCode"); + } + }; + // 组装请求参数 + JSONObject jsonBody = JSONUtil.createObj().putOpt("cameraIndexCode", cameraIndexCode); + String body = JSONUtil.toJsonStr(jsonBody); + // 设置参数提交方式 + String contentType = "application/json"; + // 调用接口 + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + log.debug("摄像头详情信息:{}", result); + return result; + } + + public String getCamerasPreview(HikVisionQuery hikVisionQuery) { + // 设置平台参数 + initHikInterfaceInfo(); + // 设置调用接口地址 + Map path = new HashMap(2) { + { + put("https://", "/artemis/api/video/v1/cameras/previewURLs"); + } + }; + // 组装请求参数 + JSONObject jsonBody = JSONUtil.createObj() + .putOpt("cameraIndexCode", hikVisionQuery.getCameraIndexCode()) + .putOpt("streamType", hikVisionQuery.getStreamType()) + .putOpt("protocol", hikVisionQuery.getProtocol()) + .putOpt("transmode", hikVisionQuery.getTransMode()); + String body = JSONUtil.toJsonStr(jsonBody); + // 设置参数提交方式 + String contentType = "application/json"; + log.debug("摄像头播放流请求参数:{}", jsonBody); + // 调用接口 + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + log.debug("摄像头预览流信息:{}", result); + return result; + } + + public String getCamerasPlayback(HikVisionQuery hikVisionQuery) { + // 设置平台参数 + initHikInterfaceInfo(); + // 设置调用接口地址 + Map path = new HashMap(2) { + { + put("https://", "/artemis/api/video/v1/cameras/playbackURLs"); + } + }; + // 组装请求参数 + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + LocalDateTime s = hikVisionQuery.getFallBackTime()[0]; + LocalDateTime e = hikVisionQuery.getFallBackTime()[1]; + String beginTime = simpleDateFormat.format(Date.from(s.atZone(ZoneId.systemDefault()).toInstant())); + String endTime = simpleDateFormat.format(Date.from(e.atZone(ZoneId.systemDefault()).toInstant())); + JSONObject jsonBody = JSONUtil.createObj() + .putOpt("cameraIndexCode", hikVisionQuery.getCameraIndexCode()) + .putOpt("protocol", hikVisionQuery.getProtocol()) + .putOpt("transmode", hikVisionQuery.getTransMode()) + .putOpt("beginTime", beginTime) + .putOpt("endTime", endTime); + String body = JSONUtil.toJsonStr(jsonBody); + // 设置参数提交方式 + String contentType = "application/json"; + log.debug("摄像头回放流请求参数:{}", jsonBody); + // 调用接口 + String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null); + log.debug("摄像头回放流信息:{}", result); + return result; + } + +} diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/HomePageService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/HomePageService.java new file mode 100644 index 0000000..8268f7a --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/HomePageService.java @@ -0,0 +1,446 @@ +package com.aisino.iles.lawenforcement.service; + +import com.aisino.iles.common.util.PageableHelper; +import com.aisino.iles.common.util.StringUtils; +import com.aisino.iles.lawenforcement.model.*; +import com.aisino.iles.lawenforcement.model.dto.*; +import com.aisino.iles.lawenforcement.model.enums.FlowNode; +import com.aisino.iles.lawenforcement.model.query.CaseQuery; +import com.aisino.iles.lawenforcement.model.query.DocumentQuery; +import com.aisino.iles.lawenforcement.model.query.EnforceCheckQuery; +import com.aisino.iles.lawenforcement.repository.*; +import com.smartlx.sso.client.model.RemoteUserInfo; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Join; +import jakarta.persistence.criteria.JoinType; +import jakarta.persistence.criteria.Predicate; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.TemporalAdjusters; +import java.util.*; +import java.util.stream.Collectors; + +@Service +@Slf4j +public class HomePageService { + private final EnforcementInfoRepository enforcementInfoRepository; + private final EnforceCheckRepository enforceCheckRepo; + private final DocumentRepository documentRepository; + private final HomePageRepository homePageRepository; + private final AgencyRepository agencyRepo; + private final CaseRepository caseRepository; + + public HomePageService(DocumentRepository documentRepository, + EnforcementInfoRepository enforcementInfoRepository, + EnforceCheckRepository enforceCheckRepo, + HomePageRepository homePageRepository, + AgencyRepository agencyRepo, + CaseRepository caseRepository) { + this.enforcementInfoRepository = enforcementInfoRepository; + this.documentRepository = documentRepository; + this.enforceCheckRepo = enforceCheckRepo; + this.homePageRepository = homePageRepository; + this.agencyRepo = agencyRepo; + this.caseRepository = caseRepository; + } + + public Map getstatCount(RemoteUserInfo user) { + Long qys; + Long ajs; + Long zfxxs; + Long wss; + Long jcs; + Long cls; + Agency currentAgency = agencyRepo.findByAgencyCode(user.getGajgjgdm()).orElseThrow(() -> new RuntimeException("当前用户机构数据错误,请检查!")); + if (currentAgency.getAgencyLevel() == 3) { + qys = homePageRepository.getqysByDistrict(currentAgency.getAgencyCode()); + ajs = homePageRepository.getajsByDistrict(currentAgency.getAgencyCode()); + zfxxs = homePageRepository.getZfxxsByDistrict(currentAgency.getAgencyCode()); + wss = homePageRepository.getWssByDistrict(currentAgency.getAgencyCode()); + jcs = homePageRepository.getjcsByDistrict(currentAgency.getAgencyCode()); + cls = homePageRepository.getclsByDistrict(currentAgency.getAgencyCode()); + } else { + qys = homePageRepository.getqys(StringUtils.trimEven0(user.getGajgjgdm()) + "%"); + ajs = homePageRepository.getajs(); + zfxxs = enforcementInfoRepository.count(); + wss = documentRepository.countByStatus(Document.DocumentStatus.done); + jcs = homePageRepository.getjcs(); + cls = homePageRepository.getcls(); + } + + Map res = new HashMap<>(); + res.put("qys", qys); + res.put("ajs", ajs); + res.put("zfxxs", zfxxs); + res.put("wss", wss); + res.put("jcs", jcs); + res.put("cls", cls); + return res; + } + + public Map getdla(RemoteUserInfo user) { + Agency currentAgency = agencyRepo.findByAgencyCode(user.getGajgjgdm()).orElseThrow(() -> new RuntimeException("当前用户机构数据错误,请检查!")); + Long dlas; + if (currentAgency.getAgencyLevel() == 3) { + dlas = homePageRepository.getdlaByDistrict(currentAgency.getAgencyCode()); + } else { + dlas = homePageRepository.getdla(); + } + Map res = new HashMap<>(); + res.put("dla", dlas); + return res; + } + + public List> countCurrentNodeCode(RemoteUserInfo user) { + Agency currentAgency = agencyRepo.findByAgencyCode(user.getGajgjgdm()).orElseThrow(() -> new RuntimeException("当前用户机构数据错误,请检查!")); + if (currentAgency.getAgencyLevel() == 3) + return homePageRepository.countCurrentNodeCodeByDistrict(currentAgency.getAgencyCode()); + else + return homePageRepository.countCurrentNodeCode(); + } + + /** + * 提供平台大屏接口 + * + * @return 当月文书数 + */ + public Long getDocumentNumForPlatform() { + LocalDateTime firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN); + LocalDateTime lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX); + return homePageRepository.getDocumentNumForPlatform(firstDayOfMonth, lastDayOfMonth); + } + + /** + * 提供平台大屏接口查询当月案卷数量 + * + * @return 当月案卷数量 + */ + public Long getDossiersNumForPlatform() { + LocalDateTime firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN); + LocalDateTime lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX); + return homePageRepository.getDossiersNumForPlatform(firstDayOfMonth, lastDayOfMonth); + } + + /** + * 查询当月受理、调查、决定、执行数量 + * + * @return 查询当月受理、调查、决定、执行数量 + */ + public HomePageDto getCaseNodeNumForPlatform() { + LocalDateTime firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN); + LocalDateTime lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX); + HomePageDto dto = new HomePageDto(); + dto.setSlNum(homePageRepository.getSlNum(firstDayOfMonth, lastDayOfMonth)); + dto.setDcNum(homePageRepository.getdcNum(firstDayOfMonth, lastDayOfMonth)); + dto.setJdNum(homePageRepository.getjdNum(firstDayOfMonth, lastDayOfMonth)); + dto.setZxNum(homePageRepository.getzxNum(firstDayOfMonth, lastDayOfMonth)); + return dto; + } + + + @Transactional(readOnly = true) + public Page getDocumentForPlatformDetail(DocumentQuery query) { + LocalDateTime firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()).atTime(LocalTime.MIN); + LocalDateTime lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).atTime(LocalTime.MAX); + query.setDocumentDate(new LocalDateTime[]{firstDayOfMonth, lastDayOfMonth}); + + + return documentRepository.findAll(buildQuery(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir())).map(this::getDocumentInfo); + } + + private Specification buildQuery(DocumentQuery query) { + return Specification.where((root, q, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + predicates.add(criteriaBuilder.equal(root.get(Document_.status), Document.DocumentStatus.done)); + Optional.ofNullable(query.getDocumentDate()).filter(f -> f.length == 2).map(f -> { + List timePredicates = new ArrayList<>(); + Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get(Document_.documentDate), from)).ifPresent(timePredicates::add); + Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get(Document_.documentDate), to)).ifPresent(timePredicates::add); + return timePredicates; + }).ifPresent(predicates::addAll); + + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }); + } + + private HomePageDetailDto getDocumentInfo(Document c) { + HomePageDetailDto dto = new HomePageDetailDto(); + dto.setCaseId(c.getCaseId()); + dto.setCaseName(c.getCaseInfo().getCaseName()); + dto.setCaseNum(c.getCaseInfo().getCaseNum()); + dto.setCaseCause(c.getCaseInfo().getCaseCause()); + dto.setDocumentCode(c.getDocumentCode()); + dto.setDocumentName(c.getDocumentName()); + dto.setDocumentDate(c.getDocumentDate()); + return dto; + } + + @Transactional(readOnly = true) + public Page gettDossiersNumForPlatformDetail(CaseQuery query) { + LocalDate firstDayOfMonth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()); + LocalDate lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()); + query.setFillingDate(new LocalDate[]{firstDayOfMonth, lastDayOfMonth}); + return caseRepository.findAll(buildCondiction(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir())).map(this::getdtoInfo); + } + + private Specification buildCondiction(CaseQuery query) { + return Specification.where((root, q, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + predicates.add(criteriaBuilder.isNotNull(root.get(Case_.filePath))); + Optional.ofNullable(query.getFillingDate()).filter(f -> f.length == 2).map(f -> { + List timePredicates = new ArrayList<>(); + Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get("fillingDate"), from)).ifPresent(timePredicates::add); + Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get("fillingDate"), to)).ifPresent(timePredicates::add); + return timePredicates; + }).ifPresent(predicates::addAll); + + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }); + } + + private HomePageDetailDto getdtoInfo(Case c) { + HomePageDetailDto dto = new HomePageDetailDto(); + dto.setCaseId(c.getCaseId()); + dto.setCaseName(c.getCaseName()); + dto.setCaseNum(c.getCaseNum()); + dto.setCaseCause(c.getCaseCause()); + dto.setFillingDate(c.getFillingDate()); + dto.setCaseClosingDate(c.getCaseClosingDate()); + dto.setUnitName(c.getEnforcementInfo().getEnterprise().getUnitName()); + dto.setUnifiedSocialCode(c.getEnforcementInfo().getEnterprise().getUnifiedSocialCode()); + return dto; + } + + private Specification buildSpec(CaseQuery query) { + return Specification.where((root, q, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + Join enforcementInfoCaseRoot = root.join("enforcementInfo", JoinType.LEFT); + predicates.add(criteriaBuilder.equal((enforcementInfoCaseRoot.get(EnforcementInfo_.fillingFlag)), "1")); + Optional.ofNullable(query.getFlowNodes()).ifPresent(o -> { + CriteriaBuilder.In nods = criteriaBuilder.in(enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode)); + for (FlowNode flowNode : o) { + nods.value(flowNode); + } + predicates.add(nods); + }); + Optional.ofNullable(query.getFillingDate()).filter(f -> f.length == 2).map(f -> { + List timePredicates = new ArrayList<>(); + Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get("fillingDate"), from)).ifPresent(timePredicates::add); + Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get("fillingDate"), to)).ifPresent(timePredicates::add); + return timePredicates; + }).ifPresent(predicates::addAll); + + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }); + } + + @Transactional(readOnly = true) + public Page getCaseNodeNumForPlatformDetail(CaseQuery query) { + String conditionlike = query.getConditionlike(); + if ("sl".equals(conditionlike)) { + query.setFlowNodes(new FlowNode[]{FlowNode.filed, FlowNode.investigating, FlowNode.investigation_done, FlowNode.analyze_judge, FlowNode.reviewing_failed, FlowNode.reviewing_done, FlowNode.brainstorm, FlowNode.closed, FlowNode.done}); + } else if ("dc".equals(conditionlike)) { + query.setFlowNodes(new FlowNode[]{FlowNode.investigating, FlowNode.investigation_done, FlowNode.analyze_judge, FlowNode.reviewing_failed, FlowNode.reviewing_done, FlowNode.brainstorm, FlowNode.closed, FlowNode.done}); + } else if ("la".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.filed, FlowNode.investigating, FlowNode.investigation_done, FlowNode.analyze_judge, FlowNode.inform, FlowNode.hearing, FlowNode.decided, FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("dcqz".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.investigation_done, FlowNode.analyze_judge, FlowNode.inform, FlowNode.hearing, FlowNode.decided, FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("sls".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.analyze_judge, FlowNode.inform, FlowNode.hearing, FlowNode.decided, FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("gz".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.inform, FlowNode.hearing, FlowNode.decided, FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("tz".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.hearing, FlowNode.decided, FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("zx".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.decided, FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("jd".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.execute, FlowNode.closed, FlowNode.done}); + else if ("ja".equals(conditionlike)) + query.setFlowNodes(new FlowNode[]{FlowNode.closed, FlowNode.done}); + + return caseRepository.findAll(buildSpec(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir())).map(this::getdtoInfo); + } + + + /** + * 执法趋势统计 + * + * @return 统计结果 + */ + public Map zfqstj(EnforceCheckQuery query) { + Map result = new LinkedHashMap<>(); + LocalDateTime[] times = query.getCreateTime(); + if (null != times && times.length == 2) { + LocalDate now = times[1].toLocalDate(); + LocalDate start = times[0].toLocalDate(); + DateTimeFormatter ym = DateTimeFormatter.ofPattern("yyyy-MM"); + List pastMonths = new ArrayList<>(); + LocalDate current = start.withDayOfMonth(1); + LocalDate end = now.with(TemporalAdjusters.lastDayOfMonth()); + while (!current.isAfter(end)) { + pastMonths.add(current.format(ym)); + current = current.plusMonths(1); + } + List dtos = enforceCheckRepo.checkGroupByMonth(start, end); + Map zfjcMap = dtos.stream() + .collect(Collectors.toMap(dto -> formatMonth(dto.getDateStr()), EnforceCheckDto::getNum)); + + List zfjc = pastMonths.stream() + .map(month -> zfjcMap.getOrDefault(month, 0L)) + .toList(); + List caseDtos = caseRepository.caseGroupByMonth(start, end); + Map zflaMap = caseDtos.stream() + .collect(Collectors.toMap(dto -> formatMonth(dto.getDateStr()), EnforceCheckDto::getNum)); + List zfla = pastMonths.stream() + .map(month -> zflaMap.getOrDefault(month, 0L)) + .toList(); + List keys = List.of("执法检查", "执法立案"); + result.put("legend", keys); + result.put("xAxis", pastMonths); + result.put("执法检查", zfjc); + result.put("执法立案", zfla); + } + return result; + } + + private String formatMonth(String dateStr) { + if (dateStr == null || dateStr.isEmpty()) + return dateStr; + String[] parts = dateStr.split("-"); + if (parts.length != 2) + return dateStr; + try { + int year = Integer.parseInt(parts[0]); + int month = Integer.parseInt(parts[1]); + return String.format("%d-%02d", year, month); + } catch (NumberFormatException e) { + return dateStr; + } + } + + /** + * 行政执法案件进度一览表 + * + * @return 列表 + */ + public List ajjdlb(EnforceCheckQuery query) { + LocalDateTime[] times = query.getCreateTime(); + LocalDate start = times[0].toLocalDate(); + LocalDate end = times[1].toLocalDate().with(TemporalAdjusters.lastDayOfMonth()); + List list = documentRepository.getList(start.atStartOfDay(), end.atTime(23, 59, 59)); + List documentOrder = Arrays.asList( + "现场检查记录", + "立案审批表", + "案件调查终结报告", + "行政执法决定法制审核意见书", + "行政处罚告知书", + "听证会报告书", + "行政处罚集体讨论记录", + "行政处罚决定书", + "结案审批表" + ); + List res = new ArrayList<>(); + if (!list.isEmpty()) { + Map> map = list.stream().filter(o -> documentOrder.contains(o.getDocumentName())).collect(Collectors.groupingBy(DocumentDto::getCaseId)); + map.keySet().forEach(key -> { + List dtos = map.get(key); + DocumentDto dto = new DocumentDto(); + List ls = new ArrayList<>(); + for (int i = 0; i < documentOrder.size(); i++) { + String column = ""; + if (0 == i) column = "检查"; + else if (1 == i) column = "立案"; + else if (2 == i) column = "调查终结"; + else if (3 == i) column = "审理"; + else if (4 == i) column = "告知"; + else if (5 == i) column = "申辩与听证"; + else if (6 == i) column = "执行"; + else if (7 == i) column = "决定"; + else column = "结案"; + String k = documentOrder.get(i); + DocumentDto.DocumentList dto1 = new DocumentDto.DocumentList(); + dto1.setDocumentName(k); + if (dtos.stream().noneMatch(o -> k.equals(o.getDocumentName()))) { + dto1.setStatusTxt("未开始"); + dto1.setDocumentDate(null); + } else { + List dtoList = dtos.stream().filter(o -> k.equals(o.getDocumentName())).toList(); + Optional dtoOptional; + if (dtoList.size() > 1) + dtoOptional = dtoList.stream().filter(o -> Document.DocumentStatus.done.equals(o.getStatus())).findFirst(); + else + dtoOptional = dtoList.stream().findFirst(); + dtoOptional.ifPresent(o -> { + if (null == o.getDocumentDate()) + dto1.setStatusTxt("未开始"); + if (StringUtils.isEmpty(dto1.getStatusTxt())) { + if (Document.DocumentStatus.afoot.equals(o.getStatus())) { + if (ls.stream().anyMatch(oo -> "未开始".equals(oo.getStatusTxt())) + || ls.stream().anyMatch(oo -> "进行中".equals(oo.getStatusTxt()))) + dto1.setStatusTxt("未开始"); + else dto1.setStatusTxt("进行中"); + } else if (Document.DocumentStatus.done.equals(o.getStatus())) { + if (ls.stream().anyMatch(oo -> "未开始".equals(oo.getStatusTxt())) + || ls.stream().anyMatch(oo -> "进行中".equals(oo.getStatusTxt()))) + dto1.setStatusTxt("未开始"); + else dto1.setStatusTxt("已完成"); + } + } + dto1.setDocumentName(o.getDocumentName()); + dto1.setDocumentDate(o.getDocumentDate()); + }); + } + if ("未开始".equals(dto1.getStatusTxt())) + dto1.setDocumentDate(null); + dto1.setColumn(column); + ls.add(dto1); + } + dto.setCaseName(dtos.get(0).getCaseName()); + dto.setCaseId(dtos.get(0).getCaseId()); + ls.sort(Comparator.comparingInt(o -> { + int index = documentOrder.indexOf(o.getDocumentName()); + return index == -1 ? Integer.MAX_VALUE : index; + })); + dto.setList(ls); + res.add(dto); + }); + } + return res; + } + + /** + * 节点案件数量 + * + * @param query 查询参数 + * @return 节点案件数量 + */ + public NodeCaseNumDto getNodeCaseNum(CaseQuery query) { +// filed-立案 +// investigation_done-完成调查取证 +// analyze_judge-审理 +// inform-告知 +// hearing-陈述申辩或听证 +// execute-执行 +// decided-决定 +// closed-结案 + return homePageRepository.getNodeCaseNum(); + } + + public Map ajtj(EnforceCheckQuery query, RemoteUserInfo user) { + Agency currentAgency = agencyRepo.findByAgencyCode(user.getGajgjgdm()).orElseThrow(() -> new RuntimeException("当前用户机构数据错误,请检查!")); + String code = StringUtils.trimEven0(currentAgency.getAgencyCode()) + "%"; + Long ajs = homePageRepository.getajsByAgencyCode(code); + Map res = new HashMap<>(); + res.put("ajs", ajs); + return res; + } + +} diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/InsEnterprseService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/InsEnterprseService.java new file mode 100644 index 0000000..33ee6fb --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/InsEnterprseService.java @@ -0,0 +1,38 @@ +package com.aisino.iles.lawenforcement.service; + +import com.aisino.iles.lawenforcement.model.Enterprise; +import com.aisino.iles.lawenforcement.model.InsEnterprse; +import com.aisino.iles.lawenforcement.model.dto.InsEnterprseDto; +import com.aisino.iles.lawenforcement.repository.InsEnterprseRepository; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * 在线巡查企业信息服务类 + */ +@Service +public class InsEnterprseService { + + private final InsEnterprseRepository insEnterprseRepository; + + public InsEnterprseService(InsEnterprseRepository insEnterprseRepository) { + this.insEnterprseRepository = insEnterprseRepository; + } + + @Transactional + public void saveEnterprise(InsEnterprseDto insEnterprseDto) { + insEnterprseDto.getEnterpriseIds().forEach(id -> { + InsEnterprse insEnterprse = new InsEnterprse(); + insEnterprse.setValidStartTime(insEnterprseDto.getValidStartTime()); + insEnterprse.setValidEndTime(insEnterprseDto.getValidEndTime()); + insEnterprse.setCreateUserId(insEnterprseDto.getCreateUserId()); + insEnterprse.setCreateUserName(insEnterprseDto.getCreateUserName()); + insEnterprse.setCreateTime(insEnterprseDto.getCreateTime()); + Enterprise enterprise = new Enterprise(); + enterprise.setEnterpriseId(id); + insEnterprse.setEnterprise(enterprise); + insEnterprseRepository.save(insEnterprse); + }); + } + +} diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/LawEnfPenaltyStatService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/LawEnfPenaltyStatService.java new file mode 100644 index 0000000..c5dae7d --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/LawEnfPenaltyStatService.java @@ -0,0 +1,90 @@ +package com.aisino.iles.lawenforcement.service; + +import com.aisino.iles.common.util.Constants; +import com.aisino.iles.lawenforcement.model.Agency; +import com.aisino.iles.lawenforcement.model.EnforcementInfoHistory; +import com.aisino.iles.lawenforcement.model.OnlinePatrol; +import com.aisino.iles.lawenforcement.model.query.CaseQuery; +import com.aisino.iles.lawenforcement.model.query.LawEnfPenaltyStatQuery; +import com.aisino.iles.lawenforcement.repository.AgencyRepository; +import com.aisino.iles.lawenforcement.repository.LawEnfPenaltyStatRepository; +import com.aisino.iles.lawenforcement.repository.impl.StatisticCustomRepositoryImpl; +import com.smartlx.sso.client.model.RemoteUserInfo; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * 执法处罚统计服务类 + */ +@Service +public class LawEnfPenaltyStatService { + + private final LawEnfPenaltyStatRepository lawEnfPenaltyStatRepository; + private final AgencyRepository agencyRepo; + private final StatisticCustomRepositoryImpl customRepository; + + public LawEnfPenaltyStatService(LawEnfPenaltyStatRepository lawEnfPenaltyStatRepository,AgencyRepository agencyRepo,StatisticCustomRepositoryImpl customRepository) { + this.lawEnfPenaltyStatRepository = lawEnfPenaltyStatRepository; + this.agencyRepo = agencyRepo; + this.customRepository = customRepository; + } + + /** + * 查询执法处罚统计列表 + * + * @param lawEnfPenaltyStatQuery + * @return 执法处罚统计列表 + */ + public List> getLawEnfPenaltyStat(LawEnfPenaltyStatQuery lawEnfPenaltyStatQuery, RemoteUserInfo user) { + Agency currentAgency = agencyRepo.findByAgencyCode(user.getGajgjgdm()).orElseThrow(() -> new RuntimeException("当前用户机构数据错误,请检查!")); + LocalDateTime startTime = Optional.ofNullable(lawEnfPenaltyStatQuery.getStatisticsTime()).map(list -> list[0]).orElse(LocalDateTime.now().minusMonths(1)); + LocalDateTime endTime = Optional.ofNullable(lawEnfPenaltyStatQuery.getStatisticsTime()).map(list -> list[1]).orElse(LocalDateTime.now()); + if(currentAgency.getAgencyLevel()==2) + return lawEnfPenaltyStatRepository.getLawEnfPenaltyStat(startTime, endTime); + else + return lawEnfPenaltyStatRepository.getLawEnfPenaltyStatByDistrict(currentAgency.getAgencyCode(), startTime, endTime); + } + + @Transactional(readOnly = true) + public Page getPagexccsDetail(LawEnfPenaltyStatQuery query, RemoteUserInfo user) { + LocalDateTime startTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[0]).orElse(LocalDateTime.now().minusMonths(1)); + LocalDateTime endTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[1]).orElse(LocalDateTime.now()); + return customRepository.fxczfXCDetail(query.page(), query.pageSize(), query.sort(), query.dir(), query.getAgencyCode(), startTime,endTime); + } + @Transactional(readOnly = true) + public Page getPagefxczffxwtDetail(LawEnfPenaltyStatQuery query, RemoteUserInfo user) { + LocalDateTime startTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[0]).orElse(LocalDateTime.now().minusMonths(1)); + LocalDateTime endTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[1]).orElse(LocalDateTime.now()); + return customRepository.fxczffxwtDetail(query.page(), query.pageSize(), query.sort(), query.dir(), query.getAgencyCode(), startTime,endTime); + } + @Transactional(readOnly = true) + public Page getPagefxczfjjwtDetail(LawEnfPenaltyStatQuery query, RemoteUserInfo user) { + LocalDateTime startTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[0]).orElse(LocalDateTime.now().minusMonths(1)); + LocalDateTime endTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[1]).orElse(LocalDateTime.now()); + return customRepository.fxczfjjwtDetail(query.page(), query.pageSize(), query.sort(), query.dir(), query.getAgencyCode(), startTime,endTime); + } + + @Transactional(readOnly = true) + public Page getPagefxczflasDetail(LawEnfPenaltyStatQuery query, RemoteUserInfo user) { + LocalDateTime startTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[0]).orElse(LocalDateTime.now().minusMonths(1)); + LocalDateTime endTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[1]).orElse(LocalDateTime.now()); + return customRepository.fxczflasDetail(query.page(), query.pageSize(), query.sort(), query.dir(), query.getAgencyCode(), startTime,endTime); + } + + @Transactional(readOnly = true) + public Page getPagefxczfcfsDetail(LawEnfPenaltyStatQuery query, RemoteUserInfo user) { + LocalDateTime startTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[0]).orElse(LocalDateTime.now().minusMonths(1)); + LocalDateTime endTime = Optional.ofNullable(query.getStatisticsTime()).map(list -> list[1]).orElse(LocalDateTime.now()); + return customRepository.fxczfcfsDetail(query.page(), query.pageSize(), query.sort(), query.dir(), query.getAgencyCode(), startTime,endTime); + } + + + + +} diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/LegalReviewService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/LegalReviewService.java new file mode 100644 index 0000000..9c0d0bf --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/LegalReviewService.java @@ -0,0 +1,220 @@ +package com.aisino.iles.lawenforcement.service; + +import com.aisino.iles.common.util.PageableHelper; +import com.aisino.iles.common.util.StringUtils; +import com.aisino.iles.core.exception.BusinessError; +import com.aisino.iles.core.repository.DictItemRepo; +import com.aisino.iles.lawenforcement.event.DataChangeAction; +import com.aisino.iles.lawenforcement.event.aop.PublishDataChange; +import com.aisino.iles.lawenforcement.model.*; +import com.aisino.iles.lawenforcement.model.dto.LegalReviewDto; +import com.aisino.iles.lawenforcement.model.enums.FlowNode; +import com.aisino.iles.lawenforcement.model.query.EnforcementInfoQuery; +import com.aisino.iles.lawenforcement.repository.*; +import jakarta.persistence.criteria.Predicate; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 法制审核及执法监督服务类 + */ +@Service +@Slf4j +public class LegalReviewService { + + private final EnforcementInfoRepository enforcementInfoRepository; + private final OfficerRepository officerRepository; + private final ExamineReportRepository examineReportRepository; + private final EnforceCheckRepository enforceCheckRepository; + private final CheckItemRepository checkItemRepository; + private final CaseRepository caseRepository; + private final DictItemRepo dictItemRepo; + + public LegalReviewService(EnforcementInfoRepository enforcementInfoRepository, + OfficerRepository officerRepository, + ExamineReportRepository examineReportRepository, + EnforceCheckRepository enforceCheckRepository, + CheckItemRepository checkItemRepository, + CaseRepository caseRepository, + DictItemRepo dictItemRepo) { + this.enforcementInfoRepository = enforcementInfoRepository; + this.officerRepository = officerRepository; + this.examineReportRepository = examineReportRepository; + this.enforceCheckRepository = enforceCheckRepository; + this.checkItemRepository = checkItemRepository; + this.caseRepository = caseRepository; + this.dictItemRepo = dictItemRepo; + } + + /** + * 分页查询执法信息 + * + * @param query@return 分页执法信息 + */ + @Transactional(readOnly = true) + public Page findEnforcementInfosPage(EnforcementInfoQuery query) { + return enforcementInfoRepository + .findAll(buildSpecification(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir())) + .map(this::handleResult); + } + + private Specification buildSpecification(EnforcementInfoQuery query) { + return Specification.where((root, criteriaQuery, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + List orPredicates = new ArrayList<>(); + orPredicates.add(criteriaBuilder.equal(root.get("currentNodeCode"), FlowNode.analyze_judge)); + orPredicates.add(criteriaBuilder.equal(root.get("currentNodeCode"), FlowNode.reviewing_failed)); + predicates.add(criteriaBuilder.or(orPredicates.toArray(new Predicate[0]))); + Optional.ofNullable(query.getAgencyCode()).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get("agency").get("agencyCode"), StringUtils.trimEven0(o) + "%"))); + Optional.ofNullable(query.getUnitName()).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get("enterprise").get("unitName"), "%" + o + "%"))); + Optional.ofNullable(query.getCurrentNodeCode()).filter(StringUtils::isNotEmpty).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get(EnforcementInfo_.currentNodeCode), FlowNode.fromString(o)))); + Optional.ofNullable(query.getStartTime()).ifPresent(o -> predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), o))); + Optional.ofNullable(query.getEndTime()).ifPresent(o -> predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), o))); + return criteriaBuilder.and(predicates.toArray(new Predicate[0])); + }); + } + + private EnforcementInfo handleResult(EnforcementInfo enforcementInfoDto) { + Optional.ofNullable(enforcementInfoDto.getEnterprise()).ifPresent(enterprise -> enterprise.getUnitName()); + Optional.ofNullable(enforcementInfoDto.getAgency()).ifPresent(agency -> agency.getAgencyName()); + return enforcementInfoDto; + } + + /** + * 根据ID查询执法信息 + * + * @param enforcementId 执法信息ID + * @return 执法信息 + */ + @Transactional(readOnly = true) + public Optional findEnforcementInfoById(String enforcementId) { + return enforcementInfoRepository.findById(enforcementId).map(enforcementInfo -> { + // 机构信息 + Optional.ofNullable(enforcementInfo.getAgency()).ifPresent(agency -> agency.getAgencyName()); + // 企业信息 + Optional.ofNullable(enforcementInfo.getEnterprise()).ifPresent(enterprise -> enterprise.getUnitName()); + // 检查记录信息 + List enforceChecks = enforceCheckRepository.findByEnforcementId(enforcementInfo.getEnforcementId()); + enforceChecks.forEach(enforceCheck -> { + String officerIds = enforceCheck.getOfficerIds(); + if (StringUtils.isNotEmpty(officerIds)) { + List officerList = new ArrayList<>(); + Arrays.stream(officerIds.split(",")).forEach(id -> officerRepository.findById(id).ifPresent(officerList::add)); + enforceCheck.setOfficerList(officerList); + } + String checkStatusMsg = "1".equals(enforceCheck.getCheckStatus()) ? "待检查" : "已检查"; + enforceCheck.setCheckStatusMsg(checkStatusMsg); + dictItemRepo.findByDictDictCodeAndValue("dm_cljg", enforceCheck.getCheckResult()).ifPresent(o -> enforceCheck.setCheckResultMsg(o.getDisplay())); + }); + // 排序 + enforceChecks.stream().sorted((a, b) -> b.getCreateTime().compareTo(a.getCreateTime())).collect(Collectors.toList()); + enforcementInfo.setEnforceChecks(enforceChecks); + // 检查项信息 + if (enforceChecks.size() > 0 && StringUtils.isNotEmpty(enforceChecks.get(0).getCheckItemIds())) { + enforcementInfo.setCheckItems(checkItemRepository.findByItemIdIn(enforceChecks.get(0).getCheckItemIds().split(","))); + } + return enforcementInfo; + }); + } + + /** + * 根据ID查询执法信息 + * + * @param enforcementId 执法信息ID + * @return 执法信息 + */ + @Transactional(readOnly = true) + public Optional findLegalReviewInfoById(String enforcementId) { + return enforcementInfoRepository.findById(enforcementId).map(enforcementInfo -> { + // 机构信息 + Optional.ofNullable(enforcementInfo.getAgency()).ifPresent(agency -> agency.getAgencyName()); + // 案件信息 + caseRepository.findByEnforcementInfoEnforcementId(enforcementInfo.getEnforcementId()).ifPresent(caseInfo -> enforcementInfo.setCaseInfo(caseInfo)); + // 检查记录信息 + List enforceChecks = enforceCheckRepository.findByEnforcementId(enforcementInfo.getEnforcementId()); + enforceChecks.forEach(enforceCheck -> { + String officerIds = enforceCheck.getOfficerIds(); + if (StringUtils.isNotEmpty(officerIds)) { + List officerList = new ArrayList<>(); + Arrays.stream(officerIds.split(",")).forEach(id -> officerRepository.findById(id).ifPresent(officerList::add)); + enforceCheck.setOfficerList(officerList); + } + String checkStatusMsg = "1".equals(enforceCheck.getCheckStatus()) ? "待检查" : "已检查"; + enforceCheck.setCheckStatusMsg(checkStatusMsg); + dictItemRepo.findByDictDictCodeAndValue("dm_cljg", enforceCheck.getCheckResult()).ifPresent(o -> enforceCheck.setCheckResultMsg(o.getDisplay())); + }); + // 排序 + enforceChecks.stream().sorted((a, b) -> b.getCreateTime().compareTo(a.getCreateTime())).collect(Collectors.toList()); + enforcementInfo.setEnforceChecks(enforceChecks); + // 检查项信息 + if (enforceChecks.size() > 0 && StringUtils.isNotEmpty(enforceChecks.get(0).getCheckItemIds())) + enforcementInfo.setCheckItems(checkItemRepository.findByItemIdIn(enforceChecks.get(0).getCheckItemIds().split(","))); + return enforcementInfo; + }); + } + + /** + * 法治审核信息 + * + * @param legalReviewDto 法治审核信息 + * @return 更新后的执法信息 + */ + @Transactional + @PublishDataChange(action = DataChangeAction.SAVE) + public EnforcementInfo saveLegalReviewInfo(LegalReviewDto legalReviewDto) { + EnforcementInfo enforcementInfo = enforcementInfoRepository.findById(legalReviewDto.getEnforcementId()) + .orElseThrow(() -> new BusinessError("未找到指定的执法信息:" + legalReviewDto.getEnforcementId())); + + if ("1".equals(legalReviewDto.getIsRegister()) ) { + enforcementInfo.setCurrentNodeCode(FlowNode.reviewing_done); + enforcementInfo.setCurrentNode("法治审核完成"); + enforcementInfo.setAuditType(legalReviewDto.getAuditType()); + } else { + enforcementInfo.setCurrentNodeCode(FlowNode.reviewing_failed); + enforcementInfo.setCurrentNode("法治审核未通过"); + } + enforcementInfo.setAuditComment(legalReviewDto.getAuditComment()); + enforcementInfo.setAuditAgencyName(legalReviewDto.getAuditAgencyName()); + enforcementInfo.setAuditAgencyCode(legalReviewDto.getAuditAgencyCode()); + enforcementInfo.setAuditUserId(legalReviewDto.getAuditUserId()); + enforcementInfo.setAuditUserName(legalReviewDto.getAuditUserName()); + enforcementInfo.setAuditTime(legalReviewDto.getAuditTime()); + + // AOP切面会拦截此返回值并发布事件 + return enforcementInfo; + } + + /** + * 保存调查报告 + * + * @param examineReport 调查报告 + * @return 保存后的执法信息 + */ + @Transactional + public ExamineReport saveEnforcementInfo(ExamineReport examineReport) { + Optional optionalEnforcementInfo = enforcementInfoRepository.findById(examineReport.getEnforcementId()); + if (optionalEnforcementInfo.isPresent()) { + EnforcementInfo enforcementInfo = optionalEnforcementInfo.get(); + examineReport.setEnforcementId(enforcementInfo.getEnforcementId()); + //examineReport.setUserId(enforcementInfo); + examineReport.setExamineReportTime(LocalDateTime.now()); + examineReportRepository.save(examineReport); + enforcementInfo.setExamineReport(examineReport); + enforcementInfoRepository.save(enforcementInfo); + return examineReport; + } else { + throw new BusinessError("无查询结果不能导出"); + } + } + +} diff --git a/server/src/main/java/com/aisino/iles/lawenforcement/service/MessageService.java b/server/src/main/java/com/aisino/iles/lawenforcement/service/MessageService.java new file mode 100644 index 0000000..4f355c2 --- /dev/null +++ b/server/src/main/java/com/aisino/iles/lawenforcement/service/MessageService.java @@ -0,0 +1,241 @@ +package com.aisino.iles.lawenforcement.service; + +import com.aisino.iles.core.exception.BusinessError; +import com.aisino.iles.lawenforcement.model.Message; +import com.aisino.iles.lawenforcement.model.Message.MessageStatus; +import com.aisino.iles.lawenforcement.model.MessageReceiver; +import com.aisino.iles.lawenforcement.model.dto.message.MessageDto.MessageCountResponse; +import com.aisino.iles.lawenforcement.model.dto.message.MessageDto.MessageResponse; +import com.aisino.iles.lawenforcement.model.dto.message.MessageDto.SendMessageRequest; +import com.aisino.iles.lawenforcement.repository.MessageReceiverRepository; +import com.aisino.iles.lawenforcement.repository.MessageRepository; +import com.smartlx.sso.client.model.RemoteUserInfo; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +/** + * 消息服务 + * 提供消息的发送、查询、状态更新等功能 + */ +@Service +@Slf4j +@RequiredArgsConstructor +public class MessageService { + + private final MessageRepository messageRepository; + private final MessageReceiverRepository messageReceiverRepository; + + /** + * 发送消息 + * + * @param request 发送消息请求 + * @param user 当前用户 + * @return 消息ID + */ + @Transactional + public String sendMessage(SendMessageRequest request, RemoteUserInfo user) { + // 获取当前用户ID + String currentUserId = user.getYhwybs(); + + // 检查是否存在相同业务键的消息(用于去重) + if (request.getBusinessKey() != null && !request.getBusinessKey().isEmpty()) { + Optional existingMessage = messageRepository.findByBusinessKey(request.getBusinessKey()); + if (existingMessage.isPresent()) { + log.info("消息已存在,业务键: {}", request.getBusinessKey()); + return existingMessage.get().getId(); + } + } + + // 创建新消息 + Message message = new Message(); + message.setTitle(request.getTitle()); + message.setContent(request.getContent()); + message.setSenderId(currentUserId); + message.setRouteUrl(request.getRouteUrl()); + message.setRouteParams(request.getRouteParams()); + message.setBusinessKey(request.getBusinessKey()); + + // 添加接收者 + for (String receiverId : request.getReceiverIds()) { + message.addReceiver(receiverId); + } + + // 保存消息 + messageRepository.save(message); + log.info("消息发送成功,ID: {}, 接收者数量: {}", message.getId(), request.getReceiverIds().size()); + + return message.getId(); + } + + /** + * 获取当前用户的消息列表 + * + * @param status 消息状态过滤(可选) + * @param pageable 分页参数 + * @param user 当前用户 + * @return 消息列表(分页) + */ + @Transactional(readOnly = true) + public Page getUserMessages(MessageStatus status, Pageable pageable, RemoteUserInfo user) { + String currentUserId = user.getYhwybs(); + + Page receivers; + if (status != null) { + // 如果指定了状态,则按该状态查询 + receivers = messageReceiverRepository.findByReceiverIdAndStatusIn( + currentUserId, Arrays.asList(status), pageable); + } else { + // 否则,查询所有未删除的消息(未读和已读) + receivers = messageReceiverRepository.findByReceiverIdAndStatusIn( + currentUserId, Arrays.asList(MessageStatus.UNREAD, MessageStatus.READ), pageable); + } + + return receivers.map(messageReceiver -> { + messageReceiver.setUser(user); + return convertToMessageResponse(messageReceiver); + }); + } + + /** + * 获取消息详情 + * + * @param messageId 消息ID + * @param user 当前用户 + * @return 消息详情 + * @throws BusinessError 如果消息不存在或当前用户无权访问 + */ + @Transactional(readOnly = true) + public MessageResponse getMessageById(String messageId, RemoteUserInfo user) { + String currentUserId = user.getYhwybs(); + + MessageReceiver receiver = messageReceiverRepository.findByReceiverIdAndMessageId(currentUserId, messageId) + .orElseThrow(() -> new BusinessError("消息不存在或无权访问")); + receiver.setUser(user); + return convertToMessageResponse(receiver); + } + + /** + * 更新消息状态 + * + * @param messageId 消息ID + * @param status 新状态 + * @param user 当前用户 + * @throws BusinessError 如果消息不存在或当前用户无权访问 + */ + @Transactional + public void updateMessageStatus(String messageId, MessageStatus status, RemoteUserInfo user) { + String currentUserId = user.getYhwybs(); + + MessageReceiver receiver = messageReceiverRepository.findByReceiverIdAndMessageId(currentUserId, messageId) + .orElseThrow(() -> new BusinessError("消息不存在或无权访问")); + + if (status == MessageStatus.READ) { + receiver.markAsRead(); + } else if (status == MessageStatus.DELETED) { + receiver.markAsDeleted(); + } + + messageReceiverRepository.save(receiver); + log.info("消息状态已更新,ID: {}, 新状态: {}", messageId, status); + } + + /** + * 删除消息(逻辑删除) + * + * @param messageId 消息ID + * @param user 当前用户 + * @throws RuntimeException 如果消息不存在或当前用户无权访问 + */ + @Transactional + public void deleteMessage(String messageId, RemoteUserInfo user) { + updateMessageStatus(messageId, MessageStatus.DELETED, user); + } + + /** + * 批量删除消息(逻辑删除) + * + * @param messageIds 消息ID列表 + * @param user 当前用户 + */ + @Transactional + public void deleteMessagesForCurrentUser(List messageIds, RemoteUserInfo user) { + String currentUserId = user.getYhwybs(); + List receivers = messageReceiverRepository.findByReceiverIdAndMessageIdIn(currentUserId, messageIds); + + if (receivers.isEmpty()) { + log.warn("没有找到任何属于用户 {} 的消息,消息ID: {}", currentUserId, messageIds); + return; + } + + for (MessageReceiver receiver : receivers) { + receiver.setStatus(MessageStatus.DELETED); + } + + messageReceiverRepository.saveAll(receivers); + log.info("用户 {} 成功删除了 {} 条消息", currentUserId, receivers.size()); + } + + /** + * 获取当前用户的未读消息数 + * + * @return 未读消息数量 + */ + @Transactional(readOnly = true) + public MessageCountResponse getUnreadMessageCount(RemoteUserInfo user) { + String currentUserId = user.getYhwybs(); + + long count = messageReceiverRepository.countByReceiverIdAndStatus(currentUserId, MessageStatus.UNREAD); + + MessageCountResponse response = new MessageCountResponse(); + response.setUnreadCount(count); + return response; + } + + /** + * 检查消息是否重复 + * + * @param businessKey 业务键 + * @return 是否存在相同业务键的消息 + */ + @Transactional(readOnly = true) + public boolean checkDuplicateMessage(String businessKey) { + if (businessKey == null || businessKey.isEmpty()) { + return false; + } + return messageRepository.existsByBusinessKey(businessKey); + } + + /** + * 将MessageReceiver转换为MessageResponse + * + * @param receiver 消息接收记录 + * @return 消息响应DTO + */ + private MessageResponse convertToMessageResponse(MessageReceiver receiver) { + Message message = receiver.getMessage(); + + MessageResponse response = new MessageResponse(); + response.setId(message.getId()); + response.setTitle(message.getTitle()); + response.setContent(message.getContent()); + response.setSenderId(message.getSenderId()); + response.setSenderName(receiver.getUser().getXm()); // 假设有方法获取用户名 + response.setSenderAgencyName(receiver.getUser().getGajgmc()); + response.setStatus(receiver.getStatus()); + response.setCreateTime(message.getCreateTime()); + response.setReadTime(receiver.getReadTime()); + response.setRouteUrl(message.getRouteUrl()); + response.setRouteParams(message.getRouteParams()); + + return response; + } + +}