feat: 新增商品统计组件和优化数据处理逻辑
- 引入商品排行和商品概况组件,展示商品相关统计信息 - 更新商品统计 API,支持时间范围查询和数据格式化 - 优化数据加载逻辑,提升用户体验 - 添加日期范围选择器,增强统计数据的灵活性
This commit is contained in:
@@ -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' };
|
||||
};
|
||||
|
||||
@@ -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<Props>(), {
|
||||
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,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-4">
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2" :class="gridColumnsClass">
|
||||
<template v-for="item in itemsData" :key="item.title">
|
||||
<Card :title="item.title" class="w-full">
|
||||
<CardHeader>
|
||||
<CardTitle class="text-xl">{{ item.title }}</CardTitle>
|
||||
<CardTitle class="text-xl">
|
||||
<div class="flex items-center">
|
||||
<span>{{ item.title }}</span>
|
||||
<span v-if="item.tooltip" class="ml-1 inline-block">
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
<TooltipTrigger>
|
||||
<div
|
||||
class="inline-flex h-4 w-4 translate-y-[-3px] items-center justify-center rounded-full bg-gray-200 text-xs font-bold text-gray-600"
|
||||
>
|
||||
!
|
||||
</div>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>{{ item.tooltip }}</TooltipContent>
|
||||
</Tooltip>
|
||||
</TooltipProvider>
|
||||
</span>
|
||||
</div>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent class="flex items-center justify-between">
|
||||
|
||||
@@ -6,6 +6,7 @@ interface AnalysisOverviewItem {
|
||||
totalTitle?: string;
|
||||
totalValue?: number;
|
||||
value: number;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
interface WorkbenchProjectItem {
|
||||
|
||||
33
packages/icons/src/svg/icons/eye.svg
Normal file
33
packages/icons/src/svg/icons/eye.svg
Normal file
@@ -0,0 +1,33 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300">
|
||||
<!-- 样式定义 -->
|
||||
<style>
|
||||
.eye-outline { fill: #0D47A1; }
|
||||
.eye-white { fill: #BBDEFB; }
|
||||
.eye-iris { fill: #2196F3; }
|
||||
.eye-pupil { fill: #000000; }
|
||||
.eye-highlight { fill: #FFFFFF; }
|
||||
.eye-shadow { fill: #1565C0; }
|
||||
</style>
|
||||
|
||||
<!-- 眼睛外轮廓 -->
|
||||
<path class="eye-outline" d="M200,250c-80,0-160-60-200-100c40-40,120-100,200-100s160,60,200,100C360,190,280,250,200,250z"/>
|
||||
|
||||
<!-- 眼睛白色部分 -->
|
||||
<path class="eye-white" d="M200,70c70,0,140,50,180,80c-40,30-110,80-180,80s-140-50-180-80C60,120,130,70,200,70z"/>
|
||||
|
||||
<!-- 眼睑阴影 -->
|
||||
<path class="eye-shadow" d="M200,90c-60,0-120,40-160,60c40,20,100,60,160,60s120-40,160-60C320,130,260,90,200,90z"/>
|
||||
|
||||
<!-- 虹膜 -->
|
||||
<circle class="eye-iris" cx="200" cy="150" r="60"/>
|
||||
|
||||
<!-- 瞳孔 - 确保是明显的黑色圆形 -->
|
||||
<circle class="eye-pupil" cx="200" cy="150" r="25"/>
|
||||
|
||||
<!-- 高光 -->
|
||||
<circle class="eye-highlight" cx="180" cy="130" r="12"/>
|
||||
|
||||
<!-- 装饰线条 -->
|
||||
<path class="eye-highlight" d="M100,110c10-5,30-15,40-20c3-1,2-5-1-4c-10,5-30,15-40,20C96,107,97,111,100,110z"/>
|
||||
<path class="eye-highlight" d="M300,190c2-5,5-10,10-15c10-10,20-20,30-25c2-1,0-5-2-4c-15,10-30,30-40,45C297,193,299,195,300,190z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -10,6 +10,7 @@ const SvgDownloadIcon = createIconifyIcon('svg:download');
|
||||
const SvgCardIcon = createIconifyIcon('svg:card');
|
||||
const SvgBellIcon = createIconifyIcon('svg:bell');
|
||||
const SvgCakeIcon = createIconifyIcon('svg:cake');
|
||||
const SvgEyeIcon = createIconifyIcon('svg:eye');
|
||||
const SvgAntdvLogoIcon = createIconifyIcon('svg:antdv-logo');
|
||||
|
||||
/** AI */
|
||||
@@ -44,6 +45,7 @@ export {
|
||||
SvgCakeIcon,
|
||||
SvgCardIcon,
|
||||
SvgDownloadIcon,
|
||||
SvgEyeIcon,
|
||||
SvgGptIcon,
|
||||
SvgMockIcon,
|
||||
SvgWalletIcon,
|
||||
|
||||
Reference in New Issue
Block a user