新增大屏、案件信息、执法检查、数据同步等接口

This commit is contained in:
huxin02 2025-03-07 17:29:34 +08:00
parent 722fdab1f2
commit 8383232e5c
5 changed files with 2046 additions and 0 deletions

View File

@ -0,0 +1,764 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.common.util.PageableHelper;
import com.aisino.iles.lawenforcement.model.*;
import com.aisino.iles.lawenforcement.model.dto.BigScreenDto;
import com.aisino.iles.lawenforcement.model.query.CaseQuery;
import com.aisino.iles.lawenforcement.model.query.EnforceCheckQuery;
import com.aisino.iles.lawenforcement.model.query.EnforcementInfoQuery;
import com.aisino.iles.lawenforcement.model.query.OfficerQuery;
import com.aisino.iles.lawenforcement.repository.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.smartlx.sso.client.model.RemoteUserInfo;
import jakarta.persistence.criteria.Predicate;
import lombok.Data;
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 org.springframework.util.StringUtils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 执法一张图
*/
@Service
public class BigScreenService {
private final BigScreenRepository bigScreenRepository;
private final OnlinePatrolRepository onlinePatrolRepository;
private final EnterpriseRepository enterpriseRepository;
private final EnforcementInfoRepository enforcementInfoRepository;
private final EnforcementInfoService enforcementInfoService;
private final EnforceCheckRepository enforceCheckRepository;
private final OfficerRepository officerRepository;
private final CaseRepository caseRepository;
private final AutoEnforcementPlanRepository autoEnforcementPlanRepository;
private final SupervisionCheckRepository supervisionCheckRepository;
private final ReportCheckOperRepository reportCheckOperRepository;
public BigScreenService(BigScreenRepository bigScreenRepository,
OnlinePatrolRepository onlinePatrolRepository,
EnterpriseRepository enterpriseRepository,
EnforcementInfoRepository enforcementInfoRepository,
EnforcementInfoService enforcementInfoService,
EnforceCheckRepository enforceCheckRepository,
OfficerRepository officerRepository,
CaseRepository caseRepository,
AutoEnforcementPlanRepository autoEnforcementPlanRepository,
SupervisionCheckRepository supervisionCheckRepository,
ReportCheckOperRepository reportCheckOperRepository) {
this.bigScreenRepository = bigScreenRepository;
this.onlinePatrolRepository = onlinePatrolRepository;
this.enterpriseRepository = enterpriseRepository;
this.enforcementInfoRepository = enforcementInfoRepository;
this.enforcementInfoService = enforcementInfoService;
this.enforceCheckRepository = enforceCheckRepository;
this.officerRepository = officerRepository;
this.caseRepository = caseRepository;
this.autoEnforcementPlanRepository = autoEnforcementPlanRepository;
this.supervisionCheckRepository = supervisionCheckRepository;
this.reportCheckOperRepository = reportCheckOperRepository;
}
public Map<String, Long> getDataOverview() {
// Long qys = bigScreenRepository.getqys();
// Long ajs = bigScreenRepository.getajs();
Map<String, Long> res = new HashMap<>();
// res.put("qys", qys);
// res.put("ajs", ajs);
return res;
}
public Map<String, Long> getEnterpriseStatistics(RemoteUserInfo user) {
String agencyCode = com.aisino.iles.common.util.StringUtils.trimEven0(user.getGajgjgdm()) + "%";
Map<String, Long> res = new HashMap<>();
Long qys = bigScreenRepository.getqys(agencyCode);
res.put("qys", qys);
res.put("A", 0L);
res.put("B", 0L);
res.put("C", 0L);
res.put("D", 0L);
List<Map<String, Object>> list = bigScreenRepository.getqyfjfl(agencyCode);
// 1 A 2 B 3 C 4 D
list.stream().forEach(map -> {
Object categoryObj = map.get("business_category");
Object numObj = map.get("num");
if (categoryObj != null && numObj != null) {
try {
int category = Integer.parseInt(categoryObj.toString());
long num = Long.parseLong(numObj.toString());
String categoryLetter = switch (category) {
case 1 -> "A";
case 2 -> "B";
case 3 -> "C";
case 4 -> "D";
default -> " ";
};
if (categoryLetter.matches("[A-D]")) {
res.put(categoryLetter, res.get(categoryLetter) + num);
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
});
return res;
}
public Map<String, Long> getEnterpriseStatistics2(RemoteUserInfo user) {
String agencyCode = com.aisino.iles.common.util.StringUtils.trimEven0(user.getGajgjgdm()) + "%";
Long qys = bigScreenRepository.getqys(agencyCode);
List<Map<String, Object>> list = bigScreenRepository.getqyfjfl2(agencyCode);
Map<String, Long> res = new HashMap<>();
res.put("qys", qys);
res.put("wh", 0L);
res.put("gy", 0L);
res.put("sm", 0L);
res.put("jy", 0L);
res.put("ks", 0L);
res.put("qt", 0L);
list.stream().forEach(map -> {
Object categoryObj = map.get("industry_type");
Object numObj = map.get("num");
if (categoryObj != null && numObj != null) {
try {
int category = Integer.parseInt(categoryObj.toString());
long num = Long.parseLong(numObj.toString());
switch (category) {
case 1: // 矿山
res.put("ks", res.get("ks") + num);
break;
case 2: // 危险化学品生产
case 3: // 危险化学品经营仓储
case 4: // 危险化学品经营无仓储
res.put("wh", res.get("wh") + num);
break;
case 5: // 加油站
res.put("jy", res.get("jy") + num);
break;
case 6: // 工业企业
res.put("gy", res.get("gy") + num);
break;
case 7: // 商贸企业
res.put("sm", res.get("sm") + num);
break;
case 99: // 其他
res.put("qt", res.get("qt") + num);
break;
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
});
return res;
}
public List<Map<String, Object>> getZfjcs(BigScreenDto bigScreenDto) {
LocalDateTime startTime;
LocalDateTime endTime = LocalDateTime.now();
if ("1".equals(bigScreenDto.getTimeType())) {
startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
} else {
startTime = LocalDateTime.of(endTime.getYear(), Month.JANUARY, 1, 0, 0);
}
List<Map<String, Object>> res = bigScreenRepository.getzfjcs(startTime, endTime);
return res;
}
public Map<String, Long> getAjbl() {
Long ajzs = bigScreenRepository.getajzs();
Long ajcfs = bigScreenRepository.getajcfs();
Map<String, Long> res = new HashMap<>();
res.put("ajzs", ajzs);
res.put("ajcfs", ajcfs);
return res;
}
public List<Map<String, Object>> getZfxs() {
// {value: '1', label: '日常检查'},
// {value: '2', label: '专项检查'},
// {value: '3', label: '举报核查'},
// {value: '4', label: '随机抽查'},
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
List<Map<String, Object>> data = bigScreenRepository.getzfxs();
List<Map<String, Object>> res = list.stream()
.map(item -> data.stream()
.filter(map -> map.get("check_type") != null)
.filter(map -> item.equals(map.get("check_type").toString()))
.findFirst()
.orElseGet(() -> {
Map<String, Object> defaultMap = new HashMap<>();
defaultMap.put("check_type", item);
defaultMap.put("num", 0);
return defaultMap;
}))
.collect(Collectors.toList());
return res;
}
public List<Map<String, Object>> getZfxs2() {
List<Map<String, Object>> data = bigScreenRepository.getzdzfs();
Long zxjcs = bigScreenRepository.getzxjcs();
Long tsjbs = bigScreenRepository.gettsjbs();
List<String> checkTypes = Arrays.asList("1", "2");
List<Map<String, Object>> res = checkTypes.stream()
.map(checkType -> data.stream()
.filter(map -> checkType.equals(String.valueOf(map.get("check_type"))))
.findFirst()
.orElseGet(() -> {
Map<String, Object> defaultMap = new HashMap<>();
defaultMap.put("check_type", checkType);
defaultMap.put("num", 0);
return defaultMap;
})
)
.collect(Collectors.toList());
Map<String, Object> zxjcsEntry = new HashMap<>();
zxjcsEntry.put("check_type", "3");
zxjcsEntry.put("num", zxjcs);
res.add(zxjcsEntry);
Map<String, Object> tsjbsEntry = new HashMap<>();
tsjbsEntry.put("check_type", "4");
tsjbsEntry.put("num", tsjbs);
res.add(tsjbsEntry);
return res;
}
public List<Map<String, Object>> getAjly(RemoteUserInfo user) {
// {value: '1', label: '日常检查发现'}, 检查发现
// {value: '2', label: '机构监测报告'}, 行业部分移送
// {value: '3', label: '举报投诉'}, 举报核查
// {value: '4', label: '上级交办'}, 上级交办
// {value: '5', label: '下级情报'}, 下级报请
// {value: '6', label: '有关部门移送'}, 处室移送
// {value: '7', label: '其他'}, 其他
String agencyCode = com.aisino.iles.common.util.StringUtils.trimEven0(user.getGajgjgdm()) + "%";
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
List<Map<String, Object>> data = bigScreenRepository.getajly(agencyCode);
List<Map<String, Object>> res = list.stream()
.map(item -> data.stream()
.filter(map -> map.get("case_source_code") != null)
.filter(map -> item.equals(map.get("case_source_code").toString()))
.findFirst()
.orElseGet(() -> {
Map<String, Object> defaultMap = new HashMap<>();
defaultMap.put("case_source_code", item);
defaultMap.put("num", 0);
return defaultMap;
}))
.collect(Collectors.toList());
return res;
}
public List<Map<String, Object>> getJcajqs(BigScreenDto bigScreenDto) {
LocalDateTime startTime;
LocalDateTime endTime = LocalDateTime.now();
if ("1".equals(bigScreenDto.getTimeType())) {
LocalDate currentDate = LocalDate.now();
YearMonth yearMonth = YearMonth.from(currentDate).minusMonths(11);
startTime = LocalDateTime.of(yearMonth.getYear(), yearMonth.getMonthValue(), 1, 0, 0);
List<String> months = IntStream.range(0, 12)
.mapToObj(i -> endTime.minusMonths(i))
.sorted() // 按日期升序排序
.map(date -> date.format(DateTimeFormatter.ofPattern("yyyy-MM")))
.collect(Collectors.toList());
List<Map<String, Object>> jfjc = bigScreenRepository.getjfjcByMonth(startTime, endTime);
List<Map<String, Object>> sasl = bigScreenRepository.getsaslByMonth(startTime.toLocalDate(), endTime.toLocalDate());
// 处理数据
List<Map<String, Object>> res = months.stream()
.map(month -> {
Map<String, Object> jfjcMap = jfjc.stream().filter(data -> month.equals(data.get("createTime"))).findFirst().orElse(null);
Map<String, Object> saslMap = sasl.stream().filter(data -> month.equals(data.get("fillingDate"))).findFirst().orElse(null);
Map<String, Object> resultMap = new java.util.HashMap<>();
resultMap.put("date", month);
resultMap.put("jfjc", jfjcMap != null ? jfjcMap.get("num") : 0); // 默认值设为0
resultMap.put("sasl", saslMap != null ? saslMap.get("num") : 0); // 默认值设为0
return resultMap;
})
.collect(Collectors.toList());
return res;
} else {
LocalDate currentDate = LocalDate.now();
YearMonth yearMonth = YearMonth.from(currentDate).minusYears(4);
startTime = LocalDateTime.of(yearMonth.getYear(), 1, 1, 0, 0);
List<String> years = IntStream.range(0, 5)
.mapToObj(i -> endTime.minusYears(i))
.sorted() // 按日期升序排序
.map(date -> date.format(DateTimeFormatter.ofPattern("yyyy")))
.collect(Collectors.toList());
List<Map<String, Object>> jfjc = bigScreenRepository.getjfjcByYear(startTime, endTime);
List<Map<String, Object>> sasl = bigScreenRepository.getsaslByYear(startTime.toLocalDate(), endTime.toLocalDate());
// 处理数据
List<Map<String, Object>> res = years.stream()
.map(year -> {
Map<String, Object> jfjcMap = jfjc.stream().filter(data -> year.equals(data.get("createTime"))).findFirst().orElse(null);
Map<String, Object> saslMap = sasl.stream().filter(data -> year.equals(data.get("fillingDate"))).findFirst().orElse(null);
Map<String, Object> resultMap = new java.util.HashMap<>();
resultMap.put("date", year);
resultMap.put("jfjc", jfjcMap != null ? jfjcMap.get("num") : 0); // 默认值设为0
resultMap.put("sasl", saslMap != null ? saslMap.get("num") : 0); // 默认值设为0
return resultMap;
})
.collect(Collectors.toList());
return res;
}
}
public List<Map<String, Object>> getJctj(BigScreenDto bigScreenDto) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = LocalDateTime.of(endTime.getYear(), Month.JANUARY, 1, 0, 0);
List<Map<String, Object>> res = bigScreenRepository.getjctj(startTime, endTime);
return res;
}
public List<Map<String, Object>> getAjtj(BigScreenDto bigScreenDto) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = LocalDateTime.of(endTime.getYear(), Month.JANUARY, 1, 0, 0);
List<Map<String, Object>> res = bigScreenRepository.getajtj(startTime, endTime);
return res;
}
public List<Map<String, Object>> getCfjetj(BigScreenDto bigScreenDto) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = LocalDateTime.of(endTime.getYear(), Month.JANUARY, 1, 0, 0);
List<Map<String, Object>> res = bigScreenRepository.getcfjetj(startTime, endTime);
return res;
}
public List<Map<String, Object>> getRwwj(BigScreenDto bigScreenDto) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = LocalDateTime.of(endTime.getYear(), Month.JANUARY, 1, 0, 0);
List<Map<String, Object>> res = bigScreenRepository.getrwwj(startTime, endTime);
return res;
}
public List<Map<String, Object>> getFxczftj(String type) {
LocalDate currentDate = LocalDate.now();
if ("1".equals(type)) {
// 按月统计最近12个月
LocalDateTime startTime = currentDate.minusMonths(11).atStartOfDay();
LocalDateTime endTime = LocalDateTime.now();
List<String> months = IntStream.rangeClosed(0, 11)
.mapToObj(i -> YearMonth.now().minusMonths(i).format(DateTimeFormatter.ofPattern("yyyy-MM")))
.sorted()
.collect(Collectors.toList());
List<Map<String, Object>> fxczf = Optional.ofNullable(
onlinePatrolRepository.getfxczfByMonth(startTime, endTime)
).orElse(Collections.emptyList());
Map<String, Map<String, Object>> fxczfMap = fxczf.stream()
.collect(Collectors.toMap(
data -> (String) data.get("createTime"),
data -> data,
(existing, replacement) -> existing
));
return months.stream()
.map(month -> {
Map<String, Object> data = fxczfMap.getOrDefault(month, Collections.emptyMap());
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("date", month);
resultMap.put("zxxcs", data.getOrDefault("zxxcs", 0));
resultMap.put("wfwgs", data.getOrDefault("wfwgs", 0));
return resultMap;
})
.collect(Collectors.toList());
} else if ("2".equals(type)) {
// 按年统计最近6年
int startYear = currentDate.getYear() - 6;
LocalDateTime startTime = LocalDateTime.of(startYear, 1, 1, 0, 0);
LocalDateTime endTime = LocalDateTime.now();
List<Integer> years = IntStream.rangeClosed(startYear, currentDate.getYear())
.boxed()
.collect(Collectors.toList());
List<Map<String, Object>> fxczf = Optional.ofNullable(
onlinePatrolRepository.getfxczfByYear(startTime, endTime)
).orElse(Collections.emptyList());
Map<String, Map<String, Object>> fxczfMap = fxczf.stream()
.collect(Collectors.toMap(
data -> (String) data.get("createTime"),
data -> data,
(existing, replacement) -> existing
));
return years.stream()
.map(year -> {
String yearStr = String.valueOf(year);
Map<String, Object> data = fxczfMap.getOrDefault(yearStr, Collections.emptyMap());
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("date", yearStr);
resultMap.put("zxxcs", data.getOrDefault("zxxcs", 0));
resultMap.put("wfwgs", data.getOrDefault("wfwgs", 0));
return resultMap;
})
.collect(Collectors.toList());
}
return Collections.emptyList(); // 默认返回空列表
}
public List<Map<String, Object>> getJdjcjhtj() {
List<Map<String, Object>> res = bigScreenRepository.getjdjcjh();
return res;
}
public List<Enterprise> findEnterprisesByBusinessRating(String businessRating) {
List<Enterprise> list = enterpriseRepository.findAll(buildSpecification(businessRating));
return list;
}
/**
* 构建查询条件
*
* @param businessRating 查询条件
* @return 规格
*/
private Specification<Enterprise> buildSpecification(String businessRating) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
root.join(Enterprise_.agency);
if (StringUtils.hasText(businessRating)) {
predicates.add(root.get(Enterprise_.businessRating).in(Arrays.asList(businessRating)));
}
predicates.add(root.get(Enterprise_.longitude).isNotNull());
predicates.add(root.get(Enterprise_.latitude).isNotNull());
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
public List<EnforcementInfo> findEnforcementInfoByEnterpriseId(String enterpriseId) {
List<EnforcementInfo> list = new ArrayList<>();
enforcementInfoRepository
.findByEnterpriseIdAndCreateTimeBetween(enterpriseId, LocalDateTime.now().minusYears(1), LocalDateTime.now())
.stream()
.forEach(item -> enforcementInfoService.findEnforcementInfoById(item.getEnforcementId()).ifPresent(enforcementInfo -> list.add(enforcementInfo)));
return list;
}
public Long getZfdxsl() {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
return bigScreenRepository.getZfdxsl(startTime, endTime);
}
public Page<EnforcementInfo> getZfdxslfy(EnforcementInfoQuery query) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
return enforcementInfoRepository.findAll(buildSpec(startTime, startTime), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir()));
}
/**
* 构建查询条件
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return
*/
private Specification<EnforcementInfo> buildSpec(LocalDateTime startTime, LocalDateTime endTime) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get(EnforcementInfo_.createTime), startTime));
predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get(EnforcementInfo_.createTime), endTime));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
public Long getZfrysl() {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
List<String> list = enforceCheckRepository.getZfrysl(startTime, endTime);
long num = list.parallelStream()
.filter(Objects::nonNull)
.flatMap(item -> Arrays.stream(item.split(",")))
.map(String::trim)
.filter(part -> !part.isEmpty())
.distinct()
.count();
return num;
}
public Page<Officer> getZfryslfy(OfficerQuery query) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
List<String> list = enforceCheckRepository.getZfrysl(startTime, endTime);
List<String> ids = list.parallelStream()
.filter(Objects::nonNull)
.flatMap(item -> Arrays.stream(item.split(",")))
.map(String::trim)
.filter(part -> !part.isEmpty())
.distinct()
.collect(Collectors.toList());
return officerRepository.findAll(buildSpec2(ids), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir()));
}
private Specification<Officer> buildSpec2(List<String> ids) {
return Specification.where((root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(root.get(Officer_.officerId).in(ids));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
});
}
/**
* 获取检查数量
*
* @return 检查数量
*/
public Long checkCount() {
LocalDate endTime = LocalDate.now();
LocalDate startTime = endTime.withDayOfMonth(1);
return enforceCheckRepository.countByCheckDateBetween(startTime, endTime);
}
@Transactional(readOnly = true)
public Page<ZfjcDto> getzfjcslDetail(EnforceCheckQuery query) {
LocalDate endTime = LocalDate.now();
LocalDate startTime = endTime.withDayOfMonth(1);
query.setCheckDate(new LocalDate[]{startTime, endTime});
return enforceCheckRepository.findAll(buildCondiction(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir())).map(enforceCheck -> {
ZfjcDto zfjcDto = new ZfjcDto();
AtomicReference<String> officerName = new AtomicReference<>("");
zfjcDto.setCheckDate(enforceCheck.getCheckDate());
zfjcDto.setAgencyName(enforceCheck.getEnforcementInfo().getAgency().getAgencyName());
zfjcDto.setUnitName(enforceCheck.getEnforcementInfo().getEnterprise().getUnitName());
zfjcDto.setUnifiedSocialCode(enforceCheck.getEnforcementInfo().getEnterprise().getUnifiedSocialCode());
Arrays.stream(enforceCheck.getOfficerIds().split(",")).forEach(id -> officerRepository.findById(id).ifPresent(officer -> officerName.set(officerName.get() + officer + ",")));
zfjcDto.setOfficers(officerName.get());
return zfjcDto;
});
}
private Specification<EnforceCheck> buildCondiction(EnforceCheckQuery query) {
return Specification.where((root, q, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
Optional.ofNullable(query.getCheckDate()).filter(f -> f.length == 2).map(f -> {
List<Predicate> timePredicates = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get(EnforceCheck_.checkDate), from)).ifPresent(timePredicates::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get(EnforceCheck_.checkDate), to)).ifPresent(timePredicates::add);
return timePredicates;
}).ifPresent(predicates::addAll);
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
});
}
/**
* 查询当月事故单位报告公众举报下级部门报告媒体舆情监测其他部分移送数量
*
* @return 统计结果
*/
public DytjDto dytjs() {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
List<BigScreenDto> dtos = bigScreenRepository.getajly(startTime, endTime);
DytjDto stats = new DytjDto();
dtos.stream().filter(dto -> "1".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setRcjdfxs(dto.getNum()), () -> stats.setRcjdfxs(0L));
dtos.stream().filter(dto -> "2".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setJgjcbgs(dto.getNum()), () -> stats.setJgjcbgs(0L));
dtos.stream().filter(dto -> "3".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setJbtss(dto.getNum()), () -> stats.setJbtss(0L));
dtos.stream().filter(dto -> "4".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setSjjbs(dto.getNum()), () -> stats.setSjjbs(0L));
dtos.stream().filter(dto -> "5".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setXjqbs(dto.getNum()), () -> stats.setXjqbs(0L));
dtos.stream().filter(dto -> "6".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setYgbmyss(dto.getNum()), () -> stats.setYgbmyss(0L));
dtos.stream().filter(dto -> "7".equals(dto.getCode())).findFirst().ifPresentOrElse(dto -> stats.setQts(dto.getNum()), () -> stats.setQts(0L));
return stats;
}
@Transactional(readOnly = true)
public Page<DytjsDto> getdytjDetail(CaseQuery query) {
LocalDateTime endTime = LocalDateTime.now();
LocalDateTime startTime = endTime.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
query.setSupplementVerifyTime(new LocalDateTime[]{startTime, endTime});
return caseRepository.findAll(buildQuery(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), query.sort(), query.dir())).map(c -> {
DytjsDto dto = new DytjsDto();
dto.setAgencyName(c.getEnforcementInfo().getAgency().getAgencyName());
dto.setUnitName(c.getEnforcementInfo().getEnterprise().getUnitName());
dto.setUnifiedSocialCode(c.getEnforcementInfo().getEnterprise().getUnifiedSocialCode());
dto.setCreatedTime(c.getCreatedTime());
return dto;
});
}
private Specification<Case> buildQuery(CaseQuery query) {
return Specification.where((root, q, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
Optional.ofNullable(query.getConditionlike()).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get(Case_.caseSourceCode), o)));
Optional.ofNullable(query.getSupplementVerifyTime()).filter(f -> f.length == 2).map(f -> {
List<Predicate> timePredicates = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get(Case_.createdTime), from)).ifPresent(timePredicates::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get(Case_.createdTime), to)).ifPresent(timePredicates::add);
return timePredicates;
}).ifPresent(predicates::addAll);
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
});
}
@Data
public static class DytjDto {
/**
* 日常检查发现
*/
private Long rcjdfxs;
/**
* 机构监测报告
*/
private Long jgjcbgs;
/**
* 举报投诉
*/
private Long jbtss;
/**
* 上级交办
*/
private Long sjjbs;
/**
* 下级情报
*/
private Long xjqbs;
/**
* 有关部门移送
*/
private Long ygbmyss;
/**
* 其他
*/
private Long qts;
}
@Data
public static class ZfjcDto {
/**
* 企业名称
*/
private String unitName;
/**
* 统一社会信用代码
*/
private String unifiedSocialCode;
/**
* 立案日期
*/
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate checkDate;
/**
* 机构名称
*/
private String agencyName;
private String officers;
}
@Data
public static class DytjsDto {
/**
* 企业名称
*/
private String unitName;
/**
* 统一社会信用代码
*/
private String unifiedSocialCode;
/**
* 录入时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createdTime;
/**
* 机构名称
*/
private String agencyName;
}
public List<Map<String, Object>> rwwctj() {
List<Map<String, Object>> res = new ArrayList<>();
// 用数组常量替代HashMap减少集合初始化开销
String[][] typeConfigs = {
{"5", "zxjcs", "zxjcwcs", "wcl"}, // 专项检查督导检查
{"6", "jbtss", "jbtswcs", "wcl"}, // 投诉举报交叉互查
{"7", "zdqyjcs", "zdqyjcwcs", "wcl"}, // 重点企业检查
{"8", "ssjjcs", "ssjjcwcs", "wcl"} // 双随机检查
};
bigScreenRepository.rwwctj().forEach(originalMap -> {
String checktype = originalMap.get("checktype").toString();
for (String[] config : typeConfigs) {
if (config[0].equals(checktype)) {
res.add(processMap(originalMap, config[1], config[2], config[3]));
break;
}
}
});
return res;
}
/**
* 处理Map设置任务名称并计算完成率
*/
private Map<String, Object> processMap(Map<String, Object> originalMap, String totalKey, String wcsKey, String rateKey) {
Map<String, Object> item = new HashMap<>();
String checktype = originalMap.get("checktype").toString();
String planid = originalMap.get("planid").toString();
String taskName = switch (checktype) {
case "5" -> supervisionCheckRepository.findById(planid)
.map(SupervisionCheck::getCheckType)
.orElse("未知任务");
case "6" -> reportCheckOperRepository.findById(planid)
.map(ReportCheckOper::getOperType)
.orElse("未知任务");
case "7", "8" -> autoEnforcementPlanRepository.findById(planid)
.map(AutoEnforcementPlan::getTaskName)
.orElse("未知任务");
default -> "未知任务";
};
item.put("taskName", taskName);
try {
long total = parseLong(originalMap.get(totalKey));
long wcs = parseLong(originalMap.get(wcsKey));
item.put("sum", total);
item.put("wcs", wcs);
item.put(rateKey, total == 0 ? 0 : Math.round((double) wcs / total * 10000) / 100.0);
} catch (Exception e) {
item.put(rateKey, 0);
}
return item;
}
private long parseLong(Object obj) {
if (obj == null) return 0;
if (obj instanceof Number num) return num.longValue();
try {
return Long.parseLong(obj.toString().trim());
} catch (NumberFormatException e) {
return 0;
}
}
}

