feat:对接景区接口

This commit is contained in:
zjc
2025-01-17 19:15:14 +08:00
parent fd8ede8a32
commit 8eb966fa14
29 changed files with 510 additions and 315 deletions

10
package-lock.json generated
View File

@@ -14,7 +14,9 @@
"element-plus": "^2.9.0", "element-plus": "^2.9.0",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"hls.js": "^1.5.18", "hls.js": "^1.5.18",
"mitt": "^3.0.1",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"pubsub-js": "^1.9.5",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-countup-v3": "^1.4.2", "vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",
@@ -2580,8 +2582,7 @@
"node_modules/mitt": { "node_modules/mitt": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
"dev": true
}, },
"node_modules/mlly": { "node_modules/mlly": {
"version": "1.7.3", "version": "1.7.3",
@@ -2864,6 +2865,11 @@
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" "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": { "node_modules/punycode": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",

View File

@@ -15,7 +15,9 @@
"element-plus": "^2.9.0", "element-plus": "^2.9.0",
"flv.js": "^1.6.2", "flv.js": "^1.6.2",
"hls.js": "^1.5.18", "hls.js": "^1.5.18",
"mitt": "^3.0.1",
"pinia": "^2.2.6", "pinia": "^2.2.6",
"pubsub-js": "^1.9.5",
"vue": "^3.5.13", "vue": "^3.5.13",
"vue-countup-v3": "^1.4.2", "vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",

View File

@@ -65,3 +65,11 @@ export function getSpotApi() {
method: 'post' method: 'post'
}) })
} }
// 景区列表
export function getSpotListApi() {
return request({
url: '/fjtcc-api/api/largeScreen/spot/list',
method: 'get'
})
}

View File

