Files
gao-customer-h5/src/pages/event/component/PackagePurchaseForm.vue
T
2026-09-03 14:27:40 +08:00

147 lines
3.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<section class="package-purchase-form">
<div v-if="props.packageConfig" class="config-summary">
<div class="header">
<div class="text-bold" v-text="props.packageConfig.name || '未命名套餐'" />
<div class="price">
<span class="label gray">标准价:</span>
<span class="value red text-bold" v-text="formatPackageAmount(props.packageConfig.standardAmount)" />
</div>
</div>
<div class="description" v-text="props.packageConfig.description" />
</div>
<div v-else class="center-tips" v-text="'当前购买事件未返回绑定套餐,无法完成购买。'" />
<t-form-item label="成交价(元)" label-width="6rem" required-mark>
<t-input
v-model.trim="saleAmount"
type="number"
align="right"
borderless
:readonly="!props.canPriceOverride"
placeholder="请输入成交价"
/>
</t-form-item>
<t-form-item label-width="0">
<div class="items">
<div class="title">
<strong>购买权益明细</strong>
<span v-if="!props.canPriceOverride">当前账号无定制权限,明细不可修改</span>
</div>
<t-form-item
v-for="(item, index) in itemList"
:key="`${index}-${item.productId}-${item.productUnitId}`"
class="item"
:label="getItemLabel(item)"
>
<t-input
:model-value="item.totalQuantity"
type="number"
:readonly="!props.canPriceOverride"
placeholder="总权益数量"
borderless
align="right"
@update:model-value="updateItemQuantity(index, $event)"
>
<template #suffix-icon>
<span class="unit" v-text="getItemUnit(item)" />
</template>
</t-input>
</t-form-item>
<div v-if="!itemList.length" class="center-tips" v-text="'当前套餐暂无权益明细'" />
</div>
</t-form-item>
</section>
</template>
<script setup lang="ts">
import type { GaoPackageConfig, PackagePurchaseItem } from "@/types/Package";
import { formatPackageAmount } from "@/utils/package";
defineOptions({ name: "PackagePurchaseForm" });
interface Props {
packageConfig?: GaoPackageConfig;
canPriceOverride: boolean;
}
const props = defineProps<Props>();
const saleAmount = defineModel<string>("saleAmount", { required: true });
const itemList = defineModel<PackagePurchaseItem[]>("itemList", { required: true });
function getItemLabel(item: PackagePurchaseItem): string {
const configItem = props.packageConfig?.itemList?.find(config => config.productId === item.productId && config.productUnitId === item.productUnitId);
return configItem ? `${configItem.productNameSnapshot || "未命名产品"} · ${configItem.unitSnapshot || "未设置单位"}` : "产品权益";
}
function getItemUnit(item: PackagePurchaseItem): string {
return props.packageConfig?.itemList?.find(config => config.productId === item.productId && config.productUnitId === item.productUnitId)?.unitSnapshot || "";
}
function updateItemQuantity(index: number, value: string | number): void {
itemList.value = itemList.value.map((item, itemIndex) => itemIndex === index ? {
...item,
totalQuantity: String(value)
} : item);
}
</script>
<style scoped lang="less">
.package-purchase-form {
gap: .75rem;
display: grid;
margin-top: 1rem;
.config-summary {
gap: .25rem;
margin: 0 1rem;
padding: .5rem .75rem;
display: flex;
background: var(--td-error-color-1);
border-radius: .75rem;
flex-direction: column;
.header {
display: flex;
justify-content: space-between;
.price {
display: flex;
align-items: baseline;
.label {
font-size: .75rem;
}
.value {
font-size: 1.75rem;
line-height: 1;
}
}
}
}
.items {
gap: .5rem;
display: grid;
.title {
font-size: .8125rem;
margin-bottom: .5rem;
}
.item {
border-radius: 1rem;
box-shadow: .25rem .25rem 1rem rgba(0, 0, 0, .08);
&::after {
display: none;
}
.unit {
font-size: 1rem;
}
}
}
}
</style>