View File

@ -0,0 +1,840 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.common.model.enums.IndustryCategoryForFile;
import com.aisino.iles.common.service.FtpService;
import com.aisino.iles.common.util.Constants;
import com.aisino.iles.common.util.PageableHelper;
import com.aisino.iles.common.util.PdfMerger;
import com.aisino.iles.core.exception.BusinessError;
import com.aisino.iles.core.service.GenerateCodeService;
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.FormDataDto;
import com.aisino.iles.lawenforcement.model.enums.FlowNode;
import com.aisino.iles.lawenforcement.model.query.CaseQuery;
import com.aisino.iles.lawenforcement.repository.AgencyRepository;
import com.aisino.iles.lawenforcement.repository.CaseRepository;
import com.aisino.iles.lawenforcement.repository.DocumentRepository;
import com.aisino.iles.lawenforcement.repository.EnforcementInfoRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.apache.pdfbox.pdmodel.PDDocument;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.file.Files;
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 static com.aisino.iles.common.util.PdfMerger.mergePDFsWithPageNumbers;
@Service
@Slf4j
public class CaseService {
private final CaseRepository caseRepository;
private final EnforcementInfoRepository enforcementInfoRepository;
private final DocumentRepository documentRepository;
private final ObjectMapper objectMapper;
private final FtpService ftpService;
private final GenerateCodeService generateCodeService;
private final EnforceCheckService enforceCheckService;
private final AgencyRepository agencyRepo;
public CaseService(CaseRepository caseRepository,
EnforcementInfoRepository enforcementInfoRepository,
DocumentRepository documentRepository,
ObjectMapper objectMapper,
FtpService ftpService,
GenerateCodeService generateCodeService,
EnforceCheckService enforceCheckService, AgencyRepository agencyRepo) {
this.caseRepository = caseRepository;
this.enforcementInfoRepository = enforcementInfoRepository;
this.documentRepository = documentRepository;
this.objectMapper = objectMapper;
this.ftpService = ftpService;
this.generateCodeService = generateCodeService;
this.enforceCheckService = enforceCheckService;
this.agencyRepo = agencyRepo;
}
/**
* 案件信息
*
* @param query@return 分页案件信息
*/
@Transactional(readOnly = true)
public Page<Case> findCasesPage(CaseQuery query, RemoteUserInfo user) {
if ("zfwsquery".equals(query.getSpecialCondition()))
return caseRepository.findAll(buildSpec(query, user), PageableHelper.buildPageRequest(query.page(), query.pageSize(), "fillingDate", "desc")).map(this::handleResult);
if (query.getStatus() != null && ("filed".equals(query.getStatus().getValue()) || "investigation_done".equals(query.getStatus().getValue())))
return caseRepository.findAll(buildSpec(query, user), PageableHelper.buildPageRequest(query.page(), query.pageSize(), "fillingDate", "desc")).map(this::getCaseevidenceDetailInfo);
else
return caseRepository.findAll(buildSpec(query, user), PageableHelper.buildPageRequest(query.page(), query.pageSize(), "fillingDate", "desc")).map(this::getCaseDetailInfo);
}
private Case handleResult(Case caseInfoDto) {
//文书管理显示完成度
int process = documentRepository.countByCaseIdAndStatus(caseInfoDto.getCaseId(), Document.DocumentStatus.done);
long persent = Math.round(((double) process / 31 * 100));
caseInfoDto.setDocumentCount(process);
caseInfoDto.setDocumentProgress(persent);
caseInfoDto.getEnforcementInfo().getAgency().getAgencyName();
caseInfoDto.getEnforcementInfo().getEnterprise().getUnitName();
caseInfoDto.setEnterprise(caseInfoDto.getEnforcementInfo().getEnterprise());
Optional.ofNullable(caseInfoDto.getFilePath()).filter(StringUtils::hasText).ifPresent(o -> caseInfoDto.setDownUrl(ftpService.getFileUrl(o)));
switch (caseInfoDto.getCaseSourceCode()) {
case "1" -> caseInfoDto.setCaseSourceCode("日常检查发现");
case "2" -> caseInfoDto.setCaseSourceCode("机构监测报告");
case "3" -> caseInfoDto.setCaseSourceCode("举报投诉");
case "4" -> caseInfoDto.setCaseSourceCode("上级交办");
case "5" -> caseInfoDto.setCaseSourceCode("下级情报");
case "6" -> caseInfoDto.setCaseSourceCode("有关部门移送");
case "7" -> caseInfoDto.setCaseSourceCode("其他");
}
switch (caseInfoDto.getCaseCause()) {
case "1" -> caseInfoDto.setCaseCause("安全生产行政许可类违法");
case "2" -> caseInfoDto.setCaseCause("安全生产管理机构和管理人员类违法");
case "3" -> caseInfoDto.setCaseCause("安全生产建设工程项目类违法");
case "4" -> caseInfoDto.setCaseCause("安全生产规章制度类违法");
case "5" -> caseInfoDto.setCaseCause("安全生产培训教育类违法");
case "6" -> caseInfoDto.setCaseCause("安全生产资金投入类违法");
case "7" -> caseInfoDto.setCaseCause("安全生产隐患管理类违法");
case "8" -> caseInfoDto.setCaseCause("生产安全事故应急救援类违法");
case "9" -> caseInfoDto.setCaseCause("安全生产承包租赁类违法");
case "10" -> caseInfoDto.setCaseCause("安全生产警示标志类违法");
case "11" -> caseInfoDto.setCaseCause("安全生产中介机构类违法");
case "12" -> caseInfoDto.setCaseCause("安全设备使用维护类违法");
case "13" -> caseInfoDto.setCaseCause("重大危险源管理类违法");
case "14" -> caseInfoDto.setCaseCause("生产经营单位作业现场管理类违法");
case "15" -> caseInfoDto.setCaseCause("生产安全事故报告类违法");
case "16" -> caseInfoDto.setCaseCause("生产安全事故责任类违法");
case "17" -> caseInfoDto.setCaseCause("其他");
}
return caseInfoDto;
}
private Specification<Case> buildSpec(CaseQuery query, RemoteUserInfo user) {
return Specification.where((root, q, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
Optional.ofNullable(query.getCaseName()).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get("caseName"), "%" + o + "%")));
Optional.ofNullable(query.getCaseNum()).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get("caseNum"), o)));
Optional.ofNullable(query.getArchivalNum()).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get("archivalNum"), o)));
Optional.ofNullable(query.getCaseStatus()).filter("simp"::equals).ifPresent(o -> {
CriteriaBuilder.In<Case.CaseStatus> in = criteriaBuilder.in(root.get(Case_.status));
in.value(Case.CaseStatus.closing);
in.value(Case.CaseStatus.archived);
predicates.add(in);
});
Join<Case, EnforcementInfo> enforcementInfoCaseRoot = root.join("enforcementInfo", JoinType.LEFT);
Optional.ofNullable(query.getStatus()).ifPresent(o -> {
//进入调查取证流程查询 已立案和取证中两种状态
if (FlowNode.filed.equals(query.getStatus())) {
CriteriaBuilder.In<FlowNode> nods = criteriaBuilder.in(enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode));
nods.value(FlowNode.filed);
nods.value(FlowNode.investigating);
predicates.add(nods);
} else if (FlowNode.reviewing_done.equals(query.getStatus())) {
// 查询立案后的所有状态案件
CriteriaBuilder.In<FlowNode> nods = criteriaBuilder.in(enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode));
nods.value(FlowNode.filed);
nods.value(FlowNode.investigating);
nods.value(FlowNode.investigation_done);
nods.value(FlowNode.analyze_judge);
nods.value(FlowNode.inform);
nods.value(FlowNode.hearing);
nods.value(FlowNode.decided);
nods.value(FlowNode.execute);
nods.value(FlowNode.done);
predicates.add(nods);
} else {
predicates.add(criteriaBuilder.equal((enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode)), o));
}
// else if (FlowNode.execute.equals(query.getStatus())) { // 到结案时查询执行及完成节点的信息
// CriteriaBuilder.In<FlowNode> nods = criteriaBuilder.in(enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode));
// nods.value(FlowNode.execute);
// nods.value(FlowNode.done);
// predicates.add(nods);
// }
});
Optional.ofNullable(query.getFillingDate()).filter(f -> f.length == 2).map(f -> {
List<Predicate> 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);
Optional.ofNullable(query.getCaseClosingDate()).filter(f -> f.length == 2).map(f -> {
List<Predicate> timePredicates = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get("caseClosingDate"), from)).ifPresent(timePredicates::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get("caseClosingDate"), to)).ifPresent(timePredicates::add);
return timePredicates;
}).ifPresent(predicates::addAll);
Optional.ofNullable(query.getArchiveDate()).filter(f -> f.length == 2).map(f -> {
List<Predicate> timePredicates = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get("archiveDate"), from)).ifPresent(timePredicates::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get("archiveDate"), to)).ifPresent(timePredicates::add);
return timePredicates;
}).ifPresent(predicates::addAll);
Optional.ofNullable(query.getConditionlike()).filter(StringUtils::hasText).ifPresent(o -> {
List<Predicate> orPredicates = new ArrayList<>();
Predicate p1 = criteriaBuilder.like(root.get(Case_.caseNum), "%" + o + "%");
orPredicates.add(criteriaBuilder.or(p1));
Predicate p2 = criteriaBuilder.like(root.get(Case_.caseName), "%" + o + "%");
orPredicates.add(criteriaBuilder.or(p2));
Predicate p3 = criteriaBuilder.like(root.get(Case_.caseCause), "%" + o + "%");
orPredicates.add(criteriaBuilder.or(p3));
Predicate p = criteriaBuilder.or(orPredicates.toArray(new Predicate[0]));
predicates.add(p);
});
Optional.ofNullable(query.getSupplementVerifyResult()).ifPresent(o -> {
// 填报内容查询
if ("tb".equals(o)) {
predicates.add(criteriaBuilder.or(
criteriaBuilder.notEqual(root.get("supplementVerifyResult"), "1"),
criteriaBuilder.isNull(root.get("supplementVerifyResult"))
));
}
//审批内容查询
else if ("sp".equals(o)) {
predicates.add(criteriaBuilder.equal(root.get("supplementVerifyResult"), "2"));
} else {
predicates.add(criteriaBuilder.equal(root.get("supplementVerifyResult"), o));
}
});
Optional.ofNullable(query.getSupplementVerifyTime()).filter(f -> f.length == 2).map(f -> {
List<Predicate> timePredicates = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get("supplementVerifyTime"), from)).ifPresent(timePredicates::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get("supplementVerifyTime"), to)).ifPresent(timePredicates::add);
return timePredicates;
}).ifPresent(predicates::addAll);
if (null != query.getCaseIds() && !query.getCaseIds().isEmpty()) {
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get(Case_.caseId));
query.getCaseIds().forEach(in::value);
predicates.add(in);
}
if ("decided".equals(query.getTag())) {
Predicate p1 = criteriaBuilder.equal(enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode), FlowNode.hearing);
Predicate p2 = criteriaBuilder.and(
criteriaBuilder.equal(enforcementInfoCaseRoot.get(EnforcementInfo_.currentNodeCode), FlowNode.inform),
criteriaBuilder.equal(root.get(Case_.sfsqtz), "0")
);
predicates.add(criteriaBuilder.or(p1, p2));
}
// 机构
Join<Case, Agency> agencyCaseRoot = root.join("agency", JoinType.LEFT);
if (StringUtils.hasText(query.getAgencyCode())) {
String code= com.aisino.iles.common.util.StringUtils.trimEven0(query.getAgencyCode()) + "%";
predicates.add(criteriaBuilder.like((agencyCaseRoot.get(Agency_.agencyCode)), code));
} else {
Agency currentAgency = agencyRepo.findByAgencyCode(user.getGajgjgdm()).orElseThrow(() -> new RuntimeException("当前用户机构数据错误,请检查!"));
String code= com.aisino.iles.common.util.StringUtils.trimEven0(currentAgency.getAgencyCode()) + "%";
predicates.add(criteriaBuilder.like((agencyCaseRoot.get(Agency_.agencyCode)), code));
}
if ("1".equals(query.getAjbjlx())) { // 案件已办结
CriteriaBuilder.In<Case.CaseStatus> in = criteriaBuilder.in(root.get(Case_.status));
in.value(Case.CaseStatus.closing);
in.value(Case.CaseStatus.archived);
predicates.add(in);
} else if ("2".equals(query.getAjbjlx())) { // 案件未办结
CriteriaBuilder.In<Case.CaseStatus> in = criteriaBuilder.in(root.get(Case_.status));
in.value(Case.CaseStatus.filed);
in.value(Case.CaseStatus.investigating);
in.value(Case.CaseStatus.investigation_done);
in.value(Case.CaseStatus.analyze_judge);
predicates.add(in);
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
});
}
/**
* 保存案件
*
* @param c 案件信息
* @return 保存后案件信息
*/
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public Case saveCase(Case c) {
// 生成案件号
String caseNum = generateCodeService.buildCode("xa", "case", null, 0);
c.setCaseNum(caseNum);
if (c.getArchiveDate() != null) {
// 归档
c.setStatus(Case.CaseStatus.archived);
}
return caseRepository.save(c);
}
@Transactional(readOnly = true)
public Optional<Case> findCaseById(String caseId) {
return caseRepository.findById(caseId).map(c -> {
//获取执法结构信息
c.getEnforcementInfo().getAgency().getAgencyName();
//获取企业信息
c.getEnforcementInfo().getEnterprise().getUnitName();
c.setEnterprise(c.getEnforcementInfo().getEnterprise());
//获取 执法检查信息
enforceCheckService.getEnforceCheckByEnforcementId(c.getEnforcementInfo().getEnforcementId()).ifPresent(check -> {
c.setEnforceCheck(check);
});
return c;
});
}
private Case getCaseevidenceDetailInfo(Case c) {
c.getEnforcementInfo().getAgency().getAgencyName();
c.getEnforcementInfo().getEnterprise().getUnitName();
c.setEnterprise(c.getEnforcementInfo().getEnterprise());
switch (c.getCaseSourceCode()) {
case "1" -> c.setCaseSourceCode("日常检查发现");
case "2" -> c.setCaseSourceCode("机构监测报告");
case "3" -> c.setCaseSourceCode("举报投诉");
case "4" -> c.setCaseSourceCode("上级交办");
case "5" -> c.setCaseSourceCode("下级情报");
case "6" -> c.setCaseSourceCode("有关部门移送");
case "7" -> c.setCaseSourceCode("其他");
}
switch (c.getCaseCause()) {
case "1" -> c.setCaseCause("安全生产行政许可类违法");
case "2" -> c.setCaseCause("安全生产管理机构和管理人员类违法");
case "3" -> c.setCaseCause("安全生产建设工程项目类违法");
case "4" -> c.setCaseCause("安全生产规章制度类违法");
case "5" -> c.setCaseCause("安全生产培训教育类违法");
case "6" -> c.setCaseCause("安全生产资金投入类违法");
case "7" -> c.setCaseCause("安全生产隐患管理类违法");
case "8" -> c.setCaseCause("生产安全事故应急救援类违法");
case "9" -> c.setCaseCause("安全生产承包租赁类违法");
case "10" -> c.setCaseCause("安全生产警示标志类违法");
case "11" -> c.setCaseCause("安全生产中介机构类违法");
case "12" -> c.setCaseCause("安全设备使用维护类违法");
case "13" -> c.setCaseCause("重大危险源管理类违法");
case "14" -> c.setCaseCause("生产经营单位作业现场管理类违法");
case "15" -> c.setCaseCause("生产安全事故报告类违法");
case "16" -> c.setCaseCause("生产安全事故责任类违法");
case "17" -> c.setCaseCause("其他");
}
Optional.ofNullable(c.getEvidence()).ifPresent(e -> {
Optional.ofNullable(e.get("filesData")).ifPresent(list -> {
List<Map<String, String>> files = (ArrayList) list;
files.forEach(f -> {
String savePathName = f.get("savePathName");
String url = ftpService.getFileUrl(savePathName);
String downloadUrl = ftpService.getFileUrl(savePathName);
f.put("url", url);
f.put("downloadUrl", downloadUrl);
});
});
});
return c;
}
private Case getCaseDetailInfo(Case c) {
c.getEnforcementInfo().getAgency().getAgencyName();
c.getEnforcementInfo().getEnterprise().getUnitName();
c.setEnterprise(c.getEnforcementInfo().getEnterprise());
Optional.ofNullable(c.getFilePath()).filter(StringUtils::hasText).ifPresent(o -> c.setDownUrl(ftpService.getFileUrl(o)));
switch (c.getCaseSourceCode()) {
case "1" -> c.setCaseSourceCode("日常检查发现");
case "2" -> c.setCaseSourceCode("机构监测报告");
case "3" -> c.setCaseSourceCode("举报投诉");
case "4" -> c.setCaseSourceCode("上级交办");
case "5" -> c.setCaseSourceCode("下级情报");
case "6" -> c.setCaseSourceCode("有关部门移送");
case "7" -> c.setCaseSourceCode("其他");
}
switch (c.getCaseCause()) {
case "1" -> c.setCaseCause("安全生产行政许可类违法");
case "2" -> c.setCaseCause("安全生产管理机构和管理人员类违法");
case "3" -> c.setCaseCause("安全生产建设工程项目类违法");
case "4" -> c.setCaseCause("安全生产规章制度类违法");
case "5" -> c.setCaseCause("安全生产培训教育类违法");
case "6" -> c.setCaseCause("安全生产资金投入类违法");
case "7" -> c.setCaseCause("安全生产隐患管理类违法");
case "8" -> c.setCaseCause("生产安全事故应急救援类违法");
case "9" -> c.setCaseCause("安全生产承包租赁类违法");
case "10" -> c.setCaseCause("安全生产警示标志类违法");
case "11" -> c.setCaseCause("安全生产中介机构类违法");
case "12" -> c.setCaseCause("安全设备使用维护类违法");
case "13" -> c.setCaseCause("重大危险源管理类违法");
case "14" -> c.setCaseCause("生产经营单位作业现场管理类违法");
case "15" -> c.setCaseCause("生产安全事故报告类违法");
case "16" -> c.setCaseCause("生产安全事故责任类违法");
case "17" -> c.setCaseCause("其他");
}
Optional.ofNullable(c.getEvidence()).ifPresent(e -> {
Optional.ofNullable(e.get("filesData")).ifPresent(list -> {
List<Map<String, String>> files = (ArrayList) list;
files.forEach(f -> {
String savePathName = f.get("savePathName");
String url = ftpService.getFileUrl(savePathName);
String downloadUrl = ftpService.getFileUrl(savePathName);
f.put("url", url);
f.put("downloadUrl", downloadUrl);
});
});
});
Optional.ofNullable(c.getExecute()).ifPresent(e -> {
Optional.ofNullable(e.get("annexs")).ifPresent(list -> {
List<Map<String, String>> files = (ArrayList) list;
files.forEach(f -> {
String savePathName = f.get("savePathName");
String url = ftpService.getFileUrl(savePathName);
String downloadUrl = ftpService.getFileUrl(savePathName);
f.put("url", url);
f.put("downloadUrl", downloadUrl);
});
});
});
return c;
}
/**
* 查询案件集合
*
* @param query 查询条件
* @return 查询结果
*/
public List<Case> listCases(CaseQuery query, RemoteUserInfo user) {
Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
query.setSort(sort.toString());
if ("Y".equals(query.getTag())) {
List<String> caseIds = documentRepository.findDistinctCaseIdByStatus(Document.DocumentStatus.done);
query.setCaseIds(caseIds);
}
return caseRepository.findAll(buildSpec(query, user));
}
/**
* 保存调查取证材料
*
* @param formData 调查取证材料
* @return 保存后案件信息
*/
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public Case saveEvidence(FormDataDto formData) {
// TODO
MultipartFile[] files = formData.getFiles();
Case caseInfo = new Case();
try {
caseInfo = objectMapper.readValue(formData.getFormDataJson(), Case.class);
Map<String, Object> evidence = caseInfo.getEvidence();
Object filesData = evidence.get("filesData");
List<Map<String, Object>> oldfilePaths = new ArrayList<>();
if (oldfilePaths != null)
oldfilePaths = (List<Map<String, Object>>) filesData;
oldfilePaths.forEach(file -> {
if (file.get("savePathName") != null && StringUtils.hasText(String.valueOf(file.get("savePathName"))))
ftpService.deletePathFile(String.valueOf(file.get("savePathName"))); // 删除文件服务器上的文件
});
List<Map<String, Object>> newfilePaths = new ArrayList<>();
for (MultipartFile file : files) {
String url;
try {
url = ftpService.uploadTempFile(IndustryCategoryForFile.pub, file.getOriginalFilename(), file.getInputStream());
if (!StringUtils.hasText(url)) {
throw new BusinessError(file.getOriginalFilename() + "失败:上传时异常");
}
Map<String, Object> singlePath = new HashMap<>();
singlePath.put("name", file.getOriginalFilename());
singlePath.put("savePathName", url);
singlePath.put("dowloadUrl", ftpService.getFileUrl(url));
newfilePaths.add(singlePath);
} catch (Exception e) {
throw new BusinessError(file.getOriginalFilename() + "上传失败:" + e);
}
}
caseRepository.findById(caseInfo.getCaseId()).map(c -> {
return c;
});
} catch (JsonProcessingException e) {
log.error(e.getMessage(), e);
}
return null;
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public List<Object> saveEvidence(Case c) {
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
List<Object> result = new ArrayList<>();
//删除文件
// if (c.getEvidence() != null && c.getEvidence().get("filesData") != null && oldCase.getEvidence() != null && oldCase.getEvidence().get("filesData") != null) {
// List<Map<String, Object>> newfilePaths = (List<Map<String, Object>>) c.getEvidence().get("filesData");
// List<Map<String, Object>> oldfilePaths = (List<Map<String, Object>>) oldCase.getEvidence().get("filesData");
// Set<Map<String, Object>> bSet = new HashSet<>(newfilePaths);
// for (Map<String, Object> num : oldfilePaths) {
// if (!bSet.contains(num)) {
// ftpService.deletePathFile(String.valueOf(num.get("savePathName")));
// }
// }
// }
oldCase.setEvidence(c.getEvidence());
result.add(oldCase);
//修改执法流程节点
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
if (c.getStatus().equals(Case.CaseStatus.investigating)) {
enforcementInfo.setCurrentNodeCode(FlowNode.investigating);
enforcementInfo.setCurrentNode("调查取证中");
result.add(enforcementInfo);
} else if (c.getStatus().equals(Case.CaseStatus.investigation_done)) {
enforcementInfo.setCurrentNodeCode(FlowNode.investigation_done);
enforcementInfo.setCurrentNode("调查取证完成");
result.add(enforcementInfo);
}
});
oldCase.setStatus(Case.CaseStatus.investigation_done);
caseRepository.save(oldCase);
return result;
}).get();
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public List<Object> fxyp(Case c) {
if (c.getAnalyzeJudge() != null && c.getAnalyzeJudge().get("shjg") != null) {
List<Object> result = new ArrayList<>();
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
result.add(oldCase);
if ((Integer) c.getAnalyzeJudge().get("shjg") == 0) {
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.done);
enforcementInfo.setCurrentNode("结案");
result.add(enforcementInfo);
});
}
oldCase.setAnalyzeJudge(c.getAnalyzeJudge());
oldCase.setStatus(Case.CaseStatus.analyze_judge);
caseRepository.save(oldCase);
return result;
}).get();
} else {
throw new BusinessError("法制审核保存失败:数据错误,请联系管理员");
}
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public List<Object> discuss(Case c) {
if (c.getDiscuss() != null) {
List<Object> result = new ArrayList<>();
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
result.add(oldCase);
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.analyze_judge);
enforcementInfo.setCurrentNode("审理");
result.add(enforcementInfo);
});
oldCase.setDiscuss(c.getDiscuss());
caseRepository.save(oldCase);
return result;
}).get();
} else {
throw new BusinessError("集体讨论保存失败:数据错误,请联系管理员");
}
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public List<Object> inform(Case c) {
if (c.getInform() != null) {
List<Object> result = new ArrayList<>();
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
result.add(oldCase);
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.inform);
enforcementInfo.setCurrentNode("告知");
result.add(enforcementInfo);
});
oldCase.setInform(c.getInform());
caseRepository.save(oldCase);
return result;
}).get();
} else {
throw new BusinessError("告知失败:数据错误,请联系管理员");
}
}
/**
* 案件 陈述申辩或听证
* @param c
* @return
*/
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public List<Object> informsbtz(Case c) {
if (c.getInformsbtz() != null ) {
List<Object> result = new ArrayList<>();
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
result.add(oldCase);
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.hearing);
enforcementInfo.setCurrentNode("陈述申辩或听证");
result.add(enforcementInfo);
});
oldCase.setInformsbtz(c.getInformsbtz());
caseRepository.save(oldCase);
return result;
}).get();
} else {
throw new BusinessError("审理失败:数据错误,请联系管理员");
}
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public Case exportPdf(String caseId) throws IOException {
Case caseInfo = new Case();
List<PdfMerger.PdfInput> inputs = new ArrayList<>();
documentRepository.findByCaseIdAndStatusOrderByDocumentNoAsc(caseId, Document.DocumentStatus.done).forEach(document -> {
try {
inputs.add(new PdfMerger.PdfInput(document.getFileName(), document, ftpService.getFileAsBytes(document.getFilePath())));
} catch (IOException e) {
throw new RuntimeException(e);
}
});
if (inputs.size() > 0) {
PDDocument mergedDoc = null;
String path = this.getClass().getClassLoader().getResource("").getPath() + "tempExportPdf/" + caseId + ".pdf";
File outputFile = new File(path);
File parentDir = outputFile.getParentFile();
if (parentDir != null && !parentDir.exists()) {
parentDir.mkdirs(); // 自动创建父目录
}
try {
// mergedDoc = PdfMerger.mergePdf(inputs);
// mergedDoc.save(path);
mergePDFsWithPageNumbers(inputs, path);
System.out.println("PDF合并并添加页码完成");
log.info("成功整合案卷保存成功: " + caseId + ".pdf");
caseInfo = caseRepository.findById(caseId).map(c -> {
//如果已经生成过案卷则先删除服务器上的老文件
Optional.ofNullable(c.getFilePath()).filter(StringUtils::hasText).ifPresent(o -> ftpService.deletePathFile(o));
try (InputStream in = new FileInputStream(path)) {
String saveFtpUrl = ftpService.uploadTempFile(IndustryCategoryForFile.pub, caseId + ".pdf", in);
c.setFilePath(saveFtpUrl);
c.setFilePathTime(LocalDateTime.now());
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
return c;
}).orElse(null);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
if (mergedDoc != null) {
mergedDoc.close(); // 确保文档关闭
}
}
// 删除服务器上生成的零时文件
Files.delete(outputFile.toPath());
}
caseInfo.setDownUrl(ftpService.getFileUrl(caseInfo.getFilePath()));
return caseInfo;
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public Case saveSupplement(Case c, RemoteUserInfo user) {
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
c.getSupplement().put("tbr", user.getXm());
c.getSupplement().put("tbsj", LocalDateTime.now().format(formatter));
oldCase.setSupplement(c.getSupplement());
oldCase.setUpdatedTime(LocalDateTime.now());
oldCase.setSupplementVerifyResult("2");
return caseRepository.save(oldCase);
}).get();
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public Case updateSupplementVerify(Case c, RemoteUserInfo user) {
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
oldCase.setSupplementVerifyResult(c.getSupplementVerifyResult());
oldCase.setSupplementVerifyDesc(c.getSupplementVerifyDesc());
oldCase.setSupplementVerifyUserName(user.getXm());
oldCase.setSupplementVerifyTime(LocalDateTime.now());
return caseRepository.save(oldCase);
}).get();
}
/**
* 查询案件集合
*
* @param query 查询条件
* @return 查询结果
*/
@Transactional(readOnly = true)
public List<Case> listZflatj(CaseQuery query, RemoteUserInfo user) {
Sort sort = Sort.by(Sort.Direction.DESC, "supplementVerifyTime");
query.setSort(sort.toString());
//判断周期类型组装日期条件
Optional.ofNullable(query.getPeriod()).ifPresent(o -> {
if ("month".equals(o)) {
LocalDate[] fillingDate = new LocalDate[]{query.getYd(), query.getYd().with(TemporalAdjusters.lastDayOfMonth())};
query.setFillingDate(fillingDate);
} else if ("quarter".equals(o)) {
if (query.getJd() == 1) {
LocalDate start = LocalDate.of(LocalDate.now().getYear(), 1, 1);
LocalDate end = LocalDate.of(LocalDate.now().getYear(), 3, 31);
LocalDate[] fillingDate = new LocalDate[]{start, end};
query.setFillingDate(fillingDate);
} else if (query.getJd() == 2) {
LocalDate start = LocalDate.of(LocalDate.now().getYear(), 4, 1);
LocalDate end = LocalDate.of(LocalDate.now().getYear(), 6, 30);
LocalDate[] fillingDate = new LocalDate[]{start, end};
query.setFillingDate(fillingDate);
} else if (query.getJd() == 3) {
LocalDate start = LocalDate.of(LocalDate.now().getYear(), 7, 1);
LocalDate end = LocalDate.of(LocalDate.now().getYear(), 9, 30);
LocalDate[] fillingDate = new LocalDate[]{start, end};
query.setFillingDate(fillingDate);
} else if (query.getJd() == 4) {
LocalDate start = LocalDate.of(LocalDate.now().getYear(), 10, 1);
LocalDate end = LocalDate.of(LocalDate.now().getYear(), 12, 31);
LocalDate[] fillingDate = new LocalDate[]{start, end};
query.setFillingDate(fillingDate);
}
}
});
return caseRepository.findAll(buildSpec(query, user)).stream().map(this::transferInfo).toList();
}
private Case transferInfo(Case c) {
c.getEnforcementInfo().getAgency().getAgencyName();
c.getEnforcementInfo().getEnterprise().getUnitName();
Optional.ofNullable(c.getCaseSourceCode()).ifPresent(caseSourseCode -> {
switch (caseSourseCode) {
case "1" -> c.setCaseSourceCode("日常检查发现");
case "2" -> c.setCaseSourceCode("机构监测报告");
case "3" -> c.setCaseSourceCode("举报投诉");
case "4" -> c.setCaseSourceCode("上级交办");
case "5" -> c.setCaseSourceCode("下级情报");
case "6" -> c.setCaseSourceCode("有关部门移送");
case "7" -> c.setCaseSourceCode("其他");
}
});
Optional.ofNullable(c.getCaseCause()).ifPresent(caseCause -> {
switch (caseCause) {
case "1" -> c.setCaseCause("安全生产行政许可类违法");
case "2" -> c.setCaseCause("安全生产管理机构和管理人员类违法");
case "3" -> c.setCaseCause("安全生产建设工程项目类违法");
case "4" -> c.setCaseCause("安全生产规章制度类违法");
case "5" -> c.setCaseCause("安全生产培训教育类违法");
case "6" -> c.setCaseCause("安全生产资金投入类违法");
case "7" -> c.setCaseCause("安全生产隐患管理类违法");
case "8" -> c.setCaseCause("生产安全事故应急救援类违法");
case "9" -> c.setCaseCause("安全生产承包租赁类违法");
case "10" -> c.setCaseCause("安全生产警示标志类违法");
case "11" -> c.setCaseCause("安全生产中介机构类违法");
case "12" -> c.setCaseCause("安全设备使用维护类违法");
case "13" -> c.setCaseCause("重大危险源管理类违法");
case "14" -> c.setCaseCause("生产经营单位作业现场管理类违法");
case "15" -> c.setCaseCause("生产安全事故报告类违法");
case "16" -> c.setCaseCause("生产安全事故责任类违法");
case "17" -> c.setCaseCause("其他");
}
});
String industryType = c.getEnforcementInfo().getEnterprise().getIndustryType();
String industryTypeName = Constants.DictDisplay.hylbMap.get(industryType);
c.setEnterprise(c.getEnforcementInfo().getEnterprise());
//行业类别分类
c.getEnterprise().setIndustryType(industryTypeName);
//获取 执法检查信息
enforceCheckService.getEnforceCheckByEnforcementId(c.getEnforcementInfo().getEnforcementId()).ifPresent(check -> {
c.setEnforceCheck(check);
});
return c;
}
@PublishDataChange(action = DataChangeAction.SAVE)
@Transactional
public List<Object> decided(Case c) {
if (c.getPunishmentItems() != null || c.getDecided() != null) {
List<Object> result = new ArrayList<>();
return caseRepository.findById(c.getCaseId()).map(oldCase -> {
result.add(oldCase);
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.decided);
enforcementInfo.setCurrentNode("决定");
result.add(enforcementInfo);
});
oldCase.setPunishmentItems(c.getPunishmentItems());
oldCase.setDecided(c.getDecided());
oldCase.setDecidePayment(c.getDecidePayment());
oldCase.setUpdatedTime(LocalDateTime.now());
caseRepository.save(oldCase);
return result;
}).get();
} else {
throw new BusinessError("决定失败:数据错误,请联系管理员");
}
}
@Transactional
@PublishDataChange(action = DataChangeAction.SAVE)
public void execute(Case c) {
caseRepository.findById(c.getCaseId()).ifPresent(caseInfo -> {
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.execute);
enforcementInfo.setCurrentNode("执行");
});
caseInfo.setExecute(c.getExecute());
caseRepository.save(caseInfo);
});
}
@Transactional
@PublishDataChange(action = DataChangeAction.SAVE)
public void finalCase(Case c) {
caseRepository.findById(c.getCaseId()).ifPresent(caseInfo -> {
enforcementInfoRepository.findById(c.getEnforcementId()).ifPresent(enforcementInfo -> {
enforcementInfo.setCurrentNodeCode(FlowNode.done);
enforcementInfo.setCurrentNode("完成");
});
caseInfo.setStatus(Case.CaseStatus.closing);
caseInfo.setFinalCase(c.getFinalCase());
caseRepository.save(caseInfo);
});
}
public Map<String, Long> ajtj(RemoteUserInfo user) {
String gajgjgdm = com.aisino.iles.common.util.StringUtils.trimEven0(user.getGajgjgdm());
Map<String, Long> ajtj = caseRepository.ajtj(gajgjgdm + "%");
return ajtj;
}
}

