From 658107c8a09e2ef74bab1ad7114eeaf367848a25 Mon Sep 17 00:00:00 2001
From: MrShi <1878285526@qq.com>
Date: 星期一, 06 七月 2026 18:14:16 +0800
Subject: [PATCH] Merge branch '3.0.1' of http://139.186.142.91:10010/r/productDev/parkBike into 3.0.1
---
bicycle/pages/businessOverview/businessOverview.vue | 554 +++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 436 insertions(+), 118 deletions(-)
diff --git a/bicycle/pages/businessOverview/businessOverview.vue b/bicycle/pages/businessOverview/businessOverview.vue
index 337cd5b..d670893 100644
--- a/bicycle/pages/businessOverview/businessOverview.vue
+++ b/bicycle/pages/businessOverview/businessOverview.vue
@@ -4,28 +4,28 @@
<view class="yy_cate_item" style="margin-bottom: 40rpx;">
<image src="/static/images/ic_users@2x.png" mode="widthFix"></image>
<view class="yy_cate_item_info">
- <text>329</text>
+ <text>{{ overviewInfo.totalMembers || 0 }}</text>
<text>鎬绘敞鍐岀敤鎴�</text>
</view>
</view>
<view class="yy_cate_item" style="margin-bottom: 40rpx;">
<image src="/static/images/ic_newuser@2x.png" mode="widthFix"></image>
<view class="yy_cate_item_info">
- <text>143</text>
+ <text>{{ overviewInfo.todayMembers || 0 }}</text>
<text>浠婃棩鏂板鐢ㄦ埛</text>
</view>
</view>
<view class="yy_cate_item">
<image src="/static/images/ic_bike@2x.png" mode="widthFix"></image>
<view class="yy_cate_item_info">
- <text>700</text>
+ <text>{{ overviewInfo.bikeCount || 0 }}</text>
<text>鑷杞︽暟閲�</text>
</view>
</view>
<view class="yy_cate_item">
<image src="/static/images/ic_ebike@2x.png" mode="widthFix"></image>
<view class="yy_cate_item_info">
- <text>12839.23</text>
+ <text>{{ overviewInfo.eleBikeCount || 0 }}</text>
<text>鐢靛姩杞︽暟閲�</text>
</view>
</view>
@@ -38,28 +38,45 @@
<text>鏀跺叆缁熻</text>
</view>
<view class="right">
- <view class="right_item active">杩�7澶�</view>
- <view class="right_item">杩�15澶�</view>
- <view class="right_item">杩�30澶�</view>
- <view class="right_item">鑷畾涔�</view>
+ <view v-for="item in incomeDateOptions" :key="item.value"
+ :class="incomeDateType === item.value ? 'right_item active' : 'right_item'"
+ @click="changeIncomeDateType(item.value)">
+ {{ item.label }}
+ </view>
</view>
+ </view>
+ <view v-if="incomeDateType === 4" class="custom-date-row">
+ <picker mode="date" style="flex: 1;" :value="incomeStartDate" @change="onIncomeStartDateChange">
+ <view class="custom-date-picker" :style="{ color: incomeStartDate ? '' : '#999999' }">{{ incomeStartDate || '寮�濮嬫棩鏈�' }}</view>
+ </picker>
+ <view class="custom-date-separator">鑷�</view>
+ <picker mode="date" style="flex: 1;" :value="incomeEndDate" @change="onIncomeEndDateChange">
+ <view class="custom-date-picker" :style="{ color: incomeEndDate ? '' : '#999999' }">{{ incomeEndDate || '缁撴潫鏃ユ湡' }}</view>
+ </picker>
</view>
<view class="content">
<view class="content_title">绱鏀跺叆(鍏�)锛�</view>
<view class="content_info">
- <view class="content_info_a">34500.00</view>
+ <view class="content_info_a">{{ formatAmount(incomeInfo.totalIncome) }}</view>
<view class="content_info_b">
<view class="content_info_b_label">鍚屾瘮</view>
- <view class="content_info_b_val">3.12%</view>
+ <view class="content_info_b_val">
+ {{ incomeInfo.yearOnYearRate }}%
+ <image :src="incomeInfo.yearOnYearRate > 0 ? '/static/icon/ic_up@2x.png' : '/static/icon/ic_down@2x.png'" mode="widthFix"></image>
+ </view>
</view>
<view class="content_info_b">
<view class="content_info_b_label">鐜瘮</view>
- <view class="content_info_b_val">11.12%</view>
+ <view class="content_info_b_val">
+ {{ incomeInfo.chainRate }}%
+ <image :src="incomeInfo.chainRate > 0 ? '/static/icon/ic_up@2x.png' : '/static/icon/ic_down@2x.png'" mode="widthFix"></image>
+ </view>
</view>
</view>
</view>
<view class="chart">
- <qiun-data-charts canvasId="incomeColumnChart" type="column" :opts="chart1Opts" :chartData="chart1Data" />
+ <qiun-data-charts :key="incomeChartKey" :ontouch="true" canvasId="incomeColumnChart" type="column" :opts="chart1Opts"
+ :chartData="chart1Data" />
</view>
</view>
<view class="box_xian"></view>
@@ -70,14 +87,29 @@
<text>鏀跺叆杞﹀瀷鍒嗘瀽</text>
</view>
<view class="right">
- <view class="right_item active">杩�7澶�</view>
- <view class="right_item">杩�15澶�</view>
- <view class="right_item">杩�30澶�</view>
- <view class="right_item">鑷畾涔�</view>
+ <view v-for="item in bikeIncomeDateOptions" :key="item.value"
+ :class="bikeIncomeDateType === item.value ? 'right_item active' : 'right_item'"
+ @click="changeBikeIncomeDateType(item.value)">
+ {{ item.label }}
+ </view>
</view>
</view>
+ <view v-if="bikeIncomeDateType === 4" class="custom-date-row">
+ <picker mode="date" style="flex: 1;" :value="bikeIncomeStartDate" @change="onBikeIncomeStartDateChange">
+ <view class="custom-date-picker" :style="{ color: bikeIncomeStartDate ? '' : '#999999' }">{{ bikeIncomeStartDate || '寮�濮嬫棩鏈�' }}</view>
+ </picker>
+ <view class="custom-date-separator">鑷�</view>
+ <picker mode="date" style="flex: 1;" :value="bikeIncomeEndDate" @change="onBikeIncomeEndDateChange">
+ <view class="custom-date-picker" :style="{ color: bikeIncomeEndDate ? '' : '#999999' }">{{ bikeIncomeEndDate || '缁撴潫鏃ユ湡' }}</view>
+ </picker>
+ </view>
<view class="chart1">
- <qiun-data-charts canvasId="vehicleRingChart" type="ring" :opts="vehicleChartOpts" :chartData="vehicleChartData" />
+ <qiun-data-charts :key="vehicleChartKey" canvasId="vehicleRingChart" type="ring" :opts="vehicleChartOpts"
+ :chartData="vehicleChartData" />
+ <view class="ring-center">
+ <view class="ring-center__label">杞﹁締鎬绘暟</view>
+ <view class="ring-center__value">{{ totalVehicleCount }}</view>
+ </view>
</view>
<view class="table">
<view class="table_head">
@@ -85,44 +117,109 @@
<view class="table_head_row">杞﹁締鏀跺叆(鍏�)</view>
<view class="table_head_row">鍗犳瘮(%)</view>
</view>
- <view class="table_content">
- <view class="table_content_row">鍗曚汉鑷杞�</view>
- <view class="table_content_row">8393.45</view>
- <view class="table_content_row">30.00</view>
+ <view class="table_content" v-for="item in vehicleSummary" :key="item.paramId">
+ <view class="table_content_row">{{ item.paramName }}</view>
+ <view class="table_content_row">{{ formatAmount(item.income) }}</view>
+ <view class="table_content_row">{{ item.percent }}</view>
</view>
- <view class="table_content">
- <view class="table_content_row">鍗曚汉鑷杞�</view>
- <view class="table_content_row">8393.45</view>
- <view class="table_content_row">30.00</view>
- </view>
+ <view class="table_empty" v-if="!vehicleSummary.length">鏆傛棤鏀跺叆杞﹀瀷鍒嗘瀽鏁版嵁</view>
</view>
</view>
</view>
</template>
<script>
- export default {
- computed: {
- totalVehicleCount() {
- return this.vehicleChartData.series[0].data.reduce((sum, item) => sum + item.value, 0)
+ const defaultIncomeChartData = {
+ categories: [],
+ series: [{
+ name: '鏀跺叆',
+ data: [],
+ color: '#01B6AD',
+ textColor: '#01B6AD',
+ textSize: 11
+ }]
+ }
+
+ export default {
+ computed: {
+ incomeChartKey() {
+ return `income-column-${this.incomeDateType}-${this.incomeStartDate || ''}-${this.incomeEndDate || ''}-${this.chart1Data.categories.join('_')}-${this.incomeInfo.dailyList.map(item => `${item.date || ''}-${item.income || 0}`).join('_')}`
+ },
+ vehicleChartKey() {
+ return `vehicle-ring-${this.bikeIncomeDateType}-${this.bikeIncomeStartDate || ''}-${this.bikeIncomeEndDate || ''}-${this.vehicleSummary.map(item => `${item.paramId}-${item.income}`).join('_')}`
+ },
+ totalVehicleCount() {
+ return this.vehicleSummary.reduce((sum, item) => sum + Number(item.bikeCount || 0), 0)
+ },
+ incomeChartItemCount() {
+ if (this.incomeDateType === 1) {
+ return 7
+ }
+
+ if (this.incomeDateType === 2) {
+ return 8
+ }
+
+ if (this.incomeDateType === 3) {
+ return 10
+ }
+
+ return 7
+ },
+ incomeRangeText() {
+ if (this.incomeDateType === 4) {
+ if (this.incomeStartDate && this.incomeEndDate) {
+ return `${this.incomeStartDate} 鑷� ${this.incomeEndDate}`
+ }
+
+ return '璇烽�夋嫨鏃ユ湡鑼冨洿'
+ }
+
+ const current = this.incomeDateOptions.find(item => item.value === this.incomeDateType)
+ return current ? current.label : '-'
}
},
data() {
return {
+ overviewInfo: {
+ bikeCount: 0,
+ eleBikeCount: 0,
+ todayMembers: 0,
+ totalMembers: 0
+ },
+ incomeDateType: 1,
+ incomeDateOptions: [{
+ label: '杩�7澶�',
+ value: 1
+ },
+ {
+ label: '杩�15澶�',
+ value: 2
+ },
+ {
+ label: '杩�30澶�',
+ value: 3
+ },
+ {
+ label: '鑷畾涔�',
+ value: 4
+ }
+ ],
+ incomeStartDate: '',
+ incomeEndDate: '',
+ incomeInfo: {
+ totalIncome: 0,
+ chainRate: 0,
+ yearOnYearRate: 0,
+ dailyList: []
+ },
chart1Data: {
- categories: ['鍙屾帓杞�', '鍗曚汉杞�', '浜插瓙杞�', '灞卞湴杞�', '鍔╁姏杞�'],
- series: [{
- name: '鏀跺叆',
- data: [8.5, 6.8, 5.2, 3.9, 2.6],
- color: '#01B6AD',
- textColor: '#01B6AD',
- textSize: 11
- }]
+ ...defaultIncomeChartData
},
chart1Opts: {
color: ['#01B6AD'],
padding: [36, 20, 12, 18],
- enableScroll: false,
+ enableScroll: true,
fontSize: 12,
fontColor: '#999999',
dataLabel: true,
@@ -132,7 +229,11 @@
xAxis: {
disableGrid: true,
fontColor: '#666666',
- marginTop: 10
+ marginTop: 10,
+ scrollShow: true,
+ itemCount: 7,
+ rotateLabel: true,
+ rotateAngle: 35
},
yAxis: {
showTitle: true,
@@ -141,7 +242,7 @@
gridColor: '#E8EEF2',
data: [{
min: 0,
- title: '鏀跺叆(涓囧厓)',
+ title: '鏀跺叆(鍏�)',
titleFontColor: '#666666',
titleFontSize: 12,
titleOffsetY: -4
@@ -152,50 +253,28 @@
type: 'group',
width: 20,
labelPosition: 'top'
- }
+ },
+ scrollPosition: 'right'
}
},
vehicleChartData: {
series: [{
- data: [{
- name: '鍗曚汉鑷杞�',
- value: 700,
- color: '#11D5CF'
- }, {
- name: '鍗曚汉浜插瓙杞�',
- value: 12839,
- color: '#3183FF'
- }, {
- name: '鍓嶅悗鍙屼汉杞�',
- value: 12839,
- color: '#FFD369'
- }, {
- name: '鍙屼汉浜插瓙杞�',
- value: 12839,
- color: '#FE8F52'
- }, {
- name: '鍗曟帓瀹跺涵杞�',
- value: 12839,
- color: '#F24679'
- }, {
- name: '鍙屾帓鍥涗汉杞�',
- value: 12839,
- color: '#F377B5'
- }, {
- name: '鍙屾帓涓夊骇鐢靛姩浠f杞�',
- value: 12839,
- color: '#DB77F3'
- }, {
- name: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
- value: 12839,
- color: '#8477F3'
- }]
+ data: []
}]
},
vehicleChartOpts: {
- // color: ['#01B6AD', '#5ED9D2'],
- padding: [5,5,5,5],
+ padding: [5, 5, 5, 5],
dataLabel: false,
+ title: {
+ name: '',
+ fontSize: 15,
+ color: '#666666'
+ },
+ subtitle: {
+ name: '',
+ fontSize: 25,
+ color: '#7cb5ec'
+ },
legend: {
show: true,
position: 'bottom',
@@ -216,42 +295,239 @@
}
}
},
- vehicleSummary: [
- {
- label: '鍗曚汉鑷杞�',
- value: '700杈�',
- color: '#11D5CF'
- }, {
- label: '鍗曚汉浜插瓙杞�',
- value: '12839杈�',
- color: '#3183FF'
- }, {
- label: '鍓嶅悗鍙屼汉杞�',
- value: '12839杈�',
- color: '#FFD369'
- }, {
- label: '鍙屼汉浜插瓙杞�',
- value: '12839杈�',
- color: '#FE8F52'
- }, {
- label: '鍗曟帓瀹跺涵杞�',
- value: '12839杈�',
- color: '#F24679'
- }, {
- label: '鍙屾帓鍥涗汉杞�',
- value: '12839杈�',
- color: '#F377B5'
- }, {
- label: '鍙屾帓涓夊骇鐢靛姩浠f杞�',
- value: '12839杈�',
- color: '#DB77F3'
- }, {
- label: '鍙屾帓鍥涘骇鐢靛姩浠f杞�',
- value: '12839杈�',
- color: '#8477F3'
- }
- ]
+ bikeIncomeDateType: 1,
+ bikeIncomeDateOptions: [{
+ label: '杩�7澶�',
+ value: 1
+ }, {
+ label: '杩�15澶�',
+ value: 2
+ }, {
+ label: '杩�30澶�',
+ value: 3
+ }, {
+ label: '鑷畾涔�',
+ value: 4
+ }],
+ bikeIncomeStartDate: '',
+ bikeIncomeEndDate: '',
+ bikeIncomeColors: ['#11D5CF', '#3183FF', '#FFD369', '#FE8F52', '#F24679', '#F377B5', '#DB77F3', '#8477F3', '#01B6AD', '#5DBB63'],
+ vehicleSummary: []
};
+ },
+ onLoad() {
+ this.getOverview()
+ this.getIncomeStat()
+ this.getData()
+ },
+ methods: {
+ changeBikeIncomeDateType(value) {
+ this.bikeIncomeDateType = value
+
+ if (value === 4) {
+ this.bikeIncomeStartDate = ''
+ this.bikeIncomeEndDate = ''
+ } else {
+ this.getData()
+ }
+ },
+ onBikeIncomeStartDateChange(event) {
+ this.bikeIncomeStartDate = event.detail.value
+
+ if (this.bikeIncomeStartDate && this.bikeIncomeEndDate) {
+ this.getData()
+ }
+ },
+ onBikeIncomeEndDateChange(event) {
+ this.bikeIncomeEndDate = event.detail.value
+
+ if (this.bikeIncomeStartDate && this.bikeIncomeEndDate) {
+ this.getData()
+ }
+ },
+ buildBikeIncomeChartData(list = []) {
+ return {
+ series: [{
+ data: list.map((item, index) => ({
+ name: item.paramName || item.category || '-',
+ value: Number(item.income || 0),
+ color: this.bikeIncomeColors[index % this.bikeIncomeColors.length]
+ }))
+ }]
+ }
+ },
+ buildBikeIncomeSummary(list = []) {
+ const total = list.reduce((sum, item) => sum + Number(item.income || 0), 0)
+
+ return list.map((item, index) => ({
+ ...item,
+ paramId: item.paramId || `${item.category || 'category'}-${index}`,
+ paramName: item.paramName || item.category || '-',
+ bikeCount: Number(item.bikeCount || 0),
+ income: Number(item.income || 0),
+ percent: total ? ((Number(item.income || 0) / total) * 100).toFixed(2) : '0.00'
+ }))
+ },
+ async getData() {
+ const data = {
+ dateType: this.bikeIncomeDateType
+ }
+
+ if (this.bikeIncomeDateType === 4) {
+ if (!this.bikeIncomeStartDate || !this.bikeIncomeEndDate) {
+ uni.showToast({
+ title: '璇烽�夋嫨寮�濮嬪拰缁撴潫鏃ユ湡',
+ icon: 'none'
+ })
+ return
+ }
+
+ if (this.bikeIncomeStartDate > this.bikeIncomeEndDate) {
+ uni.showToast({
+ title: '寮�濮嬫棩鏈熶笉鑳藉ぇ浜庣粨鏉熸棩鏈�',
+ icon: 'none'
+ })
+ return
+ }
+
+ data.startDate = `${this.bikeIncomeStartDate} 00:00:00`
+ data.endDate = `${this.bikeIncomeEndDate} 23:59:59`
+ }
+ const res = await this.$u.api.bikeIncome(data)
+
+ if (res.code === 200) {
+ const list = res.data || []
+ this.vehicleSummary = this.buildBikeIncomeSummary(list)
+ this.vehicleChartData = this.buildBikeIncomeChartData(this.vehicleSummary)
+ }
+ },
+ formatChartDate(dateText) {
+ if (!dateText) {
+ return ''
+ }
+
+ const text = `${dateText}`
+ const match = text.match(/\d{4}-(\d{2})-(\d{2})/)
+
+ if (match) {
+ return `${match[1]}/${match[2]}`
+ }
+
+ if (text.length >= 10) {
+ return `${text.slice(5, 7)}/${text.slice(8, 10)}`
+ }
+
+ return text
+ },
+ formatDate(date) {
+ const year = date.getFullYear()
+ const month = `${date.getMonth() + 1}`.padStart(2, '0')
+ const day = `${date.getDate()}`.padStart(2, '0')
+
+ return `${year}-${month}-${day}`
+ },
+ formatAmount(value) {
+ if (value === '' || value === null || value === undefined) {
+ return '0'
+ }
+
+ return `${value}`
+ },
+ changeIncomeDateType(value) {
+ this.incomeDateType = value
+
+ if (value === 4) {
+ this.incomeStartDate = ''
+ this.incomeEndDate = ''
+ } else {
+ this.getIncomeStat()
+ }
+ },
+ onIncomeStartDateChange(event) {
+ this.incomeStartDate = event.detail.value
+
+ if (this.incomeStartDate && this.incomeEndDate) {
+ this.getIncomeStat()
+ }
+ },
+ onIncomeEndDateChange(event) {
+ this.incomeEndDate = event.detail.value
+
+ if (this.incomeStartDate && this.incomeEndDate) {
+ this.getIncomeStat()
+ }
+ },
+ buildIncomeChartData(dailyList = []) {
+ return {
+ categories: dailyList.map(item => this.formatChartDate(item.date)),
+ series: [{
+ name: '鏀跺叆',
+ data: dailyList.map(item => Number(item.income || 0)),
+ color: '#01B6AD',
+ textColor: '#01B6AD',
+ textSize: 11
+ }]
+ }
+ },
+ async getOverview() {
+ const res = await this.$u.api.overview()
+
+ if (res.code === 200) {
+ this.overviewInfo = {
+ bikeCount: res.data ? res.data.bikeCount : 0,
+ eleBikeCount: res.data ? res.data.eleBikeCount : 0,
+ todayMembers: res.data ? res.data.todayMembers : 0,
+ totalMembers: res.data ? res.data.totalMembers : 0
+ }
+ }
+ },
+ async getIncomeStat() {
+ const data = {
+ dateType: this.incomeDateType
+ }
+
+ if (this.incomeDateType === 4) {
+ if (!this.incomeStartDate || !this.incomeEndDate) {
+ uni.showToast({
+ title: '璇烽�夋嫨寮�濮嬪拰缁撴潫鏃ユ湡',
+ icon: 'none'
+ })
+ return
+ }
+
+ if (this.incomeStartDate > this.incomeEndDate) {
+ uni.showToast({
+ title: '寮�濮嬫棩鏈熶笉鑳藉ぇ浜庣粨鏉熸棩鏈�',
+ icon: 'none'
+ })
+ return
+ }
+
+ data.startDate = this.incomeStartDate + ' 00:00:00'
+ data.endDate = this.incomeEndDate + ' 23:59:59'
+ }
+ const res = await this.$u.api.incomeStat(data)
+
+ if (res.code === 200) {
+ const incomeInfo = res.data || {}
+ const dailyList = incomeInfo.dailyList || []
+
+ this.incomeInfo = {
+ totalIncome: incomeInfo.totalIncome || 0,
+ chainRate: incomeInfo.chainRate || 0,
+ yearOnYearRate: incomeInfo.yearOnYearRate || 0,
+ dailyList
+ }
+ this.chart1Opts = {
+ ...this.chart1Opts,
+ xAxis: {
+ ...this.chart1Opts.xAxis,
+ itemCount: this.incomeChartItemCount
+ }
+ }
+ this.chart1Data = this.buildIncomeChartData(dailyList)
+ }
+ }
}
}
</script>
@@ -360,6 +636,34 @@
}
}
+ .custom-date-row {
+ width: 100%;
+ margin-top: 20rpx;
+ display: flex;
+ align-items: center;
+ flex-wrap: wrap;
+ }
+
+ .custom-date-picker {
+ flex: 1;
+ text-align: center;
+ height: 64rpx;
+ padding: 0 20rpx;
+ line-height: 64rpx;
+ font-size: 24rpx;
+ color: #333333;
+ background: #F8F9FB;
+ border-radius: 12rpx;
+ box-sizing: border-box;
+ }
+
+ .custom-date-separator {
+ flex-shrink: 0;
+ margin: 0 12rpx;
+ font-size: 24rpx;
+ color: #777777;
+ }
+
.content {
width: 100%;
padding: 24rpx;
@@ -401,6 +705,12 @@
font-weight: bold;
font-size: 26rpx;
color: #222222;
+ display: flex;
+ align-items: center;
+ image {
+ width: 20rpx;
+ height: 20rpx;
+ }
}
}
}
@@ -412,6 +722,7 @@
}
.chart1 {
+ position: relative;
width: 100%;
padding: 24rpx 0 8rpx;
box-sizing: border-box;
@@ -429,7 +740,7 @@
&__label {
font-size: 26rpx;
- color: #666666;
+ color: #6C717A;
line-height: 36rpx;
}
@@ -437,17 +748,24 @@
margin-top: 10rpx;
font-size: 44rpx;
font-weight: 700;
- color: #111111;
+ color: #222222;
line-height: 60rpx;
}
}
}
- .table {
- width: 100%;
- margin-top: 40rpx;
+ .table {
+ width: 100%;
+ margin-top: 40rpx;
- .table_head {
+ .table_empty {
+ padding: 40rpx 0 10rpx;
+ font-size: 26rpx;
+ color: #999999;
+ text-align: center;
+ }
+
+ .table_head {
width: 100%;
height: 80rpx;
display: flex;
--
Gitblit v1.9.3