feat: 完成营业时间模块拆分并补充页面注释规范

This commit is contained in:
2026-02-16 09:59:44 +08:00
parent 4be997df63
commit 14857549ba
31 changed files with 3726 additions and 1 deletions

View File

@@ -0,0 +1,182 @@
<script setup lang="ts">
import type { HolidayFormState } from '../types';
import type { HolidayType } from '#/api/store-hours';
import { Button, Drawer, Input, Textarea } from 'ant-design-vue';
interface Props {
holidayForm: HolidayFormState;
holidayTypeClosed: HolidayType;
holidayTypeSpecial: HolidayType;
isHolidaySubmitting: boolean;
onSetDateMode: (mode: 'range' | 'single') => void;
onSetEndTime: (value: string) => void;
onSetRangeEnd: (value: string) => void;
onSetRangeStart: (value: string) => void;
onSetReason: (value: string) => void;
onSetRemark: (value: string) => void;
onSetSingleDate: (value: string) => void;
onSetStartTime: (value: string) => void;
onSetType: (type: HolidayType) => void;
open: boolean;
submitText: string;
title: string;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(event: 'submit'): void;
(event: 'update:open', value: boolean): void;
}>();
function getInputValue(event: Event) {
const target = event.target as HTMLInputElement | null;
return target?.value ?? '';
}
</script>
<template>
<Drawer
:open="props.open"
:title="props.title"
:width="500"
:mask-closable="false"
:body-style="{ paddingBottom: '88px' }"
@update:open="(value) => emit('update:open', value)"
>
<div class="form-block">
<label class="form-label required">类型</label>
<div class="type-pill-group">
<button
type="button"
class="type-pill ht-closed"
:class="{
active: props.holidayForm.type === props.holidayTypeClosed,
}"
@click="props.onSetType(props.holidayTypeClosed)"
>
休息
</button>
<button
type="button"
class="type-pill ht-special"
:class="{
active: props.holidayForm.type === props.holidayTypeSpecial,
}"
@click="props.onSetType(props.holidayTypeSpecial)"
>
特殊营业
</button>
</div>
</div>
<div class="form-block">
<label class="form-label required">日期</label>
<div class="date-mode-row">
<button
type="button"
class="date-mode-pill"
:class="{ active: props.holidayForm.dateMode === 'single' }"
@click="props.onSetDateMode('single')"
>
单日
</button>
<button
type="button"
class="date-mode-pill"
:class="{ active: props.holidayForm.dateMode === 'range' }"
@click="props.onSetDateMode('range')"
>
日期范围
</button>
</div>
<template v-if="props.holidayForm.dateMode === 'single'">
<input
:value="props.holidayForm.singleDate"
type="date"
class="native-input"
@input="(event) => props.onSetSingleDate(getInputValue(event))"
/>
</template>
<template v-else>
<div class="date-range-row">
<input
:value="props.holidayForm.rangeStart"
type="date"
class="native-input"
@input="(event) => props.onSetRangeStart(getInputValue(event))"
/>
<span>~</span>
<input
:value="props.holidayForm.rangeEnd"
type="date"
class="native-input"
@input="(event) => props.onSetRangeEnd(getInputValue(event))"
/>
</div>
</template>
</div>
<div
v-if="props.holidayForm.type === props.holidayTypeSpecial"
class="form-block"
>
<label class="form-label">营业时间</label>
<div class="time-grid">
<div class="form-block">
<label class="form-sub-label">开始</label>
<input
:value="props.holidayForm.startTime"
type="time"
class="native-input"
@input="(event) => props.onSetStartTime(getInputValue(event))"
/>
</div>
<div class="form-block">
<label class="form-sub-label">结束</label>
<input
:value="props.holidayForm.endTime"
type="time"
class="native-input"
@input="(event) => props.onSetEndTime(getInputValue(event))"
/>
</div>
</div>
</div>
<div class="form-block">
<label class="form-label required">原因</label>
<Input
:value="props.holidayForm.reason"
placeholder="如:春节假期、情人节延长营业"
@update:value="props.onSetReason"
/>
</div>
<div class="form-block">
<label class="form-label">备注</label>
<Textarea
:value="props.holidayForm.remark"
:rows="2"
placeholder="可选"
@update:value="props.onSetRemark"
/>
</div>
<template #footer>
<div class="drawer-footer">
<Button @click="emit('update:open', false)">取消</Button>
<Button
type="primary"
:loading="props.isHolidaySubmitting"
@click="emit('submit')"
>
{{ props.submitText }}
</Button>
</div>
</template>
</Drawer>
</template>