车辆三检批量审核

This commit is contained in:
2026-06-17 10:36:39 +08:00
parent c737dd5571
commit f21c57943c
6 changed files with 366 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ package com.hotwj.platform.config.vehicleThreeInspect.controller;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectBatchAuditBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectMultiVehicleBatchAuditBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectProcessVo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectVehicleQueryBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectReceivedVehicleVo;
@@ -224,6 +225,27 @@ public class HotVehicleThreeInspectController extends BaseController {
return hotVehicleThreeInspectService.querySummaryPageList(bo, pageQuery);
}
/**
* 查询当前人员可进行多车辆批量审核的车辆三检列表
*/
@GetMapping("/multiVehicleBatchAudit/list")
@Operation(summary = "分页查询当前人员可进行多车辆批量审核的车辆三检列表")
public TableDataInfo<HotVehicleThreeInspectSummaryVo> listMultiVehicleBatchAudit(HotVehicleThreeInspectVehicleQueryBo bo, PageQuery pageQuery) {
return hotVehicleThreeInspectService.queryBatchAuditVehiclePageList(bo, pageQuery);
}
/**
* 多车辆批量审核车辆三检
*/
@Log(title = "车辆三检多车辆批量审核", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PostMapping("/multiVehicleBatchAudit")
@Operation(summary = "多车辆批量审核车辆三检")
public R<Void> multiVehicleBatchAudit(@Validated @RequestBody HotVehicleThreeInspectMultiVehicleBatchAuditBo bo) {
hotVehicleThreeInspectService.multiVehicleBatchAudit(bo);
return R.ok();
}
/**
* 查询车辆三检历史记录列表
*/

View File

@@ -0,0 +1,57 @@
package com.hotwj.platform.config.vehicleThreeInspect.domain.bo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Date;
import java.util.List;
/**
* 车辆三检多车辆批量审核业务对象
*
* @author shihongwei
* @date 2026-06-17
*/
@Data
public class HotVehicleThreeInspectMultiVehicleBatchAuditBo {
/**
* 三检流程ID集合
*/
@NotEmpty(message = "三检流程ID不能为空")
private List<Long> inspectIds;
/**
* 是否存在隐患 0=否, 1=是
*/
@NotNull(message = "是否存在隐患不能为空")
private Long hasHiddenDanger;
/**
* 评估人ID
*/
private Long evaluatorId;
/**
* 审核时间
*/
private Date auditTime;
/**
* 审核结论
*/
private String auditResult;
/**
* 审核不通过原因
*/
private String rejectReason;
/**
* 审核人员签名图片url
*/
@NotBlank(message = "审核人员签名不能为空")
private String auditorSignImgUrl;
}

View File

@@ -57,6 +57,20 @@ public interface HotVehicleThreeInspectMapper extends BaseMapperPlus<HotVehicleT
@Param("bo") HotVehicleThreeInspectBo bo
);
/**
* 分页查询当前人员可进行多车辆批量审核的车辆三检聚合列表
*
* @param page 分页参数
* @param bo 查询条件
* @param auditorId 当前审核人ID
* @return 聚合分页列表
*/
Page<HotVehicleThreeInspectSummaryVo> queryBatchAuditVehiclePageList(
Page<HotVehicleThreeInspectSummaryVo> page,
@Param("bo") HotVehicleThreeInspectVehicleQueryBo bo,
@Param("auditorId") Long auditorId
);
/**
* 按流程ID查询车辆三检聚合详情
*

View File

@@ -2,6 +2,7 @@ package com.hotwj.platform.config.vehicleThreeInspect.service;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectBatchAuditBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectMultiVehicleBatchAuditBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectVehicleQueryBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectProcessVo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectReceivedVehicleVo;
@@ -82,6 +83,15 @@ public interface IHotVehicleThreeInspectService {
*/
TableDataInfo<HotVehicleThreeInspectSummaryVo> querySummaryPageList(HotVehicleThreeInspectBo bo, PageQuery pageQuery);
/**
* 分页查询当前人员可进行多车辆批量审核的三检流程列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 聚合分页列表
*/
TableDataInfo<HotVehicleThreeInspectSummaryVo> queryBatchAuditVehiclePageList(HotVehicleThreeInspectVehicleQueryBo bo, PageQuery pageQuery);
/**
* 查询车辆三检历史记录分页列表
*
@@ -181,4 +191,11 @@ public interface IHotVehicleThreeInspectService {
* @param bo 批量审核业务对象
*/
void batchAudit(HotVehicleThreeInspectBatchAuditBo bo);
/**
* 多车辆批量审核车辆三检
*
* @param bo 多车辆批量审核业务对象
*/
void multiVehicleBatchAudit(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo);
}

