优化套餐编辑逻辑

This commit is contained in:
wuweihua
2026-10-21 14:51:44 +08:00
parent 26a3285571
commit 1e8a449dda
11 changed files with 217 additions and 111 deletions
@@ -30,6 +30,9 @@ public interface PrcPriceSetDetailMapper
public int deletePrcPriceSetDetailByPsvId(Long psvId);
/** Hard delete detail rows by ids (draft / pending). */
public int physicalDeleteByIds(Long[] psdIds);
/** Hard delete all detail rows under a version. */
public int physicalDeleteByPsvId(@Param("psvId") Long psvId);
@@ -23,6 +23,9 @@ public interface PrcPriceSetProductMapper
public int deleteByPsvIdAndCode(@Param("psvId") Long psvId, @Param("productCode") String productCode);
/** Hard delete one product under a version (draft / pending). */
public int physicalDeleteByPsvIdAndCode(@Param("psvId") Long psvId, @Param("productCode") String productCode);
/** Hard delete all product rows under a version. */
public int physicalDeleteByPsvId(@Param("psvId") Long psvId);
@@ -35,6 +35,16 @@ public interface PrcSurchargeRelMapper
@Param("productIds") List<Long> productIds,
@Param("priceType") String priceType);
/** Hard delete surcharge rows by detail ids (draft / pending). */
public int physicalDeleteByDetailIdsAndPriceType(
@Param("detailIds") List<Long> detailIds,
@Param("priceType") String priceType);
/** Hard delete surcharge rows by set-product ids (draft / pending). */
public int physicalDeleteByProductIdsAndPriceType(
@Param("productIds") List<Long> productIds,
@Param("priceType") String priceType);
/** Hard delete surcharge rows linked to products/details under a version. */
public int physicalDeleteByPsvId(@Param("psvId") Long psvId);
@@ -547,9 +547,8 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
throw new ServiceException(MessageUtils.message("price.set.version.delete.statusNotAllowed"));
}
requireSet(version.getPriceSetId());
deleteSalesRelsByPsvId(psvId);
detailMapper.deletePrcPriceSetDetailByPsvId(psvId);
setProductMapper.deleteByPsvId(psvId);
// Draft / pending only reach here: hard-delete children with the version row
wipeVersionChildren(psvId, version.getStatus());
int rows = versionMapper.deletePrcPriceSetVersionByIds(new Long[] { psvId });
// Rechain expire_time / status for remaining versions (e.g. reopen previous effect window)
refreshVersionStatus(version.getPriceSetId());
@@ -1506,7 +1505,8 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
if (!deleteIds.isEmpty())
{
detailMapper.deletePrcPriceSetDetailByIds(deleteIds.toArray(new Long[0]));
// Draft/pending: hard delete covered rows; effect/expired: soft delete.
deleteDetailRowsByIds(deleteIds, isDraftOrPendingVersionStatus(resolveVersionStatus(psvId)));
}
removeDetailsByReplaceScopes(details, detailIndex, replaceScopes);
}
@@ -2122,9 +2122,20 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
@Override
public int deleteDetailByIds(Long[] psdIds)
{
Set<String> touchKeys = new HashSet<String>();
if (psdIds == null || psdIds.length == 0)
{
return 0;
}
List<Long> hardIds = new ArrayList<Long>();
List<Long> softIds = new ArrayList<Long>();
Set<String> hardTouchKeys = new HashSet<String>();
Set<String> softTouchKeys = new HashSet<String>();
for (Long id : psdIds)
{
if (id == null)
{
continue;
}
PrcPriceSetDetail old = detailMapper.selectPrcPriceSetDetailById(id);
if (old == null)
{
@@ -2132,27 +2143,84 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
PrcPriceSet db = requireSet(resolvePriceSetIdByPsvId(old.getPsvId()));
assertChildEditable(db);
if (old.getPsvId() != null && StringUtils.isNotEmpty(old.getProductCode()))
boolean hard = isDraftOrPendingVersionStatus(resolveVersionStatus(old.getPsvId()));
if (hard)
{
touchKeys.add(old.getPsvId() + "|" + old.getProductCode());
}
}
if (psdIds != null && psdIds.length > 0)
{
List<Long> ids = new ArrayList<Long>();
for (Long id : psdIds)
{
if (id != null)
hardIds.add(id);
if (old.getPsvId() != null && StringUtils.isNotEmpty(old.getProductCode()))
{
ids.add(id);
hardTouchKeys.add(old.getPsvId() + "|" + old.getProductCode());
}
}
if (!ids.isEmpty())
else
{
surchargeRelMapper.deleteByDetailIdsAndPriceType(ids, PrcSurchargeRel.PRICE_TYPE_SALES);
softIds.add(id);
if (old.getPsvId() != null && StringUtils.isNotEmpty(old.getProductCode()))
{
softTouchKeys.add(old.getPsvId() + "|" + old.getProductCode());
}
}
}
int rows = detailMapper.deletePrcPriceSetDetailByIds(psdIds);
int rows = 0;
if (!hardIds.isEmpty())
{
rows += deleteDetailRowsByIds(hardIds, true);
cleanupOrphanSetProducts(hardTouchKeys, true);
}
if (!softIds.isEmpty())
{
rows += deleteDetailRowsByIds(softIds, false);
cleanupOrphanSetProducts(softTouchKeys, false);
}
return rows;
}
/**
* Delete detail rows (+ SALES surcharge rels).
* hard=true: physical delete (draft/pending); false: soft delete (effect/expired).
*/
private int deleteDetailRowsByIds(List<Long> ids, boolean hard)
{
if (ids == null || ids.isEmpty())
{
return 0;
}
Long[] arr = ids.toArray(new Long[0]);
if (hard)
{
surchargeRelMapper.physicalDeleteByDetailIdsAndPriceType(ids, PrcSurchargeRel.PRICE_TYPE_SALES);
return detailMapper.physicalDeleteByIds(arr);
}
surchargeRelMapper.deleteByDetailIdsAndPriceType(ids, PrcSurchargeRel.PRICE_TYPE_SALES);
return detailMapper.deletePrcPriceSetDetailByIds(arr);
}
/** Version status draft(0) / pending(3): hard delete children. */
private boolean isDraftOrPendingVersionStatus(String status)
{
return VER_DRAFT.equals(status) || VER_PENDING.equals(status);
}
private String resolveVersionStatus(Long psvId)
{
if (psvId == null)
{
return null;
}
PrcPriceSetVersion ver = versionMapper.selectPrcPriceSetVersionById(psvId);
return ver == null ? null : ver.getStatus();
}
/**
* After detail delete: if no detail left for product, remove set-product + its SALES rels.
* hard=true uses physical delete (draft/pending); otherwise soft delete (effect/expired).
*/
private void cleanupOrphanSetProducts(Set<String> touchKeys, boolean hard)
{
if (touchKeys == null || touchKeys.isEmpty())
{
return;
}
for (String key : touchKeys)
{
int sep = key.indexOf('|');
@@ -2166,18 +2234,51 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
q.setPsvId(psvId);
q.setProductCode(productCode);
List<PrcPriceSetDetail> left = detailMapper.selectPrcPriceSetDetailList(q);
if (left == null || left.isEmpty())
if (left != null && !left.isEmpty())
{
Long pspId = lookupSetProductId(psvId, productCode);
if (pspId != null)
continue;
}
Long pspId = lookupSetProductId(psvId, productCode);
if (pspId != null)
{
List<Long> pspIds = java.util.Collections.singletonList(pspId);
if (hard)
{
surchargeRelMapper.deleteByProductIdsAndPriceType(
java.util.Collections.singletonList(pspId), PrcSurchargeRel.PRICE_TYPE_SALES);
surchargeRelMapper.physicalDeleteByProductIdsAndPriceType(pspIds, PrcSurchargeRel.PRICE_TYPE_SALES);
}
else
{
surchargeRelMapper.deleteByProductIdsAndPriceType(pspIds, PrcSurchargeRel.PRICE_TYPE_SALES);
}
}
if (hard)
{
setProductMapper.physicalDeleteByPsvIdAndCode(psvId, productCode);
}
else
{
setProductMapper.deleteByPsvIdAndCode(psvId, productCode);
}
}
return rows;
}
/** Wipe version products/details/SALES rels: physical for draft/pending, soft otherwise. */
private void wipeVersionChildren(Long psvId, String versionStatus)
{
if (psvId == null)
{
return;
}
if (isDraftOrPendingVersionStatus(versionStatus))
{
surchargeRelMapper.physicalDeleteByPsvId(psvId);
detailMapper.physicalDeleteByPsvId(psvId);
setProductMapper.physicalDeleteByPsvId(psvId);
return;
}
deleteSalesRelsByPsvId(psvId);
detailMapper.deletePrcPriceSetDetailByPsvId(psvId);
setProductMapper.deleteByPsvId(psvId);
}
@Override
@@ -3207,9 +3308,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
return;
}
Long psvId = db.getPsvId();
deleteSalesRelsByPsvId(psvId);
detailMapper.deletePrcPriceSetDetailByPsvId(psvId);
setProductMapper.deleteByPsvId(psvId);
wipeVersionChildren(psvId, db.getStatus());
if ("IMPORT".equalsIgnoreCase(newMode))
{
copyLatestPriorVersionChildren(db.getPriceSetId(), psvId);
@@ -3332,9 +3431,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
set.setDetails(new ArrayList<PrcPriceSetDetail>());
return;
}
deleteSalesRelsByPsvId(version.getPsvId());
detailMapper.deletePrcPriceSetDetailByPsvId(version.getPsvId());
setProductMapper.deleteByPsvId(version.getPsvId());
wipeVersionChildren(version.getPsvId(), version.getStatus());
// clean legacy rows without psv_id under this set (would look like duplicates in UI)
detailMapper.deleteOrphanDetailsByPriceSetId(set.getPriceSetId());
int productRows = setProductMapper.insertFromLibrary(version.getPsvId());
@@ -3481,8 +3578,7 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
}
if (!orphanIds.isEmpty())
{
surchargeRelMapper.deleteByDetailIdsAndPriceType(orphanIds, PrcSurchargeRel.PRICE_TYPE_SALES);
detailMapper.deletePrcPriceSetDetailByIds(orphanIds.toArray(new Long[0]));
deleteDetailRowsByIds(orphanIds, isDraftOrPendingVersionStatus(version.getStatus()));
}
Set<String> keepCodes = new HashSet<String>();
if (details != null)
@@ -426,6 +426,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</update>
<delete id="physicalDeleteByIds" parameterType="Long">
delete from prc_price_set_detail
where psd_id in
<foreach item="psdId" collection="array" open="(" separator="," close=")">
#{psdId}
</foreach>
</delete>
<update id="deletePrcPriceSetDetailByPriceSetId" parameterType="Long">
update prc_price_set_detail d
inner join prc_price_set_version v on v.psv_id = d.psv_id
@@ -105,6 +105,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and ifnull(is_del, '0') = '0'
</update>
<delete id="physicalDeleteByPsvIdAndCode">
delete from prc_price_set_product
where psv_id = #{psvId}
and product_code = #{productCode}
</delete>
<insert id="copyFromVersion">
insert into prc_price_set_product (
price_type, psv_id, product_code, product_name, service_level, cargo_attr,
@@ -136,6 +136,24 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</update>
<delete id="physicalDeleteByDetailIdsAndPriceType">
delete from prc_surcharge_rel
where price_type = #{priceType}
and detail_id in
<foreach item="id" collection="detailIds" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<delete id="physicalDeleteByProductIdsAndPriceType">
delete from prc_surcharge_rel
where price_type = #{priceType}
and product_id in
<foreach item="id" collection="productIds" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
<delete id="physicalDeleteByPsvId">
delete r from prc_surcharge_rel r
where exists (