
翠屏区交通应急指挥和信息化中心
项目介绍 Link to 项目介绍
本系统专为翠屏区设计,旨在提升交通管理和应急响应效率。系统包含以下核心模块:
综合交通监测:实时展示交通数据的大屏监控。 Link to 综合交通监测:实时展示交通数据的大屏监控。
道路客运监测 公路货运监测
科技治违监测
交通执法监测
渡口监测
交通工程监测
公路养护监测
安全应急监测
信息接入中心:负责维护和更新大屏显示的数据。 Link to 信息接入中心:负责维护和更新大屏显示的数据。
非法营运监测:监控和识别非法营运行为。 Link to 非法营运监测:监控和识别非法营运行为。
交通应急指挥:在紧急情况下协调和指挥交通资源。 Link to 交通应急指挥:在紧急情况下协调和指挥交通资源。
事件登记 指挥调度
主题配置
视频汇聚中心:集成第三方视频监控系统。 Link to 视频汇聚中心:集成第三方视频监控系统。
交通数据中心:与第三方平台进行数据交互和集成 Link to 交通数据中心:与第三方平台进行数据交互和集成
项目难点 Link to 项目难点
- Leaflet地图操作
- 需求:在地图上实现多图层的绘制与移除,包括点位、路线、箭头和区域;并能够绘制特定范围以检索该区域内的物资。
- 解决方案:利用Leaflet的图层管理功能,实现动态添加和移除图层;通过地理围栏技术划定区域,结合后端服务进行物资检索。
- 视频监控播放
- 需求:对接1078设备协议,实现第三方视频监控的播放。
- 解决方案:开发适配1078协议的接口,确保视频流的稳定接收和播放,同时优化视频加载和播放的用户体验。
- 门户系统
- 需求:提供开放接口,实现内部子系统的免登跳转和第三方系统接入。
- 解决方案:
- PC、H5门户系统免登实现:
- 门户跳转子系统时,通过地址栏传输token和projectId。
- 子系统携带这些信息调用免登校验接口,获取并保存用户信息。
- 登录成功后,用户可直接进入系统。
- H5门户系统在同一窗口中打开子系统(见下方代码示例):
门户端点击子系统跳转时,跳转到门户系统中的webview页面。
webview页面的URL携带token和projectId,并监听message事件以接收子系统发送的消息。
子系统接收这些信息,调用免登校验接口获取用户信息并保存。
登录成功后,子系统自定义顶部导航栏,通过发送消息给webview页面实现返回门户端的功能。
自定义多选弹窗组件
- 需求:开发一个基于Vue的自定义多选弹窗组件。
- 解决方案:利用Vue的组件化特性,设计和实现一个灵活、可复用的多选弹窗组件vue-select-dialog,支持多种选择模式和用户交互。
代码示例 Link to 代码示例
门户端跳转子系统 Link to 门户端跳转子系统
VUE
1234567891011121314151617181920212223
<script>
export default {
methods: {
goNewPage(data) {
let showTopBar = data.projectType !== 0; // 是否展示顶部标题栏[0内部系统]
let passData = JSON.stringify({
sysCode: data.sysCode,
token: this.vuex_token, // 门户系统登录时会存储的token
navigateUrl: location.href,
});
uni.navigateTo({
url:
"/pages/common/webview?url=" +
`${data.projectUrl}?data=${passData}` +
"&title=" +
data.appName +
"&showTopBar=" +
showTopBar,
});
},
},
};
</script>
门户端webview封装 Link to 门户端webview封装
VUE
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
<template>
<view class="wrap-view">
<view class="wrap-view-header" v-if="showTopBar">
<i class="uni-btn-icon icon" @click="goBack"></i>
<text class="text">{{ title }}</text>
</view>
<view
class="wrap-view-content"
:style="{
height: showTopBar ? 'calc(100vh - 88rpx)' : '100vh',
top: showTopBar ? '88rpx' : '0',
}"
>
<web-view
:webview-styles="webviewStyles"
:src="url"
@message="getMessage"
></web-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
showTopBar: true,
url: "",
title: "",
webviewStyles: {
progress: {
color: "#FF7200",
},
},
};
},
onLoad(params) {
this.initData(params);
},
methods: {
getMessage(e) {
const data = e.data;
if (typeof data !== "string") return;
let dataObj;
try {
dataObj = JSON.parse(data);
} catch (error) {
console.error("Failed to parse data:", error);
return;
}
if (dataObj.data === "back") {
this.autoBackIndex();
} else if (dataObj.data === "logout") {
this.autoLogOut();
}
},
autoBackIndex() {
uni.reLaunch({
url: "/pages/sys/workbench/index",
});
},
autoLogOut() {
this.$u.api.normal
.logOut()
.then((res) => {
this.$u.toast(res.message);
if (res.code == "1") {
setTimeout(() => {
uni.clearStorage();
}, 500);
}
})
.finally(() => {
setTimeout(() => {
uni.removeStorageSync("lifeData");
uni.reLaunch({
url: "/pages/sys/login/index",
});
}, 500);
});
},
initData(params) {
let { url, title, showTopBar, href } = params;
this.url = url;
this.title = title;
this.showTopBar = JSON.parse(showTopBar);
},
goBack() {
uni.reLaunch({
url: "/pages/sys/workbench/index",
});
},
handleMessage(event) {
const message = JSON.parse(event.detail.data);
if (message.type === "navigateBack") {
uni.reLaunch({
url: message.url,
});
}
},
},
mounted() {
// #ifdef H5
// A项目运行在H5时,如果不加这句代码,真机运行的时候,就无法监听到message事件
window.addEventListener("message", this.getMessage, false);
// #endif
},
};
</script>
<style lang="scss">
.wrap-view {
height: 100vh;
position: relative;
&-header {
height: 44px;
background-color: #3296fa;
color: #fff;
z-index: 9999 !important;
position: absolute;
font-size: 32rpx;
top: 0;
left: 0;
width: 100vw;
text-align: center;
line-height: 44px;
font-weight: 700;
.icon {
position: absolute;
left: 10rpx;
top: 50%;
transform: translateY(-50%);
font-size: 54rpx;
color: #fff;
}
}
&-content {
position: absolute;
left: 0;
width: 100vw;
}
}
</style>
子系统自定义顶部导航栏 Link to 子系统自定义顶部导航栏
JSON
123456789
[
{
"path": "pages/sys/workbench/index",
"style": {
"navigationBarTitleText": "工作台",
"navigationStyle": "custom"
}
}
]
JS
12345678910111213141516
let normalMsg = {
data: "back" // back 返回到主系统;logout 退出登录并返回到主系统登录页
};
export default function (msg = normalMsg) {
// #ifndef MP-WEIXIN
// const webview = web.webView
// if (typeof webview !== "undefined") {
// webview.postMessage({ data: "back" });
// }
// #endif
if (window) {
window.parent.postMessage(JSON.stringify(msg), "*");
}
}
VUE
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
<template>
<view class="wrap-view">
<view class="wrap-view-header" v-if="showTopBar">
<i class="uni-btn-icon icon" @click="goBack"></i>
<text class="text">{{ title }}</text>
</view>
<view
class="wrap-view-content"
:style="{
top: showTopBar ? '88rpx' : '0',
bottom: '100rpx'
}"
>
<slot name="content"></slot>
</view>
</view>
</template>
<script>
import webviewBack from "@/common/webviewBack";
export default {
props: {
title: {
type: String,
default: ""
},
showTopBar: {
type: Boolean,
default: true
}
},
data() {
return {};
},
onLoad(params) {
},
methods: {
goBack() {
webviewBack({
data: "back"
});
}
}
};
</script>
<style lang="scss">
.wrap-view {
position: relative;
&-header {
height: 88rpx;
background-color: #3296fa;
color: #fff;
z-index: 9999 !important;
position: fixed;
font-size: 32rpx;
top: 0;
left: 0;
width: 100vw;
text-align: center;
line-height: 88rpx;
font-weight: 700;
.icon {
position: absolute;
left: 10rpx;
top: 50%;
transform: translateY(-50%);
font-size: 54rpx;
color: #fff;
}
}
&-content {
position: absolute;
left: 0;
width: 100vw;
}
}
</style>
子系统使用自定义导航栏 Link to 子系统使用自定义导航栏
VUE
123456789101112131415
<template>
<ytNavbar title="工作台">
<template slot="content">
内容
</template>
</ytNavbar>
</template>
<script>
import ytNavbar from "@/components/ytNavbar/ytNavbar.vue";
export default {
components: {
ytNavbar
},
}
</script>
翠屏区交通应急指挥和信息化中心
Copyright © 毛杭飞 2025 - All Rights Reserved