@@ -6,10 +6,10 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeelowcode.core.framework.config.btncommand.param.ButtonParamImport ;
import com.jeelowcode.core.framework.entity.ExcelFileDataEntity ;
import com.jeelowcode.core.framework.entity.FormEntity ;
import com.jeelowcode.core.framework.service.IExcelFileDataService ;
import com.jeelowcode.core.framework.service.IExcelImportService ;
import com.jeelowcode.core.framework.service.IFormService ;
import com.jeelowcode.core. framework.service.IFrameService ;
import com.jeelowcode.core.framework.entity.FormFieldEntity ;
import com.jeelowcode.core.framework.params.model.ExcelImportDataDictModel ;
import com.jeelowcode.core.framework.service.* ;
import com.jeelowcode.framework.utils.enums.JeeLowCodeFieldTypeEnum ;
import com.jeelowcode.core.framework.utils.Func ;
import com.jeelowcode.core.framework.utils.FuncWeb ;
import com.jeelowcode.framework.exception.JeeLowCodeException ;
@@ -22,7 +22,11 @@ import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Service ;
import java.time.LocalDate ;
import java.time.format.DateTimeFormatter ;
import java.time.temporal.ChronoUnit ;
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
import java.util.Objects ;
@@ -32,45 +36,311 @@ public class PersonInfoServiceImpl implements IExcelImportService {
@Autowired
private IFrameService frameService ;
@Autowired
private IExcelService excelService ;
@Autowired
private IFormService formService ;
@Override
public void importExcelCheck ( ButtonParamImport buttonParam ) {
Map < String , Object > params = new HashMap < > ( ) ;
params . put ( ParamEnum . PAGE_NO . getCode ( ) , 1 ) ;
params . put ( ParamEnum . PAGE_SIZE . getCode ( ) , 1000 ) ;
IFrameService proxyService = SpringUtils . getBean ( IFrameService . class ) ;
ResultDataModel model = proxyService . getDataList ( NumberUtil . toLong ( " 1964207990401785857 " ) , params ) ;
//获取字典 - 使用SpringUtils获取, 避免注入为null的问题
IExcelService excelServiceBean = excelService ! = null ? excelService : SpringUtils . getBean ( IExcelService . class ) ;
ExcelImportDataDictModel dictModel = excelServiceBean . formatExcelImportDataList ( buttonParam . getDbFormId ( ) ) ;
Map < String , Map < String , String > > dictMaps = dictModel ! = null ? dictModel . getDictMaps ( ) : null ;
// 如果字典为空或数据列表为空,直接返回
if ( dictMaps = = null | | dictMaps . isEmpty ( ) | | CollectionUtil . isEmpty ( buttonParam . getDataMapList ( ) ) ) {
return ;
}
// 以遍历dictMaps为起点, 检查每个字典字段
for ( Map . Entry < String , Map < String , String > > dictEntry : dictMaps . entrySet ( ) ) {
String fieldCode = dictEntry . getKey ( ) ; // 字段名,如 supplierId、demandId
Map < String , String > dictMap = dictEntry . getValue ( ) ; // 该字段对应的字典映射
// 遍历导入数据列表,查找是否有匹配的字段
for ( Map < String , Object > dataMap : buttonParam . getDataMapList ( ) ) {
// 检查数据中是否包含该字段
if ( dataMap . containsKey ( fieldCode ) ) {
Object fieldValue = dataMap . get ( fieldCode ) ;
// 如果字段有值
if ( fieldValue ! = null & & ! fieldValue . toString ( ) . trim ( ) . isEmpty ( ) ) {
String valueStr = fieldValue . toString ( ) ;
// 检查该值在对应的字典中是否存在
if ( dictMap = = null | | ! dictMap . containsKey ( valueStr ) ) {
throw new JeeLowCodeException ( " 字段[ " + fieldCode + " ]的值[ " + valueStr + " ]在字典中不存在 " ) ;
}
}
}
}
}
// 校验身份证格式
if ( CollectionUtil . isNotEmpty ( buttonParam . getDataMapList ( ) ) ) {
for ( Map < String , Object > dataMap : buttonParam . getDataMapList ( ) ) {
if ( dataMap . containsKey ( " cardNo " ) ) {
Object cardNoValue = dataMap . get ( " cardNo " ) ;
if ( cardNoValue ! = null & & ! cardNoValue . toString ( ) . trim ( ) . isEmpty ( ) ) {
String cardNo = cardNoValue . toString ( ) . trim ( ) ;
if ( ! isValidIdCard ( cardNo ) ) {
throw new JeeLowCodeException ( " 身份证号[ " + cardNo + " ]格式不正确 " ) ;
}
}
}
}
}
// 校验日期类型字段格式
validateDateFields ( buttonParam ) ;
}
/**
* 校验日期类型字段格式
*/
private void validateDateFields ( ButtonParamImport buttonParam ) {
if ( CollectionUtil . isEmpty ( buttonParam . getDataMapList ( ) ) ) {
return ;
}
// 获取字段列表
List < FormFieldEntity > fieldList = formService . getDbFieldList ( buttonParam . getDbFormId ( ) ) ;
if ( CollectionUtil . isEmpty ( fieldList ) ) {
return ;
}
// 找出所有日期类型字段( Date 和 DateTime)
Map < String , JeeLowCodeFieldTypeEnum > dateFieldMap = new HashMap < > ( ) ;
for ( FormFieldEntity field : fieldList ) {
String fieldType = field . getFieldType ( ) ;
JeeLowCodeFieldTypeEnum fieldTypeEnum = JeeLowCodeFieldTypeEnum . getByFieldType ( fieldType ) ;
if ( fieldTypeEnum = = JeeLowCodeFieldTypeEnum . DATE | | fieldTypeEnum = = JeeLowCodeFieldTypeEnum . DATETIME ) {
dateFieldMap . put ( field . getFieldCode ( ) , fieldTypeEnum ) ;
}
}
if ( dateFieldMap . isEmpty ( ) ) {
return ;
}
// 遍历数据,校验日期字段格式
for ( Map < String , Object > dataMap : buttonParam . getDataMapList ( ) ) {
for ( Map . Entry < String , JeeLowCodeFieldTypeEnum > dateFieldEntry : dateFieldMap . entrySet ( ) ) {
String fieldCode = dateFieldEntry . getKey ( ) ;
JeeLowCodeFieldTypeEnum fieldTypeEnum = dateFieldEntry . getValue ( ) ;
if ( dataMap . containsKey ( fieldCode ) ) {
Object fieldValue = dataMap . get ( fieldCode ) ;
if ( fieldValue ! = null & & ! fieldValue . toString ( ) . trim ( ) . isEmpty ( ) ) {
String valueStr = fieldValue . toString ( ) . trim ( ) ;
if ( ! isValidDate ( valueStr , fieldTypeEnum ) ) {
String expectedFormat = fieldTypeEnum = = JeeLowCodeFieldTypeEnum . DATE
? " yyyy-MM-dd "
: " yyyy-MM-dd HH:mm:ss " ;
throw new JeeLowCodeException ( " 字段[ " + fieldCode + " ]的值[ " + valueStr + " ]日期格式不正确,期望格式: " + expectedFormat ) ;
}
}
}
}
}
}
/**
* 校验日期格式是否正确
* @param dateStr 日期字符串
* @param fieldTypeEnum 字段类型枚举( DATE 或 DATETIME)
* @return true-格式正确, false-格式错误
*/
private boolean isValidDate ( String dateStr , JeeLowCodeFieldTypeEnum fieldTypeEnum ) {
if ( dateStr = = null | | dateStr . trim ( ) . isEmpty ( ) ) {
return false ;
}
dateStr = dateStr . trim ( ) ;
try {
if ( fieldTypeEnum = = JeeLowCodeFieldTypeEnum . DATE ) {
// 日期格式: yyyy-MM-dd
LocalDate . parse ( dateStr , DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) ;
return true ;
} else if ( fieldTypeEnum = = JeeLowCodeFieldTypeEnum . DATETIME ) {
// 日期时间格式: yyyy-MM-dd HH:mm:ss
java . time . LocalDateTime . parse ( dateStr , DateTimeFormatter . ofPattern ( " yyyy-MM-dd HH:mm:ss " ) ) ;
return true ;
}
} catch ( Exception e ) {
// 解析失败,格式不正确
return false ;
}
return false ;
}
/**
* 校验身份证格式
* @param cardNo 身份证号
* @return true-格式正确, false-格式错误
*/
private boolean isValidIdCard ( String cardNo ) {
if ( cardNo = = null | | cardNo . trim ( ) . isEmpty ( ) ) {
return false ;
}
cardNo = cardNo . trim ( ) ;
// 18位身份证: 前17位必须是数字, 最后一位可以是数字或X( 大小写都可以)
if ( cardNo . length ( ) = = 18 ) {
// 前17位必须是数字
String first17 = cardNo . substring ( 0 , 17 ) ;
if ( ! first17 . matches ( " \\ d{17} " ) ) {
return false ;
}
// 最后一位可以是数字或X( 大小写都可以)
char lastChar = cardNo . charAt ( 17 ) ;
return Character . isDigit ( lastChar ) | | lastChar = = 'X' | | lastChar = = 'x' ;
}
// 15位身份证( 旧版) : 全部15位都是数字
if ( cardNo . length ( ) = = 15 ) {
return cardNo . matches ( " \\ d{15} " ) ;
}
// 其他长度都不符合
return false ;
}
@Override
public void importExcelDataUpdate ( ButtonParamImport buttonParam ) {
// Map<String, Object> params =new HashMap<>();
// params.put(ParamEnum.PAGE_NO.getCode(),1) ;
// params.put(ParamEnum.PAGE_SIZE.getCode(),1000);
// IFrameService proxyService = SpringUtils.getBean(IFrameService.class);
// ResultDataModel model = proxyService.getDataList(NumberUtil.toLong("1964207990401785857"), params);
// if(CollectionUtil.isNotEmpty( buttonParam. getDataMapList())) {
// for(Map<String, Object> map : buttonParam.getDataMapList()) {
// if(map.containsKey("supplierName")){
// Map<String, Object> depMap = model.getRecords().stream().filter(t->t.get("full_name").equals(map.get("supplierName"))).findFirst().orElse(null);
// if(Objects.nonNull(depMap)){
// map.put("supplierId",depMap.get("id"));
// }else {
// throw new JeeLowCodeException("供应商:"+map.get("supplierName") + "不存在");
// }
// }
//
// if(map.containsKey("demandName")){
// Map<String, Object> depMap = model.getRecords().stream().filter(t->t.get("full_name").equals(map.get("demandName"))).findFirst().orElse(null);
// if(Objects.nonNull(depMap)) {
// map.put("demandId",depMap.get("id")) ;
// }else {
// throw new JeeLowCodeException("用人单位:"+map.get("demandName") + "不存在");
// }
// }
// }
// }
if ( CollectionUtil . isEmpty ( buttonParam . getDataMapList ( ) ) ) {
return ;
}
// 遍历数据列表,提取身份证信息
for ( Map < String , Object > dataMap : buttonParam. getDataMapList( ) ) {
if ( dataMap . containsKey ( " cardNo " ) ) {
Object cardNoValue = dataMap . get ( " cardNo " ) ;
if ( cardNoValue ! = null & & ! cardNoValue . toString ( ) . trim ( ) . isEmpty ( ) ) {
String cardNo = cardNoValue . toString ( ) . trim ( ) ;
// 提取身份证信息
IdCardInfo idCardInfo = extractIdCardInfo ( cardNo ) ;
if ( idCardInfo ! = null ) {
// 设置出生日期
if ( idCardInfo . getBirthDate ( ) ! = null ) {
dataMap . put ( " birthday " , idCardInfo . getBirthDate ( ) ) ;
}
// 设置年龄
if ( idCardInfo . getAge ( ) ! = null ) {
dataMap . put ( " personAge " , idCardInfo . getAge ( ) ) ;
}
// 设置性别("男"或"女")
if ( idCardInfo . getGender ( ) ! = null ) {
dataMap . put ( " personSex " , idCardInfo . getGender ( ) ) ;
}
}
}
}
}
}
/**
* 身份证信息类
*/
private static class IdCardInfo {
private String birthDate ; // 出生日期, 格式: yyyy-MM-dd
private Integer age ; // 年龄
private String gender ; // 性别:"男"或"女"
public String getBirthDate ( ) {
return birthDate ;
}
public void setBirthDate ( String birthDate ) {
this . birthDate = birthDate ;
}
public Integer getAge ( ) {
return age ;
}
public void setAge ( Integer age ) {
this . age = age ;
}
public String getGender ( ) {
return gender ;
}
public void setGender ( String gender ) {
this . gender = gender ;
}
}
/**
* 从身份证号提取信息(出生日期、年龄、性别)
* @param cardNo 身份证号
* @return 身份证信息, 如果格式不正确返回null
*/
private IdCardInfo extractIdCardInfo ( String cardNo ) {
if ( cardNo = = null | | cardNo . trim ( ) . isEmpty ( ) ) {
return null ;
}
cardNo = cardNo . trim ( ) ;
IdCardInfo info = new IdCardInfo ( ) ;
String birthDateStr = null ;
LocalDate birthDate = null ;
// 18位身份证
if ( cardNo . length ( ) = = 18 ) {
// 提取出生日期: 第7-14位( YYYYMMDD格式)
String yearMonthDay = cardNo . substring ( 6 , 14 ) ;
try {
birthDate = LocalDate . parse ( yearMonthDay , DateTimeFormatter . ofPattern ( " yyyyMMdd " ) ) ;
birthDateStr = birthDate . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) ;
} catch ( Exception e ) {
// 日期解析失败, 返回null
return null ;
}
// 提取性别: 第17位( 奇数为男, 偶数为女)
int genderCode = Character . getNumericValue ( cardNo . charAt ( 16 ) ) ;
info . setGender ( genderCode % 2 = = 1 ? " 男 " : " 女 " ) ;
}
// 15位身份证( 旧版)
else if ( cardNo . length ( ) = = 15 ) {
// 提取出生日期: 第7-12位( YYMMDD格式)
try {
int year = Integer . parseInt ( cardNo . substring ( 6 , 8 ) ) ;
int month = Integer . parseInt ( cardNo . substring ( 8 , 10 ) ) ;
int day = Integer . parseInt ( cardNo . substring ( 10 , 12 ) ) ;
// 年份需要加1900
birthDate = LocalDate . of ( 1900 + year , month , day ) ;
birthDateStr = birthDate . format ( DateTimeFormatter . ofPattern ( " yyyy-MM-dd " ) ) ;
} catch ( Exception e ) {
// 日期解析失败, 返回null
return null ;
}
// 提取性别: 第15位( 奇数为男, 偶数为女)
int genderCode = Character . getNumericValue ( cardNo . charAt ( 14 ) ) ;
info . setGender ( genderCode % 2 = = 1 ? " 男 " : " 女 " ) ;
}
else {
// 长度不符合, 返回null
return null ;
}
// 计算年龄
if ( birthDate ! = null ) {
LocalDate now = LocalDate . now ( ) ;
long age = ChronoUnit . YEARS . between ( birthDate , now ) ;
info . setAge ( ( int ) age ) ;
info . setBirthDate ( birthDateStr ) ;
}
return info ;
}
}