Merge pull request 'demand: 报价录入重复校验逻辑调整' (#92) from develop into master

Reviewed-on: http://git.xdadan.loc/tanex/emis-service/pulls/92
This commit is contained in:
heyu 2025-07-04 15:02:51 +08:00
commit a7de130dc3
3 changed files with 133 additions and 70 deletions

View File

@ -72,6 +72,8 @@ public class EmisQuotePrice extends BaseEntity
private String carryType;
/* 启用状态 0-启用 1-停用 */
private Integer status;
/* 状态名称 */
private String statusName;
/* 派件区域 */
private Long dispAreaId;
/* 派件区域名称 */
@ -123,6 +125,9 @@ public class EmisQuotePrice extends BaseEntity
/* 客户月结账号名称 */
private String custName;
/* 规则公式 */
private String exprJson;
private List<EmisQuoteExpression> exprList;
}

View File

@ -24,6 +24,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xdadan.erp.emis.service.IEmisQuotePriceService;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* 费用报价Service业务层处理
@ -52,6 +54,11 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
@Autowired
private EmisRegionMapper emisRegionMapper;
@Autowired
private EmisQuoteSendAreaMapper emisQuoteSendAreaMapper;
@Autowired
private EmisQuoteDispAreaMapper emisQuoteDispAreaMapper;
/**
* 查询费用报价
@ -224,6 +231,9 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
@Override
@Transactional
public void importDraftQuotePrice(EmisQuotePrice emisQuotePrice) throws EmisBizError {
// exprJson转exprList
transferExprJson(emisQuotePrice);
// 必填项校验
checkParam(emisQuotePrice);
@ -233,24 +243,60 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
// name-code转换
nameToCode(emisQuotePrice);
// 唯一性/重复校验
List<EmisQuotePrice> listOld = emisQuotePriceMapper.checkUnique(emisQuotePrice);
if (!CollectionUtil.isEmpty(listOld)) {
String estNameStr = "";
for (EmisQuotePrice item : listOld) {
estNameStr = estNameStr + item.getQuoteName() + ",";
}
throw new EmisBizError(EmisBizErrorType.EXISTS, "报价重复[" + estNameStr + "]");
}
// 保存报价
insertEmisQuotePrice(emisQuotePrice);
// 保存表达式
if (!CollectionUtil.isEmpty(emisQuotePrice.getExprList())) {
for (EmisQuoteExpression expr : emisQuotePrice.getExprList()) {
expr.setId(null);
expr.setQuoteId(emisQuotePrice.getQuoteId());
emisQuoteExpressionMapper.insertEmisQuoteExpression(expr);
}
private static void transferExprJson(EmisQuotePrice emisQuotePrice) throws EmisBizError {
if ((emisQuotePrice.getExprList() == null || emisQuotePrice.getExprList().isEmpty())
&& emisQuotePrice.getExprJson() != null && !emisQuotePrice.getExprJson().trim().isEmpty()) {
try {
ObjectMapper objectMapper = new ObjectMapper();
List<java.util.Map<String, Object>> exprJsonList = objectMapper.readValue(emisQuotePrice.getExprJson(),
new TypeReference<List<java.util.Map<String, Object>>>() {
});
List<EmisQuoteExpression> exprList = new java.util.ArrayList<>();
for (java.util.Map<String, Object> exprMap : exprJsonList) {
EmisQuoteExpression expr = new EmisQuoteExpression();
// 解析r字段 例如 0<w<=1 1<w<=20
String r = (String) exprMap.get("r");
if (r != null) {
// 支持格式: 0<w<=1 或 1<w<=20
r = r.replaceAll("\\s", "");
String[] parts = r.split("<w<=");
if (parts.length == 2) {
try {
expr.setStartWeight(Double.valueOf(parts[0]));
expr.setEndWeight(Double.valueOf(parts[1]));
} catch (Exception ignore) {
}
} else {
// 兼容 0<w<1 这种格式
parts = r.split("<w<");
if (parts.length == 2) {
try {
expr.setStartWeight(Double.valueOf(parts[0]));
expr.setEndWeight(Double.valueOf(parts[1]));
} catch (Exception ignore) {
}
}
}
}
expr.setCalculateExpression((String) exprMap.get("e"));
if (exprMap.get("id") != null) {
expr.setQuoteSequence(Integer.parseInt((String) exprMap.get("id")));
}
if (exprMap.get("i") != null) {
expr.setInitialWeight(Double.valueOf(exprMap.get("i").toString()));
}
if (exprMap.get("s") != null) {
expr.setAdditionalWeight(Double.valueOf(exprMap.get("s").toString()));
}
exprList.add(expr);
}
emisQuotePrice.setExprList(exprList);
} catch (Exception e) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "exprJson解析失败: " + e.getMessage());
}
}
}
@ -274,47 +320,15 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "未找到对应的产品类型: " + emisQuotePrice.getProdName());
}
emisQuotePrice.setProdCode(prod.getProdCode());
// 派件区域 name-code
if (emisQuotePrice.getDispAreaName() != null && !emisQuotePrice.getDispAreaName().trim().isEmpty()) {
EmisRegion queryRegion = new EmisRegion();
queryRegion.setRegionName(emisQuotePrice.getDispAreaName());
List<EmisRegion> dispAreaList = emisRegionMapper.selectEmisRegionList(queryRegion);
if (dispAreaList == null || dispAreaList.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "未找到对应的派件区域: " + emisQuotePrice.getDispAreaName());
// 价格取值
if (emisQuotePrice.getPriceType() != null && !emisQuotePrice.getPriceType().isEmpty()) {
String priceType = DictUtils.getDictValue("emis_price_type", emisQuotePrice.getPriceType());
if (priceType == null || priceType.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "价格取值无效: " + emisQuotePrice.getPriceType());
}
EmisRegion dispArea = dispAreaList.get(0);
emisQuotePrice.setDispAreaId(dispArea.getId());
emisQuotePrice.setDispAreaSiteCode(dispArea.getRegionCode());
emisQuotePrice.setPriceType(priceType);
}
// 寄件区域 name-code
if (emisQuotePrice.getSendAreaName() != null && !emisQuotePrice.getSendAreaName().trim().isEmpty()) {
EmisRegion queryRegion = new EmisRegion();
queryRegion.setRegionName(emisQuotePrice.getSendAreaName());
List<EmisRegion> sendAreaList = emisRegionMapper.selectEmisRegionList(queryRegion);
if (sendAreaList == null || sendAreaList.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "未找到对应的寄件区域: " + emisQuotePrice.getSendAreaName());
}
EmisRegion sendArea = sendAreaList.get(0);
emisQuotePrice.setSendAreaId(sendArea.getId());
emisQuotePrice.setSendAreaSiteCode(sendArea.getRegionCode());
}
// 费用类型 name-code
if (emisQuotePrice.getFeeType() != null && !emisQuotePrice.getFeeType().isEmpty()) {
String feeTypeCode = DictUtils.getDictValue("emis_fee_type", emisQuotePrice.getFeeType());
if (feeTypeCode == null || feeTypeCode.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "费用类型无效: " + emisQuotePrice.getFeeType());
}
emisQuotePrice.setFeeType(feeTypeCode);
}
// 币种 name-code
if (emisQuotePrice.getCurrency() != null && !emisQuotePrice.getCurrency().isEmpty()) {
String currencyCode = DictUtils.getDictValue("emis_currency", emisQuotePrice.getCurrency());
if (currencyCode == null || currencyCode.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "费用币种无效: " + emisQuotePrice.getCurrency());
}
emisQuotePrice.setCurrency(currencyCode);
}
// 计费类型 name-code
// 计费类型
if (emisQuotePrice.getBillType() != null && !emisQuotePrice.getBillType().isEmpty()) {
String billType = emisQuotePrice.getBillType().trim();
if ("重量计费".equals(billType)) {
@ -325,15 +339,15 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "计费类型无效: " + emisQuotePrice.getBillType());
}
}
// 启用状态 name-code
if (emisQuotePrice.getStatus() != null) {
Object statusObj = emisQuotePrice.getStatus();
// 启用状态
if (emisQuotePrice.getStatusName() != null) {
Object statusObj = emisQuotePrice.getStatusName();
if (statusObj instanceof String) {
String statusStr = ((String) statusObj).trim();
if ("启用".equals(statusStr)) {
emisQuotePrice.setStatus(0);
} else if ("停用".equals(statusStr)) {
emisQuotePrice.setStatus(1);
} else if ("停用".equals(statusStr)) {
emisQuotePrice.setStatus(0);
} else {
try {
int statusInt = Integer.parseInt(statusStr);
@ -354,6 +368,51 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "启用状态无效: " + statusObj);
}
}
// 费用类型
if (emisQuotePrice.getFeeType() != null && !emisQuotePrice.getFeeType().isEmpty()) {
String feeTypeCode = DictUtils.getDictValue("emis_fee_type", emisQuotePrice.getFeeType());
if (feeTypeCode == null || feeTypeCode.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "费用类型无效: " + emisQuotePrice.getFeeType());
}
emisQuotePrice.setFeeType(feeTypeCode);
}
// 币种
// if (emisQuotePrice.getCurrency() != null && !emisQuotePrice.getCurrency().isEmpty()) {
// String currencyCode = DictUtils.getDictValue("sys_currency_type", emisQuotePrice.getCurrency());
// if (currencyCode == null || currencyCode.isEmpty()) {
// throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "费用币种无效: " + emisQuotePrice.getCurrency());
// }
// emisQuotePrice.setCurrency(currencyCode);
// }
// 寄件区域
if (emisQuotePrice.getSendAreaName() != null && !emisQuotePrice.getSendAreaName().trim().isEmpty()) {
EmisQuoteSendArea querySendArea = new EmisQuoteSendArea();
querySendArea.setAreaName(emisQuotePrice.getSendAreaName());
querySendArea.setUseSiteCode(emisQuotePrice.getUseSiteCode());
List<EmisQuoteSendArea> sendAreaList = emisQuoteSendAreaMapper.selectEmisQuoteSendAreaList(querySendArea);
if (sendAreaList == null || sendAreaList.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "未找到对应的寄件区域: " + emisQuotePrice.getSendAreaName());
}
EmisQuoteSendArea sendArea = sendAreaList.get(0);
emisQuotePrice.setSendAreaId(sendArea.getAreaId());
emisQuotePrice.setSendAreaSiteCode(sendArea.getAreaSiteCode());
emisQuotePrice.setSendAreaSite(sendArea.getAreaSite());
}
// 派件区域
if (emisQuotePrice.getDispAreaName() != null && !emisQuotePrice.getDispAreaName().trim().isEmpty()) {
EmisQuoteDispArea queryDispArea = new EmisQuoteDispArea();
queryDispArea.setAreaName(emisQuotePrice.getDispAreaName());
queryDispArea.setUseSiteCode(emisQuotePrice.getUseSiteCode());
List<EmisQuoteDispArea> dispAreaList = emisQuoteDispAreaMapper.selectEmisQuoteDispAreaList(queryDispArea);
if (dispAreaList == null || dispAreaList.isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "未找到对应的派件区域: " + emisQuotePrice.getDispAreaName());
}
EmisQuoteDispArea dispArea = dispAreaList.get(0);
emisQuotePrice.setDispAreaId(dispArea.getAreaId());
emisQuotePrice.setDispAreaSiteCode(dispArea.getAreaSiteCode());
emisQuotePrice.setDispAreaSite(dispArea.getAreaSite());
}
emisQuotePrice.setQuoteType("1");
}
private static void checkDate(EmisQuotePrice emisQuotePrice) throws EmisBizError {
@ -392,7 +451,7 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
if (emisQuotePrice.getBillType() == null || emisQuotePrice.getBillType().trim().isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "计费类型不能为空");
}
if (emisQuotePrice.getStatus() == null) {
if (emisQuotePrice.getStatusName() == null || emisQuotePrice.getStatusName().trim().isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "启用状态不能为空");
}
if (emisQuotePrice.getFeeType() == null || emisQuotePrice.getFeeType().isEmpty()) {
@ -401,10 +460,10 @@ public class EmisQuotePriceServiceImpl implements IEmisQuotePriceService
if (emisQuotePrice.getCurrency() == null || emisQuotePrice.getCurrency().trim().isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "费用币种不能为空");
}
if (emisQuotePrice.getSendAreaId() == null) {
if (emisQuotePrice.getSendAreaName() == null || emisQuotePrice.getSendAreaName().trim().isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "寄件区域不能为空");
}
if (emisQuotePrice.getDispAreaId() == null) {
if (emisQuotePrice.getDispAreaName() == null || emisQuotePrice.getDispAreaName().trim().isEmpty()) {
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "派件区域不能为空");
}
}

View File

@ -173,19 +173,18 @@
<if test="quoteId != null "> and quote_id != #{quoteId}</if>
<if test="customerCode != null and customerCode != ''"> and customer_code=#{customerCode}</if>
<if test="recPayType != null and recPayType != ''"> and rec_pay_type = #{recPayType}</if>
<if test="custNo != null and custNo != ''"> and cust_no=#{custNo}</if>
and use_site_code = #{useSiteCode}
and trans_line_code = #{transLineCode}
and prod_code = #{prodCode}
and fee_type = #{feeType}
and rec_pay_type = #{recPayType}
and bill_type = #{billType}
and ( find_in_set(#{dispAreaSiteCode},disp_area_site_code) or disp_area_site_code='-1' )
and ( find_in_set(#{sendAreaSiteCode},send_area_site_code) or send_area_site_code='-1')
and (
( start_date <![CDATA[< ]]> #{startDate} and #{startDate} <![CDATA[<= ]]> end_date ) or ( start_date <![CDATA[< ]]> #{endDate} and #{endDate} <![CDATA[<= ]]> end_date )
and ( disp_area_id=#{dispAreaId} or disp_area_site_code='-1' )
and ( send_area_id=#{sendAreaId} or send_area_site_code='-1')
and (
( start_date <![CDATA[< ]]> #{startDate} and #{startDate} <![CDATA[<= ]]> end_date ) or ( start_date
<![CDATA[< ]]> #{endDate} and #{endDate} <![CDATA[<= ]]> end_date )
)
</select>