147 lines
3.9 KiB
Vue
147 lines
3.9 KiB
Vue
<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>
|