feat: 套餐分配生效条件选择
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 9m23s

This commit is contained in:
luo
2026-07-22 14:21:15 +08:00
parent fbfdd01eec
commit 68aa03b538
11 changed files with 500 additions and 90 deletions

View File

@@ -40,6 +40,21 @@
<span class="amount-value">¥{{ (row.cost_price / 100).toFixed(2) }}</span>
</template>
</ElTableColumn>
<ElTableColumn label="套餐默认生效条件" minWidth="150">
<template #default="{ row }">
{{ row.default_expiry_base_name || '-' }}
</template>
</ElTableColumn>
<ElTableColumn label="覆盖生效条件" minWidth="150">
<template #default="{ row }">
{{ row.expiry_base_override_name || '-' }}
</template>
</ElTableColumn>
<ElTableColumn label="最终生效条件" minWidth="150">
<template #default="{ row }">
{{ row.effective_expiry_base_name || '-' }}
</template>
</ElTableColumn>
<ElTableColumn label="上架状态" width="100" align="center">
<template #default="{ row }">
<ElTag v-if="row.shelf_status === 1" type="success" size="small">上架</ElTag>
@@ -112,6 +127,25 @@
}}
</div>
</ElFormItem>
<ElFormItem label="生效条件">
<ElRadioGroup v-model="packageForm.expiry_base_override">
<ElRadio value="default">跟随套餐默认</ElRadio>
<ElRadio value="from_purchase">购买即生效</ElRadio>
<ElRadio value="from_realname">实名即生效</ElRadio>
</ElRadioGroup>
<div class="form-tip">仅影响后续新订单不影响已购买套餐</div>
</ElFormItem>
<template v-if="packageDialogType === 'edit'">
<ElFormItem label="套餐默认生效条件">
{{ packageForm.default_expiry_base_name || '-' }}
</ElFormItem>
<ElFormItem label="覆盖生效条件">
{{ packageForm.expiry_base_override_name || '-' }}
</ElFormItem>
<ElFormItem label="最终生效条件">
{{ packageForm.effective_expiry_base_name || '-' }}
</ElFormItem>
</template>
</ElForm>
<template #footer>
@@ -142,12 +176,24 @@
ElInputNumber,
ElForm,
ElFormItem,
ElRadioGroup,
ElRadio,
ElMessage,
FormInstance,
FormRules
} from 'element-plus'
import { ArrowLeft } from '@element-plus/icons-vue'
import { ShopSeriesGrantService, PackageManageService } from '@/api/modules'
import type { GrantPackageInfo, GrantPackageItem, PackageResponse } from '@/types/api'
import {
ShopSeriesGrantService,
ShopPackageAllocationService,
PackageManageService
} from '@/api/modules'
import type {
GrantPackageInfo,
GrantPackageItem,
PackageAllocationExpiryBaseOverride,
PackageResponse
} from '@/types/api'
import { useAuth } from '@/composables/useAuth'
defineOptions({ name: 'SeriesGrantPackages' })
@@ -163,6 +209,7 @@
const grantId = computed(() => Number(route.params.id))
const seriesId = ref<number>(0)
const shopId = ref<number>(0)
const grantName = ref<string>('')
const packageList = ref<GrantPackageInfo[]>([])
const availablePackages = ref<PackageResponse[]>([])
@@ -171,6 +218,8 @@
const packageDialogVisible = ref(false)
const packageDialogType = ref<'add' | 'edit'>('add')
type ExpiryBaseSelection = PackageAllocationExpiryBaseOverride | 'default'
type PackageFormState = {
package_id?: number
package_name?: string
@@ -178,13 +227,21 @@
cost_price_yuan: number
original_cost_price?: number
suggested_retail_price?: number
allocation_id?: number
expiry_base_override: ExpiryBaseSelection
initial_expiry_base_override: ExpiryBaseSelection
default_expiry_base_name?: string | null
expiry_base_override_name?: string | null
effective_expiry_base_name?: string | null
}
const createDefaultPackageForm = (): PackageFormState => ({
package_id: undefined,
package_name: undefined,
package_code: undefined,
cost_price_yuan: 0
cost_price_yuan: 0,
expiry_base_override: 'default',
initial_expiry_base_override: 'default'
})
const packageForm = ref<PackageFormState>(createDefaultPackageForm())
@@ -266,6 +323,7 @@
if (res.code === 0) {
packageList.value = res.data.packages || []
seriesId.value = res.data.series_id
shopId.value = res.data.shop_id
grantName.value = `${res.data.series_name} - ${res.data.shop_name}`
}
} catch (error) {
@@ -293,7 +351,13 @@
package_code: row.package_code,
cost_price_yuan: row.cost_price / 100,
original_cost_price: packagePricing.original_cost_price,
suggested_retail_price: packagePricing.suggested_retail_price
suggested_retail_price: packagePricing.suggested_retail_price,
allocation_id: row.allocation_id,
expiry_base_override: row.expiry_base_override ?? 'default',
initial_expiry_base_override: row.expiry_base_override ?? 'default',
default_expiry_base_name: row.default_expiry_base_name,
expiry_base_override_name: row.expiry_base_override_name,
effective_expiry_base_name: row.effective_expiry_base_name
})
packageDialogVisible.value = true
nextTick(() => packageFormRef.value?.clearValidate())
@@ -369,14 +433,46 @@
if (Number.isNaN(currentCostPriceYuan)) {
throw new Error('当前成本价无效,无法保存')
}
const packages: GrantPackageItem[] = [
{
package_id: packageForm.value.package_id,
cost_price: Math.round(currentCostPriceYuan * 100)
const costPrice = Math.round(currentCostPriceYuan * 100)
if (packageDialogType.value === 'add') {
await ShopPackageAllocationService.createShopPackageAllocation({
shop_id: shopId.value,
package_id: packageForm.value.package_id!,
cost_price: costPrice,
expiry_base_override:
packageForm.value.expiry_base_override === 'default'
? null
: packageForm.value.expiry_base_override
})
} else {
const expiryBaseChanged =
packageForm.value.expiry_base_override !==
packageForm.value.initial_expiry_base_override
if (expiryBaseChanged && !packageForm.value.allocation_id) {
ElMessage.error('该套餐分配记录缺少ID无法更新生效条件')
return
}
]
await ShopSeriesGrantService.manageGrantPackages(grantId.value, { packages })
const packages: GrantPackageItem[] = [
{ package_id: packageForm.value.package_id, cost_price: costPrice }
]
await Promise.all([
ShopSeriesGrantService.manageGrantPackages(grantId.value, { packages }),
...(expiryBaseChanged
? [
ShopPackageAllocationService.updateShopPackageAllocationExpiryBase(
packageForm.value.allocation_id!,
{
expiry_base_override:
packageForm.value.expiry_base_override === 'default'
? null
: packageForm.value.expiry_base_override
}
)
]
: [])
])
}
packageDialogVisible.value = false
await fetchPackageList()
} catch (error) {