diff --git a/apps/web-ele/src/api/mall/statistics/product.ts b/apps/web-ele/src/api/mall/statistics/product.ts index d458d4353..089da4af7 100644 --- a/apps/web-ele/src/api/mall/statistics/product.ts +++ b/apps/web-ele/src/api/mall/statistics/product.ts @@ -2,6 +2,8 @@ import type { PageParam, PageResult } from '@vben/request'; import type { MallDataComparisonResp } from './common'; +import { formatDate2 } from '@vben/utils'; + import { requestClient } from '#/api/request'; export namespace MallProductStatisticsApi { @@ -38,26 +40,58 @@ export namespace MallProductStatisticsApi { /** 浏览转化率 */ browseConvertPercent: number; } + + /** 会员分析 Request */ + export interface ProductStatisticsReq { + times: Date[]; + } } /** 获得商品统计分析 */ -export function getProductStatisticsAnalyse(params: PageParam) { +export function getProductStatisticsAnalyse( + params: MallProductStatisticsApi.ProductStatisticsReq, +) { return requestClient.get< MallDataComparisonResp - >('/statistics/product/analyse', { params }); + >('/statistics/product/analyse', { + params: { + times: [ + formatDate2(params.times[0] || new Date()), + formatDate2(params.times[1] || new Date()), + ], + }, + }); } /** 获得商品状况明细 */ -export function getProductStatisticsList(params: PageParam) { +export function getProductStatisticsList( + params: MallProductStatisticsApi.ProductStatisticsReq, +) { return requestClient.get( '/statistics/product/list', - { params }, + { + params: { + times: [ + formatDate2(params.times[0] || new Date()), + formatDate2(params.times[1] || new Date()), + ], + }, + }, ); } /** 导出获得商品状况明细 Excel */ -export function exportProductStatisticsExcel(params: PageParam) { - return requestClient.download('/statistics/product/export-excel', { params }); +export function exportProductStatisticsExcel( + params: MallProductStatisticsApi.ProductStatisticsReq, +) { + return requestClient.download('/statistics/product/export-excel', { + params: { + times: [ + formatDate2(params.times[0] || new Date()), + formatDate2(params.times[1] || new Date()), + ], + }, + }); } /** 获得商品排行榜分页 */ diff --git a/apps/web-ele/src/views/mall/statistics/product/components/product-rank.vue b/apps/web-ele/src/views/mall/statistics/product/components/product-rank.vue new file mode 100644 index 000000000..09ba064c5 --- /dev/null +++ b/apps/web-ele/src/views/mall/statistics/product/components/product-rank.vue @@ -0,0 +1,153 @@ + + + diff --git a/apps/web-ele/src/views/mall/statistics/product/components/product-summary.vue b/apps/web-ele/src/views/mall/statistics/product/components/product-summary.vue new file mode 100644 index 000000000..3b8c16cdf --- /dev/null +++ b/apps/web-ele/src/views/mall/statistics/product/components/product-summary.vue @@ -0,0 +1,300 @@ + + + diff --git a/apps/web-ele/src/views/mall/statistics/product/index.vue b/apps/web-ele/src/views/mall/statistics/product/index.vue index cfc1f5ce3..ede53465c 100644 --- a/apps/web-ele/src/views/mall/statistics/product/index.vue +++ b/apps/web-ele/src/views/mall/statistics/product/index.vue @@ -1,7 +1,8 @@ diff --git a/packages/@core/base/shared/src/utils/index.ts b/packages/@core/base/shared/src/utils/index.ts index 7a22c972d..0323d0315 100644 --- a/packages/@core/base/shared/src/utils/index.ts +++ b/packages/@core/base/shared/src/utils/index.ts @@ -22,3 +22,18 @@ export { default as cloneDeep } from 'lodash.clonedeep'; export { default as get } from 'lodash.get'; export { default as isEqual } from 'lodash.isequal'; export { default as set } from 'lodash.set'; + +/** + * 构建排序字段 + * @param prop 字段名称 + * @param order 顺序 + */ +export const buildSortingField = ({ + prop, + order, +}: { + order: 'ascending' | 'descending'; + prop: string; +}) => { + return { field: prop, order: order === 'ascending' ? 'asc' : 'desc' }; +}; diff --git a/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue b/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue index 65eafa735..9b735707f 100644 --- a/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue +++ b/packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue @@ -9,6 +9,10 @@ import { CardFooter, CardHeader, CardTitle, + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, VbenCountToAnimator, VbenIcon, } from '@vben-core/shadcn-ui'; @@ -16,6 +20,7 @@ import { interface Props { items?: AnalysisOverviewItem[]; modelValue?: AnalysisOverviewItem[]; + columnsNumber?: number; } defineOptions({ @@ -25,6 +30,7 @@ defineOptions({ const props = withDefaults(defineProps(), { items: () => [], modelValue: () => [], + columnsNumber: 4, }); const emit = defineEmits(['update:modelValue']); @@ -33,14 +39,45 @@ const itemsData = computed({ get: () => (props.modelValue?.length ? props.modelValue : props.items), set: (value) => emit('update:modelValue', value), }); + +// 计算动态的grid列数类名 +const gridColumnsClass = computed(() => { + const colNum = props.columnsNumber; + return { + 'lg:grid-cols-1': colNum === 1, + 'lg:grid-cols-2': colNum === 2, + 'lg:grid-cols-3': colNum === 3, + 'lg:grid-cols-4': colNum === 4, + 'lg:grid-cols-5': colNum === 5, + 'lg:grid-cols-6': colNum === 6, + }; +});