work join date

dev-deployment
luotaiqian 2026-07-01 11:03:58 +08:00
parent 0ca52c4077
commit a5a30f8d7e
13 changed files with 268 additions and 43 deletions

View File

@ -4,6 +4,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.qinan.safetyeval.client.api.QualFilingApi; import org.qinan.safetyeval.client.api.QualFilingApi;
import org.qinan.safetyeval.client.co.QualFilingCO; import org.qinan.safetyeval.client.co.QualFilingCO;
import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO;
import org.qinan.safetyeval.client.co.QualFilingDetailCO; import org.qinan.safetyeval.client.co.QualFilingDetailCO;
import org.qinan.safetyeval.client.dto.PageResponse; import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse; import org.qinan.safetyeval.client.dto.SingleResponse;
@ -137,4 +138,10 @@ public class QualFilingController {
public PageResponse<QualFilingCO> page(@Validated QualFilingPageQuery query) { public PageResponse<QualFilingCO> page(@Validated QualFilingPageQuery query) {
return qualFilingApi.page(query); return qualFilingApi.page(query);
} }
@ApiOperation("合规检查")
@GetMapping("/compliance-check")
public SingleResponse<List<QualFilingComplianceCheckResultCO>> complianceCheck(@RequestParam Long id) {
return qualFilingApi.complianceCheck(id);
}
} }

View File

