feat:对接景区接口
This commit is contained in:
10
package-lock.json
generated
10
package-lock.json
generated
@@ -14,7 +14,9 @@
|
||||
"element-plus": "^2.9.0",
|
||||
"flv.js": "^1.6.2",
|
||||
"hls.js": "^1.5.18",
|
||||
"mitt": "^3.0.1",
|
||||
"pinia": "^2.2.6",
|
||||
"pubsub-js": "^1.9.5",
|
||||
"vue": "^3.5.13",
|
||||
"vue-countup-v3": "^1.4.2",
|
||||
"vue-echarts": "^7.0.3",
|
||||
@@ -2580,8 +2582,7 @@
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
|
||||
},
|
||||
"node_modules/mlly": {
|
||||
"version": "1.7.3",
|
||||
@@ -2864,6 +2865,11 @@
|
||||
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/pubsub-js": {
|
||||
"version": "1.9.5",
|
||||
"resolved": "https://registry.npmmirror.com/pubsub-js/-/pubsub-js-1.9.5.tgz",
|
||||
"integrity": "sha512-5MZ0I9i5JWVO7SizvOviKvZU2qaBbl2KQX150FAA+fJBwYpwOUId7aNygURWSdPzlsA/xZ/InUKXqBbzM0czTA=="
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
"element-plus": "^2.9.0",
|
||||
"flv.js": "^1.6.2",
|
||||
"hls.js": "^1.5.18",
|
||||
"mitt": "^3.0.1",
|
||||
"pinia": "^2.2.6",
|
||||
"pubsub-js": "^1.9.5",
|
||||
"vue": "^3.5.13",
|
||||
"vue-countup-v3": "^1.4.2",
|
||||
"vue-echarts": "^7.0.3",
|
||||
|
||||
@@ -65,3 +65,11 @@ export function getSpotApi() {
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 景区列表
|
||||
export function getSpotListApi() {
|
||||
return request({
|
||||
url: '/fjtcc-api/api/largeScreen/spot/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
class="progress"
|
||||
:id="id"
|
||||
:style="{
|
||||
width: styleUtil.px2vw(width),
|
||||
@@ -10,10 +9,11 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import * as echarts from 'echarts'
|
||||
import { guid } from '@/utils/util'
|
||||
import styleUtil from '@/utils/styleUtil'
|
||||
import { fitChartSize } from '@/utils/dataUtil'
|
||||
import { useEchart } from '@/hooks/echart'
|
||||
|
||||
const { id, setOption } = useEchart()
|
||||
|
||||
const props = defineProps({
|
||||
width: {
|
||||
@@ -23,14 +23,36 @@
|
||||
height: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
title: {
|
||||
type: [String, Number],
|
||||
default: () => ''
|
||||
},
|
||||
subTitle: {
|
||||
type: [String, Number],
|
||||
default: () => ''
|
||||
}
|
||||
})
|
||||
let progressChart = null
|
||||
let id = ref(guid())
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
(val) => {
|
||||
setTimeout(() => {
|
||||
init()
|
||||
}, 1000)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
let params = null
|
||||
let defaultCofig = {
|
||||
title: [
|
||||
{
|
||||
text: '45.5%',
|
||||
text: props.title,
|
||||
x: 'center',
|
||||
top: '34%',
|
||||
textStyle: {
|
||||
@@ -39,7 +61,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
text: '完成率',
|
||||
text: props.subTitle,
|
||||
x: 'center',
|
||||
top: '56%',
|
||||
textStyle: {
|
||||
@@ -99,7 +121,7 @@
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 50
|
||||
value: props.value
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -151,27 +173,24 @@
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 50
|
||||
value: props.value
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
const init = () => {
|
||||
// 基于准备好的dom,初始化echarts实例
|
||||
progressChart = echarts.init(document.getElementById(id.value))
|
||||
progressChart.setOption({ ...defaultCofig })
|
||||
window.addEventListener('resize', resize)
|
||||
}
|
||||
const resize = () => {
|
||||
if (progressChart) {
|
||||
progressChart.dispose()
|
||||
init()
|
||||
if (!params) {
|
||||
params = defaultCofig
|
||||
} else {
|
||||
params.title[0].text = props.title
|
||||
params.title[1].text = props.subTitle
|
||||
params.series.map((item) => {
|
||||
item.data[0].value = props.value
|
||||
})
|
||||
}
|
||||
setOption(params)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="count-item">
|
||||
<div class="flex align-center">
|
||||
<img src="@/assets/images/dot-primary.svg" />
|
||||
<img v-if="type == 0" src="@/assets/images/dot-primary.svg" />
|
||||
<img v-if="type == 1" src="@/assets/images/dot-error.svg" />
|
||||
<span class="label">{{ label }}</span>
|
||||
</div>
|
||||
<div class="count">
|
||||
<img class="bg" src="@/assets/images/mask-success.png" />
|
||||
<img v-if="type == 0" class="bg" src="@/assets/images/mask-success.png" />
|
||||
<img v-if="type == 1" class="bg" src="@/assets/images/mask-error.png" />
|
||||
<div class="flex align-center">
|
||||
<countup class="value" :end-val="count" :style="{ color: color }" />
|
||||
<span class="suffix" :style="{ color: color }">{{ suffix }}</span>
|
||||
@@ -26,6 +28,10 @@
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
type: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#02f9fa'
|
||||
|
||||
@@ -12,7 +12,12 @@
|
||||
>
|
||||
{{ item.name }}
|
||||
</li>
|
||||
<!-- <el-dropdown v-if="navLeft.length > 3" trigger="click" @command="handleCommand">
|
||||
<!-- v-if="navLeft.length > 3" -->
|
||||
<el-dropdown
|
||||
v-if="router.currentRoute.value.path == '/scenic'"
|
||||
trigger="click"
|
||||
@command="handleCommand"
|
||||
>
|
||||
<li
|
||||
class="nav-left-item"
|
||||
:style="{
|
||||
@@ -24,12 +29,12 @@
|
||||
</li>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item v-for="(item, index) in navLeft" :key="index" :command="item">
|
||||
<el-dropdown-item v-for="(item, index) in otherNav" :key="index" :command="item">
|
||||
<span class="label"> {{ item.name }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown> -->
|
||||
</el-dropdown>
|
||||
</ul>
|
||||
<div class="title">
|
||||
<span>{{ title }}</span>
|
||||
@@ -63,9 +68,9 @@
|
||||
import title2 from '@/assets/images/title-2.png'
|
||||
import title2Select from '@/assets/images/title-2-select.png'
|
||||
import { getWeatherApi } from '@/api/home'
|
||||
import { getSpotApi } from '@/api/sentiment'
|
||||
import { getSpotListApi } from '@/api/sentiment'
|
||||
|
||||
const emit = defineEmits(['change'])
|
||||
import pubSub from 'pubsub-js'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -78,6 +83,18 @@
|
||||
let isBack = ref(false)
|
||||
let current = ref(0)
|
||||
let otherScenic = ref('')
|
||||
let otherNav = ref([
|
||||
{
|
||||
name: '大窝景区'
|
||||
},
|
||||
{
|
||||
name: '天坑景区'
|
||||
},
|
||||
{
|
||||
name: '旅游环线'
|
||||
}
|
||||
])
|
||||
let spotList = ref([])
|
||||
|
||||
// 补零
|
||||
const fillZero = (value) => {
|
||||
@@ -102,6 +119,7 @@
|
||||
const handleBack = () => {
|
||||
router.go(-1)
|
||||
}
|
||||
const handleCommand = () => {}
|
||||
// 点击导航
|
||||
const handleNav = (item, index) => {
|
||||
if (isSkip.value) {
|
||||
@@ -111,15 +129,24 @@
|
||||
otherScenic.value = ''
|
||||
current.value = index
|
||||
title.value = item.name
|
||||
pubSub.publish('scenicChange', item)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取天气数据
|
||||
const getWeather = async () => {
|
||||
let res = await getWeatherApi()
|
||||
weatherData.value = res.data
|
||||
}
|
||||
// 获取景区列表
|
||||
const getSpotList = async () => {
|
||||
let res = await getSpotListApi()
|
||||
spotList.value = res.data
|
||||
}
|
||||
// 设置当前路由导航栏
|
||||
const setNav = async () => {
|
||||
navLeft.value = []
|
||||
navRight.value = []
|
||||
switch (router.currentRoute.value.path) {
|
||||
case '/home':
|
||||
title.value = '奉节县旅游指挥调度中心'
|
||||
@@ -138,55 +165,29 @@
|
||||
case '/scenic':
|
||||
isSkip.value = false
|
||||
isBack.value = true
|
||||
let res = await getSpotApi()
|
||||
navLeft.value = res.data.map((item) => {
|
||||
return {
|
||||
name: item.ssname,
|
||||
id: item.id
|
||||
}
|
||||
})
|
||||
let res = await getSpotListApi()
|
||||
navLeft.value = res.data
|
||||
title.value = navLeft.value[current.value].name
|
||||
navRight.value = []
|
||||
pubSub.publish('scenicChange', navLeft.value[current.value])
|
||||
|
||||
break
|
||||
case '/sentiment':
|
||||
title.value = '舆情检测'
|
||||
navLeft.value = []
|
||||
navRight.value = []
|
||||
|
||||
isBack.value = true
|
||||
break
|
||||
case '/workOrder':
|
||||
title.value = '工单消息'
|
||||
navLeft.value = []
|
||||
navRight.value = []
|
||||
isBack.value = true
|
||||
break
|
||||
case '/traffic':
|
||||
title.value = '交通大屏'
|
||||
navLeft.value = []
|
||||
navRight.value = []
|
||||
isBack.value = true
|
||||
break
|
||||
case '/monitor':
|
||||
title.value = '监控大屏'
|
||||
navLeft.value = [
|
||||
{
|
||||
name: '奉节县',
|
||||
path: '/sceneTesting'
|
||||
},
|
||||
{
|
||||
name: '三峡之巅',
|
||||
path: '/sceneTesting'
|
||||
},
|
||||
{
|
||||
name: '白帝城',
|
||||
path: '/sceneTesting'
|
||||
},
|
||||
{
|
||||
name: '龙河桥',
|
||||
path: '/sceneTesting'
|
||||
}
|
||||
]
|
||||
navRight.value = []
|
||||
let res1 = await getSpotListApi()
|
||||
navLeft.value = res1.data
|
||||
isBack.value = true
|
||||
break
|
||||
case '/sceneTesting':
|
||||
@@ -240,6 +241,7 @@
|
||||
)
|
||||
onMounted(() => {
|
||||
getWeather()
|
||||
getSpotList()
|
||||
getCurrentDate()
|
||||
setInterval(() => {
|
||||
getCurrentDate()
|
||||
@@ -253,7 +255,7 @@
|
||||
left: vw(326);
|
||||
.weather {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: vh(10);
|
||||
font-weight: 400;
|
||||
font-size: vw(18);
|
||||
@@ -264,7 +266,7 @@
|
||||
}
|
||||
.date {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: vh(10);
|
||||
font-weight: 400;
|
||||
font-size: vw(18);
|
||||
@@ -293,7 +295,7 @@
|
||||
}
|
||||
}
|
||||
.title {
|
||||
width: vw(3133);
|
||||
width: vw(3170);
|
||||
height: vh(120);
|
||||
line-height: vh(90);
|
||||
text-align: center;
|
||||
@@ -316,7 +318,7 @@
|
||||
}
|
||||
.nav-left {
|
||||
position: absolute;
|
||||
right: vw(2100);
|
||||
right: vw(2120);
|
||||
top: vh(34);
|
||||
display: flex;
|
||||
&-item {
|
||||
@@ -338,7 +340,7 @@
|
||||
}
|
||||
.nav-right {
|
||||
position: absolute;
|
||||
left: vw(2110);
|
||||
left: vw(2130);
|
||||
top: vh(34);
|
||||
display: flex;
|
||||
&-item {
|
||||
|
||||
@@ -31,7 +31,7 @@ export function useWebSocket(url) {
|
||||
}
|
||||
|
||||
const sendMessage = (message) => {
|
||||
if (socket.value) {
|
||||
if (socket.value && isConnected.value) {
|
||||
socket.value.send(message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,10 +46,9 @@ export const useHomeStore = defineStore('home', () => {
|
||||
let wordkOrderList = ref([])
|
||||
// 工单统计
|
||||
let wordkOrderData = ref({
|
||||
toDayData: { count: 15, end: 0, rate: '0.0' },
|
||||
warnData: { count: 15, end: 0, rate: '0.0' }
|
||||
toDayData: { count: 0, end: 0, rate: '0.0' },
|
||||
warnData: { count: 0, end: 0, rate: '0.0' }
|
||||
})
|
||||
|
||||
// 交通信息
|
||||
let trafficInfoData = ref({
|
||||
data: {
|
||||
|
||||
@@ -13,21 +13,30 @@ export const useScenicStore = defineStore('scenic', () => {
|
||||
// 景区排队信息
|
||||
let scenicQueueData = ref({ dataList: [], header: { jrcp: 0, jrjdrs: 0, pdcxsj: 0, pdrs: 0 } })
|
||||
// 景区负载信息
|
||||
let scenicBearData = ref({ dataList: [], header: { jqzdcz: 0, jrjdrs: 0 } })
|
||||
let scenicBearData = ref({ dataList: [], header: { jqRate: 0, jqzdcz: 0, jrjdrs: 0 } })
|
||||
// 景区停车信息
|
||||
let stopCarData = ref({
|
||||
dataList: [],
|
||||
dataLists: [],
|
||||
headList: []
|
||||
headList: [],
|
||||
info: {
|
||||
count: 0,
|
||||
remain: 0
|
||||
}
|
||||
})
|
||||
// 安全信息
|
||||
let secureData = ref({
|
||||
dataList: []
|
||||
dataList: [],
|
||||
headList: [
|
||||
{ name: '当前告警总数', count: 0, type: 0 },
|
||||
{ name: '安全告警总数', count: 0, type: 0 },
|
||||
{ name: '已解除告警数', count: 0, type: 0 }
|
||||
]
|
||||
})
|
||||
// 交通信息
|
||||
let trafficData = ref({
|
||||
infoList: [
|
||||
{ name: '总通景路段', value: 100 },
|
||||
{ name: '总通景路段', value: 0 },
|
||||
{ name: '通景路段拥堵', value: 0 },
|
||||
{ name: '通景拥堵开始时间', value: 0 },
|
||||
{ name: '拥堵持续时间', value: 0 }
|
||||
@@ -49,7 +58,29 @@ export const useScenicStore = defineStore('scenic', () => {
|
||||
})
|
||||
// 工单列表
|
||||
let wordkOrderList = ref([])
|
||||
// 工单统计
|
||||
let wordkOrderData = ref({
|
||||
toDayData: { count: 0, end: 0, rate: '0.0' },
|
||||
warnData: { count: 0, end: 0, rate: '0.0' }
|
||||
})
|
||||
// 车船信息
|
||||
let carShipData = ref({
|
||||
car: {
|
||||
count: { nonDrivingCount: 0, drivingCount: 0 },
|
||||
list: []
|
||||
},
|
||||
ship: {
|
||||
count: { nonDrivingCount: 0, drivingCount: 0 },
|
||||
list: []
|
||||
}
|
||||
})
|
||||
|
||||
const setCarShipData = (val) => {
|
||||
carShipData.value = val
|
||||
}
|
||||
const setWordkOrderData = (val) => {
|
||||
wordkOrderData.value = val
|
||||
}
|
||||
const setWordkOrderList = (val) => {
|
||||
wordkOrderList.value = val
|
||||
}
|
||||
@@ -75,6 +106,7 @@ export const useScenicStore = defineStore('scenic', () => {
|
||||
scenicSpotData.value = val
|
||||
}
|
||||
return {
|
||||
wordkOrderData,
|
||||
wordkOrderList,
|
||||
scenicSpotData,
|
||||
scenicQueueData,
|
||||
@@ -83,6 +115,8 @@ export const useScenicStore = defineStore('scenic', () => {
|
||||
secureData,
|
||||
trafficData,
|
||||
userPortraitData,
|
||||
carShipData,
|
||||
setWordkOrderData,
|
||||
setWordkOrderList,
|
||||
setScenicSpotData,
|
||||
setScenicQueueData,
|
||||
@@ -90,6 +124,7 @@ export const useScenicStore = defineStore('scenic', () => {
|
||||
setStopCarData,
|
||||
setSecureData,
|
||||
setTrafficData,
|
||||
setUserPortraitData
|
||||
setUserPortraitData,
|
||||
setCarShipData
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ export const proBaseUrl = 'http://192.168.77.200'
|
||||
export const socketBaseUrl = 'ws://36.138.38.16:81'
|
||||
export const proSocketBaseUrl = 'ws://192.168.77.200:8060'
|
||||
|
||||
export const mode = 'pro'
|
||||
export const mode = 'pro' // 测试 dev 正式 pro
|
||||
|
||||
export const devToken =
|
||||
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.BTxvu6jUWbN0qONWf5K6VzXopE8T8qXzKuX-mij21VJT4U0LdgnqToyqeNDQ2OyJ6cvpdJBzQ9mEEb-dnwrTpQ'
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
v-for="(item, index) in homeStore.scenicBearData.info"
|
||||
:key="index"
|
||||
>
|
||||
<gauge :value="item.value" />
|
||||
<gauge :value="parseFloat(item.value)" />
|
||||
<span class="statistic-title">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -131,10 +131,10 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import top from './top.vue'
|
||||
import age from './age.vue'
|
||||
import gauge from './gauge.vue'
|
||||
import ticket from './ticket.vue'
|
||||
import top from './top'
|
||||
import age from './age'
|
||||
import gauge from './gauge'
|
||||
import ticket from './ticket'
|
||||
import countup from 'vue-countup-v3'
|
||||
import { useHomeStore } from '@/stores/home'
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
<span class="text">工单完成数</span>
|
||||
<div class="progress-1">
|
||||
<el-progress
|
||||
:percentage="homeStore.wordkOrderData.toDayData.rate"
|
||||
:percentage="parseFloat(homeStore.wordkOrderData.toDayData.rate)"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
@@ -91,7 +91,7 @@
|
||||
<span class="text">工单完成数</span>
|
||||
<div class="progress-2">
|
||||
<el-progress
|
||||
:percentage="homeStore.wordkOrderData.warnData.rate"
|
||||
:percentage="parseFloat(homeStore.wordkOrderData.warnData.rate)"
|
||||
:show-text="false"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -231,7 +231,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="occupancy">
|
||||
<Title3 title="酒店入住人数及入住率" />
|
||||
<Title3 title="酒店入住率" />
|
||||
</div>
|
||||
<occupancy :list="homeStore.hotelData?.list" />
|
||||
</div>
|
||||
|
||||
@@ -25,11 +25,9 @@
|
||||
watch(
|
||||
() => props.value,
|
||||
(val) => {
|
||||
if (val) {
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
init()
|
||||
})
|
||||
}
|
||||
}, 1000)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
@@ -44,7 +42,7 @@
|
||||
endAngle: 0,
|
||||
min: 0,
|
||||
max: 100,
|
||||
radius: '100%',
|
||||
radius: '120%',
|
||||
splitNumber: 10,
|
||||
center: ['50%', '60%'],
|
||||
itemStyle: {
|
||||
@@ -65,11 +63,11 @@
|
||||
}
|
||||
],
|
||||
global: false
|
||||
},
|
||||
shadowColor: 'rgba(0,138,255,0.45)',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 2,
|
||||
shadowOffsetY: 2
|
||||
}
|
||||
// shadowColor: 'red',
|
||||
// shadowBlur: 10,
|
||||
// shadowOffsetX: 2,
|
||||
// shadowOffsetY: 2
|
||||
},
|
||||
progress: {
|
||||
show: true,
|
||||
@@ -130,7 +128,7 @@
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gauge {
|
||||
width: vw(70);
|
||||
width: vw(120);
|
||||
height: vh(50);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
return props.list.map((item) => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: item.count,
|
||||
value: item.duration,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
@@ -61,7 +61,7 @@
|
||||
return props.list.map((item) => {
|
||||
return {
|
||||
name: item.name,
|
||||
value: item.count,
|
||||
value: item.duration,
|
||||
itemStyle: {
|
||||
color: '#fff',
|
||||
opacity: 1
|
||||
@@ -70,7 +70,7 @@
|
||||
})
|
||||
}
|
||||
const setYAxisData = () => {
|
||||
return props.list.map((item) => item.count)
|
||||
return props.list.map((item) => item.duration)
|
||||
}
|
||||
const init = () => {
|
||||
if (!params) {
|
||||
@@ -110,10 +110,10 @@
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
data: [],
|
||||
axisLabel: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
data: []
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
@@ -122,10 +122,8 @@
|
||||
axisLine: 'none',
|
||||
show: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(12)
|
||||
},
|
||||
fontSize: fitChartSize(12),
|
||||
verticalAlign: 'bottom',
|
||||
padding: [0, 0, 6, 0],
|
||||
inside: true,
|
||||
@@ -150,7 +148,7 @@
|
||||
type: 'bar',
|
||||
barWidth: fitChartSize(8),
|
||||
showBackground: true,
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
backgroundStyle: {
|
||||
color: 'rgba(0, 150, 255, 0.15)'
|
||||
},
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
grid: {
|
||||
left: '4%',
|
||||
right: '4%',
|
||||
top: '14%',
|
||||
top: '16%',
|
||||
bottom: '4%',
|
||||
containLabel: false
|
||||
},
|
||||
@@ -122,10 +122,8 @@
|
||||
axisLine: 'none',
|
||||
show: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(12)
|
||||
},
|
||||
fontSize: fitChartSize(12),
|
||||
verticalAlign: 'bottom',
|
||||
padding: [0, 0, 10, 0],
|
||||
inside: true,
|
||||
@@ -150,7 +148,7 @@
|
||||
type: 'bar',
|
||||
barWidth: fitChartSize(8),
|
||||
showBackground: true,
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
backgroundStyle: {
|
||||
color: 'rgba(0, 150, 255, 0.15)'
|
||||
},
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
const { id, setOption } = useEchart()
|
||||
|
||||
let x = 15
|
||||
let y = 25
|
||||
let x = 25
|
||||
let y = 35
|
||||
let params = null
|
||||
|
||||
watch(
|
||||
@@ -38,7 +38,7 @@
|
||||
type: 'pie',
|
||||
clockwise: false,
|
||||
silent: true,
|
||||
radius: [`${x * (index + 1)}%`, `${y + index * 15}%`],
|
||||
radius: [`${x * (index + 1)}%`, `${y + index * 25}%`],
|
||||
center: ['50%', '40%'],
|
||||
label: { show: false },
|
||||
labelLine: { show: false },
|
||||
@@ -66,7 +66,7 @@
|
||||
legend: {
|
||||
show: true,
|
||||
x: 'center',
|
||||
y: '70%',
|
||||
y: '74%',
|
||||
itemHeight: fitChartSize(12),
|
||||
itemWidth: fitChartSize(12),
|
||||
itemGap: fitChartSize(6),
|
||||
|
||||
@@ -52,10 +52,8 @@
|
||||
axisLine: 'none',
|
||||
show: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(18)
|
||||
},
|
||||
fontSize: fitChartSize(18),
|
||||
verticalAlign: 'bottom',
|
||||
padding: [0, -fitChartSize(10), fitChartSize(10), 0],
|
||||
inside: true,
|
||||
@@ -78,7 +76,7 @@
|
||||
type: 'bar',
|
||||
barWidth: fitChartSize(12),
|
||||
showBackground: true,
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
backgroundStyle: {
|
||||
color: 'rgba(0, 150, 255, 0.15)'
|
||||
},
|
||||
@@ -99,7 +97,7 @@
|
||||
name: item.name,
|
||||
value: Number(item.value),
|
||||
itemStyle: {
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
color: parseFloat(item.value) > 50 ? '#FF7021' : '#00CCFF'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
return props.list.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
value: item.occupiedPercentage,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
@@ -60,6 +61,7 @@
|
||||
return props.list.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
value: item.occupiedPercentage,
|
||||
itemStyle: {
|
||||
color: '#fff',
|
||||
opacity: 1
|
||||
@@ -68,7 +70,7 @@
|
||||
})
|
||||
}
|
||||
const getYAxisData = () => {
|
||||
return props.list.map((item) => item.value)
|
||||
return props.list.map((item) => item.occupied)
|
||||
}
|
||||
const init = () => {
|
||||
if (!params) {
|
||||
@@ -148,7 +150,7 @@
|
||||
type: 'bar',
|
||||
barWidth: fitChartSize(8),
|
||||
showBackground: true,
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
backgroundStyle: {
|
||||
color: 'rgba(0, 150, 255, 0.15)'
|
||||
},
|
||||
|
||||
@@ -83,8 +83,16 @@
|
||||
type: 'bar',
|
||||
showBackground: true,
|
||||
barWidth: fitChartSize(8),
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(10)
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
|
||||
@@ -126,7 +126,6 @@
|
||||
params.series[0].data = getSeriesData()
|
||||
params.series[1].data = getSeriesData()
|
||||
}
|
||||
console.log(params, 'params')
|
||||
setOption(params)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
(val) => {
|
||||
if (val && !map.value) {
|
||||
setTimeout(() => {
|
||||
initMap('big-car-ship', 109.491961, 31.024285, 16)
|
||||
addMarker(carIcon, [109.491045, 31.028725], [36, 50])
|
||||
addMarker(carIcon, [109.483266, 31.024718], [36, 50])
|
||||
addMarker(shipIcon, [109.479062, 31.021499], [36, 50])
|
||||
addMarker(shipIcon, [109.488907, 31.017476], [36, 50])
|
||||
}, 500)
|
||||
initMap('big-car-ship', 109.552461, 31.049607, 15)
|
||||
addMarker(carIcon, [109.551419, 31.050001], [36, 50])
|
||||
addMarker(shipIcon, [109.551671, 31.04847], [36, 50])
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -42,15 +42,15 @@
|
||||
:deep(.el-dialog) {
|
||||
width: vw(2540);
|
||||
height: vh(900);
|
||||
padding: 0;
|
||||
padding: vh(40) vw(40);
|
||||
}
|
||||
:deep(.el-dialog__header) {
|
||||
padding-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
.big-car-ship {
|
||||
width: vw(2540);
|
||||
height: vh(900);
|
||||
width: 100%;
|
||||
height: vh(820);
|
||||
}
|
||||
.close {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -39,35 +39,55 @@
|
||||
<div class="footer">
|
||||
<div class="flex">
|
||||
<div class="item">
|
||||
<CircleProgress :width="170" :height="90" />
|
||||
<circle-progress
|
||||
:width="170"
|
||||
:height="90"
|
||||
:value="scenicStore.wordkOrderData.toDayData.rate"
|
||||
:title="`${scenicStore.wordkOrderData.toDayData.rate}%`"
|
||||
subTitle="完成率"
|
||||
/>
|
||||
<div>
|
||||
<div class="bg">
|
||||
<span class="label">今日工单总条数:</span>
|
||||
<span class="value"> <countup :endVal="1234" /></span>
|
||||
<span class="value success">
|
||||
<countup :end-val="scenicStore.wordkOrderData.toDayData.count" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="bg">
|
||||
<span class="label">工单完成数:</span>
|
||||
<span class="value"> <countup :endVal="1234" /></span>
|
||||
<span class="value">
|
||||
<countup :end-val="scenicStore.wordkOrderData.toDayData.end" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<CircleProgress :width="170" :height="90" />
|
||||
<circle-progress
|
||||
:width="170"
|
||||
:height="90"
|
||||
:value="scenicStore.wordkOrderData.warnData.rate"
|
||||
:title="`${scenicStore.wordkOrderData.warnData.rate}%`"
|
||||
subTitle="完成率"
|
||||
/>
|
||||
<div>
|
||||
<div class="bg">
|
||||
<span class="label">今日工单总条数:</span>
|
||||
<span class="value"> <countup :endVal="1234" /></span>
|
||||
<span class="label">今日紧急工单数:</span>
|
||||
<span class="value error">
|
||||
<countup :end-val="scenicStore.wordkOrderData.warnData.count" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="bg">
|
||||
<span class="label">工单完成数:</span>
|
||||
<span class="value"> <countup :endVal="1234" /></span>
|
||||
<span class="label">紧急工单完成数:</span>
|
||||
<span class="value">
|
||||
<countup :end-val="scenicStore.wordkOrderData.warnData.end" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex align-center justify-between">
|
||||
<div>
|
||||
<vue3-seamless-scroll
|
||||
<Vue3SeamlessScroll
|
||||
class="list"
|
||||
:list="scenicStore.wordkOrderList"
|
||||
:limitScrollNum="3"
|
||||
@@ -82,7 +102,7 @@
|
||||
{{ item.title }}
|
||||
</p>
|
||||
</div>
|
||||
</vue3-seamless-scroll>
|
||||
</Vue3SeamlessScroll>
|
||||
</div>
|
||||
<img class="more" src="@/assets/images/more-col.png" alt="查看更多" @click="handleMore" />
|
||||
</div>
|
||||
@@ -203,8 +223,14 @@
|
||||
.value {
|
||||
font-weight: bold;
|
||||
font-size: vw(28);
|
||||
color: #fff;
|
||||
}
|
||||
.success {
|
||||
color: #02f9fa;
|
||||
}
|
||||
.error {
|
||||
color: #e21b1b;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list {
|
||||
|
||||
@@ -40,7 +40,13 @@
|
||||
<div class="box mr-8">
|
||||
<Title1 title="景区承载" />
|
||||
<div class="flex">
|
||||
<circle-progress :width="200" :height="70" />
|
||||
<circle-progress
|
||||
:width="200"
|
||||
:height="70"
|
||||
:value="scenicStore.scenicBearData.header.jqRate"
|
||||
:title="`${scenicStore.scenicBearData.header.jqRate}%`"
|
||||
subTitle="景区承载率"
|
||||
/>
|
||||
<div class="flex flex-1 justify-between">
|
||||
<count-item
|
||||
label="景区当前人数"
|
||||
@@ -69,14 +75,24 @@
|
||||
<div class="box-1 mr-8">
|
||||
<Title1 title="停车信息" />
|
||||
<div class="flex">
|
||||
<div class="flex">
|
||||
<circle-progress :width="140" :height="70" />
|
||||
<circle-progress :width="140" :height="70" />
|
||||
<circle-progress :width="140" :height="70" />
|
||||
<div class="height70 flex flex-1">
|
||||
<circle-progress
|
||||
v-for="(item, index) in garageList"
|
||||
:key="index"
|
||||
:width="140"
|
||||
:height="70"
|
||||
:value="item.ratio"
|
||||
:title="item.over"
|
||||
:subTitle="`${item.name}剩余`"
|
||||
/>
|
||||
</div>
|
||||
<div class="ml-20 flex flex-1 justify-between">
|
||||
<count-item label="总车位数" :count="561" suffix="个" />
|
||||
<count-item label="剩余车位数" :count="15" suffix="个" />
|
||||
<count-item label="总车位数" :count="scenicStore.stopCarData.info.count" suffix="个" />
|
||||
<count-item
|
||||
label="剩余车位数"
|
||||
:count="scenicStore.stopCarData.info.remain"
|
||||
suffix="个"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex">
|
||||
@@ -103,9 +119,14 @@
|
||||
<div class="box-2">
|
||||
<Title1 title="安全信息 " />
|
||||
<div class="count-box flex">
|
||||
<count-item label="当前告警总数" :count="561" suffix="次" />
|
||||
<count-item label="安全告警总数" :count="561" suffix="次" />
|
||||
<count-item label="已解除告警数" :count="561" />
|
||||
<count-item
|
||||
v-for="item in scenicStore.secureData.headList"
|
||||
:label="item.name"
|
||||
:count="item.count"
|
||||
:type="item.type"
|
||||
:color="item.type == 0 ? '#0096FF' : '#E21B1B'"
|
||||
suffix="次"
|
||||
/>
|
||||
</div>
|
||||
<div class="border flex-1">
|
||||
<div class="pt-10">
|
||||
@@ -115,7 +136,7 @@
|
||||
label="安全告警占比"
|
||||
:dataList="scenicStore.secureData.dataList"
|
||||
:total="alarmTotal"
|
||||
:width="460"
|
||||
:width="440"
|
||||
:height="300"
|
||||
/>
|
||||
</div>
|
||||
@@ -140,11 +161,21 @@
|
||||
</div>
|
||||
<div class="border mr-8">
|
||||
<Title3 title="拥堵次数占比" />
|
||||
<jam :width="220" :height="160" />
|
||||
<jam
|
||||
:width="220"
|
||||
:height="300"
|
||||
sub-title="拥堵频次总数"
|
||||
:list="scenicStore.trafficData.data.countRate"
|
||||
/>
|
||||
</div>
|
||||
<div class="border">
|
||||
<Title3 title="拥堵时长占比" />
|
||||
<jam :width="220" :height="160" />
|
||||
<jam
|
||||
:width="220"
|
||||
:height="300"
|
||||
sub-title="拥堵总时长"
|
||||
:list="scenicStore.trafficData.data.countRate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -167,7 +198,7 @@
|
||||
<span class="text">{{ item.name }}</span>
|
||||
<div class="progress">
|
||||
<el-progress
|
||||
:percentage="item.value"
|
||||
:percentage="parseFloat(item.value)"
|
||||
:show-text="false"
|
||||
:color="
|
||||
item.name == '女'
|
||||
@@ -186,7 +217,7 @@
|
||||
</div>
|
||||
<div class="border flex-1">
|
||||
<Title3 title="购票来源" />
|
||||
<div class="count">总人数:<countup endVal="124563" /></div>
|
||||
<div class="count">总人数:<countup :end-val="channelTotal" /></div>
|
||||
<ticket />
|
||||
</div>
|
||||
</div>
|
||||
@@ -196,53 +227,65 @@
|
||||
<Title1 title="车船信息" />
|
||||
<div class="flex mb-6">
|
||||
<div class="border mr-8 pt-10 pb-10">
|
||||
<div class="flex justify-between">
|
||||
<Title2 title="景区车辆" />
|
||||
<div class="sum">
|
||||
<span>总数:</span>
|
||||
<countup
|
||||
:end-val="
|
||||
scenicStore.carShipData.car.count?.drivingCount +
|
||||
scenicStore.carShipData.car.count?.nonDrivingCount
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-box mt-10">
|
||||
<img class="icon" src="@/assets/images/icon-6.png" />
|
||||
<div class="car-item pr-20">
|
||||
<div class="label">车总数</div>
|
||||
<div class="value">130辆</div>
|
||||
<div class="label">运营车辆</div>
|
||||
<div class="value flex">
|
||||
<countup :end-val="scenicStore.carShipData.car.count?.drivingCount" />
|
||||
<span class="suffix"> 辆 </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-item">
|
||||
<div class="label">今日累计运营(班次)</div>
|
||||
<div class="value">130次</div>
|
||||
<div class="label">空闲车辆</div>
|
||||
<div class="value flex">
|
||||
<countup :end-val="scenicStore.carShipData.car.count?.nonDrivingCount" />
|
||||
<span class="suffix"> 辆 </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-box">
|
||||
<span class="text">运营130辆</span>
|
||||
<div class="progress">
|
||||
<el-progress
|
||||
:percentage="50"
|
||||
:show-text="false"
|
||||
color="linear-gradient(to right, rgba(0,150,255,0) 0%, #F15A25 100%)"
|
||||
/>
|
||||
</div>
|
||||
<span class="value">空余100辆</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border pt-10 pb-10">
|
||||
<div class="flex justify-between">
|
||||
<Title2 title="景区船只" />
|
||||
<div class="sum">
|
||||
<span>总数:</span>
|
||||
<countup
|
||||
:end-val="
|
||||
scenicStore.carShipData.ship.count?.drivingCount +
|
||||
scenicStore.carShipData.ship.count?.nonDrivingCount
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-box mt-10">
|
||||
<img class="icon" src="@/assets/images/icon-6.png" />
|
||||
<div class="car-item pr-20">
|
||||
<div class="label">船总数</div>
|
||||
<div class="value">130辆</div>
|
||||
<div class="label">运营船只</div>
|
||||
<div class="value flex">
|
||||
<countup :end-val="scenicStore.carShipData.ship.count?.drivingCount" />
|
||||
<span class="suffix">辆</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="car-item">
|
||||
<div class="label">今日累计运营(班次)</div>
|
||||
<div class="value">130次</div>
|
||||
<div class="label">空闲船只</div>
|
||||
<div class="value flex">
|
||||
<countup :end-val="scenicStore.carShipData.ship.count?.nonDrivingCount" />
|
||||
<span class="suffix">只</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="progress-box">
|
||||
<span class="text">运营130辆</span>
|
||||
<div class="progress">
|
||||
<el-progress
|
||||
:percentage="50"
|
||||
:show-text="false"
|
||||
color="linear-gradient(to right, rgba(0,150,255,0) 0%, #F15A25 100%)"
|
||||
/>
|
||||
</div>
|
||||
<span class="value">空余100辆</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -273,6 +316,21 @@
|
||||
const scenicStore = useScenicStore()
|
||||
const { initMap, addMarker } = useMap()
|
||||
|
||||
const garageList = computed(() => {
|
||||
return scenicStore.stopCarData.headList.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
ratio: ((item.count - item.over) / item.count) * 100
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const channelTotal = computed(() => {
|
||||
return scenicStore.userPortraitData.data.channel.reduce((pre, cur) => {
|
||||
return pre + parseInt(cur.count)
|
||||
}, 0)
|
||||
})
|
||||
|
||||
const ageTotal = computed(() => {
|
||||
return scenicStore.userPortraitData.data.genderRate.reduce((pre, cur) => {
|
||||
return pre + parseInt(cur.count)
|
||||
@@ -313,12 +371,26 @@
|
||||
})
|
||||
|
||||
let show = ref(false)
|
||||
|
||||
watch(
|
||||
() => scenicStore.carShipData,
|
||||
(val) => {
|
||||
if (val.car.list.length > 0) {
|
||||
setTimeout(() => {
|
||||
val.car.list.map((item) => {
|
||||
addMarker(carIcon, [109.551419, 31.050001], [36, 50])
|
||||
})
|
||||
val.ship.list.map((item) => {
|
||||
addMarker(shipIcon, [109.551671, 31.04847], [36, 50])
|
||||
})
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
initMap('car-ship', 109.491961, 31.024285, 13)
|
||||
addMarker(carIcon, [109.491045, 31.028725], [36, 50])
|
||||
addMarker(carIcon, [109.483266, 31.024718], [36, 50])
|
||||
addMarker(shipIcon, [109.479062, 31.021499], [36, 50])
|
||||
addMarker(shipIcon, [109.488907, 31.017476], [36, 50])
|
||||
initMap('car-ship', 109.552461, 31.049607, 15)
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -329,6 +401,9 @@
|
||||
:deep(.anchorBL) {
|
||||
display: none;
|
||||
}
|
||||
.height70 {
|
||||
height: vh(70);
|
||||
}
|
||||
.legend {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -399,29 +474,7 @@
|
||||
height: vh(904);
|
||||
}
|
||||
}
|
||||
.progress-box {
|
||||
margin-top: vh(10);
|
||||
height: vh(20);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(to right, rgba(0, 150, 255, 0) 0%, rgba(0, 150, 255, 0.17) 100%);
|
||||
.text {
|
||||
margin-right: vw(10);
|
||||
font-weight: 400;
|
||||
font-size: vw(14);
|
||||
color: #ffffff;
|
||||
}
|
||||
.progress {
|
||||
width: vw(70);
|
||||
}
|
||||
.value {
|
||||
margin-left: vw(10);
|
||||
font-weight: 400;
|
||||
font-size: vw(14);
|
||||
color: #f15a25;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
margin: vh(120) 0 0 vw(10);
|
||||
.count-box {
|
||||
@@ -491,11 +544,23 @@
|
||||
font-size: vw(24);
|
||||
color: #02f9fa;
|
||||
margin-top: vh(6);
|
||||
align-items: flex-end;
|
||||
}
|
||||
.suffix {
|
||||
font-size: vw(12);
|
||||
color: #02f9fa;
|
||||
}
|
||||
}
|
||||
.sum {
|
||||
font-weight: bold;
|
||||
font-size: vw(18);
|
||||
color: #02f9fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.car-ship {
|
||||
width: vw(660);
|
||||
height: vh(240);
|
||||
height: vh(250);
|
||||
}
|
||||
.full {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -22,77 +22,78 @@
|
||||
type: Number,
|
||||
default: () => 0
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
list: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
title: {
|
||||
type: [String, Number],
|
||||
default: () => ''
|
||||
},
|
||||
subTitle: {
|
||||
type: [String, Number],
|
||||
default: () => ''
|
||||
}
|
||||
})
|
||||
|
||||
const { id, setOption } = useEchart()
|
||||
|
||||
var colorList = ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA', '']
|
||||
var title = ['企业', '农业', '工业', '纺织']
|
||||
var dataValue = ['15', '30', '35', '20']
|
||||
var dataList = title.map((item, index) => {
|
||||
watch(
|
||||
() => props.list,
|
||||
(val) => {
|
||||
setTimeout(() => {
|
||||
init()
|
||||
}, 1000)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
let params = null
|
||||
|
||||
const getSeriesData = () => {
|
||||
return props.list.map((item) => {
|
||||
return {
|
||||
name: item,
|
||||
value: dataValue[index]
|
||||
...item,
|
||||
value: parseFloat(item.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
var defaultCofig = {
|
||||
color: colorList,
|
||||
const getTotal = () => {
|
||||
return props.list.reduce((per, cur) => {
|
||||
return per + cur.count
|
||||
}, 0)
|
||||
}
|
||||
|
||||
const formatLabel = () => {
|
||||
return () => `{value|${getTotal()}}` + '\n' + `{name|${props.subTitle}}`
|
||||
}
|
||||
|
||||
let defaultCofig = {
|
||||
color: ['#A665F1', '#0063FF', '#00D0FF', '#01FEFE', '#FC2638', '#FED958'],
|
||||
legend: {
|
||||
x: 'left',
|
||||
y: '74%',
|
||||
itemHeight: fitChartSize(12),
|
||||
itemWidth: fitChartSize(12),
|
||||
itemGap: fitChartSize(10),
|
||||
formatter: function (name) {
|
||||
return '{name|' + name + '}'
|
||||
},
|
||||
textStyle: {
|
||||
rich: {
|
||||
name: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(14)
|
||||
},
|
||||
value: {
|
||||
color: '#00D5F6',
|
||||
fontSize: fitChartSize(14)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
startAngle: 360,
|
||||
center: ['50%', '40%'],
|
||||
radius: ['65%', '80%'],
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: 50,
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 1,
|
||||
y: 1,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(0, 150, 255, 0)'
|
||||
},
|
||||
{
|
||||
offset: 0.5,
|
||||
color: 'rgba(0, 150, 255, 0.47)'
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(0, 150, 255, 0)'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
name: 'bottom',
|
||||
value: 50,
|
||||
itemStyle: {
|
||||
color: 'transparent'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'pie',
|
||||
center: ['50%', '40%'],
|
||||
@@ -105,9 +106,7 @@
|
||||
show: true,
|
||||
position: 'center',
|
||||
fontWeight: 'bold',
|
||||
formatter: function (o) {
|
||||
return `{value|123456}` + '\n' + `{name|整改率}`
|
||||
},
|
||||
formatter: formatLabel(),
|
||||
rich: {
|
||||
value: {
|
||||
color: '#fff',
|
||||
@@ -116,7 +115,7 @@
|
||||
padding: [0, 0, 5, 0]
|
||||
},
|
||||
name: {
|
||||
color: '#7894A8',
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(12)
|
||||
}
|
||||
}
|
||||
@@ -124,21 +123,20 @@
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: dataList
|
||||
data: getSeriesData()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
setOption({
|
||||
...defaultCofig,
|
||||
...props.config
|
||||
})
|
||||
if (!params) {
|
||||
params = defaultCofig
|
||||
} else {
|
||||
params.series[0].label.formatter = formatLabel()
|
||||
params.series[0].data = getSeriesData()
|
||||
}
|
||||
setOption(params)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
const { id, setOption } = useEchart()
|
||||
|
||||
let x = 15
|
||||
let y = 25
|
||||
let x = 30
|
||||
let y = 40
|
||||
let params = null
|
||||
|
||||
watch(
|
||||
@@ -38,7 +38,7 @@
|
||||
type: 'pie',
|
||||
clockwise: false,
|
||||
silent: true,
|
||||
radius: [`${x * (index + 1)}%`, `${y + index * 15}%`],
|
||||
radius: [`${x * (index + 1)}%`, `${y + index * 30}%`],
|
||||
center: ['50%', '40%'],
|
||||
label: { show: false },
|
||||
labelLine: { show: false },
|
||||
@@ -100,7 +100,7 @@
|
||||
|
||||
<style scoped lang="scss">
|
||||
.ticket {
|
||||
width: vw(260);
|
||||
width: vw(240);
|
||||
height: vh(336);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
grid: {
|
||||
left: '4%',
|
||||
right: '4%',
|
||||
top: '10%',
|
||||
top: '4%',
|
||||
bottom: '-4%',
|
||||
containLabel: false
|
||||
},
|
||||
@@ -52,10 +52,8 @@
|
||||
axisLine: 'none',
|
||||
show: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(18)
|
||||
},
|
||||
fontSize: fitChartSize(18),
|
||||
verticalAlign: 'bottom',
|
||||
padding: [0, -fitChartSize(10), fitChartSize(10), 0],
|
||||
inside: true,
|
||||
@@ -78,7 +76,7 @@
|
||||
type: 'bar',
|
||||
barWidth: fitChartSize(12),
|
||||
showBackground: true,
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
backgroundStyle: {
|
||||
color: 'rgba(0, 150, 255, 0.15)'
|
||||
},
|
||||
@@ -99,7 +97,7 @@
|
||||
name: item.name,
|
||||
value: Number(item.value),
|
||||
itemStyle: {
|
||||
barBorderRadius: [0, 0, 0, 0],
|
||||
borderRadius: [0, 0, 0, 0],
|
||||
color: parseFloat(item.value) > 50 ? '#FF7021' : '#00CCFF'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<!-- 交通负载 -->
|
||||
<template>
|
||||
<div class="traffic-flow" :id="id" />
|
||||
</template>
|
||||
@@ -43,7 +44,7 @@
|
||||
left: '4%',
|
||||
right: '4%',
|
||||
top: '10%',
|
||||
bottom: '10%',
|
||||
bottom: '4%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
@@ -82,6 +83,14 @@
|
||||
type: 'bar',
|
||||
showBackground: true,
|
||||
barWidth: fitChartSize(16),
|
||||
label: {
|
||||
show: true,
|
||||
position: 'top',
|
||||
textStyle: {
|
||||
color: '#fff',
|
||||
fontSize: fitChartSize(10)
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
|
||||
@@ -10,20 +10,26 @@
|
||||
import { useScenicStore } from '@/stores/scenic'
|
||||
import { mode, socketBaseUrl, proSocketBaseUrl } from '@/utils/config'
|
||||
|
||||
import PubSub from 'pubsub-js'
|
||||
|
||||
const scenicStore = useScenicStore()
|
||||
|
||||
const { isConnected, sendMessage, dataRes } = useWebSocket(
|
||||
`${mode == 'dev' ? socketBaseUrl : proSocketBaseUrl}/ws/scenic-spot`
|
||||
)
|
||||
|
||||
let id = ref('')
|
||||
|
||||
watch(
|
||||
() => isConnected.value,
|
||||
() => [isConnected.value, id.value],
|
||||
(val) => {
|
||||
if (val) {
|
||||
sendMessage(JSON.stringify({ action: 'start', type: '', scenicSpotId: '1' }))
|
||||
}
|
||||
if (val[0] && val[1]) {
|
||||
sendMessage(JSON.stringify({ action: 'start', type: '', scenicSpotId: id.value }))
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => dataRes.value,
|
||||
(val) => {
|
||||
@@ -33,6 +39,9 @@
|
||||
case 'wordkOrderlist':
|
||||
scenicStore.setWordkOrderList(val.data)
|
||||
break
|
||||
case 'wordkOrderTotal':
|
||||
scenicStore.setWordkOrderData(val)
|
||||
break
|
||||
case 'scenicSpotData':
|
||||
scenicStore.setScenicSpotData(val.data)
|
||||
break
|
||||
@@ -54,10 +63,22 @@
|
||||
case 'userPortrait':
|
||||
scenicStore.setUserPortraitData(val)
|
||||
break
|
||||
case 'carShipData':
|
||||
scenicStore.setCarShipData(val.data)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
let scenicChange = null
|
||||
onMounted(() => {
|
||||
scenicChange = PubSub.subscribe('scenicChange', (msg, data) => {
|
||||
id.value = data.scenicSpotId
|
||||
})
|
||||
})
|
||||
onUnmounted(() => {
|
||||
PubSub.unsubscribe(scenicChange)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
Reference in New Issue
Block a user