View File

@ -0,0 +1,148 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.common.util.PageableHelper;
import com.aisino.iles.lawenforcement.model.CheckItem;
import com.aisino.iles.lawenforcement.model.CheckItem_;
import com.aisino.iles.lawenforcement.model.query.CheckItemQuery;
import com.aisino.iles.lawenforcement.repository.CheckItemRepository;
import com.smartlx.sso.client.model.RemoteUserInfo;
import jakarta.persistence.criteria.Predicate;
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 org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* 检查项信息服务类
*/
@Service
public class CheckItemService {
private final CheckItemRepository checkItemRepo;
public CheckItemService(CheckItemRepository checkItemRepo) {
this.checkItemRepo = checkItemRepo;
}
/**
* 保存检查项信息
*
* @param checkItem 检查项信息
* @return 保存后的检查项信息
*/
@Transactional
public CheckItem saveCheckItem(CheckItem checkItem, RemoteUserInfo user, String type) {
LocalDateTime now = LocalDateTime.now();
if ("add".equals(type)) {
checkItem.setEnabled(true);
checkItem.setCreateTime(now);
if (null != user) {
checkItem.setCreatedBy(user.getXm());
checkItem.setCreatedAccountBy(user.getYhwybs());
}
}
checkItem.setUpdateTime(now);
return checkItemRepo.save(checkItem);
}
/**
* 根据ID查询检查项信息
*
* @param checkItemId 检查项ID
* @return 检查项信息
*/
public Optional<CheckItem> findCheckItemById(String checkItemId) {
return checkItemRepo.findById(checkItemId);
}
/**
* 根据查询条件分页查询检查项信息
*
* @param query 查询条件
* @return 分页检查项信息
*/
public Page<CheckItem> findCheckItemPage(CheckItemQuery query) {
return checkItemRepo.findAll(build(query),
PageableHelper.buildPageRequest(query.page(), query.pageSize(),
(StringUtils.hasText(query.sort()) ? query.sort() : "createTime"),
(StringUtils.hasText(query.dir()) ? query.dir() : "desc")),
"checklist");
}
/**
* 构建查询条件
*
* @param query 查询条件
* @return 规格
*/
private Specification<CheckItem> build(CheckItemQuery query) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
Optional.ofNullable(query.getItemName()).filter(StringUtils::hasText).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get(CheckItem_.itemName), "%" + o + "%")));
Optional.ofNullable(query.getItemTable()).filter(StringUtils::hasText).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get(CheckItem_.itemTable), o)));
Optional.ofNullable(query.getItemType()).filter(StringUtils::hasText).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get(CheckItem_.itemType), o)));
Optional.ofNullable(query.getUpdateTimeList()).filter(f -> f.length == 2).map(f -> {
List<Predicate> ts = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get(CheckItem_.updateTime), from)).ifPresent(ts::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get(CheckItem_.updateTime), to)).ifPresent(ts::add);
return ts;
}).ifPresent(predicates::addAll);
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
/**
* 根据ID删除检查项信息
*
* @param checkItemId 检查项ID
*/
@Transactional
public void deleteCheckItemById(String checkItemId) {
checkItemRepo.deleteById(checkItemId);
}
/**
* 检查项是否存在
*
* @param checkItemId 检查项ID
* @return 是否存在
*/
public boolean existsCheckItemById(String checkItemId) {
return checkItemRepo.existsById(checkItemId);
}
/**
* 批量删除检查项
*
* @param itemIds 检查项ID列表
*/
@Transactional
public void deleteCheckItemByIds(List<String> itemIds) {
checkItemRepo.deleteAllById(itemIds);
}
/**
* 查询检查项列表
*
* @return 分页检查项信息
*/
public List<CheckItem> findCheckItems(CheckItemQuery query) {
if (StringUtils.hasText(query.getItemTable()))
return checkItemRepo.findByItemTableAndEnabled(query.getItemTable(), true);
else
return checkItemRepo.findByEnabled(true);
}
}

