统计:增加商品统计
This commit is contained in:
parent
80355f3acd
commit
ca35e1a4af
52
src/api/mall/statistics/product.ts
Normal file
52
src/api/mall/statistics/product.ts
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
import { DataComparisonRespVO } from '@/api/mall/statistics/common'
|
||||||
|
|
||||||
|
export interface ProductStatisticsVO {
|
||||||
|
id: number
|
||||||
|
day: string
|
||||||
|
spuId: number
|
||||||
|
spuName: string
|
||||||
|
spuPicUrl: string
|
||||||
|
browseCount: number
|
||||||
|
browseUserCount: number
|
||||||
|
favoriteCount: number
|
||||||
|
cartCount: number
|
||||||
|
orderCount: number
|
||||||
|
orderPayCount: number
|
||||||
|
orderPayPrice: number
|
||||||
|
afterSaleCount: number
|
||||||
|
afterSaleRefundPrice: number
|
||||||
|
browseConvertPercent: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// 商品统计 API
|
||||||
|
export const ProductStatisticsApi = {
|
||||||
|
// 获得商品统计分析
|
||||||
|
getProductStatisticsAnalyse: (params: any) => {
|
||||||
|
return request.get<DataComparisonRespVO<ProductStatisticsVO>>({
|
||||||
|
url: '/statistics/product/analyse',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获得商品状况明细
|
||||||
|
getProductStatisticsList: (params: any) => {
|
||||||
|
return request.get<ProductStatisticsVO[]>({
|
||||||
|
url: '/statistics/product/list',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 导出获得商品状况明细 Excel
|
||||||
|
exportProductStatisticsExcel: (params: any) => {
|
||||||
|
return request.download({
|
||||||
|
url: '/statistics/product/export-excel',
|
||||||
|
params
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获得商品排行榜分页
|
||||||
|
getProductStatisticsRankPage: async (params: any) => {
|
||||||
|
return await request.get({
|
||||||
|
url: `/statistics/product/rank-page`,
|
||||||
|
params
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -66,9 +66,9 @@ export const getTradeStatisticsSummary = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获得交易状况统计
|
// 获得交易状况统计
|
||||||
export const getTradeTrendSummary = (params: TradeTrendReqVO) => {
|
export const getTradeStatisticsAnalyse = (params: TradeTrendReqVO) => {
|
||||||
return request.get<DataComparisonRespVO<TradeTrendSummaryRespVO>>({
|
return request.get<DataComparisonRespVO<TradeTrendSummaryRespVO>>({
|
||||||
url: '/statistics/trade/trend/summary',
|
url: '/statistics/trade/analyse',
|
||||||
params: formatDateParam(params)
|
params: formatDateParam(params)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -70,27 +70,11 @@ service.interceptors.request.use(
|
|||||||
}
|
}
|
||||||
// get参数编码
|
// get参数编码
|
||||||
if (config.method?.toUpperCase() === 'GET' && params) {
|
if (config.method?.toUpperCase() === 'GET' && params) {
|
||||||
let url = config.url + '?'
|
|
||||||
for (const propName of Object.keys(params)) {
|
|
||||||
const value = params[propName]
|
|
||||||
if (value !== void 0 && value !== null && typeof value !== 'undefined') {
|
|
||||||
if (typeof value === 'object') {
|
|
||||||
for (const val of Object.keys(value)) {
|
|
||||||
const params = propName + '[' + val + ']'
|
|
||||||
const subPart = encodeURIComponent(params) + '='
|
|
||||||
url += subPart + encodeURIComponent(value[val]) + '&'
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
url += `${propName}=${encodeURIComponent(value)}&`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 给 get 请求加上时间戳参数,避免从缓存中拿数据
|
|
||||||
// const now = new Date().getTime()
|
|
||||||
// params = params.substring(0, url.length - 1) + `?_t=${now}`
|
|
||||||
url = url.slice(0, -1)
|
|
||||||
config.params = {}
|
config.params = {}
|
||||||
config.url = url
|
const paramsStr = qs.stringify(params, { allowDots: true })
|
||||||
|
if (paramsStr) {
|
||||||
|
config.url = config.url + '?' + paramsStr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
},
|
},
|
||||||
|
@ -285,3 +285,12 @@ export const getUrlValue = (key: string, urlStr: string = location.href): string
|
|||||||
export const getUrlNumberValue = (key: string, urlStr: string = location.href): number => {
|
export const getUrlNumberValue = (key: string, urlStr: string = location.href): number => {
|
||||||
return toNumber(getUrlValue(key, urlStr))
|
return toNumber(getUrlValue(key, urlStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建排序字段
|
||||||
|
* @param prop 字段名称
|
||||||
|
* @param order 顺序
|
||||||
|
*/
|
||||||
|
export const buildSortingField = ({ prop, order }) => {
|
||||||
|
return { field: prop, order: order === 'ascending' ? 'asc' : 'desc' }
|
||||||
|
}
|
||||||
|
104
src/views/mall/statistics/product/components/ProductRank.vue
Normal file
104
src/views/mall/statistics/product/components/ProductRank.vue
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="flex flex-row items-center justify-between">
|
||||||
|
<CardTitle title="商品排行" />
|
||||||
|
<!-- 查询条件 -->
|
||||||
|
<ShortcutDateRangePicker ref="shortcutDateRangePicker" @change="handleDateRangeChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 排行列表 -->
|
||||||
|
<el-table v-loading="loading" :data="list" @sort-change="handleSortChange">
|
||||||
|
<el-table-column label="商品ID" prop="spuId" min-width="70" />
|
||||||
|
<el-table-column label="商品图片" align="center" prop="picUrl" width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-image
|
||||||
|
:src="row.picUrl"
|
||||||
|
:preview-src-list="[row.picUrl]"
|
||||||
|
class="h-30px w-30px"
|
||||||
|
preview-teleported
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="商品名称" prop="name" min-width="200" :show-overflow-tooltip="true" />
|
||||||
|
<el-table-column label="浏览量" prop="browseCount" min-width="90" sortable="custom" />
|
||||||
|
<el-table-column label="访客数" prop="browseUserCount" min-width="90" sortable="custom" />
|
||||||
|
<el-table-column label="加购件数" prop="cartCount" min-width="105" sortable="custom" />
|
||||||
|
<el-table-column label="下单件数" prop="orderCount" min-width="105" sortable="custom" />
|
||||||
|
<el-table-column label="支付件数" prop="orderPayCount" min-width="105" sortable="custom" />
|
||||||
|
<el-table-column label="支付金额" prop="orderPayPrice" min-width="105" sortable="custom" />
|
||||||
|
<el-table-column label="收藏数" prop="favoriteCount" min-width="90" sortable="custom" />
|
||||||
|
<el-table-column
|
||||||
|
label="访客-支付转化率(%)"
|
||||||
|
prop="browseConvertPercent"
|
||||||
|
min-width="180"
|
||||||
|
sortable="custom"
|
||||||
|
:formatter="formatConvertRate"
|
||||||
|
/>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getSpuList"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ProductStatisticsApi, ProductStatisticsVO } from '@/api/mall/statistics/product'
|
||||||
|
import { CardTitle } from '@/components/Card'
|
||||||
|
import { buildSortingField } from '@/utils'
|
||||||
|
|
||||||
|
/** 商品排行 */
|
||||||
|
defineOptions({ name: 'ProductRank' })
|
||||||
|
|
||||||
|
// 格式化:访客-支付转化率
|
||||||
|
const formatConvertRate = (row: ProductStatisticsVO) => {
|
||||||
|
return `${row.browseConvertPercent}%`
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSortChange = (params: any) => {
|
||||||
|
queryParams.sortingFields = [buildSortingField(params)]
|
||||||
|
getSpuList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDateRangeChange = (times: any[]) => {
|
||||||
|
queryParams.times = times as []
|
||||||
|
getSpuList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const shortcutDateRangePicker = ref()
|
||||||
|
// 查询参数
|
||||||
|
const queryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
times: [],
|
||||||
|
sortingFields: {}
|
||||||
|
})
|
||||||
|
// 列表的加载中
|
||||||
|
const loading = ref(false)
|
||||||
|
// 列表的总页数
|
||||||
|
const total = ref(0)
|
||||||
|
// 列表的数据
|
||||||
|
const list = ref<ProductStatisticsVO[]>([])
|
||||||
|
|
||||||
|
/** 查询商品列表 */
|
||||||
|
const getSpuList = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await ProductStatisticsApi.getProductStatisticsRankPage(queryParams)
|
||||||
|
list.value = data.list
|
||||||
|
total.value = data.total
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(async () => {
|
||||||
|
await getSpuList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
304
src/views/mall/statistics/product/components/ProductSummary.vue
Normal file
304
src/views/mall/statistics/product/components/ProductSummary.vue
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<div class="flex flex-row items-center justify-between">
|
||||||
|
<CardTitle title="商品概况" />
|
||||||
|
<!-- 查询条件 -->
|
||||||
|
<ShortcutDateRangePicker ref="shortcutDateRangePicker" @change="getProductTrendData">
|
||||||
|
<el-button
|
||||||
|
class="ml-4"
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
|
v-hasPermi="['statistics:product:export']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:download" class="mr-1" />导出
|
||||||
|
</el-button>
|
||||||
|
</ShortcutDateRangePicker>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<!-- 统计值 -->
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col :xl="4" :md="8" :sm="24">
|
||||||
|
<SummaryCard
|
||||||
|
title="商品浏览量"
|
||||||
|
tooltip="在选定条件下,所有商品详情页被访问的次数,一个人在统计时间内访问多次记为多次"
|
||||||
|
icon="ep:view"
|
||||||
|
icon-color="bg-blue-100"
|
||||||
|
icon-bg-color="text-blue-500"
|
||||||
|
prefix="¥"
|
||||||
|
:decimals="2"
|
||||||
|
:value="fenToYuan(trendSummary?.value?.browseCount || 0)"
|
||||||
|
:percent="
|
||||||
|
calculateRelativeRate(
|
||||||
|
trendSummary?.value?.browseCount,
|
||||||
|
trendSummary?.reference?.browseCount
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xl="4" :md="8" :sm="24">
|
||||||
|
<SummaryCard
|
||||||
|
title="商品访客数"
|
||||||
|
tooltip="在选定条件下,访问任何商品详情页的人数,一个人在统计时间范围内访问多次只记为一个"
|
||||||
|
icon="ep:user-filled"
|
||||||
|
icon-color="bg-purple-100"
|
||||||
|
icon-bg-color="text-purple-500"
|
||||||
|
prefix="¥"
|
||||||
|
:decimals="2"
|
||||||
|
:value="fenToYuan(trendSummary?.value?.browseUserCount || 0)"
|
||||||
|
:percent="
|
||||||
|
calculateRelativeRate(
|
||||||
|
trendSummary?.value?.browseUserCount,
|
||||||
|
trendSummary?.reference?.browseUserCount
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xl="4" :md="8" :sm="24">
|
||||||
|
<SummaryCard
|
||||||
|
title="支付件数"
|
||||||
|
tooltip="在选定条件下,成功付款订单的商品件数之和"
|
||||||
|
icon="fa-solid:money-check-alt"
|
||||||
|
icon-color="bg-yellow-100"
|
||||||
|
icon-bg-color="text-yellow-500"
|
||||||
|
prefix="¥"
|
||||||
|
:decimals="2"
|
||||||
|
:value="fenToYuan(trendSummary?.value?.orderPayCount || 0)"
|
||||||
|
:percent="
|
||||||
|
calculateRelativeRate(
|
||||||
|
trendSummary?.value?.orderPayCount,
|
||||||
|
trendSummary?.reference?.orderPayCount
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xl="4" :md="8" :sm="24">
|
||||||
|
<SummaryCard
|
||||||
|
title="支付金额"
|
||||||
|
tooltip="在选定条件下,成功付款订单的商品金额之和"
|
||||||
|
icon="ep:warning-filled"
|
||||||
|
icon-color="bg-green-100"
|
||||||
|
icon-bg-color="text-green-500"
|
||||||
|
prefix="¥"
|
||||||
|
:decimals="2"
|
||||||
|
:value="fenToYuan(trendSummary?.value?.orderPayPrice || 0)"
|
||||||
|
:percent="
|
||||||
|
calculateRelativeRate(
|
||||||
|
trendSummary?.value?.orderPayPrice,
|
||||||
|
trendSummary?.reference?.orderPayPrice
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xl="4" :md="8" :sm="24">
|
||||||
|
<SummaryCard
|
||||||
|
title="退款件数"
|
||||||
|
tooltip="在选定条件下,成功退款的商品件数之和"
|
||||||
|
icon="fa-solid:wallet"
|
||||||
|
icon-color="bg-cyan-100"
|
||||||
|
icon-bg-color="text-cyan-500"
|
||||||
|
prefix="¥"
|
||||||
|
:decimals="2"
|
||||||
|
:value="fenToYuan(trendSummary?.value?.afterSaleCount || 0)"
|
||||||
|
:percent="
|
||||||
|
calculateRelativeRate(
|
||||||
|
trendSummary?.value?.afterSaleCount,
|
||||||
|
trendSummary?.reference?.afterSaleCount
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
<el-col :xl="4" :md="8" :sm="24">
|
||||||
|
<SummaryCard
|
||||||
|
title="退款金额"
|
||||||
|
tooltip="在选定条件下,成功退款的商品金额之和"
|
||||||
|
icon="fa-solid:award"
|
||||||
|
icon-color="bg-yellow-100"
|
||||||
|
icon-bg-color="text-yellow-500"
|
||||||
|
prefix="¥"
|
||||||
|
:decimals="2"
|
||||||
|
:value="fenToYuan(trendSummary?.value?.afterSaleRefundPrice || 0)"
|
||||||
|
:percent="
|
||||||
|
calculateRelativeRate(
|
||||||
|
trendSummary?.value?.afterSaleRefundPrice,
|
||||||
|
trendSummary?.reference?.afterSaleRefundPrice
|
||||||
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<!-- 折线图 -->
|
||||||
|
<el-skeleton :loading="trendLoading" animated>
|
||||||
|
<Echart :height="500" :options="lineChartOptions" />
|
||||||
|
</el-skeleton>
|
||||||
|
</el-card>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ProductStatisticsApi, ProductStatisticsVO } from '@/api/mall/statistics/product'
|
||||||
|
import SummaryCard from '@/components/SummaryCard/index.vue'
|
||||||
|
import { EChartsOption } from 'echarts'
|
||||||
|
import { DataComparisonRespVO } from '@/api/mall/statistics/common'
|
||||||
|
import { calculateRelativeRate, fenToYuan } from '@/utils'
|
||||||
|
import download from '@/utils/download'
|
||||||
|
import { CardTitle } from '@/components/Card'
|
||||||
|
import * as DateUtil from '@/utils/formatTime'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
|
||||||
|
/** 商品概况 */
|
||||||
|
defineOptions({ name: 'ProductSummary' })
|
||||||
|
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const trendLoading = ref(true) // 商品状态加载中
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
const trendSummary = ref<DataComparisonRespVO<ProductStatisticsVO>>() // 商品状况统计数据
|
||||||
|
const shortcutDateRangePicker = ref()
|
||||||
|
|
||||||
|
/** 折线图配置 */
|
||||||
|
const lineChartOptions = reactive<EChartsOption>({
|
||||||
|
dataset: {
|
||||||
|
dimensions: ['time', 'browseCount', 'browseUserCount', 'orderPayPrice', 'afterSaleRefundPrice'],
|
||||||
|
source: []
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: 20,
|
||||||
|
right: 20,
|
||||||
|
bottom: 20,
|
||||||
|
top: 80,
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: 50
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{ name: '商品浏览量', type: 'line', smooth: true, itemStyle: { color: '#B37FEB' } },
|
||||||
|
{ name: '商品访客数', type: 'line', smooth: true, itemStyle: { color: '#FFAB2B' } },
|
||||||
|
{ name: '支付金额', type: 'bar', smooth: true, yAxisIndex: 1, itemStyle: { color: '#1890FF' } },
|
||||||
|
{ name: '退款金额', type: 'bar', smooth: true, yAxisIndex: 1, itemStyle: { color: '#00C050' } }
|
||||||
|
],
|
||||||
|
toolbox: {
|
||||||
|
feature: {
|
||||||
|
// 数据区域缩放
|
||||||
|
dataZoom: {
|
||||||
|
yAxisIndex: false // Y轴不缩放
|
||||||
|
},
|
||||||
|
brush: {
|
||||||
|
type: ['lineX', 'clear'] // 区域缩放按钮、还原按钮
|
||||||
|
},
|
||||||
|
saveAsImage: { show: true, name: '商品状况' } // 保存为图片
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis',
|
||||||
|
axisPointer: {
|
||||||
|
type: 'cross'
|
||||||
|
},
|
||||||
|
padding: [5, 10]
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: true,
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '金额',
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#7F8B9C'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#F5F7F9'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
name: '数量',
|
||||||
|
axisLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#7F8B9C'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#F5F7F9'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}) as EChartsOption
|
||||||
|
|
||||||
|
/** 处理商品状况查询 */
|
||||||
|
const getProductTrendData = async () => {
|
||||||
|
trendLoading.value = true
|
||||||
|
// 1. 处理时间: 开始与截止在同一天的, 折线图出不来, 需要延长一天
|
||||||
|
const times = shortcutDateRangePicker.value.times
|
||||||
|
if (DateUtil.isSameDay(times[0], times[1])) {
|
||||||
|
// 前天
|
||||||
|
times[0] = DateUtil.formatDate(dayjs(times[0]).subtract(1, 'd'))
|
||||||
|
}
|
||||||
|
// 查询数据
|
||||||
|
await Promise.all([getProductTrendSummary(), getProductStatisticsList()])
|
||||||
|
trendLoading.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询商品状况数据统计 */
|
||||||
|
const getProductTrendSummary = async () => {
|
||||||
|
const times = shortcutDateRangePicker.value.times
|
||||||
|
trendSummary.value = await ProductStatisticsApi.getProductStatisticsAnalyse({ times })
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 查询商品状况数据列表 */
|
||||||
|
const getProductStatisticsList = async () => {
|
||||||
|
// 查询数据
|
||||||
|
const times = shortcutDateRangePicker.value.times
|
||||||
|
const list: ProductStatisticsVO[] = await ProductStatisticsApi.getProductStatisticsList({ times })
|
||||||
|
// 处理数据
|
||||||
|
for (let item of list) {
|
||||||
|
item.orderPayPrice = fenToYuan(item.orderPayPrice)
|
||||||
|
item.afterSaleRefundPrice = fenToYuan(item.afterSaleRefundPrice)
|
||||||
|
}
|
||||||
|
// 更新 Echarts 数据
|
||||||
|
if (lineChartOptions.dataset && lineChartOptions.dataset['source']) {
|
||||||
|
lineChartOptions.dataset['source'] = list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
|
const handleExport = async () => {
|
||||||
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const times = shortcutDateRangePicker.value.times
|
||||||
|
const data = await ProductStatisticsApi.exportProductStatisticsExcel({ times })
|
||||||
|
download.excel(data, '商品状况.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
14
src/views/mall/statistics/product/index.vue
Normal file
14
src/views/mall/statistics/product/index.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 商品概览 -->
|
||||||
|
<ProductSummary />
|
||||||
|
<!-- 商品排行 -->
|
||||||
|
<ProductRank class="mt-16px" />
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import ProductSummary from './components/ProductSummary.vue'
|
||||||
|
import ProductRank from './components/ProductRank.vue'
|
||||||
|
|
||||||
|
/** 商品统计 */
|
||||||
|
defineOptions({ name: 'ProductStatistics' })
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped></style>
|
@ -298,7 +298,7 @@ const getTradeTrendData = async () => {
|
|||||||
times[0] = DateUtil.formatDate(dayjs(times[0]).subtract(1, 'd'))
|
times[0] = DateUtil.formatDate(dayjs(times[0]).subtract(1, 'd'))
|
||||||
}
|
}
|
||||||
// 查询数据
|
// 查询数据
|
||||||
await Promise.all([getTradeTrendSummary(), getTradeStatisticsList()])
|
await Promise.all([getTradeStatisticsAnalyse(), getTradeStatisticsList()])
|
||||||
trendLoading.value = false
|
trendLoading.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,9 +308,9 @@ const getTradeStatisticsSummary = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** 查询交易状况数据统计 */
|
/** 查询交易状况数据统计 */
|
||||||
const getTradeTrendSummary = async () => {
|
const getTradeStatisticsAnalyse = async () => {
|
||||||
const times = shortcutDateRangePicker.value.times
|
const times = shortcutDateRangePicker.value.times
|
||||||
trendSummary.value = await TradeStatisticsApi.getTradeTrendSummary({ times })
|
trendSummary.value = await TradeStatisticsApi.getTradeStatisticsAnalyse({ times })
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 查询交易状况数据列表 */
|
/** 查询交易状况数据列表 */
|
||||||
|
Loading…
Reference in New Issue
Block a user