非现场检查、执法人员服务等接口

This commit is contained in:
songxudong 2025-03-07 17:35:47 +08:00
parent 809aaae720
commit 44e6b957e6
4 changed files with 945 additions and 0 deletions

View File

@ -0,0 +1,315 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.core.exception.BusinessError;
import com.aisino.iles.lawenforcement.model.*;
import com.aisino.iles.lawenforcement.model.dto.OfficerDto;
import com.aisino.iles.lawenforcement.model.query.NotificationQuery;
import com.aisino.iles.lawenforcement.repository.AgencyRepository;
import com.aisino.iles.lawenforcement.repository.NoticeReceivingUnitRepository;
import com.aisino.iles.lawenforcement.repository.NoticeRepository;
import com.aisino.iles.lawenforcement.repository.OfficerRepository;
import com.smartlx.sso.client.model.RemoteUserInfo;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.Predicate;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
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.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
/**
* 通知公告
*/
@Service
@Validated
@Transactional(readOnly = true)
public class NoticeService {
private NoticeRepository noticeRepository;
private NoticeReceivingUnitRepository noticeReceivingUnitRepository;
private OfficerRepository officerRepository;
private AgencyRepository agencyRepository;
public NoticeService(NoticeRepository noticeRepository,
NoticeReceivingUnitRepository noticeReceivingUnitRepository,
OfficerRepository officerRepository,
AgencyRepository agencyRepository) {
this.noticeRepository = noticeRepository;
this.noticeReceivingUnitRepository = noticeReceivingUnitRepository;
this.officerRepository = officerRepository;
this.agencyRepository = agencyRepository;
}
/**
* 分页查询
*
* @param query
* @param user
* @return
*/
public Page<Notice> pageNotice(NotificationQuery query, RemoteUserInfo user) {
Integer _psize = Optional.ofNullable(query.pageSize()).filter(f -> f > 0).orElse(20);
Integer _page = Optional.ofNullable(query.page()).filter(f -> f > 0).map(f -> f - 1).orElse(0);
String _sort = Optional.ofNullable(query.sort()).filter(com.aisino.iles.common.util.StringUtils::isNotEmpty).orElse(Notice_.RELEASE_TIME);
String _dir = Optional.ofNullable(query.dir()).filter(d -> Sort.Direction.fromOptionalString(d).isPresent()).orElse("desc");
return noticeRepository.findAll(buildQueryCondition(query, user), PageRequest.of(_page, _psize, Sort.by(Sort.Direction.fromString(_dir), _sort)));
}
/**
* 动态查询条件构建
*/
private Specification<Notice> buildQueryCondition(NotificationQuery query, RemoteUserInfo user) {
return (root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
//标题
Optional.ofNullable(query.getNotificationTitle()).filter(com.aisino.iles.common.util.StringUtils::isNotEmpty).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get("noticeTitle"), "%" + o + "%")));
//接收单位类型
predicates.add(criteriaBuilder.equal(root.get("receivingUnitType"), "2"));
//发布单位
String gxdwbm;
if (!StringUtils.hasText(query.getPublishingUnitCode())) {
gxdwbm = user.getGajgjgdm();
} else {
gxdwbm = query.getPublishingUnitCode();
}
Optional.ofNullable(gxdwbm).filter(com.aisino.iles.common.util.StringUtils::isNotEmpty).map(f -> {
Join<Notice, Agency> join = root.join(Notice_.agency);
return criteriaBuilder.like(join.get(Agency_.agencyCode), com.aisino.iles.common.util.StringUtils.trimEven0(f) + "%");
}).ifPresent(predicates::add);
// // 接收单位
// Optional.ofNullable(gxdwbm).filter(com.aisino.iles.common.util.StringUtils::isNotEmpty).map(f -> {
// Join<Notice, NoticeReceivingUnit> join = root.join(Notice_.noticeReceivingUnit);
// return criteriaBuilder.like(join.get(NoticeReceivingUnit_.receivingUnitCode), com.aisino.iles.common.util.StringUtils.trimEven0(f) + "%");
// }).ifPresent(predicates::add);
// 发布单位-接受单位条件
if (com.aisino.iles.common.util.StringUtils.isNotEmpty(gxdwbm)) {
List<Predicate> orPredicates = new ArrayList();
Join<Notice, Agency> join = root.join(Notice_.agency);
Predicate p1 = criteriaBuilder.like(join.get(Agency_.agencyCode), com.aisino.iles.common.util.StringUtils.trimEven0(gxdwbm) + "%");
orPredicates.add(criteriaBuilder.or(p1));
Join<Notice, NoticeReceivingUnit> join2 = root.join(Notice_.noticeReceivingUnit);
Predicate p2 = criteriaBuilder.equal(join2.get(NoticeReceivingUnit_.receivingUnitCode), gxdwbm);
orPredicates.add(criteriaBuilder.or(p2));
Predicate p = criteriaBuilder.or(orPredicates.toArray(new Predicate[0]));
predicates.add(p);
}
//发布时间
Optional.ofNullable(query.getReleaseTimeFist())
.ifPresent(o -> predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("releaseTime"), o)));
Optional.ofNullable(query.getReleaseTimeLast())
.map(date -> date.plusDays(1L))
.map(localDate -> criteriaBuilder.lessThan(root.get("releaseTime"), localDate))
.ifPresent(predicates::add);
Optional.ofNullable(query.getReleaseTime()).filter(f -> f.length == 2).map(f -> {
List<Predicate> timePredicates = new ArrayList<>();
Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get("releaseTime"), from)).ifPresent(timePredicates::add);
Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get("releaseTime"), to)).ifPresent(timePredicates::add);
return timePredicates;
}).ifPresent(predicates::addAll);
criteriaQuery.distinct(true);
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
}
/**
* 新增
*
* @param notice
* @param user
* @return
*/
@Transactional
public Notice addNotice(Notice notice, RemoteUserInfo user) {
notice.setPublisherUserId(user.getYhwybs());
notice.setReceivingUnitType("2"); // 默认接收类型为2
notice.setPublishingUnitCode(notice.getAgency().getAgencyCode()); // 发布单位编码
notice.setPublishingUnit(notice.getAgency().getAgencyName()); // 发布单位
// 根据管辖单位编码查询机构赋值机构
notice.setAgency(queryAgency(notice.getAgency().getAgencyCode()));
Notice noticeSave = noticeRepository.save(notice);
if (notice.isSelectAll()) {
String gxdwbm = "";
if (com.aisino.iles.common.util.StringUtils.isNotEmpty(notice.getLtdJurisdictionCode())) {
gxdwbm = com.aisino.iles.common.util.StringUtils.trimEven0(notice.getLtdJurisdictionCode());
} else {
if (StringUtils.isEmpty(gxdwbm)) {
gxdwbm = com.aisino.iles.common.util.StringUtils.trimEven0(user.getGajgjgdm());
}
}
officerRepository.findByAgencyCode(gxdwbm + "%").forEach(a -> {
NoticeReceivingUnit unit = new NoticeReceivingUnit();
unit.setNoticeId(noticeSave.getNoticeId()); // 通知ID
unit.setReceivingUnitId(a.getAgencyId()); // 接受单位ID
unit.setReceivingUnitCode(a.getAgencyCode()); // 接收单位代码
unit.setReceivingUnitName(a.getAgencyName()); // 接受人姓名
unit.setMsgflag("0"); // 查看标识
unit.setCollectionTime(LocalDateTime.now()); // 收取时间
unit.setCertificateNo(a.getCertificateNo()); // 执法证号ID
noticeReceivingUnitRepository.save(unit);
});
} else { // 前台选择接收人
Set<Officer> jsrs = notice.getPeoplePolices();
if (null != jsrs && jsrs.size() > 0) {
jsrs.forEach(j -> {
NoticeReceivingUnit unit = new NoticeReceivingUnit();
// Optional<Officer> officer = officerRepository.findByCertificateNo(j.getCertificateNo());
// if (!officer.isPresent()) {
// throw new BusinessError("" + j.getCertificateNo() + " 接收人不存在!");
// }
Optional<Agency> agency = agencyRepository.findById(j.getAgencyId());
if (!agency.isPresent()) throw new BusinessError(""+j.getCertificateNo() + " 所属单位不存在!");
unit.setNoticeId(noticeSave.getNoticeId()); // 通知ID
unit.setReceivingUnitId(agency.get().getAgencyId()); // 接受单位ID
unit.setReceivingUnitCode(agency.get().getAgencyCode()); // 接收单位代码
unit.setReceivingUnitName(agency.get().getAgencyName()); // 接受人姓名
unit.setMsgflag("0"); // 查看标识
unit.setCollectionTime(LocalDateTime.now()); // 收取时间
// unit.setCertificateNo(officer.get().getCertificateNo()); // 执法证号ID
noticeReceivingUnitRepository.save(unit);
});
}
}
return noticeSave;
}
/**
* 单条查询
*
* @param noticeId
* @return
*/
public Optional<Notice> findOneNotice(String noticeId, RemoteUserInfo user) {
return noticeRepository.findById(noticeId).map(notice -> this.listNoticeItem(notice, user));
}
@Transactional
public Notice listNoticeItem(Notice notice, RemoteUserInfo user) {
List<NoticeReceivingUnit> unitList = noticeReceivingUnitRepository.findByNoticeId(notice.getNoticeId()).stream().collect(Collectors.toList());
Set<Officer> officers = new HashSet<>();
unitList.forEach(e -> {
Officer officer = new Officer();
Optional<Agency> agencyOptional = agencyRepository.findByAgencyCode(e.getReceivingUnitCode());
if (!agencyOptional.isPresent()) {
throw new BusinessError(""+e.getCertificateNo() + " 接受单位不存在!");
}
// Optional<Officer> officerOptional = officerRepository.findByCertificateNo(e.getCertificateNo());
// if (!officerOptional.isPresent()) {
// throw new BusinessError(""+e.getCertificateNo() + " 执法证号不存在!");
// }
// officer.setOfficerId(officerOptional.get().getOfficerId()); // 执法人员唯一IDULID
// officer.setCertificateNo(e.getCertificateNo()); // 执法证号唯一标识
// officer.setOfficerName(officerOptional.get().getOfficerName()); // 执法人员姓名
// officer.setAgencyId(officerOptional.get().getAgencyId()); // 所属执法机构IDULID
// officer.setRole(officerOptional.get().getRole()); // 角色
// officer.setRoleName(officerOptional.get().getRoleName()); // 角色名称
officer.setAgency(agencyOptional.get()); // 机构
officer.setAgencyId(agencyOptional.get().getAgencyId()); // 机构ID
officer.setAgencyCode(agencyOptional.get().getAgencyCode()); // 机构代码
officer.setAgencyName(agencyOptional.get().getAgencyName()); // 机构名称
officer.setAgencySimpleCode(agencyOptional.get().getAgencySimpleCode()); // 机构简码
officer.setLeaf(agencyOptional.get().getLeaf()); // 是否为最下级
officers.add(officer);
});
notice.setPeoplePolices(officers);
return notice;
}
/**
* 修改
*/
@Transactional
public void modifyNotice(String noticeId, Notice notice, RemoteUserInfo user) {
Optional<Notice> noticeQuery = noticeRepository.findById(noticeId);
Notice noticeSave = noticeQuery.get();
if (noticeQuery.isPresent()) {
com.aisino.iles.common.util.BeanUtils.copyNoNullProperties(notice, noticeSave, "noticeReceivingUnit");
// 根据管辖单位编码查询机构赋值机构
notice.setAgency(queryAgency(notice.getAgency().getAgencyCode()));
notice.setPublishingUnitCode(notice.getAgency().getAgencyCode()); // 发布单位编码
notice.setPublishingUnit(notice.getAgency().getAgencyName()); // 发布单位
if (notice.isSelectAll()) {
String gxdwbm = "";
if (com.aisino.iles.common.util.StringUtils.isNotEmpty(notice.getLtdJurisdictionCode())) {
gxdwbm = com.aisino.iles.common.util.StringUtils.trimEven0(notice.getLtdJurisdictionCode());
} else {
if (StringUtils.isEmpty(gxdwbm)) {
gxdwbm = com.aisino.iles.common.util.StringUtils.trimEven0(user.getGajgjgdm());
}
}
officerRepository.findByAgencyCode(gxdwbm + "%").forEach(a -> {
NoticeReceivingUnit unit = new NoticeReceivingUnit();
unit.setNoticeId(noticeSave.getNoticeId()); // 通知ID
unit.setReceivingUnitId(a.getAgencyId()); // 接受单位ID
unit.setReceivingUnitCode(a.getAgencyCode()); // 接收单位代码
unit.setReceivingUnitName(a.getAgencyName()); // 接受人姓名
unit.setMsgflag("0"); // 查看标识
unit.setCollectionTime(LocalDateTime.now()); // 收取时间
noticeReceivingUnitRepository.save(unit);
});
} else { // 前台选择接收人
Set<Officer> jsrs = notice.getPeoplePolices();
if (null != jsrs && jsrs.size() > 0) {
jsrs.forEach(j -> {
NoticeReceivingUnit unit = new NoticeReceivingUnit();
// Optional<OfficerDto> officer = officerRepository.findByAgencyCertificateNo(j.getCertificateNo());
// if (!officer.isPresent()) {
// throw new BusinessError("" + j.getCertificateNo() + " 接收人不存在!");
// }
Optional<Agency> agency = agencyRepository.findById(j.getAgencyId());
if (!agency.isPresent()) {
throw new BusinessError(""+j.getCertificateNo() + " 所属单位不存在!");
}
unit.setNoticeId(noticeSave.getNoticeId()); // 通知ID
unit.setReceivingUnitId(agency.get().getAgencyId()); // 接受单位ID
unit.setReceivingUnitCode(agency.get().getAgencyCode()); // 接收单位代码
unit.setReceivingUnitName(agency.get().getAgencyName()); // 接受人姓名
unit.setMsgflag("0"); // 查看标识
unit.setCollectionTime(LocalDateTime.now()); // 收取时间
// unit.setCertificateNo(officer.get().getCertificateNo()); // 执法证号ID
noticeReceivingUnitRepository.save(unit);
});
}
}
}
}
/**
* 删除
*
* @param noticeId
*/
@Transactional
public void removeNotice(String noticeId, RemoteUserInfo user) {
noticeReceivingUnitRepository.deleteBynoticeId(noticeId);
noticeRepository.deleteById(noticeId);
}
/**
* 通知通告列表
*
* @param query 查询参数
* @param user 当前用户
* @return 通知通告列表
*/
public List<Notice> list(NotificationQuery query, RemoteUserInfo user) {
return noticeRepository.findAll(buildQueryCondition(query, user), Sort.by(Sort.Direction.DESC, Notice_.RELEASE_TIME));
}
public Agency queryAgency(String agencyCode) {
Optional<Agency> agency = agencyRepository.findByAgencyCode(agencyCode);
if (!agency.isPresent()) {
throw new BusinessError(""+agencyCode + " 所属单位不存在!");
}
return agency.get();
}
}

