外协人员excel导入优化

This commit is contained in:
2025-12-18 09:27:45 +08:00
parent 235b95a653
commit 4b45b69291
12 changed files with 1697 additions and 53 deletions

View File

@@ -1,6 +1,7 @@
package com.jeelowcode.core.framework.service;
import com.jeelowcode.core.framework.service.impl.PersonInfoServiceImpl;
import com.jeelowcode.framework.utils.tool.spring.SpringUtils;
import org.springframework.stereotype.Service;
@Service
@@ -8,7 +9,8 @@ public class ExcelExtendFactory {
public IExcelImportService getExcelImportService(String tableName) {
if(tableName.toLowerCase().equals("lc_outside_person")){
return new PersonInfoServiceImpl();
// 从Spring容器中获取实例确保依赖注入正常
return SpringUtils.getBean(PersonInfoServiceImpl.class);
}
return null;
}

View File

@@ -1,6 +1,7 @@
package com.jeelowcode.core.framework.service;
import com.jeelowcode.core.framework.params.model.ExcelImportDataDictModel;
import com.jeelowcode.core.framework.params.model.ExcelModel;
import com.jeelowcode.core.framework.params.model.ExcelTemplateModel;
import org.springframework.web.context.request.ServletRequestAttributes;
@@ -34,4 +35,6 @@ public interface IExcelService {
* 处理临时库
*/
void handleTempTable(ServletRequestAttributes sra,Long dbFormId, Long fieldId);
ExcelImportDataDictModel formatExcelImportDataList(Long dbformId);
}

View File

@@ -219,7 +219,8 @@ public class ExcelServiceImpl implements IExcelService {
//获取字典
private ExcelImportDataDictModel formatExcelImportDataList(Long dbformId) {
@Override
public ExcelImportDataDictModel formatExcelImportDataList(Long dbformId) {
List<FormFieldEntity> fieldList = formService.getDbFieldList(dbformId);
//字典集合

View File

@@ -40,6 +40,7 @@ import com.jeelowcode.framework.utils.model.ResultDataModel;
import com.jeelowcode.framework.utils.tool.spring.SpringUtils;
import com.jeelowcode.framework.utils.utils.FuncBase;
import com.jeelowcode.framework.utils.utils.JeeLowCodeUtils;
import com.jeelowcode.tool.framework.datapermission.core.annotation.DataPermission;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import org.jetbrains.annotations.NotNull;
@@ -685,6 +686,7 @@ public class FrameServiceImpl implements IFrameService {
}
//保存导入数据
@DataPermission(enable = false) // 关闭数据权限,避免只查看自己时,查询不到部门。
@Override
public ExecuteEnhanceModel saveImportData(Long dbFormId, Map<String, Object> params) {
String duplicateType = FuncBase.getMap2Str(params, JeeLowCodeConstant.IMPORT_DUPLICATE_TYPE);

View File

@@ -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;
}
}