feat(largeScreen): 大屏展示功能开发

- 新增 RevenueContractCard 组件,用于展示收入、支出等合同数据
- 实现 bottomboxconpoent 组件的通用化,支持自定义标题、数值等
- 在 centerPage 中集成 RevenueContractCard 组件,展示大屏数据
- 更新 rightPage 组件,添加实际数据请求和展示
- 优化 optionList 中的图表配置,提高图表可读性
This commit is contained in:
tcy
2025-08-22 16:37:14 +08:00
parent c1512c5a34
commit ad04cff917
6 changed files with 144 additions and 76 deletions

View File

@ -0,0 +1,22 @@
import request from '@/utils/request';
// 合同金额
export const totalAmount = () => {
return request({
url: '/money/big/screen/totalAmount',
method: 'get',
});
};
// 资金KPI
export const monthMoney = () => {
return request({
url: '/money/big/screen/monthMoney',
method: 'get',
});
};
// 现金流
export const monthCash = () => {
return request({
url: '/money/big/screen/monthCash',
method: 'get',
});
};

View File

@ -5,25 +5,18 @@
<!-- 数值区域 --> <!-- 数值区域 -->
<div class="stat-card__value-container"> <div class="stat-card__value-container">
<span class="stat-card__value">{{ formattedValue }}</span> <span class="stat-card__value">{{ props.value }}</span>
<span class="stat-card__unit">{{ unit }}</span> <span class="stat-card__unit">{{ unit }}</span>
</div> </div>
<!-- 底部信息区域 --> <!-- 底部信息区域 -->
<div class="stat-card__footer"> <div class="stat-card__footer" v-if="showIcon">
<div class="stat-card__trend"> <div class="stat-card__trend">
<img <img class="stat-card__trend-icon" :src="'/src/assets/large/' + trendIcon + '.png'"
class="stat-card__trend-icon" :alt="trendDirection === 'up' ? '上升' : '下降'">
:src="'/src/assets/large/' + trendIcon+'.png'"
:alt="trendDirection === 'up' ? '上升' : '下降'"
>
<span class="stat-card__trend-text">{{ trendText }}</span> <span class="stat-card__trend-text">{{ trendText }}</span>
</div> </div>
<img <img class="stat-card__badge" :src="'/src/assets/large/' + badgeIcon + '.png'" alt="徽章图标">
class="stat-card__badge"
:src="'/src/assets/large/'+badgeIcon+'.png'"
alt="徽章图标"
>
</div> </div>
</div> </div>
</template> </template>
@ -78,6 +71,10 @@ const props = defineProps({
customStyles: { customStyles: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
},
showIcon: {
type: Boolean,
default: false
} }
}); });
@ -103,10 +100,12 @@ const trendText = computed(() => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
padding: 20px; padding: 35px 10px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(29, 214, 255, 0.1); border: 1px solid rgba(29, 214, 255, 0.1);
border-radius: 4px; // 增加轻微圆角,提升视觉效果 border-radius: 4px; // 增加轻微圆角,提升视觉效果
text-align: center;
&__title { &__title {
font-size: 14px; font-size: 14px;
@ -115,8 +114,10 @@ const trendText = computed(() => {
} }
&__value-container { &__value-container {
display: flex; // display: flex;
align-items: baseline; align-items: baseline;
// align-items: center;
// flex-direction: column;
} }
&__value { &__value {

View File

@ -1,21 +1,41 @@
<template> <template>
<div class="bottom_box"> <div class="bottom_box">
<div class="bottom_box_title">收入合同</div> <div class="bottom_box_title">{{ title }}</div>
<div> <div>
<span class="bottom_box_number">205,805.17</span> <span class="bottom_box_number">{{ value }}</span>
<span>万元</span> <span>{{ unit }}</span>
</div> </div>
<div class="bottom_box_bottom"> <div class="bottom_box_bottom">
<el-progress :percentage="50" color="rgba(255, 147, 42, 1)" /> <el-progress :percentage="50" color="rgba(255, 147, 42, 1)" />
</div> </div>
<div class="bottom_box_text"> <div class="bottom_box_text">
成本率 {{ period }}
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
const props = defineProps({
title: {
type: String,
default: '收入合同'
},
value: {
type: Number,
default: 205805.17
},
unit: {
type: String,
default: '万元'
},
growthRate: {
type: Number,
default: 3.2
},
period: {
type: String,
}
})
</script> </script>
<style lang="scss"> <style lang="scss">

View File

@ -16,14 +16,19 @@
<img class="top_img" src="@/assets/large/top1.png" alt=""></img> <img class="top_img" src="@/assets/large/top1.png" alt=""></img>
</div> </div>
</div> --> </div> -->
<RevenueContractCard title="收入合同" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="up" <!-- <RevenueContractCard title="收入合同" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="up"
badgeIcon="top1" period="较上月" /> badgeIcon="top1" period="较上月" />
<RevenueContractCard title="支出合同" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="up" <RevenueContractCard title="支出合同" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="up"
badgeIcon="top2" period="较上月" /> badgeIcon="top2" period="较上月" />
<RevenueContractCard title="合同利润" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="down" <RevenueContractCard title="合同利润" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="down"
badgeIcon="top3" period="较上月" /> badgeIcon="top3" period="较上月" />
<RevenueContractCard title="工程变更" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="up" <RevenueContractCard title="工程变更" :value="156234.89" :growthRate="-1.5" trendDirection="up" trendIcon="up"
badgeIcon="top4" period="较上月" /> badgeIcon="top4" period="较上月" /> -->
<RevenueContractCard title="收入合同" :value="bigDataObj.incomeTotalAmount" />
<RevenueContractCard title="支出合同" :value="bigDataObj.expensesTotalAmount" />
<RevenueContractCard title="合同利润" :value="bigDataObj.profitAmount" />
<RevenueContractCard title="工程变更" :value="bigDataObj.changeAmount" unit="%" />
</div> </div>
</div> </div>
<div class="centerPage_map"> <div class="centerPage_map">
@ -44,7 +49,7 @@
成本率 成本率
</div> </div>
</div> --> </div> -->
<bottomboxconpoent> </bottomboxconpoent> <bottomboxconpoent title="材料成本" unit="万元" :value="1"> </bottomboxconpoent>
<bottomboxconpoent> </bottomboxconpoent> <bottomboxconpoent> </bottomboxconpoent>
<bottomboxconpoent> </bottomboxconpoent> <bottomboxconpoent> </bottomboxconpoent>
<bottomboxconpoent> </bottomboxconpoent> <bottomboxconpoent> </bottomboxconpoent>
@ -59,7 +64,16 @@ import * as echarts from 'echarts';
import china from '@/assets/china.json'; import china from '@/assets/china.json';
import RevenueContractCard from './RevenueContractCard.vue'; import RevenueContractCard from './RevenueContractCard.vue';
import bottomboxconpoent from './bottomboxconpoent.vue'; import bottomboxconpoent from './bottomboxconpoent.vue';
const data = ref<any>({}); import { totalAmount } from "@/api/largeScreen/index.js"
const bigDataObj = ref<any>({});
const getTotalAmount = async () => {
const { data: { incomeTotalAmount, expensesTotalAmount, profitAmount, changeAmount } } = await totalAmount()
bigDataObj.value.incomeTotalAmount = incomeTotalAmount || 0;
bigDataObj.value.expensesTotalAmount = expensesTotalAmount || 0;
bigDataObj.value.profitAmount = profitAmount || 0;
bigDataObj.value.changeAmount = changeAmount || 0;
}
// 地图容器引用 // 地图容器引用
const mapRef = ref<HTMLDivElement | null>(null); const mapRef = ref<HTMLDivElement | null>(null);
@ -181,6 +195,7 @@ const initEcharts = () => {
// 组件挂载时初始化 // 组件挂载时初始化
onMounted(() => { onMounted(() => {
getTotalAmount()
// 确保DOM渲染完成 // 确保DOM渲染完成
nextTick(() => { nextTick(() => {
initEcharts(); initEcharts();

View File

@ -907,7 +907,7 @@ export const getBarOptions2 = (data: any) => {
show: false show: false
}, },
data: [ data: [
{ value: 3, name: '100万下' }, { value: 3, name: '100万下' },
{ value: 4, name: '100-500万' }, { value: 4, name: '100-500万' },
{ value: 5, name: '500-1000万' }, { value: 5, name: '500-1000万' },
{ value: 4, name: '1000万以上' }, { value: 4, name: '1000万以上' },

View File

@ -45,38 +45,48 @@ import TitleComponent from './TitleComponent.vue';
import EchartBox from '@/components/EchartBox/index.vue'; import EchartBox from '@/components/EchartBox/index.vue';
import { getLineOption, getBarOptions } from './optionList'; import { getLineOption, getBarOptions } from './optionList';
import ProgressComponent from './ProgressComponent.vue'; import ProgressComponent from './ProgressComponent.vue';
import { monthMoney, monthCash } from '@/api/largeScreen';
const lineOption = ref(); const lineOption = ref();
const barOption = ref(); const barOption = ref();
const getCapitalData = (data?: any) => { const getCapitalData = async () => {
const { data } = await monthMoney()
const month = data.map((item: any) => item.month);
const income = data.map((item: any) => item.incomeAmount);
const expenses = data.map((item: any) => item.expensesAmount);
const profit = data.map((item: any) => item.profitAmount);
// const xData = data.map((item) => item.time); // const xData = data.map((item) => item.time);
// const yData = data.map((item) => item.content); // const yData = data.map((item) => item.content);
const lineData = { const lineData = {
xLabel: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], xLabel: month,
line1: [ line1: [
[100, 200, 150, 300, 250, 350, 400, 350, 450, 500, 400, 550], income,
[220, 250, 230, 280, 270, 300, 350, 320, 380, 400, 450, 500], expenses,
[300, 350, 320, 380, 400, 450, 500, 480, 520, 550, 600, 650] profit
] ]
// line2: ['20', '50', '12', '65', '30', '60'] // line2: ['20', '50', '12', '65', '30', '60']
}; };
lineOption.value = getLineOption(lineData); lineOption.value = getLineOption(lineData);
}; };
const getTurnoverList = (data?: any) => { const getTurnoverList = async () => {
// const xData = data.map((item) => item.time); // const xData = data.map((item) => item.time);
// const yData = data.map((item) => { // const yData = data.map((item) => {
// // 先将content转换为数字再调用toFixed // // 先将content转换为数字再调用toFixed
// const num = Number(item.content); // const num = Number(item.content);
// return isNaN(num) ? 0 : Number(num.toFixed(2)); // return isNaN(num) ? 0 : Number(num.toFixed(2));
// }); // });
const { data } = await monthCash()
const month = data.map((item: any) => item.month);
const income = data.map((item: any) => item.incomeAmount);
const expenses = data.map((item: any) => item.expensesAmount);
// const profit = data.map((item: any) => item.profitAmount);
const barData = { const barData = {
name: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], name: month,
value: [ value: [
[2, 5, 15, 30, 25, 35, 40, 35, 45, 50, 40, 55], income,
[4, 3, 6, 11, 15, 22, 30, 14, 48, 22, 25, 60] expenses
] ]
}; };
barOption.value = getBarOptions(barData); barOption.value = getBarOptions(barData);