119 lines
3.1 KiB
Vue
119 lines
3.1 KiB
Vue
<template>
|
|
<div v-can="permissionCodes.stat.read" class="data-charts-page">
|
|
<store-chart-summary :date-text-list="dateTextList" />
|
|
|
|
<store-event-record-calendar-section />
|
|
<store-customer-growth-chart :date-text-list="dateTextList" />
|
|
<store-event-record-trend-chart :date-text-list="dateTextList" />
|
|
<store-event-structure-chart :date-text-list="dateTextList" />
|
|
<store-customer-gender-chart :date-text-list="dateTextList" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { Time } from "timi-web";
|
|
import StoreChartSummary from "@/pages/store/component/StoreChartSummary.vue";
|
|
import StoreCustomerGenderChart from "@/pages/store/component/StoreCustomerGenderChart.vue";
|
|
import StoreCustomerGrowthChart from "@/pages/store/component/StoreCustomerGrowthChart.vue";
|
|
import StoreEventRecordCalendarSection from "@/pages/store/component/StoreEventRecordCalendarSection.vue";
|
|
import StoreEventRecordTrendChart from "@/pages/store/component/StoreEventRecordTrendChart.vue";
|
|
import StoreEventStructureChart from "@/pages/store/component/StoreEventStructureChart.vue";
|
|
import { permissionCodes } from "@/utils/permission";
|
|
|
|
defineOptions({
|
|
name: "StoreDataCharts"
|
|
});
|
|
|
|
// ---------- 数据源 ----------
|
|
|
|
const beginDate = getDateStart(addMonths(new Date(), -1));
|
|
const endDate = getDateEnd(new Date());
|
|
const dateTextList = buildDateTextList(beginDate, endDate);
|
|
|
|
// ---------- 日期工具 ----------
|
|
|
|
function getDateStart(date: Date): Date {
|
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
|
|
}
|
|
|
|
function getDateEnd(date: Date): Date {
|
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
|
|
}
|
|
|
|
function addDays(date: Date, days: number): Date {
|
|
const value = new Date(date);
|
|
value.setDate(value.getDate() + days);
|
|
return value;
|
|
}
|
|
|
|
function addMonths(date: Date, months: number): Date {
|
|
return new Date(date.getFullYear(), date.getMonth() + months, date.getDate(), 0, 0, 0, 0);
|
|
}
|
|
|
|
function buildDateTextList(begin: Date, end: Date): string[] {
|
|
const list: string[] = [];
|
|
for (let item = getDateStart(begin); item <= end; item = addDays(item, 1)) {
|
|
list.push(Time.formatDate(item));
|
|
}
|
|
return list;
|
|
}
|
|
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.data-charts-page {
|
|
gap: 1rem;
|
|
padding: calc(var(--app-nav-height) + 1rem) 1rem 1rem 1rem;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.summary {
|
|
gap: .75rem;
|
|
display: grid;
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
|
|
.item {
|
|
padding: .875rem .625rem;
|
|
display: flex;
|
|
min-width: 0;
|
|
background: rgba(255, 255, 255, .92);
|
|
box-shadow: var(--td-shadow-1);
|
|
align-items: center;
|
|
border-radius: 1rem;
|
|
flex-direction: column;
|
|
|
|
span {
|
|
color: #52607a;
|
|
font-size: .75rem;
|
|
}
|
|
|
|
strong {
|
|
margin-top: .375rem;
|
|
color: #0f172a;
|
|
font-size: 1.125rem;
|
|
font-weight: 700;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
:global(html.theme-dark) {
|
|
.data-charts-page {
|
|
.summary {
|
|
.item {
|
|
background: rgba(15, 23, 42, .88);
|
|
box-shadow: 0 .75rem 2rem rgba(2, 6, 23, .32);
|
|
|
|
span {
|
|
color: #94a3b8;
|
|
}
|
|
|
|
strong {
|
|
color: #e2e8f0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|