View File

@ -0,0 +1,109 @@
package com.aisino.iles.lawenforcement.service;
import com.aisino.iles.lawenforcement.repository.EnterpriseRepository;
import com.aisino.iles.lawenforcement.repository.EnterpriseWarnRepository;
import com.aisino.iles.lawenforcement.repository.OnlinePatrolRepository;
import jodd.util.StringUtil;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Service
public class OffSiteLawEnforceService {
private final EnterpriseRepository enterpriseRepository;
private final OnlinePatrolRepository onlinePatrolRepository;
private final EnterpriseWarnRepository enterpriseWarnRepository;
public OffSiteLawEnforceService(EnterpriseRepository enterpriseRepository,
OnlinePatrolRepository onlinePatrolRepository,
EnterpriseWarnRepository enterpriseWarnRepository) {
this.enterpriseRepository = enterpriseRepository;
this.onlinePatrolRepository = onlinePatrolRepository;
this.enterpriseWarnRepository = enterpriseWarnRepository;
}
public Long getQyjrtj() {
return enterpriseRepository.findQyjrtj();
}
public Map<String, Long> getQyjrlxtj() {
Map<String, Long> res = new HashMap<>();
List<Map<String, Object>> qyjrlx = enterpriseRepository.findQyjrlxtj();
res.put("ks", getLongValue(qyjrlx, "1"));
res.put("wh", getLongValue(qyjrlx, "2") + getLongValue(qyjrlx, "3") + getLongValue(qyjrlx, "4"));
res.put("jyz", getLongValue(qyjrlx, "5"));
res.put("gm", getLongValue(qyjrlx, "6") + getLongValue(qyjrlx, "7"));
res.put("aqsc", getLongValue(qyjrlx, "8") + getLongValue(qyjrlx, "9") + getLongValue(qyjrlx, "10"));
res.put("jzsg", enterpriseRepository.findQyjzsgtj());
res.put("yy", enterpriseRepository.findQyyytj());
return res;
}
private Long getLongValue(List<Map<String, Object>> dataList, String key) {
for (Map<String, Object> map : dataList) {
if (key.equals(map.get("industry_type").toString())) {
String value = map.get("num").toString();
return StringUtil.isNotEmpty(value) ? Long.valueOf(value) : 0L;
}
}
return 0L;
}
public Map<String, Long> getFxczfzs() {
Long sumNum = onlinePatrolRepository.getSumNum();
LocalDateTime endTime = LocalDateTime.now();
Long weekNum = onlinePatrolRepository.getNumByCreatTime(endTime.minusWeeks(1), endTime);
Long monthNum = onlinePatrolRepository.getNumByCreatTime(endTime.minusMonths(1), endTime);
Long yearNum = onlinePatrolRepository.getNumByCreatTime(endTime.minusYears(1), endTime);
Map<String, Long> res = new HashMap<>();
res.put("sumNum", sumNum);
res.put("weekNum", weekNum);
res.put("monthNum", monthNum);
res.put("yearNum", yearNum);
return res;
}
public List<Map<String, Object>> getQyyjtj() {
List<Map<String, Object>> res = enterpriseWarnRepository.getNumGroupByEventDesc();
return res;
}
public List<Map<String, Object>> getFxczftj(String type) {
if ("1".equals(type)) {
return onlinePatrolRepository.getFxczftjByAgency();
} else {
LocalDate currentDate = LocalDate.now();
YearMonth yearMonth = YearMonth.from(currentDate).minusMonths(11);
LocalDateTime startTime = LocalDateTime.of(yearMonth.getYear(), yearMonth.getMonthValue(), 1, 0, 0);
LocalDateTime endTime = LocalDateTime.now();
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>> fxczftj = onlinePatrolRepository.getfxczftjByMonth(startTime, endTime);
// 处理数据
List<Map<String, Object>> res = months.stream()
.map(month -> {
Map<String, Object> fxczftjMap = fxczftj.stream().filter(data -> month.equals(data.get("createTime"))).findFirst().orElse(null);
Map<String, Object> resultMap = new java.util.HashMap<>();
resultMap.put("date", month);
resultMap.put("zs", fxczftjMap != null ? fxczftjMap.get("zs") : 0); // 默认值设为0
return resultMap;
})
.collect(Collectors.toList());
return res;
}
}
}