View File

@ -0,0 +1,139 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.common.util.PageableHelper;
import com.aisino.iles.lawenforcement.model.Checklist;
import com.aisino.iles.lawenforcement.model.Checklist_;
import com.aisino.iles.lawenforcement.model.query.ChecklistQuery;
import com.aisino.iles.lawenforcement.repository.ChecklistRepository;
import com.smartlx.sso.client.model.RemoteUserInfo;
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 org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* 检查表服务类
*/
@Service
@Slf4j
public class ChecklistService {
private final ChecklistRepository checklistRepo;
public ChecklistService(ChecklistRepository checklistRepo) {
this.checklistRepo = checklistRepo;
}
/**
* 保存检查表信息
*
* @param checklist 检查表信息
* @return 保存后的检查表信息
*/
@Transactional
public Checklist saveChecklist(Checklist checklist, RemoteUserInfo user, String type) {
LocalDateTime now = LocalDateTime.now();
if ("add".equals(type)) {
checklist.setIsRemove(false);
checklist.setCreateTime(now);
}
return checklistRepo.save(checklist);
}
/**
* 根据ID查询检查表信息
*
* @param checklistId 检查表ID
* @return 检查表信息
*/
public Optional<Checklist> findChecklistById(String checklistId) {
return checklistRepo.findById(checklistId);
}
/**
* 根据查询条件分页查询检查表信息
*
* @param query 查询条件
* @return 分页检查表信息
*/
public Page<Checklist> findChecklistPage(ChecklistQuery query) {
return checklistRepo.findAll(build(query), PageableHelper.buildPageRequest(query.page(),
query.pageSize(),
(StringUtils.hasText(query.sort()) ? query.sort() : "createTime"),
(StringUtils.hasText(query.dir()) ? query.dir() : "desc")));
}
/**
* 构建查询条件
*
* @param query 查询条件
* @return 规格
*/
private Specification<Checklist> build(ChecklistQuery query) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
Optional.ofNullable(query.getIsRemove()).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get(Checklist_.isRemove), o)));
Optional.ofNullable(query.getEnabled()).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get(Checklist_.enabled), o)));
Optional.ofNullable(query.getChecklistName()).filter(StringUtils::hasText).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get(Checklist_.checklistName), "%" + o + "%")));
Optional.ofNullable(query.getDescription()).filter(StringUtils::hasText).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get(Checklist_.description), "%" + o + "%")));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
/**
* 根据ID删除检查表信息
*
* @param checklistId 检查表ID
*/
@Transactional
public void deleteChecklistById(String checklistId) {
checklistRepo.findById(checklistId).ifPresent(checklist -> {
checklist.setIsRemove(true);
checklist.setRemoveTime(LocalDateTime.now());
checklistRepo.save(checklist);
});
}
/**
* 检查表是否存在
*
* @param checklistId 检查表ID
* @return 是否存在
*/
public boolean existsChecklistById(String checklistId) {
return checklistRepo.existsById(checklistId);
}
/**
* 批量删除检查表
*
* @param itemIds 检查表ID列表
*/
@Transactional
public void deleteChecklistByIds(List<String> itemIds) {
checklistRepo.findAllById(itemIds).forEach(checklist -> {
checklist.setIsRemove(true);
checklist.setRemoveTime(LocalDateTime.now());
checklistRepo.save(checklist);
});
}
/**
* 根据查询条件获取检查表列表
*
* @param query 查询条件
* @return 检查表集合
*/
public List<Checklist> getChecklistList(ChecklistQuery query) {
return checklistRepo.findAll(build(query));
}
}

