Commit 63a9fe11783fc7d6a31e45b276d2368dfea392be
Merge branch 'master' of http://39.98.150.180/webapp/GreenwayWeb
Showing
4 changed files
with
168 additions
and
130 deletions
admin-web-master/src/api/cereBusinessInfo.js
| ... | ... | @@ -52,3 +52,12 @@ export function getInvestmentStatistics(data) { |
| 52 | 52 | }) |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | +// 招商方案统计 | |
| 56 | +export function getInvestmentPlanStatistics(data) { | |
| 57 | + return request({ | |
| 58 | + url: '/attractInvestmentStatisticsController/getInvestmentPlanStatistics', | |
| 59 | + method: 'post', | |
| 60 | + data | |
| 61 | + }) | |
| 62 | +} | |
| 63 | + | ... | ... |
admin-web-master/src/views/rent/InvestmentAnalysis/index.vue
admin-web-master/src/views/scheme/statistics.vue
| ... | ... | @@ -7,14 +7,14 @@ |
| 7 | 7 | </div> |
| 8 | 8 | <div class="toolbar"> |
| 9 | 9 | <el-form :inline="true" :model="pageindex"> |
| 10 | - <el-form-item label="资源类型"> | |
| 10 | + <!-- <el-form-item label="资源类型"> | |
| 11 | 11 | <el-select placeholder="全部" v-model="pageindex.leaseType" |
| 12 | 12 | style="width: 120px;margin-right: 15px"> |
| 13 | 13 | <el-option label="商铺" value="商铺" /> |
| 14 | 14 | <el-option label="场地" value="场地" /> |
| 15 | 15 | <el-option label="广告位" value="广告位" /> |
| 16 | 16 | </el-select> |
| 17 | - </el-form-item> | |
| 17 | + </el-form-item> --> | |
| 18 | 18 | <el-form-item label="日期"> |
| 19 | 19 | <el-date-picker |
| 20 | 20 | v-model="pageindex.list" |
| ... | ... | @@ -75,7 +75,7 @@ |
| 75 | 75 | |
| 76 | 76 | <script> |
| 77 | 77 | import { |
| 78 | - getInvestmentStatistics | |
| 78 | + getInvestmentPlanStatistics | |
| 79 | 79 | } from '@/api/cereBusinessInfo' |
| 80 | 80 | import * as echarts from 'echarts' |
| 81 | 81 | export default { |
| ... | ... | @@ -129,56 +129,42 @@ |
| 129 | 129 | const chartDom = this.$refs.shop2TJ |
| 130 | 130 | // 初始化 ECharts 实例 |
| 131 | 131 | const myChart = echarts.init(chartDom); |
| 132 | - // 模拟数据 | |
| 133 | - const shopCount = 50; | |
| 134 | - const adCount = 30; | |
| 135 | - const venueCount = 20; | |
| 136 | - const totalCount = shopCount + adCount + venueCount; | |
| 132 | + | |
| 137 | 133 | |
| 138 | 134 | const option = { |
| 139 | 135 | tooltip: { |
| 140 | 136 | trigger: 'item', |
| 141 | - formatter: '{a} <br/>{b}: {c} ({d}%)' | |
| 137 | + formatter: function (params) { | |
| 138 | + const dataItem = val.find(item => item.businessPurpose === params.name); | |
| 139 | + return `${params.name}<br/>数量: ${dataItem.num}<br/>占比: ${dataItem.proportion}%`; | |
| 140 | + } | |
| 142 | 141 | }, |
| 143 | 142 | legend: { |
| 144 | 143 | orient: 'horizontal', // 横向展示 |
| 145 | 144 | left: 'center', // 居中显示 |
| 146 | - data: ['商铺', '广告位', '场地'] | |
| 145 | + data: val.map(item => item.businessPurpose) | |
| 147 | 146 | }, |
| 148 | 147 | series: [ |
| 149 | 148 | { |
| 149 | + color: ['#4A90E2', '#37c954','#ff94e8', '#7a69d8','#aaffe7', '#8cd89b','#feff89', '#d8d6d5'], | |
| 150 | 150 | name: '资源分布', |
| 151 | 151 | type: 'pie', |
| 152 | - radius: ['50%', '70%'], | |
| 152 | + radius: ['0%', '60%'], | |
| 153 | 153 | avoidLabelOverlap: false, |
| 154 | 154 | label: { |
| 155 | 155 | show: true, |
| 156 | 156 | position: 'outside', |
| 157 | - formatter: '{b}: {c}' | |
| 157 | + formatter: '{b}: {c}%' | |
| 158 | 158 | }, |
| 159 | 159 | labelLine: { |
| 160 | 160 | show: true |
| 161 | 161 | }, |
| 162 | - data: [ | |
| 163 | - { value: shopCount, name: '商铺' }, | |
| 164 | - { value: adCount, name: '广告位' }, | |
| 165 | - { value: venueCount, name: '场地' } | |
| 166 | - ] | |
| 162 | + data: val.map(item => ({ | |
| 163 | + value: item.proportion, | |
| 164 | + name: item.businessPurpose | |
| 165 | + })) | |
| 167 | 166 | }, |
| 168 | - { | |
| 169 | - name: '总量', | |
| 170 | - type: 'pie', | |
| 171 | - radius: ['0%', '0%'], // 不显示圆形 | |
| 172 | - label: { | |
| 173 | - show: true, | |
| 174 | - position: 'center', | |
| 175 | - formatter: `总量: ${totalCount}`, | |
| 176 | - fontSize: 20 | |
| 177 | - }, | |
| 178 | - data: [ | |
| 179 | - { value: totalCount, name: '总量' } | |
| 180 | - ] | |
| 181 | - } | |
| 167 | + | |
| 182 | 168 | ] |
| 183 | 169 | }; |
| 184 | 170 | // 使用刚指定的配置项和数据显示图表 |
| ... | ... | @@ -191,25 +177,38 @@ |
| 191 | 177 | |
| 192 | 178 | const chartDom = this.$refs.shop1ZX; |
| 193 | 179 | const myChart = echarts.init(chartDom) |
| 194 | - | |
| 195 | - // 模拟数据 | |
| 196 | - const shopCount = 50; | |
| 197 | - const adCount = 30; | |
| 198 | - const venueCount = 20; | |
| 199 | - const totalCount = shopCount + adCount + venueCount; | |
| 180 | + let shopCount = 0; | |
| 181 | + let adCount = 0; | |
| 182 | + let venueCount = 0; | |
| 183 | + let totalCount = 0; | |
| 184 | + val.forEach(item => { | |
| 185 | + totalCount += item.num; | |
| 186 | + if (item.businessPurpose === '商铺合同') { | |
| 187 | + shopCount = item.proportion; | |
| 188 | + } else if (item.businessPurpose === '场地合同') { | |
| 189 | + venueCount = item.proportion; | |
| 190 | + } else if (item.businessPurpose === '广告位合同') { | |
| 191 | + adCount = item.proportion; | |
| 192 | + } | |
| 193 | + }); | |
| 200 | 194 | |
| 201 | 195 | const option = { |
| 202 | 196 | tooltip: { |
| 203 | 197 | trigger: 'item', |
| 204 | - formatter: '{a} <br/>{b}: {c} ({d}%)' | |
| 198 | + formatter: function (params) { | |
| 199 | + const dataItem = val.find(item => item.businessPurpose === params.name); | |
| 200 | + return `${params.name}<br/>数量: ${dataItem.num}<br/>占比: ${dataItem.proportion}%`; | |
| 201 | + } | |
| 205 | 202 | }, |
| 206 | 203 | legend: { |
| 207 | - orient: 'horizontal', // 横向展示 | |
| 208 | - left: 'center', // 居中显示 | |
| 209 | - data: ['商铺', '广告位', '场地'] | |
| 204 | + orient: 'horizontal', | |
| 205 | + left: 'center', | |
| 206 | + data: val.map(item => item.businessPurpose) | |
| 210 | 207 | }, |
| 211 | 208 | series: [ |
| 209 | + | |
| 212 | 210 | { |
| 211 | + color: ['#4A90E2', '#37c954','#ff94e8', '#7a69d8','#aaffe7', '#8cd89b','#feff89', '#d8d6d5'], | |
| 213 | 212 | name: '资源分布', |
| 214 | 213 | type: 'pie', |
| 215 | 214 | radius: ['50%', '70%'], |
| ... | ... | @@ -217,30 +216,27 @@ |
| 217 | 216 | label: { |
| 218 | 217 | show: true, |
| 219 | 218 | position: 'outside', |
| 220 | - formatter: '{b}: {c}' | |
| 219 | + formatter: '{b}: {c}%' | |
| 221 | 220 | }, |
| 222 | 221 | labelLine: { |
| 223 | 222 | show: true |
| 224 | 223 | }, |
| 225 | - data: [ | |
| 226 | - { value: shopCount, name: '商铺' }, | |
| 227 | - { value: adCount, name: '广告位' }, | |
| 228 | - { value: venueCount, name: '场地' } | |
| 229 | - ] | |
| 224 | + data: val.map(item => ({ | |
| 225 | + value: item.proportion, | |
| 226 | + name: item.businessPurpose | |
| 227 | + })) | |
| 230 | 228 | }, |
| 231 | 229 | { |
| 232 | - name: '总量', | |
| 233 | - type: 'pie', | |
| 234 | - radius: ['0%', '0%'], // 不显示圆形 | |
| 235 | - label: { | |
| 236 | - show: true, | |
| 237 | - position: 'center', | |
| 238 | - formatter: `总量: ${totalCount}`, | |
| 239 | - fontSize: 20 | |
| 240 | - }, | |
| 241 | - data: [ | |
| 242 | - { value: totalCount, name: '总量' } | |
| 243 | - ] | |
| 230 | + name: '总数', | |
| 231 | + type: 'pie', | |
| 232 | + radius: ['0%', '0%'], | |
| 233 | + label: { | |
| 234 | + show: true, | |
| 235 | + position: 'center', | |
| 236 | + formatter: `总数: ${totalCount}`, | |
| 237 | + fontSize: 20 | |
| 238 | + }, | |
| 239 | + data: [{ value: totalCount, name: '总数' }] | |
| 244 | 240 | } |
| 245 | 241 | ] |
| 246 | 242 | }; |
| ... | ... | @@ -251,15 +247,21 @@ |
| 251 | 247 | charDam3(val) { |
| 252 | 248 | let Dom = this.$refs.shop1TJ |
| 253 | 249 | let myChart = echarts.init(Dom) |
| 254 | - // val.sort((a, b) => { | |
| 255 | - // return new Date(a.mouth) - new Date(b.mouth); | |
| 256 | - // }); | |
| 257 | - // const months = val.map(item => item.mouth); | |
| 258 | - // const intentMerchants = val.map(item => item.intention); | |
| 259 | - // const signedMerchants = val.map(item => item.signContract); | |
| 260 | - // 模拟月度签约数据 | |
| 261 | - const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']; | |
| 262 | - const contractCounts = [12, 15, 20, 18, 22, 25, 28, 30, 26, 24, 21, 23]; | |
| 250 | + // 处理数据 | |
| 251 | + const months = Object.keys(val).reverse(); // 反转月份顺序,最新月份在前 | |
| 252 | + const shopData = []; | |
| 253 | + const venueData = []; | |
| 254 | + const adData = []; | |
| 255 | + | |
| 256 | + months.forEach(month => { | |
| 257 | + const monthData = val[month]; | |
| 258 | + const shop = monthData.find(item => item.contractType === '商铺合同')?.contractCount || 0; | |
| 259 | + const venue = monthData.find(item => item.contractType === '场地合同')?.contractCount || 0; | |
| 260 | + const ad = monthData.find(item => item.contractType === '广告位合同')?.contractCount || 0; | |
| 261 | + shopData.push(shop); | |
| 262 | + venueData.push(venue); | |
| 263 | + adData.push(ad); | |
| 264 | + }); | |
| 263 | 265 | |
| 264 | 266 | const option = { |
| 265 | 267 | tooltip: { |
| ... | ... | @@ -272,33 +274,37 @@ |
| 272 | 274 | }, |
| 273 | 275 | yAxis: { |
| 274 | 276 | type: 'value', |
| 275 | - name: '签约数' | |
| 277 | + name: '合同数量' | |
| 276 | 278 | }, |
| 277 | 279 | series: [ |
| 278 | 280 | { |
| 279 | - name: '签约数', | |
| 281 | + name: '商铺合同', | |
| 280 | 282 | type: 'line', |
| 281 | - data: contractCounts, | |
| 283 | + data: shopData, | |
| 282 | 284 | symbol: 'circle', |
| 283 | - lineStyle: { | |
| 284 | - color: '#4A90E2' | |
| 285 | - }, | |
| 286 | - itemStyle: { | |
| 287 | - color: '#4A90E2' | |
| 288 | - }, | |
| 289 | - areaStyle: { | |
| 290 | - color: new echarts.graphic.LinearGradient( | |
| 291 | - 0, 0, 0, 1, | |
| 292 | - [ | |
| 293 | - { offset: 0, color: 'rgba(74, 144, 226, 0.3)' }, | |
| 294 | - { offset: 1, color: 'rgba(74, 144, 226, 0.1)' } | |
| 295 | - ] | |
| 296 | - ) | |
| 297 | - } | |
| 285 | + lineStyle: { color: '#4A90E2' }, | |
| 286 | + itemStyle: { color: '#4A90E2' } | |
| 287 | + }, | |
| 288 | + { | |
| 289 | + name: '场地合同', | |
| 290 | + type: 'line', | |
| 291 | + data: venueData, | |
| 292 | + symbol: 'square', | |
| 293 | + lineStyle: { color: '#52C41A' }, | |
| 294 | + itemStyle: { color: '#52C41A' } | |
| 295 | + }, | |
| 296 | + { | |
| 297 | + name: '广告位合同', | |
| 298 | + type: 'line', | |
| 299 | + data: adData, | |
| 300 | + symbol: 'triangle', | |
| 301 | + lineStyle: { color: '#FF7800' }, | |
| 302 | + itemStyle: { color: '#FF7800' } | |
| 298 | 303 | } |
| 299 | 304 | ] |
| 300 | 305 | }; |
| 301 | 306 | |
| 307 | + | |
| 302 | 308 | option && myChart.setOption(option); |
| 303 | 309 | window.addEventListener('resize', function() { |
| 304 | 310 | myChart.resize(); |
| ... | ... | @@ -313,48 +319,72 @@ |
| 313 | 319 | const myChart = echarts.init(chartDom); |
| 314 | 320 | |
| 315 | 321 | |
| 316 | - // 模拟租金价格数据,这里假设是按月份统计 | |
| 317 | - const months = ['1月', '2月', '3月', '4月', '5月', '6月']; | |
| 318 | - const rentPrices = [50, 52, 55, 53, 56, 58]; | |
| 319 | - | |
| 320 | - const option = { | |
| 321 | - tooltip: { | |
| 322 | - trigger: 'axis' | |
| 323 | - }, | |
| 324 | - xAxis: { | |
| 325 | - type: 'category', | |
| 326 | - data: months, | |
| 327 | - boundaryGap: false | |
| 328 | - }, | |
| 329 | - yAxis: { | |
| 330 | - type: 'value', | |
| 331 | - name: '租金价格(元/m²)' | |
| 332 | - }, | |
| 333 | - series: [ | |
| 334 | - { | |
| 322 | + const allDates = []; | |
| 323 | + const leaseTerms = ['季', '年', '日', '月']; | |
| 324 | + const seriesData = { | |
| 325 | + '季': [], | |
| 326 | + '年': [], | |
| 327 | + '日': [], | |
| 328 | + '月': [] | |
| 329 | + }; | |
| 330 | + | |
| 331 | + // 收集所有日期 | |
| 332 | + leaseTerms.forEach(term => { | |
| 333 | + val[term].forEach(item => { | |
| 334 | + if (!allDates.includes(item.createDay)) { | |
| 335 | + allDates.push(item.createDay); | |
| 336 | + } | |
| 337 | + }); | |
| 338 | + }); | |
| 339 | + | |
| 340 | + // 按日期排序 | |
| 341 | + allDates.sort(); | |
| 342 | + | |
| 343 | + // 填充各租赁期限的数据 | |
| 344 | + leaseTerms.forEach(term => { | |
| 345 | + allDates.forEach(date => { | |
| 346 | + const found = val[term].find(item => item.createDay === date); | |
| 347 | + seriesData[term].push(found ? found.rentalPrice : null); | |
| 348 | + }); | |
| 349 | + }); | |
| 350 | + | |
| 351 | + const option = { | |
| 352 | + tooltip: { | |
| 353 | + trigger: 'axis', | |
| 354 | + axisPointer: { | |
| 355 | + type: 'cross', | |
| 356 | + crossStyle: { | |
| 357 | + color: '#999' | |
| 358 | + } | |
| 359 | + } | |
| 360 | + }, | |
| 361 | + legend: { | |
| 362 | + data: leaseTerms | |
| 363 | + }, | |
| 364 | + xAxis: { | |
| 365 | + type: 'category', | |
| 366 | + data: allDates | |
| 367 | + }, | |
| 368 | + yAxis: { | |
| 369 | + type: 'value', | |
| 335 | 370 | name: '租金价格', |
| 371 | + axisLabel: { | |
| 372 | + formatter: '{value}' | |
| 373 | + } | |
| 374 | + }, | |
| 375 | + series: leaseTerms.map(term => ({ | |
| 376 | + name: term, | |
| 336 | 377 | type: 'line', |
| 337 | - data: rentPrices, | |
| 378 | + data: seriesData[term], | |
| 338 | 379 | symbol: 'circle', |
| 339 | - lineStyle: { | |
| 340 | - color: '#4A90E2' | |
| 380 | + label: { | |
| 381 | + show: false | |
| 341 | 382 | }, |
| 342 | - itemStyle: { | |
| 343 | - color: '#4A90E2' | |
| 344 | - }, | |
| 345 | - areaStyle: { | |
| 346 | - color: new echarts.graphic.LinearGradient( | |
| 347 | - 0, 0, 0, 1, | |
| 348 | - [ | |
| 349 | - { offset: 0, color: 'rgba(74, 144, 226, 0.3)' }, | |
| 350 | - { offset: 1, color: 'rgba(74, 144, 226, 0.1)' } | |
| 351 | - ] | |
| 352 | - ) | |
| 383 | + lineStyle: { | |
| 384 | + width: 2 | |
| 353 | 385 | } |
| 354 | - } | |
| 355 | - ] | |
| 356 | - }; | |
| 357 | - | |
| 386 | + })) | |
| 387 | + }; | |
| 358 | 388 | // 使用刚指定的配置项和数据显示图表 |
| 359 | 389 | option && myChart.setOption(option) |
| 360 | 390 | window.addEventListener('resize', function() { |
| ... | ... | @@ -364,11 +394,11 @@ |
| 364 | 394 | }, |
| 365 | 395 | |
| 366 | 396 | async getAll() { |
| 367 | - const res = await getInvestmentStatistics(this.pageindex) | |
| 368 | - this.charDam3() | |
| 369 | - this.charDam1() | |
| 370 | - this.charDam() | |
| 371 | - this.charDam5() | |
| 397 | + const res = await getInvestmentPlanStatistics(this.pageindex) | |
| 398 | + this.charDam3(res.data.monthlyContractVOList) | |
| 399 | + this.charDam1(res.data.resourceUsageRatioVOList) | |
| 400 | + this.charDam(res.data.businessTypeProportionList) | |
| 401 | + this.charDam5(res.data.rentTrendMap) | |
| 372 | 402 | |
| 373 | 403 | }, |
| 374 | 404 | ... | ... |
lvdao-miniapp/pagesA/rentPay/rentPayDetails.vue
| ... | ... | @@ -138,7 +138,6 @@ |
| 138 | 138 | }, |
| 139 | 139 | confirm(e) { |
| 140 | 140 | this.pageIndex.time = e.year |
| 141 | - | |
| 142 | 141 | const { |
| 143 | 142 | firstDay, |
| 144 | 143 | lastDay |
| ... | ... | @@ -150,7 +149,6 @@ |
| 150 | 149 | }, 1).then(res => { |
| 151 | 150 | console.log(res) |
| 152 | 151 | if (res.data.data.length > 0) { |
| 153 | - | |
| 154 | 152 | this.getAll(res.data.data[0].cerePropertyOrderList) |
| 155 | 153 | } else { |
| 156 | 154 | this.dataList = [] | ... | ... |