View File

@ -0,0 +1,296 @@
package com.aisino.iles.lawenforcement.service;
import cn.hutool.core.util.StrUtil;
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.lawenforcement.model.Agency;
import com.aisino.iles.lawenforcement.model.Officer;
import com.aisino.iles.lawenforcement.model.Officer_;
import com.aisino.iles.lawenforcement.model.dto.OfficerDto;
import com.aisino.iles.lawenforcement.model.query.OfficerQuery;
import com.aisino.iles.lawenforcement.repository.AgencyRepository;
import com.aisino.iles.lawenforcement.repository.OfficerRepository;
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 java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
/**
* 执法人员服务类
*/
@Service
public class OfficerService {
private final OfficerRepository officerRepository;
private final AgencyRepository agencyRepo;
public OfficerService(OfficerRepository officerRepository,
AgencyRepository agencyRepo) {
this.officerRepository = officerRepository;
this.agencyRepo = agencyRepo;
}
/**
* 保存执法人员信息
*
* @param officer 执法人员信息
* @return 保存后的执法人员信息
*/
@Transactional
public Officer saveOfficer(Officer officer) {
// 基础去空格与校验
String name = StrUtil.trimToNull(officer.getOfficerName());
String lawNo = StrUtil.trimToNull(officer.getLawNo());
String certNo = StrUtil.trimToNull(officer.getCertificateNo());
String agencyId = StrUtil.trimToNull(officer.getAgencyId());
String contactPhone = StrUtil.trimToNull(officer.getContactPhone());
if (name == null) {
throw new IllegalArgumentException("执法人员姓名不能为空");
}
if (lawNo == null) {
throw new IllegalArgumentException("执法号不能为空");
}
if (agencyId == null) {
throw new IllegalArgumentException("所属执法机构不能为空");
}
// 机构存在性校验
agencyRepo.findById(agencyId).orElseThrow(() -> new IllegalArgumentException("所属执法机构不存在"));
officer.setOfficerName(name);
officer.setLawNo(lawNo);
officer.setCertificateNo(certNo);
officer.setAgencyId(agencyId);
officer.setContactPhone(contactPhone);
boolean isCreate = StrUtil.isBlank(officer.getOfficerId());
// 执法号唯一性
officerRepository.findByLawNo(lawNo)
.filter(existing -> isCreate || !existing.getOfficerId().equals(officer.getOfficerId()))
.ifPresent(e -> {
throw new IllegalStateException("执法号已存在");
});
// 执法证号唯一性可选字段若传入则校验唯一
if (StrUtil.isNotBlank(certNo)) {
officerRepository.findByCertificateNo(certNo)
.filter(existing -> isCreate || !existing.getOfficerId().equals(officer.getOfficerId()))
.ifPresent(e -> {
throw new IllegalStateException("执法证号已存在");
});
}
Officer saved = officerRepository.save(officer);
// 填充瞬态机构字段便于前端展示
populateAgencyTransientFields(saved);
return saved;
}
/**
* 批量保存执法人员信息
*
* @param officers 执法人员信息列表
* @return 保存后的执法人员信息列表
*/
@Transactional
public List<Officer> saveOfficers(List<Officer> officers) {
return officerRepository.saveAll(officers);
}
/**
* 根据ID查询执法人员信息
*
* @param officerId 执法人员ID
* @return 执法人员信息
*/
public Optional<Officer> findOfficerById(String officerId) {
return officerRepository.findById(officerId, "officer-with-agency")
.map(o -> {
populateAgencyTransientFields(o);
return o;
});
}
/**
* 根据系统用户id查询执法人员信息
*
* @param certificateNo 系统用户id
* @return 执法人员信息
*/
public Optional<Officer> findOfficerByCertificateNo(String certificateNo) {
return officerRepository.findWithAgencyByCertificateNo(certificateNo)
.map(o -> {
populateAgencyTransientFields(o);
return o;
});
}
/**
* 根据所属执法机构ID查询执法人员列表
*
* @param agencyId 执法机构ID
* @return 执法人员列表
*/
public List<OfficerDto> findOfficersByAgencyId(String agencyId) {
Optional<Agency> agencyOptional = agencyRepo.findById(agencyId);
if (agencyOptional.isPresent()) {
String agencyCode = agencyOptional.get().getAgencyCode();
return officerRepository.findByAgencyCodeLike(StringUtils.trimEven0(agencyCode) + "%");
} else {
throw new BusinessError("不存在此执法机构ID【" + agencyId + "");
}
}
/**
* 根据执法人员姓名模糊查询执法人员列表
*
* @param officerName 执法人员姓名
* @return 执法人员列表
*/
public List<Officer> findOfficersByOfficerName(String officerName) {
return officerRepository.findByOfficerNameContaining(officerName);
}
/**
* 分页查询执法人员信息
*
* @param officerQuery@return 分页执法人员信息
*/
public Page<Officer> findOfficersPage(OfficerQuery officerQuery) {
Page<Officer> page = officerRepository.findAll(
buildSpec(officerQuery),
PageableHelper.buildPageRequest(officerQuery.page(), officerQuery.pageSize(), officerQuery.sort(), officerQuery.dir()),
"officer-with-agency"
);
// 填充瞬态机构字段
page.getContent().forEach(this::populateAgencyTransientFields);
return page;
}
private Specification<Officer> buildSpec(OfficerQuery query) {
return (root, q, builder) -> {
List<Predicate> predicates = Stream.of(
Optional.ofNullable(query.getOfficerId())
.map(StrUtil::trimToNull)
.map(id -> builder.equal(root.get(Officer_.officerId), id)),
Optional.ofNullable(query.getOfficerName())
.map(StrUtil::trimToNull)
.map(name -> builder.like(root.get(Officer_.officerName), "%" + name + "%")),
Optional.ofNullable(query.getLawNo())
.map(StrUtil::trimToNull)
.map(no -> builder.equal(root.get(Officer_.lawNo), no)),
Optional.ofNullable(query.getCertificateNo())
.map(StrUtil::trimToNull)
.map(no -> builder.equal(root.get(Officer_.certificateNo), no)),
Optional.ofNullable(query.getAgencyId())
.map(StrUtil::trimToNull)
.map(aid -> builder.equal(root.get(Officer_.agencyId), aid)),
Optional.ofNullable(query.getContactPhone())
.map(StrUtil::trimToNull)
.map(p -> builder.like(root.get(Officer_.contactPhone), "%" + p + "%"))
).filter(Optional::isPresent)
.map(Optional::get)
.toList();
return builder.and(predicates.toArray(new Predicate[0]));
};
}
/**
* 条件查询执法人员信息
*
* @param spec 查询条件
* @return 执法人员信息列表
*/
public List<Officer> findOfficersBySpec(Specification<Officer> spec) {
return officerRepository.findAll(spec);
}
/**
* 根据ID删除执法人员信息
*
* @param officerId 执法人员ID
*/
@Transactional
public void deleteOfficerById(String officerId) {
officerRepository.deleteById(officerId);
}
/**
* 批量删除执法人员信息
*
* @param officerIds 执法人员ID列表
*/
@Transactional
public void deleteOfficersByIds(List<String> officerIds) {
officerRepository.deleteAllById(officerIds);
}
/**
* 检查执法人员是否存在
*
* @param officerId 执法人员ID
* @return 是否存在
*/
public boolean existsOfficerById(String officerId) {
return officerRepository.existsById(officerId);
}
/**
* 执法号是否已存在
*
* @param lawNo 执法号
* @param excludeOfficerId 排除的执法人员ID编辑场景传入自身ID
* @return true 表示已存在false 表示不存在
*/
public boolean existsLawNo(String lawNo, String excludeOfficerId) {
String no = StrUtil.trimToNull(lawNo);
if (no == null) return false;
return officerRepository.findByLawNo(no)
.filter(o -> excludeOfficerId == null || !o.getOfficerId().equals(excludeOfficerId))
.isPresent();
}
/**
* 获取执法人员总数
*
* @return 执法人员总数
*/
public long countOfficers() {
return officerRepository.count();
}
/**
* 查询执法人员列表
*
* @param query 查询条件
* @return 执法人员列表
*/
public List<Officer> listOfficers(OfficerQuery query) {
List<Officer> list = officerRepository.findAll(buildSpec(query), "officer-with-agency");
list.forEach(this::populateAgencyTransientFields);
return list;
}
/**
* 填充机构相关的瞬态字段便于前端直接展示
*/
private void populateAgencyTransientFields(Officer officer) {
if (officer == null || officer.getAgency() == null) return;
Agency a = officer.getAgency();
officer.setAgencyName(a.getAgencyName());
officer.setAgencyCode(a.getAgencyCode());
officer.setAgencySimpleCode(a.getAgencySimpleCode());
officer.setAgencyLevel(a.getAgencyLevel() == null ? null : a.getAgencyLevel().toString());
officer.setLeaf(a.getLeaf());
}
}

