初始提交

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,217 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="指令详情" :showRight="false" :showLeft="true" />
<div class="detailBox">
<div class="detailInfo">
<div class="detailInfo-left">
<!-- <div class="photo"><img :src="detailInfo.carImg" alt=""></div> -->
<div class="photo"><img :src="detailInfo.photo" alt=""></div>
<div class="title">预警</div>
</div>
<div class="detailInfo-right">
<div class="info-item"><van-icon name="coupon-o" />{{detailInfo.plateNumber}}</div>
<div class="info-item"><van-icon name="manager-o" />{{detailInfo.userName}}</div>
<div class="info-item"><van-icon name="coupon-o" />{{detailInfo.checkName}}</div>
<div class="info-item">
<van-icon name="location-o" />{{detailInfo.activityAddress}}
</div>
<div class="info-item">
<van-icon name="clock-o" />{{detailInfo.time}}
</div>
</div>
</div>
<div class="liucheng">
<Steps :data="stepsData">
<template v-slot:default="{ scope }">
<div class="content">
<div class="cont_l" v-if="scope.isQsStatus == '01'">
<span class="triangleleft"></span>
<div class="status">待签收</div>
<div class="btns">
<span @click="handelEvents('reback')">拒绝</span>
<span @click="handelEvents('receive')">签收</span>
</div>
</div>
<div class="cont_l" v-if="scope.isQsStatus == '02'">
<span class="triangleleft"></span>
<div class="text">已签收</div>
<div class="text">
<van-icon name="manager-o" />周瓜皮 特警大队
</div>
<div class="text">
<van-icon
name="location-o"
/>成都市武侯区高新成都市武侯区高新公安局公安局
</div>
</div>
<div class="cont_l" v-if="scope.isQsStatus == '03'">
<span class="triangleleft"></span>
<div class="text">
<van-icon name="manager-o" />周瓜皮 特警大队
</div>
<div class="text">
<van-icon
name="location-o"
/>成都市武侯区高新成都市武侯区高新公安局公安局
</div>
</div>
</div>
</template>
</Steps>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import TopNav from "../../../components/topNav.vue";
import Steps from "../../../components/Steps.vue";
import { updateDetail,getyjzlInfoDetail } from "../../../api/checkponit.js";
import { useRouter, useRoute } from "vue-router";
import { Form } from "vant";
const route = useRoute();
const router = useRouter();
const detailInfo = ref({})
const stepsData = ref([
{ time: route.query.time, isQsStatus: "01" },
]);
onMounted(() => {
detailInfo.value = route.query
getInfoDetail('01')
});
// 签收
function handelEvents(val){
switch(val){
case 'receive':
getInfoDetail('02')
break
case 'reback':
break
}
}
// 指令详情
function getDetail(zlId){
getyjzlInfoDetail(zlId).then(res=>{
})
}
function getInfoDetail(zlztdm){
let params = {
zlztsj:route.query.time,
zlztddxz:route.query.activityAddress,
zlztddjd:route.query.jd,
zlztddwd:route.query.wd,
zlid:route.query.id,
zlztbmdm:JSON.parse(window.localStorage.getItem("userInfo")).deptList[0].deptCode,
zlztbmmc:JSON.parse(window.localStorage.getItem("userInfo")).deptList[0].deptName,
zlztrysfzh:route.query.sfzh,
zlztryxm:route.query.userName,
ssfxjmc:'',
ssfxjdm:'',
ssdszmc:'',
ssdszdm:'',
zlztdm:zlztdm,
}
updateDetail(params).then(res=>{
getDetail(route.query.id)
})
}
</script>
<style lang="scss" scoped>
.detailBox {
background: #e9e9e9;
height: calc(100vh - 13vw);
padding: 2vw 4vw;
box-sizing: border-box;
.detailInfo {
display: flex;
width: 100%;
background: #fff;
font-size: 14px;
padding: 2vw;
box-sizing: border-box;
.detailInfo-left {
margin-right: 4vw;
.photo {
width: 90px;
height: 110px;
border: 1px solid #e9e9e9;
img{
width: 100%;
height: 100%;
}
}
.title {
text-align: center;
line-height: 8vw;
color: #000;
}
}
.detailInfo-right {
flex: 1;
.info-item {
line-height: 7vw;
.van-icon {
margin-right: 2vw;
}
}
}
}
.liucheng {
.content {
padding: 2vw;
box-sizing: border-box;
.cont_l {
position: relative;
padding: 2vw;
box-sizing: border-box;
background: #fff;
.status {
line-height: 10vw;
border-bottom: 1px solid #ccc;
}
.btns {
display: flex;
span {
flex: 1;
text-align: center;
margin-top: 4vw;
color: #3373fa;
}
span:nth-child(1) {
color: red;
}
}
.triangleleft {
position: absolute;
left: -16px;
top: 46%;
display: inline-block;
width: 0;
height: 0;
border: 8px solid transparent;
border-right-color: #fff;
}
.text {
line-height: 7vw;
.van-icon {
margin-right: 2vw;
}
}
}
}
}
}
::v-deep .main .item .item_l .icon {
top: 50%;
}
::v-deep .main .item .item_l {
padding-top: 13%;
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,365 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="指令列表" :showRight="false" :showLeft="true" />
<div class="search">
<div class="sort">
<van-icon name="arrow-up" />
<van-icon name="arrow-down" />
时间排序
</div>
<span class="search-filter" @click="showRight = true">过滤筛选 <van-icon name="filter-o" /></span>
</div>
<!-- 列表 -->
<ul class="listBox">
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list v-model:loading="loading" :finished="finished" finished-text="" @load="onLoad" offset="1"
:immediate-check="false">
<li class="listBox-item" v-for="(item, index) in yjList" :key="index" @click="handelDetail(item)">
<YjzlItem :data="item" />
</li>
<van-empty description="暂无信息" image="default" v-if="yjList.length <= 0 && !loading" />
</van-list>
</van-pull-refresh>
</ul>
<!-- 弹出层 -->
<van-popup v-model:show="showRight" position="right" :style="{ width: '60%', height: '100%' }">
<div class="popup-content">
<div class="popup-title">过滤筛选</div>
<ul class="popup-box">
<li class="popup-item yjlx-info">
<van-field v-model="form.warnType" label-width="60px" label="预警类型:" readonly placeholder="请选择预警类型"
@click.stop="chooseYjlx()"></van-field>
<ul class="select-box" v-if="showLx">
<span class="triangleup"></span>
<li class="select-box-li" :class="isActive == 0 ? 'active' : ''" @click="cilickLx(0)">
车辆
</li>
<li class="select-box-li" :class="isActive == 1 ? 'active' : ''" @click="cilickLx(1)">
人员
</li>
</ul>
</li>
<li class="popup-item">
<van-field v-model="form.beginDate" label-width="60px" label="开始时间:" input-align="left"
placeholder="请选择开始时间" readonly @click.stop="onClickTime('start')"></van-field>
</li>
<li class="popup-item">
<van-field v-model="form.endDate" label-width="60px" input-align="left" label="结束时间:"
@click.stop="onClickTime('end')" placeholder="请选择结束时间" readonly></van-field>
</li>
</ul>
<div style="padding: 4vw 2vw">
<van-button block plain @click="(form = {}), (form.beginDate = dateFormat())"
style="margin-bottom: 2vw">重置</van-button>
<van-button block type="primary" @click="onSubmit" loading-type="spinner"
loading-text="登录中...">查询</van-button>
</div>
</div>
</van-popup>
<!-- 时间选择器 -->
<SelectTime :timeType="timeType" v-if="timeShow" @update:time="onSelectTime"
@update:cancelTime="timeShow = false" />
<!-- 时间提示框 -->
<van-popup v-model:show="alertInfo" round :style="{ width: '80%' }">
<div class="alertInfoBox">
<div class="alert">结束时间必须大于开始时间</div>
<div class="alertBtn" @click="alertInfo = false">确定</div>
</div>
</van-popup>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import TopNav from "../../../components/topNav.vue";
import YjzlItem from "../../../components//yjzlItem.vue";
import SelectTime from "../../../components//SelectTime.vue";
import { useRouter, useRoute } from "vue-router";
import { getyjzlList } from "../../../api/checkponit.js";
import { dateFormat } from "../../../utils/tools.js";
import { Loading } from "vant";
const route = useRoute();
const router = useRouter();
const showRight = ref(false);
const form = ref({ beginDate: dateFormat() });
const isActive = ref(-1);
const showLx = ref(false); //显示类型
const timeType = ref("start");
const timeShow = ref(false); //是否显示时间选择器
const page = ref(1); //分页
const pageSize = ref(10); //分页数
const total = ref(0); //总数
const yjList = ref([]);
const loadingPull = ref(false); //下拉刷新
const loading = ref(true); //数据加载中
const finished = ref(false); //数据加载完成
const alertInfo = ref(false) //消息提示
onMounted(() => {
getYjList();
});
// 触底加载数据
function onLoad() {
if (yjList.value.length < total.value) {
page.value++;
getYjList();
} else {
loading.value = false;
finished.value = true;
}
}
//下拉刷新
function onRefresh() {
loading.value = false;
loadingPull.value = false;
finished.value = false;
page.value = 1;
getYjList();
}
// 查询
function onSubmit() {
let date1 = new Date(form.value.beginDate); //开始
let date2 = new Date(form.value.endDate); //结束
if (date1 > date2) {
alertInfo.value = true
} else {
yjList.value = [];
showRight.value = false;
page.value = 1;
loading.value = true
getYjList();
}
}
// 获取预警指令列表
function getYjList() {
let warnType =
form.value.warnType == "车辆"
? "1"
: form.value.warnType == "人员"
? "2"
: "";
let params = {
currentPage: page.value,
pageSize: pageSize.value,
beginDate: '2022-01-01',
// beginDate: form.value.beginDate,
checkpointCode: route.query.kkid,
warnType: warnType,
endDate: form.value.endDate,
};
getyjzlList(params)
.then((res) => {
if (page.value == 1) {
yjList.value = res.records;
} else {
yjList.value = yjList.value.concat(res.records);
}
page.value = res.current;
pageSize.value = res.size;
total.value = res.total;
loading.value = false;
})
.catch(() => {
loading.value = false;
});
}
//查看详情
function handelDetail(item) {
let data = {
time: item.warnningTime,
label: item.label,
plateNumber: item.plateNumber,
checkName: item.checkName,
activityAddress: item.activityAddress,
id: item.id,
carImg: item.carImg,
userName: item.userName,
photo: item.idcardPhoto,
jd: item.jd,
wd: item.wd,
sfzh: item.idcard
}
router.push({ path: '/lmjHome/zlJczDetail', query: data })
}
// 时间点击
function onClickTime(val) {
timeType.value = val;
timeShow.value = true;
}
// 时间选中
function onSelectTime(val) {
if (timeType.value == "start") {
form.value.beginDate = val;
} else {
form.value.endDate = val;
}
timeShow.value = false;
}
// 选则类型
function chooseYjlx() {
showLx.value = !showLx.value;
}
// 选中类型
function cilickLx(val) {
isActive.value = val;
switch (val) {
case 0:
form.value.warnType = "车辆";
break;
case 1:
form.value.warnType = "人员";
break;
}
showLx.value = !showLx.value;
}
</script>
<style lang="scss" scoped>
.search {
padding: 2vw 2vw 0;
box-sizing: border-box;
height: 11vw;
line-height: 5vw;
font-size: 12px;
background: #f1f1f1;
.sort {
float: left;
padding: 1vw 3vw 1vw 6vw;
border: 1px solid #e9e9e9;
position: relative;
background: #fff;
.van-icon-arrow-up {
position: absolute;
left: 4px;
top: 2px;
}
.van-icon-arrow-down {
position: absolute;
left: 4px;
bottom: 2px;
}
}
.search-filter {
float: right;
color: #3373fa;
line-height: 8vw;
.van-icon {
font-size: 13px;
}
}
}
.listBox {
height: calc(100vh - 24vw);
overflow: hidden;
overflow-y: auto;
// .van-pull-refresh{
// height: 100%;
// overflow-y: auto;
// }
.listBox-item {}
}
// 弹窗
.popup-content {
.popup-title {
height: 40px;
line-height: 40px;
text-align: center;
background: #fff;
color: #000;
}
.popup-box {
border-top: 1px solid #e5e5e5;
font-size: 12px;
line-height: 11vw;
color: #000;
.popup-item {
border-bottom: 1px solid #e5e5e5;
.popup-name {
display: inline-block;
width: 60px;
text-align-last: justify;
}
}
}
.yjlx-info {
position: relative;
.select-box {
position: absolute;
z-index: 99;
width: 50%;
background: #fff;
border: 1px solid #ccc;
top: 50px;
right: 20px;
.select-box-li {
padding-left: 2vw;
box-sizing: border-box;
border-bottom: 1px solid #e9e9e9;
}
.active {
background: rgb(22, 220, 255);
color: #fff;
}
.select-box-li:last-child {
border: none;
}
}
.triangleup {
position: absolute;
left: 50px;
top: -13px;
display: inline-block;
width: 0;
height: 0;
border: 6px solid transparent;
border-bottom-color: #ccc;
}
}
}
.alertInfoBox {
padding: 2vw;
.alert {
line-height: 10vw;
text-align: center;
color: #8f8f94;
border-bottom: 1px solid #ddd;
}
.alertBtn {
text-align: center;
height: 12vw;
line-height: 12vw;
margin: 4vw 0;
background: #eee;
color: #8f8f94
}
}
</style>

View File

@ -0,0 +1,165 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="选择执勤卡点" :showRight="false" :showLeft="true" />
<div class="heckpointBox">
<!-- 查询 -->
<Search
v-model="jczValue"
placeholder="请输入搜索关键词"
@update:modelValue="onSearch"
></Search>
<!-- 列表 -->
<ul class="list">
<li class="item" v-for="(item, index) in List" :key="index">
<div class="title">{{ item.areaName }}</div>
<div class="item-li">
<van-radio-group v-model="cheaked" @change="chooseJcz(item.areaName)">
<van-radio
v-for="itemChid in item.checkList"
:name="itemChid.checkCode"
:key="itemChid.checkCode"
>{{ itemChid.pointName }}</van-radio
>
</van-radio-group>
</div>
</li>
<van-empty v-if="List.length<=0" description="暂无数据"/>
</ul>
<!-- 弹窗 -->
<van-popup
v-model:show="peoplePopupShow"
round
:style="{ width: '80%' }"
close-icon="close"
:overlay="true"
>
<div class="info">
<div class="info_title">是否选择{{selectTitle}}?</div>
<div class="info-btns">
<span @click="handlePClose"></span>
<span @click="handlePass"></span>
</div>
</div>
</van-popup>
</div>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import Search from "../../components/search.vue";
import router from "../../router/index.js";
import { getJczList } from "../../api/checkponit.js";
import { ref, reactive, onMounted, onUnmounted, onActivated } from "vue";
const jczValue = ref(""); //搜索关键字
const List = ref([]); //检查站列表
const cheaked = ref(null); //选择的检查站
const peoplePopupShow = ref(false); //弹窗
const selectTitle = ref(''); //弹窗标题
onMounted(() => {
getList(); //获取列表
});
// 搜索
function onSearch() {
}
// 获取列表
function getList() {
let user = JSON.parse(window.localStorage.getItem("userInfo"));
getJczList({ username: user.idEntityCard }).then((res) => {
List.value = handellArray(res);
});
}
// 处理数据
function handellArray(array) {
let arrWrap = [],resuleArr = [];
array.forEach((item) => {
if (!arrWrap.includes(item.areaCode)) {
let obj = {
areaName: item.areaName,
checkList: [],
};
obj.checkList.push(item);
resuleArr.push(obj);
arrWrap.push(item.areaCode);
} else {
resuleArr[arrWrap.indexOf(item.areaCode)].checkList.push(item);
}
});
return resuleArr;
}
// 选择检查站
function chooseJcz(val) {
peoplePopupShow.value = true
List.value.forEach(item=>{
if(item.areaName == val){
item.checkList.forEach(child=>{
if(child.checkCode == cheaked.value) selectTitle.value = child.pointName
})
}
})
}
// 确定弹窗
function handlePass(){
peoplePopupShow.value = false
router.push({path:'/',query:{kkid:cheaked.value,kkmc:selectTitle.value}});
}
// 关闭弹窗
function handlePClose() {
peoplePopupShow.value = false
}
</script>
<style lang="scss" scoped>
.heckpointBox {
.list {
.title {
height: 50px;
font-size: 20px;
line-height: 50px;
background: #ddd;
padding: 0 6vw;
box-sizing: border-box;
color: #999;
}
.item-li {
padding: 0 6vw;
box-sizing: border-box;
.van-radio {
height: 46px;
line-height: 46px;
border-bottom: 1px solid #e9e9e9;
}
}
}
}
// 提示数据
.info{
.info_title{
text-align: center;
line-height: 15vw;
border: 1px solid #e9e9e9;
padding:'10px';
box-sizing: border-box;
font-size: 17px;
}
.info-btns{
display: flex;
justify-content: space-around;
align-items: center;
height: 11vw;
span{
flex: 1;
text-align: center;
color: #007aff;
}
}
}
</style>

View File

@ -0,0 +1,249 @@
<template>
<div style="height:100vh;padding-top: 13vw;">
<TopNav navTitle="当前位置" :showRight="false" :showLeft="true" />
<GdMap />
</div>
</template>
<script setup>
import Axios from "axios";
import { getyjzlCount } from "../../api/checkponit.js";
import { qcckGet } from "@/api/qcckApi.js";
import {
dateFormat,
setUserHome,
hintToast,
timeValidate,
} from "../../utils/tools.js";
import TopNav from "../../components/topNav.vue";
import GdMap from "../../components/GdMap/index.vue";
import { setUserDefaultModleData, getUserLzLocation } from "../../api/user.js";
import emitter from "../../utils/eventBus.js";
import {
ref,
onMounted,
} from "vue";
import { useRouter, useRoute } from "vue-router";
import { Dialog } from "vant";
const route = useRoute();
const Loadtion = ref({
address: "暂无地址信息",
lng: "暂无",
lat: "暂无",
ly: "暂无",
});
let timer;
onMounted(() => {
localStorage.removeItem('NFC')
localStorage.removeItem('OCR')
_getUserLocation(true); //获取当前位置
setInterval(() => {
_getUserLocation(false); //获取当前位置
}, 5000);
});
//获取当前位置信息
function _getUserLocation(sfdw) {
let { lng, lat, zbly } = getLocation();
if (lng && lat) {
Loadtion.value.lng = lng;
Loadtion.value.lat = lat;
Loadtion.value.ly = zbly == 1 ? "GPS" : "融合";
emitter.emit("deletePointArea", "dw");
//地图撒点然后移动
emitter.emit("addPointArea", {
coords: [{ jd: lng, wd: lat }],
icon: require("../../assets/lz/dw.png"),
flag: "dw",
sfdw: sfdw,
sizeX: 30,
sizeY: 35
});
} else {
hintToast("暂无坐标信息");
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
::v-deep .van-radio-group {
padding: 5vw;
}
::v-deep .van-radio {
padding: 2vw 0;
}
.homeTotal_box {
position: absolute;
bottom: 13.5vw;
z-index: 20;
background: #fff;
width: 100%;
border-top-left-radius: 2vw;
border-top-right-radius: 2vw;
}
.home_box {
padding: 1vw 3vw 3vw 3vw;
}
.point-pop-alert {
position: absolute;
display: flex;
flex-direction: column;
top: 80px;
right: 10px;
>img {
width: 45px;
height: 45px;
margin: 2vw 0;
}
}
.count-box {
display: flex;
flex-wrap: wrap;
line-height: 3.5vh;
justify-content: space-around;
@include font_size($font_medium_s);
.count-item {
margin-top: 1vh;
width: 47%;
display: flex;
margin-top: 3%;
align-items: center;
background-color: rgba(140, 175, 206, 0.1);
border-radius: 1.5vw;
.bottom-box {
flex: 1;
box-sizing: border-box;
padding: 10px;
border-right: 1px dashed rgb(172, 171, 171);
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
line-height: 2.5vh;
.inner-box {
width: 70%;
text-align: center;
}
}
.text-box {
color: rgb(179, 179, 179);
}
.left {
flex: 1;
text-align: center;
// margin-right: 4vw;
}
.right {
flex: 1;
text-align: center;
// margin-left: 4vw;
}
.num1 {
color: rgb(16, 16, 16);
font-weight: bold;
}
.num2 {
color: rgb(5, 167, 24);
font-weight: bold;
}
.num3 {
color: rgb(241, 8, 8);
font-weight: bold;
}
.top {
display: flex;
}
}
// 检查站
.count-item-jcz {
width: calc(50% - 1px);
text-align: center;
color: #999;
border-top: 1px solid #e9e9e9;
.count-time-jcz {
font-size: 1rem;
color: #222;
line-height: 12vw;
}
.count-item-jcz-num {
display: flex;
@include font_size($font_medium_s);
.count-item-jcz-num-left {
position: relative;
width: 50%;
text-align: right;
padding: 0 3vw;
box-sizing: border-box;
}
.count-item-jcz-num-right {
width: 50%;
text-align: left;
padding: 0 3vw;
box-sizing: border-box;
}
.count-item-jcz-num-left::after {
content: "";
position: absolute;
right: 0;
top: 10px;
bottom: 10px;
width: 1px;
background: #e9e9e9;
border-radius: 1px;
}
.num-red {
color: #f00;
font-size: 14px;
}
.num {
color: #000;
font-size: 14px;
}
}
}
.count-item-jcz:nth-child(2n + 1) {
border-right: 1px solid #e9e9e9;
}
}
.count-box-jcz {
padding-top: 1vh;
box-sizing: border-box;
}
.hsf {
position: absolute;
top: 20px;
right: 18px;
}
</style>

39
src/pages/error/index.vue Normal file
View File

@ -0,0 +1,39 @@
<template>
<div class="errorbox">
<div>
<img src="../../assets/error.png" alt="">
<div class="text_l">无法连接到网络</div>
<div class="text_s">请检查到网络后退出重试</div>
</div>
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.errorbox{
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
background: #eef8fe;
img{
width: 74vw;
}
.text_l{
text-align: center;
line-height: 8vw;
margin-top: 2vw;
font-size: 16px;
color: #000;
}
.text_s{
text-align: center;
@include font_size($font_medium_s);
color: #ccc;
}
}
</style>

172
src/pages/login/index.vue Normal file
View File

@ -0,0 +1,172 @@
<template>
<div class="login">
<van-tabs v-model:active="TabActiveName">
<van-tab title="账号登录" name="a"></van-tab>
<!-- <van-tab title="手机号登录" name="b"></van-tab> -->
</van-tabs>
<van-form @submit="onSubmit" class="form" v-show="TabActiveName == 'a'">
<van-field v-model="form.userName" name="userName" label="用户名" placeholder="用户名" left-icon="manager"
label-width="50px" :rules="[{ required: true, message: '请填写用户名' }]" />
<van-field v-model="form.password" type="password" name="password" label="密码" placeholder="密码" left-icon="lock"
label-width="50px" :rules="[{ required: true, message: '请填写密码' }]" />
<van-field name="radio" label="人员类型" left-icon="manager">
<template #input>
<van-radio-group v-model="form.type" direction="horizontal">
<van-radio name="01">民警</van-radio>
<van-radio name="02">辅警</van-radio>
</van-radio-group>
</template>
</van-field>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="登录中...">登录</van-button>
</div>
</van-form>
<van-form @submit="onSubmit" class="form" v-show="TabActiveName == 'b'">
<van-field v-model="form.phone" name="phone" label="手机号" placeholder="手机号" left-icon="manager" label-width="50px"
:rules="[{ required: true, message: '请填写手机号' }]" />
<van-field v-model="form.code" center clearable label="短信验证码" placeholder="请输入短信验证码" left-icon="lock"
:rules="[{ required: true, message: '请输入短信验证码' }]">
<template #button>
<van-button type="primary" :disabled="countdown > 0" @click="sendCode">
{{ countdown > 0 ? `${countdown}s后重新发送` : '发送验证码' }}
</van-button>
<!-- <van-button size="small" type="primary">发送验证码</van-button> -->
</template>
</van-field>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="登录中...">登录</van-button>
</div>
</van-form>
</div>
</template>
<script setup>
import "vant/es/toast/style";
import Base64 from "base-64";
import { login, idCardlogin, getUserOrFjInfo } from "../../api/user.js";
import { computed, ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { Overlay, Toast } from "vant";
import axios from "axios";
const router = useRouter();
const store = useStore();
const TabActiveName = ref()
const count = ref(0);
const form = reactive({
userName: "",
password: "",
type: "02"
});
const countdown = ref(0);
const isLoading = ref(false);
onMounted(() => {
_idCardlogin();
});
//身份证登录
function _idCardlogin() {
try {
let userinfo = JSON.parse(bridge.getLocation());
Toast.loading({
message: "登录中...",
forbidClick: true,
loadingType: "spinner",
overlay: true,
duration: 0,
});
isLoading.value = true;
form.userName = userinfo.app_sfzh;
idCardlogin({ idCardNo: userinfo.app_sfzh })
.then((res) => {
const token = res.jwtToken;
_getUserInfo(res.userId, res.idEntityCard, res.deptList[0].deptName, res.deptList);
store.commit("setToken", token);
})
.catch((err) => {
Toast.clear();
isLoading.value = false;
});
} catch (error) { }
}
const sendCode = async () => {
// 发送短信验证码的逻辑
// 比如调用API发送短信
// console.log('发送验证码给', form.value.phone);
// 模拟计时器
countdown.value = 60;
const intervalId = setInterval(() => {
if (countdown.value > 0) {
countdown.value--;
} else {
clearInterval(intervalId);
}
}, 1000);
};
//手动登录
const onSubmit = (e) => {
isLoading.value = true;
Toast.loading({
message: "登录中...",
forbidClick: true,
loadingType: "spinner",
overlay: true,
duration: 0,
});
login({
kaptcha: "",
userName: e.userName.trim(),
password: Base64.encode(e.password.trim()),
type: form.type
})
.then((res) => {
const token = res.jwtToken;
_getUserInfo(res.userId, res.idEntityCard, res.deptList[0].deptName, res.deptList);
store.commit("setToken", token);
})
.catch((err) => {
Toast.clear();
isLoading.value = false;
});
};
//获取用户信息
function _getUserInfo(id, sfzh, deptName, deptList) {
getUserOrFjInfo({ id, sfzh }).then((res) => {
let { userName, id, idEntityCard, mobile, inDustRialId, sex } = res;
let userinfo = {
deptName,
userName,
deptList,
id,
idEntityCard,
mobile,
inDustRialId,
sex,
};
store.commit("userStatus", userinfo);
//获取用户上次访问的首页
let path = getStorage("homeUrl");
setTimeout(() => {
isLoading.value = false;
router.replace("/Home");
Toast.clear();
}, 1e3);
});
}
</script>
<style lang="scss" scoped>
.login {
width: 90%;
margin: 0 auto;
margin-top: 20vh;
}
.form {
margin-top: 10%;
background-color: #fff;
overflow: hidden;
}
</style>

296
src/pages/my/index.vue Normal file
View File

@ -0,0 +1,296 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="我的" :showRight="true" :showLeft="true" />
<div class="user_box" @touchstart="onTouchstart" @touchmove="onTouchmove" @touchend="onTouchchend">
<img src="../../assets/images/tx.png" alt="" style="width: 75px; height: 75px" />
<div class="user">
<span class="user_name">{{ user.userName }}</span>
<span class="user_dep">{{ user.deptName }}</span>
</div>
</div>
<div class="user_function_box">
<div class="user_function_item" v-for="(item, index) in functionList.list" :key="index"
@click="onClickSkip(item.path)">
<div class="">
<img :src="item.imgUrl" alt="" style="width: 28px; height: 28px" />
<span class="function_title">{{ item.name }}</span>
</div>
<van-icon name="arrow" />
</div>
</div>
<van-popup v-model:show="showLoadtion">
<div class="loadtion_box">
<van-field v-model="Loadtion.address" colon label="地址" label-width="40px" />
<van-field v-model="Loadtion.lng" colon label="经度" label-width="40px" />
<van-field v-model="Loadtion.lat" colon label="纬度" label-width="40px" />
<van-field v-model="Loadtion.ly" colon label="来源" label-width="40px" />
</div>
</van-popup>
<van-popup v-model:show="showLogin">
<van-form @submit="onSubmit" class="form">
<van-field v-model="form.userName" name="userName" label="用户名" placeholder="身份证号或警号" left-icon="manager"
label-width="50px" :rules="[{ required: true, message: '请填写身份证号或警号' }]" />
<van-field v-model="form.password" type="password" name="password" label="密码" placeholder="密码" left-icon="lock"
label-width="50px" :rules="[{ required: true, message: '请填写密码' }]" />
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="登录中...">登录</van-button>
</div>
</van-form>
</van-popup>
<!-- 底部tas -->
<!-- <BottomTabs type="wd" /> -->
<div style="height: 11.8666vw"></div>
</div>
</template>
<script setup>
import Base64 from "base-64";
import { ref, reactive, onMounted, onActivated } from "vue";
import {
login,
idCardlogin,
getUserInfo,
getUserLzLocation,
} from "../../api/user.js";
import BottomTabs from "../../components/bottomTabs.vue";
import TopNav from "../../components/topNav.vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import { hintToast } from "../../utils/tools.js";
const store = useStore();
const showLogin = ref(false);
const showLoadtion = ref(false);
const Loadtion = ref({
address: "暂无地址信息",
lng: "暂无",
lat: "暂无",
ly: "暂无",
});
const form = ref({
userName: "",
password: "",
});
const user = ref({
userName: "警官",
deptName: "测试部门",
});
const isLoading = ref(false);
const router = useRouter();
const caEnevt = ref(0);
//功能模块
const functionList = reactive({
list: [
{
name: "个人信息",
imgUrl: require("../../assets/images/menu-info.png"),
path: "/userInfo",
},
{
name: "工作日志",
imgUrl: require("../../assets/images/menu-gzrz@2x.png"),
path: "/gzrz",
},
{
name: "我的轨迹",
imgUrl: require("../../assets/images/menu-wdgj.png"),
path: "/wdgj",
},
{
name: "收藏应用",
imgUrl: require("../../assets/images/menu-scyy.png"),
path: "/scyy",
},
{
name: "任务中心",
imgUrl: require("../../assets/images/menu-rwtj.png"),
path: "/yyzx/rwzx",
},
{
name: "我的巡防报备",
imgUrl: require("../../assets/images/menu-rwzx.png"),
path: "/calendar",
},
{
name: "我的值班报备",
imgUrl: require("../../assets/images/leader/top_bb.png"),
path: "/zbbbCalendar",
},
// {
// name: "通讯录",
// imgUrl: require("../../assets/images/menu-txl.png"),
// path: "/txl",
// },
{
name: "当前位置",
imgUrl: require("../../assets/gxapp/overview.png"),
path: "dqwz",
},
],
});
onMounted(() => {
user.value = JSON.parse(window.localStorage.getItem("userInfo"));
});
//获取当前位置信息
function _getUserLocation() {
let { lng, lat, zbly } = getLocation();
if (jd && lat) {
Loadtion.value.lng = lng;
Loadtion.value.lat = lat;
Loadtion.value.ly = zbly == 1 ? "GPS" : "融合";
getUserLzLocation({ "jd": lng, "wd": lat }).then((res) => {
if (res) {
Loadtion.value.address = res;
}
});
showLoadtion.value = true;
} else {
hintToast("暂无坐标信息");
}
}
//长按事件
function onTouchstart() {
window.isClick = true;
caEnevt.value = setTimeout(() => {
window.isClick = false;
showLogin.value = true;
}, 5e3);
return false;
}
//清除事件
function onTouchmove() {
clearTimeout(caEnevt.value);
caEnevt.value = 0;
}
//释放事件
function onTouchchend() {
clearTimeout(caEnevt.value);
if (caEnevt.value) {
}
return false;
}
//手动登录
const onSubmit = (e) => {
isLoading.value = true;
login({
kaptcha: "",
userName: e.userName.trim(),
password: Base64.encode(e.password.trim()),
})
.then((res) => {
isLoading.value = false;
const token = res.jwtToken;
_getUserInfo(res.userId, res.deptList[0].deptName, res.deptList);
store.commit("setToken", token);
})
.catch((err) => {
isLoading.value = false;
});
};
//获取用户信息
function _getUserInfo(id, deptName, deptList) {
getUserInfo(id).then((res) => {
let { userName, id, idEntityCard, mobile, inDustRialId, sex } = res;
let userinfo = {
deptName,
userName,
deptList,
id,
idEntityCard,
mobile,
inDustRialId,
sex,
};
store.commit("userStatus", userinfo);
showLogin.value = false;
user.value = JSON.parse(getStorage("userInfo"));
user.value = userinfo;
form.value.userName = "";
form.value.password = "";
});
}
//跳转
function onClickSkip(url) {
switch (url) {
case "dqwz":
router.push('/dqLocation')
// _getUserLocation();
break;
default:
router.push(url);
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.user_function_box,
.user_box {
@include font_color($font-color-theme);
}
.user_box {
display: flex;
align-items: center;
padding: 4vw 3vw;
margin: 3vw;
border-radius: 5px;
@include user_function_item_color($user-function-item-theme);
.user {
display: flex;
flex-direction: column;
margin-left: 3vw;
.user_name {
@include font_size($font_large_s);
}
.user_dep {
@include font_size($font_medium_s);
margin-top: 2vw;
}
}
}
.user_function_box {
@include user_function_item_color($user-function-item-theme);
@include font_size($font_medium_s);
margin: 0 3vw;
border-radius: 5px;
padding: 0vw 3vw;
.user_function_item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 3vw 0;
@include item_bottom_color($bottom-border-top-clore-theme);
>div {
display: flex;
align-items: center;
.function_title {
display: inline-block;
margin-left: 5vw;
}
}
}
}
.form {
width: 350px;
border-radius: 2vw;
}
.loadtion_box {
width: 340px;
}
::v-deep .van-popup {
border-radius: 1.5vw;
}
</style>

103
src/pages/my/views/gzrz.vue Normal file
View File

@ -0,0 +1,103 @@
<template>
<div style="padding-top: 13vw;">
<TopNav navTitle="工作日志" :rightTitle="'地图模式'"/>
<div class="rz_item_box" v-for="(item,index) in gzrzList.list" :key="index" >
<div class="rz_item_img_box">
<van-image width="45px" height="45px" fit="contain" :src="item.imgUrl">
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
<div class="rz_item_text">
<div class="time">{{item.time}}</div>
<div>
<soan>{{item.name}}</soan>
<soan class="address">{{item.address}}</soan>
</div>
</div>
</div>
<soan class="rz_zt" :class="item.status == 0 ? 'proceed' : 'accomplish'">{{item.status == 0 ? '进行中' : '已完成'}}</soan>
</div>
</div>
</template>
<script setup>
import TopNav from '../../../components/topNav.vue';
import {
ref,
reactive
} from 'vue';
const themeType = ref(getStorage('themeSetting'));
const gzrzList = reactive({
list: [{
name: '人员核查',
time: '2022-03-11 14:32:55',
address: '高新区创业路5号3单元',
imgUrl: require('../../../assets/images/menu-yyhc.png'),
status: 0
},
{
name: '车辆核查',
time: '2022-03-11 14:32:55',
address: '高新区创业路5号3单元',
imgUrl: require('../../../assets/images/menu-clhc.png'),
status: 1
},
{
name: '人员报备',
time: '2022-03-11 14:32:55',
address: '高新区创业路5号3单元',
imgUrl: require('../../../assets/images/menu-rwzx.png'),
status: 1
}
]
})
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.rz_item_box {
display: flex;
justify-content: space-between;
align-items: center;
padding:4vw 3vw;
// border-bottom: 1px solid #F1F3F4;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
@include item_bottom_color($bottom-border-top-clore-theme);
.rz_item_img_box {
display: flex;
align-items: center;
}
.rz_item_text {
margin-left: 3vw;
.time {
@include font_size($font_medium);
margin-bottom: 1.5vw;
}
.address {
margin-left: 5vw;
}
}
.rz_zt {
height: 5vw;
@include font_size($font_little_s);
padding: 2px 8px;
border-radius: 15px;
color: #fff;
}
.accomplish{
background-color: #23D96E;
}
.proceed{
background-color: #3e6ee8;
}
}
</style>

106
src/pages/my/views/scyy.vue Normal file
View File

@ -0,0 +1,106 @@
<template>
<div style="padding-top: 13vw;">
<TopNav navTitle="收藏应用" />
<div class="function_item_box">
<div @click="routerPush(item.path)" class="function_item" v-for="item in zhxfList.list" :key="item">
<van-image width="55px" height="55px" fit="contain" :src="item.imgUrl">
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
<div class="item_name">{{item.name}}</div>
</div>
</div>
</div>
</template>
<script setup>
import TopNav from '../../../components/topNav.vue';
import {
ref,
reactive
} from 'vue';
import router from '../../../router';
//智慧巡防
const zhxfList = reactive({
list: [{
name: '巡防报告',
imgUrl: require('../../../assets/images/menu-rwzx.png'),
path: ''
},
{
name: '盘查物品',
imgUrl: require('../../../assets/images/home/FXYJ@3x.png'),
path: ''
}, {
name: '指令信息',
imgUrl: require('../../../assets/images/menu-zlzx.png'),
path: ''
},
{
name: '报备信息',
imgUrl: require('../../../assets/images/menu-qwzx.png'),
path: ''
},
{
name: '指令设置',
imgUrl: require('../../../assets/images/menu-qwzx.png'),
path: ''
},
{
name: '巡防区',
imgUrl: require('../../../assets/images/11.png'),
path: '/scyy/xfq'
},
{
name: '警务站',
imgUrl: require('../../../assets/images/2.png'),
path: '/scyy/jwz'
},
{
name: '快反点',
imgUrl: require('../../../assets/images/3.png'),
path: '/scyy/kfd'
},
{
name: '巡防力量',
imgUrl: require('../../../assets/images/4.png'),
path: '/scyy/xfll'
},
{
name: '车辆',
imgUrl: require('../../../assets/images/5.png'),
path: '/scyy/cl'
},
{
name: '装备',
imgUrl: require('../../../assets/images/6.png'),
path: '/scyy/zb'
}
]
})
function routerPush(url){
router.push(url)
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.function_item_box {
display: flex;
flex-wrap: wrap;
@include font_color($font-color-theme);
.function_item {
// border: 1px solid red;
width: 25%;
text-align: center;
margin-top: 4vw;
.item_name {
margin-top: 1.5vw;
@include font_size($font_medium_s);
}
}
}
</style>

View File

@ -0,0 +1,54 @@
<template>
<van-config-provider :theme-vars="themeVars">
<div style="padding-top: 13vw">
<TopNav navTitle="通讯录" />
<!-- <van-index-bar> -->
<!-- <van-index-anchor index="A" /> -->
<Search
v-model="kwd"
placeholder="请输入搜索关键词"
@update:modelValue="onSearch"
></Search>
<template v-for="item in 10" :key="item">
<van-cell title="张三(高新网安大队)" label="13612345678">
<template #right-icon>
<van-icon name="phone-circle" color="#3e6ee8" class="search-icon" />
</template>
</van-cell>
<van-cell title="李四(高新网安大队)" label="13612345678">
<template #right-icon>
<van-icon name="phone-circle" color="#3e6ee8" class="search-icon" />
</template>
</van-cell>
<van-cell title="王五(高新网安大队)" label="13612345678">
<template #right-icon>
<van-icon name="phone-circle" color="#3e6ee8" class="search-icon" />
</template>
</van-cell>
</template>
<!-- </van-index-bar> -->
</div>
</van-config-provider>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import Search from "../../../components/search.vue";
import { ref, reactive } from "vue";
const listIndex = ref(["A"]);
const themeType = ref(getStorage("themeSetting"));
const kwd = ref("");
const themeVars = ref({
cellBackgroundColor: themeType.value == "light" ? "#fff" : "#041634",
cellBorderColor: themeType.value == "light" ? "#dbdbdb" : "#001e6b",
cellTextColor: themeType.value == "light" ? "#333" : "#fff",
});
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.search-icon {
font-size: 30px;
}
</style>

View File

@ -0,0 +1,182 @@
<template>
<van-config-provider :theme-vars="themeVars">
<div style="padding-top: 13vw">
<TopNav navTitle="个人信息" />
<div class="user_function_box">
<div
class="user_function_item"
v-for="(item, index) in functionList.list"
:key="index"
>
<span class="function_title">{{ item.name }}</span>
<van-image
width="45px"
height="45px"
fit="contain"
:src="item.message"
v-if="item.isImg"
>
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
<!-- <template v-slot:error>图片加载失败</template> -->
</van-image>
<van-field
v-model="item.message"
input-align="right"
:readonly="item.readonly"
v-else
/>
</div>
</div>
<div style="margin: 10vw 3vw" @click="onClickSave">
<van-button type="primary" round block>保存</van-button>
</div>
</div>
</van-config-provider>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import TopNav from "../../../components/topNav.vue";
import { hintToast } from "../../../utils/tools.js";
const themeType = ref(getStorage("themeSetting"));
const themeVars = ref({
cellBackgroundColor: themeType.value == "light" ? "#fff" : "#092556",
fieldInputTextColor: themeType.value == "light" ? "#333" : "#fff",
});
//功能模块
const functionList = reactive({
list: [
{
name: "姓名",
message: "警官",
readonly: true,
},
{
name: "照片",
message: require("../../../assets/images/tx.png"),
isImg: true,
},
{
name: "性别",
message: "男",
readonly: true,
},
{
name: "座机电话",
message: "02812345678",
readonly: false,
},
{
name: "手机",
message: "13612345678",
readonly: false,
},
{
name: "组织机构",
message: "测试部门",
readonly: true,
},
{
name: "警号",
message: "121380",
readonly: true,
},
],
});
onMounted(() => {
let user = JSON.parse(getStorage("userInfo"));
functionList.list.forEach((item) => {
switch (item.name) {
case "姓名":
item.message = user.userName;
break;
case "性别":
if (user.sex == 1) {
item.message = "男";
} else if (user.sex == 2) {
item.message = "女";
} else {
item.message = "未知";
}
break;
case "座机电话":
item.message = user.telePhone;
break;
case "手机":
item.message = user.mobile;
break;
case "组织机构":
item.message = user.deptName;
break;
case "警号":
item.message = user.inDustRialId;
break;
}
});
});
//保存
function onClickSave() {
hintToast("保存成功")
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.user_function_box,
.user_box {
@include font_color($font-color-theme);
}
.user_box {
// background: url('../../../assets/images/my-info-bg@2x.png') no-repeat;
// background-size: 100% 100%;
display: flex;
align-items: center;
padding: 4vw 3vw;
margin: 3vw;
border-radius: 5px;
@include user_function_item_color($user-function-item-theme);
.user {
display: flex;
flex-direction: column;
margin-left: 3vw;
.user_name {
@include font_size($font_large_s);
}
.user_dep {
@include font_size($font_medium_s);
margin-top: 2vw;
}
}
}
.user_function_box {
margin-bottom: 10vw;
@include user_function_item_color($user-function-item-theme);
@include font_size($font_medium_s);
padding: 2vw 3vw;
margin: 3vw;
border-radius: 5px;
.user_function_item {
display: flex;
align-items: center;
justify-content: space-between;
@include item_bottom_color($bottom-border-top-clore-theme);
padding: 2vw 0;
.function_title {
width: 22vw;
}
}
.user_function_item:last-child {
border-bottom: none;
}
}
::v-deep .van-field__control--right {
@include font_size($font_medium_s);
}
</style>

163
src/pages/my/views/wdgj.vue Normal file
View File

@ -0,0 +1,163 @@
<!--
* @Author: your name
* @Date: 2022-09-15 14:10:42
* @LastEditTime: 2022-09-27 16:12:16
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \new_gxga_app\src\pages\my\views\wdgj.vue
-->
<template>
<van-config-provider :theme-vars="themeVars">
<div style="padding-top: 13vw">
<TopNav
navTitle="我的轨迹"
rightIcon="location"
:showRight="true"
@clickRight="onClickRight"
/>
<van-cell title="选择时间" @click="calShow = true">
<template #value>
<span>{{ chooseTime }}</span>
</template>
</van-cell>
<van-calendar
v-model:show="calShow"
@confirm="onConfirm"
:min-date="minDate"
:max-date="maxDate"
color="#3e6ee8"
></van-calendar>
<van-list
v-model:loading="loading"
:finished="finished"
finished-text=" "
@load="onLoad"
offset="30"
:immediate-check="false"
>
<van-steps
direction="vertical"
:active="0"
active-color="#3e6ee8"
:inactive-color="themeType == 'light' ? '#333' : '#fff'"
>
<van-step v-for="item in gjList" :key="item">
<div class="steps_box">{{ item.dwsj }}</div>
<div class="steps_box">地址{{ item.dzxz }}</div>
<div class="steps_box">
停留时长{{ (item.xfsc / 60 / 60).toFixed(2) }}小时
</div>
</van-step>
</van-steps>
<van-empty
description="暂无轨迹信息"
image="default"
v-if="gjList.length <= 0 && showEmpty"
/>
</van-list>
</div>
</van-config-provider>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { ref, reactive, onMounted } from "vue";
import { getWdgj } from "../../../api/common.js";
import { getUserLzLocation } from "../../../api/user.js";
import { dateFormat } from "../../../utils/tools.js";
import router from "../../../router/index.js";
const themeType = ref(getStorage("themeSetting"));
const themeVars = ref({
stepsBackgroundColor: themeType.value == "light" ? "#fff" : "#041634",
});
const minDate = new Date(2000, 0, 1);
const maxDate = new Date();
const chooseTime = ref(dateFormat());
const calShow = ref(false); //是否显示日历
const gjList = ref([]); //轨迹数据
const loading = ref(false);
const finished = ref(false);
const pageSize = ref(10);
const pageCurrent = ref(1);
const total = ref(0);
const showEmpty = ref(false);
const kssj = ref(dateFormat());
const jssj = ref(dateFormat());
onMounted(() => {
_getWdgj();
});
//触底加载
function onLoad() {
if (total.value <= pageCurrent.value) {
finished.value = true;
return;
}
pageCurrent.value++;
_getWdgj();
}
//确认日期选择
function onConfirm(val) {
calShow.value = false;
pageCurrent.value = 1;
gjList.value = [];
chooseTime.value = dateFormat("", val);
_getWdgj();
}
//点击地图模式
function onClickRight() {
router.push(`/my/views/wdgjMapPoint?time=${chooseTime.value}`);
}
//获取轨迹数据
function _getWdgj() {
loading.value = true;
let data = {
pageSize: pageSize.value,
pageCurrent: pageCurrent.value,
dwrq: chooseTime.value,
sfzh: JSON.parse(window.localStorage.getItem("userInfo")).idEntityCard,
};
getWdgj(data)
.then((res) => {
loading.value = false;
if (res && res.records.length > 0) {
total.value = res.pages;
for (let i = 0; i < res.records.length; i++) {
res.records[i].address = "";
// _getUserLocation(res.records[i].jd, res.records[i].wd, (_res) => {
// res.records[i].address = _res;
// gjList.value.push(res.records[i]);
// });
gjList.value.push(res.records[i]);
}
} else {
showEmpty.value = true;
}
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
//获取当前位置信息
function _getUserLocation(jd, wd, fun) {
getUserLzLocation({ jd, wd }).then((res) => {
if (res) {
fun(res);
}
});
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
::v-deep .van-step__line {
background: #ebedf0 !important;
}
.steps_box {
// @include font_color($font-color-theme);
@include font_size($font_medium_s);
line-height: 6vw;
}
</style>

View File

@ -0,0 +1,78 @@
<template>
<div>
<TopNav navTitle="地图模式" :showRight="false" :showLeft="true" />
<GdMap />
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import TopNav from "../../../components/topNav.vue";
import GdMap from "../../../components/GdMap/index.vue";
import { getMApWdgj } from "../../../api/common.js";
import { hintToast } from "../../../utils/tools.js";
import emitter from "../../../utils/eventBus.js";
const item = ref(null); // 警情数据
const isRlt = ref(false);
const points = ref([]);
onMounted(() => {
window.closeMapTitle = closeMapTitle;
_getMApWdgj();
});
//获取坐标数据
function _getMApWdgj() {
let data = {
dwrq: useRoute().query.time,
sfzh: JSON.parse(window.localStorage.getItem("userInfo")).idEntityCard,
};
getMApWdgj(data).then((res) => {
if (res && res.zbList.length > 0) {
for (let i = 0; i < res.zbList.length; i++) {
points.value = [...points.value, ...res.zbList[i]];
}
points.value = points.value.join(",");
emitter.emit("drawLine", points.value);
}
});
}
//关闭弹窗dom
function closeMapTitle(val) {
let doms = document.getElementById(val);
doms.remove();
}
</script>
<style lang="scss" scoped>
.map_but_box {
position: absolute;
bottom: 10vw;
width: 50%;
left: 50%;
z-index: 99;
margin-left: -25%;
}
.top_btn {
position: fixed;
top: 16vw;
left: 0;
right: 12px;
height: 24px;
color: #fff;
z-index: 9;
text-align: right;
span {
display: inline-block;
border: 1px solid #fff;
line-height: 22px;
padding: 0 12px;
border-radius: 12px;
font-size: 14px;
}
span.active {
background: #517cea;
border-color: #517cea;
}
}
</style>

View File

@ -0,0 +1,94 @@
<template>
<ul>
<li v-for="item in listData" :key="item" @click="changeOpen(item)">
<img :src="item.imgUrl" alt="">
<div class="text">{{ item.text }}</div>
</li>
</ul>
<PrpcPopup ref="prpc" :key="pcKey + 'pc'" />
</template>
<script setup>
import { ref, onMounted,nextTick } from "vue";
import { useRouter, useRoute } from "vue-router";
import PrpcPopup from "../spsHome/components/prpcPopup.vue";
const router = useRouter();
const pcKey = ref(0);
const prpc = ref(null);
const listData = ref([
{
text: '勤务报备',
imgUrl: require("@/assets/home/qwbb.png"),
type: 'qwbb',
path: '/yyzx/xfbb/addXfbb'
},
{
text: '人车盘查',
imgUrl: require("@/assets/home/rcpc.png"),
type: 'rcpc',
path: '/yyzx/xfbb/addXfbb'
},
{
text: '巡逻打卡',
imgUrl: require("@/assets/home/xldk.png"),
type: 'xldk',
path: '/clock'
},
{
text: '信息交互',
imgUrl: require("@/assets/home/zllz.png"),
type: 'zllz',
path: '/yyzx/zlzx/zlzxIndex'
},
{
text: '处警报送',
imgUrl: require("@/assets/home/dqwz.png"),
type: 'cjbs',
path: '/cjbsPage'
},
{
text: '个人信息',
imgUrl: require("@/assets/home/grxx.png"),
type: 'grxx',
path: '/my'
}
])
const changeOpen = (val) => {
switch (val.type) {
case 'qwbb':
case 'xldk':
case 'zllz':
case 'grxx':
case 'cjbs':
router.push(val.path)
break
case 'rcpc':
pcKey.value++;
nextTick(() => {
prpc.value.handleOpen();
});
break;
}
}
</script>
<style lang="scss" scoped>
ul {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 10px;
box-sizing: border-box;
overflow: hidden;
height: 100vh;
li {
width: 48%;
height: 31.5vh;
text-align: center;
padding-top: 80px;
box-sizing: border-box;
border: 1px solid #E5E5E5;
border-radius: 10px;
margin-bottom: 10px;
}
}
</style>

View File

@ -0,0 +1,274 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav :navTitle="'下发指令'" />
<van-form @submit="onSubmit">
<van-field v-model="normalForm.zlbt" label="指令标题" placeholder="请输入指令标题" input-align="right" required
:rules="[{ required: true, message: '请输入指令标题' }]" />
<van-cell-group>
<van-cell clickable title="等级" :border="false">
<template #right-icon>
<van-radio-group v-model="zldj" direction="horizontal">
<van-radio :name="item.dm" v-for="item in D_BZ_TYJB" :key="item">{{ item.zdmc }}</van-radio>
</van-radio-group>
</template>
</van-cell>
<van-cell clickable title="接收对象" :border="false">
<template #right-icon>
<van-radio-group v-model="jsdx" direction="horizontal">
<van-radio :name="item.dm" v-for="item in D_BZ_ZLJSDX" :key="item">{{ item.zdmc }}</van-radio>
</van-radio-group>
</template>
</van-cell>
</van-cell-group>
<van-cell class="mulSelect" title="人员" color="#1989fa" v-if="jsdx == '01'">
<template #right-icon>
<van-icon @click.stop="onSelectData('mj')" name="add-o" color="#1989fa" size="22" />
</template>
<template #default>
<div class="selected-box">
<div class="check-item-tag" v-for="(item, index) in list.mj" :key="index">
<van-tag color="#7232dd" closeable @close="deleteCheckTag(item, index, 'mj')" plain>{{ item.zxrXm
}}</van-tag>
</div>
</div>
</template>
</van-cell>
<van-field v-model="normalForm.bmName" label="部门" placeholder="请选择部门" input-align="right" readonly is-link
required :rules="[{ required: true, message: '请选择部门' }]"
@click="(bmShow = true), (selectType = 'bm'), (showSelect = false)" v-if="jsdx == '02'" />
<van-cell class="mulSelect" title="巡组" color="#1989fa" v-if="jsdx == '03'">
<template #right-icon>
<van-icon @click.stop="onSelectData('xz')" name="add-o" color="#1989fa" size="22" />
</template>
<template #default>
<div class="selected-box">
<div class="check-item-tag" v-for="(item, index) in list.xz" :key="index">
<van-tag color="#7232dd" closeable @close="deleteCheckTag(item, index, 'xz')" plain>{{ item.zxrXzmc
}}</van-tag>
</div>
</div>
</template>
</van-cell>
<van-field rows="3" label="内容" type="textarea" label-width="35px" v-model="normalForm.zlnr"
placeholder="请输入指令内容" />
<div style="margin: 20vw 0; padding: 0 5vw">
<van-button :loading="loading" round native-type="submit" block type="primary">
提交
</van-button>
</div>
</van-form>
<Select bclx="02" :dwlx="dwlx" :checked="r_checked" :selectType="selectType" :show="showSelect"
:checkedList="list.checkedList" @update:cancel="showSelect = false" @update:confirm="onComfirm"
:key="selectIndex" />
<van-dialog :show="bmShow" title="选择部门" show-cancel-button @confirm="bmShow = false" @cancel="bmShow = false"
confirmButtonColor="#3e6ee8">
<van-cascader v-model="normalForm.deptName" :closeable="false" @change="onChangeBm" :show-header="false"
active-color="#3e6ee8" title="请选择部门" :options="list.options" :field-names="customFieldName"
@click-tab="onClickTabCascader">
</van-cascader>
</van-dialog>
</div>
</template>
<script setup>
import { selectNextPage } from "../../api/yjxx.js";
import TopNav from "../../components/topNav.vue";
import { getDictList, setDict } from "../../utils/dict";
import { onMounted, ref, reactive } from "vue";
import { addZlData } from "../../api/zlzx.js";
import Select from "../../components/Select.vue";
import { hintToast } from "../../utils/tools.js";
import router from "@/router/index.js";
const { D_BZ_TYJB, D_BZ_ZLJSDX } = getDictList("D_BZ_TYJB", "D_BZ_ZLJSDX"); //字典信息
const zldj = ref("40"); //指令等级 默认蓝色
const jsdx = ref("01"); //接收对象 默认人员
const dwlx = ref("01");
const r_checked = ref(""); //单选框默认选中
const kwd = ref(""); //选择器关键字
const selectIndex = ref(1); //选择器组件KEY
const selectType = ref(""); //选择的类型
const showSelect = ref(false);
const bmShow = ref(false); //部门选择器
const list = reactive({
checkedList: [],
mj: [],
xz: [],
bm: [],
options: [],
tabCascader: [], //选中部门的临时数据
});
//选择器字段
const customFieldName = {
text: "orgName",
value: "id",
children: "childDeptList",
};
//表单数据
const normalForm = ref({
zlbt: "",
zlnr: "",
deptName: "",
bmName: "",
});
const zxrDtoList = ref([]);
onMounted(() => {
_selectNextPage();
});
//选中的部门数据
function onChangeBm(val) {
list.tabCascader = val.selectedOptions;
let info = val.selectedOptions.find((item) => {
return item.id == val.value;
});
if (info) {
let { orgName, id } = info;
normalForm.value.bmName = orgName;
list.bm = [{ ssbmid: id, ssbmmc: orgName }];
}
}
//部门选择tabs
function onClickTabCascader(val) {
let info = list.tabCascader[val];
if (info) {
let { orgName, id } = info;
normalForm.value.bmName = orgName;
list.bm = [{ ssbmid: id, ssbmmc: orgName }];
}
}
//查询部门数据
function _selectNextPage() {
selectNextPage({
size: 100,
current: 1,
}).then((res) => {
list.options = [res.records[0]];
});
}
//提交指令
function onSubmit() {
switch (selectType.value) {
case "mj":
zxrDtoList.value = list.mj;
break;
case "bm":
zxrDtoList.value = list.bm;
break;
case "xz":
zxrDtoList.value = list.xz;
break;
}
let data = {
zlbt: normalForm.value.zlbt,
zldj: zldj.value,
zljsdx: jsdx.value,
zllx: "08",
zlnr: normalForm.value.zlnr,
zxrDtoList: zxrDtoList.value,
};
addZlData(data).then((res) => {
hintToast("下发成功!");
router.replace("/newTwoHome/myZl");
});
}
//打开弹窗
function onSelectData(val) {
selectType.value = val;
showSelect.value = true;
list.bm = [];
list.mj = [];
list.xz = [];
selectIndex.value++;
}
//确认选择
function onComfirm(val) {
if (val.length <= 0) return;
switch (selectType.value) {
case "mj":
list.checkedList = [];
val.forEach((item) => {
list.checkedList.push(item.key);
toggle(item);
});
break;
case "xz":
list.checkedList = [];
val.forEach((item) => {
list.checkedList.push(item.key);
toggle(item);
});
break;
}
}
//设置选中值
const toggle = (item) => {
switch (selectType.value) {
case "mj":
list.mj.push({
zxrJllx: item.fl,
zxrLx: "01",
zxrSfz: item.sfzh,
jlxm: item.xm,
sfzh: item.sfzh,
zxrXm: item.xm,
zxrId: item.ryid,
});
break;
case "xz":
list.xz.push({
zxrXzmc: item.jzMc || item.fzrXm + "组",
zxrXzid: item.id,
});
break;
}
};
//删除选中数据
function deleteCheckTag(item, index, val) {
switch (val) {
case "mj":
list.mj.splice(index, 1);
break;
case "xz":
list.xz.splice(index, 1);
break;
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.container {
margin-top: 2vw;
}
::v-deep .mulSelect .van-cell__title,
.van-cell__value {
flex: unset;
}
::v-deep .mulSelect .van-cell__value {
flex: 1;
}
.van-cell:after {
display: none;
}
.van-cell {
@include table_item_color($table-item-theme);
box-sizing: border-box;
border-radius: 4px;
padding: 6px;
margin: 8px 4%;
width: 92%;
overflow: hidden;
color: var(--van-cell-text-color);
font-size: var(--van-cell-font-size);
line-height: var(--van-cell-line-height);
}
.check-item-tag {
display: inline-block;
margin: 0 6px;
}
</style>

View File

@ -0,0 +1,490 @@
<template>
<div class="" @click="showThemeSetting = false">
<div class="new_leaderTop">
<div class="new_welcome">
<div class="userName_box">
<div class="wd">
{{ weatherInfo.typeName }} {{ weatherInfo.minTemp }}-{{
weatherInfo.maxTemp
}} {{ weatherInfo.wind }} {{ weatherInfo.power }}
</div>
<img class="face" src="../../assets/images/leader/face@2x.png" />
<span class="tq_box">欢迎您&ensp;{{ userInfo.userName }}</span>
</div>
<van-popover v-model:show="showThemeSetting" :actions="actions" :theme="defaultThemeQp" :offset="[16, -25]"
placement="bottom-end" @select="onSelectSeting" :teleport="isbody">
<template #reference>
<van-icon name="weapp-nav" color="#fff" size="22px" @click.stop="showThemeSetting = true" />
</template>
</van-popover>
</div>
</div>
<div class="center_function_box">
<div class="f_item" v-for="item in home.functionList" :key="item" @click="onRouter(item.path)">
<img :src="item.imgUrl" alt="" />
<div>{{ item.name }}</div>
</div>
</div>
<div style="height: 3vw; background: #eff0f5"></div>
<div style="padding: 3vw" @click="onClickLdjsc">
<div class="ldjsc_box">
<div class="ldjsc_detail">
<span class="ldjsc_title">领导驾驶舱</span>
<span class="ldjsc_hint">点击进入领导驾驶舱看板</span>
</div>
<div class="ckgd">查看更多</div>
</div>
</div>
<div style="height: 3vw; background: #eff0f5"></div>
<div class="zszh_box_box">
<div class="zszh">掌上指挥</div>
<!-- <div class="zszh_box">
<div
class="zszh_box_item"
style="
background: linear-gradient(90deg, #fff9f1 0%, #f9f1e4 100%);
color: #783000;
"
@click="onCLickFqzl"
>
<van-icon
:name="require('../../assets/images/new/cswdzl.png')"
size="11vw"
badge="+"
></van-icon>
<div class="zszh_title">新增指令</div>
</div>
<div
class="zszh_box_item"
style="
background: linear-gradient(90deg, #fff9f1 0%, #f9f1e4 100%);
color: #783000;
"
@click="onCLickZlLb"
>
<van-icon
:name="require('../../assets/images/new/cswdzl.png')"
size="11vw"
:badge="myzlCount"
></van-icon>
<div class="zszh_title">我发起的指令</div>
</div>
<div
class="zszh_box_item"
style="
background: linear-gradient(90deg, #f6fafd 0%, #e8f0fc 100%);
color: #163678;
"
@click="onCLickYwcldzl"
>
<van-icon
:name="require('../../assets/images/new/wcldzl.png')"
size="11vw"
:badge="ywclzlCount"
></van-icon>
<div class="zszh_title">由我处理指令</div>
</div>
<div
class="zszh_box_item"
style="
background: linear-gradient(90deg, #f6fafd 0%, #e8fcfa 100%);
color: #397361;
"
>
<van-icon
:name="require('../../assets/images/new/wfsdzl.png')"
size="11vw"
:badge="cswdzlCount"
></van-icon>
<div class="zszh_title">抄送我的指令</div>
</div>
</div> -->
<div class="zszh_box">
<div class="zszh_box_item" v-for="item in home.totalLit" :key="item"
:style="{ background: item.bg, color: item.colors }" @click="onCLickSelect(item.url)">
<van-icon :name="item.icons" size="11vw" :badge="item.badges"></van-icon>
<div class="zszh_title">{{ item.text }}</div>
</div>
</div>
</div>
<van-dialog :show="showUserChangePicker" title="选择角色" show-cancel-button @confirm="onConfirm"
@cancel="showUserChangePicker = false" confirmButtonColor="#3e6ee8">
<van-radio-group v-model="isActive">
<van-radio v-for="item in radioList" :key="item.id" :name="item.id">{{
item.homename
}}</van-radio>
</van-radio-group>
</van-dialog>
<!-- 盘人 -->
<checkedPeople ref="peo" :key="zdgzKey + 'pr'" />
<!-- 盘车 -->
<checkedCar ref="car" :key="zdgzKey + 'pc'" />
<PcModel ref="dhcr" :key="zdgzKey + 'dhcr'"></PcModel>
<!-- 底部tas -->
<div style="height: 11.8666vw"></div>
<BottomTabs type="sy" />
</div>
</template>
<script setup>
import BottomTabs from "../../components/bottomTabs.vue";
import { getUserSelectPage } from "../../api/gxHomeApi.js";
import { dateFormat, setUserHome, getWeatherData } from "../../utils/tools.js";
import checkedCar from "../../pages/spsHome/components/checkCar.vue";
import checkedPeople from "../../pages/spsHome/components/checkPeople.vue";
import PcModel from "../../components/pcModel.vue";
import { getHomejqtj } from "../../api/jqxx.js";
import { getZdRyCount } from "../../api/zdry.js";
import { ref, onMounted, onUnmounted, onActivated, reactive } from "vue";
import { getMyTaskList, getMyTaskTotal, upGrzt } from "../../api/rwzx.js";
import { getMyZlList } from "../../api/zlzx.js";
import router from "../../router";
import { onBeforeRouteLeave } from "vue-router";
const isActive = ref(6); //用户选中的身份
const radioList = ref([]); //用户身份数据
const showUserChangePicker = ref(false); //用户换身份弹窗
const showThemeSetting = ref(false); //是否显示设置主题模板
const defaultThemeQp = ref("light"); //默认的右侧气泡框主题
const isbody = ref("body");
const weatherInfo = ref({
maxTemperature: 24,
minTemperature: 14,
type: "多云",
}); //天气数据
const actions = [
{
text: "切换身份",
icon: "exchange",
},
];
const dhcr = ref(); //电话查人组件对象
const peo = ref(); //盘查人员组件对象
const car = ref(); //盘查车辆组件对象
const ywclzlCount = ref(0); //由我处理的指令统计
const myzlCount = ref(0);
const cswdzlCount = ref(0); //抄送我的指令统计
const zdgzKey = ref(1);
const userInfo = JSON.parse(window.localStorage.getItem("userInfo")); //用户信息
const home = reactive({
functionList: [
{
name: "人员盘查",
imgUrl: require("../../assets/images/menu-yyhc.png"),
path: "pr",
},
{
name: "勤务统计",
imgUrl: require("../../assets/images/qwtj.png"),
path: "/hisQwCenter",
},
{
name: "车辆盘查",
imgUrl: require("../../assets/images/menu-clhc.png"),
path: "pc",
},
{
name: "巡防报备",
imgUrl: require("../../assets/images/menu-rwzx.png"),
path: "/yyzx/xfbb/addXfbb",
},
{
name: "预警统计",
imgUrl: require("../../assets/images/jq_home.png"),
path: "/yyzx/yjxx/yjTotal",
},
{
name: "值班报备",
imgUrl: require("../../assets/images/menu-qwzx.png"),
path: "/yyzx/views/addZbbb",
},
{
name: "查看更多",
imgUrl: require("../../assets/images/new_gd.png"),
path: "/yyzx",
},
], //中间功能区
rwList: [],
totalLit: [
{
url: "/newTwoHome/addZl",
icons: require("../../assets/images/new/cswdzl.png"),
text: "新增指令",
bg: "linear-gradient(90deg, #fff9f1 0%, #f9f1e4 100%)",
colors: "#783000",
badges: "+",
},
{
url: "/newTwoHome/myZl",
icons: require("../../assets/images/new/cswdzl.png"),
text: "我发起的指令",
bg: "linear-gradient(90deg, #fff9f1 0%, #f9f1e4 100%)",
colors: "#783000",
badges: 0,
},
{
url: "/yyzx/zlzx/zlzxIndex",
icons: require("../../assets/images/new/wcldzl.png"),
text: "由我处理的指令",
bg: "linear-gradient(90deg, #f6fafd 0%, #e8f0fc 100%)",
colors: "#163678",
badges: 0,
},
{
url: "/newTwoHome/myZl?type=cs",
icons: require("../../assets/images/new/wfsdzl.png"),
text: "抄送我的指令",
bg: "linear-gradient(90deg, #f6fafd 0%, #e8fcfa 100%)",
colors: "#397361",
badges: 0,
},
],
});
const timeObj = reactive({
kssj: "",
jssj: "",
});
onMounted(() => {
zdgzKey.value++;
_getUserSelectPage();
_getMyTaskTotal();
});
//跳转
function onCLickSelect(url) {
router.push(url);
}
//发起指令
function onCLickFqzl() {
router.push("/newTwoHome/addZl");
}
// 我发起的指令列表
function onCLickZlLb() {
router.push("/newTwoHome/myZl");
}
//点击由我处理的指令
function onCLickYwcldzl() {
router.push("/yyzx/zlzx/zlzxIndex");
}
//跳转领导驾驶舱
function onClickLdjsc() {
router.push("/newTwoHome/ldjsc");
}
//获取任务统计
function _getMyTaskTotal() {
getMyTaskTotal({ sfzh: userInfo.idEntityCard }).then((res) => {
if (res) {
res.forEach((item) => {
if (item.rwxl == "05") {
ywclzlCount.value = item.count;
}
if (item.rwxl == "06") {
}
});
}
});
getMyZlList({
pageSize: 10,
pageCurrent: 1,
}).then((res) => {
myzlCount.value = res.total;
});
}
//获取用户首页模板
function _getUserSelectPage() {
getUserSelectPage({
size: 20,
current: 1,
}).then((res) => {
res.records.forEach((item) => {
radioList.value.push(item);
});
});
}
//选中的设置信息
function onSelectSeting(e) {
switch (e.text) {
case "切换身份":
showUserChangePicker.value = true;
break;
}
}
//用户选中身份
function onConfirm() {
showUserChangePicker.value = false;
setUserHome(isActive.value);
}
//跳转页面
function onRouter(path) {
switch (path) {
case "/rw":
case "/yyzx":
router.replace(path);
break;
case "pr":
checkPeople();
break;
case "pc":
checkCar();
break;
case "/dhcr":
checkDhcr();
break;
case "rhjs":
try {
bridge.toFusionComputing();
} catch (error) { }
break;
default:
router.push(path);
}
}
//点击盘人
function checkPeople() {
peo.value.handleOpen();
}
//点击盘车
function checkCar() {
car.value.handleOpen();
}
// 点击电弧查人
function checkDhcr() {
dhcr.value.peoplePopupShow = true;
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.zszh_box_box {
padding: 3vw;
.zszh {
@include font_size($font_medium);
font-weight: 700;
}
}
.zszh_box {
@include font_size($font_medium_s);
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 4vw;
.zszh_box_item {
text-align: center;
width: 30%;
padding: 4vw 0;
border-radius: 3vw;
margin-bottom: 5vw;
.zszh_title {
margin-top: 2vw;
}
}
}
.new_leaderTop {
height: 26.33334vw;
background: url("../../assets/images/new/banner.png") no-repeat;
background-size: 100%;
top: 0;
@include font_size($font_medium_s);
}
.new_welcome {
padding: 5.5vw 5vw 3vw 5vw;
display: flex;
justify-content: space-between;
font-size: 13px;
@include font_size($font_medium_s);
.userName_box {
color: #fff;
.wd {
margin-bottom: 3vw;
}
.tq_box {
@include font_size($font_medium);
position: relative;
top: -0.5vw;
}
.face {
width: 5vw;
height: 4vw;
margin-right: 2.5vw;
}
}
}
.center_function_box {
display: flex;
align-items: center;
flex-wrap: wrap;
background: #fff;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
padding: 4vw 1vw 0 1vw;
.f_item {
text-align: center;
width: 20%;
margin: 0 0 4.5vw 0;
&>img {
width: 13vw;
height: 13vw;
margin-bottom: 2vw;
}
}
}
::v-deep .van-radio-group {
padding: 5vw;
}
::v-deep .van-radio {
padding: 2vw 0;
}
.ldkb_img {
width: 100%;
}
.ldjsc_box {
background: url("../../assets/images/new/ldjsc_url.png");
background-size: 100% 100%;
height: 26vw;
@include font_size($font_medium_s);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 6vw;
}
.ldjsc_detail {
display: flex;
flex-direction: column;
.ldjsc_title {
font-size: 5vw;
font-weight: 700;
color: #104ca5;
}
.ldjsc_hint {
margin-top: 3vw;
}
}
.ckgd {
height: 7vw;
line-height: 7vw;
width: 20vw;
text-align: center;
color: #fff;
border-radius: 4vw;
background: linear-gradient(90deg, #2972fa 0%, #0aa7f8 100%);
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<div style="padding-top: 14vw">
<TopNav navTitle="警情详情" :showRight="false" :showLeft="true" />
<div class="ry_info">
<List :item="jqDetail" v-if="jqDetail" />
</div>
<Steps :data="stepsData">
<template v-slot:default="{ scope }">
<div class="content">
<div class="cont_l">
<div class="text title">{{ scope.content }}</div>
<div class="text">执行人:{{ scope.cjPoliceName }}</div>
<div class="text">执行部门:{{ scope.cjOrgName }}</div>
<div class="text">状态:{{ scope.statusName }}</div>
</div>
</div>
</template>
</Steps>
<van-empty
description="没有警情信息"
image="default"
v-if="stepsData.length <= 0 && showEmpty"
/>
</div>
</template>
<script setup>
import axios from "axios";
import List from "../../../components/xzjqList.vue";
import TopNav from "../../../components/topNav.vue";
import Steps from "../../../components/Steps.vue";
import { getJqInfo } from "../../../api/jqxx";
import { onMounted, ref } from "vue";
import { baseUrl2 } from "../../../utils/request";
const route = useRoute();
const jqDetail = ref();
const stepsData = ref([]);
const showEmpty = ref(false);
onMounted(() => {
jqDetail.value = JSON.parse(route.query.item);
_getCjList(jqDetail.value.incidentCode);
});
//获取处警记录
function _getCjList(incidentCode) {
axios
.get(`${baseUrl2}/xz1Api/api/alarm/cj/${incidentCode}`, {})
.then((res) => {
if (res.data && res.data.data.length > 0) {
for (let i = 0; i < res.data.data.length; i++) {
let item = res.data.data[i];
item.time = item.cjTime.substring(0, item.cjTime.length - 3);
}
res.data.data.sort(
(a, b) => new Date(b.time).getTime() - new Date(a.time).getTime()
);
stepsData.value = res.data.data;
} else {
showEmpty.value = true;
}
})
.catch((err) => {
showEmpty.value = true;
});
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.ry_info {
margin: 2vw 3vw;
border-radius: 2vw;
@include jrtz_fill_color($jrtz-fill-color-theme);
}
.content {
display: flex;
padding-bottom: 20px;
.cont_l {
margin-right: 16px;
.text {
line-height: 5.5vw;
}
.title {
@include font_size($font_medium);
font-weight: 550;
}
}
}
</style>

View File

@ -0,0 +1,178 @@
<template>
<div>
<TopNav navTitle="警情列表" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="sticky_box">
<Tabs :status="status" @TabsItem="onSelect" :key="tabsIndex"></Tabs>
<Search
placeholder="请输入关键字"
v-model="kwd"
:isSx="true"
@update:sx="showPopup = !showPopup"
@update:modelValue="onSearch"
></Search>
</div>
</van-sticky>
<SxPopup
:showPopup="showPopup"
:list="yjxx.sxList"
:p_top="145"
@update:close="showPopup = false"
@update:onConfirm="onConfirm"
/>
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list
v-model:loading="loading"
:finished="finished"
finished-text=" "
@load="onLoad"
offset="3"
:immediate-check="false"
>
<List
v-for="(item, index) in yjxx.list"
:key="index"
:item="item"
path="/newTwoHome/jq/xzjqDetail"
/>
<van-empty
description="没有警情信息"
image="default"
v-if="yjxx.list.length <= 0 && showEmpty"
/>
</van-list>
</van-pull-refresh>
</div>
</template>
<script>
export default {
name: "newTwoHome/jq/xzjqlist",
};
</script>
<script setup>
import axios from "axios";
import { baseUrl2 } from "../../../utils/request";
import TopNav from "../../../components/topNav.vue";
import Search from "../../../components/search.vue";
import Tabs from "../../../components/tabs/tabs.vue";
import SxPopup from "../../../components/SxPopup.vue";
import List from "../../../components/xzjqList.vue";
import { setTimeQuantum, dateFormat } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, reactive, onMounted, watch, onActivated } from "vue";
import { getJqList, getStatistics } from "../../../api/jqxx";
import { useRoute, onBeforeRouteLeave } from "vue-router";
import router from "../../../router";
const status = ref(1);
const showEmpty = ref(false);
const loading = ref(false);
const total = ref(0);
const tabsIndex = ref(1);
const params = ref({
pageNum: 1,
pageSize: 20,
bjnr: "",
endTime: dateFormat(),
startTime: dateFormat("z"),
});
const yjxx = reactive({
sxList: [setTimeQuantum()], //筛选条件数据
list: [], //预警列表数据,
});
const kwd = ref("");
const finished = ref(false);
const loadingPull = ref(false);
const showPopup = ref(false); //筛选弹窗
onMounted(() => {
if (useRoute().query.status) {
status.value = useRoute().query.status;
onSelect();
}
});
//下拉刷新
function onRefresh() {
yjxx.list = [];
tabsIndex.value++;
params.value.pageNum = 1;
params.value.bjnr = "";
params.value.endTime = dateFormat();
params.value.startTime = dateFormat("z");
onSelect();
}
//触底加载
function onLoad() {
if (params.value.pageNum >= total.value) {
finished.value = true;
} else {
params.value.pageNum++;
onSelect();
}
}
/**
* tab选择
* @param {Object} val
*/
function onSelect(val) {
if (val || val == 0) {
status.value = val + 1;
yjxx.list = [];
params.value.pageNum = 1;
params.value.bjnr = "";
finished.value = false;
}
loading.value = true;
let data = {
orgId: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0]
.deptCode,
startTime: `${params.value.startTime} 16:00:00`,
endTime: `${params.value.endTime} 16:00:00`,
type: status.value,
keyword: params.value.bjnr,
currPage: params.value.pageNum,
pageSize: params.value.pageSize,
};
axios
.post(`${baseUrl2}/xz1Api/api/alarm/list `, data)
.then((res) => {
loading.value = false;
loadingPull.value = false;
if (res.data && res.data.data.list.length > 0) {
yjxx.list = [...res.data.data.list, ...yjxx.list];
total.value = res.data.data.totalPage;
} else {
showEmpty.value = true;
}
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
/**
* 关键字搜索
* @param {Object} val
*/
function onSearch(val) {
yjxx.list = [];
params.value.endTime = dateFormat();
params.value.startTime = dateFormat("z");
params.value.pageNum = 1;
params.value.bjnr = val;
finished.value = false;
onSelect();
}
function onConfirm(val) {
yjxx.list = [];
params.value.startTime = `${val.startTime}`;
params.value.endTime = `${val.endTime}`;
showPopup.value = false;
params.value.pageNum = 1;
params.value.bjnr = "";
finished.value = false;
onSelect();
}
</script>
<style>
</style>

View File

@ -0,0 +1,222 @@
<template>
<div>
<TopNav navTitle="警情列表" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="sticky_box">
<Tabs
:list="tabs"
@onYjjb="onSelect"
:type="'car'"
:key="tabsIndex"
></Tabs>
<Search
placeholder="请输入关键字"
v-model="kwd"
:isSx="true"
@update:sx="showPopup = !showPopup"
@update:modelValue="onSearch"
></Search>
</div>
</van-sticky>
<SxPopup
:showPopup="showPopup"
:list="yjxx.sxList"
:p_top="145"
@update:close="showPopup = false"
@update:onConfirm="onConfirm"
/>
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list
v-model:loading="loading"
:finished="finished"
finished-text=" "
@load="onLoad"
offset="3"
:immediate-check="false"
>
<List
v-for="(item, index) in yjxx.list"
:key="index"
:item="item"
path="/yyzx/jqxx/jqDetail"
/>
<van-empty
description="没有警情信息"
image="default"
v-if="yjxx.list.length <= 0 && showEmpty"
/>
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import Search from "../../../components/search.vue";
import Tabs from "../../../components/tabs.vue";
import SxPopup from "../../../components/SxPopup.vue";
import List from "../../../components/JqList.vue";
import { setTimeQuantum, dateFormat } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, reactive, onMounted, watch } from "vue";
import { getJqList, getStatistics } from "../../../api/jqxx";
const tabs = ref([
{
name: "全部警情",
value: null,
count: 0,
},
{
name: "刑事警情",
value: 1,
count: 0,
},
{
name: "行政警情",
value: 2,
count: 0,
},
{
name: "交通警情",
value: 3,
count: 0,
},
{
name: "其他",
value: 4,
count: 0,
},
]);
const yjxx = reactive({
sxList: [setTimeQuantum()], //筛选条件数据
list: [], //预警列表数据,
total: 0,
});
const params = ref({
pageNum: 1,
pageSize: 20,
bjnr: "",
bjlb: "",
endTime: dateFormat(),
startTime: dateFormat(),
});
const tabsIndex = ref(1);
const kwd = ref("");
const finished = ref(false);
const loading = ref(false);
const loadingPull = ref(false);
const showEmpty = ref(false);
const showPopup = ref(false); //筛选弹窗
//下拉刷新
function onRefresh() {
tabsIndex.value++;
yjxx.list = [];
params.value.pageNum = 1;
params.value.bjnr = "";
params.value.bjlb = "";
params.value.endTime = "";
params.value.startTime = "";
getList();
getJqtj();
}
//获取警情列表
function getList() {
loading.value = true;
getJqList(params.value)
.then((res) => {
loading.value = false;
loadingPull.value = false;
if (res.records && res.records.length > 0) {
yjxx.list = res.records;
} else {
showEmpty.value = true;
}
yjxx.total = res.total;
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
function onLoad() {
if (yjxx.list.length >= yjxx.total) {
finished.value = true;
} else {
params.value.pageNum++;
loading.value = true;
getJqList(params.value)
.then((res) => {
loading.value = false;
loadingPull.value = false;
yjxx.list.push(...res.records);
yjxx.total = res.total;
})
.catch((err) => {
loading.value = false;
});
}
}
//获取警情统计数据
function getJqtj() {
const data = {
endTime: params.value.endTime,
startTime: params.value.startTime,
bjnr: params.value.bjnr,
};
getStatistics(data).then((res) => {
tabs.value[0].count = res.jtCount + res.qtCount + res.xsCount + res.xzCount;
tabs.value[1].count = res.xsCount;
tabs.value[2].count = res.xzCount;
tabs.value[3].count = res.jtCount;
tabs.value[4].count = res.qtCount;
});
}
onMounted(() => {
getList();
getJqtj();
});
/**
* tab选择
* @param {Object} val
*/
function onSelect(val) {
yjxx.list = [];
params.value.bjnr = "";
params.value = {
pageNum: 1,
pageSize: 20,
endTime: params.value.endTime,
startTime: params.value.startTime,
bjlb: !val ? null : val,
};
getList();
}
/**
* 关键字搜索
* @param {Object} val
*/
function onSearch(val) {
yjxx.list = [];
params.value.bjnr = val;
params.value = {
pageNum: 1,
pageSize: 20,
endTime: "",
startTime: "",
bjlb: !val ? null : val,
};
getList();
getJqtj();
}
function onConfirm(val) {
yjxx.list = [];
params.value.startTime = val.startTime;
params.value.endTime = val.endTime;
getList();
getJqtj();
showPopup.value = false;
}
</script>
<style>
</style>

View File

@ -0,0 +1,987 @@
<template>
<div class="" style="padding-top: 13vw">
<TopNav navTitle="领导驾驶舱" :showRight="false" :showLeft="true" />
<div class="wddb_box">
<div class="wdrw_title">我的待办任务</div>
<div class="dbrw_total">
<div @click="routerPush('/rw')" class="wddb_item">
<span class="num">{{ myDb.dcl }}</span><br />
待处理任务
</div>
<div @click="routerPush('/newTwoHome/yclList')" class="wddb_item">
<span class="num">{{ myDb.ycl }}</span><br />
已处理任务
</div>
</div>
</div>
<div style="height: 3vw; background: #eff0f5"></div>
<div class="jq_box topM">
<span class="jmsfjq_total_title">警情态势</span>
</div>
<div class="jq_box">
<div class="jq_item left_item" style="padding: 0">
<div class="jrjqzs_total jq_total_item" @click="onClickJqTotal(1)">
<span class="jmsfjq_total_title">今日总警情</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ jqTotal.total }} </span>
<span style="display: inline-block; margin-left: 6vw">环比<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.totalHb > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.totalHb > 0 ? 'red' : 'green'">
{{ jqTotal.totalHb }}%</span>
</span>
</span>
</div>
</div>
<div class="zdjqzs_total jq_total_item" @click="onClickJqTotal(2)">
<span class="jmsfjq_total_title">今日重大警情</span>
<div style="margin: 1vw 0 0 0">
<span class="red jq_num">{{ jqTotal.zdCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
占比<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.zdHb > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.zdHb > 0 ? 'red' : 'green'">
{{ jqTotal.zdHb }}%</span></span>
</span>
</div>
</div>
<div class="wffzzs_total jq_total_item" @click="onClickJqTotal(3)">
<span class="jmsfjq_total_title">今日违法犯罪警情</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ jqTotal.wffzCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
环比<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.wffzHb > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.wffzHb > 0 ? 'red' : 'green'">
{{ jqTotal.wffzHb }}%</span></span>
</span>
</div>
<div class="xz_xs_total">
<span>刑事 {{ jqTotal.xsCount }} </span>
<span class="sx"></span>
<span>行政 {{ jqTotal.xzCount }}</span>
</div>
</div>
<div class="jq_total_item dxzp_item" @click="onClickJqTotal(12)">
<span class="jmsfjq_total_title">今日一般警情</span>
<div style="margin: 1vw 0 0 0">
<span class="jq_num">{{ jqTotal.dzCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
占比<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.dzHb > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.dzHb > 0 ? 'red' : 'green'">
{{ jqTotal.dzHb }}%</span></span>
</span>
</div>
</div>
</div>
<div class="jq_item jmsfjq_box">
<div class="jmsfjq_total_title">街面实发警情</div>
<div style="margin-top: 2vw">
<span style="font-size: 6vw; font-weight: 700">{{
jqTotal.jmsfTotal
}}</span>
<span>&ensp;&ensp;</span>
<span>较昨日 &ensp;<span :class="zrjqTotal > 0 ? 'red' : 'green'">{{
zrjqTotal > 0 ? "+" + zrjqTotal : zrjqTotal
}}</span></span>
</div>
<div class="mk_jq_total_box" @click="onClickJqTotal(9)">
<div class="jq_total">
<div>
<span class="red"># </span>
<span>两抢</span>
</div>
<div>
<span style="font-size: 4.5vw">{{ jqTotal.lqCount }}</span>
<span class="jq_total_unit">&ensp;</span>
</div>
</div>
<span class="jqhb">&emsp;较昨日&ensp;<span :class="jqTotal.lqCount > 0 ? 'red' : 'green'">{{ jqTotal.lqUp > 0 ?
"+" + jqTotal.lqUp : jqTotal.lqUp }}</span></span>
</div>
<div class="mk_jq_total_box" @click="onClickJqTotal(10)">
<div class="jq_total">
<div>
<span class="red"># </span>
<span>盗窃汽车</span>
</div>
<div>
<span style="font-size: 4.5vw">
{{ jqTotal.qcCount }}
</span>
<span class="jq_total_unit"> </span>
</div>
</div>
<span class="jqhb">&emsp;较昨日&ensp;<span :class="jqTotal.qcUp > 0 ? 'red' : 'green'">{{ jqTotal.qcUp > 0 ? "+"
+ jqTotal.qcUp : jqTotal.qcUp }}</span></span>
</div>
<div class="mk_jq_total_box" @click="onClickJqTotal(8)">
<div class="jq_total">
<div>
<span class="red"># </span>
<span>盗窃车内财物</span>
</div>
<div>
<span style="font-size: 4.5vw">{{ jqTotal.ccCount }}</span>
<span class="jq_total_unit"> </span>
</div>
</div>
<span class="jqhb">&emsp;较昨日&ensp;<span :class="jqTotal.ccUp > 0 ? 'red' : 'green'">{{ jqTotal.ccUp > 0 ? "+"
+ jqTotal.ccUp : jqTotal.ccUp }}</span></span>
</div>
<div class="mk_jq_total_box" @click="onClickJqTotal(7)">
<div class="jq_total">
<div>
<span class="red"># </span>
<span>扒窃</span>
</div>
<div>
<span style="font-size: 4.5vw">{{ jqTotal.pqCount }}</span>
<span class="jq_total_unit"> </span>
</div>
</div>
<span class="jqhb">&emsp;较昨日&ensp;<span :class="jqTotal.pqUp > 0 ? 'red' : 'green'">{{ jqTotal.pqUp > 0 ? "+"
+ jqTotal.pqUp : jqTotal.pqUp }}</span></span>
</div>
<div class="mk_jq_total_box" @click="onClickJqTotal(6)">
<div class="jq_total">
<div>
<span class="red"># </span>
<span>盗窃三车</span>
</div>
<div>
<span style="font-size: 4.5vw">{{ jqTotal.dqscCount }}</span>
<span class="jq_total_unit"> </span>
</div>
</div>
<span class="jqhb">&emsp;较昨日&ensp;<span :class="jqTotal.dqscUp > 0 ? 'red' : 'green'">{{
jqTotal.dqscUp > 0 ? "+" + jqTotal.dqscUp : jqTotal.dqscUp
}}</span></span>
</div>
<!-- <div class="mk_jq_total_box">
<div class="jq_total">
<div>
<span class="red"># </span>
<span>入室盗窃</span>
</div>
<div>
<span style="font-size: 4.5vw">{{ jqTotal.rdCount }}</span>
<span class="jq_total_unit"> </span>
</div>
</div>
<span class="jqhb"
>&emsp;较昨日&ensp;<span
:class="jqTotal.rdUp > 0 ? 'red' : 'green'"
>{{ jqTotal.rdUp > 0 ? "+" + jqTotal.rdUp : jqTotal.rdUp }}</span
></span
>
</div> -->
</div>
</div>
<!-- <div style="height: 3vw; background: #eff0f5"></div> -->
<!-- <div class="wqts_box">
<div class="jq_box topM">
<span class="jmsfjq_total_title">稳情态势</span>
</div>
<div class="order_total">
<div class="total_item" style="background: #dd2024">
<span>2</span><br />
<span>失控数量</span>
</div>
<div class="total_item" style="background: #fb8734">
<span>10</span><br />
<span>在控数量</span>
</div>
<div class="total_item" style="background: #ecc617">
<span>10</span><br />
<span>待反馈数</span>
</div>
</div>
</div>
<div class="wk_echart">
<WqtsChart style="flex: 1" />
<div style="flex: 1">
<div class="wk_item" v-for="(item, index) in wkList" :key="index">
<span class="wk_dot" :style="{ background: item.color }"></span
>{{ item.text }}&nbsp; {{ item.hb }}% &nbsp; {{ item.num }}
</div>
</div>
</div> -->
<!-- <div style="height: 3vw; background: #eff0f5"></div> -->
<div style="height: 3vw; background: #eff0f5"></div>
<div class="qwqk_box">
<div class="jmsfjq_total_title title_box" @click="routerPush(`/qwCenter`, { status: '街面警力' })">
<span>勤务情况</span>
<span class="look_more">查看更多 </span>
</div>
<div class="qu_total">
<div class="qu_item_total">
<span>{{ qwData.zbld.zbldxm }}</span><br /><span>值班领导</span>
</div>
<div class="qu_item_total">
<span>{{ qwData.zgjl }}</span><br /><span>在岗警力</span>
</div>
<div class="qu_item_total">
<span>{{ qwData.jmjl }}</span><br /><span>街面警力</span>
</div>
</div>
<div class="zdqw_box" v-if="qwData.xfList.length > 0">
<div class="zdqw_item_box" v-for="item in qwData.xfList" :key="item" @click="onClickXfInfo(item.id)">
<div class="zdqw_title_box">
<span class="zdqw_msg" style="font-size: 15px; font-weight: 700"><span style="
background: #4d1717;
color: #fff;
display: inline-block;
padding: 0 1vw;
margin-right: 1.5vw;
border-radius: 3px;
font-size: 11px;
">类型</span>{{ setDict(item.qwlx, D_BZ_QWLX) }}</span>
<span class="">负责人<span style="
display: inline-block;
background: #fff;
border-radius: 10px;
padding: 0 1.5vw;
">{{ item.fzrXm }}</span></span>
</div>
<div class="zdqw_mj_fj_num">
<span class="van-ellipsis">备注{{ item.bz }}</span>
<div class="" style="font-weight: 700; line-height: 5vw">
<span class="zdqw_msg">民警{{ item.pbmj.length }}</span>
<span class="zdqw_msg" style="padding-left: 5vw; border-left: 1px solid #4d1717">辅警{{ item.pbfj.length
}}</span>
</div>
</div>
</div>
</div>
<div class="wzdqw_box" v-else>无重大勤务</div>
<div class="zbld_box">
<div class="zbld_item_box" v-for="item in qwData.zbList" :key="item" @click="onClickZbInfo(item.id)">
<img src="../../assets/images/new/jc.png" />
<div class="abld_detail">
<span>{{ item.zbldXm }}</span><br />
<span style="display: inline-block; width: 28vw; margin-top: 1vw" class="van-ellipsis">{{ item.ssbm
}}</span>
</div>
</div>
</div>
</div>
<div style="height: 3vw; background: #eff0f5"></div>
<div class="sjkb_box">
<div class="jmsfjq_total_title">数据详览</div>
<div class="sjkb_item_box">
<div @click="routerPush('/yyzx/fmjq/index')" class="sjkb_item">
方面性警情分析
</div>
<div @click="routerPush('/jqfx', { jqlx: 'zjq' })" class="sjkb_item">
总警情分析
</div>
<div @click="routerPush('/jqfx', { jqlx: 'wffzjq' })" class="sjkb_item">
违法犯罪警情分析
</div>
<div @click="routerPush('/jqfx', { jqlx: 'jmjq' })" class="sjkb_item">
街面警情分析
</div>
</div>
</div>
<div style="height: 3vw; background: #eff0f5"></div>
<!-- <div class="jq_box topM">
<span class="jmsfjq_total_title" style="paddingtop: 2vw">部门动态</span>
</div>
<div class="bmdt_box">
<div
v-for="(item, index) in bmList"
:key="index"
style="text-align: center; margin-right: 1.5vw"
@click="bmClick(item)"
>
<img :src="item.img" alt="" class="bmdt_img" />
<div class="bm_item">
{{ item.text }}
<span
v-if="index != 0"
style="font-weight: 100; color: #333; margin-top: 2vw"
>开发中</span
>
</div>
</div>
</div> -->
</div>
</template>
<script setup>
import WqtsChart from "./wqtsChart.vue";
import { getMyTaskTotal } from "../../api/rwzx.js";
import { getZdRyCount } from "../../api/zdry.js";
import {
getYclTask,
getZbld,
getJmjlCount,
getZgjlCount,
getTbQwZbbb,
getTbQwXfbb,
} from "../../api/ldjsc.js";
import { baseUrl2 } from "../../utils/request";
import { getDictList, setDict } from "../../utils/dict";
import TopNav from "../../components/topNav.vue";
import { ref, onMounted, onUnmounted, onActivated, reactive } from "vue";
import router from "../../router";
import axios from "axios";
import { dateFormat } from "../../utils/tools.js";
import { getYqList } from "../../api/common.js";
import store from "../../store";
import { onBeforeRouteLeave } from "vue-router";
const { D_BZ_QWLX } = getDictList("D_BZ_QWLX");
const userInfo = JSON.parse(window.localStorage.getItem("userInfo"));
const myDb = reactive({
dcl: 0,
ycl: 0,
});
const zdgz = reactive({
hszdry: 0,
});
const qwData = reactive({
zgjl: 0, //在岗警力
jmjl: 0, //街面警力
zbld: {}, //值班领导
zbList: [], //勤务值班列表
xfList: [], //巡防列表
});
const wkList = ref([
{
text: "红色预警",
color: "#dd2024",
num: 2,
hb: ((2 / 22) * 100).toFixed(0),
},
{
text: "橙色预警",
color: "#fb8734",
num: 4,
hb: ((4 / 22) * 100).toFixed(0),
},
{
text: "黄色预警",
color: "#ecc617",
num: 6,
hb: ((6 / 22) * 100).toFixed(0),
},
{
text: "蓝色预警",
color: "#4399fc",
num: 10,
hb: ((10 / 22) * 100).toFixed(0),
},
]);
const bmList = ref([
{
text: "巡大",
num: 0,
img: require("../../assets/images/new/xd.png"),
},
{
text: "出入境管理",
num: 0,
img: require("../../assets/images/new/crjgl.png"),
},
{
text: "侦察署",
num: 0,
img: require("../../assets/images/new/zcs.png"),
},
{
text: "办公室",
num: 0,
img: require("../../assets/images/new/bgs.png"),
},
{
text: "指挥室",
num: 0,
img: require("../../assets/images/new/zhs.png"),
},
{
text: "政治处",
num: 0,
img: require("../../assets/images/new/zzc.png"),
},
{
text: "政经文保署",
num: 0,
img: require("../../assets/images/new/zjwbs.png"),
},
{
text: "治安署",
num: 0,
img: require("../../assets/images/new/zas.png"),
},
{
text: "法制大队",
num: 0,
img: require("../../assets/images/new/fzdd.png"),
},
{
text: "纪检组",
num: 0,
img: require("../../assets/images/new/jjz.png"),
},
]);
function bmClick(item) {
switch (item.text) {
case "巡大":
router.push("/newTwoHome/xd");
break;
default:
break;
}
}
const jqTotal = ref({}); //今日警情统计
const zrjqTotal = ref(0); //昨日警情数据
const QWLX = ref([]); //勤务类型
//点击警情统计查看列表
function onClickJqTotal(status) {
if (status === 1) {
router.push(`/newTwoHome/zjq`);
} else {
router.push(`/newTwoHome/jq/xzjqlist?status=${status}`);
}
}
//获取警情统计 type 是否是昨日
function _getJqTotal(type) {
return new Promise((ok) => {
let data = {
orgId: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0]
.deptCode,
startTime: `${dateFormat("z")} 16:00:00`,
endTime: `${dateFormat()} 16:00:00`,
type: 1,
keyword: "",
};
if (type) {
data.startTime = `${dateFormat("z2")} 16:00:00`;
data.endTime = `${dateFormat("z")} 16:00:00`;
}
axios.post(`${baseUrl2}/xz1Api/api/alarm/count`, data).then((res) => {
if (res.data) {
if (type) {
let num =
res.data.data.lqCount +
res.data.data.qcCount +
res.data.data.ccCount +
res.data.data.pqCount +
res.data.data.dqscCount;
zrjqTotal.value = jqTotal.value.jmsfTotal - num;
} else {
jqTotal.value = res.data.data;
jqTotal.value.jmsfTotal =
res.data.data.lqCount +
res.data.data.qcCount +
res.data.data.ccCount +
res.data.data.pqCount +
res.data.data.dqscCount;
}
ok();
}
});
});
}
//查看巡防详情
function onClickXfInfo(id) {
router.push({
path: "/yyzx/xfbb/addtsXfbb",
query: {
bbid: id,
},
});
}
//查看值班详情
function onClickZbInfo(id) {
router.push({
path: "/yyzx/views/addZbbbInfo",
query: {
zt: "",
id: id,
text: "",
color: "",
flag: "",
},
});
}
//获取巡防列表
function _getTbQwXfbb() {
let data = {
pageSize: 1000,
pageCurrent: 1,
qwlxs: "01,02,03,04,05",
ssbmid: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0]
.deptId,
bbzt: 0,
};
getTbQwXfbb(data).then((res) => {
if (res && res.records.length > 0) {
res.records.forEach((item) => {
if (item.pbfj) {
item.pbfj = JSON.parse(item.pbfj);
} else {
item.pbfj = [];
}
if (item.pbmj) {
item.pbmj = JSON.parse(item.pbmj);
} else {
item.pbmj = [];
}
qwData.xfList.push(item);
});
}
});
}
//获取值班列表
function _getTbQwZbbb() {
let data = {
pageSize: 50,
pageCurrent: 1,
startTime: `${dateFormat("z")} 16:00:00`,
endTime: `${dateFormat()} 16:00:00`,
ssbmdm: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0]
.deptCode,
};
getTbQwZbbb(data).then((res) => {
if (res && res.records.length > 0) {
qwData.zbList = res.records;
}
});
}
//获取勤务数据
function _getQwData() {
getZbld().then((res) => {
if (res) qwData.zbld = res;
});
getJmjlCount().then((res) => {
if (res) qwData.jmjl = res.jmjl;
});
getZgjlCount().then((res) => {
if (res) qwData.zgjl = res.zgjl;
});
}
function getZdgz() {
zdgz.hszdry = 0;
getZdRyCount({}).then((res) => {
res.forEach((v) => {
zdgz.hszdry += v.COUNT;
});
});
}
//待办任务数据
function getMyDb() {
myDb.dcl = 0;
getMyTaskTotal({ sfzh: userInfo.idEntityCard }).then((res) => {
if (res) {
res.forEach((e) => {
myDb.dcl += e.count;
});
}
});
getYclTask().then((res) => {
myDb.ycl = res;
});
}
function routerPush(url, data = {}) {
router.push({
path: url,
query: data,
});
}
onMounted(async () => {
getMyDb();
getZdgz();
await _getJqTotal();
await _getJqTotal(true);
_getQwData();
_getTbQwZbbb();
_getTbQwXfbb();
});
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.sjkb_box {
@include font_size($font_medium_s);
font-weight: 700;
padding: 3vw;
.sjkb_item_box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-top: 3vw;
.sjkb_item {
width: 44%;
margin-bottom: 3vw;
padding: 2vw 2vw;
background: #ebf2fa;
text-align: center;
border-radius: 1vw;
color: #00347e;
border: 1px solid #0d4595;
}
}
}
.wddb_box {
@include font_size($font_medium_s);
background: url("../../assets/images/new/ldjsc_total.png");
background-size: 100% 100%;
margin: 3vw;
color: #ffffff;
padding: 4vw 0;
.wdrw_title {
text-align: center;
@include font_size($font_medium);
font-weight: 700;
}
.dbrw_total {
display: flex;
justify-content: space-between;
// padding: 2vw 3.5vw 5vw 3.5vw;
}
.wddb_item {
width: 41%;
border-radius: 2vw;
text-align: center;
.num {
font-size: 5vw;
margin-right: 1.5vw;
display: inline-block;
margin-bottom: 1vw;
}
}
}
.jq_box {
display: flex;
justify-content: space-between;
@include font_size($font_medium_s);
margin: 0 3vw 3vw 3vw;
.jmsfjq_box {
background: linear-gradient(0deg, #f4f8fb 35%, #e1eeff 100%);
}
.left_item {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.jq_item {
width: 46.85%;
border-radius: 2vw;
padding: 1.5vw;
.mk_jq_total_box {
margin: 5vw 0;
.jq_total {
@include font_size($font_medium);
display: flex;
justify-content: space-between;
.jq_total_unit {
@include font_size($font_medium_s);
}
}
.jqhb {
display: inline-block;
margin-top: 1vw;
color: #999;
}
}
.jq_total_item {
padding: 2.5vw;
border-radius: 2vw;
}
.dxzp_item {
background: rgba(81, 193, 242, 0.1);
}
.zdjqzs_total {
background: url("../../assets/images/new/zdjqzs.png");
background-size: 100%;
}
.jrjqzs_total {
background: rgba(125, 148, 248, 0.3);
}
.wffzzs_total {
background: #fae9e1;
.xz_xs_total {
display: flex;
justify-content: space-between;
color: #7c4e19;
.sx {
width: 1px;
background: #7c4e19;
}
}
}
}
}
.order_total {
margin: 3vw;
@include font_size($font_medium_s);
display: flex;
justify-content: space-between;
margin-top: 3vw;
color: #fff;
.total_item {
border-radius: 5px;
width: 31%;
padding: 2.5vw 0;
text-align: center;
&>span:nth-child(1) {
display: inline-block;
@include font_size($font_medium);
font-weight: 700;
margin-bottom: 1.5vw;
}
}
}
.wk_echart {
display: flex;
align-items: flex-start;
@include font_size($font_medium_s);
height: 40vw;
overflow: hidden;
.wk_dot {
display: inline-block;
width: 2vw;
height: 2vw;
border-radius: 50%;
margin-right: 2vw;
}
.wk_item {
margin: 4vw;
}
}
.topM {
padding-top: 2vw;
}
.yuqts_box {
display: flex;
justify-content: center;
height: 40vw;
overflow: auto;
// background: #f1f6f4;
// margin: 0 3vw 3vw 3vw;
// padding: 2.5vw;
padding-bottom: 5vw;
@include font_size($font_medium_s);
}
.bmdt_box {
display: flex;
justify-content: flex-start;
align-items: center;
overflow-x: auto;
margin: 0 2.5vw 3vw 2.5vw;
@include font_size($font_medium_s);
.bm_item {
// white-space: nowrap;
border-radius: 10px;
flex-shrink: 0;
height: 12vw;
margin: 0 1vw;
padding: 0 5px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-weight: 700;
}
}
.qwqk_box {
margin: 3vw;
@include font_size($font_medium_s);
.title_box {
display: flex;
justify-content: space-between;
}
.qu_total {
display: flex;
justify-content: space-between;
margin-top: 3vw;
.qu_item_total {
width: 31.5%;
text-align: center;
background: #f5f5f5;
padding: 3vw 0;
border-radius: 1.5vw;
&>span:nth-child(1) {
display: inline-block;
@include font_size($font_medium);
font-weight: 700;
margin-bottom: 2vw;
}
}
}
.zbld_box {
margin-top: 3vw;
overflow-x: auto;
display: flex;
.zbld_item_box {
border: 1px solid #eee;
padding: 2.5vw 3vw;
flex-shrink: 0;
width: 39vw;
margin-right: 2.5vw;
display: table;
border-radius: 1.5vw;
&>img {
position: relative;
top: -1vw;
}
.abld_detail {
display: inline-block;
margin-left: 1.7vw;
&>span:nth-child(1) {
@include font_size($font_medium);
font-weight: 700;
}
}
}
}
.zdqw_box {
margin-top: 3vw;
overflow-x: auto;
display: flex;
.zdqw_item_box {
background: #fef4f4;
line-height: 6vw;
margin-right: 3vw;
// padding: 2vw;
flex-shrink: 0;
display: table;
border-radius: 1.5vw;
width: 60vw;
overflow: hidden;
color: #4d1717;
.zdqw_msg {
display: inline-block;
margin-right: 5vw;
}
}
}
}
.wzdqw_box {
padding: 2.5vw;
text-align: center;
background: rgba(106, 188, 131, 0.2);
margin-top: 3vw;
border-radius: 1.5vw;
@include font_size($font_medium);
font-weight: 700;
}
.jmsfjq_total_title {
@include font_size($font_medium);
font-weight: 700;
}
.bl_img {
width: 2vw;
height: 2.5vw;
margin-right: 1vw;
}
.jq_num {
font-size: 6vw;
font-weight: 700;
margin: 2vw 0;
}
.wqts_box {
background: url("../../assets/images/new/wqts.png");
background-size: 100%;
padding: 2vw 0;
}
.yqts_box {
background: url("../../assets/images/new/yqts.png");
background-size: 100% 100%;
padding: 2vw 0;
}
.look_more {
font-weight: normal;
color: #777;
@include font_size($font_medium_s);
}
.zdqw_title_box {
background: #f5e9e9;
padding: 1.5vw;
display: flex;
justify-content: space-between;
align-items: center;
}
.zdqw_mj_fj_num {
padding: 2vw;
}
.bmdt_img {
width: 11vw;
height: 11vw;
padding: 4vw 5.5vw;
background: #f5f7fd;
border-radius: 5px;
}
</style>

View File

@ -0,0 +1,322 @@
<template>
<div style="padding-top: 13vw">
<TopNav :navTitle="title" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="myzls">
<Search placeholder="请输入关键字" v-model="kwd" :isSx="true" @update:sx="showPopup = !showPopup"
@update:modelValue="onSearch"></Search>
</div>
</van-sticky>
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list v-model:loading="loading" :finished="finished" finished-text=" " @load="onLoad" offset="1"
:immediate-check="false">
<ZlList v-for="(item, index) in zlList.list" :key="index" :item="item"
:dict="{ D_BZ_ZXZTAI, D_BZ_RGZLLX, D_BZ_ZLLY, D_BZ_ZLLX }" :path="`/yyzx/zlzx/zlDetail?id=${item.zlId}`"
:isMyFqdzl="true">
</ZlList>
<van-empty description="暂无指令信息" image="default" v-if="showEmpty" />
</van-list>
</van-pull-refresh>
<SxPopup :showPopup="showPopup" :list="zlList.sxTypeList" :p_top="105" @update:close="showPopup = false"
@update:onConfirm="onConfirm" />
</div>
</template>
<script setup>
import { getTrsToken } from "@/api/common";
import Tabs from "../../components/tabs.vue";
import TopNav from "../../components/topNav.vue";
import Search from "../../components/search.vue";
import ZlList from "../../components/zlList.vue";
import SxPopup from "../../components/SxPopup.vue";
import {
dateFormat,
setTimeQuantum,
setEchartTime,
} from "../../utils/tools.js";
import { getDictList, setDict } from "../../utils/dict";
import { ref, onMounted, reactive, watch } from "vue";
import { Toast } from "vant";
import { getMyZlList, getMyCsList } from "../../api/zlzx.js";
import { useRoute } from "vue-router";
const { D_BZ_ZXZTAI, D_BZ_RGZLLX, D_BZ_ZLLY, D_BZ_ZLLX } = getDictList(
"D_BZ_ZXZTAI",
"D_BZ_RGZLLX",
"D_BZ_ZLLY",
"D_BZ_ZLLX"
); //字典信息
const userInfo = JSON.parse(window.localStorage.getItem("userInfo"));
const kwd = ref(""); //搜索关键字
const showPopup = ref(false); //赛选条件窗口
const zlztIndex = ref(-1); //选中的指令状态下标
const timeShow = ref(false); //时间选择器
const presentTime = ref(new Date()); //当前时间
const timeType = ref(""); //选择的时间类型
const startTime = ref(""); //开始时间
const endTime = ref(""); //结束时间
const loading = ref(false);
const loadingPull = ref(false);
const finished = ref(false);
const showEmpty = ref(false);
const pageSize = ref(10);
const pageCurrent = ref(1);
const zllx = ref(""); // 指令类型
const zlTypeIndex = ref(""); //选中的查询类型下标
const total = ref(0); //
const tabsIndex = ref(1);
const zlList = reactive({
list: [], //指令列表数据
sxTypeList: [], //筛选项数据
});
const title = ref("我发起的指令");
const type = ref("");
watch(D_BZ_ZXZTAI, (newValue) => {
//设置筛选值
let array = [];
for (let i = 0; i < newValue.length; i++) {
array.push({
name: newValue[i].text,
key: newValue[i].dm,
isCheck: false,
});
}
zlList.sxTypeList = [
{
title: "指令进行状态",
isCheckBox: false,
array: array,
},
];
zlList.sxTypeList[1] = setTimeQuantum();
});
onMounted(() => {
type.value = useRoute().query.type;
if (type.value == "cs") {
title.value = "抄送我的指令";
}
_getZlList();
});
//下拉刷新
function onRefresh() {
zlList.list = [];
zlList.Sclist = [];
pageCurrent.value = 1;
zlTypeIndex.value = "";
kwd.value = "";
startTime.value = "";
endTime.value = "";
loading.value = false;
loadingPull.value = false;
finished.value = false;
tabsIndex.value++;
_getZlList();
}
//关键字查询
function onSearch(e) {
kwd.value = e;
zlList.list = [];
zlList.Sclist = [];
pageCurrent.value = 1;
showEmpty.value = false;
_getZlList();
}
// //类型查询
function onSelect(val) {
zlList.list = [];
zlList.Sclist = [];
pageCurrent.value = 1;
zllx.value = tabs.value[val].zllx;
loading.value = false;
loadingPull.value = false;
finished.value = false;
_getZlList();
}
//获取指令数据列表
function _getZlList() {
loading.value = true;
showEmpty.value = false;
let data = {
pageSize: pageSize.value,
pageCurrent: pageCurrent.value,
zlzxzt: zlTypeIndex.value,
zlnr: kwd.value,
kssj: startTime.value,
jssj: endTime.value,
zllx: zllx.value,
sfcs: type.value ? 1 : 0,
};
if (type.value) {
getMyCsList(data).then((res) => {
loading.value = false;
loadingPull.value = false;
total.value = res.pages;
if (res.records.length > 0) {
res.records.forEach((item) => {
zlList.list.push(item);
});
} else {
showEmpty.value = true;
}
});
} else {
getMyZlList(data).then((res) => {
loading.value = false;
loadingPull.value = false;
total.value = res.pages;
if (res.records.length > 0) {
res.records.forEach((item) => {
zlList.list.push(item);
});
} else {
showEmpty.value = true;
}
});
}
}
//选中时间
function onTimeConfirm(val) {
if (timeType.value == "start") {
startTime.value = dateFormat("", val);
} else {
endTime.value = dateFormat("", val);
}
timeShow.value = false;
}
//选中指令状态
function onClickZlzt(index, dm) {
zlTypeIndex.value = dm;
zlztIndex.value = index;
}
//确认筛选条件
function onConfirm(val) {
zlList.list = [];
zlList.Sclist = [];
pageCurrent.value = 1;
startTime.value = val.startTime;
endTime.value = val.endTime;
showEmpty.value = false;
zlTypeIndex.value = "";
for (let i = 0; i < val.list.length; i++) {
for (let j = 0; j < val.list[i].array.length; j++) {
if (val.list[i].array[j].isCheck) {
zlTypeIndex.value = val.list[i].array[j].key;
break;
}
}
}
_getZlList();
showPopup.value = false;
}
//重置筛选条件
function onReset() {
startTime.value = "";
endTime.value = "";
zlztIndex.value = -1;
}
//触底加载
function onLoad() {
if (pageCurrent.value >= total.value) {
finished.value = true;
return;
}
pageCurrent.value += 1;
_getZlList();
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.sticky_box {
@include bg_color($background-color-theme);
.tabs_box {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
display: flex;
.tabs_item {
width: 25%;
text-align: center;
.tabs_count {
margin-top: 2vw;
}
}
}
}
.zl_sx_box {
@include font_size($font_medium_s);
padding: 4vw 0;
.item_title {
padding: 0 3.5vw;
font-weight: 600;
}
.zlzt_box {
padding: 4vw;
.tag_item {
margin: 0 3vw 3vw 0;
padding: 1vw 3vw;
}
}
}
.but_box {
display: flex;
justify-content: space-between;
margin-top: 5vw;
}
.item_box {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
margin: 0 3.5vw 4vw 3.5vw;
padding: 2vw;
.time_box {
display: flex;
justify-content: space-between;
align-items: center;
.ststus {
font-size: 10px;
padding: 0 10px;
color: #fff;
border-radius: 10px;
}
.dfk {
background-color: rgb(242, 199, 6);
}
.yfk {
background-color: #3e6ee8;
}
.ywj {
background-color: #4fbe0d;
}
.ddc {
background-color: orangered;
}
.djc {
background-color: orange;
}
}
>div {
line-height: 20px;
}
.title {
@include font_size($font_medium);
font-weight: bold;
}
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<div id="wqts" style="width: 60vw; height: 50vw"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, reactive, nextTick } from "vue";
import * as echarts from "echarts";
onMounted(() => {
hamdlegfChart();
});
function hamdlegfChart() {
var m2R2Data = [
{
value: 2,
itemStyle: { color: "#dd2024" },
},
{
value: 4,
itemStyle: { color: "#fb8734" },
},
{
value: 6,
itemStyle: { color: "#ecc617" },
},
{
value: 10,
itemStyle: { color: "#4399fc" },
},
];
if (document.getElementById("wqts")) {
let myechart = echarts.init(document.getElementById("wqts"));
myechart.setOption({
title: [
{
text: 22 + "",
subtext: "预警总数",
textStyle: {
fontSize: 16,
color: "#4e5486",
},
subtextStyle: {
fontSize: 10,
color: "black",
},
textAlign: "center",
x: "37.5%",
y: "26%",
},
],
legend: {
show: false,
},
series: [
{
type: "pie",
center: ["40%", "38%"],
radius: ["40%", "65%"],
itemStyle: {
borderWidth: 3,
borderColor: "#fff",
},
clockwise: false, //饼图的扇区是否是顺时针排布
avoidLabelOverlap: false,
labelLine: {
show: false,
},
label: {
show: false,
},
data: m2R2Data,
},
],
});
window.addEventListener("resize", () => {
myechart.resize();
});
}
}
</script>
<style>
</style>

269
src/pages/newTwoHome/xd.vue Normal file
View File

@ -0,0 +1,269 @@
<template>
<div class="" style="padding-top: 13vw">
<TopNav navTitle="巡大" :showRight="false" :showLeft="true" />
<div class="jq_box topM">
<span class="jmsfjq_total_title">街面六类</span>
</div>
<div class="jq_box">
<div class="jq_item left_item" style="padding: 0">
<div class="jrjqzs_total jq_total_item" @click="onClickJqTotal(1)">
<span class="jmsfjq_total_title">抢夺</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ jqTotal.lqCount }} </span>
<span style="display: inline-block; margin-left: 6vw">较昨日<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.lqUp > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.lqCount > 0 ? 'red' : 'green'">
{{ jqTotal.lqUp > 0 ? "+" + jqTotal.lqUp : jqTotal.lqUp }}%</span>
</span>
</span>
</div>
</div>
<div class="jrjqzs_total jq_total_item" @click="onClickJqTotal(2)">
<span class="jmsfjq_total_title">抢劫</span>
<div style="margin: 1vw 0 0 0">
<span class="red jq_num">{{ jqTotal.lqCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
较昨日<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.lqUp > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.lqCount > 0 ? 'red' : 'green'">
{{ jqTotal.lqUp > 0 ? "+" + jqTotal.lqUp : jqTotal.lqUp }}%</span></span>
</span>
</div>
</div>
<!-- zdjqzs_total jq_total_item wffzzs_total jq_total_item-->
<div class="zdjqzs_total jq_total_item" @click="onClickJqTotal(3)">
<span class="jmsfjq_total_title">盗窃汽车</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ jqTotal.qcCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
较昨日<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.qcUp > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.qcUp > 0 ? 'red' : 'green'">
{{ jqTotal.qcUp > 0 ? "+" + jqTotal.qcUp : jqTotal.qcUp }}%</span></span>
</span>
</div>
<!-- <div class="xz_xs_total">
<span>刑事 {{ jqTotal.xsCount }} </span>
<span class="sx"></span>
<span>行政 {{ jqTotal.xzCount }}</span>
</div> -->
</div>
<div class="zdjqzs_total jq_total_item" @click="onClickJqTotal(1)">
<span class="jmsfjq_total_title">盗窃车内财物</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ jqTotal.ccCount }} </span>
<span style="display: inline-block; margin-left: 6vw">较昨日<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.ccUp > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.ccUp > 0 ? 'red' : 'green'">
{{ jqTotal.ccUp > 0 ? "+" + jqTotal.ccUp : jqTotal.ccUp }}%</span>
</span>
</span>
</div>
</div>
<div class="wffzzs_total jq_total_item" @click="onClickJqTotal(2)">
<span class="jmsfjq_total_title">扒窃</span>
<div style="margin: 1vw 0 0 0">
<span class="red jq_num">{{ jqTotal.pqCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
较昨日<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.pqUp > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.pqUp > 0 ? 'red' : 'green'">
{{ jqTotal.pqUp > 0 ? "+" + jqTotal.pqUp : jqTotal.pqUp }}%</span></span>
</span>
</div>
</div>
<div class="wffzzs_total jq_total_item" @click="onClickJqTotal(3)">
<span class="jmsfjq_total_title">盗窃三车</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ jqTotal.dqscCount }}</span>
<span style="display: inline-block; margin-left: 6vw">
较昨日<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="jqTotal.dqscUp > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="jqTotal.dqscUp > 0 ? 'red' : 'green'">
{{ jqTotal.dqscUp > 0 ? "+" + jqTotal.dqscUp : jqTotal.dqscUp }}%</span></span>
</span>
</div>
<!-- <div class="xz_xs_total">
<span>刑事 {{ jqTotal.xsCount }} </span>
<span class="sx"></span>
<span>行政 {{ jqTotal.xzCount }}</span>
</div> -->
</div>
</div>
</div>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import { ref, onMounted, onUnmounted, onActivated, reactive } from "vue";
import { dateFormat } from "../../utils/tools.js";
import { baseUrl2 } from "../../utils/request";
import router from "../../router";
import axios from "axios";
const jqTotal = ref({}); //今日警情统计
const zrjqTotal = ref(0); //昨日警情数据
const QWLX = ref([]); //勤务类型
onMounted(() => {
_getJqTotal();
_getJqTotal(true);
});
//点击警情统计查看列表
function onClickJqTotal(status) {
router.push(`/newTwoHome/jq/xzjqlist?status=${status}`);
}
//获取警情统计 type 是否是昨日
function _getJqTotal(type) {
let data = {
orgId: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0]
.deptCode,
startTime: `${dateFormat("z")} 16:00:00`,
endTime: `${dateFormat()} 16:00:00`,
type: 1,
keyword: "",
};
if (type) {
data.startTime = `${dateFormat("z2")} 16:00:00`;
data.endTime = `${dateFormat("z")} 16:00:00`;
}
axios.post(`${baseUrl2}/xz1Api/api/alarm/count`, data).then((res) => {
if (res.data) {
if (type) {
let num =
res.data.data.lqCount +
res.data.data.qcCount +
res.data.data.ccCount +
res.data.data.pqCount +
res.data.data.dqscCount;
zrjqTotal.value = jqTotal.value.jmsfTotal - num;
} else {
jqTotal.value = res.data.data;
jqTotal.value.jmsfTotal =
res.data.data.lqCount +
res.data.data.qcCount +
res.data.data.ccCount +
res.data.data.pqCount +
res.data.data.dqscCount;
}
}
});
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.jq_box {
display: flex;
justify-content: space-between;
@include font_size($font_medium_s);
margin: 0 3vw 3vw 3vw;
.jmsfjq_box {
background: linear-gradient(0deg, #f4f8fb 35%, #e1eeff 100%);
}
.left_item {
display: flex;
// flex-direction: column;
justify-content: space-between;
}
.jq_item {
// flex-shrink: 0;
flex-wrap: wrap;
border-radius: 2vw;
padding: 1.5vw;
.mk_jq_total_box {
margin: 5vw 0;
.jq_total {
@include font_size($font_medium);
display: flex;
justify-content: space-between;
.jq_total_unit {
@include font_size($font_medium_s);
}
}
.jqhb {
display: inline-block;
margin-top: 1vw;
color: #999;
}
}
.jq_total_item {
width: 37vw;
padding: 2.5vw;
border-radius: 2vw;
margin: 2vw;
}
.dxzp_item {
background: rgba(81, 193, 242, 0.1);
}
.zdjqzs_total {
background: url("../../assets/images/new/zdjqzs.png");
background-size: 100%;
}
.jrjqzs_total {
background: #7d9ef8;
}
.wffzzs_total {
background: #fae9e1;
.xz_xs_total {
display: flex;
justify-content: space-between;
color: #7c4e19;
.sx {
width: 1px;
background: #7c4e19;
}
}
}
}
}
.topM {
padding-top: 2vw;
}
.bl_img {
width: 2vw;
height: 2.5vw;
margin-right: 1vw;
}
.jq_num {
font-size: 6vw;
font-weight: 700;
margin: 2vw 0;
}
</style>

View File

@ -0,0 +1,51 @@
<template>
<div style="padding-top: 14vw">
<TopNav navTitle="已处理任务" :showRight="false" :showLeft="true" />
<div class="rw_list_box" v-for="item in list" :key="item.id">
<SwiperCell :item="item" :dict="{ D_BZ_GRRWZT }"></SwiperCell>
</div>
<van-empty description="暂无信息" image="default" v-if="showEmpty" />
</div>
</template>
<script setup>
import SwiperCell from "../../components/swiperCell.vue";
import TopNav from "../../components/topNav.vue";
import { getYclTaskList } from "../../api/ldjsc.js";
import { onMounted, ref } from "vue";
import { getDictList } from "../../utils/dict";
const { D_BZ_GRRWZT } = getDictList("D_BZ_GRRWZT");
const list = ref([]);
const showEmpty = ref(false);
const queryLsit = ref({
pageCurrent: 1,
pageSize: 20,
});
function getList() {
getYclTaskList(queryLsit.value)
.then((res) => {
if (res && res.records.length > 0) {
list.value = res.records;
} else {
showEmpty.value = true;
}
})
.catch((err) => {
showEmpty.value = true;
});
}
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.rw_list_box {
padding: 3vw 0;
margin: 0 3vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
@include item_bottom_color($bottom-border-top-clore-theme);
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<div style="padding-top: 14vw">
<TopNav navTitle="值班情况" :showRight="false" :showLeft="true" />
<div class="list_item" v-for="(item,index) in list" :key="index+'zbqk'">
<span>{{item.ssbmmc}}</span>
<span>{{setDict(item.type,dict)}}</span>
</div>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import { getBbListByDept } from "../../api/ldjsc.js";
import { setDict } from "../../utils/dict";
import { onMounted, ref } from "vue";
import { Toast } from "vant";
const dict = [
{text:'未排班',value:'wpb'},
{text:'已报备',value:'ybb'},
{text:'未报备',value:'wbb'}
]
const list = ref([]);
function getList() {
Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
getBbListByDept().then((res) => {
list.value = res;
Toast.clear();
});
}
onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.list_item{
width: 95vw;
margin: 2vw auto;
background: rgb(240, 242, 246);
@include font_size($font_medium_s);
padding: 6px 10px;
display: flex;
box-sizing: border-box;
color: #333;
justify-content: space-between;
>span:nth-child(1){
flex: 1;
}
>span:nth-child(2){
width: 15vw;
text-align: right;
}
}
</style>

View File

@ -0,0 +1,220 @@
<template>
<div class="" style="padding-top: 13vw">
<TopNav navTitle="总警情分类" :showRight="false" :showLeft="true" />
<div class="jq_box">
<div class="jq_item left_item" style="padding: 0">
<div class="jq_total_item" v-for="(item, index) in Tabslist" :class="index == 0 || index == 1 ? 'jrjqzs_total' :
index == 2 || index == 3 ? 'zdjqzs_total' : 'wffzzs_total'" :key="index"
@click="onClickJqTotal(item.type)">
<span class="jmsfjq_total_title">{{ item.name }}</span>
<div style="margin: 1vw 0">
<span class="jq_num">{{ item.count }} </span>
<span style="display: inline-block; margin-left: 6vw">环比<br />
<span style="display: inline-block; margin-top: 1vw">
<img src="../../assets/images/leader/arrow-up@2x.png" class="bl_img" v-if="item.hb > 0" />
<img src="../../assets/images/leader/arrow-down@2x.png" class="bl_img" v-else />
<span :class="item.hb > 0 ? 'red' : 'green1'">{{ item.hb }}%</span>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
</script>
<script setup>
import TopNav from "../../components/topNav.vue";
import { ref, onMounted, onUnmounted, onActivated, reactive } from "vue";
import { dateFormat } from "../../utils/tools.js";
import { baseUrl2 } from "../../utils/request";
import router from "../../router";
import axios from "axios";
import { onBeforeRouteLeave } from "vue-router";
const jqTotal = ref({}); //今日警情统计
const zrjqTotal = ref(0); //昨日警情数据
const QWLX = ref([]); //勤务类型
const Tabslist = ref([
{ name: "刑事", count: 0, hb: 0, type: 5 },//4
{ name: "行政", count: 0, hb: 0, type: 4 },//3
{ name: "纠纷", count: 0, hb: 0, type: 13 },//12
{ name: "求助", count: 0, hb: 0, type: 14 },//13
{ name: "其他", count: 0, hb: 0, type: 15 },//14
])
onMounted(() => {
getCount()//// 获取统计
_getJqTotal();
_getJqTotal(true);
});
// 获取统计
function getCount() {
let data = {
orgId: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0].deptCode,
startTime: `${dateFormat("z")} 16:00:00`,
endTime: `${dateFormat()} 16:00:00`,
type: 1,
keyword: "",
};
axios.post(`${baseUrl2}/xz1Api/api/alarm/count`, data).then((res) => {
if (res.data) {
Tabslist.value[0].count = res.data.data.xsCount //刑事
Tabslist.value[0].hb = res.data.data.xsHb //刑事环比
Tabslist.value[1].count = res.data.data.xzCount //行政
Tabslist.value[1].hb = res.data.data.xzHb //行政环比
Tabslist.value[2].count = res.data.data.jfCount //纠纷
Tabslist.value[2].hb = res.data.data.jfHb //纠纷环比
Tabslist.value[3].count = res.data.data.qzCount //求助
Tabslist.value[3].hb = res.data.data.qcHb //求助环比
Tabslist.value[4].count = res.data.data.qtCount //其他
Tabslist.value[4].hb = res.data.data.qtHb //其他环比
}
});
}
//点击警情统计查看列表
function onClickJqTotal(status) {
router.push(`/newTwoHome/jq/xzjqlist?status=${status}`);
}
//获取警情统计 type 是否是昨日
function _getJqTotal(type) {
let data = {
orgId: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0]
.deptCode,
startTime: `${dateFormat("z")} 16:00:00`,
endTime: `${dateFormat()} 16:00:00`,
type: 1,
keyword: "",
};
if (type) {
data.startTime = `${dateFormat("z2")} 16:00:00`;
data.endTime = `${dateFormat("z")} 16:00:00`;
}
axios.post(`${baseUrl2}/xz1Api/api/alarm/count`, data).then((res) => {
if (res.data) {
if (type) {
let num =
res.data.data.lqCount +
res.data.data.qcCount +
res.data.data.ccCount +
res.data.data.pqCount +
res.data.data.dqscCount;
zrjqTotal.value = jqTotal.value.jmsfTotal - num;
} else {
jqTotal.value = res.data.data;
jqTotal.value.jmsfTotal =
res.data.data.lqCount +
res.data.data.qcCount +
res.data.data.ccCount +
res.data.data.pqCount +
res.data.data.dqscCount;
}
}
});
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.jq_box {
display: flex;
justify-content: space-between;
@include font_size($font_medium_s);
margin: 0 3vw 3vw 3vw;
.jmsfjq_box {
background: linear-gradient(0deg, #f4f8fb 35%, #e1eeff 100%);
}
.left_item {
display: flex;
// flex-direction: column;
justify-content: space-between;
}
.jq_item {
// flex-shrink: 0;
flex-wrap: wrap;
border-radius: 2vw;
padding: 1.5vw;
.mk_jq_total_box {
margin: 5vw 0;
.jq_total {
@include font_size($font_medium);
display: flex;
justify-content: space-between;
.jq_total_unit {
@include font_size($font_medium_s);
}
}
.jqhb {
display: inline-block;
margin-top: 1vw;
color: #999;
}
}
.jq_total_item {
width: 37vw;
padding: 2.5vw;
border-radius: 2vw;
margin: 2vw;
}
.dxzp_item {
background: rgba(81, 193, 242, 0.1);
}
.zdjqzs_total {
background: url("../../assets/images/new/zdjqzs.png");
background-size: 100%;
}
.jrjqzs_total {
background: #7d9ef8;
}
.wffzzs_total {
background: #fae9e1;
.xz_xs_total {
display: flex;
justify-content: space-between;
color: #7c4e19;
.sx {
width: 1px;
background: #7c4e19;
}
}
}
}
}
.topM {
padding-top: 2vw;
}
.bl_img {
width: 2vw;
height: 2.5vw;
margin-right: 1vw;
}
.jq_num {
font-size: 6vw;
font-weight: 700;
margin: 2vw 0;
}
.green1 {
color: #57fc48;
}
</style>

360
src/pages/rw/index.vue Normal file
View File

@ -0,0 +1,360 @@
<template>
<div>
<TopNav navTitle="待办" :showRight="false" :showLeft="false" />
<van-sticky>
<div class="sticky_box">
<Tabs :list="tabs" @onYjjb="onSelect" :type="'car'" :checked="tabsKey" :key="tabsIndex"></Tabs>
<Search v-model="kwd" :isSx="true" @update:sx="showPopup = !showPopup" placeholder="请输入关键字"
@update:modelValue="onClickSearch"></Search>
</div>
</van-sticky>
<SxPopup :showPopup="showPopup" :list="queryData.sxList" :p_top="145" @update:close="showPopup = false"
@update:onConfirm="onConfirm" />
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list :finished="finished" finished-text=" " @load="onLoad" offset="1" :immediate-check="false">
<div class="rw_list_box" v-for="item in rwObj.rwList" :key="item.id" @click="
onLookRw(
item.id,
item.rwxl,
item.rwlx,
item.ywid,
item.rwzt,
item.grrwzt,
item.rwid
)
">
<SwiperCell :item="item" @click:Transmit="onClickTransmit" @click:onDown="onClickDown"
:dict="{ D_BZ_GRRWZT }"></SwiperCell>
</div>
</van-list>
<van-loading style="text-align: center" v-if="listLoading">加载中...</van-loading>
<van-empty description="暂无任务信息" v-if="showEmpty" />
</van-pull-refresh>
<!-- 底部tas -->
<BottomTabs type="rw" />
<div style="height: 15.8666vw"></div>
<!-- 转发人数据 -->
<van-popup v-model:show="showfzrPicker" position="bottom">
<van-search v-model="list.phone" placeholder="请输入电话号码" @update:model-value="getLdList()" />
<van-picker :columns="list.fzrList" @confirm="onfzrConfirm" @cancel="showfzrPicker = false"
:columns-field-names="customfzrFieldNamed" />
</van-popup>
</div>
</template>
<script>
export default {
name: "rw",
};
</script>
<script setup>
import { ref, onMounted, reactive, watch } from "vue";
import SxPopup from "../../components/SxPopup.vue";
import SwiperCell from "../../components/swiperCell.vue";
import Tabs from "../../components/tabs.vue";
import BottomTabs from "../../components/bottomTabs.vue";
import TopNav from "../../components/topNav.vue";
import { getMyTaskList, getMyTaskTotal, upGrzt } from "../../api/rwzx.js";
import router from "../../router/index.js";
import { sysUser } from "../../api/patrolBasicInfo.js";
import { Dialog } from "vant";
import { setTimeQuantum } from "../../utils/tools";
import Search from "../../components/search.vue";
import { transmitTask } from "../../api/yyzxApi.js";
import { getDictList, setDict } from "../../utils/dict";
import { useRoute, onBeforeRouteLeave } from "vue-router";
const { D_BZ_GRRWZT, D_BZ_RWXL } = getDictList("D_BZ_GRRWZT", "D_BZ_RWXL"); //字典信息
const showfzrPicker = ref(false); //是否显示转发人弹窗
const showPopup = ref(false);
//搜索配置
const queryData = reactive({
sxList: [setTimeQuantum()],
});
const list = reactive({
phone: "", //转发人手机号
fzrList: [], //转发人数据
});
const tabsIndex = ref(1);
//指定picker选择器字段
const customfzrFieldNamed = {
text: "userName",
};
const tabs = ref([
{
name: "全部",
count: 0,
value: "all",
},
]);
watch(
() => D_BZ_RWXL.value,
() => {
tabs.value.push(
...D_BZ_RWXL.value.map((item) => {
return {
name: item.text,
count: 0,
value: item.value,
};
})
);
_getMyTaskTotal();
},
{
deep: true,
}
);
const themeType = ref(getStorage("themeSetting"));
const active = ref(1);
const kwd = ref(""); //搜索关键字
const pageSize = ref(10);
const pageCurrent = ref(1);
const tabsKey = ref(0);
const userInfo = JSON.parse(window.localStorage.getItem("userInfo"));
const rwObj = reactive({
rwList: [], //任务数据
rwTotal: {}, //任务统计
});
const rwjxzt = ref(""); //查询类型
const listLoading = ref(false);
const loadingPull = ref(false);
const finished = ref(false);
const total = ref(0);
const rwId = ref(""); //操作的任务ID
const showEmpty = ref(false);
//搜索框背景颜色
const searchBack = ref({});
onMounted(() => {
if (useRoute().query.tabsType) {
tabsKey.value = useRoute().query.tabsType;
rwjxzt.value = "05";
}
// rwjxzt.value
_getMyTaskList();
// _getMyTaskTotal();
getLdList();
});
//下拉刷新
function onRefresh() {
tabs.value[0].count = 0;
rwObj.rwList = [];
pageCurrent.value = 1;
kwd.value = "";
tabsIndex.value++;
finished.value = false;
_getMyTaskList();
_getMyTaskTotal();
}
//判断任务是暂停和关闭
function _setRwNotify(rwzt) {
if (rwzt == 1) {
hintToast("任务已关闭!!!");
return false;
}
if (rwzt == 2) {
hintToast("任务已暂停!!!");
return false;
}
return true;
}
//点击转发按钮打开人员选择器
function onClickTransmit(val) {
if (!_setRwNotify(val.rwzt)) {
return;
}
rwId.value = val.id;
showfzrPicker.value = true;
}
//驳回任务
function onClickDown(val) {
if (!_setRwNotify(val.rwzt)) {
return;
}
Dialog.confirm({
title: "提示",
message: "是否确认驳回该条任务信息!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
_setTransmitTask(rwId.value, 4);
});
}
//确认转发任务
function onfzrConfirm(val) {
Dialog.confirm({
title: "提示",
message: "是否确认转发任务!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
_setTransmitTask(rwId.value, 3, val.id);
});
}
/**
* 设置任务状态
* @export
* @param {*} rwid
* @param {*} rwzt 1 进行中 2 已完成 3 已转发 4 已驳回
* @param {*} zfjsrid 转发人ID
*/
function _setTransmitTask(rwid, rwzt, zfjsrid) {
let data = { rwid, rwzt, zfjsrid };
try {
let location = JSON.parse(bridge.getLocation());
data.jd = location.app_x;
data.wd = location.app_y;
} catch (error) { }
transmitTask(data).then((res) => {
showfzrPicker.value = false;
if (rwzt != 1) {
hintToast("成功");
}
_getMyTaskList();
});
}
// 查询转发人数据
function getLdList() {
sysUser({
current: 1,
size: 50,
phone: list.phone,
}).then((res) => {
list.fzrList = res.records;
});
}
//查看任务详情
function onLookRw(id, rwxl, rwlx, ywid, rwzt, grrwzt, rwid) {
if (!_setRwNotify(rwzt)) {
return;
}
if (grrwzt === "0") {
upGrzt({ rwid: rwid, rwzt: "1" });
}
//通知任务
if (rwlx == 1) {
router.push(`/rw/views/rwDetail?id=${rwid}`);
return;
}
//值班任务
if (rwxl == "04") {
router.push("/yyzx/views/addZbbb");
return;
}
//巡防任务
if (rwxl == "03") {
router.push("/yyzx/xfbb/addXfbb");
return;
}
//指令任务
if (rwxl == "05") {
router.push(`/yyzx/zlzx/zlDetail?id=${ywid}`);
return;
}
//实有人口任务
if (rwxl == "01") {
router.push(`/rw/views/syrkRwDetail?id=${rwid}`);
return;
}
}
function onConfirm(val) {
rwObj.rwList = [];
timeObj.kssj = val.startTime;
timeObj.jssj = val.endTime;
_getMyTaskList();
showPopup.value = false;
}
//关键字搜索
function onClickSearch(e) {
rwObj.rwList = [];
pageCurrent.value = 1;
_getMyTaskList();
}
//按类型查询
function onSelect(val) {
rwObj.rwList = [];
pageCurrent.value = 1;
switch (val) {
case 0:
rwjxzt.value = "";
break;
default:
rwjxzt.value = tabs.value[val].value;
break;
}
_getMyTaskList();
}
//获取任务统计
function _getMyTaskTotal() {
getMyTaskTotal({ sfzh: userInfo.idEntityCard }).then((res) => {
if (res) {
res.forEach((e) => {
tabs.value[0].count += e.count;
});
tabs.value.forEach((v) => {
const tjarr = res.filter((item) => item.rwxl === v.value);
if (tjarr.length > 0) {
v.count = tjarr[0].count;
}
});
}
});
}
//触底加载
function onLoad() {
if (pageCurrent.value >= total.value) {
finished.value = true;
return;
}
pageCurrent.value += 1;
_getMyTaskList();
}
const timeObj = reactive({
kssj: "",
jssj: "",
});
//获取任务列表
function _getMyTaskList() {
listLoading.value = true;
showEmpty.value = false;
let data = {
pageSize: pageSize.value,
pageCurrent: pageCurrent.value,
jsrsfzh: userInfo.idEntityCard,
rwnr: kwd.value,
// grrwzt: rwjxzt.value,
rwxl: rwjxzt.value,
kssj: timeObj.kssj,
jssj: timeObj.jssj,
};
getMyTaskList(data)
.then((res) => {
total.value = res.pages;
listLoading.value = false;
loadingPull.value = false;
if (res.records.length > 0) {
res.records.forEach((item) => {
rwObj.rwList.push(item);
});
} else {
showEmpty.value = true;
}
})
.catch((err) => {
listLoading.value = false;
showEmpty.value = true;
});
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.rw_list_box {
padding: 3vw 0;
margin: 0 3vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
@include item_bottom_color($bottom-border-top-clore-theme);
}
</style>

401
src/pages/rw/rwlist.vue Normal file
View File

@ -0,0 +1,401 @@
<template>
<div>
<TopNav navTitle="任务列表" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="sticky_box">
<Tabs :list="tabs" @onYjjb="onSelect" :type="'car'" :key="tabsIndex"></Tabs>
<Search v-model="kwd" :isSx="true" @update:sx="showPopup = !showPopup" placeholder="请输入关键字"
@update:modelValue="onClickSearch"></Search>
</div>
</van-sticky>
<SxPopup :showPopup="showPopup" :list="queryData.sxList" :p_top="145" @update:close="showPopup = false"
@update:onConfirm="onConfirm" />
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list v-show="!showPopup" :finished="finished" finished-text=" " @load="onLoad" offset="1"
:immediate-check="false">
<div class="rw_list_box" v-for="item in rwObj.rwList" :key="item.id"
@click="onLookRw(item.id, item.rwxl, item.rwlx, item.ywid, item.rwzt)">
<SwiperCell :isMy="true" :item="item" @click:Transmit="onClickTransmit" @click:onDown="onClickDown"
:dict="{ D_BZ_GRRWZT }"></SwiperCell>
</div>
</van-list>
<van-loading style="text-align: center" v-if="listLoading">加载中...</van-loading>
<van-empty description="暂无任务信息" v-if="showEmpty" />
</van-pull-refresh>
<div style="height: 15.8666vw"></div>
<!-- 转发人数据 -->
<van-popup v-model:show="showfzrPicker" position="bottom">
<van-search v-model="list.phone" placeholder="请输入电话号码" @update:model-value="getLdList()" />
<van-picker :columns="list.fzrList" @confirm="onfzrConfirm" @cancel="showfzrPicker = false"
:columns-field-names="customfzrFieldNamed" />
</van-popup>
</div>
</template>
<script>
export default {
name: "rwlist",
};
</script>
<script setup>
import { ref, onMounted, reactive, watch } from "vue";
import SxPopup from "../../components/SxPopup.vue";
import SwiperCell from "../../components/swiperCell.vue";
import Tabs from "../../components/tabs.vue";
import BottomTabs from "../../components/bottomTabs.vue";
import TopNav from "../../components/topNav.vue";
import { getRwList, getTjRw, isMyTask } from "../../api/rwzx.js";
import router from "../../router/index.js";
import { sysUser } from "../../api/patrolBasicInfo.js";
import { Dialog } from "vant";
import { setTimeQuantum, hintToast } from "../../utils/tools";
import Search from "../../components/search.vue";
import { transmitTask } from "../../api/yyzxApi.js";
import { getDictList, setDict } from "../../utils/dict";
import { useRoute, onBeforeRouteLeave } from "vue-router";
import store from "../../store";
const { D_BZ_GRRWZT, D_BZ_RWJXZT, D_BZ_RWJSDX, D_BZ_RWXL } = getDictList(
"D_BZ_GRRWZT",
"D_BZ_RWJXZT",
"D_BZ_RWJSDX",
"D_BZ_RWXL"
); //字典信息
const showfzrPicker = ref(false); //是否显示转发人弹窗
const showPopup = ref(false);
const tabsIndex = ref(1);
//搜索配置
const queryData = reactive({
sxList: [
{
title: "任务接收对象",
isCheckBox: true,
array: [],
},
{
title: "任务细类",
isCheckBox: true,
array: [],
},
setTimeQuantum(),
],
});
watch(
() => D_BZ_RWJSDX.value,
() => {
queryData.sxList[0].array = D_BZ_RWJSDX.value.map((item) => {
return {
name: item.text,
key: item.value,
isCheck: false,
};
});
},
{ deep: true }
);
watch(
() => D_BZ_RWXL.value,
() => {
queryData.sxList[1].array = D_BZ_RWXL.value.map((item) => {
return {
name: item.text,
key: item.value,
isCheck: false,
};
});
},
{ deep: true }
);
const list = reactive({
phone: "", //转发人手机号
fzrList: [], //转发人数据
});
//指定picker选择器字段
const customfzrFieldNamed = {
text: "userName",
};
const themeType = ref(getStorage("themeSetting"));
const tabs = ref([
{
name: "全部",
count: 0,
value: "all",
},
]);
// watch()
watch(
() => D_BZ_RWJXZT.value,
() => {
tabs.value.push(
...D_BZ_RWJXZT.value.map((item) => {
return {
name: item.text,
count: 0,
value: item.value,
};
})
);
_getMyTaskTotal();
},
{ deep: true }
);
const active = ref(1);
const kwd = ref(""); //搜索关键字
const pageSize = ref(10);
const pageCurrent = ref(1);
const userInfo = JSON.parse(window.localStorage.getItem("userInfo"));
const rwObj = reactive({
rwList: [], //任务数据
rwTotal: {}, //任务统计
});
const rwjxzt = ref(""); //查询类型
const listLoading = ref(false);
const loadingPull = ref(false);
const finished = ref(false);
const total = ref(0);
const rwId = ref(""); //操作的任务ID
const showEmpty = ref(false);
//搜索框背景颜色
const searchBack = ref({});
onMounted(() => {
_getMyTaskList();
_getMyTaskTotal();
getLdList();
});
//下拉刷新
function onRefresh() {
tabsIndex.value++;
rwObj.rwList = [];
pageCurrent.value = 1;
kwd.value = "";
// rwjxzt.value = "";
finished.value = false;
_getMyTaskList();
_getMyTaskTotal();
}
//判断任务是暂停和关闭
function _setRwNotify(rwzt) {
if (rwzt == 1) {
hintToast("任务已关闭!!!");
return false;
}
if (rwzt == 2) {
hintToast("任务已暂停!!!");
return false;
}
return true;
}
//点击转发按钮打开人员选择器
function onClickTransmit(val) {
if (!_setRwNotify(val.rwzt)) {
return;
}
rwId.value = val.id;
showfzrPicker.value = true;
}
//驳回任务
function onClickDown(val) {
if (!_setRwNotify(val.rwzt)) {
return;
}
Dialog.confirm({
title: "提示",
message: "是否确认驳回该条任务信息!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
_setTransmitTask(rwId.value, 4);
});
}
//确认转发任务
function onfzrConfirm(val) {
Dialog.confirm({
title: "提示",
message: "是否确认转发任务!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
_setTransmitTask(rwId.value, 3, val.id);
});
}
/**
* 设置任务状态
* @export
* @param {*} rwid
* @param {*} rwzt 1 进行中 2 已完成 3 已转发 4 已驳回
* @param {*} zfjsrid 转发人ID
*/
function _setTransmitTask(rwid, rwzt, zfjsrid) {
let data = { rwid, rwzt, zfjsrid };
try {
let location = JSON.parse(bridge.getLocation());
data.jd = location.app_x;
data.wd = location.app_y;
} catch (error) { }
transmitTask(data).then((res) => {
showfzrPicker.value = false;
if (rwzt != 1) {
hintToast("成功");
}
_getMyTaskList();
});
}
// 查询转发人数据
function getLdList() {
sysUser({
current: 1,
size: 50,
phone: list.phone,
}).then((res) => {
list.fzrList = res.records;
});
}
//查看任务详情
function onLookRw(id, rwxl, rwlx, ywid, rwzt) {
isMyTask(id).then((res) => {
if (res) {
if (!_setRwNotify(rwzt)) {
return;
}
//通知任务
if (rwlx == 1) {
router.push(`/rw/views/rwDetail?id=${id}`);
return;
}
//值班任务
if (rwxl == "04") {
router.push("/yyzx/views/addZbbb");
return;
}
//巡防任务
if (rwxl == "03") {
router.push("/yyzx/xfbb/addXfbb");
return;
}
//指令任务
if (rwxl == "05") {
router.push(`/yyzx/zlzx/zlDetail?id=${ywid}`);
return;
}
} else {
hintToast("只能查看本人任务");
}
});
}
function onConfirm(val) {
rwObj.rwList = [];
pageCurrent.value = 1;
queryRw.kssj = val.startTime;
queryRw.jssj = val.endTime;
queryRw.rwxl = val.list[1].array
.filter((item) => item.isCheck)
.map((item) => item.key)
.join(",");
queryRw.rwjsdx = val.list[0].array
.filter((item) => item.isCheck)
.map((item) => item.key)
.join(",");
_getMyTaskList();
_getMyTaskTotal();
showPopup.value = false;
}
//关键字搜索
function onClickSearch(e) {
rwObj.rwList = [];
pageCurrent.value = 1;
_getMyTaskList();
}
//按类型查询
function onSelect(val) {
rwObj.rwList = [];
pageCurrent.value = 1;
switch (val) {
case 0:
rwjxzt.value = "";
break;
default:
rwjxzt.value = tabs.value[val].value;
break;
}
finished.value = false;
_getMyTaskList();
}
//获取任务统计
function _getMyTaskTotal() {
// const queryRw
getTjRw(queryRw).then((res) => {
tabs.value[0].count = 0;
if (res) {
tabs.value.forEach((v) => {
const tjarr = res.filter((item) => item.rwjxzt === v.value);
if (tjarr.length > 0) {
v.count = tjarr[0].count;
} else {
v.count = 0;
}
});
res.forEach((e) => {
tabs.value[0].count += e.count;
});
}
});
}
//触底加载
function onLoad() {
if (pageCurrent.value >= total.value) {
finished.value = true;
return;
}
pageCurrent.value += 1;
_getMyTaskList();
}
const queryRw = reactive({
rwjsdx: "",
rwxl: "",
kssj: "",
jssj: "",
});
//获取任务列表
function _getMyTaskList() {
listLoading.value = true;
showEmpty.value = false;
let data = {
pageSize: pageSize.value,
pageCurrent: pageCurrent.value,
jsrsfzh: userInfo.idEntityCard,
rwnr: kwd.value,
rwjxzt: rwjxzt.value,
rwjsdx: queryRw.rwjsdx,
rwxl: queryRw.rwxl,
kssj: queryRw.kssj,
jssj: queryRw.jssj,
};
getRwList(data)
.then((res) => {
total.value = res.pages;
listLoading.value = false;
loadingPull.value = false;
if (res.records.length > 0) {
res.records.forEach((item) => {
rwObj.rwList.push(item);
});
} else {
showEmpty.value = true;
}
})
.catch((err) => {
listLoading.value = false;
showEmpty.value = true;
});
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.rw_list_box {
padding: 3vw 0;
margin: 0 3vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
@include item_bottom_color($bottom-border-top-clore-theme);
}
</style>

View File

@ -0,0 +1,304 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="任务详情" :showRight="false" :showLeft="true" />
<div class="detail_box" v-if="reDetail">
<div class="item">
<span class="label">名称</span>
<span class="text">{{ reDetail.rwmc }}</span>
</div>
<div class="item">
<span class="label">内容</span>
<span class="text">{{ reDetail.rwnr }}</span>
</div>
<!-- <div class="item">
<span class="label">链接</span>
<span class="text">{{ reDetail.rwlj }}</span>
</div> -->
<div class="item">
<span class="label">状态</span>
<span class="text" :class="{
green: reDetail.rwzt == 0,
yellow: reDetail.rwzt == 1 || reDetail.rwzt == 2,
}">{{ setDict(reDetail.rwzt, D_BZ_RWZT) }}</span>
</div>
<!-- <div class="item">
<span class="label">执行人员数</span>
<span class="text">{{ reDetail.rwzxrysl }}</span>
</div> -->
<div class="item">
<span class="label">发起人</span>
<span class="text">{{ reDetail.cjrxm }}{{ reDetail.cjrlxdh }}</span>
</div>
<div class="item">
<span class="label">紧急程度</span>
<span class="text">{{ setDict(reDetail.rwjjcd, D_BZ_RWJJCD) }}</span>
</div>
<div class="item">
<span class="label">任务细类</span>
<span class="text">{{ setDict(reDetail.rwxl, D_BZ_RWXL) }}</span>
</div>
<div class="item">
<span class="label">进行状态</span>
<span class="text" :class="{
bule: reDetail.rwjxzt == 1,
yellow: reDetail.rwjxzt == 4,
green: reDetail.rwjxzt == 3,
red: reDetail.rwjxzt == 2,
}">{{ setDict(reDetail.rwjxzt, D_BZ_RWJXZT) }}</span>
</div>
<div class="item">
<span class="label">发起时间</span>
<span class="text">{{ reDetail.rwfqsj }}</span>
</div>
<div class="item">
<span class="label">要求完成时间</span>
<span class="text">{{ reDetail.rwyqwcsj }}</span>
</div>
<div class="item">
<span class="label">个人执行状态</span>
<span class="text">{{ setDict(userRwzt, D_BZ_GRRWZT) }}</span>
</div>
<div class="item" v-if="reDetail.rwwcsj">
<span class="label">完成时间</span>
<span class="text">{{ reDetail.rwwcsj }}</span>
</div>
<div class="item" style="border: none" v-if="reDetail.fjid">
<span class="label">附件</span>
<div>
<div class="fj_item" v-for="(item, index) in fjList" :key="index + 'file'">
<van-image width="120px" height="120px" fit="cover" :src="baseUrl + reDetail.fjid.split(',')[index]"
@click="onClickImg(baseUrl + reDetail.fjid.split(',')[index])" v-if="item && item.fileFormat == 'png'">
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
<a :href="baseUrl + reDetail.fjid.split(',')[index]" style="text-decoration: underline" v-else>{{ item.name
}}</a>
</div>
</div>
</div>
<!-- 通知任务 -->
<div v-if="
reDetail.rwlx == 1 &&
reDetail.rwjxzt !== '3' &&
reDetail.rwjxzt !== '4'
" class="btn_box">
<van-button :loading="loading" round block type="success" style="margin: 0 2vw" @click="onConfirm">
确认
</van-button>
</div>
</div>
<van-loading type="spinner" style="padding-top: 50vw; text-align: center" v-if="loading" />
<van-empty v-if="showEmpty" description="错误" image="error" />
</div>
</template>
<script setup>
import axios from "axios";
import { ref, onMounted, reactive } from "vue";
import TopNav from "../../../components/topNav.vue";
import { getMyTaskDetail, getFjInfo } from "../../../api/rwzx.js";
import { getDictList, setDict } from "../../../utils/dict";
import { baseUrl2 } from "../../../utils/request.js";
import { Dialog, ImagePreview } from "vant";
import { transmitTask } from "../../../api/yyzxApi.js";
import router from "../../../router/index.js";
import { IS_PNG, hintToast } from "../../../utils/tools.js";
const {
D_BZ_RWXL,
D_BZ_RWJJCD,
D_BZ_RWJXZT,
D_BZ_RWZT,
D_BZ_GRRWZT,
} = getDictList(
"D_BZ_RWXL",
"D_BZ_RWJJCD",
"D_BZ_RWJXZT",
"D_BZ_RWZT",
"D_BZ_GRRWZT"
); //字典信息
import { useRoute } from "vue-router";
import { format } from "echarts";
const id = ref("");
const reDetail = ref(null); //任务详情数据
const loading = ref(true);
const showEmpty = ref(false);
const showImage = ref(false); //是否预览图片
const userRwzflx = ref(""); //用户任务类型
const userRwzt = ref(""); //个人任务状态
const baseUrl = `${baseUrl2}/mosty-api/mosty-base/minio/image/download/`;
const list = reactive({
phone: "", //转发人手机号
fzrList: [], //转发人数据
});
const rwId = ref("");
onMounted(() => {
rwId.value = useRoute().query.id;
_getMyTaskDetail();
});
//预览图片
function onClickImg(url) {
ImagePreview([url]);
}
//处置任务下一步
function onNext() {
if (reDetail.value.rwxl == "04") {
router.push("/yyzx/views/addZbbb");
} else if (reDetail.value.rwxl == "03") {
router.push("/yyzx/xfbb/addXfbb");
}
}
//确认任务
function onConfirm() {
Dialog.confirm({
title: "提示",
message: "是否知晓任务信息!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
_setTransmitTask(reDetail.value.id, 2);
});
}
/**
* 设置任务状态
* @export
* @param {*} rwid
* @param {*} rwzt 1 进行中 2 已完成 3 已转发 4 已驳回
* @param {*} zfjsrid 转发人ID
*/
function _setTransmitTask(rwid, rwzt, zfjsrid) {
let data = {
rwid,
rwzt,
zfjsrid,
};
try {
let location = JSON.parse(bridge.getLocation());
data.jd = location.app_x;
data.wd = location.app_y;
} catch (error) { }
transmitTask(data).then((res) => {
if (rwzt != 1) {
hintToast("成功")
}
// _getMyTaskDetail();
router.go(-1);
});
}
//获取任务详情
function _getMyTaskDetail() {
getMyTaskDetail(rwId.value)
.then((res) => {
loading.value = false;
reDetail.value = res;
if (res.fjid) {
_getFile(res.fjid);
_getUserRwzflx();
}
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
/**
*
* @param {Object} fjid
*/
const fjList = ref([]);
function _getFile(fjid) {
const requestArr = fjid.split(",").map((item) => {
return getFjInfo(item);
});
Promise.all(requestArr).then((resArr) => {
resArr.forEach((res) => {
if (IS_PNG(res.suffix.substring(1, res.suffix.length))) {
res.fileFormat = "png";
} else {
res.fileFormat = "file";
}
fjList.value.push(res);
});
});
}
//获取用户任务转发类型
function _getUserRwzflx() {
if (reDetail.value && reDetail.value.userDtoList.length > 0) {
let info = reDetail.value.userDtoList[0];
userRwzflx.value = info.rwzflx;
userRwzt.value = info.rwzt;
//如果是待查看 改为进行中
// if (userRwzt.value == 0) _setTransmitTask(reDetail.value.id, 1);
}
// let userInfo = JSON.parse(getStorage("userInfo"));
// switch (reDetail.value.rwjsdx) {
// case "01":
// if (reDetail.value && reDetail.value.userDtoList.length > 0) {
// let info = reDetail.value.userDtoList.find((item) => {
// return userInfo.idEntityCard == item.jsrsfzh;
// });
// userRwzflx.value = info.rwzflx;
// userRwzt.value = info.rwzt;
// //如果是待查看 改为进行中
// // if (userRwzt.value == 0) _setTransmitTask(reDetail.value.id, 1);
// }
// break;
// case "02":
// if (reDetail.value && reDetail.value.userDtoList.length > 0) {
// let info = reDetail.value.userDtoList.find((item) => {
// return userInfo.deptList[0].deptId == item.jsbmdm;
// });
// userRwzflx.value = info.rwzflx;
// userRwzt.value = info.rwzt;
// //如果是待查看 改为进行中
// // if (userRwzt.value == 0) _setTransmitTask(reDetail.value.id, 1);
// }
// break;
// case "03":
// break;
// }
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.detail_box {
padding: 3vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.item {
display: flex;
justify-content: space-between;
padding: 3vw 0;
@include item_bottom_color($bottom-border-top-clore-theme);
.label {
width: 25%;
}
.text {
width: 70%;
text-align: right;
}
}
}
.fj_item {
padding: 8px 0;
}
.btn_box {
display: flex;
justify-content: space-between;
margin-top: 5vw;
}
</style>

View File

@ -0,0 +1,441 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav :navTitle="'人口核实详情'" />
<van-form @submit="onSubmit">
<div class="title_tab">基本信息</div>
<van-field
v-model="normalForm.gmsfhm"
label="身份证号"
placeholder="请输入身份证号"
input-align="right"
/>
<van-field
v-model="normalForm.xm"
label="姓名"
placeholder="请输入姓名"
input-align="right"
/>
<div class="title_tab">核实信息</div>
<van-field
v-model="normalForm.reason"
label="任务类型"
placeholder="请输入任务类型"
input-align="right"
/>
<van-field
v-model="normalForm.createdAt"
label="生成时间"
placeholder="请输入生成时间"
input-align="right"
/>
<van-cell-group>
<van-cell clickable title="处理结果" :border="false">
<template #right-icon>
<van-radio-group v-model="cljgRadio" direction="horizontal">
<van-radio name="1">属实</van-radio>
<van-radio name="9">不属实</van-radio>
</van-radio-group>
</template>
</van-cell>
</van-cell-group>
<van-field
v-model="normalForm.jzxqmc"
label="所属小区"
placeholder="请输入所属小区"
input-align="right"
v-if="cljgRadio == 1"
/>
<van-field
v-model="normalForm.dzmc"
@click="popupShow = true"
label="小区地址"
type="textarea"
placeholder="请输入小区地址"
input-align="right"
v-if="cljgRadio == 1"
/>
<van-cell-group v-if="cljgRadio == 9">
<van-cell clickable title="识别情况" :border="false">
<template #right-icon>
<van-radio-group v-model="rysfsbqkRadio" direction="horizontal">
<van-radio name="1">准确</van-radio>
<van-radio name="5">错误</van-radio>
<van-radio name="9">不确定</van-radio>
</van-radio-group>
</template>
</van-cell>
</van-cell-group>
<van-field
rows="3"
type="textarea"
v-model="normalForm.clbz"
placeholder="处理说明"
/>
<div class="title_tab">
<s></s>
<span>通行轨迹({{ txTotal }})</span>
<span class="all" @click="routerPush(normalForm.gmsfhm)"
>更多
<van-icon name="arrow"></van-icon>
</span>
</div>
<div class="txgj_box">
<div
class="item_img_box"
v-for="(item, index) in txgjList"
:key="item.id"
>
<van-image
width="100%"
height="30vw"
:src="item.baseUrl"
style="flex: 1"
@click.stop="onClickImg(item.ryPhoto, index)"
>
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
<div class="time">{{ item.djsj }}</div>
<div
class="jcFlag"
:class="{
bg_green: item.inOut === 'in',
bg_orange: item === 'out',
}"
>
{{ item.inOut === "out" ? "出" : "进" }}
</div>
</div>
</div>
<div style="margin: 16px 0; padding: 0 5vw">
<van-button
:loading="loading"
round
native-type="submit"
block
type="primary"
>
提交
</van-button>
</div>
</van-form>
<van-popup
v-model:show="popupShow"
round
position="center"
style="width: 90%"
>
<van-cascader
active-color="#1989fa"
v-model="list.check"
title="选择具体地址"
:options="list.ldList"
@close="popupShow = false"
@change="onCascaderChange"
@finish="onFinish"
></van-cascader>
</van-popup>
</div>
</template>
<script setup>
import { getBase64 } from "../../../utils/tools.js";
import TopNav from "../../../components/topNav.vue";
import { Dialog, Toast } from "vant";
import {
dateFormat,
ymGetRequest,
ymPostRequest,
getYmToken,
hintToast,
} from "../../../utils/tools.js";
import { computed, ref, reactive, onMounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import { ImagePreview } from "vant";
import router from "../../../router";
function _getBase64(item) {
getBase64((res) => {
item.baseUrl = res;
}, item.ryPhoto);
}
const cljgRadio = ref("1");
const rysfsbqkRadio = ref("5"); // 人员身份识别情况
const popupShow = ref(false);
const cascaderValue = ref(""); //级联默认值
const copyToken = ref("");
const list = reactive({
ldList: [], //楼栋数据
check: "",
});
//通行轨迹数据
const txgjList = ref([]);
//表单数据
const normalForm = ref({
gmsfhm: "",
xm: "",
jzxqmc: "",
dzmc: "",
zzzhz: "",
createdAt: "",
clbz: "",
reason: "",
cljg: "",
});
//不属实 置空
watch(
() => cljgRadio.value,
(newValue) => {
if (newValue == 9) normalForm.value.clbz = "";
}
);
//选择数据
onMounted(() => {
let userCrd = JSON.parse(window.localStorage.getItem("userInfo"))
.idEntityCard;
let rwid = useRoute().query.id;
getYmToken(
{
userid: userCrd,
code: "GxGA510109",
},
(res) => {
copyToken.value = res.data.token;
_getData(res.data.token, "001d902c4aee42cd89f0dc3fa470abb7");
}
);
});
//获取任务数据数据
function _getData(token, id) {
ymGetRequest(`/person/taskDetail`, { id }, token, (res) => {
normalForm.value = res.data;
normalForm.value.clbz = "核实为实有人口";
_getLdData(res.data.jzxqid, token);
getRytxList(res.data.gmsfhm);
});
}
//获取楼栋数据
function _getLdData(placeId, token) {
ymGetRequest(`/place/placeBuild`, { placeId }, token, (res) => {
if (res.data.length > 0) {
for (let i = 0; i < res.data.lengt; i++) {
res.data[i].text = res.data[i].dzmc;
res.data[i].value = res.data[i].parentid;
res.data[i].children = [];
}
list.ldList = res.data.map((item) => {
return {
text: item.dzmc,
value: item.id,
children: [],
};
});
}
});
}
//单元 楼栋 房号数据
function onCascaderChange(value) {
if (value.tabIndex === 0) {
const index = list.ldList.map((item) => item.value).indexOf(value.value);
ymGetRequest(
`/place/placeBzdz`,
{ parentId: value.value },
copyToken.value,
(res) => {
list.ldList[index].children = res.data.map((item) => {
return {
text: item.dzjc,
value: item.id,
};
});
}
);
}
}
//人员通行列表
const txTotal = ref(0);
function getRytxList(gmsfhm) {
ymPostRequest(
"/person/record_list",
{ gmsfhm, page: 1, psize: 3 },
copyToken.value,
(res) => {
txgjList.value = res.data.content;
txgjList.value.map((item) => {
_getBase64(item);
});
txTotal.value = res.data.totalElements;
}
);
}
function onFinish({ selectedOptions }) {
popupShow.value = false;
normalForm.value.dzmc = selectedOptions.map((option) => option.text).join("");
normalForm.value.dzid = selectedOptions[selectedOptions.length - 1].value;
}
function onClickImg(url, index) {
ImagePreview({
images: txgjList.value.map((item) => item.baseUrl),
startPosition: index,
});
}
function routerPush(sfzh) {
router.push({
path: "/rw/views/txgj",
query: {
sfzh: sfzh,
token: copyToken.value,
},
});
}
function onSubmit() {
const data = {
addWhiteList: 0,
clbz: normalForm.value.clbz,
cljg: normalForm.value.cljg,
cljgfk: 0,
dzid: normalForm.value.dzid,
id: normalForm.value.id,
whiteRemark: "",
whiteTime: "",
};
ymPostRequest("/person/taskHandle", { ...data }, copyToken.value, (res) => {
if (res.status === 200) {
hintToast("处理成功");
router.go(-1);
} else {
hintToast(res.message);
}
});
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.container {
margin-top: 2vw;
}
.nav_tab {
padding: 2vw;
display: flex;
justify-content: space-around;
.tab {
background: #a4aec8;
color: #fff;
height: 32px;
line-height: 32px;
width: 40vw;
text-align: center;
border-radius: 16px 16px 16px 0;
}
.tab.active {
background: #517cea;
}
}
.popupTitle {
text-align: center;
background-color: rgb(11, 137, 247);
height: 6vh;
line-height: 6vh;
}
.popbtn-box {
width: 100%;
display: flex;
justify-content: space-around;
}
.check-item-tag {
display: inline-block;
margin: 0 6px;
}
.check-data-box {
height: 25vh;
overflow: auto;
}
.time-box {
display: flex;
}
::v-deep .mulSelect .van-cell__title,
.van-cell__value {
flex: unset;
}
::v-deep .mulSelect .van-cell__value {
flex: 1;
}
.title_tab {
@include font_color($font-color-theme);
padding: 0 3vw 0 7vw;
position: relative;
margin: 2vw 0;
letter-spacing: 2px;
display: flex;
justify-content: space-between;
align-items: center;
.all {
@include font_size($font_medium_s);
}
}
.title_tab::after {
content: "";
position: absolute;
top: 0;
left: 5vw;
bottom: 0;
width: 4px;
background: #3b6be7;
border-radius: 2px;
}
.van-cell:after {
display: none;
}
.van-cell {
@include table_item_color($table-item-theme);
box-sizing: border-box;
border-radius: 4px;
padding: 6px;
margin: 8px 4%;
width: 92%;
overflow: hidden;
color: var(--van-cell-text-color);
font-size: var(--van-cell-font-size);
line-height: var(--van-cell-line-height);
}
.popupTitle {
color: #fff;
}
.txgj_box {
display: flex;
padding: 0 4.5%;
justify-content: space-between;
flex-wrap: wrap;
}
.item_img_box {
// border: 1px solid red;
position: relative;
width: 31%;
.time {
font-size: 11px;
// @include font_size($font_medium_s);
}
.jcFlag {
position: absolute;
top: 0;
right: 0;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
@include font_size($font_medium_s);
padding: 1vw;
}
}
</style>

View File

@ -0,0 +1,129 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav :navTitle="'通行轨迹'" :showLeft="true" />
<van-list
:finished="finished"
finished-text="没有更多数据了"
@load="onLoad"
offset="1"
:immediate-check="false"
>
<div class="txgj_box">
<div class="item_img_box" v-for="(item, index) in list" :key="item.id">
<van-image
width="100%"
height="30vw"
:src="item.baseUrl"
style="flex: 1"
@click.stop="onClickImg(item.ryPhoto, index)"
>
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
<div class="time">{{ item.djsj }}</div>
<div
class="jcFlag"
:class="{
bg_green: item.inOut === 'in',
bg_orange: item === 'out',
}"
>
{{ item.inOut === "out" ? "出" : "进" }}
</div>
</div>
</div>
</van-list>
</div>
</template>
<script setup>
import { onMounted, ref } from "vue";
import { getBase64 } from "../../../utils/tools.js";
import TopNav from "../../../components/topNav.vue";
import { ImagePreview } from "vant";
import { ymPostRequest } from "../../../utils/tools.js";
import { useRoute } from "vue-router";
const route = useRoute();
const list = ref([]);
const finished = ref(false);
const queryList = ref({
page: 1,
psize: 10,
gmsfhm: route.query.sfzh,
});
function _getBase64(item) {
getBase64((res) => {
item.baseUrl = res;
}, item.ryPhoto);
}
const total = ref(0);
const getList = () => {
ymPostRequest(
"/person/record_list",
{ ...queryList.value },
route.query.token,
(res) => {
if (queryList.value.page === 1) {
list.value = res.data.content;
list.value.map((item) => {
_getBase64(item);
});
} else {
res.data.content.map(item=>{
_getBase64(item);
list.value.push(item)
})
}
total.value = res.data.totalElements;
}
);
};
function onLoad() {
if (list.value.length === total.value) {
finished.value = true;
} else {
queryList.value.page++;
getList();
}
}
function onClickImg(url, index) {
ImagePreview({
images: list.value.map((item) => item.baseUrl),
startPosition: index,
});
}
onMounted(() => {
getList();
});
</script>
<style lang='scss' scoped>
@import "../../../assets/styles/mixin.scss";
.txgj_box {
display: flex;
padding: 16px 4.5% 0;
justify-content: space-between;
flex-wrap: wrap;
}
.item_img_box {
// border: 1px solid red;
position: relative;
width: 48%;
.time {
font-size: 11px;
// @include font_size($font_medium_s);
}
.jcFlag {
position: absolute;
top: 0;
right: 0;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
@include font_size($font_medium_s);
padding: 1vw;
}
}
</style>

108
src/pages/scyy/cl.vue Normal file
View File

@ -0,0 +1,108 @@
<template>
<div class="container" style="padding-top:13vw">
<TopNav navTitle="车辆" />
<div class="search-boxSJY">
<van-search v-model="clList.cph" placeholder="请输入车牌号" style="width: 100%" @update:model-value="getList(1)" />
</div>
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<div class="item-box jwz-line" v-for="(item, index) in clList.list" :key="index">
<div class="ps-title">{{ item.cph }}</div>
<div class="lineSJY">所属部门: {{ item.ssbm }}</div>
<div class="lineSJY">
车辆状态: {{ item.zbzt == "1" ? "正常" : "非正常" }}
</div>
<div class="lineSJY">
<div class="first-one">车牌号: {{ item.cph }}</div>
<div class="first-one">车辆年款: {{ item.clnk }}</div>
</div>
<div class="lineSJY">
<div style="display: flex; width: 50%">
号牌种类:{{ setDict(item.cllx, D_BZ_CLLX) }}
</div>
<div style="display: flex; width: 50%">
车辆品牌{{ item.clpp }}
</div>
</div>
<div class="lineSJY">
<div class="first-one">购置日期: {{ item.gmrq }}</div>
<div class="first-one">报废日期: {{ item.bfrq }}</div>
</div>
</div>
</van-list>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import { getClList } from "../../api/scyy.js";
import { ref, reactive, onMounted } from "vue";
import { getDictList, setDict } from "../../utils/dict";
import { useRouter } from "vue-router";
const router = useRouter();
function onClickLeft() {
router.push("/home");
}
const { D_BZ_CLLX } = getDictList("D_BZ_CLLX");
const clList = reactive({
list: [],
cph: "",
});
onMounted(() => {
getList();
});
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const total = ref(0);
function getList(val) {
loading.value = false;
if (val === 1) {
page.value = 1
}
getClList({
pageCurrent: page.value,
pageSize: 10,
cph: clList.cph,
})
.then((res) => {
if (val === 1) {
clList.list = res.records;
} else {
res.records.forEach((ele) => {
clList.list.push(ele);
});
}
total.value = res.total;
onLoad();
finished.value = true;
})
.catch((err) => {
finished.value = true;
});
}
function onLoad() {
if (page.value * 10 < total.value) {
page.value++;
getList();
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.item-box {
line-height: 1.8em;
margin: 0 5vw;
border-bottom: 1px solid #f3f3f3;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
.ps-title {
color: #1F6CEC;
font-weight: bold;
@include font_size($font_medium);
line-height: 6vw;
}
</style>

119
src/pages/scyy/jwz.vue Normal file
View File

@ -0,0 +1,119 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="警务站" />
<div class="search-box">
<van-search v-model="jwzList.jwzMc" placeholder="请输入警务站名称" style="width: 100%" @update:model-value="getList(1)" />
</div>
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<div class="listInfoBox">
<List :labelData="jwzList.list">
<template v-slot="{ item }">
<div class="ps-title">{{ item.jwzMc }}</div>
<div class="line">
警务站类型{{ setDict(item.jwzLx, D_BZ_JWZLX) }}
</div>
<div class="line"><van-icon name="location-o" /> 详细地址: {{ item.jwzDz }}</div>
<div class="line"><van-icon name="underway-o" /> 建立日期: {{ item.xjSj }}</div>
<div class="line">
<van-icon name="user-o" /> 负责人:
{{ item.fzrXm }}&nbsp;&nbsp;&nbsp;{{ item.ssbm }}
</div>
<div class="lineGap"></div>
</template>
</List>
</div>
</van-list>
</div>
</template>
<script setup>
import List from "../../components/ListItem.vue";
import TopNav from "../../components/topNav.vue";
import { getJwzList } from "../../api/scyy.js";
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { getDictList, setDict } from "../../utils/dict";
const router = useRouter();
function onClickLeft() {
router.push("/home");
}
const { D_BZ_JWZLX } = getDictList("D_BZ_JWZLX");
const jwzList = reactive({
list: [],
jwzMc: "",
});
function goCreatePoliceStation() {
router.push("/createPoliceStation");
}
onMounted(() => {
getList();
});
// 查询警务站列表
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const total = ref(0);
function getList(val) {
loading.value = false;
getJwzList({
pageNo: page.value,
pageSize: 10,
jwzMc: jwzList.jwzMc,
})
.then((res) => {
if (val === 1) {
jwzList.list = res.records;
} else {
res.records.forEach((ele) => {
jwzList.list.push(ele);
});
}
total.value = res.total;
onLoad();
finished.value = true;
})
.catch((err) => {
finished.value = true;
});
}
function onLoad() {
if (page.value * 10 < total.value) {
page.value++;
getList();
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.search-box {
display: flex;
align-items: center;
}
// 列表
.listInfoBox {
@include font_size($font_medium_s);
padding: 0 4vw;
box-sizing: border-box;
.ps-title {
color: #1f6cec;
font-weight: bold;
line-height: 6vw;
@include font_size($font_medium);
}
.line {
line-height: 5vw;
}
.lineGap {
height: 4px;
border-bottom: 1px solid #e9e9e9;
}
}
</style>

83
src/pages/scyy/kfd.vue Normal file
View File

@ -0,0 +1,83 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="快反点" />
<van-search v-model="kfdList.kfdMc" placeholder="请输入快反点名称" @update:model-value="serachData" />
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<div class="item-box" v-for="(item, index) in kfdList.list" :key="index">
<div class="titleSJY">{{ item.kfdMc }}</div>
<!-- <div><van-icon name="underway-o" /> 建立日期: {{ item.xtCjsj }}</div> -->
<div><van-icon name="user-o" /> 市所属部门: {{ item.ssbm }}</div>
<div><van-icon name="location-o" /> 地址: {{ item.kfdDz }}</div>
</div>
</van-list>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import { getKfdList } from "../../api/scyy.js";
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const kfdList = reactive({
list: [],
kfdMc: "",
});
onMounted(() => {
serachData();
});
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const total = ref(0);
function serachData() {
page.value = 1
getList()
}
function getList() {
loading.value = false;
let params = {
pageNum: page.value,
pageSize: 10,
kfdMc: kfdList.kfdMc,
};
getKfdList(params)
.then((res) => {
if (page.value === 1) {
kfdList.list = res.records;
} else {
kfdList.list = kfdList.list.concat(res.records);
}
total.value = res.total;
onLoad();
finished.value = true;
})
.catch((err) => {
finished.value = true;
});
}
function onLoad() {
if (page.value * 10 < total.value) {
page.value++;
getList();
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.item-box {
line-height: 1.8em;
margin: 0 5vw;
border-bottom: 1px solid #f3f3f3;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
.titleSJY {
color: #1f6cec;
font-weight: bold;
@include font_size($font_medium);
}
</style>

129
src/pages/scyy/xfll.vue Normal file
View File

@ -0,0 +1,129 @@
<template>
<div class="container" style="padding-top: 13vw">
<van-sticky :offset-top="0">
<TopNav navTitle="巡防力量" />
<div class="search-boxSJY">
<van-search v-model="xlllList.xm" placeholder="请输入搜索关键词" style="width: 100%" @update:model-value="getList(1)" />
</div>
</van-sticky>
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad"
:immediate-check="false">
<div class="item-boxxfll" :class="item.fl === '01' ? 'bgColorm' : 'bgColorf'"
v-for="(item, index) in xlllList.list" :key="index">
<div class="image-box">
<van-image fill="cover" :src="require('../../assets/images/tx.png')" />
</div>
<div class="xlll-info-box">
<div :class="item.fl === '01' ? 'title-box1' : 'title-box2'">
<div :class="item.fl === '01' ? 'line-y1' : 'line-y2'"></div>
<span>{{ item.xm }}</span>&nbsp;&nbsp;&nbsp;
<span>
<dict-tag :options="D_BZ_XB" :value="item.xbdm" :tag="false" /> </span>&nbsp;&nbsp;&nbsp;
<span>{{ item.fl === "01" ? "民警" : "辅警" }}</span>
</div>
<div>{{ item.sfzh }}</div>
<div>所在部门: {{ item.ssbm }}</div>
<div>警员编号: {{ item.jh }}</div>
<div>联系电话: {{ item.lxdh }}</div>
</div>
</div>
</van-list>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import { getXfllList } from "../../api/scyy.js";
import { ref, reactive, onMounted } from "vue";
import { useRouter } from "vue-router";
import { getDictList, setDict } from "../../utils/dict";
const { D_BZ_XB } = getDictList("D_BZ_XB");
const router = useRouter();
const xlllList = reactive({
list: [],
xm: "",
total: 0,
});
onMounted(() => {
getList(1);
});
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const total = ref(0);
function getList(val) {
loading.value = true;
getXfllList({
pageCurrent: page.value,
pageSize: 10,
xm: xlllList.xm,
})
.then((res) => {
total.value = res.total;
if (val === 1) {
xlllList.list = res.records;
} else {
res.records.forEach((ele) => {
xlllList.list.push(ele);
});
}
loading.value = false;
})
.catch((err) => {
finished.value = true;
});
}
function onLoad() {
if (page.value * 10 < total.value) {
page.value++;
getList();
} else {
finished.value = true;
}
}
// 添加民警
function goCreatePeoplePolice() {
router.push("/createMJ");
}
// 添加辅警
function goCreateAssistantPolice() {
router.push("/createFJ");
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.item-boxxfll {
line-height: 1.8em;
margin: 2vw;
padding: 2vw;
box-sizing: border-box;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
display: flex;
.image-box {
flex: 1;
margin: 2vw;
}
.xlll-info-box {
flex: 3;
}
}
.bgColorm {
background-color: #f0f6ff;
}
.bgColorf {
background-color: #f9eeff;
}
.titleSJY {
color: #1f6cec;
font-weight: bold;
@include font_size($font_medium);
}
</style>

85
src/pages/scyy/xfq.vue Normal file
View File

@ -0,0 +1,85 @@
<template>
<div class="container" style="padding-top:13vw">
<TopNav navTitle="巡防区" />
<van-search v-model="xfqList.xfqMc" placeholder="请输入巡防区名称" @update:model-value="getList(1)" />
<van-list v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
<div class="item-box" v-for="(item, index) in xfqList.list" :key="index">
<div class="titleSJY">{{ item.xfqMc }}</div>
<div>建立时间: {{ item.xtCjsj }}</div>
<div><van-icon name="user-o" /> 负责人: {{ item.xfqFzr }}</div>
<div>负责人身份证号{{ item.xfqFzrSfz }}</div>
<div>所属部门{{ item.ssbm }}</div>
<div class="line">巡防区等级:{{ setDict(item.xfqDj, D_BZ_XFQDJ) }}</div>
<div class="line">巡防区类型:{{ setDict(item.xfqLx, D_BZ_XQLX) }}</div>
</div>
</van-list>
</div>
</template>
<script setup>
import TopNav from "../../components/topNav.vue";
import { getXfqList } from "../../api/scyy.js";
import { ref, reactive, onMounted } from "vue";
import { getDictList, setDict } from "../../utils/dict";
import { useRouter } from "vue-router";
const router = useRouter();
const { D_BZ_XFQDJ, D_BZ_XQLX } = getDictList("D_BZ_XFQDJ", "D_BZ_XQLX");
const xfqList = reactive({
list: [],
xfqMc: "",
});
onMounted(() => {
getList();
});
const loading = ref(false);
const finished = ref(false);
const page = ref(1);
const total = ref(0);
function getList(val) {
loading.value = false;
getXfqList({
pageCurrent: page.value,
pageSize: 10,
xfqMc: xfqList.xfqMc,
})
.then((res) => {
if (val === 1) {
xfqList.list = res.records;
} else {
res.records.forEach((ele) => {
xfqList.list.push(ele);
});
}
total.value = res.total;
onLoad();
finished.value = true;
})
.catch((err) => {
finished.value = true;
});
}
function onLoad() {
if (page.value * 10 < total.value) {
page.value++;
getXfqList();
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.item-box {
line-height: 1.8em;
margin: 0 5vw;
border-bottom: 1px solid #f3f3f3;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
.titleSJY {
color: #1F6CEC;
font-weight: bold;
@include font_size($font_medium);
}
</style>

187
src/pages/scyy/zb.vue Normal file
View File

@ -0,0 +1,187 @@
<template>
<div class="container" style="padding-top:13vw">
<TopNav navTitle="装备" />
<van-tabs v-model:active="active" background="#fff" color="#1989fa">
<van-tab title="智能装备管理">
<div class="search-boxSJY">
<van-search v-model="zbList.sbmc" placeholder="请输入智能装备名称" style="width: 100%"
@update:model-value="getList(1)" />
</div>
<van-list v-model:loading="loading1" :finished="finished1" finished-text="没有更多了" @load="onLoad1">
<div class="item-box" v-for="(item, index) in zbList.list" :key="index">
<div class="titleSJY">{{ item.sbmc }}</div>
<div class="lineSJY">所属部门: {{ item.ssbm }}</div>
<div class="lineSJY">
<div class="first-one">装备型号: {{ item.xh }}</div>
<div style="display: flex">
装备类型:&nbsp;<dict-tag :options="D_BZ_ZNZBFL" :value="item.scode" :tag="false" />
</div>
</div>
<div class="lineSJY">
<div>生产厂商: {{ item.sccs }}</div>
</div>
<div class="lineSJY">
<div class="first-one">采购日期: {{ item.cgrq }}</div>
<div>到期时间: {{ item.dqsj }}</div>
</div>
</div>
</van-list>
</van-tab>
<van-tab title="警用器械管理">
<div class="search-boxSJY">
<van-search v-model="zbList.qxMc" placeholder="请输入警用器械名称" style="width: 100%"
@update:model-value="getJyqxList(1)" />
</div>
<van-list v-model:loading="loading2" :finished="finished2" finished-text="没有更多了" @load="onLoad2">
<div class="item-box" v-for="(item, index) in zbList.jyqxList" :key="index">
<div class="titleSJY">
<div class="line-y"></div>
&nbsp;&nbsp;{{ item.qxMc }}
</div>
<div class="lineSJY">
<div class="first-one">器械编码: {{ item.qxbh }}</div>
<div>器械名称: {{ item.qxMc }}</div>
</div>
<div class="lineSJY">
<div class="first-one">
器械类型:&nbsp;<dict-tag :options="D_BZ_JYQXFL" :value="item.scode" :tag="false" />
</div>
<div>生产厂商: {{ item.sccs }}</div>
</div>
<div class="lineSJY">
<div class="first-one">采购日期: {{ item.cgrq }}</div>
<div>到期时间: {{ item.dqsj }}</div>
</div>
<div class="lineSJY">
<div class="first-one">所属部门: {{ item.ssbm }}</div>
<div>录入批次: {{ item.qxPch }}</div>
</div>
</div>
</van-list>
</van-tab>
</van-tabs>
</div>
</template>
<script setup>
import { getZnzb, selectJyqx } from "../../api/scyy.js";
import TopNav from "../../components/topNav.vue";
import { ref, reactive, onMounted, watch } from "vue";
import { getDictList, setDict } from "../../utils/dict";
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();
const { D_BZ_ZNZBFL, D_BZ_JYQXFL } = getDictList("D_BZ_ZNZBFL", "D_BZ_JYQXFL");
function goCreateEquipment(val) {
router.push({ name: "CreateEquipment", params: { sign: val } });
}
const active = ref(0);
watch(active, (newVal, oldVal) => {
if (newVal === 0) {
zbList.list = [];
getList();
} else {
zbList.jyqxList = [];
getJyqxList();
}
});
watch(route.params.flag, (val) => {
active.value = val;
});
const zbList = reactive({
list: [],
sbmc: "",
jyqxList: [],
qxMc: "",
});
onMounted(() => {
getList();
});
// 获取智能装备
const loading1 = ref(false);
const finished1 = ref(false);
const page1 = ref(1);
const total1 = ref(0);
function getList(val) {
loading1.value = false;
getZnzb({
pageNo: page1.value,
pageSize: 10,
sbmc: zbList.sbmc,
})
.then((res) => {
if (val === 1) {
zbList.list = res.records;
} else {
res.records.forEach((ele) => {
zbList.list.push(ele);
});
}
total1.value = res.total;
onLoad();
finished1.value = true;
})
.catch((err) => {
finished1.value = true;
});
}
function onLoad1() {
if (page1.value * 10 < total1.value) {
page1.value++;
getList();
}
}
// 查询警用器械
const loading2 = ref(false);
const finished2 = ref(false);
const page2 = ref(1);
const total2 = ref(0);
function getJyqxList(val) {
loading2.value = false;
selectJyqx({
pageNo: page2.value,
pageSize: 10,
qxMc: zbList.qxMc,
})
.then((res) => {
if (val === 1) {
zbList.jyqxList = res.records;
} else {
res.records.forEach((ele) => {
zbList.jyqxList.push(ele);
});
}
total2.value = res.total;
finished2.value = true;
})
.catch((err) => {
finished2.value = true;
});
}
function onLoad2() {
if (page2.value * 10 < total2.value) {
page2.value++;
getJyqxList();
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
.item-box {
line-height: 1.8em;
margin: 0 5vw;
border-bottom: 1px solid #f3f3f3;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
.titleSJY {
color: #1F6CEC;
font-weight: bold;
@include font_size($font_medium);
line-height: 6vw;
}
</style>

View File

@ -0,0 +1,289 @@
<template>
<div class="container">
<!-- 盘车 -->
<van-popup v-model:show="peopleCarShow" round :style="{ width: '90%' }" close-icon="close" :overlay="true"
@close="handleClose">
<div class="checkPeoplePopup">
<div class="select-box">
<div class="item-boxs" v-for="(item, index) in checkCList" :key="index" @click="getCItem(item, index)">
<span :class="cCheckFlag === item.value ? 'checkText' : ''">{{ item.label }}</span>
</div>
</div>
<div class="content-boxs">
<div v-if="cCheckFlag === 'plateNum'">
<div class="plateNum">
<van-field v-model="from.value" readonly is-link placeholder="请选择车辆类型"
@click="isShowCommonPicker = true;">
</van-field>
<van-icon @click="ocrSb" style="padding: 0 12px" name="photograph" color="#969799" />
</div>
<div class="input-number flex">
<div class="p_div" v-for="(item, index) in cpList.licensePlateNumber" :key="index"
:class="{ current: cpList.currentValIndex === index }" @click="showKeyboardFn(index)">
{{ item }}
</div>
<div class="add-number" v-if="from.hplx == '02'"
@click="cpList.licensePlateNumber.push(''), from.hplx = '52'">
<van-icon name="plus" color="rgb(34,146,254)" />
<span style="font-size: 12px">新能源</span>
</div>
<div class="add-number" v-if="from.hplx == '52'"
@click="cpList.licensePlateNumber.pop(0), from.hplx = '02'">
<van-icon name="plus" color="rgb(34,146,254)" />
<span style="font-size: 12px">汽车</span>
</div>
</div>
</div>
<van-field v-model="from.value" placeholder="请输入车辆识别码" v-if="cCheckFlag === 'plateCode'"
:rules="[{ required: true, message: '请输入车辆识别码' }]" right-icon="photograph">
</van-field>
<svg-icon icon="chuzu" />
</div>
<div class="footBtn">
<van-button native-type="submit" @click="checkC('sd')" type="primary" round block>查询</van-button>
<div class="toolsTip">请根据工作需求使用功能您的每次查询将记录日志</div>
</div>
</div>
</van-popup>
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="D_BZ_HPZL" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
<!-- 车牌键盘 -->
<VehicleKeyboard ref="vehicleKeyboards" @setValue="setValue" />
</div>
</template>
<script setup>
import { Toast } from "vant";
import VehicleKeyboard from "../../../components/VehicleKeyboard.vue";
import {
ref,
reactive,
watch,
defineProps,
defineEmits,
defineExpose,
toRefs,
onMounted,
onUnmounted,
} from "vue";
import { useRouter } from "vue-router";
import { getDictList, setDict } from "../../../utils/dict";
const { D_BZ_HPZL } = getDictList("D_BZ_HPZL");
const router = useRouter();
const peopleCarShow = ref(false);
const props = defineProps({
zlId: String,
});
const baseInfo = ref({
baseImage: '',//回显图片
})
function handleOpen() {
peopleCarShow.value = true;
window.addEventListener("message", receivePost);
}
function handleClose() {
peopleCarShow.value = false;
window.removeEventListener("message", receivePost);
}
defineExpose({
handleOpen,
});
const from = reactive({
value: "小型汽车号牌",
hplx: "02",
pcsrlx: "2",
});
const vehicleKeyboards = ref();
const cpList = reactive({
licensePlateNumber: ["", "", "", "", "", "", ""],
currentValIndex: 0,
});
function showKeyboardFn(index) {
cpList.currentValIndex = index;
const showProvince = index === 0;
const showNumber = index > 1;
if (index === cpList.licensePlateNumber.length) {
vehicleKeyboards.value.changeDialogShow(false, showProvince, showNumber);
} else {
vehicleKeyboards.value.changeDialogShow(true, showProvince, showNumber);
}
}
function setValue(val) {
if (val === "delete") {
if (cpList.currentValIndex > 2) {
cpList.licensePlateNumber[cpList.currentValIndex] = "";
cpList.currentValIndex--;
} else {
cpList.licensePlateNumber[cpList.currentValIndex] = "";
}
} else {
cpList.licensePlateNumber[cpList.currentValIndex] = val;
cpList.currentValIndex += 1;
showKeyboardFn(cpList.currentValIndex);
}
}
function ocrSb() {
try {
bridge.pZ("pzsbcphm");
} catch (error) {
window.setcphm("川RRF435");
}
}
//接收postMessage消息
function receivePost(mes) {
var str = "";
try {
str = mes.data.type;
} catch (error) { }
switch (str) {
case 'PHOTO':
let str = mes.data.data;
baseInfo.value.baseImage = str;
break;
case "cphm":
try {
getCphm(mes.data.data);
} catch (error) { }
break;
case "color":
try {
console.log(mes.data);
getColor(mes.data.data);
} catch (error) { }
break;
}
}
//通过ocr获取车牌
function getCphm(data) {
var cparr = ["", "", "", "", "", "", ""];
try {
if (data && data.length > 6) {
cparr = data.split("");
} else {
Toast.fail("OCR识别失败");
}
} catch (error) { }
cpList.licensePlateNumber = cparr;
}
//ocr获取车牌颜色
function getColor(val) {
D_BZ_HPZL.value.forEach(item => {
if (item.dm == val) {
from.hplx = item.dm;
from.value = item.zdmc
}
});
}
// 盘车
function checkC(val) {
let hphm = cpList.licensePlateNumber.join("");
let hplx = from.hplx;
let pcsrlx = val ? '2' : '7' //有参数是手动盘查没有是ocr识别
peopleCarShow.value = false
router.push({
path: "/canVehicle",
query: { hphm: hphm, hplx: hplx, pcsrlx: pcsrlx, zlId: props.zlId, }
});
}
function onConfirm(val) {
isShowCommonPicker.value = false;
from.value = val.text;
from.hplx = val.value;
}
const checkCList = [
{ label: "车牌", value: "plateNum" },
{ label: "车辆识别码", value: "plateCode" },
];
const cCheckFlag = ref("plateNum");
function getCItem(item, index) {
cCheckFlag.value = item.value;
console.log(D_BZ_HPZL.value);
}
// 弹出层数据
const columns = ref(["测试1", "测试2", "测试3"]);
const isShowCommonPicker = ref(false);
</script>
<style lang="scss" scoped>
.input-number {
height: 7vh;
// line-height: 6vh;
overflow: hidden;
margin: 10px 5vw 0;
text-align: center;
// border-radius: 5px;
// border: 1px rgb(81, 81, 81) solid;
.p_div {
background-color: #f5f5f5;
height: 7vh;
line-height: 7vh;
width: 12%;
box-sizing: border-box;
&:not(:last-child) {
border-left: 1px #e5e5e5 solid;
border-top: 1px #e5e5e5 solid;
border-bottom: 1px #e5e5e5 solid;
background: #f5f5f5;
// border-radius: 5px;
}
}
.p_div:nth-child(8) {
border: 1px #e5e5e5 solid;
}
.add-number {
width: 52px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #1143ca;
border: 1px solid #1143ca;
}
.p_div.current {
border: 1px solid #66aef6;
border-radius: 5px;
}
}
.plateNum {
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #e5e5e5;
margin: 0 5vw;
}
.flex {
display: flex;
}
.plateNum .van-cell {
padding-left: 0;
padding-right: 0;
}
.footBtn {
margin: 10px 5vw;
.toolsTip {
color: red;
font-size: 12px;
// transform: scale(.9);
margin: 1vw 0;
text-align: center;
}
}
</style>

View File

@ -0,0 +1,298 @@
<template>
<div class="container">
<!-- 盘车 -->
<!-- <van-popup v-model:show="peopleCarShow" round :style="{ width: '90%' }" close-icon="close" :overlay="true"
@close="handleClose"> -->
<div class="checkPeoplePopup">
<!-- <div class="select-box">
<div class="item-boxs" v-for="(item, index) in checkCList" :key="index" @click="getCItem(item, index)">
<span :class="cCheckFlag === item.value ? 'checkText' : ''">{{ item.label }}</span>
</div>
</div> -->
<div class="content-boxs">
<div v-if="cCheckFlag === 'plateNum'">
<div class="plateNum">
<van-field v-model="from.value" readonly is-link placeholder="请选择车辆类型"
@click="isShowCommonPicker = true;">
</van-field>
<van-icon @click="ocrSb" style="padding: 0 12px" name="photograph" color="#969799" />
</div>
<div class="input-number flex">
<div class="p_div" v-for="(item, index) in cpList.licensePlateNumber" :key="index"
:class="{ current: cpList.currentValIndex === index }" @click="showKeyboardFn(index)">
{{ item }}
</div>
<div class="add-number" v-if="from.hplx == '02'"
@click="cpList.licensePlateNumber.push(''), from.hplx = '52'">
<van-icon name="plus" color="rgb(34,146,254)" />
<span style="font-size: 12px">新能源</span>
</div>
<div class="add-number" v-if="from.hplx == '52'"
@click="cpList.licensePlateNumber.pop(0), from.hplx = '02'">
<van-icon name="plus" color="rgb(34,146,254)" />
<span style="font-size: 12px">汽车</span>
</div>
</div>
</div>
<van-field v-model="from.value" placeholder="请输入车辆识别码" v-if="cCheckFlag === 'plateCode'"
:rules="[{ required: true, message: '请输入车辆识别码' }]" right-icon="photograph">
</van-field>
<svg-icon icon="chuzu" />
</div>
<div class="footBtn">
<van-button native-type="submit" @click="checkC('sd')" type="primary" round block>查询</van-button>
<div class="toolsTip">请根据工作需求使用功能您的每次查询将记录日志</div>
</div>
</div>
<!-- </van-popup> -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="D_BZ_HPZL" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
<!-- 车牌键盘 -->
<VehicleKeyboard ref="vehicleKeyboards" @setValue="setValue" />
</div>
</template>
<script setup>
import { Toast } from "vant";
import VehicleKeyboard from "../../../components/VehicleKeyboard.vue";
import {
ref,
reactive,
watch,
defineProps,
defineEmits,
defineExpose,
toRefs,
onMounted,
onUnmounted,
} from "vue";
import { useRouter } from "vue-router";
import { getDictList, setDict } from "../../../utils/dict";
import emitter from "@/utils/eventBus";
const { D_BZ_HPZL } = getDictList("D_BZ_HPZL");
const router = useRouter();
const peopleCarShow = ref(false);
const props = defineProps({
zlId: String,
});
const baseInfo = ref({
baseImage: '',//回显图片
})
function handleOpen() {
peopleCarShow.value = true;
window.addEventListener("message", receivePost);
}
function handleClose() {
peopleCarShow.value = false;
window.removeEventListener("message", receivePost);
}
onMounted(()=>{
emitter.on('closeCarJp',(res)=>{
console.log(res,'res');
vehicleKeyboards.value.changeDialogShow(false, 0, 0);
})
})
defineExpose({
handleOpen,
});
const from = reactive({
value: "小型汽车号牌",
hplx: "02",
pcsrlx: "2",
});
const vehicleKeyboards = ref();
const cpList = reactive({
licensePlateNumber: ["", "", "", "", "", "", ""],
currentValIndex: 0,
});
function showKeyboardFn(index) {
cpList.currentValIndex = index;
const showProvince = index === 0;
const showNumber = index > 1;
if (index === cpList.licensePlateNumber.length) {
vehicleKeyboards.value.changeDialogShow(false, showProvince, showNumber);
} else {
vehicleKeyboards.value.changeDialogShow(true, showProvince, showNumber);
}
}
function setValue(val) {
if (val === "delete") {
if (cpList.currentValIndex > 2) {
cpList.licensePlateNumber[cpList.currentValIndex] = "";
cpList.currentValIndex--;
} else {
cpList.licensePlateNumber[cpList.currentValIndex] = "";
}
} else {
cpList.licensePlateNumber[cpList.currentValIndex] = val;
cpList.currentValIndex += 1;
showKeyboardFn(cpList.currentValIndex);
}
}
function ocrSb() {
try {
bridge.pZ("pzsbcphm");
} catch (error) {
window.setcphm("川RRF435");
}
}
//接收postMessage消息
function receivePost(mes) {
var str = "";
try {
str = mes.data.type;
} catch (error) { }
switch (str) {
case 'PHOTO':
let str = mes.data.data;
baseInfo.value.baseImage = str;
break;
case "cphm":
try {
getCphm(mes.data.data);
} catch (error) { }
break;
case "color":
try {
console.log(mes.data);
getColor(mes.data.data);
} catch (error) { }
break;
}
}
//通过ocr获取车牌
function getCphm(data) {
var cparr = ["", "", "", "", "", "", ""];
try {
if (data && data.length > 6) {
cparr = data.split("");
} else {
Toast.fail("OCR识别失败");
}
} catch (error) { }
cpList.licensePlateNumber = cparr;
}
//ocr获取车牌颜色
function getColor(val) {
D_BZ_HPZL.value.forEach(item => {
if (item.dm == val) {
from.hplx = item.dm;
from.value = item.zdmc
}
});
}
// 盘车
function checkC(val) {
let hphm = cpList.licensePlateNumber.join("");
let hplx = from.hplx;
let pcsrlx = val ? '2' : '7' //有参数是手动盘查没有是ocr识别
peopleCarShow.value = false
router.push({
path: "/canVehicle",
query: { hphm: hphm, hplx: hplx, pcsrlx: pcsrlx, zlId: props.zlId, }
});
}
function onConfirm(val) {
isShowCommonPicker.value = false;
from.value = val.text;
from.hplx = val.value;
}
const checkCList = [
{ label: "车牌", value: "plateNum" },
// { label: "车辆识别码", value: "plateCode" },
];
const cCheckFlag = ref("plateNum");
function getCItem(item, index) {
cCheckFlag.value = item.value;
console.log(D_BZ_HPZL.value);
}
// 弹出层数据
const columns = ref(["测试1", "测试2", "测试3"]);
const isShowCommonPicker = ref(false);
onUnmounted(()=>{
emitter.off('closeCarJp')
})
</script>
<style lang="scss" scoped>
.input-number {
height: 7vh;
// line-height: 6vh;
overflow: hidden;
margin: 10px 5vw 0;
text-align: center;
// border-radius: 5px;
// border: 1px rgb(81, 81, 81) solid;
.p_div {
background-color: #f5f5f5;
height: 7vh;
line-height: 7vh;
width: 12%;
box-sizing: border-box;
&:not(:last-child) {
border-left: 1px #e5e5e5 solid;
border-top: 1px #e5e5e5 solid;
border-bottom: 1px #e5e5e5 solid;
background: #f5f5f5;
// border-radius: 5px;
}
}
.p_div:nth-child(8) {
border: 1px #e5e5e5 solid;
}
.add-number {
width: 52px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #1143ca;
border: 1px solid #1143ca;
}
.p_div.current {
border: 1px solid #66aef6;
border-radius: 5px;
}
}
.plateNum {
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #e5e5e5;
margin: 0 5vw;
}
.flex {
display: flex;
}
.plateNum .van-cell {
padding-left: 0;
padding-right: 0;
}
.footBtn {
margin: 10px 5vw;
.toolsTip {
color: red;
font-size: 12px;
// transform: scale(.9);
margin: 1vw 0;
text-align: center;
}
}
</style>

View File

@ -0,0 +1,210 @@
<template>
<div class="container">
<!-- 盘人 -->
<van-popup v-model:show="peoplePopupShow" round :style="{ width: '90%' }" close-icon="close" :overlay="true"
@close="handleClose">
<div class="checkPeoplePopup">
<div class="select-box">
<div class="item-boxs" v-for="(item, index) in checkPList" :key="index" @click="pCheckFlag = item.value">
<span :class="pCheckFlag === item.value ? 'checkText' : ''">{{ item.label }}</span>
</div>
</div>
<div class="content-box">
<van-form @submit="onSubmit">
<van-field class="border" v-model="form.sfzh" placeholder="请输入身份证号" v-if="pCheckFlag === 'sfzh'"
right-icon="photograph" @click-right-icon="handleOCR" :rules="sfzhRuls">
</van-field>
<van-field class="border" v-model="form.value" placeholder="请输入手机号" right-icon="graphic"
v-if="pCheckFlag === 'phoneNum'" :rules="dhhmRuls">
</van-field>
<div class="photo" v-if="pCheckFlag === 'photo'" @click="takePhoto">
<img :src="require('../../../assets/images/new/photoin.png')" alt="" width="100" height="100" />
<span>开始拍照</span>
</div>
<div class="footBtn" v-if="pCheckFlag != 'photo'">
<van-button native-type="submit" type="primary" round block>查询</van-button>
</div>
<div class="toolsTip">请根据工作需求使用功能您的每次查询将记录日志</div>
</van-form>
</div>
</div>
</van-popup>
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="columns" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
</div>
</template>
<script setup>
import { ref, defineProps, defineExpose } from "vue";
import { Toast } from "vant";
import { useRouter } from "vue-router";
import { IdCardValidator, phoneValidator } from "../../../utils/rules.js"
import { login } from "@/api/user.js";
const props = defineProps({ zlId: String });
const router = useRouter();
const peoplePopupShow = ref(false);
const form = ref({
sfzh: "",
lxdh: "",
});
const pCheckFlag = ref("sfzh");
// 弹出层数据
const columns = ref(["测试1", "测试2", "测试3"]);
const checkPList = [
{ label: "身份证", value: "sfzh" },
{ label: "手机号", value: "phoneNum" },
{ label: "人像", value: "photo" },
];// 盘人弹框按钮List
const isShowCommonPicker = ref(false);
const sfzhRuls = ref([
{ required: true, message: '身份证号码不能为空', trigger: 'onChange/onBlur' },
{ validator: (value) => { return IdCardValidator(value) }, trigger: 'onChange/onBlur' }
])
const dhhmRuls = ref([
{ required: true, message: '电话号码不能为空', trigger: 'onChange/onBlur' },
{ validator: (value) => { return phoneValidator(value) }, trigger: 'onChange/onBlur' }
])
// 打开弹窗
function handleOpen() {
peoplePopupShow.value = true;
window.addEventListener("message", receivePost);
}
function handleClose() {
peoplePopupShow.value = false
window.removeEventListener("message", receivePost);
}
// 处理人OCR
function handleOCR() {
try {
window.bridge.openOcrDiscern();
} catch (error) { }
}
//接收postMessage消息
function receivePost(mes) {
var str = "";
try {
str = mes.data.type;
} catch (error) { }
switch (str) {
case 'PHOTO':
try {
if (mes.data.data) {
let str = mes.data.data
router.push({ path: "/peopleList", query: { info: str, pcsrlx: "5" } });
} else {
Toast.fail("人像识别失败");
}
} catch (error) { }
break;
case "sfzh":
try {
if (mes.data.data) {
let info = JSON.parse(mes.data.data)
localStorage.setItem('OCR', mes.data.data)
let data = { sfzh: info.num, pcsrlx: 7, zlId: props.zlId }
router.push({ path: "/quarantinePersonnel", query: data });
} else {
Toast.fail("OCR识别失败");
}
} catch (error) { }
break;
case "NFC":
try {
if (mes.data.data) {
let obj = mes.data.data
let data = { sfzh: obj.data.sfzh, pcsrlx: 1, zlId: props.zlId }
window.localStorage.setItem("NFC", JSON.stringify(mes.data.data));
router.push({ path: "/quarantinePersonnel", query: data });
} else {
Toast.fail("NFC识别失败");
}
} catch (error) { }
break;
}
}
// 人像
function takePhoto() {
try {
bridge.pZ('pz_system_rxsb_yk')
} catch (error) { }
}
// 盘人提交按钮
function onSubmit(values) {
switch (pCheckFlag.value) {
case "sfzh":
let data = { sfzh: form.value.sfzh, pcsrlx: "2", zlId: props.zlId }
localStorage.setItem('NFC', JSON.stringify(data))
router.push({ path: "/quarantinePersonnel", query: data });
break;
case "phoneNum":
let prams = { dhhm: form.value.value, isPc: 1, pcsrlx: "6" }
router.push({ path: "/yyzx/dhcr", query: prams });
break;
}
peoplePopupShow.value = false;
}
defineExpose({ handleOpen });
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.item-boxs {
@include font_size($font_medium_s);
}
.sub-btn {
@include font_size($font_medium);
}
.border {
border: 1px solid #ccc;
background: #f5f5f5;
}
.photo {
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 4vh;
align-items: center;
span {
text-align: center;
line-height: 2em;
color: #ec6b2b;
@include font_size($font_medium);
font-weight: bold;
font-family: PingFang SC;
}
}
.footBtn {
margin: 10px 0px;
}
.van-form {
width: 83%;
}
::v-deep .van-uploader__wrapper {
justify-content: center;
}
.toolsTip {
color: red;
font-size: 12px;
margin: 2vw 0;
text-align: center;
}
</style>

View File

@ -0,0 +1,210 @@
<template>
<div class="container">
<!-- 盘人 -->
<!-- <van-popup v-model:show="peoplePopupShow" round :style="{ width: '90%' }" close-icon="close" :overlay="true"
@close="handleClose"> -->
<div class="checkPeoplePopup">
<!-- <div class="select-box">
<div class="item-boxs" v-for="(item, index) in checkPList" :key="index" @click="pCheckFlag = item.value">
<span :class="pCheckFlag === item.value ? 'checkText' : ''">{{ item.label }}</span>
</div>
</div> -->
<div class="content-box">
<van-form @submit="onSubmit">
<van-field class="border" v-model="form.sfzh" placeholder="请输入身份证号" v-if="pCheckFlag === 'sfzh'"
right-icon="photograph" @click-right-icon="handleOCR" :rules="sfzhRuls">
</van-field>
<van-field class="border" v-model="form.value" placeholder="请输入手机号" right-icon="graphic"
v-if="pCheckFlag === 'phoneNum'" :rules="dhhmRuls">
</van-field>
<div class="photo" v-if="pCheckFlag === 'photo'" @click="takePhoto">
<img :src="require('../../../assets/images/new/photoin.png')" alt="" width="100" height="100" />
<span>开始拍照</span>
</div>
<div class="footBtn" v-if="pCheckFlag != 'photo'">
<van-button native-type="submit" type="primary" round block>查询</van-button>
</div>
<div class="toolsTip">请根据工作需求使用功能您的每次查询将记录日志</div>
</van-form>
</div>
</div>
<!-- </van-popup> -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="columns" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
</div>
</template>
<script setup>
import { ref, defineProps, defineExpose } from "vue";
import { Toast } from "vant";
import { useRouter } from "vue-router";
import { IdCardValidator, phoneValidator } from "../../../utils/rules.js"
import { login } from "@/api/user.js";
const props = defineProps({ zlId: String });
const router = useRouter();
const peoplePopupShow = ref(false);
const form = ref({
sfzh: "",
lxdh: "",
});
const pCheckFlag = ref("sfzh");
// 弹出层数据
const columns = ref(["测试1", "测试2", "测试3"]);
const checkPList = [
{ label: "身份证", value: "sfzh" },
// { label: "手机号", value: "phoneNum" },
// { label: "人像", value: "photo" },
];// 盘人弹框按钮List
const isShowCommonPicker = ref(false);
const sfzhRuls = ref([
{ required: true, message: '身份证号码不能为空', trigger: 'onChange/onBlur' },
{ validator: (value) => { return IdCardValidator(value) }, trigger: 'onChange/onBlur' }
])
const dhhmRuls = ref([
{ required: true, message: '电话号码不能为空', trigger: 'onChange/onBlur' },
{ validator: (value) => { return phoneValidator(value) }, trigger: 'onChange/onBlur' }
])
// 打开弹窗
function handleOpen() {
peoplePopupShow.value = true;
window.addEventListener("message", receivePost);
}
function handleClose() {
peoplePopupShow.value = false
window.removeEventListener("message", receivePost);
}
// 处理人OCR
function handleOCR() {
try {
window.bridge.openOcrDiscern();
} catch (error) { }
}
//接收postMessage消息
function receivePost(mes) {
var str = "";
try {
str = mes.data.type;
} catch (error) { }
switch (str) {
case 'PHOTO':
try {
if (mes.data.data) {
let str = mes.data.data
router.push({ path: "/peopleList", query: { info: str, pcsrlx: "5" } });
} else {
Toast.fail("人像识别失败");
}
} catch (error) { }
break;
case "sfzh":
try {
if (mes.data.data) {
let info = JSON.parse(mes.data.data)
localStorage.setItem('OCR', mes.data.data)
let data = { sfzh: info.num, pcsrlx: 7, zlId: props.zlId }
router.push({ path: "/quarantinePersonnel", query: data });
} else {
Toast.fail("OCR识别失败");
}
} catch (error) { }
break;
case "NFC":
try {
if (mes.data.data) {
let obj = mes.data.data
let data = { sfzh: obj.data.sfzh, pcsrlx: 1, zlId: props.zlId }
window.localStorage.setItem("NFC", JSON.stringify(mes.data.data));
router.push({ path: "/quarantinePersonnel", query: data });
} else {
Toast.fail("NFC识别失败");
}
} catch (error) { }
break;
}
}
// 人像
function takePhoto() {
try {
bridge.pZ('pz_system_rxsb_yk')
} catch (error) { }
}
// 盘人提交按钮
function onSubmit(values) {
switch (pCheckFlag.value) {
case "sfzh":
let data = { sfzh: form.value.sfzh, pcsrlx: "2", zlId: props.zlId }
localStorage.setItem('NFC', JSON.stringify(data))
router.push({ path: "/quarantinePersonnel", query: data });
break;
case "phoneNum":
let prams = { dhhm: form.value.value, isPc: 1, pcsrlx: "6" }
router.push({ path: "/yyzx/dhcr", query: prams });
break;
}
peoplePopupShow.value = false;
}
defineExpose({ handleOpen });
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.item-boxs {
@include font_size($font_medium_s);
}
.sub-btn {
@include font_size($font_medium);
}
.border {
border: 1px solid #ccc;
background: #f5f5f5;
}
.photo {
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 4vh;
align-items: center;
span {
text-align: center;
line-height: 2em;
color: #ec6b2b;
@include font_size($font_medium);
font-weight: bold;
font-family: PingFang SC;
}
}
.footBtn {
margin: 10px 0px;
}
.van-form {
width: 90%;
}
::v-deep .van-uploader__wrapper {
justify-content: center;
}
.toolsTip {
color: red;
font-size: 12px;
margin: 2vw 0;
text-align: center;
}
</style>

View File

@ -0,0 +1,125 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="人员列表" :showRight="false" :showLeft="true" />
<ul class="people-box">
<li class="people-item boxItem" v-for="(item, index) in dataList" @click="lookDetail(item)" :key="index">
<div class="text">相似度{{ item.xsd }}%</div>
<div class="item-left">
<van-image @click.stop="ImagePreview([item.baseUrl])" :src="item.baseUrl">
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
</div>
<div class="item-right">
<div class="info">姓名 {{ item.xm }}</div>
<div class="info">性别 {{ item.xbdm == "1" ? "男" : "女" }}</div>
<div class="info">出生日期 {{ item.csrq }}</div>
<div class="info">身份证号 {{ item.sfzh }}</div>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "peopleList",
};
</script>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { onMounted, ref } from "vue";
import { useRouter, useRoute } from "vue-router";
import { selectRx } from "../../../api/common.js";
import { ImagePreview } from "vant";
import { hintToast, getBase64 } from "../../../utils/tools.js";
const router = useRouter();
const route = useRoute();
const dataList = ref([]);
onMounted(() => {
let str = route.query.info;
let data = new FormData();
data.append("base64Str", str);
selectRx(data).then((res) => {
if (res && res.length > 0) {
dataList.value = res.slice(0, 10);
dataList.value.forEach((item) => {
getBase64((url) => {
item.baseUrl = url;
}, item.url);
});
} else {
hintToast("未查到人员信息");
}
});
});
//获取base64地址
function _getBase64(item) {
getBase64((res) => {
item.baseUrl = res;
}, item.url);
}
// 查看详情
function lookDetail(item) {
router.push({
path: "/quarantinePersonnel",
query: { sfzh: item.sfzh, pcsrlx: "5" },
});
}
</script>
<style lang="scss" scoped>
.people-box {
padding: 4vw;
box-sizing: border-box;
.people-item {
display: flex;
border: 1px solid #e9e9e9;
padding: 2vw;
border-radius: 1vw;
margin-bottom: 2vw;
position: relative;
overflow: hidden;
.text {
position: absolute;
right: -21px;
top: 17px;
width: 106px;
text-align: center;
height: 22px;
line-height: 24px;
background: red;
font-size: 12px;
color: #fff;
transform: rotate(42deg);
}
.item-left {
width: 22vw;
margin-right: 2vw;
text-align: center;
::v-deep .van-image {
width: 22vw;
max-height: 27vw;
img {
width: 22vw;
max-height: 27vw;
}
}
}
.item-right {
flex: 1;
.info {
line-height: 7vw;
}
}
}
}
</style>

View File

@ -0,0 +1,95 @@
<template>
<div class="container">
<!-- 盘人 -->
<van-popup v-model:show="peoplePopupShow" round :style="{ width: '90%' }" teleport="body" close-icon="close" :overlay="true"
@close="handleClose">
<van-tabs v-model:active="active" @change="tabChange">
<van-tab title="盘人">
<CheckPeople />
</van-tab>
<van-tab title="盘车">
<CheckCar />
</van-tab>
</van-tabs>
</van-popup>
</div>
</template>
<script setup>
import { ref, defineProps, defineExpose } from "vue";
import { Toast } from "vant";
import { useRouter } from "vue-router";
import CheckCar from "./checkCarNew.vue";
import CheckPeople from "./checkPeopleNew.vue";
import { login } from "@/api/user.js";
import emitter from "@/utils/eventBus";
const props = defineProps({ zlId: String });
const router = useRouter();
const peoplePopupShow = ref(false);
const active=ref('0')
// 打开弹窗
function handleOpen() {
peoplePopupShow.value = true;
}
function handleClose() {
peoplePopupShow.value = false
}
const tabChange=()=>{
emitter.emit('closeCarJp',false)
}
defineExpose({ handleOpen });
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.item-boxs {
@include font_size($font_medium_s);
}
.sub-btn {
@include font_size($font_medium);
}
.border {
border: 1px solid #ccc;
background: #f5f5f5;
}
.photo {
display: flex;
flex-direction: column;
justify-content: center;
margin-bottom: 4vh;
align-items: center;
span {
text-align: center;
line-height: 2em;
color: #ec6b2b;
@include font_size($font_medium);
font-weight: bold;
font-family: PingFang SC;
}
}
.footBtn {
margin: 10px 0px;
}
.van-form {
width: 90%;
}
::v-deep .van-uploader__wrapper {
justify-content: center;
}
.toolsTip {
color: red;
font-size: 12px;
margin: 2vw 0;
text-align: center;
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<div class="container">
<!-- 盘人 -->
<van-popup v-model:show="peoplePopupShow" round :style="{ width: '80%' }" close-icon="close" :overlay="true"
@close="handlePClose">
<div class="checkPeoplePopup">
<div class="select-box">
<div class="item-boxs" v-for="(item, index) in checkPList" :key="index" @click="getPItem(item, index)">
<span :class="pCheckFlag === item.value ? 'checkText' : ''">{{
item.label
}}</span>
</div>
</div>
<div class="content-box">
<van-field v-model="form.sfzh" placeholder="请输入身份证号" v-if="pCheckFlag === 'sfzh'" right-icon="photograph"
:rules="[{ required: true, message: '请输入身份证号码' }]">
</van-field>
<van-field v-model="form.value" placeholder="请输入手机号" right-icon="graphic" v-if="pCheckFlag === 'phoneNum'"
:rules="[{ required: true, message: '请输入手机号码' }]">
</van-field>
<div v-if="pCheckFlag === 'photo'">
<img :src="require('../../../../assets/images/new/photoin.png')" alt="" width="100" height="100" />
</div>
<div v-if="pCheckFlag === 'scanf'">
<!-- <van-icon name="scan" /> -->
</div>
<!-- 综合 -->
<div v-if="pCheckFlag === 'comprehensive'" style="width: 100%">
<van-field v-model="form.value" placeholder="请输入姓名" :rules="[{ required: true, message: '请输入姓名' }]"
right-icon="user-o">
</van-field>
<!-- <van-field
v-model="value"
readonly
name="calendar"
placeholder="请输入出生日期"
@click="showCalendar = true"
>
<template #right-icon>
<i class="iconfontorange">&#xe613;</i>
</template>
</van-field> -->
<van-field v-model="form.value" name="csrq" placeholder="请输入生日,格式为2020-01-01" right-icon="calendar-o"
@touchstart.stop="showDateKeyboard = true" :rules="[
{
pattern: /\d{4}-\d{2}-\d{2}/,
required: true,
message: '请输入生日,格式为2020-01-01',
},
]">
</van-field>
<van-field v-model="form.result" name="picker" clickable placeholder="请选择性别" right-icon="award-o"
@click="getCommonPop('sex')">
</van-field>
</div>
</div>
<div class="checkPeopleSubmit" @click="checkP(pCheckFlag)" v-if="pCheckFlag != 'photo'">
<div class="sub-btn">
<img :src="require('../../../../assets/images/new/faceR.png')" alt="" width="17"
height="17" />&nbsp;&nbsp;盘查人员
</div>
</div>
</div>
</van-popup>
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="columns" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
</div>
</template>
<script setup>
import {
ref,
reactive,
watch,
defineProps,
defineEmits,
defineExpose,
toRefs,
toRef,
} from "vue";
import { hintToast } from "../../../../utils/tools.js";
import { useRouter } from "vue-router";
const router = useRouter();
const peoplePopupShow = ref(false);
function handleOpen() {
peoplePopupShow.value = true;
}
function handlePClose() {
peoplePopupShow.value = false;
}
defineExpose({
handleOpen,
});
const form = ref({
sfzh: "",
lxdh: "",
});
// 盘人
function checkP(e) {
switch (e) {
case "sfzh":
if (form.value.sfzh) {
router.push({
path: "/quarantinePersonnel",
query: {
sfzh: form.value.sfzh,
pcsrlx: "2",
},
});
} else {
hintToast("请输入身份证号码");
}
break;
}
}
// 盘人弹框按钮List
const checkPList = [
{ label: "身份证", value: "sfzh" },
{ label: "手机号", value: "phoneNum" },
// { label: "人像", value: "photo" },
// { label: "扫码", value: "scanf" },
// { label: "综合", value: "comprehensive" },
];
const pCheckFlag = ref("sfzh");
function getPItem(item, index) {
pCheckFlag.value = item.value;
}
// 弹出层数据
const columns = ref(["测试1", "测试2", "测试3"]);
const isShowCommonPicker = ref(false);
function getCommonPop(val) {
switch (val) {
case "cllx":
columns.value = ["1", "2", "3"];
break;
case "sex":
columns.value = ["男", "女", "未知"];
break;
}
isShowCommonPicker.value = true;
}
</script>
<style lang="scss" scoped>
@import "../../../../assets/styles/mixin.scss";
.item-boxs {
@include font_size($font_medium_s);
}
.sub-btn {
@include font_size($font_medium_s);
}
</style>

View File

@ -0,0 +1,776 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="车辆盘查" :showRight="false" :showLeft="true" />
<div class="tip_text">
盘查结果{{ clxx.pcbqsm }}
</div>
<!-- <div class="head-nav-banner" v-if="clxx.jdcsyr"></div>
<div class="top" v-if="clxx.jdcsyr">
<div class="basic-info">
<div class="img-box">
<img :class="_getBase64(clxx)" :src="clxx.baseUrl" width="60" />
</div>
<div class="IDcard-info">
<div class="text">{{ clxx.hphm }}</div>
<div>所有人: {{ clxx.jdcsyr }}</div>
<div>车主身份证{{ clxx.jdcsyrsfzh }}</div>
<div>识别代码: {{ clxx.clsbdh }}</div>
</div>
</div>
</div>
<div class="bg_ban"></div>
<div class="center" v-if="clxx.jdcsyr">
<div class="associated-information">
<div class="sign-title">关联信息</div>
<div class="content1">
<div class="item-box" @click="goCanTrack">
<div class="ass-item-box">
<div class="circlebox bg2"></div>
<span>盘查轨迹</span>
</div>
</div>
</div>
</div>
<div class="pick-up-information">
<div class="sign-title">采集信息</div>
<div class="pick-box">
<van-badge class="pick-item-box pbg3" :content="wpdjList.length" @click="isShowSignIn = true">
<div>物品登记</div>
<div class="tp"></div>
</van-badge>
<van-popup v-model:show="isShowSignIn" :style="{ width: '90vw' }">
<van-form @submit="onSubmitWp">
<van-cell-groub>
<van-field name="uploader" label="物品图片">
<template #input>
<van-uploader v-model="wpTpIdList" multiple :max-count="3" :after-read="upLoadImg2" />
</template>
</van-field>
</van-cell-groub>
<van-cell-groub>
<van-field v-model="wpdjForm.wpms" label="物品描述" placeholder="物品描述" rows="2" maxlength="50"
show-word-limit></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请填写物品数量' }]" v-model="wpdjForm.wpsl" label="物品数量"
placeholder="物品数量" type="number"></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请选择物品类型' }]" readonly is-link v-model="wpdjForm.wplx"
label="物品类型" placeholder="选择物品类型" @click="showPicker = true"></van-field>
</van-cell-groub>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" size="small">提交</van-button>
</div>
</van-form>
</van-popup>
</div>
</div>
<div class="vehicular">
<div class="sign-title">
<span>同乘人员</span><span class="chooseP" @click="isWithStaff = true;">选择人员</span>
</div>
<div class="ry_item">
<div v-if="rypcidList.length === 0" style="text-align: center">
暂无数据
</div>
<div v-else>
<div class="item_flex" v-for="(item, index) in rypcidList" :key="index + 'ryid'">
<van-badge>
<div class="item_tcry">
<span style="width: 15vw">{{
rypcOptions.filter((e) => e.value === item)[0].xm
}}</span>
&emsp;
<span>{{
rypcOptions.filter((e) => e.value === item)[0].sfzh
}}</span>
</div>
<template #content>
<van-icon name="cross" class="badge-icon" @click="deleterypc(index)" />
</template>
</van-badge>
<van-button v-if="
rypcOptions.filter((e) => e.value === item)[0].pcclJg == 1
" round class="fxBtn" type="default" style="padding: 0 12px" size="mini">放行</van-button>
<van-button v-else-if="
rypcOptions.filter((e) => e.value === item)[0].pcclJg == 2
" round class="yjBtn" style="padding: 0 12px" type="default" size="mini">移交</van-button>
<van-button v-else round class="fxBtn" style="padding: 0 12px" type="default" size="mini">盘查</van-button>
</div>
</div>
</div>
<van-popup v-model:show="isWithStaff" :style="{ height: '55%', width: '70%', borderRadius: '8px' }">
<div class="staff-title">选择同乘人员</div>
<div class="staff-content">
<div style="text-align: center; margin-top: 16px" v-if="rypcOptions.length === 0">
暂无同乘人员~
</div>
<div v-else>
<van-checkbox-group v-model="rypcidList">
<van-cell-group inset>
<van-cell v-for="(item, index) in rypcOptions" :key="index + 'rypcid'" :title="item.xm"
@click="toggle(index)">
<template #right-icon>
<van-checkbox :name="item.value" :ref="(el) => (checkboxRefs[index] = el)"
@click.stop></van-checkbox>
</template>
</van-cell>
</van-cell-group>
</van-checkbox-group>
</div>
</div>
<div class="staff-sure">
<van-button size="small" class="yjBtn" type="default" block @click="prLoad">盘人</van-button>
<van-button size="small" class="fxBtn" type="default" @click="onOkTcry" block>确认</van-button>
</div>
</van-popup>
<div class="veh-box">
<div class="no-veh">暂无乘坐车辆~</div>
</div>
</div>
</div>
<div class="bg_ban"></div>
<div class="upload" v-if="clxx.jdcsyr">
<div class="tsxx" v-show="fileList.length === 0">
点击上传图片
<br />
最多可上传 3 张照片
</div>
<van-uploader v-model="fileList" multiple :max-count="3" :after-read="upLoadImg">
<van-button class="up_btn" icon="plus"></van-button>
</van-uploader>
</div> -->
<!-- <div class="bg_ban" style="height: 100px"></div> -->
<div class="bottom-box">
<div @click="save('1')">
<img src="../../../assets/images/new/fangxing.png" />
放行
</div>
<div @click="save('2')" class="yj">
<img src="../../../assets/images/new/yijiao.png" />
移交
</div>
</div>
<van-popup v-model:show="showPicker" position="bottom">
<van-picker :columns="D_BZ_BPCRCWP" @confirm="onConfirmWp" @cancel="showPicker = false" />
</van-popup>
<!-- 移交弹窗 -->
<van-popup v-model:show="showYj" round :style="{ width: '90vw' }">
<van-form @submit="onYj">
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请填写移交单位' }]" v-model="yjForm.pcclYjdw" label="移交单位"
placeholder="移交单位"></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field :rules="[{ required: true, message: '请选择移交原因' }]" readonly is-link v-model="yjForm.pcclYjyy"
label="移交原因" placeholder="选择移交原因" @click="showYjyy = true"></van-field>
</van-cell-groub>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" size="small">移交</van-button>
</div>
</van-form>
</van-popup>
<!-- 移交原因 -->
<van-popup round v-model:show="showYjyy" position="bottom">
<van-picker :columns="D_BZ_BPCCLYJYY" @cancel="showYjyy = false" @confirm="onConfirmYjyy"></van-picker>
</van-popup>
<checkedPeople ref="peo" />
</div>
</template>
<script setup>
import ImageCompressor from "image-compressor.js";
import TopNav from "../../../components/topNav";
import checkedPeople from "./components/checkPeople";
import { ref, reactive, onMounted, onBeforeUpdate, watch } from "vue";
import { useRouter } from "vue-router";
import { selectCl, saveBpccl, upImage, getClry2h } from "../../../api/common";
import { getDictList, setDict } from "../../../utils/dict";
import { zlPrPc } from "../../../api/zlzx.js";
import { getBase64, hintToast } from "../../../utils/tools.js";
const router = useRouter();
//移交表单
const { D_BZ_BPCRCWP, D_BZ_BPCCLYJYY } = getDictList("D_BZ_BPCRCWP", "D_BZ_BPCCLYJYY");
const yjForm = ref({});
const zlId = ref("");
const loading = ref(true);
const showEmpty = ref(false);
const copyCphm = ref("");
const wpTpIdList = ref([]);
const peo = ref(null);
const fileList = ref([]);
const isWithStaff = ref(false);
const showYj = ref(false);
const gps = ref({});
const clxx = ref({});
const showYjyy = ref(false);
const rypcidList = ref([]);//人员盘查id集合
const rypcOptions = ref([]);
const checkboxRefs = ref([]);
const wpdjList = ref([]);//物品登记数据
const wpdjForm = ref({
wpms: "",
wpTpIdList: [],
wpsl: 1,
wplx: "",
});
const tpIdList = ref([]);
const isShowSignIn = ref(false);// 物品登记
const addfileList = ref([]);
const result = ref("");
const showPicker = ref(false);
onBeforeUpdate(() => {
checkboxRefs.value = [];
});
onMounted(() => {
zlId.value = router.currentRoute.value.query.zlId;
copyCphm.value = router.currentRoute.value.query.hphm;
getTcry();
try {
gps = JSON.parse(bridge.getLocation());
} catch (error) { }
let hphm = router.currentRoute.value.query.hphm;
if (hphm) {
clxxQueryDetail(hphm);
} else {
hintToast("无车辆信息,请重试!");
showEmpty.value = true;
loading.value = false;
}
});
function toggle(index) {
checkboxRefs.value[index].toggle();
}
function onOkTcry() {
isWithStaff.value = false;
}
//获取base64地址
function _getBase64(item) {
getBase64((res) => { item.baseUrl = res; }, `http://10.64.201.128:2366/xlpcAdminNew/requestservice/czrk/ryxp.jpg?sfzh=${item.jdcsyrsfzh}`);
}
// 盘查人员
function prLoad() {
peo.value.handleOpen();
}
// 移交原因
function onConfirmYjyy(val) {
showYjyy.value = false;
yjForm.value.pcclYjyy = val.text;
}
function deleterypc(e) {
rypcidList.value.splice(e, 1);
}
function onSubmitWp() {
isShowSignIn.value = false;
wpdjList.value.push({
wpms: wpdjForm.value.wpms,
wpTpIdList: wpdjForm.value.wpTpIdList,
wplx: wpdjForm.value.wplxdm,
wpsl: wpdjForm.value.wpsl,
});
wpTpIdList.value = [];
wpdjForm.value = {
wpms: "",
wpTpIdList: [],
wpsl: 1,
wplx: "",
};
}
function onConfirmWp(val) {
showPicker.value = false;
wpdjForm.value.wplx = val.text;
wpdjForm.value.wplxdm = val.dm;
}
function getTcry() {
getClry2h().then((res) => {
rypcOptions.value = res.map((item) => {
return {
xm: item.xm,
value: item.id,
sfzh: item.sfzh,
pcclJg: item.pcclJg,
};
});
});
}
function clxxQueryDetail(hphm) {
let hplx = router.currentRoute.value.query.hplx
selectCl({
hphm: hphm,
hpzl: hplx,
jd: gps.app_x,
wd: gps.app_y,
sjly: "",
zdxh: gps.zdxh,
pcsrlx: router.currentRoute.value.query.pcsrlx,
zdch: gps.zdch,
zdsim: gps.zdsim,
glxtdm: "",
glxtid: "",
jzid: "",
bbid: "",
pcfs: "",
}).then((res) => {
loading.value = false;
if (res) {
clxx.value = res;
} else {
hintToast("查无此车,请核对信息!");
router.go(-1);
}
//如果是指令页面跳转过来 嗲用
if (zlId.value) {
zlPrPc({ pclxdm: 2, pcryclId: clxx.value.id, zlId: zlId.value }).then((res) => { });
}
});
}
// 关联信息
function goCanTrack() {
router.push({
path: "/TrackInventory", query: { hphm: clxx.value.hphm },
});
}
// 放行移交
function save(val) {
if (val === "1") {
clxx.value.pcclJg = val;
clxx.value.pcclJgmc = "放行";
clxx.value.jd = gps.app_x;
clxx.value.wd = gps.app_y;
const formData = {
id: clxx.value.id,
pcclJg: "1",
pcclJgmc: "放行",
tpIdList: tpIdList.value,
clWpList: wpdjList.value,
rypcidList: rypcidList.value,
};
saveBpccl(formData).then((res) => {
hintToast("放行成功!");
router.go(-1);
});
} else {
clxx.value.pcclJg = val;
clxx.value.pcclJgmc = "移交";
showYj.value = true;
}
}
// 移交
function onYj() {
const formData = {
id: clxx.value.id,
pcclJg: "2",
pcclJgmc: "移交",
pcclYjdw: yjForm.value.pcclYjdw,
pcclYjyy: yjForm.value.pcclYjyy,
tpIdList: tpIdList.value,
clWpList: wpdjList.value,
rypcidList: rypcidList.value,
};
saveBpccl(formData).then((res) => {
hintToast("移交成功!");
router.go(-1);
});
}
// 上传图片
async function upLoadImg(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!tpIdList.value.includes(res)) tpIdList.value.push(res);
});
}
// 上传图片
async function upLoadImg2(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!wpdjForm.value.wpTpIdList.includes(res)) wpdjForm.value.wpTpIdList.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.bg_ban {
background: #eff0f5;
height: 12px;
}
.container {
// height: 100vh;
margin-bottom: 8vh;
}
.top {
background-image: url("../../../assets/images/new/cl_bg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
height: 22vw;
padding: 3vh 5vw;
margin: 0 4vw 12px;
position: relative;
z-index: 2;
}
.basic-info {
color: #4d4d4d;
display: flex;
flex-direction: row;
.img-box {
flex: 1;
>img {
border-radius: 5px;
border: 1px solid #1143ca;
overflow: hidden;
}
}
.IDcard-info {
flex: 3;
@include font_size($font_medium_s);
.text {
// @include font_size($font_large);
@include font_size($font_medium);
font-weight: bold;
color: #1f6cec;
}
}
}
.contact-way {
margin-top: 3vh;
line-height: 3vh;
@include font_size($font_medium_s);
.one-line {
display: flex;
.phoneNum {
width: 50%;
}
}
}
.fxBtn {
background: linear-gradient(148deg, #5897ff, #1862de);
color: #f2f2f2;
}
.yjBtn {
background: linear-gradient(148deg, #ffbb6b, #ff7a45);
color: #f2f2f2;
}
.center {
padding: 0 3vw;
.sign-title {
padding-left: 14px;
position: relative;
line-height: 3vh;
@include font_size($font_medium);
font-weight: bold;
display: flex;
justify-content: space-between;
margin: 1vh 0;
.chooseP {
@include font_size($font_medium_s);
color: rgb(0, 102, 255);
font-weight: normal;
}
}
.sign-title::after {
content: "";
position: absolute;
left: 0;
top: 2px;
bottom: 2px;
width: 4px;
background: linear-gradient(0deg, #7ec2ff 0%, #0e8aff 100%);
border-radius: 1px;
}
.associated-information {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.item-box {
margin: 2vw 4vw;
display: flex;
.ass-item-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
.content1 {
display: flex;
.circlebox {
width: 15vw;
height: 15vw;
// border-radius: 15vw;
text-align: center;
line-height: 15vw;
margin-bottom: 2vw;
}
.bg1 {
background: url("../../../assets/images/new/zhda.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg2 {
background: url("../../../assets/images/new/pcgj.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg3 {
background: url("../../../assets/images/new/tcry.png");
background-size: contain;
background-repeat: no-repeat;
}
}
}
.pick-up-information {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.pick-box {
display: flex;
justify-content: flex-start;
margin: 3vw 0;
}
.pick-item-box {
padding: 3vw 3vw 10vw;
width: 30%;
margin-right: 2vw;
// border-radius: 3vw;
position: relative;
.tp {
position: absolute;
bottom: 0;
right: 0;
}
}
.pbg1 {
background: url("../../../assets/images/new/bg-blue.png") no-repeat;
background-size: cover;
}
.pbg2 {
background: url("../../../assets/images/new/bg-orgin.png") no-repeat;
background-size: cover;
}
.pbg3 {
color: #397361;
background: url("../../../assets/images/new/wpdj.png") no-repeat;
background-size: 100% 100%;
}
}
.vehicular {
@include font_color($font-color-theme);
.no-veh {
text-align: center;
}
.veh-box {
margin: 1vh 0;
}
}
}
.line1 {
width: 100vw;
background-color: #eee;
height: 1vh;
}
.upload {
padding: 1vh 3vw;
height: 80px;
position: relative;
.tsxx {
position: absolute;
color: #a8a8a8;
top: 0;
left: 30%;
bottom: 0;
padding: 8% 0;
font-size: 14px;
}
.up_btn {
height: 80px;
width: 80px;
color: #a8a8a8;
font-size: 24px;
background: #f2f2f2 url("../../../assets/images/new/upimg_bg.png") no-repeat;
background-size: 100% 100%;
}
}
.bottom-box {
text-align: center;
background: #fff;
border-top: 1px solid #ddddde;
position: fixed;
bottom: 0;
width: 100vw;
height: 6vh;
line-height: 6vh;
display: flex;
>div {
height: 6vh;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
>img {
width: 20px;
margin-right: 8px;
}
}
.yj {
background: #f0f0f0;
}
}
.upload-box {
margin: 1vh 3vw;
}
.ry_item {
background: #f8f8f8;
opacity: 0.7;
margin-bottom: 16px;
line-height: 1.8em;
}
.staff-title {
height: 6vh;
background-color: rgb(13, 106, 245);
text-align: center;
line-height: 6vh;
color: #fff;
}
.staff-sure {
position: fixed;
bottom: 5vw;
right: 5vw;
left: 5vw;
.yjBtn {
margin-bottom: 12px;
border-radius: 8px;
}
.fxBtn {
border-radius: 8px;
}
}
.head-nav-banner {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 35vw;
z-index: 1;
background: #1143ca;
}
::v-deep .headBlue {
background-color: #1143ca !important;
}
.navTitle {
position: absolute;
top: 0;
color: #fff;
// @include font_size($font_large);
font-size: 5.5vw;
text-align: center;
width: 100%;
padding: 3vw 0;
}
.item_tcry {
padding: 2px 24px;
background: #d2e3ff;
border-radius: 8px;
>span {
display: inline-block;
}
}
.badge-icon {
display: block;
font-size: 10px;
line-height: 16px;
}
.item_flex {
padding: 6px 0;
display: flex;
justify-content: space-between;
}
.tip_text{
font-size: 18px;
margin-top: 10px;
}
</style>

View File

@ -0,0 +1,240 @@
<template>
<div style="padding-top: 13vw">
<TopNav :navTitle="title" />
<van-form @submit="onSubmit" style="height: calc(100vh - 13vw);">
<div class="infoBox">
<ul class="cardInfo">
<li class="item">
<van-field v-model="normalForm.sbsj" required name="申报时间" readonly label="申报时间" input-align="right"
:rules="[{ required: true, message: '请选择时间' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.sblxmc" required name="申报类型" is-link readonly label="申报类型" placeholder="点击设置"
input-align="right" :rules="[{ required: true, message: '请选择申报类型' }]" @click="getCommonPop('sblx')" />
</li>
<li class="item">
<van-field required name="申报原因" readonly label="申报原因" />
</li>
<van-field placeholder="请输入相关内容" v-model="normalForm.sbyy" rows="4" autosize accept=".txt,.png,.zip,jpg,jpeg"
maxlength="500" show-word-limit type="textarea"></van-field>
<li class="item">
<div><span class="mark"></span>添加附件</div>
</li>
<!-- 附件 -->
<div class="fjBox">
<van-uploader v-model="fileList" multiline :max-count="3" :after-read="afterRead"></van-uploader>
</div>
</ul>
<div class="footer">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="登录中...">提交</van-button>
</div>
</div>
</van-form>
<!-- 弹窗 -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker v-if="clickType == 'sblx'" :columns="columns" @cancel="isShowCommonPicker = false"
@confirm="onConfirm" />
</van-popup>
</div>
</template>
<script setup>
import { baseUrl2 } from "@/utils/request.js";
import { upImage } from "@/api/common";
import ImageCompressor from "image-compressor.js";
import TopNav from "../../../components/topNav.vue";
import { getDictList, setDict } from "@/utils/dict";
import { timeValidate ,hintToast} from "@/utils/tools.js";
import { zgDetail, editDataZg, addDataZg } from "../../../api/xfgl.js";
import { useRouter, useRoute } from "vue-router";
import { ref, onMounted, reactive, defineProps } from "vue";
const urlImg = `${baseUrl2}/mosty-api/mosty-base/minio/image/download/`;
const { D_SB_SBLX } = getDictList("D_SB_SBLX");
const route = useRoute();
const router = useRouter();
const message = ref("");
const normalForm = ref({
sbsj:timeValidate(),
ssbmdm:JSON.parse(window.localStorage.getItem("userInfo")).deptList[0].deptCode
});
const isLoading = ref(false)
const isShowCommonPicker = ref(false);
const clickType = ref('');
const columns = ref([]);
const fileList = ref([])
const wpTpIdList = ref([])
const title = ref('')
onMounted(()=>{
title.value = route.query.id ? "编辑战果申报" : "新增战果申报";
if (route.query.id) {
_getDetailById(); //根据id获取详情
}
})
//根据id获取详情
function _getDetailById() {
zgDetail(route.query.id).then((res) => {
D_SB_SBLX.value.forEach((element) => {
if (element.dm == res.sblx) res.sblxmc = element.text;
});
let ids = res.sbfjid.split(',')
fileList.value = []
ids.forEach(item => {
let img = baseUrl2 + "/mosty-api/mosty-base/minio/image/download/" + item;
let obj = {
url: img,
codeId: item,
isImage: true,
status: "done",
message: "上传成功",
};
fileList.value.push(obj)
});
normalForm.value = res;
});
}
// 选择
function getCommonPop(val) {
clickType.value = val;
switch (val) {
case "sblx":
columns.value = D_SB_SBLX.value;
break;
}
isShowCommonPicker.value = true;
}
// 确定选择
function onConfirm(val) {
isShowCommonPicker.value = false;
switch (clickType.value) {
case "sblx":
normalForm.value.sblx = val.dm;
normalForm.value.sblxmc = val.zdmc;
break;
}
}
// 提交
function onSubmit(){
let params = { ...normalForm.value }
delete params.sblxmc
let ids1 = fileList.value.filter(item=>{return item.codeId}).map(v=>{return v.codeId})
let ids2 = wpTpIdList.value.join(',')
params.sbfjid = (ids1.concat(ids2)).join(',')
isLoading.value = true;
if(title.value == '编辑战果申报'){
editDataZg(params).then(res=>{
hintToast('编辑成功')
router.go(-1);
})
}else{
addDataZg(params).then(res=>{
hintToast('新增成功')
router.go(-1);
})
}
}
// 文件预览
async function afterRead(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
file.status = "uploading";
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!wpTpIdList.value.includes(res)) wpTpIdList.value.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
</script>
<style lang="less" scoped>
.infoBox {
height: 100%;
position: relative;
.cardInfo {
height: calc(100vh - 13vw);
padding: 1vw 4vw;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
height: 8vw;
width: 100%;
border-bottom: 1px solid #e5e5e5;
.mark {
margin: 0 10px;
color: red;
font-size: 16px;
}
.text {
color: #767676;
}
}
.item::before {
position: absolute;
content: "";
left: 0;
top: 50%;
transform: translateY(-50%);
background: #0066ff;
width: 2px;
height: 12px;
z-index: 11;
}
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
text-align: center;
.btn {
padding: 2vw 6vw;
background: #1989fa;
color: #fff;
border-radius: 4px;
}
}
}
::v-deep .van-field__control {
background: #f8fafd;
padding-left: 4px;
}
.fjBox {
padding: 4vw;
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,529 @@
<template>
<div style="padding-top: 13vw">
<TopNav :navTitle="title" />
<van-form @submit="onSubmit" style="height: calc(100vh - 13vw);">
<div class="infoBox">
<ul class="cardInfo">
<li class="item">
<van-field v-model="normalForm.xfsj" required name="时间" is-link readonly label="时间" placeholder="点击设置"
input-align="right" :rules="[{ required: true, message: '请选择时间' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.xfzzXm" required name="巡访主责人" is-link readonly label="巡访主责人"
placeholder="点击设置" input-align="right" :rules="[{ required: true, message: '请选择巡访主责人' }]"
@click="showDialogfn('xfzz')" />
</li>
<li class="item">
<van-field v-model="normalForm.xfzzSfzh" required name="身份证号" readonly input-align="right" label="身份证号"
:rules="[{ required: true, message: '请输入组长身份证号' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.xfmj" name="巡访同行人(民警)" is-link label-width="108px" readonly label="巡访同行人(民警)"
placeholder="点击设置" input-align="right" @click="showDialogfn('xfmj')" />
</li>
<li class="item">
<van-field v-model="normalForm.xffj" name="巡访同行人(辅警)" is-link label-width="108px" readonly label="巡访同行人(辅警)"
placeholder="点击设置" input-align="right" @click="showDialogfn('xffj')" />
</li>
<li class="item">
<van-field v-model="normalForm.sfdw" name="巡访单位" is-link readonly label="巡访单位" placeholder="点击设置"
input-align="right" required :rules="[{ required: true, message: '请选择巡访单位' }]"
@click="showDialogfn('xfdw')" />
</li>
<li class="item">
<van-field v-model="normalForm.dz" required name="巡访地点" label="巡访地点" placeholder="输入地点" input-align="right"
:rules="[{ required: true, message: '请选择巡访地点' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.xflxmc" required name="巡访类型" is-link readonly label="巡访类型" placeholder="点击设置"
input-align="right" :rules="[{ required: true, message: '请选择巡访类型' }]" @click="getCommonPop('xflx')" />
</li>
<li class="item">
<van-field v-model="normalForm.rwztmc" name="任务状态" is-link readonly label="任务状态" placeholder="选择任务状态"
input-align="right" @click="getCommonPop('rwzt')" />
</li>
<li class="item">
<van-field name="巡访内容" @click="showDialogfn('xfnr')" readonly label="巡访内容" />
</li>
<div class="textarea">
<van-field placeholder="请输相关内容" v-model="normalForm.xfnr" rows="4" autosize maxlength="500" show-word-limit
type="textarea"></van-field>
</div>
<li class="item">
<div class="itemlabel"><span class="mark"></span>拍照打卡</div>
</li>
<!-- 附件 -->
<div class="fjBox">
<van-uploader v-model="fileList" multiline :max-count="3" :after-read="afterRead"
:before-delete="deleteFj"></van-uploader>
</div>
<li class="item">
<van-field v-model="sbsj" required name="申报时间" readonly label="申报时间" input-align="right"
:rules="[{ required: true, message: '请选择时间' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.sblxmc" required name="申报类型" is-link readonly label="申报类型" placeholder="点击设置"
input-align="right" :rules="[{ required: true, message: '请选择申报类型' }]" @click="getCommonPop('sblx')" />
</li>
<li class="item">
<van-field required name="申报原因" readonly label="申报原因" />
</li>
<van-field placeholder="请输入相关内容" v-model="normalForm.sbyy" rows="4" autosize accept=".txt,.png,.zip,jpg,jpeg"
maxlength="500" show-word-limit type="textarea"></van-field>
<li class="item">
<div class="itemlabel"><span class="mark"></span>添加附件</div>
</li>
<!-- 附件 -->
<div class="fjBox">
<van-uploader v-model="fjData" multiline :max-count="3" accept="" :after-read="afterReadFjsb"
:before-delete="beforeDeletefJ">
</van-uploader>
</div>
<li class="item">
<div class="itemlabel"><span class="mark"></span>附件列表</div>
</li>
<div class="fjBox">
<div v-for="(it, idex) in fileBoxs" :key="idex" class="listitem">
<span class="name">{{ it.name }}</span>
<span> <van-icon name="close" color="#ff0000" @click="deletDate(it, idex)"></van-icon> </span>
</div>
</div>
</ul>
<div class="footer">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="登录中...">提交</van-button>
</div>
</div>
</van-form>
<!-- 弹窗 -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="columns" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
<!-- 弹窗 -->
<Select v-if="showSelect" :checked="r_checked" :selectType="selectType" :show="showSelect"
:checkedList="hasCheckedList" @update:cancel="showSelect = false" @update:confirm="onComfirm"
:key="selectIndex" />
</div>
</template>
<script setup>
import { baseUrl2 } from "@/utils/request.js";
import ImageCompressor from "image-compressor.js";
import { upImage } from "@/api/common";
import Select from "./components/Select.vue";
import { hintToast, timeValidate } from "../../../utils/tools";
import { rwDetail, eidtRw, addRw } from "../../../api/xfgl.js";
import TopNav from "../../../components/topNav.vue";
import { useRouter, useRoute } from "vue-router";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, onMounted, reactive, defineProps, nextTick } from "vue";
const { D_BZ_XFLX, D_BZ_RWZT, D_SB_SBLX } = getDictList("D_BZ_XFLX", "D_BZ_RWZT", "D_SB_SBLX");
const route = useRoute();
const router = useRouter();
const fileList = ref([]);
const fjData = ref([]) //附件
const normalForm = ref({
xfsj: timeValidate(),
sbsj: timeValidate(),
rwztmc: '正常',
rwzt: 0,
ssbmdm: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0].deptCode
});
const sbsj = timeValidate()
const title = ref("新增巡防任务");
const clickType = ref(""); //点击选择
const columns = ref([]);
const time = ref();
const isShowCommonPicker = ref(false);
const showSelect = ref(false);
const selectType = ref(""); //选择的类型
const r_checked = ref(""); //选择的类型
const hasCheckedList = ref([]); //选择的类型
const selectIndex = ref(1); //选择器组件KEY
const wpTpIdList = ref([]);
const sbTpIdList = ref([]);
const isLoading = ref(false)
const fileBoxs = ref([]) //附件其他类型
const urlImg = `${baseUrl2}/mosty-api/mosty-base/minio/image/download/`;
const dataList = reactive({
fzrList: [], //巡访组长
nrList: [], //巡访内容
mjList: [], //组员民警
fjList: [], //组员辅警
xfdwList: [],//巡访单位
});
onMounted(() => {
title.value = route.query.id ? "编辑战果申报" : "新增战果申报";
if (route.query.id) {
nextTick(() => {
_getDetailById(); //根据id获取详情
});
}
});
// 打开弹窗
function showDialogfn(type) {
selectType.value = type; //选取的类型
showSelect.value = true; //打开弹窗
hasCheckedList.value = [];
r_checked.value = "";
selectIndex.value++;
hasChooseData();
}
// 已经选取的数据回显
function hasChooseData() {
switch (selectType.value) {
case "xfzz":
if (!dataList.fzrList.length) return false;
r_checked.value = dataList.fzrList[0].key;
break;
case "xfnr":
if (!dataList.nrList.length) return false;
r_checked.value = dataList.nrList[0].key;
break;
case "xfmj":
if (!dataList.mjList.length) return false;
hasCheckedList.value = dataList.mjList.map((item) => {
return item.key;
});
break;
case "xffj":
if (!dataList.fjList.length) return false;
hasCheckedList.value = dataList.fjList.map((item) => {
return item.key;
});
break;
case "xfdw":
if (!dataList.xfdwList.length) return false;
hasCheckedList.value = dataList.xfdwList.map((item) => {
return item.key;
});
break;
}
}
//确认选择
function onComfirm(val) {
if (val.length <= 0) return false;
switch (selectType.value) {
case "xfzz":
dataList.fzrList = val; //选取的负责人数据
normalForm.value.xfzzXm = val[0].xm;
normalForm.value.xfzzSfzh = val[0].sfzh;
break;
case "xfnr":
dataList.nrList = val; //巡防内容
normalForm.value.xfnr = val[0].nr;
break;
case "xfmj":
dataList.mjList = val; //选取的组员民警
normalForm.value.xfmj = val.map(v => { return v.xm }).join(',')
break;
case "xffj":
dataList.fjList = val; //选取的组员辅警
normalForm.value.xffj = val.map(v => { return v.xm }).join(',')
break;
case "xfdw":
dataList.xfdwList = val; //选取的单位
normalForm.value.sfdw = val.map(v => { return v.dwmc }).join(',')
normalForm.value.dz = val[0].dz
break;
}
}
//根据id获取详情
function _getDetailById() {
rwDetail(route.query.id).then((res) => {
let List = JSON.parse(res.xfzy);
dataList.mjList = List.filter(v => { return v.fl == '01' })
res.xfmj = dataList.mjList.map(it => { return it.xm }).join(',')
dataList.fjList = List.filter(v => { return v.fl == '02' })
res.xffj = dataList.fjList.map(it => { return it.xm }).join(',')
dataList.xfdwList = JSON.parse(res.xfdw)
res.sfdw = dataList.xfdwList.map(it => { return it.dwmc }).join(',')
res.dz = dataList.xfdwList.length > 0 ? dataList.xfdwList[0].dz : '';
let ids = res.xfzp ? res.xfzp.split(',') : []
fileList.value = []
wpTpIdList.value = []
ids.forEach(item => {
wpTpIdList.value.push(item)
let img = baseUrl2 + "/mosty-api/mosty-base/minio/image/download/" + item;
let obj = {
url: img,
codeId: item,
isImage: true,
status: "done",
message: "上传成功",
};
fileList.value.push(obj)
});
fjData.value = []
fileBoxs.value = []
sbTpIdList.value = []
let fjarr = res.sbfj ? JSON.parse(res.sbfj) : [];
let imgType = ['image/png', 'image/jpeg', 'image/jpg']
fjarr.forEach(item => {
sbTpIdList.value.push(item)
if (imgType.includes(item.type)) {
let img1 = baseUrl2 + "/mosty-api/mosty-base/minio/image/download/" + item.id;
let obj1 = {
url: img1,
codeId: item.id,
isImage: true,
status: "done",
message: "上传成功",
};
fjData.value.push(obj1)
} else {
fileBoxs.value.push(item)
}
})
normalForm.value = res;
setTimeout(() => {
D_SB_SBLX.value.forEach((element) => {
if (element.dm == res.sblx) normalForm.value.sblxmc = element.text;
});
D_BZ_XFLX.value.forEach((element) => {
if (element.dm == res.xflx) normalForm.value.xflxmc = element.text;
});
D_BZ_RWZT.value.forEach((element) => {
if (element.dm == res.rwzt) normalForm.value.rwztmc = element.text;
});
}, 500)
});
}
// 删除其他文件
function deletDate(it, idex) {
fileBoxs.value.splice(idex, 1)
let index = sbTpIdList.value.findIndex(item => {
return item.id == it.id
})
if (index != -1) sbTpIdList.value.splice(index, 1)
}
// 打开弹窗
function getCommonPop(val) {
clickType.value = val;
switch (val) {
case "xflx":
columns.value = D_BZ_XFLX.value;
break;
case "rwzt":
columns.value = D_BZ_RWZT.value;
break;
case "sblx":
columns.value = D_SB_SBLX.value;
break;
}
isShowCommonPicker.value = true;
}
// 确定选择
function onConfirm(val) {
isShowCommonPicker.value = false;
switch (clickType.value) {
case "xflx":
normalForm.value.xflxmc = val.text;
normalForm.value.xflx = val.dm;
break;
case "rwzt":
normalForm.value.rwztmc = val.text;
normalForm.value.rwzt = val.dm;
break;
case "sblx":
normalForm.value.sblx = val.dm;
normalForm.value.sblxmc = val.zdmc;
break;
}
}
// 删除神宝宝附件
const beforeDeletefJ = (url, val) => {
fjData.value.splice(val.index, 1)
let index = sbTpIdList.value.findIndex(item => {
return item.id == url.codeId
})
if (index != -1) sbTpIdList.value.splice(index, 1)
}
// 申报附件
async function afterReadFjsb(file) {
file.message = "上传中...";
let imgType = ['image/png', 'image/jpeg', 'image/jpg']
let type = file.file.type;
const data = new FormData();
if (imgType.includes(type)) {
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
data.append("file", fileData);
} else {
data.append("file", file.file);
}
file.status = "uploading";
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
sbTpIdList.value.push({ id: res, type: type, name: file.file.name });
});
}
// 删除照片上传
const deleteFj = (url, val) => {
fileList.value.splice(val.index, 1)
wpTpIdList.value.splice(val.index, 1)
}
// 文件预览
async function afterRead(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
file.status = "uploading";
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!wpTpIdList.value.includes(res)) wpTpIdList.value.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
// 提交
function onSubmit() {
let arr = [...dataList.mjList, ...dataList.fjList]
let params = {
...normalForm.value,
xfzy: JSON.stringify(arr),
xfdw: JSON.stringify(dataList.xfdwList),
}
params.xfzp = wpTpIdList.value.join(',')
params.sbfj = JSON.stringify(sbTpIdList.value)
isLoading.value = true;
if (title.value == '编辑战果申报') {
eidtRw(params).then(res => {
hintToast('编辑成功')
router.go(-1);
}).catch(() => {
isLoading.value = false
})
} else {
addRw(params).then(res => {
hintToast('新增成功')
router.go(-1);
}).catch(() => {
isLoading.value = false
})
}
}
</script>
<style lang="less" scoped>
.infoBox {
height: 100%;
position: relative;
.cardInfo {
height: calc(100vh - 13vw);
padding: 1vw 4vw;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
border-bottom: 1px solid #e5e5e5;
.itemlabel {
height: 30px;
line-height: 30px;
font-size: 14px;
color: #646566;
}
.mark {
margin: 0 10px;
font-size: 16px;
}
.text {
color: #767676;
}
}
.item::before {
position: absolute;
content: "";
left: 0;
top: 32%;
background: #0066ff;
width: 2px;
height: 12px;
z-index: 11;
}
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
text-align: center;
.btn {
padding: 2vw 6vw;
background: #1989fa;
color: #fff;
border-radius: 4px;
}
}
}
.textarea {
::v-deep .van-field__control {
background: #f8fafd;
padding-left: 4px;
}
}
.fjBox {
padding: 4vw;
box-sizing: border-box;
.listitem {
display: flex;
justify-content: space-between;
margin-bottom: 4vw;
font-size: 16px;
.name {
color: blue;
}
}
}
</style>

View File

@ -0,0 +1,213 @@
<template>
<div style="padding-top: 13vw">
<TopNav :navTitle="title" />
<van-form @submit="onSubmit" style="height: calc(100vh - 13vw);">
<div class="infoBox">
<ul class="cardInfo">
<li class="item">
<van-field v-model="normalForm.xm" required name="姓名" label="姓名" :disabled="disabled" placeholder="输入姓名"
input-align="right" :rules="[{ required: true, message: '请输入姓名' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.sfzh" required :disabled="disabled" name="身份证号" label="身份证号"
placeholder="输入身份证号" input-align="right" :rules="sfzhRuls" />
</li>
<li class="item">
<van-field v-model="normalForm.xbmc" required :disabled="disabled" name="性别" label="性别" placeholder="请选择性别"
input-align="right" readonly :rules="[{ required: true, message: '请选择性别' }]"
@click="getCommonPop('sex')" />
</li>
<li class="item">
<van-field v-model="normalForm.csrq" :disabled="disabled" required name="出生日期" label="出生日期"
placeholder="点击设置" input-align="right" :rules="[{ required: true, message: '请选择出生日期' }]"
@click="getCommonPop('time')" />
</li>
<li class="item">
<van-field v-model="normalForm.lxdh" required name="联系电话" label="联系电话" placeholder="请输入联系电话"
input-align="right" :rules="lxdhRuls" />
</li>
<li class="item">
<van-field v-model="normalForm.xxdz" required name="现住址" label="现住址" placeholder="请输入住址名称"
input-align="right" :rules="[{ required: true, message: '请输入住址名称' }]" />
</li>
<li class="item">
<van-field name="备注" readonly label="备注" />
</li>
<div class="textarea">
<van-field placeholder="请输备注" v-model="normalForm.bz" rows="4" autosize maxlength="500" show-word-limit
type="textarea"></van-field>
</div>
</ul>
<div class="footer">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="登录中...">提交</van-button>
</div>
</div>
</van-form>
</div>
<!-- 弹窗 -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker v-if="clickType == 'sex'" :columns="columns" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
<van-datetime-picker @cancel="isShowCommonPicker = false" @confirm="onConfirm" v-if="clickType == 'time'" v-model="time" type="date" title="选择年月日">
</van-datetime-picker>
</van-popup>
</template>
<script setup>
import { IdCardValidator, phoneValidator } from "../../../utils/rules.js"
import { cyryDetail, editDetail, addDetail } from "../../../api/xfgl.js";
import { useRouter, useRoute } from "vue-router";
import TopNav from "../../../components/topNav.vue";
import { hintToast, timeValidate } from "../../../utils/tools";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, onMounted, reactive, defineProps } from "vue";
const { D_BZ_XB } = getDictList("D_BZ_XB");
const route = useRoute();
const router = useRouter();
const message = ref("");
const normalForm = ref({});
const columns = ref([]);
const time = ref();
const isLoading = ref(false);
const disabled = ref(false)
const isShowCommonPicker = ref(false);
const clickType = ref(""); //点击选择
const title = ref("新增人员");
const sfzhRuls = ref([
{ required: true, message: '身份证号码不能为空', trigger: 'onChange/onBlur' },
{ validator: (value) => { return IdCardValidator(value) }, trigger: 'onChange/onBlur' }
])
const lxdhRuls = ref([
{ required: true, message: '联系电话不能为空', trigger: 'onChange/onBlur' },
{ validator: (value) => { return phoneValidator(value) }, trigger: 'onChange/onBlur' }
])
onMounted(() => {
title.value = route.query.id ? "编辑人员" : "新增人员";
disabled.value = route.query.id ? true : false;
if (route.query.id) _getDetailById(); //根据id获取详情
});
//根据id获取详情
function _getDetailById() {
cyryDetail(route.query.id).then((res) => {
normalForm.value = res;
D_BZ_XB.value.forEach((element) => {
if (element.dm == res.xb) normalForm.value.xbmc = element.text;
});
});
}
// 选择性别
function getCommonPop(val) {
if (disabled.value) return false;
clickType.value = val;
switch (val) {
case "sex":
columns.value = D_BZ_XB.value;
break;
}
isShowCommonPicker.value = true;
}
// 确定选择
function onConfirm(val) {
isShowCommonPicker.value = false;
switch (clickType.value) {
case "sex":
normalForm.value.xbmc = val.text;
normalForm.value.xb = val.dm;
break;
case "time":
normalForm.value.csrq = timeValidate(val, "ymd");
break;
}
}
// 提交
function onSubmit() {
isLoading.value = true;
delete normalForm.value.xbmc
if (title.value == '编辑人员') {
editDetail(normalForm.value).then(res => {
hintToast('编辑成功')
router.go(-1);
})
} else {
addDetail(normalForm.value).then(res => {
hintToast('新增成功')
router.go(-1);
})
}
}
</script>
<style lang="less" scoped>
.infoBox {
height: 100%;
position: relative;
.cardInfo {
height: calc(100vh - 13vw);
padding: 1vw 4vw;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
// height: 8vw;
width: 100%;
border-bottom: 1px solid #e5e5e5;
.mark {
margin: 0 10px;
color: red;
font-size: 16px;
}
.text {
color: #767676;
}
}
.item::before {
position: absolute;
content: "";
left: 0;
top: 20%;
// transform: translateY(-50%);
background: #0066ff;
width: 2px;
height: 12px;
z-index: 11;
}
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
text-align: center;
.btn {
padding: 2vw 6vw;
background: #1989fa;
color: #fff;
border-radius: 4px;
}
}
}
.textarea {
::v-deep .van-field__control {
background: #f8fafd;
padding-left: 4px;
}
}
.fjBox {
padding: 4vw;
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,348 @@
<template>
<div style="padding-top: 13vw">
<TopNav :navTitle="title" />
<van-form @submit="onSubmit" style="height: calc(100vh - 13vw);">
<div class="infoBox">
<ul class="cardInfo">
<li class="item">
<van-field v-model="normalForm.dwlxmc" required name="单位类型" label="单位类型" :disabled="disabled"
placeholder="请选择单位类型" input-align="right" readonly is-link
:rules="[{ required: true, message: '请选择单位类型' }]" @click="getCommonPop('dwlx')" />
</li>
<li class="item">
<van-field v-model="normalForm.dwmc" required name="单位名称" label="单位名称" :disabled="disabled"
placeholder="请输入单位名称" input-align="right" :rules="[{ required: true, message: '请输入单位名称' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.dwflmc" required name="单位分类" label="单位分类" is-link :disabled="disabled"
placeholder="请选择单位分类" input-align="right" readonly :rules="[{ required: true, message: '请选择单位分类' }]"
@click="getCommonPop('dwfl')" />
</li>
<li class="item">
<van-field v-model="normalForm.lxdh" required :disabled="disabled" name="联系电话" label="联系电话"
placeholder="请输入联系电话" input-align="right" :rules="[{ required: true, message: '请输入联系电话' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.dws" required :disabled="disabled" name="单位数" label="单位数"
placeholder="请输入单位数" input-align="right" type="digit" :rules="[{ required: true, message: '请输入单位数' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.addreess" required :disabled="disabled" name="地址" label="地址" readonly />
<div @click="addDz"><van-icon name="location" color="#4788e1" size="6vw" /></div>
</li>
<ul>
<li class="item-li" v-for="(it, idx) in dzList" :key="idx">
<span class="text">地址{{ idx + 1 }}</span>
<span class="info"><van-field v-model="it.dz" /></span>
<span @click="deletItem('dz', idx)" class="iconClose"><van-icon name="close" color="red" size="6vw" /></span>
</li>
</ul>
<li class="item">
<van-field v-model="normalForm.addreess" required :disabled="disabled" name="从业人员" label="从业人员" readonly />
<div @click="showDialogfn('cyry')"><van-icon name="add-o" color="#4788e1" size="6vw" /></div>
</li>
<ul>
<li class="item-li" v-for="(it, idx) in dataList.ryList" :key="idx">
<span class="text">人员</span>
<span class="info"><van-field readonly v-model="it.info" /></span>
<span @click="deletItem('ry', idx)" class="iconClose"><van-icon name="close" color="red" size="6vw" /></span>
</li>
</ul>
<li class="item">
<van-field name="备注" readonly label="备注" />
</li>
<div class="textarea">
<van-field placeholder="请输备注" v-model="normalForm.bz" :disabled="disabled" rows="4" autosize maxlength="500" show-word-limit type="textarea"></van-field>
</div>
</ul>
<div class="footer">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner" loading-text="登录中...">提交</van-button>
</div>
</div>
</van-form>
</div>
<!-- 弹窗 -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker v-if="clickType == 'dwlx' || clickType == 'dwfl'" :columns="columns"
@cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
<!-- 弹窗 -->
<Select v-if="showSelect" :checked="r_checked" :selectType="selectType" :show="showSelect"
:checkedList="hasCheckedList" @update:cancel="showSelect = false" @update:confirm="onComfirm" :key="selectIndex" />
</template>
<script setup>
import Select from "./components/Select.vue";
import { dwglDetail, editDwgl, addDwgl } from "../../../api/xfgl.js";
import { useRouter, useRoute } from "vue-router";
import TopNav from "../../../components/topNav.vue";
import { hintToast, timeValidate } from "../../../utils/tools";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, onMounted, reactive, defineProps } from "vue";
const { D_BZ_DWLX, D_BZ_DWFL } = getDictList("D_BZ_DWLX", "D_BZ_DWFL");
const route = useRoute();
const router = useRouter();
const message = ref("");
const normalForm = ref({
ssbmdm: JSON.parse(window.localStorage.getItem("userInfo")).deptList[0].deptCode
});
const columns = ref([]);
const isLoading = ref(false);
const disabled = ref(false)
const isShowCommonPicker = ref(false);
const clickType = ref(""); //点击选择
const showSelect = ref(false);
const r_checked = ref(""); //选择的类型
const hasCheckedList = ref([]); //选择的类型
const selectIndex = ref(1); //选择器组件KEY
const title = ref("新增单位");
const dzList = ref([])
const selectType = ref('')
const dataList = reactive({
ryList: [], //人员
});
onMounted(() => {
title.value = route.query.id ? "编辑单位" : "新增单位";
// disabled.value = route.query.id ? true : false;
if (route.query.id) _getDetailById(); //根据id获取详情
});
//根据id获取详情
function _getDetailById() {
dwglDetail(route.query.id).then((res) => {
normalForm.value = res;
D_BZ_DWLX.value.forEach((element) => {
if (element.dm == res.dwlx) normalForm.value.dwlxmc = element.text;
});
D_BZ_DWFL.value.forEach((element) => {
if (element.dm == res.dwfl) normalForm.value.dwflmc = element.text;
});
let list = res.cyry ? JSON.parse(res.cyry) : []
dataList.ryList = list.map(item => {
if (!item.info) item.xm + '(' + item.sfzh + ')'
return item
})
hasCheckedList.value = dataList.ryList.map((item) => {
return item.key;
});
dzList.value = []
for (let key in res) {
if (key.search('dz') != -1) dzList.value.push({ dz: res[key] });
}
});
}
// 新增地址
function addDz() {
if (disabled.value) return false;
dzList.value.push({ dz: '' })
}
// 打开弹窗
function showDialogfn(type) {
if (disabled.value) return false;
selectType.value = type; //选取的类型
showSelect.value = true; //打开弹窗
hasCheckedList.value = [];
r_checked.value = "";
selectIndex.value++;
hasChooseData();
}
// 已经选取的数据回显
function hasChooseData() {
switch (selectType.value) {
case "cyry":
if (!dataList.ryList.length) return false;
hasCheckedList.value = dataList.ryList.map((item) => {
return item.key;
});
break;
}
}
//确认选择
function onComfirm(val) {
if (val.length <= 0) return false;
switch (selectType.value) {
case "cyry":
dataList.ryList = val.map(v => {
v.info = v.xm + '(' + v.sfzh + ')'
return v
}); //选取的组员
normalForm.value.cyry = JSON.stringify(val)
break;
}
}
// 选择
function getCommonPop(val) {
if (disabled.value) return false;
clickType.value = val;
switch (val) {
case "dwlx":
columns.value = D_BZ_DWLX.value;
break;
case "dwfl":
columns.value = D_BZ_DWFL.value;
break;
}
isShowCommonPicker.value = true;
}
// 确定选择
function onConfirm(val) {
isShowCommonPicker.value = false;
switch (clickType.value) {
case "dwlx":
normalForm.value.dwlxmc = val.text;
normalForm.value.dwlx = val.dm;
break;
case "dwfl":
normalForm.value.dwflmc = val.text;
normalForm.value.dwfl = val.dm;
break;
}
}
// 删除选择的人员-地址
function deletItem(type, index) {
if (disabled.value) return false;
switch (type) {
case 'dz':
dzList.value.splice(index, 1)
break;
case 'cyry':
dataList.ryList.splice(index, 1);
hasCheckedList.value = dataList.ryList.map((item) => {
return item.key;
});
normalForm.value.cyry = JSON.stringify(dataList.ryList)
break;
}
}
// 提交
function onSubmit() {
let pramas = {
...normalForm.value
}
dzList.value.forEach((item, idex) => {
if (idex > 0) {
pramas['dz' + idex] = item.dz
} else {
pramas['dz'] = item.dz
}
})
isLoading.value = true;
if (title.value == '编辑单位') {
editDwgl(pramas).then(res => {
hintToast('编辑成功')
router.push({ path: "/Declaration" });
})
} else {
addDwgl(pramas).then(res => {
hintToast('新增成功')
router.push({ path: "/Declaration" });
})
}
}
</script>
<style lang="less" scoped>
.infoBox {
height: 100%;
position: relative;
.cardInfo {
height: calc(100vh - 13vw);
padding: 1vw 4vw;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
// height: 8vw;
width: 100%;
border-bottom: 1px solid #e5e5e5;
.mark {
margin: 0 10px;
color: red;
font-size: 16px;
}
.text {
color: #767676;
}
}
.item::before {
position: absolute;
content: "";
left: 0;
top: 50%;
transform: translateY(-50%);
background: #0066ff;
width: 2px;
height: 12px;
z-index: 11;
}
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
text-align: center;
.btn {
padding: 2vw 6vw;
background: #1989fa;
color: #fff;
border-radius: 4px;
}
}
}
.item-li {
display: flex;
justify-content: space-between;
padding: 2vw 4vw;
box-sizing: border-box;
.info {
margin: 0 10px;
flex: 1;
::v-deep .van-cell__value {
background: #e5eff5;
padding-left: 10px;
box-sizing: border-box;
}
::v-deep .van-cell {
padding: 0;
}
}
.text {
color: #8b8b94;
width: 16vw;
}
.iconClose {
display: inline-block;
width: 6vw;
}
}
.textarea {
::v-deep .van-field__control {
background: #f8fafd;
padding-left: 4px;
}
}
</style>

View File

@ -0,0 +1,386 @@
<template>
<div style="padding-top: 13vw">
<TopNav :navTitle="title" />
<van-form @submit="onSubmit" style="height: calc(100vh - 13vw);">
<div class="infoBox">
<ul class="cardInfo">
<li class="item">
<van-field v-model="normalForm.xfsj" required name="时间" is-link readonly label="时间" placeholder="点击设置"
input-align="right" :rules="[{ required: true, message: '请选择时间' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.xfzzXm" required name="巡访主责人" is-link readonly label="巡访主责人"
placeholder="点击设置" input-align="right" :rules="[{ required: true, message: '请选择巡访主责人' }]"
@click="showDialogfn('xfzz')" />
</li>
<li class="item">
<van-field v-model="normalForm.xfzzSfzh" required name="身份证号" readonly input-align="right" label="身份证号"
:rules="[{ required: true, message: '请输入组长身份证号' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.xfmj" name="巡访同行人(民警)" is-link label-width="108px" readonly label="巡访同行人(民警)"
placeholder="点击设置" input-align="right" @click="showDialogfn('xfmj')" />
</li>
<li class="item">
<van-field v-model="normalForm.xffj" name="巡访同行人(辅警)" is-link label-width="108px" readonly label="巡访同行人(辅警)"
placeholder="点击设置" input-align="right" @click="showDialogfn('xffj')" />
</li>
<li class="item">
<van-field v-model="normalForm.sfdw" name="巡访单位" is-link readonly label="巡访单位" placeholder="点击设置"
input-align="right" required :rules="[{ required: true, message: '请选择巡访单位' }]"
@click="showDialogfn('xfdw')" />
</li>
<li class="item">
<van-field v-model="normalForm.dz" required name="巡访地点" label="巡访地点" placeholder="输入地点" input-align="right"
:rules="[{ required: true, message: '请选择巡访地点' }]" />
</li>
<li class="item">
<van-field v-model="normalForm.xflxmc" required name="巡访类型" is-link readonly label="巡访类型" placeholder="点击设置"
input-align="right" :rules="[{ required: true, message: '请选择巡访类型' }]" @click="getCommonPop('xflx')" />
</li>
<li class="item">
<van-field v-model="normalForm.rwztmc" name="任务状态" is-link readonly label="任务状态" placeholder="选择任务状态"
input-align="right" @click="getCommonPop('rwzt')" />
</li>
<li class="item">
<van-field name="巡访内容" @click="showDialogfn('xfnr')" readonly label="巡访内容" />
</li>
<div class="textarea">
<van-field placeholder="请输相关内容" v-model="normalForm.xfnr" rows="4" autosize maxlength="500" show-word-limit type="textarea"></van-field>
</div>
<li class="item">
<div><span class="mark"></span>拍照打卡</div>
</li>
<!-- 附件 -->
<div class="fjBox">
<van-uploader v-model="fileList" multiline :max-count="3" :after-read="afterRead"></van-uploader>
</div>
</ul>
<div class="footer">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner" loading-text="登录中...">提交</van-button>
</div>
</div>
</van-form>
<!-- 弹窗 -->
<van-popup v-model:show="isShowCommonPicker" round position="bottom">
<van-picker :columns="columns" @cancel="isShowCommonPicker = false" @confirm="onConfirm" />
</van-popup>
<!-- 弹窗 -->
<Select v-if="showSelect" :checked="r_checked" :selectType="selectType" :show="showSelect"
:checkedList="hasCheckedList" @update:cancel="showSelect = false" @update:confirm="onComfirm"
:key="selectIndex" />
</div>
</template>
<script setup>
import { baseUrl2 } from "@/utils/request.js";
import ImageCompressor from "image-compressor.js";
import { upImage } from "@/api/common";
import Select from "./components/Select.vue";
import { hintToast, timeValidate } from "../../../utils/tools";
import { rwDetail, eidtRw, addRw } from "../../../api/xfgl.js";
import TopNav from "../../../components/topNav.vue";
import { useRouter, useRoute } from "vue-router";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, onMounted, reactive, defineProps, nextTick } from "vue";
const { D_BZ_XFLX, D_BZ_RWZT } = getDictList("D_BZ_XFLX", "D_BZ_RWZT");
const route = useRoute();
const router = useRouter();
const fileList = ref([]);
const normalForm = ref({
xfsj: timeValidate(),
rwztmc: '正常',
rwzt: 0
});
const title = ref("新增巡防任务");
const clickType = ref(""); //点击选择
const columns = ref([]);
const time = ref();
const isShowCommonPicker = ref(false);
const showSelect = ref(false);
const selectType = ref(""); //选择的类型
const r_checked = ref(""); //选择的类型
const hasCheckedList = ref([]); //选择的类型
const selectIndex = ref(1); //选择器组件KEY
const wpTpIdList = ref([]);
const isLoading = ref(false)
const urlImg = `${baseUrl2}/mosty-api/mosty-base/minio/image/download/`;
const dataList = reactive({
fzrList: [], //巡访组长
nrList: [], //巡访内容
mjList: [], //组员民警
fjList: [], //组员辅警
xfdwList: [],//巡访单位
});
onMounted(() => {
title.value = route.query.id ? "编辑巡防任务" : "新增巡防任务";
if (route.query.id) {
nextTick(() => {
_getDetailById(); //根据id获取详情
});
}
});
// 打开弹窗
function showDialogfn(type) {
selectType.value = type; //选取的类型
showSelect.value = true; //打开弹窗
hasCheckedList.value = [];
r_checked.value = "";
selectIndex.value++;
hasChooseData();
}
// 已经选取的数据回显
function hasChooseData() {
switch (selectType.value) {
case "xfzz":
if (!dataList.fzrList.length) return false;
r_checked.value = dataList.fzrList[0].key;
break;
case "xfnr":
if (!dataList.nrList.length) return false;
r_checked.value = dataList.nrList[0].key;
break;
case "xfmj":
if (!dataList.mjList.length) return false;
hasCheckedList.value = dataList.mjList.map((item) => {
return item.key;
});
break;
case "xffj":
if (!dataList.fjList.length) return false;
hasCheckedList.value = dataList.fjList.map((item) => {
return item.key;
});
break;
case "xfdw":
if (!dataList.xfdwList.length) return false;
hasCheckedList.value = dataList.xfdwList.map((item) => {
return item.key;
});
break;
}
}
//确认选择
function onComfirm(val) {
if (val.length <= 0) return false;
switch (selectType.value) {
case "xfzz":
dataList.fzrList = val; //选取的负责人数据
normalForm.value.xfzzXm = val[0].xm;
normalForm.value.xfzzSfzh = val[0].sfzh;
break;
case "xfnr":
dataList.nrList = val; //巡防内容
normalForm.value.xfnr = val[0].nr;
break;
case "xfmj":
dataList.mjList = val; //选取的组员民警
normalForm.value.xfmj = val.map(v => { return v.xm }).join(',')
break;
case "xffj":
dataList.fjList = val; //选取的组员辅警
normalForm.value.xffj = val.map(v => { return v.xm }).join(',')
break;
case "xfdw":
dataList.xfdwList = val; //选取的单位
normalForm.value.sfdw = val.map(v => { return v.dwmc }).join(',')
normalForm.value.dz = val[0].dz
break;
}
}
//根据id获取详情
function _getDetailById() {
rwDetail(route.query.id).then((res) => {
let List = JSON.parse(res.xfzy);
dataList.mjList = List.filter(v => { return v.fl == '01' })
res.xfmj = dataList.mjList.map(it => { return it.xm }).join(',')
dataList.fjList = List.filter(v => { return v.fl == '02' })
res.xffj = dataList.fjList.map(it => { return it.xm }).join(',')
D_BZ_XFLX.value.forEach((element) => {
if (element.dm == res.xflx) res.xflxmc = element.text;
});
D_BZ_RWZT.value.forEach((element) => {
if (element.dm == res.rwzt) res.rwztmc = element.text;
});
dataList.xfdwList = JSON.parse(res.xfdw)
res.sfdw = dataList.xfdwList.map(it => { return it.dwmc }).join(',')
res.dz = dataList.xfdwList.length > 0 ? dataList.xfdwList[0].dz : '';
let ids = res.xfzp.split(',')
fileList.value = []
ids.forEach(item => {
let img = baseUrl2 + "/mosty-api/mosty-base/minio/image/download/" + item;
let obj = {
url: img,
codeId: item,
isImage: true,
status: "done",
message: "上传成功",
};
fileList.value.push(obj)
});
normalForm.value = res;
});
}
// 打开弹窗
function getCommonPop(val) {
clickType.value = val;
switch (val) {
case "xflx":
columns.value = D_BZ_XFLX.value;
break;
case "rwzt":
columns.value = D_BZ_RWZT.value;
break;
}
isShowCommonPicker.value = true;
}
// 确定选择
function onConfirm(val) {
isShowCommonPicker.value = false;
switch (clickType.value) {
case "xflx":
normalForm.value.xflxmc = val.text;
normalForm.value.xflx = val.dm;
break;
case "rwzt":
normalForm.value.rwztmc = val.text;
normalForm.value.rwzt = val.dm;
break;
}
}
// 文件预览
async function afterRead(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
file.status = "uploading";
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!wpTpIdList.value.includes(res)) wpTpIdList.value.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
// 提交
function onSubmit() {
let arr = [...dataList.mjList, ...dataList.fjList]
let params = {
...normalForm.value,
xfzy: JSON.stringify(arr),
xfdw: JSON.stringify(dataList.xfdwList),
}
let ids1 = fileList.value.filter(item => { return item.codeId }).map(v => { return v.codeId })
let ids2 = wpTpIdList.value.join(',')
params.xfzp = (ids1.concat(ids2)).join(',')
isLoading.value = true;
if (title.value == '编辑巡防任务') {
eidtRw(params).then(res => {
hintToast('编辑成功')
router.go(-1);
})
} else {
addRw(params).then(res => {
hintToast('新增成功')
router.go(-1);
})
}
}
</script>
<style lang="less" scoped>
.infoBox {
height: 100%;
position: relative;
.cardInfo {
height: calc(100vh - 13vw);
padding: 1vw 4vw;
box-sizing: border-box;
overflow: hidden;
overflow-y: auto;
.item {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
border-bottom: 1px solid #e5e5e5;
.mark {
margin: 0 10px;
color: red;
font-size: 16px;
}
.text {
color: #767676;
}
}
.item::before {
position: absolute;
content: "";
left: 0;
top: 32%;
background: #0066ff;
width: 2px;
height: 12px;
z-index: 11;
}
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
height: 60px;
text-align: center;
.btn {
padding: 2vw 6vw;
background: #1989fa;
color: #fff;
border-radius: 4px;
}
}
}
.textarea {
::v-deep .van-field__control {
background: #f8fafd;
padding-left: 4px;
}
}
.fjBox {
padding: 4vw;
box-sizing: border-box;
}
</style>

View File

@ -0,0 +1,327 @@
<template>
<van-popup v-model:show="props.show" style="width: 90%">
<div class="popupTitle">{{ popupTitle }}</div>
<van-search v-model="kwd" :placeholder="placeholder" @search="onUpdate" @clear="onClear" />
<div class="check-data-box" ref="listBox" :loading="loading">
<!-- 单选 -->
<van-radio-group v-model="radioChecked" v-if="isRadio">
<van-cell-group>
<van-cell v-for="item in list.mulChooseList" clickable :key="item" :title="`${item.value}`" :border="false">
<template #right-icon>
<van-radio :name="item.key" @click="onRadionChange(item.key)" />
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
<!-- 多选 -->
<van-checkbox-group v-model="checkedLists" v-else @change="onCheckboxnChange">
<van-cell-group>
<van-cell v-for="item in list.mulChooseList" clickable :key="item" :title="`${item.value}`">
<template #right-icon>
<van-checkbox shape="square" :name="item.key" />
</template>
<template #label v-if="title === '选择警用器械'">
数量
<van-stepper v-model="item.sl" integer />
</template>
</van-cell>
</van-cell-group>
</van-checkbox-group>
<van-empty description="没有数据" image="default" v-if="list.mulChooseList.length <= 0 && showEmpty" />
</div>
<div class="popbtn-box">
<van-button style="flex: 1" type="default" @click="onCancel">取消
</van-button>
<van-button style="flex: 1" type="primary" @click="onConfirm">确定</van-button>
</div>
</van-popup>
</template>
<script setup>
import { getBBData } from "@/api/xfbbAndZbbb.js";
import { defineProps, ref, defineEmits, watch, reactive, onMounted } from "vue";
import { dateFormat, hintToast } from "@/utils/tools";
const props = defineProps({
selectType: String, //查询的类型 详情见watch 监听
show: Boolean, //是否显示
checkedList: Array, //默认选中 多选
checked: String, //单选
});
const emits = defineEmits([
"update:cancel",
"update:confirm",
"update:kwd",
"update:tabs",
"update:tag",
]);
const hasChoosZb = ref([]);
const listBox = ref(null);
const page = ref(1);
const size = ref(10);
const total = ref(0);
const radioChecked = ref("");
const checkedLists = ref([]);
const loading = ref(false);
const finished = ref(false);
const selectObj = ref([]); //选中的数据
const tagCode = ref(""); //智能设备选中状态
const placeholder = ref(""); //占位字符
const showEmpty = ref(false);
const kwd = ref(""); //选择器关键字
const selectType = ref(""); //选择的类型
const znzbCode = ref(""); //智能装备类型筛选
const popupTitle = ref(""); //标题
const isRadio = ref(false); //是否是单选
const list = reactive({
mulChooseList: []
});
watch(
() => props.selectType,
(newValue) => {
checkedLists.value = props.checkedList;
radioChecked.value = props.checked;
},
{ immediate: true, deep: true }
);
onMounted(() => {
_getSelectData(props.selectType);
scroll();
});
//触底加载
function scroll() {
let scrollTargetBox = listBox.value;
if (!scrollTargetBox) return false;
scrollTargetBox.onscroll = (e) => {
var scrollHeight = scrollTargetBox.scrollHeight; //251
var scrollTop = scrollTargetBox.scrollTop; //0-18
var clientHeight = scrollTargetBox.clientHeight; //233
if (scrollHeight - clientHeight == scrollTop) {
//滚动条滚到最底部
if (list.mulChooseList.length < total.value) {
page.value++;
_getSelectData(props.selectType);
}
}
};
}
//获取数据
function _getSelectData(val) {
let obj = {}; //亲求路径及参数
switch (val) {
case "xfzz":
case "xfmj":
case "xffj":
popupTitle.value = "选择民警";
placeholder.value = "请输入姓名";
obj["url"] = "/mosty-jcgl/tbJcglXfll/getXfllList";
obj["jllx"] = "01";
if (val == 'xffj') {
popupTitle.value = "选择辅警";
obj["jllx"] = "02";
}
isRadio.value = false;
if (val == "xfzz") isRadio.value = true;
break;
case "xfdw":
popupTitle.value = "选择巡访单位";
placeholder.value = "请输入单位名称";
obj["url"] = "/mosty-jcgl/tbJcglXfDwgl";
isRadio.value = false;
break;
case "xfnr":
popupTitle.value = "选择巡访内容";
placeholder.value = "请输入巡访内容";
obj["url"] = "/mosty-jcgl/tbJcglXfNrmb";
isRadio.value = true;
break;
case "cyry":
popupTitle.value = "选择从业人员";
placeholder.value = "选择从业人员";
obj["url"] = "/mosty-jcgl/tbJcglXfCyry";
isRadio.value = false;
break;
}
if (Object.keys(obj).length > 0) _getBBData(obj, val);
}
//获取数据
function _getBBData(obj, type) {
//url 请求地址jllx 警力类型 有需要就传scode 智能装备筛选条件 有需要就传
let { url, jllx, xz } = obj;
loading.value = true;
let data = { keyword: kwd.value, jllx, pageCurrent: page.value, pageSize: size.value };
if (type == 'xfnr') {
data = { nr: kwd.value, pageCurrent: page.value, pageSize: size.value }
}
getBBData(url, data)
.then((res) => {
loading.value = false;
total.value = res.total;
if (jllx) {
if (res && res.records && res.records.length > 0) {
_setData(res.records, type);
} else {
showEmpty.value = true;
}
} else {
if (res && res.length > 0 && !res.records) {
_setData(res, type);
} else if (res && res.records) {
_setData(res.records, type);
} else {
showEmpty.value = true;
}
}
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
//搜索关键词
function onUpdate(val) {
page.value = 1;
list.mulChooseList = [];
_getSelectData(props.selectType);
}
//清空关键字
function onClear() {
list.mulChooseList = [];
_getSelectData(props.selectType);
}
//关闭弹窗
function onCancel() {
emits("update:cancel", false);
}
//点击单选
function onRadionChange(val) {
_backData(val);
}
//点击多选
function onCheckboxnChange(val) {
_backData(val);
}
//确认选择
function onConfirm() {
emits("update:confirm", selectObj.value);
emits("update:cancel", false);
}
//处理返回父组件数据
function _backData(val) {
if (typeof val == "string") {
//单选数据
let obj = list.mulChooseList.find((item) => {
return item.key == val;
});
selectObj.value = [obj];
} else {
//多选数据
let arr = [];
for (let i = 0; i < val.length; i++) {
for (let j = 0; j < list.mulChooseList.length; j++) {
if (val[i] == list.mulChooseList[j].key) {
arr.push(list.mulChooseList[j]);
}
}
}
selectObj.value = arr;
}
}
//设置数据
function _setData(res, type) {
for (let i = 0; i < res.length; i++) {
switch (type) {
case "xfzz":
case "xfzy":
case "xfmj":
res[i].value = `${res[i].ssbm}-${res[i].xm}`;
res[i].key = res[i].ryid;
break;
case "xffj":
res[i].value = `${res[i].ssbm}-${res[i].xm}`;
res[i].key = res[i].id;
break;
case "xfdw":
res[i].value = `${res[i].dwmc}(电话:${res[i].lxdh}`;
res[i].key = res[i].id;
break;
case "xfnr":
res[i].value = `${res[i].nr}`;
res[i].key = res[i].id;
break;
case "cyry":
res[i].value = `${res[i].xm}${res[i].sfzh}`;
res[i].key = res[i].id;
break;
}
}
if (page.value == 1) {
list.mulChooseList = res;
} else {
list.mulChooseList = list.mulChooseList.concat(res);
}
loading.value = false;
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/mixin.scss";
.popupTitle {
text-align: center;
background-color: rgb(11, 137, 247);
height: 6vh;
line-height: 6vh;
color: #fff;
}
.popbtn-box {
width: 100%;
display: flex;
justify-content: space-around;
padding-top: 2vw;
}
.check-data-box {
height: 100vw;
overflow: auto;
}
::v-deep .van-stepper__input {
width: 100px;
}
.zn_tag_select {
padding: 2vw 3.5vw;
display: flex;
align-items: center;
.squre {
display: inline-block;
width: 20px;
height: 20px;
border: 1px solid #cccccc;
border-radius: 4px;
margin-left: 10px;
text-align: center;
line-height: 20px;
}
.isActiveAll {
background: #1989fa;
}
}
::v-deep .van-cell {
align-items: flex-start;
}
::v-deep .van-cell__title,
.van-cell__value {
margin-right: 1vw;
}
</style>

View File

@ -0,0 +1,71 @@
<template>
<van-swipe-cell>
<div class="XFItem-box">
<div class="name">
{{props.data.xm}}
<span v-for="v in props.dic.D_BZ_XB " :key="v">
<span class="xb" v-if="v.dm == props.data.xb">{{v.text}}</span>
</span>
</div>
<div class="text">
身份证号<span class="mess">{{props.data.sfzh}}</span>
</div>
<div class="text">籍贯<span class="mess">{{props.data.jg}}</span></div>
<div class="text">联系电话<span class="mess">{{props.data.lxdh}}</span></div>
</div>
<template #right>
<van-button style="height: 100%; width: 60px" type="primary" @click="gotoEdit">编辑</van-button>
<van-button style="height: 100%; width: 60px" type="danger" @click="deleteItem" >删除</van-button>
</template>
</van-swipe-cell>
</template>
<script setup>
import { useRouter } from "vue-router";
import { ref, onMounted, reactive, defineEmits, defineProps } from "vue";
const emits = defineEmits(["deletedata"]);
const router = useRouter();
const props = defineProps({
data: {
type: Object,
default: {},
},
dic:{
type: Object,
default: {},
}
});
// 编辑
function gotoEdit() {
localStorage.setItem('XF_Active',0)
router.push({ path: "/Declaration/addEditCyry", query: { id: props.data.id } });
}
// 删除
function deleteItem() {
emits("deletedata", props.data.id);
}
</script>
<style lang="scss" scoped>
.XFItem-box {
padding: 3vw 4vw;
box-sizing: border-box;
background-color: #f6fafd;
position: relative;
.name {
color: #4788e1;
line-height: 6vw;
.xb {
margin: 0 14px;
}
}
.text {
color: #9f9f9f;
line-height: 6vw;
.mess {
color: #000;
}
}
}
</style>

View File

@ -0,0 +1,96 @@
<template>
<van-swipe-cell>
<div class="XFItem-box">
<div class="item-tip" :class="changeBq(props.data.dwlx)">{{ setDict(props.data.dwlx, props.dic.D_BZ_DWLX) }}</div>
<div class="text">归属单位<span class="mess">{{props.data.dwmc}}</span></div>
<div class="text">单位名称<span class="mess">{{props.data.ssbm}}</span></div>
<div class="text">单位地址<span class="mess">{{props.data.dz}}</span></div>
<div class="text">单位分类<span class="mess">{{ setDict(props.data.dwfl, props.dic.D_BZ_DWFL) }}</span></div>
</div>
<template #right>
<van-button style="height:100%;width:60px;" type="primary" @click="gotoEdit">编辑</van-button>
<van-button style="height:100%;width:60px;" type="danger" @click="deleteItem">删除</van-button>
</template>
</van-swipe-cell>
</template>
<script setup>
import { useRouter } from "vue-router";
import { setDict } from "../../../../utils/dict";
import { ref, onMounted, reactive, defineEmits,defineProps } from "vue";
const emits = defineEmits(['deletedata'])
const router = useRouter();
const props = defineProps({
data:{
type:Object,
default:{}
},
dic:{
type:Object,
default:{}
}
});
// 编辑
function gotoEdit(){
localStorage.setItem('XF_Active',1)
router.push({path: "/Declaration/addEditDw", query: {id:props.data.id}});
}
// 删除
function deleteItem(){
emits('deletedata',props.data.id)
}
// 标签
function changeBq(val){
switch(val){
case '02':
return 'green';
break;
case '01':
return 'blue';
break;
default:
return 'blue';
}
}
</script>
<style lang="scss" scoped>
.XFItem-box {
padding: 3vw 4vw;
box-sizing: border-box;
background-color: #f6fafd;
position: relative;
.item-tip {
position: absolute;
top: 0;
right: 0;
width: 60px;
height: 26px;
color: #fff;
text-align: center;
line-height: 26px;
font-size: 14px;
}
.red {
background: url("../../../../assets/images/red.png") no-repeat;
}
.green {
background: url("../../../../assets/images/green.png") no-repeat;
}
.blue {
background: url("../../../../assets/images/blue.png") no-repeat;
}
.orange {
background: url("../../../../assets/images/orange.png") no-repeat;
}
.text {
color: #9f9f9f;
line-height: 6vw;
.mess {
color: #000;
}
}
}
</style>

View File

@ -0,0 +1,81 @@
<template>
<van-swipe-cell>
<div class="XFItem-box">
<div class="time"><van-icon name="clock-o" />{{props.data.xfsj}}</div>
<div class="text">巡防主责人<span class="mess">{{props.data.xfzzXm}}</span></div>
<div class="text">巡防商铺
<span class="mess">
<span class="tag" v-for="it in props.data.xfdw" :key="it.id" style="margin:0 4px;">{{it.dwmc}}</span>
</span>
</div>
<div class="text">巡防类型
<span class="mess">{{ setDict(props.data.xflx, props.dic.D_BZ_XFLX) }}</span></div>
<div class="text text_detail">
巡防内容<span class="mess">{{props.data.xfnr}}</span>
</div>
</div>
<template #right>
<van-button style="height:100%;width:60px;" type="primary" @click="gotoEdit">编辑</van-button>
<van-button style="height:100%;width:60px;" type="danger" @click="deleteItem">删除</van-button>
</template>
</van-swipe-cell>
</template>
<script setup>
import { setDict } from "../../../../utils/dict";
import { useRouter } from "vue-router";
import { ref, onMounted, reactive, defineEmits,defineProps } from "vue";
const emits = defineEmits(['deletedata'])
const router = useRouter();
const props = defineProps({
data:{
type:Object,
default:{}
},
dic:{
type:Object,
default:{}
}
});
// 编辑
function gotoEdit(){
localStorage.setItem('XF_Active',2)
router.push({path: "/Declaration/addEditRw", query: {id:props.data.id}});
}
// 删除
function deleteItem(){
emits('deletedata',props.data.id)
}
</script>
<style lang="scss" scoped>
.XFItem-box {
padding: 3vw 4vw;
box-sizing: border-box;
background-color: #f6fafd;
position: relative;
.time {
font-size: 16px;
line-height: 5vw;
.van-icon-clock-o {
margin-right: 2vw;
font-size: 16px;
}
}
.text {
color: #9f9f9f;
line-height: 6vw;
.mess {
color: #000;
}
}
}
.tag{
border: 1px solid #5e9fdd;
border-radius: 4px;
font-size: 14px;
color: #409eff;
padding: 1px 4px;
}
</style>

View File

@ -0,0 +1,110 @@
<template>
<van-swipe-cell>
<div class="XFItem-box">
<!-- <div class="item-tip" :class="changeBq(props.data.lx)">{{props.data.ztmc}}</div> -->
<div class="time"><van-icon name="clock-o" />{{props.data.sbsj}}</div>
<div class="text">申报类型<span class="mess">{{ setDict(props.data.sblx, props.dic.D_SB_SBLX) }}</span></div>
<div class="text text_detail">
申报内容<span class="mess">{{props.data.sbyy}}</span>
</div>
</div>
<template #right>
<van-button style="height:100%;width:60px;" type="primary" @click="gotoEdit">编辑</van-button>
<van-button style="height:100%;width:60px;" type="danger" @click="deleteItem">删除</van-button>
</template>
</van-swipe-cell>
</template>
<script setup>
import { useRouter } from "vue-router";
import { setDict } from "../../../../utils/dict";
import { ref, onMounted, reactive, defineEmits,defineProps } from "vue";
const emits = defineEmits(['deletedata'])
const router = useRouter();
const props = defineProps({
data:{
type:Object,
default:{lx:0}
} ,
dic:{
type:Object,
default:{}
}
});
// 标签
function changeBq(val){
switch(val){
case 0:
return 'orange';
break;
case 1:
return 'green';
break;
case 2:
return 'red';
break;
case 3:
return 'blue';
break;
default:
return 'blue';
}
}
// 编辑
function gotoEdit(){
localStorage.setItem('XF_Active',3)
router.push({path: "/Declaration/addEdit", query: {id:props.data.id}});
}
// 删除
function deleteItem(){
emits('deletedata',props.data.id)
}
</script>
<style lang="scss" scoped>
.XFItem-box {
padding: 3vw 4vw;
box-sizing: border-box;
background-color: #f6fafd;
position: relative;
.time {
font-size: 16px;
line-height: 5vw;
.van-icon-clock-o {
margin-right: 2vw;
font-size: 16px;
}
}
.text {
color: #9f9f9f;
line-height: 6vw;
.mess {
color: #000;
}
}
.item-tip {
position: absolute;
top: 0;
right: 0;
width: 60px;
height: 26px;
color: #fff;
text-align: center;
line-height: 26px;
font-size: 14px;
}
.red {
background: url("../../../../assets/images/red.png") no-repeat;
}
.green {
background: url("../../../../assets/images/green.png") no-repeat;
}
.blue {
background: url("../../../../assets/images/blue.png") no-repeat;
}
.orange {
background: url("../../../../assets/images/orange.png") no-repeat;
}
}
</style>

View File

@ -0,0 +1,100 @@
<template>
<van-swipe-cell>
<div class="XFItem-box" @click.stop="handleItem(props.data)">
<div class="isCheck" v-show="props.data.isCheck" :class="props.data.isCheck ? 'isCheck-y':''"><van-icon name="success" color="#ffffff"></van-icon></div>
<div class="time"><van-icon name="clock-o" />{{props.data.xfsj}}</div>
<div class="text">巡防主责人<span class="mess">{{props.data.xfzzXm}}</span></div>
<div class="text">巡防商铺
<span class="mess">
<span class="tag" v-for="it in props.data.xfdw" :key="it.id" style="margin:0 4px;">{{it.dwmc}}</span>
</span>
</div>
<div class="text">巡防类型
<span class="mess">{{ setDict(props.data.xflx, props.dic.D_BZ_XFLX) }}</span></div>
<div class="text text_detail">
巡防内容<span class="mess">{{props.data.xfnr}}</span>
</div>
</div>
<template #right>
<van-button style="height:100%;width:60px;" type="primary" @click="gotoEdit">编辑</van-button>
<van-button style="height:100%;width:60px;" type="danger" @click="deleteItem">删除</van-button>
</template>
</van-swipe-cell>
</template>
<script setup>
import { setDict } from "../../../../utils/dict";
import { useRouter } from "vue-router";
import { ref, onMounted, reactive, defineEmits,defineProps } from "vue";
const emits = defineEmits(['deletedata','chooseData'])
const router = useRouter();
const props = defineProps({
data:{
type:Object,
default:{}
},
dic:{
type:Object,
default:{}
}
});
// 编辑
function gotoEdit(){
localStorage.setItem('XF_Active',3)
router.push({path: "/Declaration/addEdit", query: {id:props.data.id}});
}
// 删除
function deleteItem(){
emits('deletedata',props.data.id)
}
// 点击
function handleItem(item){
emits('chooseData',item)
}
</script>
<style lang="scss" scoped>
.XFItem-box {
padding: 3vw 4vw;
box-sizing: border-box;
background-color: #f6fafd;
position: relative;
.isCheck{
position: absolute;
top: 0vw;
right: 0vw;
width: 6vw;
height: 6vw;
border-radius: 50%;
border: 1px solid #c8c9cc;
text-align: center;
line-height: 6vw;
}
.isCheck-y{
background: #1989fa;
}
.time {
font-size: 16px;
line-height: 5vw;
.van-icon-clock-o {
margin-right: 2vw;
font-size: 16px;
}
}
.text {
color: #9f9f9f;
line-height: 6vw;
.mess {
color: #000;
}
}
}
.tag{
border: 1px solid #5e9fdd;
border-radius: 4px;
font-size: 14px;
color: #409eff;
padding: 1px 4px;
}
</style>

View File

@ -0,0 +1,515 @@
<template>
<div class="container">
<TopNav navTitle="巡访管理" :rightTitle="rightTitle" @clickRight="clickRight" />
<div>
<Tabs :checked="isActive" :list="zdModule" @onYjjb="changeTab" />
<Search placeholder="请输入关键字" v-model="keyWord" :isSx="true" @update:sx="handleSx" @update:modelValue="onSearch">
</Search>
<SxPopup :showPopup="showPopup" :list="sxList" :p_top="145" :showTime="isShowTime" @update:close="showPopup = false" @update:onConfirm="onConfirm" @reset="reset">
</SxPopup>
<!-- 列表数据 -->
<ul class="listBox" :loading="isLoading" ref="dateScroll">
<li style="margin-bottom: 2vw" v-for="(item, idex) in list" :key="idex">
<CyryItem v-if="isActive == 0" @deletedata="deletedata" :dic="{ D_BZ_XB }" :data="item" />
<DwglItem v-if="isActive == 1" @deletedata="deletedata" :dic="{ D_BZ_DWLX, D_BZ_DWFL }" :data="item" />
<RwItem v-if="isActive == 2" @deletedata="deletedata" :data="item" :dic="{ D_BZ_XFLX }" />
<ZgItem v-if="isActive == 3" @deletedata="deletedata" @chooseData="chooseData" :data="item"
:dic="{ D_BZ_XFLX }" />
<!-- <ZgItem v-if="isActive == 3" @deletedata="deletedata" :data="item" :dic="{D_SB_SBLX}" /> -->
</li>
</ul>
</div>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import Tabs from "../../../components/tabs.vue";
import Search from "../../../components/search.vue";
import SxPopup from "../../../components/SxPopupNew.vue";
import ZgItem from "./components/zgItem.vue";
import CyryItem from "./components/cyryItem.vue";
import RwItem from "./components/rwItem.vue";
import DwglItem from "./components/dwglItem.vue";
import { useRouter, useRoute } from "vue-router";
import { Dialog, Notify } from "vant";
import { getdataCyry, deletedataCyry, getdataDwgl, deletedataDw, deletedataZg, getdataRw, plsbData, deletedataRw, getdataZg } from "../../../api/xfgl.js";
import { getDictList, setDict } from "../../../utils/dict";
import { setTimeQuantum, dateFormat, hintToast } from "../../../utils/tools.js";
import { ref, reactive, watch, onMounted, nextTick } from "vue";
const { D_BZ_XB, D_BZ_DWFL, D_BZ_DWLX, D_BZ_XFLX, D_SB_SBLX } = getDictList("D_BZ_XB", "D_BZ_DWFL", "D_BZ_DWLX", "D_BZ_XFLX", "D_SB_SBLX");
const router = useRouter();
const route = useRoute();
const dateScroll = ref(null)
const isLoading = ref(false) //加载
const zdModule = ref([
{ name: "从业人员管理" },
{ name: "单位管理" },
{ name: "巡防任务" },
{ name: "战果管理" },
]);
const keyWord = ref(""); //关键字搜索
const showPopup = ref(false); //赛选条件窗口
const dateForm = ref({
sblxmc: "",
sblxdm: "",
});
const isShowTime = ref(true);
const selectList = ref([]); //选择类型
const List1 = ref([
{ label: "类型1", value: "01" },
{ label: "类型2", value: "02" },
{ label: "类型3", value: "03" },
]);
const chooseType = ref(false); //选择类型
const rightTitle = ref('新增')
const sxList = ref([]); //筛选条件数据
const pageCurrent = ref(1); //分页
const total = ref(0); //总数
const showEmpty = ref(false); //数据状态
const list = ref([]); //列表数据
const searchDate = ref({}); //查询条件
const isActive = ref(); //当前位置
const haschooseList = ref([]) //已选中的数据
onMounted(() => {
let ac = localStorage.getItem('XF_Active')
isActive.value = ac ? parseInt(ac) : 0;
rightTitle.value = isActive.value == 3 ? '批量申报' : '新增'
nextTick(() => { getOtherDate(); })
scroll()
});
//触底加载
function scroll() {
let scrollTargetBox = dateScroll.value;
if (!scrollTargetBox) return false;
scrollTargetBox.onscroll = (e) => {
var scrollHeight = scrollTargetBox.scrollHeight; //251
var scrollTop = scrollTargetBox.scrollTop; //0-18
var clientHeight = scrollTargetBox.clientHeight; //233
if (scrollHeight - clientHeight == scrollTop) {
//滚动条滚到最底部
if (list.value.length < total.value) {
pageCurrent.value++;
getOtherDate(); //根据不同类型掉接口
}
}
};
}
// 处理筛选
function handleSx() {
isShowTime.value = true;
switch (isActive.value) {
case 0: //从业人员管理
isShowTime.value = false;
sxList.value = [
{
title: "身份证号",
type: "input",
lebel: "sfzh",
placeholder: "请输入身份证号",
},
{
title: "姓名",
type: "input",
lebel: "xm",
placeholder: "请输入姓名",
},
];
break;
case 1: //单位管理
D_BZ_DWFL.value.forEach((element) => {
element.isCheck = false;
element.key = element.dm;
});
D_BZ_DWLX.value.forEach((element) => {
element.isCheck = false;
element.key = element.dm;
});
isShowTime.value = false;
sxList.value = [
{
title: "单位名称",
type: "input",
lebel: "dwmc",
placeholder: "请输入单位名称",
},
{
title: "单位分类",
isCheckBox: false,
type: "checkBox",
lebel: "dwfl",
array: D_BZ_DWFL.value,
},
{
title: "单位类型",
isCheckBox: false,
type: "checkBox",
lebel: "dwlx",
array: D_BZ_DWLX.value,
},
];
break;
case 2: //寻巡访任务
D_BZ_XFLX.value.forEach((element) => {
element.isCheck = false;
element.key = element.dm;
});
sxList.value = [
{ type: "checkBox", ...setTimeQuantum() },
{
type: "checkBox",
title: "巡防类型",
array: D_BZ_XFLX.value,
},
];
break;
case 3: //战果申报
sxList.value = [
{ type: "checkBox", ...setTimeQuantum() },
{
title: "申报类型",
type: "checkBox",
lebel: "sblx",
array: [
{ isCheck: false, name: "类型1", value: "01", key: "fl1" },
{ isCheck: false, name: "类型2", value: "02", key: "fl2" },
],
},
];
selectList.value = List1.value;
break;
}
showPopup.value = !showPopup.value;
}
// 搜索
function onConfirm(val) {
searchDate.value = val;
getOtherDate();
}
// 选择类型
function changeTab(val) {
pageCurrent.value = 1
isActive.value = val;
showPopup.value = false;
list.value = []
rightTitle.value = val == 3 ? '批量申报' : '新增'
getOtherDate() //获取列表数据
}
// 更具类型获取数据
function getOtherDate() {
switch (isActive.value) {
case 0:
_getList_Cyry(); //从业人员管理
break;
case 1:
_getList_Dwgl()//单位管理
break;
case 2:
_getList_Rw()//寻巡访任务
break;
case 3:
_getList_Rw()//寻巡访任务
// _getList_Zg()//战果申报
break;
}
}
// 获取从业人员列表
function _getList_Cyry() {
let pramas = {
pageSize: 10,
pageCurrent: pageCurrent.value,
...searchDate.value.data,
};
if (!searchDate.value.data) pramas.xm = keyWord.value;
if (searchDate.value.data && !searchDate.value.data.xm) pramas.xm = keyWord.value;
isLoading.value = true
getdataCyry(pramas).then((res) => {
let arr = res.records || [];
isLoading.value = false;
list.value = pageCurrent.value == 1 ? arr : list.value.concat(arr);
total.value = res.total;
}).catch(() => {
isLoading.value = false;
});
}
// 获取单位管理
function _getList_Dwgl() {
let pramas = {
pageSize: 10,
pageCurrent: pageCurrent.value,
...searchDate.value.data,
};
let brr = searchDate.value.list ? searchDate.value.list : []
let arr = brr.filter(item => {
return item.type == 'checkBox'
})
arr.forEach(v => {
v.array.forEach(it => {
if (it.isCheck) pramas[v.lebel] = it.value
})
})
if (!searchDate.value.data || (searchDate.value.data && !searchDate.value.data.dwmc)) {
pramas.dwmc = keyWord.value;
}
isLoading.value = true;
getdataDwgl(pramas).then((res) => {
let arr = res.records || [];
list.value = pageCurrent.value == 1 ? arr : list.value.concat(arr);
total.value = res.total;
isLoading.value = false;
}).catch(() => {
isLoading.value = false;
});
}
// 获取任务
function _getList_Rw() {
let pramas = {
pageSize: 10,
pageCurrent: pageCurrent.value,
...searchDate.value,
};
if (!searchDate.value.data) pramas.xfdw = keyWord.value;
if (searchDate.value.data && !searchDate.value.xfdw) pramas.xfdw = keyWord.value;
if (isActive.value == 2) {
pramas.xfnr = keyWord.value;
delete pramas.xfdw;
delete pramas.data;
}
if (pramas.list) {
let arr = pramas.list[0].array
let obj = arr.find(item => { return item.isCheck == true })
pramas.rwzt = obj.dm
}
isLoading.value = true;
getdataRw(pramas).then((res) => {
let arr = res.records || [];
isLoading.value = false;
arr.forEach(item => {
item.isCheck = false
item.xfdw = JSON.parse(item.xfdw)
item.xfzy = JSON.parse(item.xfzy)
})
list.value = pageCurrent.value == 1 ? arr : list.value.concat(arr);
total.value = res.total;
}).catch(() => {
isLoading.value = false;
});
}
// 点击内容
function chooseData(item) {
if (isActive.value == 3) {
list.value.forEach(it => {
if (it.id == item.id) it.isCheck = !it.isCheck;
})
haschooseList.value = list.value.filter(v => { return v.isCheck == true })
}
}
// 获取任务
function _getList_Zg() {
let pramas = {
pageSize: 10,
pageCurrent: pageCurrent.value,
};
if (searchDate.value) {
let kssj = searchDate.value.startTime
let jssj = searchDate.value.startTime
pramas.kssj = kssj ? kssj + ' 00:00:00' : '';
pramas.kssj = jssj ? jssj + ' 23:59:59' : '';
let arr = searchDate.value.list
if (arr) {
let list = arr[0].array.filter(v => { return v.isCheck == true }).map(it => { return it.value })
pramas.sblx = list.join(',');
}
}
isLoading.value = true;
getdataZg(pramas).then((res) => {
let arr = res.records || [];
isLoading.value = false;
list.value = pageCurrent.value == 1 ? arr : list.value.concat(arr);
total.value = res.total;
}).catch(() => {
isLoading.value = false;
});
}
// 点击新增
function clickRight() {
localStorage.setItem('XF_Active', isActive.value)
switch (isActive.value) {
case 0: //从业人员管理
router.push({ path: "/Declaration/addEditCyry" });
break;
case 1: //单位管理
router.push({ path: "/Declaration/addEditDw" });
break;
case 2: //寻巡访任务
router.push({ path: "/Declaration/addEditRw" });
break;
case 3: //战果申报
plsbDate()// 批量申报
// router.push({ path: "/Declaration/addEdit"});
break;
}
}
// 批量申报
function plsbDate() {
if (haschooseList.value.length == 0) return Notify({ type: 'warning', message: '请选择申报的内容' });
let isTrue = true; //判断内容是否填完
haschooseList.value.forEach(item => {
if (!item.sbyy) isTrue = false
})
if (!isTrue) Notify({ type: 'warning', message: '请核实申报数据核实原因是否填写!' });
if (isTrue) {
let ids = haschooseList.value.map(it => { return it.id })
plsbData(ids).then(res => {
hintToast('申报成功')
_getList_Rw()
})
// 查询接口
}
}
//关键字查询
function onSearch(e) {
keyWord.value = e;
pageCurrent.value = 1;
showEmpty.value = false;
getOtherDate();//更具类型获取数据
}
// 选择类型
function chooseItem(val) {
dateForm.value.sblxmc = val.label;
dateForm.value.sblxdm = val.value;
chooseType.value = false;
}
// 重置
function reset() {
dateForm.value.sblxmc = "";
dateForm.value.sblxdm = "";
searchDate.value = {};
keyWord.value = ''
getOtherDate();
}
// 删除数据
function deletedata(id) {
Dialog.confirm({
title: "提示",
message: "是否确认删除该数据!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
switch (isActive.value) {
case 0: //从业人员管理
deletedataCyry([id]).then(res => {
hintToast('删除成功')
_getList_Cyry()
})
break;
case 1: //单位管理
deletedataDw([id]).then(res => {
hintToast('删除成功')
_getList_Dwgl()
})
break;
case 2: //寻巡访任务
case 3: //战果申报
deletedataRw([id]).then(res => {
hintToast('删除成功')
_getList_Rw()
})
break;
// case 3: //战果申报
// deletedataZg([id]).then(res=>{
// hintToast('删除成功')
// _getList_Zg()
// })
// break;
}
});
}
</script>
<style lang="less" scoped>
.chooseBox {
position: relative;
display: flex;
width: 100%;
justify-content: space-between;
align-content: center;
padding: 2vw 1vw;
box-sizing: border-box;
border: 1px solid #507ce9;
border-radius: 4px;
color: #d3d0d0;
font-size: 14px;
.outBox {
width: 100%;
position: absolute;
top: 38px;
background: #fff;
padding-top: 4vw;
z-index: 999;
border-radius: 4px;
.selectBox {
width: 100%;
padding: 4vw;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 4px;
.selectItem {
padding-left: 4vw;
box-sizing: border-box;
border-bottom: 1px solid #e9e9e9;
line-height: 30px;
color: #4a4646;
}
}
.selectBox::before {
position: absolute;
content: "";
top: -4px;
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border: 10px solid;
border-color: transparent transparent #ccc transparent;
}
}
.hoverClose {
display: none;
}
}
.listBox {
height: calc(100vh - 20vw);
overflow: hidden;
overflow-y: auto;
padding: 1vw 4vw;
padding-bottom: 0;
box-sizing: border-box;
.listItem {
background-color: rgba(241, 241, 241, 0.5);
padding: 2vw;
border: 1px solid;
}
}
</style>

View File

@ -0,0 +1,40 @@
<template>
<div class="container containerLicence" style="padding-top: 13vw; box-sizing: border-box">
<TopNav navTitle="核查驾驶证" />
<van-steps direction="vertical" active-color="#969799" :active="0">
<van-step>
<p>驾驶证号: 511525199910238410</p>
<p>姓名:周正伟</p>
<p>性别:男性</p>
<p>出生日期:1999年10月23日</p>
<p>国籍:</p>
<p>准驾车型: C1</p>
<p>发证机关:川Q</p>
<p>初次领证日期:2018-08-02 00:00:00</p>
<p>有效期限:2018-08-02 00:00:00-2024-08-02 00:00:00</p>
<p>住址:</p>
<p>现住址详址:四川省高县胜天镇马鞍村2组46号</p>
</van-step>
</van-steps>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { ref, reactive, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
</script>
<style lang="scss" scoped>
</style>
<style>
.containerLicence .van-icon{
color: #148aec!important;
}
.containerLicence .van-step__line{
background-color: #148aec!important;
}
</style>

View File

@ -0,0 +1,122 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="特征信息" />
<van-collapse v-model="activeName" @change="activeJs = false" accordion>
<van-collapse-item v-for="(item, i) in D_BZ_RYTZBQLB" :key="item.id" :title="item.py">
<span :class="it.zt === 1 ? 'coll_item active' : 'coll_item'" v-for="(it, index) in item.bqList" :key="index"
@click="checkBq(i, index, it.zt)">
{{ it.tzsx }}
</span>
<div class="coll_item_js" @click="activeJs = !activeJs">
查看代码解释>>>
</div>
<span :class="it.zt === 1 ? 'coll_item active' : 'coll_item'" v-show="activeJs" class="coll_item"
v-for="(it, index) in item.bqList" :key="index">
{{ it.tzbqmc }}
</span>
</van-collapse-item>
</van-collapse>
<div class="popbtn-box">
<van-button style="width: 100%" type="primary" @click="submit">确定</van-button>
</div>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { getDictList } from "../../../utils/dict";
import { selectRytzbqList } from "../../../api/common";
import { ref, reactive, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
// 字典信息
const { D_BZ_RYTZBQLB } = getDictList("D_BZ_RYTZBQLB");
const router = useRouter();
const activeJs = ref(false);
const activeName = ref("");
const checkList = ref([]);
function checkBq(i, index, zt) {
if (zt == 1) {
D_BZ_RYTZBQLB.value[i].bqList[index].zt = 0;
} else {
D_BZ_RYTZBQLB.value[i].bqList[index].zt = 1;
}
}
function submit() {
const data = [];
D_BZ_RYTZBQLB.value.forEach((v) => {
v.bqList.forEach((v2) => {
if (v2.zt == 1) {
data.push({
tzbqdm: v2.tzbqdm,
tzbqlb: v2.tzbqlb,
tzbqmc: v2.tzbqmc,
});
}
});
});
try {
setStorage("LIST", JSON.stringify(data));
} catch (error) {
setStorage("LIST", data);
}
router.go(-1);
}
watch(
() => D_BZ_RYTZBQLB.value.length,
() => {
D_BZ_RYTZBQLB.value.forEach((item) => {
selectRytzbqList({ tzbqlb: item.dm }).then((res) => {
item.bqList = res;
item.bqList.forEach((v) => {
if (checkList.value.includes(v.tzbqdm)) {
v.zt = 1;
} else {
v.zt = 0;
}
});
});
});
}
);
onMounted(() => {
let item;
try {
item = JSON.parse(getStorage("LIST"));
} catch (error) {
item = getStorage("LIST");
}
checkList.value = item.map((item) => item.tzbqdm);
});
</script>
<style lang="scss" scoped>
.coll_item {
display: inline-block;
width: 30%;
text-align: center;
margin: 0 0 12px 3%;
padding: 2px 0;
background: #eee;
border-radius: 4px;
}
.coll_item.active {
background: #2698e4;
color: #fff;
}
.coll_item_js {
text-align: center;
color: #2698e4;
margin: 1px 0px 5px 0px;
}
.popbtn-box {
position: fixed;
bottom: 0;
right: 0;
left: 0;
}
</style>

View File

@ -0,0 +1,958 @@
<template>
<div class="container" style="padding-top: 13vw; box-sizing: border-box">
<TopNav navTitle="人员盘查" :showRight="false" :showLeft="true" />
<div class="tip_text">
盘查结果{{ ryxx.pcbqsm }}
</div>
<div class="head-nav-banner" v-if="ryxx.xm"></div>
<!-- <div class="top" v-if="ryxx.xm">
<div class="basic-info">
<div class="IDcard-info">
<div class="info-item">
<span class="bt">姓名</span>
<span>{{ ryxx.xm }}</span>
</div>
<div class="info-item">
<span class="bt">性别</span>
<span class="text">{{ setDict(ryxx.xbdm, D_BZ_XB) }}</span>&emsp;
<span class="bt">民族</span>
<span>{{ setDict(ryxx.mzdm, D_BZ_MZ) || "汉" }}</span>
</div>
<div class="info-item">
<span class="bt">出生</span>{{ ryxx.csrq }}
</div>
<div class="info-item">
<span class="bt">住址</span>
<span class="text">{{ ryxx.zzxz }}</span>
</div>
</div>
<div class="img-box">
<img :src="ryxx.baseUrl" width="75" />
</div>
</div>
<div class="sfzh">
<span class="bt">公民身份证号码</span>
<span class="idNumber">{{ ryxx.sfzh }}</span>
</div>
</div>
<div class="ry_xgxx">
<div class="contact-way">
<div>
人员标签
<span v-if="ryxx.bqxxsj">
<span class="rybq" v-for="(e, i) in ryxx.bqxxsj.split(',')" :key="i + 'bq'">{{ e }}</span>
</span>
<span style="color: #808080" v-else>暂无标签</span>
</div>
</div>
<div>
联系电话 :<span>{{ ryxx.lxdh || "未知" }}</span>
</div>
<div>从业单位 :<span>未知</span></div>
</div>
<div class="bg_ban"></div>
<div class="center" v-if="ryxx.xm">
<div class="associated-information">
<div class="sign-title">关联信息</div>
<div class="content1">
<div class="item-box" @click="goCanTrack">
<div class="ass-item-box">
<div class="circlebox bg2"></div>
<span>盘查轨迹</span>
</div>
</div>
<div class="item-box">
<div class="ass-item-box" @click="goLicence">
<div class="circlebox bg4"></div>
<span>核查驾驶证</span>
</div>
</div>
<div class="item-box" @click="goVhicol">
<div class="ass-item-box">
<div class="circlebox bg5"></div>
<span>核查机动车</span>
</div>
</div>
</div>
</div>
<div class="pick-up-information">
<div class="sign-title">采集信息</div>
<div class="pick-box">
<div class="pick-item-box pbg2" @click="goFeatureInfo">
<div>特征信息</div>
</div>
<van-badge @click="showWpdj = true" class="pick-item-box pbg3" :content="wpdjList.length">
<div>物品登记</div>
</van-badge>
</div>
</div>
<div class="vehicular">
<div class="sign-title">
乘坐车辆
<span @click="showCar" style="color: #153fba; font-size: 12px; font-weight: normal">手动输入</span>
</div>
<div class="veh-box">
<div @click="onConfirmCzcl(item)" v-for="item in clList"
:class="ryxx.pcclId === item.id ? 'active cp_item' : 'cp_item'" :key="item.id">
{{ item.text.substr(0, 2) }}
<span></span>
{{ item.text.substr(2, item.text.length - 2) }}
</div>
<div v-if="clList.length === 0" class="no-veh">暂无乘坐车辆~</div>
</div>
</div>
</div> -->
<!-- 物品登记弹窗 -->
<van-popup v-model:show="showWpdj" round :style="{ width: '90vw' }">
<van-form @submit="onSubmit">
<van-cell-groub>
<van-field name="uploader" label="物品图片">
<template #input>
<van-uploader v-model="wpTpIdList" multiple :max-count="3" :after-read="upLoadImg2" />
</template>
</van-field>
</van-cell-groub>
<van-cell-groub>
<van-field v-model="wpForm.wpms" label="物品描述" placeholder="物品描述" rows="2" maxlength="50"
show-word-limit></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field v-model="wpForm.wpsl" label="物品数量" placeholder="物品数量" type="number"
:rules="[{ required: true, message: '请填写物品数量' }]"></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field v-model="wpForm.wplx" label="物品类型" @click="showWplx = true" readonly is-link placeholder="选择物品类型"
:rules="[{ required: true, message: '请选择物品类型' }]"></van-field>
</van-cell-groub>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" size="small">提交</van-button>
</div>
</van-form>
</van-popup>
<!-- 移交弹窗 -->
<van-popup v-model:show="showYj" round :style="{ width: '90vw' }">
<van-form @submit="onYj">
<van-cell-groub>
<van-field v-model="yjForm.pcclYjdw" label="移交单位" placeholder="移交单位"
:rules="[{ required: true, message: '请填写移交单位' }]"></van-field>
</van-cell-groub>
<van-cell-groub>
<van-field v-model="yjForm.pcclYjyy" label="移交原因" placeholder="选择移交原因" @click="showYjyy = true" readonly
is-link :rules="[{ required: true, message: '请选择移交原因' }]"></van-field>
</van-cell-groub>
<div style="margin: 16px">
<van-button round block type="primary" native-type="submit" size="small">移交</van-button>
</div>
</van-form>
</van-popup>
<!-- 物品类型 -->
<van-popup round v-model:show="showWplx" position="bottom">
<van-picker :columns="D_BZ_BPCRCWP" @cancel="showWplx = false" @confirm="onConfirmWplx"></van-picker>
</van-popup>
<!-- 移交原因 -->
<van-popup round v-model:show="showYjyy" position="bottom">
<van-picker :columns="D_BZ_BPCRYYJYY" @cancel="showYjyy = false" @confirm="onConfirmYjyy"></van-picker>
</van-popup>
<div class="bg_ban"></div>
<!-- <div class="upload" v-if="ryxx.xm">
<div class="tsxx" v-show="fileList.length === 0">
点击上传图片 <br />
最多可上传 3 张照片
</div>
<van-uploader v-model="fileList" multiple :max-count="3" :after-read="afterRead">
<van-button class="up_btn" icon="plus"></van-button>
</van-uploader>
</div>
<div class="foot_ban"></div> -->
<div class="bottom-box">
<div @click="save('1')">
<img src="../../../assets/images/new/fangxing.png" />放行
</div>
<div @click="save('2')" class="yj">
<img src="../../../assets/images/new/yijiao.png" /> 移交
</div>
</div>
<van-loading type="spinner" style="padding: 20vw 0; text-align: center" v-if="loading" />
<van-empty image="network" description="错误,请稍后再试" v-if="showEmpty" />
<!-- 盘车 -->
<checkedCar ref="car" />
</div>
</template>
<script setup>
import ImageCompressor from "image-compressor.js";
import TopNav from "../../../components/topNav";
import checkedCar from "../../spsHome/components/checkCar.vue";
import { ref, reactive, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
import {
selectRy,
selectRybq,
saveBpcry,
upImage,
getClOf2h,
} from "../../../api/common";
import { getDictList, setDict } from "../../../utils/dict";
import { zlPrPc, saveNFC } from "../../../api/zlzx.js";
import { getBase64, hintToast } from "../../../utils/tools.js";
const { D_BZ_BPCRCWP, D_BZ_MZ, D_BZ_BPCRYYJYY, D_BZ_XB } = getDictList(
"D_BZ_BPCRCWP",
"D_BZ_MZ",
"D_BZ_BPCRYYJYY",
"D_BZ_XB"
);
const clList = ref([]);
const router = useRouter();
const loading = ref(true);
const showEmpty = ref(false);
const car = ref(); //盘查车辆组件对象
const zlId = ref("");
const yjForm = ref({});
const showYjyy = ref(false);
const showCzcl = ref(false); //乘坐车辆数据
const czclHp = ref(null);
const wpdjList = ref([]); //物品登记集合
const showYj = ref(false);
const tpIdList = ref([]); //图片id集合
const wpTpIdList = ref([]);
const showWpdj = ref(false);
const showWplx = ref(false);
const fileList = ref([]);
const wpForm = ref({
wpms: "",
wpTpIdList: [],
wpsl: 1,
wplx: "",
});
const gps = ref({});
const gps1 = ref({});
const ryxx = ref({
sfzh: "",
xm: "",
xbdm: "",
xb: "",
csrq: "",
zzxz: "",
pcclId: "",
});
const bbinfo = ref({}); //报备数据
const userInfo = JSON.parse(getStorage("userInfo"));
const pcsrlx = ref(null);
onMounted(() => {
zlId.value = router.currentRoute.value.query.zlId;
getClDict(); //获取是否有乘坐车辆
let sfzh = router.currentRoute.value.query.sfzh;
pcsrlx.value = router.currentRoute.value.query.pcsrlx;
bbinfo.value = localStorage.getItem("GET_BBINFO")
? JSON.parse(localStorage.getItem("GET_BBINFO"))
: "";
try {
gps = JSON.parse(bridge.getLocation());
gps1 = JSON.parse(bridge.getPhoneInfo());
} catch (error) { }
if (sfzh) {
if (pcsrlx.value == 2 || pcsrlx.value == 6 || pcsrlx.value == 5) {
czrkQueryDetail(sfzh); //获取人员信息
} else if (pcsrlx.value == 7) {
let data = localStorage.getItem("OCR");
if (data) {
// let obj = JSON.parse(data).data;
// saveNFCData(obj);
}
} else if (pcsrlx.value == 1) {
let data = localStorage.getItem("NFC");
if (data) {
let obj = JSON.parse(data).data;
saveNFCData(obj);
}
}
} else {
hintToast("身份证为空,请重试!");
showEmpty.value = true;
loading.value = false;
}
});
// NFC保存
function saveNFCData(obj) {
let pramas = {
xm: obj.xm,
sfzh: obj.sfzh,
csrq: obj.csrq,
xbdm: obj.xb,
mzdm: obj.mz,
jgdm: obj.jgssx,
zzxz: obj.zzxz,
bbid: bbinfo.value ? bbinfo.value.id : "",
jd: gps.app_x,
wd: gps.app_y,
pcsrlx: "1",
pcfs: "02",
xjzdz: obj.zzxz,
zdch: gps.app_tfSn,
zdsim: gps1.zdlmei,
zdxh: gps.zdxh,
};
loading.value = true;
saveNFC(pramas)
.then((res) => {
ryxx.value = res;
// ryxx.value.baseUrl = "data:image/png;base64," + obj.zp;
ryxx.value.baseUrl =
"http://10.64.201.128:2366/xlpcAdminNew/requestservice/czrk/ryxp.jpg?sfzh=" +
res.sfzh;
loading.value = false;
// getPersonBq(res.id);
})
.catch(() => {
loading.value = false;
});
}
// 获取人员信息
function czrkQueryDetail(sfzh) {
let params = {
sfzh: sfzh,
jd: gps.app_x,
wd: gps.app_y,
sjly: "",
zdxh: gps.zdxh,
zdch: gps.app_tfSn,
zdsim: gps1.zdlmei,
pcsrlx: pcsrlx.value,
glxtdm: "",
glxtid: "",
jzid: "",
bbid: bbinfo.value ? bbinfo.value.id : "",
pcfs: "",
};
loading.value = true;
selectRy(params)
.then((res) => {
loading.value = false;
if (res) {
ryxx.value = res;
ryxx.value.baseUrl =
"http://10.64.201.128:2366/xlpcAdminNew/requestservice/czrk/ryxp.jpg?sfzh=" +
res.sfzh;
// getPersonBq(res.id); //获取人员标签
} else {
hintToast("查无此人,请核对人员信息!");
router.go(-1);
}
})
.catch(() => {
loading.value = false;
});
//如果是指令页面跳转过来调用
if (zlId.value) {
zlPrPc({
pclxdm: 1,
pcryclId: ryxx.value.id,
zlId: zlId.value,
}).then((res) => { });
}
}
// 获取人员标签
function getPersonBq(id) {
selectRybq({ id }).then((res1) => {
ryxx.value.bqxxsj = res1.bqxxsj;
});
}
// 获取是否有乘坐车辆
function getClDict() {
getClOf2h().then((res) => {
clList.value = res.map((item) => {
return { id: item.id, text: item.hphm };
});
});
}
// 核查驾驶证
function goLicence() {
router.push({ path: "/drivinglicence", query: { sfzh: ryxx.value.sfzh } });
}
// 核查机动车
function goVhicol() {
router.push({ path: "/motorVehicle", query: { sfzh: ryxx.value.sfzh } });
}
// 关联信息
function goCanTrack() {
router.push({ path: "/TrackInventory", query: { sfzh: ryxx.value.sfzh } });
}
// 移交原因
function onConfirmYjyy(val) {
showYjyy.value = false;
yjForm.value.pcclYjyy = val.text;
}
// 物品类型
function onConfirmWplx(val) {
showWplx.value = false;
wpForm.value.wplx = val.text;
}
// 特征信息
function goFeatureInfo() {
router.push("/featureInfo");
}
// 打开查询车辆弹窗
function showCar() {
car.value.handleOpen();
}
function onConfirmCzcl(val) {
czclHp.value = val.text;
if (ryxx.value.pcclId === val.id) {
ryxx.value.pcclId = "";
} else {
ryxx.value.pcclId = val.id;
}
}
// 物品登记提交
function onSubmit() {
wpdjList.value.push(wpForm.value);
showWpdj.value = false;
wpForm.value = { wpms: "", wpTpIdList: [], wpsl: 1, wplx: "" };
}
//获取文件
async function afterRead(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!tpIdList.value.includes(res)) tpIdList.value.push(res);
});
}
// 上传图片
async function upLoadImg2(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
file.status = "uploading";
upImage(data).then((res) => {
file.status = "done";
file.message = "上传成功";
if (!wpForm.value.wpTpIdList.includes(res))
wpForm.value.wpTpIdList.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
// 移交或者放行
function save(val) {
if (val === "1") {
const formData = {
pcclId: ryxx.value.pcclId,
id: ryxx.value.id,
pcclJg: "1",
pcclJgmc: "放行",
pcclYjdw: yjForm.value.pcclYjdw,
ryWpList: wpdjList.value,
tpIdList: tpIdList.value,
tzbqList: ryxx.value.tzList,
};
// if (pcsrlx.value != 7 && pcsrlx.value != 1 && fileList.value.length == 0) {
// return hintToast("非刷二代证件盘查,必须采集照片!");
// }
saveBpcry(formData).then((res) => {
if (pcsrlx.value == "6" || pcsrlx.value == "5") {
router.go(-2); //保存成功退回上一级
} else {
router.go(-1); //保存成功退回上一级
}
hintToast("放行成功!");
});
} else {
ryxx.value.pcclJg = val;
ryxx.value.pcclJgmc = "移交";
showYj.value = true;
}
}
//移交表单
function onYj() {
const formData = {
pcclId: ryxx.value.pcclId,
id: ryxx.value.id,
pcclJg: "2",
pcclJgmc: "移交",
pcclYjdw: yjForm.value.pcclYjdw,
ryWpList: wpdjList.value,
tpIdList: tpIdList.value,
tzbqList: ryxx.value.tzList,
};
// if (pcsrlx.value != 7 || (pcsrlx.value != 1 && fileList.value.length == 0)) {
// return hintToast("非刷二代证件盘查,必须采集照片!");
// }
saveBpcry(formData).then((res) => {
hintToast("移交成功!"); //保存成功退回上一级
if (pcsrlx.value == "6" || pcsrlx.value == "5") {
router.go(-2); //保存成功退回上一级
} else {
router.go(-1); //保存成功退回上一级
}
});
}
//获取base64地址
function _getBase64(item) {
getBase64((res) => {
item.baseUrl = res;
}, `http://10.64.201.128:2366/xlpcAdminNew/requestservice/czrk/ryxp.jpg?sfzh=${item.sfzh}`);
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.bg_ban {
background: #eff0f5;
height: 12px;
}
.foot_ban {
height: 12px;
background: #eff0f5;
}
.container {
margin-bottom: 6vh;
}
.top {
background-image: url("../../../assets/images/new/id_card.png");
background-size: 100% 100%;
background-repeat: no-repeat;
min-height: 28vw;
padding: 2vh 0 2vh 5vw;
margin: 0 2vw;
position: relative;
z-index: 2;
.basic-info {
color: #4d4d4d;
display: flex;
justify-content: space-between;
.IDcard-info {
flex: 1;
@include font_size($font_medium_s);
.info-item {
line-height: 6vw;
.bt {
display: inline-block;
width: 34px;
text-align-last: justify;
color: #1f6cec;
margin-right: 10px;
}
}
}
.img-box {
margin-right: 12px;
width: 74px;
height: 94px;
>img {
border-radius: 5px;
border: 1px solid #e5e5e5;
overflow: hidden;
}
}
}
.sfzh {
@include font_size($font_medium_s);
margin-top: 1vw;
.bt {
color: #1f6cec;
margin-right: 10px;
}
.idNumber {
font-size: 16px;
font-weight: bold;
}
}
}
.ry_xgxx {
margin: 0 2vw 12px;
background: #f3f6fe;
padding: 12px;
@include font_size($font_medium_s);
.bq {
margin-bottom: 8px;
>span {
display: inline-block;
padding: 2px 4px;
border: 1px solid #3a9687;
border-radius: 3px;
margin-right: 8px;
background: #e7f5f3;
}
}
div {
line-height: 1.8em;
>span {
color: #013791;
}
}
.contact-way {
line-height: 2vh;
@include font_size($font_medium_s);
.one-line {
display: flex;
.phoneNum {
width: 50%;
}
}
}
}
.fxBtn {
background: linear-gradient(148deg, #5897ff, #1862de);
color: #f2f2f2;
}
.yjBtn {
background: linear-gradient(148deg, #ffbb6b, #ff7a45);
color: #f2f2f2;
}
.center {
padding: 0 3vw;
.sign-title {
padding-left: 14px;
line-height: 3vh;
@include font_size($font_medium);
font-weight: bold;
display: flex;
position: relative;
justify-content: space-between;
margin: 1vh 0;
.chooseP {
@include font_size($font_medium_s);
color: rgb(0, 102, 255);
font-weight: normal;
}
}
.sign-title::after {
content: "";
position: absolute;
left: 0;
top: 2px;
bottom: 2px;
width: 4px;
background: linear-gradient(0deg, #7ec2ff 0%, #0e8aff 100%);
border-radius: 1px;
}
.associated-information {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.item-box {
margin: 2vw 4vw;
display: flex;
.ass-item-box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
}
.content1 {
display: flex;
.circlebox {
width: 15vw;
height: 15vw;
text-align: center;
line-height: 15vw;
margin-bottom: 2vw;
}
.bg1 {
background: url("../../../assets/images/new/sydj_bg.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg2 {
background: url("../../../assets/images/new/pcgj.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg3 {
background: url("../../../assets/images/new/tcry.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg4 {
background: url("../../../assets/images/new/hcjsz.png");
background-size: contain;
background-repeat: no-repeat;
}
.bg5 {
background: url("../../../assets/images/new/hcjdc.png");
background-size: contain;
background-repeat: no-repeat;
}
}
}
.pick-up-information {
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.pick-box {
display: flex;
justify-content: flex-start;
margin: 3vw 0;
}
.pick-item-box {
padding: 3vw 3vw 10vw;
width: 30%;
margin-right: 2vw;
// border-radius: 3vw;
position: relative;
.tp {
position: absolute;
bottom: 0;
right: 0;
}
}
.pbg1 {
background: url("../../../assets/images/new/bg-blue.png") no-repeat;
background-size: cover;
}
.pbg2 {
background: url("../../../assets/images/new/tzxx_bg.png") no-repeat;
background-size: 100% 100%;
color: #464d82;
}
.pbg3 {
color: #397361;
background: url("../../../assets/images/new/wpdj.png") no-repeat;
background-size: 100% 100%;
}
}
.vehicular {
@include font_color($font-color-theme);
.no-veh {
text-align: center;
@include font_size($font_medium_s);
color: #cccccc;
margin: 4vw 0;
}
.veh-box {
margin: 1vh 0;
.cp_item {
display: inline-block;
text-align: center;
line-height: 2em;
@include font_size($font_medium_s);
width: 31.33%;
margin-right: 2%;
background: url("../../../assets/images/new/cp_bg.png") no-repeat;
background-size: 100% 100%;
>span {
display: inline-block;
width: 4px;
height: 4px;
border-radius: 50%;
background: #333;
margin-bottom: 4%;
}
}
.active.cp_item {
background: url("../../../assets/images/new/cp_bg_active.png") no-repeat;
background-size: 100% 100%;
color: #fff;
>span {
background: #fff;
}
}
}
}
}
.line1 {
width: 100vw;
background-color: #eee;
height: 1vh;
}
.upload {
padding: 1vh 3vw;
height: 80px;
position: relative;
.tsxx {
position: absolute;
color: #a8a8a8;
top: 0;
left: 30%;
bottom: 0;
padding: 8% 0;
font-size: 14px;
}
.up_btn {
height: 80px;
width: 80px;
color: #a8a8a8;
font-size: 24px;
background: #f2f2f2 url("../../../assets/images/new/upimg_bg.png") no-repeat;
background-size: 100% 100%;
}
}
.bottom-box {
text-align: center;
background: #fff;
border-top: 1px solid #ddddde;
position: fixed;
bottom: 0;
width: 100vw;
height: 6vh;
line-height: 6vh;
display: flex;
>div {
height: 6vh;
flex: 1;
display: flex;
align-items: center;
justify-content: center;
>img {
width: 20px;
margin-right: 8px;
}
}
.yj {
background: #f0f0f0;
}
}
.upload-box {
margin: 1vh 3vw;
}
.staff-title {
height: 5vh;
background-color: rgb(13, 106, 245);
text-align: center;
line-height: 5vh;
}
.staff-sure {
position: fixed;
bottom: 0;
width: 100%;
}
.head-nav-banner {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 35vw;
z-index: 1;
background: #1143ca;
}
::v-deep .headBlue {
background-color: #1143ca !important;
}
.navTitle {
position: absolute;
top: 0;
color: #fff;
font-size: 5.5vw;
text-align: center;
width: 100%;
padding: 3vw 0;
}
.rybq {
display: inline-block;
padding: 0 4px;
background: #f00;
color: #f2f2f2;
border-radius: 4px;
margin: 4px;
}
.no-veh_cp {
display: flex;
>span {
flex: 1;
}
}
.tip_text{
font-size: 18px;
margin-top: 10px;
}
</style>

View File

@ -0,0 +1,43 @@
<template>
<div class="container containerLicence" style="padding-top: 13vw; box-sizing: border-box">
<TopNav navTitle="核查机动车" />
<van-steps direction="vertical" active-color="#969799" :active="0">
<van-step>
<p>号牌种类 : 小型车辆</p>
<p>号牌号码 : 穿A88888</p>
<p>车辆识别代码 : LVHR98545869852</p>
<p>发动机型号 : RWED12</p>
<p>发动机号 : 124525</p>
<p>车身颜色 : </p>
<p>车辆品牌 : </p>
<p>核定载重量 : </p>
<p>排量 : </p>
<p>功率 </p>
<p>载重量 : </p>
<p>机动车所有人 : </p>
<p>机动车所有人身份证号 : </p>
<p>登记住址详址 : </p>
</van-step>
</van-steps>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { ref, reactive, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
</script>
<style lang="scss" scoped>
</style>
<style>
.containerLicence .van-icon{
color: #148aec!important;
}
.containerLicence .van-step__line{
background-color: #148aec!important;
}
</style>

View File

@ -0,0 +1,311 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="涉疫登记" />
<div class="card">
<van-image class="img_van" :class="_getBase64(ryxx)" :src="ryxx.baseUrl"></van-image>
<div class="card_main">
<div>
<span class="main_one">姓名{{ ryxx.xm }}</span>
<span>性别{{ setDict(ryxx.sex, D_BZ_XB) }}</span>
</div>
<div>
<span class="main_one">出生年月{{ ryxx.bird }}</span>
<span>民族{{ setDict(ryxx.mz, D_BZ_MZ) }}</span>
</div>
<div>
<span>证件号码{{ ryxx.sfzh }}</span>
</div>
<div>
<span>家庭住址{{ ryxx.jtzz }}</span>
</div>
</div>
</div>
<div class="title_tag">天府健康码核验</div>
<div class="fydj_main">
<van-radio-group direction="horizontal" v-model="form.jkmzt">
<van-radio name="1" shape="square">
<template #default>
<span style="color: #4cdf58">绿码</span>
</template>
</van-radio>
<van-radio name="2" shape="square">
<template #default>
<span style="color: #e69529">黄码</span>
</template>
</van-radio>
<van-radio name="3" shape="square">
<template #default>
<span style="color: #ff0000">红码</span>
</template>
</van-radio>
</van-radio-group>
</div>
<div class="title_tag">疫苗接种情况</div>
<div class="fydj_main">
<van-radio-group v-model="form.ymjzqk" direction="horizontal">
<van-radio v-for="item in D_BZ_YMJZQK" :key="item.value" shape="square" :name="item.value" class="m_radio">{{
item.text }}</van-radio>
</van-radio-group>
</div>
<div class="title_tag">来源地与目的地</div>
<div class="fydj_main_n">
<div>
<div style="color: #1565eb; text-align: center">来源地</div>
<van-field readonly @click="show = true" class="bg" v-model="form.lz" placeholder="请输入来源地" type="textarea"
rows="2"></van-field>
</div>
<van-icon class="fy_icon" name="arrow"></van-icon>
<div>
<div style="color: #1565eb; text-align: center">目的地</div>
<van-field readonly class="bg" @click="showEnd = true" placeholder="请输入目的地" v-model="form.qw" type="textarea"
rows="2"></van-field>
</div>
</div>
<div class="title_tag">通行大数据行程卡是否带*</div>
<div class="fydj_main">
<van-radio-group v-model="form.txxck" direction="horizontal">
<van-radio v-for="item in D_BZ_SF" :key="item.value" shape="square" :name="item.value" class="m_radio">{{
item.text }}</van-radio>
</van-radio-group>
</div>
<div class="title_tag_s">14天内到达或途径城市</div>
<div class="fydj_main">
<van-field class="bg" v-model="form.ddhtjcs"></van-field>
</div>
<div class="title_tag">上传照片</div>
<div class="fydj_main">
<van-uploader v-model="imgList" multiple :max-count="3" :after-read="upLoadImg" />
</div>
<div style="margin: 16px">
<van-button round block type="primary" @click="onSubmit">提交</van-button>
</div>
<van-popup v-model:show="show" round position="bottom">
<van-cascader close-icon="success" v-model="cascaderVakue.city" title="请选择来源地" :options="city" @close="close"
@finish="onFinish"></van-cascader>
<van-field v-model="cascaderVakue.text" label="详细地址" placeholder="请输入详细地址"></van-field>
</van-popup>
<van-popup v-model:show="showEnd" round position="bottom">
<van-cascader close-icon="success" v-model="cascaderVakueEnd.city" title="请选择目的地" :options="city"
@close="closeEnd" @finish="onFinishEnd"></van-cascader>
<van-field v-model="cascaderVakueEnd.text" label="详细地址" placeholder="请输入详细地址"></van-field>
</van-popup>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { useRouter } from "vue-router";
import { upImage, getRySydjInfo, saveSydj } from "../../../api/common";
import { ref, onMounted } from "vue";
// import city from "../../../assets/jsonData/city.json";
import { getBase64, hintToast } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { baseUrl2 } from "../../../utils/request.js";
const { D_BZ_YMJZQK, D_BZ_SF, D_BZ_XB, D_BZ_MZ } = getDictList(
"D_BZ_YMJZQK",
"D_BZ_SF",
"D_BZ_XB",
"D_BZ_MZ"
);
const router = useRouter();
const url = baseUrl2 + "/mosty-api/mosty-base/minio/image/download/";
const show = ref(false);
const showEnd = ref(false);
const cascaderVakue = ref({
city: "",
text: "",
});
const cascaderVakueEnd = ref({
city: "",
text: "",
});
const form = ref({
ddhtjcs: "", //14天内到达或途径城市
jkmzt: "", //天府健康码状态
lz: "", //来自哪里
pcid: "", //盘查id
qw: "", //去往哪里
ryxm: "", //人员姓名
sfzh: "", //身份证号
tpid: "", //图片Id
txxck: "", //通讯行程卡是否带*
ymjzqk: "",
});
100;
const imgList = ref([]);
const ryxx = ref({
imgUrl: "",
xm: router.currentRoute.value.query.ryxm,
sfzh: router.currentRoute.value.query.sfzh,
sex: router.currentRoute.value.query.xbdm,
bird: router.currentRoute.value.query.csrq,
mz: router.currentRoute.value.query.mzdm,
jtzz: router.currentRoute.value.query.zzxz,
});
//获取base64地址
function _getBase64(item) {
getBase64((res) => {
item.baseUrl = res;
}, `http://10.64.201.128:2366/xlpcAdminNew/requestservice/czrk/ryxp.jpg?sfzh=${item.sfzh}`);
}
function close() {
show.value = false;
form.value.lz += cascaderVakue.value.text;
}
function onFinish({ selectedOptions }) {
form.value.lz = selectedOptions.map((item) => item.text).join("/");
}
function closeEnd() {
showEnd.value = false;
form.value.qw += cascaderVakueEnd.value.text;
}
function onFinishEnd({ selectedOptions }) {
form.value.qw = selectedOptions.map((item) => item.text).join("/");
}
function upLoadImg(file) {
const data = new FormData();
data.append("file", file.file);
file.status = "uploading";
file.message = "上传中...";
upImage(data)
.then((res) => {
file.status = "done";
file.message = "上传成功";
file.id = res;
})
.catch(() => {
file.status = "failed";
file.message = "上传失败";
});
}
function onSubmit() {
form.value.pcid = router.currentRoute.value.query.pcid;
form.value.ryxm = router.currentRoute.value.query.ryxm;
form.value.sfzh = router.currentRoute.value.query.sfzh;
form.value.tpid = imgList.value.map((item) => item.id).join(",");
saveSydj(form.value).then(() => {
hintToast("保存成功")
router.go(-1);
});
}
function getSydjInfo() {
const data = {
pcid: router.currentRoute.value.query.pcid,
sfzh: router.currentRoute.value.query.sfzh,
};
getRySydjInfo(data).then((res) => {
form.value = res;
if (res.tpid) {
imgList.value = res.tpid.split(",").map((item) => {
return {
url: url + item,
id: item,
isImage: true,
};
});
}
});
}
onMounted(() => {
getSydjInfo();
});
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.card {
margin: 5vw;
width: 90vw;
@include font_color($font-color-theme);
border-radius: 2.5vw;
@include bg_color($background-color-theme);
@include border_outer_color($border-outer-color-theme);
display: flex;
font-size: 12px;
padding: 3vw;
box-sizing: border-box;
.img_van {
width: 65px;
height: 76px;
margin-right: 12px;
}
.card_main {
flex: 1;
>div {
display: flex;
line-height: 1.5em;
.main_one {
width: 65%;
}
}
}
}
.title_tag_s {
@include font_color($font-color-theme);
position: relative;
padding-left: 12px;
margin: 12px 5vw;
}
.title_tag {
position: relative;
padding-left: 12px;
margin: 12px 5vw;
@include font_color($font-color-theme);
}
.title_tag::after {
content: "";
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 4px;
background: #1666eb;
border-radius: 2px;
}
.fydj_main {
box-sizing: border-box;
padding: 0 6vw;
.m_radio {
width: 50%;
margin: 6px 0;
}
}
.fydj_main_n {
box-sizing: border-box;
padding: 0 6vw;
display: flex;
align-items: center;
.bg {
background: #f0f0f0;
border-radius: 4px;
margin-top: 8px;
}
.fy_icon {
margin: 24px 5vw 0;
color: #1666eb;
}
}
.bg {
background: #f0f0f0;
border-radius: 4px;
}
::v-deep .van-radio__label {
@include font_color($font-color-theme);
color: #333;
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav :navTitle="title" />
<van-list v-model:loading="loading" :finished='finished' finished-text='沒有更多了' @load="onLoad">
<van-cell v-for="(item,index) in list" :key="index+'rygj'">
<div v-if="title==='人员轨迹'" class="item_main item_box">
<div style="color:#027db4">{{item.pcsj}}</div>
<div>姓名{{item.xm}} <span style="color:f00">{{item.bqxxsj}}</span></div>
<div>性别{{item.xbdm==1?'男':'女'}}</div>
<div>身份证号{{item.sfzh}}</div>
<div>所属单位{{item.ssbm}}</div>
<div>所乘车辆暂无</div>
<div @click="preview(item.tpList)">照片数量{{item.tpList.length}}</div>
<div>盘查特征{{item.tzList==null?'暂无':item.tzList.join(',')}}</div>
<div>盘查物品
<span v-for="(e,index) in item.wpVoList"
:key="index+'pctp'">{{setDict(e.wplx,D_BZ_WPLX)+'*'+e.wpsl}}</span>
<span v-show="item.wpVoList.length===0">暂无</span>
</div>
<div>处理结果
<span v-show="item.pcclJg==1">放行</span>
<span v-show="item.pcclJg==2">移交</span>
<span v-show="item.pcclJg==9">盘查</span>
</div>
</div>
<div v-else class="item_main item_box">
<div style="color:#027db4">{{item.pcsj}}</div>
<div>车牌号{{item.hphm}}</div>
<div>车主姓名{{item.jdcsyr}}</div>
<div>身份证号{{item.jdcsyrsfzh}}</div>
<div>号牌种类{{setDict(item.hpzl,D_BZ_HPZL)}}</div>
<div>盘查结果{{item.pcclJg==1?'放行':'移交'}}</div>
<div>盘查方式{{item.pcfs=='01'?'车牌设备自动':'民警手动'}}</div>
<div>盘查物品
<span v-for="(e,index) in item.wpVoList"
:key="index+'pctp'">{{setDict(e.wplx,D_BZ_WPLX)+'*'+e.wpsl}}</span>
<span v-show="item.wpVoList.length===0">暂无</span>
</div>
<div>处理结果
<span v-show="item.pcclJg==1">放行</span>
<span v-show="item.pcclJg==2">移交</span>
<span v-show="item.pcclJg==9">盘查</span>
</div>
</div>
</van-cell>
</van-list>
</div>
</template>
<script setup>
import { ref,onMounted } from 'vue'
import { useRouter } from "vue-router";
import TopNav from "../../../components/topNav.vue";
import {getDictList,setDict} from '../../../utils/dict'
import { getRypcList,getClpcList } from '../../../api/common'
import { ImagePreview } from 'vant'
const { D_BZ_WPLX,D_BZ_HPZL } = getDictList('D_BZ_WPLX','D_BZ_HPZL')
const router = useRouter();
const loading = ref(false)
const finished = ref(false)
const total=ref(0)
const title = router.currentRoute.value.query.sfzh?'人员轨迹':"车辆轨迹"
const url = '/mosty-api/mosty-base/minio/image/download/'
const queryList = ref({
pageCurrent:1,
pageSize:10,
sfzh:router.currentRoute.value.query.sfzh,
hphm:router.currentRoute.value.query.hphm
})
const list = ref([])
function preview(e){
const imgIdList = e.map(e=>url+e.id)
if(imgIdList.length>0){
ImagePreview({imgIdList,closeable:true})
}
}
function onLoad(){
if(router.currentRoute.value.query.sfzh){
getRypcList(queryList.value).then(res=>{
list.value.push(...res.records)
total.value = res.total
loading.value = false
queryList.value.pageCurrent++
if(list.value.length>=res.total){
finished.value = true
}
})
}else{
getClpcList(queryList.value).then(res=>{
list.value.push(...res.records)
total.value = res.total
loading.value = false
queryList.value.pageCurrent++
if(list.value.length>=res.total){
finished.value = true
}
})
}
}
onMounted(()=>{})
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.item_main {
box-sizing: border-box;
padding: 2.5vw;
border-radius: 4px;
margin: 16px 2.5vw;
}
.van-cell {
background-color: rgba(0, 0, 0, 0);
}</style>

View File

@ -0,0 +1,677 @@
<template>
<div class="compare" v-if="showPage">
<div class="title-box">
<div class="title">
<span @click="isShowJqType = true">{{ jqTitle }}</span>
<img src="../../../assets/images/xiala.png" width class="img" alt="" @click="isShowJqType = true" />
<van-action-sheet v-model:show="isShowJqType">
<van-picker :columns="jqTypeList" @confirm="onJqChange" @cancel="isShowJqType = false" />
</van-action-sheet>
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">分局{{ jqTitle }}走势图</div>
</div>
<jqChart :data1="jqzs.data1" :data2="jqzs.data2" :data3="jqzs.data3" :timeList="jqzs.timeList" :jqType="jqType"
v-if="jqzs.timeList.length > 0" />
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">城区分局{{ jqTitle }}环比</div>
</div>
<div class="all-box" v-if="m2List.length > 0">
<percent :list="m2List" :day="dqTime" :yesterday="sygTime" />
</div>
<div style="height: 10vh; text-align: center; line-height: 10vh" v-else>
没有数据
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">城区分局{{ jqTitle }}类别环比</div>
</div>
<div v-if="list3.length <= 0" style="height: 10vh; text-align: center; line-height: 10vh">
没有数据
</div>
<div class="fjAndCqfj-box" v-else>
<div class="first-line">
<div class="first-line-item"></div>
<div class="first-line-item" v-for="(item, index) in list3" :key="index">
{{ item.name }}
</div>
</div>
<div class="right-box">
<div class="right-box-line-item" v-for="(_item, i) in list3Title" :key="i">
<div class="right-line-box" v-if="_item">
<div class="first-line-item-right">{{ _item }}</div>
<div class="first-line-item-right" v-for="(item, index) in list3" :key="index + 'cc'">
<span v-if="_item == '对比'" :style="{
color:
item['高新区'] - item[list3Title[i - 1]] < 0
? 'green'
: 'red',
}">{{ item["高新区"] - item[list3Title[i - 1]] }}</span>
<span v-else>{{ item[_item] }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">派出所{{ jqTitle }}环比</div>
</div>
<div v-if="m4List.length > 0">
<percent :list="m4List" :day="dqTime" :yesterday="sygTime" />
</div>
<div v-else style="height: 10vh; text-align: center; line-height: 10vh">
没有数据
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">派出所{{ jqTitle }}类别环比</div>
</div>
<div v-if="list5.length <= 0" style="height: 10vh; text-align: center; line-height: 10vh">
没有数据
</div>
<div class="fjAndCqfj-box" v-else>
<div class="first-line">
<div class="first-line-item"></div>
<div class="first-line-item"></div>
<div class="first-line-item" v-for="(item, index) in list5" :key="index">
{{ item.name }}
</div>
</div>
<div class="right-box">
<div class="right-box-line-item" v-for="(_item, i) in list5Title" :key="i">
<div class="right-line-box" v-if="_item" style="width: 45vw">
<div class="first-line-item-right">{{ _item }}</div>
<div class="first-line-item-right lb_title" style="color: #3e6ee8">
<span>{{ dqTime }}</span>
<span>{{ sygTime }}</span>
<span>环比</span>
</div>
<div class="first-line-item-right lb_title" v-for="(item, index) in list5" :key="index + 'cc'">
<template v-for="(val, key) in item" :key="val">
<template v-if="
_item === key.split('_')[0] && _item + '_data2' == key
">
<span>{{ item[_item + "_data1"] }}</span>
<span>{{ item[_item + "_data2"] }}</span>
<span :style="{
color:
item[_item + '_data1'] - item[_item + '_data2'] <= 0
? 'green'
: 'red',
}">
{{ item[_item + "_data1"] - item[_item + "_data2"] }}
</span>
</template>
</template>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import jqChart from "./components/lineChart.vue";
import percent from "./percent.vue";
import * as echarts from "echarts";
import { jqfxCorrelation } from "../../../api/jqfxApi.js";
import { Toast } from "vant";
export default {
components: {
jqChart,
percent,
},
props: ["timeActive"],
watch: {
timeActive: {
handler(val) {
this.list3 = [];
this.list5 = [];
switch (val) {
case 0:
this.sygTime = "昨日";
this.dqTime = "今日";
break;
case 1:
this.sygTime = "上个7日";
this.dqTime = "近7日";
break;
case 2:
this.sygTime = "上个30日";
this.dqTime = "近30日";
break;
case 3:
this.sygTime = "上个90日";
this.dqTime = "近90日";
break;
}
this.tiemType = val + 1;
this._allRequest();
this.keyIndex += 1;
},
immediate: true,
deep: true,
},
},
data() {
return {
showPage: false,
keyIndex: 1,
sygTime: "昨日",
dqTime: "今日",
tiemType: 0, //时间查询类型
jqType: 1, //警情类型
zlShow: false,
isShowJqType: false,
jqTitle: "总警情",
jqTypeList: ["总警情", "街面警情", "违法犯罪警情"],
//警情走势图数据
jqzs: {
data1: [],
data2: [],
data3: [],
timeList: [],
},
//城区总警情类别环比标题
list3Title: [
"",
"高新区",
"青羊区",
"对比",
"锦江区",
"对比",
"金牛区",
"对比",
"武侯区",
"对比",
"成华区",
"对比",
"天府新区",
"对比",
],
list3: [], //城区总警情类别环比
list5: [], //派出所总警情类别环比
list5Title: [
"",
"中和派出所",
"合作派出所",
"和平派出所",
"新会展派出所",
"新川派出所",
"新益州派出所",
"桂溪派出所",
"石羊派出所",
"肖家河派出所",
"芳草街派出所",
"西园派出所",
], //派出所总警情类别环比标题
m2List: [], //城区分局总警情环比
m4List: [], //派出所警情环比
};
},
mounted() {
try {
if (this.$route.query.jqlx === "jmjq") {
this.onJqChange("街面警情");
} else if (this.$route.query.jqlx === "zjq") {
this.onJqChange("总警情");
} else if (this.$route.query.jqlx === "wffzjq") {
this.onJqChange("违法犯罪警情");
}
} catch (error) {
this._allRequest();
}
},
methods: {
//切换警情类型
onJqChange(val) {
switch (val) {
case "总警情":
this.jqType = 1;
this.jqTitle = "总警情";
break;
case "违法犯罪警情":
this.jqType = 3;
this.jqTitle = "违法犯罪警情";
break;
case "街面警情":
this.jqType = 2;
this.jqTitle = "街面警情";
break;
}
this._allRequest();
this.isShowJqType = false;
this.keyIndex += 1;
},
//
_allRequest() {
Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
Promise.all([
this._getCqjqfjhbData(),
this._getCqjqlbhbData(),
this._getPcsjqhbData(),
this._getPcsjqlbhbData(),
this._getFjjqzstData(),
]).then((res) => {
setTimeout(() => {
this.showPage = true;
Toast.clear();
}, 4e3);
});
},
//获取分局警情走势图
_getFjjqzstData() {
let data = {
type: this.tiemType,
ssfjdm: "510109000000",
jqType: this.jqType,
};
jqfxCorrelation("/tbJq/jqtjDbFjjqzs", data).then((res) => {
if (res) this.jqzs = res;
});
},
//派出所警情类别环比
_getPcsjqlbhbData() {
let data = {
type: this.tiemType,
jqType: this.jqType,
ssfjdm: "510109000000",
};
jqfxCorrelation("/tbJq/jqtjDbPcsHbTable", data).then((res) => {
this.list5 = res;
});
},
//派出所警情环比
_getPcsjqhbData() {
let data = {
type: this.tiemType,
jqType: this.jqType,
ssfjdm: "510109000000",
};
jqfxCorrelation("/tbJq/jqtjDbPcsHb", data).then((res) => {
for (let i = 0; i < res.length; i++) {
res[i].orgname = res[i].orgname.replace("派出所", "");
}
this.m4List = res;
});
},
//获取城区总警情类别环比
_getCqjqlbhbData() {
let data = {
type: this.tiemType,
jqType: this.jqType,
};
jqfxCorrelation("/tbJq/jqtjDbCqfjhbTable", data).then((res) => {
this.list3 = res;
});
},
//获取城区总警情环比
_getCqjqfjhbData() {
let data = {
type: this.tiemType,
jqType: this.jqType,
};
jqfxCorrelation("/tbJq/jqtjDbCqfjhb", data).then((res) => {
this.m2List = res;
});
},
},
};
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.title-box {
display: flex;
justify-content: center;
}
.title {
width: 92vw;
height: 4vw;
background: url("../../../assets/images/bigTitle@2x.png");
background-size: 100% 100%;
margin-top: 10px;
text-align: center;
line-height: 4vw;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
::v-deep .nav-box[data-v-19978886] {
border-bottom: 1px solid #203967;
}
.zst-box {
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
.zst-title-box {
width: 100vw;
margin-top: 20px;
display: flex;
justify-content: space-between;
}
.zst-title-left {
background: url("../../../assets/images/lanmu-title.png") no-repeat;
background-size: 100% 100%;
flex: 2;
height: 28px;
line-height: 28px;
padding-left: 10px;
@include font_color($font-color-theme);
@include font_size($font_medium);
}
.zst-title-right {
flex: 1;
span-align: right;
height: 28px;
line-height: 28px;
padding-right: 10px;
color: #47b8ff;
text-align: right;
}
.zst-title-right1 {
flex: 1;
height: 28px;
line-height: 28px;
padding-right: 10px;
/* color: #47B8FF; */
}
.sendZL {
width: 70px;
height: 26px;
border-radius: 5px;
background-image: linear-gradient(#00c0fa, #015eea);
span-align: center;
margin-left: 16vw;
color: #fff;
font-size: 14px;
text-align: center;
line-height: 26px;
}
.img {
margin-left: 3px;
}
.assess-box {
padding: 10px;
line-height: 18px;
// @include font_size($font_medium_s);
// @include font_color($font-color-theme);
}
.fjAndCqfj-box {
margin: 0 auto;
width: 95vw;
/* height: 40vh; */
margin-top: 10px;
display: flex;
flex-direction: row;
}
.first-line {
flex: 1;
overflow: auto;
border: 1px solid #333;
display: flex;
flex-direction: column;
// justify-content: space-between;
align-items: center;
background-color: rgb(51, 157, 255, 0.2);
}
.first-line :first-child {
border-top: unset;
}
.first-line :last-child {
border-bottom: unset;
}
.first-line-item {
flex: 1;
height: 3.5vh;
border-bottom: 1px solid #333;
display: flex;
align-items: center;
width: 100%;
padding-left: 1.5vw;
white-space: nowrap;
overflow-x: scroll;
}
.right-box {
flex: 4.5;
display: flex;
border-top: 1px solid #333;
border-bottom: 1px solid #333;
border-right: 1px solid #333;
overflow: auto;
}
.right-box-line-item {
/* width: 33vw; */
border-right: 1px solid #333;
display: flex;
position: relative;
}
.right-line-box-m5 {
display: flex;
justify-content: center;
align-items: center;
width: 42vw;
}
.right-line-box-m5 :last-child {
border-right: unset;
}
.table-content-m5 {
display: flex;
width: 42vw;
}
.right-line-box {
width: 14vw;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.first-line-item-right {
// flex: 1;
height: 3.5vh;
border-bottom: 1px solid #333;
// border-right: 1px solid #18325e;
span-align: center;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
// padding-left: 1.5vw;
}
.lb_title {
display: flex;
justify-content: space-between;
}
.lb_title>span {
width: 33.3%;
text-align: center;
border-right: 1px solid #333;
height: 3.5vh;
line-height: 3.6vh;
}
.lb_title>span:last-child {
border: none;
}
.first-line-item-rightsss {
height: 3.5vh;
border-bottom: 1px solid #333;
span-align: center;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
}
.first-line-item-rightsss:last-child {
border-bottom: none;
// border-right:none;
}
.first-line-item-right:last-child {
border-bottom: none;
// border-right:none;
}
.first-line-item-right-m5 {
height: 3.5vh;
border-top: 1px solid #333;
border-bottom: 0.5px solid #333;
span-align: center;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
padding-left: 1.5vw;
}
.first-line-item-right-m5:last-child {
// border-bottom:none;
border-right: none;
}
/* .right-line-box :first-child {
border-right: unset;
} */
.right-title-box {
width: 42vw;
// span-align: center;
text-align: center;
line-height: 3.6vh;
white-space: nowrap;
overflow-x: scroll;
}
/* echarts */
#jqChart {
width: 100%;
height: 40vh;
}
#chainChart1 {
width: 100%;
height: 43vh;
}
.zhanbi1 {
margin-top: 4.5vh;
height: 33.5vh;
display: flex;
flex-direction: column;
align-items: center;
line-height: 4.5vh;
}
.zhanbi1-item {
flex: 1;
}
.all-box {
display: flex;
}
.pop-box {
padding: 2vw 4vw;
}
.span-zhanbi {
color: #ff7327;
font-size: 18px;
}
.slot-content {
padding: 2vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
}
.first-Line-content {
margin-bottom: 10px;
}
.other-content {
// height: 161px;
// background-color: #293647;
// overflow: auto;
padding: 2vw;
border-radius: 5px;
white-space: pre-line;
@include border_outer_color($border-outer-color-theme);
}
.empty-box {
line-height: 8vh;
span-align: center;
}
.content-module5 {
display: flex;
flex-direction: column;
}
.db_span {
color: #ed0000;
}
::v-deep .modal-box .u-popup__content[data-v-3a231fda] {
background-color: #333 !important;
}
::v-deep .modal-box .u-line {
border-right-color: #333 !important;
border-top-color: #333 !important;
border-left-color: #333 !important;
border-bottom: #333 !important;
}
::v-deep .modal-box .u-modal__button-group__wrapper__span[data-v-0156a215] {
color: #fff !important;
}
</style>

View File

@ -0,0 +1,112 @@
<template>
<view class="box" v-if="ayList.length > 0">
<view class="total_box" v-for="(item,index) in list" :key="index">
<view class="total_name">
<span>{{item.ay ? _getayName(item.ay) : item.name}}</span>
<view v-if="item.text">{{item.text}}</view>
</view>
<view class="total_num">
<view class="percent" :class="index > 1 ? 'orange' : 'red'" style="width: 100%;" v-if="index == 0">
</view>
<view class="percent" :class="index > 1 ? 'orange' : 'red'"
:style="{width:item.sl / list[0].sl * 100 + '%'}" v-else></view>
<span>{{item.sl}}</span>
</view>
</view>
</view>
</template>
<script>
import { jqfxCorrelation } from "../../../../api/jqfxApi.js";
export default {
props: ["list"],
watch: {
list: {
handler(val) {
this._getAjlxData()
},
immediate: true,
deep: true
}
},
data() {
return {
ayList: [],//案由数据
totalList:[],//统计数据
}
},
created() {
},
methods: {
/**
* 获取案由
* @param {Object} code 字典代码
*/
_getAjlxData(code) {
jqfxCorrelation('/xtzd/aylx',{}).then(res => {
this.ayList = res
this.totalList = this.list
})
},
//获取案由名称
_getayName(code) {
let name = ''
let info = this.ayList.find(item => {
return code == item.code
})
if (info) {
name = info.name
return name
}
return code
}
}
}
</script>
<style scoped>
.box {
width: 100%;
height: 100%;
}
.total_box {
display: flex;
width: 100%;
margin-bottom: 5vw;
}
.total_name {
flex: 1;
}
.total_name>view {
color: #999;
}
.total_num {
border: 1px solid #264479;
border: 1px solid #e0e0e0;
flex: 4.5;
display: flex;
align-items: center;
height: 8vw;
padding: 1vw;
justify-content: space-between;
}
.total_num .percent {
width: 92%;
height: 5vw;
}
.total_num .red {
background-image: linear-gradient(to right, #b6359c, #ef0a6a);
}
.total_num .orange {
background-image: linear-gradient(to right, #f28e26, #fd644f);
}
</style>

View File

@ -0,0 +1,165 @@
<template>
<div :id="echid" class="gfChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: ["datas"],
watch: {
datas: {
handler(val) {
this.hamdlegfChart();
},
immediate: true,
deep: true,
},
},
data() {
return {
echid: "",
};
},
created() {
this.echid = "ech_" + new Date().getTime();
},
mounted() {
// this.titles = this.titles
// this.datas = this.datas
this.hamdlegfChart();
},
methods: {
hamdlegfChart() {
if (document.getElementById(this.echid)) {
let myechart = echarts.init(document.getElementById(this.echid));
myechart.setOption({
tooltip: {},
grid: {
left: "5",
right: "5",
bottom: "0",
top: "35",
containLabel: true,
},
legend: {
textStyle: {
color: "#333",
},
},
dataset: {
// dimensions: ['product', '警情', '时长', '里程'],
source: this.datas,
},
xAxis: {
type: "category",
},
yAxis: {
type: "value",
splitLine: {
show: true,
lineStyle: {
// color: "#224465",
},
},
},
series: [
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#ff887c",
},
{
offset: 1,
color: "#b6325f",
},
],
},
],
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#205ddb",
},
{
offset: 1,
color: "#1bdffc",
},
],
},
],
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#98e05f",
},
{
offset: 1,
color: "#0de3ac",
},
],
},
],
},
],
});
}
},
},
};
</script>
<style scoped>
.gfChart {
margin-top: 1vw;
height: 65vw;
width: 95vw;
margin: 0 auto;
}
</style>

View File

@ -0,0 +1,172 @@
<template>
<div :id="echid" class="gfChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: ["datas"],
watch: {
datas: {
handler(val) {
this.hamdlegfChart();
},
immediate: true,
deep: true,
},
},
data() {
return {
echid: "",
};
},
created() {
this.echid = "ech_" + new Date().getTime();
},
mounted() {
// this.titles = this.titles
// this.datas = this.datas
this.hamdlegfChart();
},
methods: {
hamdlegfChart() {
if (document.getElementById(this.echid)) {
let myechart = echarts.init(document.getElementById(this.echid));
myechart.setOption({
tooltip: {},
grid: {
left: "10",
right: "20",
bottom: "0",
top: "35",
containLabel: true,
},
legend: {
textStyle: {
color: "#333",
},
},
xAxis: {
type: "value",
splitLine: {
show: true,
lineStyle: {
// color: "#224465",
},
},
},
yAxis: {
type: "category",
data: this.datas.titles,
},
series: [
{
name: "刑事",
type: "bar",
stack: "total",
label: {
show: true,
color: "#fff",
fontSize: 12,
},
emphasis: {
focus: "series",
},
data: this.datas.xsList,
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#015eea",
},
{
offset: 1,
color: "#00c0fa",
},
],
},
],
},
{
name: "行政",
type: "bar",
stack: "total",
label: {
show: true,
color: "#fff",
},
emphasis: {
focus: "series",
},
data: this.datas.xzList,
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#b6325f",
},
{
offset: 1,
color: "#ff887c",
},
],
},
],
},
// {
// name: '总数',
// type: 'bar',
// stack: 'total',
// label: {
// show: false,
// color: '#000'
// },
// emphasis: {
// focus: 'series'
// },
// data: this.datas.zsList,
// color: [{
// type: 'linear',
// x: 0,
// y: 0,
// x2: 0,
// y2: 1,
// colorStops: [{
// offset: 0,
// color: '#ecc801'
// },
// {
// offset: 1,
// color: '#feef45'
// }
// ]
// }]
// },
],
});
}
},
},
};
</script>
<style scoped>
.gfChart {
margin-top: 1vw;
height: 65vw;
width: 95vw;
margin: 0 auto;
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<div :id="echid" class="gfChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: ["datas"],
watch: {
datas: {
handler(val) {
this.hamdlegfChart();
},
immediate: true,
deep: true,
},
},
data() {
return {
echid: "",
};
},
created() {
this.echid = "ech_" + new Date().getTime();
},
mounted() {
// this.titles = this.titles
// this.datas = this.datas
this.hamdlegfChart();
},
methods: {
hamdlegfChart() {
if (document.getElementById(this.echid)) {
let myechart = echarts.init(document.getElementById(this.echid));
myechart.setOption({
tooltip: {},
grid: {
left: "5",
right: "5",
bottom: "0",
top: "35",
containLabel: true,
},
legend: {
textStyle: {
color: "#333",
},
},
dataset: {
// dimensions: ['product', '警情', '时长', '里程'],
source: this.datas,
},
xAxis: {
type: "category",
},
yAxis: {
type: "value",
splitLine: {
show: true,
lineStyle: {
// color: "#224465",
},
},
},
series: [
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#b6325f",
},
{
offset: 1,
color: "#ff887c",
},
],
},
],
barGap: "50%",
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#205ddb",
},
{
offset: 1,
color: "#1bdffc",
},
],
},
],
},
],
});
}
},
},
};
</script>
<style scoped>
.gfChart {
margin-top: 1vw;
height: 65vw;
width: 95vw;
margin: 0 auto;
}
</style>

View File

@ -0,0 +1,168 @@
<template>
<div class="cntBox">
<div class="box-left">
<div class="left-item" v-for="(v,index) in list" :key="index">
<div class="title">
{{index+1}}.{{v.name}}
</div>
<div class="number">
{{v.todayNum}}
<img src="../../../../assets/images/leader/arrow-up@2x.png" v-if="v.todayNum > v.lastNum"/>
<img src="../../../../assets/images/leader/arrow-down@2x.png" v-else/>
</div>
</div>
</div>
<div class="box-right">
<div class="sircle-one">
<div class="sircle-one-middle">
<div class="sircle-one-small">前科</div>
<div class="sircle-two">吸毒</div>
<div class="sircle-three">本区</div>
<div class="sircle-four">精神病人</div>
<div class="sircle-five">外省</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{name:'前科',todayNum:180,lastNum:20},
{name:'吸毒',todayNum:180,lastNum:1120},
{name:'本区',todayNum:180,lastNum:20},
{name:'外省',todayNum:180,lastNum:1120},
{name:'精神病人',todayNum:180,lastNum:20}
]
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
@import "../../../../assets/styles/mixin.scss";
.cntBox{
width: 100%;
height: 25vh;
}
.box-left{
width: 35%;
height: 100%;
float: left;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.left-item{
flex: 1;
}
.title{
float: left;
}
.number{
float: right;
}
.box-right{
width: 65%;
height: 100%;
float: right;
position: relative;
@include font_size($font_medium_s);
}
.sircle-one{
position: absolute;
width: 21vw;
height: 21vw;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
border: 1px solid #1565cb;
border-radius:50%;
}
.sircle-one-middle{
width: 18vw;
height: 18vw;
border: 1px solid #1874E7;
border-radius:50%;
margin: 0 auto;
top: 1.25vw;
position: relative;
}
.sircle-one-small{
position: absolute;
width: 15vw;
height: 15vw;
border: 1px solid #1874E7;
border-radius:50%;
top: 0;
left: 0;
bottom: 0;
right: 0;
margin: auto;
box-shadow: inset 0 0 10px #1874E7;
background: rgba(12,76,180,.3);
text-align: center;
line-height: 16vw;
}
.sircle-two{
position: absolute;
width: 18vw;
height: 18vw;
left: -17vw;
bottom: -1px;
border: 1px solid #E5E718;
box-shadow: inset 0 0 20px #E5E718;
border-radius:50%;
text-align: center;
line-height: 18vw;
}
.sircle-three{
position: absolute;
width: 17vw;
height: 17vw;
bottom: 16.5vw;
border: 1px solid #E78D18;
box-shadow: inset 0 0 20px #E78D18;
border-radius:50%;
text-align: center;
line-height: 17vw;
}
.sircle-four{
position: absolute;
width: 16vw;
height: 16vw;
left: 20vw;
bottom: 8vw;
border: 1px solid #14F5F2;
box-shadow: inset 0 0 20px #14F5F2;
border-radius:50%;
text-align: center;
line-height: 16vw;
}
.sircle-five{
position: absolute;
width: 15vw;
height: 15vw;
left: 12vw;
bottom: -11vw;
border: 1px solid #14A3F5;
box-shadow: inset 0 0 20px #14A3F5;
border-radius:50%;
text-align: center;
line-height: 15vw;
}
img{
width: 2vw;
margin-left: 2vw;
}
</style>

View File

@ -0,0 +1,140 @@
<template>
<div :id="echid" class="gfChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: {
data1: Array,
data2: Array,
data3: Array,
timeList: Array,
jqType: Number,
},
data() {
return {
echid: "",
};
},
created() {
this.echid = "ech2_" + new Date().getTime();
},
watch: {
data2: {
handler(val) {
this.hamdleJqChart();
},
immediate: true,
deep: true,
},
},
mounted() {
this.hamdleJqChart();
},
methods: {
hamdleJqChart() {
if (document.getElementById(this.echid)) {
let myechart = echarts.init(document.getElementById(this.echid));
myechart.setOption({
color:
this.jqType == 1
? ["#268bff", "#FF1A1A", "#FF7B1A"]
: ["#FF1A1A", "#268bff"],
tooltip: {
trigger: "axis",
axiosPointer: {
type: "cross",
crossStyle: {
color: "#888",
},
lineStyle: {
type: "dashed",
},
},
},
grid: {
left: "10",
right: "10",
bottom: "0",
top: "60",
containLabel: true,
},
legend: {
data:
this.jqType == 1
? ["总警情", "违法犯罪", "街面警情"]
: ["刑事", "行政"],
orient: "horizontal",
show: true,
top: 25,
},
xAxis: {
type: "category",
data: this.timeList,
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
yAxis: {
type: "value",
axisLabel: {
color: "#888",
textStyle: {
fontSize: 12,
},
},
splitLine: {
show: true,
lineStyle: {
// color: "#224465",
},
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
series: [
{
name: this.jqType == 1 ? "总警情" : "刑事",
type: "line",
smooth: true,
data: this.data1,
},
{
name: this.jqType == 1 ? "违法犯罪" : "行政",
type: "line",
smooth: true,
data: this.data2,
},
{
name: "街面警情",
type: "line",
smooth: true,
data: this.data3,
},
],
});
}
},
},
};
</script>
<style scoped>
.gfChart {
margin-top: 1vw;
height: 65vw;
width: 100vw;
margin: 0 auto;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,621 @@
<template>
<div class="compare">
<div class="title-box">
<div class="title">
{{ jqTitle }}
<img src="../../../assets/images/xiala.png" width class="img" alt="" @click="isShowJqType = true" />
<van-action-sheet v-model:show="isShowJqType">
<van-picker :columns="jqTypeList" @confirm="groupChange" @cancel="isShowJqType = false" />
</van-action-sheet>
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">高发时段分析</div>
<div class="zst-title-right">
{{ gfsdTime }}
<img src="../../../assets/images/xiala.png" width class="img" alt="" @click="chooseTime('gfsd')" />
<van-action-sheet v-model:show="isShowDataCount1">
<van-picker :columns="timeList" @confirm="change_data_count" @cancel="isShowDataCount1 = false" />
</van-action-sheet>
</div>
</div>
<div class="tag_box">
<van-tag v-for="(item, index) in tags" @click="changeTime(item)" :key="index" plain
:color="isTimeActive == item ? '#3c9cff' : ''" style="margin-right: 1vw">{{ item }}
</van-tag>
</div>
<Bar :datas="pcsfaList" />
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">高发区域TOP5</div>
<div class="zst-title-right">
{{ gfqyTime }}
<img src="../../../assets/images/xiala.png" width class="img" alt="" @click="chooseTime('gfqy')" />
<van-action-sheet v-model:show="isShowDataCount2">
<van-picker :columns="timeList" @confirm="change_data_count" @cancel="isShowDataCount2 = false" />
</van-action-sheet>
</div>
</div>
<div class="fjChart">
<TopArea :list="gfqyLIst" v-if="gfqyLIst.length > 0" />
<div v-else style="height: 10vh; text-align: center; line-height: 10vh">
没有数据
</div>
</div>
<!-- <div class="but_box" v-if="gfqyLIst.length > 0">
<span>发送指令</span>
<span>以地图展示</span>
</div> -->
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">高发类型TOP5</div>
<div class="zst-title-right">
{{ gflxTime }}
<img src="../../../assets/images/xiala.png" width class="img" alt="" @click="chooseTime('gflx')" />
<van-action-sheet v-model:show="isShowDataCount3">
<van-picker :columns="timeList" @confirm="change_data_count" @cancel="isShowDataCount3 = false" />
</van-action-sheet>
</div>
</div>
<div class="fjChart">
<TopArea :list="gflxList" v-if="gflxList.length > 0" />
<div v-else style="height: 10vh; text-align: center; line-height: 10vh">
没有数据
</div>
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">高发对象-作案人员(模拟)</div>
<div class="zst-title-right">
今日
<img src="../../../assets/images/xiala.png" width class="img" alt="" />
</div>
</div>
<div class="fjChart">
<CasePerson></CasePerson>
</div>
</div>
<div class="zst-box">
<div class="zst-title-box">
<div class="zst-title-left">高发对象-受害人(模拟)</div>
<div class="zst-title-right">
今日
<img src="../../../assets/images/xiala.png" width class="img" alt="" />
</div>
</div>
<div class="fjChart">
<CasePerson></CasePerson>
</div>
</div>
</div>
</template>
<script>
import Bar from "./components/barEcharts.vue";
import TopArea from "./components/TopArea.vue";
import CasePerson from "./components/casePerson.vue";
import {
timeValidate,
getRecentDay,
getnRencebtMonth,
} from "../../../utils/tools.js";
import { jqfxCorrelation } from "../../../api/jqfxApi.js";
export default {
components: {
Bar,
TopArea,
CasePerson,
},
data() {
return {
isShowJqType: false,
jqTitle: "总警情",
jqTypeList: ["总警情", "街面警情", "违法犯罪警情"],
//时间段选择数据
timeList: ["今日", "近7日", "近7周", "近7月"],
count: 0,
isTimeActive: "6时段",
tags: ["3时段", "4时段", "6时段", "8时段"],
pcsfaListCopy: [],
pcsfaList: [],
gflxList: [], //高发类型数据
gfqyLIst: [], //高发区域
isShowDataCount1: false, //日期选择
isShowDataCount2: false, //日期选择
isShowDataCount3: false, //日期选择
submitType: "", //选择的模块
gfsdTime: "今日",
gfqyTime: "今日",
gflxTime: "今日",
gfdxTime: "今日",
gfsdTime: "今日",
};
},
mounted() {
this.get_gfsdfx_data();
this.get_gflx_zjq_data(); //高发类别TOP5
this._getgfquData();
},
methods: {
// 时间选择
change_data_count(val) {
this._getTimeSelectData(val);
this.isShowDataCount1 = false;
this.isShowDataCount2 = false;
this.isShowDataCount3 = false;
},
//根据时间查询的数据
_getTimeSelectData(time) {
switch (this.submitType) {
case "gfsd":
this.gfsdTime = time;
this.get_gfsdfx_data();
break;
case "gflx":
this.gflxTime = time;
this.get_gflx_zjq_data();
break;
case "gfqy":
this.gfqyTime = time;
this._getgfquData();
break;
}
},
// 选择时间段
chooseTime(type) {
this.submitType = type; //选择那个模块时间
switch (type) {
case "gfsd":
this.isShowDataCount1 = true;
break;
case "gfqy":
this.isShowDataCount2 = true;
break;
case "gflx":
this.isShowDataCount3 = true;
break;
}
},
// 下拉切换 总警情、违法犯罪警情、街面警情
groupChange(val) {
switch (val.value[0]) {
case "总警情":
this.jqTitle = "总警情";
break;
case "违法犯罪警情":
this.jqTitle = "违法犯罪警情";
break;
case "街面警情":
this.jqTitle = "街面警情";
break;
}
this.isShowJqType = false;
this.get_gfsdfx_data(); //高发时段分析
this.get_gflx_zjq_data(); //高发类别TOP5
this._getgfquData(); //高发区域
},
// 高发时段分析
get_gfsdfx_data() {
let params = {
ssxgajdm: "1",
};
switch (this.gfsdTime) {
case "今日":
params.ksrq = timeValidate(new Date(), "ymd");
params.jsrq = timeValidate(new Date(), "ymd");
break;
case "近7日":
params.ksrq = getRecentDay(-7);
params.jsrq = timeValidate(new Date(), "ymd");
break;
case "近7周":
params.ksrq = getRecentDay(-49);
params.jsrq = timeValidate(new Date(), "ymd");
break;
default:
params.ksny = getnRencebtMonth(6);
params.jsny = getnRencebtMonth(0);
break;
}
// 总警情
if (this.jqTitle == "总警情") {
if (this.gfsdTime == "近7月") {
this._getJqData("/sgfx/gfsdfx/yzjq", params);
} else {
this._getJqData("/sgfx/gfsdfx/zjq", params);
}
}
if (this.jqTitle == "违法犯罪警情") {
if (this.gfsdTime == "近7月") {
this._getJqData("/sgfx/gfsdfx/ywffzjq", params);
} else {
this._getJqData("/sgfx/gfsdfx/wffzjq", params);
}
}
// 街面警情
if (this.jqTitle == "街面警情") {
if (this.gfsdTime == "近7月") {
this._getJqData("/sgfx/gfsdfx/yjmjq", params);
} else {
this._getJqData("/sgfx/gfsdfx/jmjq", params);
}
}
},
//请求高发地图警情数据
_getJqData(url, params) {
jqfxCorrelation(url, params).then((res) => {
let timeArr = [];
for (var i = 0; i < 24; i++) {
let obj = {
product: i,
警情: 0,
时长: 0,
里程: 0,
};
for (var j = 0; j < res.length; j++) {
let item = res[j];
if (i == item.jqfsksxs) {
obj["警情"] = item.sl;
}
}
timeArr.push(obj);
}
this.pcsfaListCopy = timeArr;
this.changeTime("6时段");
});
},
// 高发时段分析时段切换
changeTime(value) {
this.isTimeActive = value;
if (value == "3时段") {
this.pcsfaList = this.getGroup(3);
}
if (value == "4时段") {
this.pcsfaList = this.getGroup(4);
}
if (value == "6时段") {
this.pcsfaList = this.getGroup(6);
}
if (value == "8时段") {
this.pcsfaList = this.getGroup(8);
}
},
// 时间分组
getGroup(val) {
let arr = [];
let num = 24 / val;
if (arr.length < num) {
for (let j = 1; j <= num; j++) {
let obj = {
product: "",
警情: 0,
时长: 0,
里程: 0,
};
for (let t = 0; t < this.pcsfaListCopy.length; t++) {
let it = this.pcsfaListCopy[t];
if ((j - 1) * val <= t && t < j * val) {
let objs = JSON.parse(JSON.stringify(obj));
objs.product = (j - 1) * val + "-" + (it.product + 1);
this.count = this.count + it["警情"];
if (t % val == val - 1) {
objs["警情"] = this.count;
this.count = 0;
arr.push(objs);
break;
}
}
}
}
}
return arr;
},
//高发区域 TOP5
_getgfquData() {
let params = {
ssxgajdm: "1", //分县局代码
};
switch (this.gfqyTime) {
case "今日":
params.ksrq = timeValidate(new Date(), "ymd");
params.jsrq = timeValidate(new Date(), "ymd");
break;
case "近7日":
params.ksrq = getRecentDay(-7);
params.jsrq = timeValidate(new Date(), "ymd");
break;
case "近7周":
params.ksrq = getRecentDay(-49);
params.jsrq = timeValidate(new Date(), "ymd");
break;
default:
params.ksny = getnRencebtMonth(6);
params.jsny = getnRencebtMonth(0);
break;
}
if (this.jqTitle == "总警情") {
params.type = 1;
}
if (this.jqTitle == "违法犯罪警情") {
params.type = 3;
}
if (this.jqTitle == "街面警情") {
params.type = 2;
}
this.gfqyLIst = [];
jqfxCorrelation("/tbJq/querySgfx", params).then((res) => {
if (res && res.length > 0) {
res.forEach((item) => {
if (!item.error) {
item.name = item.address.road || item.display_name.split(",")[0];
item.sl = item.jqsl;
this.gfqyLIst.push(item);
}
});
}
});
},
// 高发类型TOP5
get_gflx_zjq_data() {
let params = {
ssxgajdm: "1", //分县局代码
};
switch (this.gflxTime) {
case "今日":
params.ksrq = timeValidate(new Date(), "ymd");
params.jsrq = timeValidate(new Date(), "ymd");
break;
case "近7日":
params.ksrq = getRecentDay(-7);
params.jsrq = timeValidate(new Date(), "ymd");
break;
case "近7周":
params.ksrq = getRecentDay(-49);
params.jsrq = timeValidate(new Date(), "ymd");
break;
default:
params.ksny = getnRencebtMonth(6);
params.jsny = getnRencebtMonth(0);
break;
}
// 总警情
if (this.jqTitle == "总警情") {
if (this.gflxTime == "近7月") {
this._getGflxData("/sgfx/gflx/yzjq", params);
} else {
this._getGflxData("/sgfx/gflx/zjq", params);
}
}
// 违法犯罪警情
if (this.jqTitle == "违法犯罪警情") {
if (this.gflxTime == "近7月") {
this._getGflxData("/sgfx/gflx/yzwffzjq", params);
} else {
this._getGflxData("/sgfx/gflx/wffzjq", params);
}
}
// 街面警情
if (this.jqTitle == "街面警情") {
if (this.gflxTime == "近7月") {
this._getGflxData("/sgfx/gflx/yjmjq", params);
} else {
this._getGflxData("/sgfx/gflx/jmjq", params);
}
}
},
//获取高发类型数据
_getGflxData(url, params) {
jqfxCorrelation(url, params).then((res) => {
if (res && res.length > 0) {
this.gflxList = res.slice(0, 5);
}
});
},
},
};
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.compare {
padding-bottom: 3vw;
}
.title-box {
display: flex;
justify-content: center;
}
.title {
width: 92vw;
height: 4vw;
background: url("../../../assets/images/bigTitle@2x.png");
background-size: 100% 100%;
margin-top: 10px;
text-align: center;
line-height: 4vw;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
::v-deep .nav-box[data-v-19978886] {
border-bottom: 1px solid #203967;
}
.zst-box {
@include font_color($font-color-theme);
@include font_size($font_medium_s);
}
.zst-title-box {
margin-top: 20px;
display: flex;
justify-content: space-between;
@include font_color($font-color-theme);
}
.zst-title-left {
background: url("../../../assets/images/lanmu-title.png") no-repeat;
background-size: 100% 100%;
flex: 2;
height: 28px;
line-height: 28px;
padding-left: 10px;
@include font_size($font_medium);
}
.zst-title-right {
flex: 1;
text-align: right;
height: 28px;
line-height: 28px;
padding-right: 10px;
color: #47b8ff;
}
.zst-title-right1 {
flex: 1;
display: flex;
justify-content: flex-end;
height: 28px;
line-height: 28px;
padding-right: 10px;
/* color: #47B8FF; */
}
.sendZL {
width: 70px;
height: 26px;
border-radius: 5px;
background-image: linear-gradient(#00c0fa, #015eea);
text-align: center;
}
.img {
margin-left: 3px;
}
.fjChart {
/* width: 80vw; */
padding: 3.5vw 3.5vw 0 3.5vw;
/* height: 30vh; */
}
.assess-box {
padding: 10px;
line-height: 18px;
font-size: 12px;
color: #e3e3e3;
}
.fjAndCqfj-box {
width: 100%;
/* height: 40vh; */
margin-top: 10px;
display: flex;
flex-direction: row;
}
.first-line {
width: 11vw;
border: 1px solid #178bed;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
background-color: rgb(51, 157, 255, 0.2);
}
.first-line :last-child {
border-bottom: unset;
}
.first-line-item {
flex: 1;
border: 1px solid #18325e;
text-align: center;
display: flex;
align-items: center;
width: 100%;
padding-left: 1.5vw;
}
.right-box {
display: flex;
border-top: 1px solid #178bed;
border-bottom: 1px solid #178bed;
width: 89vw;
overflow: auto;
}
.right-box-line-item {
width: 33vw;
border-right: 1px solid #178bed;
display: flex;
position: relative;
}
.right-line-box {
width: 11vw;
height: 40vh;
/* border: 0.5px solid #18325E; */
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
}
.first-line-item-right {
flex: 1;
border-bottom: 0.5px solid #18325e;
border-right: 1px solid #18325e;
text-align: center;
display: flex;
align-items: center;
width: 100%;
padding-left: 1.5vw;
}
.right-line-box :first-child {
border-right: unset;
}
.right-title-box {
position: absolute;
top: 0;
text-align: center;
width: 100%;
line-height: 4vh;
}
/* echarts */
#gfChart {
width: 100%;
height: 40vh;
}
.tag_box {
display: flex;
padding: 3vw;
@include font_color($font-color-theme);
@include font_size($font_medium);
}
.but_box {
text-align: center;
}
.but_box>span {
display: inline-block;
padding: 1.5vw 3vw;
margin: 0 1.5vw;
border-radius: 5px;
background-image: linear-gradient(to top, #015eea, #00c0fa);
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<div style="padding-top: 14vw">
<TopNav navTitle="警情分析" />
<TopSelectTime @chenge:time="onSelectTime" />
<div class="jqfx_box">
<compareFx :timeActive="timeActive" :keyIndex="keyIndex" />
<!-- <van-tabs
v-model:active="active"
@click-tab="getNav"
title-active-color="rgb(60, 156, 255)"
color="rgb(60, 156, 255)"
:background="backgroundColor"
:title-inactive-color="inactive"
>
<van-tab title="对比分析">
<compareFx :timeActive="timeActive" :keyIndex="keyIndex" />
</van-tab>
<van-tab title="四高分析">
<fourTallFx :timeActive="timeActive" :keyIndex="keyIndex" />
</van-tab>
<van-tab title="专题分析">
<dqscFx :timeActive="timeActive" :keyIndex="keyIndex" />
</van-tab>
</van-tabs> -->
<!-- <u-tabs :list="navList" @click="getNav" :activeStyle="{color: '#fff'}"
:inactiveStyle="{color:'#7188AF'}"
itemStyle="display:flex;justify-content: space-around;padding-left:15px;padding-right:15px; height:42.5px;">
</u-tabs> -->
<!-- </van-sticky> -->
</div>
</div>
</template>
<script setup>
import dqscFx from "./dqscFx.vue";
import compareFx from "./compareFx.vue";
import fourTallFx from "./fourTallFx.vue";
import TopNav from "../../../components/topNav.vue";
import TopSelectTime from "../../../components/topSelectTime.vue";
import { onMounted, ref } from "vue";
import { useRoute } from "vue-router";
const keyIndex = ref(1);
const active = ref(0);
const backgroundColor = ref("#fff");
const inactive = ref("#333");
const timeActive = ref(0);
// onActivated(() => {
// const route = useRoute();
// try {
// if (route.query.jqlx == "jmjq") {
// keyIndex.value++;
// }
// } catch (error) {}
// });
onMounted(() => {
if (getStorage("themeSetting") == "light") {
backgroundColor.value = "#fff";
inactive.value = "#333";
} else {
backgroundColor.value = "#041634";
inactive.value = "#fff";
}
});
function getNav(item) {
active.value = item.name;
}
function onSelectTime(val) {
timeActive.value = val;
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.jqfx_box {
padding-bottom: 2vw;
}
::v-deep .van-tabs__nav {
@include bg_color($background-color-theme);
}
::v-deep .van-tabs__nav--card {
margin: 0 1vw;
}
</style>

View File

@ -0,0 +1,165 @@
<template>
<div class="container">
<div class="title-box">
<div class="one-box">
<div class="react-box onebg"></div>
<span>{{ day }}</span>
</div>
<div class="one-box">
<div class="react-box twobg"></div>
<span>{{ yesterday }}</span>
</div>
</div>
<div class="content-box" v-for="(item, index) in dataList" :key="index">
<div class="front-box">
<div class="top-span">{{ item.orgname }}</div>
<div class="bottom-tex" :style="{ color: item.hb <= 0 ? 'green' : 'red' }">
环比:{{ item.hb }}
</div>
</div>
<div class="center-box">
<div class="center-x">
<div class="line-box onebg" :style="'width:' +
(
item.count /
(item.count + item.count1 == 0 ? 1 : item.count + item.count1)
).toFixed(2) *
100 +
'%;'
"></div>
<span>{{ item.count }}</span>
</div>
<div class="center-x">
<div class="line-box twobg" :style="'width:' +
(
item.count1 /
(item.count + item.count1 == 0 ? 1 : item.count + item.count1)
).toFixed(2) *
100 +
'%;'
"></div>
<span>{{ item.count1 }}</span>
</div>
</div>
<div class="right-box">
<div>占比</div>
<span class="span-zhanb">{{ item.zb }}</span>
</div>
</div>
</div>
</template>
<script>
import { compare } from "../../../utils/tools.js";
export default {
props: {
list: Array,
day: String,
yesterday: String,
},
watch: {
list: {
handler(val) {
for (let i = 0; i < val.length; i++) {
let item = val[i];
item.zb = (
(item.count / (item.count2 == 0 ? 1 : item.count2)) *
100
).toFixed(2);
item.hb = item.count - item.count1;
}
this.dataList = val.sort(compare("zb", true));
},
immediate: true,
deep: true,
},
},
data() {
return {
dataList: [],
};
},
methods: {},
};
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.title-box {
margin: 3vh 0;
width: 100vw;
display: flex;
justify-content: center;
@include font_color($font-color-theme);
}
.one-box {
display: flex;
margin-right: 2vw;
height: 4vw;
line-height: 4vw;
}
.react-box {
width: 8vw;
height: 4vw;
border-radius: 1vw;
margin-right: 1vw;
}
.onebg {
background: linear-gradient(#0bbafb, #4285ec);
}
.twobg {
background: linear-gradient(#98e05f, #0de3ac);
}
.content-box {
font-size: 11px;
margin: 3vw;
border-bottom: 1px dashed #224465;
display: flex;
padding-bottom: 2vw;
@include font_color($font-color-theme);
}
.center-x {
display: flex;
align-items: center;
}
.line-box {
/* width: 10vw; */
height: 2vw;
border-radius: 1vw;
margin-right: 1vw;
}
.front-box {
flex: 1;
}
.center-box {
flex: 3;
}
.right-box {
flex: 1;
margin-left: 2vw;
text-align: right;
}
.span-zhanb {
color: #ff7327;
font-size: 18px;
span-align: center;
line-height: 6vw;
}
.bottom-tex {
color: #e82929;
font-size: 11px;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav :navTitle="route.query.zt==0?'报备':'报备信息'" />
<div class="nav_tab">
<span @click="active='a'" :class="active==='a'?'tab active':'tab'">正常报备</span>
<span @click="active='b'" :class="active==='b'?'tab active':'tab'">特殊勤务报备</span>
</div>
<normalReport v-if="active==='a'" />
<specialReport v-else/>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import normalReport from "./components/normalReport";
import specialReport from "./components/specialReport";
import { computed, ref, reactive, watch, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
import { Toast } from "vant";
const router = useRouter();
const route = useRoute();
const active = ref('a')
</script>
<style lang="scss" scoped>
.container {
margin-top: 2vw;
}
.nav_tab{
padding: 2vw;
display: flex;
justify-content: space-around;
.tab{
background: #a4aec8;
color: #fff;
height: 32px;
line-height: 32px;
width: 40vw;
text-align: center;
border-radius: 16px 16px 16px 0;
}
.tab.active{
background: #517cea;
}
}
</style>

View File

@ -0,0 +1,509 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav navTitle="报备" />
<van-form @submit="onSubmit">
<van-field
:rules="[{ required: true, message: '请输入勤务名称' }]"
required
v-model="normalForm.qwmc"
label="勤务名称"
>
</van-field>
<div class="title_tab">勤务时间</div>
<van-cell title="勤务日期" @click="calShow = true">
<template #value>
<span>{{ normalForm.qwrq }}</span>
</template>
</van-cell>
<van-calendar
v-model:show="calShow"
@confirm="onConfirmTime"
:min-date="minDate"
:max-date="maxDate"
color="#3e6ee8"
></van-calendar>
<van-field
readonly
:rules="[{ required: true, message: '请选择开始时间' }]"
required
v-model="normalForm.kssj"
placeholder="请选择开始时间"
input-align="right"
is-link
label="开始时间"
@click="showkssjPicker = true"
/>
<van-popup v-model:show="showkssjPicker" position="bottom">
<van-datetime-picker
v-model="startTime"
type="datatime"
title="选择时间"
:min-date="minDate"
:max-date="maxDate"
@cancel="showkssjPicker = false"
@confirm="ksConfirm"
/>
</van-popup>
<van-field
readonly
:rules="[{ required: true, message: '请选择结束时间' }]"
required
placeholder="请选择结束时间"
v-model="normalForm.jssj"
input-align="right"
is-link
label="结束时间"
@click="showjssjPicker = true"
/>
<van-popup v-model:show="showjssjPicker" position="bottom">
<van-datetime-picker
v-model="endTime"
type="datatime"
title="选择时间"
@cancel="showjssjPicker = false"
@confirm="jsConfirm"
/>
</van-popup>
<div class="title_tab">勤务警力</div>
<van-field
v-model="normalForm.xm"
readonly
input-align="right"
label="姓名"
is-link
@click="showDialogfn('ry')"
/>
<div
class="listBox"
v-for="(item, index) in normalForm.qwjlLists"
:key="index"
>
<div class="left">
<div>{{ item.xm }} ({{ item.sfzh }})</div>
<div class="adress">{{ item.dwmc }}</div>
</div>
<div class="right" @click="deleteRy(index)">-</div>
</div>
<van-field v-model="normalForm.clxx" label="车辆信息"> </van-field>
<van-field
v-model="normalForm.sbmc"
readonly
input-align="right"
label="选择设备信息"
is-link
placeholder="请选择设备信息"
@click="popupShowCar = true"
/>
<div class="title_tab">装备信息</div>
<div class="zbBox">
<span class="zbBox-item" v-for="(item,i) in normalForm.qwzbLists" :key="i">
<span class="bt">{{item.zbmc}}</span>
<van-stepper :min="0" :max="1000" v-model="item.zbsl" />
</span>
</div>
<div style="padding: 0 5vw" v-if="obj.bbInfo">
<van-button
style="margin: 16px 0"
:loading="loading"
round
@click="editFn(0)"
block
type="success"
>
结束报备
</van-button>
</div>
<div style="margin: 16px 0; padding: 0 5vw" v-else>
<van-button
:loading="loading"
round
native-type="submit"
block
type="primary"
>
开始报备
</van-button>
</div>
</van-form>
<!-- 负责人 -->
<SelectPeo
:isRadio="isRadio"
:selectType="selectType"
:show="showSelect"
:checkedList="normalForm.qwjlLists"
@update:cancel="showSelect = false"
@update:confirm="onComfirm"
:key="selectIndex"
/>
<!-- 弹出层 -->
<van-popup v-model:show="popupShowCar" round position="bottom">
<van-picker
:columns="sblist.list"
:columns-field-names="customFieldName"
@cancel="popupShowCar = false"
@confirm="submitPoup"
/>
</van-popup>
</div>
</template>
<script setup>
import { getZBList, qwbbAdd, getSBList } from "@/api/checkponit.js";
import { getItem } from "../../../utils/storage";
import TopNav from "../../../components/topNav";
import SelectPeo from "./selectPeo.vue";
import { Dialog, Toast } from "vant";
import { dateFormat, hintToast } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { computed, ref, reactive, onMounted, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import { get } from "vant/lib/utils";
Toast.allowMultiple();
const { D_BZ_HPZL } = getDictList("D_BZ_HPZL");
const router = useRouter();
const route = useRoute();
const minDate = new Date(2022, 0, 1);
const maxDate = new Date(2050, 0, 1);
const userInfo = getItem("userInfo");
const popupShowCar = ref(false); //选择车辆弹窗
const selectType = ref(""); //选择的类型
const isRadio = ref(false); //单选框默认选中
const showSelect = ref(false); //人员弹窗
const selectIndex = ref(1); //选择器组件KEY
const calShow = ref(false); //是否显示巡防日期选择器
const showkssjPicker = ref(false); // 开始时间结束时间
const showjssjPicker = ref(false); // 结束时间结束时间
const startTime = new Date()
const endTime = new Date()
const normalForm = reactive({
qwmc: "",
qwrq: dateFormat("", new Date()),
ssbm: userInfo.deptName,
ssbmdm: userInfo.deptList[0].deptCode,
sbbh: "",
sbmc: "",
qwjlLists: [],
qwzbLists: [
{
zbmc: "枪支",
zbsl: 0,
entryCode: "qz",
},
{
zbmc: "弹药",
zbsl: 0,
entryCode: "dy",
},
{
zbmc: "手铐",
zbsl: 1,
entryCode: "sk",
},
{
zbmc: "执法仪",
zbsl: 0,
entryCode: "zfy",
},
{
zbmc: "警棍",
zbsl: 0,
entryCode: "jg",
},
{
zbmc: " 盾牌",
zbsl: 0,
entryCode: "dp",
},
{
zbmc: "手电",
zbsl: 1,
entryCode: "sd",
},
{
zbmc: " 急救包",
zbsl: 0,
entryCode: "jjb",
},
{
zbmc: "防暴叉",
zbsl: 0,
entryCode: "fbc",
},
{
zbmc: "防暴头盔",
zbsl: 0,
entryCode: "fbtk",
},
{
zbmc: "手持对讲机",
zbsl: 0,
entryCode: "sjdjj",
},
{
zbmc: "移动警务终端",
zbsl: 0,
entryCode: "ydjwzd",
},
]
}); //表单数据
// 巡防日期
const obj = ref({
bbInfo: null,
});
const sblist = {
list: [],
}; //设备数据
const customFieldName = {
text: "baseName",
};
onMounted(() => {
getZbList();
getsBList();
});
// 装备数据
function getZbList() {
getZBList({ scSysDictionaryCatalogId: 20 }).then((res) => {
let arr = [];
normalForm.qwzbLists = res.scSysDictionaryEntrys.map((item) => {
return {
zbmc: item.entryName,
zbsl: 0,
entryCode: item.entryCode,
};
});
});
}
// 设备数据
function getsBList() {
getSBList({ typeDevicesCode: 8 }).then((res) => {
sblist.list = res;
});
}
// 选择开始时间
function ksConfirm(val) {
normalForm.kssj = dateFormat("all", val);
showkssjPicker.value = false;
}
// 选择结束时间
function jsConfirm(val) {
normalForm.jssj = dateFormat("all", val);
showjssjPicker.value = false;
}
//打开勤务警力选择框
function showDialogfn(val) {
selectType.value = val;
showSelect.value = true;
selectIndex.value++;
}
//选中勤务时间
function onConfirmTime(val) {
calShow.value = false;
normalForm.qwrq = dateFormat("", val);
}
//选中人员确认按钮
function onComfirm(val) {
let arr = [];
val.forEach((item) => {
let obj = {
id: item.id,
sfzh: item.sfzh,
dwdm: item.ssbmdm,
dwmc: item.ssbm,
jylx: item.jylx,
xm: item.xm,
sjhm: item.lxdh,
};
arr.push(obj);
});
normalForm.qwjlLists = arr;
}
// 删除人员
function deleteRy(index) {
normalForm.qwjlLists.splice(index, 1);
}
// 新增报备接口
function onSubmit() {
normalForm.qwjlLists.forEach(item=>{
item.jylx = item.jylx == '01'?1:2
delete item.id
})
normalForm.kkbh = route.query.kkid;
normalForm.kkmc = route.query.kkmc;
qwbbAdd(normalForm).then((res) => {
hintToast("保存成功");
router.go(-1)
});
}
function submitPoup(val) {
normalForm.sbbh = val.scDevicesInfoId;
normalForm.sbmc = val.baseName;
popupShowCar.value = false;
}
//结束报备
function editFn(e) {
Dialog.confirm({
title: "提示",
message: "是否确认结束报备!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {});
}
// 获取装备数据
function getZbData() {}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.popupTitle {
text-align: center;
background-color: rgb(11, 137, 247);
height: 6vh;
line-height: 6vh;
}
.popbtn-box {
width: 100%;
display: flex;
justify-content: space-around;
}
.check-item-tag {
display: inline-block;
margin: 0 6px;
}
.check-data-box {
height: 25vh;
overflow: auto;
}
.time-box {
display: flex;
}
::v-deep .mulSelect .van-cell__title,
.van-cell__value {
flex: unset;
}
::v-deep .mulSelect .van-cell__value {
flex: 1;
}
.title_tab {
@include font_color($font-color-theme);
padding-left: 7vw;
position: relative;
margin: 2vw 0;
letter-spacing: 2px;
}
.title_tab::after {
content: "";
position: absolute;
top: 0;
left: 5vw;
bottom: 0;
width: 4px;
background: #3b6be7;
border-radius: 2px;
}
.van-cell:after {
display: none;
}
.van-cell {
@include table_item_color($table-item-theme);
box-sizing: border-box;
border-radius: 4px;
padding: 6px;
margin: 8px 5%;
width: 90%;
overflow: hidden;
color: var(--van-cell-text-color);
font-size: var(--van-cell-font-size);
line-height: var(--van-cell-line-height);
}
.zbBox {
display: flex;
font-size: 12px;
color: rgb(150, 146, 146);
padding: 0 5vw;
box-sizing: border-box;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
.zbBox-item {
width: 48%;
margin: 2vw 0;
.bt {
display: inline-block;
width: 60px;
text-align: center;
}
.zbBox-item:nth-child(2n) {
margin-left: 4vw;
}
}
}
.popupTitle {
color: #fff;
}
.listBox {
display: flex;
justify-content: space-between;
align-items: center;
margin: 4vw 5vw;
border-radius: 2vw;
padding: 0.5vw 2vw;
box-sizing: border-box;
font-size: 13px;
background-color: #e8eeff;
.left {
flex: 1;
> div {
max-width: 280px;
line-height: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.adress {
color: #727171;
}
}
.right {
width: 20px;
height: 20px;
margin-left: 4vw;
line-height: 16px;
text-align: center;
background: red;
border-radius: 50%;
color: #fff;
font-size: 20px;
font-weight: 800;
}
}
::v-deep .van-field__label {
margin-right: 0px;
}
::v-deep .van-radio-group--horizontal,
.van-checkbox-group--horizontal {
flex-wrap: nowrap;
@include font_size($font_medium_s);
}
::v-deep .van-field__control--custom {
justify-content: flex-end;
}
::v-deep .van-field__control {
text-align: right;
}
</style>

View File

@ -0,0 +1,229 @@
<template>
<van-popup v-model:show="props.show" round style="width: 95%" @click-overlay="onClickOverlay">
<div style="padding: 3vw">
<div class="other_type_title">附近力量</div>
<div class="function_box">
<div @click="onClickFjll(item)" v-for="item in points.fjllList" :key="item" class="function_item">
<img :src="item.imgUrl" alt="" :class="{ imgBack: item.checked }" />
<div class="function_title">{{ item.title }}</div>
</div>
</div>
<div class="other_type_title">附近资源</div>
<div class="function_box">
<div @click="onClickFjzy(item)" v-for="item in points.fjzyList" :key="item" class="function_item">
<img :src="item.imgUrl" alt="" :class="{ imgBack: item.checked }" />
<div class="function_title">{{ item.title }}</div>
</div>
</div>
<div class="other_type_title">附近场所</div>
<div class="function_box">
<div @click="onClickFjcs(item)" v-for="item in points.fjcsList" :key="item" class="function_item">
<img :src="item.imgUrl" alt="" :class="{ imgBack: item.checked }" />
<div class="function_title">{{ item.title }}</div>
</div>
</div>
</div>
</van-popup>
</template>
<script setup>
import { timeValidate} from "@/utils/tools.js";
import emitter from "@/utils/eventBus.js";
import { serviceHttp } from '@/api/serviceHttp.js'
import { getDictList, setDict } from "@/utils/dict";
import { defineProps, ref, reactive, defineEmits } from "vue";
const { JQLB_DP , D_BZ_BMYWLX} = getDictList( "JQLB_DP" ,"D_BZ_BMYWLX");
const props = defineProps({
show:{
type:Boolean,
default:false
}
})
const emits = defineEmits(["update:close"]);
//点位功能
const points = reactive({
//附近力量
fjllList: [
{
imgUrl: require("../../../assets/lz/xz.png"),
title: "巡组",
checked: false,
},
{
imgUrl: require("../../../assets/lz/jwz.png"),
title: "警务站",
checked: false,
},
{
imgUrl: require("../../../assets/lz/kfd.png"),
title: "快反点",
checked: false,
},
],
//附近资源
fjzyList: [
{
imgUrl: require("../../../assets/lz/sp.png"),
title: "视频",
checked: false,
},
{
imgUrl: require("../../../assets/lz/jtkk.png"),
title: "交通卡口",
checked: false,
},
{
imgUrl: require("../../../assets/lz/zl.png"),
title: "指令",
checked: false,
},
{
imgUrl: require("../../../assets/lz/jq.png"),
title: "警情",
checked: false,
},
{
imgUrl: require("../../../assets/lz/jq.png"),
title: "战果",
checked: false,
},
],
//附近场所
fjcsList: [
{
imgUrl: require("../../../assets/lz/ld.png"),
title: "旅店",
checked: false,
},
{
imgUrl: require("../../../assets/lz/wb.png"),
title: "网吧",
checked: false,
},
{
imgUrl: require("../../../assets/lz/dzjg.png"),
title: "党政机关",
checked: false,
},
],
});
//点击遮罩层
function onClickOverlay() {
emits("update:close", false);
}
//点击附近力量
function onClickFjll(item) {
item.checked = !item.checked;
points.fjllList.forEach(item=>{
if(item.checked && item.title == '巡组') handleGroup();
if(!item.checked && item.title == '巡组') emitter.emit("deletePointZBAll");
if(item.checked && item.title == '警务站') getPoints('jwz');
if(!item.checked && item.title == '警务站') emitter.emit("deletePoint", "jwz");
if(item.checked && item.title == '快反点') getPoints('kfd');
if(!item.checked && item.title == '快反点') emitter.emit("deletePoint", "kfd");
})
}
// 获取巡组信息
const handleGroup = () => {
let pramas = { xfzt:' 0,1,2', qwlx: '01,02,03', pageSize: 500, pageCurrent: 1 }
serviceHttp.get(pramas,'/mosty-qwzx/tbQwXfbb/selectDeckList').then(res=>{
let arr = res.records ? res.records : [];
let brrSd = arr.filter((v) => { return v.jd && v.wd; });
let pramas = { coords: brrSd,undel:true, icon: '', flag: "rx" }
emitter.emit("addPointTakeTittle", pramas);
})
}
// 处理警务站 - 快返回点
const getPoints = (type) =>{
let data = {ysdl: "001", yszl: "001001"}
let icon = ''
switch(type){
case 'jwz':
data.ysxl = "001001007";
icon = require("@/assets/pointIcon/jwz.png");
break;
case 'kfd':
data.ysxl = "001001008";
icon = require("@/assets/pointIcon/f.png");
break;
}
serviceHttp.post(data,'/mosty-yszx/tbYsGajg/getList').then(res=>{
let arr = res.records ? res.records : [];
handlePoint(arr, icon, type);
})
}
// 处理撒点
const handlePoint = (arr,icon,flag,scale) =>{
let list = arr.filter((item) => { return item.jd && item.wd; });
emitter.emit("addPoint", { coords: list, icon: icon, flag: flag ,scale });
}
//点击附近资源
const onClickFjzy = (item) => {
item.checked = !item.checked;
points.fjzyList.forEach(item=>{
if(item.checked && item.title == '指令') handleZl();
if(!item.checked && item.title == '指令') emitter.emit("deletePoint", "yjMap");
if(item.checked && item.title == '警情') handleJQ();
if(!item.checked && item.title == '警情') emitter.emit("deletePoint", "jqMap");
})
}
// 处理指令
const handleZl = () =>{
let params = { startTime: timeValidate(new Date(), "ymd"), endTime: timeValidate(new Date(), "ymd")};
serviceHttp.get(params,'/mosty-yjzl/tbYjxx/getList').then(res=>{
let arr = res ? res : [];
let icon = require("@/assets/pointIcon/icon-zl.png")
handlePoint(arr, icon, 'yjMap',1.2);
})
}
// 处理警情
const handleJQ = () =>{
let jqlb = JQLB_DP.value.map(item => {return item.value})
let params = {
startTime: timeValidate(new Date(), "ymd"),
endTime: timeValidate(new Date(), "ymd"),
bjlbs:jqlb.join(','),
mylb:'1,2'
};
serviceHttp.get(params,'/mosty-sjzx/tbJq/getList').then(res=>{
let arr = res ? res : [];
let icon = require("@/assets/pointIcon/jqIcon.png")
handlePoint(arr, icon, 'jqMap',1.2);
})
}
//点击附近场所
function onClickFjcs(item) {
item.checked = !item.checked;
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.function_box {
@include font_size($font_medium_s);
display: flex;
flex-wrap: wrap;
.function_item {
text-align: center;
width: 25%;
padding: 3vw 0;
.function_title {
margin-top: 1vw;
}
> img {
background: #3e6ee8;
width: 25px;
height: 25px;
border-radius: 50%;
padding: 2.5vw;
}
.imgBack {
background: orange;
}
}
}
</style>

View File

@ -0,0 +1,250 @@
<template>
<van-popup v-model:show="props.show" style="width: 90%">
<div class="popupTitle">{{ popupTitle }}</div>
<van-tabs v-model:active="active" color="#3e6ee8" @change="onActive">
<van-tab title="民警" name="01"> </van-tab>
<van-tab title="辅警" name="02"> </van-tab>
</van-tabs>
<van-search
v-model="searchVal"
:placeholder="placeholder"
@search="onUpdate"
@clear="onClear"
/>
<div class="check-data-box">
<van-list
v-model:loading="loading"
:finished="finished"
finished-text=""
@load="onLoad"
offset="1"
:immediate-check="false"
>
<!-- 单选 -->
<van-radio-group v-model="radioChecked" v-if="props.isRadio">
<van-cell-group>
<van-cell
v-for="item in list.mulChooseList"
clickable
:key="item"
:title="`${item.xm} (${item.lxdh})`"
:border="false"
>
<template #right-icon>
<van-radio :name="item.id" />
</template>
<template #label>
<div>
<span :class="active == '02'?'bqBox':'bqBox1'">{{active == '02'?'辅警':'民警'}}</span> {{ item.ssbm }}
</div>
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
<!-- 多选 -->
<van-checkbox-group
v-else
v-model="checkedLists"
@change="hoooo"
>
<van-cell-group v-if="list.mulChooseList.length > 0">
<van-cell
v-for="item in list.mulChooseList"
clickable
:key="item"
:title="item.xm +(item.lxdh)"
>
<template #right-icon>
<van-checkbox shape="square" :name="item.id" />
</template>
<template #label>
<span :class="active == '02'?'bqBox':'bqBox1'">{{active == '02'?'辅警':'民警'}}</span>
<div>{{ item.ssbm }}</div>
</template>
</van-cell>
</van-cell-group>
</van-checkbox-group>
<van-empty
description="没有数据"
image="default"
v-if="list.mulChooseList.length <= 0 && loading == false"
/>
</van-list>
</div>
<div class="popbtn-box">
<van-button style="flex: 1" type="default" @click="onCancel"
>取消
</van-button>
<van-button style="flex: 1" type="primary" @click="onConfirm"
>确定</van-button
>
</div>
</van-popup>
</template>
<script setup>
import { getBBData ,getXfllRyData} from "@/api/xfbbAndZbbb.js";
import { defineProps, ref, defineEmits, watch, reactive, onMounted } from "vue";
import { dateFormat, hintToast } from "@/utils/tools";
const props = defineProps({
selectType: String, //查询的类型 详情见watch 监听
show: Boolean, //是否显示
checkedList: Array, //默认选中 多选
isRadio: String, //单选
});
const emits = defineEmits([
"update:cancel",
"update:confirm",
"update:tabs",
"update:tag",
]);
const popupTitle = ref("人员"); //标题
const active = ref('01'); //默认的TBS 选择
const loading = ref(false); //列表加载
const finished = ref(false);
const checkedLists = ref([]); //选中的数据
const page = ref(1);
const total = ref(0);
const radioChecked = ref("");
const placeholder = ref(""); //占位字符
const list = reactive({
mulChooseList: [],
}); //列表数据
const sowMuList = ref([]) //展示民警辅警的数据
watch(
() => props.checkedList,
(newValue) => {
if (props.isRadio && newValue.length>0) {
radioChecked.value = newValue[0].id;
} else {
checkedLists.value = newValue.map((item) => {
return item.id;
});
}
},
{ immediate: true, deep: true }
);
onMounted(()=>{
getList('01') //获取民警人员列表
})
//tabs切换
function onActive(val) {
page.value = 1
list.mulChooseList = []
getList(val)
}
const searchVal = ref(""); //选择器关键字
//搜索关键词
function onUpdate() {
page.value = 1
getList(active.value)
}
//清空关键字
function onClear() {
page.value = 1
getList(active.value)
}
//触底加载
function onLoad() {
if (page.value >= total.value) {
finished.value = true;
return;
}
page.value++;
getList(active.value)
}
function hoooo(){
}
// 获取民警、辅警数据列表
function getList(jllx){
loading.value = true
let params = {
pageCurrent: page.value,
pageSize: 10,
keyword: searchVal.value,
jllx
}
getXfllRyData(params).then(res=>{
if(page.value == 1){
list.mulChooseList = res.records
}else{
list.mulChooseList = list.mulChooseList.concat(res.records)
}
sowMuList.value = sowMuList.value.concat(res.records)
let newObj = {}
sowMuList.value = sowMuList.value.reduce((preval,curval)=>{
newObj[curval.id]?'':newObj[curval.id] = preval.push(curval)
return preval
},[])
total.value = res.total
loading.value = false
})
}
//关闭弹窗
function onCancel() {
emits("update:cancel", false);
}
//确认选择
function onConfirm() {
if (radioChecked.value == "" && checkedLists.value.length <= 0) {
hintToast("请选择人员");
} else {
let arr = props.isRadio ? [radioChecked.value] : checkedLists.value;
let brr = []
sowMuList.value.forEach(v=>{
v.jylx = active.value
arr.forEach(t=>{if(v.id == t) brr.push(v)})
})
emits("update:confirm", brr);
emits("update:cancel", false);
}
}
</script>
<style lang="scss" scoped>
@import "@/assets/styles/mixin.scss";
.popupTitle {
text-align: center;
background-color: rgb(11, 137, 247);
height: 6vh;
line-height: 6vh;
color: #fff;
}
.popbtn-box {
width: 100%;
display: flex;
justify-content: space-around;
padding-top: 2vw;
}
.check-data-box {
height: 100vw;
overflow: auto;
}
::v-deep .van-stepper__input {
width: 100px;
}
.zn_tag_select {
padding: 2vw 3.5vw;
}
.bqBox{
padding: 0.5vw 2vw;
border-radius: 1vw;
background: rgb(42, 209, 167);
color: #fff;
font-size: 12px;
}
.bqBox1{
padding: 0.5vw 2vw;
border-radius: 1vw;
background: rgb(21, 178, 240);
color: #fff;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,703 @@
<template>
<div style="height:100vh">
<GdMap />
<div class="point-pop-alert">
<img :src="require('../../assets/images/p1.png')" @click="onClickYjbj" alt />
<img :src="require('../../assets/images/p2.png')" @click="functionShow = true" alt />
</div>
<div class="hsf">
<van-popover v-model:show="showThemeSetting" :actions="actions" :theme="defaultThemeQp" :offset="[16, 0]"
placement="bottom-end" @select="onSelectSeting" :teleport="isbody">
<template #reference>
<van-icon name="weapp-nav" color="#fff" size="22px" @click.stop="showThemeSetting = true" />
</template>
</van-popover>
</div>
<FjFunction :show="functionShow" @update:close="functionShow = false" />
<div class="homeTotal_box">
<TopTabs :list="zdModule" :kkid="route.query.kkid" :kkmc="route.query.kkmc" @onPcTypeShow="onPcTypeShow"
:xzList="xzList" />
<div class="home_box">
<!-- 检查站 -->
<ul class="count-box count-box-jcz" v-if="isShowModel">
<li class="count-item-jcz">
<div class="count-item-jcz-name">执勤时长</div>
</li>
<li class="count-item-jcz" v-for="(item, index) in countJczList" :key="index">
<div class="count-item-jcz-num">
<div class="count-item-jcz-num-left">
<span class="num-red">{{ item.total1 }}</span> <br />
<span class="text">{{ item.text1 }}</span>
</div>
<div class="count-item-jcz-num-right">
<span class="num">{{ item.total2 }}</span> <br />
<span class="text">{{ item.text2 }}</span>
</div>
</div>
<div class="count-item-jcz-name">{{ item.title }}</div>
</li>
</ul>
<!-- 巡防 -->
<div class="count-box" v-else>
<div class="count-item" v-for="(item, index) in countList" :key="index">
<div class="bottom-box">
<div class="inner-box">{{ item.title }}</div>
</div>
<div class="left" @click="uploadSsxz(item, 'L')">
<div class="num1">{{ item.total1 }}</div>
<div class="text-box">{{ item.text1 }}</div>
</div>
<div class="right" @click="uploadSsxz(item, 'R')">
<div :class="item.title === '实时巡组'
? 'num1'
: item.title === '指令信息'
? 'num2'
: 'num3'
">
{{ item.total2 }}
</div>
<div class="text-box">{{ item.text2 }}</div>
</div>
</div>
</div>
</div>
</div>
<van-dialog :show="showUserChangePicker" title="选择角色" show-cancel-button @confirm="onConfirm"
@cancel="showUserChangePicker = false" confirmButtonColor="#3e6ee8">
<van-radio-group v-model="isActive">
<van-radio v-for="item in radioList" :key="item.id" :name="item.id">{{
item.homename
}}</van-radio>
</van-radio-group>
</van-dialog>
<BottomTabs type="sy" />
<!-- 盘人 街面巡防 -->
<checkedPeople ref="pr" :key="pcKey + 'pr'" />
<!-- 盘车 -->
<checkedCar ref="pc" :key="pcKey + 'pc'" />
</div>
</template>
<script setup>
import Axios from "axios";
import { getyjzlCount } from "../../api/checkponit.js";
import checkedCar from "../spsHome/components/checkCar.vue";
import { qcckGet } from "@/api/qcckApi.js";
import checkedPeople from "../spsHome/components/checkPeople.vue";
import {
dateFormat,
setUserHome,
hintToast,
timeValidate,
} from "../../utils/tools.js";
import TopTabs from "../../components/topTabs.vue";
import GdMap from "../../components/GdMap/index.vue";
import BottomTabs from "../../components/bottomTabs.vue";
import FjFunction from "./components/fjFunction.vue";
import { setUserDefaultModleData, getUserLzLocation } from "../../api/user.js";
import {
getRypcList,
getRypcCount,
getClpcCount,
getClpcPcList,
getNearXz,
queryListfzyc,
} from "../../api/common.js";
import {
getUserSelectPage,
selectDeck1,
getZlsl,
selectDeck3,
addYjbj,
} from "../../api/gxHomeApi.js";
import emitter from "../../utils/eventBus.js";
import {
ref,
onMounted,
onUnmounted,
reactive,
nextTick,
onBeforeUnmount,
} from "vue";
import { useRouter, useRoute } from "vue-router";
import { Dialog } from "vant";
const route = useRoute();
const timeHour = ref(0); //小时
const timeMine = ref(0); //分钟
const timeSec = ref(0); //秒
const Loadtion = ref({
address: "暂无地址信息",
lng: "暂无",
lat: "暂无",
ly: "暂无",
});
const isShowModel = ref(false); //展示底部模块
//统计数据
const countJczList = ref([
{
text1: "执勤",
text2: "接收",
title: "预警指令",
total1: 0,
total2: 0,
},
{
text1: "盘查",
text2: "移交",
title: "盘查人员",
total1: 0,
total2: 0,
},
{
text1: "盘查",
text2: "移交",
title: "盘查车辆",
total1: 0,
total2: 0,
},
]);
//统计数据
const countList = ref([
{
text1: "巡组",
text2: "警力",
title: "实时巡组",
total1: 0,
total2: 0,
},
{
text1: "完成",
text2: "执行中",
title: "预警指令",
total1: 0,
total2: 0,
},
{
text1: "总数",
text2: "移交",
title: "盘查人员",
total1: 0,
total2: 0,
},
{
text1: "总数",
text2: "移交",
title: "盘查车辆",
total1: 0,
total2: 0,
},
]);
function uploadSsxz(row, type) {
switch (row.title) {
case "实时巡组":
router.push("/qwCenter");
break;
case "预警指令":
router.push("/yyzx/zlzx/zlzxIndex");
break;
case "盘查人员":
router.push("/yyzx/views/pcry");
break;
case "盘查车辆":
router.push("/yyzx/views/clpc");
break;
}
}
let timer;
onMounted(() => {
localStorage.removeItem('NFC')
localStorage.removeItem('OCR')
_getUserLocation(true); //获取当前位置
setInterval(() => {
_getUserLocation(false); //获取当前位置
}, 5000);
if (route.query.kkid) {
isShowModel.value = true; //展示检查站
getCountJcz(); //获取检查站预警指令统计
getPcCountJcz(); //获取盘查统计接口
setInterval(() => { getTimer(); }, 1000);
} else {
isShowModel.value = false; //展示街面巡防
onShowFZYC(); //显示犯罪区域
_getUserSelectPage();
getTjdata();
timer = setInterval(() => {
getJmxzList();
}, 5e3);
}
});
//获取当前位置信息
function _getUserLocation(sfdw) {
let { lng, lat, zbly } = getLocation();
if (lng && lat) {
// qcckGet({ longitude: lng, latitude: lat }, "/mosty-wzzx/gxga/locationInfo/wgs842Mercator").then(res => {
// emitter.emit("deletePointArea", "dw");
// emitter.emit("addPointArea", {
// coords: [{ jd: res.longitude, wd: res.latitude }],
// icon: require("../../assets/lz/dw.png"),
// flag: "dw",
// sfdw: sfdw,
// sizeX: 30,
// sizeY: 35
// });
// })
Loadtion.value.lng = lng;
Loadtion.value.lat = lat;
Loadtion.value.ly = zbly == 1 ? "GPS" : "融合";
emitter.emit("deletePointArea", "dw");
//地图撒点然后移动
emitter.emit("addPointArea", {
coords: [{ jd: lng, wd: lat }],
icon: require("../../assets/lz/dw.png"),
flag: "dw",
sfdw: sfdw,
sizeX: 30,
sizeY: 35
});
} else {
hintToast("暂无坐标信息");
}
}
// 获取计数器
function getTimer() {
timeSec.value++;
if (timeSec.value >= 60) {
timeSec.value = 1;
timeMine.value++;
}
if (timeMine.value >= 60) {
timeMine.value = 1;
timeHour.value++;
}
}
onUnmounted(() => {
clearInterval(timer);
});
// 获取检查站-预警指令统计数据
function getCountJcz() {
let params = {
beginDate: dateFormat() + " 00:00:00",
checkpointCode: route.query.kkid,
};
getyjzlCount(params).then((res) => {
countJczList.value[0].total1 = res.completed; //执勤
countJczList.value[0].total2 = res.received; //接收
});
}
// 获取检查站 - 盘查 人-车-统计数据
function getPcCountJcz() {
// 盘查人员 移交
getRypcList({
pageCurrent: 1,
pageSize: 10,
pcclJg: 2,
kkid: route.query.kkid,
}).then((res) => {
countJczList.value[1].total2 = res.total;
});
// 盘查人员 盘查
getRypcList({
pageCurrent: 1,
pageSize: 10,
pcclJg: 9,
kkid: route.query.kkid,
}).then((res) => {
countJczList.value[1].total1 = res.total;
});
// 盘查车辆 移交
getClpcPcList({
pageCurrent: 1,
pageSize: 10,
pcclJg: 2,
kkid: route.query.kkid,
}).then((res) => {
countJczList.value[2].total2 = res.total;
});
// 盘查车辆 盘查
getClpcPcList({
pageCurrent: 1,
pageSize: 10,
pcclJg: 9,
kkid: route.query.kkid,
}).then((res) => {
countJczList.value[2].total1 = res.total;
});
}
// 盘查数据tab
function onPcTypeShow(type) {
pcKey.value++;
switch (type) {
case "pr":
nextTick(() => {
pr.value.handleOpen();
});
break;
case "pc":
nextTick(() => {
pc.value.handleOpen();
});
break;
}
}
// *******************************************************
const userInfo = getStorage("userInfo");
const pcKey = ref(1);
const pr = ref(null);
const pc = ref(null);
const router = useRouter();
const isActive = ref(7); //用户选中的身份
const radioList = ref([]); //用户身份数据
const showUserChangePicker = ref(false); //用户换身份弹窗
const showThemeSetting = ref(false); //是否显示设置主题模板
const defaultThemeQp = ref("light"); //默认的右侧气泡框主题
const isbody = ref("body");
const xzList = ref([]); //巡组数据
const actions = [
{
text: "切换身份",
icon: "exchange",
},
];
const functionShow = ref(false); //是否显示点位功能区
const zdModule = ref([
{
bkmc: "报备",
},
{
bkmc: "特殊报备",
},
{
bkmc: "盘人",
},
{
bkmc: "盘车",
},
{
bkmc: "指令",
},
]);
// 查询巡组并撒点
function getJmxzList(xfzt) {
let data = {
bbrq: timeValidate(new Date(), "ymd"),
xfzt: "0,1,2",
pageSize: 500,
pageCurrent: 1,
};
}
//点击一键报警
function onClickYjbj() {
let { lng, lat, zbly } = getLocation();
if (lng && lat) {
Loadtion.value.lng = lng;
Loadtion.value.lat = lat;
getUserLzLocation({ lng, lat }).then((res) => {
if (res) {
Loadtion.value.address = res.city + res.suburb + res.town + res.village;
}
});
} else {
Loadtion.value.lng = jd;
Loadtion.value.lat = wd;
Loadtion.value.address = address;
}
Dialog.confirm({
title: "提示",
message: "是否一键报警?",
})
.then((res) => {
addYjbj({
jd: Loadtion.value.lng,
wd: Loadtion.value.lat,
sfdz: Loadtion.value.address,
}).then((res) => { });
hintToast("您选择了一键报警!");
})
.catch((err) => {
hintToast("您取消了一键报警!");
});
}
//获取用户首页模板
function _getUserSelectPage() {
getUserSelectPage({
size: 20,
current: 1,
}).then((res) => {
res.records.forEach((item) => {
radioList.value.push(item);
});
});
}
//选中的设置信息
function onSelectSeting(e) {
switch (e.text) {
case "切换身份":
showUserChangePicker.value = true;
break;
}
}
//获取统计数据
function getTjdata() {
selectDeck1({}).then((res) => {
countList.value[0].total2 = res.jmfjsl + res.jmmjsl;
countList.value[0].total1 = res.sjsl;
});
// 模块二
getZlsl({}).then((res) => {
if (res) {
countList.value[1].total2 = res.all - res.wwc;
countList.value[1].total1 = res.all;
}
});
// 模块三 盘查人员
// 移交
// getRypcList({ pageCurrent: 1, pageSize: 10, pcclJg: 2 }).then((res) => {
// countList.value[2].total1 = res.total;
// });
// // 盘查
// getRypcList({
// pageCurrent: 1,
// pageSize: 10,
// pcclJg: 9,
// }).then((res) => {
// countList.value[2].total2 = res.total;
// });
getRypcCount({}).then((res) => {
countList.value[2].total1 = res.All;
countList.value[2].total2 = res.yj;
});
// 模块四 盘查车辆
// 移交
// getClpcPcList({
// pageCurrent: 1,
// pageSize: 10,
// pcclJg: 2,
// }).then((res) => {
// countList.value[3].total1 = res.total;
// });
// // 盘查
// getClpcPcList({
// pageCurrent: 1,
// pageSize: 10,
// pcclJg: 9,
// }).then((res) => {
// countList.value[3].total2 = res.total;
// });
getClpcCount({}).then((res) => {
countList.value[3].total1 = res.All;
countList.value[3].total2 = res.yj;
});
}
//用户选中身份
function onConfirm() {
showUserChangePicker.value = false;
setUserHome(isActive.value);
}
//犯罪区域撒点
function onShowFZYC() {
emitter.emit("deletePointArea", 'fzyc')
queryListfzyc().then((res) => {
if (res.length == 0) return false;
res.forEach((item, index) => {
emitter.emit("setFzyc", { data: item, index: index, });
});
});
}
</script>
<style lang="scss" scoped>
@import "../../assets/styles/mixin.scss";
::v-deep .van-radio-group {
padding: 5vw;
}
::v-deep .van-radio {
padding: 2vw 0;
}
.homeTotal_box {
position: absolute;
bottom: 13.5vw;
z-index: 20;
background: #fff;
width: 100%;
border-top-left-radius: 2vw;
border-top-right-radius: 2vw;
}
.home_box {
padding: 1vw 3vw 3vw 3vw;
}
.point-pop-alert {
position: absolute;
display: flex;
flex-direction: column;
top: 80px;
right: 10px;
>img {
width: 45px;
height: 45px;
margin: 2vw 0;
}
}
.count-box {
display: flex;
flex-wrap: wrap;
line-height: 3.5vh;
justify-content: space-around;
@include font_size($font_medium_s);
.count-item {
margin-top: 1vh;
width: 47%;
display: flex;
margin-top: 3%;
align-items: center;
background-color: rgba(140, 175, 206, 0.1);
border-radius: 1.5vw;
.bottom-box {
flex: 1;
box-sizing: border-box;
padding: 10px;
border-right: 1px dashed rgb(172, 171, 171);
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
line-height: 2.5vh;
.inner-box {
width: 70%;
text-align: center;
}
}
.text-box {
color: rgb(179, 179, 179);
}
.left {
flex: 1;
text-align: center;
// margin-right: 4vw;
}
.right {
flex: 1;
text-align: center;
// margin-left: 4vw;
}
.num1 {
color: rgb(16, 16, 16);
font-weight: bold;
}
.num2 {
color: rgb(5, 167, 24);
font-weight: bold;
}
.num3 {
color: rgb(241, 8, 8);
font-weight: bold;
}
.top {
display: flex;
}
}
// 检查站
.count-item-jcz {
width: calc(50% - 1px);
text-align: center;
color: #999;
border-top: 1px solid #e9e9e9;
.count-time-jcz {
font-size: 1rem;
color: #222;
line-height: 12vw;
}
.count-item-jcz-num {
display: flex;
@include font_size($font_medium_s);
.count-item-jcz-num-left {
position: relative;
width: 50%;
text-align: right;
padding: 0 3vw;
box-sizing: border-box;
}
.count-item-jcz-num-right {
width: 50%;
text-align: left;
padding: 0 3vw;
box-sizing: border-box;
}
.count-item-jcz-num-left::after {
content: "";
position: absolute;
right: 0;
top: 10px;
bottom: 10px;
width: 1px;
background: #e9e9e9;
border-radius: 1px;
}
.num-red {
color: #f00;
font-size: 14px;
}
.num {
color: #000;
font-size: 14px;
}
}
}
.count-item-jcz:nth-child(2n + 1) {
border-right: 1px solid #e9e9e9;
}
}
.count-box-jcz {
padding-top: 1vh;
box-sizing: border-box;
}
.hsf {
position: absolute;
top: 20px;
right: 18px;
}
</style>

View File

@ -0,0 +1,172 @@
<template>
<div>
<TopNav navTitle="处警记录" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="sticky_box">
<Search placeholder="请输入上报人员姓名" v-model="kwd" :isSx="true" @update:sx="showPopup = !showPopup"
@update:modelValue="onSearch"></Search>
</div>
</van-sticky>
<SxPopup :showPopup="showPopup" :list="cjxx.sxList" :showTime='false' :p_top="110" @update:close="showPopup = false"
@update:onConfirm="onConfirm" />
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list v-model:loading="loading" :finished="finished" finished-text=" " @load="onLoad" offset="1"
:immediate-check="false">
<List v-for="(item, index) in cjxx.list" :key="index" :item="item" :dict="{ D_QW_CJSBLX }" />
<van-empty description="暂无信息" image="default" v-if="cjxx.list.length <= 0 && showEmpty" />
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup>
import { getRypcList, getRypcCount } from "../../../api/common.js";
import TopNav from "../../../components/topNav.vue";
import Search from "../../../components/search.vue";
import Tabs from "../../../components/tabs.vue";
import SxPopup from "../../../components/SxPopup.vue";
import List from "../../../components/cjbsList.vue";
import { setTimeQuantum } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, reactive, onMounted, watch } from "vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
const showEmpty = ref(false);
const { D_QW_CJSBLX } = getDictList(
"D_QW_CJSBLX"
); //字典信息
watch(D_QW_CJSBLX, (newValue) => {
for (let i = 0; i < newValue.length; i++) {
newValue[i].name = newValue[i].text;
newValue[i].key = newValue[i].dm;
newValue[i].isCheck = false;
}
cjxx.sxList = [
{
title: "警情类型",
isCheckBox: true,
array: newValue,
},
];
//时间段选项
// cjxx.sxList[1] = setTimeQuantum();
});
const tabsIndex = ref(1);
const total = ref(0);
const tabs = ref([
{
name: "全部",
count: 0,
pclx: "",
},
{
name: "盘查",
count: 0,
pclx: "9",
},
{
name: "移交",
count: 0,
pclx: "2",
},
{
name: "放行",
count: 0,
pclx: "1",
},
]);
const cjxx = reactive({
pageNum: 1,
pageSize: 10,
yjJb: "",
yjLx: "",
startTime: "",
endTime: "",
yjLx: "",
sxList: [], //筛选条件数据
list: [], //预警列表数据
});
const kwd = ref("");
const finished = ref(false);
const loading = ref(false);
const loadingPull = ref(false);
const showPopup = ref(false); //筛选弹窗
onMounted(() => {
getList();
});
//下拉刷新
function onRefresh() {
cjxx.list = [];
cjxx.pageNum = 1;
kwd.value = "";
tabsIndex.value++;
getList();
}
// 获取警情信息
function getList() {
loading.value = true;
qcckGet({
pageCurrent: cjxx.pageNum,
pageSize: cjxx.pageSize,
cjsbRyXm: kwd.value,
cjsbLx: cjxx.cjsbLx
}, "/mosty-qwzx/tbQwCjbs/selectPage")
.then((res) => {
loading.value = false;
loadingPull.value = false;
if (!res.records || res.records.length <= 0) showEmpty.value = true;
if (cjxx.pageNum == 1) {
cjxx.list = res.records;
} else {
res.records.forEach((item) => {
cjxx.list.push(item);
});
}
total.value = res.pages;
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
/**
* 关键字搜索
* @param {Object} val
*/
function onSearch(val) {
cjxx.pageNum = 1;
getList();
}
// 弹框盒子
function onConfirm(val) {
cjxx.startTime = val.startTime;
cjxx.endTime = val.endTime;
let arr = [];
if (val.list) {
val.list[0].array.forEach((item) => {
if (item.isCheck) {
arr.push(item.value);
}
});
cjxx.cjsbLx = arr.join(",");
}
cjxx.pageNum = 1;
getList();
showPopup.value = false;
}
function onLoad() {
if (cjxx.pageNum >= total.value) {
finished.value = true;
return;
}
cjxx.pageNum += 1;
getList();
}
</script>
<style lang="scss" scoped>
.sticky_box {
margin-top: 13vw;
}
</style>

View File

@ -0,0 +1,131 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="处警报送" :showRight="isSeeInfo ? true : false" :showLeft="true" @clickRight="onClickRight" />
<div class="main_box">
<van-form @submit="onSubmit" class="form" :disabled="isSeeInfo ? false : true">
<van-field name="radio" label="警情类型">
<template #input>
<van-radio-group v-model="params.cjsbLx" direction="horizontal" :disabled="isSeeInfo ? false : true">
<van-radio :name="item.dm" v-for="item in D_QW_CJSBLX" :key="item">{{ item.zdmc }}</van-radio>
</van-radio-group>
</template>
</van-field>
<van-field v-model="params.cjsbQk" name="cjsbQk" type="textarea" label="处警情况" placeholder="请输入处警情况"
:rules="[{ required: true, message: '请输入处警情况' }]" />
<van-field name="uploader" label="图片">
<template #input>
<van-uploader :disabled="isSeeInfo ? false : true" v-model="wpTpIdList" multiple :after-read="upLoadImg" />
</template>
</van-field>
<div style="margin: 16px" v-show="isSeeInfo">
<van-button round block type="primary" native-type="submit" :loading="isLoading" loading-type="spinner"
loading-text="提交中...">提交</van-button>
</div>
</van-form>
</div>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { qcckGet, qcckPost } from "../../../api/qcckApi.js";
import ImageCompressor from "image-compressor.js";
import {
timeValidate
} from "../../../utils/tools.js";
import { ImagePreview } from "vant";
import { getMybbTodayNew } from "../../../api/common";
import { useRoute } from "vue-router";
import { onMounted, ref } from 'vue';
import { upImage } from "@/api/common";
import { hintToast } from "@/utils/tools";
import router from "@/router";
import { getDictList, setDict } from "../../../utils/dict";
const { D_QW_CJSBLX } = getDictList(
"D_QW_CJSBLX"
);
const route = useRoute();
const wpTpIdList = ref([]);
const isSeeInfo = ref(true);
const fileList = ref([])
const params = ref({
cjsbTpid: '',//图片
})
const baseUrl = ref("");
const workTips = ref();
// 上传图片
async function upLoadImg(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
upImage(data).then((res) => {
console.log(res, 'res');
file.status = "done";
file.message = "上传成功";
if (!fileList.value.includes(res)) fileList.value.push(res);
});
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
const onSubmit = () => {
if (fileList.value.length > 0) params.value.cjsbTpid = fileList.value.join(',');
qcckPost(params.value, "/mosty-qwzx/tbQwCjbs/save").then(res => {
hintToast('添加成功')
router.back()
})
}
const onClickRight = () => {
router.push('/cjbsList')
}
const getImageUrl = (item) => {
return new Promise((ok) => {
qcckGet({}, `/mosty-base/minio/file/download/${item}`).then(res => {
ok(res.url);
})
});
}
onMounted(async () => {
if (route.query.item) {
isSeeInfo.value = false;
params.value = JSON.parse(route.query.item);
let imgId = params.value.cjsbTpid.split(',');
for (let i = 0; i < imgId.length; i++) {
const el = imgId[i];
wpTpIdList.value.push({ url: await getImageUrl(el) });
console.log(wpTpIdList.value, 'wpTpIdList.value');
}
}
})
</script>
<style lang="scss" scoped>
.main_box {
padding: 10px;
box-sizing: border-box;
}
::v-deep .van-radio {
margin-bottom: 4px;
}
::v-deep .van-radio__label--disabled{
color: #000!important;
}
::v-deep .van-field__label{
color: #000!important;
}
</style>

View File

@ -0,0 +1,132 @@
<template>
<div>
<TopNav navTitle="打卡记录" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="sticky_box">
<Search placeholder="请输入人员姓名" v-model="kwd" :isSx="false" @update:sx="showPopup = !showPopup"
@update:modelValue="onSearch"></Search>
</div>
</van-sticky>
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list v-model:loading="loading" :finished="finished" finished-text=" " @load="onLoad" offset="1"
:immediate-check="false">
<List v-for="(item, index) in yjxx.list" :key="index" :item="item" />
<van-empty description="暂无信息" image="default" v-if="yjxx.list.length <= 0 && showEmpty" />
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup>
import { getRypcList, getRypcCount } from "../../../api/common.js";
import TopNav from "../../../components/topNav.vue";
import Search from "../../../components/search.vue";
import Tabs from "../../../components/tabs.vue";
import SxPopup from "../../../components/SxPopup.vue";
import List from "../../../components/clockList.vue";
import { setTimeQuantum } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, reactive, onMounted, watch } from "vue";
import { qcckGet, qcckPost } from "@/api/qcckApi.js";
const showEmpty = ref(false);
const tabsIndex = ref(1);
const total = ref(0);
const tabs = ref([
{
name: "全部",
count: 0,
pclx: "",
},
{
name: "盘查",
count: 0,
pclx: "9",
},
{
name: "移交",
count: 0,
pclx: "2",
},
{
name: "放行",
count: 0,
pclx: "1",
},
]);
const yjxx = reactive({
pageNum: 1,
pageSize: 10,
yjJb: "",
yjLx: "",
startTime: "",
endTime: "",
yjLx: "",
sxList: [], //筛选条件数据
list: [], //预警列表数据
});
const kwd = ref("");
const finished = ref(false);
const loading = ref(false);
const loadingPull = ref(false);
const showPopup = ref(false); //筛选弹窗
onMounted(() => {
getList();
});
//下拉刷新
function onRefresh() {
yjxx.list = [];
yjxx.pageNum = 1;
kwd.value = "";
tabsIndex.value++;
getList();
}
// 获取警情信息
function getList() {
loading.value = true;
qcckPost({
pageCurrent: yjxx.pageNum,
pageSize: yjxx.pageSize,
dkrxm: kwd.value,
}, "/mosty-qwzx/tbQwXfbb/selectXfbbDkPage")
.then((res) => {
loading.value = false;
loadingPull.value = false;
if (!res.records || res.records.length <= 0) showEmpty.value = true;
if (yjxx.pageNum == 1) {
yjxx.list = res.records;
} else {
res.records.forEach((item) => {
yjxx.list.push(item);
});
}
total.value = res.pages;
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
/**
* 关键字搜索
* @param {Object} val
*/
function onSearch(val) {
yjxx.pageNum = 1;
getList();
}
function onLoad() {
if (yjxx.pageNum >= total.value) {
finished.value = true;
return;
}
yjxx.pageNum += 1;
getList();
}
</script>
<style lang="scss" scoped>
.sticky_box {
margin-top: 13vw;
}
</style>

View File

@ -0,0 +1,325 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="打卡" :showRight="true" :showLeft="true" @clickRight="onClickRight" />
<div class="main_box">
<!-- <div class="top_box">
<div class="left_top">
<div class="top_text">上班09:00:00</div>
<div class="tip_text">未打卡</div>
</div>
<div class="left_top">
<div class="top_text">下班09:00:00</div>
<div class="tip_text">未打卡</div>
</div>
</div> -->
<div class="upload_box">
<div class="image_box" v-if="baseUrl">
<van-icon name="close" class="close_icon" @click="clearImage" color="#000" size="24px" />
<van-image :src="baseUrl" @click="onClickImg(baseUrl)" style="flex: 1">
<template v-slot:loading>
<van-loading type="spinner" size="20" />
</template>
</van-image>
</div>
<div class="upload_icon_box" v-else>
<van-icon @click="photoFn" name="plus" />
</div>
<!-- <van-uploader v-model="clockList" :max-count="1" :after-read="afterRead" capture="camera"
:before-read="beforeRead" accept="image/*" /> -->
<div class="upload_tip"><span style="color: red;">*</span>须拍摄实景图才可进行打卡</div>
</div>
<div class="dk_box">
<div class="circle_box" @click="workFn">
{{ workTips ? workTips : '打卡' }}
</div>
<!-- <div class="dk_tip" v-show="rangeShow"><van-icon name="checked" color="#08B353" />已进入考勤范围德阳市某某某</div>
<div class="dk_tip" v-show="!rangeShow"><van-icon name="clear" color="red" />未进入考勤范围德阳市某某某</div> -->
</div>
<!-- <div class="bzt_box">
<div style="color: #75787F;">时间轴</div>
<van-steps direction="vertical" :active="-1" active-color="#1DB1FF">
<van-step>
<div style="color:#000">上班打卡</div>
<img src="@/assets/images/menu-dk.png" alt="">
</van-step>
<van-step style="color:#000">
<div>下班打卡</div>
<img src="@/assets/images/menu-dk.png" alt="">
</van-step>
</van-steps>
</div> -->
<div class="choose_dw">
<van-button type="primary" block @click="chooseDwFn">{{ workTips ? workTips : '点位选择' }}</van-button>
<van-popup v-model:show="showPicker" position="bottom">
<van-picker :columns="columns" @confirm="onConfirm" @cancel="showPicker = false" />
</van-popup>
</div>
</div>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import { qcckGet, qcckPost } from "../../../api/qcckApi.js";
import ImageCompressor from "image-compressor.js";
import {
timeValidate
} from "../../../utils/tools.js";
import { ImagePreview } from "vant";
import { getMybbTodayNew } from "../../../api/common";
import { onMounted, ref } from 'vue';
import { upImage } from "@/api/common";
import { hintToast } from "@/utils/tools";
import router from "@/router";
const clockList = ref();
const rangeShow = ref(true);
const showPicker = ref(false);
const columns = ref([
]);
const params = ref({
bbid: "",//报备id,
bxdid: "",//必巡id
tpid: '',//附件
})
const baseUrl = ref("");
const workTips = ref()
const Loadtion = ref({
jd: "暂无",
wd: "暂无",
radius: 5000
});
// 文件预览
async function afterRead(file) {
file.message = "上传中...";
let fileBlob = await _compressImage(file.file);
let fileData = new File([fileBlob], fileBlob.name, { type: fileBlob.type });
const data = new FormData();
data.append("file", fileData);
file.status = "uploading";
upImage(data).then((res) => {
console.log(res, 'res');
file.status = "done";
file.message = "上传成功";
params.value.tpid = res;
});
}
const beforeRead = (file) => {
// 判断相册里面的照片是不是最新拍摄的照片
let timestamp = file.lastModified;
let newTime = new Date().getTime() - 5 * 60 * 1000;
if (timestamp < newTime) {
hintToast('请重新拍摄最新时间的拍照')
return true
} else {
return true
}
}
const photoFn = () => {
try {
bridge.pZ("photo");
} catch (err) {
console.log(err, 'err');
}
}
//预览图片
function onClickImg(url) {
ImagePreview([url]);
}
// 删除图片
const clearImage = () => {
baseUrl.value = ""
}
//压缩图片
const _compressImage = (file) => {
return new Promise((resolve, reject) => {
new ImageCompressor(file, {
quality: 0.6, //压缩质量
success(res) {
resolve(res);
},
error(e) {
reject(e);
},
});
});
};
//获取当前位置信息
function _getUserLocation(sfdw) {
let { lng, lat, zbly } = getLocation();
if (lng && lat) {
Loadtion.value.jd = lng;
Loadtion.value.wd = lat;
getBxList()
} else {
hintToast("暂无坐标信息");
}
}
const chooseDwFn = () => {
showPicker.value = true;
}
const onConfirm = (e) => {
workTips.value = e.text;
params.value.bxdid = e.value;
showPicker.value = false;
}
// 上班打卡
const workFn = () => {
if (params.value.tpid == '') {
hintToast('请拍照再打卡');
return
}
qcckPost(params.value, "/mosty-qwzx/tbQwXfbb/addXfbbDk").then(res => {
hintToast('打卡成功');
router.back()
})
}
const onClickRight = () => {
router.push('/clockList')
}
// 获取报备id
const getBbInfo = () => {
getMybbTodayNew().then(res => {
params.value.bbid = res ? res.id : '';
})
}
// 获取必训点
const getBxList = () => {
qcckGet(Loadtion.value, "/mosty-jcgl/tbJcglBxd/selectNearbyList").then(res => {
console.log(res, 'res');
columns.value = res.map((item) => {
return { text: item.bxdMc, value: item.id }
})
})
}
function setimage_base64(pzid, base64) {
console.log(base64, 'base64');
baseUrl.value = `data:image/jpeg;base64,${base64}`;
qcckPost({base64:base64}, "/mosty-base/minio/image/upload/base64").then(res => {
params.value.tpid = res;
})
}
function btof(data, fileName) {
const dataArr = data.split(',')
const byteString = atob(dataArr[1])
const options = {
type: 'image/jpeg',
endings: 'native'
}
const u8Arr = new Uint8Array(byteString.length)
for (let i = 0; i < byteString.length; i++) {
u8Arr[i] = byteString.charCodeAt(i)
}
return new File([u8Arr], fileName + '.jpg', options)
}
onMounted(() => {
getBbInfo();
_getUserLocation(true); //获取当前位置
setInterval(() => {
// _getUserLocation(false); //获取当前位置
}, 5000);
window.setimagebase64 = setimage_base64;
})
</script>
<style lang="scss" scoped>
.main_box {
padding: 10px;
box-sizing: border-box;
}
.top_box {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
.left_top {
width: 48%;
height: 80px;
padding: 10px;
box-sizing: border-box;
top: 61px;
left: 10px;
gap: 0px;
border-radius: 10px;
opacity: 0px;
background-color: #EDEDED;
.tip_text {
color: #75787F;
margin-top: 6px;
}
}
}
.upload_box {
display: flex;
.upload_tip {
color: #75787F;
font-size: 13px;
}
.image_box {
position: relative;
width: 160px;
height: 100px;
.close_icon {
position: absolute;
right: 0;
top: 0;
z-index: 20;
}
::v-deep .van-image {
width: 100%;
}
}
.upload_icon_box {
border: 1px solid #ccc;
text-align: center;
width: 160px;
height: 100px;
line-height: 100px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 10px;
}
}
.dk_box {
text-align: center;
.dk_tip {
color: #707070;
margin-top: 6px;
}
}
.circle_box {
width: 160px;
height: 160px;
line-height: 160px;
margin: 0 auto;
margin-top: 40%;
border-radius: 50%;
color: #fff;
font-size: 20px;
text-align: center;
background: linear-gradient(to bottom, #1DB1FF, #007DE9);
}
.choose_dw {
position: absolute;
bottom: 0;
width: 100%;
left: 0;
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<ul class="box-rank">
<li class="item">
<div class="text title">日期</div>
<div class="text title">执勤时间</div>
<div class="text title">执勤状态</div>
</li>
<li class="item" v-for="(item, index) in data" :key="index" @click="routePush(item)">
<div class="text title">{{ item.time }}</div>
<div class="text title">{{ item.zqsj }}</div>
<div class="text title" :class="item.zqzt == '请假' ? 'red' : item.zqzt == '未执勤' ? '' : 'green'
">
{{ item.zqzt }}
</div>
</li>
<van-empty description="暂无信息" image="default" v-if="data.length <= 0 && !loading" />
</ul>
</template>
<script setup>
import { ref, defineExpose, watch, onMounted } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const props = defineProps({
listData: { type: Array },
});
watch(
() => props.listData,
() => {
data.value = props.listData;
},
{ deep: true }
);
function routePush(row) {
const timeDay = new Date()
let y = timeDay.getFullYear()
let m = timeDay.getMonth() + 1 < 10 ? '0' + (timeDay.getMonth() + 1) : timeDay.getMonth() + 1
let d = timeDay.getDate() < 10 ? '0' + timeDay.getDate() : timeDay.getDate()
const dtime = y + '-' + m + '-' + d
if (row.zt === "04") {
return false;
} else {
router.push({
path: "/xfbbInfo",
query: {
zt: row.zt,
pbid: row.zt === '01' ? row.id : null,
bbid: row.zt === '01' ? null : row.id,
isDay: dtime === row.time ? 1 : 0
},
});
}
}
const loading = ref(false);
const data = ref([]);
onMounted(() => {
data.value = props.listData;
})
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.box-rank {
width: 100%;
height: 100%;
.item {
display: flex;
align-items: center;
justify-content: center;
height: 8vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.text {
flex: 1;
text-align: center;
}
.mc {
color: #3e6ee8;
}
}
.item:nth-child(2n + 1) {
@include table_item_color($table-item-theme);
}
.item:nth-child(1) {
background: #3e6ee8 !important;
color: #fff;
}
.red {
color: red !important;
}
.green {
color: #88e9af;
}
.blue {
color: #3e6ee8;
}
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<ul class="box-rank">
<li class="item">
<div class="text title">日期</div>
<div class="text title">执勤时间</div>
<div class="text title">执勤状态</div>
</li>
<li class="item" v-for="(item, index) in data" :key="index" @click="routePush(item)">
<div class="text title">{{ item.time }}</div>
<div class="text title">{{ item.zqsj }}</div>
<div class="text title" :class="item.zqzt == '请假' ? 'red' : item.zqzt == '未值班' ? '' : 'green'
">
{{ item.zqzt }}
</div>
</li>
<van-empty description="暂无信息" image="default" v-if="data.length <= 0 && !loading" />
</ul>
</template>
<script setup>
import { ref, defineExpose, watch, onMounted } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
const props = defineProps({
listData: { type: Array },
});
watch(
() => props.listData,
() => {
data.value = props.listData;
},
{ deep: true }
);
function routePush(row) {
const timeDay = new Date()
let y = timeDay.getFullYear()
let m = timeDay.getMonth() + 1 < 10 ? '0' + (timeDay.getMonth() + 1) : timeDay.getMonth() + 1
let d = timeDay.getDate() < 10 ? '0' + timeDay.getDate() : timeDay.getDate()
const dtime = y + '-' + m + '-' + d
if (row.zt === "04") {
return false;
} else {
router.push({
path: "/yyzx/views/addZbbbInfo",
query: {
zt: row.zt,
id: row.id,
flag: dtime === row.time ? 1 : 0,
text: row.zqzt
},
});
}
}
const loading = ref(false);
const data = ref([]);
onMounted(() => {
data.value = props.listData;
})
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.box-rank {
width: 100%;
height: 100%;
.item {
display: flex;
align-items: center;
justify-content: center;
height: 8vw;
@include font_size($font_medium_s);
@include font_color($font-color-theme);
.text {
flex: 1;
text-align: center;
}
.mc {
color: #3e6ee8;
}
}
.item:nth-child(2n + 1) {
@include table_item_color($table-item-theme);
}
.item:nth-child(1) {
background: #3e6ee8 !important;
color: #fff;
}
.red {
color: red !important;
}
.green {
color: #88e9af;
}
.blue {
color: #3e6ee8;
}
}
</style>

View File

@ -0,0 +1,446 @@
<template>
<div class="container">
<van-form>
<div class="title_tab">值班班次</div>
<van-cell title="值班日期" @click="calShow = true">
<template #value>
<span>{{ chooseTime }}</span>
</template>
</van-cell>
<van-calendar v-model:show="calShow" @confirm="onConfirm" :min-date="minDate" :max-date="maxDate"
color="#3e6ee8"></van-calendar>
<van-field v-model="normalForm.bcmc" name="班次" is-link readonly label="班次" placeholder="请选择班次" input-align="right"
@click="showDialogfn('qwbc')" />
<van-field readonly v-if="normalForm.bcsc" v-model="normalForm.bcsc" input-align="right" label="班次时段" />
<div class="title_tab">值班人员</div>
<van-field v-model="normalForm.zbld" name="值班领导" required input-align="right" label="值班领导" is-link readonly
placeholder="请值班领导" :rules="[{ required: true, message: '请选择值班领导' }]" @click="showDialogfn('zbld')" />
<van-field v-model="normalForm.zhz" readonly input-align="right" name="picker" label="指挥长" placeholder="请选择指挥长"
@click="showDialogfn('zhz')" is-link />
<van-field v-model="normalForm.zzzhz" readonly input-align="right" name="picker" label="专职指挥长"
placeholder="请选择专职指挥长" @click="showDialogfn('zzzhz')" is-link />
<van-field v-model="normalForm.fz" readonly input-align="right" name="picker" label="法制" placeholder="请选择法制"
@click="showDialogfn('fz')" is-link />
<van-cell class="mulSelect" title="值班民警" color="#1989fa">
<template #right-icon>
<van-icon @click.stop="showDialogfn('mj')" name="add-o" color="#1989fa" size="22" />
</template>
<template #default>
<div class="selected-box">
<div class="check-item-tag" v-for="(item, index) in list.mj" :key="index">
<van-tag color="#7232dd" closeable @close="deleteCheckTag(item, index, 'mj')" plain>{{ item.jlxm
}}</van-tag>
</div>
</div>
</template>
</van-cell>
<van-cell class="mulSelect" title="值班辅警" color="#1989fa">
<template #right-icon>
<van-icon @click.stop="showDialogfn('fj')" name="add-o" color="#1989fa" size="22" />
</template>
<template #default>
<div class="selected-box">
<div class="check-item-tag" v-for="(item, index) in list.fj" :key="index">
<van-tag closeable @close="deleteCheckTag(item, index, 'fj')" color="#7232dd" plain>{{ item.jlxm
}}</van-tag>
</div>
</div>
</template>
</van-cell>
<div class="title_tab">联系方式</div>
<van-field v-model="normalForm.zbdh" name="值班电话" label="值班电话" type="tel" placeholder="请选择值班电话"
input-align="right" />
<van-field v-model="normalForm.hh" name="呼号" label="呼号" type="digit" placeholder="请输入呼号" input-align="right" />
<div style="margin: 16px 0; padding: 0 5vw">
<van-button style="margin: 16px 0" round @click="editFn()" block type="success" v-if="list.bbInfo">
结束报备
</van-button>
<van-button round @click="_submitZbbbData" block type="primary" v-else>
开始报备
</van-button>
</div>
</van-form>
<!-- 负责人 -->
<Select bclx="01" :checked="r_checked" :selectType="selectType" :show="showSelect" :checkedList="list.checkedList"
@update:cancel="showSelect = false" @update:confirm="onComfirm" :key="selectIndex" />
</div>
</template>
<script setup>
import { Dialog, Toast } from "vant";
import { dateFormat, timeValidate, hintToast } from "../../../utils/tools.js";
import { computed, ref, reactive, onMounted, watch, defineEmits } from "vue";
import { useRouter, useRoute } from "vue-router";
import Select from "../../../components/Select.vue";
import {
getMyZbbbData,
getMyZbpbData,
submitZbbbData,
startAndEndZbbbData,
endTaskStatus,
} from "../../../api/yyzxApi.js";
import { getBcList, getXfqList, getKfdList } from "../../../api/xfbbAndZbbb.js";
const router = useRouter();
const route = useRoute();
const emit = defineEmits(["setTitle"]);
//表单数据
const normalForm = reactive({
bcmc: "",
bcsc: "",
zbld: "",
zhz: "",
zzzhz: "",
fz: "",
hh: "",
bcsc: "",
zbdh: "",
});
//选择数据
const list = reactive({
mj: [], //选中的民警数据
fj: [], //选中的辅警数据
bcList: [], //班次信息
bpInfo: { zbmj: [], zbfj: [], jlList: [], zbpbId: "", zbrq: "", qwbcid: "" }, //无报备的排班信息
bbInfo: null, //报备信息
checkedList: [], //默认选中的民辅警数据
});
const showSelect = ref(false);
const r_checked = ref(""); //单选框默认选中
const selectIndex = ref(1); //选择器组件KEY
const selectType = ref(""); //选择的类型
// 巡防日期
const minDate = new Date(2000, 0, 1);
const maxDate = new Date(2050, 0, 1);
const calShow = ref(false);
const chooseTime = ref(timeValidate(new Date(), "ymd"));
const titleTime = ref();
function onConfirm(val) {
calShow.value = false;
chooseTime.value = timeValidate(val, "ymd");
titleTime.value = timeValidate(val, "ymd");
}
onMounted(() => {
_getBcData();
_getMyZbbbData();
});
//确认选择
function onComfirm(val) {
if (val.length <= 0) return;
switch (selectType.value) {
case "qwbc":
r_checked.value = val[0].key;
onbcConfirm(val[0]);
break;
case "zbld":
case "zhz":
case "zzzhz":
case "fz":
if (r_checked.value == val[0].key) {
r_checked.value = "";
if (selectType.value == "zbld") normalForm.zbld = "";
if (selectType.value == "zhz") normalForm.zhz = "";
if (selectType.value == "zzzhz") normalForm.zzzhz = "";
if (selectType.value == "fz") normalForm.fz = "";
} else {
r_checked.value = val[0].key;
onfzrConfirm(val[0]);
}
break;
case "mj":
// list.mj = [];
val.forEach((item) => {
list.checkedList.push(item.key);
toggle(item);
});
break;
case "fj":
// list.fj = [];
val.forEach((item) => {
list.checkedList.push(item.key);
toggle(item);
});
break;
}
}
//打开选择框
function showDialogfn(val) {
if (selectType.value !== val) r_checked.value = "";
selectType.value = val;
showSelect.value = true;
selectIndex.value++;
}
//开始报备
function _submitZbbbData() {
Reflect.deleteProperty(list.bpInfo, "zbmj");
Reflect.deleteProperty(list.bpInfo, "zbfj");
list.bpInfo.jlList = [...list.fj, ...list.mj];
if (!list.bpInfo.id) {
hintToast("没有排班信息");
return;
}
list.bpInfo.zbpbId = list.bpInfo.id; //排班ID
list.bpInfo.zbrq = dateFormat();
submitZbbbData(list.bpInfo).then((res) => {
hintToast("成功");
_startZbbbData(res, 0);
_endTaskStatus("04", list.bpInfo.mrjlid, 2);
});
}
//结束任务
function _endTaskStatus(rwxl, ywid, rwzt) {
let data = { rwxl, ywid, rwzt };
try {
let location = JSON.parse(bridge.getLocation());
data.jd = location.app_x;
data.wd = location.app_y;
} catch (error) { }
endTaskStatus(data).then((res) => { });
}
//结束报备
function editFn() {
Dialog.confirm({
title: "提示",
message: "是否确认结束报备!",
confirmButtonColor: "#3e6ee8",
}).then((res) => {
_startZbbbData(list.bbInfo.id, 1);
});
}
//提交开始||结束报备
function _startZbbbData(id, bbzt) {
startAndEndZbbbData({ id, bbzt }).then((res) => {
list.bpInfo = null;
router.go(-1);
});
}
//获取我的值班报备信息
function _getMyZbbbData() {
Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
getMyZbbbData()
.then((res) => {
if (res) {
list.bbInfo = res;
emit("setTitle", "值班报备信息");
_setHxData(res);
Toast.clear();
} else {
//没有报备信息调用
_getMyZbpbData();
}
})
.catch((err) => {
Toast.clear();
});
}
//获取我的值班排班信息
function _getMyZbpbData() {
getMyZbpbData().then((res) => {
//回显班次数据
emit("setTitle", "值班排班信息");
if (res) {
_setHxData(res);
list.bpInfo = res;
} else {
hintToast("没有值班和排班信息");
}
Toast.clear();
});
}
//设置页面回显
function _setHxData(res) {
let info = list.bcList.find((item) => {
return item.id == res.qwbcid;
});
if (info) onbcConfirm(info);
//值班人
normalForm.zbld = `${res.zbldXm ? res.zbldXm : ""} ${res.zbldDh ? res.zbldDh : ""
}`;
normalForm.zbdh = res.zbldDh ? res.zbldDh : "";
normalForm.zhz = `${res.zbzhzXm ? res.zbzhzXm : ""} ${res.zbzhzDh ? res.zbzhzDh : ""
}`;
normalForm.zzzhz = `${res.zzzhzXm ? res.zzzhzXm : ""} ${res.zzzhzDh ? res.zzzhzDh : ""
}`;
normalForm.fz = `${res.fzzbXm ? res.fzzbXm : ""} ${res.fzzbDh ? res.fzzbDh : ""
}`;
//呼号
normalForm.hh = res.hh;
//民辅警
list.mj = JSON.parse(res.zbmj);
list.fj = JSON.parse(res.zbfj);
}
//选中的班次数据
function onbcConfirm(val) {
list.bpInfo.qwbcid = val.id;
normalForm.bcmc = val.bcmc;
normalForm.bcsc = `${val.kssj} - ${val.jssj}`;
}
//获取班次数据
function _getBcData() {
return new Promise((ok) => {
let data = {
type: 2,
keyword: "",
bclx: "01",
};
getBcList(data).then((res) => {
if (res) {
for (let i = 0; i < res.length; i++) {
res[i].value = `${res[i].ssbm}-${res[i].bcmc}`;
res[i].key = res[i].id;
}
list.bcList = res;
}
ok();
});
});
}
//选中领导数据
function onfzrConfirm(val) {
switch (selectType.value) {
case "zbld":
normalForm.zbld = `${val.xm} ${val.lxdh}`;
normalForm.zbdh = val.lxdh;
break;
case "zhz":
normalForm.zhz = `${val.xm} ${val.lxdh}`;
break;
case "zzzhz":
normalForm.zzzhz = `${val.xm} ${val.lxdh}`;
break;
case "fz":
normalForm.fz = `${val.xm} ${val.lxdh}`;
break;
}
}
//删除选中的民辅警数据
function deleteCheckTag(item, index, val) {
switch (val) {
case "mj":
list.mj.splice(index, 1);
break;
case "fj":
list.fj.splice(index, 1);
break;
}
}
//选中民辅警数据
const toggle = (item) => {
switch (selectType.value) {
case "mj":
list.mj.push({
jh: item.jh,
jllx: item.fl,
jlxm: item.xm,
sfzh: item.sfzh,
xm: item.xm,
lxdh: item.lxdh,
xbdm: item.xbdm,
id: item.ryid,
qwjzId: "",
jlId: item.ryid,
});
break;
case "fj":
list.fj.push({
jh: item.jh,
jllx: item.fl,
jlxm: item.xm,
id: item.id,
sfzh: item.sfzh,
xm: item.xm,
lxdh: item.lxdh,
xbdm: item.xbdm,
qwjzId: "",
jlId: item.id,
});
break;
}
};
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.popupTitle {
text-align: center;
background-color: rgb(11, 137, 247);
height: 6vh;
line-height: 6vh;
}
.popbtn-box {
width: 100%;
display: flex;
justify-content: space-around;
}
.check-item-tag {
display: inline-block;
margin: 0 6px;
}
.check-data-box {
height: 25vh;
overflow: auto;
}
.time-box {
display: flex;
}
::v-deep .mulSelect .van-cell__title,
.van-cell__value {
flex: unset;
}
::v-deep .mulSelect .van-cell__value {
flex: 1;
}
.title_tab {
@include font_color($font-color-theme);
padding-left: 7vw;
position: relative;
margin: 2vw 0;
letter-spacing: 2px;
}
.title_tab::after {
content: "";
position: absolute;
top: 0;
left: 5vw;
bottom: 0;
width: 4px;
background: #3b6be7;
border-radius: 2px;
}
.van-cell:after {
display: none;
}
.van-cell {
@include table_item_color($table-item-theme);
box-sizing: border-box;
border-radius: 4px;
padding: 6px;
margin: 8px 5%;
width: 90%;
overflow: hidden;
color: var(--van-cell-text-color);
font-size: var(--van-cell-font-size);
line-height: var(--van-cell-line-height);
}
.popupTitle {
color: #fff;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,462 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="部门巡防报备清单" :showLeft="true" />
<div class="calenderBox">
<div class="calender-head">
<div class="btn" @click="last">
<van-icon name="arrow-left" color="#fff" />
</div>
<div class="text">{{ Year }}{{ month }}</div>
<div class="btn" @click="next">
<van-icon name="arrow" color="#fff" />
</div>
</div>
<!-- 日历 -->
<div class="list">
<ul class="week">
<li class="days" v-for="(item, index) in week" :key="index">
{{ item }}
</li>
</ul>
<div class="wrap">
<div @click="checkDay(Year + '-' + month + '-' + item.value)" class="item"
v-for="(item, index) in calendarList" :key="index">
<div class="num" :class="calendarActive == Year + '-' + month + '-' + item.value ? 'active' : ''">
{{ item.value }}<span v-show="item.value"></span>
</div>
<div class="status" v-show="item.value">
<div v-for="item2 in item.list" :key="item2.id">
<span @click="itemClick(item)" v-show="item.value" :style="{ background: item.color }">{{ item2.fzrXm }}
{{ item2.kssj.split(":")[0] + ":" + item2.kssj.split(":")[1] }}
{{ item2.jssj.split(":")[0] + ":" + item2.jssj.split(":")[1] }}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-for="item in zbInfo.list" :key="item.id" class="list-item item_box">
<div class="title">部门巡防报备详情</div>
<div>
<div class="num-text">负责人{{ item.fzrXm }}</div>
<div class="num-text">
巡防民警{{ checkJSON(item.pbmj, 'jlxm') }}
</div>
<div class="num-text">
巡防辅警{{ checkJSON(item.pbfj, 'jlxm') }}
</div>
<div class="num-text">
巡防车辆{{ checkJSON(item.pbcl, 'jdchphm') }}
</div>
<div class="num-text">负责人电话{{ item.fzrLxdh }}</div>
<div class="num-text">巡防时间{{ item.kssj }} - {{ item.jssj }}</div>
</div>
</div>
<div v-if="zbInfo.list.length === 0" style="text-align: center; padding: 12px 0; color: #828282">
暂无今日报备
</div>
</div>
</template>
<script setup>
import { getXfbbByMonth } from "../../../api/calender";
import TopNav from "../../../components/topNav.vue";
import { onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { Toast } from "vant";
const zbInfo = ref({
list: [],
});
const router = useRouter();
const week = ref(["周日", "周一", "周二", "周三", "周四", "周五", "周六"]);
const Year = ref(new Date().getFullYear()); //日历上的年份
const month = ref(new Date().getMonth() + 1); //日历上的月份
const Day = ref(new Date().getDate()); //日历上的天份
const nowYear = ref(new Date().getFullYear());
const nowmonth = ref(new Date().getMonth() + 1);
const nowDay = ref(new Date().getDate());
//日历选中高亮
const calendarActive = ref("");
const starttime = ref("");
const endtime = ref("");
const nowtime = ref("");
const calendarList = ref([]);
onMounted(() => {
Draw(nowYear.value, nowmonth.value);
let time_month = nowmonth.value; //现在的月份
let time_day = nowDay.value; //现在的天数
if (nowmonth.value < 10) {
time_month = 0 + "" + nowmonth.value;
}
if (nowDay.value < 10) {
time_day = 0 + "" + nowDay.value;
}
nowtime.value = nowYear.value + "-" + time_month + "-" + time_day;
calendarActive.value =
nowYear.value + "-" + nowmonth.value + "-" + nowDay.value;
starttime.value = nowtime.value;
endtime.value = nowtime.value;
});
//处理JSON数据
function checkJSON(row, key) {
var data = []
try {
data = JSON.parse(row)
} catch (error) {
data = []
}
var str = ''
try {
str = data.map(item => item[key]).join(',')
} catch (error) {
}
return !str ? '暂无' : str
}
function itemClick(e) {
zbInfo.value = e;
}
//状态字典
const ztDict = [
{
label: "无报备",
value: "00",
color: "#7b7b7b",
},
{
label: "有报备",
value: "01",
color: "#51fb06",
},
{
label: "今日报备",
value: "02",
color: "#51fb06",
},
{
label: "今日排班",
value: "03",
color: "#7b7b7b",
},
{
label: "无",
value: "04",
color: "#7b7b7b",
},
{
label: "有排班",
value: "05",
color: "#7b7b7b",
},
{
label: "无排班",
value: "06",
color: "#7b7b7b",
},
];
//状态数据处理
function checkZt(list = []) {
var zt = [];
if (list.length > 0) {
zt = list.map((item) => {
return {
text: ztDict.filter((item2) => item2.value === item.zt)[0].label,
color: ztDict.filter((item2) => item2.value === item.zt)[0].color,
id: item.id,
zt: item.zt,
};
});
}
return zt;
}
const isToday = ref(true);
function Draw(Year, Month) {
Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
getXfbbByMonth({ time: Year + "-" + Month })
.then((res) => {
const copyRes = JSON.parse(JSON.stringify(res)).map((c) => {
var ccc = [];
if (!c.list) {
ccc = [];
} else {
ccc = c.list.map((ci) => {
return {
...ci,
zt: c.type,
};
});
}
return {
...c,
label: ztDict.filter((item2) => item2.value === c.type)[0].label,
color: ztDict.filter((item2) => item2.value === c.type)[0].color,
list: ccc,
};
});
calendarList.value = copyRes.map((item, index) => {
return {
value: index + 1,
kssj: "20:00", //假数据
jssj: "23:59",
status: checkZt(item.list), //假的状态
count: Year + "-" + Month + "-" + item.day,
...item,
};
});
if (isToday.value) {
var toTime = new Date();
var m =
toTime.getMonth() < 9
? "0" + (toTime.getMonth() + 1)
: toTime.getMonth() + 1;
var d = toTime.getDay() < 10 ? "0" + toTime.getDay() : toTime.getDay();
var toDay = toTime.getFullYear() + "-" + m + "-" + d;
calendarList.value.forEach((v) => {
if (v.time === toDay) {
zbInfo.value = v;
isToday.value = false;
}
});
}
for (
var i = 1, firstDay = new Date(Year, Month - 1, 1).getDay();
i <= firstDay;
i++
) {
calendarList.value.unshift("");
}
Toast.clear();
})
.catch((err) => {
Toast.clear();
});
}
function checkDay(val) {
calendarActive.value = val;
}
// 上个月
function last() {
month.value--;
if (month.value == 0) {
month.value = 12;
Year.value--;
}
Draw(Year.value, month.value);
}
// 下个月
function next() {
month.value++;
if (month.value == 13) {
month.value = 1;
Year.value++;
}
Draw(Year.value, month.value);
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.calenderBox {
width: 100%;
padding: 1vw;
box-sizing: border-box;
.calender-head {
width: 100%;
height: 15vw;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-weight: bold;
line-height: 40px;
position: relative;
.change {
position: absolute;
right: 1vw;
bottom: 2vw;
cursor: pointer;
color: #3e6ee8;
@include font_size($font_medium_s);
}
.btn {
width: 7vw;
height: 7vw;
line-height: 7vw;
text-align: center;
border-radius: 1vw;
background: #3e6ee8;
color: #fff;
}
.text {
margin: 0 4vw;
@include font_color($font-color-theme);
}
}
.week {
width: 100%;
display: flex;
flex-wrap: nowrap;
text-align: center;
height: 10vw;
line-height: 10vw;
background: #164acc;
color: #fff;
.days {
flex: 1;
}
}
.wrap {
width: 100%;
display: flex;
flex-wrap: wrap;
.item {
width: calc((100% / 7) - 1.3px);
border: 1px solid #3e6ee8;
border-top: none;
font-size: 10px;
min-height: 15vw;
.num {
text-align: right;
padding-right: 1vw;
box-sizing: border-box;
@include font_color($font-color-theme);
}
.num.active {
color: #1adb10;
}
.status {
text-align: center;
margin: 1vw 0;
span {
background: #3e6ee8;
padding: 1px 1vw;
display: block;
width: 10vw;
color: #fff;
border-radius: 1vw;
margin: 6px auto;
}
.green {
background: #1adb10;
}
.gray {
background: #83868f;
}
}
.time {
font-size: 10px;
// height: 5vw;
// line-height: 7vw;
color: #3e6ee8;
text-align: center;
}
.greenColor {
color: #1adb10;
}
.grayColr {
color: #83868f;
}
.BlueColor {
color: #3e6ee8;
}
}
.item:nth-child(7n + 2) {
border-left: none;
}
.item:nth-child(7n + 3) {
border-left: none;
}
.item:nth-child(7n + 4) {
border-left: none;
}
.item:nth-child(7n + 5) {
border-left: none;
}
.item:nth-child(7n + 6) {
border-left: none;
}
.item:nth-child(7n + 7) {
border-left: none;
}
}
}
.list {
// max-height: calc(100vh - 35vw);
// overflow: hidden;
// overflow-y: auto;
}
.list-item {
padding: 3vw;
margin: 2vh 5vw;
border-radius: 2vw;
.phone-icon {
position: absolute;
right: 5vw;
}
.address-box {
display: flex;
justify-content: space-between;
.adress-left {
color: #3e6ee8;
}
}
.name-text {
@include font_size($font_medium);
color: #3e6ee8;
margin-bottom: 1vh;
font-weight: bold;
display: flex;
justify-content: flex-start;
align-items: center;
}
.title {
@include font_size($font_medium);
font-weight: 550;
}
.num-text {
@include font_size($font_medium_s);
color: #2b2b2b;
padding: 4px 0;
}
}
</style>

View File

@ -0,0 +1,461 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="部门值班报备清单" :showLeft="true" />
<div class="calenderBox">
<div class="calender-head">
<div class="btn" @click="last">
<van-icon name="arrow-left" color="#fff" />
</div>
<div class="text">{{ Year }}{{ month }}</div>
<div class="btn" @click="next">
<van-icon name="arrow" color="#fff" />
</div>
</div>
<!-- 日历 -->
<div class="list">
<ul class="week">
<li class="days" v-for="(item, index) in week" :key="index">
{{ item }}
</li>
</ul>
<div class="wrap">
<div @click="checkDay(Year + '-' + month + '-' + item.value)" class="item"
v-for="(item, index) in calendarList" :key="index">
<div class="num" :class="calendarActive == Year + '-' + month + '-' + item.value
? 'active'
: ''
">
{{ item.value }}<span v-show="item.value"></span>
</div>
<div class="status" v-show="item.value">
<div v-for="item2 in item.list" :key="item2.id">
<span @click="itemClick(item)" v-show="item.value" :style="{ background: item.color }">{{ item2.zbldXm
}}
{{
item2.kssj.split(":")[0] + ":" + item2.kssj.split(":")[1]
}}
{{
item2.jssj.split(":")[0] + ":" + item2.jssj.split(":")[1]
}}
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="list-item item_box">
<div class="title">部门值班报备详情</div>
<div v-for="item in zbInfo.list" :key="item.id">
<div class="num-text">值班领导{{ item.zbldXm }}</div>
<div class="num-text" v-if="item.zbmj && item.zbmj.length > 0">
值班民警{{
JSON.parse(item.zbmj)
.map((jl) => jl.jlxm)
.join("、") || "暂无"
}}
</div>
<div class="num-text" v-if="item.zbfj && item.zbfj.length > 0">
值班辅警{{
JSON.parse(item.zbfj)
.map((jl) => jl.jlxm)
.join("、") || "暂无"
}}
</div>
<div class="num-text">值班电话{{ item.zbldDh }}</div>
<div class="num-text">值班时间{{ item.kssj }} - {{ item.jssj }}</div>
</div>
</div>
<div v-if="zbInfo.list.length === 0" style="text-align: center; padding: 12px 0; color: #828282">
无今日值班
</div>
</div>
</template>
<script setup>
import { getDeptByMonth } from "../../../api/calender";
import TopNav from "../../../components/topNav.vue";
import { onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { Toast } from "vant";
const zbInfo = ref({
list: [],
});
//日历选中高亮
const calendarActive = ref("");
const router = useRouter();
const week = ref(["周日", "周一", "周二", "周三", "周四", "周五", "周六"]);
const Year = ref(new Date().getFullYear()); //日历上的年份
const month = ref(new Date().getMonth() + 1); //日历上的月份
const Day = ref(new Date().getDate()); //日历上的天份
const nowYear = ref(new Date().getFullYear());
const nowmonth = ref(new Date().getMonth() + 1);
const nowDay = ref(new Date().getDate());
const starttime = ref("");
const endtime = ref("");
const nowtime = ref("");
const calendarList = ref([]);
onMounted(() => {
Draw(nowYear.value, nowmonth.value);
let time_month = nowmonth.value; //现在的月份
let time_day = nowDay.value; //现在的天数
if (nowmonth.value < 10) {
time_month = 0 + "" + nowmonth.value;
}
if (nowDay.value < 10) {
time_day = 0 + "" + nowDay.value;
}
nowtime.value = nowYear.value + "-" + time_month + "-" + time_day;
calendarActive.value =
nowYear.value + "-" + nowmonth.value + "-" + nowDay.value;
starttime.value = nowtime.value;
endtime.value = nowtime.value;
});
function itemClick(e) {
zbInfo.value = e;
}
function checkDay(val) {
calendarActive.value = val;
}
//状态字典
const ztDict = [
{
label: "无报备",
value: "00",
color: "#7b7b7b",
},
{
label: "有报备",
value: "01",
color: "#51fb06",
},
{
label: "今日报备",
value: "02",
color: "#51fb06",
},
{
label: "今日排班",
value: "03",
color: "#7b7b7b",
},
{
label: "无",
value: "04",
color: "#7b7b7b",
},
{
label: "有排班",
value: "05",
color: "#7b7b7b",
},
{
label: "无排班",
value: "06",
color: "#7b7b7b",
},
];
//状态数据处理
function checkZt(list = []) {
var zt = [];
if (list.length > 0) {
zt = list.map((item) => {
return {
text: ztDict.filter((item2) => item2.value === item.zt)[0].label,
color: ztDict.filter((item2) => item2.value === item.zt)[0].color,
id: item.id,
zt: item.zt,
};
});
}
return zt;
}
const isToday = ref(true);
function Draw(Year, Month) {
Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
getDeptByMonth({ time: Year + "-" + Month })
.then((res) => {
const copyRes = JSON.parse(JSON.stringify(res)).map((c) => {
var ccc = [];
if (!c.list) {
ccc = [];
} else {
ccc = c.list.map((ci) => {
return {
...ci,
zt: c.type,
};
});
}
return {
...c,
label: ztDict.filter((item2) => item2.value === c.type)[0].label,
color: ztDict.filter((item2) => item2.value === c.type)[0].color,
list: ccc,
};
});
calendarList.value = copyRes.map((item, index) => {
return {
value: index + 1,
kssj: "20:00", //假数据
jssj: "23:59",
status: checkZt(item.list), //假的状态
count: Year + "-" + Month + "-" + item.day,
...item,
};
});
if (isToday.value) {
var toTime = new Date();
var m =
toTime.getMonth() < 9
? "0" + (toTime.getMonth() + 1)
: toTime.getMonth() + 1;
var d =
toTime.getDate() < 10 ? "0" + toTime.getDate() : toTime.getDate();
var toDay = toTime.getFullYear() + "-" + m + "-" + d;
calendarList.value.forEach((v) => {
if (v.time === toDay) {
zbInfo.value = v;
isToday.value = false;
}
});
}
for (
var i = 1, firstDay = new Date(Year, Month - 1, 1).getDate();
i <= firstDay;
i++
) {
calendarList.value.unshift("");
}
Toast.clear();
})
.catch((err) => {
Toast.clear();
});
}
// 上个月
function last() {
month.value--;
if (month.value == 0) {
month.value = 12;
Year.value--;
}
Draw(Year.value, month.value);
}
// 下个月
function next() {
month.value++;
if (month.value == 13) {
month.value = 1;
Year.value++;
}
Draw(Year.value, month.value);
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.calenderBox {
width: 100%;
padding: 1vw;
box-sizing: border-box;
.calender-head {
width: 100%;
height: 15vw;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-weight: bold;
line-height: 40px;
position: relative;
.change {
position: absolute;
right: 1vw;
bottom: 2vw;
cursor: pointer;
color: #3e6ee8;
@include font_size($font_medium_s);
}
.btn {
width: 7vw;
height: 7vw;
line-height: 7vw;
text-align: center;
border-radius: 1vw;
background: #3e6ee8;
color: #fff;
}
.text {
margin: 0 4vw;
@include font_color($font-color-theme);
}
}
.week {
width: 100%;
display: flex;
flex-wrap: nowrap;
text-align: center;
height: 10vw;
line-height: 10vw;
background: #164acc;
color: #fff;
.days {
flex: 1;
}
}
.wrap {
width: 100%;
display: flex;
flex-wrap: wrap;
.item {
width: calc((100% / 7) - 1.3px);
border: 1px solid #3e6ee8;
border-top: none;
font-size: 10px;
min-height: 15vw;
.num {
text-align: right;
padding-right: 1vw;
box-sizing: border-box;
@include font_color($font-color-theme);
}
.num.active {
color: #1adb10;
}
.status {
text-align: center;
margin: 1vw 0;
span {
background: #3e6ee8;
padding: 1px 1vw;
display: block;
width: 10vw;
color: #fff;
border-radius: 1vw;
margin: 6px auto;
}
.green {
background: #1adb10;
}
.gray {
background: #83868f;
}
}
.time {
font-size: 10px;
// height: 5vw;
// line-height: 7vw;
color: #3e6ee8;
text-align: center;
}
.greenColor {
color: #1adb10;
}
.grayColr {
color: #83868f;
}
.BlueColor {
color: #3e6ee8;
}
}
.item:nth-child(7n + 2) {
border-left: none;
}
.item:nth-child(7n + 3) {
border-left: none;
}
.item:nth-child(7n + 4) {
border-left: none;
}
.item:nth-child(7n + 5) {
border-left: none;
}
.item:nth-child(7n + 6) {
border-left: none;
}
.item:nth-child(7n + 7) {
border-left: none;
}
}
}
.list {
max-height: calc(100vh - 35vw);
// overflow: hidden;
// overflow-y: auto;
}
.list-item {
padding: 3vw;
margin: 2vh 5vw;
border-radius: 2vw;
.phone-icon {
position: absolute;
right: 5vw;
}
.address-box {
display: flex;
justify-content: space-between;
.adress-left {
color: #3e6ee8;
}
}
.name-text {
@include font_size($font_medium);
color: #3e6ee8;
margin-bottom: 1vh;
font-weight: bold;
display: flex;
justify-content: flex-start;
align-items: center;
}
.title {
@include font_size($font_medium);
font-weight: 550;
}
.num-text {
@include font_size($font_medium_s);
color: #2b2b2b;
padding: 4px 0;
}
}
</style>

View File

@ -0,0 +1,131 @@
<template>
<div class="container" style="padding-top: 13vw">
<TopNav :navTitle="'盘查人员信息'" />
<van-form>
<div class="title_tab other_type_title">人员信息</div>
<div
@click="routerPush(item)"
class="info_box item_box"
v-for="(item, i) in userInfo"
:key="i"
>
<div class="item">
<span class="name">姓名</span>
<span class="text">
<span class="info">{{ item.xm ? item.xm : "未知" }}</span>
</span>
</div>
<div class="item">
<span class="name">权重</span>
<span class="text">
<span class="info">{{ item.qz }}</span>
</span>
</div>
<div class="item">
<span class="name">身份证号</span>
<span class="text">
<span class="info">{{ item.zjhm }}</span>
</span>
</div>
</div>
</van-form>
<van-empty
description="暂无数据"
image="default"
v-if="userInfo.length <= 0"
/>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from "vue";
import TopNav from "../../../components/topNav";
import { useRoute, useRouter } from "vue-router";
import { hintToast } from "../../../utils/tools.js";
import { Toast ,showLoadingToast} from "vant";
import { editYyzxApi } from "../../../api/yyzxApi.js";
const router = useRouter();
const route = useRoute();
const userInfo = ref([]);
const TOASTT = ref()
onMounted(() => {
if (route.query.dhhm) {
_getUserInfo(route.query.dhhm);
}
});
// 电话
function _getUserInfo(val) {
TOASTT.value = Toast.loading({
message: "加载...",
forbidClick: true,
loadingType: "spinner",
duration: 0,
});
editYyzxApi(`/mosty-hczx/tbHcBpcry/getRyListBySjhm/${val}`, {})
.then((res) => {
TOASTT.value.clear();
if (res.length > 0) userInfo.value = res;
})
.catch((err) => {
TOASTT.value.clear();
});
}
function routerPush(row) {
router.push({
path: "/quarantinePersonnel",
query: { sfzh: row.zjhm, pcsrlx: "6", dhpc: route.query.dhhm },
});
}
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.popupTitle {
text-align: center;
background-color: rgb(11, 137, 247);
height: 6vh;
line-height: 6vh;
}
.title_tab {
margin: 2vw 0 2vw 6vw;
}
.info_box {
margin: 2vw 4vw;
padding: 2vw;
box-sizing: border-box;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
.item {
display: flex;
justify-content: space-between;
background-color: #e8eeff;
margin-bottom: 2vw;
padding: 2vw;
box-sizing: border-box;
.name {
display: inline-block;
width: 14vw;
text-align-last: justify;
}
.text {
display: inline-block;
width: calc(100% - 15vw);
.info {
float: right;
}
}
}
}
.rycard {
display: flex;
img {
margin-right: 2.5vw;
}
.item_ry {
line-height: 1.5em;
}
}
</style>

254
src/pages/yyzx/index.vue Normal file
View File

@ -0,0 +1,254 @@
<template>
<div style="padding-top: 13vw">
<TopNav navTitle="应用中心" :showRight="false" :showLeft="false" />
<YyzxItem title="置顶" :list="zdList.list" />
<!-- <YyzxItem title="勤务中心" :list="qwzxList.list" />
<YyzxItem title="预警中心" :list="yjzxList.list" />
<YyzxItem title="指令中心" :list="zlzxList.list" /> -->
<!-- <YyzxItem title="警情中心" :list="wqList.list" /> -->
<!-- <YyzxItem title="核查中心" :list="hcList.list" /> -->
<!-- <YyzxItem title="任务中心" :list="rwzxList.list" /> -->
<!-- <YyzxItem title="公共应用" :list="ggyyList.list" /> -->
<!-- 底部tas -->
<BottomTabs type="yyzx" />
<!-- 盘人 -->
<checkedPeople ref="peo" :key="zdgzKey + 'pr'" />
<!-- 盘车 -->
<checkedCar ref="car" :key="zdgzKey + 'pc'" />
<PcModel ref="dhcr" :key="zdgzKey + 'dhcr'"></PcModel>
<div style="height: 14.8666vw"></div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, onUnmounted, onActivated } from "vue";
import checkedCar from "../spsHome/components/checkCar.vue";
import checkedPeople from "../spsHome/components/checkPeople.vue";
import YyzxItem from "../../components/yyzxItem.vue";
import BottomTabs from "../../components/bottomTabs.vue";
import TopNav from "../../components/topNav.vue";
import PcModel from "../../components/pcModel.vue";
import emitter from "../../utils/eventBus.js";
import { onBeforeRouteLeave } from "vue-router";
const peo = ref(); //盘查人员组件对象
const car = ref(); //盘查车辆组件对象
const dhcr = ref(); //电话查人组件对象
const zdgzKey = ref(1);
const hcList = reactive({
list: [
{
name: "人员盘查",
imgUrl: require("../../assets/images/menu-yyhc.png"),
path: "pr",
},
{
name: "车辆盘查",
imgUrl: require("../../assets/images/menu-clhc.png"),
path: "pc",
},
{
name: "人员盘查列表",
imgUrl: require("../../assets/images/rypclb.png"),
path: "/yyzx/views/pcry",
},
{
name: "车辆盘查列表",
imgUrl: require("../../assets/images/clpclb.png"),
path: "/yyzx/views/clpc",
},
{
name: "巡访管理",
imgUrl: require("../../assets/images/11.png"),
path: "/Declaration",
},
],
});
const wqList = reactive({
list: [
{
name: "警情统计",
imgUrl: require("../../assets/images/menu-yjzl.png"),
path: "/jqfx",
},
{
name: "警情列表",
imgUrl: require("../../assets/images/menu-yjzl.png"),
path: "/yyzx/jqxx/index",
},
],
});
const rwzxList = reactive({
list: [
{
name: "任务统计",
imgUrl: require("../../assets/images/rwtj.png"),
path: "/yyzx/rwzx",
},
{
name: "任务列表",
imgUrl: require("../../assets/images/rwtj.png"),
path: "/rwlist",
},
],
});
const zlzxList = reactive({
list: [
{
name: "指令统计",
imgUrl: require("../../assets/images/menu-zlzx.png"),
path: "/yyzx/zlzx/zlTotal",
},
{
name: "指令列表",
imgUrl: require("../../assets/images/menu-zlzx.png"),
path: "/yyzx/zlzx/zlzxIndex",
},
],
});
const yjzxList = reactive({
list: [
{
name: "预警统计",
imgUrl: require("../../assets/images/yjtj.png"),
path: "/yyzx/yjxx/yjTotal",
},
{
name: "预警列表",
imgUrl: require("../../assets/images/menu-yjzx.png"),
path: "/yyzx/yjxx/index",
},
],
});
const qwzxList = reactive({
list: [
{
name: "今日勤务",
imgUrl: require("../../assets/images/qwtj.png"),
path: "/qwCenter",
},
// 存在问题
// {
// name: "历史勤务",
// imgUrl: require("../../assets/images/qwtj.png"),
// path: "/hisQwCenter",
// },
{
name: "巡防报备",
imgUrl: require("../../assets/images/menu-rwzx.png"),
path: "/yyzx/xfbb/addXfbb",
},
{
name: "临时勤务报备",
imgUrl: require("../../assets/images/menu-rwzx.png"),
path: "/yyzx/xfbb/addtsXfbb",
},
{
name: "值班报备",
imgUrl: require("../../assets/images/zbbb.png"),
path: "/yyzx/views/addZbbb",
},
{
name: "我的巡防",
imgUrl: require("../../assets/images/xfbbqd.png"),
path: "/calendar",
},
{
name: "我的值班",
imgUrl: require("../../assets/images/zbbb.png"),
path: "/zbbbCalendar",
},
{
name: "临时勤务列表",
imgUrl: require("../../assets/images/menu-rwzx.png"),
path: "/yyzx/xfbb/tsXfbbList",
},
{
name: "部门值班",
imgUrl: require("../../assets/images/zbbb.png"),
path: "/deptzbbbCalendar",
},
{
name: "部门巡防",
imgUrl: require("../../assets/images/xfbbqd.png"),
path: "/deptxfbbCalendar",
},
{
name: "人员休假",
imgUrl: require("../../assets/images/xfbbqd.png"),
path: "/deptryxjCalendar",
},
],
});
//置顶
const zdList = reactive({
list: [
{
name: "人员盘查",
imgUrl: require("../../assets/images/menu-yyhc.png"),
path: "pr",
},
{
name: "车辆盘查",
imgUrl: require("../../assets/images/menu-clhc.png"),
path: "pc",
},
{
name: "打卡",
imgUrl: require("../../assets/images/menu-dk.png"),
path: "/clock",
},
],
});
//公共应用
const ggyyList = reactive({
list: [
{
name: "意见反馈",
imgUrl: require("../../assets/yyzx/yjsj.png"),
path: "/yjsj",
},
{
name: "意见反馈统计",
imgUrl: require("../../assets/images/yjfktj.png"),
path: "/xttj",
},
],
});
onActivated(() => {
zdgzKey.value++;
});
onMounted(() => {
zdgzKey.value++;
//点击盘查功能
emitter.on("onClickPc", (res) => {
if (res == "pr") {
checkPeople();
} else if (res == "/dhcr") {
checkDhcr();
} else {
checkCar();
}
});
});
onUnmounted(() => {
emitter.off("onClickPc");
localStorage.removeItem('XF_Active')
});
//点击盘人
function checkPeople() {
peo.value.handleOpen();
}
//点击盘车
function checkCar() {
car.value.handleOpen();
}
// 点击电弧查人
function checkDhcr() {
dhcr.value.peoplePopupShow = true;
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,32 @@
<template>
<!-- 关联警情 -->
<div style="padding-top:13vw">
<TopNav navTitle="关联警情" :showRight="false" :showLeft="true" />
<List
v-for="(item, index) in list"
:key="index"
:item="item"
/>
</div>
</template>
<script setup>
import List from "../../../components/JqList.vue";
import TopNav from "../../../components/topNav.vue";
import { onMounted, ref } from "vue";
import { getGljq } from "../../../api/jqxx";
import { useRoute } from "vue-router";
const route = useRoute()
const list = ref([]);
function getList() {
getGljq({ jjdbh:route.query.jjdbh }).then((res) => {
list.value = res;
});
}
onMounted(() => {
getList();
});
</script>
<style>
</style>

View File

@ -0,0 +1,218 @@
<template>
<div>
<TopNav navTitle="警情列表" :showRight="false" :showLeft="true" />
<van-sticky>
<div class="sticky_box">
<Tabs
:list="tabs"
@onYjjb="onSelect"
:type="'car'"
:key="tabsIndex"
></Tabs>
<Search
placeholder="请输入关键字"
v-model="kwd"
:isSx="true"
@update:sx="showPopup = !showPopup"
@update:modelValue="onSearch"
></Search>
</div>
</van-sticky>
<SxPopup
:showPopup="showPopup"
:list="yjxx.sxList"
:p_top="145"
@update:close="showPopup = false"
@update:onConfirm="onConfirm"
:kssj="dateFormat()"
:jssj="dateFormat()"
/>
<van-pull-refresh v-model="loadingPull" @refresh="onRefresh">
<van-list
v-model:loading="loading"
:finished="finished"
finished-text=" "
@load="onLoad"
offset="1"
:immediate-check="false"
>
<List
v-for="(item, index) in yjxx.list"
:key="index"
:item="item"
path="/yyzx/jqxx/jqDetail"
/>
<van-empty
description="没有警情信息"
image="default"
v-if="yjxx.list.length <= 0 && showEmpty"
/>
</van-list>
</van-pull-refresh>
</div>
</template>
<script setup>
import TopNav from "../../../components/topNav.vue";
import Search from "../../../components/search.vue";
import Tabs from "../../../components/tabs.vue";
import SxPopup from "../../../components/SxPopup.vue";
import List from "../../../components/JqList.vue";
import { setTimeQuantum, dateFormat } from "../../../utils/tools.js";
import { getDictList, setDict } from "../../../utils/dict";
import { ref, reactive, onMounted, watch } from "vue";
import { getJqList, getStatistics } from "../../../api/jqxx";
const tabs = ref([
{
name: "全部警情",
value: null,
count: 0,
},
{
name: "刑事警情",
value: 1,
count: 0,
},
{
name: "行政警情",
value: 2,
count: 0,
},
{
name: "交通警情",
value: 3,
count: 0,
},
{
name: "其他",
value: 4,
count: 0,
},
]);
const sx = ref([setTimeQuantum()]);
sx.value[0].array[0].isCheck = true;
const yjxx = reactive({
sxList: sx.value, //筛选条件数据
list: [], //预警列表数据,
total: 0,
});
const params = ref({
pageNum: 1,
pageSize: 10,
bjnr: "",
bjlb: "",
endTime: dateFormat(),
startTime: dateFormat(),
});
const tabsIndex = ref(1);
const kwd = ref("");
const finished = ref(false);
const loading = ref(false);
const loadingPull = ref(false);
const showEmpty = ref(false);
const showPopup = ref(false); //筛选弹窗
//下拉刷新
function onRefresh() {
tabsIndex.value++;
yjxx.list = [];
params.value.pageNum = 1;
params.value.bjnr = "";
params.value.bjlb = "";
params.value.endTime = "";
params.value.startTime = "";
getList();
getJqtj();
}
//获取警情列表
function getList() {
loading.value = false;
getJqList(params.value)
.then((res) => {
loading.value = false;
loadingPull.value = false;
if (res.records && res.records.length > 0) {
yjxx.list.push(...res.records);
} else {
showEmpty.value = true;
}
yjxx.total = res.total;
})
.catch((err) => {
loading.value = false;
showEmpty.value = true;
});
}
function onLoad() {
if (yjxx.list >= yjxx.total) {
finished.value = true;
return;
}
params.value.pageNum++;
getList();
}
//获取警情统计数据
function getJqtj() {
const data = {
endTime: params.value.endTime,
startTime: params.value.startTime,
bjnr: params.value.bjnr,
};
getStatistics(data).then((res) => {
tabs.value[0].count = res.jtCount + res.qtCount + res.xsCount + res.xzCount;
tabs.value[1].count = res.xsCount;
tabs.value[2].count = res.xzCount;
tabs.value[3].count = res.jtCount;
tabs.value[4].count = res.qtCount;
});
}
onMounted(() => {
getList();
getJqtj();
});
/**
* tab选择
* @param {Object} val
*/
function onSelect(val) {
// loading.value = true;
finished.value = false;
yjxx.list = [];
params.value.bjnr = "";
params.value = {
pageNum: 1,
pageSize: 10,
endTime: params.value.endTime,
startTime: params.value.startTime,
bjlb: !val ? null : val,
};
getList();
}
/**
* 关键字搜索
* @param {Object} val
*/
function onSearch(val) {
yjxx.list = [];
params.value.bjnr = val;
params.value = {
pageNum: 1,
pageSize: 20,
endTime: "",
startTime: "",
bjlb: !val ? null : val,
};
getList();
getJqtj();
}
function onConfirm(val) {
yjxx.list = [];
params.value.startTime = val.startTime;
params.value.endTime = val.endTime;
getList();
getJqtj();
showPopup.value = false;
}
</script>
<style>
</style>

View File

@ -0,0 +1,91 @@
<template>
<div style="padding-top: 14vw">
<TopNav navTitle="警情详情" :showRight="false" :showLeft="true" />
<div class="ry_info">
<List :item="jqDetail" path="/yyzx/jqxx/jqDetail" />
</div>
<!-- <Steps :data="stepsData">
<template v-slot:default="{ scope }">
<div class="content">
<div class="cont_l">
<div class="text title">{{ scope.title }}</div>
<div class="text">执行人:{{ scope.zxr }}</div>
<div class="text">执行部门:{{ scope.zxbm }}</div>
</div>
</div>
</template>
</Steps> -->
<div class="mapPattern">
<van-button round block type="primary" @click="routerPush('/yyzx/jqxx/gljqList')"> 关联警情 </van-button>
</div>
</div>
</template>
<script setup>
import List from "../../../components/JqList.vue";
import TopNav from "../../../components/topNav.vue";
import Steps from "../../../components/Steps.vue";
import { getJqInfo } from "../../../api/jqxx";
import { onMounted, ref } from "vue";
import { useRoute } from "vue-router";
import router from "../../../router";
const route = useRoute()
const jqDetail = ref({});
const stepsData = ref([
{
title: "接到警情",
zxr: "张三",
zxbm: "高新区派出所",
time: "2022-10-27 20:11:26",
},
{
title: "接到警情",
zxr: "张三",
zxbm: "高新区派出所",
time: "2022-10-27 20:11:26",
},
{
title: "接到警情",
zxr: "张三",
zxbm: "高新区派出所",
time: "2022-10-27 20:11:26",
}
]);
//获取详情
function getInfo(){
getJqInfo(route.query.id).then(res=>{
jqDetail.value = res
})
}
function routerPush(path){
router.push({
path:path,
query:{jjdbh:jqDetail.value.jjdbh}
})
}
onMounted(()=>{
getInfo()
})
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.ry_info {
margin: 2vw 3vw;
border-radius: 2vw;
@include jrtz_fill_color($jrtz-fill-color-theme);
}
.content {
display: flex;
padding-bottom: 20px;
.cont_l {
margin-right: 16px;
.text{
line-height: 5.5vw;
}
.title{
@include font_size($font_medium);
font-weight: 550;
}
}
}
</style>

View File

@ -0,0 +1,329 @@
<template>
<div class="mryq_box">
<div class="title red">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
<div class="dw_rq d_bottom">
<span>单位巡警大队 </span>
<span> 2022年11月8日 </span>
</div>
<div class="dw_rq">
<span>审核领导邱文宇 </span>
<span> 撰稿人胡云建 </span>
</div>
<div class="text_box">
<span class="twxc_title"> 1发案情况</span><br />
&emsp;&emsp;街面实发警情共8件相对昨日减少6件其中盗窃三车警情3件相对昨日减少3件扒窃警情5件相对昨日增加2件车财警情0件相对昨日减少5件<br />
<span class="twxc_title"> 2今日发案分布</span><br />
<div class="table_box">
<div class="fafb_table_header header">
<div>单位</div>
<div>芳草</div>
<div>桂溪</div>
<div>合作</div>
<div>和平</div>
<div>石羊</div>
<div>西园</div>
<div>肖家</div>
<div>新川</div>
<div>会展</div>
<div>益州</div>
<div>中和</div>
<div>合计</div>
</div>
<div class="data_box">
<div class="table_box">
<div
class="fafb_table_header right"
v-for="item in mryq.fafb"
:key="item"
>
<div>{{ Object.keys(item)[0] }}</div>
<div v-for="_item in item[Object.keys(item)[0]]" :key="_item">
{{ _item }}
</div>
</div>
</div>
</div>
</div>
<span class="twxc_title"> 3热点区域图</span><br />
<span class="twxc_title"> 4巡大天网巡查情况</span><br />
<div class="twxc_box">
<div v-for="item in mryq.twxc" :key="item" class="twxc_item">
<div class="twxc_title">{{ item.ssbm }}</div>
<div>重点区域{{ item.zdqu }}</div>
<div>巡控时段{{ item.xksd }}</div>
<div>必巡线必巡点{{ item.bxxBxd }}</div>
<div>天网杆号{{ item.twgh }}</div>
<div>巡查时间{{ item.xcsj }}</div>
<div>巡查原因{{ item.xcyy }}</div>
<div>巡逻质效{{ item.xlzx }}</div>
</div>
</div>
<span class="twxc_title"> 5警情图巡情况</span><br />
<div class="twxc_box">
<div v-for="item in mryq.jqtx" :key="item" class="twxc_item">
<div class="twxc_title">{{ item.ssbm }}</div>
<div>图巡时段{{ item.txsd }}</div>
<div>点位地址{{ item.dwdz }}</div>
<div>天网号{{ item.twh }}</div>
<div>巡查情况{{ item.xcqk }}</div>
<div>巡查原因{{ item.xcyy }}</div>
<div>巡逻质效{{ item.xlzx }}</div>
<div>存在问题{{ item.czwt }}</div>
<div>整改措施{{ item.zgcs }}</div>
</div>
</div>
<span class="twxc_title"> 6移动巡逻盘查数据</span><br />
<div class="table_box">
<div class="fafb_table_header header" style="width: 30%">
<div></div>
<div>卡点与街面巡防</div>
<div>芳草</div>
<div>桂溪</div>
<div>合作</div>
<div>和平</div>
<div>石羊</div>
<div>西园</div>
<div>肖家</div>
<div>新川</div>
<div>会展</div>
<div>益州</div>
<div>中和</div>
</div>
<div class="data_box" style="width: 70%">
<div class="table_box">
<div
class="fafb_table_header right"
v-for="item in mryq.ydxlpc"
:key="item"
:style="Object.keys(item)[0] == '盘查合计数' ? 'width:18%' : ''"
>
<div>{{ Object.keys(item)[0] }}</div>
<div class="two_table">
<div
v-for="_item in item[Object.keys(item)[0]]"
:key="_item"
:style="_item.title == '人员、车辆' ? 'width:100%' : ''"
>
{{ _item.title }}
</div>
</div>
<template style="display: flex">
<div
class="total_item_sum"
v-for="_item in item[Object.keys(item)[0]]"
:key="_item"
:style="_item.title == '人员、车辆' ? 'width:100%' : ''"
>
<div v-for="_it in _item.arr" :key="_it">
{{ _it }}
</div>
</div>
</template>
</div>
</div>
</div>
</div>
<span class="twxc_title">7质效评估</span><br />
&emsp;&emsp;今日和平三个警情相比昨日上升一个于上月环比上升1件桂溪西园合作肖家所有街面实发六类侵财警情巡逻防控未取得质效其余各所无街面实发六类侵财警情巡逻防控取得质效<br />
<span class="twxc_title">8工作指令</span><br />
&emsp;&emsp;今日街面实发警情8件分布于***地方巡大各所根据发案时段发案区域合理部署警力在街面警情热点区域开展巡逻防控和逢疑必查工作
</div>
</div>
</template>
<script setup>
import { reactive } from "vue";
const mryq = reactive({
fafb: [
{ 两抢: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
{ 汽盗: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
{ 车财: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
{ 三车: [0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3] },
{ 扒窃: [0, 0, 1, 1, 0, 2, 1, 0, 0, 0, 0, 4] },
{ 六类汇总: [0, 1, 3, 1, 0, 2, 1, 0, 0, 0, 0, 8] },
],
twxc: [
{
ssbm: "桂溪",
zdqu: "名都路沿线周边",
xksd: "00:00-04:00",
bxxBxd: "名都路沿线",
twgh: "D-09030939",
xcsj: "11月7日 01:00-02:00",
xcyy: "车财易发案区域",
xlzx: "巡查时段无警力巡逻,无街面发案",
},
{
ssbm: "合作",
zdqu: "龙湖时代天街周边",
xksd: "18:00-21:00",
bxxBxd: "龙湖时代天街周边道路沿线",
twgh: "Y-09055102",
xcsj: "11月6日 19:00-20:00",
xcyy: "扒窃易发案区域",
xlzx: "巡查时段无警力巡逻,无街面发案",
},
{
ssbm: "石羊",
zdqu: "复城国际周边",
xksd: "19:00-22:00",
bxxBxd: "盛华南路沿线",
twgh: "D-09040960",
xcsj: "11月7日 20:00-21:00",
xcyy: "三车易发案区域",
xlzx: "巡查时段有警车巡逻,无街面发案",
},
],
jqtx: [
{
ssbm: "中和所",
txsd: "11月7日 01:00-02:00",
dwdz: "紫竹广场",
twh: "09025301",
xcqk: "巡查时段无警力巡逻,无街面发案",
xcyy: "车财易发案区域",
xlzx: "无街面发案",
czwt: "1、巡查时段街面三车随意停放无人员管理。",
zgcs: "加强巡逻遥控,规范停车",
},
{
ssbm: "合作所",
txsd: "11月7日 01:00-02:00",
dwdz: "紫竹广场",
twh: "09025301",
xcqk: "巡查时段无警力巡逻,无街面发案",
xcyy: "车财易发案区域",
xlzx: "无街面发案",
czwt: "1、巡查时段街面三车随意停放无人员管理。",
zgcs: "加强巡逻遥控,规范停车",
},
],
ydxlpc: [
{
盘车人员: [
{ title: "移交人员数", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
{ title: "人员合计数", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
],
},
{
盘查车辆: [
{ title: "移交车辆数", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
{ title: "车辆合计数", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
],
},
{
盘查物品: [
{ title: "人员物品数", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
{ title: "车辆物品数", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
],
},
{
盘查合计数: [
{ title: "人员、车辆", arr: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] },
],
},
],
});
</script>
<style lang="scss" scoped>
@import "../../../assets/styles/mixin.scss";
.mryq_box {
padding: 0 3vw 5vw 3vw;
@include font_color($font-color-theme);
@include font_size($font_medium_s);
.title {
font-size: 10vw;
text-align: center;
padding: 5vw 15vw 2vw 15vw;
display: flex;
justify-content: space-between;
align-items: center;
// letter-spacing: 40px;
}
.dw_rq {
display: flex;
justify-content: space-between;
@include font_size($font_medium);
font-weight: 600;
padding: 1vw;
}
.d_bottom {
border-bottom: 3px solid red;
}
.text_box {
line-height: 5.5vw;
.table_box {
display: flex;
.header {
width: 15%;
text-align: center;
& > div {
height: 5vw;
}
}
.header:nth-child(1) {
border-left: 1px solid #999;
}
.data_box {
width: 85%;
overflow-x: scroll;
.table_box {
display: flex;
width: 230%;
}
.right {
width: 28%;
& > div {
height: 5vw;
}
}
}
}
.twxc_box {
.twxc_item {
border-bottom: 1px solid #eff0f5;
padding: 2vw 0;
}
}
.twxc_title {
display: inline-block;
@include font_size($font_medium);
font-weight: 600;
margin: 2vw 0;
}
}
}
.two_table {
display: flex;
& > div {
width: 50%;
}
}
.total_item_sum {
width: 50%;
text-align: center;
& > div {
border-top: 1px solid #999;
border-right: 1px solid #999;
height: 5vw;
}
& > div:last-child {
border-bottom: 1px solid #999;
}
}
.fafb_table_header {
& > div {
text-align: center;
border-top: 1px solid #999;
border-right: 1px solid #999;
}
& > div:last-child {
border-bottom: 1px solid #999;
}
}
</style>

View File

@ -0,0 +1,223 @@
<template>
<div :id="echid" class="gfChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: ["list"],
watch: {
list: {
handler(val) {
this.hamdlegfChart();
},
immediate: true,
deep: true,
},
},
data() {
return {
echid: "",
themeType: getStorage("themeSetting"),
};
},
created() {
this.echid = "echi_et" + new Date().getTime();
},
mounted() {
this.hamdlegfChart();
},
methods: {
hamdlegfChart() {
if (document.getElementById(this.echid)) {
let myChart = echarts.init(document.getElementById(this.echid));
var option = {
grid: {
left: "0",
right: "0",
bottom: "48",
top: "10",
containLabel: true,
},
legend: {
left: "center",
bottom: 0, //具体
textStyle: {
color: this.themeType == "light" ? "#333" : "#fff",
},
},
tooltip: {},
dataset: {
source: this.list,
},
xAxis: {
type: "category",
axisLabel: {
color: this.themeType == "light" ? "#333" : "#fff",
},
},
yAxis: {
splitLine: { show: false },
axisLabel: {
color: this.themeType == "light" ? "#333" : "#fff",
},
},
series: [
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
// barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#1eabff",
},
{
offset: 1,
color: "#4760ff",
},
],
},
],
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
// barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#88f2b9",
},
{
offset: 1,
color: "#0dda72",
},
],
},
],
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
// barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#ffd91b",
},
{
offset: 1,
color: "#ff8e43",
},
],
},
],
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
// barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#f87373",
},
{
offset: 1,
color: "#e81b1b",
},
],
},
],
},
{
type: "bar",
barWidth: 9,
itemStyle: {
normal: {
// barBorderRadius: [5, 5, 5, 5],
},
},
color: [
{
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#f9906f",
},
{
offset: 1,
color: "#f05654",
},
],
},
],
},
],
};
option && myChart.setOption(option);
}
},
},
};
</script>
<style scoped>
.gfChart {
margin-top: 1vw;
height: 100%;
width: 100%;
margin: 0 auto;
}
</style>

View File

@ -0,0 +1,109 @@
<template>
<ul class="box-rank">
<li class="item">
<div class="text title">名次</div>
<div class="text title" v-if="active == 1">名称</div>
<div class="text title">完成数</div>
<div class="text title">未完成</div>
<div class="text title">完成</div>
<div class="text title dep" style="text-align: center">部门</div>
</li>
<li class="item" v-for="(item, index) in data" :key="index">
<div class="text title mc" v-if="index == 0">
<van-image
width="5vw"
height="5vw"
fit="contain"
:src="require('../../../../assets/gxapp/j.png')"
/>
</div>
<div class="text title mc" v-else-if="index == 1">
<van-image
width="5vw"
height="5vw"
fit="contain"
:src="require('../../../../assets/gxapp/y.png')"
/>
</div>
<div class="text title mc" v-else-if="index == 2">
<van-image
width="5vw"
height="5vw"
fit="contain"
:src="require('../../../../assets/gxapp/t.png')"
/>
</div>
<div class="text title mc" v-else>{{ index + 1 }}</div>
<div class="text title" v-if="active == 1">{{ item.jsrmc }}</div>
<div class="text title">{{ item.ys }}</div>
<div class="text title">{{ item.ns }}</div>
<div class="text title">{{ (item.rate * 100).toFixed(0) }}%</div>
<div class="text title dep">{{ item.ssbm }}</div>
</li>
<van-empty description="暂无信息" image="default" v-if="data.length <= 0" />
</ul>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { getGrphbData,getBmpm } from "../../../../api/rwzx.js";
const props = defineProps({
active: Number, //选中的排行榜 0部门 1 个人
});
//个人排行榜数据
const data = ref([]);
if (props.active == 1) {
_getGrphbData();
} else {
_getBmpm()
}
//获取个人排行榜数据
function _getGrphbData() {
getGrphbData({}).then((res) => {
if (res.length > 0) data.value = res;
});
}
//获取部门排名数据
function _getBmpm(){
getBmpm({}).then(res => {
if (res.length > 0) data.value = res;
})
}
</script>
<style lang="scss" scoped>
@import "../../../../assets/styles/mixin.scss";
.box-rank {
width: 100%;
height: 100%;
.item {
display: flex;
align-items: center;
justify-content: center;
@include font_size($font_medium_s);
height: 8vw;
.text {
flex: 2;
text-align: center;
}
.mc {
color: #3e6ee8;
}
.dep {
flex: 3;
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}
}
.item:nth-child(2n + 1) {
@include table_item_color($table-item-theme);
}
.item:nth-child(1) {
background: #3e6ee8 !important;
color: #fff;
}
}
</style>

View File

@ -0,0 +1,344 @@
<template>
<div :id="echid" class="gfChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
props: ["datas"],
watch: {
datas: {
handler(val) {
this.hamdlegfChart();
},
immediate: true,
deep: true,
},
},
data() {
return {
echid: "",
themeType: getStorage("themeSetting"),
};
},
created() {
this.echid = "ech_rw" + new Date().getTime();
},
mounted() {
this.hamdlegfChart();
},
methods: {
hamdlegfChart() {
if (document.getElementById(this.echid)) {
let myChart = echarts.init(document.getElementById(this.echid));
var option = {
grid: {
left: "0",
right: "0",
bottom: "0",
top: "0",
containLabel: true,
},
tooltip: {
trigger: "item",
},
legend: {
bottom: "5",
left: "center",
textStyle: {
color: this.themeType == "light" ? "#333" : "#fff",
},
},
graphic: {
type: "text",
left: 133,
top: 107,
style: {
text: "任务类型",
textAlign: "center",
fill: "#377aff",
fontSize: 14,
fontWeight: 600,
},
},
series: [{
name: "Access From",
type: "pie",
radius: ["30%", "50%"],
center: ["50%", "40%"],
avoidLabelOverlap: false,
label: {
alignTo: "edge",
edgeDistance: 10,
textStyle: {
fontSize: 13,
// color: "#000",
lineHeight: 30,
},
formatter: function(data) {
//自定义,加个判断 渲染不同样式 配🍱
if (data.name == "已完成") {
return (
"{name|" +
data.name +
"}" +
"{value|" +
data.value +
" }" +
" \n" +
"{num1|" +
data.percent +
"%" +
"}"
);
}
if (data.name == "超期完成") {
return (
"{name|" +
data.name +
"}" +
"{value|" +
data.value +
" }" +
" \n" +
"{num2|" +
data.percent +
"%" +
"}"
);
}
if (data.name == "超期进行中") {
return (
"{name|" +
data.name +
"}" +
"{value|" +
data.value +
" }" +
" \n" +
"{num3|" +
data.percent +
"%" +
"}"
);
}
if (data.name == "进行中") {
return (
"{name|" +
data.name +
"}" +
"{value|" +
data.value +
" }" +
" \n" +
"{num4|" +
data.percent +
"%" +
"}"
);
}
if (data.name == "超期未完成") {
return (
"{name|" +
data.name +
"}" +
"{value|" +
data.value +
" }" +
" \n" +
"{num5|" +
data.percent +
"%" +
"}"
);
}
},
rich: {
num1: {
fontSize: 16,
fontWeight: 600,
color: "#1bb0ff",
},
num2: {
fontSize: 16,
fontWeight: 600,
color: "#ffde19",
},
num3: {
fontSize: 16,
fontWeight: 600,
color: "#f87373",
},
num4: {
fontSize: 16,
fontWeight: 600,
color: "#88f2b9",
},
num5: {
fontSize: 16,
fontWeight: 600,
color: "#f05654",
},
},
},
labelLine: {
length: 8,
length2: 20,
maxSurfaceAngle: 80,
},
labelLayout: function(params) {
const isLeft = params.labelRect.x < myChart.getWidth() / 2;
const points = params.labelLinePoints;
points[2][0] = isLeft ?
params.labelRect.x :
params.labelRect.x + params.labelRect.width;
return {
labelLinePoints: points,
};
},
emphasis: {
label: {
show: true,
fontSize: "20",
fontWeight: "bold",
},
},
data: [{
value: this.datas.ywc,
name: "已完成",
itemStyle: {
normal: {
//颜色渐变
color: new echarts.graphic.LinearGradient(
1,
0,
1,
1, //(上-下 渐变)
[{
offset: 1,
color: "#4760ff"
},
{
offset: 0.5,
color: "#1bb0ff"
},
]
),
},
},
},
{
value: this.datas.jxz,
name: "进行中",
itemStyle: {
normal: {
//颜色渐变
color: new echarts.graphic.LinearGradient(
1,
0,
1,
1, //(左上-右下 渐变)
[{
offset: 0,
color: "#88f2b9",
},
{
offset: 1,
color: "#0dda72",
},
],
),
},
},
},
{
value: this.datas.cqwc,
name: "超期完成",
itemStyle: {
normal: {
//颜色渐变
color: new echarts.graphic.LinearGradient(
1,
0,
1,
1, //(左上-右下 渐变)
[{
offset: 1,
color: "#ff8747"
},
{
offset: 0.5,
color: "#ffde19"
},
]
),
},
},
},
{
value: this.datas.cqjxz,
name: "超期进行中",
itemStyle: {
normal: {
//颜色渐变
color: new echarts.graphic.LinearGradient(
1,
0,
1,
1, //(左上-右下 渐变)
[{
offset: 1,
color: "#ea2121"
},
{
offset: 0.5,
color: "#f87373"
},
]
),
},
},
},
{
value: this.datas.cqwwc,
name: "超期未完成",
itemStyle: {
normal: {
//颜色渐变
color: new echarts.graphic.LinearGradient(
1,
0,
1,
1, //(左上-右下 渐变)
[{
offset: 1,
color: "#f05654"
},
{
offset: 0.5,
color: "#f9906f"
},
]
),
},
},
},
],
}, ],
};
option && myChart.setOption(option);
}
},
},
};
</script>
<style scoped>
.gfChart {
margin-top: 1vw;
height: 100%;
width: 100%;
margin: 0 auto;
}
</style>

Some files were not shown because too many files have changed in this diff Show More