This commit is contained in:
13684185576
2025-07-16 19:44:39 +08:00
parent 224fddb6af
commit 46fb5f3ce5
1122 changed files with 243510 additions and 0 deletions

View File

@ -0,0 +1,107 @@
<template>
<ul class="patrol-missions" v-if="showModel" infinite-scroll-distance="1" v-infinite-scroll="loadList" v-loading="loading">
<li class="test-item" v-for="(item, index) in list" :key="`info${index}`">
<div class="person-img"><img src="@/assets/images/person.png" /></div>
<div class="info">
<div class="text one_text_detail f16">{{ item.qwmc }}</div>
<div class="text lh30">负责人:{{ item.xm }}</div>
<div class="lh30">电话:{{ item.lxdh }}</div>
<div class="one_text_detail">巡逻路线:{{ item.bxxmc }}</div>
</div>
</li>
<p class="tc" v-if="list.length > 0 && noMore && !loading ">没有数据了</p>
<MOSTY.Empty :show="true" :imgSize="100" v-if="list.length == 0 && !loading"></MOSTY.Empty>
</ul>
</template>
<script setup>
import * as MOSTY from "@/components/MyComponents/index";
import { qcckGet } from "@/api/qcckApi.js";
import { onMounted, ref } from 'vue';
const list = ref([])
const loading = ref(false);
const page = ref(1);
const total = ref(0)
const noMore = ref(false)
const showModel = ref(false)
onMounted(()=>{
showModel.value = true;
getDateMeta()
})
// 更新数据
const getDateMeta = () =>{
loading.value = true;
let params = {
pageSize:10,
pageCurrent:page.value,
}
qcckGet(params,'/mosty-jbld/dptj/getJbxlrw').then(res=>{
loading.value = false;
let arr = res.records || []
list.value = page.value == 1 ? arr : list.value.concat(arr);
total.value = res.total
}).catch(()=>{
loading.value = false;
})
}
// 滚动加载
const loadList = () =>{
console.log('鸡杂');
if(list.value.length == total.value) return noMore.value = true;
noMore.value = false;
page.value++;
getDateMeta();
}
</script>
<style lang="scss" scoped>
.patrol-missions {
margin-top: 10px;
height: calc(100% - 10px);
padding: 10px 10px 0 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.test-item {
background: url("~@/assets/images/bi/xlrw.png") no-repeat center center;
background-size: 100% 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 10px 14px 20px;
box-sizing: border-box;
margin-bottom: 4px;
&:nth-last-child(1){
margin-bottom: 0;
}
.person-img {
width: 116px;
height: 90px;
img {
width: 100%;
height: 100%;
}
}
.info {
width: calc(100% - 145px);
.text{
color: rgb(1, 252, 254);
}
}
}
}
::-webkit-scrollbar {
background-color: #263b70 !important;
}
::-webkit-scrollbar-thumb {
background-color: #146bbe !important;;
border-radius: 50px;
}
::-webkit-scrollbar-track {
background-color: #263b70 !important;;
}
::-webkit-scrollbar-corner {
background-color: #142141 !important;;
}
</style>

View File

