优化套餐新建版本的逻辑
This commit is contained in:
@@ -205,6 +205,7 @@ price.bill.fee.idRequired=费用ID不能为空
|
|||||||
|
|
||||||
price.set.version.effectiveTime.empty=版本生效时间不能为空
|
price.set.version.effectiveTime.empty=版本生效时间不能为空
|
||||||
price.set.version.effectiveTime.beforePrev=生效时间不能早于上一版本的生效时间
|
price.set.version.effectiveTime.beforePrev=生效时间不能早于上一版本的生效时间
|
||||||
|
price.set.version.effectiveTime.hitBoundary=生效时间不能与已有版本的生效时间或失效时间相同
|
||||||
price.set.version.notExists=套餐版本不存在
|
price.set.version.notExists=套餐版本不存在
|
||||||
price.set.version.activate.statusNotAllowed=仅草稿或待生效版本可设置生效时间
|
price.set.version.activate.statusNotAllowed=仅草稿或待生效版本可设置生效时间
|
||||||
price.set.version.delete.statusNotAllowed=仅草稿、待生效或已生效版本可删除
|
price.set.version.delete.statusNotAllowed=仅草稿、待生效或已生效版本可删除
|
||||||
|
|||||||
+45
@@ -401,11 +401,21 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
{
|
{
|
||||||
throw new ServiceException(MessageUtils.message("price.set.edit.stopped"));
|
throw new ServiceException(MessageUtils.message("price.set.edit.stopped"));
|
||||||
}
|
}
|
||||||
|
boolean importFresh = "IMPORT_FRESH".equalsIgnoreCase(StringUtils.trim(version.getPriceBuildMode()));
|
||||||
|
if (importFresh)
|
||||||
|
{
|
||||||
|
// May start inside a prior version window; forbid equal to any other version's eff/exp.
|
||||||
|
// refreshVersionStatus then sets B.expire=A.eff, A.expire=B.oldExpire and syncs children.
|
||||||
|
validateImportFreshActivateTime(version, effectiveTime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Date prevEffective = findPrevVersionEffectiveTime(version);
|
Date prevEffective = findPrevVersionEffectiveTime(version);
|
||||||
if (prevEffective != null && effectiveTime.before(prevEffective))
|
if (prevEffective != null && effectiveTime.before(prevEffective))
|
||||||
{
|
{
|
||||||
throw new ServiceException(MessageUtils.message("price.set.version.effectiveTime.beforePrev"));
|
throw new ServiceException(MessageUtils.message("price.set.version.effectiveTime.beforePrev"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Set schedule; refreshVersionStatus decides PENDING(3) vs EFFECT(1) and chains expire_time
|
// Set schedule; refreshVersionStatus decides PENDING(3) vs EFFECT(1) and chains expire_time
|
||||||
version.setEffectiveTime(effectiveTime);
|
version.setEffectiveTime(effectiveTime);
|
||||||
version.setExpireTime(null);
|
version.setExpireTime(null);
|
||||||
@@ -415,6 +425,41 @@ public class PrcPriceSetServiceImpl implements IPrcPriceSetService
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IMPORT_FRESH activate: allow effective time earlier than prev-by-seq (incl. inside prior window B).
|
||||||
|
* Must not equal any other timed version's effectiveTime or expireTime.
|
||||||
|
*/
|
||||||
|
private void validateImportFreshActivateTime(PrcPriceSetVersion version, Date effectiveTime)
|
||||||
|
{
|
||||||
|
if (version == null || version.getPriceSetId() == null || effectiveTime == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PrcPriceSetVersion q = new PrcPriceSetVersion();
|
||||||
|
q.setPriceSetId(version.getPriceSetId());
|
||||||
|
q.setPriceType(com.bms.price.domain.PriceType.SALES);
|
||||||
|
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(MessageUtils.message("price.set.version.effectiveTime.hitBoundary"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Previous version (lower version_seq) effective_time; null if none. */
|
/** Previous version (lower version_seq) effective_time; null if none. */
|
||||||
private Date findPrevVersionEffectiveTime(PrcPriceSetVersion version)
|
private Date findPrevVersionEffectiveTime(PrcPriceSetVersion version)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,6 +58,7 @@
|
|||||||
<div class="build-card__desc">按产品库基础价生成套餐产品列表,可再导入 Excel 修改价格</div>
|
<div class="build-card__desc">按产品库基础价生成套餐产品列表,可再导入 Excel 修改价格</div>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
v-if="showImportInherit"
|
||||||
type="button"
|
type="button"
|
||||||
class="build-card build-card--import"
|
class="build-card build-card--import"
|
||||||
:class="{ selected: isImportBuildMode(priceBuildMode) }"
|
:class="{ selected: isImportBuildMode(priceBuildMode) }"
|
||||||
@@ -247,7 +248,12 @@ const props = defineProps({
|
|||||||
/** True when build mode changed locally and not saved yet */
|
/** True when build mode changed locally and not saved yet */
|
||||||
buildModeDirty: { type: Boolean, default: false },
|
buildModeDirty: { type: Boolean, default: false },
|
||||||
/** False while parent still loading package data — avoid first click being wiped by applySetData */
|
/** False while parent still loading package data — avoid first click being wiped by applySetData */
|
||||||
buildModeReady: { type: Boolean, default: true }
|
buildModeReady: { type: Boolean, default: true },
|
||||||
|
/**
|
||||||
|
* Show「按上一版 Excel 建价」(IMPORT). Hidden for brand-new package create
|
||||||
|
* (no prior version); keep for newVersion / copy / edit.
|
||||||
|
*/
|
||||||
|
showImportInherit: { type: Boolean, default: true }
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits(['update:psvId', 'update:priceBuildMode', 'update:pefId'])
|
const emit = defineEmits(['update:psvId', 'update:priceBuildMode', 'update:pefId'])
|
||||||
|
|||||||
@@ -173,7 +173,8 @@ const noneSc = '无'
|
|||||||
const isFixed = computed(() => isFixedType(props.setType))
|
const isFixed = computed(() => isFixedType(props.setType))
|
||||||
const title = computed(() => {
|
const title = computed(() => {
|
||||||
const v = props.version || {}
|
const v = props.version || {}
|
||||||
return (v.versionNo || '-') + ' · 版本明细'
|
const eff = v.effectiveTime || '未设置生效时间'
|
||||||
|
return eff + ' · 版本明细'
|
||||||
})
|
})
|
||||||
const detailTitleText = computed(() => {
|
const detailTitleText = computed(() => {
|
||||||
const p = activeProduct.value || {}
|
const p = activeProduct.value || {}
|
||||||
|
|||||||
@@ -19,13 +19,10 @@
|
|||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
<el-table :data="filteredVersions" border empty-text="暂无版本">
|
<el-table :data="filteredVersions" border empty-text="暂无版本">
|
||||||
<el-table-column :label="colNo" width="100">
|
|
||||||
<template #default="{ row }">
|
|
||||||
<el-button link type="primary" @click="openDetails(row)">{{ row.versionNo || '-' }}</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column :label="colEff" min-width="170">
|
<el-table-column :label="colEff" min-width="170">
|
||||||
<template #default="{ row }">{{ row.effectiveTime || '-' }}</template>
|
<template #default="{ row }">
|
||||||
|
<el-button link type="primary" @click="openDetails(row)">{{ row.effectiveTime || '未设置' }}</el-button>
|
||||||
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column :label="colExp" min-width="170">
|
<el-table-column :label="colExp" min-width="170">
|
||||||
<template #default="{ row }">{{ row.expireTime || '-' }}</template>
|
<template #default="{ row }">{{ row.expireTime || '-' }}</template>
|
||||||
@@ -90,7 +87,6 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(['update:modelValue', 'create-version', 'open-details', 'view-import-attach', 'activate', 'reschedule', 'edit', 'remove'])
|
const emit = defineEmits(['update:modelValue', 'create-version', 'open-details', 'view-import-attach', 'activate', 'reschedule', 'edit', 'remove'])
|
||||||
|
|
||||||
const title = '套餐版本'
|
const title = '套餐版本'
|
||||||
const colNo = '版本号'
|
|
||||||
const colEff = '生效时间'
|
const colEff = '生效时间'
|
||||||
const colExp = '失效时间'
|
const colExp = '失效时间'
|
||||||
const colStatus = '状态'
|
const colStatus = '状态'
|
||||||
@@ -121,10 +117,33 @@ function tabLabel(key) {
|
|||||||
|
|
||||||
const hasDraft = computed(() => (props.versions || []).some(v => isDraftVersion(v)))
|
const hasDraft = computed(() => (props.versions || []).some(v => isDraftVersion(v)))
|
||||||
|
|
||||||
|
function toEffMs(v) {
|
||||||
|
if (!v || !v.effectiveTime) return NaN
|
||||||
|
const t = new Date(String(v.effectiveTime).replace(/-/g, '/')).getTime()
|
||||||
|
return Number.isNaN(t) ? NaN : t
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sort by effective time descending; drafts without time last. */
|
||||||
|
function sortByEffectiveTime(list) {
|
||||||
|
return (list || []).slice().sort((a, b) => {
|
||||||
|
const ta = toEffMs(a)
|
||||||
|
const tb = toEffMs(b)
|
||||||
|
const aNull = Number.isNaN(ta)
|
||||||
|
const bNull = Number.isNaN(tb)
|
||||||
|
if (aNull && bNull) return (Number(b.versionSeq) || 0) - (Number(a.versionSeq) || 0)
|
||||||
|
if (aNull) return 1
|
||||||
|
if (bNull) return -1
|
||||||
|
if (tb !== ta) return tb - ta
|
||||||
|
return (Number(b.versionSeq) || 0) - (Number(a.versionSeq) || 0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const filteredVersions = computed(() => {
|
const filteredVersions = computed(() => {
|
||||||
const list = props.versions || []
|
const list = props.versions || []
|
||||||
if (statusTab.value === 'all') return list
|
const filtered = statusTab.value === 'all'
|
||||||
return list.filter(v => String(v.status) === statusTab.value)
|
? list
|
||||||
|
: list.filter(v => String(v.status) === statusTab.value)
|
||||||
|
return sortByEffectiveTime(filtered)
|
||||||
})
|
})
|
||||||
|
|
||||||
function detailCount(row) {
|
function detailCount(row) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
:live-persist="livePersist"
|
:live-persist="livePersist"
|
||||||
:build-mode-dirty="buildModeDirty"
|
:build-mode-dirty="buildModeDirty"
|
||||||
:build-mode-ready="pageReady"
|
:build-mode-ready="pageReady"
|
||||||
|
:show-import-inherit="showImportInherit"
|
||||||
:header-title="detailsHeaderTitle"
|
:header-title="detailsHeaderTitle"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -82,6 +83,8 @@ const deferPersist = computed(() => copyMode.value || newVersionMode.value)
|
|||||||
const showBasic = computed(() => !deferPersist.value && String(route.query.step || '') !== '2')
|
const showBasic = computed(() => !deferPersist.value && String(route.query.step || '') !== '2')
|
||||||
/** Edit existing version: live PUT/pull/import. New create / copy / newVersion: defer until finish. */
|
/** Edit existing version: live PUT/pull/import. New create / copy / newVersion: defer until finish. */
|
||||||
const livePersist = computed(() => !!form.priceSetId && !deferPersist.value)
|
const livePersist = computed(() => !!form.priceSetId && !deferPersist.value)
|
||||||
|
/** Brand-new package has no prior version — hide IMPORT inherit card. */
|
||||||
|
const showImportInherit = computed(() => newVersionMode.value || copyMode.value)
|
||||||
|
|
||||||
const detailsHeaderTitle = '编辑产品价格'
|
const detailsHeaderTitle = '编辑产品价格'
|
||||||
|
|
||||||
@@ -382,7 +385,7 @@ function onPriceBuildModeUpdate(mode) {
|
|||||||
proxy.$modal.msgSuccess("已拉取产品列表,可继续编辑价格")
|
proxy.$modal.msgSuccess("已拉取产品列表,可继续编辑价格")
|
||||||
}).catch(() => {})
|
}).catch(() => {})
|
||||||
})
|
})
|
||||||
} else if (mode === 'IMPORT') {
|
} else if (mode === 'IMPORT' && showImportInherit.value) {
|
||||||
nextTick(async () => {
|
nextTick(async () => {
|
||||||
// newVersion/copy: wait until loadExisting fills priceSetId
|
// newVersion/copy: wait until loadExisting fills priceSetId
|
||||||
const qid = route.query.priceSetId
|
const qid = route.query.priceSetId
|
||||||
@@ -397,7 +400,7 @@ function onPriceBuildModeUpdate(mode) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!form.priceSetId) {
|
if (!form.priceSetId) {
|
||||||
proxy.$modal.msgSuccess("新建套餐无历史版本可带出,请直接导入 Excel 建价")
|
proxy.$modal.msgSuccess("请直接导入 Excel 建价")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -50,9 +50,6 @@
|
|||||||
@closed="onActivateClosed"
|
@closed="onActivateClosed"
|
||||||
>
|
>
|
||||||
<el-form ref="activateFormRef" :model="activateForm" :rules="activateRules" label-width="100px">
|
<el-form ref="activateFormRef" :model="activateForm" :rules="activateRules" label-width="100px">
|
||||||
<el-form-item label="版本号">
|
|
||||||
<span>{{ activateForm.versionNo || '-' }}</span>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="生效时间" prop="effectiveTime">
|
<el-form-item label="生效时间" prop="effectiveTime">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="activateForm.effectiveTime"
|
v-model="activateForm.effectiveTime"
|
||||||
@@ -92,7 +89,7 @@ import { usePriceSetRefData } from './composables/usePriceSetRefData'
|
|||||||
import {
|
import {
|
||||||
getPriceSet, disablePriceSet, enablePriceSet, activatePriceSetVersion, deletePriceSetVersion
|
getPriceSet, disablePriceSet, enablePriceSet, activatePriceSetVersion, deletePriceSetVersion
|
||||||
} from '@/api/price/set'
|
} from '@/api/price/set'
|
||||||
import { isDraftVersion, isPendingVersion, isEffectVersion } from './utils/priceSet'
|
import { isDraftVersion, isPendingVersion, isEffectVersion, isImportFreshBuildMode } from './utils/priceSet'
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
@@ -233,8 +230,18 @@ const activateConfirmText = computed(() =>
|
|||||||
activateMode.value === 'reschedule' ? '确认修改' : '确认启动'
|
activateMode.value === 'reschedule' ? '确认修改' : '确认启动'
|
||||||
)
|
)
|
||||||
const activatePrevEffectiveTime = ref(undefined)
|
const activatePrevEffectiveTime = ref(undefined)
|
||||||
|
const activateIsImportFresh = ref(false)
|
||||||
|
/** Other versions' effective/expire times (hour) — forbidden for IMPORT_FRESH */
|
||||||
|
const activateBoundaryTimes = ref([])
|
||||||
const activateEffBeforePrevMsg = '生效时间不能早于上一版本的生效时间'
|
const activateEffBeforePrevMsg = '生效时间不能早于上一版本的生效时间'
|
||||||
|
const activateEffHitBoundaryMsg = '生效时间不能与已有版本的生效时间或失效时间相同'
|
||||||
const activateDialogHint = computed(() => {
|
const activateDialogHint = computed(() => {
|
||||||
|
if (activateIsImportFresh.value) {
|
||||||
|
const base = activateMode.value === 'reschedule'
|
||||||
|
? 'Excel 重新建价:生效时间可落在历史版本区间内,将自动截断该版本失效时间并同步产品/明细。'
|
||||||
|
: 'Excel 重新建价:生效时间可落在历史版本区间内;落在版本 B 区间时,B 失效时间改为本次启动时间,本版本失效时间取 B 原失效时间,并同步双方产品/明细。'
|
||||||
|
return base + '不可与已有版本的生效时间或失效时间相同。'
|
||||||
|
}
|
||||||
const base = activateMode.value === 'reschedule'
|
const base = activateMode.value === 'reschedule'
|
||||||
? '仅待生效版本可修改;若时间晚于当前仍为待生效,到时自动生效并使上一版本失效。'
|
? '仅待生效版本可修改;若时间晚于当前仍为待生效,到时自动生效并使上一版本失效。'
|
||||||
: '若生效时间晚于当前,版本将进入「待生效」;到时自动生效并使上一版本失效。'
|
: '若生效时间晚于当前,版本将进入「待生效」;到时自动生效并使上一版本失效。'
|
||||||
@@ -242,20 +249,27 @@ const activateDialogHint = computed(() => {
|
|||||||
if (!prev) return base
|
if (!prev) return base
|
||||||
return base + '不得早于上一版:' + prev + '。'
|
return base + '不得早于上一版:' + prev + '。'
|
||||||
})
|
})
|
||||||
const activateRules = {
|
const activateRules = computed(() => ({
|
||||||
effectiveTime: [
|
effectiveTime: [
|
||||||
{ required: true, message: '请选择生效时间', trigger: 'change' },
|
{ required: true, message: '请选择生效时间', trigger: 'change' },
|
||||||
{
|
{
|
||||||
validator: (_r, v, cb) => {
|
validator: (_r, v, cb) => {
|
||||||
|
if (!v) return cb()
|
||||||
|
if (activateIsImportFresh.value) {
|
||||||
|
const ms = toTimeMs(v)
|
||||||
|
if (activateBoundaryTimes.value.some(b => toTimeMs(b) === ms)) {
|
||||||
|
return cb(new Error(activateEffHitBoundaryMsg))
|
||||||
|
}
|
||||||
|
return cb()
|
||||||
|
}
|
||||||
const prev = activatePrevEffectiveTime.value
|
const prev = activatePrevEffectiveTime.value
|
||||||
if (!v || !prev) return cb()
|
if (prev && toTimeMs(v) < toTimeMs(prev)) return cb(new Error(activateEffBeforePrevMsg))
|
||||||
if (toTimeMs(v) < toTimeMs(prev)) return cb(new Error(activateEffBeforePrevMsg))
|
|
||||||
cb()
|
cb()
|
||||||
},
|
},
|
||||||
trigger: 'change'
|
trigger: 'change'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}))
|
||||||
|
|
||||||
function toTimeMs(val) {
|
function toTimeMs(val) {
|
||||||
if (val == null || val === '') return NaN
|
if (val == null || val === '') return NaN
|
||||||
@@ -278,13 +292,30 @@ function findPrevVersionEffectiveTime(row) {
|
|||||||
return prev ? normalizeToHour(prev.effectiveTime) : undefined
|
return prev ? normalizeToHour(prev.effectiveTime) : undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickActivateDefaultTime(prev) {
|
/** Collect other versions' effective/expire hour times (forbidden for IMPORT_FRESH). */
|
||||||
|
function collectActivateBoundaryTimes(excludePsvId) {
|
||||||
|
const out = []
|
||||||
|
const seen = new Set()
|
||||||
|
for (const v of set.value.versions || []) {
|
||||||
|
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 pickActivateDefaultTime(prev, importFresh) {
|
||||||
const now = formatNow()
|
const now = formatNow()
|
||||||
if (!prev) return now
|
if (importFresh || !prev) return now
|
||||||
return toTimeMs(now) >= toTimeMs(prev) ? now : prev
|
return toTimeMs(now) >= toTimeMs(prev) ? now : prev
|
||||||
}
|
}
|
||||||
|
|
||||||
function disabledActivateDate(date) {
|
function disabledActivateDate(date) {
|
||||||
|
if (activateIsImportFresh.value) return false
|
||||||
const prev = activatePrevEffectiveTime.value
|
const prev = activatePrevEffectiveTime.value
|
||||||
if (!prev || !date) return false
|
if (!prev || !date) return false
|
||||||
const prevDay = new Date(String(prev).replace(/-/g, '/'))
|
const prevDay = new Date(String(prev).replace(/-/g, '/'))
|
||||||
@@ -295,13 +326,27 @@ function disabledActivateDate(date) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function disabledActivateHours() {
|
function disabledActivateHours() {
|
||||||
const prev = activatePrevEffectiveTime.value
|
|
||||||
const cur = activateForm.effectiveTime
|
const cur = activateForm.effectiveTime
|
||||||
if (!prev) return []
|
|
||||||
const prevD = new Date(String(prev).replace(/-/g, '/'))
|
|
||||||
const curD = cur
|
const curD = cur
|
||||||
? new Date(String(normalizeToHour(cur)).replace(/-/g, '/'))
|
? new Date(String(normalizeToHour(cur)).replace(/-/g, '/'))
|
||||||
: new Date()
|
: new Date()
|
||||||
|
if (activateIsImportFresh.value) {
|
||||||
|
const hours = new Set()
|
||||||
|
for (const b of activateBoundaryTimes.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]
|
||||||
|
}
|
||||||
|
const prev = activatePrevEffectiveTime.value
|
||||||
|
if (!prev) return []
|
||||||
|
const prevD = new Date(String(prev).replace(/-/g, '/'))
|
||||||
if (
|
if (
|
||||||
prevD.getFullYear() !== curD.getFullYear() ||
|
prevD.getFullYear() !== curD.getFullYear() ||
|
||||||
prevD.getMonth() !== curD.getMonth() ||
|
prevD.getMonth() !== curD.getMonth() ||
|
||||||
@@ -321,30 +366,38 @@ function onActivatePickerVisible(visible) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onActivateVersion(row) {
|
function openActivateDialog(row, mode) {
|
||||||
if (!row || row.psvId == null) return
|
if (!row || row.psvId == null) return
|
||||||
activateMode.value = 'activate'
|
activateMode.value = mode
|
||||||
activateForm.psvId = row.psvId
|
activateForm.psvId = row.psvId
|
||||||
activateForm.versionNo = row.versionNo || ''
|
activateForm.versionNo = row.versionNo || ''
|
||||||
|
activateIsImportFresh.value = isImportFreshBuildMode(row.priceBuildMode)
|
||||||
activatePrevEffectiveTime.value = findPrevVersionEffectiveTime(row)
|
activatePrevEffectiveTime.value = findPrevVersionEffectiveTime(row)
|
||||||
activateForm.effectiveTime = pickActivateDefaultTime(activatePrevEffectiveTime.value)
|
activateBoundaryTimes.value = activateIsImportFresh.value
|
||||||
|
? collectActivateBoundaryTimes(row.psvId)
|
||||||
|
: []
|
||||||
|
const prev = activatePrevEffectiveTime.value
|
||||||
|
if (mode === 'reschedule') {
|
||||||
|
const cur = normalizeToHour(row.effectiveTime)
|
||||||
|
if (activateIsImportFresh.value) {
|
||||||
|
activateForm.effectiveTime = cur || pickActivateDefaultTime(prev, true)
|
||||||
|
} else if (cur && (!prev || toTimeMs(cur) >= toTimeMs(prev))) {
|
||||||
|
activateForm.effectiveTime = cur
|
||||||
|
} else {
|
||||||
|
activateForm.effectiveTime = pickActivateDefaultTime(prev, false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
activateForm.effectiveTime = pickActivateDefaultTime(prev, activateIsImportFresh.value)
|
||||||
|
}
|
||||||
activateVisible.value = true
|
activateVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onActivateVersion(row) {
|
||||||
|
openActivateDialog(row, 'activate')
|
||||||
|
}
|
||||||
|
|
||||||
function onRescheduleVersion(row) {
|
function onRescheduleVersion(row) {
|
||||||
if (!row || row.psvId == null) return
|
openActivateDialog(row, 'reschedule')
|
||||||
activateMode.value = 'reschedule'
|
|
||||||
activateForm.psvId = row.psvId
|
|
||||||
activateForm.versionNo = row.versionNo || ''
|
|
||||||
activatePrevEffectiveTime.value = findPrevVersionEffectiveTime(row)
|
|
||||||
const cur = normalizeToHour(row.effectiveTime)
|
|
||||||
const prev = activatePrevEffectiveTime.value
|
|
||||||
if (cur && (!prev || toTimeMs(cur) >= toTimeMs(prev))) {
|
|
||||||
activateForm.effectiveTime = cur
|
|
||||||
} else {
|
|
||||||
activateForm.effectiveTime = pickActivateDefaultTime(prev)
|
|
||||||
}
|
|
||||||
activateVisible.value = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onActivateClosed() {
|
function onActivateClosed() {
|
||||||
@@ -353,6 +406,8 @@ function onActivateClosed() {
|
|||||||
activateForm.versionNo = ''
|
activateForm.versionNo = ''
|
||||||
activateForm.effectiveTime = undefined
|
activateForm.effectiveTime = undefined
|
||||||
activatePrevEffectiveTime.value = undefined
|
activatePrevEffectiveTime.value = undefined
|
||||||
|
activateIsImportFresh.value = false
|
||||||
|
activateBoundaryTimes.value = []
|
||||||
activateFormRef.value && activateFormRef.value.clearValidate()
|
activateFormRef.value && activateFormRef.value.clearValidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,8 +449,8 @@ function onCreateVersion() {
|
|||||||
function onRemoveVersion(row) {
|
function onRemoveVersion(row) {
|
||||||
if (!row || row.psvId == null) return
|
if (!row || row.psvId == null) return
|
||||||
const msg = isEffectVersion(row)
|
const msg = isEffectVersion(row)
|
||||||
? "确认软删除已生效版本 " + (row.versionNo || '') + "?版本及产品、明细将标记为已删除,上一版将自动恢复生效并清空失效时间。"
|
? "确认软删除已生效版本(生效时间:" + (row.effectiveTime || '未设置') + ")?版本及产品、明细将标记为已删除,上一版将自动恢复生效并清空失效时间。"
|
||||||
: "确认删除" + (isPendingVersion(row) ? "待生效" : "草稿") + "版本 " + (row.versionNo || '') + "?其明细与附加费将一并删除。"
|
: "确认删除" + (isPendingVersion(row) ? "待生效" : "草稿") + "版本(生效时间:" + (row.effectiveTime || '未设置') + ")?其明细与附加费将一并删除。"
|
||||||
proxy.$modal.confirm(msg).then(() => {
|
proxy.$modal.confirm(msg).then(() => {
|
||||||
removingPsvId.value = row.psvId
|
removingPsvId.value = row.psvId
|
||||||
proxy.$modal.loading("正在删除,请稍候...")
|
proxy.$modal.loading("正在删除,请稍候...")
|
||||||
|
|||||||
Reference in New Issue
Block a user