|
@@ -1,53 +1,212 @@
|
|
|
<template>
|
|
|
<div class="p-4">
|
|
|
- <GrowCard :loading="loading" class="enter-y" :list="list" />
|
|
|
+ <GrowCard :loading="loading" class="enter-y" :list="growCardList" />
|
|
|
<div class="md:flex !my-4 enter-y">
|
|
|
- <lineEcharts class="md:w-1/2 w-full !md:mt-0 !mt-4 !md:mr-4" name="chartRef1" :loading="loading" />
|
|
|
- <lineEcharts2 name="chartRef2" class="md:w-1/2 mx-4 w-full" :loading="loading" />
|
|
|
+ <lineEcharts
|
|
|
+ class="md:w-1/2 w-full !md:mt-0 !mt-4 !md:mr-4"
|
|
|
+ name="chartRef1"
|
|
|
+ :loading="loading"
|
|
|
+ @change="Search"
|
|
|
+ :propsData="echartData"
|
|
|
+ @export="handleExport"
|
|
|
+ />
|
|
|
+ <lineEcharts2 name="chartRef2" class="md:w-1/2 mx-4 w-full" @export="handleExport" @change="Search" :echartData="orderData" />
|
|
|
</div>
|
|
|
- <SiteAnalysis class="!my-4 enter-y" :loading="loading" />
|
|
|
- <div class="md:flex enter-y">
|
|
|
+ <sceneEchart title="近半年场景新增趋势" class="!my-4 enter-y" @export="handleExport" @change="Search" :echartData="scenetData" :loading="loading" />
|
|
|
+ <!-- <SiteAnalysis class="!my-4 enter-y" :loading="loading" /> -->
|
|
|
+ <!-- <div class="md:flex enter-y">
|
|
|
<VisitRadar class="md:w-1/3 w-full" :loading="loading" />
|
|
|
<VisitSource class="md:w-1/3 !md:mx-4 !md:my-0 !my-4 w-full" :loading="loading" />
|
|
|
<SalesProductPie class="md:w-1/3 w-full" :loading="loading" />
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
</div>
|
|
|
</template>
|
|
|
<script lang="ts" setup>
|
|
|
- import { ref, onMounted } from 'vue';
|
|
|
- import { userTotal } from '/@/api/statistics/index';
|
|
|
- import GrowCard from './components/GrowCard.vue';
|
|
|
- import SiteAnalysis from './components/SiteAnalysis.vue';
|
|
|
- import VisitSource from './components/VisitSource.vue';
|
|
|
- import VisitRadar from './components/VisitRadar.vue';
|
|
|
- import lineEcharts from './components/lineEcharts.vue';
|
|
|
- import lineEcharts2 from './components/lineEcharts2.vue';
|
|
|
- import SalesProductPie from './components/SalesProductPie.vue';
|
|
|
- import { Row, Col } from 'ant-design-vue';
|
|
|
- const loading = ref(true);
|
|
|
- interface GrowCardItem {
|
|
|
- icon: string;
|
|
|
- title: string;
|
|
|
- value: number;
|
|
|
- unit: string;
|
|
|
- color: string;
|
|
|
- action: string;
|
|
|
+import { ref, onMounted, reactive } from 'vue';
|
|
|
+import { userTotal, orderTotal, orderTrend,userTrend, cameraExport, downExport, incrementExport } from '/@/api/statistics/index';
|
|
|
+import GrowCard from './components/GrowCard.vue';
|
|
|
+import SiteAnalysis from './components/SiteAnalysis.vue';
|
|
|
+import sceneEchart from './components/orderEchart.vue';
|
|
|
+import VisitSource from './components/VisitSource.vue';
|
|
|
+import VisitRadar from './components/VisitRadar.vue';
|
|
|
+import lineEcharts from './components/lineEcharts.vue';
|
|
|
+import lineEcharts2 from './components/lineEcharts2.vue';
|
|
|
+import SalesProductPie from './components/SalesProductPie.vue';
|
|
|
+import { downloadByData, } from '/@/utils/file/download';
|
|
|
+import { Row, Col } from 'ant-design-vue';
|
|
|
+const loading = ref(true);
|
|
|
+interface GrowCardItem {
|
|
|
+ icon: string;
|
|
|
+ title: string;
|
|
|
+ value: number;
|
|
|
+ unit: string;
|
|
|
+ color: string;
|
|
|
+ action: string;
|
|
|
+}
|
|
|
+const orderData = reactive({
|
|
|
+ xdata:[],
|
|
|
+ downOrder:[],
|
|
|
+ incrementOrder:[],
|
|
|
+ partOrder:[],
|
|
|
+ })
|
|
|
+const echartData = reactive({
|
|
|
+ xData:[],
|
|
|
+ yData:[],
|
|
|
+ })
|
|
|
+const scenetData = reactive({
|
|
|
+ xdata:[],
|
|
|
+ downOrder:[],
|
|
|
+ incrementOrder:[],
|
|
|
+ partOrder:[],
|
|
|
+ echartTypr:'bar',
|
|
|
+ })
|
|
|
+const SearchData = reactive({
|
|
|
+ startTime:'',
|
|
|
+ endTime:'',
|
|
|
+ orderType:0,
|
|
|
+ sceneType:0,
|
|
|
+ userType:0,
|
|
|
+ })
|
|
|
+onMounted(() => {
|
|
|
+ getData();
|
|
|
+ getAddUser();
|
|
|
+ getOrder()
|
|
|
+ getSceneList()
|
|
|
+});
|
|
|
+const growCardList = ref<GrowCardItem[]>([]);
|
|
|
+async function getData() {
|
|
|
+ try {
|
|
|
+ loading.value = true;
|
|
|
+ const { totalUserCount, preMonthAddCount, todayAddCount, todayActiveCount } = await userTotal();
|
|
|
+ const { preMonThPowCount, preMonThDownCount, preMonThPartCount } = await orderTotal();
|
|
|
+ let list = [
|
|
|
+ {
|
|
|
+ title: '累计用户',
|
|
|
+ // icon: 'fa6-solid:users-gear',
|
|
|
+ icon: 'visit-count|svg',
|
|
|
+ value: totalUserCount || 0,
|
|
|
+ unit: '人',
|
|
|
+ color: 'green',
|
|
|
+ action: '年',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '上月新增用户',
|
|
|
+ icon: 'akar-icons:person-add',
|
|
|
+ value: preMonthAddCount || 0,
|
|
|
+ unit: '人',
|
|
|
+ color: 'blue',
|
|
|
+ action: '月',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '今日新增用户',
|
|
|
+ icon: 'carbon:user-role',
|
|
|
+ value: todayAddCount || 0,
|
|
|
+ unit: '人',
|
|
|
+ color: 'orange',
|
|
|
+ action: '日',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '上月权益订单数',
|
|
|
+ icon: 'fxemoji:notchedrightsemi3dot',
|
|
|
+ value: preMonThPowCount,
|
|
|
+ unit: '人',
|
|
|
+ color: 'blue',
|
|
|
+ action: '月',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '上月下载订单数',
|
|
|
+ icon: 'download-count|svg',
|
|
|
+ value: preMonThDownCount,
|
|
|
+ unit: '人',
|
|
|
+ color: 'orange',
|
|
|
+ action: '月',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '上月配件订单数',
|
|
|
+ icon: 'transaction|svg',
|
|
|
+ value: preMonThPartCount,
|
|
|
+ unit: '人',
|
|
|
+ color: 'blue',
|
|
|
+ action: '月',
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ growCardList.value = list;
|
|
|
+ loading.value = false;
|
|
|
+ } catch (error) {
|
|
|
+ loading.value = false;
|
|
|
}
|
|
|
- onMounted(() => {
|
|
|
- getData();
|
|
|
- });
|
|
|
- const list = ref<GrowCardItem[]>([]);
|
|
|
- async function getData() {
|
|
|
- try {
|
|
|
- loading.value = true;
|
|
|
- const Total = await userTotal();
|
|
|
- console.log('sData', Total);
|
|
|
- loading.value = false;
|
|
|
- } catch (error) {
|
|
|
- loading.value = false;
|
|
|
- }
|
|
|
+}
|
|
|
+async function getAddUser() {
|
|
|
+ let xdata = []
|
|
|
+ loading.value = true;
|
|
|
+ const {downOrder,incrementOrder,partOrder} = await userTrend({...SearchData,type:SearchData.userType});
|
|
|
+ echartData.xData = xdata
|
|
|
+ echartData.yData = incrementOrder.map(ele => ele.count)
|
|
|
+ loading.value = false;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+async function getOrder() {
|
|
|
+ let downlist = [],xdata = []
|
|
|
+ loading.value = true;
|
|
|
+ const {downOrder,incrementOrder,partOrder} = await orderTrend({...SearchData,type:SearchData.orderType});
|
|
|
+ downOrder.map(ele => {
|
|
|
+ xdata.push(ele.groupKey)
|
|
|
+ downlist.push(ele.count)
|
|
|
+ })
|
|
|
+ orderData.xdata = xdata
|
|
|
+ orderData.downOrder = downlist
|
|
|
+ orderData.incrementOrder = incrementOrder.map(ele => ele.count)
|
|
|
+ orderData.partOrder = partOrder &&partOrder.map(ele => ele.count)|| []
|
|
|
+ console.log('getList',orderData)
|
|
|
+ loading.value = false;
|
|
|
}
|
|
|
- setTimeout(() => {
|
|
|
+ async function getSceneList() {
|
|
|
+ let downlist = [],xdata = []
|
|
|
+ loading.value = true;
|
|
|
+ const {downOrder,incrementOrder,partOrder} = await orderTrend({...SearchData,type:SearchData.sceneType});
|
|
|
+ downOrder.map(ele => {
|
|
|
+ xdata.push(ele.groupKey)
|
|
|
+ downlist.push(ele.count)
|
|
|
+ })
|
|
|
+ scenetData.xdata = xdata
|
|
|
+ scenetData.downOrder = downlist
|
|
|
+ scenetData.incrementOrder = incrementOrder.map(ele => ele.count)
|
|
|
+ scenetData.partOrder = partOrder &&partOrder.map(ele => ele.count)|| []
|
|
|
loading.value = false;
|
|
|
- }, 1500);
|
|
|
+ }
|
|
|
+ function handleExport(val){
|
|
|
+ console.log('handleExport',val)
|
|
|
+ let obj = {
|
|
|
+ 'user':cameraExport,
|
|
|
+ 'order':incrementExport,
|
|
|
+ 'scene':downExport,
|
|
|
+ }
|
|
|
+ let apiSrc = obj[val] || cameraExport
|
|
|
+ apiSrc({}).then(res => {
|
|
|
+ console.log('handlerowClick',res)
|
|
|
+ downloadByData(res.data,'导出文件.xls')
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function Search(val){
|
|
|
+ const {value,type} = val
|
|
|
+ console.log('handleChange',value,type)
|
|
|
+ if(type){
|
|
|
+ switch(type){
|
|
|
+ case 'user':
|
|
|
+ SearchData.userType = value
|
|
|
+ getAddUser()
|
|
|
+ break;
|
|
|
+ case 'order':
|
|
|
+ SearchData.orderType = value
|
|
|
+ getOrder()
|
|
|
+ break;
|
|
|
+ case 'scene':
|
|
|
+ SearchData.sceneType = value
|
|
|
+ getSceneList()
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
</script>
|