修改产品价和红线价功能

This commit is contained in:
wuweihua
2026-10-28 22:44:13 +08:00
parent 1d47d5781b
commit 3bb7267b0b
9 changed files with 269 additions and 69 deletions
@@ -29,11 +29,10 @@ public class PrcPriceSetVersion extends BaseEntity
/** 0 draft / 3 pending / 1 active / 2 expired */
private String status;
/**
* Create-price mode for this version:
* PULL = from product library,
* IMPORT = Excel with prior version preload,
* IMPORT_FRESH = Excel without prior version data.
* Column: price_build_mode
* Create-price mode for this version (column: price_build_mode).
* SALES: PULL = product library; IMPORT = Excel + prior version; IMPORT_FRESH = Excel blank.
* PRODUCT/REDLINE: IMPORT = copy from effect version; IMPORT_FRESH = rebuild (Excel).
* Legacy catalog: COPY → IMPORT, old IMPORT → IMPORT_FRESH (see migrate SQL).
*/
private String priceBuildMode;
/** 0 normal / 1 soft-deleted */
@@ -102,7 +102,8 @@ public class CatalogVersionSupport
nv.setVersionNo("V" + next);
nv.setEffectiveTime(effectiveTime);
nv.setStatus(STATUS_DRAFT);
nv.setPriceBuildMode("IMPORT");
// IMPORT = inherit effect version; IMPORT_FRESH = empty rebuild (Excel)
nv.setPriceBuildMode(copyFromLatest ? "IMPORT" : "IMPORT_FRESH");
nv.setCreateBy("system");
versionMapper.insertPrcPriceSetVersion(nv);
@@ -122,7 +123,11 @@ public class CatalogVersionSupport
return nv;
}
/** Activate draft: set EFFECT, chain expire on previous EFFECT versions of same type. */
/**
* Activate draft/pending catalog version.
* IMPORT_FRESH (align sales): may start inside a prior window; forbid equal to any other
* version's effective/expire of the same price_type; then chain expire times and sync children.
*/
public void activateVersion(Long psvId, Date effectiveTime)
{
PrcPriceSetVersion ver = versionMapper.selectPrcPriceSetVersionById(psvId);
@@ -140,39 +145,165 @@ public class CatalogVersionSupport
{
throw new ServiceException("请选择生效时间");
}
Date prevEff = findPrevEffectiveTime(ver);
if (prevEff != null && eff.before(prevEff))
boolean importFresh = "IMPORT_FRESH".equalsIgnoreCase(StringUtils.trim(ver.getPriceBuildMode()));
if (importFresh)
{
throw new ServiceException("生效时间不能早于上一版本");
validateImportFreshActivateTime(ver, eff);
}
boolean future = eff.after(new Date());
if (!future)
else
{
PrcPriceSetVersion q = new PrcPriceSetVersion();
q.setPriceType(ver.getPriceType());
q.setStatus(STATUS_EFFECT);
List<PrcPriceSetVersion> prevList = versionMapper.selectPrcPriceSetVersionList(q);
if (prevList != null)
Date prevEff = findPrevEffectiveTime(ver);
if (prevEff != null && eff.before(prevEff))
{
for (PrcPriceSetVersion prev : prevList)
{
if (prev.getPsvId().equals(psvId))
{
continue;
}
prev.setExpireTime(eff);
prev.setStatus(STATUS_EXPIRED);
versionMapper.updatePrcPriceSetVersion(prev);
}
throw new ServiceException("生效时间不能早于上一版本");
}
}
ver.setEffectiveTime(eff);
ver.setExpireTime(null);
ver.setStatus(future ? STATUS_PENDING : STATUS_EFFECT);
versionMapper.updatePrcPriceSetVersion(ver);
refreshCatalogStatuses(ver.getPriceType());
// Chain B.expire=A.eff, A.expire=next/B.oldExpire; refresh status + product/detail effect
chainAndRefreshCatalogStatuses(ver.getPriceType());
}
/**
* IMPORT_FRESH: may be earlier than prev-by-seq; must not equal any other version's eff/exp
* within the same PRODUCT/REDLINE type.
*/
private void validateImportFreshActivateTime(PrcPriceSetVersion version, Date effectiveTime)
{
if (version == null || effectiveTime == null || StringUtils.isEmpty(version.getPriceType()))
{
return;
}
PrcPriceSetVersion q = new PrcPriceSetVersion();
q.setPriceType(version.getPriceType());
List<PrcPriceSetVersion> list = versionMapper.selectPrcPriceSetVersionList(q);
if (list == null || list.isEmpty())
{
return;
}
for (PrcPriceSetVersion v : list)
{
if (v == null)
{
continue;
}
if (version.getPsvId() != null && version.getPsvId().equals(v.getPsvId()))
{
continue;
}
if (sameTime(v.getEffectiveTime(), effectiveTime) || sameTime(v.getExpireTime(), effectiveTime))
{
throw new ServiceException("生效时间不能与已有版本的生效时间或失效时间相同");
}
}
}
/**
* Sort timed versions by effective_time, chain expire_time = next start, then set status
* and sync product/detail effect fields (same idea as sales refreshVersionStatus).
*/
private void chainAndRefreshCatalogStatuses(String priceType)
{
assertCatalogType(priceType);
PrcPriceSetVersion q = new PrcPriceSetVersion();
q.setPriceType(priceType);
List<PrcPriceSetVersion> versions = versionMapper.selectPrcPriceSetVersionList(q);
if (versions == null || versions.isEmpty())
{
return;
}
versions.sort((a, b) -> {
Date ta = a.getEffectiveTime();
Date tb = b.getEffectiveTime();
if (ta == null && tb == null)
{
return Integer.compare(nullToZero(a.getVersionSeq()), nullToZero(b.getVersionSeq()));
}
if (ta == null)
{
return 1;
}
if (tb == null)
{
return -1;
}
int c = ta.compareTo(tb);
if (c != 0)
{
return c;
}
return Integer.compare(nullToZero(a.getVersionSeq()), nullToZero(b.getVersionSeq()));
});
Date now = new Date();
Long effectPsvId = null;
for (int i = 0; i < versions.size(); i++)
{
PrcPriceSetVersion v = versions.get(i);
Date nextStart = null;
for (int j = i + 1; j < versions.size(); j++)
{
Date t = versions.get(j).getEffectiveTime();
if (t != null)
{
nextStart = t;
break;
}
}
v.setExpireTime(nextStart);
if (v.getEffectiveTime() == null)
{
v.setStatus(STATUS_DRAFT);
continue;
}
if (v.getEffectiveTime().getTime() > now.getTime())
{
v.setStatus(STATUS_PENDING);
continue;
}
if (nextStart != null && nextStart.getTime() <= now.getTime())
{
v.setStatus(STATUS_EXPIRED);
continue;
}
v.setStatus(STATUS_EFFECT);
effectPsvId = v.getPsvId();
}
if (effectPsvId != null)
{
for (PrcPriceSetVersion v : versions)
{
if (STATUS_EFFECT.equals(v.getStatus())
&& v.getPsvId() != null
&& !v.getPsvId().equals(effectPsvId))
{
v.setStatus(STATUS_EXPIRED);
}
}
}
for (PrcPriceSetVersion v : versions)
{
PrcPriceSetVersion db = versionMapper.selectPrcPriceSetVersionById(v.getPsvId());
if (db == null)
{
continue;
}
boolean statusChanged = !String.valueOf(v.getStatus()).equals(String.valueOf(db.getStatus()));
boolean expireChanged = !sameTime(v.getExpireTime(), db.getExpireTime());
boolean effChanged = !sameTime(v.getEffectiveTime(), db.getEffectiveTime());
if (statusChanged || expireChanged || effChanged)
{
versionMapper.updatePrcPriceSetVersion(v);
}
}
productMapper.syncEffectByPriceType(priceType);
detailMapper.syncEffectByPriceType(priceType);
}
private static int nullToZero(Integer v)
{
return v == null ? 0 : v.intValue();
}
public List<PrcPriceSetVersion> listVersions(String priceType, String status)
@@ -345,14 +476,16 @@ public class CatalogVersionSupport
/**
* Prepare draft for catalog price create page.
* copyFromLatest=true: copy from current EFFECT version when draft is empty.
* copyFromLatest=false: empty draft (Excel import / rebuild).
* copyFromLatest=true → priceBuildMode=IMPORT: copy from current EFFECT version when draft is empty.
* copyFromLatest=false → priceBuildMode=IMPORT_FRESH: empty draft (Excel import / rebuild).
* Legacy values COPY/IMPORT are migrated by SQL to IMPORT/IMPORT_FRESH.
*/
public PrcPriceSetVersion prepareDraftVersion(String priceType, boolean copyFromLatest)
{
assertCatalogType(priceType);
List<PrcPriceSetVersion> drafts = listVersions(priceType, STATUS_DRAFT);
PrcPriceSetVersion draft;
String mode = copyFromLatest ? "IMPORT" : "IMPORT_FRESH";
if (drafts.isEmpty())
{
if (copyFromLatest)
@@ -364,7 +497,7 @@ public class CatalogVersionSupport
}
}
draft = ensureDraftVersion(priceType, null, copyFromLatest);
draft.setPriceBuildMode(copyFromLatest ? "COPY" : "IMPORT");
draft.setPriceBuildMode(mode);
versionMapper.updatePrcPriceSetVersion(draft);
return reloadCatalogVersion(draft.getPsvId(), priceType);
}
@@ -386,12 +519,12 @@ public class CatalogVersionSupport
productMapper.updatePriceTypeByPsvId(draft.getPsvId(), priceType);
detailMapper.updatePriceTypeByPsvId(draft.getPsvId(), priceType);
}
draft.setPriceBuildMode("COPY");
draft.setPriceBuildMode(mode);
versionMapper.updatePrcPriceSetVersion(draft);
}
else if (count == 0)
{
draft.setPriceBuildMode("IMPORT");
draft.setPriceBuildMode(mode);
versionMapper.updatePrcPriceSetVersion(draft);
}
return reloadCatalogVersion(draft.getPsvId(), priceType);
+1 -1
View File
@@ -1298,7 +1298,7 @@ CREATE TABLE `prc_price_set_version` (
`effective_time` datetime DEFAULT NULL COMMENT '生效时间',
`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继承上一版 IMPORT_FRESH=Excel重新建价',
`price_build_mode` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建价格方式 SALES:PULL/IMPORT/IMPORT_FRESH; PRODUCT/REDLINE:IMPORT=沿用生效版 IMPORT_FRESH=重新建价',
`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 '创建时间',
@@ -0,0 +1,15 @@
-- Catalog (PRODUCT / REDLINE) price_build_mode rename:
-- COPY → IMPORT (按现有生效版本建价)
-- IMPORT → IMPORT_FRESH (重新建产品价)
-- Order matters: migrate old IMPORT first, then COPY.
SET NAMES utf8mb4;
UPDATE prc_price_set_version
SET price_build_mode = 'IMPORT_FRESH'
WHERE price_type IN ('PRODUCT', 'REDLINE')
AND UPPER(IFNULL(price_build_mode, '')) = 'IMPORT';
UPDATE prc_price_set_version
SET price_build_mode = 'IMPORT'
WHERE price_type IN ('PRODUCT', 'REDLINE')
AND UPPER(IFNULL(price_build_mode, '')) = 'COPY';
@@ -1,3 +1,3 @@
-- Add create-price mode on package version: PULL / IMPORT
ALTER TABLE prc_price_set_version
ADD COLUMN price_build_mode varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建价格方式 PULL=拉取产品库 IMPORT=Excel继承上一版 IMPORT_FRESH=Excel重新建价' AFTER status;
ADD COLUMN price_build_mode varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建价格方式 SALES:PULL/IMPORT/IMPORT_FRESH; PRODUCT/REDLINE:IMPORT=沿用生效版 IMPORT_FRESH=重新建价' AFTER status;
@@ -1,10 +1,7 @@
<!-- start catalog version: pick effective hour -->
<!-- start catalog version: pick effective hour;IMPORT_FRESH 对齐销售价规则 -->
<template>
<el-dialog v-model="visible" :title="dialogTitle" width="460px" append-to-body @closed="onClosed">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-form-item :label="labNo">
<span>{{ form.versionNo || '-' }}</span>
</el-form-item>
<el-form-item :label="labEff" prop="effectiveTime">
<el-date-picker
v-model="form.effectiveTime"
@@ -17,6 +14,7 @@
:disabled-hours="disabledHours"
style="width: 100%"
@change="onTimeChange"
@visible-change="onPickerVisible"
/>
</el-form-item>
<div class="activate-hint">{{ hint }}</div>
@@ -28,6 +26,8 @@
</el-dialog>
</template>
<script setup>
import { isImportFreshBuildMode } from '@/views/price/set/utils/priceSet'
const props = defineProps({
loadVersions: { type: Function, required: true },
activateFn: { type: Function, required: true }
@@ -39,31 +39,43 @@ const submitting = ref(false)
const formRef = ref()
const versions = ref([])
const prevEff = ref()
const form = reactive({ psvId: undefined, versionNo: '', versionSeq: 0, effectiveTime: undefined })
const isImportFresh = ref(false)
const boundaryTimes = ref([])
const form = reactive({ psvId: undefined, versionNo: '', versionSeq: 0, effectiveTime: undefined, priceBuildMode: undefined })
const dialogTitle = '启动版本'
const labNo = '版本号'
const labEff = '生效时间'
const ph = '请选择生效时间'
const btnCancel = '取消'
const btnOk = '确认启动'
const beforePrev = '生效时间不能早于上一版本的生效时间'
const hitBoundary = '生效时间不能与已有版本的生效时间或失效时间相同'
const hint = computed(() => {
if (isImportFresh.value) {
return '重新建价:生效时间可落在历史版本区间内;落在版本 B 区间时,B 失效时间改为本次启动时间,本版本失效时间取 B 原失效时间,并同步产品/明细。不可与本类型已有版本的生效时间或失效时间相同。'
}
const base = '若生效时间晚于当前,版本将进入待生效;到时自动生效并使上一版本失效。'
return prevEff.value ? (base + '不得早于上一版:' + prevEff.value + '。') : base
})
const rules = {
const rules = computed(() => ({
effectiveTime: [
{ required: true, message: ph, trigger: 'change' },
{
validator: (_r, v, cb) => {
if (!v || !prevEff.value) return cb()
if (toMs(v) < toMs(prevEff.value)) return cb(new Error(beforePrev))
if (!v) return cb()
if (isImportFresh.value) {
const ms = toMs(v)
if (boundaryTimes.value.some(b => toMs(b) === ms)) {
return cb(new Error(hitBoundary))
}
return cb()
}
if (prevEff.value && toMs(v) < toMs(prevEff.value)) return cb(new Error(beforePrev))
cb()
},
trigger: 'change'
}
]
}
}))
function pad2(n) { return String(n).padStart(2, '0') }
function formatHour(d) {
if (!d || Number.isNaN(d.getTime())) return undefined
@@ -93,14 +105,29 @@ function findPrev(row) {
}
return prev ? normalizeToHour(prev.effectiveTime) : undefined
}
function pickDefault(prev) {
function collectBoundaryTimes(excludePsvId) {
const out = []
const seen = new Set()
for (const v of versions.value || []) {
if (!v || v.psvId == null || String(v.psvId) === String(excludePsvId)) continue
;[v.effectiveTime, v.expireTime].forEach(t => {
const n = t ? normalizeToHour(t) : ''
if (!n || seen.has(n)) return
seen.add(n)
out.push(n)
})
}
return out
}
function pickDefault(prev, importFresh) {
const d = new Date()
d.setHours(9, 0, 0, 0)
const now = formatHour(d)
if (!prev) return now
if (importFresh || !prev) return now
return toMs(now) >= toMs(prev) ? now : prev
}
function disabledDate(date) {
if (isImportFresh.value) return false
if (!prevEff.value || !date) return false
const prevDay = new Date(String(prevEff.value).replace(/-/g, '/'))
prevDay.setHours(0, 0, 0, 0)
@@ -109,11 +136,25 @@ function disabledDate(date) {
return d.getTime() < prevDay.getTime()
}
function disabledHours() {
if (!prevEff.value) return []
const prevD = new Date(String(prevEff.value).replace(/-/g, '/'))
const curD = form.effectiveTime
? new Date(String(normalizeToHour(form.effectiveTime)).replace(/-/g, '/'))
: new Date()
if (isImportFresh.value) {
const hours = new Set()
for (const b of boundaryTimes.value) {
const bd = new Date(String(b).replace(/-/g, '/'))
if (
bd.getFullYear() === curD.getFullYear() &&
bd.getMonth() === curD.getMonth() &&
bd.getDate() === curD.getDate()
) {
hours.add(bd.getHours())
}
}
return [...hours]
}
if (!prevEff.value) return []
const prevD = new Date(String(prevEff.value).replace(/-/g, '/'))
if (prevD.getFullYear() !== curD.getFullYear() || prevD.getMonth() !== curD.getMonth() || prevD.getDate() !== curD.getDate()) return []
const hours = []
for (let h = 0; h < prevD.getHours(); h++) hours.push(h)
@@ -123,6 +164,9 @@ function onTimeChange(val) {
form.effectiveTime = normalizeToHour(val)
formRef.value && formRef.value.validateField('effectiveTime')
}
function onPickerVisible(visible) {
if (visible && formRef.value) formRef.value.validateField('effectiveTime')
}
async function open(row) {
if (!row || row.psvId == null) return
const list = await props.loadVersions()
@@ -131,15 +175,21 @@ async function open(row) {
form.psvId = found.psvId
form.versionNo = found.versionNo || ''
form.versionSeq = found.versionSeq
form.priceBuildMode = found.priceBuildMode
isImportFresh.value = isImportFreshBuildMode(found.priceBuildMode)
prevEff.value = findPrev(found)
form.effectiveTime = pickDefault(prevEff.value)
boundaryTimes.value = isImportFresh.value ? collectBoundaryTimes(found.psvId) : []
form.effectiveTime = pickDefault(prevEff.value, isImportFresh.value)
visible.value = true
}
function onClosed() {
form.psvId = undefined
form.versionNo = ''
form.effectiveTime = undefined
form.priceBuildMode = undefined
prevEff.value = undefined
isImportFresh.value = false
boundaryTimes.value = []
formRef.value && formRef.value.clearValidate()
}
function submit() {
@@ -29,8 +29,8 @@
<div class="build-choice__cards">
<button
type="button"
class="build-card build-card--pull"
:class="{ selected: buildMode === 'COPY' }"
class="build-card build-card--import"
:class="{ selected: buildMode === 'IMPORT' }"
:disabled="!!psvId || choosing || finishing"
@click="chooseMode(true)"
>
@@ -39,8 +39,8 @@
</button>
<button
type="button"
class="build-card build-card--import"
:class="{ selected: buildMode === 'IMPORT' }"
class="build-card build-card--import-fresh"
:class="{ selected: buildMode === 'IMPORT_FRESH' }"
:disabled="!!psvId || choosing || finishing"
@click="chooseMode(false)"
>
@@ -183,7 +183,7 @@ const route = useRoute()
const labTip = '创建价格方式'
const labModeCopy = '按现有生效版本建价'
const labModeCopyDesc = '先本地预览已生效版本产品,点击「完成」时再复制到待生效草稿'
const labModeFresh = '重新建产品价'
const labModeFresh = '新建产品价'
const labModeFreshDesc = "不沿用已生效版本;导入解析后先展示,点「完成」时再写入草稿"
const labImport = '导入 Excel 建价'
const labImportAll = '全部导入(多国家价表)'
@@ -300,9 +300,10 @@ function applyVersion(ver) {
}
psvId.value = ver.psvId
versionNo.value = ver.versionNo || ''
// Catalog: IMPORT = 沿用生效版; IMPORT_FRESH = 重新建价. Legacy COPY → IMPORT.
const mode = String(ver.priceBuildMode || '').toUpperCase()
if (mode === 'COPY') buildMode.value = 'COPY'
else if (mode === 'IMPORT' || mode === 'PULL') buildMode.value = 'IMPORT'
if (mode === 'IMPORT' || mode === 'COPY') buildMode.value = 'IMPORT'
else if (mode === 'IMPORT_FRESH' || mode === 'PULL') buildMode.value = 'IMPORT_FRESH'
}
async function loadProducts() {
@@ -329,7 +330,7 @@ async function bootstrap() {
psvId.value = Number(qPsv)
versionNo.value = (route.query && route.query.versionNo) ? String(route.query.versionNo) : ''
editingExisting.value = true
if (!buildMode.value) buildMode.value = 'IMPORT'
if (!buildMode.value) buildMode.value = 'IMPORT_FRESH'
await loadProducts()
}
} finally {
@@ -337,10 +338,10 @@ async function bootstrap() {
}
}
/** Mode select: local only, no DB write. */
/** Mode select: local only, no DB write. inherit=IMPORT, fresh=IMPORT_FRESH. */
async function chooseMode(copyFromLatest) {
if (psvId.value || choosing.value || finishing.value) return
const next = copyFromLatest ? 'COPY' : 'IMPORT'
const next = copyFromLatest ? 'IMPORT' : 'IMPORT_FRESH'
if (buildMode.value === next && (copyFromLatest ? rows.value.length : true)) {
if (copyFromLatest && rows.value.length) return
if (!copyFromLatest && !rows.value.length && !pendingImports.value.length) return
@@ -426,7 +427,7 @@ async function persistDraft() {
proxy.$modal.msgWarning('请先选择建价方式')
return false
}
const res = await props.prepareFn(buildMode.value === 'COPY')
const res = await props.prepareFn(buildMode.value === 'IMPORT')
applyVersion(res.data)
return !!psvId.value
}
@@ -682,8 +683,10 @@ onMounted(() => { bootstrap() })
.build-card:hover:not(:disabled) { box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06); }
.build-card:disabled { opacity: 0.55; cursor: not-allowed; }
.build-card__title { font-size: 16px; font-weight: 600; color: #303133; margin-bottom: 10px; }
.build-card--pull .build-card__title { color: #67c23a; }
.build-card--import .build-card__title { color: #409eff; }
.build-card--import-fresh .build-card__title { color: #e6a23c; }
.build-card--import:hover:not(:disabled) { border-color: #409eff; }
.build-card--import-fresh:hover:not(:disabled) { border-color: #e6a23c; }
.build-card__desc { font-size: 13px; line-height: 1.6; color: #909399; }
.filters { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.filters__left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
@@ -75,7 +75,7 @@
:disabled="!canChooseBuildMode || !isFixedType(setType)"
@click="chooseBuildMode('IMPORT_FRESH')"
>
<div class="build-card__title">Excel 重新建价</div>
<div class="build-card__title">Excel 新建价</div>
<div class="build-card__desc">不延用以前的产品价格,不带出上一版,上传 Excel 直接生成套餐销售价</div>
</button>
</div>
@@ -338,7 +338,7 @@ const importDesc = computed(() => {
return [
'适用威狮B2C小包价表(含「产品目录」)。',
'不延用以前的产品价格;导入按「产品+国家」写入套餐销售价,直接生成产品明细。',
'同一产品下重复国家+重量段将整单失败。仅固定价套餐「Excel 重新建价」可用。'
'同一产品下重复国家+重量段将整单失败。仅固定价套餐「Excel 新建价」可用。'
]
}
return [
@@ -351,7 +351,7 @@ const importDesc = computed(() => {
const typeHint = computed(() => {
if (isPullBuildMode(props.priceBuildMode)) return '· 按产品价建价'
if (isImportBuildMode(props.priceBuildMode)) return '· 按上一版 Excel 建价'
if (isImportFreshBuildMode(props.priceBuildMode)) return '· Excel 重新建价'
if (isImportFreshBuildMode(props.priceBuildMode)) return '· Excel 新建价'
if (hasBuildMode.value) return '· 当前:' + setTypeLabel(props.setType)
return '· 请选择创建价格方式'
})
+2 -2
View File
@@ -235,8 +235,8 @@ const activateEffHitBoundaryMsg = '生效时间不能与已有版本的生效时
const activateDialogHint = computed(() => {
if (activateIsImportFresh.value) {
const base = activateMode.value === 'reschedule'
? 'Excel 重新建价:生效时间可落在历史版本区间内,将自动截断该版本失效时间并同步产品/明细。'
: 'Excel 重新建价:生效时间可落在历史版本区间内;落在版本 B 区间时,B 失效时间改为本次启动时间,本版本失效时间取 B 原失效时间,并同步双方产品/明细。'
? 'Excel 新建价:生效时间可落在历史版本区间内,将自动截断该版本失效时间并同步产品/明细。'
: 'Excel 新建价:生效时间可落在历史版本区间内;落在版本 B 区间时,B 失效时间改为本次启动时间,本版本失效时间取 B 原失效时间,并同步双方产品/明细。'
return base + '不可与已有版本的生效时间或失效时间相同。'
}
const base = activateMode.value === 'reschedule'