Browse Source

add:右侧营收对接完成

zhangyong/milestone-20250913-现金管理
lihui 1 month ago
parent
commit
928fae73a1
  1. 240
      src/components/workspace/CashManagement.vue
  2. 210
      src/components/workspace/CashManagementMarkets.vue

240
src/components/workspace/CashManagement.vue

@ -1,72 +1,199 @@
<template>
<div class="cash-management">
<div class="cash-title">
<div class="text1"> 现金管理
<span class="text1-update-time">最后更新时间{{
workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据'
}}</span>
<div class="text1">
现金管理
<span class="text1-update-time">
最后更新时间{{ workDataUpdateTime || '该地区暂无数据' }}
</span>
<!--
<el-popover
placement="top-start"
title="数据说明"
:width="240"
trigger="hover"
content="此数据实时计算,存在误差,请勿作为最终数据使用。"
>
<template #reference>
<el-icon
class="service-icon"
style="
margin-left: 5px;
cursor: pointer;
font-size: 22px;
transition: all 0.3s ease;
"
>
<Service />
</el-icon>
</template>
</el-popover>
-->
</div>
</div>
<div class="text2"><span class="text2-income">总营收{{ cashData.totalIncome }}</span></div>
<div class="text2">
<span class="text2-income">总营收{{ totalIncome}} 新币</span>
</div>
<div class="chart-container">
<!-- 左侧数据列表 -->
<div class="market-data">
<div v-for="market in cashData.markets" :key="market.name" class="market-item">
<span class="market-name">{{ market.name }}:</span>
<span class="market-value">{{ market.value.toLocaleString() }}新币</span>
<div v-if="marksFlag" v-for="market in cashData.markets" :key="market.name" class="market-item">
<span class="market-name">{{ market.name }}</span>
<span class="market-value">{{ market.value.toLocaleString() }} 新币</span>
</div>
<div v-else>
<div v-for="item in cashData.markets" :key="item.name" class="market-item">
<span class="market-name">代收{{ item.name }}</span>
<span class="market-value">{{ item.value.toLocaleString() }} </span>
</div>
</div>
</div>
<!-- 图表区域 -->
<!-- 图表 -->
<div ref="chartRef" class="chart"></div>
</div>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import {ref, onMounted} from 'vue'
import {onMounted, ref} from 'vue'
import request from "@/util/http.js";
import API from "@/util/http.js";
import {Service} from "@element-plus/icons-vue";
//
const chartRef = ref(null)
let chartInstance = null
//
const cashData = ref({
updateTime: '2025-09-24 12:00:00',
totalIncome: 1200000,
markets: [
{name: '北京', value: 450000},
{name: '上海', value: 300000},
{name: '广州', value: 200000},
{name: '深圳', value: 150000},
{name: '其他', value: 100000}
]
markets: []
})
const chartRef = ref(null)
let chartInstance = null
const markets =ref()
const renderChart = () => {
if (!chartInstance && chartRef.value) {
chartInstance = echarts.init(chartRef.value)
const workDataUpdateTime = ref('')
const totalIncome = ref(0)
//
const currentYear = new Date().getFullYear();
// 00:00:00
const startDate = `${currentYear}-01-01 00:00:00`;
// 23:59:59
const endDate = `${currentYear}-12-31 23:59:59`;
//
const fetchCashData = async () => {
try {
const res = await request({
url: '/workbench/getTotalRevenue',
method: 'POST',
data: {
startDate: startDate,
endDate: endDate
}
})
console.log("jjjjjjj", res.market)
// const data = res
console.log("jjjjjjj", res)
//
console.log("totalIncome", res)
totalIncome.value= res.reduce((sum, item) => {
return sum + (item.totalSGD || 0);
}, 0);
//
if (marksFlag.value) {
markets.value = res.map(item => ({
name: item.market,
value: item.totalSGD ? Number(item.totalSGD) : 0
}))
} else {
// 1.
const currencyMap = {
usd: '美元',
hkd: '港币',
sgd: '新币',
myr: '马币',
thb: '泰铢',
cad: '加币',
vdn: '越南盾',
krw: '韩元'
}
// 2. market totalSGD
const currencyKeys = Object.keys(res[0]).filter(
key => key !== 'market' && key !== 'totalSGD'
)
// 3.
markets.value = currencyKeys.map(currency => {
const total = res.reduce((sum, item) => sum + (Number(item[currency]) || 0), 0)
return {
name: currencyMap[currency.toLowerCase()] || currency.toUpperCase(),
value: total
}
})
}
//
cashData.value.markets = markets.value
console.log("cashData", cashData.value.markets)
// // 使reducemarketsvaluetotalIncome
// totalIncome.value = markets.value.reduce((sum, cur) => sum + cur.value, 0)
// workDataUpdateTime.value = new Date().toLocaleString('zh-CN', { hour12: false })
renderChart()
} catch (err) {
console.error('获取数据失败:', err)
}
}
//
const marksFlag = ref();
const loading = ref(true); //
const getAdminData = async function () {
try {
loading.value = true; //
const result = await API({url: '/admin/userinfo', data: {}});
marksFlag.value = result.markets === '总部' || result.markets === '研发部';
console.log("marksFlag", marksFlag.value);
// alert(marksFlag.value)
} catch (error) {
console.log('请求失败', error);
} finally {
loading.value = false; //
}
};
//
const renderChart = () => {
if (!chartRef.value) return
if (!chartInstance) chartInstance = echarts.init(chartRef.value)
const option = {
tooltip: {trigger: 'item'},
legend: {
bottom: 5, //
bottom: 5,
icon: 'circle',
left: 'center'
},
series: [
{
label: {show: false},
type: 'pie',
radius: ['40%', '70%'],
data: cashData.value.markets,
center: ['60%', '45%'] //
center: ['60%', '45%']
}
]
}
@ -74,17 +201,17 @@ const renderChart = () => {
}
onMounted(() => {
renderChart()
fetchCashData()
getAdminData()
})
</script>
<style scoped>
/* 背景卡片大小 */
/* 保留你原来的样式 */
.cash-management {
margin: 10px 5px;
width: 100%;
height: 550px;
flex-shrink: 0;
border-radius: 8px;
background: #E7F4FD;
box-shadow: 0 2px 2px 0 #00000040;
@ -93,17 +220,6 @@ onMounted(() => {
align-items: center;
}
/*
.cash-card {
width: 100%;
}
.chart {
width: 100%;
height: 200px;
} */
.cash-title {
width: 100%;
height: 5vh;
@ -120,29 +236,21 @@ onMounted(() => {
color: #040a2d;
font-family: "PingFang SC";
font-size: 28px;
font-style: normal;
font-weight: 900;
line-height: 31.79px;
}
.text1-update-time {
width: 100%;
height: 26px;
flex-shrink: 0;
margin-left: 10px;
color: #040a2d;
font-family: "PingFang SC";
font-size: 20px;
font-style: normal;
font-weight: 700;
line-height: 31.79px;
}
/* 总收入的渐变框 */
.text2 {
margin: 13px;
width: 95%;
height: 48px;
flex-shrink: 0;
border-radius: 8px;
background: linear-gradient(90deg, #E4F0FC 0%, #C1DCF8 50%, #E4F0FC 100%);
box-shadow: 0 2px 2px 0 #00152940;
@ -151,20 +259,12 @@ onMounted(() => {
justify-content: center;
}
/* 总收入字体 */
.text2-income {
width: 215px;
height: 26px;
flex-shrink: 0;
color: #040a2d;
font-family: "PingFang SC";
font-size: 20px;
font-style: normal;
font-weight: 900;
line-height: 31.79px;
}
/* 图表容器 */
.chart-container {
display: flex;
align-items: center;
@ -173,7 +273,6 @@ onMounted(() => {
padding: 10px;
}
/* 左侧数据列表,使用指定的样式 */
.market-data {
display: flex;
width: 180px;
@ -185,27 +284,30 @@ onMounted(() => {
}
.market-item {
margin: 10px 0;
display: flex;
justify-content: space-between;
width: 100%;
font-family: "PingFang SC";
font-size: 16px;
color: #040a2d;
line-height: 1.5;
}
.market-name {
white-space: nowrap;
font-weight: 700;
text-align: left; /* 左边文本左对齐 */
}
.market-value {
font-weight: 500;
text-align: right; /* 右边数字右对齐 */
}
/* 图表样式 */
.chart {
flex: 1;
height: 300px;
margin-top: 10px;
}
</style>

210
src/components/workspace/CashManagementMarkets.vue

@ -1,210 +0,0 @@
<!--各地区的现金管理情况-->
<template>
<div class="cash-management">
<div class="cash-title">
<div class="text1"> 现金管理
<span class="text1-update-time">最后更新时间{{
workDataUpdateTime && workDataUpdateTime !== '1970-01-01 08:00:00' ? workDataUpdateTime : '该地区暂无数据'
}}</span>
</div>
</div>
<div class="text2"><span class="text2-income">总营收{{ cashData.totalIncome }}</span></div>
<div class="chart-container">
<!-- 左侧数据列表 -->
<div class="market-data">
<div v-for="market in cashData.markets" :key="market.name" class="market-item">
<span class="market-name">{{ market.name }}:</span>
<span class="market-value">{{ market.value.toLocaleString() }}</span>
</div>
</div>
<!-- 图表区域 -->
<div ref="chartRef" class="chart"></div>
</div>
</div>
</template>
<script setup>
import * as echarts from 'echarts'
import {ref, onMounted} from 'vue'
//
const cashData = ref({
updateTime: '2025-09-24 12:00:00',
totalIncome: 1200000,
markets: [
{name: '北京', value: 450000},
{name: '上海', value: 300000},
{name: '广州', value: 200000},
{name: '深圳', value: 150000},
{name: '其他', value: 100000}
]
})
const chartRef = ref(null)
let chartInstance = null
const renderChart = () => {
if (!chartInstance && chartRef.value) {
chartInstance = echarts.init(chartRef.value)
}
const option = {
tooltip: {trigger: 'item'},
legend: {
bottom: 5, //
left: 'center'
},
series: [
{
label: {show: false},
type: 'pie',
radius: ['40%', '70%'],
data: cashData.value.markets,
center: ['60%', '45%'] //
}
]
}
chartInstance.setOption(option)
}
onMounted(() => {
renderChart()
})
</script>
<style scoped>
/* 背景卡片大小 */
.cash-management {
margin: 10px 5px;
width: 100%;
height: 50vh;
flex-shrink: 0;
border-radius: 8px;
background: #E7F4FD;
box-shadow: 0 2px 2px 0 #00000040;
display: flex;
flex-direction: column;
align-items: center;
}
/*
.cash-card {
width: 100%;
}
.chart {
width: 100%;
height: 200px;
} */
.cash-title {
width: 100%;
height: 5vh;
flex-shrink: 0;
border-radius: 8px;
background: linear-gradient(90deg, #E4F0FC 0%, #C6ADFF 50%, #E4F0FC 100%);
box-shadow: 0 2px 2px 0 #00152940;
display: flex;
align-items: center;
justify-content: center;
}
.text1 {
color: #040a2d;
font-family: "PingFang SC";
font-size: 28px;
font-style: normal;
font-weight: 900;
line-height: 31.79px;
}
.text1-update-time {
width: 100%;
height: 26px;
flex-shrink: 0;
color: #040a2d;
font-family: "PingFang SC";
font-size: 20px;
font-style: normal;
font-weight: 700;
line-height: 31.79px;
}
/* 总收入的渐变框 */
.text2 {
margin: 13px;
width: 95%;
height: 48px;
flex-shrink: 0;
border-radius: 8px;
background: linear-gradient(90deg, #E4F0FC 0%, #C1DCF8 50%, #E4F0FC 100%);
box-shadow: 0 2px 2px 0 #00152940;
display: flex;
align-items: center;
justify-content: center;
}
/* 总收入字体 */
.text2-income {
width: 215px;
height: 26px;
flex-shrink: 0;
color: #040a2d;
font-family: "PingFang SC";
font-size: 20px;
font-style: normal;
font-weight: 900;
line-height: 31.79px;
}
/* 图表容器 */
.chart-container {
display: flex;
align-items: center;
width: 100%;
height: 100%;
padding: 10px;
}
/* 左侧数据列表,使用您指定的样式 */
.market-data {
display: flex;
width: 179px;
flex-direction: column;
align-items: flex-start;
gap: 12px;
padding: 10px;
margin-left: 80px;
}
.market-item {
display: flex;
justify-content: space-between;
width: 100%;
font-family: "PingFang SC";
font-size: 16px;
color: #040a2d;
}
.market-name {
font-weight: 700;
}
.market-value {
font-weight: 500;
}
/* 图表样式 */
.chart {
flex: 1;
height: 300px;
margin-top: 10px;
}
</style>
Loading…
Cancel
Save