客户批量绑定价格套餐

This commit is contained in:
wuweihua
2026-10-10 09:40:49 +08:00
parent 037d4b7cdf
commit 899589cf87
8 changed files with 358 additions and 1 deletions
@@ -116,6 +116,13 @@ public class BmsCustomer extends BaseEntity
@Excel(name = "绑定产品代码")
private String productCodes;
/** 已绑定价格套餐ID(join prc_customer_price_set,一个客户至多一个套餐;非表字段,仅展示) */
private Long priceSetId;
/** 已绑定价格套餐名称(join prc_price_set;非表字段,仅展示) */
@Excel(name = "绑定套餐")
private String priceSetName;
/** 附件列表(子表 ctr_customer_attachment) */
private List<BmsCustomerAttachment> attachmentList;
@@ -0,0 +1,44 @@
package com.bms.customer.customerinfo.domain;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.bms.common.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 客户套餐批量绑定入参(客户管理列表-批量绑定套餐)
*
* @author bms
* @date 2026-10-10
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BmsCustomerPriceSetBatch extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 待绑定客户ID集合 */
private List<Long> customerIds;
/** 价格套餐ID */
private Long priceSetId;
/** 绑定优先级,数字越小越优先 */
private Integer bindPriority;
/** 绑定生效日期 */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date prBegindate;
/** 绑定失效日期(空=长期) */
@JsonFormat(pattern = "yyyy-MM-dd")
private Date prEnddate;
/** 绑定备注 */
private String priceSetNote;
/** 已绑定套餐的客户是否覆盖更换(false=跳过,true=更换为本次套餐) */
private Boolean overwriteExisting;
}
@@ -2,6 +2,7 @@ package com.bms.customer.customerinfo.service;
import java.util.List;
import com.bms.customer.customerinfo.domain.BmsCustomerPriceSet;
import com.bms.customer.customerinfo.domain.BmsCustomerPriceSetBatch;
import com.bms.customer.customerinfo.domain.BmsPriceSetOption;
/**
@@ -23,6 +24,12 @@ public interface IBmsCustomerPriceSetService
*/
public int saveBind(BmsCustomerPriceSet bind);
/**
* 批量绑定套餐:未绑定的客户新增;已绑定客户按 overwriteExisting 决定更换或跳过。
* 返回执行结果摘要文案。
*/
public String batchBind(BmsCustomerPriceSetBatch req);
/** 按绑定主键解绑 */
public int deleteBindByIds(Long[] customerPricesetIds);
}
@@ -7,6 +7,7 @@ import org.springframework.stereotype.Service;
import com.bms.common.exception.ServiceException;
import com.bms.customer.customerinfo.domain.BmsCustomer;
import com.bms.customer.customerinfo.domain.BmsCustomerPriceSet;
import com.bms.customer.customerinfo.domain.BmsCustomerPriceSetBatch;
import com.bms.customer.customerinfo.domain.BmsPriceSetOption;
import com.bms.customer.customerinfo.mapper.BmsCustomerPriceSetMapper;
import com.bms.customer.customerinfo.service.IBmsCustomerLogService;
@@ -122,6 +123,99 @@ public class BmsCustomerPriceSetServiceImpl implements IBmsCustomerPriceSetServi
return rows;
}
@Override
@org.springframework.transaction.annotation.Transactional(rollbackFor = Exception.class)
public String batchBind(BmsCustomerPriceSetBatch req)
{
if (req == null || req.getCustomerIds() == null || req.getCustomerIds().isEmpty())
{
throw new ServiceException("请先勾选要绑定套餐的客户");
}
if (req.getPriceSetId() == null)
{
throw new ServiceException("请选择要绑定的套餐");
}
BmsPriceSetOption set = bindMapper.selectPriceSetOptionById(req.getPriceSetId());
if (set == null)
{
throw new ServiceException("所选套餐不存在");
}
if (!"E".equals(set.getStatus()))
{
throw new ServiceException("仅生效中的套餐允许绑定,当前套餐状态不可用");
}
if (req.getPrBegindate() == null)
{
throw new ServiceException("绑定生效日期不能为空");
}
if (req.getPrEnddate() != null && req.getPrBegindate().after(req.getPrEnddate()))
{
throw new ServiceException("失效日期不能早于生效日期");
}
Integer priority = (req.getBindPriority() == null || req.getBindPriority() < 1) ? 1 : req.getBindPriority();
boolean overwrite = Boolean.TRUE.equals(req.getOverwriteExisting());
// 去重,保持勾选顺序
List<Long> customerIds = req.getCustomerIds().stream().distinct().collect(java.util.stream.Collectors.toList());
int inserted = 0, replaced = 0, skipped = 0;
List<String> skippedNames = new java.util.ArrayList<>();
for (Long customerId : customerIds)
{
BmsCustomer customer = customerService.selectBmsCustomerByCustomerId(customerId);
if (customer == null)
{
skipped++;
skippedNames.add("ID:" + customerId + "(不存在)");
continue;
}
BmsCustomerPriceSet existing = bindMapper.selectBindByCustomerId(customerId);
if (existing != null && !overwrite)
{
skipped++;
skippedNames.add(customer.getCustomerName());
continue;
}
BmsCustomerPriceSet bind = new BmsCustomerPriceSet();
bind.setCustomerId(customerId);
bind.setPriceSetId(req.getPriceSetId());
bind.setBindPriority(priority);
bind.setPrBegindate(req.getPrBegindate());
bind.setPrEnddate(req.getPrEnddate());
bind.setPriceSetNote(req.getPriceSetNote());
bind.setCreateBy(req.getCreateBy());
bind.setUpdateBy(req.getUpdateBy());
// saveBind 内部完成客户/套餐校验、新增或更新、业务操作日志记录
saveBind(bind);
if (existing != null)
{
replaced++;
}
else
{
inserted++;
}
}
StringBuilder msg = new StringBuilder();
msg.append("批量绑定完成:共 ").append(customerIds.size()).append(" 个客户,新绑定 ")
.append(inserted).append(" 个");
if (overwrite)
{
msg.append(",更换 ").append(replaced).append(" 个");
}
msg.append(",跳过 ").append(skipped).append(" 个");
if (skipped > 0 && !overwrite)
{
String names = skippedNames.stream().limit(10).collect(java.util.stream.Collectors.joining("、"));
msg.append("(已绑定套餐:").append(names);
if (skippedNames.size() > 10)
{
msg.append(" 等");
}
msg.append(",如需更换请勾选覆盖选项)");
}
return msg.toString();
}
@Override
public int deleteBindByIds(Long[] customerPricesetIds)
{