diff --git a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java index d5b6beb..7317b8a 100644 --- a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java +++ b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java @@ -9,6 +9,7 @@ import org.qinan.safetyeval.client.co.QualFilingChangeCO; import org.qinan.safetyeval.client.co.QualFilingChangeComplianceCheckResultCO; import org.qinan.safetyeval.client.co.QualFilingChangeOrgCO; import org.qinan.safetyeval.client.dto.*; +import org.qinan.safetyeval.domain.constant.QualFilingStatusEnum; import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter; import org.qinan.safetyeval.infrastructure.dataobject.base.Req; import org.springframework.validation.annotation.Validated; @@ -63,6 +64,7 @@ public class QualFilingChangeController { @ApiOperation("聚合新增or编辑资质备案变更申请") @PostMapping("/aggregationSaveOrEdit") public SingleResponse aggregationSaveOrEdit(@RequestBody AggregationSaveOrEditQualFilingChangeCmd cmd) { + cmd.getQualFilingChangeAddCmd().setFilingStatusCode(QualFilingStatusEnum.CHANGE_REVIEWING.getCode()); return qualFilingChangeApi.aggregationSaveOrEdit(cmd); } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java index b97e246..064df2d 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java @@ -23,6 +23,7 @@ import org.qinan.safetyeval.domain.service.QualFilingDomainService; import org.qinan.safetyeval.domain.service.QualFilingReviewDomainService; import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter; import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter; +import org.qinan.safetyeval.infrastructure.dataobject.QualFilingChangeCountDO; import org.qinan.safetyeval.infrastructure.mapper.QualFilingChangeMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; @@ -31,10 +32,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.stream.Collectors; /** @@ -168,7 +166,6 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { domainQuery.setPageNum(query.getCurrent()); domainQuery.setPageSize(query.getSize()); domainQuery.setTenantId(AuthUserContextAdapter.getCurrentTenantId()); - domainQuery.setOrgId(ThreadLocalUserInfoAdapter.getOrgId()); domainQuery.setFilingNo(query.getFilingNo()); domainQuery.setFilingStatusCode(query.getFilingStatusCode()); PageResult pageResult = qualFilingChangeDomainService.page(domainQuery); @@ -189,7 +186,24 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { // 直连 infrastructure 层 Mapper,跳过 domain,由 XML 直接返回 CO,无需转换 Page page = new Page<>(domainQuery.getPageNum(), domainQuery.getPageSize()); IPage result = qualFilingChangeMapper.orgPage(page, domainQuery); - return PageResponse.of(result.getRecords(), result.getTotal()); + + // 存在数据时,一次批量统计每个 filingId 在 qual_filing_change 表中的变更次数 + List records = result.getRecords(); + if (!CollectionUtils.isEmpty(records)) { + List filingIds = records.stream() + .map(QualFilingChangeOrgCO::getFilingId) + .filter(Objects::nonNull) + .distinct() + .collect(Collectors.toList()); + List countList = qualFilingChangeMapper.countByFilingIds(filingIds); + Map countMap = countList.stream() + .collect(Collectors.toMap( + QualFilingChangeCountDO::getFilingId, + QualFilingChangeCountDO::getChangeCount)); + records.forEach(co -> co.setChangeCount(countMap.getOrDefault(co.getFilingId(), 1L) - 1)); + } + + return PageResponse.of(records, result.getTotal()); } @Override diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeAddCmd.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeAddCmd.java index 26ca20a..52e4c70 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeAddCmd.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeAddCmd.java @@ -1,7 +1,10 @@ package org.qinan.safetyeval.client.change.request; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.qinan.safetyeval.client.common.jackson.DateToLocalDateTimeDeserializer; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -69,11 +72,15 @@ public class QualFilingPersonnelChangeAddCmd implements Serializable { * 出生日期 */ @ApiModelProperty(value = "出生日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @JsonDeserialize(using = DateToLocalDateTimeDeserializer.class) private LocalDateTime birthDate; /** * 参加工作时间 */ @ApiModelProperty(value = "参加工作时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @JsonDeserialize(using = DateToLocalDateTimeDeserializer.class) private LocalDateTime joinWorkDate; /** * 身份证号 diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeUpdateCmd.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeUpdateCmd.java index cd88557..09b002c 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeUpdateCmd.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/change/request/QualFilingPersonnelChangeUpdateCmd.java @@ -1,8 +1,10 @@ package org.qinan.safetyeval.client.change.request; import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import io.swagger.annotations.ApiModelProperty; import lombok.Data; +import org.qinan.safetyeval.client.common.jackson.DateToLocalDateTimeDeserializer; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -71,11 +73,15 @@ public class QualFilingPersonnelChangeUpdateCmd implements Serializable { * 出生日期 */ @ApiModelProperty(value = "出生日期") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @JsonDeserialize(using = DateToLocalDateTimeDeserializer.class) private LocalDateTime birthDate; /** * 参加工作时间 */ @ApiModelProperty(value = "参加工作时间") + @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") + @JsonDeserialize(using = DateToLocalDateTimeDeserializer.class) private LocalDateTime joinWorkDate; /** * 身份证号 diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeOrgCO.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeOrgCO.java index f98d612..60ec84f 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeOrgCO.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeOrgCO.java @@ -113,4 +113,7 @@ public class QualFilingChangeOrgCO { @ApiModelProperty(value = "租户ID") private Long tenantId; + + @ApiModelProperty(value = "变更次数") + private Long changeCount; } diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/common/jackson/DateToLocalDateTimeDeserializer.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/common/jackson/DateToLocalDateTimeDeserializer.java new file mode 100644 index 0000000..cae5f13 --- /dev/null +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/common/jackson/DateToLocalDateTimeDeserializer.java @@ -0,0 +1,46 @@ +package org.qinan.safetyeval.client.common.jackson; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 兼容前端仅传递日期(yyyy-MM-dd)的 LocalDateTime 反序列化器。 + *

+ * 当入参为 "yyyy-MM-dd" 时补全为当天 00:00:00; + * 当入参为标准日期时间(如 "yyyy-MM-dd HH:mm:ss" / "yyyy-MM-dd'T'HH:mm:ss")时按原值解析。 + * + * @Author: ltq + * @date 2026-07-07 + */ +public class DateToLocalDateTimeDeserializer extends JsonDeserializer { + + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Override + public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + String text = p.getText(); + if (text == null || text.trim().isEmpty()) { + return null; + } + String value = text.trim(); + try { + return LocalDateTime.parse(value); + } catch (Exception ignore) { + // 继续尝试其它格式 + } + try { + return LocalDateTime.parse(value, DATE_TIME_FORMATTER); + } catch (Exception ignore) { + // 继续尝试日期格式 + } + // 仅日期格式: 补全为当天 00:00:00 + return LocalDate.parse(value, DATE_FORMATTER).atStartOfDay(); + } +} diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/dataobject/QualFilingChangeCountDO.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/dataobject/QualFilingChangeCountDO.java new file mode 100644 index 0000000..3fc2f15 --- /dev/null +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/dataobject/QualFilingChangeCountDO.java @@ -0,0 +1,16 @@ +package org.qinan.safetyeval.infrastructure.dataobject; + +import lombok.Data; + +/** + * 备案变更次数统计结果 + * + * @author safety-eval + */ +@Data +public class QualFilingChangeCountDO { + + private Long filingId; + + private Long changeCount; +} diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/mapper/QualFilingChangeMapper.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/mapper/QualFilingChangeMapper.java index 32ab04a..6a2936c 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/mapper/QualFilingChangeMapper.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/mapper/QualFilingChangeMapper.java @@ -6,8 +6,12 @@ import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.qinan.safetyeval.client.co.QualFilingChangeOrgCO; import org.qinan.safetyeval.domain.query.QualFilingChangeQuery; +import org.qinan.safetyeval.infrastructure.dataobject.QualFilingChangeCountDO; import org.qinan.safetyeval.infrastructure.dataobject.QualFilingChangeDO; +import java.util.Collection; +import java.util.List; + @Mapper public interface QualFilingChangeMapper extends BaseMapper { @@ -15,4 +19,9 @@ public interface QualFilingChangeMapper extends BaseMapper { * 机构端分页查询:每个filing_id只取最新一条变更记录,直接返回CO */ IPage orgPage(IPage page, @Param("query") QualFilingChangeQuery query); + + /** + * 按 filing_id 批量统计变更次数 + */ + List countByFilingIds(@Param("filingIds") Collection filingIds); } diff --git a/safety-eval-infrastructure/src/main/resources/mapper/QualFilingChangeMapper.xml b/safety-eval-infrastructure/src/main/resources/mapper/QualFilingChangeMapper.xml index 3201a32..3e17656 100644 --- a/safety-eval-infrastructure/src/main/resources/mapper/QualFilingChangeMapper.xml +++ b/safety-eval-infrastructure/src/main/resources/mapper/QualFilingChangeMapper.xml @@ -108,4 +108,16 @@ WHERE temp.rn = 1 + + +