修改基础价格版本功能
This commit is contained in:
@@ -63,3 +63,11 @@ export function delProduct(productIds) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/** List base-price version options (by effective_date desc) for package create */
|
||||
export function listProductPriceVersions() {
|
||||
return request({
|
||||
url: '/price/product/priceVersions',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ import { formatWeightLabel } from '@/views/price/set/utils/priceSet'
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const columns = [
|
||||
{ prop: 'versionNo', label: '版本', width: 70, align: 'center', formatter: (row) => row.versionNo || '-' },
|
||||
{ prop: 'countryName', label: '国家', width: 120, showOverflowTooltip: true },
|
||||
// { prop: 'countryCode', label: 'ISO2', width: 60, align: 'center' },
|
||||
{ prop: 'zoneName', label: '分区名称', width: 140, showOverflowTooltip: true, formatter: (row) => row.zoneName || '-' },
|
||||
|
||||
@@ -116,12 +116,13 @@ const regionOptions = ref([])
|
||||
const countryImportQuery = computed(() => ({ countryCode: importCountryCode.value }))
|
||||
const allImportDesc = [
|
||||
'适用多国家价表(B2C 小包价表等),按目录 sheet 匹配国家导入。',
|
||||
'生效日期必填。新版导入时上一版失效日=本次生效日,复制上一版后按国家/分区/重量段匹配:命中更新,未命中插入。',
|
||||
'请在弹窗底部下载模板,按模板格式整理后上传。相同产品代码+生效日期不覆盖主数据。'
|
||||
]
|
||||
const countryImportDesc = [
|
||||
'选择目的国家后上传专线成本价表,目录中的产品都会记到该国家。',
|
||||
'邮编、赔偿标准等 sheet 不导入。相同产品代码+生效日期不覆盖主数据,重量段按生效日写入。',
|
||||
'可在弹窗底部下载模板,按模板格式整理后上传。'
|
||||
'生效日期必填。新版会复制上一版全部国家明细再与导入行匹配更新/插入;其他国家行会转结到新版。',
|
||||
'邮编、赔偿标准等 sheet 不导入。可在弹窗底部下载模板。'
|
||||
]
|
||||
|
||||
const columns = [
|
||||
|
||||
@@ -7,6 +7,25 @@
|
||||
<div class="form-hint">显示给客户的套餐对外名称</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="基础价格版本" prop="baseVersionNo">
|
||||
<el-select
|
||||
v-model="basic.baseVersionNo"
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择基础价格版本"
|
||||
style="width: 100%"
|
||||
:loading="versionLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, idx) in versionOptions"
|
||||
:key="item.versionNo"
|
||||
:label="versionLabel(item, idx === 0)"
|
||||
:value="item.versionNo"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="form-hint">创建套餐价格时按此版本从产品库拉取明细;默认最新版本</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="计价类型" prop="setType">
|
||||
<div class="type-row">
|
||||
<div
|
||||
@@ -50,19 +69,41 @@
|
||||
|
||||
<script setup name="StepBasicInfo">
|
||||
/**
|
||||
* 第 1 步 · 基本信息
|
||||
* 直接读写父级传入的 basic 对象(同一引用),校验规则由本组件维护。
|
||||
* Step1 basic info. baseVersionNo is pull-only (not persisted).
|
||||
*/
|
||||
import { listProductPriceVersions } from '@/api/price/product'
|
||||
|
||||
const basic = defineModel({ type: Object, required: true })
|
||||
|
||||
const formRef = ref()
|
||||
const versionLoading = ref(false)
|
||||
const versionOptions = ref([])
|
||||
|
||||
const rules = {
|
||||
priceSetName: [{ required: true, message: '套餐名称不能为空', trigger: 'blur' }],
|
||||
baseVersionNo: [{ required: true, message: '请选择基础价格版本', trigger: 'change' }],
|
||||
setType: [{ required: true, message: '请选择计价类型', trigger: 'change' }],
|
||||
}
|
||||
|
||||
/** 供父级在下一步 / 保存前调用 */
|
||||
function versionLabel(item, isLatest) {
|
||||
const no = item.versionNo || '-'
|
||||
return no
|
||||
}
|
||||
|
||||
async function loadVersions() {
|
||||
versionLoading.value = true
|
||||
try {
|
||||
const res = await listProductPriceVersions()
|
||||
const list = res.data || []
|
||||
versionOptions.value = list
|
||||
if (!basic.value.baseVersionNo && list.length) {
|
||||
basic.value.baseVersionNo = list[0].versionNo
|
||||
}
|
||||
} finally {
|
||||
versionLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function validate() {
|
||||
return new Promise(resolve => {
|
||||
if (!formRef.value) return resolve(false)
|
||||
@@ -70,46 +111,20 @@ function validate() {
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadVersions()
|
||||
})
|
||||
|
||||
defineExpose({ validate })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.max-form {
|
||||
max-width: 760px;
|
||||
}
|
||||
.form-hint {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 1.4;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.unit {
|
||||
margin-left: 8px;
|
||||
color: #909399;
|
||||
}
|
||||
.type-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
.type-card {
|
||||
flex: 1;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 6px;
|
||||
padding: 14px 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.type-card.selected {
|
||||
border-color: #1890ff;
|
||||
background: #e6f7ff;
|
||||
}
|
||||
.t-title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.t-desc {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.max-form { max-width: 760px; }
|
||||
.form-hint { font-size: 12px; color: #909399; line-height: 1.4; margin-top: 4px; }
|
||||
.unit { margin-left: 8px; color: #909399; }
|
||||
.type-row { display: flex; gap: 12px; width: 100%; }
|
||||
.type-card { flex: 1; border: 1px solid #d9d9d9; border-radius: 6px; padding: 14px 16px; cursor: pointer; }
|
||||
.type-card.selected { border-color: #1890ff; background: #e6f7ff; }
|
||||
.t-title { font-weight: 600; margin-bottom: 4px; }
|
||||
.t-desc { font-size: 12px; color: #909399; line-height: 1.5; }
|
||||
</style>
|
||||
|
||||
@@ -220,6 +220,7 @@ function buildPayload() {
|
||||
setType: basic.setType,
|
||||
defaultDiscount: basic.setType === 'DISCOUNT' ? basic.defaultDiscount : undefined,
|
||||
priceSetNote: basic.priceSetNote,
|
||||
baseVersionNo: basic.baseVersionNo || undefined,
|
||||
version: {
|
||||
psvId: copyMode.value ? undefined : version.psvId,
|
||||
versionNo: version.versionNo
|
||||
|
||||
@@ -361,6 +361,7 @@ export function createEmptyBasicInfo() {
|
||||
defaultDiscount: 88,
|
||||
effectiveDate: undefined,
|
||||
expireDate: undefined,
|
||||
baseVersionNo: undefined,
|
||||
priceSetNote: ''
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user