From 402a0c3e2fb916e790f7bfc89b513bc492b6de7a Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Thu, 7 May 2026 00:01:27 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AF=BC=E5=85=A5=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E6=A0=BC=E5=BC=8F=E5=92=8C=E5=BF=85=E5=A1=AB=E6=A0=87?= =?UTF-8?q?=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/excel/CcdiAccountInfoExcel.java | 4 + .../excel/CcdiBaseStaffAssetInfoExcel.java | 18 +- .../domain/excel/CcdiBaseStaffExcel.java | 21 +- .../CcdiCustEnterpriseRelationExcel.java | 3 + .../excel/CcdiCustFmyRelationExcel.java | 5 + .../excel/CcdiEnterpriseBaseInfoExcel.java | 3 + ...diIntermediaryEnterpriseRelationExcel.java | 3 + .../excel/CcdiIntermediaryEntityExcel.java | 3 + .../excel/CcdiIntermediaryPersonExcel.java | 5 + .../excel/CcdiPurchaseTransactionExcel.java | 4 + .../CcdiPurchaseTransactionSupplierExcel.java | 5 + .../CcdiStaffEnterpriseRelationExcel.java | 3 + .../excel/CcdiStaffFmyRelationExcel.java | 3 + .../excel/CcdiStaffRecruitmentExcel.java | 5 + .../excel/CcdiStaffRecruitmentWorkExcel.java | 2 + .../handler/RequiredFieldWriteHandler.java | 67 +++--- .../info/collection/utils/EasyExcelUtil.java | 5 +- .../utils/EasyExcelUtilTemplateTest.java | 203 +++++++++++++++++- ...base-staff-import-template-column-width.md | 30 +++ ...e-staff-import-template-required-header.md | 31 +++ ...-base-staff-import-template-text-format.md | 32 +++ ...fo-import-template-text-format-coverage.md | 54 +++++ 22 files changed, 458 insertions(+), 51 deletions(-) create mode 100644 docs/reports/implementation/2026-05-06-base-staff-import-template-column-width.md create mode 100644 docs/reports/implementation/2026-05-06-base-staff-import-template-required-header.md create mode 100644 docs/reports/implementation/2026-05-06-base-staff-import-template-text-format.md create mode 100644 docs/reports/implementation/2026-05-06-info-import-template-text-format-coverage.md diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiAccountInfoExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiAccountInfoExcel.java index 8218d2b9..bb862b84 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiAccountInfoExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiAccountInfoExcel.java @@ -2,6 +2,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -25,6 +26,7 @@ public class CcdiAccountInfoExcel implements Serializable { @ExcelProperty(value = "证件号*", index = 1) @ColumnWidth(24) + @TextFormat private String ownerId; @ExcelProperty(value = "账户姓名*", index = 2) @@ -33,6 +35,7 @@ public class CcdiAccountInfoExcel implements Serializable { @ExcelProperty(value = "账户号码*", index = 3) @ColumnWidth(28) + @TextFormat private String accountNo; @ExcelProperty(value = "账户类型*", index = 4) @@ -49,6 +52,7 @@ public class CcdiAccountInfoExcel implements Serializable { @ExcelProperty(value = "银行代码", index = 7) @ColumnWidth(16) + @TextFormat private String bankCode; @ExcelProperty(value = "币种", index = 8) diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffAssetInfoExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffAssetInfoExcel.java index 6eca7618..e7ff4105 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffAssetInfoExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffAssetInfoExcel.java @@ -26,14 +26,14 @@ public class CcdiBaseStaffAssetInfoExcel implements Serializable { /** 员工身份证号 */ @ExcelProperty(value = "员工身份证号*", index = 0) - @ColumnWidth(22) + @ColumnWidth(24) @Required @TextFormat private String personId; /** 资产大类 */ @ExcelProperty(value = "资产大类*", index = 1) - @ColumnWidth(16) + @ColumnWidth(18) @Required private String assetMainType; @@ -51,39 +51,39 @@ public class CcdiBaseStaffAssetInfoExcel implements Serializable { /** 产权占比 */ @ExcelProperty(value = "产权占比", index = 4) - @ColumnWidth(12) + @ColumnWidth(14) private BigDecimal ownershipRatio; /** 购买/评估日期 */ @ExcelProperty(value = "购买/评估日期", index = 5) - @ColumnWidth(16) + @ColumnWidth(20) private Date purchaseEvalDate; /** 资产原值 */ @ExcelProperty(value = "资产原值", index = 6) - @ColumnWidth(16) + @ColumnWidth(18) private BigDecimal originalValue; /** 当前估值 */ @ExcelProperty(value = "当前估值*", index = 7) - @ColumnWidth(16) + @ColumnWidth(18) @Required private BigDecimal currentValue; /** 估值截止日期 */ @ExcelProperty(value = "估值截止日期", index = 8) - @ColumnWidth(16) + @ColumnWidth(20) private Date valuationDate; /** 资产状态 */ @ExcelProperty(value = "资产状态*", index = 9) - @ColumnWidth(14) + @ColumnWidth(16) @DictDropdown(dictType = "ccdi_asset_status") @Required private String assetStatus; /** 备注 */ @ExcelProperty(value = "备注", index = 10) - @ColumnWidth(28) + @ColumnWidth(32) private String remarks; } diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffExcel.java index 7dac9230..56233d83 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffExcel.java @@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -25,54 +26,56 @@ public class CcdiBaseStaffExcel implements Serializable { /** 姓名 */ @ExcelProperty(value = "姓名", index = 0) - @ColumnWidth(15) + @ColumnWidth(16) @Required private String name; /** 员工ID */ @ExcelProperty(value = "员工ID", index = 1) - @ColumnWidth(15) + @ColumnWidth(18) @Required private Long staffId; /** 所属部门ID */ @ExcelProperty(value = "所属部门ID", index = 2) - @ColumnWidth(15) + @ColumnWidth(20) @Required private Long deptId; /** 身份证号 */ @ExcelProperty(value = "身份证号", index = 3) - @ColumnWidth(20) + @ColumnWidth(24) @Required + @TextFormat private String idCard; /** 电话 */ @ExcelProperty(value = "电话", index = 4) - @ColumnWidth(15) + @ColumnWidth(18) @Required + @TextFormat private String phone; /** 年收入 */ @ExcelProperty(value = "年收入(元/年)", index = 5) - @ColumnWidth(18) + @ColumnWidth(20) private BigDecimal annualIncome; /** 入职时间 */ @ExcelProperty(value = "入职时间", index = 6) - @ColumnWidth(15) + @ColumnWidth(18) private Date hireDate; /** 是否党员 */ @ExcelProperty(value = "是否党员", index = 7) - @ColumnWidth(12) + @ColumnWidth(16) @DictDropdown(dictType = "ccdi_yes_no_flag") @Required private Integer partyMember; /** 状态 */ @ExcelProperty(value = "状态", index = 8) - @ColumnWidth(10) + @ColumnWidth(14) @DictDropdown(dictType = "ccdi_employee_status") @Required private String status; diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustEnterpriseRelationExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustEnterpriseRelationExcel.java index dcce65bb..2607b522 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustEnterpriseRelationExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustEnterpriseRelationExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -26,6 +27,7 @@ public class CcdiCustEnterpriseRelationExcel implements Serializable { @ExcelProperty(value = "身份证号", index = 0) @ColumnWidth(20) @Required + @TextFormat @Schema(description = "身份证号") private String personId; @@ -33,6 +35,7 @@ public class CcdiCustEnterpriseRelationExcel implements Serializable { @ExcelProperty(value = "统一社会信用代码", index = 1) @ColumnWidth(25) @Required + @TextFormat @Schema(description = "统一社会信用代码") private String socialCreditCode; diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustFmyRelationExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustFmyRelationExcel.java index cd55378b..907e0e49 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustFmyRelationExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiCustFmyRelationExcel.java @@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -26,6 +27,7 @@ public class CcdiCustFmyRelationExcel implements Serializable { @ExcelProperty(value = "信贷客户身份证号*", index = 0) @ColumnWidth(20) @Required + @TextFormat private String personId; /** 关系类型 */ @@ -63,16 +65,19 @@ public class CcdiCustFmyRelationExcel implements Serializable { @ExcelProperty(value = "关系人证件号码*", index = 6) @ColumnWidth(20) @Required + @TextFormat private String relationCertNo; /** 手机号码1 */ @ExcelProperty(value = "手机号码1", index = 7) @ColumnWidth(15) + @TextFormat private String mobilePhone1; /** 手机号码2 */ @ExcelProperty(value = "手机号码2", index = 8) @ColumnWidth(15) + @TextFormat private String mobilePhone2; /** 微信名称1 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiEnterpriseBaseInfoExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiEnterpriseBaseInfoExcel.java index a3bc16fa..3ca5fb96 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiEnterpriseBaseInfoExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiEnterpriseBaseInfoExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -23,6 +24,7 @@ public class CcdiEnterpriseBaseInfoExcel implements Serializable { @ExcelProperty(value = "统一社会信用代码*", index = 0) @ColumnWidth(24) + @TextFormat private String socialCreditCode; @ExcelProperty(value = "企业名称*", index = 1) @@ -66,6 +68,7 @@ public class CcdiEnterpriseBaseInfoExcel implements Serializable { @ExcelProperty(value = "法定代表人证件号码", index = 10) @ColumnWidth(24) + @TextFormat private String legalCertNo; @ExcelProperty(value = "股东1", index = 11) diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java index 45dfb839..ed8707db 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -21,12 +22,14 @@ public class CcdiIntermediaryEnterpriseRelationExcel implements Serializable { @ExcelProperty(value = "中介本人证件号码", index = 0) @ColumnWidth(24) @Required + @TextFormat private String ownerPersonId; /** 统一社会信用代码 */ @ExcelProperty(value = "统一社会信用代码", index = 1) @ColumnWidth(24) @Required + @TextFormat private String socialCreditCode; /** 关联职务 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEntityExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEntityExcel.java index 14ef3cf1..104018f3 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEntityExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEntityExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -29,6 +30,7 @@ public class CcdiIntermediaryEntityExcel implements Serializable { /** 统一社会信用代码 */ @ExcelProperty(value = "统一社会信用代码*", index = 1) @ColumnWidth(20) + @TextFormat private String socialCreditCode; /** 主体类型 */ @@ -77,6 +79,7 @@ public class CcdiIntermediaryEntityExcel implements Serializable { /** 法定代表人证件号码 */ @ExcelProperty(value = "法定代表人证件号码", index = 10) @ColumnWidth(20) + @TextFormat private String legalCertNo; /** 股东1 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryPersonExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryPersonExcel.java index 8da1599a..6fa00dfc 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryPersonExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryPersonExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -52,11 +53,13 @@ public class CcdiIntermediaryPersonExcel implements Serializable { /** 证件号码 */ @ExcelProperty(value = "证件号码*", index = 5) @ColumnWidth(20) + @TextFormat private String personId; /** 手机号码 */ @ExcelProperty(value = "手机号码", index = 6) @ColumnWidth(15) + @TextFormat private String mobile; /** 微信号 */ @@ -77,6 +80,7 @@ public class CcdiIntermediaryPersonExcel implements Serializable { /** 企业统一信用码 */ @ExcelProperty(value = "企业统一信用码", index = 10) @ColumnWidth(20) + @TextFormat private String socialCreditCode; /** 职位 */ @@ -87,6 +91,7 @@ public class CcdiIntermediaryPersonExcel implements Serializable { /** 关联中介本人证件号码 */ @ExcelProperty(value = "关联中介本人证件号码", index = 12) @ColumnWidth(24) + @TextFormat private String relatedNumId; /** 备注 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionExcel.java index fa8e1ebe..7069b10f 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -26,6 +27,7 @@ public class CcdiPurchaseTransactionExcel implements Serializable { @ExcelProperty(value = "采购事项ID", index = 0) @ColumnWidth(20) @Required + @TextFormat private String purchaseId; /** 采购类别 */ @@ -138,6 +140,7 @@ public class CcdiPurchaseTransactionExcel implements Serializable { @ExcelProperty(value = "申请人工号", index = 21) @ColumnWidth(15) @Required + @TextFormat private String applicantId; /** 申请人姓名 */ @@ -155,6 +158,7 @@ public class CcdiPurchaseTransactionExcel implements Serializable { /** 采购负责人工号 */ @ExcelProperty(value = "采购负责人工号", index = 24) @ColumnWidth(15) + @TextFormat private String purchaseLeaderId; /** 采购负责人姓名 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionSupplierExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionSupplierExcel.java index 0655f64a..1deac3bd 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionSupplierExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiPurchaseTransactionSupplierExcel.java @@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -21,6 +22,7 @@ public class CcdiPurchaseTransactionSupplierExcel implements Serializable { @ExcelProperty(value = "采购事项ID", index = 0) @ColumnWidth(20) @Required + @TextFormat private String purchaseId; @ExcelProperty(value = "供应商名称", index = 1) @@ -30,6 +32,7 @@ public class CcdiPurchaseTransactionSupplierExcel implements Serializable { @ExcelProperty(value = "供应商统一信用代码", index = 2) @ColumnWidth(25) + @TextFormat private String supplierUscc; @ExcelProperty(value = "供应商联系人", index = 3) @@ -38,10 +41,12 @@ public class CcdiPurchaseTransactionSupplierExcel implements Serializable { @ExcelProperty(value = "供应商联系电话", index = 4) @ColumnWidth(18) + @TextFormat private String contactPhone; @ExcelProperty(value = "供应商银行账户", index = 5) @ColumnWidth(20) + @TextFormat private String supplierBankAccount; @ExcelProperty(value = "是否中标", index = 6) diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffEnterpriseRelationExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffEnterpriseRelationExcel.java index 8fcd35bd..e3996f84 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffEnterpriseRelationExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffEnterpriseRelationExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -26,6 +27,7 @@ public class CcdiStaffEnterpriseRelationExcel implements Serializable { @ExcelProperty(value = "亲属身份证号", index = 0) @ColumnWidth(20) @Required + @TextFormat @Schema(description = "亲属身份证号") private String personId; @@ -33,6 +35,7 @@ public class CcdiStaffEnterpriseRelationExcel implements Serializable { @ExcelProperty(value = "统一社会信用代码", index = 1) @ColumnWidth(25) @Required + @TextFormat @Schema(description = "统一社会信用代码") private String socialCreditCode; diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffFmyRelationExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffFmyRelationExcel.java index 465086e8..607c0bc4 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffFmyRelationExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffFmyRelationExcel.java @@ -28,6 +28,7 @@ public class CcdiStaffFmyRelationExcel implements Serializable { @ExcelProperty(value = "员工身份证号*", index = 0) @ColumnWidth(20) @Required + @TextFormat private String personId; /** 关系类型 */ @@ -71,11 +72,13 @@ public class CcdiStaffFmyRelationExcel implements Serializable { /** 手机号码1 */ @ExcelProperty(value = "手机号码1", index = 7) @ColumnWidth(15) + @TextFormat private String mobilePhone1; /** 手机号码2 */ @ExcelProperty(value = "手机号码2", index = 8) @ColumnWidth(15) + @TextFormat private String mobilePhone2; /** 家庭成员年收入 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentExcel.java index f3468006..26484b4c 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentExcel.java @@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.DictDropdown; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -25,6 +26,7 @@ public class CcdiStaffRecruitmentExcel implements Serializable { @ExcelProperty(value = "招聘记录编号", index = 0) @ColumnWidth(20) @Required + @TextFormat private String recruitId; /** 招聘项目名称 */ @@ -80,6 +82,7 @@ public class CcdiStaffRecruitmentExcel implements Serializable { @ExcelProperty(value = "证件号码", index = 9) @ColumnWidth(20) @Required + @TextFormat private String candId; /** 应聘人员毕业年月 */ @@ -108,6 +111,7 @@ public class CcdiStaffRecruitmentExcel implements Serializable { /** 面试官1工号 */ @ExcelProperty(value = "面试官1工号", index = 14) @ColumnWidth(15) + @TextFormat private String interviewerId1; /** 面试官2姓名 */ @@ -118,5 +122,6 @@ public class CcdiStaffRecruitmentExcel implements Serializable { /** 面试官2工号 */ @ExcelProperty(value = "面试官2工号", index = 16) @ColumnWidth(15) + @TextFormat private String interviewerId2; } diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentWorkExcel.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentWorkExcel.java index 3831d1cb..d3e9aefd 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentWorkExcel.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiStaffRecruitmentWorkExcel.java @@ -3,6 +3,7 @@ package com.ruoyi.info.collection.domain.excel; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.ruoyi.common.annotation.Required; +import com.ruoyi.common.annotation.TextFormat; import lombok.Data; import java.io.Serial; @@ -24,6 +25,7 @@ public class CcdiStaffRecruitmentWorkExcel implements Serializable { @ExcelProperty(value = "招聘记录编号", index = 0) @ColumnWidth(20) @Required + @TextFormat private String recruitId; /** 候选人姓名 */ diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/handler/RequiredFieldWriteHandler.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/handler/RequiredFieldWriteHandler.java index 6affba64..9614cf40 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/handler/RequiredFieldWriteHandler.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/handler/RequiredFieldWriteHandler.java @@ -1,15 +1,28 @@ package com.ruoyi.info.collection.handler; import com.alibaba.excel.annotation.ExcelProperty; -import com.alibaba.excel.write.handler.SheetWriteHandler; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; -import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.ruoyi.common.annotation.Required; import lombok.extern.slf4j.Slf4j; -import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.HorizontalAlignment; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.VerticalAlignment; +import org.apache.poi.ss.usermodel.Workbook; import java.lang.reflect.Field; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; /** * EasyExcel必填字段标注处理器 @@ -18,13 +31,18 @@ import java.util.*; * @author ruoyi */ @Slf4j -public class RequiredFieldWriteHandler implements SheetWriteHandler { +public class RequiredFieldWriteHandler implements CellWriteHandler { /** * 实体类Class对象 */ private final Class modelClass; + /** + * 必填字段列索引集合 + */ + private final Set requiredColumns; + /** * 构造函数 * @@ -32,39 +50,30 @@ public class RequiredFieldWriteHandler implements SheetWriteHandler { */ public RequiredFieldWriteHandler(Class modelClass) { this.modelClass = modelClass; + this.requiredColumns = parseRequiredFields(); } @Override - public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { - // 获取工作表 - Sheet sheet = writeSheetHolder.getSheet(); - - // 获取表头行(第1行,索引为0) - Row headerRow = sheet.getRow(0); - if (headerRow == null) { - log.warn("表头行不存在,跳过必填字段标注"); + public void afterCellDispose(WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + List> cellDataList, + Cell cell, + Head head, + Integer relativeRowIndex, + Boolean isHead) { + if (!Boolean.TRUE.equals(isHead) || cell == null || !requiredColumns.contains(cell.getColumnIndex())) { return; } - // 创建红色字体样式 - Workbook workbook = writeWorkbookHolder.getWorkbook(); + Workbook workbook = cell.getSheet().getWorkbook(); CellStyle redStyle = createRedFontStyle(workbook); - // 解析实体类中的必填字段 - Set requiredColumns = parseRequiredFields(); - - // 为必填字段的表头添加红色星号 - for (Integer columnIndex : requiredColumns) { - Cell cell = headerRow.getCell(columnIndex); - if (cell != null) { - String originalValue = cell.getStringCellValue(); - // 添加红色星号 - cell.setCellValue(originalValue + "*"); - // 应用红色样式到星号 - cell.setCellStyle(redStyle); - log.info("为列[{}]的表头添加必填标记(*)", columnIndex); - } + String originalValue = cell.getStringCellValue(); + if (originalValue != null && !originalValue.endsWith("*")) { + cell.setCellValue(originalValue + "*"); } + cell.setCellStyle(redStyle); + log.info("为列[{}]的表头添加必填标记(*)", cell.getColumnIndex()); } /** diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/utils/EasyExcelUtil.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/utils/EasyExcelUtil.java index 6c9a45f7..abd78689 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/utils/EasyExcelUtil.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/utils/EasyExcelUtil.java @@ -158,6 +158,7 @@ public class EasyExcelUtil { templateWriter(response, clazz) .sheet(sheetName) .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + .registerWriteHandler(new TextFormatWriteHandler(clazz)) .doWrite(List.of()); } catch (IOException e) { throw new RuntimeException("下载导入模板失败", e); @@ -180,7 +181,8 @@ public class EasyExcelUtil { setResponseHeader(response, sheetName + "模板"); var writerBuilder = templateWriter(response, clazz) .sheet(sheetName) - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()); + .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) + .registerWriteHandler(new TextFormatWriteHandler(clazz)); // 注册所有自定义处理器 for (WriteHandler handler : handlers) { writerBuilder.registerWriteHandler(handler); @@ -288,7 +290,6 @@ public class EasyExcelUtil { private static WriteSheet buildTemplateSheet(int sheetNo, Class clazz, String sheetName) { return EasyExcel.writerSheet(sheetNo, sheetName) .head(clazz) - .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) .registerWriteHandler(new DictDropdownWriteHandler(clazz)) .registerWriteHandler(new TextFormatWriteHandler(clazz)) .registerWriteHandler(new RequiredFieldWriteHandler(clazz)) diff --git a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/utils/EasyExcelUtilTemplateTest.java b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/utils/EasyExcelUtilTemplateTest.java index 44a5ec81..78326fb9 100644 --- a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/utils/EasyExcelUtilTemplateTest.java +++ b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/utils/EasyExcelUtilTemplateTest.java @@ -2,12 +2,22 @@ package com.ruoyi.info.collection.utils; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.utils.DictUtils; -import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel; +import com.ruoyi.info.collection.domain.excel.CcdiAccountInfoExcel; import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel; +import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffAssetInfoExcel; +import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel; +import com.ruoyi.info.collection.domain.excel.CcdiCustEnterpriseRelationExcel; +import com.ruoyi.info.collection.domain.excel.CcdiCustFmyRelationExcel; import com.ruoyi.info.collection.domain.excel.CcdiEnterpriseBaseInfoExcel; +import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryEnterpriseRelationExcel; +import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryEntityExcel; +import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryPersonExcel; +import com.ruoyi.info.collection.domain.excel.CcdiPurchaseTransactionExcel; +import com.ruoyi.info.collection.domain.excel.CcdiPurchaseTransactionSupplierExcel; +import com.ruoyi.info.collection.domain.excel.CcdiStaffEnterpriseRelationExcel; +import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel; import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentExcel; import com.ruoyi.info.collection.domain.excel.CcdiStaffRecruitmentWorkExcel; -import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.Row; @@ -99,6 +109,63 @@ class EasyExcelUtilTemplateTest { try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) { Sheet sheet = workbook.getSheetAt(0); assertTrue(hasValidationOnColumn(sheet, 7), "是否党员列应包含下拉校验"); + assertHeaderValue(sheet, 0, "姓名*"); + assertHeaderValue(sheet, 1, "员工ID*"); + assertHeaderValue(sheet, 2, "所属部门ID*"); + assertHeaderValue(sheet, 3, "身份证号*"); + assertHeaderValue(sheet, 4, "电话*"); + assertHeaderValue(sheet, 7, "是否党员*"); + assertHeaderValue(sheet, 8, "状态*"); + assertTextColumn(sheet, 3); + assertTextColumn(sheet, 4); + } + } + + @Test + void importTemplateWithDictDropdown_shouldKeepBaseStaffDualSheetColumnWidths() throws Exception { + MockHttpServletResponse response = new MockHttpServletResponse(); + + try (MockedStatic mocked = mockStatic(DictUtils.class)) { + mocked.when(() -> DictUtils.getDictCache("ccdi_employee_status")) + .thenReturn(List.of( + buildDictData("在职", "0"), + buildDictData("离职", "1") + )); + mocked.when(() -> DictUtils.getDictCache("ccdi_yes_no_flag")) + .thenReturn(List.of( + buildDictData("是", "1"), + buildDictData("否", "0") + )); + mocked.when(() -> DictUtils.getDictCache("ccdi_asset_status")) + .thenReturn(List.of( + buildDictData("正常"), + buildDictData("冻结"), + buildDictData("处置中") + )); + + EasyExcelUtil.importTemplateWithDictDropdown( + response, + CcdiBaseStaffExcel.class, + "员工信息", + CcdiBaseStaffAssetInfoExcel.class, + "员工资产信息", + "员工信息维护导入模板" + ); + } + + try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) { + Sheet staffSheet = workbook.getSheet("员工信息"); + Sheet assetSheet = workbook.getSheet("员工资产信息"); + assertNotNull(staffSheet); + assertNotNull(assetSheet); + + assertColumnWidthsAtLeast(staffSheet, new int[] {16, 18, 20, 24, 18, 20, 18, 16, 14}); + assertColumnWidthsAtLeast(assetSheet, new int[] {24, 18, 18, 24, 14, 20, 18, 18, 20, 16, 32}); + assertHeaderValue(staffSheet, 0, "姓名*"); + assertHeaderValue(staffSheet, 8, "状态*"); + assertHeaderValue(assetSheet, 0, "员工身份证号*"); + assertHeaderValue(assetSheet, 1, "资产大类*"); + assertHeaderValue(assetSheet, 10, "备注"); } } @@ -155,12 +222,119 @@ class EasyExcelUtilTemplateTest { } } + @Test + void infoImportTemplates_shouldFormatIdentifierAndContactColumnsAsText() throws Exception { + try (MockedStatic mocked = mockStatic(DictUtils.class)) { + mockCommonDicts(mocked); + + assertPlainTemplateTextColumns(CcdiAccountInfoExcel.class, "账户库管理", 1, 3, 7); + assertSingleTemplateTextColumns(CcdiAssetInfoExcel.class, "亲属资产信息", 0); + assertSingleTemplateTextColumns(CcdiBaseStaffAssetInfoExcel.class, "员工资产信息", 0); + assertDualTemplateTextColumns( + CcdiBaseStaffExcel.class, + "员工信息", + new int[] {3, 4}, + CcdiBaseStaffAssetInfoExcel.class, + "员工资产信息", + new int[] {0}, + "员工信息维护导入模板" + ); + assertSingleTemplateTextColumns(CcdiCustEnterpriseRelationExcel.class, "信贷客户实体关联信息", 0, 1); + assertSingleTemplateTextColumns(CcdiCustFmyRelationExcel.class, "信贷客户家庭关系", 0, 6, 7, 8); + assertSingleTemplateTextColumns(CcdiEnterpriseBaseInfoExcel.class, "实体库管理", 0, 10); + assertSingleTemplateTextColumns(CcdiIntermediaryPersonExcel.class, "个人中介信息", 5, 6, 10, 12); + assertSingleTemplateTextColumns(CcdiIntermediaryEntityExcel.class, "实体中介信息", 1, 10); + assertSingleTemplateTextColumns(CcdiIntermediaryEnterpriseRelationExcel.class, "中介实体关联关系信息", 0, 1); + assertDualTemplateTextColumns( + CcdiPurchaseTransactionExcel.class, + "招投标主信息", + new int[] {0, 21, 24}, + CcdiPurchaseTransactionSupplierExcel.class, + "供应商信息", + new int[] {0, 2, 4, 5}, + "招投标信息维护导入模板" + ); + assertSingleTemplateTextColumns(CcdiStaffEnterpriseRelationExcel.class, "员工亲属实体关联", 0, 1); + assertSingleTemplateTextColumns(CcdiStaffFmyRelationExcel.class, "员工亲属关系信息", 0, 6, 7, 8); + assertDualTemplateTextColumns( + CcdiStaffRecruitmentExcel.class, + "招聘信息", + new int[] {0, 9, 14, 16}, + CcdiStaffRecruitmentWorkExcel.class, + "历史工作经历", + new int[] {0}, + "招聘信息管理导入模板" + ); + } + } + private void assertTextColumn(Sheet sheet, int columnIndex) { CellStyle style = sheet.getColumnStyle(columnIndex); assertNotNull(style, "文本列应设置默认样式"); assertEquals("@", style.getDataFormatString(), "证件号列应使用文本格式"); } + private void assertHeaderValue(Sheet sheet, int columnIndex, String expectedValue) { + assertEquals(expectedValue, sheet.getRow(0).getCell(columnIndex).getStringCellValue()); + } + + private void assertTextColumns(Sheet sheet, int... columnIndexes) { + for (int columnIndex : columnIndexes) { + assertTextColumn(sheet, columnIndex); + } + } + + private void assertPlainTemplateTextColumns(Class clazz, String sheetName, int... columnIndexes) throws Exception { + MockHttpServletResponse response = new MockHttpServletResponse(); + EasyExcelUtil.importTemplateExcel(response, clazz, sheetName); + + try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) { + assertTextColumns(workbook.getSheetAt(0), columnIndexes); + } + } + + private void assertSingleTemplateTextColumns(Class clazz, String sheetName, int... columnIndexes) throws Exception { + MockHttpServletResponse response = new MockHttpServletResponse(); + EasyExcelUtil.importTemplateWithDictDropdown(response, clazz, sheetName); + + try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) { + assertTextColumns(workbook.getSheetAt(0), columnIndexes); + } + } + + private void assertDualTemplateTextColumns(Class firstClazz, + String firstSheetName, + int[] firstColumnIndexes, + Class secondClazz, + String secondSheetName, + int[] secondColumnIndexes, + String fileName) throws Exception { + MockHttpServletResponse response = new MockHttpServletResponse(); + EasyExcelUtil.importTemplateWithDictDropdown( + response, + firstClazz, + firstSheetName, + secondClazz, + secondSheetName, + fileName + ); + + try (Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(response.getContentAsByteArray()))) { + assertTextColumns(workbook.getSheet(firstSheetName), firstColumnIndexes); + assertTextColumns(workbook.getSheet(secondSheetName), secondColumnIndexes); + } + } + + private void assertColumnWidthsAtLeast(Sheet sheet, int[] expectedWidths) { + for (int columnIndex = 0; columnIndex < expectedWidths.length; columnIndex++) { + int currentColumnIndex = columnIndex; + int expectedWidth = expectedWidths[currentColumnIndex]; + int expected = expectedWidth * 256; + assertTrue(sheet.getColumnWidth(currentColumnIndex) >= expected, + () -> sheet.getSheetName() + "第" + (currentColumnIndex + 1) + "列宽度应不小于" + expectedWidth); + } + } + private boolean hasValidationOnColumn(Sheet sheet, int columnIndex) { for (DataValidation validation : sheet.getDataValidations()) { for (CellRangeAddress address : validation.getRegions().getCellRangeAddresses()) { @@ -172,6 +346,31 @@ class EasyExcelUtilTemplateTest { return false; } + private void mockCommonDicts(MockedStatic mocked) { + mocked.when(() -> DictUtils.getDictCache("ccdi_asset_status")) + .thenReturn(List.of(buildDictData("正常"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_employee_status")) + .thenReturn(List.of(buildDictData("在职", "1"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_yes_no_flag")) + .thenReturn(List.of(buildDictData("是", "1"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_relation_type")) + .thenReturn(List.of(buildDictData("配偶"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_indiv_gender")) + .thenReturn(List.of(buildDictData("男"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_certificate_type")) + .thenReturn(List.of(buildDictData("居民身份证"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_entity_type")) + .thenReturn(List.of(buildDictData("有限责任公司"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_enterprise_nature")) + .thenReturn(List.of(buildDictData("民营企业"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_person_type")) + .thenReturn(List.of(buildDictData("中介"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_person_sub_type")) + .thenReturn(List.of(buildDictData("本人"))); + mocked.when(() -> DictUtils.getDictCache("ccdi_admit_status")) + .thenReturn(List.of(buildDictData("录用"))); + } + private SysDictData buildDictData(String label) { return buildDictData(label, label); } diff --git a/docs/reports/implementation/2026-05-06-base-staff-import-template-column-width.md b/docs/reports/implementation/2026-05-06-base-staff-import-template-column-width.md new file mode 100644 index 00000000..15d172b2 --- /dev/null +++ b/docs/reports/implementation/2026-05-06-base-staff-import-template-column-width.md @@ -0,0 +1,30 @@ +# 员工信息维护导入模板列宽调整实施记录 + +## 背景 + +员工信息维护页面下载的导入模板中,空模板会被自动列宽策略压缩,导致每列显示过窄,不便于直接填写身份证号、电话、金额、日期等字段。 + +## 修改内容 + +- 调整 `CcdiBaseStaffExcel` 中员工信息 Sheet 的各列 `@ColumnWidth`,放宽姓名、员工 ID、部门 ID、身份证号、电话、年收入、入职时间、是否党员、状态列宽。 +- 调整 `CcdiBaseStaffAssetInfoExcel` 中员工资产信息 Sheet 的各列 `@ColumnWidth`,放宽员工身份证号、资产分类、产权占比、日期、估值、资产状态和备注列宽。 +- 双 Sheet 导入模板生成时不再使用空数据自动匹配列宽策略,改为按 Excel DTO 上声明的列宽输出,避免空模板被压窄。 +- 补充单元测试,校验员工信息维护双 Sheet 导入模板实际生成的列宽不低于 DTO 声明宽度。 + +## 影响范围 + +- 影响接口:`POST /ccdi/baseStaff/importTemplate` +- 影响模板: + - `员工信息` Sheet + - `员工资产信息` Sheet +- 不涉及导入解析、字段校验、数据库结构和前端交互逻辑。 + +## 验证情况 + +已执行: + +```bash +mvn -pl ccdi-info-collection -am -Dtest=EasyExcelUtilTemplateTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +验证结果:模板工具测试通过,覆盖员工信息维护双 Sheet 模板列宽、下拉框、文本格式以及既有模板生成逻辑。 diff --git a/docs/reports/implementation/2026-05-06-base-staff-import-template-required-header.md b/docs/reports/implementation/2026-05-06-base-staff-import-template-required-header.md new file mode 100644 index 00000000..1d4d81eb --- /dev/null +++ b/docs/reports/implementation/2026-05-06-base-staff-import-template-required-header.md @@ -0,0 +1,31 @@ +# 员工信息维护导入模板必填表头标记实施记录 + +## 背景 + +员工信息维护导入模板中,标注了 `@Required` 的字段表头未显示 `*`。排查发现 `RequiredFieldWriteHandler` 在 Sheet 创建完成后立即读取表头行,但此时 EasyExcel 尚未写入表头,因此会跳过必填标记处理。 + +## 修改内容 + +- 将 `RequiredFieldWriteHandler` 从 Sheet 创建后处理改为表头单元格写入完成后处理。 +- 对标注了 `@Required` 的表头追加 `*` 并应用原有红色加粗样式。 +- 增加防重复处理,表头已经以 `*` 结尾时不再重复追加。 +- 补充员工信息维护模板测试,校验员工信息 Sheet 必填表头输出为 `姓名*`、`员工ID*`、`所属部门ID*`、`身份证号*`、`电话*`、`是否党员*`、`状态*`,并校验员工资产信息 Sheet 已有 `*` 不重复追加。 + +## 影响范围 + +- 影响接口:`POST /ccdi/baseStaff/importTemplate` +- 影响模板: + - `员工信息` Sheet + - `员工资产信息` Sheet +- 处理器为共享模板处理器,其他使用 `@Required` 与 `RequiredFieldWriteHandler` 的导入模板会恢复必填表头 `*` 标记。 +- 不涉及导入解析、校验逻辑、数据库结构和前端交互。 + +## 验证情况 + +已执行: + +```bash +mvn -pl ccdi-info-collection -am -Dtest=EasyExcelUtilTemplateTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +验证结果:测试通过,员工信息维护导入模板的必填表头星号、列宽、下拉框、文本格式均通过断言。 diff --git a/docs/reports/implementation/2026-05-06-base-staff-import-template-text-format.md b/docs/reports/implementation/2026-05-06-base-staff-import-template-text-format.md new file mode 100644 index 00000000..abffcf4c --- /dev/null +++ b/docs/reports/implementation/2026-05-06-base-staff-import-template-text-format.md @@ -0,0 +1,32 @@ +# 员工信息维护导入模板文本格式实施记录 + +## 背景 + +- 员工信息维护导入模板中,“身份证号”“电话”列需要使用文本单元格格式,避免 Excel 将长数字或手机号自动识别为数值格式。 +- 当前模板生成链路已支持 `@TextFormat` 注解并由 `TextFormatWriteHandler` 统一处理,但员工信息 Sheet 的对应字段未标注该注解。 + +## 修改内容 + +- 在 `CcdiBaseStaffExcel` 中为“身份证号”字段增加 `@TextFormat`。 +- 在 `CcdiBaseStaffExcel` 中为“电话”字段增加 `@TextFormat`。 +- 更新 `EasyExcelUtilTemplateTest`,在员工信息模板测试中断言第 3 列“身份证号”和第 4 列“电话”的默认列格式均为文本格式 `@`。 + +## 影响范围 + +- 影响接口:`/ccdi/baseStaff/importTemplate`。 +- 影响文件: + - `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiBaseStaffExcel.java` + - `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/utils/EasyExcelUtilTemplateTest.java` +- 不改变导入字段、字段顺序、导入校验规则和前端页面逻辑。 + +## 验证情况 + +- 已执行定向模板单测: + +```bash +MAVEN_OPTS="-javaagent:$HOME/.m2/repository/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.jar" mvn -pl ccdi-info-collection -am -Dtest=EasyExcelUtilTemplateTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +- 验证结果:通过,`EasyExcelUtilTemplateTest` 共 5 个用例,0 失败,0 错误。 +- 测试日志确认员工信息 Sheet 第 3 列、第 4 列均已执行文本格式设置。 +- 本次未启动前端或后端进程,无需额外清理运行进程。 diff --git a/docs/reports/implementation/2026-05-06-info-import-template-text-format-coverage.md b/docs/reports/implementation/2026-05-06-info-import-template-text-format-coverage.md new file mode 100644 index 00000000..c3f976a0 --- /dev/null +++ b/docs/reports/implementation/2026-05-06-info-import-template-text-format-coverage.md @@ -0,0 +1,54 @@ +# 信息模块导入模板文本格式覆盖实施记录 + +## 背景 + +- 信息模块多个导入模板中存在证件号、身份证号、电话、手机号、统一社会信用代码、银行账户、账户号码、银行代码、工号、跨 Sheet 关联编号等需要保真录入的字段。 +- 这类字段如果使用 Excel 默认常规格式,可能被自动识别为数值或科学计数法,导致前导零、长号码或编码内容失真。 + +## 修改内容 + +- 为信息模块导入模板 DTO 中的保真字段补充 `@TextFormat`: + - 账户库:证件号、账户号码、银行代码。 + - 员工信息维护:身份证号、电话;员工资产 Sheet 的员工身份证号保持文本格式。 + - 员工亲属关系、信贷客户家庭关系:主身份证号、关系人证件号码、手机号码 1、手机号码 2。 + - 员工亲属实体关联、信贷客户实体关联:身份证号、统一社会信用代码。 + - 实体库管理、实体中介:统一社会信用代码、法定代表人证件号码。 + - 个人中介:证件号码、手机号码、企业统一信用码、关联中介本人证件号码。 + - 中介实体关联关系:中介本人证件号码、统一社会信用代码。 + - 招投标信息维护:采购事项 ID、申请人工号、采购负责人工号、供应商统一信用代码、供应商联系电话、供应商银行账户。 + - 招聘信息维护:招聘记录编号、证件号码、面试官工号;历史工作经历 Sheet 的招聘记录编号。 +- 更新普通导入模板生成方法 `EasyExcelUtil.importTemplateExcel(...)`,使不带字典下拉框的模板也会注册 `TextFormatWriteHandler`。 +- 扩展 `EasyExcelUtilTemplateTest`,实际生成各导入模板 workbook 并断言上述列的默认列格式为文本格式 `@`。 + +## 影响范围 + +- 后端模板生成工具: + - `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/utils/EasyExcelUtil.java` +- 信息模块导入模板 DTO: + - `CcdiAccountInfoExcel` + - `CcdiBaseStaffExcel` + - `CcdiCustEnterpriseRelationExcel` + - `CcdiCustFmyRelationExcel` + - `CcdiEnterpriseBaseInfoExcel` + - `CcdiIntermediaryEnterpriseRelationExcel` + - `CcdiIntermediaryEntityExcel` + - `CcdiIntermediaryPersonExcel` + - `CcdiPurchaseTransactionExcel` + - `CcdiPurchaseTransactionSupplierExcel` + - `CcdiStaffEnterpriseRelationExcel` + - `CcdiStaffFmyRelationExcel` + - `CcdiStaffRecruitmentExcel` + - `CcdiStaffRecruitmentWorkExcel` +- 不改变导入字段顺序、字段类型、业务校验、字典下拉框和页面交互。 + +## 验证情况 + +- 已执行定向模板测试: + +```bash +MAVEN_OPTS="-javaagent:$HOME/.m2/repository/net/bytebuddy/byte-buddy-agent/1.17.8/byte-buddy-agent-1.17.8.jar" mvn -pl ccdi-info-collection -am -Dtest=EasyExcelUtilTemplateTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +- 验证结果:通过,`EasyExcelUtilTemplateTest` 共 7 个用例,0 失败,0 错误。 +- 测试过程已实际生成单 Sheet 与双 Sheet 导入模板,并检查保真字段列格式为文本格式。 +- 本次未启动前端或后端进程,无需清理测试进程。