提交第三方接口订单同步功能
This commit is contained in:
+35
@@ -2,10 +2,13 @@ package com.ruoyi.web.controller.api;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.annotation.Anonymous;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
@@ -13,8 +16,10 @@ import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.config.properties.TmsApiProperties;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.ruoyi.price.service.IPrcBillService;
|
||||
import com.ruoyi.price.service.ITmsPriceQuoteService;
|
||||
|
||||
/**
|
||||
@@ -35,6 +40,9 @@ public class TmsPriceController extends BaseController
|
||||
@Autowired
|
||||
private ITmsPriceQuoteService tmsPriceQuoteService;
|
||||
|
||||
@Autowired
|
||||
private IPrcBillService prcBillService;
|
||||
|
||||
@Autowired
|
||||
private TmsApiProperties tmsApiProperties;
|
||||
|
||||
@@ -52,6 +60,33 @@ public class TmsPriceController extends BaseController
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync order and persist receivable bill (prc_bill / prc_bill_fee).
|
||||
* Same price match as quote. Same orderNo upserts.
|
||||
*/
|
||||
@PostMapping("/bill")
|
||||
public AjaxResult bill(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@Validated @RequestBody TmsPriceBillRequest request)
|
||||
{
|
||||
assertApiCode(headerApiCode, request == null ? null : request.getApiCode());
|
||||
TmsPriceQuoteResult result = prcBillService.bill(request);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query receivable bill by orderNo after sync.
|
||||
*/
|
||||
@GetMapping("/bill/by-order/{orderNo}")
|
||||
public AjaxResult getBillByOrder(
|
||||
@RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode,
|
||||
@PathVariable("orderNo") String orderNo,
|
||||
@RequestParam(value = "apiCode", required = false) String apiCode)
|
||||
{
|
||||
assertApiCode(headerApiCode, apiCode);
|
||||
return success(prcBillService.getBillByOrderNo(orderNo));
|
||||
}
|
||||
|
||||
private void assertApiCode(String headerApiCode, String bodyApiCode)
|
||||
{
|
||||
String expected = tmsApiProperties.getApiCode();
|
||||
|
||||
+30
@@ -13,9 +13,12 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.price.domain.PrcBill;
|
||||
import com.ruoyi.price.domain.PrcQuote;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.ruoyi.price.service.IPrcBillService;
|
||||
import com.ruoyi.price.service.ITmsPriceQuoteService;
|
||||
|
||||
/**
|
||||
@@ -30,6 +33,9 @@ public class BillingController extends BaseController
|
||||
@Autowired
|
||||
private ITmsPriceQuoteService tmsPriceQuoteService;
|
||||
|
||||
@Autowired
|
||||
private IPrcBillService prcBillService;
|
||||
|
||||
/**
|
||||
* Historical quote list.
|
||||
*/
|
||||
@@ -62,4 +68,28 @@ public class BillingController extends BaseController
|
||||
TmsPriceQuoteResult result = tmsPriceQuoteService.quote(request);
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/list")
|
||||
public TableDataInfo billList(PrcBill query)
|
||||
{
|
||||
startPage();
|
||||
List<PrcBill> list = prcBillService.selectBillList(query);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@GetMapping("/bill/{billId}")
|
||||
public AjaxResult getBill(@PathVariable String billId)
|
||||
{
|
||||
return success(prcBillService.getBill(billId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:billing:bill')")
|
||||
@PostMapping("/bill")
|
||||
public AjaxResult bill(@Validated @RequestBody TmsPriceBillRequest request)
|
||||
{
|
||||
TmsPriceQuoteResult result = prcBillService.bill(request);
|
||||
return success(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,4 +150,4 @@ xss:
|
||||
bms:
|
||||
tms:
|
||||
# Agreed API identification code for TMS callers
|
||||
api-code: BMS.TMS._Q2WnPXiXwGW2Dl-iSGNzLfrhUgQogNo
|
||||
api-code: BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw
|
||||
|
||||
@@ -77,6 +77,7 @@ price.set.customer.customerId.empty=客户ID不能为空
|
||||
price.set.customer.beginDate.empty=客户绑定生效日期不能为空
|
||||
price.set.customer.date.invalid=客户绑定生效日期不能晚于失效日期
|
||||
price.set.customer.alreadyBound=该客户已绑定套餐,一个客户只能绑定一个套餐
|
||||
price.set.customer.masterNotFound=客户主数据不存在
|
||||
price.set.customer.priority.invalid=优先级必须大于等于 1
|
||||
# 重量段 PrcWeight
|
||||
price.weight.range.empty=起始重量和结束重量不能为空
|
||||
@@ -119,3 +120,8 @@ price.quote.hitCustomerFixedPackageDetail=命中客户套餐固定价格明细
|
||||
|
||||
# ---- 状态自动刷新 ----
|
||||
price.status.refresh.success=状态刷新完成:bms_product 更新 {0} 行,bms_product_country 更新 {1} 行
|
||||
# receivable bill
|
||||
price.bill.orderNoRequired=订单号为空
|
||||
price.bill.billIdRequired=计费ID为空
|
||||
price.bill.notFound=计费记录不存在
|
||||
price.bill.bizDateRequired=业务日期为空
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ public class TmsApiProperties
|
||||
/**
|
||||
* Agreed API identification code (header X-Api-Code or body apiCode).
|
||||
*/
|
||||
private String apiCode = "BMS.TMS._Q2WnPXiXwGW2Dl-iSGNzLfrhUgQogNo";
|
||||
private String apiCode = "BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw";
|
||||
|
||||
public String getApiCode()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.ruoyi.price.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/** receivable bill header prc_bill */
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class PrcBill extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String billId;
|
||||
private String billKey;
|
||||
private String orderNo;
|
||||
private String trackingNo;
|
||||
private Long customerId;
|
||||
private String customerCode;
|
||||
private String customerName;
|
||||
private Integer pieces;
|
||||
private BigDecimal actualWeight;
|
||||
private BigDecimal volume;
|
||||
private BigDecimal volumeWeight;
|
||||
private BigDecimal pkgLength;
|
||||
private BigDecimal pkgWidth;
|
||||
private BigDecimal pkgHeight;
|
||||
private String shipperName;
|
||||
private String consigneeName;
|
||||
private String destPostcode;
|
||||
private String warehouseCode;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date orderTime;
|
||||
private String orderRemark;
|
||||
private String productCode;
|
||||
private String productName;
|
||||
private String countryCode;
|
||||
private String countryName;
|
||||
private BigDecimal weight;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date bizDate;
|
||||
private Long tmsId;
|
||||
|
||||
private String matchSource;
|
||||
private String matchMessage;
|
||||
private Long priceSetId;
|
||||
private String priceSetCode;
|
||||
private String priceSetName;
|
||||
private String setType;
|
||||
private Integer bindPriority;
|
||||
private Long customerPricesetId;
|
||||
private Long productCountryId;
|
||||
private BigDecimal weightMin;
|
||||
private BigDecimal weightMax;
|
||||
private String weightLabel;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date effectiveDate;
|
||||
private BigDecimal chargeWeight;
|
||||
private BigDecimal freightRate;
|
||||
private BigDecimal baseFreightRate;
|
||||
private BigDecimal discountPercent;
|
||||
private BigDecimal registrationFee;
|
||||
private BigDecimal freightAmount;
|
||||
private BigDecimal surchargeAmount;
|
||||
private BigDecimal payableTotal;
|
||||
private String currency;
|
||||
private String roundMode;
|
||||
|
||||
private List<PrcBillFee> fees;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ruoyi.price.domain;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
/** receivable bill fee detail prc_bill_fee */
|
||||
@Data
|
||||
public class PrcBillFee implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String feeId;
|
||||
private String billId;
|
||||
private String feeType;
|
||||
private String feeName;
|
||||
private Long scId;
|
||||
private BigDecimal amount;
|
||||
private String currency;
|
||||
private String roundMode;
|
||||
private String remark;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createdAt;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.ruoyi.price.domain.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import jakarta.validation.constraints.AssertTrue;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/** Sync order -> receivable bill. Quote fields plus order snapshot. */
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class TmsPriceBillRequest extends TmsPriceQuoteRequest
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@NotBlank(message = "orderNo is required")
|
||||
private String orderNo;
|
||||
|
||||
private String trackingNo;
|
||||
private String customerName;
|
||||
private Integer pieces;
|
||||
private BigDecimal actualWeight;
|
||||
private BigDecimal volume;
|
||||
private BigDecimal volumeWeight;
|
||||
private BigDecimal pkgLength;
|
||||
private BigDecimal pkgWidth;
|
||||
private BigDecimal pkgHeight;
|
||||
private String shipperName;
|
||||
private String consigneeName;
|
||||
private String destPostcode;
|
||||
private String warehouseCode;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date orderTime;
|
||||
private String orderRemark;
|
||||
|
||||
@JsonIgnore
|
||||
@AssertTrue(message = "bizDate is required")
|
||||
public boolean isBizDatePresent()
|
||||
{
|
||||
String bizDate = getBizDate();
|
||||
return bizDate != null && !bizDate.trim().isEmpty();
|
||||
}
|
||||
}
|
||||
+19
-1
@@ -53,6 +53,24 @@ public class TmsPriceQuoteResult implements Serializable
|
||||
/** 费用明细:运费/挂号费各一行,附加费按具体名称各一行 */
|
||||
private List<TmsPriceQuoteFeeLine> feeDetails;
|
||||
private String quoteId;
|
||||
/** true=命中已落库试算 */
|
||||
private String billId;
|
||||
private String orderNo;
|
||||
private String trackingNo;
|
||||
private String customerCode;
|
||||
private String customerName;
|
||||
private Integer pieces;
|
||||
private BigDecimal actualWeight;
|
||||
private BigDecimal volume;
|
||||
private BigDecimal volumeWeight;
|
||||
private BigDecimal pkgLength;
|
||||
private BigDecimal pkgWidth;
|
||||
private BigDecimal pkgHeight;
|
||||
private String shipperName;
|
||||
private String consigneeName;
|
||||
private String destPostcode;
|
||||
private String warehouseCode;
|
||||
private Date orderTime;
|
||||
private String orderRemark;
|
||||
/** true=hit stored quote */
|
||||
private Boolean fromCache;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.ruoyi.price.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.ruoyi.price.domain.PrcBillFee;
|
||||
|
||||
/** receivable bill fee detail mapper */
|
||||
public interface PrcBillFeeMapper
|
||||
{
|
||||
public List<PrcBillFee> selectByBillId(String billId);
|
||||
|
||||
public int insertPrcBillFee(PrcBillFee fee);
|
||||
|
||||
public int insertBatch(@Param("list") List<PrcBillFee> fees);
|
||||
|
||||
public int deleteByBillId(String billId);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.ruoyi.price.mapper;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.ruoyi.price.domain.PrcBill;
|
||||
|
||||
/** receivable bill header mapper */
|
||||
public interface PrcBillMapper
|
||||
{
|
||||
public PrcBill selectPrcBillByOrderNo(String orderNo);
|
||||
|
||||
public PrcBill selectPrcBillById(String billId);
|
||||
|
||||
public List<PrcBill> selectPrcBillList(PrcBill bill);
|
||||
|
||||
public int insertPrcBill(PrcBill bill);
|
||||
|
||||
public int updatePrcBill(PrcBill bill);
|
||||
|
||||
public int updateBillAmounts(@Param("billId") String billId,
|
||||
@Param("surchargeAmount") BigDecimal surchargeAmount,
|
||||
@Param("payableTotal") BigDecimal payableTotal);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.ruoyi.price.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.price.domain.PrcBill;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteResult;
|
||||
|
||||
/** Receivable billing from synced orders. Same price match as quote, persist prc_bill. */
|
||||
public interface IPrcBillService
|
||||
{
|
||||
TmsPriceQuoteResult bill(TmsPriceBillRequest request);
|
||||
|
||||
List<PrcBill> selectBillList(PrcBill query);
|
||||
|
||||
TmsPriceQuoteResult getBill(String billId);
|
||||
|
||||
TmsPriceQuoteResult getBillByOrderNo(String orderNo);
|
||||
}
|
||||
@@ -18,6 +18,9 @@ public interface ITmsPriceQuoteService
|
||||
{
|
||||
TmsPriceQuoteResult quote(TmsPriceQuoteRequest request);
|
||||
|
||||
/** Calc only, no prc_quote persist. Used by receivable billing. */
|
||||
TmsPriceQuoteResult calculate(TmsPriceQuoteRequest request);
|
||||
|
||||
List<PrcQuote> selectQuoteList(PrcQuote query);
|
||||
|
||||
TmsPriceQuoteResult getQuote(String quoteId);
|
||||
|
||||
+291
@@ -0,0 +1,291 @@
|
||||
package com.ruoyi.price.service.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.MessageUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.sign.Md5Utils;
|
||||
import com.ruoyi.price.domain.PrcBill;
|
||||
import com.ruoyi.price.domain.PrcBillFee;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceBillRequest;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteFeeLine;
|
||||
import com.ruoyi.price.domain.vo.TmsPriceQuoteResult;
|
||||
import com.ruoyi.price.mapper.PrcBillFeeMapper;
|
||||
import com.ruoyi.price.mapper.PrcBillMapper;
|
||||
import com.ruoyi.price.service.IPrcBillService;
|
||||
import com.ruoyi.price.service.ITmsPriceQuoteService;
|
||||
|
||||
@Service
|
||||
public class PrcBillServiceImpl implements IPrcBillService
|
||||
{
|
||||
@Autowired
|
||||
private ITmsPriceQuoteService tmsPriceQuoteService;
|
||||
|
||||
@Autowired
|
||||
private PrcBillMapper billMapper;
|
||||
|
||||
@Autowired
|
||||
private PrcBillFeeMapper billFeeMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public TmsPriceQuoteResult bill(TmsPriceBillRequest request)
|
||||
{
|
||||
if (request == null || StringUtils.isEmpty(request.getOrderNo()))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.orderNoRequired"));
|
||||
}
|
||||
request.setOrderNo(request.getOrderNo().trim());
|
||||
if (StringUtils.isEmpty(request.getBizDate()))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired"));
|
||||
}
|
||||
Date bizDate = resolveBizDate(request.getBizDate());
|
||||
BigDecimal weight = request.getWeight();
|
||||
TmsPriceQuoteResult result = tmsPriceQuoteService.calculate(request);
|
||||
persistBill(request, weight, bizDate, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PrcBill> selectBillList(PrcBill query)
|
||||
{
|
||||
return billMapper.selectPrcBillList(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmsPriceQuoteResult getBill(String billId)
|
||||
{
|
||||
if (billId == null)
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.billIdRequired"));
|
||||
}
|
||||
PrcBill bill = billMapper.selectPrcBillById(billId);
|
||||
if (bill == null)
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.notFound"));
|
||||
}
|
||||
return toResult(bill, billFeeMapper.selectByBillId(billId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmsPriceQuoteResult getBillByOrderNo(String orderNo)
|
||||
{
|
||||
if (StringUtils.isEmpty(orderNo))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.orderNoRequired"));
|
||||
}
|
||||
PrcBill bill = billMapper.selectPrcBillByOrderNo(orderNo.trim());
|
||||
if (bill == null)
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.notFound"));
|
||||
}
|
||||
return toResult(bill, billFeeMapper.selectByBillId(bill.getBillId()));
|
||||
}
|
||||
|
||||
private void persistBill(TmsPriceBillRequest request, BigDecimal weight, Date bizDate,
|
||||
TmsPriceQuoteResult result)
|
||||
{
|
||||
String orderNo = request.getOrderNo();
|
||||
String billKey = Md5Utils.hash(orderNo);
|
||||
PrcBill existed = billMapper.selectPrcBillByOrderNo(orderNo);
|
||||
PrcBill bill = existed == null ? new PrcBill() : existed;
|
||||
if (existed == null)
|
||||
{
|
||||
bill.setBillId(UUID.randomUUID().toString());
|
||||
}
|
||||
bill.setBillKey(billKey);
|
||||
bill.setOrderNo(orderNo);
|
||||
bill.setCustomerId(request.getCustomerId() == null ? Long.valueOf(0L) : request.getCustomerId());
|
||||
bill.setCustomerCode(request.getCustomerCode());
|
||||
bill.setCustomerName(request.getCustomerName());
|
||||
bill.setTrackingNo(request.getTrackingNo());
|
||||
bill.setPieces(request.getPieces());
|
||||
bill.setActualWeight(request.getActualWeight());
|
||||
bill.setVolume(request.getVolume());
|
||||
bill.setVolumeWeight(request.getVolumeWeight());
|
||||
bill.setPkgLength(request.getPkgLength());
|
||||
bill.setPkgWidth(request.getPkgWidth());
|
||||
bill.setPkgHeight(request.getPkgHeight());
|
||||
bill.setShipperName(request.getShipperName());
|
||||
bill.setConsigneeName(request.getConsigneeName());
|
||||
bill.setDestPostcode(request.getDestPostcode());
|
||||
bill.setWarehouseCode(request.getWarehouseCode());
|
||||
bill.setOrderTime(request.getOrderTime());
|
||||
bill.setOrderRemark(request.getOrderRemark());
|
||||
bill.setProductCode(result.getProductCode());
|
||||
bill.setProductName(result.getProductName());
|
||||
bill.setCountryCode(result.getCountryCode());
|
||||
bill.setCountryName(result.getCountryName());
|
||||
bill.setWeight(weight);
|
||||
bill.setBizDate(bizDate);
|
||||
bill.setTmsId(request.getTmsId() == null ? null : Long.valueOf(request.getTmsId()));
|
||||
bill.setMatchSource(result.getMatchSource());
|
||||
bill.setMatchMessage(result.getMatchMessage());
|
||||
bill.setPriceSetId(result.getPriceSetId());
|
||||
bill.setPriceSetCode(result.getPriceSetCode());
|
||||
bill.setPriceSetName(result.getPriceSetName());
|
||||
bill.setSetType(result.getSetType());
|
||||
bill.setBindPriority(result.getBindPriority());
|
||||
bill.setCustomerPricesetId(result.getCustomerPricesetId());
|
||||
bill.setProductCountryId(result.getProductCountryId());
|
||||
bill.setWeightMin(result.getWeightMin());
|
||||
bill.setWeightMax(result.getWeightMax());
|
||||
bill.setWeightLabel(result.getWeightLabel());
|
||||
bill.setEffectiveDate(result.getEffectiveDate());
|
||||
bill.setChargeWeight(result.getChargeWeight());
|
||||
bill.setFreightRate(result.getFreightRate());
|
||||
bill.setBaseFreightRate(result.getBaseFreightRate());
|
||||
bill.setDiscountPercent(result.getDiscountPercent());
|
||||
bill.setRegistrationFee(result.getRegistrationFee());
|
||||
bill.setFreightAmount(result.getFreightAmount());
|
||||
bill.setSurchargeAmount(result.getSurchargeAmount());
|
||||
bill.setPayableTotal(result.getPayableTotal());
|
||||
bill.setCurrency(result.getCurrency());
|
||||
bill.setRoundMode(result.getRoundMode());
|
||||
if (existed == null)
|
||||
{
|
||||
billMapper.insertPrcBill(bill);
|
||||
}
|
||||
else
|
||||
{
|
||||
billMapper.updatePrcBill(bill);
|
||||
billFeeMapper.deleteByBillId(bill.getBillId());
|
||||
}
|
||||
List<PrcBillFee> fees = toFeeRows(bill.getBillId(), result);
|
||||
if (!fees.isEmpty())
|
||||
{
|
||||
billFeeMapper.insertBatch(fees);
|
||||
}
|
||||
result.setBillId(bill.getBillId());
|
||||
result.setOrderNo(orderNo);
|
||||
result.setCustomerCode(request.getCustomerCode());
|
||||
fillResultOrder(result, bill);
|
||||
result.setFromCache(Boolean.valueOf(existed != null));
|
||||
}
|
||||
|
||||
private List<PrcBillFee> toFeeRows(String billId, TmsPriceQuoteResult result)
|
||||
{
|
||||
List<PrcBillFee> fees = new ArrayList<PrcBillFee>();
|
||||
if (result.getFeeDetails() == null)
|
||||
{
|
||||
return fees;
|
||||
}
|
||||
for (TmsPriceQuoteFeeLine line : result.getFeeDetails())
|
||||
{
|
||||
PrcBillFee fee = new PrcBillFee();
|
||||
fee.setFeeId(UUID.randomUUID().toString());
|
||||
fee.setBillId(billId);
|
||||
fee.setFeeType(line.getFeeType());
|
||||
fee.setFeeName(line.getFeeName());
|
||||
fee.setScId(line.getScId() == null ? 0L : line.getScId());
|
||||
fee.setAmount(line.getAmount() == null ? BigDecimal.ZERO : line.getAmount());
|
||||
fee.setCurrency(line.getCurrency());
|
||||
fee.setRoundMode(line.getRoundMode());
|
||||
fee.setRemark(line.getRemark());
|
||||
fees.add(fee);
|
||||
}
|
||||
return fees;
|
||||
}
|
||||
|
||||
private TmsPriceQuoteResult toResult(PrcBill bill, List<PrcBillFee> fees)
|
||||
{
|
||||
TmsPriceQuoteResult r = new TmsPriceQuoteResult();
|
||||
r.setBillId(bill.getBillId());
|
||||
r.setOrderNo(bill.getOrderNo());
|
||||
r.setCustomerCode(bill.getCustomerCode());
|
||||
fillResultOrder(r, bill);
|
||||
r.setFromCache(Boolean.TRUE);
|
||||
r.setMatchSource(bill.getMatchSource());
|
||||
r.setMatchMessage(bill.getMatchMessage());
|
||||
r.setCustomerId(bill.getCustomerId());
|
||||
r.setPriceSetId(bill.getPriceSetId());
|
||||
r.setPriceSetCode(bill.getPriceSetCode());
|
||||
r.setPriceSetName(bill.getPriceSetName());
|
||||
r.setSetType(bill.getSetType());
|
||||
r.setBindPriority(bill.getBindPriority());
|
||||
r.setCustomerPricesetId(bill.getCustomerPricesetId());
|
||||
r.setProductCode(bill.getProductCode());
|
||||
r.setProductName(bill.getProductName());
|
||||
r.setCountryCode(bill.getCountryCode());
|
||||
r.setCountryName(bill.getCountryName());
|
||||
r.setProductCountryId(bill.getProductCountryId());
|
||||
r.setWeightMin(bill.getWeightMin());
|
||||
r.setWeightMax(bill.getWeightMax());
|
||||
r.setWeightLabel(bill.getWeightLabel());
|
||||
r.setEffectiveDate(bill.getEffectiveDate());
|
||||
r.setWeight(bill.getWeight());
|
||||
r.setChargeWeight(bill.getChargeWeight());
|
||||
r.setFreightRate(bill.getFreightRate());
|
||||
r.setBaseFreightRate(bill.getBaseFreightRate());
|
||||
r.setDiscountPercent(bill.getDiscountPercent());
|
||||
r.setRegistrationFee(bill.getRegistrationFee());
|
||||
r.setFreightAmount(bill.getFreightAmount());
|
||||
r.setSurchargeAmount(bill.getSurchargeAmount());
|
||||
r.setPayableTotal(bill.getPayableTotal());
|
||||
r.setCurrency(bill.getCurrency());
|
||||
r.setRoundMode(bill.getRoundMode());
|
||||
List<TmsPriceQuoteFeeLine> lines = new ArrayList<TmsPriceQuoteFeeLine>();
|
||||
if (fees != null)
|
||||
{
|
||||
for (PrcBillFee fee : fees)
|
||||
{
|
||||
TmsPriceQuoteFeeLine line = new TmsPriceQuoteFeeLine();
|
||||
line.setFeeType(fee.getFeeType());
|
||||
line.setFeeName(fee.getFeeName());
|
||||
line.setScId(fee.getScId());
|
||||
line.setAmount(fee.getAmount());
|
||||
line.setCurrency(fee.getCurrency());
|
||||
line.setRoundMode(fee.getRoundMode());
|
||||
line.setRemark(fee.getRemark());
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
r.setFeeDetails(lines);
|
||||
return r;
|
||||
}
|
||||
|
||||
private void fillResultOrder(TmsPriceQuoteResult r, PrcBill bill)
|
||||
{
|
||||
r.setTrackingNo(bill.getTrackingNo());
|
||||
r.setCustomerName(bill.getCustomerName());
|
||||
r.setPieces(bill.getPieces());
|
||||
r.setActualWeight(bill.getActualWeight());
|
||||
r.setVolume(bill.getVolume());
|
||||
r.setVolumeWeight(bill.getVolumeWeight());
|
||||
r.setPkgLength(bill.getPkgLength());
|
||||
r.setPkgWidth(bill.getPkgWidth());
|
||||
r.setPkgHeight(bill.getPkgHeight());
|
||||
r.setShipperName(bill.getShipperName());
|
||||
r.setConsigneeName(bill.getConsigneeName());
|
||||
r.setDestPostcode(bill.getDestPostcode());
|
||||
r.setWarehouseCode(bill.getWarehouseCode());
|
||||
r.setOrderTime(bill.getOrderTime());
|
||||
r.setOrderRemark(bill.getOrderRemark());
|
||||
}
|
||||
|
||||
private Date resolveBizDate(String bizDate)
|
||||
{
|
||||
if (StringUtils.isEmpty(bizDate))
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired"));
|
||||
}
|
||||
try
|
||||
{
|
||||
return new SimpleDateFormat("yyyy-MM-dd").parse(bizDate.trim());
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new ServiceException(MessageUtils.message("price.quote.bizDateInvalid"));
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -113,6 +113,16 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TmsPriceQuoteResult calculate(TmsPriceQuoteRequest request)
|
||||
{
|
||||
validateRequest(request);
|
||||
Date bizDate = resolveBizDate(request.getBizDate());
|
||||
TmsPriceQuoteResult result = doQuote(request, bizDate);
|
||||
applySurchargesAndFees(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PrcQuote> selectQuoteList(PrcQuote query)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.price.mapper.PrcBillFeeMapper">
|
||||
|
||||
<resultMap type="PrcBillFee" id="PrcBillFeeResult">
|
||||
<id property="feeId" column="fee_id" />
|
||||
<result property="billId" column="bill_id" />
|
||||
<result property="feeType" column="fee_type" />
|
||||
<result property="feeName" column="fee_name" />
|
||||
<result property="scId" column="sc_id" />
|
||||
<result property="amount" column="amount" />
|
||||
<result property="currency" column="currency" />
|
||||
<result property="roundMode" column="round_mode" />
|
||||
<result property="remark" column="remark" />
|
||||
<result property="createdAt" column="created_at" />
|
||||
</resultMap>
|
||||
|
||||
<select id="selectByBillId" parameterType="String" resultMap="PrcBillFeeResult">
|
||||
select fee_id, bill_id, fee_type, fee_name, sc_id, amount, currency, round_mode, remark, created_at
|
||||
from prc_bill_fee
|
||||
where bill_id = #{billId}
|
||||
order by field(fee_type, 'BASIC_FREIGHT', 'REGISTRATION_FEE', 'SURCHARGE'), fee_id
|
||||
</select>
|
||||
|
||||
<insert id="insertPrcBillFee" parameterType="PrcBillFee">
|
||||
insert into prc_bill_fee (
|
||||
fee_id, bill_id, fee_type, fee_name, sc_id, amount, currency, round_mode, remark, created_at
|
||||
) values (
|
||||
#{feeId}, #{billId}, #{feeType}, #{feeName}, #{scId}, #{amount}, #{currency}, #{roundMode}, #{remark}, sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="insertBatch" parameterType="java.util.List">
|
||||
insert into prc_bill_fee (
|
||||
fee_id, bill_id, fee_type, fee_name, sc_id, amount, currency, round_mode, remark, created_at
|
||||
) values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.feeId}, #{item.billId}, #{item.feeType}, #{item.feeName}, #{item.scId}, #{item.amount},
|
||||
#{item.currency}, #{item.roundMode}, #{item.remark}, sysdate())
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<delete id="deleteByBillId" parameterType="String">
|
||||
delete from prc_bill_fee where bill_id = #{billId}
|
||||
</delete>
|
||||
</mapper>
|
||||
@@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.price.mapper.PrcBillMapper">
|
||||
|
||||
<resultMap type="PrcBill" id="PrcBillResult">
|
||||
<id property="billId" column="bill_id" />
|
||||
<result property="billKey" column="bill_key" />
|
||||
<result property="orderNo" column="order_no" />
|
||||
<result property="trackingNo" column="tracking_no" />
|
||||
<result property="customerId" column="customer_id" />
|
||||
<result property="customerCode" column="customer_code" />
|
||||
<result property="customerName" column="customer_name" />
|
||||
<result property="pieces" column="pieces" />
|
||||
<result property="actualWeight" column="actual_weight" />
|
||||
<result property="volume" column="volume" />
|
||||
<result property="volumeWeight" column="volume_weight" />
|
||||
<result property="pkgLength" column="pkg_length" />
|
||||
<result property="pkgWidth" column="pkg_width" />
|
||||
<result property="pkgHeight" column="pkg_height" />
|
||||
<result property="shipperName" column="shipper_name" />
|
||||
<result property="consigneeName" column="consignee_name" />
|
||||
<result property="destPostcode" column="dest_postcode" />
|
||||
<result property="warehouseCode" column="warehouse_code" />
|
||||
<result property="orderTime" column="order_time" />
|
||||
<result property="orderRemark" column="order_remark" />
|
||||
<result property="productCode" column="product_code" />
|
||||
<result property="productName" column="product_name" />
|
||||
<result property="countryCode" column="country_code" />
|
||||
<result property="countryName" column="country_name" />
|
||||
<result property="weight" column="weight" />
|
||||
<result property="bizDate" column="biz_date" />
|
||||
<result property="tmsId" column="tms_id" />
|
||||
<result property="matchSource" column="match_source" />
|
||||
<result property="matchMessage" column="match_message" />
|
||||
<result property="priceSetId" column="price_set_id" />
|
||||
<result property="priceSetCode" column="price_set_code" />
|
||||
<result property="priceSetName" column="price_set_name" />
|
||||
<result property="setType" column="set_type" />
|
||||
<result property="bindPriority" column="bind_priority" />
|
||||
<result property="customerPricesetId" column="customer_priceset_id" />
|
||||
<result property="productCountryId" column="product_country_id" />
|
||||
<result property="weightMin" column="weight_min" />
|
||||
<result property="weightMax" column="weight_max" />
|
||||
<result property="weightLabel" column="weight_label" />
|
||||
<result property="effectiveDate" column="effective_date" />
|
||||
<result property="chargeWeight" column="charge_weight" />
|
||||
<result property="freightRate" column="freight_rate" />
|
||||
<result property="baseFreightRate" column="base_freight_rate" />
|
||||
<result property="discountPercent" column="discount_percent" />
|
||||
<result property="registrationFee" column="registration_fee" />
|
||||
<result property="freightAmount" column="freight_amount" />
|
||||
<result property="surchargeAmount" column="surcharge_amount" />
|
||||
<result property="payableTotal" column="payable_total" />
|
||||
<result property="currency" column="currency" />
|
||||
<result property="roundMode" column="round_mode" />
|
||||
<result property="createBy" column="created_by" />
|
||||
<result property="createTime" column="created_at" />
|
||||
<result property="updateBy" column="updated_by" />
|
||||
<result property="updateTime" column="updated_at" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectPrcBillVo">
|
||||
select bill_id, bill_key, order_no, tracking_no, customer_id, customer_code, customer_name,
|
||||
pieces, actual_weight, volume, volume_weight, pkg_length, pkg_width, pkg_height,
|
||||
shipper_name, consignee_name, dest_postcode, warehouse_code, order_time, order_remark,
|
||||
product_code, product_name, country_code, country_name, weight, biz_date, tms_id,
|
||||
match_source, match_message, price_set_id, price_set_code, price_set_name,
|
||||
set_type, bind_priority, customer_priceset_id, product_country_id,
|
||||
weight_min, weight_max, weight_label, effective_date, charge_weight,
|
||||
freight_rate, base_freight_rate, discount_percent, registration_fee,
|
||||
freight_amount, surcharge_amount, payable_total, currency, round_mode,
|
||||
created_by, created_at, updated_by, updated_at
|
||||
from prc_bill
|
||||
</sql>
|
||||
|
||||
<select id="selectPrcBillByOrderNo" parameterType="String" resultMap="PrcBillResult">
|
||||
<include refid="selectPrcBillVo"/>
|
||||
where order_no = #{orderNo}
|
||||
</select>
|
||||
|
||||
<select id="selectPrcBillById" parameterType="String" resultMap="PrcBillResult">
|
||||
<include refid="selectPrcBillVo"/>
|
||||
where bill_id = #{billId}
|
||||
</select>
|
||||
|
||||
<select id="selectPrcBillList" parameterType="PrcBill" resultMap="PrcBillResult">
|
||||
<include refid="selectPrcBillVo"/>
|
||||
<where>
|
||||
<if test="orderNo != null and orderNo != ''">
|
||||
AND order_no like concat('%', #{orderNo}, '%')
|
||||
</if>
|
||||
<if test="trackingNo != null and trackingNo != ''">
|
||||
AND tracking_no like concat('%', #{trackingNo}, '%')
|
||||
</if>
|
||||
<if test="customerCode != null and customerCode != ''">
|
||||
AND customer_code like concat('%', #{customerCode}, '%')
|
||||
</if>
|
||||
<if test="customerName != null and customerName != ''">
|
||||
AND customer_name like concat('%', #{customerName}, '%')
|
||||
</if>
|
||||
<if test="productCode != null and productCode != ''">
|
||||
AND product_code like concat('%', #{productCode}, '%')
|
||||
</if>
|
||||
<if test="countryCode != null and countryCode != ''">
|
||||
AND country_code = #{countryCode}
|
||||
</if>
|
||||
<if test="matchSource != null and matchSource != ''">
|
||||
AND match_source = #{matchSource}
|
||||
</if>
|
||||
<if test="bizDate != null">
|
||||
AND biz_date = #{bizDate}
|
||||
</if>
|
||||
<if test="params.beginTime != null and params.beginTime != ''">
|
||||
AND date_format(created_at,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
|
||||
</if>
|
||||
<if test="params.endTime != null and params.endTime != ''">
|
||||
AND date_format(created_at,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
|
||||
</if>
|
||||
</where>
|
||||
order by created_at desc, bill_id desc
|
||||
</select>
|
||||
|
||||
<insert id="insertPrcBill" parameterType="PrcBill">
|
||||
insert into prc_bill (
|
||||
bill_id, bill_key, order_no, tracking_no, customer_id, customer_code, customer_name,
|
||||
pieces, actual_weight, volume, volume_weight, pkg_length, pkg_width, pkg_height,
|
||||
shipper_name, consignee_name, dest_postcode, warehouse_code, order_time, order_remark,
|
||||
product_code, product_name, country_code, country_name, weight, biz_date, tms_id,
|
||||
match_source, match_message, price_set_id, price_set_code, price_set_name,
|
||||
set_type, bind_priority, customer_priceset_id, product_country_id,
|
||||
weight_min, weight_max, weight_label, effective_date, charge_weight,
|
||||
freight_rate, base_freight_rate, discount_percent, registration_fee,
|
||||
freight_amount, surcharge_amount, payable_total, currency, round_mode,
|
||||
created_at
|
||||
) values (
|
||||
#{billId}, #{billKey}, #{orderNo}, #{trackingNo}, #{customerId}, #{customerCode}, #{customerName},
|
||||
#{pieces}, #{actualWeight}, #{volume}, #{volumeWeight}, #{pkgLength}, #{pkgWidth}, #{pkgHeight},
|
||||
#{shipperName}, #{consigneeName}, #{destPostcode}, #{warehouseCode}, #{orderTime}, #{orderRemark},
|
||||
#{productCode}, #{productName}, #{countryCode}, #{countryName}, #{weight}, #{bizDate}, #{tmsId},
|
||||
#{matchSource}, #{matchMessage}, #{priceSetId}, #{priceSetCode}, #{priceSetName},
|
||||
#{setType}, #{bindPriority}, #{customerPricesetId}, #{productCountryId},
|
||||
#{weightMin}, #{weightMax}, #{weightLabel}, #{effectiveDate}, #{chargeWeight},
|
||||
#{freightRate}, #{baseFreightRate}, #{discountPercent}, #{registrationFee},
|
||||
#{freightAmount}, #{surchargeAmount}, #{payableTotal}, #{currency}, #{roundMode},
|
||||
sysdate()
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updatePrcBill" parameterType="PrcBill">
|
||||
update prc_bill
|
||||
set bill_key = #{billKey},
|
||||
tracking_no = #{trackingNo},
|
||||
customer_id = #{customerId},
|
||||
customer_code = #{customerCode},
|
||||
customer_name = #{customerName},
|
||||
pieces = #{pieces},
|
||||
actual_weight = #{actualWeight},
|
||||
volume = #{volume},
|
||||
volume_weight = #{volumeWeight},
|
||||
pkg_length = #{pkgLength},
|
||||
pkg_width = #{pkgWidth},
|
||||
pkg_height = #{pkgHeight},
|
||||
shipper_name = #{shipperName},
|
||||
consignee_name = #{consigneeName},
|
||||
dest_postcode = #{destPostcode},
|
||||
warehouse_code = #{warehouseCode},
|
||||
order_time = #{orderTime},
|
||||
order_remark = #{orderRemark},
|
||||
product_code = #{productCode},
|
||||
product_name = #{productName},
|
||||
country_code = #{countryCode},
|
||||
country_name = #{countryName},
|
||||
weight = #{weight},
|
||||
biz_date = #{bizDate},
|
||||
tms_id = #{tmsId},
|
||||
match_source = #{matchSource},
|
||||
match_message = #{matchMessage},
|
||||
price_set_id = #{priceSetId},
|
||||
price_set_code = #{priceSetCode},
|
||||
price_set_name = #{priceSetName},
|
||||
set_type = #{setType},
|
||||
bind_priority = #{bindPriority},
|
||||
customer_priceset_id = #{customerPricesetId},
|
||||
product_country_id = #{productCountryId},
|
||||
weight_min = #{weightMin},
|
||||
weight_max = #{weightMax},
|
||||
weight_label = #{weightLabel},
|
||||
effective_date = #{effectiveDate},
|
||||
charge_weight = #{chargeWeight},
|
||||
freight_rate = #{freightRate},
|
||||
base_freight_rate = #{baseFreightRate},
|
||||
discount_percent = #{discountPercent},
|
||||
registration_fee = #{registrationFee},
|
||||
freight_amount = #{freightAmount},
|
||||
surcharge_amount = #{surchargeAmount},
|
||||
payable_total = #{payableTotal},
|
||||
currency = #{currency},
|
||||
round_mode = #{roundMode},
|
||||
updated_at = sysdate()
|
||||
where bill_id = #{billId}
|
||||
</update>
|
||||
|
||||
<update id="updateBillAmounts">
|
||||
update prc_bill
|
||||
set surcharge_amount = #{surchargeAmount},
|
||||
payable_total = #{payableTotal},
|
||||
updated_at = sysdate()
|
||||
where bill_id = #{billId}
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -0,0 +1,82 @@
|
||||
-- prc_bill / prc_bill_fee: receivable billing from synced orders
|
||||
-- fields follow prc_quote / prc_quote_fee; extra order_no + customer_code
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS prc_bill (
|
||||
bill_id VARCHAR(36) NOT NULL COMMENT '计费ID',
|
||||
bill_key CHAR(32) NOT NULL COMMENT 'MD5(order_no)',
|
||||
order_no VARCHAR(64) NOT NULL COMMENT '订单号',
|
||||
tracking_no VARCHAR(64) DEFAULT NULL COMMENT '运单号',
|
||||
customer_id BIGINT(20) NOT NULL DEFAULT 0 COMMENT '客户ID',
|
||||
customer_code VARCHAR(50) DEFAULT NULL COMMENT '客户代码',
|
||||
customer_name VARCHAR(100) DEFAULT NULL COMMENT '客户名称',
|
||||
pieces INT(11) DEFAULT NULL COMMENT '件数',
|
||||
actual_weight DECIMAL(10,3) DEFAULT NULL COMMENT '实际重量KG',
|
||||
volume DECIMAL(12,4) DEFAULT NULL COMMENT '体积m3',
|
||||
volume_weight DECIMAL(10,3) DEFAULT NULL COMMENT '材积重KG',
|
||||
pkg_length DECIMAL(10,2) DEFAULT NULL COMMENT '长CM',
|
||||
pkg_width DECIMAL(10,2) DEFAULT NULL COMMENT '宽CM',
|
||||
pkg_height DECIMAL(10,2) DEFAULT NULL COMMENT '高CM',
|
||||
shipper_name VARCHAR(100) DEFAULT NULL COMMENT '发件人',
|
||||
consignee_name VARCHAR(100) DEFAULT NULL COMMENT '收件人',
|
||||
dest_postcode VARCHAR(20) DEFAULT NULL COMMENT '目的邮编',
|
||||
warehouse_code VARCHAR(50) DEFAULT NULL COMMENT '仓库',
|
||||
order_time DATETIME DEFAULT NULL COMMENT '下单时间',
|
||||
order_remark VARCHAR(500) DEFAULT NULL COMMENT '订单备注',
|
||||
product_code VARCHAR(20) NOT NULL COMMENT '产品代码',
|
||||
product_name VARCHAR(100) DEFAULT NULL COMMENT '产品名称',
|
||||
country_code CHAR(2) DEFAULT NULL COMMENT '国家二字码',
|
||||
country_name VARCHAR(50) DEFAULT NULL COMMENT '国家名称',
|
||||
weight DECIMAL(10,3) NOT NULL COMMENT '计费重量KG',
|
||||
biz_date DATE NOT NULL COMMENT '计费日期',
|
||||
tms_id BIGINT(20) DEFAULT NULL COMMENT '多租户系统ID',
|
||||
match_source VARCHAR(30) DEFAULT NULL COMMENT '命中来源',
|
||||
match_message VARCHAR(200) DEFAULT NULL COMMENT '命中说明',
|
||||
price_set_id BIGINT(20) DEFAULT NULL COMMENT '价格套餐ID',
|
||||
price_set_code VARCHAR(20) DEFAULT NULL COMMENT '套餐编码',
|
||||
price_set_name VARCHAR(50) DEFAULT NULL COMMENT '套餐名称',
|
||||
set_type VARCHAR(10) DEFAULT NULL COMMENT '计价类型',
|
||||
bind_priority INT(11) DEFAULT NULL COMMENT '客户套餐优先级',
|
||||
customer_priceset_id BIGINT(20) DEFAULT NULL COMMENT '客户套餐绑定ID',
|
||||
product_country_id BIGINT(20) DEFAULT NULL COMMENT '关联 bms_product_country.detail_id',
|
||||
weight_min DECIMAL(10,4) DEFAULT NULL COMMENT '重量段下限',
|
||||
weight_max DECIMAL(10,4) DEFAULT NULL COMMENT '重量段上限',
|
||||
weight_label VARCHAR(50) DEFAULT NULL COMMENT '重量段展示',
|
||||
effective_date DATE DEFAULT NULL COMMENT '产品明细生效日',
|
||||
charge_weight DECIMAL(10,3) DEFAULT NULL COMMENT '计费重量',
|
||||
freight_rate DECIMAL(10,4) DEFAULT NULL COMMENT '运费单价',
|
||||
base_freight_rate DECIMAL(10,4) DEFAULT NULL COMMENT '折扣前单价',
|
||||
discount_percent DECIMAL(5,2) DEFAULT NULL COMMENT '折扣百分数',
|
||||
registration_fee DECIMAL(10,2) DEFAULT NULL COMMENT '挂号费',
|
||||
freight_amount DECIMAL(10,2) DEFAULT NULL COMMENT '运费金额',
|
||||
surcharge_amount DECIMAL(10,2) DEFAULT NULL COMMENT '附加费合计',
|
||||
payable_total DECIMAL(10,2) DEFAULT NULL COMMENT '应收总额',
|
||||
currency VARCHAR(10) NOT NULL DEFAULT 'CNY' COMMENT '币种',
|
||||
round_mode VARCHAR(20) NOT NULL DEFAULT 'HALF_UP' COMMENT '取值方式',
|
||||
created_by VARCHAR(64) DEFAULT '' COMMENT '创建人',
|
||||
created_at DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
updated_by VARCHAR(64) DEFAULT '' COMMENT '更新人',
|
||||
updated_at DATETIME DEFAULT NULL COMMENT '更新时间',
|
||||
PRIMARY KEY (bill_id),
|
||||
UNIQUE KEY uk_bill_order (order_no),
|
||||
UNIQUE KEY uk_bill_key (bill_key),
|
||||
INDEX idx_bill_customer (customer_code, biz_date),
|
||||
INDEX idx_bill_product (product_code, country_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='计费应收主表-订单同步计费';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS prc_bill_fee (
|
||||
fee_id VARCHAR(36) NOT NULL COMMENT '费用明细ID',
|
||||
bill_id VARCHAR(36) NOT NULL COMMENT '计费ID',
|
||||
fee_type VARCHAR(30) NOT NULL COMMENT '费用类型(字典bms_fee_type)',
|
||||
fee_name VARCHAR(100) DEFAULT NULL COMMENT '费用名称',
|
||||
sc_id BIGINT(20) NOT NULL DEFAULT 0 COMMENT '附加费配置ID',
|
||||
amount DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '金额',
|
||||
currency VARCHAR(10) NOT NULL DEFAULT 'CNY' COMMENT '币种',
|
||||
round_mode VARCHAR(20) DEFAULT 'HALF_UP' COMMENT '取值方式',
|
||||
remark VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||||
created_at DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
PRIMARY KEY (fee_id),
|
||||
UNIQUE KEY uk_bill_fee_item (bill_id, fee_type, sc_id),
|
||||
INDEX idx_bill_fee_type (fee_type),
|
||||
CONSTRAINT fk_bill_fee_bill FOREIGN KEY (bill_id) REFERENCES prc_bill (bill_id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='计费应收费用明细';
|
||||
@@ -0,0 +1,23 @@
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- visible C menu under billing center (2300)
|
||||
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
SELECT 2310, N'同步计费', 2300, 2, 'bill', 'price/billing/bill', '', 'BillingBill', 1, 0, 'C', '0', '0', 'price:billing:bill', 'list', 'admin', sysdate(), N'订单同步计费应收'
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2310);
|
||||
|
||||
UPDATE sys_menu SET menu_name = N'同步计费', parent_id = 2300, order_num = 2, path = 'bill', component = 'price/billing/bill', route_name = 'BillingBill', menu_type = 'C', visible = '0', perms = 'price:billing:bill', remark = N'订单同步计费应收'
|
||||
WHERE menu_id = 2310;
|
||||
|
||||
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time)
|
||||
SELECT 2311, N'计费查询', 2310, 1, '', NULL, 1, 0, 'F', '0', '0', 'price:billing:bill', '#', 'admin', sysdate()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2311);
|
||||
|
||||
UPDATE sys_menu SET menu_name = N'计费查询', parent_id = 2310, menu_type = 'F', path = '', component = NULL, perms = 'price:billing:bill' WHERE menu_id = 2311;
|
||||
|
||||
INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time)
|
||||
SELECT 2312, N'计费详情', 2310, 2, '', NULL, 1, 0, 'F', '0', '0', 'price:billing:bill', '#', 'admin', sysdate()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2312);
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT 1, m.menu_id FROM (SELECT 2310 AS menu_id UNION SELECT 2311 UNION SELECT 2312) m
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu rm WHERE rm.role_id = 1 AND rm.menu_id = m.menu_id);
|
||||
@@ -0,0 +1,21 @@
|
||||
-- prc_bill add order snapshot columns
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
ALTER TABLE prc_bill
|
||||
ADD COLUMN tracking_no VARCHAR(64) DEFAULT NULL COMMENT '运单号' AFTER order_no,
|
||||
ADD COLUMN customer_name VARCHAR(100) DEFAULT NULL COMMENT '客户名称' AFTER customer_code,
|
||||
ADD COLUMN pieces INT(11) DEFAULT NULL COMMENT '件数' AFTER customer_name,
|
||||
ADD COLUMN actual_weight DECIMAL(10,3) DEFAULT NULL COMMENT '实际重量KG' AFTER pieces,
|
||||
ADD COLUMN volume DECIMAL(12,4) DEFAULT NULL COMMENT '体积m3' AFTER actual_weight,
|
||||
ADD COLUMN volume_weight DECIMAL(10,3) DEFAULT NULL COMMENT '材积重KG' AFTER volume,
|
||||
ADD COLUMN pkg_length DECIMAL(10,2) DEFAULT NULL COMMENT '长CM' AFTER volume_weight,
|
||||
ADD COLUMN pkg_width DECIMAL(10,2) DEFAULT NULL COMMENT '宽CM' AFTER pkg_length,
|
||||
ADD COLUMN pkg_height DECIMAL(10,2) DEFAULT NULL COMMENT '高CM' AFTER pkg_width,
|
||||
ADD COLUMN shipper_name VARCHAR(100) DEFAULT NULL COMMENT '发件人' AFTER pkg_height,
|
||||
ADD COLUMN consignee_name VARCHAR(100) DEFAULT NULL COMMENT '收件人' AFTER shipper_name,
|
||||
ADD COLUMN dest_postcode VARCHAR(20) DEFAULT NULL COMMENT '目的邮编' AFTER consignee_name,
|
||||
ADD COLUMN warehouse_code VARCHAR(50) DEFAULT NULL COMMENT '仓库' AFTER dest_postcode,
|
||||
ADD COLUMN order_time DATETIME DEFAULT NULL COMMENT '下单时间' AFTER warehouse_code,
|
||||
ADD COLUMN order_remark VARCHAR(500) DEFAULT NULL COMMENT '订单备注' AFTER order_time;
|
||||
|
||||
ALTER TABLE prc_bill ADD INDEX idx_bill_tracking (tracking_no);
|
||||
@@ -25,3 +25,29 @@ export function getQuote(quoteId) {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
/** Sync order receivable bill */
|
||||
export function billOrder(data) {
|
||||
return request({
|
||||
url: '/price/billing/bill',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
/** Receivable bill list */
|
||||
export function listBill(query) {
|
||||
return request({
|
||||
url: '/price/billing/bill/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
/** Receivable bill detail */
|
||||
export function getBill(billId) {
|
||||
return request({
|
||||
url: '/price/billing/bill/' + billId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="app-container billing-bill">
|
||||
<basic-table
|
||||
ref="tableRef"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:query="queryList"
|
||||
row-key="billId"
|
||||
>
|
||||
<template #col-product="{ row }">
|
||||
{{ row.productName || '-' }} ({{ row.productCode }})
|
||||
</template>
|
||||
<template #col-country="{ row }">
|
||||
{{ row.countryName || '-' }} ({{ row.countryCode || '-' }})
|
||||
</template>
|
||||
<template #col-matchSource="{ row }">
|
||||
<el-tag size="small" :type="sourceTagType(row.matchSource)">{{ sourceLabel(row.matchSource) }}</el-tag>
|
||||
</template>
|
||||
<template #col-payableTotal="{ row }">
|
||||
<span class="payable">{{ formatMoney(row.payableTotal) }}</span>
|
||||
</template>
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" icon="View" @click="handleView(row)">查看</el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
|
||||
<el-drawer v-model="open" size="780px" :title="title" append-to-body>
|
||||
<div v-loading="loading">
|
||||
<el-empty v-if="!detail" description="暂无详情" />
|
||||
<div v-else class="bill-detail">
|
||||
<div class="sec-title">订单信息</div>
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="订单号">{{ detail.orderNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运单号">{{ detail.trackingNo || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户">{{ displayCustomer(detail) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="仓库">{{ detail.warehouseCode || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="发件人">{{ detail.shipperName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="收件人">{{ detail.consigneeName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的国/地区">{{ (detail.countryName || '-') + ' (' + (detail.countryCode || '-') + ')' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的邮编">{{ detail.destPostcode || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="件数">{{ detail.pieces != null ? detail.pieces : '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="尺寸(cm)">{{ dimLabel(detail) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实重(kg)">{{ formatMoney(detail.actualWeight) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="材积重(kg)">{{ formatMoney(detail.volumeWeight) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="体积(m³)">{{ formatMoney(detail.volume) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="下单时间">{{ formatDateTime(detail.orderTime) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="订单备注" :span="2">{{ detail.orderRemark || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div class="sec-title">计费信息</div>
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="产品">{{ (detail.productName || '-') + ' (' + (detail.productCode || '-') + ')' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="计费重量(kg)">{{ detail.chargeWeight ?? detail.weight ?? '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="重量段">{{ detail.weightLabel || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="计费日期">{{ formatDate(detail.bizDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="计价来源">
|
||||
<el-tag size="small" :type="sourceTagType(detail.matchSource)">{{ sourceLabel(detail.matchSource) }}</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="套餐">{{ detail.priceSetName || '-' }} {{ detail.priceSetCode ? '(' + detail.priceSetCode + ')' : '' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="币种">
|
||||
<dict-tag :options="bms_currency" :value="displayCurrency(detail.currency)" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="取值方式">{{ roundModeLabel(detail.roundMode) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运费单价">{{ formatMoney(detail.freightRate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="运费金额">{{ formatMoney(detail.freightAmount) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="挂号费">{{ formatMoney(detail.registrationFee) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="附加费">{{ formatMoney(detail.surchargeAmount) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="应收总额">
|
||||
<span class="payable">{{ formatMoney(detail.payableTotal) }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="命中说明" :span="2">{{ detail.matchMessage || '-' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-table
|
||||
v-if="detail.feeDetails && detail.feeDetails.length"
|
||||
:data="detail.feeDetails"
|
||||
border
|
||||
size="small"
|
||||
class="fee-table"
|
||||
>
|
||||
<el-table-column label="费用名称" min-width="140" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ displayFeeName(row) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="费用类型" width="110" align="center">
|
||||
<template #default="{ row }">{{ feeTypeLabel(row.feeType) || row.feeType }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" min-width="120" align="right">
|
||||
<template #default="{ row }">{{ formatMoney(row.amount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="币种" width="90" align="center">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="bms_currency" :value="displayCurrency(row.currency)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="说明" min-width="160" show-overflow-tooltip>
|
||||
<template #default="{ row }">{{ row.remark || '-' }}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="BillingBill">
|
||||
import { listBill, getBill } from '@/api/price/billing'
|
||||
|
||||
const { bms_fee_type, bms_currency } = useDict('bms_fee_type', 'bms_currency')
|
||||
const tableRef = ref()
|
||||
const open = ref(false)
|
||||
const title = ref('计费详情')
|
||||
const loading = ref(false)
|
||||
const detail = ref(null)
|
||||
|
||||
const columns = [
|
||||
{ label: '订单号', prop: 'orderNo', minWidth: 140, showOverflowTooltip: true },
|
||||
{ label: '运单号', prop: 'trackingNo', minWidth: 140, showOverflowTooltip: true },
|
||||
{ label: '客户', prop: 'customerName', minWidth: 140, showOverflowTooltip: true },
|
||||
{ label: '客户代码', prop: 'customerCode', width: 120 },
|
||||
{ label: '产品', prop: 'product', minWidth: 160, slot: 'product' },
|
||||
{ label: '国家', prop: 'country', minWidth: 130, slot: 'country' },
|
||||
{ label: '件数', prop: 'pieces', align: 'center', width: 70 },
|
||||
{ label: '计费重', prop: 'chargeWeight', align: 'center', width: 90 },
|
||||
{ label: '应收总额', prop: 'payableTotal', align: 'right', width: 120, slot: 'payableTotal' },
|
||||
{ label: '计价来源', prop: 'matchSource', align: 'center', width: 130, slot: 'matchSource' },
|
||||
{ label: '下单时间', prop: 'orderTime', align: 'center', width: 170, parseTime: true },
|
||||
{ label: '操作', prop: 'action', align: 'center', width: 90, fixed: 'right', slot: 'action', showInToolbar: false }
|
||||
]
|
||||
|
||||
const searchColumns = [
|
||||
{ label: '订单号', prop: 'orderNo', component: 'input', placeholder: '订单号', width: '160px' },
|
||||
{ label: '运单号', prop: 'trackingNo', component: 'input', placeholder: '运单号', width: '160px' },
|
||||
{ label: '客户代码', prop: 'customerCode', component: 'input', placeholder: '客户代码', width: '140px' },
|
||||
{ label: '产品代码', prop: 'productCode', component: 'input', placeholder: '产品代码', width: '140px' }
|
||||
]
|
||||
|
||||
function queryList(params) {
|
||||
return listBill(params)
|
||||
}
|
||||
|
||||
function handleView(row) {
|
||||
title.value = '计费详情 #' + (row.orderNo || row.billId)
|
||||
open.value = true
|
||||
loading.value = true
|
||||
detail.value = null
|
||||
getBill(row.billId).then(res => {
|
||||
detail.value = res.data || null
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
function displayCustomer(row) {
|
||||
if (row.customerName && row.customerCode) return row.customerName + ' (' + row.customerCode + ')'
|
||||
return row.customerName || row.customerCode || row.customerId || '-'
|
||||
}
|
||||
|
||||
function dimLabel(row) {
|
||||
if (row.pkgLength == null && row.pkgWidth == null && row.pkgHeight == null) return '-'
|
||||
return [row.pkgLength, row.pkgWidth, row.pkgHeight].map(v => v == null ? '-' : v).join(' × ')
|
||||
}
|
||||
|
||||
function formatMoney(val) {
|
||||
if (val === null || val === undefined || val === '') return '-'
|
||||
const num = Number(val)
|
||||
if (Number.isNaN(num)) return val
|
||||
return num.toFixed(4)
|
||||
}
|
||||
|
||||
function formatDate(val) {
|
||||
if (!val) return '-'
|
||||
const d = new Date(val)
|
||||
if (Number.isNaN(d.getTime())) return val
|
||||
return d.toISOString().slice(0, 10)
|
||||
}
|
||||
|
||||
function formatDateTime(val) {
|
||||
if (!val) return '-'
|
||||
const d = new Date(val)
|
||||
if (Number.isNaN(d.getTime())) return val
|
||||
const pad = n => String(n).padStart(2, '0')
|
||||
return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds())
|
||||
}
|
||||
|
||||
function sourceLabel(source) {
|
||||
const map = {
|
||||
PACKAGE_FIXED: '客户固定价套餐',
|
||||
PACKAGE_DISCOUNT: '客户折扣套餐',
|
||||
PRODUCT_DEFAULT: '产品默认价',
|
||||
FIXED: '客户固定价套餐',
|
||||
DISCOUNT: '客户折扣套餐'
|
||||
}
|
||||
return map[source] || source || '-'
|
||||
}
|
||||
|
||||
function roundModeLabel(mode) {
|
||||
const map = { UP: '向上取值', DOWN: '向下取整', HALF_UP: '四舍五入' }
|
||||
return map[mode] || mode || '四舍五入'
|
||||
}
|
||||
|
||||
function feeTypeLabel(type) {
|
||||
const found = (bms_fee_type.value || []).find(d => d.value === type)
|
||||
return found ? found.label : ''
|
||||
}
|
||||
|
||||
function displayCurrency(v) {
|
||||
if (!v || v === 'RMB' || v === 'rmb') return 'CNY'
|
||||
return v
|
||||
}
|
||||
|
||||
function displayFeeName(row) {
|
||||
const typeLabel = feeTypeLabel(row.feeType)
|
||||
const name = String(row.feeName || row.fee_name || '').trim()
|
||||
const isSurcharge = row.feeType === 'SURCHARGE' || row.feeType === '附加费'
|
||||
if (isSurcharge && name && name !== typeLabel && name !== 'SURCHARGE' && name !== '附加费') {
|
||||
return name
|
||||
}
|
||||
return name || typeLabel || row.feeType || '-'
|
||||
}
|
||||
|
||||
function sourceTagType(source) {
|
||||
if (source === 'PACKAGE_FIXED' || source === 'FIXED') return 'success'
|
||||
if (source === 'PACKAGE_DISCOUNT' || source === 'DISCOUNT') return 'warning'
|
||||
if (source === 'PRODUCT_DEFAULT') return 'info'
|
||||
return ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.billing-bill .payable {
|
||||
color: #f56c6c;
|
||||
font-weight: 600;
|
||||
}
|
||||
.billing-bill .sec-title {
|
||||
margin: 12px 0 8px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.billing-bill .sec-title:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
.billing-bill .fee-table {
|
||||
margin-top: 12px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user