diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcPriceSetDetail.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcPriceSetDetail.java index 359196a9..feecfbb1 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcPriceSetDetail.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcPriceSetDetail.java @@ -25,6 +25,8 @@ public class PrcPriceSetDetail implements Serializable private Long zdId; private Long wsdId; private String weightLabel; + /** 关联 bms_product_country.detail_id */ + private Long productCountryId; private BigDecimal fvValue; private BigDecimal fvRegistrationFee; private BigDecimal discountValue; @@ -52,6 +54,8 @@ public class PrcPriceSetDetail implements Serializable public void setWsdId(Long wsdId) { this.wsdId = wsdId; } public String getWeightLabel() { return weightLabel; } public void setWeightLabel(String weightLabel) { this.weightLabel = weightLabel; } + public Long getProductCountryId() { return productCountryId; } + public void setProductCountryId(Long productCountryId) { this.productCountryId = productCountryId; } public BigDecimal getFvValue() { return fvValue; } public void setFvValue(BigDecimal fvValue) { this.fvValue = fvValue; } public BigDecimal getFvRegistrationFee() { return fvRegistrationFee; } @@ -74,6 +78,7 @@ public class PrcPriceSetDetail implements Serializable .append("productCode", getProductCode()) .append("countryCode", getCountryCode()) .append("wsdId", getWsdId()) + .append("productCountryId", getProductCountryId()) .toString(); } } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcPriceSetServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcPriceSetServiceImpl.java index 78415dcd..927a1e47 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcPriceSetServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcPriceSetServiceImpl.java @@ -12,10 +12,12 @@ import org.springframework.transaction.annotation.Transactional; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.price.domain.BmsProductCountry; import com.ruoyi.price.domain.PrcCustomerPriceSet; import com.ruoyi.price.domain.PrcPriceSet; import com.ruoyi.price.domain.PrcPriceSetCheckItem; import com.ruoyi.price.domain.PrcPriceSetDetail; +import com.ruoyi.price.mapper.BmsProductCountryMapper; import com.ruoyi.price.mapper.PrcCustomerPriceSetMapper; import com.ruoyi.price.mapper.PrcPriceSetDetailMapper; import com.ruoyi.price.mapper.PrcPriceSetMapper; @@ -46,6 +48,9 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService @Autowired private PrcCustomerPriceSetMapper customerMapper; + @Autowired + private BmsProductCountryMapper productCountryMapper; + @Override public PrcPriceSet selectPrcPriceSetById(Long priceSetId) { @@ -621,6 +626,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService { throw new ServiceException("固定价明细必须填写挂号费"); } + fillProductCountryId(detail); } if (StringUtils.isNotEmpty(detail.getCountryCode())) { @@ -628,6 +634,69 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService } } + /** + * Resolve / verify product_country_id from bms_product_country when missing. + */ + private void fillProductCountryId(PrcPriceSetDetail detail) + { + if (detail.getProductCountryId() != null) + { + return; + } + if (StringUtils.isEmpty(detail.getProductCode()) || StringUtils.isEmpty(detail.getWeightLabel())) + { + return; + } + BmsProductCountry query = new BmsProductCountry(); + query.setProductCode(detail.getProductCode()); + List rows = productCountryMapper.selectBmsProductCountryList(query); + if (rows == null || rows.isEmpty()) + { + return; + } + for (BmsProductCountry row : rows) + { + if (!matchDetailCountry(detail, row)) + { + continue; + } + String label = formatWeightLabel(row.getWeightMin(), row.getWeightMax()); + if (detail.getWeightLabel().equals(label) + || (StringUtils.isNotEmpty(detail.getWeightLabel()) + && row.getWeightMin() != null && row.getWeightMax() != null + && detail.getWeightLabel().contains(stripTrailingZeros(row.getWeightMin())) + && detail.getWeightLabel().contains(stripTrailingZeros(row.getWeightMax())))) + { + detail.setProductCountryId(row.getDetailId()); + return; + } + } + } + + private static boolean matchDetailCountry(PrcPriceSetDetail detail, BmsProductCountry row) + { + if (StringUtils.isNotEmpty(detail.getCountryCode()) && StringUtils.isNotEmpty(row.getCountryCode())) + { + return detail.getCountryCode().equalsIgnoreCase(row.getCountryCode()); + } + return StringUtils.isNotEmpty(detail.getCountryName()) + && detail.getCountryName().equals(row.getCountryName()); + } + + private static String formatWeightLabel(BigDecimal min, BigDecimal max) + { + return stripTrailingZeros(min) + "\u2264W\u2264" + stripTrailingZeros(max); + } + + private static String stripTrailingZeros(BigDecimal v) + { + if (v == null) + { + return ""; + } + return v.stripTrailingZeros().toPlainString(); + } + private void validateCustomer(PrcCustomerPriceSet customer, PrcPriceSet set) { if (customer.getCustomerId() == null || customer.getCustomerId().longValue() <= 0) diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml index ed08074e..ea1b11db 100644 --- a/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml +++ b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcPriceSetDetailMapper.xml @@ -14,6 +14,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -24,8 +25,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select psd_id, price_set_id, product_code, product_name, country_code, country_name, - zd_id, wsd_id, weight_label, fv_value, fv_registration_fee, discount_value, - pr_id, created_at, updated_at + zd_id, wsd_id, weight_label, product_country_id, fv_value, fv_registration_fee, + discount_value, pr_id, created_at, updated_at from prc_price_set_detail @@ -68,6 +69,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" zd_id, wsd_id, weight_label, + product_country_id, fv_value, fv_registration_fee, discount_value, @@ -82,6 +84,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{zdId}, #{wsdId}, #{weightLabel}, + #{productCountryId}, #{fvValue}, #{fvRegistrationFee}, #{discountValue}, @@ -100,6 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" zd_id = #{zdId}, wsd_id = #{wsdId}, weight_label = #{weightLabel}, + product_country_id = #{productCountryId}, fv_value = #{fvValue}, fv_registration_fee = #{fvRegistrationFee}, discount_value = #{discountValue}, diff --git a/bms-back/sql/price/price_set.sql b/bms-back/sql/price/price_set.sql index eef14115..fa732e85 100644 --- a/bms-back/sql/price/price_set.sql +++ b/bms-back/sql/price/price_set.sql @@ -43,6 +43,7 @@ CREATE TABLE IF NOT EXISTS prc_price_set_detail ( zd_id BIGINT(20) DEFAULT NULL COMMENT '收费区划id', wsd_id BIGINT(20) DEFAULT NULL COMMENT '重量段明细id', weight_label VARCHAR(50) DEFAULT NULL COMMENT '重量段展示', + product_country_id BIGINT(20) DEFAULT NULL COMMENT '关联 bms_product_country.detail_id', fv_value DECIMAL(10,4) DEFAULT NULL COMMENT '运费单价 RMB/KG', fv_registration_fee DECIMAL(10,2) DEFAULT NULL COMMENT '挂号费 RMB/票', discount_value DECIMAL(5,2) DEFAULT NULL COMMENT '明细折扣百分数,DISCOUNT 可覆盖默认', @@ -52,6 +53,7 @@ CREATE TABLE IF NOT EXISTS prc_price_set_detail ( PRIMARY KEY (psd_id), INDEX idx_psd_set (price_set_id), INDEX idx_psd_product (price_set_id, product_code, country_code), + INDEX idx_psd_product_country (product_country_id), CONSTRAINT fk_psd_set FOREIGN KEY (price_set_id) REFERENCES prc_price_set (price_set_id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='价格套餐明细-固定价/折扣范围'; diff --git a/bms-back/sql/price/price_set_detail_product_country_alter.sql b/bms-back/sql/price/price_set_detail_product_country_alter.sql new file mode 100644 index 00000000..2e0477ac --- /dev/null +++ b/bms-back/sql/price/price_set_detail_product_country_alter.sql @@ -0,0 +1,6 @@ +-- 价格套餐明细关联 bms_product_country.detail_id +SET NAMES utf8mb4; + +ALTER TABLE prc_price_set_detail + ADD COLUMN product_country_id bigint DEFAULT NULL COMMENT 'bms_product_country.detail_id' AFTER weight_label, + ADD KEY idx_psd_product_country (product_country_id); diff --git a/bms-front/src/views/price/set/create.vue b/bms-front/src/views/price/set/create.vue index 824c5ce0..06b2f9bc 100644 --- a/bms-front/src/views/price/set/create.vue +++ b/bms-front/src/views/price/set/create.vue @@ -347,6 +347,7 @@ function weightOptionsOf(row) { map.set(value, { value, label: value, + detailId: item.detailId, freightPrice: item.freightPrice, registrationFee: item.registrationFee }) @@ -362,6 +363,7 @@ function emptyDetail() { countryName: undefined, _countryKey: undefined, weightLabel: undefined, + productCountryId: undefined, fvValue: undefined, fvRegistrationFee: undefined, discountValue: undefined @@ -391,6 +393,7 @@ function clearCascadeAfterProduct(row) { row.countryName = undefined row._countryKey = undefined row.weightLabel = undefined + row.productCountryId = undefined row.fvValue = undefined row.fvRegistrationFee = undefined } @@ -408,13 +411,18 @@ function onCountryChange(row) { row.countryCode = opt ? opt.code : undefined row.countryName = opt ? opt.name : undefined row.weightLabel = undefined + row.productCountryId = undefined row.fvValue = undefined row.fvRegistrationFee = undefined } function onWeightChange(row) { const opt = weightOptionsOf(row).find(w => w.value === row.weightLabel) - if (!opt) return + if (!opt) { + row.productCountryId = undefined + return + } + row.productCountryId = opt.detailId if (opt.freightPrice != null) row.fvValue = Number(opt.freightPrice) if (opt.registrationFee != null) row.fvRegistrationFee = Number(opt.registrationFee) } @@ -436,6 +444,7 @@ function hydrateDetailRow(d) { if (hit) { row.weightLabel = formatWeightLabel(hit.weightMin, hit.weightMax) row._countryKey = countryKeyOf(hit) + row.productCountryId = hit.detailId if (!row.countryCode) row.countryCode = hit.countryCode if (!row.countryName) row.countryName = hit.countryName } @@ -451,6 +460,7 @@ function buildPayload(submitFlag) { countryCode: d.countryCode || undefined, countryName: d.countryName || undefined, weightLabel: d.weightLabel || undefined, + productCountryId: d.productCountryId || undefined, fvValue: d.fvValue, fvRegistrationFee: d.fvRegistrationFee, discountValue: d.discountValue diff --git a/bms-front/src/views/price/set/detail.vue b/bms-front/src/views/price/set/detail.vue index 8b2e17ad..533982f6 100644 --- a/bms-front/src/views/price/set/detail.vue +++ b/bms-front/src/views/price/set/detail.vue @@ -76,9 +76,9 @@ - +