133 lines
3.7 KiB
Vue
133 lines
3.7 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* 文件职责:起送与配送费设置卡片。
|
||
* 1. 展示起送金额、基础配送费、免配送费门槛字段。
|
||
* 2. 通过回调上抛字段更新,保存/重置由父级处理。
|
||
*/
|
||
import { Button, Card, InputNumber } from 'ant-design-vue';
|
||
|
||
interface Props {
|
||
baseDeliveryFee: number;
|
||
canOperate: boolean;
|
||
freeDeliveryThreshold: null | number;
|
||
isSaving: boolean;
|
||
minimumOrderAmount: number;
|
||
onSetBaseDeliveryFee: (value: number) => void;
|
||
onSetFreeDeliveryThreshold: (value: null | number) => void;
|
||
onSetMinimumOrderAmount: (value: number) => void;
|
||
}
|
||
|
||
const props = defineProps<Props>();
|
||
|
||
const emit = defineEmits<{
|
||
(event: 'reset'): void;
|
||
(event: 'save'): void;
|
||
}>();
|
||
|
||
function toNumber(value: null | number | string, fallback = 0) {
|
||
const parsed = Number(value);
|
||
return Number.isFinite(parsed) ? parsed : fallback;
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<Card :bordered="false" class="fees-card">
|
||
<template #title>
|
||
<span class="section-title">起送与配送费</span>
|
||
</template>
|
||
|
||
<div class="fees-field-grid">
|
||
<div class="fees-field">
|
||
<label>起送金额</label>
|
||
<div class="fees-input-row">
|
||
<span class="fees-unit">¥</span>
|
||
<InputNumber
|
||
:value="props.minimumOrderAmount"
|
||
:min="0"
|
||
:precision="2"
|
||
:step="1"
|
||
:controls="false"
|
||
:disabled="!props.canOperate"
|
||
class="fees-input"
|
||
placeholder="如:15.00"
|
||
@update:value="
|
||
(value) =>
|
||
props.onSetMinimumOrderAmount(
|
||
toNumber(value, props.minimumOrderAmount),
|
||
)
|
||
"
|
||
/>
|
||
</div>
|
||
<div class="fees-hint">低于此金额的订单无法下单</div>
|
||
</div>
|
||
|
||
<div class="fees-field">
|
||
<label>基础配送费</label>
|
||
<div class="fees-input-row">
|
||
<span class="fees-unit">¥</span>
|
||
<InputNumber
|
||
:value="props.baseDeliveryFee"
|
||
:min="0"
|
||
:precision="2"
|
||
:step="1"
|
||
:controls="false"
|
||
:disabled="!props.canOperate"
|
||
class="fees-input"
|
||
placeholder="如:3.00"
|
||
@update:value="
|
||
(value) =>
|
||
props.onSetBaseDeliveryFee(
|
||
toNumber(value, props.baseDeliveryFee),
|
||
)
|
||
"
|
||
/>
|
||
</div>
|
||
<div class="fees-hint">每笔订单默认收取的配送费</div>
|
||
</div>
|
||
|
||
<div class="fees-field">
|
||
<label>免配送费门槛</label>
|
||
<div class="fees-input-row">
|
||
<span class="fees-unit">¥</span>
|
||
<InputNumber
|
||
:value="props.freeDeliveryThreshold ?? undefined"
|
||
:min="0"
|
||
:precision="2"
|
||
:step="1"
|
||
:controls="false"
|
||
:disabled="!props.canOperate"
|
||
class="fees-input"
|
||
placeholder="如:30.00"
|
||
@update:value="
|
||
(value) =>
|
||
props.onSetFreeDeliveryThreshold(
|
||
value === null || value === undefined
|
||
? null
|
||
: toNumber(value, props.freeDeliveryThreshold ?? 0),
|
||
)
|
||
"
|
||
/>
|
||
</div>
|
||
<div class="fees-hint">订单满此金额免配送费,留空则不启用</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="fees-actions">
|
||
<Button
|
||
:disabled="props.isSaving || !props.canOperate"
|
||
@click="emit('reset')"
|
||
>
|
||
重置
|
||
</Button>
|
||
<Button
|
||
type="primary"
|
||
:loading="props.isSaving"
|
||
:disabled="!props.canOperate"
|
||
@click="emit('save')"
|
||
>
|
||
保存设置
|
||
</Button>
|
||
</div>
|
||
</Card>
|
||
</template>
|