View File

@ -0,0 +1,155 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.lawenforcement.config.SyncApiProperties;
import com.aisino.iles.lawenforcement.exception.DataSyncException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.smartlx.sso.client.model.AccessToken;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class DataSyncService {
// 用于死信队列的专用Logger
private static final Logger DEAD_LETTER_LOGGER = LoggerFactory.getLogger("dead-letter-log");
private final ObjectMapper objectMapper;
private final RestTemplate restTemplate;
private final AuthService authService;
private final SyncApiProperties syncApiProperties;
@Value("${third-party.enterprise.yddh}")
private String yddh;
// 用于存储实体类型与对应API路径的映射
private final Map<Class<?>, String> apiPathRegistry = new HashMap<>();
public DataSyncService(RestTemplate restTemplate,
AuthService authService,
ObjectMapper objectMapper,
SyncApiProperties syncApiProperties) {
this.restTemplate = restTemplate;
this.authService = authService;
this.syncApiProperties = syncApiProperties;
this.objectMapper = objectMapper;
}
/**
* 初始化API路径注册表
*/
@PostConstruct
public void init() {
if (syncApiProperties.getEndpoints() == null) {
log.warn("未在配置文件中找到 'iles.sync.api.endpoints' 配置。数据同步功能可能无法正常工作。");
return;
}
syncApiProperties.getEndpoints().forEach((className, path) -> {
try {
Class<?> clazz = Class.forName(className);
apiPathRegistry.put(clazz, path);
log.info("已注册数据同步API端点: {} -> {}", clazz.getSimpleName(), path);
} catch (ClassNotFoundException e) {
log.error("无法加载API端点配置中的类: {}。请检查 'iles.sync.api.endpoints' 配置。", className, e);
}
});
}
@Retryable(
retryFor = {DataSyncException.class}, // 仅在捕获到我们自定义的异常时重试
maxAttempts = 2, // 最多尝试2次
backoff = @Backoff(delay = 2000, multiplier = 2) // 第一次延迟2秒第二次延迟4秒
)
public <T> void sendData(T data, Class<?> entityType) {
log.info("正在尝试发送数据,类型: [{}], 尝试次数: {}", entityType.getSimpleName(), org.springframework.retry.support.RetrySynchronizationManager.getContext().getRetryCount() + 1);
try {
// 1. 获取动态API URL
String apiUrl = getApiUrlForEntity(entityType);
// 2. 获取认证Token
AccessToken token = authService.getTokenBackend(yddh);
HttpHeaders headers = new HttpHeaders();
headers.setBearerAuth(token.getAccess_token());
headers.setContentType(MediaType.APPLICATION_JSON);
// 3. 将数据对象序列化为JSON字符串
String jsonData = objectMapper.writeValueAsString(data);
HttpEntity<String> requestEntity = new HttpEntity<>(jsonData, headers);
// 4. 调用第三方API
log.debug("同步数据内容: {}", jsonData);
ResponseEntity<String> response = restTemplate.postForEntity(apiUrl, requestEntity, String.class);
// 5. 处理响应
if (!response.getStatusCode().is2xxSuccessful()) {
log.error("数据同步失败URL: {}, 响应状态: {}, 响应体: {}", apiUrl, response.getStatusCode(), response.getBody());
throw new DataSyncException("请求失败,状态码: " + response.getStatusCode());
}
log.info("数据同步成功URL: {}, 响应状态: {}", apiUrl, response.getStatusCode());
} catch (JsonProcessingException e) {
log.error("数据序列化为JSON时出错: {}", data, e);
// 对于序列化失败不进行重试直接进入恢复逻辑
throw new DataSyncException("数据序列化失败", e);
} catch (RestClientException e) {
log.error("调用API时发生网络或客户端错误: {}", e.getMessage());
// 对于网络等问题抛出异常以触发重试
throw new DataSyncException("因网络错误导致数据发送失败", e);
} catch (Exception e) {
log.error("处理数据同步时发生未知错误", e);
// 对于未知异常也触发重试
throw new DataSyncException("数据发送时发生未知错误", e);
}
}
@Recover
public <T> void recover(DataSyncException e, T data, Class<?> entityType) {
String dataType = entityType.getSimpleName();
log.error("数据类型 [{}] 的所有重试尝试均已失败。正在写入死信日志。", dataType, e);
try {
String dataAsJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(data);
String logMessage = String.format(
"{\n \"timestamp\": \"%s\",\n \"dataType\": \"%s\",\n \"error\": \"%s\",\n \"payload\": %s\n}",
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME),
dataType,
e.getMessage(),
dataAsJson
);
DEAD_LETTER_LOGGER.error(logMessage);
} catch (com.fasterxml.jackson.core.JsonProcessingException jsonProcessingException) {
log.error("严重错误未能将数据序列化为JSON以写入死信日志。数据将会丢失。数据类型: {}, 数据: {}", dataType, data, jsonProcessingException);
}
}
/**
* 根据实体类型获取对应的API完整URL
*/
private String getApiUrlForEntity(Class<?> entityClass) {
String relativePath = apiPathRegistry.get(entityClass);
if (relativePath == null) {
log.error("未找到实体类 {} 对应的API路径配置。", entityClass.getName());
throw new IllegalArgumentException("未配置实体 " + entityClass.getSimpleName() + " 的API路径");
}
return syncApiProperties.getBaseUrl() + relativePath;
}
}