@ -0,0 +1,105 @@
<template>
<div class="patrol-missions" v-if="showModel" infinite-scroll-distance="1" v-infinite-scroll="loadList" v-loading="loading">
<div class="test-item" v-for="(item, index) in list" :key="`info${index}`">
<div class="person-img"><img src="@/assets/images/person.png" /></div>
<div class="info">
<div class="text lh30">负责人:{{ item.xm }}</div>
<div class="lh30">电话:{{ item.lxdh }}</div>
<div class="one_text_detail">巡逻地址:{{ item.zsdmc }}</div>
</div>
</div>
<p class="tc" v-if="list.length > 0 && noMore && !loading ">没有数据了</p>
<MOSTY.Empty :show="true" :imgSize="100" v-if="list.length == 0 && !loading"></MOSTY.Empty>
</div>
</template>
<script setup>
import { qcckGet } from "@/api/qcckApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import { fa } from "element-plus/es/locale.mjs";
import { onMounted, ref } from 'vue';
const list = ref([]);
const loading = ref(false);
const page = ref(1);
const total = ref(0)
const noMore = ref(false);
const showModel = ref(false)
onMounted(()=>{
showModel.value = true;
getDateMeta()
})
// 更新数据
const getDateMeta = () =>{
loading.value = true;
let params = {
pageSize:10,
pageCurrent:page.value,
}
qcckGet(params,'/mosty-jbld/dptj/getZsba').then(res=>{
loading.value = false;
let arr = res.records || []
list.value = page.value == 1 ? arr : list.value.concat(arr);
total.value = res.total
}).catch(()=>{
loading.value = false;
})
}
// 滚动加载
const loadList = () =>{
if(list.value.length == total.value) return noMore.value = true;
noMore.value = false;
page.value++;
getDateMeta();
}
</script>
<style lang="scss" scoped>
.patrol-missions {
margin-top: 10px;
height: calc(100% - 10px);
overflow: hidden;
overflow-y: auto;
padding: 10px;
box-sizing: border-box;
.test-item {
background: url("~@/assets/images/bi/xlrw.png") no-repeat center center;
background-size: 100% 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 14px 10px 14px 20px;
box-sizing: border-box;
margin-bottom: 4px;
&:nth-last-child(1){
margin-bottom: 0;
}
.person-img {
width: 116px;
height: 90px;
img {
width: 100%;
height: 100%;
}
}
.info {
width: calc(100% - 145px);
.text{
color: rgb(1, 252, 254);
}
}
}
}
::-webkit-scrollbar {
background-color: #263b70 !important;
}
::-webkit-scrollbar-thumb {
background-color: #146bbe !important;;
border-radius: 50px;
}
::-webkit-scrollbar-track {
background-color: #263b70 !important;;
}
::-webkit-scrollbar-corner {
background-color: #142141 !important;;
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<div class="security-forces">
<div class="security-forces-content noScollLine" v-loading="loading">
<div v-for="(item, index) in list" :key="index" class="mt5 mb5">
<div class="flex align-center title">
<img src="@/assets/images/bi/abll.png" /><span class="f18">{{ item.ssbm }}</span>
</div>
<div class="row-container">
<el-row class="mb2 pl20 pb2">
<el-col :span="12">值守点位:<span class="num"> {{ item.zsdSl }} </span></el-col>
<el-col :span="12">保安巡逻组:<span class="num"> {{ item.baxlzSl }} </span></el-col>
</el-row>
<el-row class="pl20 pb2">
<el-col :span="12">保安值守:<span class="num"> {{ item.baSl }} </span></el-col>
<el-col :span="12">保安巡逻:<span class="num"> {{ item.baxlSl }} </span></el-col>
</el-row>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { qcckGet } from "@/api/qcckApi.js";
import { onMounted, ref } from 'vue';
const list = ref([])
const loading = ref(false)
onMounted(()=>{
getCount()
})
// 更新数据
const getCount = () =>{
loading.value = true;
qcckGet({},'/mosty-jbld/dptj/getAbxxtj').then(res=>{
loading.value = false;
list.value = res || []
}).catch(()=>{
loading.value = false;
})
}
</script>
<style lang="scss" scoped>
.security-forces {
padding: 10px 10px 5px 10px;
height: 100%;
overflow: hidden;
box-sizing: border-box;
.security-forces-content {
height: 100%;
overflow: auto;
box-sizing: border-box;
}
.title {
font-family: "YSBTH";
-webkit-background-clip: text;
background-image: linear-gradient(to top, #a3c6f5 20%, #ffffff 80%);
background-clip: text;
color: transparent;
-webkit-text-fill-color: transparent;
}
.el-row {
background: url("~@/assets/images/bi/nrk.png") no-repeat center center;
background-size: 100% 100%;
box-sizing: border-box;
.num {
font-size: 18px;
color: rgb(1, 252, 254);
margin: 0 5px;
}
.el-col{
padding: 2px 0;
box-sizing: border-box;
}
}
}
</style>
<style>
.el-loading-mask{
background: rgba(0,0,0,0.5);
}
</style>

View File

@ -0,0 +1,103 @@
<template>
<div class="street-conditions">
<ul class="flex just-center mt10 mb10">
<li class="btn ml4 mr4" v-for="(it, idx) in btns" :key="it" :class="active == idx ? 'activeBtn' : ''"
@click="changeTab(it, idx)">{{ it }}</li>
</ul>
<div class="container" v-if="showModel" infinite-scroll-distance="1" v-infinite-scroll="loadList"
v-loading="loading">
<div v-for="(item, index) in list" :key="`info${index}`" class="item">
<!-- 警情 -->
<JqItem :item="item" v-if="active == 0"></JqItem>
<!-- 街面状况 -->
<JmItem :item="item" v-if="active == 1"></JmItem>
</div>
<p class="tc" v-if="list.length > 0 && noMore && !loading">没有数据了</p>
<MOSTY.Empty :show="true" :imgSize="100" v-if="list.length == 0 && !loading"></MOSTY.Empty>
</div>
</div>
</template>
<script setup>
import { qcckGet } from "@/api/qcckApi.js";
import * as MOSTY from "@/components/MyComponents/index";
import JqItem from './jqItem.vue'
import JmItem from './jmItem.vue'
import { reactive, ref, onMounted } from "vue";
const btns = reactive(['警 情', '街面状况'])
const active = ref(1);
const list = ref([]);
const loading = ref(false);
const page = ref(1);
const total = ref(0)
const noMore = ref(false)
const showModel = ref(false)
onMounted(() => {
showModel.value = true;
getDate()
})
const getDate = () => {
getDate_jq()
}
const changeTab = (val, idx) => {
list.value = [];
page.value = 1
active.value = idx;
getDate_jq()
}
// 更新数据
const getDate_jq = () => {
let params = {
pageSize: 10,
pageCurrent: page.value,
}
let url = active.value == 0 ? '/mosty-jbld/tbJq/getPageList' : '/mosty-jbld/jbjmzk/selelctPage';
if (url) {
loading.value = true;
qcckGet(params, url).then(res => {
loading.value = false;
let arr = res.records || []
list.value = page.value == 1 ? arr : list.value.concat(arr);
total.value = res.total
}).catch(() => {
loading.value = false;
})
}
}
// 滚动加载
const loadList = () => {
if (list.value.length == total.value) return noMore.value = true;
noMore.value = false;
page.value++;
getDateMeta();
}
</script>
<style lang="scss" scoped>
.street-conditions {
height: 100%;
.btn {
cursor: pointer;
background: url("~@/assets/images/bi/wxz.png") no-repeat center center;
background-size: 100% 100%;
width: 159px;
height: 43px;
line-height: 43px;
text-align: center;
}
.activeBtn {
background: url("~@/assets/images/bi/xz.png") no-repeat center center;
background-size: 100% 100%;
}
.container {
height: calc(100% - 76px);
overflow: hidden;
overflow-y: auto;
}
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<div class="top-statistics-container">
<div class="top-statistics transition" :style="{height:isShow ? '83px' : 0 }">
<div class="test-item" v-for="(item,idx) in list" :key="idx">
<div class="desc"><span class="num">{{ item.label }}</span></div>
<div class="f18">{{ item.value }}</div>
</div>
</div>
<el-icon class="f28 pointer" @click="isShow = !isShow" :title="isShow ? '点击收起' : '点击展开'">
<el-icon color="#333"><CaretTop v-if="isShow" /><CaretBottom v-else /></el-icon>
</el-icon>
</div>
</template>
<script setup>
import { qcckGet } from "@/api/qcckApi.js";
import { ref ,onMounted} from "vue";
const isShow = ref(true);
const list = ref([
{ label:'值守点位',value:0,lx:'zsdSl' },
{ label:'保安值守数',value:0,lx:'baSl' },
{ label:'保安巡逻组',value:0,lx:'baxlzSl' },
{ label:'保安巡逻数',value:0,lx:'baxlSl' },
{ label:'临时任务',value:0,lx:'rwSl' },
{ label:'警情协助',value:0,lx:'jqxzSl' },
])
onMounted(()=>{
getDate()
})
const getDate = () =>{
qcckGet({},'/mosty-jbld/dptj/getDpxxtj').then(res=>{
let data = res || {}
for(let key in data){
list.value.forEach(v=>{
if(v.lx == key) v.value = data[key]
})
}
})
}
</script>
<style lang="scss" scoped>
.top-statistics-container {
position: absolute;
left: 50%;
transform: translateX(-50%);
width: 50%;
top: 130px;
z-index: 3;
text-align: center;
z-index: 3;
.top-statistics {
overflow: hidden;
padding: 10px 0 0 0;
height: 83px;
width: 100%;
display: flex;
justify-content: space-around;
gap: 5px;
.test-item {
width: 130px;
background: url("~@/assets/images/bi/zjtj.png") no-repeat center center;
background-size: 100% 100%;
padding-top: 10px;
box-sizing: border-box;
.desc {
white-space: nowrap;
overflow: hidden;
.num {
font-family: "YSBTH";
font-size: 20px;
background-image: linear-gradient(to top, #a3c6f5 20%, #ffffff 80%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
-webkit-text-fill-color: transparent;
}
}
}
}
}
.transition{
transition: all 0.5s;
}
</style>

View File

@ -0,0 +1,131 @@
<!--
* @Author: your name
* @Date: 2022-09-20 10:22:51
* @LastEditTime: 2024-02-19 11:40:22
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \rs-web\src\views\situationPresentation\dialog\gzyInfo.vue
-->
<template>
<div class="dialogBox" >
<div class="title">
<span class="mc">感知源</span>
<span @click="close" class="close"><el-icon><Close /></el-icon> </span>
</div>
<div class="videoLIstBox">
<div v-for="(item, index) in info" :key="index">
<div class="infoBox">
<div class="content">{{ item.sbmc }}</div>
<div class="other">
<p>设备编号{{ item.sbbh }}</p>
<p>所属部门{{ item.ssbm }}</p>
<p class="itemBox">
<span>厂商名称{{ item.csmc }}</span>
<button class="dp-default small" v-if="item.isPlay" @click="closePlay(item.id)"> 关闭 </button>
<button v-else class="dp-default small" @click="openVideo(item)">播放 </button>
</p>
<div class="videoBox" :id="'id_'+item.sbbh" v-if="item.isPlay">
</div>
</div>
<div class="addressBox">
<div class="ddd">
<img src="@/assets/images/dingwei.png" />
<span>{{ item.dzmc }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, getCurrentInstance, watch } from "vue";
// import VideoPay from "@/components/wsVideoSenior/wsPlayOne/index"; //ws播放高阶
// import VideoPay from "@/components/videoOne/index"; //ws播放
import VideoPay from "@/components/wsVideoSenior/wsIframe/index"; //iframe播放
import emitter from "@/utils/eventBus.js";
const { proxy } = getCurrentInstance();
const props = defineProps({
data:{
type:Array,
default:[]
}
})
const info = ref([])
watch(()=>props.data,(val)=>{
info.value = val
},{
immediate:true
})
// 打开视频
function openVideo(item) {
if (!item.sbbh) return proxy.$message({ type: "info", message: "暂无视频" });
SPPUC.rdCard(item.sbbh, 1, ["10%", "40%"]);
}
//关闭视频
function closePlay(id) {
info.value.forEach((item) => {
if (item.id == id) item.isPlay = false;
});
}
//关闭弹窗
function close() {
emitter.emit("deletePointArea", "lang");
emitter.emit("showGzy", false);
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/largeScreen.scss";
@import "@/assets/css/homeScreen.scss";
.dialogBox{
padding: 0 0 10px 0;
box-sizing: border-box;
.title {
border-bottom: 1px solid #275288;
margin-bottom: 6px;
.mc { margin-left: 10px; }
}
.videoLIstBox {
max-height: 680px;
padding: 4px 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.infoBox {
position: relative;
padding: 4px 10px;
box-sizing: border-box;
border-bottom: 1px solid #20557c;
.content {
padding: 10px 10px 0 10px;
font-size: 14px;
}
.other {
margin: 0 10px;
padding: 0px;
color: #779dcd;
list-style: none;
.itemBox {
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
span {
display: inline-block;
}
}
.videoBox {
height: 160px;
background: #000;
}
p { margin: 5px 0; }
}
}
}
}
.ddd{
}
</style>

View File

@ -0,0 +1,142 @@
<!--
* @Author: your name
* @Date: 2022-09-20 10:22:51
* @LastEditTime: 2024-02-19 11:40:22
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \rs-web\src\views\situationPresentation\dialog\gzyInfo.vue
-->
<template>
<div class="dialogBox">
<div class="title">
<span class="mc">值守点</span>
<span @click="close" class="close"><el-icon>
<Close />
</el-icon> </span>
</div>
<div class="videoLIstBox">
<div v-for="(item, index) in info" :key="index">
<div class="infoBox">
<div class="other">
<div><span style="color:#fff">值守点名称</span>{{ item.zsdMc }}</div>
<div v-if="item.smjlList && item.smjlList.length > 0">
<span style="color:#fff">打卡人员</span>
<div v-for="el in item.smjlList" :key="el">{{
el.xm
}} ({{ el.smsj }})</div>
</div>
<p><span style="color:#fff">所属部门</span>{{ item.ssbm }}</p>
<p><span style="color:#fff">二维码</span><el-image style="width: 70px;"
:preview-src-list="[`data:image/png;base64,${item.ewm}`]" :src="`data:image/png;base64,${item.ewm}`"
preview-teleported>
</el-image></p>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, getCurrentInstance, watch } from "vue";
// import VideoPay from "@/components/wsVideoSenior/wsPlayOne/index"; //ws播放高阶
// import VideoPay from "@/components/videoOne/index"; //ws播放
import VideoPay from "@/components/wsVideoSenior/wsIframe/index"; //iframe播放
import emitter from "@/utils/eventBus.js";
const { proxy } = getCurrentInstance();
const props = defineProps({
data: {
type: Array,
default: []
}
})
const info = ref([])
watch(() => props.data, (val) => {
info.value = val
}, {
immediate: true
})
// 打开视频
function openVideo(item) {
if (!item.sbbh) return proxy.$message({ type: "info", message: "暂无视频" });
SPPUC.rdCard(item.sbbh, 1, ["10%", "40%"]);
}
//关闭视频
function closePlay(id) {
info.value.forEach((item) => {
if (item.id == id) item.isPlay = false;
});
}
//关闭弹窗
function close() {
emitter.emit("deletePointArea", "lang");
emitter.emit("showZsdw", false);
}
</script>
<style lang="scss" scoped>
@import "@/assets/css/largeScreen.scss";
@import "@/assets/css/homeScreen.scss";
.dialogBox {
padding: 0 0 10px 0;
box-sizing: border-box;
.title {
border-bottom: 1px solid #275288;
margin-bottom: 6px;
.mc {
margin-left: 10px;
}
}
.videoLIstBox {
max-height: 680px;
padding: 4px 10px;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.infoBox {
position: relative;
padding: 4px 10px;
box-sizing: border-box;
border-bottom: 1px solid #20557c;
.content {
padding: 10px 10px 0 10px;
font-size: 14px;
}
.other {
margin: 0 10px;
padding: 0px;
color: #779dcd;
list-style: none;
.itemBox {
display: flex;
justify-content: space-between;
flex-wrap: nowrap;
span {
display: inline-block;
}
}
.videoBox {
height: 160px;
background: #000;
}
p {
margin: 5px 0;
}
}
}
}
}
.ddd {}
</style>

View File

@ -0,0 +1,96 @@
<template>
<div class="itemsBox">
<div class="time flex just-between align-center pr10">
<span class="f14 ml4">{{ item.bjsj }}</span>
</div>
<div class="cards">
<div class="flex just-between">
<span class="text">辖区{{ item.ssxq }}</span>
<span class="text one_text_detail">上报人{{ item.sbrxm }}</span>
</div>
<div class="flex just-between">
<span class="text">街面情况{{ item.jmzk }}</span>
<span class="text one_text_detail">巡逻路线{{ item.xllx }}</span>
</div>
<div class="flex just-between">
<span style="width: 100%;" class="text one_text_detail">状况描述{{ item.zkms }}</span>
</div>
<div class="foot flex align-center two_text_detail">
<img src="@/assets/images/bi/ddtb.png" />{{ item.dz }}
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
item: {
type: Object,
default: {}
}
})
</script>
<style lang="scss" scoped>
.itemsBox {
position: relative;
padding: 0 0 12px 10px;
box-sizing: border-box;
border-left: 1px solid #0072ff;
margin-left: 12px;
&::before {
position: absolute;
content: '';
left: -7px;
top: 0;
width: 14px;
height: 14px;
border-radius: 50%;
background: #061b44;
border: 2px solid #43c276;
}
.dw {
color: #0072ff;
}
.cards {
background: url("~@/assets/images/bi/jqk.png") no-repeat center center;
background-size: 100% 100%;
padding: 20px 5px 10px 10px;
box-sizing: border-box;
margin-top: 6px;
overflow: hidden;
.text {
font-size: 12px;
width: calc(50% - 12px);
line-height: 24px;
white-space: nowrap;
position: relative;
padding-left: 14px;
box-sizing: border-box;
&::before {
position: absolute;
content: '';
width: 8px;
height: 8px;
border-radius: 50%;
background: linear-gradient(180deg, #FFFFFF 30.4658203125%, #89AFCF 100%);
left: 0px;
top: 50%;
transform: translateY(-50%);
}
}
.foot {
border-top: 1px dashed #89AFCF;
margin-top: 4px;
padding-top: 4px;
}
}
}
</style>

View File

@ -0,0 +1,108 @@
<template>
<div class="itemsBox">
<div class="time flex just-between align-center pr10">
<span class="f14 ml4">{{ item.bjsj }}</span>
<span class="dw pointer">重新定位</span>
</div>
<div class="cards">
<div class="marks">已派警</div>
<div class="mb4 text_detail">{{ item.bjnr }}</div>
<div class="flex just-between">
<span class="text">报警人{{ item.bjrXm }}</span>
<span class="text one_text_detail">报警时间{{ item.bjsj }}</span>
</div>
<div class="flex just-between">
<span class="text">报警类型{{ item.bjlxmc }}</span>
<span class="text one_text_detail">报警细类{{ item.bjxlmc }}</span>
</div>
<div class="flex just-between">
<span style="width: 100%;" class="text one_text_detail">管辖单位{{ item.ssbm }}</span>
</div>
<div class="foot flex align-center two_text_detail">
<img src="@/assets/images/bi/ddtb.png" />{{ item.sfdz }}
</div>
</div>
</div>
</template>
<script setup>
import {ref } from 'vue'
const props = defineProps({
item:{
type:Object,
default:{}
}
})
</script>
<style lang="scss" scoped>
.itemsBox{
position: relative;
padding: 0 0 12px 10px;
box-sizing: border-box;
border-left: 1px solid #0072ff;
margin-left: 12px;
&::before{
position: absolute;
content: '';
left: -7px;
top: 0;
width: 14px;
height: 14px;
border-radius: 50%;
background: #061b44;
border: 2px solid #43c276;
}
.dw{
color: #0072ff;
}
.cards{
position: relative;
background: url("~@/assets/images/bi/jqk.png") no-repeat center center;
background-size: 100% 100%;
padding: 20px 5px 10px 10px;
box-sizing: border-box;
margin-top: 6px;
overflow: hidden;
.text{
font-size: 12px;
width: calc(50% - 12px);
line-height: 24px;
white-space: nowrap;
position: relative;
padding-left: 14px;
box-sizing: border-box;
&::before{
position: absolute;
content: '';
width: 8px;
height: 8px;
border-radius: 50%;
background: linear-gradient(180deg, #FFFFFF 30.4658203125%, #89AFCF 100%);
left: 0px;
top: 50%;
transform: translateY(-50%);
}
}
.foot{
border-top: 1px dashed #89AFCF;
margin-top: 4px;
padding-top: 4px;
}
.marks{
position: absolute;
right: -32px;
top: 4px;
width: 100px;
height: 24px;
text-align: center;
line-height: 24px;
color: #fff;
background: #47e5ad;
font-size: 12px;
transform: rotate(38deg);
}
}
}
</style>

View File

@ -0,0 +1,75 @@
<template>
<div class="all-dialog noScollLine" :style="{ left: props.isPosition ? '0px' : '448px' }"
style="transition: all 0.5s">
<!-- 感知源弹窗 -->
<GzyInfo v-if="isShow.showGzy" :data="list.gzyxqList" />
<!-- 值守点 -->
<ZsdInfo v-if="isShow.showZsdw" :data="list.zsdwList" />
</div>
</template>
<script setup>
import emitter from "@/utils/eventBus.js";
import GzyInfo from "./dialog/gzyInfo.vue";
import ZsdInfo from "./dialog/zsdInfo.vue";
import { ref, defineProps, onMounted, onUnmounted, reactive } from "vue";
const props = defineProps({
isPosition: Boolean
});
const isShowDefault = ref({});
const isShow = ref({
showGzy: false, //感知源
showZsdw: false, //值守点
});
const list = reactive({
gzyxqList: [], //感知元数据
zsdwList: [], //感知元数据
});
onMounted(() => {
isShowDefault.value = JSON.parse(JSON.stringify(isShow.value));
// 感知源
emitter.on("showGzy", (res) => {
isShow.value.showGzy = res ? true : false;
if (res) {
list.gzyxqList = res.map((item) => {
item.isPlay = false;
return item;
});
}
});
// 必巡点
emitter.on("showZsdw", (res) => {
console.log(res,'res');
isShow.value.showZsdw = res ? true : false;
if (res) {
list.zsdwList = res.map((item) => {
item.isPlay = false;
return item;
});
}
});
});
onUnmounted(() => {
emitter.off("showGzy");
emitter.off("showZsdw");
});
</script>
<style lang="scss" scoped>
@import "@/assets/css/homeScreen.scss";
.all-dialog {
position: absolute;
width: 370px;
top: 24%;
max-height: 76vh;
overflow: hidden;
overflow-y: auto;
padding-right: 10px;
box-sizing: border-box;
z-index: 9;
}
</style>

View File

@ -0,0 +1,159 @@
<template>
<div class="top-statistics">
<div class="test-item" :class="item.active ? 'test-item-active' : ''" v-for="(item, index) in info"
@click="handlePoint(item)" :key="`${index}info`">
<img :src="!item.active ? item.url : item.urlActive" />
<div>{{ item.title }} </div>
</div>
</div>
</template>
<script setup>
import { ElMessage } from "element-plus";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
import emitter from "@/utils/eventBus.js";
import { reactive } from "vue";
import { fa } from "element-plus/es/locale.mjs";
const info = reactive([
{
title: "值守点位",
active: false,
url: require("@/assets/images/bi/zsdw.png"),
urlActive: require("@/assets/images/bi/zsdw-active.png"),
},
{
title: "巡逻路线",
active: false,
url: require("@/assets/images/bi/lx.png"),
urlActive: require("@/assets/images/bi/lx-active.png"),
},
// {
// title: "必巡点",
// active: false,
// url: require("@/assets/images/bi/bxd.png"),
// urlActive: require("@/assets/images/bi/bxd-active.png"),
// },
{
title: "感知源",
active: false,
url: require("@/assets/images/bi/gzy.png"),
urlActive: require("@/assets/images/bi/gzy-active.png"),
},
{
title: "清除",
url: require("@/assets/images/bi/qc-active.png"),
urlActive: require("@/assets/images/bi/qc-active.png"),
}
]);
const handlePoint = (val) => {
val.active = !val.active;
switch (val.title) {
case '值守点位':
if (val.active) getPoint_ZSDW();
else clearnPoint(['map_zsdw'])
break;
case '巡逻路线':
if (val.active) getPoint_XLX();
else clearnPoint(['map_line', 'map_line_dw'])
break;
case '必巡点':
if (val.active) getPoint_BXD();
else clearnPoint(['map_bxd'])
break;
case '感知源':
if (val.active) getPoint_GZY()
else clearnPoint(['map_gzy'])
break;
case '清除':
emitter.emit("removeAll");
info.forEach(item => { item.active = false })
break;
}
}
// 值守点位
const getPoint_ZSDW = () => {
qcckGet({}, '/mosty-jbld/jbldzsd/selectList').then(res => {
console.log(res);
if (!res) return ElMessage({ message: "暂无值守点位数据", type: "warning" });
let arr = res ? res : [];
let icon = require("@/assets/point/zsd1.png");
let obj = { coords: arr, flag: "map_zsdw", icon };
emitter.emit("addPointArea", obj);
})
}
// 巡逻路线
const getPoint_XLX = () => {
qcckGet({}, '/mosty-jbld/jbldBxx/selecList').then(res => {
if (!res) return ElMessage({ message: "暂无值巡逻路线数据", type: "warning" });
let arr = res ? res : [];
let points = []
let coords = arr.map((v) => {
points = points.concat(v.bxds)
return { coords: [v.zb], text: v.zrqMc };
});
let icon = require("@/assets/point/zsdw.png");
let obj = { coords: points, flag: "map_line_dw", icon };
emitter.emit("addPointArea", obj);// 撒点
emitter.emit("echoLine", { coords, width: 3, flag: "map_line", type: "solid", color: '#ff0000' });// 画线
})
}
// 感知源
const getPoint_GZY = () => {
qcckPost({}, '/mosty-jmxf/tbYsSxt/getList').then(res => {
if (!res) return ElMessage({ message: "暂无感知源数据", type: "warning" });
let arr = res ? res : [];
let icon = require("@/assets/point/sp.png");
let obj = { coords: arr, flag: "map_gzy", icon };
emitter.emit("addPoint", obj);
})
}
// 比巡点
const getPoint_BXD = () => {
qcckGet({}, '/mosty-jbld/jbldBxx/selecBxdList').then(res => {
if (!res) return ElMessage({ message: "暂无值必巡点数据", type: "warning" });
let arr = res ? res : [];
let icon = require("@/assets/point/zsdw.png");
let obj = { coords: arr, flag: "map_bxd", icon };
emitter.emit("showPoint", obj);
})
}
// 清处点位
const clearnPoint = (falgArr) => {
falgArr.forEach((flag) => {
emitter.emit("deletePointArea", flag);
});
}
</script>
<style lang="scss" scoped>
.top-statistics {
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 0px;
width: 53%;
z-index: 3;
padding: 10px 50px;
box-sizing: border-box;
display: flex;
justify-content: center;
.test-item {
cursor: pointer;
width: 160px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #0072ff;
}
.test-item-active {
color: orange;
}
}
</style>

132
src/views/dataBI/index.vue Normal file
View File

@ -0,0 +1,132 @@
<template>
<div class="homeBox">
<!-- 头部 -->
<Head></Head>
<GdMap></GdMap>
<!-- 左边 -->
<div class="home-aside aside-left">
<div class="asideModel">
<div class="common-title">安保信息</div>
<div class="comom-cnt">
<Securityforces></Securityforces>
</div>
</div>
<div class="asideModel">
<div class="common-title">警保巡逻任务</div>
<div class="comom-cnt">
<Patrolmissions></Patrolmissions>
</div>
</div>
<div class="asideModel">
<div class="common-title">值守保安</div>
<div class="comom-cnt">
<SecurityInfo></SecurityInfo>
</div>
</div>
</div>
<!-- 右边 -->
<div class="home-aside aside-right">
<div class="right-top">
<div class="common-title">街面情况</div>
<div class="comom-cnt">
<StreetConditions></StreetConditions>
</div>
</div>
</div>
<!-- 统计 -->
<TopStatistics></TopStatistics>
<!-- 地图资源 -->
<BottomStatistics></BottomStatistics>
<LeftDialog />
</div>
</template>
<script setup>
import Head from "./layout/head.vue";
import Securityforces from "./components/Securityforces.vue";
import Patrolmissions from "./components/Patrolmissions.vue";
import StreetConditions from "./components/StreetConditions.vue";
import SecurityInfo from "./components/SecurityInfo.vue";
import TopStatistics from "./components/TopStatistics.vue";
import BottomStatistics from "./components/mapResource.vue";
import LeftDialog from "./components/leftDialog.vue";
import GdMap from "@/components/GdMap/index.vue";
import { onMounted, ref } from "vue";
onMounted(() => {
// 融合通迅
let idEntityCard = window.localStorage.getItem("idEntityCard");
let sfrh = window.localStorage.getItem("SFRH");
if (sfrh == 1 && idEntityCard) {
try {
SPPUC.init(
idEntityCard,
"",
function () { },
function (device_id, type, [lng, lat, speed]) { }
);
console.log(SPPUC, 'SPPUC');
} catch { }
}
})
</script>
<style lang="scss" scoped>
.homeBox {
width: 100%;
height: 100vh;
position: relative;
.home-aside {
position: absolute;
overflow: hidden;
top: 70px;
height: calc(100vh - 67px);
background: #263445;
z-index: 3;
width: 442px;
.asideModel {
height: calc(100%/3);
background: url("~@/assets/images/bi/L_B.png") no-repeat center center;
background-size: 100% 100%;
}
.right-top {
height: 100%;
background: url("~@/assets/images/bi/R_T.png") no-repeat center center;
background-size: 100% 100%;
}
}
.aside-left {
left: 0;
}
.aside-right {
right: 0;
}
// 公用
.common-title {
padding: 0 54px;
box-sizing: border-box;
font-size: 22px;
font-family: "YSBTH";
background: linear-gradient(0deg, #59a6f4 0%, #ffffff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.comom-cnt {
height: calc(100% - 30px);
padding: 4px 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
min-height: 0;
}
}
</style>

View File

@ -0,0 +1,132 @@
<template>
<div class="head-container">
<div class="home-head-box relative">
<div class="time absolute">
<div class="f20">{{ datatime }}</div>
<div class="f18 pl104">{{ hour + ":" + minute + ":" + second }}</div>
</div>
<div class="title absolute" @click="goPath">{{ props.title }}</div>
<!-- <div class="title-tow" absolute>
<div class="back"><span class="ml40">林芝市</span></div>
</div> -->
<div class="wd absolute">
<el-icon size="25px" style="top: 6px" color="#86C8EB"><Sunny /></el-icon>
<span> 温度 1~7°C </span>
</div>
</div>
</div>
</template>
<script setup>
import { useRouter } from "vue-router";
import { getRecentDay, timeValidate } from "@/utils/tools.js";
import { ref, onMounted, defineProps, onUnmounted } from "vue";
const props = defineProps({
title: {
type: String,
default: "警保联动"
}
});
const datatime = ref(getRecentDay(0));
const minute = ref("00"); //分
const second = ref("00"); //秒
const hour = ref("00"); //时
const day = ref(0);
const timersfm = ref(null);
const router = useRouter();
onMounted(() => {
timersfm.value = setInterval(() => {
CurrentTime();
}, 1000);
});
// 获取时分秒
function CurrentTime() {
const date = new Date();
hour.value = date.getHours();
minute.value = date.getMinutes();
second.value = date.getSeconds();
day.value = day.value < 10 ? "0" + day.value : day.value;
hour.value = hour.value < 10 ? "0" + hour.value : hour.value;
minute.value = minute.value < 10 ? "0" + minute.value : minute.value;
second.value = second.value < 10 ? "0" + second.value : second.value;
}
function goPath() {
router.push("/editPassword");
}
</script>
<style lang="scss" scoped>
.head-container {
width: 100%;
height: 135px;
position: relative;
background: #263445;
z-index: 2;
}
.home-head-box {
width: 100%;
height: 138px;
background: url("~@/assets/images/home_head.png") no-repeat center center;
z-index: 2;
.title {
font-size: 36px;
left: 50%;
top: 10px;
transform: translateX(-50%);
font-family: "YSBTH";
background: linear-gradient(0deg, #59a6f4 0%, #ffffff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.title-tow {
background: #fff;
position: absolute;
height: 70px;
width: 500px;
top: 50px;
left: calc(50% - 270px);
font-size: 36px;
font-family: "YSBTH";
background: linear-gradient(0deg, #59a6f4 0%, #ffffff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
text-align: center;
line-height: 100px;
.back {
background: url("~@/assets/images/bi/fbt.png") no-repeat center center;
height: 100%;
width: 100%;
}
}
.time {
font-family: "DigifaceWide";
color: #fff;
left: 25%;
top: 10px;
}
.wd {
right: 25%;
top: 12px;
font-size: 16px;
font-family: "DigifaceWide";
color: #fff;
}
.zbbb {
position: absolute;
right: 20px;
top: 22px;
font-size: 16px;
width: 162px;
height: 48px;
text-align: center;
line-height: 48px;
font-size: 16px;
background: url("~@/assets/images/btnbb.png") no-repeat center center;
background-size: 100% 100%;
}
}
</style>