@ -3,6 +3,7 @@ package org.qinan.safetyeval.app.executor;
import org.qinan.safetyeval.app.orchestrator.QualFilingOrchestrator; import org.qinan.safetyeval.app.orchestrator.QualFilingOrchestrator;
import org.qinan.safetyeval.client.api.QualFilingApi; import org.qinan.safetyeval.client.api.QualFilingApi;
import org.qinan.safetyeval.client.co.QualFilingCO; import org.qinan.safetyeval.client.co.QualFilingCO;
import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO;
import org.qinan.safetyeval.client.co.QualFilingDetailCO; import org.qinan.safetyeval.client.co.QualFilingDetailCO;
import org.qinan.safetyeval.client.dto.PageResponse; import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse; import org.qinan.safetyeval.client.dto.SingleResponse;
@ -20,6 +21,7 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
/** /**
* App * App
@ -130,6 +132,11 @@ public class QualFilingExecutor implements QualFilingApi {
return SingleResponse.success(qualFilingOrchestrator.uploadMainAttachment(cmd.getId(), cmd.getAttachmentUrl())); return SingleResponse.success(qualFilingOrchestrator.uploadMainAttachment(cmd.getId(), cmd.getAttachmentUrl()));
} }
@Override
public SingleResponse<List<QualFilingComplianceCheckResultCO>> complianceCheck(Long id) {
return SingleResponse.success(qualFilingOrchestrator.complianceCheck(id));
}
private QualFilingCO toLegacyCO(QualFilingEntity entity) { private QualFilingCO toLegacyCO(QualFilingEntity entity) {
if (entity == null) { if (entity == null) {
return null; return null;

View File

@ -1,44 +1,14 @@
package org.qinan.safetyeval.app.orchestrator; package org.qinan.safetyeval.app.orchestrator;
import org.qinan.safetyeval.app.support.QualFilingAttachmentHelper; import org.qinan.safetyeval.app.support.*;
import org.qinan.safetyeval.app.support.QualFilingChangeDiffer; import org.qinan.safetyeval.client.co.*;
import org.qinan.safetyeval.app.support.QualFilingMaterialTemplateProvider;
import org.qinan.safetyeval.app.support.QualFilingOrgEquipmentImporter;
import org.qinan.safetyeval.app.support.QualFilingOrgPersonnelImporter;
import org.qinan.safetyeval.app.support.QualFilingStatusGuard;
import org.qinan.safetyeval.client.co.QualFilingChangeHistoryCO;
import org.qinan.safetyeval.client.co.QualFilingChangeHistoryItemCO;
import org.qinan.safetyeval.client.co.QualFilingCO;
import org.qinan.safetyeval.client.co.QualFilingCommitmentCO;
import org.qinan.safetyeval.client.co.QualFilingDetailCO;
import org.qinan.safetyeval.client.co.QualFilingEquipmentCO;
import org.qinan.safetyeval.client.co.QualFilingMaterialCO;
import org.qinan.safetyeval.client.co.QualFilingPersonnelCO;
import org.qinan.safetyeval.client.dto.QualFilingModifyCmd; import org.qinan.safetyeval.client.dto.QualFilingModifyCmd;
import org.qinan.safetyeval.client.dto.QualFilingPageQuery; import org.qinan.safetyeval.client.dto.QualFilingPageQuery;
import org.qinan.safetyeval.domain.constant.QualFilingApplyTypeEnum; import org.qinan.safetyeval.domain.constant.*;
import org.qinan.safetyeval.domain.constant.QualFilingMaterialUploadStatusEnum; import org.qinan.safetyeval.domain.entity.*;
import org.qinan.safetyeval.domain.constant.QualFilingStatusEnum;
import org.qinan.safetyeval.domain.entity.OrgInfoEntity;
import org.qinan.safetyeval.domain.entity.QualFilingChangeDetailEntity;
import org.qinan.safetyeval.domain.entity.QualFilingChangeEntity;
import org.qinan.safetyeval.domain.entity.QualFilingCommitmentEntity;
import org.qinan.safetyeval.domain.entity.QualFilingEntity;
import org.qinan.safetyeval.domain.entity.QualFilingEquipmentEntity;
import org.qinan.safetyeval.domain.entity.QualFilingMaterialEntity;
import org.qinan.safetyeval.domain.entity.QualFilingPersonnelCertEntity;
import org.qinan.safetyeval.domain.entity.QualFilingPersonnelEntity;
import org.qinan.safetyeval.domain.exception.BizException; import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.domain.exception.ErrorCode; import org.qinan.safetyeval.domain.exception.ErrorCode;
import org.qinan.safetyeval.domain.gateway.OrgInfoGateway; import org.qinan.safetyeval.domain.gateway.*;
import org.qinan.safetyeval.domain.gateway.QualFilingChangeDetailGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingChangeGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingCommitmentGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingEquipmentGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingMaterialGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingPersonnelCertGateway;
import org.qinan.safetyeval.domain.gateway.QualFilingPersonnelGateway;
import org.qinan.safetyeval.domain.query.PageResult; import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.query.QualFilingQuery; import org.qinan.safetyeval.domain.query.QualFilingQuery;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter; import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
@ -50,7 +20,11 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -139,7 +113,9 @@ public class QualFilingOrchestrator {
return toCO(saved); return toCO(saved);
} }
/** 用户点击暂存:暂存保持;已打回保持原状态 */ /**
*
*/
private void markDraftSaved(QualFilingEntity filing) { private void markDraftSaved(QualFilingEntity filing) {
Integer code = filing.getFilingStatusCode(); Integer code = filing.getFilingStatusCode();
if (code == null || code == QualFilingStatusEnum.DRAFT.getCode()) { if (code == null || code == QualFilingStatusEnum.DRAFT.getCode()) {
@ -766,6 +742,156 @@ public class QualFilingOrchestrator {
return co; return co;
} }
/**
* ID
*/
public List<QualFilingComplianceCheckResultCO> complianceCheck(Long id) {
QualFilingEntity filing = qualFilingGateway.get(id);
if (filing == null) {
throw new BizException(ErrorCode.QUAL_FILING_NOT_FOUND);
}
List<QualFilingComplianceCheckResultCO> results = new ArrayList<>();
// 1. 主体资格
results.add(checkMainQualification(filing));
// 2. 场所与设备
results.add(checkWorkplace(filing));
// 3. 人员数量与结构
results.add(checkPersonnelCount(id));
// 4. 人员资历
results.add(checkPersonnelExperience(id));
// 5. 关键岗位要求(暂默认通过,标记警告)
results.add(buildResult(QualFilingComplianceCheckEnum.KEY_POSITION,
QualFilingComplianceCheckEnum.STATUS_WARN));
// 6. 管理体系(暂无法判断,标记警告)
results.add(buildResult(QualFilingComplianceCheckEnum.MANAGEMENT_SYSTEM,
QualFilingComplianceCheckEnum.STATUS_WARN));
// 7. 责任承诺
results.add(checkCommitment(id));
// 8. 信息公开
results.add(checkInfoDisclosure(filing));
// 9. 信用记录
results.add(checkCreditRecord(id));
// 10. 其他
results.add(buildResult(QualFilingComplianceCheckEnum.OTHER,
QualFilingComplianceCheckEnum.STATUS_PASS));
return results;
}
/**
* >= 1000
*/
private QualFilingComplianceCheckResultCO checkMainQualification(QualFilingEntity filing) {
// 1000万元 = 10,000,000元 = 1,000,000,000分
boolean pass = filing.getFixedAssetAmount() != null
&& filing.getFixedAssetAmount() >= 1_000_000_000L;
return buildResult(QualFilingComplianceCheckEnum.MAIN_QUALIFICATION,
pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
/**
* >= 1000
*/
private QualFilingComplianceCheckResultCO checkWorkplace(QualFilingEntity filing) {
boolean pass = filing.getWorkplaceArea() != null
&& filing.getWorkplaceArea()
.compareTo(new BigDecimal(QualFilingComplianceCheckEnum.WORKPLACE_LOWER)) >= 0;
return buildResult(QualFilingComplianceCheckEnum.WORKPLACE,
pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
/**
* >= 25 >= 30%
*/
private QualFilingComplianceCheckResultCO checkPersonnelCount(Long filingId) {
List<QualFilingPersonnelEntity> personnelList =
qualFilingPersonnelGateway.listByFilingId(filingId);
int total = personnelList.size();
if (total == 0) {
return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT,
QualFilingComplianceCheckEnum.STATUS_FAIL);
}
long engineerCount = personnelList.stream()
.filter(p -> p.getRegisterEngineerFlag() != null
&& p.getRegisterEngineerFlag() == 1)
.count();
boolean pass = total >= QualFilingComplianceCheckEnum.PERSONNEL_COUNT_LOWER
&& engineerCount * 100 / total >= QualFilingComplianceCheckEnum.PERSONNEL_RATE;
return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT,
pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
/**
*
*/
private QualFilingComplianceCheckResultCO checkPersonnelExperience(Long filingId) {
List<QualFilingPersonnelEntity> personnelList =
qualFilingPersonnelGateway.listByFilingId(filingId);
if (personnelList.isEmpty()) {
return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE,
QualFilingComplianceCheckEnum.STATUS_FAIL);
}
LocalDate now = LocalDate.now();
boolean allQualified = personnelList.stream()
.allMatch(p -> p.getJoinWorkDate() != null
&& ChronoUnit.YEARS.between(p.getJoinWorkDate(), now) >= 2);
return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE,
allQualified ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
/**
* qual_filing_commitment
*/
private QualFilingComplianceCheckResultCO checkCommitment(Long filingId) {
QualFilingCommitmentEntity commitment =
qualFilingCommitmentGateway.getByFilingId(filingId);
return buildResult(QualFilingComplianceCheckEnum.COMMITMENT,
commitment != null ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
/**
* info_disclosure_url
*/
private QualFilingComplianceCheckResultCO checkInfoDisclosure(QualFilingEntity filing) {
boolean pass = filing.getInfoDisclosureUrl() != null
&& !filing.getInfoDisclosureUrl().isEmpty();
return buildResult(QualFilingComplianceCheckEnum.INFO_DISCLOSURE,
pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
/**
* qual_filing_material upload_status_code=2 material_type=4
*/
private QualFilingComplianceCheckResultCO checkCreditRecord(Long filingId) {
List<QualFilingMaterialEntity> materials =
qualFilingMaterialGateway.listByFilingId(filingId);
boolean pass = materials.stream()
.anyMatch(m -> m.getUploadStatusCode() != null
&& m.getUploadStatusCode() == QualFilingMaterialUploadStatusEnum.UPLOADED.getCode()
&& MaterialTypeEnum.NO_VIOLATION_RECORD.getCode() == m.getMaterialType());
return buildResult(QualFilingComplianceCheckEnum.CREDIT_RECORD,
pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL);
}
private QualFilingComplianceCheckResultCO buildResult(QualFilingComplianceCheckEnum item, String status) {
QualFilingComplianceCheckResultCO co = new QualFilingComplianceCheckResultCO();
co.setTitle(item.getTitle());
co.setDescription(item.getDescription());
co.setStatus(status);
return co;
}
private Long resolveOrgId() { private Long resolveOrgId() {
return orgContextResolver.resolveOrgId(null); return orgContextResolver.resolveOrgId(null);
} }

View File

@ -1,6 +1,7 @@
package org.qinan.safetyeval.client.api; package org.qinan.safetyeval.client.api;
import org.qinan.safetyeval.client.co.QualFilingCO; import org.qinan.safetyeval.client.co.QualFilingCO;
import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO;
import org.qinan.safetyeval.client.co.QualFilingDetailCO; import org.qinan.safetyeval.client.co.QualFilingDetailCO;
import org.qinan.safetyeval.client.dto.PageResponse; import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse; import org.qinan.safetyeval.client.dto.SingleResponse;
@ -10,6 +11,8 @@ import org.qinan.safetyeval.client.dto.QualFilingModifyCmd;
import org.qinan.safetyeval.client.dto.QualFilingPageQuery; import org.qinan.safetyeval.client.dto.QualFilingPageQuery;
import org.qinan.safetyeval.client.dto.QualFilingRejectCmd; import org.qinan.safetyeval.client.dto.QualFilingRejectCmd;
import java.util.List;
/** /**
* Client * Client
*/ */
@ -40,4 +43,6 @@ public interface QualFilingApi {
SingleResponse<QualFilingCO> filedDraft(); SingleResponse<QualFilingCO> filedDraft();
SingleResponse<QualFilingCO> uploadAttachment(QualFilingAttachmentUploadCmd cmd); SingleResponse<QualFilingCO> uploadAttachment(QualFilingAttachmentUploadCmd cmd);
SingleResponse<List<QualFilingComplianceCheckResultCO>> complianceCheck(Long id);
} }

View File

@ -0,0 +1,21 @@
package org.qinan.safetyeval.client.co;
import lombok.Data;
/**
* CO
*
* @author safety-eval
*/
@Data
public class QualFilingComplianceCheckResultCO {
/** 检查项标题 */
private String title;
/** 检查项描述 */
private String description;
/** 检查结果状态:✅ 通过 / ❌ 未通过 / ⚠️ 警告 */
private String status;
}

View File

@ -17,7 +17,7 @@ public class QualFilingMaterialCO {
private Long filingId; private Long filingId;
/** materialType */ /** materialType */
private String materialType; private Integer materialType;
/** materialContent */ /** materialContent */
private String materialContent; private String materialContent;

View File

@ -11,7 +11,7 @@ import lombok.Data;
public class QualFilingMaterialAddCmd { public class QualFilingMaterialAddCmd {
/** materialType */ /** materialType */
private String materialType; private Integer materialType;
/** materialContent */ /** materialContent */
private String materialContent; private String materialContent;

View File

@ -14,7 +14,7 @@ public class QualFilingMaterialModifyCmd {
private Long id; private Long id;
/** materialType */ /** materialType */
private String materialType; private Integer materialType;
/** materialContent */ /** materialContent */
private String materialContent; private String materialContent;

View File

@ -16,7 +16,7 @@ public class QualFilingMaterialPageQuery extends BasePageQuery {
private Long filingId; private Long filingId;
/** 材料类型 */ /** 材料类型 */
private String materialType; private Integer materialType;
/** 材料内容 */ /** 材料内容 */
private String materialContent; private String materialContent;

View File

@ -0,0 +1,59 @@
package org.qinan.safetyeval.domain.constant;
import java.math.BigDecimal;
/**
*
*
* @author safety-eval
*/
public enum QualFilingComplianceCheckEnum {
MAIN_QUALIFICATION("主体资格", "独立法人资格,固定资产不少于一千万元"),
WORKPLACE("场所与设备", "工作场所建筑面积不少于1000㎡"),
PERSONNEL_COUNT("人员数量与结构", "专职技术人员≥25人中级注安师≥30%"),
PERSONNEL_EXPERIENCE("人员资历", "专职技术人员在本行业领域工作二年以上"),
KEY_POSITION("关键岗位要求", "负责人具有高级职称,工作八年以上"),
MANAGEMENT_SYSTEM("管理体系", "需核验文件化管理体系是否符合要求"),
COMMITMENT("责任承诺", "法定代表人已出具承诺书"),
INFO_DISCLOSURE("信息公开", "未检测到公示网站"),
CREDIT_RECORD("信用记录", "三年内无重大违法失信记录"),
OTHER("其他", "法律、行政法规规定的其他条件"),
;
/**
*
*/
public static final String STATUS_PASS = "PASS";
/**
*
*/
public static final String STATUS_FAIL = "NOT_PASS";
/**
* /
*/
public static final String STATUS_WARN = "WARN";
/**
* 线
*/
public static final int WORKPLACE_LOWER = 1000;
public static final int PERSONNEL_COUNT_LOWER = 25;
public static final int PERSONNEL_RATE = 30;
private final String title;
private final String description;
QualFilingComplianceCheckEnum(String title, String description) {
this.title = title;
this.description = description;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
}

View File

@ -17,7 +17,7 @@ public class QualFilingMaterialEntity {
private Long filingId; private Long filingId;
/** 材料类型 */ /** 材料类型 */
private String materialType; private Integer materialType;
/** 材料内容 */ /** 材料内容 */
private String materialContent; private String materialContent;

View File

@ -23,7 +23,7 @@ public class QualFilingMaterialQuery {
private Long filingId; private Long filingId;
/** 材料类型 */ /** 材料类型 */
private String materialType; private Integer materialType;
/** 材料内容 */ /** 材料内容 */
private String materialContent; private String materialContent;

View File

@ -16,7 +16,7 @@ public class QualFilingMaterialDO {
private Long id; private Long id;
private Long filingId; private Long filingId;
private String materialType; private Integer materialType;
private String materialContent; private String materialContent;
private String materialFormat; private String materialFormat;
private Integer sortOrder; private Integer sortOrder;