From 8ed7b3146b1c96562562d0cc099ac68e7f2d4dbf Mon Sep 17 00:00:00 2001 From: wuweihua <88888888> Date: Wed, 28 Oct 2026 18:10:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A5=97=E9=A4=90=E8=A7=84?= =?UTF-8?q?=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/price/ProductController.java | 8 +- .../price/RedlineProductController.java | 8 +- .../main/resources/i18n/messages.properties | 2 +- .../bms/price/domain/PrcPriceSetVersion.java | 2 + .../mapper/PrcPriceSetVersionMapper.java | 3 + .../price/mapper/PrcSurchargeRelMapper.java | 3 + .../service/impl/PrcPriceSetServiceImpl.java | 23 +- .../support/CatalogVersionSupport.java | 113 ++++++++- .../mapper/price/PrcPriceSetVersionMapper.xml | 19 +- .../mapper/price/PrcSurchargeRelMapper.xml | 16 ++ bms-back/sql/bms_init.sql | 4 +- .../prc_price_set_version_is_del_alter.sql | 13 + .../components/CatalogActivateDialog.vue | 2 +- .../basic/components/CatalogPriceCreate.vue | 6 +- .../CatalogVersionProductsDrawer.vue | 11 +- .../basic/components/CatalogVersionTable.vue | 206 +++++++++++++++ .../src/views/price/basic/product/index.vue | 234 ++++-------------- .../src/views/price/basic/redline/index.vue | 231 ++++------------- .../set/components/detail/SetVersionTable.vue | 13 +- bms-front/src/views/price/set/detail.vue | 26 +- .../src/views/price/set/utils/priceSet.js | 4 + 21 files changed, 536 insertions(+), 411 deletions(-) create mode 100644 bms-back/sql/price/prc_price_set_version_is_del_alter.sql create mode 100644 bms-front/src/views/price/basic/components/CatalogVersionTable.vue diff --git a/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/ProductController.java b/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/ProductController.java index 7fd50e29..b022c9c4 100644 --- a/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/ProductController.java +++ b/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/ProductController.java @@ -139,8 +139,8 @@ public class ProductController extends BaseController return success(); } - /** Persist create-page preview details into draft/pending version. */ - @PreAuthorize("@ss.hasPermi('price:product:add')") + /** Persist create-page preview details into draft/pending/effect version. */ + @PreAuthorize("@ss.hasPermi('price:product:add') or @ss.hasPermi('price:product:edit')") @Log(title = "product preview apply", businessType = BusinessType.UPDATE) @PostMapping("/version/applyPreview") public AjaxResult applyPreview(@RequestBody CatalogPreviewApplyRequest body) @@ -149,7 +149,7 @@ public class ProductController extends BaseController } /** Async parallel save of create-page preview. Returns taskId; poll /import/task/{taskId}. */ - @PreAuthorize("@ss.hasPermi('price:product:add')") + @PreAuthorize("@ss.hasPermi('price:product:add') or @ss.hasPermi('price:product:edit')") @Log(title = "product preview apply", businessType = BusinessType.UPDATE) @PostMapping("/version/applyPreviewAsync") public AjaxResult applyPreviewAsync(@RequestBody CatalogPreviewApplyRequest body) @@ -160,7 +160,7 @@ public class ProductController extends BaseController return success(payload); } - /** Save import Excel attachment onto a draft/pending version (prc_price_excel_file). */ + /** Save import Excel attachment onto a draft/pending/effect version (prc_price_excel_file). */ @PreAuthorize("@ss.hasPermi('price:product:import')") @Log(title = "product version excel", businessType = BusinessType.IMPORT) @PostMapping("/version/{psvId}/excel") diff --git a/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/RedlineProductController.java b/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/RedlineProductController.java index 76515a24..950c3fd8 100644 --- a/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/RedlineProductController.java +++ b/bms-back/bms-admin/src/main/java/com/bms/web/controller/price/RedlineProductController.java @@ -139,8 +139,8 @@ public class RedlineProductController extends BaseController return success(); } - /** Persist create-page preview details into draft/pending version. */ - @PreAuthorize("@ss.hasPermi('price:redline:add')") + /** Persist create-page preview details into draft/pending/effect version. */ + @PreAuthorize("@ss.hasPermi('price:redline:add') or @ss.hasPermi('price:redline:edit')") @Log(title = "redline preview apply", businessType = BusinessType.UPDATE) @PostMapping("/version/applyPreview") public AjaxResult applyPreview(@RequestBody RedlineCatalogPreviewApplyRequest body) @@ -149,7 +149,7 @@ public class RedlineProductController extends BaseController } /** Async parallel save of create-page preview. Returns taskId; poll /import/task/{taskId}. */ - @PreAuthorize("@ss.hasPermi('price:redline:add')") + @PreAuthorize("@ss.hasPermi('price:redline:add') or @ss.hasPermi('price:redline:edit')") @Log(title = "redline preview apply", businessType = BusinessType.UPDATE) @PostMapping("/version/applyPreviewAsync") public AjaxResult applyPreviewAsync(@RequestBody RedlineCatalogPreviewApplyRequest body) @@ -160,7 +160,7 @@ public class RedlineProductController extends BaseController return success(payload); } - /** Save import Excel attachment onto a draft/pending version (prc_price_excel_file). */ + /** Save import Excel attachment onto a draft/pending/effect version (prc_price_excel_file). */ @PreAuthorize("@ss.hasPermi('price:redline:import')") @Log(title = "redline version excel", businessType = BusinessType.IMPORT) @PostMapping("/version/{psvId}/excel") diff --git a/bms-back/bms-admin/src/main/resources/i18n/messages.properties b/bms-back/bms-admin/src/main/resources/i18n/messages.properties index 71e2cfb9..140ebd22 100644 --- a/bms-back/bms-admin/src/main/resources/i18n/messages.properties +++ b/bms-back/bms-admin/src/main/resources/i18n/messages.properties @@ -207,7 +207,7 @@ price.set.version.effectiveTime.empty=版本生效时间不能为空 price.set.version.effectiveTime.beforePrev=生效时间不能早于上一版本的生效时间 price.set.version.notExists=套餐版本不存在 price.set.version.activate.statusNotAllowed=仅草稿或待生效版本可设置生效时间 -price.set.version.delete.statusNotAllowed=仅草稿或待生效版本可删除 +price.set.version.delete.statusNotAllowed=仅草稿、待生效或已生效版本可删除 price.set.version.copy.draftExists=已有草稿版本,请先启动或删除后再复制 price.set.version.create.draftExists=已有草稿版本,请先启动或删除后再新建 price.set.save.task.notExists=保存任务不存在或已过期 diff --git a/bms-back/bms-system/src/main/java/com/bms/price/domain/PrcPriceSetVersion.java b/bms-back/bms-system/src/main/java/com/bms/price/domain/PrcPriceSetVersion.java index 3a389328..e69aa7ea 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/domain/PrcPriceSetVersion.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/domain/PrcPriceSetVersion.java @@ -33,6 +33,8 @@ public class PrcPriceSetVersion extends BaseEntity * Column: price_build_mode */ private String priceBuildMode; + /** 0 normal / 1 soft-deleted */ + private String isDel; private List details; private List products; diff --git a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetVersionMapper.java b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetVersionMapper.java index 8ebf66e5..6041f2e0 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetVersionMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcPriceSetVersionMapper.java @@ -30,6 +30,9 @@ public interface PrcPriceSetVersionMapper public int deletePrcPriceSetVersionByIds(Long[] psvIds); + /** Soft-delete catalog/sales version row (is_del=1). */ + public int softDeleteById(@Param("psvId") Long psvId, @Param("updateBy") String updateBy); + public int deletePrcPriceSetVersionByPriceSetId(Long priceSetId); public List selectPriceSetIds(); diff --git a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcSurchargeRelMapper.java b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcSurchargeRelMapper.java index 05913f22..dee5784d 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcSurchargeRelMapper.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/mapper/PrcSurchargeRelMapper.java @@ -48,6 +48,9 @@ public interface PrcSurchargeRelMapper /** Hard delete surcharge rows linked to products/details under a version. */ public int physicalDeleteByPsvId(@Param("psvId") Long psvId); + /** Soft-delete surcharge rows linked to products/details under a version. */ + public int softDeleteByPsvId(@Param("psvId") Long psvId); + /** 附加费版本化编辑后,把产品关联从旧记录重指向新记录 */ public int rebindRelScId(@Param("oldScId") Long oldScId, @Param("newScId") Long newScId, @Param("operator") String operator); } diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcPriceSetServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcPriceSetServiceImpl.java index b3b7857a..5e66c17b 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcPriceSetServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcPriceSetServiceImpl.java @@ -546,16 +546,29 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService { throw new ServiceException(MessageUtils.message("price.set.version.notExists")); } - // Draft and pending versions may be deleted; effect/expired cannot. - if (!VER_DRAFT.equals(version.getStatus()) && !VER_PENDING.equals(version.getStatus())) + if ("1".equals(version.getIsDel())) + { + throw new ServiceException(MessageUtils.message("price.set.version.notExists")); + } + // Draft / pending: hard delete; EFFECT: soft delete then reopen previous via refreshVersionStatus + if (!VER_DRAFT.equals(version.getStatus()) + && !VER_PENDING.equals(version.getStatus()) + && !VER_EFFECT.equals(version.getStatus())) { throw new ServiceException(MessageUtils.message("price.set.version.delete.statusNotAllowed")); } requireSet(version.getPriceSetId()); - // 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) + int rows; + if (VER_EFFECT.equals(version.getStatus())) + { + rows = versionMapper.softDeleteById(psvId, updateBy); + } + else + { + rows = versionMapper.deletePrcPriceSetVersionByIds(new Long[] { psvId }); + } + // Rechain expire_time / status for remaining versions (reopen previous effect window) refreshVersionStatus(version.getPriceSetId()); return rows; } diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/support/CatalogVersionSupport.java b/bms-back/bms-system/src/main/java/com/bms/price/service/support/CatalogVersionSupport.java index 6370e452..f85cffdf 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/support/CatalogVersionSupport.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/support/CatalogVersionSupport.java @@ -193,8 +193,9 @@ public class CatalogVersionSupport } /** - * Hard-delete draft/pending catalog version with products, details, - * surcharge links and excel attachments. + * Delete catalog version: + * - draft / pending: hard-delete version + children + excel + * - effect: soft-delete version + products + details (+ surcharge rel) */ public int deleteDraftVersion(Long psvId) { @@ -204,9 +205,17 @@ public class CatalogVersionSupport throw new ServiceException("版本不存在"); } assertCatalogType(ver.getPriceType()); + if ("1".equals(ver.getIsDel())) + { + throw new ServiceException("版本已删除"); + } + if (STATUS_EFFECT.equals(ver.getStatus())) + { + return softDeleteEffectVersion(ver); + } if (!STATUS_DRAFT.equals(ver.getStatus()) && !STATUS_PENDING.equals(ver.getStatus())) { - throw new ServiceException("仅草稿或待生效版本可以删除"); + throw new ServiceException("仅草稿、待生效或已生效版本可以删除"); } surchargeRelMapper.physicalDeleteByPsvId(psvId); detailMapper.physicalDeleteByPsvId(psvId); @@ -215,6 +224,89 @@ public class CatalogVersionSupport return versionMapper.deletePrcPriceSetVersionByIds(new Long[] { psvId }); } + /** + * Soft-delete EFFECT version with products and details, + * then reopen the previous version as EFFECT (clear expire_time; + * product/detail expire cleared via syncEffect). + */ + private int softDeleteEffectVersion(PrcPriceSetVersion ver) + { + Long psvId = ver.getPsvId(); + String priceType = ver.getPriceType(); + surchargeRelMapper.softDeleteByPsvId(psvId); + detailMapper.deletePrcPriceSetDetailByPsvId(psvId); + productMapper.deleteByPsvId(psvId); + int rows = versionMapper.softDeleteById(psvId, null); + + PrcPriceSetVersion prev = findPreviousVersionToRestore(ver); + if (prev != null) + { + prev.setExpireTime(null); + prev.setStatus(STATUS_EFFECT); + versionMapper.updatePrcPriceSetVersion(prev); + } + refreshCatalogStatuses(priceType); + return rows; + } + + /** + * Previous catalog version (highest version_seq below deleted) that can become EFFECT again. + * Prefers expired/effect rows that already had an effective_time. + */ + private PrcPriceSetVersion findPreviousVersionToRestore(PrcPriceSetVersion deleted) + { + if (deleted == null || deleted.getPriceType() == null) + { + return null; + } + PrcPriceSetVersion q = new PrcPriceSetVersion(); + q.setPriceType(deleted.getPriceType()); + List list = versionMapper.selectPrcPriceSetVersionList(q); + if (list == null || list.isEmpty()) + { + return null; + } + int curSeq = deleted.getVersionSeq() == null ? 0 : deleted.getVersionSeq().intValue(); + PrcPriceSetVersion best = null; + int bestSeq = Integer.MIN_VALUE; + Date now = new Date(); + for (PrcPriceSetVersion v : list) + { + if (v == null || v.getPsvId() == null) + { + continue; + } + if (deleted.getPsvId() != null && deleted.getPsvId().equals(v.getPsvId())) + { + continue; + } + if (v.getEffectiveTime() == null) + { + continue; + } + // Skip future pending drafts: they are not "previous" effective windows + if (STATUS_PENDING.equals(v.getStatus()) && v.getEffectiveTime().after(now)) + { + continue; + } + if (STATUS_DRAFT.equals(v.getStatus())) + { + continue; + } + int seq = v.getVersionSeq() == null ? 0 : v.getVersionSeq().intValue(); + if (seq >= curSeq) + { + continue; + } + if (seq > bestSeq) + { + bestSeq = seq; + best = v; + } + } + return best; + } + /** Current draft version (status=0), or null. */ public PrcPriceSetVersion currentDraft(String priceType) { @@ -222,7 +314,10 @@ public class CatalogVersionSupport return drafts.isEmpty() ? null : drafts.get(0); } - /** Draft/pending catalog version that can accept preview apply / edit. */ + /** + * Catalog version that can accept preview apply / Excel attach / edit. + * Same as sales force-edit: draft, pending, and effect are writable. + */ public PrcPriceSetVersion requireEditableCatalogVersion(Long psvId, String priceType) { PrcPriceSetVersion ver = versionMapper.selectPrcPriceSetVersionById(psvId); @@ -235,9 +330,15 @@ public class CatalogVersionSupport { throw new ServiceException("版本类型不匹配"); } - if (!STATUS_DRAFT.equals(ver.getStatus()) && !STATUS_PENDING.equals(ver.getStatus())) + if ("1".equals(ver.getIsDel())) { - throw new ServiceException("仅草稿或待生效版本可以编辑"); + throw new ServiceException("版本已删除"); + } + if (!STATUS_DRAFT.equals(ver.getStatus()) + && !STATUS_PENDING.equals(ver.getStatus()) + && !STATUS_EFFECT.equals(ver.getStatus())) + { + throw new ServiceException("仅草稿、待生效或已生效版本可以编辑"); } return ver; } diff --git a/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetVersionMapper.xml b/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetVersionMapper.xml index a25414b2..8b3de3b7 100644 --- a/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetVersionMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/price/PrcPriceSetVersionMapper.xml @@ -14,6 +14,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -24,7 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select psv_id, price_set_id, price_type, version_no, version_seq, effective_time, expire_time, status, - price_build_mode, created_by, create_time, updated_by, update_time + price_build_mode, is_del, created_by, create_time, updated_by, update_time from prc_price_set_version @@ -36,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select v.psv_id, v.price_set_id, v.price_type, v.version_no, v.version_seq, - v.effective_time, v.expire_time, v.status, v.price_build_mode, + v.effective_time, v.expire_time, v.status, v.price_build_mode, v.is_del, v.created_by, v.create_time, v.updated_by, v.update_time, (select count(1) from prc_price_set_product p where p.psv_id = v.psv_id and ifnull(p.is_del, '0') = '0') as product_count, @@ -66,6 +68,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from prc_price_set_version v where v.price_set_id is null and v.price_type = #{priceType} + and ifnull(v.is_del, '0') = '0' and v.status in ('0', '3') @@ -162,6 +165,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where price_type = 'SALES' and price_set_id = #{priceSetId} + and ifnull(is_del, '0') = '0' and effective_time is not null and effective_time <= #{asOf} and (expire_time is null or expire_time > #{asOf}) @@ -173,6 +177,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where price_type = #{priceType} and price_set_id is null + and ifnull(is_del, '0') = '0' and effective_time is not null and effective_time <= #{asOf} and (expire_time is null or expire_time > #{asOf}) @@ -180,6 +185,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" limit 1 + + update prc_price_set_version + set is_del = '1', + updated_by = #{updateBy}, + update_time = sysdate() + where psv_id = #{psvId} + and ifnull(is_del, '0') = '0' + + update prc_price_set_version set status = case @@ -191,6 +205,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update_time = sysdate() where price_type = #{priceType} and price_set_id is null + and ifnull(is_del, '0') = '0' and status in ('0','1','2','3') diff --git a/bms-back/bms-system/src/main/resources/mapper/price/PrcSurchargeRelMapper.xml b/bms-back/bms-system/src/main/resources/mapper/price/PrcSurchargeRelMapper.xml index 0715215e..a2863c86 100644 --- a/bms-back/bms-system/src/main/resources/mapper/price/PrcSurchargeRelMapper.xml +++ b/bms-back/bms-system/src/main/resources/mapper/price/PrcSurchargeRelMapper.xml @@ -166,6 +166,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ) + + update prc_surcharge_rel r + set r.is_del = '1', r.update_time = sysdate() + where ifnull(r.is_del, '0') = '0' + and ( + exists ( + select 1 from prc_price_set_product p + where p.psp_id = r.product_id and p.psv_id = #{psvId} + ) + or exists ( + select 1 from prc_price_set_detail d + where d.psd_id = r.detail_id and d.psv_id = #{psvId} + ) + ) + + update prc_surcharge_rel diff --git a/bms-back/sql/bms_init.sql b/bms-back/sql/bms_init.sql index 28664879..de787531 100644 --- a/bms-back/sql/bms_init.sql +++ b/bms-back/sql/bms_init.sql @@ -1315,6 +1315,7 @@ CREATE TABLE `prc_price_set_version` ( `expire_time` datetime DEFAULT NULL COMMENT '失效时间(空=长期;下一版本启动时写入该启动时间)', `status` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '0 draft 3 pending 1 effect 2 expired', `price_build_mode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建价格方式 PULL=拉取产品库 IMPORT=Excel导入', + `is_del` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否删除 0未删除 1已删除', `created_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `updated_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新人', @@ -1324,7 +1325,8 @@ CREATE TABLE `prc_price_set_version` ( UNIQUE KEY `uk_psv_type_set_seq` (`price_type`,`price_set_id_key`,`version_seq`), KEY `idx_psv_set_eff` (`price_set_id`,`effective_time`), KEY `idx_psv_type_eff` (`price_type`,`status`,`effective_time`), - KEY `idx_psv_status` (`status`) + KEY `idx_psv_status` (`status`), + KEY `idx_psv_is_del` (`is_del`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='价格版本(三价统一;与套餐弱关联)'; diff --git a/bms-back/sql/price/prc_price_set_version_is_del_alter.sql b/bms-back/sql/price/prc_price_set_version_is_del_alter.sql new file mode 100644 index 00000000..92730e96 --- /dev/null +++ b/bms-back/sql/price/prc_price_set_version_is_del_alter.sql @@ -0,0 +1,13 @@ +-- Soft-delete flag for price versions (catalog EFFECT soft-delete) +SET @db := DATABASE(); + +SET @sql := ( + SELECT IF(COUNT(*) = 0, + 'ALTER TABLE prc_price_set_version ADD COLUMN is_del char(1) NOT NULL DEFAULT ''0'' COMMENT ''是否删除 0未删除 1已删除'' AFTER price_build_mode, ADD KEY idx_psv_is_del (is_del)', + 'SELECT 1') + FROM information_schema.COLUMNS + WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'prc_price_set_version' AND COLUMN_NAME = 'is_del' +); +PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; + +UPDATE prc_price_set_version SET is_del = '0' WHERE is_del IS NULL OR is_del = ''; diff --git a/bms-front/src/views/price/basic/components/CatalogActivateDialog.vue b/bms-front/src/views/price/basic/components/CatalogActivateDialog.vue index a2484689..19054862 100644 --- a/bms-front/src/views/price/basic/components/CatalogActivateDialog.vue +++ b/bms-front/src/views/price/basic/components/CatalogActivateDialog.vue @@ -95,7 +95,7 @@ function findPrev(row) { } function pickDefault(prev) { const d = new Date() - d.setHours(0, 0, 0, 0) + d.setHours(9, 0, 0, 0) const now = formatHour(d) if (!prev) return now return toMs(now) >= toMs(prev) ? now : prev diff --git a/bms-front/src/views/price/basic/components/CatalogPriceCreate.vue b/bms-front/src/views/price/basic/components/CatalogPriceCreate.vue index e38799bd..da37fd0b 100644 --- a/bms-front/src/views/price/basic/components/CatalogPriceCreate.vue +++ b/bms-front/src/views/price/basic/components/CatalogPriceCreate.vue @@ -243,6 +243,7 @@ const importProgressMessage = ref('') const importProgressStatus = ref(undefined) const finishing = ref(false) +const editingExisting = ref(false) const localRemoves = ref([]) const pendingImports = ref([]) const previewDetailsByCode = ref({}) @@ -327,6 +328,7 @@ async function bootstrap() { if (qPsv != null && qPsv !== '') { psvId.value = Number(qPsv) versionNo.value = (route.query && route.query.versionNo) ? String(route.query.versionNo) : '' + editingExisting.value = true if (!buildMode.value) buildMode.value = 'IMPORT' await loadProducts() } @@ -381,7 +383,7 @@ function removeRow(row) { if (!row) return const code = row.productCode if (psvId.value && row.productId != null) { - proxy.$modal.confirm('确认从草稿中移除该产品?').then(() => props.delFn(row.productId)).then(() => { + proxy.$modal.confirm(editingExisting.value ? '确认移除该产品?' : '确认从草稿中移除该产品?').then(() => props.delFn(row.productId)).then(() => { proxy.$modal.msgSuccess('移除成功') loadProducts() }).catch(() => {}) @@ -511,7 +513,7 @@ async function finishSave() { await applyPendingPreview(applyImportProgress) await savePendingExcelFiles() await applyLocalRemoves() - proxy.$modal.msgSuccess('已保存到待生效草稿') + proxy.$modal.msgSuccess(editingExisting.value ? '已保存' : '已保存到待生效草稿') goBack() } catch (e) { const msg = (e && e.message) || (e && e.msg) || 'save failed' diff --git a/bms-front/src/views/price/basic/components/CatalogVersionProductsDrawer.vue b/bms-front/src/views/price/basic/components/CatalogVersionProductsDrawer.vue index 7d04480a..1eea7b0a 100644 --- a/bms-front/src/views/price/basic/components/CatalogVersionProductsDrawer.vue +++ b/bms-front/src/views/price/basic/components/CatalogVersionProductsDrawer.vue @@ -12,9 +12,10 @@ - + @@ -33,15 +34,17 @@ const L = { colRegion: "目的区域", colAction: "操作", view: "查看明细", + surcharge: "附加费", countAll: "共 ", countUnit: " 个产品", countFilter: " 个产品(全部 ", countFilterEnd: " 个)" } const props = defineProps({ - listFn: { type: Function, required: true } + listFn: { type: Function, required: true }, + showSurcharge: { type: Boolean, default: false } }) -const emit = defineEmits(['view']) +const emit = defineEmits(['view', 'surcharge']) const visible = ref(false) const loading = ref(false) const rows = ref([]) @@ -60,6 +63,8 @@ const colCargo = L.colCargo const colRegion = L.colRegion const colAction = L.colAction const viewText = L.view +const surchargeText = L.surcharge +const showSurcharge = computed(() => !!props.showSurcharge) const labQuery = "查询" const labReset = "重置" const filteredRows = computed(() => { diff --git a/bms-front/src/views/price/basic/components/CatalogVersionTable.vue b/bms-front/src/views/price/basic/components/CatalogVersionTable.vue new file mode 100644 index 00000000..f485de45 --- /dev/null +++ b/bms-front/src/views/price/basic/components/CatalogVersionTable.vue @@ -0,0 +1,206 @@ + + + + + diff --git a/bms-front/src/views/price/basic/product/index.vue b/bms-front/src/views/price/basic/product/index.vue index c672f6ba..522fab2e 100644 --- a/bms-front/src/views/price/basic/product/index.vue +++ b/bms-front/src/views/price/basic/product/index.vue @@ -5,112 +5,38 @@ :closable="false" show-icon class="mb16" - title="已生效展示当前生效版本产品。待生效、已失效按版本展示;待生效可启动或删除整版。建价请点「新建产品价格」。" + :title="alertTitle" /> - - - - - - -
- - - - - - - - - -
- -
- - - 新建产品价格 - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - -
+ - - + + - @@ -120,53 +46,24 @@ import ProductSurchargeDrawer from './components/ProductSurchargeDrawer.vue' import CatalogVersionProductsDrawer from '../components/CatalogVersionProductsDrawer.vue' import CatalogVersionExcelDrawer from '../components/CatalogVersionExcelDrawer.vue' import CatalogActivateDialog from '../components/CatalogActivateDialog.vue' +import CatalogVersionTable from '../components/CatalogVersionTable.vue' import { listProduct, listProductVersions, activateProductVersion, deleteProductVersion, listProductVersionExcelFiles } from '@/api/price/product' const { proxy } = getCurrentInstance() -const { bms_product_effect_status } = useDict('bms_product_effect_status') -const statusTab = ref('effect') -const extraParams = reactive({ statusGroup: 'effect' }) +const alertTitle = "按版本管理产品价(与套餐版本一致)。点击版本可查看产品与明细;待生效(含草稿)可编辑、启动或硬删;已生效可软删(上一版自动恢复生效并清空失效时间)。建价请点「新建产品价格」。" +const verTitle = '产品价版本' +const createLabel = '新建产品价格' + const versionProductsRef = ref() const activateRef = ref() const versionLoading = ref(false) +const removingPsvId = ref(null) const versionRows = ref([]) -const versionTotal = ref(0) -const versionQuery = reactive({ pageNum: 1, pageSize: 10 }) -const tableRef = ref() const countryRef = ref() const surchargeRef = ref() const excelRef = ref() -const columns = [ - { prop: 'productCode', label: '产品代码', minWidth: 110 }, - { prop: 'productName', label: '产品名称', minWidth: 140, showOverflowTooltip: true }, - { prop: 'serviceLevel', label: '时效等级', width: 90, align: 'center' }, - { prop: 'cargoAttr', label: '走货属性', minWidth: 120, slot: 'cargoAttr' }, - { prop: 'destRegion', label: '目的区域', width: 90, align: 'center' }, - { prop: 'effectiveDate', label: '生效时间', width: 160, align: 'center' }, - { prop: 'expireDate', label: '失效时间', width: 160, align: 'center' }, - { prop: 'countryCount', label: '国家数', width: 80, align: 'center' }, - { prop: 'surchargeCount', label: '附加费数', width: 90, align: 'center' }, - { prop: 'status', label: '状态', width: 90, align: 'center', slot: 'status' }, - { prop: 'updateNote', label: '更新内容', minWidth: 160, showOverflowTooltip: true }, - { prop: 'action', label: '操作', width: 120, fixed: 'right', slot: 'action' } -] - -const searchColumns = [ - { prop: 'productCode', label: '产品代码', component: 'input', placeholder: '产品代码' }, - { prop: 'productName', label: '产品名称', component: 'input', placeholder: '产品名称' } -] - -function queryList(params) { - const p = { ...(params || {}) } - // Exact status search must not be limited by default statusGroup=active. - if (p.status != null && p.status !== '') { - delete p.statusGroup - } - return listProduct(p) -} - function handleAdd() { proxy.$router.push({ path: '/price/product-create/index' }) } @@ -179,32 +76,10 @@ function openExcel(row) { excelRef.value && excelRef.value.open(row) } -function onTabChange(name) { - if (name === 'pending' || name === 'expired') { - versionQuery.pageNum = 1 - loadVersions() - return - } - extraParams.statusGroup = 'effect' - nextTick(() => tableRef.value && tableRef.value.refresh()) -} - -function versionStatusText(status) { - const map = { '0': '草稿', '1': '已生效', '2': '已失效', '3': '待生效' } - return map[String(status)] || status || '-' -} - function loadVersions() { versionLoading.value = true - const params = { - pageNum: versionQuery.pageNum, - pageSize: versionQuery.pageSize - } - if (statusTab.value === 'pending') params.statusGroup = 'pending' - else params.status = '2' - listProductVersions(params).then(res => { + listProductVersions({ pageNum: 1, pageSize: 500 }).then(res => { versionRows.value = res.rows || [] - versionTotal.value = res.total || 0 }).finally(() => { versionLoading.value = false }) } @@ -230,48 +105,33 @@ function onEditVersion(row) { function onStartVersion(row) { if (row && row.psvId != null) { activateRef.value && activateRef.value.open(row) - return } - loadAllVersions().then(list => { - const pending = (list || []).filter(v => v && (String(v.status) === '0' || String(v.status) === '3')) - if (!pending.length) { - proxy.$modal.msgWarning('当前没有可启动的待生效版本') - return - } - pending.sort((a, b) => (Number(b.versionSeq) || 0) - (Number(a.versionSeq) || 0)) - const draft = pending.find(v => String(v.status) === '0') - activateRef.value && activateRef.value.open(draft || pending[0]) - }) } function onDeleteVersion(row) { if (!row || row.psvId == null) return - proxy.$modal.confirm('确认硬删除该待生效版本?版本、产品、明细将从数据库真删除,且不可恢复。').then(() => deleteProductVersion(row.psvId)).then(() => { - loadVersions() - proxy.$modal.msgSuccess('删除成功') + const effect = String(row.status) === '1' + const msg = effect ? "确认软删除该已生效版本?版本及产品、明细将标记为已删除(列表不再展示)。" : "确认硬删除该版本?版本、产品、明细将从数据库真删除,且不可恢复。" + proxy.$modal.confirm(msg).then(() => { + removingPsvId.value = row.psvId + proxy.$modal.loading("正在删除,请稍候...") + return deleteProductVersion(row.psvId).then(() => { + loadVersions() + proxy.$modal.msgSuccess("删除成功") + }).finally(() => { + removingPsvId.value = null + proxy.$modal.closeLoading() + }) }).catch(() => {}) } function onActivated() { - if (statusTab.value === 'pending' || statusTab.value === 'expired') loadVersions() - else if (tableRef.value) tableRef.value.refresh() + loadVersions() } - +onMounted(() => loadVersions()) diff --git a/bms-front/src/views/price/basic/redline/index.vue b/bms-front/src/views/price/basic/redline/index.vue index cdbfbddc..032e9a2d 100644 --- a/bms-front/src/views/price/basic/redline/index.vue +++ b/bms-front/src/views/price/basic/redline/index.vue @@ -5,163 +5,65 @@ :closable="false" show-icon class="mb16" - title="红线价已生效展示当前生效版本产品。待生效、已失效按版本展示;待生效可启动或删除整版。" + :title="alertTitle" /> - - - - - - -
- - - - - - - - - -
- -
- - - 新建红线价 - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - -
+ - - + + - - diff --git a/bms-front/src/views/price/set/components/detail/SetVersionTable.vue b/bms-front/src/views/price/set/components/detail/SetVersionTable.vue index d515e918..320c19f6 100644 --- a/bms-front/src/views/price/set/components/detail/SetVersionTable.vue +++ b/bms-front/src/views/price/set/components/detail/SetVersionTable.vue @@ -63,9 +63,11 @@ v-hasPermi="['price:set:edit']" >修改生效时间 删除 @@ -77,12 +79,13 @@