Compare commits
2 Commits
1e4711326c
...
00a690abe9
| Author | SHA1 | Date | |
|---|---|---|---|
| 00a690abe9 | |||
| 8ed7b3146b |
+4
-4
@@ -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")
|
||||
|
||||
+4
-4
@@ -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")
|
||||
|
||||
@@ -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=保存任务不存在或已过期
|
||||
|
||||
@@ -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<PrcPriceSetDetail> details;
|
||||
private List<PrcPriceSetProduct> products;
|
||||
|
||||
@@ -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<Long> selectPriceSetIds();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+18
-5
@@ -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;
|
||||
}
|
||||
|
||||
+107
-6
@@ -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<PrcPriceSetVersion> 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;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="expireTime" column="expire_time" />
|
||||
<result property="status" column="status" />
|
||||
<result property="priceBuildMode" column="price_build_mode"/>
|
||||
<result property="isDel" column="is_del" />
|
||||
<result property="createBy" column="created_by" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateBy" column="updated_by" />
|
||||
@@ -24,7 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<sql id="selectPrcPriceSetVersionVo">
|
||||
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
|
||||
</sql>
|
||||
|
||||
@@ -36,6 +37,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<select id="selectPrcPriceSetVersionList" parameterType="PrcPriceSetVersion" resultMap="PrcPriceSetVersionResult">
|
||||
<include refid="selectPrcPriceSetVersionVo"/>
|
||||
<where>
|
||||
and ifnull(is_del, '0') = '0'
|
||||
<if test="priceSetId != null">
|
||||
AND price_set_id = #{priceSetId}
|
||||
</if>
|
||||
@@ -57,7 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
|
||||
<select id="selectCatalogVersionList" parameterType="PrcPriceSetVersion" resultMap="PrcPriceSetVersionResult">
|
||||
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'
|
||||
<choose>
|
||||
<when test="statusGroup != null and statusGroup == 'pending'">
|
||||
and v.status in ('0', '3')
|
||||
@@ -162,6 +165,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<include refid="selectPrcPriceSetVersionVo"/>
|
||||
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"
|
||||
<include refid="selectPrcPriceSetVersionVo"/>
|
||||
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
|
||||
</select>
|
||||
|
||||
<update id="softDeleteById">
|
||||
update prc_price_set_version
|
||||
set is_del = '1',
|
||||
<if test="updateBy != null and updateBy != ''">updated_by = #{updateBy},</if>
|
||||
update_time = sysdate()
|
||||
where psv_id = #{psvId}
|
||||
and ifnull(is_del, '0') = '0'
|
||||
</update>
|
||||
|
||||
<update id="refreshCatalogStatusByDates">
|
||||
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')
|
||||
</update>
|
||||
|
||||
|
||||
@@ -166,6 +166,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
)
|
||||
</delete>
|
||||
|
||||
<update id="softDeleteByPsvId">
|
||||
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>
|
||||
|
||||
<!-- 附加费版本化编辑后,产品关联重指向新记录 -->
|
||||
<update id="rebindRelScId">
|
||||
update prc_surcharge_rel
|
||||
|
||||
@@ -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='价格版本(三价统一;与套餐弱关联)';
|
||||
|
||||
|
||||
|
||||
@@ -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 = '';
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
<el-table-column :label="colLevel" prop="serviceLevel" width="90" align="center" />
|
||||
<el-table-column :label="colCargo" prop="cargoAttr" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column :label="colRegion" prop="destRegion" width="90" align="center" />
|
||||
<el-table-column :label="colAction" width="110" align="center" fixed="right">
|
||||
<el-table-column :label="colAction" :width="showSurcharge ? 180 : 110" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="view(row)">{{ viewText }}</el-button>
|
||||
<el-button v-if="showSurcharge" link type="primary" @click.stop="emit('surcharge', row)">{{ surchargeText }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="catalog-ver">
|
||||
<div class="ver-head">
|
||||
<div class="ver-title">
|
||||
<i class="ver-bar" />
|
||||
<span class="ver-text">{{ title }}</span>
|
||||
<el-tag size="small" type="info" effect="plain" round>{{ filteredVersions.length }}</el-tag>
|
||||
</div>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
size="small"
|
||||
:disabled="hasDraft"
|
||||
v-hasPermi="[createPerm]"
|
||||
@click="emit('create')"
|
||||
>{{ createLabel }}</el-button>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="statusTab" class="ver-tabs">
|
||||
<el-tab-pane :label="tabLabel('all')" name="all" />
|
||||
<el-tab-pane :label="tabLabel('pending')" name="pending" />
|
||||
<el-tab-pane :label="tabLabel('1')" name="1" />
|
||||
<el-tab-pane :label="tabLabel('2')" name="2" />
|
||||
</el-tabs>
|
||||
|
||||
<el-table v-loading="loading" :data="filteredVersions" border :empty-text="emptyText" @row-click="onRowClick">
|
||||
<el-table-column :label="colNo" width="120">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="emit('view-products', row)">{{ row.versionNo || '-' }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="colEff" min-width="170">
|
||||
<template #default="{ row }">{{ row.effectiveTime || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="colExp" min-width="170">
|
||||
<template #default="{ row }">{{ row.expireTime || '-' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="colStatus" width="100" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="versionStatusTag(row.status)" size="small">{{ versionStatusLabel(row.status) }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="colProducts" prop="productCount" width="90" align="center" />
|
||||
<el-table-column :label="colRows" prop="detailCount" width="100" align="center" />
|
||||
<el-table-column :label="colAction" width="420" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="emit('view-products', row)">{{ labViewProducts }}</el-button>
|
||||
<el-button link type="primary" @click.stop="emit('view-attach', row)" v-hasPermi="[queryPerm]">{{ labViewAttach }}</el-button>
|
||||
<el-button
|
||||
v-if="showEditButton(row)"
|
||||
link
|
||||
type="primary"
|
||||
@click.stop="emit('edit', row)"
|
||||
>{{ labEdit }}</el-button>
|
||||
<el-button
|
||||
v-if="isDraftVersion(row)"
|
||||
link
|
||||
type="success"
|
||||
@click.stop="emit('activate', row)"
|
||||
v-hasPermi="[editPerm]"
|
||||
>{{ labStart }}</el-button>
|
||||
<el-button
|
||||
v-if="isDraftVersion(row) || isPendingVersion(row) || isEffectVersion(row)"
|
||||
link
|
||||
type="danger"
|
||||
:loading="isRemoving(row)"
|
||||
:disabled="removingPsvId != null"
|
||||
@click.stop="emit('remove', row)"
|
||||
v-hasPermi="[removePerm]"
|
||||
>{{ labDelete }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="CatalogVersionTable">
|
||||
import {
|
||||
versionStatusLabel,
|
||||
versionStatusTag,
|
||||
isDraftVersion,
|
||||
isPendingVersion,
|
||||
isEffectVersion,
|
||||
isPriceEditableVersion
|
||||
} from '@/views/price/set/utils/priceSet'
|
||||
import { checkPermi } from '@/utils/permission'
|
||||
|
||||
const props = defineProps({
|
||||
versions: { type: Array, default: () => [] },
|
||||
loading: { type: Boolean, default: false },
|
||||
title: { type: String, required: true },
|
||||
createLabel: { type: String, required: true },
|
||||
createPerm: { type: String, required: true },
|
||||
editPerm: { type: String, required: true },
|
||||
removePerm: { type: String, required: true },
|
||||
queryPerm: { type: String, required: true },
|
||||
removingPsvId: { type: [Number, String], default: null }
|
||||
})
|
||||
|
||||
const emit = defineEmits(['create', 'edit', 'view-products', 'view-attach', 'activate', 'remove'])
|
||||
|
||||
const colNo = '版本号'
|
||||
const colEff = '生效时间'
|
||||
const colExp = '失效时间'
|
||||
const colStatus = '状态'
|
||||
const colProducts = '产品数'
|
||||
const colRows = '明细行数'
|
||||
const colAction = '操作'
|
||||
const emptyText = '暂无版本'
|
||||
const labViewProducts = '查看产品'
|
||||
const labViewAttach = '查看附件'
|
||||
const labEdit = '编辑'
|
||||
const labStart = '启动'
|
||||
const labDelete = '删除'
|
||||
|
||||
const statusTab = ref('all')
|
||||
|
||||
const counts = computed(() => {
|
||||
const map = { all: 0, pending: 0, '1': 0, '2': 0 }
|
||||
;(props.versions || []).forEach(v => {
|
||||
map.all++
|
||||
const st = String(v.status == null ? '' : v.status)
|
||||
if (st === '0' || st === '3') map.pending++
|
||||
else if (map[st] != null) map[st]++
|
||||
})
|
||||
return map
|
||||
})
|
||||
|
||||
function tabLabel(key) {
|
||||
const labels = {
|
||||
all: '全部',
|
||||
pending: '待生效',
|
||||
'1': '已生效',
|
||||
'2': '已失效'
|
||||
}
|
||||
return labels[key] + ' (' + (counts.value[key] || 0) + ')'
|
||||
}
|
||||
|
||||
const hasDraft = computed(() => (props.versions || []).some(v => isDraftVersion(v)))
|
||||
|
||||
const filteredVersions = computed(() => {
|
||||
const list = props.versions || []
|
||||
if (statusTab.value === 'all') return list
|
||||
if (statusTab.value === 'pending') {
|
||||
return list.filter(v => {
|
||||
const st = String(v.status == null ? '' : v.status)
|
||||
return st === '0' || st === '3'
|
||||
})
|
||||
}
|
||||
return list.filter(v => String(v.status) === statusTab.value)
|
||||
})
|
||||
|
||||
function showEditButton(row) {
|
||||
if (!checkPermi([props.editPerm])) return false
|
||||
// Align with sales force-edit: draft / pending / effect can edit
|
||||
return isPriceEditableVersion(row) || isEffectVersion(row)
|
||||
}
|
||||
|
||||
function isRemoving(row) {
|
||||
return props.removingPsvId != null && row && String(props.removingPsvId) === String(row.psvId)
|
||||
}
|
||||
|
||||
function onRowClick(row) {
|
||||
emit('view-products', row)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.catalog-ver {
|
||||
background: #fff;
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px 16px;
|
||||
}
|
||||
.ver-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.ver-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
}
|
||||
.ver-bar {
|
||||
width: 3px;
|
||||
height: 14px;
|
||||
border-radius: 2px;
|
||||
background: #52c41a;
|
||||
flex: none;
|
||||
}
|
||||
.ver-text {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
.ver-tabs {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.ver-tabs :deep(.el-tabs__header) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -5,112 +5,38 @@
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb16"
|
||||
title="已生效展示当前生效版本产品。待生效、已失效按版本展示;待生效可启动或删除整版。建价请点「新建产品价格」。"
|
||||
:title="alertTitle"
|
||||
/>
|
||||
|
||||
<el-tabs v-model="statusTab" class="catalog-tabs" @tab-change="onTabChange">
|
||||
<el-tab-pane label="已生效" name="effect" />
|
||||
<el-tab-pane label="待生效" name="pending" />
|
||||
<el-tab-pane label="已失效" name="expired" />
|
||||
</el-tabs>
|
||||
|
||||
<div v-show="statusTab === 'effect'">
|
||||
<basic-table
|
||||
ref="tableRef"
|
||||
:extra-params="extraParams"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:query="queryList"
|
||||
row-key="productId"
|
||||
:selection="false"
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['price:product:add']">新建产品价格</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<template #col-cargoAttr="{ row }">
|
||||
<el-tag type="primary" size="small" effect="plain">{{ row.cargoAttr || '-' }}</el-tag>
|
||||
</template>
|
||||
|
||||
<template #col-status="{ row }">
|
||||
<dict-tag :options="bms_product_effect_status" :value="row.status" />
|
||||
</template>
|
||||
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" title="产品明细" icon="View" @click="countryRef.open(row)" v-hasPermi="['price:product:query']"></el-button>
|
||||
<el-button link type="primary" title="附加费" icon="Money" @click="surchargeRef.open(row)" v-hasPermi="['price:surcharge:query']"></el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
</div>
|
||||
|
||||
<div v-show="statusTab === 'pending'">
|
||||
<el-row class="mb12">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['price:product:add']">新建产品价格</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table v-loading="versionLoading" :data="versionRows" border empty-text="暂无待生效版本" @row-click="openVersionProducts">
|
||||
<el-table-column label="版本号" prop="versionNo" width="120" />
|
||||
<el-table-column label="生效时间" prop="effectiveTime" min-width="170" />
|
||||
<el-table-column label="失效时间" prop="expireTime" min-width="170" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">{{ versionStatusText(row.status) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品数" prop="productCount" width="90" align="center" />
|
||||
<el-table-column label="明细行数" prop="detailCount" width="100" align="center" />
|
||||
<el-table-column label="操作" width="360" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="onEditVersion(row)" v-hasPermi="['price:product:edit']">编辑</el-button>
|
||||
<el-button link type="primary" @click.stop="openVersionProducts(row)">查看产品</el-button>
|
||||
<el-button link type="primary" @click.stop="openExcel(row)" v-hasPermi="['price:product:query']">查看附件</el-button>
|
||||
<el-button link type="success" @click.stop="onStartVersion(row)" v-hasPermi="['price:product:edit']">启动</el-button>
|
||||
<el-button link type="danger" @click.stop="onDeleteVersion(row)" v-hasPermi="['price:product:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="versionTotal > 0"
|
||||
:total="versionTotal"
|
||||
v-model:page="versionQuery.pageNum"
|
||||
v-model:limit="versionQuery.pageSize"
|
||||
@pagination="loadVersions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-show="statusTab === 'expired'">
|
||||
<el-table v-loading="versionLoading" :data="versionRows" border empty-text="暂无失效版本" @row-click="openVersionProducts">
|
||||
<el-table-column label="版本号" prop="versionNo" width="120" />
|
||||
<el-table-column label="生效时间" prop="effectiveTime" min-width="170" />
|
||||
<el-table-column label="失效时间" prop="expireTime" min-width="170" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">{{ versionStatusText(row.status) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品数" prop="productCount" width="90" align="center" />
|
||||
<el-table-column label="明细行数" prop="detailCount" width="100" align="center" />
|
||||
<el-table-column label="操作" width="220" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="openVersionProducts(row)">查看产品</el-button>
|
||||
<el-button link type="primary" @click.stop="openExcel(row)" v-hasPermi="['price:product:query']">查看附件</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="versionTotal > 0"
|
||||
:total="versionTotal"
|
||||
v-model:page="versionQuery.pageNum"
|
||||
v-model:limit="versionQuery.pageSize"
|
||||
@pagination="loadVersions"
|
||||
/>
|
||||
</div>
|
||||
<catalog-version-table
|
||||
:versions="versionRows"
|
||||
:loading="versionLoading"
|
||||
:removing-psv-id="removingPsvId"
|
||||
:title="verTitle"
|
||||
:create-label="createLabel"
|
||||
create-perm="price:product:add"
|
||||
edit-perm="price:product:edit"
|
||||
remove-perm="price:product:remove"
|
||||
query-perm="price:product:query"
|
||||
@create="handleAdd"
|
||||
@edit="onEditVersion"
|
||||
@view-products="openVersionProducts"
|
||||
@view-attach="openExcel"
|
||||
@activate="onStartVersion"
|
||||
@remove="onDeleteVersion"
|
||||
/>
|
||||
|
||||
<catalog-version-excel-drawer ref="excelRef" :list-fn="listProductVersionExcelFiles" />
|
||||
<product-country-drawer ref="countryRef" />
|
||||
<product-surcharge-drawer ref="surchargeRef" @success="() => tableRef.refresh()" />
|
||||
<catalog-version-products-drawer ref="versionProductsRef" :list-fn="listProduct" @view="(row) => countryRef.open(row)" />
|
||||
<product-surcharge-drawer ref="surchargeRef" />
|
||||
<catalog-version-products-drawer
|
||||
ref="versionProductsRef"
|
||||
:list-fn="listProduct"
|
||||
show-surcharge
|
||||
@view="(row) => countryRef.open(row)"
|
||||
@surcharge="(row) => surchargeRef.open(row)"
|
||||
/>
|
||||
<catalog-activate-dialog ref="activateRef" :load-versions="loadAllVersions" :activate-fn="activateProductVersion" @success="onActivated" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -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())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mb16 { margin-bottom: 16px; }
|
||||
.mb12 { margin-bottom: 12px; }
|
||||
.catalog-tabs { margin-bottom: 8px; }
|
||||
.import-progress { padding: 8px 4px 4px; }
|
||||
.import-progress-msg {
|
||||
margin-top: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
max-height: 160px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,163 +5,65 @@
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb16"
|
||||
title="红线价已生效展示当前生效版本产品。待生效、已失效按版本展示;待生效可启动或删除整版。"
|
||||
:title="alertTitle"
|
||||
/>
|
||||
|
||||
<el-tabs v-model="statusTab" class="catalog-tabs" @tab-change="onTabChange">
|
||||
<el-tab-pane label="已生效" name="effect" />
|
||||
<el-tab-pane label="待生效" name="pending" />
|
||||
<el-tab-pane label="已失效" name="expired" />
|
||||
</el-tabs>
|
||||
|
||||
<div v-show="statusTab === 'effect'">
|
||||
<basic-table
|
||||
ref="tableRef"
|
||||
:extra-params="extraParams"
|
||||
:columns="columns"
|
||||
:search-columns="searchColumns"
|
||||
:query="queryList"
|
||||
row-key="productId"
|
||||
:selection="false"
|
||||
>
|
||||
<template #toolbar>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['price:redline:add']">新建红线价</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<template #col-cargoAttr="{ row }">
|
||||
<el-tag type="primary" size="small" effect="plain">{{ row.cargoAttr || '-' }}</el-tag>
|
||||
</template>
|
||||
|
||||
<template #col-status="{ row }">
|
||||
<dict-tag :options="bms_product_effect_status" :value="row.status" />
|
||||
</template>
|
||||
|
||||
<template #col-action="{ row }">
|
||||
<el-button link type="primary" title="红线价明细" icon="View" @click="countryRef.open(row)" v-hasPermi="['price:redline:query']"></el-button>
|
||||
<el-button link type="primary" title="附加费" icon="Money" @click="surchargeRef.open(row)" v-hasPermi="['price:surcharge:query']"></el-button>
|
||||
</template>
|
||||
</basic-table>
|
||||
</div>
|
||||
|
||||
<div v-show="statusTab === 'pending'">
|
||||
<el-row class="mb12">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['price:redline:add']">新建红线价</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table v-loading="versionLoading" :data="versionRows" border empty-text="暂无待生效版本" @row-click="openVersionProducts">
|
||||
<el-table-column label="版本号" prop="versionNo" width="120" />
|
||||
<el-table-column label="生效时间" prop="effectiveTime" min-width="170" />
|
||||
<el-table-column label="失效时间" prop="expireTime" min-width="170" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">{{ versionStatusText(row.status) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品数" prop="productCount" width="90" align="center" />
|
||||
<el-table-column label="明细行数" prop="detailCount" width="100" align="center" />
|
||||
<el-table-column label="操作" width="360" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="onEditVersion(row)" v-hasPermi="['price:redline:edit']">编辑</el-button>
|
||||
<el-button link type="primary" @click.stop="openVersionProducts(row)">查看产品</el-button>
|
||||
<el-button link type="primary" @click.stop="openExcel(row)" v-hasPermi="['price:redline:query']">查看附件</el-button>
|
||||
<el-button link type="success" @click.stop="onStartVersion(row)" v-hasPermi="['price:redline:edit']">启动</el-button>
|
||||
<el-button link type="danger" @click.stop="onDeleteVersion(row)" v-hasPermi="['price:redline:remove']">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="versionTotal > 0"
|
||||
:total="versionTotal"
|
||||
v-model:page="versionQuery.pageNum"
|
||||
v-model:limit="versionQuery.pageSize"
|
||||
@pagination="loadVersions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-show="statusTab === 'expired'">
|
||||
<el-table v-loading="versionLoading" :data="versionRows" border empty-text="暂无失效版本" @row-click="openVersionProducts">
|
||||
<el-table-column label="版本号" prop="versionNo" width="120" />
|
||||
<el-table-column label="生效时间" prop="effectiveTime" min-width="170" />
|
||||
<el-table-column label="失效时间" prop="expireTime" min-width="170" />
|
||||
<el-table-column label="状态" width="100" align="center">
|
||||
<template #default="{ row }">{{ versionStatusText(row.status) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品数" prop="productCount" width="90" align="center" />
|
||||
<el-table-column label="明细行数" prop="detailCount" width="100" align="center" />
|
||||
<el-table-column label="操作" width="220" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button link type="primary" @click.stop="openVersionProducts(row)">查看产品</el-button>
|
||||
<el-button link type="primary" @click.stop="openExcel(row)" v-hasPermi="['price:redline:query']">查看附件</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="versionTotal > 0"
|
||||
:total="versionTotal"
|
||||
v-model:page="versionQuery.pageNum"
|
||||
v-model:limit="versionQuery.pageSize"
|
||||
@pagination="loadVersions"
|
||||
/>
|
||||
</div>
|
||||
<catalog-version-table
|
||||
:versions="versionRows"
|
||||
:loading="versionLoading"
|
||||
:removing-psv-id="removingPsvId"
|
||||
:title="verTitle"
|
||||
:create-label="createLabel"
|
||||
create-perm="price:redline:add"
|
||||
edit-perm="price:redline:edit"
|
||||
remove-perm="price:redline:remove"
|
||||
query-perm="price:redline:query"
|
||||
@create="handleAdd"
|
||||
@edit="onEditVersion"
|
||||
@view-products="openVersionProducts"
|
||||
@view-attach="openExcel"
|
||||
@activate="onStartVersion"
|
||||
@remove="onDeleteVersion"
|
||||
/>
|
||||
|
||||
<catalog-version-excel-drawer ref="excelRef" :list-fn="listRedlineVersionExcelFiles" />
|
||||
<redline-country-drawer ref="countryRef" />
|
||||
<redline-surcharge-drawer ref="surchargeRef" @success="() => tableRef.refresh()" />
|
||||
<catalog-version-products-drawer ref="versionProductsRef" :list-fn="listRedline" @view="(row) => countryRef.open(row)" />
|
||||
<redline-surcharge-drawer ref="surchargeRef" />
|
||||
<catalog-version-products-drawer
|
||||
ref="versionProductsRef"
|
||||
:list-fn="listRedline"
|
||||
show-surcharge
|
||||
@view="(row) => countryRef.open(row)"
|
||||
@surcharge="(row) => surchargeRef.open(row)"
|
||||
/>
|
||||
<catalog-activate-dialog ref="activateRef" :load-versions="loadAllVersions" :activate-fn="activateRedlineVersion" @success="onActivated" />
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="PriceProduct">
|
||||
<script setup name="PriceRedline">
|
||||
import RedlineCountryDrawer from './components/RedlineCountryDrawer.vue'
|
||||
import RedlineSurchargeDrawer from './components/RedlineSurchargeDrawer.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 { listRedline, listRedlineVersions, activateRedlineVersion, deleteRedlineVersion, listRedlineVersionExcelFiles } from '@/api/price/redline'
|
||||
|
||||
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) {
|
||||
return listRedline(params)
|
||||
}
|
||||
|
||||
function handleAdd() {
|
||||
proxy.$router.push({ path: '/price/redline-create/index' })
|
||||
}
|
||||
@@ -174,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'
|
||||
listRedlineVersions(params).then(res => {
|
||||
listRedlineVersions({ pageNum: 1, pageSize: 500 }).then(res => {
|
||||
versionRows.value = res.rows || []
|
||||
versionTotal.value = res.total || 0
|
||||
}).finally(() => { versionLoading.value = false })
|
||||
}
|
||||
|
||||
@@ -225,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(() => deleteRedlineVersion(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 deleteRedlineVersion(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())
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mb16 { margin-bottom: 16px; }
|
||||
.mb12 { margin-bottom: 12px; }
|
||||
.catalog-tabs { margin-bottom: 8px; }
|
||||
.import-progress { padding: 8px 4px 4px; }
|
||||
.import-progress-msg {
|
||||
margin-top: 12px;
|
||||
color: var(--el-text-color-secondary);
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
max-height: 160px;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -63,9 +63,11 @@
|
||||
v-hasPermi="['price:set:edit']"
|
||||
>修改生效时间</el-button>
|
||||
<el-button
|
||||
v-if="isDraftVersion(row) || isPendingVersion(row)"
|
||||
v-if="isDraftVersion(row) || isPendingVersion(row) || isEffectVersion(row)"
|
||||
link
|
||||
type="danger"
|
||||
:loading="isRemoving(row)"
|
||||
:disabled="removingPsvId != null"
|
||||
@click="emit('remove', row)"
|
||||
v-hasPermi="['price:set:edit']"
|
||||
>删除</el-button>
|
||||
@@ -77,12 +79,13 @@
|
||||
|
||||
<script setup name="SetVersionTable">
|
||||
import SetSectionCard from './SetSectionCard.vue'
|
||||
import { versionStatusLabel, versionStatusTag, isDraftVersion, isPendingVersion, isPriceEditableVersion } from '../../utils/priceSet'
|
||||
import { versionStatusLabel, versionStatusTag, isDraftVersion, isPendingVersion, isEffectVersion, isPriceEditableVersion } from '../../utils/priceSet'
|
||||
import { checkPermi } from '@/utils/permission'
|
||||
|
||||
const props = defineProps({
|
||||
versions: { type: Array, default: () => [] },
|
||||
modelValue: { type: [Number, String], default: undefined }
|
||||
modelValue: { type: [Number, String], default: undefined },
|
||||
removingPsvId: { type: [Number, String], default: null }
|
||||
})
|
||||
const emit = defineEmits(['update:modelValue', 'create-version', 'open-details', 'view-import-attach', 'activate', 'reschedule', 'edit', 'remove'])
|
||||
|
||||
@@ -134,6 +137,10 @@ function showEditButton(row) {
|
||||
return isPriceEditableVersion(row) && checkPermi(['price:set:edit'])
|
||||
}
|
||||
|
||||
function isRemoving(row) {
|
||||
return props.removingPsvId != null && row && String(props.removingPsvId) === String(row.psvId)
|
||||
}
|
||||
|
||||
function openDetails(row) {
|
||||
if (!row || row.psvId == null) return
|
||||
emit('update:modelValue', row.psvId)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<set-version-table
|
||||
v-model="currentPsvId"
|
||||
:versions="set.versions || []"
|
||||
:removing-psv-id="removingPsvId"
|
||||
@create-version="onCreateVersion"
|
||||
@open-details="onOpenVersionDetails"
|
||||
@view-import-attach="onViewImportAttach"
|
||||
@@ -91,7 +92,7 @@ import { usePriceSetRefData } from './composables/usePriceSetRefData'
|
||||
import {
|
||||
getPriceSet, disablePriceSet, enablePriceSet, activatePriceSetVersion, deletePriceSetVersion
|
||||
} from '@/api/price/set'
|
||||
import { isDraftVersion, isPendingVersion } from './utils/priceSet'
|
||||
import { isDraftVersion, isPendingVersion, isEffectVersion } from './utils/priceSet'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const route = useRoute()
|
||||
@@ -99,6 +100,7 @@ const router = useRouter()
|
||||
const refData = usePriceSetRefData()
|
||||
|
||||
const loading = ref(false)
|
||||
const removingPsvId = ref(null)
|
||||
const set = ref({})
|
||||
const currentPsvId = ref()
|
||||
const detailDrawerVisible = ref(false)
|
||||
@@ -203,7 +205,7 @@ function normalizeToHour(val) {
|
||||
|
||||
function formatNow() {
|
||||
const d = new Date()
|
||||
d.setHours(0, 0, 0, 0)
|
||||
d.setHours(9, 0, 0, 0)
|
||||
return formatHour(d)
|
||||
}
|
||||
|
||||
@@ -391,13 +393,19 @@ function onCreateVersion() {
|
||||
}
|
||||
function onRemoveVersion(row) {
|
||||
if (!row || row.psvId == null) return
|
||||
const statusTip = isPendingVersion(row) ? '待生效' : '草稿'
|
||||
proxy.$modal.confirm(
|
||||
'确认删除' + statusTip + '版本 ' + (row.versionNo || '')
|
||||
+ '?其明细与附加费将一并删除。'
|
||||
).then(() => deletePriceSetVersion(row.psvId)).then(() => {
|
||||
proxy.$modal.msgSuccess('版本已删除')
|
||||
load()
|
||||
const msg = isEffectVersion(row)
|
||||
? "确认软删除已生效版本 " + (row.versionNo || '') + "?版本及产品、明细将标记为已删除,上一版将自动恢复生效并清空失效时间。"
|
||||
: "确认删除" + (isPendingVersion(row) ? "待生效" : "草稿") + "版本 " + (row.versionNo || '') + "?其明细与附加费将一并删除。"
|
||||
proxy.$modal.confirm(msg).then(() => {
|
||||
removingPsvId.value = row.psvId
|
||||
proxy.$modal.loading("正在删除,请稍候...")
|
||||
return deletePriceSetVersion(row.psvId).then(() => {
|
||||
proxy.$modal.msgSuccess("版本已删除")
|
||||
load()
|
||||
}).finally(() => {
|
||||
removingPsvId.value = null
|
||||
proxy.$modal.closeLoading()
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
function onEditVersion(row) {
|
||||
|
||||
@@ -86,6 +86,10 @@ export function isPendingVersion(row) {
|
||||
return !!row && String(row.status) === VER_STATUS.PENDING
|
||||
}
|
||||
|
||||
export function isEffectVersion(row) {
|
||||
return !!row && String(row.status) === VER_STATUS.EFFECT
|
||||
}
|
||||
|
||||
/** Draft or pending: may continue editing price details */
|
||||
export function isPriceEditableVersion(row) {
|
||||
return isDraftVersion(row) || isPendingVersion(row)
|
||||
|
||||
Reference in New Issue
Block a user