159 lines
4.3 KiB
Vue
159 lines
4.3 KiB
Vue
<script setup lang="ts">
|
|
import { Page } from '@vben/common-ui';
|
|
|
|
import { Empty, Spin } from 'ant-design-vue';
|
|
|
|
import CustomerDetailDrawer from '#/views/customer/list/components/CustomerDetailDrawer.vue';
|
|
import CustomerProfileDrawer from '#/views/customer/list/components/CustomerProfileDrawer.vue';
|
|
|
|
import AmountDistributionCard from './components/AmountDistributionCard.vue';
|
|
import AnalysisStatsGrid from './components/AnalysisStatsGrid.vue';
|
|
import AnalysisToolbar from './components/AnalysisToolbar.vue';
|
|
import CompositionCard from './components/CompositionCard.vue';
|
|
import GrowthTrendCard from './components/GrowthTrendCard.vue';
|
|
import MemberDetailDrawer from './components/MemberDetailDrawer.vue';
|
|
import RfmMatrixCard from './components/RfmMatrixCard.vue';
|
|
import SegmentDrawer from './components/SegmentDrawer.vue';
|
|
import TopCustomerTableCard from './components/TopCustomerTableCard.vue';
|
|
import { useCustomerAnalysisPage } from './composables/useCustomerAnalysisPage';
|
|
|
|
const {
|
|
detail,
|
|
handleExport,
|
|
handleSegmentPageChange,
|
|
handleSegmentSearch,
|
|
isDetailDrawerOpen,
|
|
isDetailLoading,
|
|
isExporting,
|
|
isMemberDrawerOpen,
|
|
isMemberLoading,
|
|
isOverviewLoading,
|
|
isProfileDrawerOpen,
|
|
isProfileLoading,
|
|
isSegmentDrawerOpen,
|
|
isSegmentLoading,
|
|
isStoreLoading,
|
|
memberDetail,
|
|
openDetail,
|
|
openMember,
|
|
openMemberFromDetail,
|
|
openProfile,
|
|
openProfilePage,
|
|
openSegmentByCode,
|
|
openTopCustomerDetail,
|
|
overview,
|
|
period,
|
|
profile,
|
|
segmentKeyword,
|
|
segmentPagination,
|
|
segmentResult,
|
|
selectedStoreId,
|
|
setDetailDrawerOpen,
|
|
setMemberDrawerOpen,
|
|
setPeriod,
|
|
setProfileDrawerOpen,
|
|
setSegmentDrawerOpen,
|
|
setSegmentKeyword,
|
|
setSelectedStoreId,
|
|
storeOptions,
|
|
} = useCustomerAnalysisPage();
|
|
</script>
|
|
|
|
<template>
|
|
<Page title="客户分析" content-class="page-customer-analysis">
|
|
<div class="ca-page">
|
|
<AnalysisToolbar
|
|
:selected-store-id="selectedStoreId"
|
|
:store-options="storeOptions"
|
|
:is-store-loading="isStoreLoading"
|
|
:period="period"
|
|
:is-exporting="isExporting"
|
|
@update:selected-store-id="setSelectedStoreId"
|
|
@update:period="setPeriod"
|
|
@export="handleExport"
|
|
/>
|
|
|
|
<div v-if="!selectedStoreId" class="ca-empty">
|
|
<Empty description="暂无门店,请先创建门店" />
|
|
</div>
|
|
|
|
<Spin v-else :spinning="isOverviewLoading">
|
|
<AnalysisStatsGrid :overview="overview" @segment="openSegmentByCode" />
|
|
|
|
<div class="ca-grid">
|
|
<GrowthTrendCard
|
|
:points="overview.growthTrend"
|
|
@segment="openSegmentByCode"
|
|
/>
|
|
|
|
<CompositionCard
|
|
:items="overview.composition"
|
|
:total-customers="overview.totalCustomers"
|
|
@segment="openSegmentByCode"
|
|
/>
|
|
|
|
<AmountDistributionCard
|
|
:items="overview.amountDistribution"
|
|
@segment="openSegmentByCode"
|
|
/>
|
|
|
|
<RfmMatrixCard
|
|
:rows="overview.rfmRows"
|
|
@segment="openSegmentByCode"
|
|
/>
|
|
|
|
<TopCustomerTableCard
|
|
:rows="overview.topCustomers"
|
|
@detail="openTopCustomerDetail"
|
|
@segment="openSegmentByCode"
|
|
/>
|
|
</div>
|
|
</Spin>
|
|
</div>
|
|
|
|
<SegmentDrawer
|
|
:open="isSegmentDrawerOpen"
|
|
:loading="isSegmentLoading"
|
|
:result="segmentResult"
|
|
:pagination="segmentPagination"
|
|
:keyword="segmentKeyword"
|
|
@close="setSegmentDrawerOpen(false)"
|
|
@update:keyword="setSegmentKeyword"
|
|
@search="handleSegmentSearch"
|
|
@page-change="handleSegmentPageChange"
|
|
@detail="openDetail"
|
|
@profile="openProfile"
|
|
@member="openMember"
|
|
/>
|
|
|
|
<CustomerDetailDrawer
|
|
:open="isDetailDrawerOpen"
|
|
:loading="isDetailLoading"
|
|
:detail="detail"
|
|
:show-member-action="true"
|
|
@close="setDetailDrawerOpen(false)"
|
|
@profile="openProfile"
|
|
@profile-page="openProfilePage"
|
|
@member="openMemberFromDetail"
|
|
/>
|
|
|
|
<CustomerProfileDrawer
|
|
:open="isProfileDrawerOpen"
|
|
:loading="isProfileLoading"
|
|
:profile="profile"
|
|
@close="setProfileDrawerOpen(false)"
|
|
/>
|
|
|
|
<MemberDetailDrawer
|
|
:open="isMemberDrawerOpen"
|
|
:loading="isMemberLoading"
|
|
:detail="memberDetail"
|
|
@close="setMemberDrawerOpen(false)"
|
|
/>
|
|
</Page>
|
|
</template>
|
|
|
|
<style lang="less">
|
|
@import './styles/index.less';
|
|
</style>
|