导入 excel 复杂校验和加上异常信息返回
最编程
2024-03-22 09:40:13
...
1.导出实现类
package com.dst.steed.fulfillment.modules.business.resourceplan.serviceimport;
import com.alibaba.excel.EasyExcelFactory;
import com.dst.steed.common.domain.response.Response;
import com.dst.steed.common.util.*;
import com.dst.steed.fulfillment.common.constant.DictTypeConstant;
import com.dst.steed.fulfillment.common.constant.vehicle.VehicleAttributeConstant;
import com.dst.steed.fulfillment.common.domain.acl.vehicle.attribute.AttributeValueInherit;
import com.dst.steed.fulfillment.common.domain.acl.vehicle.attribute.AttributeValueOut;
import com.dst.steed.fulfillment.common.domain.biz.resourceplan.InsertSituationRequireImportEO;
import com.dst.steed.fulfillment.common.domain.biz.resourceplan.InsertSituationRequireImportMap;
import com.dst.steed.fulfillment.common.domain.biz.resourceplan.ResourcePlanResult;
import com.dst.steed.fulfillment.common.domain.biz.resourceplan.inner.ResourceSituationInsertInnerDTO;
import com.dst.steed.fulfillment.common.enums.resourceplan.ResourceSituationSourceEnum;
import com.dst.steed.fulfillment.common.enums.resourceplan.ResourceSituationStatusEnum;
import com.dst.steed.fulfillment.common.enums.resourceplan.ResourceSituationTypeEnum;
import com.dst.steed.fulfillment.common.utils.CodeUtils;
import com.dst.steed.fulfillment.common.utils.string.StringUtil;
import com.dst.steed.fulfillment.infrastructure.acl.goods.AttributeValueServiceImpl;
import com.dst.steed.fulfillment.infrastructure.acl.goods.api.GoodsCenterServiceImpl;
import com.dst.steed.fulfillment.infrastructure.acl.operatecore.DictServiceImpl;
import com.dst.steed.fulfillment.infrastructure.acl.org.OrgServiceImpl;
import com.dst.steed.fulfillment.infrastructure.biz.resourceplan.entity.ReplaceModel;
import com.dst.steed.fulfillment.infrastructure.biz.resourceplan.entity.ResourceSituation;
import com.dst.steed.fulfillment.infrastructure.biz.resourceplan.entity.SituationRequire;
import com.dst.steed.fulfillment.infrastructure.core.resourceplan.ResourceSituationCoreService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;
import java.util.stream.Collectors;
/**
* 月资源计划-新增资源需求导入业务类
*/
@Slf4j
@Service
public class InsertSituationRequireImportService {
@Autowired
private ResourceSituationCoreService resourceSituationCoreService;
@Autowired
private AttributeValueServiceImpl attributeValueService;
@Autowired
private OrgServiceImpl orgService;
@Autowired
private DictServiceImpl dictService;
@Autowired
private GoodsCenterServiceImpl goodsCenterService;
@Autowired
private CodeUtils codeUtils;
private final static String YYYY_MM_DD = "yyyy/mm/dd";
/**
* 月资源计划-新增资源需求导入
* @param file
* @return
*/
public Response importInsertSituationRequireTemplate(MultipartFile file,String regionCode,String beginTime,String endTime) {
if (null == file || file.isEmpty()) {
return Response.error("参数验证不通过");
}
try{
List<InsertSituationRequireImportEO> eoList = EasyExcelFactory.read(file.getInputStream()).sheet(0).headRowNumber(2).head(InsertSituationRequireImportEO.class).doReadSync();
if (CollectionUtils.isEmpty(eoList) || eoList.size() < 1) {
return Response.error("导入数据为空");
}
if(eoList.size() > 1000) {
return Response.error("导入的数量不能超过1000条!");
}
InsertSituationRequireImportMap importMap = initImportMap(eoList);
List<ResourcePlanResult> validateResults = validateImport(eoList,regionCode,importMap);
if(!CollectionUtils.isEmpty(validateResults)){
return Response.succeed(validateResults);
}
//转换对应实体
packResourceSituationList(eoList,importMap,beginTime,endTime);
return Response.succeed();
} catch (Exception e) {
log.error("资源计划-新增资源需求导入错误", e);
}
return Response.error("导入失败");
}
private InsertSituationRequireImportMap initImportMap(List<InsertSituationRequireImportEO> eoList) {
InsertSituationRequireImportMap importMap = new InsertSituationRequireImportMap();
//城市名称和编码
List<String> cityNames = eoList.stream().filter(e -> StringUtil.isNotNullorEmpty(e.getCityName())).map(InsertSituationRequireImportEO::getCityName).distinct().collect(Collectors.toList());
Map<String, String> cityMap = orgService.getCityMap(cityNames);
importMap.setCityMap(cityMap);
//高中低顶要求
Map<String, String> topRequireMap = dictService.getDictNameValueMapByType(DictTypeConstant.BUSINESS_RESOURCE_PLAN_TOP_REQUIRE);
importMap.setTopRequireMap(topRequireMap);
//车辆性质
Map<String, String> carNoNatureMap = dictService.getDictNameValueMapByType(DictTypeConstant.BUSINESS_CARNO_NATURE);
importMap.setCarNoNatureMap(carNoNatureMap);
//是否可替换(0 否 1 是 )
Map<String, String> canReplaceCarModelMap = new HashMap<>();
canReplaceCarModelMap.put("否","0");
canReplaceCarModelMap.put("是","1");
importMap.setCanReplaceCarModelMap(canReplaceCarModelMap);
return importMap;
}
private Boolean packResourceSituationList(List<InsertSituationRequireImportEO> eoList,InsertSituationRequireImportMap importMap,String beginTime,String endTime) {
if (!CollectionUtils.isEmpty(eoList)) {
List<SituationRequire> situationRequires = new ArrayList<>();
List<ResourceSituation> resourceSituations = new ArrayList<>();
for (InsertSituationRequireImportEO eo : eoList) {
String situationResourceId = DstIdUtil.stringId();
SituationRequire situationRequire = new SituationRequire();
situationRequire.setId(situationResourceId);
DstBeanUtil.copy(eo, situationRequire);
situationRequire.setRequireSource(ResourceSituationSourceEnum.HANDLER_ADD.getSource());
situationRequire.setReplaceModel(eo.getReplaceModel());
if (StringUtil.isNotNullorEmpty(eo.getLastDeliverTime())) {
situationRequire.setLastDeliverTime(DstDateUtil.parse(eo.getLastDeliverTime(), YYYY_MM_DD));
}
situationRequire.setCreatorId((DstUserUtil.getUserId().isPresent()) ? String.valueOf(DstUserUtil.getUserId().get()): String.valueOf(DstUserUtil.ADMIN_ID));
situationRequire.setCreatorName((DstUserUtil.getRealName().isPresent()) ? DstUserUtil.getRealName().get(): DstUserUtil.ADMIN_REAL_NAME);
situationRequires.add(situationRequire);
// 资源情况
ResourceSituation resourceSituation = new ResourceSituation();
resourceSituation.setId(DstIdUtil.stringId());
resourceSituation.setResourceSituationCode(codeUtils.generateResourceSituationCode(ResourceSituationTypeEnum.MONTH));
resourceSituation.setSituationRequireId(situationResourceId);
resourceSituation.setCityCode(eo.getCityCode());
resourceSituation.setBeginTime(DstDateUtil.parse(beginTime,DstDateUtil.Y_M_D));
resourceSituation.setEndTime(DstDateUtil.parse(endTime,DstDateUtil.Y_M_D));
resourceSituation.setType(ResourceSituationTypeEnum.MONTH.getType());
resourceSituation.setStatus(ResourceSituationStatusEnum.MONTH_WAIT_CITY_DECISION.getStatus());
resourceSituation.setCreatorId((DstUserUtil.getUserId().isPresent()) ? String.valueOf(DstUserUtil.getUserId().get()): String.valueOf(DstUserUtil.ADMIN_ID));
resourceSituation.setCreatorName((DstUserUtil.getRealName().isPresent()) ? DstUserUtil.getRealName().get(): DstUserUtil.ADMIN_REAL_NAME);
resourceSituations.add(resourceSituation);
}
if (!CollectionUtils.isEmpty(situationRequires) && !CollectionUtils.isEmpty(situationRequires)) {
resourceSituationCoreService.batchSaveSituationInsertInnerDTO(new ResourceSituationInsertInnerDTO(resourceSituations,null,situationRequires));
return true;
}
}
return false;
}
/**
* 校验导入信息
* @param eoList
* @return
*/
private List<ResourcePlanResult> validateImport(List<InsertSituationRequireImportEO> eoList,String regionCode,InsertSituationRequireImportMap importMap) {
List<ResourcePlanResult> validateResults = new ArrayList<>();
Set<String> insertSituationRequireSet = new HashSet<>();
Map<String, List<AttributeValueOut>> valueMap = attributeValueService.getAttrValueMapByAttrKeys(VehicleAttributeConstant.exportAttrKey);
List<AttributeValueInherit> attrValueInheritList = goodsCenterService.getAttrValueInheritList();
List<String> cityCodesByRegionCode = orgService.getCityCodesByRegionCode(regionCode);
for (int i = 0; i < eoList.size() ; i++) {
StringBuffer lineError = new StringBuffer();
int lineNum = i + 3;
InsertSituationRequireImportEO data = eoList.get(i);
//非空校验
validateImportIsNull(data, lineNum, lineError);
//字典值校验
validateDict(data,lineNum,lineError,importMap,cityCodesByRegionCode);
//属性值校验
validateAttrValue(data,lineNum,lineError,valueMap,attrValueInheritList);
//校验唯一性
validateUnique(data,lineNum,lineError,insertSituationRequireSet);
if(lineError.length() > 0){
validateResults.add(new ResourcePlanResult(String.format("第%d行",lineNum),lineError.toString()));
}
}
return validateResults;
}
/**
* 校验唯一性
* @param data
* @param lineNum
* @param lineError
* @param insertSituationRequireSet
*/
private void validateUnique(InsertSituationRequireImportEO data, int lineNum, StringBuffer lineError, Set<String> insertSituationRequireSet) {
if (insertSituationRequireSet.contains(DstJsonUtil.toString(data))) {
lineError.append(String.format("第%d行表格中不能有完全重复的数据!",lineNum));
}
insertSituationRequireSet.add(DstJsonUtil.toString(data));
}
/**
* 属性值校验
* @param data
* @param lineNum
* @param lineError
* @param valueMap
*/
private void validateAttrValue(InsertSituationRequireImportEO data, int lineNum, StringBuffer lineError, Map<String, List<AttributeValueOut>> valueMap,List<AttributeValueInherit> attrValueInheritList) {
if (StringUtil.isNotNullorEmpty(data.getCarBrandName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_G_CAR_BRAND, data.getCarBrandName());
String valueId = attrValueMapByAttrKeyMap.get(data.getCarBrandName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【车辆品牌】【%s】在系统中不存在的属性值!",lineNum,data.getCarBrandName()));
} else {
data.setCarBrand(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getCarModelName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_G_CAR_MODEL, data.getCarModelName());
String valueId = attrValueMapByAttrKeyMap.get(data.getCarModelName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【车辆型号】【%s】在系统中不存在的属性值!",lineNum,data.getCarModelName()));
} else {
data.setCarModel(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getCarBrandName()) && StringUtil.isNotNullorEmpty(data.getCarModelName())){
if (!goodsCenterService.checkBranAndModeInherit(attrValueInheritList,data.getCarBrandName(),data.getCarModelName())) {
lineError.append(String.format("第%d行【车辆品牌-型号】【%s】【%s】只可填写车辆品牌下的型号!",lineNum,data.getCarBrandName(),data.getCarModelName()));
}
}
if (StringUtil.isNotNullorEmpty(data.getCarModelGroupName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_A_CAR_MODEL_GROUP, data.getCarModelGroupName());
String valueId = attrValueMapByAttrKeyMap.get(data.getCarModelGroupName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【车辆族群】【%s】在系统中不存在的属性值!",lineNum,data.getCarModelGroupName()));
} else {
data.setCarModelGroup(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getEsdTotalPowerName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_A_ESD_TOTAL_POWER, data.getEsdTotalPowerName());
String valueId = attrValueMapByAttrKeyMap.get(data.getEsdTotalPowerName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【电池包度数】【%s】在系统中不存在的属性值!",lineNum,data.getEsdTotalPowerName()));
} else {
data.setEsdTotalPower(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getEsdCompanyName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_A_ESD_COMPANY, data.getEsdCompanyName());
String valueId = attrValueMapByAttrKeyMap.get(data.getEsdCompanyName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【电池包厂商】【%s】在系统中不存在的属性值!",lineNum,data.getEsdCompanyName()));
} else {
data.setEsdCompany(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getVehicleUseName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.A_OPT_VEHICLE_USE, data.getVehicleUseName());
String valueId = attrValueMapByAttrKeyMap.get(data.getVehicleUseName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【车辆用途】【%s】在系统中不存在的属性值!",lineNum,data.getVehicleUseName()));
} else {
data.setVehicleUse(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getAssetClassifyName())) {
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.A_OPT_ASSET_CLASSIFY, data.getAssetClassifyName());
String valueId = attrValueMapByAttrKeyMap.get(data.getAssetClassifyName());
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【资产分类】【%s】在系统中不存在的属性值!",lineNum,data.getAssetClassifyName()));
} else {
data.setAssetClassify(valueId);
}
}
if (StringUtil.isNotNullorEmpty(data.getReplaceCarModelMame())) {
try {
List<ReplaceModel> replaceModels = new ArrayList<>();
String[] brandAndMode = data.getReplaceCarModelMame().split("、");
for (String item : brandAndMode) {
String[] brandAndModeSplit = item.split("/");
String brand = brandAndModeSplit[0];
String model = brandAndModeSplit[1];
ReplaceModel replaceModel = new ReplaceModel();
Map<String, String> attrBrandValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_G_CAR_BRAND, brand);
String valueId = attrBrandValueMapByAttrKeyMap.get(brand);
if (StringUtil.isBlank(valueId)) {
lineError.append(String.format("第%d行【替换车型-车辆品牌】【%s】在系统中不存在的属性值!", lineNum, brand));
} else {
replaceModel.setBrandId(valueId);
replaceModel.setBrandName(brand);
}
Map<String, String> attrValueMapByAttrKeyMap = attributeValueService.getAttrValueMapByAttrKeyMap(valueMap, VehicleAttributeConstant.AK_G_CAR_MODEL, model);
String modelValueId = attrValueMapByAttrKeyMap.get(model);
if (StringUtil.isBlank(modelValueId)) {
lineError.append(String.format("第%d行【替换车型-车辆型号】【%s】在系统中不存在的属性值!", lineNum, model));
} else {
replaceModel.setModelId(modelValueId);
replaceModel.setModelName(model);
}
if (StringUtil.isNotNullorEmpty(brand) && StringUtil.isNotNullorEmpty(model)){
if (!goodsCenterService.checkBranAndModeInherit(attrValueInheritList,brand,model)) {
lineError.append(String.format("第%d行【替换车型-车辆品牌-型号】【%s】【%s】只可填写车辆品牌下的型号!",lineNum,brand,model));
}
}
replaceModels.add(replaceModel);
}
data.setReplaceModel(replaceModels);
} catch (Exception e) {
log.error(String.format("替换车型%s输入有误",data.getReplaceCarModelMame()));
lineError.append(String.format("第%d行【替换车型】【%s】输入有误,请检查!", lineNum, data.getReplaceCarModelMame()));
}
}
}
private void validateImportIsNull(InsertSituationRequireImportEO data, int lineNum, StringBuffer lineError) {
if (StringUtil.isBlank(data.getCityName())) {
lineError.append(String.format("第%d行【城市】为空!",lineNum));
}
if(StringUtils.isBlank(data.getCarBrandName())) {
lineError.append(String.format("第%d行【车辆品牌】为空!",lineNum));
}
if(StringUtils.isBlank(data.getCarModelName())) {
lineError.append(String.format("第%d行【车辆型号】为空!",lineNum));
}
if(StringUtils.isBlank(data.getCarModelGroupName())) {
lineError.append(String.format("第%d行【车辆族群】为空!",lineNum));
}
if(StringUtils.isBlank(data.getCanReplaceCarModelMame())) {
lineError.append(String.format("第%d行【是否可替换车型】为空!",lineNum));
}else if (data.getCanReplaceCarModelMame().equals("是")) {
if (StringUtil.isBlank(data.getReplaceCarModelMame())) {
lineError.append(String.format("第%d行【可替换车型】是否可替换车型为是则为必填!",lineNum));
}
}
if(StringUtils.isBlank(data.getCarNoNatureName())) {
lineError.append(String.format("第%d行【车牌性质】为空!",lineNum));
}
if (!StringUtil.isBlank(data.getLastDeliverTime())) {
try {
DstDateUtil.parse(data.getLastDeliverTime(), YYYY_MM_DD);
} catch (Exception e) {
log.error("时间格式解析异常:{}",e.getMessage());
lineError.append(String.format("第%d行【最后交付时间】请输入yyyy/mm/dd格式",lineNum));
}
}
if(Objects.isNull(data.getRequireVehicleCount())) {
lineError.append(String.format("第%d行【需求数量】为空!",lineNum));
} else if (data.getRequireVehicleCount() <=0 ){
lineError.append(String.format("第%d行【需求数量】只可填写大于0的整数,最大可输入99999!",lineNum));
}
if (!StringUtil.isBlank(data.getNeedColor())) {
if (data.getNeedColor().length() > 50) {
lineError.append(String.format("第%d行【车身颜色】最多可填写50字符!", lineNum));
}
}
if (!StringUtil.isBlank(data.getTransformRequire())) {
if (data.getTransformRequire().length() > 50) {
lineError.append(String.format("第%d行【技改要求】最多可填写50字符!", lineNum));
}
}
}
private void validateDict(InsertSituationRequireImportEO data, int lineNum, StringBuffer lineError,InsertSituationRequireImportMap importMap,List<String> cityCodesByRegionCode) {
if (!importMap.getCityMap().containsKey(data.getCityName())) {
lineError.append(String.format("第%d行 城市:【%s】输入有误,在系统不存在,请检查!", lineNum, data.getCityName()));
} else {
data.setCityCode(importMap.getCityMap().get(data.getCityName()));
}
if (!cityCodesByRegionCode.contains(data.getCityCode())) {
lineError.append(String.format("第%d行【%s】只可填写当前大区下的城市!",lineNum,data.getCityName()));
}
if (StringUtil.isNotNullorEmpty(data.getTopRequireName())) {
if (!importMap.getTopRequireMap().containsKey(data.getTopRequireName())) {
lineError.append(String.format("第%d行 高中低顶要求:【%s】输入有误!", lineNum, data.getTopRequireName()));
} else {
data.setTopRequire(Integer.valueOf(importMap.getTopRequireMap().get(data.getTopRequireName())));
}
}
if (!importMap.getCarNoNatureMap().containsKey(data.getCarNoNatureName())) {
lineError.append(String.format("第%d行 车牌性质:【%s】输入有误!", lineNum, data.getCarNoNatureName()));
} else {
data.setCarNoNature(Integer.valueOf(importMap.getCarNoNatureMap().get(data.getCarNoNatureName())));
}
if (!importMap.getCanReplaceCarModelMap().containsKey(data.getCanReplaceCarModelMame())) {
lineError.append(String.format("第%d行 是否可替换车型:【%s】输入有误!", lineNum, data.getCanReplaceCarModelMame()));
} else {
data.setCanReplaceCarModel(importMap.getCanReplaceCarModelMap().get(data.getCanReplaceCarModelMame()));
}
}
}
2.导出异常信息类
package com.dst.steed.fulfillment.common.domain.biz.resourceplan;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
/**
*@ClassName ResourcePlanResult
*@Description 资源计划导入结果类
*@Author lwp
*@Date 2024/3/6 14:09
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
public class ResourcePlanResult {
/** 资源情况编码**/
private String index;
/** 错误信息**/
private String message;
public ResourcePlanResult(String index, String message) {
this.index = index;
this.message = message;
}
}
3.字段组装map类
package com.dst.steed.fulfillment.common.domain.biz.resourceplan;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import java.util.Map;
/**
* @Description: 月资源计划-新增资源需求导入常量透传类
* @author lwp
* @date 2024/3/7 18:06
*/
@Getter
@Setter
@ToString
@NoArgsConstructor
public class InsertSituationRequireImportMap {
/** 高低顶要求(dst_base.marketing_interior_height)**/
private Map<String, String> topRequireMap;
/** 车辆性质(dst_base.business_carno_nature)**/
private Map<String, String> carNoNatureMap;
/** 是否可替换(0 否 1 是 )**/
private Map<String, String> canReplaceCarModelMap;
/** 城市名称和编码 **/
private Map<String, String> cityMap;
}
4.导入类
package com.dst.steed.fulfillment.common.domain.biz.resourceplan;
import com.alibaba.excel.annotation.ExcelProperty;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.dst.steed.common.convert.translation.Translation;
import com.dst.steed.fulfillment.common.constant.DictTypeConstant;
import com.dst.steed.fulfillment.infrastructure.biz.resourceplan.entity.ReplaceModel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 月资源计划-新增资源需求导入类
*/
@Data
public class InsertSituationRequireImportEO implements Serializable {
/**
* 资源情况编码
*/
@ExcelProperty(index = 0)
private String cityName;
private String cityCode;
/**
* 车辆品牌
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-carBrandName")
private String carBrand;
@ExcelProperty(index = 1)
private String carBrandName;
/**
* 车辆型号
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-carModelName")
private String carModel;
@ExcelProperty(index = 2)
private String carModelName;
/**
* 车型族群
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-carModelGroupName")
private String carModelGroup;
@ExcelProperty(index = 3)
private String carModelGroupName;
/**
* 动力电池包电量
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-carModelGroupName")
private String esdTotalPower;
@ExcelProperty(index = 4)
private String esdTotalPowerName;
/**
* 电池包厂商
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-esdCompanyName")
private String esdCompany;
@ExcelProperty(index = 5)
private String esdCompanyName;
/**
* 车辆用途
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-vehicleUseName")
private String vehicleUse;
@ExcelProperty(index = 6)
private String vehicleUseName;
/**
* 资产分类
*/
@Translation(convertName = "commonConvertAttrValueIdMapValue",convertTo = "attrValueName-assetClassifyName")
private String assetClassify;
@ExcelProperty(index = 7)
private String assetClassifyName;
/**
* 高中低顶要求(字典:marketing_interior_height)
*/
@Translation(dictType = DictTypeConstant.BUSINESS_RESOURCE_PLAN_TOP_REQUIRE)
private Integer topRequire;
@ExcelProperty(index = 8)
private String topRequireName;
/**
* 车身颜色要求
*/
@ExcelProperty(index = 9)
private String needColor;
/**
* 技改要求
*/
@ExcelProperty(index = 10)
private String transformRequire;
/**
* 是否可替换车型,0.不可替换 1.可替换
*/
@ExcelProperty(index = 11)
private String canReplaceCarModelMame;
private String canReplaceCarModel;
/**
* 替换车型
*/
@ExcelProperty(index = 12)
private String replaceCarModelMame;
/**
* 车牌性质(字典:business_carno_nature)
*/
@Translation(dictType = DictTypeConstant.BUSINESS_CARNO_NATURE)
private Integer carNoNature;
@ExcelProperty(index = 13)
private String carNoNatureName;
/**
* 最后交付时间
*/
@JsonFormat(pattern = "yyyy/MM/dd", timezone = "GMT+8")
@ExcelProperty(index = 14)
private String lastDeliverTime;
/**
* 需求数量
*/
@ExcelProperty(index = 15)
private Integer requireVehicleCount;
/**
* 可替换车型(jons数组字符串)
*/
@TableField(value = "replace_model", typeHandler = JacksonTypeHandler.class)
private List<ReplaceModel> replaceModel;
}
5.前端请求接口控制层
/**
* 月资源计划-新增资源需求导入
* @author: lwp
* @date: 2024/03/04 13:50
**/
@PostMapping(value = "/importInsertSituationRequireTemplate")
public Response importInsertSituationRequireTemplate(@RequestParam(value = "file",required = true) MultipartFile file,
@RequestParam(value = "regionCode", required = true) String regionCode,
@RequestParam(value = "beginTime", required = true) String beginTime,
@RequestParam(value = "endTime", required = true) String endTime) {
return situationRequireService.importInsertSituationRequireTemplate(file,regionCode,beginTime,endTime);
6.总结
这种写法主要是代码结构清晰,再复杂的校验只要往其中填充即可
上一篇: 在监控软件中使用启发式算法
下一篇: 元搜索算法在金融领域的实际应用
推荐阅读
-
35 岁实现财务*,腾讯程序员手握2300万提前退休?-1000万房产、1000万腾讯股票、加上300万的现金,一共2300万的财产。有网友算了一笔账,假设1000万的房产用于自住,剩下1300万资产按照平均税后20-50万不等进行计算,大约花上26-60年左右的时间才能赚到这笔钱。也就是说,普通人可能奋斗一辈子,才能赚到这笔钱。在很多人还在为中年危机而惶惶不可终日的时候,有的人的35岁,就已经安全着陆,试问哪个打工人不羡慕?但问题是有这样财富积累必然有像样的实力做靠山。没有人可以不劳而获。 看到这里,肯定有人说,那么对于普通人来说,卷可能真就成了唯一的出路。但是卷也有轻松的卷,“偷懒”的卷法,对于程序员而言,刨除掉一时无法改掉的开会传统占用的大部分时间,如何把有限的时间和精力放在真正重要的架构设计、需求设计上,而不是重复的造*,编码、改bug、手动测试。因此在科技改变生活的今天,学会使用AI工具成为程序员们的必备技能。 以全栈式全自动的软件开发工具飞算SoFlu软件机器人为例,作为全球首款面向微服务架构设计和最佳实践的软件机器人,SoFlu软件机器人改变了原来手工编码的作业模式,通过可视化拖拽方式以及参数配置就能实现等同于编写复杂代码的业务逻辑,在设计业务逻辑时就完成了微服务应用开发,做到“业务即图,图即代码”,实现“软件开发,十倍提效”。 而作为飞算SoFlu软件机器人的一个重要组成部分,FuncGPT(慧函数)支持所有类型函数创建。通过自然语言描述Java函数需求,实时生成高质量、高可读性的Java函数代码。生成代码可直接复制到IDEA,或一键导入Java全自动开发工具函数库。 FuncGPT(慧函数)具有五大核心能力: ● 自然语言:通过自然语言即可生成函数,降低软件开发门槛。 ● 秒级函数开发:全自动秒级开发函数,秒级完成,效率千倍提升。 ● 一站式函数开发应用:函数生成即可直接应用,效率、安全有保障。 ● 质量可靠:生成的函数代码符合业界规范、具备良好的可读性,符合最优解。 ● 灵活生成:可以根据开发人员的具体需求生成并支持调整和修改。 以“将文件流转换为File对象”这个需求为例,以下是FuncGPT(慧函数)秒级生成的代码: / 类名:FileConverter // 函数名:convertStreamToFile // 函数功能:将文件流转换为File对象 // POM依赖包:无 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class FileConverter { /** * 将文件流转换为File对象 * @param inputStream 文件流 * @param filePath 文件路径 * @param fileName 文件名 * @return 转换后的File对象 * @throws IOException 如果发生I/O异常 */ public static File convertStreamToFile(InputStream inputStream, String filePath, String fileName) throws IOException { File file = new File(filePath + File.separator + fileName); // 创建File对象 try (FileOutputStream outputStream = new FileOutputStream(file)) { // 创建文件输出流 byte buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { // 从文件流读取数据并写入文件 outputStream.write(buffer, 0, bytesRead); } } return file; // 返回转换后的File对象 } } // 函数示例 // 将文件流转换为File对象示例 // 入参:inputStream,文件流 // 入参:filePath,文件路径 // 入参:fileName,文件名 // 出参:file,转换后的File对象 // 调用示例: // InputStream inputStream = new FileInputStream("example.txt"); // String filePath = "C:\\Users\\User\\Documents"; // String fileName = "example.txt"; // File file = FileConverter.convertStreamToFile(inputStream, filePath, fileName); // System.out.println(file.getAbsolutePath); // 输出结果:例如,将文件流转换为File对象后,文件的绝对路径为:C:\Users\User\Documents\example.txt // 则输出结果为:C:\Users\User\Documents\example.txt 通过分析,不难发现以上代码:
-
[姿势估计] 实践记录:使用 Dlib 和 mediapipe 进行人脸姿势估计 - 本文重点介绍方法 2):方法 1:基于深度学习的方法:。 基于深度学习的方法:基于深度学习的方法利用深度学习模型,如卷积神经网络(CNN)或递归神经网络(RNN),直接从人脸图像中学习姿势估计。这些方法能够学习更复杂的特征表征,并在大规模数据集上取得优异的性能。方法二:基于二维校准信息估计三维姿态信息(计算机视觉 PnP 问题)。 特征点定位:人脸姿态估计的第一步是通过特征点定位来检测和定位人脸的关键点,如眼睛、鼻子和嘴巴。这些关键点提供了人脸的局部结构信息,可用于后续的姿势估计。 旋转表示:常见的旋转表示方法包括欧拉角和旋转矩阵。欧拉角通过三个旋转角度(通常是俯仰、偏航和滚动)描述头部的旋转姿态。旋转矩阵是一个 3x3 矩阵,表示头部从一个坐标系到另一个坐标系的变换。 三维模型重建:根据特征点的定位结果,三维人脸模型可用于姿势估计。通过将人脸的二维图像映射到三维模型上,可以估算出人脸的旋转和平移信息。这就需要建立人脸的三维模型,然后通过优化方法将模型与特征点对齐,从而获得姿势估计结果。 特征点定位 特征点定位是用于检测人脸关键部位的五官基础部分,还有其他更多的特征点表示方法,大家可以参考我上一篇文章中介绍的特征点检测方案实践:人脸校正二次定位操作来解决人脸校正的问题,客户在检测关键点的代码上略有修改,坐标转换部分客户见上图 def get_face_info(image). img_copy = image.copy image.flags.writeable = False image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) results = face_detection.process(image) # 在图像上绘制人脸检测注释。 image.flags.writeable = True image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) box_info, facial = None, None if results.detections: for detection in results. for detection in results.detections: mp_drawing.Drawing.detection = 无 mp_drawing.draw_detection(image, detection) 面部 = detection.location_data.relative_keypoints 返回面部 在上述代码中,返回的数据是五官(6 个关键点的坐标),这是用 mediapipe 库实现的,下面我们可以尝试用另一个库:dlib 来实现。 使用 dlib 使用 Dlib 库在 Python 中实现人脸关键点检测的步骤如下: 确保已安装 Dlib 库,可使用以下命令: pip install dlib 导入必要的库: 加载 Dlib 的人脸检测器和关键点检测器模型: 读取图像并将其灰度化: 使用人脸检测器检测图像中的人脸: 对检测到的人脸进行遍历,并使用关键点检测器检测人脸关键点: 显示绘制了关键点的图像: 以下代码将参数 landmarks_part 添加到要返回的关键点坐标中。
-
导入 excel 复杂校验和加上异常信息返回