View File

@ -0,0 +1,225 @@
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.PageableHelper;
import com.aisino.iles.core.exception.BusinessError;
import com.aisino.iles.lawenforcement.model.EnforceCheck;
import com.aisino.iles.lawenforcement.model.EnforcementInfo;
import com.aisino.iles.lawenforcement.model.OnlinePatrol;
import com.aisino.iles.lawenforcement.model.dto.OnlinePatrolDto;
import com.aisino.iles.lawenforcement.model.enums.FlowNode;
import com.aisino.iles.lawenforcement.model.query.OnlinePatrolQuery;
import com.aisino.iles.lawenforcement.repository.OnlinePatrolRepository;
import com.aisino.iles.lawenforcement.repository.*;
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 org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@Service
public class OnlinePatrolService {
private final OnlinePatrolRepository onlinePatrolRepository;
private final EnforcementInfoRepository enforcementInfoRepository;
private final EnforceCheckRepository enforceCheckRepository;
private final FtpService ftpService;
private final ExecutorService fileUploadExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
public OnlinePatrolService(OnlinePatrolRepository onlinePatrolRepository,
EnforcementInfoRepository enforcementInfoRepository,
EnforceCheckRepository enforceCheckRepository,
FtpService ftpService) {
this.onlinePatrolRepository = onlinePatrolRepository;
this.enforcementInfoRepository = enforcementInfoRepository;
this.enforceCheckRepository = enforceCheckRepository;
this.ftpService = ftpService;
}
/**
* 保存在线巡查信息
*
* @param onlinePatrolDto 在线巡查信息
*/
@Transactional
public void saveOnlinePatrol(OnlinePatrolDto onlinePatrolDto) {
OnlinePatrol onlinePatrol = new OnlinePatrol();
onlinePatrol.setEnterpriseId(onlinePatrolDto.getEnterpriseId());
onlinePatrol.setAgencyId(onlinePatrolDto.getAgencyId());
onlinePatrol.setIsNormal(onlinePatrolDto.getIsNormal());
onlinePatrol.setDescription(onlinePatrolDto.getDescription());
onlinePatrol.setCreateTime(onlinePatrolDto.getCreateTime());
onlinePatrol.setApprovalStatus("0");
onlinePatrol.setCreateUserId(onlinePatrolDto.getCreateUserId());
onlinePatrol.setCreateUserName(onlinePatrolDto.getCreateUserName());
MultipartFile[] files = onlinePatrolDto.getFiles();
if (files != null && files.length > 0) {
List<Map<String, Object>> list = uploadAllFiles(files);
onlinePatrol.setAnnexs(list);
}
onlinePatrolRepository.save(onlinePatrol);
}
// 上传所有文件并返回结果
private List<Map<String, Object>> uploadAllFiles(MultipartFile[] files) {
// 1. 转换为List并过滤空文件
List<MultipartFile> validFiles = Arrays.stream(files).filter(file -> !file.isEmpty()).collect(Collectors.toList());
// 2. 创建上传任务
List<CompletableFuture<Map<String, Object>>> uploadFutures = validFiles.stream().map(this::uploadFile).collect(Collectors.toList());
// 3. 合并所有Future
CompletableFuture<Void> allFutures = CompletableFuture.allOf(uploadFutures.toArray(new CompletableFuture[0]));
// 4. 获取所有结果
return allFutures.thenApply(v -> uploadFutures.stream().map(CompletableFuture::join).collect(Collectors.toList())).join(); // 在当前线程等待完成
}
// 单个文件上传方法
private CompletableFuture<Map<String, Object>> uploadFile(MultipartFile file) {
return CompletableFuture.supplyAsync(() -> {
try {
String originalFilename = file.getOriginalFilename();
String fileExtension = getFileExtension(originalFilename);
// 上传文件
String url = ftpService.uploadTempFile(IndustryCategoryForFile.pub, originalFilename, file.getInputStream());
if (!StringUtils.hasText(url)) {
throw new BusinessError("文件上传失败: " + originalFilename);
}
// 构建返回结果
Map<String, Object> result = new HashMap<>();
result.put("name", originalFilename);
result.put("type", fileExtension);
result.put("savePathName", url);
result.put("downloadUrl", ftpService.getFileUrl(url));
result.put("size", file.getSize());
return result;
} catch (Exception e) {
throw new BusinessError("文件上传异常: " + file.getOriginalFilename(), e);
}
}, fileUploadExecutor); // 使用专用线程池
}
// 获取文件扩展名
private String getFileExtension(String filename) {
if (filename == null) {
return "";
}
int lastDotIndex = filename.lastIndexOf('.');
return lastDotIndex == -1 ? "" : filename.substring(lastDotIndex + 1);
}
/**
* 分页查询在线巡查信息
*
* @param query@return 分页在线巡查信息
*/
@Transactional(readOnly = true)
public Page<OnlinePatrol> findOnlinePatrolPage(OnlinePatrolQuery query) {
return onlinePatrolRepository
.findAll(buildSpecification(query), PageableHelper.buildPageRequest(query.page(), query.pageSize(), "createTime", "desc"))
.map(this::handleResult);
}
private Specification<OnlinePatrol> buildSpecification(OnlinePatrolQuery query) {
return Specification.where((root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
// predicates.add(criteriaBuilder.equal(root.get("approvalStatus"), "0"));
Optional.ofNullable(query.getIndustryType()).ifPresent(o -> predicates.add(criteriaBuilder.equal(root.get("enterprise").get("industryType"), o)));
Optional.ofNullable(query.getUnitName()).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get("enterprise").get("unitName"), "%"+ com.aisino.iles.common.util.StringUtils.trimEven0(o) + "%")));
Optional.ofNullable(query.getUnifiedSocialCode()).ifPresent(o -> predicates.add(criteriaBuilder.like(root.get("enterprise").get("unifiedSocialCode"), com.aisino.iles.common.util.StringUtils.trimEven0(o) + "%")));
// Optional.ofNullable(query.getCreateTimeArr()).filter(f -> f.length == 2).map(f -> {
// List<Predicate> ts = new ArrayList<>();
// Optional.ofNullable(f[0]).map(from -> criteriaBuilder.greaterThanOrEqualTo(root.get(EnforcementInfo_.createTime), from)).ifPresent(ts::add);
// Optional.ofNullable(f[1]).map(to -> criteriaBuilder.lessThanOrEqualTo(root.get(EnforcementInfo_.createTime), to)).ifPresent(ts::add);
// return ts;
// }).ifPresent(predicates::addAll);
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
});
}
private OnlinePatrol handleResult(OnlinePatrol onlinePatrol) {
Optional.ofNullable(onlinePatrol.getEnterprise()).ifPresent(enterprise -> enterprise.getUnitName());
Optional.ofNullable(onlinePatrol.getAgency()).ifPresent(agency -> agency.getAgencyName());
List<Map<String, Object>> annexs = onlinePatrol.getAnnexs();
if (annexs != null) {
annexs.forEach(annex -> {
String savePathName = annex.get("savePathName").toString();
String fileUrl = ftpService.getFileUrl(savePathName);
annex.put("downloadUrl", fileUrl);
});
onlinePatrol.setAnnexs(annexs);
}
return onlinePatrol;
}
/**
* 保存在线巡查信息
*
* @param onlinePatrolDto 在线巡查审批信息
*/
@Transactional
public void saveOnlinePatrolApproval(OnlinePatrolDto onlinePatrolDto, RemoteUserInfo user) {
String approvalStatus = onlinePatrolDto.getApprovalStatus();
if ("1".equals(approvalStatus)) {
EnforcementInfo enforcementInfo = new EnforcementInfo();
enforcementInfo.setEnterpriseId(onlinePatrolDto.getEnterpriseId());
enforcementInfo.setAgencyId(onlinePatrolDto.getAgencyId());
enforcementInfo.setCurrentNodeCode(FlowNode.plan_approval);
enforcementInfo.setCurrentNode("方案待审批");
enforcementInfo.setDataFrom("7");
enforcementInfo.setCreateTime(LocalDateTime.now());
enforcementInfoRepository.save(enforcementInfo);
EnforceCheck enforceCheck = new EnforceCheck();
Optional.ofNullable(onlinePatrolDto.getCheckItemIds()).ifPresent(ids -> enforceCheck.setCheckItemIds(String.join(",", ids)));
enforceCheck.setCheckType(onlinePatrolDto.getCheckType());
enforceCheck.setEnforcementId(enforcementInfo.getEnforcementId());
enforceCheck.setCreateTime(LocalDateTime.now());
enforceCheck.setCheckStatus("1");
enforceCheck.setCheckFlag("1");
enforceCheck.setWriterId(user.getYhwybs());
enforceCheck.setCreatedBy(user.getXm());
enforceCheck.setCreatedAccountBy(user.getYhwybs());
enforceCheckRepository.save(enforceCheck);
onlinePatrolRepository
.findById(onlinePatrolDto.getOnlinePatrolId())
.ifPresent(onlinePatrol -> {
onlinePatrol.setApprovalStatus("1");
onlinePatrol.setApprovalUserId(onlinePatrolDto.getApprovalUserId());
onlinePatrol.setApprovalUserName(onlinePatrolDto.getApprovalUserName());
onlinePatrol.setApprovalReceipt(onlinePatrolDto.getApprovalReceipt());
onlinePatrol.setIsCreateEnforce("1");
onlinePatrol.setEnforcementId(enforcementInfo.getEnforcementId());
onlinePatrolRepository.save(onlinePatrol);
});
} else {
onlinePatrolRepository
.findById(onlinePatrolDto.getOnlinePatrolId())
.ifPresent(onlinePatrol -> {
onlinePatrol.setApprovalStatus("2");
onlinePatrol.setApprovalUserId(onlinePatrolDto.getApprovalUserId());
onlinePatrol.setApprovalUserName(onlinePatrolDto.getApprovalUserName());
onlinePatrol.setApprovalReceipt(onlinePatrolDto.getApprovalReceipt());
onlinePatrol.setIsCreateEnforce("2");
onlinePatrolRepository.save(onlinePatrol);
});
}
}
}