增加一个打单功能套餐
This commit is contained in:
+303
@@ -0,0 +1,303 @@
|
||||
package com.bms.web.controller.price;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
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.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.bms.common.annotation.Log;
|
||||
import com.bms.common.core.controller.BaseController;
|
||||
import com.bms.common.core.domain.AjaxResult;
|
||||
import com.bms.common.core.page.TableDataInfo;
|
||||
import com.bms.common.enums.BusinessType;
|
||||
import com.bms.common.exception.ServiceException;
|
||||
import com.bms.price.domain.PaySaveCommand;
|
||||
import com.bms.price.domain.PrcCustomerPriceSet;
|
||||
import com.bms.price.domain.PrcCustomerPriceSetBatch;
|
||||
import com.bms.price.domain.PrcPriceSet;
|
||||
import com.bms.price.service.IPayProductService;
|
||||
import com.bms.price.service.IPrcPriceSetService;
|
||||
|
||||
/**
|
||||
* 打单套餐:套餐壳 + 应收价卡(pay_*)。
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/price/label")
|
||||
public class LabelPackageController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private IPrcPriceSetService priceSetService;
|
||||
|
||||
@Autowired
|
||||
private IPayProductService payProductService;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(PrcPriceSet set)
|
||||
{
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_LABEL);
|
||||
startPage();
|
||||
List<PrcPriceSet> list = priceSetService.selectPrcPriceSetList(set);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:query')")
|
||||
@GetMapping("/{priceSetId:[0-9]+}")
|
||||
public AjaxResult getInfo(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
return success(priceSetService.selectPrcPriceSetById(priceSetId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:edit')")
|
||||
@Log(title = "打单套餐基本信息", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/basic")
|
||||
public AjaxResult editBasic(@RequestBody PrcPriceSet set)
|
||||
{
|
||||
priceSetService.assertSetCategory(set.getPriceSetId(), PrcPriceSet.CATEGORY_LABEL);
|
||||
set.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updateBasicInfo(set));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:audit')")
|
||||
@Log(title = "打单套餐停用", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{priceSetId}/disable")
|
||||
public AjaxResult disable(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
return toAjax(priceSetService.disable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:audit')")
|
||||
@Log(title = "打单套餐启用", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{priceSetId}/enable")
|
||||
public AjaxResult enable(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
return toAjax(priceSetService.enable(priceSetId, getUsername()));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:remove')")
|
||||
@Log(title = "打单套餐删除", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{priceSetIds}")
|
||||
public AjaxResult remove(@PathVariable Long[] priceSetIds)
|
||||
{
|
||||
if (priceSetIds != null)
|
||||
{
|
||||
for (Long id : priceSetIds)
|
||||
{
|
||||
priceSetService.assertSetCategory(id, PrcPriceSet.CATEGORY_LABEL);
|
||||
}
|
||||
}
|
||||
return toAjax(priceSetService.deletePrcPriceSetByIds(priceSetIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:import')")
|
||||
@PostMapping("/preview")
|
||||
public AjaxResult preview(@RequestParam("file") MultipartFile file,
|
||||
@RequestParam(value = "dictValue", required = false) String dictValue,
|
||||
@RequestParam(value = "progressId", required = false) String progressId,
|
||||
@RequestParam(value = "priceSetId", required = false) Long priceSetId) throws Exception
|
||||
{
|
||||
if (file == null || file.isEmpty())
|
||||
{
|
||||
throw new ServiceException("请上传价卡文件");
|
||||
}
|
||||
String name = file.getOriginalFilename();
|
||||
if (name == null || !name.toLowerCase(Locale.ROOT).endsWith(".xlsx"))
|
||||
{
|
||||
throw new ServiceException("请上传xlsx价卡");
|
||||
}
|
||||
if (priceSetId != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
}
|
||||
// 打单独立预览:已存在按本套餐判断,不与应付公共模板互挡
|
||||
return success(payProductService.previewLabel(file.getBytes(), name, dictValue, progressId, priceSetId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:import')")
|
||||
@GetMapping("/preview/progress")
|
||||
public AjaxResult parseProgress(@RequestParam("progressId") String progressId)
|
||||
{
|
||||
return success(payProductService.parseProgress(progressId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:import')")
|
||||
@Log(title = "打单套餐导入", businessType = BusinessType.IMPORT)
|
||||
@PostMapping("/importSave")
|
||||
public AjaxResult importSave(@RequestBody PaySaveCommand command)
|
||||
{
|
||||
if (command == null)
|
||||
{
|
||||
throw new ServiceException("保存参数不能为空");
|
||||
}
|
||||
String message = payProductService.saveLabel(command);
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("message", message);
|
||||
payload.put("priceSetId", command.getPriceSetId());
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:list')")
|
||||
@GetMapping("/{priceSetId}/versions")
|
||||
public AjaxResult versions(@PathVariable Long priceSetId)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
return success(payProductService.selectLabelVersions(priceSetId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:edit')")
|
||||
@Log(title = "打单套餐启动版本", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/{priceSetId}/versions/{versionNo}/activate")
|
||||
public AjaxResult activateVersion(@PathVariable Long priceSetId, @PathVariable Integer versionNo,
|
||||
@RequestBody Map<String, Object> body)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
Date effectiveTime = parseEffectiveTime(body == null ? null : body.get("effectiveTime"));
|
||||
String message = payProductService.activateLabelVersion(priceSetId, versionNo, effectiveTime);
|
||||
Map<String, Object> payload = new HashMap<String, Object>();
|
||||
payload.put("message", message);
|
||||
return success(payload);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:list')")
|
||||
@GetMapping("/{priceSetId}/products")
|
||||
public AjaxResult products(@PathVariable Long priceSetId,
|
||||
@RequestParam(value = "versionNo", required = false) Integer versionNo)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
if (versionNo != null)
|
||||
{
|
||||
return success(payProductService.selectLabelProductsByVersion(priceSetId, versionNo));
|
||||
}
|
||||
return success(payProductService.selectLabelProducts(priceSetId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:query')")
|
||||
@GetMapping("/product/{productId}")
|
||||
public AjaxResult productDetail(@PathVariable Long productId,
|
||||
@RequestParam(value = "termId", required = false) Long termId)
|
||||
{
|
||||
if (termId != null)
|
||||
{
|
||||
return success(payProductService.selectPayProductDetailByTerm(termId));
|
||||
}
|
||||
return success(payProductService.selectPayProductDetail(productId));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:remove')")
|
||||
@Log(title = "打单套餐移除产品", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{priceSetId}/products/{productIds}")
|
||||
public AjaxResult removeProducts(@PathVariable Long priceSetId, @PathVariable Long[] productIds)
|
||||
{
|
||||
priceSetService.assertSetCategory(priceSetId, PrcPriceSet.CATEGORY_LABEL);
|
||||
return toAjax(payProductService.removeLabelProducts(priceSetId, productIds));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:list')")
|
||||
@GetMapping("/customer/list")
|
||||
public TableDataInfo customerList(PrcCustomerPriceSet customer)
|
||||
{
|
||||
if (customer != null && customer.getPriceSetId() != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(customer.getPriceSetId(), PrcPriceSet.CATEGORY_LABEL);
|
||||
}
|
||||
startPage();
|
||||
List<PrcCustomerPriceSet> list = priceSetService.selectCustomerList(customer);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:edit')")
|
||||
@Log(title = "打单套餐客户绑定", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/customer")
|
||||
public AjaxResult addCustomer(@RequestBody PrcCustomerPriceSet customer)
|
||||
{
|
||||
if (customer == null || customer.getPriceSetId() == null)
|
||||
{
|
||||
throw new ServiceException("请选择打单套餐");
|
||||
}
|
||||
priceSetService.assertSetCategory(customer.getPriceSetId(), PrcPriceSet.CATEGORY_LABEL);
|
||||
customer.setCreateBy(getUsername());
|
||||
return toAjax(priceSetService.insertCustomer(customer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:edit')")
|
||||
@Log(title = "打单套餐客户批量绑定", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/customer/batch")
|
||||
public AjaxResult batchAddCustomer(@RequestBody PrcCustomerPriceSetBatch batch)
|
||||
{
|
||||
if (batch == null || batch.getPriceSetId() == null)
|
||||
{
|
||||
throw new ServiceException("请选择打单套餐");
|
||||
}
|
||||
priceSetService.assertSetCategory(batch.getPriceSetId(), PrcPriceSet.CATEGORY_LABEL);
|
||||
batch.setCreateBy(getUsername());
|
||||
batch.setUpdateBy(getUsername());
|
||||
return success(priceSetService.batchInsertCustomers(batch));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:edit')")
|
||||
@Log(title = "打单套餐客户绑定", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/customer")
|
||||
public AjaxResult editCustomer(@RequestBody PrcCustomerPriceSet customer)
|
||||
{
|
||||
if (customer == null)
|
||||
{
|
||||
throw new ServiceException("客户绑定参数不能为空");
|
||||
}
|
||||
if (customer.getPriceSetId() != null)
|
||||
{
|
||||
priceSetService.assertSetCategory(customer.getPriceSetId(), PrcPriceSet.CATEGORY_LABEL);
|
||||
}
|
||||
customer.setUpdateBy(getUsername());
|
||||
return toAjax(priceSetService.updateCustomer(customer));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('price:label:edit')")
|
||||
@Log(title = "打单套餐客户绑定", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/customer/{customerPricesetIds}")
|
||||
public AjaxResult removeCustomer(@PathVariable Long[] customerPricesetIds)
|
||||
{
|
||||
return toAjax(priceSetService.deleteCustomerByIds(customerPricesetIds));
|
||||
}
|
||||
|
||||
private Date parseEffectiveTime(Object raw)
|
||||
{
|
||||
if (raw == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (raw instanceof Date)
|
||||
{
|
||||
return (Date) raw;
|
||||
}
|
||||
String text = String.valueOf(raw).trim();
|
||||
if (text.isEmpty() || "null".equalsIgnoreCase(text))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
// 兼容 yyyy-MM-dd / yyyy-MM-dd HH:mm:ss
|
||||
if (text.length() >= 19)
|
||||
{
|
||||
return com.bms.common.utils.DateUtils.parseDate(text);
|
||||
}
|
||||
if (text.length() >= 10)
|
||||
{
|
||||
return com.bms.common.utils.DateUtils.parseDate(text.substring(0, 10));
|
||||
}
|
||||
return com.bms.common.utils.DateUtils.parseDate(text);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -135,7 +135,7 @@ public class PayProductController extends BaseController
|
||||
payProductService.unbindChannel(channelId, payType);
|
||||
return success();
|
||||
}
|
||||
payProductService.bindChannel(channelId, link.getProductId(), link.getPriceSetId(), payType);
|
||||
payProductService.bindChannel(channelId, link.getProductId(), payType);
|
||||
return success(payProductService.selectChannelPrice(channelId, payType));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,6 @@ public class ChannelProductMap
|
||||
|
||||
private Long productId;
|
||||
|
||||
/** 应收套餐 prc_price_set.price_set_id */
|
||||
private Long priceSetId;
|
||||
|
||||
/** AR 应收,AP 应付 */
|
||||
private String payType;
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.bms.price.domain;
|
||||
|
||||
import java.util.Date;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 打单套餐价卡版本(按 pay_product_term.version_no 聚合,不走价格套餐 prc_price_set_version)。
|
||||
*/
|
||||
@Data
|
||||
public class LabelPackageVersion
|
||||
{
|
||||
private Long priceSetId;
|
||||
|
||||
private Integer versionNo;
|
||||
|
||||
/** 展示用,如 V1 */
|
||||
private String versionLabel;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date effectiveTime;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date expireTime;
|
||||
|
||||
/** 与 pay_product_term.status 一致:0待生效 1生效 2已失效 */
|
||||
private String status;
|
||||
|
||||
private Integer productCount;
|
||||
|
||||
/** status=1 生效条数 */
|
||||
private Integer activeCount;
|
||||
|
||||
/** status=0 待生效条数 */
|
||||
private Integer pendingCount;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -12,6 +12,9 @@ public class PayExtraLine
|
||||
|
||||
private Long productId;
|
||||
|
||||
/** 价卡周期,对应 pay_product_term.term_id;与 productId 组成明细维度 */
|
||||
private Long termId;
|
||||
|
||||
/** 邮编 或 配置 */
|
||||
private String lineType;
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ public class PayProductTerm extends BaseEntity
|
||||
|
||||
private Long productId;
|
||||
|
||||
/** 打单套餐ID;应付公共模板为空 */
|
||||
private Long priceSetId;
|
||||
|
||||
private Integer versionNo;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@@ -30,7 +33,7 @@ public class PayProductTerm extends BaseEntity
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private Date effectiveEnd;
|
||||
|
||||
/** 0 生效,1 失效 */
|
||||
/** 0待生效 1生效 2已失效 */
|
||||
private String status;
|
||||
|
||||
private String productName;
|
||||
|
||||
@@ -13,5 +13,17 @@ public class PaySaveCommand
|
||||
/** 为 true 时,同文件同表同名的旧产品先删后插 */
|
||||
private boolean overwrite;
|
||||
|
||||
/** 打单套餐ID;有值时走 LABEL 导入(稳定 product_id + term.price_set_id) */
|
||||
private Long priceSetId;
|
||||
|
||||
/** 打单套餐名称;priceSetId 为空时新建套餐壳 */
|
||||
private String priceSetName;
|
||||
|
||||
/** 打单套餐备注 */
|
||||
private String priceSetNote;
|
||||
|
||||
/** 编辑待生效版本时传入,覆盖该 version_no,不新建版本号 */
|
||||
private Integer versionNo;
|
||||
|
||||
private List<PayProduct> products = new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@ public class PaySurcharge
|
||||
|
||||
private Long productId;
|
||||
|
||||
/** 所属价卡版本,跟产品版本一起变 */
|
||||
/** 价卡周期,对应 pay_product_term.term_id;与 productId 组成明细维度 */
|
||||
private Long termId;
|
||||
|
||||
/** 所属价卡版本,跟产品版本一起变(展示兼容) */
|
||||
private Integer versionNo;
|
||||
|
||||
private String sectionName;
|
||||
|
||||
@@ -13,7 +13,10 @@ public class PayWeightBand
|
||||
|
||||
private Long productId;
|
||||
|
||||
/** 所属价卡版本,跟产品版本一起变 */
|
||||
/** 价卡周期,对应 pay_product_term.term_id;与 productId 组成明细维度 */
|
||||
private Long termId;
|
||||
|
||||
/** 所属价卡版本,跟产品版本一起变(展示兼容) */
|
||||
private Integer versionNo;
|
||||
|
||||
/** 报价区块,例如派送费、偏远附加费 */
|
||||
|
||||
@@ -19,6 +19,8 @@ public class PrcPriceSet extends BaseEntity
|
||||
public static final String CATEGORY_PACKAGE = "PACKAGE";
|
||||
/** Boss exclusive quote. */
|
||||
public static final String CATEGORY_EXCLUSIVE = "EXCLUSIVE";
|
||||
/** Label / 打单套餐(应收价卡套餐). */
|
||||
public static final String CATEGORY_LABEL = "LABEL";
|
||||
|
||||
private Long priceSetId;
|
||||
private String priceSetCode;
|
||||
@@ -26,7 +28,7 @@ public class PrcPriceSet extends BaseEntity
|
||||
private String priceSetNote;
|
||||
/** FIXED / DISCOUNT */
|
||||
private String setType;
|
||||
/** PACKAGE=ordinary set / EXCLUSIVE=boss exclusive quote */
|
||||
/** PACKAGE=ordinary set / EXCLUSIVE=boss exclusive quote / LABEL=打单套餐 */
|
||||
private String setCategory;
|
||||
private BigDecimal defaultDiscount;
|
||||
private String defaultType;
|
||||
|
||||
@@ -38,16 +38,33 @@ public interface PayProductMapper
|
||||
|
||||
List<PayWeightBand> selectWeightBands(@Param("productIds") List<Long> productIds);
|
||||
|
||||
List<PayWeightBand> selectWeightBandsByTerm(@Param("termIds") List<Long> termIds);
|
||||
|
||||
List<PaySurcharge> selectSurcharges(@Param("productIds") List<Long> productIds);
|
||||
|
||||
List<PaySurcharge> selectSurchargesByTerm(@Param("termIds") List<Long> termIds);
|
||||
|
||||
List<PayExtraLine> selectExtraLines(@Param("productIds") List<Long> productIds);
|
||||
|
||||
List<PayExtraLine> selectExtraLinesByTerm(@Param("termIds") List<Long> termIds);
|
||||
|
||||
int deleteWeightBands(@Param("productIds") List<Long> productIds);
|
||||
|
||||
int deleteSurcharges(@Param("productIds") List<Long> productIds);
|
||||
|
||||
int deleteExtraLines(@Param("productIds") List<Long> productIds);
|
||||
|
||||
int deleteWeightBandsByTerm(@Param("termIds") List<Long> termIds);
|
||||
|
||||
int deleteSurchargesByTerm(@Param("termIds") List<Long> termIds);
|
||||
|
||||
int deleteExtraLinesByTerm(@Param("termIds") List<Long> termIds);
|
||||
|
||||
Long selectTemplateIdByType(@Param("dictValue") String dictValue, @Param("productType") String productType);
|
||||
|
||||
/** 打单专用:命中仅属于打单套餐的 AR 产品,不命中应付公共模板 */
|
||||
Long selectLabelProductIdByDict(@Param("dictValue") String dictValue);
|
||||
|
||||
int deletePayProducts(@Param("productIds") List<Long> productIds);
|
||||
|
||||
List<Long> selectFamilyIds(@Param("rootId") Long rootId);
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.bms.price.mapper;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.bms.price.domain.LabelPackageVersion;
|
||||
import com.bms.price.domain.PayProductTerm;
|
||||
|
||||
/**
|
||||
@@ -16,6 +17,24 @@ public interface PayProductTermMapper
|
||||
|
||||
PayProductTerm selectByProductId(Long productId);
|
||||
|
||||
List<PayProductTerm> selectByPriceSetId(@Param("priceSetId") Long priceSetId);
|
||||
|
||||
List<PayProductTerm> selectByPriceSetIdAndVersion(@Param("priceSetId") Long priceSetId,
|
||||
@Param("versionNo") Integer versionNo);
|
||||
|
||||
/** 打单套餐:按 version_no 聚合版本(含已失效) */
|
||||
List<LabelPackageVersion> selectLabelVersionGroups(@Param("priceSetId") Long priceSetId);
|
||||
|
||||
/** 打单套餐:批量改某一版的生效起止与状态 */
|
||||
int updateLabelVersionPeriod(@Param("priceSetId") Long priceSetId, @Param("versionNo") Integer versionNo,
|
||||
@Param("effectiveStart") Date effectiveStart, @Param("effectiveEnd") Date effectiveEnd,
|
||||
@Param("status") String status, @Param("updateBy") String updateBy);
|
||||
|
||||
Integer selectMaxVersionByProduct(@Param("productId") Long productId, @Param("priceSetId") Long priceSetId);
|
||||
|
||||
/** 打单套餐下最大 version_no */
|
||||
Integer selectMaxVersionByPriceSet(@Param("priceSetId") Long priceSetId);
|
||||
|
||||
int insertTerm(PayProductTerm term);
|
||||
|
||||
int updatePeriod(PayProductTerm term);
|
||||
@@ -25,7 +44,29 @@ public interface PayProductTermMapper
|
||||
/** 新版本生效时,把同一产品仍生效的旧版本关掉,结束日收到新版本开始的前一天 */
|
||||
int closeOpenTerms(@Param("dictValue") String dictValue, @Param("endDate") Date endDate, @Param("updateBy") String updateBy);
|
||||
|
||||
/** 打单套餐:按套餐+产品关闭仍生效的旧周期 */
|
||||
int closeOpenTermsBySetProduct(@Param("priceSetId") Long priceSetId, @Param("productId") Long productId,
|
||||
@Param("endDate") Date endDate, @Param("updateBy") String updateBy);
|
||||
|
||||
/** 打单:只关掉某产品本套餐待生效 term */
|
||||
int closePendingBySetProduct(@Param("priceSetId") Long priceSetId, @Param("productId") Long productId,
|
||||
@Param("endDate") Date endDate, @Param("updateBy") String updateBy);
|
||||
|
||||
/** 打单:启动某版本时,关掉本套餐其它版本的生效 term */
|
||||
int closeEffectExceptVersion(@Param("priceSetId") Long priceSetId, @Param("versionNo") Integer versionNo,
|
||||
@Param("endDate") Date endDate, @Param("updateBy") String updateBy);
|
||||
|
||||
/** 打单:预约未来生效时,只写旧版失效日,仍保持生效;并恢复被提前关掉但未到期的旧版 */
|
||||
int scheduleEndExceptVersion(@Param("priceSetId") Long priceSetId, @Param("versionNo") Integer versionNo,
|
||||
@Param("endDate") Date endDate, @Param("today") Date today, @Param("updateBy") String updateBy);
|
||||
|
||||
/** 打单:恢复「失效日未到却被标成已失效」的 term */
|
||||
int restorePrematureClosed(@Param("priceSetId") Long priceSetId, @Param("today") Date today,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
int deleteByProductIds(@Param("productIds") List<Long> productIds);
|
||||
|
||||
int deleteByTermIds(@Param("termIds") List<Long> termIds);
|
||||
|
||||
int updateProductEffectiveDate(@Param("productId") Long productId, @Param("effectiveDate") Date effectiveDate);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.bms.price.service;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
import com.bms.price.domain.LabelPackageVersion;
|
||||
import com.bms.price.domain.PayParseProgress;
|
||||
import com.bms.price.domain.PayPreview;
|
||||
import com.bms.price.domain.PayPriceCompare;
|
||||
@@ -54,7 +55,34 @@ public interface IPayProductService
|
||||
PayProduct selectChannelPrice(String channelId, String payType);
|
||||
|
||||
/** 只绑定产品编号,不产生新版本;同时落 channel_code。payType 为空时按应付 AP */
|
||||
void bindChannel(String channelId, Long productId, Long priceSetId, String payType);
|
||||
void bindChannel(String channelId, Long productId, String payType);
|
||||
|
||||
/**
|
||||
* 打单套餐预览:解析复用应付解析器,但「已存在」只按本套餐 price_set_id 判断,
|
||||
* 不与应付公共模板互相挡导入。
|
||||
*/
|
||||
PayPreview previewLabel(byte[] bytes, String filename, String dictValue, String progressId, Long priceSetId);
|
||||
|
||||
/** 打单套餐导入:稳定 product_id,明细挂 term_id,term 写 price_set_id;跳过仅限本套餐已有生效版 */
|
||||
String saveLabel(PaySaveCommand command);
|
||||
|
||||
/** 打单套餐价卡版本列表(按 term.version_no 聚合) */
|
||||
List<LabelPackageVersion> selectLabelVersions(Long priceSetId);
|
||||
|
||||
/** 启动/修改打单套餐某一版生效时间,并视情况启用套餐 */
|
||||
String activateLabelVersion(Long priceSetId, Integer versionNo, Date effectiveTime);
|
||||
|
||||
/** 打单套餐内当前生效/待生效产品列表 */
|
||||
List<PayProduct> selectLabelProducts(Long priceSetId);
|
||||
|
||||
/** 打单套餐某一版本的产品列表 */
|
||||
List<PayProduct> selectLabelProductsByVersion(Long priceSetId, Integer versionNo);
|
||||
|
||||
/** 按 term 加载明细 */
|
||||
PayProduct selectPayProductDetailByTerm(Long termId);
|
||||
|
||||
/** 从打单套餐移除产品(失效/清理对应 term 明细) */
|
||||
int removeLabelProducts(Long priceSetId, Long[] productIds);
|
||||
|
||||
/** 取消渠道上指定收付类型的产品。payType 为空时按应付 AP */
|
||||
void unbindChannel(String channelId, String payType);
|
||||
|
||||
+580
-32
@@ -25,6 +25,7 @@ import com.bms.common.utils.SecurityUtils;
|
||||
import com.bms.common.utils.file.OssStorage;
|
||||
import com.bms.common.utils.uuid.IdUtils;
|
||||
import com.bms.price.domain.ChannelProductMap;
|
||||
import com.bms.price.domain.LabelPackageVersion;
|
||||
import com.bms.price.domain.PayExtraLine;
|
||||
import com.bms.price.domain.PayParseProgress;
|
||||
import com.bms.price.domain.PayPreview;
|
||||
@@ -35,11 +36,13 @@ import com.bms.price.domain.PayProductTerm;
|
||||
import com.bms.price.domain.PaySaveCommand;
|
||||
import com.bms.price.domain.PaySurcharge;
|
||||
import com.bms.price.domain.PayWeightBand;
|
||||
import com.bms.price.domain.PrcPriceSet;
|
||||
import com.bms.masterdata.domain.ServiceChannel;
|
||||
import com.bms.masterdata.mapper.ServiceChannelMapper;
|
||||
import com.bms.price.mapper.ChannelProductMapMapper;
|
||||
import com.bms.price.mapper.PayProductMapper;
|
||||
import com.bms.price.mapper.PayProductTermMapper;
|
||||
import com.bms.price.mapper.PrcPriceSetMapper;
|
||||
import com.bms.price.pay.PayParseProgressListener;
|
||||
import com.bms.price.pay.PayWorkbookParser;
|
||||
import com.bms.price.service.IPayProductService;
|
||||
@@ -59,6 +62,13 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
|
||||
private static final String PAY_TYPE_AR = "AR";
|
||||
|
||||
/** pay_product_term.status:0待生效 1生效 2已失效 */
|
||||
private static final String TERM_PENDING = "0";
|
||||
|
||||
private static final String TERM_EFFECT = "1";
|
||||
|
||||
private static final String TERM_EXPIRED = "2";
|
||||
|
||||
@Autowired
|
||||
private PayProductMapper payProductMapper;
|
||||
|
||||
@@ -71,6 +81,9 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
@Autowired
|
||||
private PayProductTermMapper payProductTermMapper;
|
||||
|
||||
@Autowired
|
||||
private PrcPriceSetMapper priceSetMapper;
|
||||
|
||||
@Autowired
|
||||
private ISysDictTypeService dictTypeService;
|
||||
|
||||
@@ -97,6 +110,21 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
|
||||
@Override
|
||||
public PayPreview preview(byte[] bytes, String filename, String dictValue, String progressId)
|
||||
{
|
||||
return doPreview(bytes, filename, dictValue, progressId, false, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayPreview previewLabel(byte[] bytes, String filename, String dictValue, String progressId, Long priceSetId)
|
||||
{
|
||||
return doPreview(bytes, filename, dictValue, progressId, true, priceSetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param labelMode true=打单套餐:已存在仅看本套餐;false=应付:看公共模板
|
||||
*/
|
||||
private PayPreview doPreview(byte[] bytes, String filename, String dictValue, String progressId,
|
||||
boolean labelMode, Long priceSetId)
|
||||
{
|
||||
String progressKey = progressKey(progressId);
|
||||
PayParseProgressListener listener = progressKey == null ? null : (percent, message) ->
|
||||
@@ -115,9 +143,24 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
for (PayProduct product : preview.getProducts())
|
||||
{
|
||||
product.setFilePath(stored);
|
||||
Long existsId = isBlank(product.getDictValue()) ? null : payProductMapper.selectTemplateId(product.getDictValue());
|
||||
product.setDuplicated(existsId != null);
|
||||
product.setExistsId(existsId);
|
||||
if (labelMode)
|
||||
{
|
||||
product.setProductType(PAY_TYPE_AR);
|
||||
// 只认「打单侧」产品,绝不把应付公共模板标成已存在
|
||||
Long existsId = isBlank(product.getDictValue()) ? null
|
||||
: payProductMapper.selectLabelProductIdByDict(product.getDictValue());
|
||||
product.setExistsId(existsId);
|
||||
// 仅待生效占用标「已存在」;已生效可继续建新版本
|
||||
boolean pendingInSet = priceSetId != null && existsId != null
|
||||
&& hasLabelTermStatus(priceSetId, existsId, TERM_PENDING);
|
||||
product.setDuplicated(pendingInSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
Long existsId = isBlank(product.getDictValue()) ? null : payProductMapper.selectTemplateId(product.getDictValue());
|
||||
product.setDuplicated(existsId != null);
|
||||
product.setExistsId(existsId);
|
||||
}
|
||||
}
|
||||
writeProgress(progressKey, 100, "解析完成", PayParseProgress.SUCCESS);
|
||||
return preview;
|
||||
@@ -220,7 +263,6 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
product.setFilePath(resolveSource(product));
|
||||
prepareCounts(product);
|
||||
fitColumns(product);
|
||||
product.setProductId(null);
|
||||
product.setChannelId(null);
|
||||
product.setCreateBy(operator);
|
||||
product.setCreateTime(new Date());
|
||||
@@ -231,13 +273,14 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
}
|
||||
else
|
||||
{
|
||||
product.setProductId(null);
|
||||
product.setOriginId(null);
|
||||
product.setVersionNo(1);
|
||||
payProductMapper.insertPayProduct(product);
|
||||
openTerm(product, false, null);
|
||||
insertBands(product);
|
||||
insertSurcharges(product);
|
||||
insertExtras(product);
|
||||
openTerm(product, false);
|
||||
}
|
||||
saved++;
|
||||
}
|
||||
@@ -426,11 +469,29 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
|
||||
private void replaceChildren(Long productId, PayProduct product)
|
||||
{
|
||||
List<Long> ids = Collections.singletonList(productId);
|
||||
payProductMapper.deleteWeightBands(ids);
|
||||
payProductMapper.deleteSurcharges(ids);
|
||||
payProductMapper.deleteExtraLines(ids);
|
||||
product.setProductId(productId);
|
||||
if (product.getTermId() == null)
|
||||
{
|
||||
PayProductTerm term = payProductTermMapper.selectByProductId(productId);
|
||||
if (term != null)
|
||||
{
|
||||
product.setTermId(term.getTermId());
|
||||
}
|
||||
}
|
||||
if (product.getTermId() != null)
|
||||
{
|
||||
List<Long> termIds = Collections.singletonList(product.getTermId());
|
||||
payProductMapper.deleteWeightBandsByTerm(termIds);
|
||||
payProductMapper.deleteSurchargesByTerm(termIds);
|
||||
payProductMapper.deleteExtraLinesByTerm(termIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Long> ids = Collections.singletonList(productId);
|
||||
payProductMapper.deleteWeightBands(ids);
|
||||
payProductMapper.deleteSurcharges(ids);
|
||||
payProductMapper.deleteExtraLines(ids);
|
||||
}
|
||||
insertBands(product);
|
||||
insertSurcharges(product);
|
||||
insertExtras(product);
|
||||
@@ -511,7 +572,7 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
{
|
||||
term.setDictValue(termKey(product));
|
||||
term.setVersionNo(product.getVersionNo() == null ? 1 : product.getVersionNo());
|
||||
term.setStatus("0");
|
||||
term.setStatus(TERM_EFFECT);
|
||||
term.setCreateBy(operator);
|
||||
payProductTermMapper.insertTerm(term);
|
||||
}
|
||||
@@ -535,9 +596,10 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
@Override
|
||||
public int changeTermStatus(PayProductTerm term)
|
||||
{
|
||||
if (term == null || (!"0".equals(term.getStatus()) && !"1".equals(term.getStatus())))
|
||||
if (term == null || (!TERM_PENDING.equals(term.getStatus()) && !TERM_EFFECT.equals(term.getStatus())
|
||||
&& !TERM_EXPIRED.equals(term.getStatus())))
|
||||
{
|
||||
throw new ServiceException("请选择生效或失效");
|
||||
throw new ServiceException("状态只能是待生效、生效或已失效");
|
||||
}
|
||||
if (term.getTermId() == null && term.getProductId() != null)
|
||||
{
|
||||
@@ -556,27 +618,48 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
}
|
||||
|
||||
/** 给刚保存的这一版记一条生效记录。新版本从生效日开始,旧版本收到生效日前一天。 */
|
||||
private void openTerm(PayProduct product, boolean replacePrevious)
|
||||
private PayProductTerm openTerm(PayProduct product, boolean replacePrevious, Long priceSetId)
|
||||
{
|
||||
String key = termKey(product);
|
||||
if (product.getEffectiveDate() == null)
|
||||
boolean labelMode = priceSetId != null;
|
||||
// 应付:无生效日则默认今天;打单:创建不写默认生效日,由详情「启动」设置
|
||||
if (!labelMode && product.getEffectiveDate() == null)
|
||||
{
|
||||
product.setEffectiveDate(today());
|
||||
}
|
||||
if (replacePrevious)
|
||||
{
|
||||
java.time.LocalDate start = toLocalDate(product.getEffectiveDate());
|
||||
payProductTermMapper.closeOpenTerms(key, toDate(start.minusDays(1)), product.getCreateBy());
|
||||
Date endDate;
|
||||
if (product.getEffectiveDate() != null)
|
||||
{
|
||||
endDate = toDate(toLocalDate(product.getEffectiveDate()).minusDays(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
endDate = toDate(toLocalDate(today()).minusDays(1));
|
||||
}
|
||||
if (labelMode)
|
||||
{
|
||||
payProductTermMapper.closeOpenTermsBySetProduct(priceSetId, product.getProductId(), endDate, product.getCreateBy());
|
||||
}
|
||||
else
|
||||
{
|
||||
payProductTermMapper.closeOpenTerms(key, endDate, product.getCreateBy());
|
||||
}
|
||||
}
|
||||
PayProductTerm term = new PayProductTerm();
|
||||
term.setDictValue(key);
|
||||
term.setProductId(product.getProductId());
|
||||
term.setPriceSetId(priceSetId);
|
||||
term.setVersionNo(product.getVersionNo() == null ? 1 : product.getVersionNo());
|
||||
term.setEffectiveStart(product.getEffectiveDate());
|
||||
term.setEffectiveStart(labelMode ? null : product.getEffectiveDate());
|
||||
term.setFilePath(sourcePath(product.getFilePath()));
|
||||
term.setStatus("0");
|
||||
// 打单套餐新建为待生效,详情启动后再变生效;应付公共模板直接生效
|
||||
term.setStatus(labelMode ? TERM_PENDING : TERM_EFFECT);
|
||||
term.setCreateBy(product.getCreateBy());
|
||||
payProductTermMapper.insertTerm(term);
|
||||
product.setTermId(term.getTermId());
|
||||
return term;
|
||||
}
|
||||
|
||||
private String termKey(PayProduct product)
|
||||
@@ -730,6 +813,20 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
{
|
||||
return null;
|
||||
}
|
||||
PayProductTerm term = payProductTermMapper.selectByProductId(productId);
|
||||
if (term != null)
|
||||
{
|
||||
product.setTermId(term.getTermId());
|
||||
product.setTermStatus(term.getStatus());
|
||||
product.setTermStart(term.getEffectiveStart());
|
||||
product.setTermEnd(term.getEffectiveEnd());
|
||||
product.setVersionNo(term.getVersionNo() == null ? product.getVersionNo() : term.getVersionNo());
|
||||
List<Long> termIds = Collections.singletonList(term.getTermId());
|
||||
product.setWeightBands(payProductMapper.selectWeightBandsByTerm(termIds));
|
||||
product.setSurcharges(payProductMapper.selectSurchargesByTerm(termIds));
|
||||
product.setExtraLines(payProductMapper.selectExtraLinesByTerm(termIds));
|
||||
return product;
|
||||
}
|
||||
List<Long> ids = Collections.singletonList(productId);
|
||||
product.setWeightBands(payProductMapper.selectWeightBands(ids));
|
||||
product.setSurcharges(payProductMapper.selectSurcharges(ids));
|
||||
@@ -737,6 +834,450 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
return product;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayProduct selectPayProductDetailByTerm(Long termId)
|
||||
{
|
||||
if (termId == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
PayProductTerm term = payProductTermMapper.selectById(termId);
|
||||
if (term == null || term.getProductId() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
PayProduct product = payProductMapper.selectPayProductById(term.getProductId());
|
||||
if (product == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
product.setTermId(term.getTermId());
|
||||
product.setTermStatus(term.getStatus());
|
||||
product.setTermStart(term.getEffectiveStart());
|
||||
product.setTermEnd(term.getEffectiveEnd());
|
||||
product.setVersionNo(term.getVersionNo() == null ? product.getVersionNo() : term.getVersionNo());
|
||||
if (!isBlank(term.getFilePath()))
|
||||
{
|
||||
product.setFilePath(term.getFilePath());
|
||||
}
|
||||
List<Long> termIds = Collections.singletonList(termId);
|
||||
product.setWeightBands(payProductMapper.selectWeightBandsByTerm(termIds));
|
||||
product.setSurcharges(payProductMapper.selectSurchargesByTerm(termIds));
|
||||
product.setExtraLines(payProductMapper.selectExtraLinesByTerm(termIds));
|
||||
return product;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String saveLabel(PaySaveCommand command)
|
||||
{
|
||||
if (command == null || command.getProducts() == null || command.getProducts().isEmpty())
|
||||
{
|
||||
throw new ServiceException("请先勾选要保存的产品");
|
||||
}
|
||||
Long priceSetId = ensureLabelPriceSet(command);
|
||||
String operator = SecurityUtils.getUsername();
|
||||
Date keepStart = null;
|
||||
String keepStatus = TERM_PENDING;
|
||||
int nextVersionNo;
|
||||
boolean editPendingVersion = command.getVersionNo() != null;
|
||||
if (editPendingVersion)
|
||||
{
|
||||
// 编辑待生效版:清掉该 version 后按原号重写,保留原生效日
|
||||
LabelVersionKeep keep = clearPendingLabelVersion(priceSetId, command.getVersionNo(), operator);
|
||||
keepStart = keep.effectiveStart;
|
||||
keepStatus = keep.status == null ? TERM_PENDING : keep.status;
|
||||
nextVersionNo = command.getVersionNo();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 整批统一套餐级 version_no:新建套餐从 1,新建版本 = max+1
|
||||
Integer maxSetVer = payProductTermMapper.selectMaxVersionByPriceSet(priceSetId);
|
||||
nextVersionNo = (maxSetVer == null ? 0 : maxSetVer) + 1;
|
||||
}
|
||||
int saved = 0;
|
||||
int replaced = 0;
|
||||
int skipped = 0;
|
||||
for (PayProduct product : command.getProducts())
|
||||
{
|
||||
if (product == null || isBlank(product.getProductName()) || isBlank(product.getSheetName()) || isBlank(product.getFileMd5()))
|
||||
{
|
||||
throw new ServiceException("产品名称、工作表和文件摘要不能为空");
|
||||
}
|
||||
product.setProductType(PAY_TYPE_AR);
|
||||
String dict = blankTo(product.getDictValue(), product.getProductName());
|
||||
product.setDictValue(dict);
|
||||
// 独立产品族:只复用打单侧 AR,绝不复用/改写应付公共模板
|
||||
Long existsId = isBlank(dict) ? null : payProductMapper.selectLabelProductIdByDict(dict);
|
||||
// 编辑待生效版时强制覆盖;新建版本仅「待生效」占用时跳过
|
||||
boolean hasPending = !editPendingVersion && existsId != null
|
||||
&& hasLabelTermStatus(priceSetId, existsId, TERM_PENDING);
|
||||
if (hasPending && !command.isOverwrite())
|
||||
{
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
product.setFilePath(resolveSource(product));
|
||||
prepareCounts(product);
|
||||
fitColumns(product);
|
||||
product.setChannelId(null);
|
||||
product.setCreateBy(operator);
|
||||
product.setUpdateBy(operator);
|
||||
product.setCreateTime(new Date());
|
||||
product.setVersionNo(nextVersionNo);
|
||||
// 打单不写默认生效日,由详情设置;编辑时下面统一回写 keepStart
|
||||
product.setEffectiveDate(null);
|
||||
if (existsId != null)
|
||||
{
|
||||
appendLabelVersion(existsId, product, operator, priceSetId, nextVersionNo,
|
||||
editPendingVersion || command.isOverwrite());
|
||||
replaced++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 新建打单专用产品行,与应付同名字典产品并存互不影响
|
||||
product.setProductId(null);
|
||||
product.setOriginId(null);
|
||||
payProductMapper.insertPayProduct(product);
|
||||
openTerm(product, false, priceSetId);
|
||||
insertBands(product);
|
||||
insertSurcharges(product);
|
||||
insertExtras(product);
|
||||
}
|
||||
saved++;
|
||||
}
|
||||
if (editPendingVersion && keepStart != null)
|
||||
{
|
||||
payProductTermMapper.updateLabelVersionPeriod(priceSetId, nextVersionNo, keepStart, null, keepStatus, operator);
|
||||
}
|
||||
return editPendingVersion
|
||||
? ("套餐" + priceSetId + "版本V" + nextVersionNo + "已更新" + saved + "个产品")
|
||||
: ("套餐" + priceSetId + "已保存" + saved + "个产品,新版本" + replaced + "个,跳过" + skipped + "个");
|
||||
}
|
||||
|
||||
private static final class LabelVersionKeep
|
||||
{
|
||||
private Date effectiveStart;
|
||||
private String status;
|
||||
}
|
||||
|
||||
/** 仅允许清待生效版;返回原生效日便于编辑后回写 */
|
||||
private LabelVersionKeep clearPendingLabelVersion(Long priceSetId, Integer versionNo, String operator)
|
||||
{
|
||||
if (priceSetId == null || versionNo == null)
|
||||
{
|
||||
throw new ServiceException("请指定要编辑的版本");
|
||||
}
|
||||
List<PayProductTerm> terms = payProductTermMapper.selectByPriceSetIdAndVersion(priceSetId, versionNo);
|
||||
if (terms == null || terms.isEmpty())
|
||||
{
|
||||
throw new ServiceException("该版本不存在或没有产品");
|
||||
}
|
||||
LabelVersionKeep keep = new LabelVersionKeep();
|
||||
List<Long> termIds = new ArrayList<>();
|
||||
for (PayProductTerm term : terms)
|
||||
{
|
||||
if (!TERM_PENDING.equals(term.getStatus()))
|
||||
{
|
||||
// 兼容:生效日未到但 status 误为 1,仍允许编辑
|
||||
boolean futureStart = term.getEffectiveStart() != null
|
||||
&& toLocalDate(term.getEffectiveStart()).isAfter(toLocalDate(today()));
|
||||
if (!futureStart)
|
||||
{
|
||||
throw new ServiceException("只能编辑待生效版本");
|
||||
}
|
||||
}
|
||||
if (keep.effectiveStart == null && term.getEffectiveStart() != null)
|
||||
{
|
||||
keep.effectiveStart = term.getEffectiveStart();
|
||||
}
|
||||
if (keep.status == null)
|
||||
{
|
||||
keep.status = TERM_PENDING;
|
||||
}
|
||||
termIds.add(term.getTermId());
|
||||
}
|
||||
payProductMapper.deleteWeightBandsByTerm(termIds);
|
||||
payProductMapper.deleteSurchargesByTerm(termIds);
|
||||
payProductMapper.deleteExtraLinesByTerm(termIds);
|
||||
payProductTermMapper.deleteByTermIds(termIds);
|
||||
return keep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayProduct> selectLabelProducts(Long priceSetId)
|
||||
{
|
||||
return toLabelProducts(payProductTermMapper.selectByPriceSetId(priceSetId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PayProduct> selectLabelProductsByVersion(Long priceSetId, Integer versionNo)
|
||||
{
|
||||
if (priceSetId == null || versionNo == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return toLabelProducts(payProductTermMapper.selectByPriceSetIdAndVersion(priceSetId, versionNo));
|
||||
}
|
||||
|
||||
private List<PayProduct> toLabelProducts(List<PayProductTerm> terms)
|
||||
{
|
||||
if (terms == null || terms.isEmpty())
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<PayProduct> list = new ArrayList<>();
|
||||
for (PayProductTerm term : terms)
|
||||
{
|
||||
PayProduct product = payProductMapper.selectPayProductById(term.getProductId());
|
||||
if (product == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
product.setTermId(term.getTermId());
|
||||
product.setTermStatus(term.getStatus());
|
||||
product.setTermStart(term.getEffectiveStart());
|
||||
product.setTermEnd(term.getEffectiveEnd());
|
||||
product.setVersionNo(term.getVersionNo() == null ? product.getVersionNo() : term.getVersionNo());
|
||||
product.setSourceFile(blankTo(term.getSourceFile(), product.getSourceFile()));
|
||||
if (!isBlank(term.getFilePath()))
|
||||
{
|
||||
product.setFilePath(term.getFilePath());
|
||||
}
|
||||
product.setWeightCount(term.getWeightCount() == null ? product.getWeightCount() : term.getWeightCount());
|
||||
product.setSurchargeCount(term.getSurchargeCount() == null ? product.getSurchargeCount() : term.getSurchargeCount());
|
||||
list.add(product);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int removeLabelProducts(Long priceSetId, Long[] productIds)
|
||||
{
|
||||
if (priceSetId == null || productIds == null || productIds.length == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int n = 0;
|
||||
List<PayProductTerm> allTerms = payProductTermMapper.selectByPriceSetId(priceSetId);
|
||||
if (allTerms == null || allTerms.isEmpty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
Set<Long> removeIds = new LinkedHashSet<>(Arrays.asList(productIds));
|
||||
List<Long> termIds = new ArrayList<>();
|
||||
for (PayProductTerm term : allTerms)
|
||||
{
|
||||
if (term.getProductId() != null && removeIds.contains(term.getProductId()))
|
||||
{
|
||||
termIds.add(term.getTermId());
|
||||
}
|
||||
}
|
||||
if (termIds.isEmpty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
payProductMapper.deleteWeightBandsByTerm(termIds);
|
||||
payProductMapper.deleteSurchargesByTerm(termIds);
|
||||
payProductMapper.deleteExtraLinesByTerm(termIds);
|
||||
payProductTermMapper.deleteByTermIds(termIds);
|
||||
return termIds.size();
|
||||
}
|
||||
|
||||
private boolean hasActiveLabelTerm(Long priceSetId, Long productId)
|
||||
{
|
||||
return hasLabelTermStatus(priceSetId, productId, TERM_PENDING)
|
||||
|| hasLabelTermStatus(priceSetId, productId, TERM_EFFECT);
|
||||
}
|
||||
|
||||
private boolean hasLabelTermStatus(Long priceSetId, Long productId, String status)
|
||||
{
|
||||
List<PayProductTerm> terms = payProductTermMapper.selectByPriceSetId(priceSetId);
|
||||
if (terms == null || productId == null || status == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (PayProductTerm term : terms)
|
||||
{
|
||||
if (productId.equals(term.getProductId()) && status.equals(term.getStatus()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 打单追加版本:不关闭已生效 term,只在覆盖时关掉待生效;version_no 用套餐级批次号。
|
||||
*/
|
||||
private PayProduct appendLabelVersion(Long rootId, PayProduct incoming, String operator, Long priceSetId,
|
||||
int versionNo, boolean overwritePending)
|
||||
{
|
||||
Long root = resolveRoot(rootId);
|
||||
PayProduct base = payProductMapper.selectPayProductById(root);
|
||||
PayProduct copy = copyHeader(base, incoming == null ? base : incoming);
|
||||
copy.setProductId(root);
|
||||
copy.setOriginId(null);
|
||||
copy.setChannelId(null);
|
||||
copy.setDictValue(blankTo(copy.getDictValue(), base.getDictValue()));
|
||||
copy.setVersionNo(versionNo);
|
||||
copy.setEffectiveDate(null);
|
||||
copy.setCreateBy(operator);
|
||||
copy.setUpdateBy(operator);
|
||||
copy.setCreateTime(new Date());
|
||||
prepareCounts(copy);
|
||||
fitColumns(copy);
|
||||
payProductMapper.updatePayProduct(copy);
|
||||
if (overwritePending)
|
||||
{
|
||||
Date endDate = toDate(toLocalDate(today()).minusDays(1));
|
||||
payProductTermMapper.closePendingBySetProduct(priceSetId, root, endDate, operator);
|
||||
}
|
||||
openTerm(copy, false, priceSetId);
|
||||
insertBands(copy);
|
||||
insertSurcharges(copy);
|
||||
insertExtras(copy);
|
||||
return selectPayProductDetailByTerm(copy.getTermId());
|
||||
}
|
||||
|
||||
private Long ensureLabelPriceSet(PaySaveCommand command)
|
||||
{
|
||||
if (command.getPriceSetId() != null)
|
||||
{
|
||||
PrcPriceSet db = priceSetMapper.selectPrcPriceSetById(command.getPriceSetId());
|
||||
if (db == null)
|
||||
{
|
||||
throw new ServiceException("打单套餐不存在");
|
||||
}
|
||||
if (!PrcPriceSet.CATEGORY_LABEL.equalsIgnoreCase(String.valueOf(db.getSetCategory())))
|
||||
{
|
||||
throw new ServiceException("只能向打单套餐导入价卡");
|
||||
}
|
||||
return db.getPriceSetId();
|
||||
}
|
||||
if (isBlank(command.getPriceSetName()))
|
||||
{
|
||||
throw new ServiceException("请填写打单套餐名称");
|
||||
}
|
||||
String operator = SecurityUtils.getUsername();
|
||||
PrcPriceSet set = new PrcPriceSet();
|
||||
set.setPriceSetName(command.getPriceSetName().trim());
|
||||
set.setPriceSetNote(command.getPriceSetNote());
|
||||
set.setSetType("FIXED");
|
||||
set.setSetCategory(PrcPriceSet.CATEGORY_LABEL);
|
||||
// 新建为待启用,详情页设启动时间后再生效(对齐价格套餐)
|
||||
set.setStatus("D");
|
||||
set.setCreateBy(operator);
|
||||
set.setUpdateBy(operator);
|
||||
priceSetMapper.insertPrcPriceSet(set);
|
||||
set.setPriceSetCode(String.format("LBL%04d", set.getPriceSetId()));
|
||||
priceSetMapper.updatePrcPriceSet(set);
|
||||
command.setPriceSetId(set.getPriceSetId());
|
||||
return set.getPriceSetId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelPackageVersion> selectLabelVersions(Long priceSetId)
|
||||
{
|
||||
if (priceSetId == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
PrcPriceSet set = priceSetMapper.selectPrcPriceSetById(priceSetId);
|
||||
if (set == null)
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Date now = today();
|
||||
// 纠正历史:未来生效版启动时把旧版提前标成已失效
|
||||
payProductTermMapper.restorePrematureClosed(priceSetId, now, "system");
|
||||
List<LabelPackageVersion> groups = payProductTermMapper.selectLabelVersionGroups(priceSetId);
|
||||
if (groups == null || groups.isEmpty())
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
for (LabelPackageVersion ver : groups)
|
||||
{
|
||||
ver.setPriceSetId(priceSetId);
|
||||
ver.setVersionLabel("V" + (ver.getVersionNo() == null ? 1 : ver.getVersionNo()));
|
||||
int active = ver.getActiveCount() == null ? 0 : ver.getActiveCount();
|
||||
int pending = ver.getPendingCount() == null ? 0 : ver.getPendingCount();
|
||||
Date start = ver.getEffectiveTime();
|
||||
Date end = ver.getExpireTime();
|
||||
// 按日期判定:未到生效日=待生效;已过失效日=已失效;中间段=生效
|
||||
if (start == null)
|
||||
{
|
||||
ver.setStatus(pending > 0 ? TERM_PENDING : (active > 0 ? TERM_EFFECT : TERM_EXPIRED));
|
||||
}
|
||||
else if (toLocalDate(start).isAfter(toLocalDate(now)))
|
||||
{
|
||||
ver.setStatus(TERM_PENDING);
|
||||
}
|
||||
else if (end != null && toLocalDate(end).isBefore(toLocalDate(now)))
|
||||
{
|
||||
ver.setStatus(TERM_EXPIRED);
|
||||
}
|
||||
else
|
||||
{
|
||||
ver.setStatus(TERM_EFFECT);
|
||||
}
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String activateLabelVersion(Long priceSetId, Integer versionNo, Date effectiveTime)
|
||||
{
|
||||
if (priceSetId == null || versionNo == null)
|
||||
{
|
||||
throw new ServiceException("请选择要启动的版本");
|
||||
}
|
||||
if (effectiveTime == null)
|
||||
{
|
||||
throw new ServiceException("请选择生效时间");
|
||||
}
|
||||
PrcPriceSet set = priceSetMapper.selectPrcPriceSetById(priceSetId);
|
||||
if (set == null)
|
||||
{
|
||||
throw new ServiceException("打单套餐不存在");
|
||||
}
|
||||
if (!PrcPriceSet.CATEGORY_LABEL.equalsIgnoreCase(String.valueOf(set.getSetCategory())))
|
||||
{
|
||||
throw new ServiceException("只能启动打单套餐版本");
|
||||
}
|
||||
String operator = SecurityUtils.getUsername();
|
||||
boolean future = toLocalDate(effectiveTime).isAfter(toLocalDate(today()));
|
||||
Date endDate = toDate(toLocalDate(effectiveTime).minusDays(1));
|
||||
if (future)
|
||||
{
|
||||
// 未到生效日:本版保持待生效;旧版只预约失效日,当前仍生效
|
||||
payProductTermMapper.scheduleEndExceptVersion(priceSetId, versionNo, endDate, today(), operator);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 当天或已过:本版立刻生效,旧版关掉
|
||||
payProductTermMapper.closeEffectExceptVersion(priceSetId, versionNo, endDate, operator);
|
||||
}
|
||||
String termStatus = future ? TERM_PENDING : TERM_EFFECT;
|
||||
int n = payProductTermMapper.updateLabelVersionPeriod(priceSetId, versionNo, effectiveTime, null, termStatus, operator);
|
||||
if (n <= 0)
|
||||
{
|
||||
throw new ServiceException("该版本没有可启动的产品价卡");
|
||||
}
|
||||
// 真正生效时才把套餐壳置为生效
|
||||
if (!future && !"E".equalsIgnoreCase(String.valueOf(set.getStatus())))
|
||||
{
|
||||
PrcPriceSet upd = new PrcPriceSet();
|
||||
upd.setPriceSetId(priceSetId);
|
||||
upd.setStatus("E");
|
||||
upd.setUpdateBy(operator);
|
||||
priceSetMapper.updatePrcPriceSetStatus(upd);
|
||||
}
|
||||
return future ? "已设为待生效" : "版本已启动";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deletePayProducts(Long[] productIds)
|
||||
@@ -826,6 +1367,7 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
for (PayWeightBand row : rows)
|
||||
{
|
||||
row.setProductId(product.getProductId());
|
||||
row.setTermId(product.getTermId());
|
||||
row.setVersionNo(product.getVersionNo() == null ? 1 : product.getVersionNo());
|
||||
}
|
||||
for (int i = 0; i < rows.size(); i += BATCH)
|
||||
@@ -844,6 +1386,7 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
for (PaySurcharge row : rows)
|
||||
{
|
||||
row.setProductId(product.getProductId());
|
||||
row.setTermId(product.getTermId());
|
||||
row.setVersionNo(product.getVersionNo() == null ? 1 : product.getVersionNo());
|
||||
}
|
||||
for (int i = 0; i < rows.size(); i += BATCH)
|
||||
@@ -868,6 +1411,7 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
for (PayExtraLine row : rows)
|
||||
{
|
||||
row.setProductId(product.getProductId());
|
||||
row.setTermId(product.getTermId());
|
||||
}
|
||||
for (int i = 0; i < rows.size(); i += BATCH)
|
||||
{
|
||||
@@ -938,7 +1482,7 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindChannel(String channelId, Long productId, Long priceSetId, String payType)
|
||||
public void bindChannel(String channelId, Long productId, String payType)
|
||||
{
|
||||
if (isBlank(channelId) || productId == null)
|
||||
{
|
||||
@@ -955,7 +1499,6 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
row.setChannelId(channelId);
|
||||
row.setChannelCode(channel.getChannelCode());
|
||||
row.setProductId(storedId);
|
||||
row.setPriceSetId(priceSetId);
|
||||
row.setPayType(type);
|
||||
String operator = SecurityUtils.getUsername();
|
||||
row.setCreateBy(operator);
|
||||
@@ -1015,37 +1558,42 @@ public class PayProductServiceImpl implements IPayProductService
|
||||
return compared;
|
||||
}
|
||||
|
||||
/** 在同一个产品编号下追加一版价格,不新开产品编号。 */
|
||||
/** 在同一个产品编号下追加一版价格:复用稳定 product_id,明细挂新 term_id。 */
|
||||
private PayProduct appendVersion(Long rootId, PayProduct incoming, String operator)
|
||||
{
|
||||
return appendVersion(rootId, incoming, operator, null);
|
||||
}
|
||||
|
||||
private PayProduct appendVersion(Long rootId, PayProduct incoming, String operator, Long priceSetId)
|
||||
{
|
||||
Long root = resolveRoot(rootId);
|
||||
PayProduct base = payProductMapper.selectPayProductById(root);
|
||||
PayProduct copy = copyHeader(base, incoming == null ? base : incoming);
|
||||
copy.setProductId(null);
|
||||
copy.setOriginId(root);
|
||||
copy.setProductId(root);
|
||||
copy.setOriginId(null);
|
||||
copy.setChannelId(null);
|
||||
copy.setDictValue(blankTo(copy.getDictValue(), base.getDictValue()));
|
||||
Integer maxVersion = payProductMapper.selectMaxVersion(root);
|
||||
Integer maxVersion = payProductTermMapper.selectMaxVersionByProduct(root, priceSetId);
|
||||
if (maxVersion == null || maxVersion < 1)
|
||||
{
|
||||
maxVersion = payProductMapper.selectMaxVersion(root);
|
||||
}
|
||||
copy.setVersionNo((maxVersion == null ? 1 : maxVersion) + 1);
|
||||
if (copy.getEffectiveDate() == null)
|
||||
{
|
||||
copy.setEffectiveDate(today());
|
||||
}
|
||||
copy.setCreateBy(operator);
|
||||
copy.setUpdateBy(operator);
|
||||
copy.setCreateTime(new Date());
|
||||
prepareCounts(copy);
|
||||
fitColumns(copy);
|
||||
payProductMapper.insertPayProduct(copy);
|
||||
payProductMapper.updatePayProduct(copy);
|
||||
openTerm(copy, true, priceSetId);
|
||||
insertBands(copy);
|
||||
insertSurcharges(copy);
|
||||
insertExtras(copy);
|
||||
openTerm(copy, true);
|
||||
PayProduct saved = selectPayProductDetail(copy.getProductId());
|
||||
if (saved != null)
|
||||
{
|
||||
saved.setOriginId(root);
|
||||
}
|
||||
return saved;
|
||||
return selectPayProductDetailByTerm(copy.getTermId());
|
||||
}
|
||||
|
||||
/** 渠道产品绑定记在映射表,产品编号是不变的根产品。 */
|
||||
|
||||
+10
-2
@@ -77,6 +77,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
||||
private static final String TYPE_FIXED = "FIXED";
|
||||
private static final String CATEGORY_PACKAGE = PrcPriceSet.CATEGORY_PACKAGE;
|
||||
private static final String CATEGORY_EXCLUSIVE = PrcPriceSet.CATEGORY_EXCLUSIVE;
|
||||
private static final String CATEGORY_LABEL = PrcPriceSet.CATEGORY_LABEL;
|
||||
private static final String TYPE_DISCOUNT = "DISCOUNT";
|
||||
private static final String VER_DRAFT = "0";
|
||||
private static final String VER_EFFECT = "1";
|
||||
@@ -2979,16 +2980,23 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
||||
/** PACKAGE (default) or EXCLUSIVE. */
|
||||
public static String normalizeSetCategory(String setCategory)
|
||||
{
|
||||
if (CATEGORY_EXCLUSIVE.equalsIgnoreCase(StringUtils.trim(setCategory)))
|
||||
String raw = StringUtils.trim(setCategory);
|
||||
if (CATEGORY_EXCLUSIVE.equalsIgnoreCase(raw))
|
||||
{
|
||||
return CATEGORY_EXCLUSIVE;
|
||||
}
|
||||
if (CATEGORY_LABEL.equalsIgnoreCase(raw))
|
||||
{
|
||||
return CATEGORY_LABEL;
|
||||
}
|
||||
return CATEGORY_PACKAGE;
|
||||
}
|
||||
|
||||
private static String buildPriceSetCode(String setCategory, Long priceSetId)
|
||||
{
|
||||
String prefix = CATEGORY_EXCLUSIVE.equals(normalizeSetCategory(setCategory)) ? "EXC" : "SET";
|
||||
String category = normalizeSetCategory(setCategory);
|
||||
String prefix = CATEGORY_EXCLUSIVE.equals(category) ? "EXC"
|
||||
: (CATEGORY_LABEL.equals(category) ? "LBL" : "SET");
|
||||
return String.format("%s%04d", prefix, priceSetId);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="selectByChannelAndType" resultType="com.bms.price.domain.ChannelProductMap">
|
||||
select id, channel_id as channelId, channel_code as channelCode, product_id as productId,
|
||||
price_set_id as priceSetId, pay_type as payType, create_by as createBy, create_time as createTime,
|
||||
pay_type as payType, create_by as createBy, create_time as createTime,
|
||||
update_by as updateBy, update_time as updateTime
|
||||
from srv_channel_product_map
|
||||
where channel_id = #{channelId} and pay_type = #{payType}
|
||||
@@ -15,14 +15,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<insert id="upsert">
|
||||
insert into srv_channel_product_map (
|
||||
channel_id, channel_code, product_id, price_set_id, pay_type, create_by, create_time, update_by, update_time
|
||||
channel_id, channel_code, product_id, pay_type, create_by, create_time, update_by, update_time
|
||||
) values (
|
||||
#{channelId}, #{channelCode}, #{productId}, #{priceSetId}, #{payType}, #{createBy}, sysdate(), #{updateBy}, sysdate()
|
||||
#{channelId}, #{channelCode}, #{productId}, #{payType}, #{createBy}, sysdate(), #{updateBy}, sysdate()
|
||||
)
|
||||
on duplicate key update
|
||||
channel_code = values(channel_code),
|
||||
product_id = values(product_id),
|
||||
price_set_id = values(price_set_id),
|
||||
update_by = values(update_by),
|
||||
update_time = sysdate()
|
||||
</insert>
|
||||
|
||||
@@ -49,6 +49,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<where>
|
||||
<if test="templateOnly != null and templateOnly">
|
||||
and (pay_product.channel_id is null or pay_product.channel_id = '')
|
||||
and not (
|
||||
exists (
|
||||
select 1 from pay_product_term t_label
|
||||
where t_label.product_id = pay_product.product_id
|
||||
and t_label.price_set_id is not null
|
||||
)
|
||||
and not exists (
|
||||
select 1 from pay_product_term t_pay
|
||||
where t_pay.product_id = pay_product.product_id
|
||||
and t_pay.price_set_id is null
|
||||
)
|
||||
)
|
||||
</if>
|
||||
<if test="currentOnly != null and currentOnly">
|
||||
and pay_product.origin_id is null
|
||||
@@ -129,7 +141,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
inner join pay_product v on v.product_id = t2.product_id
|
||||
where (v.channel_id is null or v.channel_id = '')
|
||||
and (v.product_id = pay_product.product_id or v.origin_id = pay_product.product_id)
|
||||
order by case when t2.status = '0' then 0 else 1 end, ifnull(v.version_no, 1) desc, t2.term_id desc
|
||||
and t2.price_set_id is null
|
||||
order by case when t2.status = '1' then 0 when t2.status = '0' then 1 else 2 end, ifnull(v.version_no, 1) desc, t2.term_id desc
|
||||
limit 1
|
||||
)
|
||||
left join pay_product cur on cur.product_id = t.product_id
|
||||
@@ -202,15 +215,65 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
where product_id = #{productId}
|
||||
</update>
|
||||
|
||||
<!-- 应付公共模板:排除「仅打单套餐」产品(有 label term、无公共 term) -->
|
||||
<sql id="payPublicTemplateOnly">
|
||||
and not (
|
||||
exists (
|
||||
select 1 from pay_product_term t_label
|
||||
where t_label.product_id = pay_product.product_id
|
||||
and t_label.price_set_id is not null
|
||||
)
|
||||
and not exists (
|
||||
select 1 from pay_product_term t_pay
|
||||
where t_pay.product_id = pay_product.product_id
|
||||
and t_pay.price_set_id is null
|
||||
)
|
||||
)
|
||||
</sql>
|
||||
|
||||
<select id="selectTemplateId" resultType="long">
|
||||
select product_id from pay_product
|
||||
where dict_value = #{dictValue}
|
||||
and (channel_id is null or channel_id = '')
|
||||
and origin_id is null
|
||||
<include refid="payPublicTemplateOnly"/>
|
||||
order by product_id
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectTemplateIdByType" resultType="long">
|
||||
select product_id from pay_product
|
||||
where dict_value = #{dictValue}
|
||||
and ifnull(product_type, 'AP') = #{productType}
|
||||
and (channel_id is null or channel_id = '')
|
||||
and origin_id is null
|
||||
<include refid="payPublicTemplateOnly"/>
|
||||
order by product_id
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<!-- 打单套餐专用:只命中已有 label term 的 AR 产品,绝不碰应付公共模板 -->
|
||||
<select id="selectLabelProductIdByDict" resultType="long">
|
||||
select p.product_id
|
||||
from pay_product p
|
||||
where p.dict_value = #{dictValue}
|
||||
and ifnull(p.product_type, 'AP') = 'AR'
|
||||
and (p.channel_id is null or p.channel_id = '')
|
||||
and p.origin_id is null
|
||||
and exists (
|
||||
select 1 from pay_product_term t
|
||||
where t.product_id = p.product_id
|
||||
and t.price_set_id is not null
|
||||
)
|
||||
and not exists (
|
||||
select 1 from pay_product_term t2
|
||||
where t2.product_id = p.product_id
|
||||
and t2.price_set_id is null
|
||||
)
|
||||
order by p.product_id
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<select id="selectTemplateOptions" resultMap="PayProductResult">
|
||||
select p.product_id, p.product_name, p.product_type, p.dict_value, p.sheet_name, p.supplier_name, p.effective_date,
|
||||
p.currency, ifnull(cur.version_no, p.version_no) as version_no
|
||||
@@ -221,13 +284,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
inner join pay_product v on v.product_id = t2.product_id
|
||||
where (v.channel_id is null or v.channel_id = '')
|
||||
and (v.product_id = p.product_id or v.origin_id = p.product_id)
|
||||
order by case when t2.status = '0' then 0 else 1 end, ifnull(v.version_no, 1) desc, t2.term_id desc
|
||||
and t2.price_set_id is null
|
||||
order by case when t2.status = '1' then 0 when t2.status = '0' then 1 else 2 end, ifnull(v.version_no, 1) desc, t2.term_id desc
|
||||
limit 1
|
||||
)
|
||||
left join pay_product cur on cur.product_id = t.product_id
|
||||
where (p.channel_id is null or p.channel_id = '')
|
||||
and p.origin_id is null
|
||||
and ifnull(p.product_type, 'AP') = #{payType}
|
||||
and not (
|
||||
exists (
|
||||
select 1 from pay_product_term t_label
|
||||
where t_label.product_id = p.product_id
|
||||
and t_label.price_set_id is not null
|
||||
)
|
||||
and not exists (
|
||||
select 1 from pay_product_term t_pay
|
||||
where t_pay.product_id = p.product_id
|
||||
and t_pay.price_set_id is null
|
||||
)
|
||||
)
|
||||
order by p.product_name
|
||||
</select>
|
||||
|
||||
@@ -238,11 +314,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<insert id="insertWeightBands">
|
||||
insert into pay_weight_band (
|
||||
product_id, version_no, section_name, country_name, country_code, zone_name, weight_label, weight_min, weight_max,
|
||||
product_id, term_id, version_no, section_name, country_name, country_code, zone_name, weight_label, weight_min, weight_max,
|
||||
volume_text, charge_name, price, price_unit, sort_no
|
||||
) values
|
||||
<foreach collection="list" item="row" separator=",">
|
||||
(#{row.productId}, ifnull(#{row.versionNo}, 1), #{row.sectionName}, #{row.countryName}, #{row.countryCode}, #{row.zoneName},
|
||||
(#{row.productId}, #{row.termId}, ifnull(#{row.versionNo}, 1), #{row.sectionName}, #{row.countryName}, #{row.countryCode}, #{row.zoneName},
|
||||
#{row.weightLabel}, #{row.weightMin}, #{row.weightMax}, #{row.volumeText}, #{row.chargeName}, #{row.price},
|
||||
#{row.priceUnit}, #{row.sortNo})
|
||||
</foreach>
|
||||
@@ -250,11 +326,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<insert id="insertSurcharges">
|
||||
insert into pay_surcharge (
|
||||
product_id, version_no, section_name, fee_name, zone_name, charge_text, amount, currency, price_unit, fee_desc, period_text,
|
||||
product_id, term_id, version_no, section_name, fee_name, zone_name, charge_text, amount, currency, price_unit, fee_desc, period_text,
|
||||
effective_start, effective_end, charge_timing, calc_rule, calc_param, weight_min, weight_max, postcode_param, sort_no
|
||||
) values
|
||||
<foreach collection="list" item="row" separator=",">
|
||||
(#{row.productId}, ifnull(#{row.versionNo}, 1), #{row.sectionName}, #{row.feeName}, #{row.zoneName}, #{row.chargeText}, #{row.amount},
|
||||
(#{row.productId}, #{row.termId}, ifnull(#{row.versionNo}, 1), #{row.sectionName}, #{row.feeName}, #{row.zoneName}, #{row.chargeText}, #{row.amount},
|
||||
#{row.currency}, #{row.priceUnit}, #{row.feeDesc}, #{row.periodText}, #{row.effectiveStart}, #{row.effectiveEnd},
|
||||
#{row.chargeTiming}, ifnull(#{row.calcRule}, 'MANUAL'), #{row.calcParam}, #{row.weightMin}, #{row.weightMax},
|
||||
#{row.postcodeParam}, #{row.sortNo})
|
||||
@@ -262,14 +338,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</insert>
|
||||
|
||||
<insert id="insertExtraLines">
|
||||
insert into pay_extra_line (product_id, line_type, line_text, sort_no) values
|
||||
insert into pay_extra_line (product_id, term_id, line_type, line_text, sort_no) values
|
||||
<foreach collection="list" item="row" separator=",">
|
||||
(#{row.productId}, #{row.lineType}, #{row.lineText}, #{row.sortNo})
|
||||
(#{row.productId}, #{row.termId}, #{row.lineType}, #{row.lineText}, #{row.sortNo})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<select id="selectWeightBands" resultType="com.bms.price.domain.PayWeightBand">
|
||||
select band_id as bandId, product_id as productId, version_no as versionNo, section_name as sectionName, country_name as countryName,
|
||||
select band_id as bandId, product_id as productId, term_id as termId, version_no as versionNo, section_name as sectionName, country_name as countryName,
|
||||
country_code as countryCode, zone_name as zoneName, weight_label as weightLabel, weight_min as weightMin,
|
||||
weight_max as weightMax, volume_text as volumeText, charge_name as chargeName, price, price_unit as priceUnit, sort_no as sortNo
|
||||
from pay_weight_band
|
||||
@@ -278,8 +354,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
order by product_id, sort_no, band_id
|
||||
</select>
|
||||
|
||||
<select id="selectWeightBandsByTerm" resultType="com.bms.price.domain.PayWeightBand">
|
||||
select band_id as bandId, product_id as productId, term_id as termId, version_no as versionNo, section_name as sectionName, country_name as countryName,
|
||||
country_code as countryCode, zone_name as zoneName, weight_label as weightLabel, weight_min as weightMin,
|
||||
weight_max as weightMax, volume_text as volumeText, charge_name as chargeName, price, price_unit as priceUnit, sort_no as sortNo
|
||||
from pay_weight_band
|
||||
where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
order by product_id, sort_no, band_id
|
||||
</select>
|
||||
|
||||
<select id="selectSurcharges" resultType="com.bms.price.domain.PaySurcharge">
|
||||
select surcharge_id as surchargeId, product_id as productId, version_no as versionNo, section_name as sectionName, fee_name as feeName,
|
||||
select surcharge_id as surchargeId, product_id as productId, term_id as termId, version_no as versionNo, section_name as sectionName, fee_name as feeName,
|
||||
zone_name as zoneName, charge_text as chargeText, amount, currency, price_unit as priceUnit, fee_desc as feeDesc,
|
||||
period_text as periodText, effective_start as effectiveStart, effective_end as effectiveEnd,
|
||||
charge_timing as chargeTiming, calc_rule as calcRule, calc_param as calcParam,
|
||||
@@ -290,14 +376,47 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
order by product_id, sort_no, surcharge_id
|
||||
</select>
|
||||
|
||||
<select id="selectSurchargesByTerm" resultType="com.bms.price.domain.PaySurcharge">
|
||||
select surcharge_id as surchargeId, product_id as productId, term_id as termId, version_no as versionNo, section_name as sectionName, fee_name as feeName,
|
||||
zone_name as zoneName, charge_text as chargeText, amount, currency, price_unit as priceUnit, fee_desc as feeDesc,
|
||||
period_text as periodText, effective_start as effectiveStart, effective_end as effectiveEnd,
|
||||
charge_timing as chargeTiming, calc_rule as calcRule, calc_param as calcParam,
|
||||
weight_min as weightMin, weight_max as weightMax, postcode_param as postcodeParam, sort_no as sortNo
|
||||
from pay_surcharge
|
||||
where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
order by product_id, sort_no, surcharge_id
|
||||
</select>
|
||||
|
||||
<select id="selectExtraLines" resultType="com.bms.price.domain.PayExtraLine">
|
||||
select line_id as lineId, product_id as productId, line_type as lineType, line_text as lineText, sort_no as sortNo
|
||||
select line_id as lineId, product_id as productId, term_id as termId, line_type as lineType, line_text as lineText, sort_no as sortNo
|
||||
from pay_extra_line
|
||||
where product_id in
|
||||
<foreach collection="productIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
order by product_id, sort_no, line_id
|
||||
</select>
|
||||
|
||||
<select id="selectExtraLinesByTerm" resultType="com.bms.price.domain.PayExtraLine">
|
||||
select line_id as lineId, product_id as productId, term_id as termId, line_type as lineType, line_text as lineText, sort_no as sortNo
|
||||
from pay_extra_line
|
||||
where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
order by product_id, sort_no, line_id
|
||||
</select>
|
||||
|
||||
<delete id="deleteWeightBandsByTerm">
|
||||
delete from pay_weight_band where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
<delete id="deleteSurchargesByTerm">
|
||||
delete from pay_surcharge where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
<delete id="deleteExtraLinesByTerm">
|
||||
delete from pay_extra_line where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
|
||||
<delete id="deleteWeightBands">
|
||||
delete from pay_weight_band where product_id in
|
||||
<foreach collection="productIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
@@ -323,13 +442,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
where product_id = #{rootId} or origin_id = #{rootId}
|
||||
</select>
|
||||
|
||||
<!-- 取价只看有效期。生效/失效开关不参与,和历史页说明一致。 -->
|
||||
<!-- 取价只看有效期。生效/失效开关不参与,和历史页说明一致。仅应付公共 term。 -->
|
||||
<select id="selectEffectiveVersionId" resultType="long">
|
||||
select v.product_id
|
||||
from pay_product v
|
||||
inner join pay_product_term t on t.product_id = v.product_id
|
||||
where (v.channel_id is null or v.channel_id = '')
|
||||
and (v.product_id = #{stableId} or v.origin_id = #{stableId})
|
||||
and t.price_set_id is null
|
||||
and t.status = '1'
|
||||
and (t.effective_start is null or t.effective_start <= date(#{bizDate}))
|
||||
and (t.effective_end is null or t.effective_end >= date(#{bizDate}))
|
||||
order by ifnull(v.version_no, 1) desc, v.product_id desc
|
||||
|
||||
@@ -5,7 +5,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<mapper namespace="com.bms.price.mapper.PayProductTermMapper">
|
||||
|
||||
<select id="selectByDict" resultType="com.bms.price.domain.PayProductTerm">
|
||||
select t.term_id as termId, t.dict_value as dictValue, t.product_id as productId, t.version_no as versionNo,
|
||||
select t.term_id as termId, t.dict_value as dictValue, t.product_id as productId, t.price_set_id as priceSetId,
|
||||
t.version_no as versionNo,
|
||||
t.effective_start as effectiveStart, t.effective_end as effectiveEnd, t.status,
|
||||
t.created_by as createBy, t.create_time as createTime, t.remark,
|
||||
p.product_name as productName, p.source_file as sourceFile,
|
||||
@@ -15,29 +16,107 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
join pay_product p on p.product_id = t.product_id
|
||||
where t.dict_value = #{dictValue}
|
||||
and (p.channel_id is null or p.channel_id = '')
|
||||
and t.price_set_id is null
|
||||
order by t.version_no desc, t.term_id desc
|
||||
</select>
|
||||
|
||||
<select id="selectById" resultType="com.bms.price.domain.PayProductTerm">
|
||||
select term_id as termId, dict_value as dictValue, product_id as productId, version_no as versionNo,
|
||||
select term_id as termId, dict_value as dictValue, product_id as productId, price_set_id as priceSetId,
|
||||
version_no as versionNo,
|
||||
effective_start as effectiveStart, effective_end as effectiveEnd, status
|
||||
from pay_product_term
|
||||
where term_id = #{termId}
|
||||
</select>
|
||||
|
||||
<!-- 应付侧当前版:只取公共 term;优先生效(1),其次待生效(0) -->
|
||||
<select id="selectByProductId" resultType="com.bms.price.domain.PayProductTerm">
|
||||
select term_id as termId, dict_value as dictValue, product_id as productId, version_no as versionNo,
|
||||
select term_id as termId, dict_value as dictValue, product_id as productId, price_set_id as priceSetId,
|
||||
version_no as versionNo,
|
||||
effective_start as effectiveStart, effective_end as effectiveEnd, status
|
||||
from pay_product_term
|
||||
where product_id = #{productId}
|
||||
and price_set_id is null
|
||||
and status in ('0', '1')
|
||||
order by case when status = '1' then 0 when status = '0' then 1 else 2 end, version_no desc, term_id desc
|
||||
limit 1
|
||||
</select>
|
||||
|
||||
<!-- 打单套餐产品列表:待生效+生效 -->
|
||||
<select id="selectByPriceSetId" resultType="com.bms.price.domain.PayProductTerm">
|
||||
select t.term_id as termId, t.dict_value as dictValue, t.product_id as productId, t.price_set_id as priceSetId,
|
||||
t.version_no as versionNo,
|
||||
t.effective_start as effectiveStart, t.effective_end as effectiveEnd, t.status,
|
||||
p.product_name as productName, p.source_file as sourceFile,
|
||||
ifnull(t.file_path, p.file_path) as filePath, p.weight_count as weightCount,
|
||||
p.surcharge_count as surchargeCount, p.currency
|
||||
from pay_product_term t
|
||||
join pay_product p on p.product_id = t.product_id
|
||||
where t.price_set_id = #{priceSetId}
|
||||
and t.status in ('0', '1')
|
||||
order by p.product_name, t.term_id desc
|
||||
</select>
|
||||
|
||||
<select id="selectByPriceSetIdAndVersion" resultType="com.bms.price.domain.PayProductTerm">
|
||||
select t.term_id as termId, t.dict_value as dictValue, t.product_id as productId, t.price_set_id as priceSetId,
|
||||
t.version_no as versionNo,
|
||||
t.effective_start as effectiveStart, t.effective_end as effectiveEnd, t.status,
|
||||
p.product_name as productName, p.source_file as sourceFile,
|
||||
ifnull(t.file_path, p.file_path) as filePath, p.weight_count as weightCount,
|
||||
p.surcharge_count as surchargeCount, p.currency
|
||||
from pay_product_term t
|
||||
join pay_product p on p.product_id = t.product_id
|
||||
where t.price_set_id = #{priceSetId}
|
||||
and t.version_no = #{versionNo}
|
||||
order by case when t.status = '1' then 0 when t.status = '0' then 1 else 2 end, p.product_name, t.term_id desc
|
||||
</select>
|
||||
|
||||
<select id="selectLabelVersionGroups" resultType="com.bms.price.domain.LabelPackageVersion">
|
||||
select #{priceSetId} as priceSetId,
|
||||
t.version_no as versionNo,
|
||||
min(t.effective_start) as effectiveTime,
|
||||
max(t.effective_end) as expireTime,
|
||||
count(distinct t.product_id) as productCount,
|
||||
sum(case when t.status = '1' then 1 else 0 end) as activeCount,
|
||||
sum(case when t.status = '0' then 1 else 0 end) as pendingCount,
|
||||
min(t.create_time) as createTime
|
||||
from pay_product_term t
|
||||
where t.price_set_id = #{priceSetId}
|
||||
group by t.version_no
|
||||
order by t.version_no desc
|
||||
</select>
|
||||
|
||||
<!-- 启动:写入生效日;未到日 status=0,已到/当天 status=1 -->
|
||||
<update id="updateLabelVersionPeriod">
|
||||
update pay_product_term
|
||||
set effective_start = #{effectiveStart},
|
||||
effective_end = #{effectiveEnd},
|
||||
status = #{status},
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where price_set_id = #{priceSetId}
|
||||
and version_no = #{versionNo}
|
||||
and status in ('0', '1')
|
||||
</update>
|
||||
|
||||
<select id="selectMaxVersionByProduct" resultType="int">
|
||||
select ifnull(max(version_no), 0) from pay_product_term where product_id = #{productId}
|
||||
<if test="priceSetId != null">
|
||||
and price_set_id = #{priceSetId}
|
||||
</if>
|
||||
<if test="priceSetId == null">
|
||||
and price_set_id is null
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectMaxVersionByPriceSet" resultType="int">
|
||||
select ifnull(max(version_no), 0) from pay_product_term where price_set_id = #{priceSetId}
|
||||
</select>
|
||||
|
||||
<insert id="insertTerm" parameterType="com.bms.price.domain.PayProductTerm" useGeneratedKeys="true" keyProperty="termId">
|
||||
insert into pay_product_term (
|
||||
dict_value, product_id, version_no, effective_start, effective_end, file_path, status, created_by, create_time, remark
|
||||
dict_value, product_id, price_set_id, version_no, effective_start, effective_end, file_path, status, created_by, create_time, remark
|
||||
) values (
|
||||
#{dictValue}, #{productId}, ifnull(#{versionNo}, 1), #{effectiveStart}, #{effectiveEnd}, #{filePath},
|
||||
#{dictValue}, #{productId}, #{priceSetId}, ifnull(#{versionNo}, 1), #{effectiveStart}, #{effectiveEnd}, #{filePath},
|
||||
ifnull(#{status}, '0'), #{createBy}, sysdate(), #{remark}
|
||||
)
|
||||
</insert>
|
||||
@@ -59,9 +138,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
where term_id = #{termId}
|
||||
</update>
|
||||
|
||||
<!-- 截断旧版:生效/待生效 → 已失效(2) -->
|
||||
<update id="closeOpenTerms">
|
||||
update pay_product_term
|
||||
set status = '1',
|
||||
set status = '2',
|
||||
effective_end = case
|
||||
when effective_end is not null and effective_end < #{endDate} then effective_end
|
||||
when effective_start is not null and effective_start > #{endDate} then effective_start
|
||||
@@ -70,14 +150,90 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where dict_value = #{dictValue}
|
||||
and status in ('0', '1')
|
||||
and price_set_id is null
|
||||
</update>
|
||||
|
||||
<update id="closeOpenTermsBySetProduct">
|
||||
update pay_product_term
|
||||
set status = '2',
|
||||
effective_end = case
|
||||
when effective_end is not null and effective_end < #{endDate} then effective_end
|
||||
when effective_start is not null and effective_start > #{endDate} then effective_start
|
||||
else #{endDate}
|
||||
end,
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where product_id = #{productId}
|
||||
and price_set_id = #{priceSetId}
|
||||
and status in ('0', '1')
|
||||
</update>
|
||||
|
||||
<update id="closePendingBySetProduct">
|
||||
update pay_product_term
|
||||
set status = '2',
|
||||
effective_end = case
|
||||
when effective_end is not null and effective_end < #{endDate} then effective_end
|
||||
when effective_start is not null and effective_start > #{endDate} then effective_start
|
||||
else #{endDate}
|
||||
end,
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where product_id = #{productId}
|
||||
and price_set_id = #{priceSetId}
|
||||
and status = '0'
|
||||
</update>
|
||||
|
||||
<update id="closeEffectExceptVersion">
|
||||
update pay_product_term
|
||||
set status = '2',
|
||||
effective_end = case
|
||||
when effective_end is not null and effective_end < #{endDate} then effective_end
|
||||
when effective_start is not null and effective_start > #{endDate} then effective_start
|
||||
else #{endDate}
|
||||
end,
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where price_set_id = #{priceSetId}
|
||||
and status = '1'
|
||||
and version_no <> #{versionNo}
|
||||
</update>
|
||||
|
||||
<update id="scheduleEndExceptVersion">
|
||||
update pay_product_term
|
||||
set status = '1',
|
||||
effective_end = #{endDate},
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where price_set_id = #{priceSetId}
|
||||
and version_no <> #{versionNo}
|
||||
and (
|
||||
status = '1'
|
||||
or (status = '2' and effective_end is not null and effective_end >= #{today})
|
||||
)
|
||||
</update>
|
||||
|
||||
<update id="restorePrematureClosed">
|
||||
update pay_product_term
|
||||
set status = '1',
|
||||
updated_by = #{updateBy},
|
||||
update_time = sysdate()
|
||||
where price_set_id = #{priceSetId}
|
||||
and status = '2'
|
||||
and effective_end is not null
|
||||
and effective_end >= #{today}
|
||||
</update>
|
||||
|
||||
<delete id="deleteByProductIds">
|
||||
delete from pay_product_term where product_id in
|
||||
<foreach collection="productIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
|
||||
<delete id="deleteByTermIds">
|
||||
delete from pay_product_term where term_id in
|
||||
<foreach collection="termIds" item="id" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="updateProductEffectiveDate">
|
||||
update pay_product
|
||||
set effective_date = #{effectiveDate},
|
||||
|
||||
@@ -31,11 +31,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
s.default_discount, s.default_type, s.calculate_sign,
|
||||
s.status, s.tms_id,
|
||||
s.created_by, s.create_time, s.updated_by, s.update_time,
|
||||
(select count(distinct p.product_code)
|
||||
from prc_price_set_product p
|
||||
inner join prc_price_set_version v on v.psv_id = p.psv_id
|
||||
where v.price_set_id = s.price_set_id
|
||||
and ifnull(p.is_del, '0') = '0') as product_count,
|
||||
case
|
||||
when ifnull(s.set_category, 'PACKAGE') = 'LABEL' then
|
||||
(select count(distinct t.product_id)
|
||||
from pay_product_term t
|
||||
where t.price_set_id = s.price_set_id
|
||||
and t.status = '0')
|
||||
else
|
||||
(select count(distinct p.product_code)
|
||||
from prc_price_set_product p
|
||||
inner join prc_price_set_version v on v.psv_id = p.psv_id
|
||||
where v.price_set_id = s.price_set_id
|
||||
and ifnull(p.is_del, '0') = '0')
|
||||
end as product_count,
|
||||
(select count(1) from prc_customer_price_set c where c.price_set_id = s.price_set_id) as customer_count,
|
||||
(select group_concat(
|
||||
concat(ifnull(c.customer_code, ''),
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
-- 打单套餐一键脚本(可重复执行)
|
||||
-- 合并自:pay_product_term.sql + label_package.sql + label_package_create_menu.sql
|
||||
-- 含:应付有效期表、打单表结构变更、打单/应付相关菜单权限
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
-- ========== 一、pay_product_term 建表 + 存量回填 ==========
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_product_term` (
|
||||
`term_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '有效期ID',
|
||||
`dict_value` varchar(100) NOT NULL COMMENT '产品字典值,同一产品的各版本归在一起',
|
||||
`product_id` bigint(20) NOT NULL COMMENT '这一版价格',
|
||||
`version_no` int(11) NOT NULL DEFAULT 1 COMMENT '版本号',
|
||||
`effective_start` date DEFAULT NULL COMMENT '生效开始',
|
||||
`effective_end` date DEFAULT NULL COMMENT '生效结束,空表示不限',
|
||||
`file_path` varchar(500) DEFAULT NULL COMMENT '这一版源文件OSS地址,oss://bucket/key',
|
||||
`status` char(1) NOT NULL DEFAULT '0' COMMENT '0待生效 1生效 2已失效',
|
||||
`created_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`updated_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`term_id`),
|
||||
UNIQUE KEY `uk_pay_term_product` (`product_id`),
|
||||
KEY `idx_pay_term_dict` (`dict_value`, `status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应付产品价格有效期';
|
||||
|
||||
-- 已有模板补一条生效记录,不覆盖后来手工改过的有效期
|
||||
INSERT INTO pay_product_term (
|
||||
dict_value, product_id, version_no, effective_start, status, created_by, create_time
|
||||
)
|
||||
SELECT ifnull(nullif(dict_value, ''), product_name), product_id, ifnull(version_no, 1), effective_date, '0',
|
||||
ifnull(created_by, ''), ifnull(create_time, sysdate())
|
||||
FROM pay_product p
|
||||
WHERE (p.channel_id IS NULL OR p.channel_id = '')
|
||||
AND NOT EXISTS (SELECT 1 FROM pay_product_term t WHERE t.product_id = p.product_id);
|
||||
|
||||
-- ========== 二、打单相关表结构变更 ==========
|
||||
|
||||
-- 0) pay_product_term.status:旧 0生效/1失效 → 新 0待生效/1生效/2已失效
|
||||
-- 仅当列注释仍是旧语义时迁移(可重复执行)
|
||||
SET @old_status_comment := (
|
||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'pay_product_term'
|
||||
AND COLUMN_NAME = 'status'
|
||||
AND COLUMN_COMMENT LIKE '%0生效%1失效%'
|
||||
);
|
||||
SET @sql := IF(@old_status_comment > 0,
|
||||
'UPDATE pay_product_term SET status = ''2'' WHERE status = ''1''',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
SET @sql := IF(@old_status_comment > 0,
|
||||
'UPDATE pay_product_term SET status = ''1'' WHERE status = ''0''',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
ALTER TABLE pay_product_term
|
||||
MODIFY COLUMN status char(1) NOT NULL DEFAULT '0' COMMENT '0待生效 1生效 2已失效';
|
||||
|
||||
-- 1) prc_price_set.set_category 注释增加 LABEL
|
||||
ALTER TABLE prc_price_set
|
||||
MODIFY COLUMN set_category varchar(20) NOT NULL DEFAULT 'PACKAGE'
|
||||
COMMENT '分类 PACKAGE=普通套餐 EXCLUSIVE=专属报价 LABEL=打单套餐';
|
||||
|
||||
-- 2) pay_product_term.price_set_id
|
||||
SET @exists := (
|
||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'pay_product_term'
|
||||
AND COLUMN_NAME = 'price_set_id'
|
||||
);
|
||||
SET @sql := IF(@exists = 0,
|
||||
'ALTER TABLE pay_product_term
|
||||
ADD COLUMN price_set_id bigint(20) DEFAULT NULL
|
||||
COMMENT ''打单套餐ID,对应 prc_price_set.price_set_id;应付公共模板为空''
|
||||
AFTER product_id,
|
||||
ADD KEY idx_pay_term_price_set (price_set_id)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 3) 去掉一产品一条 term 的唯一约束,支持一产品多周期
|
||||
SET @uk := (
|
||||
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'pay_product_term'
|
||||
AND INDEX_NAME = 'uk_pay_term_product'
|
||||
);
|
||||
SET @sql := IF(@uk > 0, 'ALTER TABLE pay_product_term DROP INDEX uk_pay_term_product', 'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @idx1 := (
|
||||
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'pay_product_term'
|
||||
AND INDEX_NAME = 'idx_pay_term_set_product_time'
|
||||
);
|
||||
SET @sql := IF(@idx1 = 0,
|
||||
'ALTER TABLE pay_product_term ADD KEY idx_pay_term_set_product_time (price_set_id, product_id, effective_start, effective_end)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @idx2 := (
|
||||
SELECT COUNT(1) FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'pay_product_term'
|
||||
AND INDEX_NAME = 'idx_pay_term_product_time'
|
||||
);
|
||||
SET @sql := IF(@idx2 = 0,
|
||||
'ALTER TABLE pay_product_term ADD KEY idx_pay_term_product_time (product_id, effective_start, effective_end)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 4) 明细表增加 term_id
|
||||
SET @exists := (
|
||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pay_weight_band' AND COLUMN_NAME = 'term_id'
|
||||
);
|
||||
SET @sql := IF(@exists = 0,
|
||||
'ALTER TABLE pay_weight_band
|
||||
ADD COLUMN term_id bigint(20) DEFAULT NULL
|
||||
COMMENT ''价卡版本周期ID,对应 pay_product_term.term_id;与 product_id 组成明细唯一维度''
|
||||
AFTER product_id,
|
||||
ADD KEY idx_pay_weight_product_term (product_id, term_id)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @exists := (
|
||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pay_surcharge' AND COLUMN_NAME = 'term_id'
|
||||
);
|
||||
SET @sql := IF(@exists = 0,
|
||||
'ALTER TABLE pay_surcharge
|
||||
ADD COLUMN term_id bigint(20) DEFAULT NULL
|
||||
COMMENT ''价卡版本周期ID,对应 pay_product_term.term_id;与 product_id 组成明细唯一维度''
|
||||
AFTER product_id,
|
||||
ADD KEY idx_pay_surcharge_product_term (product_id, term_id)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @exists := (
|
||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'pay_extra_line' AND COLUMN_NAME = 'term_id'
|
||||
);
|
||||
SET @sql := IF(@exists = 0,
|
||||
'ALTER TABLE pay_extra_line
|
||||
ADD COLUMN term_id bigint(20) DEFAULT NULL
|
||||
COMMENT ''价卡版本周期ID,对应 pay_product_term.term_id;与 product_id 组成明细唯一维度''
|
||||
AFTER product_id,
|
||||
ADD KEY idx_pay_extra_product_term (product_id, term_id)',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- 5) 存量明细回填 term_id(一产品多 term 时取最新一条)
|
||||
UPDATE pay_weight_band b
|
||||
INNER JOIN (
|
||||
SELECT t1.product_id, t1.term_id
|
||||
FROM pay_product_term t1
|
||||
INNER JOIN (
|
||||
SELECT product_id, MAX(term_id) AS term_id
|
||||
FROM pay_product_term
|
||||
GROUP BY product_id
|
||||
) t2 ON t2.product_id = t1.product_id AND t2.term_id = t1.term_id
|
||||
) t ON t.product_id = b.product_id
|
||||
SET b.term_id = t.term_id
|
||||
WHERE b.term_id IS NULL;
|
||||
|
||||
UPDATE pay_surcharge s
|
||||
INNER JOIN (
|
||||
SELECT t1.product_id, t1.term_id
|
||||
FROM pay_product_term t1
|
||||
INNER JOIN (
|
||||
SELECT product_id, MAX(term_id) AS term_id
|
||||
FROM pay_product_term
|
||||
GROUP BY product_id
|
||||
) t2 ON t2.product_id = t1.product_id AND t2.term_id = t1.term_id
|
||||
) t ON t.product_id = s.product_id
|
||||
SET s.term_id = t.term_id
|
||||
WHERE s.term_id IS NULL;
|
||||
|
||||
UPDATE pay_extra_line e
|
||||
INNER JOIN (
|
||||
SELECT t1.product_id, t1.term_id
|
||||
FROM pay_product_term t1
|
||||
INNER JOIN (
|
||||
SELECT product_id, MAX(term_id) AS term_id
|
||||
FROM pay_product_term
|
||||
GROUP BY product_id
|
||||
) t2 ON t2.product_id = t1.product_id AND t2.term_id = t1.term_id
|
||||
) t ON t.product_id = e.product_id
|
||||
SET e.term_id = t.term_id
|
||||
WHERE e.term_id IS NULL;
|
||||
|
||||
-- 6) 删除渠道映射上的套餐字段
|
||||
SET @exists := (
|
||||
SELECT COUNT(1) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'srv_channel_product_map'
|
||||
AND COLUMN_NAME = 'price_set_id'
|
||||
);
|
||||
SET @sql := IF(@exists > 0,
|
||||
'ALTER TABLE srv_channel_product_map DROP INDEX idx_channel_product_map_price_set, DROP COLUMN price_set_id',
|
||||
'SELECT 1');
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- ========== 三、应付配置菜单(price:pay:edit) ==========
|
||||
|
||||
SET @menuId := (SELECT menu_id FROM sys_menu WHERE perms = 'price:pay:list' LIMIT 1);
|
||||
|
||||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time)
|
||||
SELECT '应付配置修改', @menuId, 5, '', '', 1, 0, 'F', '0', '0', 'price:pay:edit', '#', 'admin', sysdate()
|
||||
WHERE @menuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'price:pay:edit');
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT DISTINCT rm.role_id, m.menu_id
|
||||
FROM sys_role_menu rm
|
||||
JOIN sys_menu src ON src.menu_id = rm.menu_id AND src.perms = 'price:pay:list'
|
||||
JOIN sys_menu m ON m.perms = 'price:pay:edit'
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM sys_role_menu x WHERE x.role_id = rm.role_id AND x.menu_id = m.menu_id
|
||||
);
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT 1, m.menu_id
|
||||
FROM sys_menu m
|
||||
WHERE m.perms = 'price:pay:edit'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM sys_role_menu x WHERE x.role_id = 1 AND x.menu_id = m.menu_id
|
||||
);
|
||||
|
||||
-- ========== 四、打单套餐菜单权限(挂在套餐管理下) ==========
|
||||
|
||||
SET @pkgParentId := (
|
||||
SELECT menu_id FROM sys_menu
|
||||
WHERE menu_id = 2200
|
||||
OR (menu_name = N'套餐管理' AND parent_id = 0 AND menu_type = 'M')
|
||||
ORDER BY CASE WHEN menu_id = 2200 THEN 0 ELSE 1 END, menu_id
|
||||
LIMIT 1
|
||||
);
|
||||
|
||||
-- 列表
|
||||
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 2620, N'打单套餐', @pkgParentId, 3, 'label', 'price/label/labelPackage', '', 'LabelPackage', 1, 0, 'C', '0', '0', 'price:label:list', 'list', 'admin', sysdate(), N'打单套餐列表'
|
||||
FROM DUAL WHERE @pkgParentId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2620 OR perms = 'price:label:list');
|
||||
|
||||
UPDATE sys_menu
|
||||
SET menu_name = N'打单套餐',
|
||||
parent_id = @pkgParentId,
|
||||
order_num = 3,
|
||||
path = 'label',
|
||||
component = 'price/label/labelPackage',
|
||||
route_name = 'LabelPackage',
|
||||
perms = 'price:label:list',
|
||||
remark = N'打单套餐列表',
|
||||
update_by = 'admin',
|
||||
update_time = sysdate()
|
||||
WHERE @pkgParentId IS NOT NULL AND (menu_id = 2620 OR perms = 'price:label:list');
|
||||
|
||||
-- 隐藏新建页
|
||||
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 2628, N'打单套餐新建', @pkgParentId, 7, 'labelCreate', 'price/label/create', '', 'LabelPackageCreate', 1, 0, 'C', '1', '0', 'price:label:add', '#', 'admin', sysdate(), N'打单套餐新建(基本信息+Excel导入)'
|
||||
FROM DUAL WHERE @pkgParentId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2628 OR path = 'labelCreate');
|
||||
|
||||
UPDATE sys_menu
|
||||
SET menu_name = N'打单套餐新建',
|
||||
parent_id = @pkgParentId,
|
||||
order_num = 7,
|
||||
path = 'labelCreate',
|
||||
component = 'price/label/create',
|
||||
route_name = 'LabelPackageCreate',
|
||||
perms = 'price:label:add',
|
||||
visible = '1',
|
||||
remark = N'打单套餐新建(基本信息+Excel导入)',
|
||||
update_by = 'admin',
|
||||
update_time = sysdate()
|
||||
WHERE @pkgParentId IS NOT NULL AND (menu_id = 2628 OR path = 'labelCreate');
|
||||
|
||||
-- 隐藏详情页
|
||||
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 2627, N'打单套餐详情', @pkgParentId, 8, 'labelDetail', 'price/label/detail', '', 'LabelPackageDetail', 1, 0, 'C', '1', '0', 'price:label:query', '#', 'admin', sysdate(), N'打单套餐产品明细'
|
||||
FROM DUAL WHERE @pkgParentId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2627 OR path = 'labelDetail');
|
||||
|
||||
UPDATE sys_menu
|
||||
SET menu_name = N'打单套餐详情',
|
||||
parent_id = @pkgParentId,
|
||||
order_num = 8,
|
||||
path = 'labelDetail',
|
||||
component = 'price/label/detail',
|
||||
route_name = 'LabelPackageDetail',
|
||||
perms = 'price:label:query',
|
||||
visible = '1',
|
||||
remark = N'打单套餐产品明细',
|
||||
update_by = 'admin',
|
||||
update_time = sysdate()
|
||||
WHERE @pkgParentId IS NOT NULL AND (menu_id = 2627 OR path = 'labelDetail');
|
||||
|
||||
-- 按钮
|
||||
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, remark)
|
||||
SELECT 2621, N'查询', 2620, 1, '', NULL, 1, 0, 'F', '0', '0', 'price:label:query', '#', 'admin', sysdate(), N''
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2621 OR (parent_id = 2620 AND perms = 'price:label:query' AND menu_type = 'F'));
|
||||
|
||||
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, remark)
|
||||
SELECT 2622, N'新增', 2620, 2, '', NULL, 1, 0, 'F', '0', '0', 'price:label:add', '#', 'admin', sysdate(), N''
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2622 OR (parent_id = 2620 AND perms = 'price:label:add' AND menu_type = 'F'));
|
||||
|
||||
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, remark)
|
||||
SELECT 2623, N'修改', 2620, 3, '', NULL, 1, 0, 'F', '0', '0', 'price:label:edit', '#', 'admin', sysdate(), N''
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2623 OR (parent_id = 2620 AND perms = 'price:label:edit' AND menu_type = 'F'));
|
||||
|
||||
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, remark)
|
||||
SELECT 2624, N'删除', 2620, 4, '', NULL, 1, 0, 'F', '0', '0', 'price:label:remove', '#', 'admin', sysdate(), N''
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2624 OR (parent_id = 2620 AND perms = 'price:label:remove' AND menu_type = 'F'));
|
||||
|
||||
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, remark)
|
||||
SELECT 2625, N'导入', 2620, 5, '', NULL, 1, 0, 'F', '0', '0', 'price:label:import', '#', 'admin', sysdate(), N''
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2625 OR (parent_id = 2620 AND perms = 'price:label:import' AND menu_type = 'F'));
|
||||
|
||||
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, remark)
|
||||
SELECT 2626, N'启停', 2620, 6, '', NULL, 1, 0, 'F', '0', '0', 'price:label:audit', '#', 'admin', sysdate(), N''
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2626 OR (parent_id = 2620 AND perms = 'price:label:audit' AND menu_type = 'F'));
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT 1, m.menu_id FROM (
|
||||
SELECT 2620 AS menu_id UNION SELECT 2621 UNION SELECT 2622
|
||||
UNION SELECT 2623 UNION SELECT 2624 UNION SELECT 2625 UNION SELECT 2626
|
||||
UNION SELECT 2627 UNION SELECT 2628
|
||||
) m
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu rm WHERE rm.role_id = 1 AND rm.menu_id = m.menu_id);
|
||||
@@ -1,54 +0,0 @@
|
||||
-- 应付产品有效期。同一产品多次导入各留一版,用这张表记录生效区间和是否生效。可重复执行。
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pay_product_term` (
|
||||
`term_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '有效期ID',
|
||||
`dict_value` varchar(100) NOT NULL COMMENT '产品字典值,同一产品的各版本归在一起',
|
||||
`product_id` bigint(20) NOT NULL COMMENT '这一版价格',
|
||||
`version_no` int(11) NOT NULL DEFAULT 1 COMMENT '版本号',
|
||||
`effective_start` date DEFAULT NULL COMMENT '生效开始',
|
||||
`effective_end` date DEFAULT NULL COMMENT '生效结束,空表示不限',
|
||||
`file_path` varchar(500) DEFAULT NULL COMMENT '这一版源文件OSS地址,oss://bucket/key',
|
||||
`status` char(1) NOT NULL DEFAULT '0' COMMENT '0生效 1失效',
|
||||
`created_by` varchar(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
|
||||
`updated_by` varchar(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
PRIMARY KEY (`term_id`),
|
||||
UNIQUE KEY `uk_pay_term_product` (`product_id`),
|
||||
KEY `idx_pay_term_dict` (`dict_value`, `status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='应付产品价格有效期';
|
||||
|
||||
-- 已有模板补一条生效记录,不覆盖后来手工改过的有效期
|
||||
INSERT INTO pay_product_term (
|
||||
dict_value, product_id, version_no, effective_start, status, created_by, create_time
|
||||
)
|
||||
SELECT ifnull(nullif(dict_value, ''), product_name), product_id, ifnull(version_no, 1), effective_date, '0',
|
||||
ifnull(created_by, ''), ifnull(create_time, sysdate())
|
||||
FROM pay_product p
|
||||
WHERE (p.channel_id IS NULL OR p.channel_id = '')
|
||||
AND NOT EXISTS (SELECT 1 FROM pay_product_term t WHERE t.product_id = p.product_id);
|
||||
|
||||
SET @menuId := (SELECT menu_id FROM sys_menu WHERE perms = 'price:pay:list' LIMIT 1);
|
||||
|
||||
INSERT INTO sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time)
|
||||
SELECT '应付配置修改', @menuId, 5, '', '', 1, 0, 'F', '0', '0', 'price:pay:edit', '#', 'admin', sysdate()
|
||||
WHERE @menuId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'price:pay:edit');
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT DISTINCT rm.role_id, m.menu_id
|
||||
FROM sys_role_menu rm
|
||||
JOIN sys_menu src ON src.menu_id = rm.menu_id AND src.perms = 'price:pay:list'
|
||||
JOIN sys_menu m ON m.perms = 'price:pay:edit'
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM sys_role_menu x WHERE x.role_id = rm.role_id AND x.menu_id = m.menu_id
|
||||
);
|
||||
|
||||
INSERT INTO sys_role_menu (role_id, menu_id)
|
||||
SELECT 1, m.menu_id
|
||||
FROM sys_menu m
|
||||
WHERE m.perms = 'price:pay:edit'
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM sys_role_menu x WHERE x.role_id = 1 AND x.menu_id = m.menu_id
|
||||
);
|
||||
Reference in New Issue
Block a user