From 04477a62f8966e9aabc31421bab138960eff323e Mon Sep 17 00:00:00 2001
From: hejianhao <15708179461@qq.com>
Date: 星期三, 26 三月 2025 15:57:29 +0800
Subject: [PATCH] 除地图外所有接口对接、样式调整
---
src/components/LeftPanel.vue | 268 +++++++++++++++++++++++++++++++++++++----------------
1 files changed, 187 insertions(+), 81 deletions(-)
diff --git a/src/components/LeftPanel.vue b/src/components/LeftPanel.vue
index e75b923..edc191b 100644
--- a/src/components/LeftPanel.vue
+++ b/src/components/LeftPanel.vue
@@ -9,13 +9,13 @@
<div class="stat-item">
<div class="stat-info">
<div class="stat-label"> <i class="icon-area"></i> 房屋总面积</div>
- <div class="stat-value">{{ totalArea }}<span class="unit">m²</span></div>
+ <div class="stat-value">{{ staticsData.houseTotalArea }}<span class="unit">m²</span></div>
</div>
</div>
<div class="stat-item">
<div class="stat-info">
<div class="stat-label"> <i class="icon-area"></i>已出租面积</div>
- <div class="stat-value">{{ rentedArea }}<span class="unit">m²</span></div>
+ <div class="stat-value">{{ staticsData.houseRentedArea }}<span class="unit">m²</span></div>
</div>
</div>
</div>
@@ -23,107 +23,147 @@
<div class="stat-group">
<div class="stat-item mt-10">
<div class="stat-info">
- <div class="stat-label"> <i class="icon-money"></i>今日已收租金</div>
- <div class="stat-value">{{ todayRent }}<span class="unit">万元</span></div>
+ <div class="stat-label"> <i class="icon-money"></i>总计应收租金</div>
+ <div class="stat-value">{{ staticsData.totalReceivableRent }}<span class="unit">万元</span></div>
</div>
</div>
<div class="stat-item mt-10">
<div class="stat-info">
- <div class="stat-label"><i class="icon-money"></i>今日已收租金</div>
- <div class="stat-value">{{ todayIncome }}<span class="unit">万元</span></div>
+ <div class="stat-label"><i class="icon-money"></i>总计已收租金</div>
+ <div class="stat-value">{{ staticsData.totalReceivedRent }}<span class="unit">万元</span></div>
</div>
</div>
</div>
</div>
</div>
<div class="chart-card" style="width: 350px;">
- <div class="chart-title">区域租金分析</div>
- <div class="area-chart" ref="areaRentChart"></div>
+ <div class="chart-title">区域租金排名</div>
+ <div class="chart-unit">单位(万元)</div>
+ <div class="rent-rank-list" ref="scrollContainer" @mouseenter="stopScroll" @mouseleave="startScroll">
+ <div class="rank-list-content" ref="scrollContent">
+ <div class="rank-list-group">
+ <div v-for="(item, index) in displayRank" :key="index" class="rent-rank-item">
+ <div class="rank-name">{{ item.streetName }}</div>
+ <div class="rank-progress">
+ <div class="rank-bar">
+ <div class="rank-bar-inner" :style="{
+ width: (item.rentAmount / Math.max(...rentRank.map(i => i.rentAmount)) * 100) + '%',
+ background: getBarColor(item.rentAmount)
+ }"></div>
+ </div>
+ <div class="rank-value">{{ item.rentAmount }}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
</div>
</template>
<script>
-import * as echarts from 'echarts'
-
export default {
name: 'LeftPanel',
+ props: {
+ staticsData: {
+ type: Object,
+ default: () => { }
+ },
+ rentRank: {
+ type: Array,
+ default: () => []
+ }
+ },
data() {
return {
- totalArea: '386.5',
- rentedArea: '316.5',
- todayRent: '316.5',
- todayIncome: '124.5',
- charts: {
- areaRent: null
+ scrollTimer: null,
+ isScrolling: true,
+ currentTranslate: 0,
+ firstItemHeight: 0,
+ animationFrameId: null,
+ lastTimestamp: 0,
+ displayRank: []
+ }
+ },
+ watch: {
+ rentRank: {
+ immediate: true,
+ handler(newVal) {
+ if (newVal && newVal.length) {
+ // 复制两组数据用于无缝滚动
+ this.displayRank = [...newVal, ...newVal];
+ }
}
}
},
mounted() {
this.$nextTick(() => {
- this.initCharts()
- })
+ const firstItem = this.$el.querySelector('.rent-rank-item');
+ if (firstItem) {
+ this.firstItemHeight = firstItem.offsetHeight + 8;
+ }
+ this.startScroll();
+ });
+ },
+ beforeDestroy() {
+ this.clearScrollTimer();
+ if (this.animationFrameId) {
+ cancelAnimationFrame(this.animationFrameId);
+ }
},
methods: {
- initCharts() {
- this.charts.areaRent = echarts.init(this.$refs.areaRentChart)
- this.charts.areaRent.setOption({
- grid: {
- left: '20%',
- right: '5%',
- top: '10%',
- bottom: '10%'
- },
- xAxis: {
- type: 'value',
- axisLine: {
- show: false
- },
- splitLine: {
- show: false
- },
- axisLabel: {
- color: '#fff'
- }
- },
- yAxis: {
- type: 'category',
- data: ['新城大道', '拉萨路', '新城大道', '拉萨路', '新城大道', '新城大道', '拉萨路', '新城大道', '拉萨路', '新城大道'],
- axisLine: {
- lineStyle: {
- color: '#fff'
- }
- },
- axisLabel: {
- color: '#fff'
- }
- },
- series: [{
- type: 'bar',
- data: [1900, 1850, 1800, 1750, 1700, 1600, 1500, 1400, 1300, 1200],
- barWidth: '30%',
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 1,
- y2: 0,
- colorStops: [{
- offset: 0,
- color: '#0ff'
- }, {
- offset: 1,
- color: '#0ff'
- }]
- }
- }
- }]
- })
+ startScroll() {
+ this.isScrolling = true;
+ if (!this.animationFrameId) {
+ this.lastTimestamp = performance.now();
+ this.startAutoScroll();
+ }
+ },
+ stopScroll() {
+ this.isScrolling = false;
+ },
+ clearScrollTimer() {
+ if (this.animationFrameId) {
+ cancelAnimationFrame(this.animationFrameId);
+ this.animationFrameId = null;
+ }
+ },
+ startAutoScroll() {
+ const animate = (timestamp) => {
+ if (!this.isScrolling) {
+ this.lastTimestamp = timestamp;
+ this.animationFrameId = requestAnimationFrame(animate);
+ return;
+ }
- window.addEventListener('resize', () => {
- this.charts.areaRent && this.charts.areaRent.resize()
- })
+ const deltaTime = timestamp - this.lastTimestamp;
+ const speed = 0.03;
+ const step = speed * deltaTime;
+
+ const content = this.$refs.scrollContent;
+ if (!content || !this.firstItemHeight) {
+ this.animationFrameId = requestAnimationFrame(animate);
+ return;
+ }
+
+ this.currentTranslate -= step;
+
+ // 当滚动到第一组数据的末尾时,重置位置到第二组数据的开始
+ const halfHeight = this.firstItemHeight * this.rentRank.length;
+ if (Math.abs(this.currentTranslate) >= halfHeight) {
+ this.currentTranslate = 0;
+ }
+
+ content.style.transform = `translateY(${this.currentTranslate}px)`;
+ this.lastTimestamp = timestamp;
+ this.animationFrameId = requestAnimationFrame(animate);
+ };
+
+ this.animationFrameId = requestAnimationFrame(animate);
+ },
+ getBarColor(value) {
+ if (value == 0) return 'transparent';
+ return '#87F7C7';
}
}
}
@@ -136,7 +176,7 @@
position: fixed;
top: 0;
left: 0;
- height: calc(100vh);
+ height: 100%;
background: linear-gradient(to right, rgba(1, 85, 121, 0.8) 0%, rgba(1, 85, 121, 0.8) 20%, rgba(151, 190, 192, 0));
z-index: 1002;
flex-direction: column;
@@ -177,6 +217,7 @@
display: flex;
align-items: center;
gap: 10px;
+ min-width: 0;
}
.icon-area,
@@ -205,6 +246,10 @@
font-size: 24px;
font-weight: bold;
color: #0ff;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 100%;
}
.unit {
@@ -219,15 +264,76 @@
border-radius: 8px;
padding: 15px;
min-height: 300px;
+ max-height: calc(100vh - 600px);
+ overflow: hidden;
+ margin-bottom: 20px;
}
.chart-title {
font-size: 16px;
- margin-bottom: 15px;
color: #fff;
}
-.area-chart {
- height: calc(100% - 30px);
+.chart-unit {
+ font-size: 12px;
+ margin-bottom: 15px;
}
-</style>
\ No newline at end of file
+
+.rent-rank-list {
+ height: calc(100% - 60px);
+ overflow: hidden;
+ padding: 10px 0;
+ position: relative;
+ max-height: calc(100% - 60px);
+}
+
+.rank-list-content {
+ position: relative;
+ transition: none;
+ transform: translateY(0);
+ will-change: transform;
+}
+
+.rank-list-group {
+ position: relative;
+}
+
+.rent-rank-item {
+ display: flex;
+ flex-direction: column;
+ padding: 8px 0;
+}
+
+.rank-name {
+ color: #fff;
+ font-size: 14px;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.rank-progress {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.rank-bar {
+ flex: 1;
+ height: 8px;
+ background: rgba(255, 255, 255, 0.1);
+ overflow: hidden;
+}
+
+.rank-bar-inner {
+ height: 100%;
+ transition: all 0.3s ease;
+}
+
+.rank-value {
+ color: #fff;
+ font-size: 14px;
+ min-width: 45px;
+ text-align: right;
+}
+</style>
\ No newline at end of file
--
Gitblit v1.7.1