Update import templates and relation query fields
This commit is contained in:
@@ -33,6 +33,10 @@ public class CcdiCustFmyRelationQueryDTO implements Serializable {
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 关系人身份证号 */
|
||||
@Schema(description = "关系人身份证号")
|
||||
private String relationCertNo;
|
||||
|
||||
/** 状态 */
|
||||
@Schema(description = "状态:0-无效,1-有效")
|
||||
private Integer status;
|
||||
|
||||
@@ -37,6 +37,10 @@ public class CcdiStaffFmyRelationQueryDTO implements Serializable {
|
||||
@Schema(description = "关系人姓名")
|
||||
private String relationName;
|
||||
|
||||
/** 关系人身份证号 */
|
||||
@Schema(description = "关系人身份证号")
|
||||
private String relationCertNo;
|
||||
|
||||
/** 状态 */
|
||||
@Schema(description = "状态:0-无效,1-有效")
|
||||
private Integer status;
|
||||
|
||||
@@ -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.Required;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@@ -17,17 +18,19 @@ public class CcdiIntermediaryEnterpriseRelationExcel implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 中介本人证件号码 */
|
||||
@ExcelProperty(value = "中介本人证件号码*", index = 0)
|
||||
@ExcelProperty(value = "中介本人证件号码", index = 0)
|
||||
@ColumnWidth(24)
|
||||
@Required
|
||||
private String ownerPersonId;
|
||||
|
||||
/** 统一社会信用代码 */
|
||||
@ExcelProperty(value = "统一社会信用代码*", index = 1)
|
||||
@ExcelProperty(value = "统一社会信用代码", index = 1)
|
||||
@ColumnWidth(24)
|
||||
@Required
|
||||
private String socialCreditCode;
|
||||
|
||||
/** 关联人职务 */
|
||||
@ExcelProperty(value = "关联人职务", index = 2)
|
||||
/** 关联职务 */
|
||||
@ExcelProperty(value = "关联职务", index = 2)
|
||||
@ColumnWidth(20)
|
||||
private String relationPersonPost;
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ public class CcdiStaffRecruitmentExcel implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 招聘项目编号 */
|
||||
@ExcelProperty(value = "招聘项目编号", index = 0)
|
||||
/** 招聘记录编号 */
|
||||
@ExcelProperty(value = "招聘记录编号", index = 0)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String recruitId;
|
||||
@@ -51,66 +51,72 @@ public class CcdiStaffRecruitmentExcel implements Serializable {
|
||||
@Required
|
||||
private String posDesc;
|
||||
|
||||
/** 应聘人员姓名 */
|
||||
@ExcelProperty(value = "应聘人员姓名", index = 5)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candName;
|
||||
|
||||
/** 应聘人员学历 */
|
||||
@ExcelProperty(value = "应聘人员学历", index = 6)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candEdu;
|
||||
|
||||
/** 应聘人员证件号码 */
|
||||
@ExcelProperty(value = "应聘人员证件号码", index = 7)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String candId;
|
||||
|
||||
/** 应聘人员毕业院校 */
|
||||
@ExcelProperty(value = "应聘人员毕业院校", index = 8)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String candSchool;
|
||||
|
||||
/** 应聘人员专业 */
|
||||
@ExcelProperty(value = "应聘人员专业", index = 9)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candMajor;
|
||||
|
||||
/** 应聘人员毕业年月 */
|
||||
@ExcelProperty(value = "应聘人员毕业年月", index = 10)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candGrad;
|
||||
|
||||
/** 录用情况 */
|
||||
@ExcelProperty(value = "录用情况", index = 11)
|
||||
@ExcelProperty(value = "录用情况", index = 5)
|
||||
@ColumnWidth(10)
|
||||
@DictDropdown(dictType = "ccdi_admit_status")
|
||||
@Required
|
||||
private String admitStatus;
|
||||
|
||||
/** 候选人姓名 */
|
||||
@ExcelProperty(value = "候选人姓名", index = 6)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candName;
|
||||
|
||||
/** 招聘类型 */
|
||||
@ExcelProperty(value = "招聘类型", index = 7)
|
||||
@ColumnWidth(12)
|
||||
@Required
|
||||
private String recruitType;
|
||||
|
||||
/** 应聘人员学历 */
|
||||
@ExcelProperty(value = "学历", index = 8)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candEdu;
|
||||
|
||||
/** 应聘人员证件号码 */
|
||||
@ExcelProperty(value = "证件号码", index = 9)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String candId;
|
||||
|
||||
/** 应聘人员毕业年月 */
|
||||
@ExcelProperty(value = "毕业年月", index = 10)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candGrad;
|
||||
|
||||
/** 应聘人员毕业院校 */
|
||||
@ExcelProperty(value = "毕业院校", index = 11)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String candSchool;
|
||||
|
||||
/** 应聘人员专业 */
|
||||
@ExcelProperty(value = "专业", index = 12)
|
||||
@ColumnWidth(15)
|
||||
@Required
|
||||
private String candMajor;
|
||||
|
||||
/** 面试官1姓名 */
|
||||
@ExcelProperty(value = "面试官1姓名", index = 12)
|
||||
@ExcelProperty(value = "面试官1姓名", index = 13)
|
||||
@ColumnWidth(15)
|
||||
private String interviewerName1;
|
||||
|
||||
/** 面试官1工号 */
|
||||
@ExcelProperty(value = "面试官1工号", index = 13)
|
||||
@ExcelProperty(value = "面试官1工号", index = 14)
|
||||
@ColumnWidth(15)
|
||||
private String interviewerId1;
|
||||
|
||||
/** 面试官2姓名 */
|
||||
@ExcelProperty(value = "面试官2姓名", index = 14)
|
||||
@ExcelProperty(value = "面试官2姓名", index = 15)
|
||||
@ColumnWidth(15)
|
||||
private String interviewerName2;
|
||||
|
||||
/** 面试官2工号 */
|
||||
@ExcelProperty(value = "面试官2工号", index = 15)
|
||||
@ExcelProperty(value = "面试官2工号", index = 16)
|
||||
@ColumnWidth(15)
|
||||
private String interviewerId2;
|
||||
}
|
||||
|
||||
@@ -61,20 +61,20 @@ public class CcdiStaffRecruitmentWorkExcel implements Serializable {
|
||||
@ColumnWidth(18)
|
||||
private String departmentName;
|
||||
|
||||
/** 岗位 */
|
||||
@ExcelProperty(value = "岗位", index = 7)
|
||||
/** 岗位名称 */
|
||||
@ExcelProperty(value = "岗位名称", index = 7)
|
||||
@ColumnWidth(20)
|
||||
@Required
|
||||
private String positionName;
|
||||
|
||||
/** 入职年月 */
|
||||
@ExcelProperty(value = "入职年月", index = 8)
|
||||
@ExcelProperty(value = "入职时间", index = 8)
|
||||
@ColumnWidth(12)
|
||||
@Required
|
||||
private String jobStartMonth;
|
||||
|
||||
/** 离职年月 */
|
||||
@ExcelProperty(value = "离职年月", index = 9)
|
||||
@ExcelProperty(value = "离职时间", index = 9)
|
||||
@ColumnWidth(12)
|
||||
private String jobEndMonth;
|
||||
|
||||
@@ -83,8 +83,8 @@ public class CcdiStaffRecruitmentWorkExcel implements Serializable {
|
||||
@ColumnWidth(30)
|
||||
private String departureReason;
|
||||
|
||||
/** 工作内容 */
|
||||
@ExcelProperty(value = "工作内容", index = 11)
|
||||
/** 主要工作内容 */
|
||||
@ExcelProperty(value = "主要工作内容", index = 11)
|
||||
@ColumnWidth(35)
|
||||
private String workContent;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public class IntermediaryEnterpriseRelationImportFailureVO implements Serializab
|
||||
@Schema(description = "统一社会信用代码")
|
||||
private String socialCreditCode;
|
||||
|
||||
@Schema(description = "关联人职务")
|
||||
@Schema(description = "关联职务")
|
||||
private String relationPersonPost;
|
||||
|
||||
@Schema(description = "备注")
|
||||
|
||||
@@ -79,12 +79,14 @@ public class CcdiIntermediaryEnterpriseRelationImportServiceImpl implements ICcd
|
||||
try {
|
||||
validateExcel(excel);
|
||||
|
||||
String ownerBizId = ownerBizIdByPersonId.get(excel.getOwnerPersonId());
|
||||
String ownerPersonId = trim(excel.getOwnerPersonId());
|
||||
String socialCreditCode = trim(excel.getSocialCreditCode());
|
||||
String ownerBizId = ownerBizIdByPersonId.get(ownerPersonId);
|
||||
if (StringUtils.isEmpty(ownerBizId)) {
|
||||
throw new RuntimeException("中介本人不存在,请先导入或维护中介本人信息");
|
||||
}
|
||||
|
||||
String combination = ownerBizId + "|" + excel.getSocialCreditCode();
|
||||
String combination = ownerBizId + "|" + socialCreditCode;
|
||||
if (existingCombinations.contains(combination)) {
|
||||
throw new RuntimeException("中介实体关联关系已存在,请勿重复导入");
|
||||
}
|
||||
@@ -95,6 +97,9 @@ public class CcdiIntermediaryEnterpriseRelationImportServiceImpl implements ICcd
|
||||
CcdiIntermediaryEnterpriseRelation relation = new CcdiIntermediaryEnterpriseRelation();
|
||||
BeanUtils.copyProperties(excel, relation);
|
||||
relation.setIntermediaryBizId(ownerBizId);
|
||||
relation.setSocialCreditCode(socialCreditCode);
|
||||
relation.setRelationPersonPost(trim(excel.getRelationPersonPost()));
|
||||
relation.setRemark(trim(excel.getRemark()));
|
||||
relation.setCreatedBy(userName);
|
||||
relation.setUpdatedBy(userName);
|
||||
successRecords.add(relation);
|
||||
@@ -165,6 +170,7 @@ public class CcdiIntermediaryEnterpriseRelationImportServiceImpl implements ICcd
|
||||
private Map<String, String> getOwnerBizIdByPersonId(List<CcdiIntermediaryEnterpriseRelationExcel> excelList) {
|
||||
List<String> ownerPersonIds = excelList.stream()
|
||||
.map(CcdiIntermediaryEnterpriseRelationExcel::getOwnerPersonId)
|
||||
.map(this::trim)
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
@@ -183,11 +189,12 @@ public class CcdiIntermediaryEnterpriseRelationImportServiceImpl implements ICcd
|
||||
List<CcdiIntermediaryEnterpriseRelationExcel> excelList) {
|
||||
List<String> combinations = excelList.stream()
|
||||
.map(excel -> {
|
||||
String ownerBizId = ownerBizIdByPersonId.get(excel.getOwnerPersonId());
|
||||
if (StringUtils.isEmpty(ownerBizId) || StringUtils.isEmpty(excel.getSocialCreditCode())) {
|
||||
String ownerBizId = ownerBizIdByPersonId.get(trim(excel.getOwnerPersonId()));
|
||||
String socialCreditCode = trim(excel.getSocialCreditCode());
|
||||
if (StringUtils.isEmpty(ownerBizId) || StringUtils.isEmpty(socialCreditCode)) {
|
||||
return null;
|
||||
}
|
||||
return ownerBizId + "|" + excel.getSocialCreditCode();
|
||||
return ownerBizId + "|" + socialCreditCode;
|
||||
})
|
||||
.filter(StringUtils::isNotEmpty)
|
||||
.distinct()
|
||||
@@ -199,24 +206,33 @@ public class CcdiIntermediaryEnterpriseRelationImportServiceImpl implements ICcd
|
||||
}
|
||||
|
||||
private void validateExcel(CcdiIntermediaryEnterpriseRelationExcel excel) {
|
||||
if (StringUtils.isEmpty(excel.getOwnerPersonId())) {
|
||||
String ownerPersonId = trim(excel.getOwnerPersonId());
|
||||
String socialCreditCode = trim(excel.getSocialCreditCode());
|
||||
String relationPersonPost = trim(excel.getRelationPersonPost());
|
||||
String remark = trim(excel.getRemark());
|
||||
|
||||
if (StringUtils.isEmpty(ownerPersonId)) {
|
||||
throw new RuntimeException("中介本人证件号码不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(excel.getSocialCreditCode())) {
|
||||
if (StringUtils.isEmpty(socialCreditCode)) {
|
||||
throw new RuntimeException("统一社会信用代码不能为空");
|
||||
}
|
||||
String ownerPersonIdError = IdCardUtil.getErrorMessage(excel.getOwnerPersonId());
|
||||
String ownerPersonIdError = IdCardUtil.getErrorMessage(ownerPersonId);
|
||||
if (ownerPersonIdError != null) {
|
||||
throw new RuntimeException("中介本人证件号码" + ownerPersonIdError);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(excel.getRelationPersonPost()) && excel.getRelationPersonPost().length() > 100) {
|
||||
throw new RuntimeException("关联人职务长度不能超过100个字符");
|
||||
if (StringUtils.isNotEmpty(relationPersonPost) && relationPersonPost.length() > 100) {
|
||||
throw new RuntimeException("关联职务长度不能超过100个字符");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(excel.getRemark()) && excel.getRemark().length() > 500) {
|
||||
if (StringUtils.isNotEmpty(remark) && remark.length() > 500) {
|
||||
throw new RuntimeException("备注长度不能超过500个字符");
|
||||
}
|
||||
}
|
||||
|
||||
private String trim(String value) {
|
||||
return value == null ? null : value.trim();
|
||||
}
|
||||
|
||||
private IntermediaryEnterpriseRelationImportFailureVO createFailureVO(CcdiIntermediaryEnterpriseRelationExcel excel,
|
||||
String errorMessage) {
|
||||
IntermediaryEnterpriseRelationImportFailureVO failure = new IntermediaryEnterpriseRelationImportFailureVO();
|
||||
|
||||
@@ -178,7 +178,7 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
||||
try {
|
||||
CcdiStaffRecruitmentAddDTO addDTO = new CcdiStaffRecruitmentAddDTO();
|
||||
BeanUtils.copyProperties(excel, addDTO);
|
||||
addDTO.setRecruitType(RecruitType.inferCode(addDTO.getRecruitName()));
|
||||
addDTO.setRecruitType(normalizeRecruitType(excel.getRecruitType()));
|
||||
|
||||
validateRecruitmentData(addDTO, mainRow.sheetRowNum());
|
||||
|
||||
@@ -376,22 +376,22 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "职位描述不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getCandName())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "应聘人员姓名不能为空");
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "候选人姓名不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getCandEdu())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "应聘人员学历不能为空");
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "学历不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getCandId())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "证件号码不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getCandSchool())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "应聘人员毕业院校不能为空");
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "毕业院校不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getCandMajor())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "应聘人员专业不能为空");
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "专业不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getCandGrad())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "应聘人员毕业年月不能为空");
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "毕业年月不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(addDTO.getAdmitStatus())) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "录用情况不能为空");
|
||||
@@ -414,10 +414,23 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
||||
}
|
||||
|
||||
if (RecruitType.getDescByCode(addDTO.getRecruitType()) == null) {
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "招聘类型只能填写'SOCIAL'或'CAMPUS'");
|
||||
throw buildValidationException(MAIN_SHEET_NAME, List.of(sheetRowNum), "招聘类型只能填写'SOCIAL/社招'或'CAMPUS/校招'");
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeRecruitType(String recruitType) {
|
||||
String value = trim(recruitType);
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
return value;
|
||||
}
|
||||
for (RecruitType type : RecruitType.values()) {
|
||||
if (type.getCode().equals(value) || type.getDesc().equals(value)) {
|
||||
return type.getCode();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private void validateWorkGroup(List<WorkImportRow> workRows, CcdiStaffRecruitment recruitment) {
|
||||
Set<Integer> processedSortOrders = new HashSet<>();
|
||||
for (WorkImportRow workRow : workRows) {
|
||||
@@ -451,14 +464,14 @@ public class CcdiStaffRecruitmentImportServiceImpl implements ICcdiStaffRecruitm
|
||||
throw buildValidationException(WORK_SHEET_NAME, List.of(sheetRowNum), "工作单位不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(trim(excel.getPositionName()))) {
|
||||
throw buildValidationException(WORK_SHEET_NAME, List.of(sheetRowNum), "岗位不能为空");
|
||||
throw buildValidationException(WORK_SHEET_NAME, List.of(sheetRowNum), "岗位名称不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(trim(excel.getJobStartMonth()))) {
|
||||
throw buildValidationException(WORK_SHEET_NAME, List.of(sheetRowNum), "入职年月不能为空");
|
||||
throw buildValidationException(WORK_SHEET_NAME, List.of(sheetRowNum), "入职时间不能为空");
|
||||
}
|
||||
validateMonth(excel.getJobStartMonth(), "入职年月", sheetRowNum);
|
||||
validateMonth(excel.getJobStartMonth(), "入职时间", sheetRowNum);
|
||||
if (StringUtils.isNotEmpty(trim(excel.getJobEndMonth()))) {
|
||||
validateMonth(excel.getJobEndMonth(), "离职年月", sheetRowNum);
|
||||
validateMonth(excel.getJobEndMonth(), "离职时间", sheetRowNum);
|
||||
}
|
||||
if (recruitment == null) {
|
||||
throw buildValidationException(WORK_SHEET_NAME, List.of(sheetRowNum), "招聘记录编号不存在,请先维护招聘主信息");
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
<if test="query.relationName != null and query.relationName != ''">
|
||||
AND r.relation_name LIKE CONCAT('%', #{query.relationName}, '%')
|
||||
</if>
|
||||
<if test="query.relationCertNo != null and query.relationCertNo != ''">
|
||||
AND r.relation_cert_no LIKE CONCAT('%', #{query.relationCertNo}, '%')
|
||||
</if>
|
||||
ORDER BY r.create_time DESC
|
||||
</select>
|
||||
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
<if test="query.relationName != null and query.relationName != ''">
|
||||
AND r.relation_name LIKE CONCAT('%', #{query.relationName}, '%')
|
||||
</if>
|
||||
<if test="query.relationCertNo != null and query.relationCertNo != ''">
|
||||
AND r.relation_cert_no LIKE CONCAT('%', #{query.relationCertNo}, '%')
|
||||
</if>
|
||||
<if test="query.status != null">
|
||||
AND r.status = #{query.status}
|
||||
</if>
|
||||
@@ -115,6 +118,9 @@
|
||||
<if test="query.relationName != null and query.relationName != ''">
|
||||
AND r.relation_name LIKE CONCAT('%', #{query.relationName}, '%')
|
||||
</if>
|
||||
<if test="query.relationCertNo != null and query.relationCertNo != ''">
|
||||
AND r.relation_cert_no LIKE CONCAT('%', #{query.relationCertNo}, '%')
|
||||
</if>
|
||||
<if test="query.status != null">
|
||||
AND r.status = #{query.status}
|
||||
</if>
|
||||
|
||||
@@ -96,6 +96,26 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoSync_shouldResolveFamilyIdFromCurrentWorkbookRelation() {
|
||||
CcdiAssetInfoExcel excel = buildExcel("320101199001010033", "股权");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(assetInfoMapper.selectOwnerCandidatesByRelationCertNos(List.of("320101199001010033")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
service.importAssetInfoSync(
|
||||
List.of(excel),
|
||||
"task-current-workbook",
|
||||
"tester",
|
||||
Map.of("320101199001010033", Set.of("320101199009090099"))
|
||||
);
|
||||
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(captor.capture());
|
||||
assertEquals("320101199009090099", captor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199001010033", captor.getValue().get(0).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoAsync_shouldFailWhenEmployeeIdCardIsUsedForFamilyAssetImport() {
|
||||
CcdiAssetInfoExcel excel = buildExcel("320101199001010011", "房产");
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.data.redis.core.ValueOperations;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -79,6 +80,26 @@ class CcdiBaseStaffAssetImportServiceImplTest {
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoSync_shouldImportWhenOwnerComesFromCurrentWorkbook() {
|
||||
CcdiBaseStaffAssetInfoExcel excel = buildExcel("320101199001010033", "存款");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(assetInfoMapper.selectOwnerCandidatesByBaseStaffIdCards(List.of("320101199001010033")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
service.importAssetInfoSync(
|
||||
List.of(excel),
|
||||
"task-current-workbook",
|
||||
"tester",
|
||||
Map.of("320101199001010033", Set.of("320101199001010033"))
|
||||
);
|
||||
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(captor.capture());
|
||||
assertEquals("320101199001010033", captor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199001010033", captor.getValue().get(0).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoAsync_shouldFailWhenFamilyCertificateIsUsed() {
|
||||
CcdiBaseStaffAssetInfoExcel excel = buildExcel("320101199201010022", "车辆");
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.info.collection.domain.CcdiStaffEnterpriseRelation;
|
||||
import com.ruoyi.info.collection.domain.CcdiStaffFmyRelation;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiStaffEnterpriseRelationAddDTO;
|
||||
@@ -10,8 +12,10 @@ import com.ruoyi.info.collection.domain.vo.CcdiStaffEnterpriseRelationOptionVO;
|
||||
import com.ruoyi.info.collection.mapper.CcdiStaffEnterpriseRelationMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
|
||||
import com.ruoyi.info.collection.service.impl.CcdiStaffEnterpriseRelationServiceImpl;
|
||||
import com.ruoyi.info.collection.service.support.EnterpriseAutoFillService;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
@@ -20,13 +24,17 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -55,8 +63,17 @@ class CcdiStaffEnterpriseRelationServiceImplTest {
|
||||
@Mock
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Mock
|
||||
private EnterpriseAutoFillService enterpriseAutoFillService;
|
||||
|
||||
@AfterEach
|
||||
void clearSecurityContext() {
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
void insertRelation_shouldAllowValidFamily() {
|
||||
mockLoginUser("tester");
|
||||
CcdiStaffEnterpriseRelationAddDTO addDTO = buildAddDto();
|
||||
CcdiStaffFmyRelation familyRelation = new CcdiStaffFmyRelation();
|
||||
familyRelation.setRelationCertNo(addDTO.getPersonId());
|
||||
@@ -75,6 +92,13 @@ class CcdiStaffEnterpriseRelationServiceImplTest {
|
||||
assertEquals(1, captor.getValue().getStatus());
|
||||
assertEquals("MANUAL", captor.getValue().getDataSource());
|
||||
assertEquals(1, captor.getValue().getIsEmpFamily());
|
||||
verify(enterpriseAutoFillService).ensureExists(argThat(item ->
|
||||
"91310000123456789A".equals(item.socialCreditCode())
|
||||
&& "测试企业".equals(item.enterpriseName())
|
||||
&& "EMP_RELATION".equals(item.entSource())
|
||||
&& "MANUAL".equals(item.dataSource())
|
||||
&& "tester".equals(item.userName())
|
||||
));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,4 +177,13 @@ class CcdiStaffEnterpriseRelationServiceImplTest {
|
||||
assistant.setCurrentNamespace(namespace);
|
||||
TableInfoHelper.initTableInfo(assistant, entityClass);
|
||||
}
|
||||
|
||||
private void mockLoginUser(String userName) {
|
||||
SysUser user = new SysUser();
|
||||
user.setUserName(userName);
|
||||
LoginUser loginUser = new LoginUser(1L, 1L, user, Set.of());
|
||||
UsernamePasswordAuthenticationToken authentication =
|
||||
new UsernamePasswordAuthenticationToken(loginUser, null, List.of());
|
||||
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# 员工亲属关系与信贷客户家庭关系关系人身份证号展示实施记录
|
||||
|
||||
## 修改内容
|
||||
|
||||
- 在【员工亲属关系维护】列表新增“关系人身份证号”列,展示接口返回的 `relationCertNo`。
|
||||
- 在【信贷客户家庭关系】列表新增“关系人身份证号”列,展示接口返回的 `relationCertNo`。
|
||||
- 两个页面查询区新增“关系人身份证号”筛选项,支持按关系人身份证号模糊查询。
|
||||
- 后端查询 DTO 与 MyBatis 分页 SQL 补充 `relationCertNo` 查询条件,保持页面查询条件与接口过滤逻辑一致。
|
||||
|
||||
## 影响范围
|
||||
|
||||
- 前端页面:
|
||||
- `ruoyi-ui/src/views/ccdiStaffFmyRelation/index.vue`
|
||||
- `ruoyi-ui/src/views/ccdiCustFmyRelation/index.vue`
|
||||
- 后端查询:
|
||||
- `CcdiStaffFmyRelationQueryDTO`
|
||||
- `CcdiCustFmyRelationQueryDTO`
|
||||
- `CcdiStaffFmyRelationMapper.xml`
|
||||
- `CcdiCustFmyRelationMapper.xml`
|
||||
|
||||
## 验证情况
|
||||
|
||||
- 已确认两个分页接口原 SQL 与 VO 均包含 `relation_cert_no` / `relationCertNo` 字段。
|
||||
- 已执行 `mvn -pl ccdi-info-collection -am compile -DskipTests`,编译通过。
|
||||
- 已按 `ruoyi-ui/.nvmrc` 使用 Node `14.21.3` 执行 `npm run build:prod`,构建通过,仅存在既有资源体积告警。
|
||||
- 已通过 `browser-use` 打开真实前端页面验证:
|
||||
- `/maintain/staffFmyRelation` 展示“关系人身份证号”筛选项与表格列,并可按 `330101196501010011` 查询到对应员工亲属关系记录。
|
||||
- `/maintain/custFmyRelation` 展示“关系人身份证号”筛选项与表格列,并可按 `330101197806060077` 查询到对应信贷客户家庭关系记录。
|
||||
- 浏览器控制台未发现错误日志。
|
||||
@@ -0,0 +1,67 @@
|
||||
# 招聘信息与中介实体关系导入模板修复实施记录
|
||||
|
||||
## 背景
|
||||
|
||||
- 【招聘信息维护】当前页面与数据库口径已调整为“招聘记录编号”,原导入模板仍存在旧字段名称和字段顺序不一致问题,导致按模板导入失败。
|
||||
- 【中介库管理】“导入中介实体关联关系”按钮对应模板字段与新增关联机构弹窗不一致,且导入提示仍要求统一社会信用代码必须已存在于机构表。
|
||||
|
||||
## 修改内容
|
||||
|
||||
### 招聘信息维护
|
||||
|
||||
- 更新招聘主 Sheet 模板字段顺序,使其与新增页字段顺序一致:
|
||||
- 招聘记录编号、招聘项目名称、职位名称、职位类别、职位描述、录用情况、候选人姓名、招聘类型、学历、证件号码、毕业年月、毕业院校、专业、面试官1姓名、面试官1工号、面试官2姓名、面试官2工号。
|
||||
- 更新历史工作经历 Sheet 字段文案:
|
||||
- 岗位名称、入职时间、离职时间、主要工作内容。
|
||||
- 导入逻辑不再从招聘项目名称推断招聘类型,改为读取模板中的“招聘类型”字段。
|
||||
- 招聘类型支持填写编码或页面文案:
|
||||
- `SOCIAL` / `社招`
|
||||
- `CAMPUS` / `校招`
|
||||
- 同步调整导入校验提示,使错误信息与当前页面字段保持一致。
|
||||
- 前端导入弹窗增加招聘类型填写说明。
|
||||
|
||||
### 中介库管理
|
||||
|
||||
- 更新“导入中介实体关联关系”模板字段:
|
||||
- 中介本人证件号码、统一社会信用代码、关联职务、备注。
|
||||
- 将必填标识改为 `@Required`,避免字段标题携带 `*` 后与页面字段不一致。
|
||||
- 导入逻辑统一 trim 证件号、统一社会信用代码、关联职务、备注,避免空格导致查询不到中介本人或重复判断失效。
|
||||
- 失败记录字段文案由“关联人职务”统一为“关联职务”。
|
||||
- 前端导入说明调整为:
|
||||
- 中介本人证件号码用于定位新增弹窗中的所属中介;
|
||||
- 其余字段与新增关联机构弹窗一致;
|
||||
- 统一社会信用代码未存在于实体库时会自动补入。
|
||||
|
||||
## 影响范围
|
||||
|
||||
- 后端导入模板与导入解析:
|
||||
- `CcdiStaffRecruitmentExcel`
|
||||
- `CcdiStaffRecruitmentWorkExcel`
|
||||
- `CcdiStaffRecruitmentImportServiceImpl`
|
||||
- `CcdiIntermediaryEnterpriseRelationExcel`
|
||||
- `CcdiIntermediaryEnterpriseRelationImportServiceImpl`
|
||||
- `IntermediaryEnterpriseRelationImportFailureVO`
|
||||
- 前端导入弹窗与失败记录展示:
|
||||
- 招聘信息维护导入提示
|
||||
- 中介库管理导入中介实体关联关系提示
|
||||
- 中介实体关系导入失败记录字段标签
|
||||
|
||||
## 验证情况
|
||||
|
||||
- 后端编译:`mvn -pl ccdi-info-collection -am compile -DskipTests` 通过。
|
||||
- 前端构建:`ruoyi-ui` 下执行 `nvm use` 后,`npm run build:prod` 通过。
|
||||
- 真实模板下载:
|
||||
- `/ccdi/staffRecruitment/importTemplate` 下载模板成功,表头已变为当前字段顺序。
|
||||
- `/ccdi/intermediary/importEnterpriseRelationTemplate` 下载模板成功,表头已变为“中介本人证件号码、统一社会信用代码、关联职务、备注”。
|
||||
- 真实接口导入:
|
||||
- 招聘信息基于下载模板造数,主 Sheet 与历史工作经历 Sheet 共 2 行导入成功,详情接口回查历史工作经历 1 条。
|
||||
- 中介实体关联关系基于下载模板造数,导入成功 1 条,列表可回查关联职务。
|
||||
- 清理情况:
|
||||
- 已删除本轮成功导入的招聘记录及历史工作经历。
|
||||
- 已删除本轮成功导入的中介实体关联关系。
|
||||
- 已删除本轮由导入自动补入的实体库测试数据。
|
||||
- 真实页面检查:
|
||||
- 使用 `browser-use` 打开真实页面 `/maintain/staffRecruitment`,确认招聘信息导入弹窗显示新的双 Sheet 和招聘类型说明。
|
||||
- 使用 `browser-use` 打开真实页面 `/maintain/intermediary`,确认“导入中介实体关联关系”按钮可打开导入弹窗,字段说明与新增关联机构口径一致。
|
||||
- `browser-use` 当前不支持文件上传,页面文件选择动作无法在浏览器插件内完成;文件上传动作已通过同一真实导入接口完成验证。
|
||||
- 测试完成后已停止本轮启动的后端与前端进程。
|
||||
@@ -24,6 +24,13 @@
|
||||
- 招投标供应商新增、编辑和导入时,对合法统一社会信用代码的供应商自动补入实体库。
|
||||
- 新增企业来源枚举 `SUPPLIER`,用于标识供应商来源。
|
||||
|
||||
### 测试补充
|
||||
|
||||
- 同步调整员工信息维护、员工亲属关系维护导入 Controller 单测,按新的统一编排入口断言返回任务 ID。
|
||||
- 补充员工资产导入单测,验证同一模板中本轮成功导入的员工身份证号可作为员工资产归属。
|
||||
- 补充亲属资产导入单测,验证同一模板中本轮成功导入的亲属关系可作为亲属资产归属。
|
||||
- 补充员工亲属实体关联新增单测,验证成功新增时调用实体库自动补入服务,来源为 `EMP_RELATION`、数据来源为 `MANUAL`。
|
||||
|
||||
## 影响范围
|
||||
|
||||
- `/ccdi/baseStaff/importData`
|
||||
@@ -36,6 +43,16 @@
|
||||
- 执行 `mvn -pl ccdi-info-collection -am -DskipTests compile`,结果:BUILD SUCCESS。
|
||||
- 执行 `mvn -DskipTests compile`,结果:BUILD SUCCESS。
|
||||
- 代码路径核对:员工主 Sheet 为空时仅调用员工资产导入服务并返回 `assetTaskId`;亲属关系主 Sheet 为空时仅调用亲属资产导入服务并返回 `assetTaskId`。
|
||||
- 复测执行 `mvn -pl ccdi-info-collection -am -Dtest=CcdiBaseStaffControllerTest,CcdiStaffFmyRelationControllerTest,CcdiBaseStaffAssetImportServiceImplTest,CcdiAssetInfoImportServiceImplTest,CcdiBaseStaffDualImportServiceTest,CcdiStaffFmyRelationImportServiceImplTest,CcdiStaffEnterpriseRelationServiceImplTest,CcdiStaffEnterpriseRelationImportServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test`,结果:BUILD SUCCESS,Tests run: 39, Failures: 0, Errors: 0, Skipped: 0。
|
||||
- 复测执行 `mvn -pl ccdi-info-collection -am -Dsurefire.failIfNoSpecifiedTests=false test`,结果:BUILD FAILURE;本次问题相关用例均已通过,剩余失败为中介实体关联测试未注入自动补入服务,以及 `CcdiPurchaseTransactionFeatureContractTest` 依赖的 `sql/ccdi_purchase_transaction.sql` 文件不存在。
|
||||
- 使用 `bin/restart_java_backend.sh` 重启后端并通过 `/login/test` 探活,结果:HTTP 200。
|
||||
- 通过真实接口下载当前导入模板,基于模板生成测试文件,执行 `/ccdi/baseStaff/importData`:员工任务 `8ea63988-deb2-4791-a24a-f15ca2c8cd6e` 与员工资产任务 `f281beca-bb58-4076-86db-6f9f948bbaf0` 均为 `SUCCESS`,成功 1 条、失败 0 条。
|
||||
- 回查 `ccdi_base_staff` 与 `ccdi_asset_info`:员工主数据写入成功;员工资产 `family_id` 与 `person_id` 均为本轮员工身份证号,第二个 Sheet 未再出现“未找到资产归属员工”。
|
||||
- 执行 `/ccdi/staffFmyRelation/importData`:亲属关系任务 `702466a9-0113-4e89-bcf1-8d760ee34543` 与亲属资产任务 `f11906d4-b9f3-4656-834c-fc9dc1a27704` 均为 `SUCCESS`,成功 1 条、失败 0 条。
|
||||
- 回查 `ccdi_staff_fmy_relation` 与 `ccdi_asset_info`:亲属关系主数据写入成功;亲属资产 `family_id` 为员工身份证号、`person_id` 为亲属身份证号,第二个 Sheet 已正确关联到本轮亲属主数据。
|
||||
- 执行 `/ccdi/staffEnterpriseRelation/importData`:员工亲属实体关联任务 `6361fc94-0d32-4da0-b1a0-7419b399710d` 为 `SUCCESS`,成功 1 条、失败 0 条。
|
||||
- 回查 `ccdi_staff_enterprise_relation` 与 `ccdi_enterprise_base_info`:实体关联写入成功;实体库自动生成对应企业,`ent_source=EMP_RELATION`、`data_source=IMPORT`。
|
||||
- 验证结束后执行清理 SQL,回查本轮员工、亲属、资产、亲属实体关联和实体库测试数据计数均为 0。
|
||||
|
||||
## 备注
|
||||
|
||||
|
||||
@@ -36,6 +36,17 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="关系人身份证号" prop="relationCertNo">
|
||||
<el-input
|
||||
v-model="queryParams.relationCertNo"
|
||||
placeholder="请输入关系人身份证号"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
@@ -100,6 +111,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="关系人姓名" align="center" prop="relationName" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="关系人身份证号" align="center" prop="relationCertNo" width="180"/>
|
||||
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.ccdi_indiv_gender" :value="scope.row.gender"/>
|
||||
@@ -497,6 +509,7 @@ export default {
|
||||
personId: null,
|
||||
relationType: null,
|
||||
relationName: null,
|
||||
relationCertNo: null,
|
||||
status: null
|
||||
},
|
||||
// 表单参数
|
||||
|
||||
@@ -130,7 +130,9 @@ export default {
|
||||
statusApi: getEnterpriseRelationImportStatus,
|
||||
tips: [
|
||||
"只导入中介与机构关系;",
|
||||
"统一社会信用代码必须已存在于系统机构表。"
|
||||
"中介本人证件号码用于定位新增弹窗中的所属中介;",
|
||||
"其余字段与新增关联机构弹窗一致;",
|
||||
"统一社会信用代码未存在于实体库时会自动补入。"
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
<el-table :data="enterpriseRelationFailureList" v-loading="enterpriseRelationFailureLoading">
|
||||
<el-table-column label="中介本人证件号码" prop="ownerPersonId" align="center" min-width="180" />
|
||||
<el-table-column label="统一社会信用代码" prop="socialCreditCode" align="center" min-width="180" />
|
||||
<el-table-column label="关联人职务" prop="relationPersonPost" align="center" />
|
||||
<el-table-column label="关联职务" prop="relationPersonPost" align="center" />
|
||||
<el-table-column label="失败原因" prop="errorMessage" align="center" min-width="220" :show-overflow-tooltip="true" />
|
||||
</el-table>
|
||||
|
||||
|
||||
@@ -36,6 +36,17 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="关系人身份证号" prop="relationCertNo">
|
||||
<el-input
|
||||
v-model="queryParams.relationCertNo"
|
||||
placeholder="请输入关系人身份证号"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
@@ -115,6 +126,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="关系人姓名" align="center" prop="relationName" :show-overflow-tooltip="true"/>
|
||||
<el-table-column label="关系人身份证号" align="center" prop="relationCertNo" width="180"/>
|
||||
<el-table-column label="家庭成员年收入" align="center" prop="annualIncome" width="160"/>
|
||||
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||
<template slot-scope="scope">
|
||||
@@ -710,6 +722,7 @@ export default {
|
||||
personName: null,
|
||||
relationType: null,
|
||||
relationName: null,
|
||||
relationCertNo: null,
|
||||
status: null
|
||||
},
|
||||
// 表单参数
|
||||
|
||||
@@ -833,7 +833,7 @@ export default {
|
||||
// 弹出层标题
|
||||
title: "招聘信息数据导入",
|
||||
// 弹窗提示
|
||||
tip: "仅允许导入\"xls\"或\"xlsx\"格式文件。模板包含“招聘信息”和“历史工作经历”两个 Sheet。",
|
||||
tip: "仅允许导入\"xls\"或\"xlsx\"格式文件。模板包含“招聘信息”和“历史工作经历”两个 Sheet,招聘类型填写“社招/SOCIAL”或“校招/CAMPUS”。",
|
||||
// 是否禁用上传
|
||||
isUploading: false,
|
||||
// 设置上传的请求头部
|
||||
@@ -1222,7 +1222,7 @@ export default {
|
||||
openImportDialog() {
|
||||
this.upload.title = "招聘信息数据导入";
|
||||
this.upload.url = process.env.VUE_APP_BASE_API + "/ccdi/staffRecruitment/importData";
|
||||
this.upload.tip = "仅允许导入\"xls\"或\"xlsx\"格式文件。模板包含“招聘信息”和“历史工作经历”两个 Sheet。";
|
||||
this.upload.tip = "仅允许导入\"xls\"或\"xlsx\"格式文件。模板包含“招聘信息”和“历史工作经历”两个 Sheet,招聘类型填写“社招/SOCIAL”或“校招/CAMPUS”。";
|
||||
if (this.isPreviewMode()) {
|
||||
this.upload.open = true;
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user