View File

@@ -10,6 +10,7 @@ import com.hotwj.platform.common.helper.DriverLoginContextHelper;
import com.hotwj.platform.config.vehicleThreeInspect.domain.HotVehicleThreeInspect;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectBatchAuditBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectMultiVehicleBatchAuditBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.bo.HotVehicleThreeInspectVehicleQueryBo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectProcessVo;
import com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectReceivedVehicleVo;
@@ -33,6 +34,7 @@ import com.hotwj.platform.securityManagement.vehicleInoutCheck.mapper.HotVehicle
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.domain.model.LoginUser;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
@@ -47,10 +49,13 @@ import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.Collections;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -224,6 +229,20 @@ public class HotVehicleThreeInspectServiceImpl implements IHotVehicleThreeInspec
return TableDataInfo.build(result);
}
@Override
public TableDataInfo<HotVehicleThreeInspectSummaryVo> queryBatchAuditVehiclePageList(HotVehicleThreeInspectVehicleQueryBo bo, PageQuery pageQuery) {
Long currentAuditorId = resolveCurrentAuditorId();
LoginUser loginUser = LoginHelper.getLoginUser();
if (bo == null) {
bo = new HotVehicleThreeInspectVehicleQueryBo();
}
if (bo.getCompanyId() == null && loginUser != null) {
bo.setCompanyId(loginUser.getCompanyId());
}
Page<HotVehicleThreeInspectSummaryVo> result = baseMapper.queryBatchAuditVehiclePageList(pageQuery.build(), bo, currentAuditorId);
return TableDataInfo.build(result);
}
@Override
public TableDataInfo<HotVehicleThreeInspectSummaryVo> queryHistoryPageList(HotVehicleThreeInspectBo bo, PageQuery pageQuery) {
return querySummaryPageList(bo, pageQuery);
@@ -701,6 +720,15 @@ public class HotVehicleThreeInspectServiceImpl implements IHotVehicleThreeInspec
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void multiVehicleBatchAudit(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo) {
validateMultiVehicleBatchAuditRequest(bo);
HotVehicleThreeInspectBatchAuditBo batchAuditBo = new HotVehicleThreeInspectBatchAuditBo();
batchAuditBo.setAuditItems(buildMultiVehicleBatchAuditItems(bo));
batchAudit(batchAuditBo);
}
private void validateBatchAuditAuditor(HotVehicleThreeInspectBatchAuditBo bo) {
Long expectedAuditorId = null;
String expectedAuditorName = null;
@@ -856,6 +884,164 @@ public class HotVehicleThreeInspectServiceImpl implements IHotVehicleThreeInspec
}
}
private void validateMultiVehicleBatchAuditRequest(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo) {
if (bo == null || bo.getInspectIds() == null || bo.getInspectIds().isEmpty()) {
throw new ServiceException("三检流程ID不能为空");
}
if (Objects.equals(bo.getHasHiddenDanger(), 1L) && bo.getEvaluatorId() == null) {
throw new ServiceException("存在隐患时评估人不能为空");
}
}
private List<HotVehicleThreeInspectBo> buildMultiVehicleBatchAuditItems(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo) {
Long currentAuditorId = resolveCurrentAuditorId();
Long currentCompanyId = resolveCurrentCompanyId();
LinkedHashSet<Long> inspectIdSet = new LinkedHashSet<>();
for (Long inspectId : bo.getInspectIds()) {
if (inspectId != null) {
inspectIdSet.add(inspectId);
}
}
if (inspectIdSet.isEmpty()) {
throw new ServiceException("三检流程ID不能为空");
}
List<HotVehicleThreeInspectVo> detailList = baseMapper.querySummaryDetailList(new ArrayList<>(inspectIdSet));
if (detailList == null || detailList.isEmpty()) {
throw new ServiceException("未查询到可批量审核的车辆三检数据");
}
fillTaskId(detailList);
Map<Long, List<HotVehicleThreeInspectVo>> detailMap = new LinkedHashMap<>();
for (HotVehicleThreeInspectVo detail : detailList) {
if (detail == null || detail.getInspectId() == null) {
continue;
}
detailMap.computeIfAbsent(detail.getInspectId(), key -> new ArrayList<>()).add(detail);
}
Date auditTime = resolveBatchAuditTime(bo);
String auditResult = buildBatchAuditResult(bo);
List<HotVehicleThreeInspectBo> auditItems = new ArrayList<>();
for (Long inspectId : inspectIdSet) {
List<HotVehicleThreeInspectVo> currentDetails = detailMap.get(inspectId);
if (currentDetails == null || currentDetails.isEmpty()) {
throw new ServiceException("三检流程不存在inspectId=" + inspectId);
}
appendPendingAuditItems(bo, currentDetails, currentAuditorId, currentCompanyId, auditTime, auditResult, auditItems);
}
if (auditItems.isEmpty()) {
throw new ServiceException("没有符合批量审核条件的数据");
}
return auditItems;
}
private void appendPendingAuditItems(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo,
List<HotVehicleThreeInspectVo> currentDetails,
Long currentAuditorId,
Long currentCompanyId,
Date auditTime,
String auditResult,
List<HotVehicleThreeInspectBo> auditItems) {
boolean hasBackCheck = false;
String plateNumber = null;
int pendingCount = 0;
for (HotVehicleThreeInspectVo detail : currentDetails) {
if (detail == null) {
continue;
}
if (Objects.equals(detail.getInspectPhase(), 3L)) {
hasBackCheck = true;
}
if (StringUtils.isBlank(plateNumber)) {
plateNumber = resolvePlateNumber(detail.getVehicleId());
}
}
if (!hasBackCheck) {
throw new ServiceException(buildBatchAuditVehicleMessage(plateNumber, "尚未完成收车检查,不可批量审核"));
}
for (HotVehicleThreeInspectVo detail : currentDetails) {
if (detail == null) {
continue;
}
if (currentCompanyId != null && !Objects.equals(currentCompanyId, detail.getCompanyId())) {
continue;
}
if (!Objects.equals(currentAuditorId, detail.getAuditorId())) {
continue;
}
if (!isPendingAuditRecord(detail)) {
continue;
}
if (StringUtils.isBlank(detail.getTaskId())) {
continue;
}
HotVehicleThreeInspectBo item = new HotVehicleThreeInspectBo();
item.setId(detail.getId());
item.setTaskId(detail.getTaskId());
item.setAuditTime(auditTime);
item.setHasHiddenDanger(bo.getHasHiddenDanger());
item.setAuditResult(auditResult);
item.setRejectReason(bo.getRejectReason());
item.setAuditorSignImgUrl(bo.getAuditorSignImgUrl());
item.setAuditorId(detail.getAuditorId());
item.setAuditorName(detail.getAuditorName());
item.setEvaluatorId(bo.getEvaluatorId());
auditItems.add(item);
pendingCount++;
}
if (pendingCount == 0) {
throw new ServiceException(buildBatchAuditVehicleMessage(plateNumber, "没有当前账号可审核的未审核数据"));
}
}
private boolean isPendingAuditRecord(HotVehicleThreeInspectVo detail) {
if (detail == null) {
return false;
}
return !"APPROVED".equals(detail.getFlowStatus()) && !"REJECTED".equals(detail.getFlowStatus());
}
private Date resolveBatchAuditTime(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo) {
return bo.getAuditTime() != null ? bo.getAuditTime() : new Date();
}
private String buildBatchAuditResult(HotVehicleThreeInspectMultiVehicleBatchAuditBo bo) {
String auditResult = StringUtils.trimToNull(bo.getAuditResult());
if (auditResult != null) {
return auditResult;
}
if (Objects.equals(bo.getHasHiddenDanger(), 1L)) {
String rejectReason = StringUtils.trimToNull(bo.getRejectReason());
return rejectReason != null ? "不通过:" + rejectReason : "不通过";
}
return "通过";
}
private String buildBatchAuditVehicleMessage(String plateNumber, String suffix) {
String vehicleName = StringUtils.defaultIfBlank(StringUtils.trimToNull(plateNumber), "当前车辆");
return vehicleName + suffix;
}
private Long resolveCurrentAuditorId() {
String businessUserId = LoginHelper.getBusinessUserId();
if (StringUtils.isBlank(businessUserId)) {
throw new ServiceException("当前登录人员不存在");
}
try {
return Long.valueOf(businessUserId);
} catch (NumberFormatException e) {
throw new ServiceException("当前登录人员信息异常");
}
}
private Long resolveCurrentCompanyId() {
LoginUser loginUser = LoginHelper.getLoginUser();
return loginUser != null ? loginUser.getCompanyId() : null;
}
private void refreshSummary(HotVehicleThreeInspectSummaryVo summary) {
if (summary == null) {
return;
@@ -973,6 +1159,14 @@ public class HotVehicleThreeInspectServiceImpl implements IHotVehicleThreeInspec
return normalized.substring(normalized.length() - 3);
}
private String resolvePlateNumber(Long vehicleId) {
if (vehicleId == null) {
return null;
}
HotVehicle vehicle = hotVehicleMapper.selectById(String.valueOf(vehicleId));
return vehicle == null ? null : StringUtils.trimToNull(vehicle.getPlateNumber());
}
private String randomFourDigits() {
return String.format("%04d", ThreadLocalRandom.current().nextInt(1000, 10000));
}

View File

@@ -268,6 +268,68 @@
GROUP BY t.inspect_id
</select>
<select id="queryBatchAuditVehiclePageList"
resultType="com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectSummaryVo">
SELECT
t.inspect_id AS inspectId,
MAX(t.inspect_no) AS inspectNo,
MAX(t.company_id) AS companyId,
MAX(t.vehicle_id) AS vehicleId,
MAX(v.plate_number) AS plateNumber,
MAX(t.driver_id) AS driverId,
MAX(t.driver_name) AS driverName,
MAX(t.driver_name) AS inspectorName,
MAX(CASE WHEN t.auditor_id = #{auditorId} THEN t.auditor_name END) AS auditorName,
MIN(IFNULL(t.inspect_time, t.create_time)) AS startTime,
MAX(IFNULL(t.inspect_time, t.create_time)) AS endTime,
CASE
WHEN MIN(IFNULL(t.inspect_time, t.create_time)) = MAX(IFNULL(t.inspect_time, t.create_time))
THEN DATE_FORMAT(MIN(IFNULL(t.inspect_time, t.create_time)), '%Y-%m-%d %H:%i:%s')
ELSE CONCAT(
DATE_FORMAT(MIN(IFNULL(t.inspect_time, t.create_time)), '%Y-%m-%d %H:%i:%s'),
' ~ ',
DATE_FORMAT(MAX(IFNULL(t.inspect_time, t.create_time)), '%Y-%m-%d %H:%i:%s')
)
END AS inspectTime,
'已完成' AS completeStatus,
1 AS completed,
CASE
WHEN COUNT(DISTINCT CASE WHEN t.inspect_phase IS NOT NULL THEN t.inspect_phase END) > 0
AND COUNT(DISTINCT CASE WHEN t.inspect_phase IS NOT NULL THEN t.inspect_phase END)
= COUNT(DISTINCT CASE WHEN t.flow_status = 'APPROVED' THEN t.inspect_phase END)
THEN '已完成审核'
ELSE '未审核'
END AS auditCompleteStatus,
CASE
WHEN COUNT(DISTINCT CASE WHEN t.inspect_phase IS NOT NULL THEN t.inspect_phase END) > 0
AND COUNT(DISTINCT CASE WHEN t.inspect_phase IS NOT NULL THEN t.inspect_phase END)
= COUNT(DISTINCT CASE WHEN t.flow_status = 'APPROVED' THEN t.inspect_phase END)
THEN 1
ELSE 0
END AS auditCompleted
FROM hot_vehicle_three_inspect t
LEFT JOIN hot_vehicle v ON t.vehicle_id = v.id
<where>
t.is_deleted = 0
AND t.inspect_id IS NOT NULL
<if test="bo.companyId != null">
AND t.company_id = #{bo.companyId}
</if>
<if test="bo.plateNumber != null and bo.plateNumber != ''">
AND v.plate_number LIKE CONCAT('%', #{bo.plateNumber}, '%')
</if>
</where>
GROUP BY t.inspect_id
HAVING SUM(CASE WHEN t.inspect_phase = 3 THEN 1 ELSE 0 END) > 0
AND SUM(CASE
WHEN t.auditor_id = #{auditorId}
AND (t.flow_status IS NULL OR t.flow_status NOT IN ('APPROVED', 'REJECTED'))
THEN 1
ELSE 0
END) > 0
ORDER BY IFNULL(MAX(t.inspect_time), MAX(t.create_time)) DESC, MAX(t.create_time) DESC
</select>
<select id="selectPrintList"
resultType="com.hotwj.platform.config.vehicleThreeInspect.domain.vo.HotVehicleThreeInspectPrintVo">
WITH base AS (