master
lion 9 months ago
parent 7f1d09a574
commit 43c304ae1f

@ -0,0 +1,10 @@
import request from "@/utils/request";
export function accompanyChart(params){
return request({
method:'get',
url:'api/admin/accompany-product/chart',
params
})
}

@ -0,0 +1,361 @@
<template>
<el-row class="rank-page" :gutter="0">
<!-- 左侧柱状图 -->
<el-col :span="16" class="chart-col">
<div style="text-align: right;width: 100%;margin-bottom: 10px;">
<el-date-picker v-model="dateRange" @change="changeDate" format="yyyy-MM-dd" value-format="yyyy-MM-dd"
type="daterange" range-separator="至" start-placeholder="开始日期" unlink-panels end-placeholder="结束日期"
:picker-options="pickerOptions">
</el-date-picker>
</div>
<div class="chart-title">{{year}}年商业购买服务区域分析图</div>
<div ref="barChart" class="bar-chart"></div>
</el-col>
<!-- 右侧信息区 -->
<el-col :span="8" class="info-col">
<div class="logo-box">
<img :src="logo" class="logo-img" alt="logo" />
</div>
<div class="summary">
<div class="summary-title">
<span class="highlight">{{startDate}}</span>
<span class="highlight">{{endDate}}</span>商业化总收入
<span class="income highlight">{{total}}</span>
</div>
<div class="rank-title">区域排名</div>
<div class="rank-list">
<div v-for="(item, idx) in barData" :key="item.name">
{{ idx + 1 }}<span class="highlight">{{ item.name }}</span>
</div>
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import echarts from 'echarts'
import {
accompanyChart
} from "@/api/chart/accompany.js"
export default {
name: 'Rank',
data() {
return {
logo: require("@/assets/logo.png"),
pickerOptions: {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三个月',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近一年',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 365);
picker.$emit('pick', [start, end]);
}
}, {
text: '最近三年',
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 365 * 3);
picker.$emit('pick', [start, end]);
}
}]
},
dateRange: [],
select: {
start_date: '',
end_date: '',
},
startDate: '',
endDate: '',
year: new Date().getFullYear() + '',
colorList: [
['#3a7bd5', '#00d2ff'], // 西
['#ff8008', '#ffc837'], //
['#ffd200', '#f7971e'], //
['#43e97b', '#38f9d7'], //
['#11998e', '#38ef7d'], //
['#f85032', '#e73827'], //
['#b6c0c5', '#b6c0c5'], //
['#b6c0c5', '#b6c0c5'] //
],
total: 0,
barData: []
}
},
mounted() {
this.getToday()
this.getChart()
// this.initChart()
window.addEventListener('resize', this.resizeChart)
},
beforeDestroy() {
window.removeEventListener('resize', this.resizeChart)
if (this.chart) this.chart.dispose()
},
methods: {
changeDate(e) {
if (e) {
this.select.start_date = e[0]
this.select.end_date = e[1]
this.startDate = this.formatDateToChinese(e[0])
this.endDate = this.formatDateToChinese(e[1])
this.getChart()
} else {
this.select.start_date = ''
this.select.end_date = ''
this.getToday()
this.getChart()
}
},
formatDateToChinese(dateStr) {
if (!dateStr) return '';
const date = new Date(dateStr);
const year = date.getFullYear();
// getMonth() 0-11 1
const month = date.getMonth() + 1;
const day = date.getDate();
return `${year}${month}${day}`;
},
getToday() {
const currentDate = new Date()
const year = currentDate.getFullYear()
const month = currentDate.getMonth() + 1
const day = currentDate.getDate()
this.endDate = year + '年' + month + '月' + day + '日'
this.startDate = year + '年' + '1月' + '1日'
},
getColor(index) {
const colorList = this.colorList
return colorList[index % colorList.length]
},
async getChart() {
const res = await accompanyChart({
start_date: this.select.start_date,
end_date: this.select.end_date
})
let arr = []
res.sites.map(item => {
arr.push({
name: item.name,
value: item.accompany_order_sum
})
})
this.barData = arr
this.initChart()
},
initChart() {
this.chart = echarts.init(this.$refs.barChart)
const option = {
grid: {
left: 60,
right: 20,
bottom: 40,
top: 60
},
xAxis: {
type: 'category',
data: this.barData.map(d => d.name),
axisLine: {
lineStyle: {
color: '#ccc'
}
},
axisLabel: {
color: '#333',
fontSize: 16
}
},
yAxis: {
type: 'value',
splitLine: {
lineStyle: {
color: '#eee'
}
},
axisLine: {
show: false
},
axisLabel: {
color: '#333',
fontSize: 16
}
},
series: [{
type: 'bar',
barWidth: 48,
data: this.barData.map((d, i) => {
const color = this.getColor(i)
return {
value: d.value,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0,
color: color[0]
},
{
offset: 1,
color: color[1]
}
]
},
borderRadius: [24, 24, 0, 0],
shadowColor: d.value > 0 ? color[0] : '#ccc',
shadowBlur: 10
},
label: {
show: true,
position: 'top',
color: color[0],
fontWeight: 'bold',
fontSize: 16,
formatter: d.value > 0 ? d.value : ''
}
}
}),
z: 3
}]
}
this.chart.setOption(option)
},
resizeChart() {
if (this.chart) this.chart.resize()
}
}
}
</script>
<style scoped>
.rank-page {
height: 100vh;
background: #fff;
min-width: 1200px;
}
.chart-col {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
background: #fff;
padding: 40px 0 0 0;
}
.chart-title {
font-size: 28px;
font-weight: bold;
text-align: left;
margin-bottom: 20px;
color: #222;
}
.bar-chart {
width: 90%;
height: 500px;
background: #fff;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.04);
}
.info-col {
background: #fff;
display: flex;
flex-direction: column;
align-items: flex-end;
padding: 40px 40px 0 0;
min-width: 350px;
}
.logo-box {
width: 220px;
margin-bottom: 30px;
align-self: flex-end;
}
.logo-img {
width: 100%;
height: auto;
}
.summary {
margin-top: 10px;
font-size: 18px;
color: #222;
width: 100%;
max-width: 350px;
}
.summary-title {
margin-bottom: 30px;
line-height: 1.8;
}
.income {
font-size: 28px;
font-weight: bold;
}
.highlight {
color: #1976d2;
}
.rank-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 10px;
color: #1976d2;
}
.rank-list {
font-size: 18px;
line-height: 2;
}
@media (max-width: 1200px) {
.rank-page {
min-width: 900px;
}
.bar-chart {
height: 350px;
}
.info-col {
padding: 20px 10px 0 0;
}
}
</style>
Loading…
Cancel
Save