📖 ERP:增加 ERP 首页的统计

pull/387/MERGE
YunaiV 2024-02-18 19:05:57 +08:00
parent 71ac59f22e
commit cd86c08e59
5 changed files with 254 additions and 0 deletions

View File

@ -0,0 +1,28 @@
import request from '@/config/axios'
// ERP 采购全局统计 VO
export interface ErpPurchaseSummaryRespVO {
todayPrice: number // 今日采购金额
yesterdayPrice: number // 昨日采购金额
monthPrice: number // 本月采购金额
yearPrice: number // 今年采购金额
}
// ERP 采购时间段统计 VO
export interface ErpPurchaseTimeSummaryRespVO {
time: string // 时间
price: number // 采购金额
}
// ERP 采购统计 API
export const PurchaseStatisticsApi = {
// 获得采购统计
getPurchaseSummary: async (): Promise<ErpPurchaseSummaryRespVO> => {
return await request.get({ url: `/erp/purchase-statistics/summary` })
},
// 获得采购时间段统计
getPurchaseTimeSummary: async (): Promise<ErpPurchaseTimeSummaryRespVO[]> => {
return await request.get({ url: `/erp/purchase-statistics/time-summary` })
}
}

View File

@ -0,0 +1,28 @@
import request from '@/config/axios'
// ERP 销售全局统计 VO
export interface ErpSaleSummaryRespVO {
todayPrice: number // 今日销售金额
yesterdayPrice: number // 昨日销售金额
monthPrice: number // 本月销售金额
yearPrice: number // 今年销售金额
}
// ERP 销售时间段统计 VO
export interface ErpSaleTimeSummaryRespVO {
time: string // 时间
price: number // 销售金额
}
// ERP 销售统计 API
export const SaleStatisticsApi = {
// 获得销售统计
getSaleSummary: async (): Promise<ErpSaleSummaryRespVO> => {
return await request.get({ url: `/erp/sale-statistics/summary` })
},
// 获得销售时间段统计
getSaleTimeSummary: async (): Promise<ErpSaleTimeSummaryRespVO[]> => {
return await request.get({ url: `/erp/sale-statistics/time-summary` })
}
}

View File

@ -0,0 +1,21 @@
<template>
<div class="flex flex-col gap-2 bg-[var(--el-bg-color-overlay)] p-6">
<div class="flex items-center justify-between text-gray-500">
<span>{{ title }}</span>
</div>
<div class="flex flex-row items-baseline justify-between">
<CountTo prefix="¥" :end-val="value" :decimals="2" :duration="500" class="text-3xl" />
</div>
</div>
</template>
<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes'
/** 价格展示 Card */
defineOptions({ name: 'ErpSummaryCard' })
defineProps({
title: propTypes.string.def('').isRequired,
value: propTypes.number.def(0).isRequired
})
</script>

View File

@ -0,0 +1,86 @@
<template>
<el-card shadow="never">
<template #header>
<CardTitle :title="props.title" />
</template>
<!-- 折线图 -->
<Echart :height="300" :options="lineChartOptions" />
</el-card>
</template>
<script lang="ts" setup>
import { EChartsOption } from 'echarts'
import { formatDate } from '@/utils/formatTime'
import { CardTitle } from '@/components/Card'
import { propTypes } from '@/utils/propTypes'
/** 会员用户统计卡片 */
defineOptions({ name: 'MemberStatisticsCard' })
const props = defineProps({
title: propTypes.string.def('').isRequired,
value: propTypes.object.isRequired
})
/** 折线图配置 */
const lineChartOptions = reactive<EChartsOption>({
dataset: {
dimensions: ['time', 'price'],
source: []
},
grid: {
left: 20,
right: 20,
bottom: 20,
top: 80,
containLabel: true
},
legend: {
top: 50
},
series: [{ name: '金额', type: 'line', smooth: true, areaStyle: {} }],
toolbox: {
feature: {
//
dataZoom: {
yAxisIndex: false // Y
},
brush: {
type: ['lineX', 'clear'] //
},
saveAsImage: { show: true, name: props.title } //
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
xAxis: {
type: 'category',
boundaryGap: false,
axisTick: {
show: false
}
},
yAxis: {
axisTick: {
show: false
}
}
}) as EChartsOption
watch(
() => props.value,
(val) => {
if (!val) {
return
}
// Echarts
if (lineChartOptions.dataset && lineChartOptions.dataset['source']) {
lineChartOptions.dataset['source'] = val
}
}
)
</script>

View File

@ -0,0 +1,91 @@
<template>
<div class="flex flex-col">
<!-- 销售/采购的全局统计 -->
<el-row :gutter="16" class="row">
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="今日销售" :value="saleSummary?.todayPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="昨日销售" :value="saleSummary?.yesterdayPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="今日采购" :value="purchaseSummary?.todayPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="昨日采购" :value="purchaseSummary?.yesterdayPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="本月销售" :value="saleSummary?.monthPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="今年销售" :value="saleSummary?.yearPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="本月采购" :value="purchaseSummary?.monthPrice" />
</el-col>
<el-col :md="6" :sm="12" :xs="24" :loading="loading">
<SummaryCard title="今年采购" :value="purchaseSummary?.yearPrice" />
</el-col>
</el-row>
<!-- 销售/采购的时段统计 -->
<el-row :gutter="16" class="row">
<!-- 销售统计 -->
<el-col :md="12" :sm="12" :xs="24" :loading="loading">
<TimeSummaryChart title="销售统计" :value="saleTimeSummaryList" />
</el-col>
<!-- 采购统计 -->
<el-col :md="12" :sm="12" :xs="24" :loading="loading">
<TimeSummaryChart title="采购统计" :value="purchaseTimeSummaryList" />
</el-col>
</el-row>
</div>
</template>
<script lang="ts" setup>
import SummaryCard from './components/SummaryCard.vue'
import TimeSummaryChart from './components/TimeSummaryChart.vue'
import {
ErpSaleSummaryRespVO,
ErpSaleTimeSummaryRespVO,
SaleStatisticsApi
} from '@/api/erp/statistics/sale'
import {
ErpPurchaseSummaryRespVO,
ErpPurchaseTimeSummaryRespVO,
PurchaseStatisticsApi
} from '@/api/erp/statistics/purchase'
/** 商城首页 */
defineOptions({ name: 'ErpHome' })
const loading = ref(true) //
/** 获得销售统计 */
const saleSummary = ref<ErpSaleSummaryRespVO>() //
const saleTimeSummaryList = ref<ErpSaleTimeSummaryRespVO[]>() //
const getSaleSummary = async () => {
saleSummary.value = await SaleStatisticsApi.getSaleSummary()
saleTimeSummaryList.value = await SaleStatisticsApi.getSaleTimeSummary()
}
/** 获得采购统计 */
const purchaseSummary = ref<ErpPurchaseSummaryRespVO>() //
const purchaseTimeSummaryList = ref<ErpPurchaseTimeSummaryRespVO[]>() //
const getPurchaseSummary = async () => {
purchaseSummary.value = await PurchaseStatisticsApi.getPurchaseSummary()
purchaseTimeSummaryList.value = await PurchaseStatisticsApi.getPurchaseTimeSummary()
}
/** 初始化 **/
onMounted(async () => {
loading.value = true
await Promise.all([getSaleSummary(), getPurchaseSummary()])
loading.value = false
})
</script>
<style lang="scss" scoped>
.row {
.el-col {
margin-bottom: 1rem;
}
}
</style>