| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032 |
- <template>
- <Layout>
- <template #left>
- <div class="left">
- <Box
- :width="665"
- :height="396"
- :name="'区域分布'"
- style="margin-bottom: 25px;"
- >
- <div class="body">
- <div class="total">
- <img
- src="../../../../assets/img/1-1.png"
- alt=""
- >
- <p>{{ region.total }}</p>
- <div>总量</div>
- </div>
- <Echart :option="region.option" />
- </div>
- </Box>
- <Box
- v-for="item in leftTitle"
- :key="item.name"
- :width="665"
- :height="396"
- :name="item.name"
- style="margin-bottom: 25px;"
- >
- <div class="body">
- <div
- v-if="item.name === '类型分布'"
- class="text"
- >
- 站场总数
- <p>{{ typeTotal }}</p>
- </div>
- <Echart
- v-if="item.option"
- :option="item.option"
- />
- </div>
- </Box>
- <Box
- :width="665"
- :height="396"
- :name="'使用情况'"
- >
- <div class="usage">
- <div
- v-for="item, index in useData"
- :key="index"
- class="list"
- >
- <img
- src="../../../../assets/img/1-1.png"
- alt=""
- >
- <div class="value">
- {{ item.number }}
- </div>
- <p> {{ item.useType }}</p>
- </div>
- </div>
- </Box>
- </div>
- </template>
- <template #right>
- <div class="right">
- <Box
- :width="1340"
- :height="393"
- :name="'运营保障'"
- style="margin-bottom: 23px;"
- >
- <div class="commercial">
- <div
- v-for="item in operateData"
- :key="item.type"
- class="commercial-vehicles"
- >
- <div class="title">
- {{ item.type === 1 ? '营运车' : '非营运车' }}
- </div>
- <div class="top">
- <div class="list">
- <div>{{ item.inNum }} <span>辆/次</span></div>
- <p>进场车次</p>
- </div>
- <div class="list">
- <div>{{ item.outNum }} <span>辆/次</span></div>
- <p>出场车次</p>
- </div>
- <div class="list">
- <div>{{ item.parkingNum }} <span>辆/次</span></div>
- <p>泊车车次</p>
- </div>
- </div>
- <div class="bottom">
- <div class="list">
- <div>{{ item.amParkingNum }} <span>辆/次</span></div>
- <p>凌晨两点泊车</p>
- </div>
- <div class="list">
- <div style="color: #E73D41;">
- {{ item.retentionNum }} <span>辆/次</span>
- </div>
- <p>长期滞留车辆(大于7天)</p>
- </div>
- </div>
- </div>
- </div>
- </Box>
- <div class="chart-box">
- <Box
- :width="665"
- :height="396"
- :name="'充电趋势'"
- >
- <div class="contet">
- <div class="title">
- 充电量\kw.h
- </div>
- <div class="chart">
- <Echart :option="powerChart" />
- </div>
- </div>
- </Box>
- <Box
- :width="665"
- :height="396"
- :name="'机场装机容量'"
- >
- <div class="airport">
- <div class="text">
- 站场总数
- <p>{{ installedCapacityTotal }}</p>
- </div>
- <Echart :option="airportChart" />
- </div>
- </Box>
- </div>
- <div class="chart-box">
- <Box
- :width="665"
- :height="396"
- :name="'充电桩服务情况'"
- >
- <ul class="hd">
- <li
- v-for="item, index in chargingStatus"
- :key="index"
- >
- <img
- src="../../../../assets/img/1-1.png"
- alt=""
- >
- <div class="txt">
- <p>{{ item.number }}</p>
- <div>{{ item.chargingStatus }}</div>
- </div>
- </li>
- </ul>
- <ul class="percentage">
- <li>
- <div class="tt">
- <p>今日充电车次</p>
- <div>
- {{ chargingStatistics.chargingNum }} <span> /{{ chargingStatistics.totalChargingNum }}</span>
- </div>
- </div>
- <n-progress
- type="line"
- :percentage="+(chargingStatistics.chargingNum / chargingStatistics.totalChargingNum * 100).toFixed(2)"
- :show-indicator="false"
- :indicator-placement="'inside'"
- processing
- :stroke-width="15"
- />
- </li>
- <li>
- <div class="tt">
- <p>今日充电电量 kw.h</p>
- <div>
- {{ chargingStatistics.electricityNum }} <span> /{{ chargingStatistics.totalElectricityNum }}</span>
- </div>
- </div>
- <n-progress
- type="line"
- :percentage="+(chargingStatistics.electricityNum / chargingStatistics.totalElectricityNum * 100).toFixed(2)"
- :show-indicator="false"
- :indicator-placement="'inside'"
- processing
- :stroke-width="15"
- />
- </li>
- </ul>
- </Box>
- <Box
- :width="665"
- :height="396"
- :name="'资源使用率'"
- >
- <ul class="btn">
- <li
- v-for="item,key in typeMap"
- :key="key"
- :class="{active:type === key}"
- @click="type = key"
- >
- {{ item }}
- </li>
- </ul>
- <n-data-table
- :columns="columns"
- :data="tableData"
- max-height="200"
- />
- </Box>
- </div>
- </div>
- </template>
- </Layout>
- </template>
- <script setup lang='ts'>
- import Layout from '@/components/layout.vue'
- import Box from '@/components/box.vue'
- import {
- Ref, computed, h, ref
- } from 'vue'
- import Echart from '@/components/chart.vue'
- import StationManagementService from '../services/stationManagement.service'
- const leftTitle: Ref<any[]> = ref([ {
- name: '类型分布',
- option: {
- color: [ 'rgb(86,137,239)', 'rgb(85,206,160)', 'rgb(88,107,141)', 'rgb(234,181,23)' ],
- tooltip: {
- formatter: '{b}: {c}个 ,占比: {d}%'
- },
- legend: {
- orient: 'horizontal',
- bottom: '0',
- icon: 'circle',
- textStyle: {
- color: '#fff',
- fontSize: 16
- }
- },
- series: {
- type: 'pie',
- radius: [ '45%', '60%' ],
- label: {
- show: true,
- color: '#fff',
- formatter: '{b}: {c}个',
- fontSize: 14
- },
- data: [
- { value: 1048, name: '首末班' },
- { value: 735, name: '枢纽站' },
- { value: 580, name: '停车场' },
- { value: 580, name: '保养场' }
- ]
- }
- }
- },
- {
- name: '面积分布',
- option: {
- color: [ 'rgb(86,137,239)', 'rgb(85,206,160)', 'rgb(88,107,141)', 'rgb(234,181,23)' ],
- tooltip: {
- formatter: '{b}: {c}个 ,占比: {d}%'
- },
- legend: {
- orient: 'horizontal',
- bottom: '0',
- icon: 'circle',
- textStyle: {
- color: '#fff',
- fontSize: 16
- }
- },
- series: {
- type: 'pie',
- radius: '70%',
- label: {
- show: true,
- color: '#fff',
- formatter: '{b}: {c}个',
- fontSize: 14
- },
- data: [
- { value: 1048, name: '<=500㎡' },
- { value: 735, name: '500~2000㎡' },
- { value: 580, name: '2000~5000㎡' },
- { value: 580, name: '5000~10000㎡' }
- ]
- }
- }
- },
- {
- name: '场站权属情况',
- option: {
- color: [ 'rgb(86,137,239)', 'rgb(85,206,160)', 'rgb(88,107,141)', 'rgb(234,181,23)' ],
- tooltip: {
- formatter: '{b}: {c}个 ,占比: {d}%'
- },
- legend: {
- orient: 'horizontal',
- bottom: '0',
- icon: 'circle',
- textStyle: {
- color: '#fff',
- fontSize: 16
- }
- },
- series: {
- type: 'pie',
- radius: '70%',
- label: {
- show: true,
- color: '#fff',
- formatter: '{b}: {c}个',
- fontSize: 14
- },
- data: [
- { value: 1048, name: '自有' },
- { value: 735, name: '临时使用' },
- { value: 580, name: '先借后租' },
- { value: 580, name: '租用' }
- ]
- }
- }
- },
- {
- name: '建设时间',
- option: {
- tooltip: {
- trigger: 'axis',
- formatter: '{b} <br/>数量: {c}个',
- axisPointer: {
- type: 'shadow'
- }
- },
- grid: {
- left: '1%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- legend: {
- show: true,
- textStyle: {
- color: '#fff'
- }
- },
- xAxis: {
- type: 'category',
- data: [ '超过十年', '5-7年', '近3年', '3-5年' ],
- axisLabel: {
- color: '#fff',
- fontSize: 16
- },
- axisTick: {
- alignWithLabel: true
- },
- splitLine: {
- show: false
- }
- },
- yAxis: {
- type: 'value',
- axisLabel: {
- color: '#fff'
- },
- splitLine: {
- show: true,
- lineStyle: {
- color: 'rgb(34,43,57)'
- }
- }
- },
- series: {
- name: '数量',
- type: 'bar',
- barMaxWidth: '40',
- itemStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [ {
- offset: 0, color: '#00fdff' // 0% 处的颜色
- }, {
- offset: 1, color: '#00aaff08' // 100% 处的颜色
- } ],
- global: false // 缺省为 false
- }
- },
- data: [ 10, 52, 200, 334, 390, 330, 220 ]
- }
- }
- } ])
- // 区域分布
- const region = ref({
- total: 40,
- option: {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- }
- },
- grid: {
- left: '1%',
- right: '4%',
- bottom: '3%',
- containLabel: true
- },
- legend: {
- show: false,
- textStyle: {
- color: '#fff'
- }
- },
- yAxis: {
- type: 'category',
- data: [ '吊挂式', '独立式', '嵌入式' ],
- axisLabel: {
- color: '#fff',
- fontSize: 16
- },
- axisTick: {
- alignWithLabel: true
- },
- splitLine: {
- show: false
- }
- },
- xAxis: {
- type: 'value',
- axisLabel: {
- color: '#fff'
- },
- splitLine: {
- show: true,
- lineStyle: {
- color: 'rgb(34,43,57)'
- }
- }
- },
- series: {
- name: '客流量',
- type: 'bar',
- barMaxWidth: '40',
- itemStyle: {
- color: 'rgb(86,137,239)',
- borderRadius: [ 0, 20, 20, 0 ]
- },
- label: {
- show: true,
- position: 'inside',
- color: '#fff'
- },
- data: [ 10, 52, 200, 334, 390, 330, 220 ]
- }
- }
- })
- const powerChart = ref({
- grid: {
- left: '3%',
- right: '6%',
- bottom: '20%',
- containLabel: true
- },
- tooltip: {
- trigger: 'axis',
- formatter: '今日{b} <br/>充电量: {c}kw·h'
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- axisLabel: {
- color: '#fff',
- fontSize: 16
- },
- data: [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun' ]
- },
- yAxis: {
- type: 'value',
- splitLine: {
- show: true,
- lineStyle: {
- color: 'rgb(34,43,57)'
- }
- },
- axisLabel: {
- color: '#fff',
- formatter: '{value} kw·h',
- fontSize: 16
- }
- },
- dataZoom: {
- show: true,
- type: 'slider'
- },
- series: {
- data: [ 820, 932, 901, 934, 1290, 1330, 1320 ],
- type: 'line',
- areaStyle: {
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [ {
- offset: 0, color: '#FFD35D ' // 0% 处的颜色
- }, {
- offset: 0.5, color: '#7ec2f3 ' // 100% 处的颜色
- }, {
- offset: 1, color: '#1890ff ' // 100% 处的颜色
- } ],
- global: false // 缺省为 false
- }
- }
- }
- })
- const airportChart = ref({
- color: [ 'rgb(86,137,239)', 'rgb(85,206,160)', 'rgb(88,107,141)', 'rgb(234,181,23)' ],
- tooltip: {
- trigger: 'item',
- formatter: '{b}: {c}个 ,占比: {d}%'
- },
- legend: {
- orient: 'horizontal',
- bottom: '0',
- icon: 'circle',
- textStyle: {
- color: '#fff',
- fontSize: 16
- }
- },
- series: {
- type: 'pie',
- radius: [ '45%', '60%' ],
- label: {
- show: true,
- color: '#fff',
- formatter: '{b}: {c}个',
- fontSize: 14
- },
- data: [
- { value: 1048, name: '<=500m' },
- { value: 735, name: '500~2000' },
- { value: 580, name: '2000~5000' },
- { value: 580, name: '5000~10000' }
- ]
- }
- })
- const originData = ref([ {
- admissionRate: 0,
- stationName: 'xxx'
- } ])
- const type = ref('admissionRate')
- const typeMap = {
- admissionRate: '各场站入场率',
- chargingCapacity: '各充电场站充电量',
- maintenanceNum: '各维保场维修保养车辆数',
- usageRate: '运维驿站使用率'
- }
- const tableData = computed(() => originData.value.map((item:any) => ({
- stationName: item.stationName,
- rate: item[type.value]
- })))
- const columns = [
- {
- title: '序号',
- render: (_: any, rowIndex: number) => h('span', rowIndex + 1)
- },
- {
- title: '场站',
- key: 'stationName'
- },
- {
- title: '入场率',
- key: 'rate'
- } ]
- const stationManagementService = new StationManagementService()
- async function getStationRegion() {
- const res = await stationManagementService.getStationRegion()
- const yData = []
- const seriesData = []
- let total = 0
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- yData.push(item.region)
- seriesData.push(item.passengerFlow)
- total += item.passengerFlow
- }
- region.value.option.yAxis.data = yData
- region.value.option.series.data = seriesData
- region.value.total = total
- }
- getStationRegion()
- const typeTotal = ref(0)
- async function getStationTypes() {
- const res = await stationManagementService.getStationTypes()
- const seriesData = []
- let total = 0
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- seriesData.push({
- name: item.type,
- value: item.number
- })
- total += item.number
- }
- leftTitle.value[0].option.series.data = seriesData
- typeTotal.value = total
- }
- getStationTypes()
- async function getStationArea() {
- const res = await stationManagementService.getStationArea()
- const seriesData = []
- let total = 0
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- seriesData.push({
- name: item.areaType,
- value: item.number
- })
- total += item.number
- }
- leftTitle.value[1].option.series.data = seriesData
- typeTotal.value = total
- }
- getStationArea()
- async function getStationOwnership() {
- const res = await stationManagementService.getStationOwnership()
- const seriesData = []
- let total = 0
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- seriesData.push({
- name: item.ownership,
- value: item.number
- })
- total += item.number
- }
- leftTitle.value[2].option.series.data = seriesData
- typeTotal.value = total
- }
- getStationOwnership()
- async function getStationConstruct() {
- const res = await stationManagementService.getStationConstruct()
- const xData = []
- const seriesData = []
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- xData.push(item.constructSituation)
- seriesData.push(item.number)
- }
- leftTitle.value[3].option.xAxis.data = seriesData
- leftTitle.value[3].option.series.data = seriesData
- }
- getStationConstruct()
- const useData = ref([] as any[])
- async function getStationUse() {
- useData.value = await stationManagementService.getStationUse()
- }
- getStationUse()
- const operateData = ref([] as any[])
- async function getStationOperate() {
- operateData.value = await stationManagementService.getStationOperate()
- }
- getStationOperate()
- async function getStationChargingTrends() {
- const res = await stationManagementService.getStationChargingTrends()
- const xData = []
- const seriesData = []
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- xData.push(item.time.slice(11))
- seriesData.push(item.number)
- }
- powerChart.value.xAxis.data = xData
- powerChart.value.series.data = seriesData
- }
- getStationChargingTrends()
- const installedCapacityTotal = ref(0)
- async function getStationInstalledCapacity() {
- const res = await stationManagementService.getStationInstalledCapacity()
- const seriesData = []
- let total = 0
- for (let i = 0; i < res.length; i++) {
- const item = res[i]
- seriesData.push({
- name: item.type,
- value: item.number
- })
- total += item.number
- }
- airportChart.value.series.data = seriesData
- installedCapacityTotal.value = total
- }
- getStationInstalledCapacity()
- const chargingStatus = ref([
- { chargingStatus: '空闲', number: 0 },
- { chargingStatus: '充满', number: 0 },
- { chargingStatus: '在充', number: 0 },
- { chargingStatus: '故障', number: 0 }
- ])
- async function getStationChargingStatus() {
- const res = await stationManagementService.getStationChargingStatus()
- }
- getStationChargingStatus()
- const chargingStatistics = ref({
- chargingNum: 1,
- totalChargingNum: 2,
- electricityNum: 1,
- totalElectricityNum: 1
- })
- async function getStationChargingStatistics() {
- chargingStatistics.value = await stationManagementService.getStationChargingStatistics()
- }
- getStationChargingStatistics()
- async function getStationResourceRate() {
- originData.value = await stationManagementService.getStationResourceRate()
- }
- getStationResourceRate()
- </script>
- <style lang="scss" scoped>
- .left {
- color: #fff;
- display: flex;
- justify-content: space-between;
- flex-wrap: wrap;
- .usage {
- width: 100%;
- height: 100%;
- display: flex;
- padding: 0 120px;
- justify-content: space-between;
- align-items: center;
- .list {
- text-align: center;
- img {
- width: 80px;
- height: 80px;
- }
- .value {
- color: #00FFFF;
- font-size: 50px;
- }
- p {
- font-size: 24px;
- }
- }
- }
- .body {
- width: 100%;
- height: 100%;
- display: flex;
- position: relative;
- .total {
- width: 136px;
- text-align: center;
- img {
- margin-top: 80px;
- width: 100px;
- height: 100px;
- }
- p {
- font-size: 60px;
- }
- div {
- font-size: 24px;
- }
- }
- .plot {
- flex: 1;
- }
- .text {
- position: absolute;
- left: 42%;
- top: 40%;
- font-size: 28px;
- text-align: center;
- }
- }
- }
- .right {
- width: 1340px;
- color: #fff;
- ul {
- margin: 0;
- padding: 0;
- li {
- list-style: none;
- }
- }
- .commercial {
- display: flex;
- justify-content: space-between;
- .commercial-vehicles {
- width: 49%;
- .title {
- color: #F59A23;
- font-size: 24px;
- line-height: 74px;
- text-indent: 10px;
- }
- .list {
- width: 33.33333%;
- border: 1px solid rgba(0, 255, 255, 0.298);
- height: 137px;
- text-align: center;
- display: flex;
- flex-direction: column;
- justify-content: center;
- div {
- font-size: 50px;
- display: flex;
- align-items: center;
- justify-content: center;
- span {
- font-size: 20px;
- line-height: 50px;
- margin-left: 10px;
- color: #fff;
- }
- }
- p {
- color: #80FFFF;
- }
- }
- .top {
- display: flex;
- }
- .bottom {
- display: flex;
- .list {
- width: 50%;
- }
- }
- }
- }
- .chart-box {
- display: flex;
- justify-content: space-between;
- .airport {
- width: 100%;
- height: 100%;
- position: relative;
- .text {
- position: absolute;
- left: 42%;
- top: 40%;
- font-size: 28px;
- text-align: center;
- }
- }
- .contet {
- width: 100%;
- height: 100%;
- display: flex;
- .title {
- font-size: 16px;
- writing-mode: vertical-lr;
- /* 从上到下排列,默认为从左到右 */
- text-orientation: sideways;
- transform: rotate(180deg);
- text-align: center;
- height: 100%;
- }
- .chart {
- flex: 1;
- }
- }
- .hd {
- display: flex;
- margin-top: 18px;
- li {
- display: flex;
- width: 25%;
- height: 137px;
- border: 1px solid rgba(0, 255, 255, 0.298);
- display: flex;
- justify-content: center;
- align-items: center;
- img {
- width: 40px;
- height: 40px;
- }
- .txt {
- margin-left: 10px;
- p {
- font-size: 26px;
- line-height: 40px;
- }
- div {
- font-size: 18px;
- color: #80FFFF;
- }
- }
- }
- }
- .percentage {
- padding-right: 40px;
- li {
- margin-top: 30px;
- .tt {
- display: flex;
- justify-content: space-between;
- line-height: 40px;
- font-size: 20px;
- margin-bottom: 10px;
- div {
- font-size: 34px;
- color: #80FFFF;
- span {
- font-size: 24px;
- color: #fff;
- }
- }
- }
- }
- }
- .btn {
- display: flex;
- flex-wrap: wrap;
- // justify-content: space-between;
- li {
- line-height: 33px;
- border-radius: 100px;
- border: 1px solid #80FFFF;
- padding: 0 10px;
- margin: 10px;
- font-size: 20px;
- cursor: pointer;
- &.active{
- background: #2f64aa;
- }
- }
- }
- }
- }
- </style>
|