初始提交

This commit is contained in:
2025-09-04 16:35:14 +08:00
commit 5cd52c4d2c
735 changed files with 155784 additions and 0 deletions

View File

@ -0,0 +1,740 @@
<template>
<div class="containerBox" style="padding-top: 13vw">
<TopNav navTitle="位置中心" />
<div class="main">
<!-- 位置统计 -->
<div class="contant">
<div class="header">
<span>
<van-icon name="friends" size="20px" color="#3e6ee8"></van-icon>
<span class="title">实时巡组</span>
</span>
</div>
<ItemList title="今日" :list="dayList" />
<ItemList title="近一周" :list="weekList" />
<ItemList title="近一月" :list="monthList" />
</div>
<!-- 实时巡组 -->
<div class="contant">
<div class="header">
<span>
<van-icon name="friends" size="20px" color="#3e6ee8"></van-icon>
<span class="title">实时巡组</span>
</span>
<div class="callAll" style="font-size: 10px">全部呼叫</div>
</div>
<div class="select_box">
<div>
<van-checkbox-group
v-model="checked"
direction="horizontal"
@change="onChangeXfzt"
>
<van-checkbox
icon-size="16"
shape="square"
:name="item.name"
v-for="(item, index) in checkList"
:key="index"
>
<span
class="dian"
:class="
item.name == 0 ? 'online' : item.name == 1 ? 'busy' : ''
"
></span>
{{ item.label }}({{ item.value }})
</van-checkbox>
</van-checkbox-group>
</div>
</div>
<div class="group item_box">
<ul class="groupList positionList" ref="xzScroll">
<li
v-for="item in xzList.list"
:key="item.id"
@click="handelClick(item)"
>
<div class="top">
<div class="top-cnt">
<span
class="dian online"
title="巡逻中"
v-if="item.xfzt == 0"
></span>
<span
class="dian busy"
title="处警中"
v-if="item.xfzt == 1"
></span>
<span class="dian" title="离线" v-if="item.xfzt == 2"></span>
<span class="name">{{ item.jzMc ? item.jzMc:item.fzrXm+'巡组' }}</span
><br />
<span class="other"
>负责人{{ item.fzrXm }} ({{ item.fzrLxdh }})</span
>
</div>
<div class="imgBtn">
<van-icon name="phone-circle-o" color="#25b882" size="30" />
</div>
</div>
<div class="address">
<van-icon
name="location"
size="15px"
color="#3e6ee8"
></van-icon>
<span>{{ item.dqwz }}</span>
</div>
</li>
<van-loading
type="spinner"
v-if="xzLoading"
style="padding-top: 50vw; text-align: center"
/>
<van-empty
image="default"
description="无列表数据"
v-if="xzList.list.length <= 0 && !xzLoading"
/>
</ul>
</div>
</div>
<!-- 人员实时位置 -->
<div class="contant">
<div class="header">
<span>
<van-icon name="manager" size="20px" color="#3e6ee8"></van-icon>
<span class="title">人员实时位置</span>
</span>
</div>
<div class="group item_box">
<Search
v-model="localVal"
placeholder="请输入相关信息"
@update:modelValue="SeachLocation"
></Search>
<ul class="groupList positionList" ref="ryScroll">
<li
v-for="item in wzList.list"
:key="item.id"
@click="handelClick(item)"
style="border-bottom:1px solid #eff0f5"
>
<div class="top">
<div class="top-cnt">
<span class="other">负责人{{ item.yh_xm }}</span>
<div class="text">
{{ item.dwrq }}
{{ item.kssj ? item.kssj.slice(11, 16) : "00:00" }}
{{ item.jssj ? item.jssj.slice(11, 16) : "00:00" }}
</div>
</div>
<div class="imgBtn">
<van-icon name="phone-circle-o" color="#25b882" size="30" />
</div>
</div>
<div class="address" v-if="item.dqwz">
<van-icon
name="location"
size="15px"
color="#3e6ee8"
></van-icon>
<span>{{ item.dqwz }}</span>
</div>
</li>
<van-loading
type="spinner"
v-if="renLoading"
style="padding-top: 4vw; text-align: center"
/>
<van-empty
image="default"
description="无列表数据"
v-if="wzList.list.length <= 0 && !renLoading"
/>
</ul>
</div>
</div>
</div>
</div>
</template>
<script setup>
import {
locationLCS,
locationXZWZS,
locationWZRS,
locationRYSSWZ,
getSelectDeckList,
} from "../../../api/yyzxApi.js";
import ItemList from "../../../components/component/itemList.vue";
import TopNav from "../../../components/topNav.vue";
import { timeValidate, getRecentDay } from "../../../utils/tools.js";
import { ref, reactive, onMounted, defineEmits } from "vue";
import Search from "../../../components/search.vue";
import { Toast } from "vant";
const xzLoading = ref(false);
const xzScroll = ref(null);
const renLoading = ref(false);
const ryScroll = ref(null);
//状态数据
const Searvalue = ref([]); // 巡组搜索关键字
const checked = ref([0, 1, 2]); //巡组复选框
const checkList = reactive([
{
name: 0,
label: "巡逻中",
value: 0,
},
{
name: 1,
value: 0,
label: "处警中",
},
{
name: 2,
value: 0,
label: "离线",
},
]);
const today = ref(timeValidate(new Date(), "ymd")); //今天
const week = ref(getRecentDay(-6, "ymd")); //近7天
const month = ref(getRecentDay(-29, "ymd"));
//今日统计数据
const dayList = ref([
{
name: "坐标总数",
count: 0,
},
{
name: "里程数",
count: 0,
isShowKm: true,
},
{
name: "巡组位置数",
count: 0,
},
]);
//周统计
const weekList = ref([
{
name: "坐标总数",
count: 0,
},
{
name: "里程数",
count: 0,
isShowKm: true,
},
{
name: "巡组位置数",
count: 0,
},
]);
//月统计
const monthList = ref([
{
name: "坐标总数",
count: 0,
},
{
name: "里程数",
count: 0,
isShowKm: true,
},
{
name: "巡组位置数",
count: 0,
},
]);
let pageCurrent = ref(1);
let xzTotal = ref(0);
let xzList = reactive({
list: [],
}); //巡组数据
let wzList = reactive({
list: [],
}); //人员实时位置
const wzTotal = ref(0);
const wzPageNum = ref(1);
const localVal = ref("");
onMounted(() => {
Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
// <!-- 位置统计 -->
// //里程数 今天 -近七天 -近30天 )
// getLcs(today.value, today.value, "day");
// getLcs(week.value, today.value, "week");
// getLcs(month.value, today.value, "month");
// // //位置人数(坐标总数) 今天 -近七天 -近30天
// getWzrs(today.value, today.value, "day");
// getWzrs(week.value, today.value, "week");
// getWzrs(month.value, today.value, "month");
// // //巡组位置巡数 今天 -近七天 -近30天
// getXzwzs(today.value, today.value, "day");
// getXzwzs(week.value, today.value, "week");
// getXzwzs(month.value, today.value, "month");
// // 实时巡组
// SelectDeckList(0);
// SelectDeckList(1);
// SelectDeckList(2);
// onChangeXfzt();
// // 人员实时位置
// getDataList();
// scroll("xz");
// scroll("ry");
Promise.all([
getLcs(today.value, today.value, "day"),
getLcs(week.value, today.value, "week"),
getLcs(month.value, today.value, "month"),
getWzrs(today.value, today.value, "day"),
getWzrs(week.value, today.value, "week"),
getWzrs(month.value, today.value, "month"),
getXzwzs(today.value, today.value, "day"),
getXzwzs(week.value, today.value, "week"),
getXzwzs(month.value, today.value, "month"),
SelectDeckList(0),
SelectDeckList(1),
SelectDeckList(2),
onChangeXfzt(),
getDataList(),
scroll("xz"),
scroll("ry"),
])
.then((res) => {
Toast.clear();
})
.catch((err) => {
Toast.clear();
});
});
// 里程数
function getLcs(start, end, type) {
let params = {
ksrq: start + " 00:00:00",
jsrq: end + " 23:59:59",
};
locationLCS("/mosty-wzzx/wztj/tj/jrlcs", params).then((res) => {
if (type == "day") {
dayList.value[1].count = (res[0].lcs / 1000).toFixed(0);
}
if (type == "week") {
weekList.value[1].count = (res[0].lcs / 1000).toFixed(0);
}
if (type == "month") {
monthList.value[1].count = (res[0].lcs / 1000).toFixed(0);
}
});
}
// 获取位置人数 / 坐标总数
function getWzrs(start, end, type) {
let params = {
ksrq: start + " 00:00:00",
jsrq: end + " 23:59:59",
};
locationWZRS(params).then((res) => {
if (type == "day") {
dayList.value[0].count = res[0].sl;
}
if (type == "week") {
weekList.value[0].count = res[0].sl;
}
if (type == "month") {
monthList.value[0].count = res[0].sl;
}
});
}
// 获取巡组位置巡数
function getXzwzs(start, end, type, status) {
let params = {
ksrq: start + " 00:00:00",
jsrq: end + " 23:59:59",
};
locationXZWZS("/mosty-wzzx/wztj/tj/jrxzwzs", params).then((res) => {
if (type == "day") {
dayList.value[2].count = res[0].wzs;
}
if (type == "week") {
weekList.value[2].count = res[0].wzs;
}
if (type == "month") {
monthList.value[2].count = res[0].wzs;
}
});
}
//选择巡防状态
function onChangeXfzt() {
let status = checked.value.join(",");
pageCurrent.value = 1;
xzList.list = [];
SelectDeckList(status);
}
//巡组列表
function SelectDeckList(xfzt) {
let data = {
xfzt,
pageSize: 10,
pageCurrent: pageCurrent.value,
};
xzLoading.value = true;
getSelectDeckList("/mosty-qwzx/tbQwXfbb/selectDeckList", data)
.then((res) => {
xzLoading.value = false;
if (res.records.length > 0) {
if (pageCurrent.value == 1) {
xzList.list = res.records;
} else {
xzList.list = xzList.list.concat(res.records);
}
}
xzTotal.value = res.total;
if (xfzt == 0) {
checkList[0].value = res.total;
}
if (xfzt == 1) {
checkList[0].value = res.total;
}
if (xfzt == 2) {
checkList[2].value = res.total;
}
})
.catch(() => {
xzLoading.value = false;
});
}
// 清除搜索
function clearDataSearch() {
wzPageNum.value = 1;
getDataList();
}
// 人员事实位置搜索
function SeachLocation() {
wzPageNum.value = 1;
getDataList();
}
// 人员实时获取数据列表
function getDataList() {
let params = {
yhxm: localVal.value,
pageCurrent: wzPageNum.value,
pageSize: 10,
};
renLoading.value = true;
locationRYSSWZ("/mosty-wzzx/wztj/wz/rywzlb", params)
.then((res) => {
renLoading.value = false;
if (wzPageNum.value == 1) {
wzList.list = res.records ? res.records : [];
} else {
let arr = res.records ? res.records : [];
wzList.list = wzList.list.concat(arr);
}
wzTotal.value = res.total;
})
.catch(() => {
renLoading.value = false;
});
}
//触底加载
function scroll(type) {
let scrollTargetBox = "";
if (type == "xz") {
scrollTargetBox = xzScroll.value;
} else {
scrollTargetBox = ryScroll.value;
}
scrollTargetBox.onscroll = (e) => {
var scrollHeight = scrollTargetBox.scrollHeight;
var scrollTop = scrollTargetBox.scrollTop;
var clientHeight = scrollTargetBox.clientHeight;
if (scrollHeight - clientHeight == scrollTop) {
//滚动条滚到最底部
if (type == "xz") {
if (xzList.list.length < xzTotal.value) {
pageCurrent++;
}
} else {
if (wzList.list.length < wzTotal.value) {
wzPageNum.value++;
getDataList();
}
}
}
};
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.main {
// padding: 0 4vw;
box-sizing: border-box;
height: calc(100vh - 100px);
overflow: hidden;
overflow-y: auto;
.contant {
margin: 2vw 0;
.header {
height: 10vw;
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 3.5vw;
// padding: 2vw 0;
.icon {
display: inline-block;
width: 6vw;
height: 6vw;
border: 1px solid #e5e5e5;
margin-right: 2vw;
}
.title {
font-size: 4vw;
font-weight: 600;
margin-left: 1vw;
@include font_color($font-color-theme);
}
}
.select_box {
padding-top: 8px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: space-between;
padding: 3.5vw;
@include font_size($font_medium_s);
}
// 位置统计
.position {
min-height: 40vh;
.position-item {
height: 24vw;
margin-bottom: 2vw;
display: flex;
border-radius: 2vw;
overflow: hidden;
box-shadow: 0 0 4px 4px #e5e5e5;
.item-left {
display: flex;
align-items: center;
justify-content: center;
width: 10vw;
height: 24vw;
background: #1e4eca;
font-size: 4vw;
color: #fff;
padding: 0 2vw;
box-sizing: border-box;
text-align: center;
}
.item-right {
flex: 1;
display: flex;
justify-content: space-around;
align-items: center;
.item {
text-align: center;
.title {
text-align: center;
font-size: 4vw;
}
.numb {
font-size: 6vw;
font-weight: bold;
line-height: 9vw;
}
.num2 {
color: #e36356;
}
.num3 {
color: #205bf3;
}
.proportion {
text-align: center;
width: 100%;
font-size: 3vw;
img {
margin: 0 2px 0 4px;
}
.up-color {
color: #2bf242;
}
.down-color {
color: #e64a4a;
}
}
}
}
}
}
// 实时巡组
.callAll {
padding: 2px 5px;
background: linear-gradient(#00befb, #0b66d8);
border-radius: 1vw;
color: #fff;
margin-right: 1vw;
}
.group {
// box-shadow: 0 0 10px #ccc;
// padding: 4vw 2vw;
box-sizing: border-box;
margin: 0 3.5vw;
.search {
display: flex;
height: 8vw;
// ::v-deep .van-search__content {
// height: 8vw;
// }
.setchBtn {
margin-left: 1vw;
background: #2c5ff1;
padding: 1vw 4vw;
border-radius: 2vw;
color: #fff;
line-height: 6.5vw;
@include font_size($font_medium_s);
}
}
ul.groupList {
min-height: 10vh;
margin-top: 2vw;
overflow: hidden;
li {
padding-bottom: 2vw;
border-radius: 2vw;
margin-top: 2vw;
position: relative;
// background: #f7f7f7;
&:first-child {
margin-top: 0px;
}
.top {
display: flex;
justify-content: space-between;
padding: 0 3vw;
padding-top: 3vw;
line-height: 7vw;
padding-bottom: 1vw;
.top-cnt {
width: 80%;
@include font_size($font_medium_s);
}
.dian {
width: 2vw;
height: 2vw;
border-radius: 50%;
background: #999;
display: inline-block;
vertical-align: middle;
margin-right: 2vw;
&.online {
background: #1fd038;
}
&.busy {
background: #ed0000;
}
}
.name {
font-size: 4vw;
color: #5471f3;
vertical-align: middle;
}
.other {
font-size: 3vw;
}
.imgBtn {
padding-top: 10px;
margin-left: 2px;
img {
margin-right: 2vw;
width: 6vw;
height: 6vw;
border: 1px solid #e5e5e5;
&:last-child {
margin-right: 0;
}
}
}
}
li.active {
border: 1px solid #108fe7;
.checkBox {
display: block;
}
}
}
}
ul.positionList {
max-height: 60vh;
overflow: hidden;
overflow-y: auto;
}
// 地址
.address {
margin: 0 2vw;
@include bottm_tab_top_color($bottom-border-top-clore-theme);
height: 6vw;
line-height: 6vw;
font-size: 3vw;
padding: 2vw 0;
img,
span {
vertical-align: middle;
}
img {
margin-right: 2vw;
width: 4vw;
height: 4vw;
border: 1px solid #e5e5e5;
}
}
}
::v-deep .van-checkbox__label {
@include font_color($font-color-theme);
font-size: 3vw;
.dian {
width: 2vw;
height: 2vw;
border-radius: 50%;
background: #999;
display: inline-block;
vertical-align: middle;
margin-right: 1vw;
&.online {
background: #1fd038;
}
&.busy {
background: #ed0000;
}
&.blue {
background: #229bf0;
}
}
}
}
}
</style>