177 lines
4.8 KiB
Vue
177 lines
4.8 KiB
Vue
<script setup lang="ts">
|
||
/**
|
||
* 文件职责:时段供应页面主视图。
|
||
* 1. 还原原型的工具栏、统计条、规则卡片、时间轴与抽屉。
|
||
* 2. 通过真实 TenantAPI 管理时段规则及关联商品。
|
||
*/
|
||
import { Page } from '@vben/common-ui';
|
||
import { IconifyIcon } from '@vben/icons';
|
||
|
||
import { Button, Empty, Input, Select, Spin } from 'ant-design-vue';
|
||
|
||
import ScheduleEditorDrawer from './components/ScheduleEditorDrawer.vue';
|
||
import ScheduleProductPickerModal from './components/ScheduleProductPickerModal.vue';
|
||
import ScheduleRuleCard from './components/ScheduleRuleCard.vue';
|
||
import ScheduleTimelineCard from './components/ScheduleTimelineCard.vue';
|
||
import { useProductSchedulePage } from './composables/useProductSchedulePage';
|
||
|
||
const {
|
||
coveredProductCount,
|
||
drawerSubmitText,
|
||
drawerTitle,
|
||
enabledCount,
|
||
filteredRows,
|
||
form,
|
||
getRuleColor,
|
||
getScheduleProductNames,
|
||
isDrawerOpen,
|
||
isDrawerSubmitting,
|
||
isLoading,
|
||
isPickerLoading,
|
||
isPickerOpen,
|
||
isStoreLoading,
|
||
keyword,
|
||
loadPickerProducts,
|
||
openCreateDrawer,
|
||
openEditDrawer,
|
||
openProductPicker,
|
||
pickerKeyword,
|
||
pickerProducts,
|
||
pickerSelectedIds,
|
||
removeFormProduct,
|
||
removeRule,
|
||
ruleCount,
|
||
selectAllDays,
|
||
selectedProducts,
|
||
selectedStoreId,
|
||
selectWeekdays,
|
||
selectWeekend,
|
||
setDrawerOpen,
|
||
setFormEndTime,
|
||
setFormName,
|
||
setFormStartTime,
|
||
setKeyword,
|
||
setPickerKeyword,
|
||
setPickerOpen,
|
||
setSelectedStoreId,
|
||
storeOptions,
|
||
submitDrawer,
|
||
submitPicker,
|
||
timelineRows,
|
||
toggleFormStatus,
|
||
togglePickerProduct,
|
||
toggleRuleStatus,
|
||
toggleWeekDay,
|
||
} = useProductSchedulePage();
|
||
</script>
|
||
|
||
<template>
|
||
<Page title="时段供应" content-class="page-product-schedule">
|
||
<div class="ptm-page">
|
||
<div class="ptm-toolbar">
|
||
<Select
|
||
class="ptm-store-select"
|
||
:value="selectedStoreId"
|
||
:options="storeOptions"
|
||
:loading="isStoreLoading"
|
||
placeholder="请选择门店"
|
||
@update:value="(value) => setSelectedStoreId(String(value ?? ''))"
|
||
/>
|
||
|
||
<Input
|
||
class="ptm-search"
|
||
:value="keyword"
|
||
placeholder="搜索规则名称…"
|
||
@update:value="(value) => setKeyword(String(value ?? ''))"
|
||
/>
|
||
|
||
<span class="ptm-spacer"></span>
|
||
|
||
<Button type="primary" @click="openCreateDrawer">+ 添加时段规则</Button>
|
||
</div>
|
||
|
||
<div v-if="selectedStoreId" class="ptm-stats">
|
||
<span>
|
||
时段规则 <strong>{{ ruleCount }}</strong>
|
||
</span>
|
||
<span>
|
||
启用 <strong>{{ enabledCount }}</strong>
|
||
</span>
|
||
<span>
|
||
覆盖商品 <strong>{{ coveredProductCount }}</strong>
|
||
</span>
|
||
</div>
|
||
|
||
<div v-if="selectedStoreId" class="ptm-banner">
|
||
<span class="icon"><IconifyIcon icon="lucide:info" /></span>
|
||
设置商品在特定时段内供应,未被任何规则覆盖的商品默认全天供应。
|
||
</div>
|
||
|
||
<div v-if="!selectedStoreId" class="ptm-empty">
|
||
暂无门店,请先创建门店
|
||
</div>
|
||
|
||
<Spin v-else :spinning="isLoading">
|
||
<template v-if="filteredRows.length > 0">
|
||
<ScheduleRuleCard
|
||
v-for="item in filteredRows"
|
||
:key="item.id"
|
||
:item="item"
|
||
:color="getRuleColor(item.id)"
|
||
:product-names="getScheduleProductNames(item)"
|
||
@edit="openEditDrawer"
|
||
@toggle-status="toggleRuleStatus"
|
||
@remove="removeRule"
|
||
/>
|
||
</template>
|
||
|
||
<div v-else class="ptm-empty">
|
||
<Empty description="暂无时段规则" />
|
||
</div>
|
||
|
||
<ScheduleTimelineCard :rows="timelineRows" />
|
||
</Spin>
|
||
</div>
|
||
|
||
<ScheduleEditorDrawer
|
||
:open="isDrawerOpen"
|
||
:title="drawerTitle"
|
||
:submit-text="drawerSubmitText"
|
||
:submitting="isDrawerSubmitting"
|
||
:form="form"
|
||
:selected-products="selectedProducts"
|
||
@close="setDrawerOpen(false)"
|
||
@set-name="setFormName"
|
||
@set-start-time="setFormStartTime"
|
||
@set-end-time="setFormEndTime"
|
||
@toggle-week-day="toggleWeekDay"
|
||
@select-all-days="selectAllDays"
|
||
@select-weekdays="selectWeekdays"
|
||
@select-weekend="selectWeekend"
|
||
@open-product-picker="openProductPicker"
|
||
@remove-product="removeFormProduct"
|
||
@toggle-status="toggleFormStatus"
|
||
@submit="submitDrawer"
|
||
/>
|
||
|
||
<ScheduleProductPickerModal
|
||
:open="isPickerOpen"
|
||
title="关联商品"
|
||
:loading="isPickerLoading"
|
||
:submitting="false"
|
||
:keyword="pickerKeyword"
|
||
:products="pickerProducts"
|
||
:selected-ids="pickerSelectedIds"
|
||
@close="setPickerOpen(false)"
|
||
@set-keyword="setPickerKeyword"
|
||
@search="loadPickerProducts"
|
||
@toggle-product="togglePickerProduct"
|
||
@submit="submitPicker"
|
||
/>
|
||
</Page>
|
||
</template>
|
||
|
||
<style lang="less">
|
||
@import './styles/index.less';
|
||
</style>
|