<template>
|
<div class="app-container home">
|
<div style="display: flex;">
|
<div>
|
<div class="card-top-left">
|
<div class="title">
|
<span style="font-weight: bold">本月销售、采购情况计划</span>
|
</div>
|
<div class="card-group">
|
<div class="info-card">
|
<div class="info-message">
|
<div class="info-number">{{contractAmount}}</div>
|
<div class="info-title">合同金额(元)</div>
|
</div>
|
<img src="@/assets/images/icon1.png" alt="" style="width: 63px;height: 63px">
|
</div>
|
<div class="info-card1">
|
<div class="info-message">
|
<div class="info-number">{{invoiceAmount}}</div>
|
<div class="info-title">开票金额(元)</div>
|
</div>
|
<img src="@/assets/images/icon2.png" alt="" style="width: 63px;height: 63px">
|
</div>
|
<div class="info-card2">
|
<div class="info-message">
|
<div class="info-number">{{receiptAmount}}</div>
|
<div class="info-title">回款金额(元)</div>
|
</div>
|
<img src="@/assets/images/icon%203.png" alt="" style="width: 63px;height: 63px">
|
</div>
|
</div>
|
</div>
|
<div class="card-top-left">
|
<div class="title">
|
<span style="font-weight: bold">本月应收、应付情况计划</span>
|
</div>
|
<div class="pie">
|
<div class="card-group">
|
<div class="pie-group">
|
<div style="margin-right: 80px">
|
<Echarts ref="chart"
|
:legend="pieLegend"
|
:chartStyle="chartStyle"
|
:series="materialPieSeries"
|
:tooltip="pieTooltip"></Echarts>
|
</div>
|
<div class="info-message2">
|
<div class="info-message1">
|
<div class="pie-title">本月回款金额</div>
|
<div class="pie-info"><span class="pie-number">{{receiveAmount}}</span>元 <span class="pie-number">{{receiveAmountPercentage}}</span>%</div>
|
</div>
|
<div class="info-message1">
|
<div class="pie-title">应收款金额</div>
|
<div class="pie-info"><span class="pie-number">{{contractAmountMonth}}</span>元</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="card-group">
|
<div class="pie-group">
|
<div style="margin-right: 80px">
|
<Echarts ref="chart"
|
:options="options"
|
:legend="pieLegend"
|
:chartStyle="chartStyle"
|
:series="materialPieSeries1"
|
:tooltip="pieTooltip1"></Echarts>
|
</div>
|
<div class="info-message2">
|
<div class="info-message1">
|
<div class="pie-title1">本月付款金额</div>
|
<div class="pie-info"><span class="pie-number1">{{paymentAmount}}</span>元 <span class="pie-number1">{{payableAmountPercentage}}</span>%</div>
|
</div>
|
<div class="info-message1">
|
<div class="pie-title1">应付款金额</div>
|
<div class="pie-info"><span class="pie-number1">{{payableAmount}}</span>元</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div>
|
<div class="card-top-right">
|
<div class="title">
|
<span style="font-weight: bold">客户合同金额TOP5统计</span>
|
</div>
|
<div>
|
<Echarts ref="chart"
|
:chartStyle="chartStyle1"
|
:grid="grid"
|
:legend="barLegend"
|
:series="barSeries"
|
:tooltip="tooltip"
|
:xAxis="xAxis1"
|
:yAxis="yAxis1"
|
style="height: 42vh;"></Echarts>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div>
|
<div>
|
<div class="card-bottom">
|
<div class="title">
|
<span style="font-weight: bold">回款、开票近半年走势图</span>
|
</div>
|
<div>
|
<Echarts ref="chart"
|
:chartStyle="chartStyle1"
|
:grid="grid"
|
:legend="barLegend"
|
:series="lineSeries"
|
:tooltip="tooltipLine"
|
:xAxis="xAxis2"
|
:yAxis="yAxis2"
|
style="height: 27vh;"></Echarts>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script setup name="Index">
|
const { proxy } = getCurrentInstance()
|
import * as echarts from 'echarts';
|
import Echarts from "@/components/Echarts/echarts.vue";
|
import {
|
getAmountHalfYear,
|
getAmountMouth,
|
getContractAmount,
|
getInvoiceAmount,
|
getReceiptAmount,
|
getTopFiveList, paymentMonthList
|
} from "@/api/viewIndex.js";
|
|
const pieLegend = reactive({
|
show: false,
|
})
|
const contractAmount = ref(0)
|
const invoiceAmount = ref(0)
|
const receiptAmount = ref(0)
|
const receiveAmount = ref(0)
|
const contractAmountMonth = ref(0)
|
const receiveAmountPercentage = ref(0)
|
const paymentAmount = ref(0)
|
const payableAmount = ref(0)
|
const payableAmountPercentage = ref(0)
|
const options = reactive({
|
graphic: {
|
type: 'circle',
|
left: 'center',
|
top: 'middle',
|
shape: {
|
r: '70%' // 圆形半径与饼图外圈相同
|
},
|
}
|
})
|
const pieTooltip = reactive({
|
trigger: 'item',
|
formatter: function (params) {
|
// 动态生成提示信息,基于数据项的 name 属性
|
const description = params.name === '本月回款金额' ? '本月回款金额' : '应收款金额';
|
return `${description} ${formatNumber(params.value)}元 ${params.percent}%`;
|
},
|
position: 'right'
|
})
|
const pieTooltip1 = reactive({
|
trigger: 'item',
|
formatter: function (params) {
|
// 动态生成提示信息,基于数据项的 name 属性
|
const description = params.name === '本月付款金额' ? '本月付款金额' : '应付款金额';
|
return `${description} ${formatNumber(params.value)}元 ${params.percent}%`;
|
},
|
position: 'right'
|
})
|
// 数字格式化函数,添加逗号作为千位分隔符
|
function formatNumber(num) {
|
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
}
|
const materialPieSeries = ref([
|
{
|
type: 'pie',
|
radius: '92%',
|
avoidLabelOverlap: false,
|
itemStyle: {
|
borderColor: '#fff',
|
borderWidth: 2
|
},
|
label: {
|
show:false
|
},
|
data: [
|
{ value: 0, name: '本月回款金额', itemStyle: { color: '#2D99FF' } },
|
{ value: 0, name: '应收款金额', itemStyle: { color: '#D4DDFF' } },
|
]
|
}
|
])
|
const materialPieSeries1 = ref([
|
{
|
type: 'pie',
|
radius: '92%',
|
avoidLabelOverlap: false,
|
itemStyle: {
|
borderColor: '#fff',
|
borderWidth: 2
|
},
|
label: {
|
show:false
|
},
|
data: [
|
{ value: 0, name: '本月付款金额', itemStyle: { color: '#1EBFAC' } },
|
{ value: 0, name: '应付款金额', itemStyle: { color: '#D0EFE1' } },
|
]
|
}
|
])
|
const chartStyle = {
|
width: '150%',
|
height: '120%' // 设置图表容器的高度
|
}
|
const chartStyle1 = {
|
width: '100%',
|
height: '100%' // 设置图表容器的高度
|
}
|
const grid = {
|
show: false
|
}
|
const tooltip = {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
}
|
}
|
const tooltipLine = {
|
trigger: 'axis',
|
}
|
const yAxis1 = ref([
|
{
|
type: 'value',
|
}
|
])
|
const xAxis1 = ref([
|
{
|
type: 'category',
|
data: []
|
}
|
])
|
const yAxis2 = ref([
|
{
|
type: 'value',
|
}
|
])
|
const xAxis2 = ref([
|
{
|
type: 'category',
|
data: []
|
}
|
])
|
const barLegend = reactive({})
|
const barSeries = ref([
|
{
|
type: 'bar',
|
data: [],
|
label: {
|
show: true
|
},
|
},
|
])
|
const lineSeries = ref([
|
{
|
type: 'line',
|
data: [],
|
label: {
|
show: true
|
},
|
},
|
])
|
// 合同金额
|
const getContractAmountNum = () => {
|
getContractAmount().then((res) => {
|
contractAmount.value = res.data
|
})
|
}
|
// 开票金额
|
const getInvoiceAmountNum = () => {
|
getInvoiceAmount().then((res) => {
|
invoiceAmount.value = res.data
|
})
|
}
|
// 回款金额
|
const getReceiptAmountNum = () => {
|
getReceiptAmount().then((res) => {
|
receiptAmount.value = res.data
|
})
|
}
|
// 月回款金额饼图
|
const getAmountMouthNum = () => {
|
getAmountMouth().then((res) => {
|
receiveAmount.value = res.data.receiveAmount
|
contractAmountMonth.value = res.data.contractAmount
|
const percentage = (receiveAmount.value / contractAmountMonth.value) * 100;
|
receiveAmountPercentage.value = percentage.toFixed(2)
|
materialPieSeries.value[0].data[0].value = receiveAmount.value
|
materialPieSeries.value[0].data[1].value = contractAmountMonth.value
|
})
|
}
|
// 月付款金额饼图
|
const paymentMonthListNum = () => {
|
paymentMonthList().then((res) => {
|
paymentAmount.value = res.data.paymentAmount
|
payableAmount.value = res.data.payableAmount
|
const percentage = (paymentAmount.value / payableAmount.value) * 100;
|
payableAmountPercentage.value = percentage.toFixed(2)
|
materialPieSeries1.value[0].data[0].value = paymentAmount.value
|
materialPieSeries1.value[0].data[1].value = payableAmount.value
|
})
|
}
|
// 客户top5
|
const getTopFiveListNum = async () => {
|
const res = await getTopFiveList()
|
const customerName = []
|
const totalAmount = []
|
res.data.forEach(item => {
|
customerName.push(item.customerName)
|
totalAmount.push(item.totalAmount)
|
})
|
// 正确响应式赋值:创建新的 xAxis 和 series 对象
|
xAxis1.value = [
|
{
|
type: 'category',
|
data: customerName
|
}
|
]
|
barSeries.value = [
|
{
|
type: 'bar',
|
data: totalAmount,
|
itemStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{ offset: 0, color: '#F7D2FF' },
|
{ offset: 1, color: '#826AF9' }
|
])
|
},
|
emphasis: {
|
itemStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{ offset: 1, color: '#826AF9' }
|
])
|
}
|
},
|
}
|
]
|
}
|
// 线形图
|
const getAmountHalfYearNum = async () => {
|
const res = await getAmountHalfYear()
|
console.log(res)
|
const monthName = []
|
const receiptAmount = []
|
const invoiceAmount = []
|
res.data.forEach(item => {
|
monthName.push(item.month)
|
receiptAmount.push(item.receiptAmount)
|
invoiceAmount.push(item.invoiceAmount)
|
})
|
// 正确响应式赋值:创建新的 xAxis 和 series 对象
|
xAxis2.value = [
|
{
|
type: 'category',
|
data: monthName
|
}
|
]
|
lineSeries.value = [
|
{
|
name: '开票',
|
type: 'line',
|
data: receiptAmount,
|
smooth: true,
|
stack: 'Total',
|
areaStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{
|
offset: 0,
|
color: 'rgba(131, 207, 255, 1)'
|
},
|
{
|
offset: 1,
|
color: 'rgba(186, 228, 255, 1)'
|
}
|
])
|
},
|
// 设置小圆点的颜色
|
itemStyle: {
|
color: '#2D99FF', // 小圆点颜色设置为#2D99FF
|
borderColor: '#2D99FF' // 如果需要的话,可以设置边框颜色
|
},
|
emphasis: {
|
focus: 'series'
|
},
|
lineStyle: {
|
width: 0
|
},
|
showSymbol: false,
|
},
|
{
|
name: '回款',
|
type: 'line',
|
data: invoiceAmount,
|
smooth: true,
|
stack: 'Total',
|
lineStyle: {
|
width: 0
|
},
|
// 设置小圆点的颜色
|
itemStyle: {
|
color: '#83CFFF', // 小圆点颜色设置为#83CFFF
|
borderColor: '#83CFFF' // 如果需要的话,可以设置边框颜色
|
},
|
showSymbol: false,
|
areaStyle: {
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
{
|
offset: 0,
|
color: 'rgba(54, 153, 255, 1)'
|
},
|
{
|
offset: 1,
|
color: 'rgba(89, 169, 254, 1)'
|
}
|
])
|
},
|
emphasis: {
|
focus: 'series'
|
},
|
}
|
]
|
}
|
getContractAmountNum()
|
getInvoiceAmountNum()
|
getReceiptAmountNum()
|
getTopFiveListNum()
|
getAmountMouthNum()
|
paymentMonthListNum()
|
getAmountHalfYearNum()
|
</script>
|
|
<style scoped>
|
.card-top-left {
|
padding: 16px;
|
background: #fff;
|
height: 24vh;
|
width: 56vw;
|
margin-bottom: 20px;
|
}
|
.card-top-right {
|
padding: 16px;
|
background: #fff;
|
height: 50.6vh;
|
width: 28vw;
|
margin-bottom: 20px;
|
margin-left: 20px;
|
}
|
.card-bottom {
|
padding: 16px;
|
background: #fff;
|
height: 34vh;
|
width: 85.2vw;
|
margin-bottom: 20px;
|
}
|
.title {
|
position: relative;
|
font-size: 18px;
|
color: #333;
|
font-weight: 400;
|
padding-left: 10px;
|
margin-bottom: 26px;
|
}
|
.title::before {
|
position: absolute;
|
left: 0;
|
top: 4px;
|
content: '';
|
width: 4px;
|
height: 18px;
|
background-color: #3A7BFA;
|
border-radius: 2px;
|
}
|
.card-group {
|
display: flex;
|
}
|
.info-card {
|
width: 300px;
|
height: 126px;
|
background-image: url("../assets/images/Rectangle 76@2x.png");
|
background-size: 100% 100%;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
}
|
.info-card1 {
|
width: 300px;
|
height: 126px;
|
background-image: url("../assets/images/Rectangle 77@2x.png");
|
background-size: 100% 100%;
|
margin: 0 40px;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
}
|
.info-card2 {
|
width: 300px;
|
height: 126px;
|
background-image: url("../assets/images/Rectangle 77@2x(1).png");
|
background-size: 100% 100%;
|
display: flex;
|
justify-content: space-around;
|
align-items: center;
|
}
|
.info-message {
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: center;
|
}
|
.info-message1 {
|
font-weight: bold;
|
display: flex;
|
flex-direction: column;
|
justify-content: center;
|
align-items: flex-start;
|
}
|
.info-message2 {
|
font-weight: bold;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
justify-content: space-around;
|
}
|
.info-number {
|
font-weight: bold;
|
font-size: 32px;
|
color: #FFFFFF;
|
margin-bottom: 10px;
|
}
|
.info-title {
|
font-weight: bold;
|
font-size: 18px;
|
color: #FFFFFF;
|
}
|
.pie {
|
display: flex;
|
flex-direction: row;
|
justify-content: space-around;
|
}
|
.pie-group {
|
display: flex;
|
}
|
.pie-title {
|
font-size: 14px;
|
line-height: 24px;
|
color: #2853FD;
|
padding-left: 16px;
|
position: relative;
|
}
|
.pie-title::before {
|
content: '';
|
width: 6px; /* 蓝点的宽度 */
|
height: 6px; /* 蓝点的高度 */
|
background-color: #2853FD; /* 蓝点的颜色 */
|
border-radius: 50%; /* 将正方形变为圆形 */
|
position: absolute;
|
left: 0; /* 定位到左边 */
|
top: 9px; /* 垂直居中对齐,根据行高调整 */
|
}
|
.pie-title1 {
|
font-size: 14px;
|
line-height: 24px;
|
color: #1EBFAC;
|
padding-left: 16px;
|
position: relative;
|
}
|
.pie-title1::before {
|
content: '';
|
width: 6px; /* 蓝点的宽度 */
|
height: 6px; /* 蓝点的高度 */
|
background-color: #1EBFAC; /* 蓝点的颜色 */
|
border-radius: 50%; /* 将正方形变为圆形 */
|
position: absolute;
|
left: 0; /* 定位到左边 */
|
top: 9px; /* 垂直居中对齐,根据行高调整 */
|
}
|
.pie-info {
|
padding-left: 16px;
|
font-size: 14px;
|
line-height: 24px;
|
}
|
.pie-number {
|
color: #2853FD;
|
}
|
.pie-number1 {
|
color: #1EBFAC;
|
}
|
</style>
|
|