Files
jdt-user/src/pages/admin/statistics/index.vue
YuanHuakk 1d8532eccf
All checks were successful
continuous-integration/drone/push Build is passing
feat(custom): 新增消息订阅
2024-08-27 17:06:59 +08:00

445 lines
9.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="statistical-page" ref="container">
<view class="navs">
<view class="list">
<view
class="item"
:class="time == 'today' ? 'on' : ''"
@click="setTime('today')">
今天
</view>
<view
class="item"
:class="time == 'yesterday' ? 'on' : ''"
@click="setTime('yesterday')">
昨天
</view>
<view
class="item"
:class="time == 'seven' ? 'on' : ''"
@click="setTime('seven')">
最近7天
</view>
<view
class="item"
:class="time == 'month' ? 'on' : ''"
@click="setTime('month')">
本月
</view>
<view
class="item"
:class="time == 'date' ? 'on' : ''"
@click="dateTitle">
自定义
</view>
</view>
</view>
<view class="wrapper">
<view class="title">
{{ title }}{{ where.type == 1 ? '营业额' : '订单量' }}
</view>
<view v-if="where.type == 1" class="money">{{ dataObj.all || 0 }}</view>
<view v-else class="money">{{ dataObj.all || 0 }}</view>
<view class="increase">
<view>
{{ time === 'date' ? '' : title }}增长率<text
:class="dataObj.growthRate >= 0 ? 'red' : 'green'">
{{ dataObj.growthRate }}%
<text
class="iconfont"
:class="
dataObj.growthRate >= 0 ? 'icon-xiangshang1' : 'icon-xiangxia2'
"></text
></text>
</view>
<view>
{{ time === 'date' ? '' : title }}增长<text
:class="dataObj.growthNumber >= 0 ? 'red' : 'green'"
>{{ dataObj.growthNumber }}
<text
class="iconfont"
:class="
dataObj.growthNumber >= 0
? 'icon-xiangshang1'
: 'icon-xiangxia2'
"></text
></text>
</view>
</view>
</view>
<view class="chart">
<canvas
canvas-id="myChart"
style="width: 100%; height: 250px"
:ontouch="true"
@touchstart="touchStart"
@touchmove="touchMove"
@touchend="touchEnd" />
</view>
<view class="Card">
<view class="top"
><text class="iconfont icon-xiangxishuju icon"></text
><text>详细数据</text></view
>
<view v-if="dataObj?.list?.length > 0">
<nut-table
:bordered="true"
class="table"
:columns="columns"
:data="dataObj?.list"></nut-table>
</view>
<nut-empty v-else description="暂无订单数据"></nut-empty>
</view>
<!-- 日期选择 -->
<nut-calendar
v-model:visible="isVisible"
type="range"
:default-value="pickerVal"
:start-date="date_start"
@close="isVisible = false"
@choose="setChooseValue">
</nut-calendar>
</view>
</template>
<script setup lang="ts">
import {ref, computed, h} from 'vue';
import Taro from '@tarojs/taro';
import {growthRate} from '../../../api/admin';
import dayjs from 'dayjs';
import uCharts from '../../../utils/js_sdk/u-charts.min.js';
const time = ref('');
const isVisible = ref(false);
let canvas_obj;
const w = Taro.getSystemInfoSync().windowWidth;
const chartWH = ref({
width: w * 0.9,
height: 250,
pixelRatio: 1,
});
const columns = ref([
{
title: '日期',
key: 'Date',
align: 'center',
},
{
title: '订单数',
key: 'TotalCount',
align: 'center',
},
{
title: '交易额',
key: 'NumberSum',
align: 'center',
render: row => {
return h(
'view',
{
style: {
color: 'red',
},
},
row.NumberSum,
);
},
},
]);
const date_start = computed(() => {
return dayjs().startOf('year').format('YYYY-MM-DD');
});
const title = ref('');
const where = ref({
type: 1,
status: 2,
start: '',
end: '',
});
const dataObj = ref<any>({});
const opts = ref<any>({
categories: [],
series: [
{
name: '营业额',
data: [],
},
{
name: '订单量',
data: [],
},
],
});
const pickerVal = ref<any>([]);
Taro.useLoad(options => {
where.value.type = options.type === 'price' ? 1 : 2;
time.value = options.time;
setTime(options.time);
// getData();
pickerVal.value = [
dayjs().format('YYYY-MM-DD'),
dayjs().format('YYYY-MM-DD'),
];
});
const setTime = (type: string) => {
time.value = type;
switch (type) {
case 'today':
title.value = '今日';
where.value.status = 2;
where.value.start = dayjs().format('YYYY-MM-DD');
where.value.end = dayjs().format('YYYY-MM-DD');
break;
case 'yesterday':
title.value = '昨日';
where.value.status = 2;
where.value.start = dayjs().add(-1, 'day').format('YYYY-MM-DD');
where.value.end = dayjs().add(-1, 'day').format('YYYY-MM-DD');
break;
case 'seven':
title.value = '7天';
where.value.status = 2;
where.value.start = dayjs().add(-6, 'day').format('YYYY-MM-DD');
where.value.end = dayjs().format('YYYY-MM-DD');
break;
case 'month':
title.value = '本月';
where.value.status = 1;
where.value.start = dayjs().startOf('month').format('YYYY-MM-DD');
where.value.end = dayjs().format('YYYY-MM-DD');
break;
}
getData();
};
const dateTitle = () => {
where.value.status = 1;
time.value = 'date';
isVisible.value = true;
};
const setChooseValue = (ref: any) => {
where.value.start = ref[0][3];
where.value.end = ref[1][3];
title.value = `${where.value.start}-${where.value.end}`;
getData();
};
const getData = async () => {
try {
const user_info = Taro.getStorageSync('userInfo');
const res = await growthRate({
bid: user_info.data.bid,
status: where.value.status,
StartTime: where.value.start,
EndTime: where.value.end,
});
dataObj.value = res.data;
opts.value.categories = [];
opts.value.series[0].data = [];
opts.value.series[1].data = [];
res.data.list.forEach((item: any) => {
opts.value.categories.push(item.Date);
opts.value.series[0].data.push(item.NumberSum);
opts.value.series[1].data.push(item.TotalCount);
});
create_canvas();
} catch (error) {
Taro.showToast({
title: error.msg,
icon: 'none',
});
throw error;
}
};
const create_canvas = () => {
const ctx = Taro.createCanvasContext('myChart');
canvas_obj = new uCharts({
type: 'column',
context: ctx,
width: chartWH.value.width,
height: chartWH.value.height,
categories: opts.value.categories,
series: opts.value.series,
pixelRatio: chartWH.value.pixelRatio,
animation: true,
background: '#FFFFFF',
color: [
'#1890FF',
'#91CB74',
'#FAC858',
'#EE6666',
'#73C0DE',
'#3CA272',
'#FC8452',
'#9A60B4',
'#ea7ccc',
],
padding: [15, 15, 0, 15],
enableScroll: true,
legend: {},
xAxis: {
disableGrid: true,
scrollShow: true,
itemCount: 3,
},
yAxis: {
data: [
{
min: 0,
},
],
},
extra: {
column: {
type: 'group',
width: 20,
activeBgColor: '#000000',
activeBgOpacity: 0.08,
},
},
});
};
const touchStart = (e: any) => {
canvas_obj.showToolTip(e, {
format: function (item: any, category: any) {
return category + ' ' + item.name + ':' + item.data;
},
});
canvas_obj.scrollStart(e);
};
const touchMove = (e: any) => {
canvas_obj.scroll(e);
};
const touchEnd = (e: any) => {
canvas_obj.scrollEnd(e);
};
</script>
<style lang="scss">
.statistical-page {
.navs {
width: 100%;
height: 96px;
background-color: #fff;
overflow: hidden;
line-height: 96px;
position: fixed;
top: 0;
left: 0;
z-index: 9;
.list {
overflow-y: hidden;
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
width: 100%;
.item {
font-size: 32px;
color: #282828;
margin-left: 60px;
display: inline-block;
}
.on {
color: #fa2c19;
}
}
}
.wrapper {
width: 95%;
background-color: #fff;
border-radius: 10px;
margin: 119px auto 0 auto;
padding: 50px 60px;
.title {
font-size: 30px;
color: #999;
text-align: center;
}
.money {
font-size: 72px;
color: #fba02a;
text-align: center;
margin-top: 10px;
}
.increase {
font-size: 28px;
color: #999;
margin-top: 20px;
display: flex;
justify-content: space-between;
align-items: center;
.red {
color: #ff6969;
}
.green {
color: #1abb1d;
}
.iconfont {
font-size: 23px;
margin-left: 15px;
}
}
}
.chart {
width: 95%;
box-sizing: border-box;
background-color: #fff;
border-radius: 10px;
margin: 23px auto;
padding: 10px;
}
.Card {
width: 95%;
background-color: #fff;
border-radius: 10px;
margin: 10px auto;
padding: 25px;
.top {
display: flex;
align-items: center;
text {
margin-right: 5px;
}
.iconfont {
color: #fa2c19;
}
}
.table {
margin-top: 10px;
}
}
}
</style>