@@ -1,6 +1,5 @@
<template> <template>
<div <div
class="progress"
:id="id" :id="id"
:style="{ :style="{
width: styleUtil.px2vw(width), width: styleUtil.px2vw(width),
@@ -10,10 +9,11 @@
</template> </template>
<script setup> <script setup>
import * as echarts from 'echarts'
import { guid } from '@/utils/util'
import styleUtil from '@/utils/styleUtil' import styleUtil from '@/utils/styleUtil'
import { fitChartSize } from '@/utils/dataUtil' import { fitChartSize } from '@/utils/dataUtil'
import { useEchart } from '@/hooks/echart'
const { id, setOption } = useEchart()
const props = defineProps({ const props = defineProps({
width: { width: {
@@ -23,14 +23,36 @@
height: { height: {
type: Number, type: Number,
default: () => 0 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 = { let defaultCofig = {
title: [ title: [
{ {
text: '45.5%', text: props.title,
x: 'center', x: 'center',
top: '34%', top: '34%',
textStyle: { textStyle: {
@@ -39,7 +61,7 @@
} }
}, },
{ {
text: '完成率', text: props.subTitle,
x: 'center', x: 'center',
top: '56%', top: '56%',
textStyle: { textStyle: {
@@ -99,7 +121,7 @@
}, },
data: [ data: [
{ {
value: 50 value: props.value
} }
] ]
}, },
@@ -151,27 +173,24 @@
}, },
data: [ data: [
{ {
value: 50 value: props.value
} }
] ]
} }
] ]
} }
onMounted(() => {
init()
})
const init = () => { const init = () => {
// 基于准备好的dom初始化echarts实例 if (!params) {
progressChart = echarts.init(document.getElementById(id.value)) params = defaultCofig
progressChart.setOption({ ...defaultCofig }) } else {
window.addEventListener('resize', resize) params.title[0].text = props.title
} params.title[1].text = props.subTitle
const resize = () => { params.series.map((item) => {
if (progressChart) { item.data[0].value = props.value
progressChart.dispose() })
init()
} }
setOption(params)
} }
</script> </script>

View File

@@ -1,11 +1,13 @@
<template> <template>
<div class="count-item"> <div class="count-item">
<div class="flex align-center"> <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> <span class="label">{{ label }}</span>
</div> </div>
<div class="count"> <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"> <div class="flex align-center">
<countup class="value" :end-val="count" :style="{ color: color }" /> <countup class="value" :end-val="count" :style="{ color: color }" />
<span class="suffix" :style="{ color: color }">{{ suffix }}</span> <span class="suffix" :style="{ color: color }">{{ suffix }}</span>
@@ -26,6 +28,10 @@
type: Number, type: Number,
default: 0 default: 0
}, },
type: {
type: Number,
default: 0
},
color: { color: {
type: String, type: String,
default: '#02f9fa' default: '#02f9fa'

View File

@@ -12,7 +12,12 @@
> >
{{ item.name }} {{ item.name }}
</li> </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 <li
class="nav-left-item" class="nav-left-item"
:style="{ :style="{
@@ -24,12 +29,12 @@
</li> </li>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <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> <span class="label"> {{ item.name }}</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>
</el-dropdown> --> </el-dropdown>
</ul> </ul>
<div class="title"> <div class="title">
<span>{{ title }}</span> <span>{{ title }}</span>
@@ -63,9 +68,9 @@
import title2 from '@/assets/images/title-2.png' import title2 from '@/assets/images/title-2.png'
import title2Select from '@/assets/images/title-2-select.png' import title2Select from '@/assets/images/title-2-select.png'
import { getWeatherApi } from '@/api/home' 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() const router = useRouter()
@@ -78,6 +83,18 @@
let isBack = ref(false) let isBack = ref(false)
let current = ref(0) let current = ref(0)
let otherScenic = ref('') let otherScenic = ref('')
let otherNav = ref([
{
name: '大窝景区'
},
{
name: '天坑景区'
},
{
name: '旅游环线'
}
])
let spotList = ref([])
// 补零 // 补零
const fillZero = (value) => { const fillZero = (value) => {
@@ -102,6 +119,7 @@
const handleBack = () => { const handleBack = () => {
router.go(-1) router.go(-1)
} }
const handleCommand = () => {}
// 点击导航 // 点击导航
const handleNav = (item, index) => { const handleNav = (item, index) => {
if (isSkip.value) { if (isSkip.value) {
@@ -111,15 +129,24 @@
otherScenic.value = '' otherScenic.value = ''
current.value = index current.value = index
title.value = item.name title.value = item.name
pubSub.publish('scenicChange', item)
} }
} }
// 获取天气数据 // 获取天气数据
const getWeather = async () => { const getWeather = async () => {
let res = await getWeatherApi() let res = await getWeatherApi()
weatherData.value = res.data weatherData.value = res.data
} }
// 获取景区列表
const getSpotList = async () => {
let res = await getSpotListApi()
spotList.value = res.data
}
// 设置当前路由导航栏 // 设置当前路由导航栏
const setNav = async () => { const setNav = async () => {
navLeft.value = []
navRight.value = []
switch (router.currentRoute.value.path) { switch (router.currentRoute.value.path) {
case '/home': case '/home':
title.value = '奉节县旅游指挥调度中心' title.value = '奉节县旅游指挥调度中心'
@@ -138,55 +165,29 @@
case '/scenic': case '/scenic':
isSkip.value = false isSkip.value = false
isBack.value = true isBack.value = true
let res = await getSpotApi() let res = await getSpotListApi()
navLeft.value = res.data.map((item) => { navLeft.value = res.data
return {
name: item.ssname,
id: item.id
}
})
title.value = navLeft.value[current.value].name title.value = navLeft.value[current.value].name
navRight.value = [] pubSub.publish('scenicChange', navLeft.value[current.value])
break break
case '/sentiment': case '/sentiment':
title.value = '舆情检测' title.value = '舆情检测'
navLeft.value = []
navRight.value = []
isBack.value = true isBack.value = true
break break
case '/workOrder': case '/workOrder':
title.value = '工单消息' title.value = '工单消息'
navLeft.value = []
navRight.value = []
isBack.value = true isBack.value = true
break break
case '/traffic': case '/traffic':
title.value = '交通大屏' title.value = '交通大屏'
navLeft.value = []
navRight.value = []
isBack.value = true isBack.value = true
break break
case '/monitor': case '/monitor':
title.value = '监控大屏' title.value = '监控大屏'
navLeft.value = [ let res1 = await getSpotListApi()
{ navLeft.value = res1.data
name: '奉节县',
path: '/sceneTesting'
},
{
name: '三峡之巅',
path: '/sceneTesting'
},
{
name: '白帝城',
path: '/sceneTesting'
},
{
name: '龙河桥',
path: '/sceneTesting'
}
]
navRight.value = []
isBack.value = true isBack.value = true
break break
case '/sceneTesting': case '/sceneTesting':
@@ -240,6 +241,7 @@
) )
onMounted(() => { onMounted(() => {
getWeather() getWeather()
getSpotList()
getCurrentDate() getCurrentDate()
setInterval(() => { setInterval(() => {
getCurrentDate() getCurrentDate()
@@ -253,7 +255,7 @@
left: vw(326); left: vw(326);
.weather { .weather {
position: absolute; position: absolute;
left: 0; right: 0;
top: vh(10); top: vh(10);
font-weight: 400; font-weight: 400;
font-size: vw(18); font-size: vw(18);
@@ -264,7 +266,7 @@
} }
.date { .date {
position: absolute; position: absolute;
right: 0; left: 0;
top: vh(10); top: vh(10);
font-weight: 400; font-weight: 400;
font-size: vw(18); font-size: vw(18);
@@ -293,7 +295,7 @@
} }
} }
.title { .title {
width: vw(3133); width: vw(3170);
height: vh(120); height: vh(120);
line-height: vh(90); line-height: vh(90);
text-align: center; text-align: center;
@@ -316,7 +318,7 @@
} }
.nav-left { .nav-left {
position: absolute; position: absolute;
right: vw(2100); right: vw(2120);
top: vh(34); top: vh(34);
display: flex; display: flex;
&-item { &-item {
@@ -338,7 +340,7 @@
} }
.nav-right { .nav-right {
position: absolute; position: absolute;
left: vw(2110); left: vw(2130);
top: vh(34); top: vh(34);
display: flex; display: flex;
&-item { &-item {

View File

@@ -31,7 +31,7 @@ export function useWebSocket(url) {
} }
const sendMessage = (message) => { const sendMessage = (message) => {
if (socket.value) { if (socket.value && isConnected.value) {
socket.value.send(message) socket.value.send(message)
} }
} }

View File

@@ -46,10 +46,9 @@ export const useHomeStore = defineStore('home', () => {
let wordkOrderList = ref([]) let wordkOrderList = ref([])
// 工单统计 // 工单统计
let wordkOrderData = ref({ let wordkOrderData = ref({
toDayData: { count: 15, end: 0, rate: '0.0' }, toDayData: { count: 0, end: 0, rate: '0.0' },
warnData: { count: 15, end: 0, rate: '0.0' } warnData: { count: 0, end: 0, rate: '0.0' }
}) })
// 交通信息 // 交通信息
let trafficInfoData = ref({ let trafficInfoData = ref({
data: { data: {

View File

@@ -13,21 +13,30 @@ export const useScenicStore = defineStore('scenic', () => {
// 景区排队信息 // 景区排队信息
let scenicQueueData = ref({ dataList: [], header: { jrcp: 0, jrjdrs: 0, pdcxsj: 0, pdrs: 0 } }) 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({ let stopCarData = ref({
dataList: [], dataList: [],
dataLists: [], dataLists: [],
headList: [] headList: [],
info: {
count: 0,
remain: 0
}
}) })
// 安全信息 // 安全信息
let secureData = ref({ let secureData = ref({
dataList: [] dataList: [],
headList: [
{ name: '当前告警总数', count: 0, type: 0 },
{ name: '安全告警总数', count: 0, type: 0 },
{ name: '已解除告警数', count: 0, type: 0 }
]
}) })
// 交通信息 // 交通信息
let trafficData = ref({ let trafficData = ref({
infoList: [ infoList: [
{ name: '总通景路段', value: 100 }, { name: '总通景路段', value: 0 },
{ name: '通景路段拥堵', value: 0 }, { name: '通景路段拥堵', value: 0 },
{ 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 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) => { const setWordkOrderList = (val) => {
wordkOrderList.value = val wordkOrderList.value = val
} }
@@ -75,6 +106,7 @@ export const useScenicStore = defineStore('scenic', () => {
scenicSpotData.value = val scenicSpotData.value = val
} }
return { return {
wordkOrderData,
wordkOrderList, wordkOrderList,
scenicSpotData, scenicSpotData,
scenicQueueData, scenicQueueData,
@@ -83,6 +115,8 @@ export const useScenicStore = defineStore('scenic', () => {
secureData, secureData,
trafficData, trafficData,
userPortraitData, userPortraitData,
carShipData,
setWordkOrderData,
setWordkOrderList, setWordkOrderList,
setScenicSpotData, setScenicSpotData,
setScenicQueueData, setScenicQueueData,
@@ -90,6 +124,7 @@ export const useScenicStore = defineStore('scenic', () => {
setStopCarData, setStopCarData,
setSecureData, setSecureData,
setTrafficData, setTrafficData,
setUserPortraitData setUserPortraitData,
setCarShipData
} }
}) })

View File

@@ -4,7 +4,7 @@ export const proBaseUrl = 'http://192.168.77.200'
export const socketBaseUrl = 'ws://36.138.38.16:81' export const socketBaseUrl = 'ws://36.138.38.16:81'
export const proSocketBaseUrl = 'ws://192.168.77.200:8060' export const proSocketBaseUrl = 'ws://192.168.77.200:8060'
export const mode = 'pro' export const mode = 'pro' // 测试 dev 正式 pro
export const devToken = export const devToken =
'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.BTxvu6jUWbN0qONWf5K6VzXopE8T8qXzKuX-mij21VJT4U0LdgnqToyqeNDQ2OyJ6cvpdJBzQ9mEEb-dnwrTpQ' 'eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6ImE1OWFmNWYwLTU3OWItNDJkNy1hZDJhLTY0Y2JlODA5ZWI1NiJ9.BTxvu6jUWbN0qONWf5K6VzXopE8T8qXzKuX-mij21VJT4U0LdgnqToyqeNDQ2OyJ6cvpdJBzQ9mEEb-dnwrTpQ'

View File

@@ -55,7 +55,7 @@
v-for="(item, index) in homeStore.scenicBearData.info" v-for="(item, index) in homeStore.scenicBearData.info"
:key="index" :key="index"
> >
<gauge :value="item.value" /> <gauge :value="parseFloat(item.value)" />
<span class="statistic-title">{{ item.name }}</span> <span class="statistic-title">{{ item.name }}</span>
</div> </div>
</div> </div>
@@ -131,10 +131,10 @@
</template> </template>
<script setup> <script setup>
import top from './top.vue' import top from './top'
import age from './age.vue' import age from './age'
import gauge from './gauge.vue' import gauge from './gauge'
import ticket from './ticket.vue' import ticket from './ticket'
import countup from 'vue-countup-v3' import countup from 'vue-countup-v3'
import { useHomeStore } from '@/stores/home' import { useHomeStore } from '@/stores/home'

View File

@@ -69,7 +69,7 @@
<span class="text">工单完成数</span> <span class="text">工单完成数</span>
<div class="progress-1"> <div class="progress-1">
<el-progress <el-progress
:percentage="homeStore.wordkOrderData.toDayData.rate" :percentage="parseFloat(homeStore.wordkOrderData.toDayData.rate)"
:show-text="false" :show-text="false"
/> />
</div> </div>
@@ -91,7 +91,7 @@
<span class="text">工单完成数</span> <span class="text">工单完成数</span>
<div class="progress-2"> <div class="progress-2">
<el-progress <el-progress
:percentage="homeStore.wordkOrderData.warnData.rate" :percentage="parseFloat(homeStore.wordkOrderData.warnData.rate)"
:show-text="false" :show-text="false"
/> />
</div> </div>

View File

@@ -231,7 +231,7 @@
</div> </div>
<div> <div>
<div class="occupancy"> <div class="occupancy">
<Title3 title="酒店入住人数及入住率" /> <Title3 title="酒店入住率" />
</div> </div>
<occupancy :list="homeStore.hotelData?.list" /> <occupancy :list="homeStore.hotelData?.list" />
</div> </div>

View File

@@ -25,11 +25,9 @@
watch( watch(
() => props.value, () => props.value,
(val) => { (val) => {
if (val) { setTimeout(() => {
nextTick(() => {
init() init()
}) }, 1000)
}
}, },
{ immediate: true } { immediate: true }
) )
@@ -44,7 +42,7 @@
endAngle: 0, endAngle: 0,
min: 0, min: 0,
max: 100, max: 100,
radius: '100%', radius: '120%',
splitNumber: 10, splitNumber: 10,
center: ['50%', '60%'], center: ['50%', '60%'],
itemStyle: { itemStyle: {
@@ -65,11 +63,11 @@
} }
], ],
global: false global: false
}, }
shadowColor: 'rgba(0,138,255,0.45)', // shadowColor: 'red',
shadowBlur: 10, // shadowBlur: 10,
shadowOffsetX: 2, // shadowOffsetX: 2,
shadowOffsetY: 2 // shadowOffsetY: 2
}, },
progress: { progress: {
show: true, show: true,
@@ -130,7 +128,7 @@
<style lang="scss" scoped> <style lang="scss" scoped>
.gauge { .gauge {
width: vw(70); width: vw(120);
height: vh(50); height: vh(50);
} }
</style> </style>

View File

@@ -34,7 +34,7 @@
return props.list.map((item) => { return props.list.map((item) => {
return { return {
name: item.name, name: item.name,
value: item.count, value: item.duration,
itemStyle: { itemStyle: {
color: { color: {
type: 'linear', type: 'linear',
@@ -61,7 +61,7 @@
return props.list.map((item) => { return props.list.map((item) => {
return { return {
name: item.name, name: item.name,
value: item.count, value: item.duration,
itemStyle: { itemStyle: {
color: '#fff', color: '#fff',
opacity: 1 opacity: 1
@@ -70,7 +70,7 @@
}) })
} }
const setYAxisData = () => { const setYAxisData = () => {
return props.list.map((item) => item.count) return props.list.map((item) => item.duration)
} }
const init = () => { const init = () => {
if (!params) { if (!params) {
@@ -110,10 +110,10 @@
axisTick: { axisTick: {
show: false show: false
}, },
data: [],
axisLabel: { axisLabel: {
show: false show: false
} },
data: []
}, },
{ {
type: 'category', type: 'category',
@@ -122,10 +122,8 @@
axisLine: 'none', axisLine: 'none',
show: true, show: true,
axisLabel: { axisLabel: {
textStyle: {
color: '#fff', color: '#fff',
fontSize: fitChartSize(12) fontSize: fitChartSize(12),
},
verticalAlign: 'bottom', verticalAlign: 'bottom',
padding: [0, 0, 6, 0], padding: [0, 0, 6, 0],
inside: true, inside: true,
@@ -150,7 +148,7 @@
type: 'bar', type: 'bar',
barWidth: fitChartSize(8), barWidth: fitChartSize(8),
showBackground: true, showBackground: true,
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
backgroundStyle: { backgroundStyle: {
color: 'rgba(0, 150, 255, 0.15)' color: 'rgba(0, 150, 255, 0.15)'
}, },

View File

@@ -85,7 +85,7 @@
grid: { grid: {
left: '4%', left: '4%',
right: '4%', right: '4%',
top: '14%', top: '16%',
bottom: '4%', bottom: '4%',
containLabel: false containLabel: false
}, },
@@ -122,10 +122,8 @@
axisLine: 'none', axisLine: 'none',
show: true, show: true,
axisLabel: { axisLabel: {
textStyle: {
color: '#fff', color: '#fff',
fontSize: fitChartSize(12) fontSize: fitChartSize(12),
},
verticalAlign: 'bottom', verticalAlign: 'bottom',
padding: [0, 0, 10, 0], padding: [0, 0, 10, 0],
inside: true, inside: true,
@@ -150,7 +148,7 @@
type: 'bar', type: 'bar',
barWidth: fitChartSize(8), barWidth: fitChartSize(8),
showBackground: true, showBackground: true,
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
backgroundStyle: { backgroundStyle: {
color: 'rgba(0, 150, 255, 0.15)' color: 'rgba(0, 150, 255, 0.15)'
}, },

View File

@@ -13,8 +13,8 @@
const { id, setOption } = useEchart() const { id, setOption } = useEchart()
let x = 15 let x = 25
let y = 25 let y = 35
let params = null let params = null
watch( watch(
@@ -38,7 +38,7 @@
type: 'pie', type: 'pie',
clockwise: false, clockwise: false,
silent: true, silent: true,
radius: [`${x * (index + 1)}%`, `${y + index * 15}%`], radius: [`${x * (index + 1)}%`, `${y + index * 25}%`],
center: ['50%', '40%'], center: ['50%', '40%'],
label: { show: false }, label: { show: false },
labelLine: { show: false }, labelLine: { show: false },
@@ -66,7 +66,7 @@
legend: { legend: {
show: true, show: true,
x: 'center', x: 'center',
y: '70%', y: '74%',
itemHeight: fitChartSize(12), itemHeight: fitChartSize(12),
itemWidth: fitChartSize(12), itemWidth: fitChartSize(12),
itemGap: fitChartSize(6), itemGap: fitChartSize(6),

View File

@@ -52,10 +52,8 @@
axisLine: 'none', axisLine: 'none',
show: true, show: true,
axisLabel: { axisLabel: {
textStyle: {
color: '#fff', color: '#fff',
fontSize: fitChartSize(18) fontSize: fitChartSize(18),
},
verticalAlign: 'bottom', verticalAlign: 'bottom',
padding: [0, -fitChartSize(10), fitChartSize(10), 0], padding: [0, -fitChartSize(10), fitChartSize(10), 0],
inside: true, inside: true,
@@ -78,7 +76,7 @@
type: 'bar', type: 'bar',
barWidth: fitChartSize(12), barWidth: fitChartSize(12),
showBackground: true, showBackground: true,
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
backgroundStyle: { backgroundStyle: {
color: 'rgba(0, 150, 255, 0.15)' color: 'rgba(0, 150, 255, 0.15)'
}, },
@@ -99,7 +97,7 @@
name: item.name, name: item.name,
value: Number(item.value), value: Number(item.value),
itemStyle: { itemStyle: {
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
color: parseFloat(item.value) > 50 ? '#FF7021' : '#00CCFF' color: parseFloat(item.value) > 50 ? '#FF7021' : '#00CCFF'
} }
} }

View File

@@ -34,6 +34,7 @@
return props.list.map((item) => { return props.list.map((item) => {
return { return {
...item, ...item,
value: item.occupiedPercentage,
itemStyle: { itemStyle: {
color: { color: {
type: 'linear', type: 'linear',
@@ -60,6 +61,7 @@
return props.list.map((item) => { return props.list.map((item) => {
return { return {
...item, ...item,
value: item.occupiedPercentage,
itemStyle: { itemStyle: {
color: '#fff', color: '#fff',
opacity: 1 opacity: 1
@@ -68,7 +70,7 @@
}) })
} }
const getYAxisData = () => { const getYAxisData = () => {
return props.list.map((item) => item.value) return props.list.map((item) => item.occupied)
} }
const init = () => { const init = () => {
if (!params) { if (!params) {
@@ -148,7 +150,7 @@
type: 'bar', type: 'bar',
barWidth: fitChartSize(8), barWidth: fitChartSize(8),
showBackground: true, showBackground: true,
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
backgroundStyle: { backgroundStyle: {
color: 'rgba(0, 150, 255, 0.15)' color: 'rgba(0, 150, 255, 0.15)'
}, },

View File

@@ -83,8 +83,16 @@
type: 'bar', type: 'bar',
showBackground: true, showBackground: true,
barWidth: fitChartSize(8), barWidth: fitChartSize(8),
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
fontSize: fitChartSize(10)
}
},
itemStyle: { itemStyle: {
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
color: { color: {
type: 'linear', type: 'linear',
x: 0, x: 0,

View File

@@ -126,7 +126,6 @@
params.series[0].data = getSeriesData() params.series[0].data = getSeriesData()
params.series[1].data = getSeriesData() params.series[1].data = getSeriesData()
} }
console.log(params, 'params')
setOption(params) setOption(params)
} }
</script> </script>

View File

@@ -20,15 +20,15 @@
(val) => { (val) => {
if (val && !map.value) { if (val && !map.value) {
setTimeout(() => { setTimeout(() => {
initMap('big-car-ship', 109.491961, 31.024285, 16) initMap('big-car-ship', 109.552461, 31.049607, 15)
addMarker(carIcon, [109.491045, 31.028725], [36, 50]) addMarker(carIcon, [109.551419, 31.050001], [36, 50])
addMarker(carIcon, [109.483266, 31.024718], [36, 50]) addMarker(shipIcon, [109.551671, 31.04847], [36, 50])
addMarker(shipIcon, [109.479062, 31.021499], [36, 50]) }, 1000)
addMarker(shipIcon, [109.488907, 31.017476], [36, 50])
}, 500)
} }
} }
) )
onMounted(() => {})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
@@ -42,15 +42,15 @@
:deep(.el-dialog) { :deep(.el-dialog) {
width: vw(2540); width: vw(2540);
height: vh(900); height: vh(900);
padding: 0; padding: vh(40) vw(40);
} }
:deep(.el-dialog__header) { :deep(.el-dialog__header) {
padding-bottom: 0 !important; padding-bottom: 0 !important;
} }
} }
.big-car-ship { .big-car-ship {
width: vw(2540); width: 100%;
height: vh(900); height: vh(820);
} }
.close { .close {
cursor: pointer; cursor: pointer;

View File

@@ -39,35 +39,55 @@
<div class="footer"> <div class="footer">
<div class="flex"> <div class="flex">
<div class="item"> <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>
<div class="bg"> <div class="bg">
<span class="label">今日工单总条数</span> <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>
<div class="bg"> <div class="bg">
<span class="label">工单完成数</span> <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>
</div> </div>
<div class="item"> <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>
<div class="bg"> <div class="bg">
<span class="label">今日工单总条</span> <span class="label">今日紧急工单数</span>
<span class="value"> <countup :endVal="1234" /></span> <span class="value error">
<countup :end-val="scenicStore.wordkOrderData.warnData.count" />
</span>
</div> </div>
<div class="bg"> <div class="bg">
<span class="label">工单完成数</span> <span class="label">紧急工单完成数</span>
<span class="value"> <countup :endVal="1234" /></span> <span class="value">
<countup :end-val="scenicStore.wordkOrderData.warnData.end" />
</span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="flex align-center justify-between"> <div class="flex align-center justify-between">
<div> <div>
<vue3-seamless-scroll <Vue3SeamlessScroll
class="list" class="list"
:list="scenicStore.wordkOrderList" :list="scenicStore.wordkOrderList"
:limitScrollNum="3" :limitScrollNum="3"
@@ -82,7 +102,7 @@
{{ item.title }} {{ item.title }}
</p> </p>
</div> </div>
</vue3-seamless-scroll> </Vue3SeamlessScroll>
</div> </div>
<img class="more" src="@/assets/images/more-col.png" alt="查看更多" @click="handleMore" /> <img class="more" src="@/assets/images/more-col.png" alt="查看更多" @click="handleMore" />
</div> </div>
@@ -203,8 +223,14 @@
.value { .value {
font-weight: bold; font-weight: bold;
font-size: vw(28); font-size: vw(28);
color: #fff;
}
.success {
color: #02f9fa; color: #02f9fa;
} }
.error {
color: #e21b1b;
}
} }
} }
.list { .list {

View File

@@ -40,7 +40,13 @@
<div class="box mr-8"> <div class="box mr-8">
<Title1 title="景区承载" /> <Title1 title="景区承载" />
<div class="flex"> <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"> <div class="flex flex-1 justify-between">
<count-item <count-item
label="景区当前人数" label="景区当前人数"
@@ -69,14 +75,24 @@
<div class="box-1 mr-8"> <div class="box-1 mr-8">
<Title1 title="停车信息" /> <Title1 title="停车信息" />
<div class="flex"> <div class="flex">
<div class="flex"> <div class="height70 flex flex-1">
<circle-progress :width="140" :height="70" /> <circle-progress
<circle-progress :width="140" :height="70" /> v-for="(item, index) in garageList"
<circle-progress :width="140" :height="70" /> :key="index"
:width="140"
:height="70"
:value="item.ratio"
:title="item.over"
:subTitle="`${item.name}剩余`"
/>
</div> </div>
<div class="ml-20 flex flex-1 justify-between"> <div class="ml-20 flex flex-1 justify-between">
<count-item label="总车位数" :count="561" suffix="个" /> <count-item label="总车位数" :count="scenicStore.stopCarData.info.count" suffix="个" />
<count-item label="剩余车位数" :count="15" suffix="个" /> <count-item
label="剩余车位数"
:count="scenicStore.stopCarData.info.remain"
suffix="个"
/>
</div> </div>
</div> </div>
<div class="flex"> <div class="flex">
@@ -103,9 +119,14 @@
<div class="box-2"> <div class="box-2">
<Title1 title="安全信息 " /> <Title1 title="安全信息 " />
<div class="count-box flex"> <div class="count-box flex">
<count-item label="当前告警总数" :count="561" suffix="次" /> <count-item
<count-item label="安全告警总数" :count="561" suffix="次" /> v-for="item in scenicStore.secureData.headList"
<count-item label="已解除告警数" :count="561" /> :label="item.name"
:count="item.count"
:type="item.type"
:color="item.type == 0 ? '#0096FF' : '#E21B1B'"
suffix="次"
/>
</div> </div>
<div class="border flex-1"> <div class="border flex-1">
<div class="pt-10"> <div class="pt-10">
@@ -115,7 +136,7 @@
label="安全告警占比" label="安全告警占比"
:dataList="scenicStore.secureData.dataList" :dataList="scenicStore.secureData.dataList"
:total="alarmTotal" :total="alarmTotal"
:width="460" :width="440"
:height="300" :height="300"
/> />
</div> </div>
@@ -140,11 +161,21 @@
</div> </div>
<div class="border mr-8"> <div class="border mr-8">
<Title3 title="拥堵次数占比" /> <Title3 title="拥堵次数占比" />
<jam :width="220" :height="160" /> <jam
:width="220"
:height="300"
sub-title="拥堵频次总数"
:list="scenicStore.trafficData.data.countRate"
/>
</div> </div>
<div class="border"> <div class="border">
<Title3 title="拥堵时长占比" /> <Title3 title="拥堵时长占比" />
<jam :width="220" :height="160" /> <jam
:width="220"
:height="300"
sub-title="拥堵总时长"
:list="scenicStore.trafficData.data.countRate"
/>
</div> </div>
</div> </div>
</div> </div>
@@ -167,7 +198,7 @@
<span class="text">{{ item.name }}</span> <span class="text">{{ item.name }}</span>
<div class="progress"> <div class="progress">
<el-progress <el-progress
:percentage="item.value" :percentage="parseFloat(item.value)"
:show-text="false" :show-text="false"
:color=" :color="
item.name == '女' item.name == '女'
@@ -186,7 +217,7 @@
</div> </div>
<div class="border flex-1"> <div class="border flex-1">
<Title3 title="购票来源" /> <Title3 title="购票来源" />
<div class="count">总人数<countup endVal="124563" /></div> <div class="count">总人数<countup :end-val="channelTotal" /></div>
<ticket /> <ticket />
</div> </div>
</div> </div>
@@ -196,53 +227,65 @@
<Title1 title="车船信息" /> <Title1 title="车船信息" />
<div class="flex mb-6"> <div class="flex mb-6">
<div class="border mr-8 pt-10 pb-10"> <div class="border mr-8 pt-10 pb-10">
<div class="flex justify-between">
<Title2 title="景区车辆" /> <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"> <div class="car-box mt-10">
<img class="icon" src="@/assets/images/icon-6.png" /> <img class="icon" src="@/assets/images/icon-6.png" />
<div class="car-item pr-20"> <div class="car-item pr-20">
<div class="label">车总数</div> <div class="label">运营车辆</div>
<div class="value">130</div> <div class="value flex">
<countup :end-val="scenicStore.carShipData.car.count?.drivingCount" />
<span class="suffix"> </span>
</div>
</div> </div>
<div class="car-item"> <div class="car-item">
<div class="label">今日累计运营(班次)</div> <div class="label">空闲车辆</div>
<div class="value">130</div> <div class="value flex">
<countup :end-val="scenicStore.carShipData.car.count?.nonDrivingCount" />
<span class="suffix"> </span>
</div> </div>
</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> </div>
<div class="border pt-10 pb-10"> <div class="border pt-10 pb-10">
<div class="flex justify-between">
<Title2 title="景区船只" /> <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"> <div class="car-box mt-10">
<img class="icon" src="@/assets/images/icon-6.png" /> <img class="icon" src="@/assets/images/icon-6.png" />
<div class="car-item pr-20"> <div class="car-item pr-20">
<div class="label">船总数</div> <div class="label">运营船只</div>
<div class="value">130</div> <div class="value flex">
<countup :end-val="scenicStore.carShipData.ship.count?.drivingCount" />
<span class="suffix"></span>
</div>
</div> </div>
<div class="car-item"> <div class="car-item">
<div class="label">今日累计运营(班次)</div> <div class="label">空闲船只</div>
<div class="value">130</div> <div class="value flex">
<countup :end-val="scenicStore.carShipData.ship.count?.nonDrivingCount" />
<span class="suffix"></span>
</div> </div>
</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> </div>
</div> </div>
@@ -273,6 +316,21 @@
const scenicStore = useScenicStore() const scenicStore = useScenicStore()
const { initMap, addMarker } = useMap() 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(() => { const ageTotal = computed(() => {
return scenicStore.userPortraitData.data.genderRate.reduce((pre, cur) => { return scenicStore.userPortraitData.data.genderRate.reduce((pre, cur) => {
return pre + parseInt(cur.count) return pre + parseInt(cur.count)
@@ -313,12 +371,26 @@
}) })
let show = ref(false) 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(() => { onMounted(() => {
initMap('car-ship', 109.491961, 31.024285, 13) initMap('car-ship', 109.552461, 31.049607, 15)
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])
}) })
</script> </script>
@@ -329,6 +401,9 @@
:deep(.anchorBL) { :deep(.anchorBL) {
display: none; display: none;
} }
.height70 {
height: vh(70);
}
.legend { .legend {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -399,29 +474,7 @@
height: vh(904); 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 { .container {
margin: vh(120) 0 0 vw(10); margin: vh(120) 0 0 vw(10);
.count-box { .count-box {
@@ -491,11 +544,23 @@
font-size: vw(24); font-size: vw(24);
color: #02f9fa; color: #02f9fa;
margin-top: vh(6); 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 { .car-ship {
width: vw(660); width: vw(660);
height: vh(240); height: vh(250);
} }
.full { .full {
cursor: pointer; cursor: pointer;

View File

@@ -22,77 +22,78 @@
type: Number, type: Number,
default: () => 0 default: () => 0
}, },
config: { list: {
type: Object, type: Array,
default: () => { default: () => []
return {} },
} title: {
type: [String, Number],
default: () => ''
},
subTitle: {
type: [String, Number],
default: () => ''
} }
}) })
const { id, setOption } = useEchart() const { id, setOption } = useEchart()
var colorList = ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA', ''] watch(
var title = ['企业', '农业', '工业', '纺织'] () => props.list,
var dataValue = ['15', '30', '35', '20'] (val) => {
var dataList = title.map((item, index) => { setTimeout(() => {
init()
}, 1000)
},
{ immediate: true }
)
let params = null
const getSeriesData = () => {
return props.list.map((item) => {
return { return {
name: item, ...item,
value: dataValue[index] value: parseFloat(item.value)
} }
}) })
}
var defaultCofig = { const getTotal = () => {
color: colorList, 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: [ 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', type: 'pie',
center: ['50%', '40%'], center: ['50%', '40%'],
@@ -105,9 +106,7 @@
show: true, show: true,
position: 'center', position: 'center',
fontWeight: 'bold', fontWeight: 'bold',
formatter: function (o) { formatter: formatLabel(),
return `{value|123456}` + '\n' + `{name|整改率}`
},
rich: { rich: {
value: { value: {
color: '#fff', color: '#fff',
@@ -116,7 +115,7 @@
padding: [0, 0, 5, 0] padding: [0, 0, 5, 0]
}, },
name: { name: {
color: '#7894A8', color: '#fff',
fontSize: fitChartSize(12) fontSize: fitChartSize(12)
} }
} }
@@ -124,21 +123,20 @@
labelLine: { labelLine: {
show: false show: false
}, },
data: dataList data: getSeriesData()
} }
] ]
} }
const init = () => { const init = () => {
setOption({ if (!params) {
...defaultCofig, params = defaultCofig
...props.config } else {
}) params.series[0].label.formatter = formatLabel()
params.series[0].data = getSeriesData()
}
setOption(params)
} }
onMounted(() => {
init()
})
</script> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>

View File

@@ -13,8 +13,8 @@
const { id, setOption } = useEchart() const { id, setOption } = useEchart()
let x = 15 let x = 30
let y = 25 let y = 40
let params = null let params = null
watch( watch(
@@ -38,7 +38,7 @@
type: 'pie', type: 'pie',
clockwise: false, clockwise: false,
silent: true, silent: true,
radius: [`${x * (index + 1)}%`, `${y + index * 15}%`], radius: [`${x * (index + 1)}%`, `${y + index * 30}%`],
center: ['50%', '40%'], center: ['50%', '40%'],
label: { show: false }, label: { show: false },
labelLine: { show: false }, labelLine: { show: false },
@@ -100,7 +100,7 @@
<style scoped lang="scss"> <style scoped lang="scss">
.ticket { .ticket {
width: vw(260); width: vw(240);
height: vh(336); height: vh(336);
} }
</style> </style>

View File

@@ -25,7 +25,7 @@
grid: { grid: {
left: '4%', left: '4%',
right: '4%', right: '4%',
top: '10%', top: '4%',
bottom: '-4%', bottom: '-4%',
containLabel: false containLabel: false
}, },
@@ -52,10 +52,8 @@
axisLine: 'none', axisLine: 'none',
show: true, show: true,
axisLabel: { axisLabel: {
textStyle: {
color: '#fff', color: '#fff',
fontSize: fitChartSize(18) fontSize: fitChartSize(18),
},
verticalAlign: 'bottom', verticalAlign: 'bottom',
padding: [0, -fitChartSize(10), fitChartSize(10), 0], padding: [0, -fitChartSize(10), fitChartSize(10), 0],
inside: true, inside: true,
@@ -78,7 +76,7 @@
type: 'bar', type: 'bar',
barWidth: fitChartSize(12), barWidth: fitChartSize(12),
showBackground: true, showBackground: true,
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
backgroundStyle: { backgroundStyle: {
color: 'rgba(0, 150, 255, 0.15)' color: 'rgba(0, 150, 255, 0.15)'
}, },
@@ -99,7 +97,7 @@
name: item.name, name: item.name,
value: Number(item.value), value: Number(item.value),
itemStyle: { itemStyle: {
barBorderRadius: [0, 0, 0, 0], borderRadius: [0, 0, 0, 0],
color: parseFloat(item.value) > 50 ? '#FF7021' : '#00CCFF' color: parseFloat(item.value) > 50 ? '#FF7021' : '#00CCFF'
} }
} }

View File

@@ -1,3 +1,4 @@
<!-- 交通负载 -->
<template> <template>
<div class="traffic-flow" :id="id" /> <div class="traffic-flow" :id="id" />
</template> </template>
@@ -43,7 +44,7 @@
left: '4%', left: '4%',
right: '4%', right: '4%',
top: '10%', top: '10%',
bottom: '10%', bottom: '4%',
containLabel: true containLabel: true
}, },
xAxis: { xAxis: {
@@ -82,6 +83,14 @@
type: 'bar', type: 'bar',
showBackground: true, showBackground: true,
barWidth: fitChartSize(16), barWidth: fitChartSize(16),
label: {
show: true,
position: 'top',
textStyle: {
color: '#fff',
fontSize: fitChartSize(10)
}
},
itemStyle: { itemStyle: {
color: { color: {
type: 'linear', type: 'linear',

View File

@@ -10,20 +10,26 @@
import { useScenicStore } from '@/stores/scenic' import { useScenicStore } from '@/stores/scenic'
import { mode, socketBaseUrl, proSocketBaseUrl } from '@/utils/config' import { mode, socketBaseUrl, proSocketBaseUrl } from '@/utils/config'
import PubSub from 'pubsub-js'
const scenicStore = useScenicStore() const scenicStore = useScenicStore()
const { isConnected, sendMessage, dataRes } = useWebSocket( const { isConnected, sendMessage, dataRes } = useWebSocket(
`${mode == 'dev' ? socketBaseUrl : proSocketBaseUrl}/ws/scenic-spot` `${mode == 'dev' ? socketBaseUrl : proSocketBaseUrl}/ws/scenic-spot`
) )
let id = ref('')
watch( watch(
() => isConnected.value, () => [isConnected.value, id.value],
(val) => { (val) => {
if (val) { if (val[0] && val[1]) {
sendMessage(JSON.stringify({ action: 'start', type: '', scenicSpotId: '1' })) sendMessage(JSON.stringify({ action: 'start', type: '', scenicSpotId: id.value }))
}
} }
},
{ immediate: true }
) )
watch( watch(
() => dataRes.value, () => dataRes.value,
(val) => { (val) => {
@@ -33,6 +39,9 @@
case 'wordkOrderlist': case 'wordkOrderlist':
scenicStore.setWordkOrderList(val.data) scenicStore.setWordkOrderList(val.data)
break break
case 'wordkOrderTotal':
scenicStore.setWordkOrderData(val)
break
case 'scenicSpotData': case 'scenicSpotData':
scenicStore.setScenicSpotData(val.data) scenicStore.setScenicSpotData(val.data)
break break
@@ -54,10 +63,22 @@
case 'userPortrait': case 'userPortrait':
scenicStore.setUserPortraitData(val) scenicStore.setUserPortraitData(val)
break 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> </script>
<style scoped lang="scss"></style> <style scoped lang="scss"></style>