feixian
zzq 2024-01-30 13:08:47 +08:00
commit a34d720286
32 changed files with 5570 additions and 900 deletions

View File

@ -7,11 +7,13 @@ NODE_ENV = development
# 本地测试
VUE_APP_BASE_API = http://221.2.83.254:9013/api
VUE_APP_BASE_IMG_URL = http://221.2.83.254:901
VUE_APP_BASE_IMG_URL = http://221.2.83.254:9013
VUE_APP_WEBSOCKET_URL = ws://221.2.83.254:9002/ws
# VUE_APP_BASE_API = http://192.168.10.114:81/api
# VUE_APP_BASE_IMG_URL = http://192.168.10.114:81
# VUE_APP_WEBSOCKET_URL = ws://221.2.83.254:9002/ws
# 测试服务区
#VUE_APP_BASE_API = http://123.132.248.154:9224/api
#VUE_APP_BASE_IMG_URL = http://123.132.248.154:9224

View File

@ -27,6 +27,7 @@
"highcharts-vue": "^1.3.5",
"jquery": "^3.6.0",
"js-cookie": "2.2.0",
"js-md5": "^0.8.3",
"jsplumb": "^2.12.8",
"leaflet": "^1.7.1",
"leaflet-minimap": "^3.6.1",

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
public/img/费县图标.zip Normal file

Binary file not shown.

View File

@ -11,10 +11,7 @@
margin: 0;
}
.camera-dia{
/* width: 100vw;
height: 100vh; */
}
.camera-box{
width: 180px;
height: 115px;

View File

@ -126,6 +126,11 @@ export const constantRouterMap = [
name: 'forestranger',
meta: { title: '护林员管理', icon: 'zhuyeicon', sortNo: 0 }, // iconfont icon-
component: () => import('@/views/gridman/forestranger/index')
},{
path: '/gridman_realtime',
name: 'gridman_realtime',
meta: { title: '实时巡检', icon: 'zhuyeicon', sortNo: 0 }, // iconfont icon-
component: () => import('@/views/gridman/realtimeinspection/index')
}
]
},
@ -151,6 +156,11 @@ export const constantRouterMap = [
name: 'adminManager',
meta: { title: '乡镇管理员', icon: 'zhuyeicon', sortNo: 1 }, // iconfont icon-
component: () => import('@/views/adminmanager/index')
},{
path: '/timeslotmanager/index',
name: 'timeslotmanager',
meta: { title: '时间配置', icon: 'zhuyeicon', sortNo: 1 }, // iconfont icon-
component: () => import('@/views/timeslotmanager/index')
},{
path: '/profile',
name: 'profile',

View File

@ -48,6 +48,7 @@
</div>
</template>
<script>
import { encode } from '../../../utils/base64';
import { listToTreeSelect } from '@/utils'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
@ -55,6 +56,7 @@
import { validateMobile, validID, validateStock } from './validate.js'
import form from '../../../store/modules/form';
let BASE_IMAGE_URL = process.env.VUE_APP_BASE_IMG_URL;
import md5 from 'js-md5'
// let BASE_IMAGE_URL = BASE_IMAGE_API_URL;
export default {
name: "AddForm",
@ -173,6 +175,7 @@
_this.addForm.password = _this.addForm.password ? _this.addForm.password : _this.addForm.account;
_this.addForm.password = md5(_this.addForm.password).toUpperCase();
//
//

View File

@ -134,7 +134,7 @@
this.addForm.sex = detail.Sex;
this.addForm.userRole = detail.UserRole ? detail.UserRole : 1;
this.addForm.areaId = detail.areaId;
this.addForm.password = null
this.formRandom = true;
}
})
@ -216,8 +216,7 @@
}
</script>
<style scoped>
::v-deep .vue-treeselect__control {
}
::v-deep .el-form-item__label {
color: #333;

View File

@ -1,8 +1,20 @@
<template>
<div class="clockin-content">
<div class="sum-button">
<el-button type="primary" size="mini" icon="el-icon-pie-chart" @click="toStatic"></el-button>
</div>
<!-- 在线人员 -->
<div class="online-user-list-container" :style="{'height': onlineuserlistshow ? '500px':'100px'}" v-if="false">
<div class="operation-button" @click="onlineuserlistshow = !onlineuserlistshow" >
<span v-if="!onlineuserlistshow">
展开
<i class="el-icon el-icon-arrow-down"></i>
</span>
<span v-else>
收起
<i class="el-icon el-icon-arrow-up"></i>
</span>
</div>
<userlist v-drag></userlist>
</div>
<div class="left-content">
<div class="filter-container">
<el-cascader
@ -17,8 +29,10 @@
<el-input type="text" v-model="listQuery.name" placeholder="请输入搜索关键字" style="width:160px;margin-right:15px;" size="mini" round></el-input>
<el-button type="default" size="mini" @click="resetListQuery"></el-button>
<!-- <el-button type="default" size="mini" @click="resetListQuery"></el-button> -->
<el-button type="primary" size="mini" icon="el-icon-search" @click="getTaskList()"></el-button>
<el-button type="primary" size="mini" icon="el-icon-pie-chart" @click="toStatic"></el-button>
<el-button type="primary" size="mini" icon="el-icon-s-claim" @click="toRealTime"></el-button>
<!-- <el-button type="primary" size="mini" icon="el-icon-plus">创建任务</el-button> -->
</div>
<div class="clock-item-container">
@ -56,9 +70,10 @@
:total="total">
</el-pagination>
</div>
</div>
<div class="item-container">
<div class="item-container" v-if="cardDetailShow">
<div style="padding:0px 0px 0px 0px;">
<el-button size="mini" type="primary" round icon="el-icon-back" @click="cardDetailShow = false;">返回</el-button>
</div>
<div class="item-container-left">
<el-divider content-position="left">打卡点信息</el-divider>
<el-descriptions class="margin-top" :column="1" :size="'mini'" border>
@ -88,11 +103,29 @@
</el-descriptions>
</div>
<div class="item-container-right" >
<div style="padding:0px 20px;margin:0px 0px 15px 0px;position: absolute;top:10px;right:10px;background:#272d39;z-index:100000;" v-if="tabActive == 1">
<el-date-picker
v-model="beginAndEndTime"
size="mini"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="timeChange"
style="width:360px;"
value-format="yyyy-MM-dd HH:mm:ss"
>
</el-date-picker>
</div>
<el-divider content-position="left">
<span :style="{'color':tabActive == 1 ? '#409eff':'#fff','cursor':'pointer'}" @click="tabActive=1"></span>
&nbsp;&nbsp;&nbsp;&nbsp;
<span :style="{'color':tabActive == 2 ? '#409eff':'#fff','cursor':'pointer'}" @click="tabActive=2"></span>
</el-divider>
<div style="width:100%;text-align:center;padding:100px 0px;" v-if="currentRouters.length<=0 && tabActive == 1">
<img src="/img/no-data.png" style="width:140px;margin-bottom:20px;">
@ -106,25 +139,15 @@
<img src="/img/gridman/user.png" alt="">
</div>
<div class="user-name">{{it.name}}</div>
<div class="user-phone">{{it.phone}}</div>
<el-button type="primary" size="mini" round @click="getTrajectoryData(it.id)" style="float:right;position:relative;top:8px;">轨迹</el-button>
<el-button type="primary" size="mini" round @click="getTrajectoryData(it)" style="float:right;position:relative;top:8px;">轨迹</el-button>
<el-button type="primary" size="mini" round @click="getRange(it.phone)" style="float:right;position:relative;top:8px;left:-12px;">范围</el-button>
</div>
{{it.startAddress}} <span style="color:#ccc;font-size:12px;">({{it.startTime}})</span>
{{it.startTime}}
&nbsp;&nbsp;<img src="/img/go.png" style="width:28px;"/>&nbsp;&nbsp;
{{it.endAddress}} <span style="color:#ccc;font-size:12px;">({{it.endTime}})</span>
<!-- <span class="history-line-button" style="float:right;" @click="getTrajectoryData"></span> -->
{{it.endTime}}
</div>
<!-- <div class="user-item" v-for="(item,index) in currentClockInfo.users" :key="index">
<div class="user-phone">{{currentClockInfo.phones[index]}}</div>
<span class="user-operation">
<el-button type="primary" size="mini" round icon="el-icon-map-location">巡检范围</el-button>
</span>
</div> -->
</div>
<div class="users-container" v-show="tabActive == 2">
@ -135,9 +158,11 @@
</div>
</div>
</div>
</div>
<div class="right-content">
<div class="map-container">
<Map :listUpdate="listUpdate" @addClockInPoint="addClockInPoint" :listQuery="listQuery" @lookClockInData="lookClockInData" @editClockInData="editClockInData" :flyCenter="flyCenter" :trajectoryId="trajectoryId" :trajectoryIdRandom="trajectoryIdRandom" :rangePhone="rangePhone" :rangePhoneRandom="rangePhoneRandom"></Map>
<Map v-if="mapShow" :currentStreet="currentStreet" :listUpdate="listUpdate" @addClockInPoint="addClockInPoint" :listQuery="listQuery" @lookClockInData="lookClockInData" @editClockInData="editClockInData" :flyCenter="flyCenter" :trajectory="trajectory" :trajectoryIdRandom="trajectoryIdRandom" :rangePhone="rangePhone" :rangePhoneRandom="rangePhoneRandom"></Map>
</div>
</div>
@ -169,11 +194,13 @@
import { getMethodCommon, postMethodCommon } from '../../../api/common';
import Map from './widget/ditu.vue';
import clockInDia from './widget/clockIn.vue';
import userlist from './widget/userlist.vue';
export default {
components:{
Map,
clockInDia
clockInDia,
userlist
},
data(){
return {
@ -196,7 +223,7 @@ export default {
lat:null,
},
flyCenter:null,
trajectoryId:null,
trajectory:null,
trajectoryIdRandom:1,
rangePhone:null,
rangePhoneRandom:1,
@ -205,17 +232,31 @@ export default {
orgId:null,
cascaderProps:{label:'name',value:'id',children:'child',checkStrictly: true},
listUpdate:1,
clockInList:[
],
clockInList:[],
tabActive:1,
cardDetailShow:false,
currentStreet:"费县",
onlineuserlistshow:false,
mapShow:false,
beginAndEndTime:[new Date(),new Date()],
}
},
created(){
let start = new Date();
let end = new Date(start.getTime()-1000*60*60*24*7)
this.beginAndEndTime = [end.getFullYear()+"-"+(end.getMonth()+1)+"-"+end.getDate()+" "+end.getHours()+":"+end.getMinutes()+":"+end.getSeconds(),start.getFullYear()+"-"+(start.getMonth()+1)+"-"+start.getDate()+" "+start.getHours()+":"+start.getMinutes()+":"+start.getSeconds()]
this.getTaskList();
this.gethlyList();
},
},
methods:{
timeChange(e){
this.getRouteList();
},
//
getClockInList(pointid){
getMethodCommon("/FireGrid/GetCheckInfoByPointId?pageIndex=1&pageSize=999&pointid="+pointid).then(res=>{
@ -227,6 +268,9 @@ export default {
toStatic(){
this.$router.push({'path':'/gridman_statistics'})
},
toRealTime(){
this.$router.push({'path':'/gridman_realtime'})
},
//
lookClockInData(val){
this.lookClockInfo(val);
@ -242,6 +286,10 @@ export default {
getMethodCommon("/FireGrid/LoadUsersArea").then(res =>{
this.orgs = res.data;
this.handleOrgs();
if(this.orgs[0].child.length == 1){
this.currentStreet = this.orgs[0].child[0].name;
}
this.mapShow = true;
})
},
handleOrgs(orgs){
@ -256,9 +304,8 @@ export default {
}
},
getTrajectoryData(id){
this.trajectoryId = id;
getTrajectoryData(item){
this.trajectory = item;
this.trajectoryIdRandom = Math.random();
},
getRange(phone){
@ -288,10 +335,12 @@ export default {
this.currentClockInfo.phones = item.userinfo && item.userinfo.split(",")
this.currentClockInfo.users = item.usernames && item.usernames.split(",")
this.currentRouters = [];
this.currentClockInfo.phones.forEach((item,index)=>{
this.getRouteList(item);
})
// this.currentClockInfo.phones.forEach((item,index)=>{
// this.getRouteList(item);
// })
this.getRouteList(item.userid);
this.getClockInList(this.currentClockInfo.id);
this.cardDetailShow = true;
},
getTaskList(){
getMethodCommon("/FireGrid/GetCheckPoint",this.listQuery).then(res=>{
@ -299,7 +348,7 @@ export default {
this.tasklist = res.data;
if(this.tasklist.length>0){
this.currentClockInfo = this.tasklist[0];
this.lookClockInfo(this.currentClockInfo);
// this.lookClockInfo(this.currentClockInfo);
this.flyCenter = [this.currentClockInfo.lng,this.currentClockInfo.lat];
this.currentClockInfo.phones = this.currentClockInfo.userinfo && this.currentClockInfo.userinfo.split(",")
this.currentClockInfo.users = this.currentClockInfo.usernames && this.currentClockInfo.usernames.split(",")
@ -308,22 +357,17 @@ export default {
}
})
},
getRouteList(phone){
getRouteList(userid){
let query = {
phone:phone,
pageIndex:1,
pageSize:9999
userId:this.currentClockInfo.userid,
beginTime:this.beginAndEndTime[0],
endTime:this.beginAndEndTime[1],
}
postMethodCommon("/Patrol/LoadPatrolInfoByPhone?pageIndex=1&pageSize=999&phone="+phone).then(res=>{
getMethodCommon("/Patrol/LoadPatrolInfoByUserIdNew",query).then(res=>{
if(res.code == 200){
res.data.forEach((item,index)=>{
item.phone = phone;
this.currentRouters.push(item);
})
this.currentRouters = res.data;
}
})
console.log("currentClockInfo",this.currentClockInfo);
},
resetListQuery(){
this.listQuery.areaId= null;
@ -362,7 +406,6 @@ export default {
width:100%;
height: calc(100vh - 100px);
padding:15px;
position:relative;
}
.sum-button{
@ -372,12 +415,12 @@ export default {
}
.left-content{
width:30%;
width:42%;
height:100%;
background:#272d39;
float:left;
border-right:1px solid #636262;
position:relative;
}
.filter-container{
width:100%;
@ -433,11 +476,32 @@ export default {
margin-top:10px;
}
.right-content{
width: calc(40% - 1px);
width: calc(58% - 1px);
height:100%;
float:right;
}
.online-user-list-container{
width:400px;
height:100px;
overflow: hidden;
position:absolute;
bottom:15px;
right:15px;
z-index:10000;
}
.operation-button{
width:80px;
height:40px;
position:absolute;
top:0px;
right:0px;
color:#999;
text-align: center;
line-height:40px;
cursor:pointer;
}
.addform-container{
width:500px;
height:400px;
@ -453,13 +517,15 @@ export default {
margin-bottom:15px;
}
.item-container{
width:30%;
width:100%;
height: 100%;
float:left;
background:#272d39;
padding:15px;
margin:0px 0px;
padding:30px;
border-right:1px solid #636262;
position:absolute;
top:0px;
left:0px;
}
.item-container-left{
@ -470,12 +536,14 @@ export default {
width:100%;
margin:0px 0px;
padding:0px;
position:relative;
}
.users-container{
width:100%;
padding-right:15px;
height: calc(100vh - 350px);
height: calc(100vh - 440px);
overflow-y:auto;
margin-top:15px;
}
.clockIn-box{
width:100%;
@ -623,4 +691,18 @@ export default {
background: rgba(0, 9, 34, 0.9);
}
::v-deep .el-input__inner {
background: none;
color: #fff;
border-radius: 0px !important;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
::v-deep .el-button{
border-radius:0px;
}
</style>

View File

@ -1,9 +1,11 @@
<template>
<div style="width:100%;padding:10px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="paramForm" :rules="rules" label-width="140px" class="clockIn">
<el-form-item label="打卡点名称" prop="address">
<el-input v-model="paramForm.address" ></el-input>
</el-form-item>
<el-form-item label="行政区划" prop="user">
<el-cascader
v-model="orgId"
@ -18,6 +20,8 @@
<treeselect :options="hlyList" :normalizer="normalizer" v-model="paramForm.user" :multiple="true" :disable-branch-nodes="true" placeholder="请选择责任人">
</treeselect>
</el-form-item>
<el-form-item style="margin-top: 16%;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="submitForm('form')"></el-button>
@ -177,7 +181,6 @@ export default {
}
})
}
} else {
console.log('error submit!!');
return false;
@ -191,6 +194,7 @@ export default {
}
</script>
<style scoped>
::v-deep .el-form-item__label {
color: #fff;
}
@ -206,4 +210,9 @@ export default {
color: #fff;
height: 36px;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
</style>

View File

@ -8,10 +8,11 @@ import mapboxgl from "mapbox-gl";
import { waiData } from "../../../../assets/xianjiewai";
import * as turf from '@turf/turf';
import { parse } from '../../../home/lib/handleGeojson.js'
import axios from "axios";
mapboxgl.accessToken = "pk.eyJ1Ijoic2hpY2hhbzEyMyIsImEiOiJja3FobnI1aDEwNGF6Mm9vOXVhNnBzZmFhIn0.2fZKiMqCQHxVY74QShMEGQ";
export default {
props: ["rowkey", "lnglat", "flyCenter","trajectoryId","trajectoryIdRandom","rangePhone","rangePhoneRandom","listQuery","listUpdate"],
props: ["rowkey", "lnglat", "flyCenter","trajectory","trajectoryIdRandom","rangePhone","rangePhoneRandom","listQuery","listUpdate","currentStreet"],
data() {
return {
map: null,
@ -49,6 +50,8 @@ export default {
editFeature:null,
saveEditPopup:null,
saveInfo:{},
maskingData:[],
streetGeoJson:{},
};
},
watch: {
@ -91,19 +94,129 @@ export default {
}
},
created(){
//
this.geoStreetData();
window.addMapTask = this.addMapTask;
window.editPosition = this.editPosition;
window.editClockInData = this.editClockInData;
window.lookClockInData = this.lookClockInData;
window.saveEditPositon = this.saveEditPositon;
window.calcleEditPosition = this.calcleEditPosition;
},
mounted() {
this.$nextTick(function () {
this.initMap();
});
let _this = this;
setTimeout(function(){
_this.getTrajectoryData();
},5000);
},
destroyed(){
this.map.remove();
this.map = null;
},
methods: {
getOnlineUserList(){ // 线
getMethodCommon("/FireManagement/GetPointByUserType?pageIndex=1&pageSize=12&type=2").then(res=>{
if(res.code == 200){
let geojson = this.handleOnlineUserGeoJson(res.data);
console.log("geojson",geojson);
this.addAndUpdateOnlineUserData(geojson);
}
})
},
handleOnlineUserGeoJson(data){ // 线GeoJson
let geojson = {
"type": "FeatureCollection",
"features": [],
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::4326"
}
}
}
data.forEach((item,index)=>{
let obj = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [parseFloat(item.lng), parseFloat(item.lat)]
},
"properties": item
}
geojson.features.push(obj);
})
return geojson
},
addAndUpdateOnlineUserData(geojson){ //
if(this.map.getSource("onlineuserSource")){ // ResourceData
this.map.getSource("onlineuserSource").setData(geojson);
}else{ //
// Source
this.map.addSource("onlineuserSource",{
type:"geojson",
data:geojson
})
// Image
let _this = this;
this.map.loadImage("/img/gridman/onlineuser-in.png",
function (error, image) {
if (error) throw error;
_this.map.addImage("onlineuserImage", image);
}
);
// Layer
this.map.addLayer({
id: "onlineuserLayer",
type: "symbol",
source: "onlineuserSource",
layout: {
"icon-image": "onlineuserImage", //
"icon-size": 0.6, //
"text-field":"{name}",
"text-offset":[0,-2.5],
"text-size":12,
"visibility":"visible"
},
paint:{
"text-color":"#fff"
}
});
}
},
geoStreetData(){ //
let filter_options = this.currentStreet != '费县' ? "&cql_filter=xzqmc%20like%20%27%25"+this.currentStreet+"%25%27" : ''
let url = "";
if(this.currentStreet == '费县'){
url = "http://175.27.168.120:8080/geoserver/feixian/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=feixian%3Axianjie&maxFeatures=50&outputFormat=application%2Fjson"
} else{
url = "http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ashp_1691822212"+filter_options+"&maxFeatures=50&outputFormat=application%2Fjson"
}
axios({
method:"get",
url:url
}).then(res=>{
let geojson = res.data;
this.streetGeoJson = geojson;
//
this.$nextTick(function () {
this.initMap(this.getPolygonCenter(geojson));
});
this.maskingData = this.getMaskingData(geojson);
})
},
getPolygonCenter(geojson){ // 使turf
var polygon = turf.polygon(geojson.features[0].geometry.coordinates[0]);
var centerLnglat = turf.centroid(polygon);
return centerLnglat.geometry.coordinates;
},
getMaskingData(geojson){ // geojson
return geojson.features[0].geometry.coordinates[0][0];
},
editClockInData(){
this.$emit("editClockInData",this.properties)
@ -359,13 +472,13 @@ export default {
});
},
initMap(url, jwd) {
initMap(center) {
let _this = this;
this.map = new mapboxgl.Map({
container: this.$refs.datamap,
style: "mapbox://styles/shichao123/clf3b1bxk007801moo0nnl87k",
// style:"mapbox://styles/mapbox/streets-v10",
center: [117.977325, 35.265961],
center: center,
zoom: 10,
language: "zh-cmn",
projection: "globe",
@ -373,8 +486,11 @@ export default {
this.map.on("load", () => {
this.loadGaoQingLayer();
this.loadMengban();
this.loadZhenJieLayer();
this.loadXianJieLayer();
// this.loadZhenJieLayer();
this.loadZhenJieGeoJsonLayer();
// this.loadXianJieLayer();
this.loadAllRangeLayer();
//
@ -455,7 +571,7 @@ export default {
[180, -90],
[-180, -90],
],
waiData.DATA,
this.maskingData,
],
},
},
@ -540,7 +656,24 @@ export default {
},
});
},
loadZhenJieGeoJsonLayer(geojson){
// Source
this.map.addSource("zhenjieSource",{
type:"geojson",
data:this.streetGeoJson
})
//
this.map.addLayer({
id: "zhenjieLayer",
type: "line",
source: "zhenjieSource",
layout: {},
paint: {
"line-width": 2,
"line-color": "orange",
},
});
},
loadClockInLayer(){
// Source Source
if(this.map.getSource("clockInSource")){
@ -582,36 +715,88 @@ export default {
},
getTrajectoryData(){
getMethodCommon("/Patrol/LoadPatrolInfoById?id="+this.trajectoryId).then(res=>{
console.log("trajectory",this.trajectory);
let query = {
userId:this.trajectory.createId,
// userId:"606ab0ad-4489-45dc-b8bb-69a25a73448b",
beginTime:this.trajectory.startTime,
endTime:this.trajectory.endTime
}
getMethodCommon("/Patrol/LoadPatrolPointByTime",query).then(res=>{
if(res.code == 200){
let data = res.data;
this.startPoint = [data[0].lng,data[0].lat];
this.endPoint = [data[data.length-1].lng,data[data.length-1].lat];
this.loadStartAndEndPoint();
this.trajectoryLayerGeoJson.features[0].geometry.coordinates[0] = [];
data.forEach((item,index)=>{
if(parseFloat(item.lng)){
this.trajectoryLayerGeoJson.features[0].geometry.coordinates[0].push([parseFloat(item.lng),parseFloat(item.lat)]);
}
})
this.loadTrajectoryLayer();
//
//
let turfStartPoint = turf.point(this.startPoint);
let turfEndPoint = turf.point(this.endPoint);
let center = turf.midpoint(turfStartPoint, turfEndPoint);
this.trajectoryLayerCenter = center.geometry.coordinates;
this.map.flyTo({
center: this.trajectoryLayerCenter, //
zoom: 18, //
curve: 1,
});
this.trajectoryLayerGeoJson = this.handleRouterData(data)
this.loadTrajectoryLayer(this.trajectoryLayerGeoJson);
}
})
},
handleRouterData(data){ // 线
let geojson = {
"type": "FeatureCollection",
"features": [],
"crs": {
"type": "name",
"properties": {
}
}
};
let der = 0;
let feature = {
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": [[]]
},
"properties": {
"id": 1,
"creater_id": 1
}
}
data.forEach((item,index)=>{
if(index == 0){
der = item.intype;
feature = {
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": [[]]
},
"properties": {
"intype":item.intype
}
}
}
if(der == item.intype){
feature.geometry.coordinates[0].push([parseFloat(item.lng),parseFloat(item.lat)]);
}else{
geojson.features.push(feature);
feature = {
"type": "Feature",
"geometry": {
"type": "MultiLineString",
"coordinates": [[
[parseFloat(data[index-1].lng),parseFloat(data[index-1].lat)]
]]
},
"properties": {
"intype":item.intype
}
}
der = item.intype;
}
if(geojson.features.length == 0 && feature.geometry.coordinates[0].length>0){
geojson.features.push(feature);
}
})
return geojson
},
getRangeData(e){
getMethodCommon("/FireGrid/GetUserRange?phone="+this.rangePhone).then(res=>{
if(res.code == 200){
@ -681,13 +866,11 @@ export default {
//
this.map.getSource("trajectorySource").setData(this.trajectoryLayerGeoJson);
}else{
// Source
this.map.addSource("trajectorySource",{
type:"geojson",
data:this.trajectoryLayerGeoJson
})
// Layer
this.map.addLayer({
id: "trajectoryLayer",
@ -698,71 +881,91 @@ export default {
source:"trajectorySource",
paint: {
"line-width": 2,
"line-color": "orange",
// "line-color": "orange",
'line-color':[
"case",
["==",["get","intype"],0],
"#ff0000",
["==",["get","intype"],1],
"#00ff00",
//
"#67C23A",
],
},
})
}
},
loadAllRangeLayer(){
if(this.map.getSource("allRangeSource")){
loadAllRangeLayer(){ //
let filter_options = this.currentStreet != '费县' ? "&cql_filter=xzq%20like%20%27%25"+this.currentStreet+"%25%27" : ''
let url = "";
if(this.currentStreet != '费县'){
url = "http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ahulinyuanguanhufanwei"+filter_options+"&maxFeatures=5000&outputFormat=application%2Fjson";
}else{
this.map.addSource("allRangeSource",{
type: "vector",
scheme: "tms", //new
tiles: [
"http://221.2.83.254:9007"+
"/geoserver/gwc/service/tms/1.0.0/ksp%3A" +
"hulinyuanguanhufanwei" +
"@EPSG:900913@pbf/{z}/{x}/{y}.pbf",
],
})
this.map.addLayer({
id: "allRangeLayerFill",
type: "fill",
source: "allRangeSource",
"source-layer": "hulinyuanguanhufanwei",
layout: {
},
paint: {
"fill-color": "#7CD00F",
"fill-opacity": 0.3,
},
})
this.map.addLayer({
id: "allRangeLayerLine",
type: "line",
source: "allRangeSource",
"source-layer": "hulinyuanguanhufanwei",
layout: {
},
paint: {
"line-color": "#F4CC39",
"line-width": 1,
},
})
this.map.addLayer({
id: "allRangeLayerName",
type: "symbol",
source: "allRangeSource",
"source-layer": "hulinyuanguanhufanwei",
layout: {
"text-field": "{hulinyuan}",
"text-size": 12,
},
paint: {
"text-color": "#000000", // #000000
"text-halo-color": "#FFFFFF",
"text-halo-width": 1,
},
})
url = "http://221.2.83.254:9007/geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=ksp%3Ahulinyuanguanhufanwei&maxFeatures=50000&outputFormat=application%2Fjson";
}
axios({
method:"get",
url:url
}).then(res=>{
let geojson = res.data;
if(this.map.getSource("allRangeSource")){
}else{
this.map.addSource("allRangeSource",{
type:"geojson",
data:geojson
// type: "vector",
// scheme: "tms", //new
// tiles: ["http://221.2.83.254:9007"+"/geoserver/gwc/service/tms/1.0.0/ksp%3A" +"hulinyuanguanhufanwei" +"@EPSG:900913@pbf/{z}/{x}/{y}.pbf"],
})
this.map.addLayer({
id: "allRangeLayerFill",
type: "fill",
source: "allRangeSource",
// "source-layer": "hulinyuanguanhufanwei",
layout: {
},
paint: {
"fill-color": "#7CD00F",
"fill-opacity": 0.3,
},
})
this.map.addLayer({
id: "allRangeLayerLine",
type: "line",
source: "allRangeSource",
// "source-layer": "hulinyuanguanhufanwei",
layout: {
},
paint: {
"line-color": "#F4CC39",
"line-width": 1,
},
})
this.map.addLayer({
id: "allRangeLayerName",
type: "symbol",
source: "allRangeSource",
// "source-layer": "hulinyuanguanhufanwei",
layout: {
"text-field": "{hulinyuan}",
"text-size": 12,
},
paint: {
"text-color": "#000000", // #000000
"text-halo-color": "#FFFFFF",
"text-halo-width": 1,
},
})
}
})
}
},
};

View File

@ -0,0 +1,173 @@
<template>
<div class='userlist-container'>
<div class="all-count">
<div class="online-user-count">
在线人数 <span style="font-size:24px;color:#108eff;margin-left:12px;">{{userlist.length}}</span>
</div>
<div class="online-user-count">
离线人数 <span style="font-size:24px;color:#108eff;margin-left:12px;">876</span>
</div>
</div>
<div class="table-header">
<div>在线人员</div>
<div>电话</div>
<div>状态</div>
<div>时间</div>
</div>
<div class="user-list-content">
<div class="user-item" v-for="(item,index) in userlist" :key="index">
<div>{{item.name}}</div>
<div>{{item.phone}}</div>
<div><span style="color:greenyellow;font-weight: 1000;font-size:14px;">·</span> 在线</div>
<div style="color:#F3A600;">32分钟</div>
</div>
</div>
</div>
</template>
<script>
import { getMethodCommon } from '../../../../api/common';
export default {
components: {},
data() {
return {
userlist:[]
};
},
computed: {},
watch: {},
methods: {
getOnlineUserList(){ // 线
getMethodCommon("/FireManagement/GetPointByUserType?pageIndex=1&pageSize=12&type=2").then(res=>{
if(res.code == 200){
this.userlist = res.data;
}
})
},
},
created() {
},
mounted() {
this.getOnlineUserList();
},
destroyed() {
},
}
</script>
<style scoped>
.userlist-container{
width:100%;
height:100%;
background:#272d39;
}
.all-count{
width:100%;
padding:40px 20px;
padding-bottom:60px;
background:#1d222b;
color:#eee;
}
.all-count div{
width:140px;
height:32px;
line-height:32px;
border-left:2px solid #409eff;
float:left;
margin-right:40px;
text-indent: 20px;
box-shadow: 0px 0px 5px #1d222b;
}
.table-header{
width:100%;
height:40px;
background:#272d39;
display: flex;
flex-direction:row;
margin:12px 0px;
}
.table-header div{
flex:1;
text-align: center;
line-height:40px;
}
.user-list-content {
width:100%;
height: calc(100% - 185px);
overflow-y: auto;
padding:0px 10px;
}
.user-list-content .user-item{
width:100%;
height:60px;
background:#1d222b;
display: flex;
flex-direction:row;
margin:6px 0px;
position: relative;
}
.user-list-content .user-item::after{
content:"";
position:absolute;
bottom:0px;
right:0px;
border-left:8px solid #1d222b;
border-top:8px solid #1d222b;
border-right:8px solid #409eff;
border-bottom:8px solid #409eff;
width:0px;
height:0px;
}
.user-list-content .user-item div{
flex:1;
text-align: center;
line-height:60px;
color:#fff;
font-size:12px;
}
::-webkit-scrollbar {
height: 10px;
width: 10px;
background: transparent;
border-radius: 5px;
}
::-webkit-scrollbar-thumb {
padding-top: 100px;
-webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1),
inset -1px -1px 0 rgba(0, 0, 0, 0.07);
background-color: rgba(0,0,0,0.2);
min-height: 28px;
border-radius: 4px;
background-clip: padding-box;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
border: 0;
}
::-webkit-scrollbar-thumb:hover {
-webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25);
background-color: rgba(0, 0, 0, 0.4);
}
::-webkit-scrollbar-thumb:active {
-webkit-box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.35);
background-color: rgba(0, 0, 0, 0.5);
}
</style>

View File

@ -1,19 +1,19 @@
<template>
<div style="width:100%;height:40vh;padding:0px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="addForm" :rules="rules" label-width="140px">
<el-form-item label="姓名: " prop="name">
<el-input v-model="addForm.name" style="width:300px ;"></el-input>
<div style="width:100%;min-height:40vh;padding:10px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="addForm" :rules="rules" label-width="120px">
<el-form-item label="人员姓名: " prop="name">
<el-input v-model="addForm.name" style="width:100%;"></el-input>
</el-form-item>
<el-form-item label="账号: " prop="account">
<el-input v-model="addForm.account" style="width:300px ;"></el-input>
<el-form-item label="账号/手机号: " prop="account">
<el-input v-model="addForm.account" style="width:100%;"></el-input>
</el-form-item>
<!-- <el-form-item label="单位名称: " prop="unitName">
<el-input v-model="addForm.unitName" style="width:300px ;"></el-input>
</el-form-item> -->
<el-form-item label="性别: " prop="sex">
<el-form-item label="人员性别: " prop="sex">
<el-radio-group v-model="addForm.sex">
<el-radio :label="0"></el-radio>
<el-radio :label="1"></el-radio>
@ -28,13 +28,34 @@
</el-form-item> -->
<el-form-item :label="'所属'">
<el-form-item :label="'所属机构'">
<treeselect :options="orgsTree" :default-expand-level="3" :multiple="true" :flat="true" :open-on-click="true"
:open-on-focus="true" :clear-on-select="true" v-model="selectOrgs" style="z-index: 2026;">
</treeselect>
</el-form-item>
<el-form-item style="margin-top: 16%;">
<el-form-item label="打卡时间" prop="time">
<p v-for="(item,index) in timeslot" :key="index" style="position:relative;">
<el-time-picker
is-range
v-model="timeslot[index]"
range-separator="-"
value-format="HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
style="width:100%;margin-bottom:5px;"
size="mini"
@change="timeslotChange"
>
</el-time-picker>
<i class="el-icon el-icon-circle-close remove-timesolt" @click="remvoeTime(index)"></i>
</p>
<el-button type="primary" round icon="el-icon-plus" @click="addTimeSlot"></el-button>
</el-form-item>
<el-form-item style="margin-top: 0px;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="submitForm('form')" v-if="detailInfo.length == 0"></el-button>
<el-button type="primary" @click="createForm('form')" v-else></el-button>
@ -67,6 +88,7 @@
password:null,
identity:0,
unitName:null,
timeSlot:[],
},
rules: {
name: [
@ -84,6 +106,7 @@
orgsTree: [], // 访
selectRoles: [], //
selectRoleNames: '',
timeslot:[],
}
},
created() {
@ -125,6 +148,15 @@
})
},
methods: {
timeslotChange(e){
console.log(e);
},
remvoeTime(index){
this.timeslot.splice(index,1);
},
addTimeSlot(){
this.timeslot.push(["",""]);
},
getDetail() {
getMethodCommon("/FireCodeApp/GetForestryUserById?id=" + this.detailInfo[0].Id, {}).then(res => {
if (res.code == 200) {
@ -135,6 +167,7 @@
this.addForm.sex = detail.Sex;
this.addForm.userRole = detail.UserRole;
this.addForm.areaId = detail.areaId;
// if(this.addForm.areaId){
// var areaId = this.addForm.areaId.split(',')
// this.addForm.areaId = turnNum(areaId)
@ -167,9 +200,14 @@
_this.addForm.password = _this.addForm.account;
//
//
this.addForm.timeSlot = [];
this.timeslot.forEach((item,index)=>{
if(item[0] != "" && item[1] != ""){
this.addForm.timeSlot.push({timeSlot:item[0]+"-"+item[1]});
}
})
postMethodCommon("/FireCodeApp/Register", _this.addForm).then(response => {
if (response.code == 200) {
// shp
@ -235,4 +273,26 @@
text-align: center;
margin-top: 100px;
}
::v-deep .el-input__inner {
background: rgba(0, 9, 34, 1);
color: #fff;
height: 36px;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
.remove-timesolt{
margin-left:12px;font-size:22px;margin-top:0px;
position:absolute;
right:-32px;
top:8px;
}
.remove-timesolt:hover{
cursor:pointer;
color:#fff;
}
</style>

View File

@ -1,11 +1,11 @@
<template>
<div style="width:100%;height:40vh;padding:0px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="addForm" :rules="rules" label-width="140px" v-if="formRandom">
<el-form-item label="姓名: " prop="name">
<div style="width:100%;min-height:40vh;padding:20px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="addForm" :rules="rules" label-width="100px" v-if="formRandom">
<el-form-item label="人员姓名: " prop="name">
<el-input v-model="addForm.name" style="width:300px ;"></el-input>
</el-form-item>
<el-form-item label="账号: " prop="account">
<el-form-item label="账号/手机: " prop="account">
<el-input v-model="addForm.account" style="width:300px ;"></el-input>
</el-form-item>
@ -13,7 +13,7 @@
<el-input v-model="addForm.unitName" style="width:300px ;"></el-input>
</el-form-item> -->
<el-form-item label="性别: " prop="sex">
<el-form-item label="人员性别: " prop="sex">
<el-radio-group v-model="addForm.sex">
<el-radio :label="0"></el-radio>
<el-radio :label="1"></el-radio>
@ -28,13 +28,33 @@
</el-form-item> -->
<el-form-item :label="'所属'">
<el-form-item :label="'所属机构'">
<treeselect :options="orgsTree" :default-expand-level="1" :multiple="true" :flat="true" :open-on-click="true"
:open-on-focus="true" :clear-on-select="true" v-model="selectOrgs" style="z-index: 2026;">
</treeselect>
</el-form-item>
<el-form-item label="打卡时间" prop="time">
<p v-for="(item,index) in timeslot" :key="index" style="position:relative;">
<el-time-picker
is-range
v-model="timeslot[index]"
range-separator="-"
value-format="HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
style="width:100%;margin-bottom:5px;"
size="mini"
@change="timeslotChange"
>
</el-time-picker>
<i class="el-icon el-icon-circle-close remove-timesolt" @click="remvoeTime(index)"></i>
</p>
<el-button type="primary" round icon="el-icon-plus" @click="addTimeSlot"></el-button>
</el-form-item>
<el-form-item style="margin-top: 16%;">
<el-form-item style="margin-top: 0px;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="submitForm('form')" >保存</el-button>
</el-form-item>
@ -83,6 +103,7 @@
selectRoles: [], //
selectRoleNames: '',
formRandom:false,
timeslot:[]
}
},
created() {
@ -118,6 +139,15 @@
})
},
methods: {
timeslotChange(e){
console.log(e);
},
remvoeTime(index){
this.timeslot.splice(index,1);
},
addTimeSlot(){
this.timeslot.push(["",""]);
},
getDetail() {
getMethodCommon("/FireCodeApp/GetForestryUserById?id=" + this.detailInfo.Id).then(res => {
@ -138,6 +168,11 @@
throw new Error("用户绑定的组织id错误");
}
this.formRandom = true;
detail.stlt.forEach((item,index)=>{
this.timeslot[index] = item.timeSlot.split("-");
console.log("this.timeslot[index]",this.timeslot[index]);
})
}
}catch(e){
throw e
@ -166,6 +201,12 @@
this.$refs['form'].validate((valid) => {
if (valid) {
//
this.addForm.timeSlot = [];
this.timeslot.forEach((item,index)=>{
if(item[0] != "" && item[1] != ""){
this.addForm.timeSlot.push({timeSlot:item[0]+"-"+item[1]});
}
})
postMethodCommon("/FireCodeApp/EditForestryUser", _this.addForm).then(response => {
if (response.code == 200) {
// shp
@ -230,4 +271,26 @@
text-align: center;
margin-top: 100px;
}
::v-deep .el-input__inner {
background: rgba(0, 9, 34, 1);
color: #fff;
height: 36px;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
.remove-timesolt{
margin-left:12px;font-size:22px;margin-top:0px;
position:absolute;
right:-32px;
top:8px;
}
.remove-timesolt:hover{
cursor:pointer;
color:#fff;
}
</style>

View File

@ -27,10 +27,13 @@
},
backPath() {
this.title = '网格化管理'
if (this.$route.path != '/gridman_navigation') {
this.$router.push({ 'path': '/gridman' })
if (this.$route.path == '/gridman_navigation') {
this.$router.push({ 'path': '/navigation' })
}else if(this.$route.path == "/gridman_statistics" || this.$route.path == "/gridman_realtime"){
this.$router.push({ 'path': '/gridman_forestranger' })
} else {
this.$router.push({ 'path': '/index' })
this.$router.push({ 'path': '/gridman_navigation' })
}
}
}

View File

@ -0,0 +1,782 @@
<template>
<div class="clockin-content">
<div class="left-content">
<!-- 筛选条件 -->
<div class="filter-container">
<el-cascader
v-model="areaId"
:options="orgs"
size="mini"
style="width:160px;margin-right:15px;"
:props="cascaderProps"
placeholder="请选择行政区划"
@change="handleChange">
</el-cascader>
<el-select v-model="listQuery.isonline" @change="stateChange" placeholder="请选择在线状态" size="mini" style="width:160px;margin-right:15px;">
<el-option
v-for="item in stateOptions"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
<!-- <el-button type="default" size="mini" @click="resetListQuery" icon="el-icon-refresh-left">重置</el-button> -->
<el-button type="primary" size="mini" icon="el-icon-search" @click="getOnlineUserList()"></el-button>
</div>
<!-- 列表 -->
<div style="height:calc(100% - 150px)">
<div class='userlist-container'>
<div class="all-count">
<div class="online-user-count">
在线人数 <span style="font-size:24px;color:#108eff;margin-left:12px;">{{onlineInfo.online}}</span>
</div>
<div class="online-user-count">
离线人数 <span style="font-size:24px;color:#108eff;margin-left:12px;">{{onlineInfo.offline}}</span>
</div>
</div>
<div class="table-header">
<div>乡镇/村庄</div>
<div>护林员姓名</div>
<div>在线状态</div>
<div>离线时长</div>
<div style="flex:2;">操作</div>
</div>
<div class="user-list-content">
<div class="user-item" v-for="(item,index) in userlist" :key="index">
<div>{{item.townName}}</div>
<div>{{item.name}}</div>
<div>
<span v-if="item.state == '在线'">
<span style="background-color:greenyellow;font-weight: 1000;font-size:14px;display: inline-block;width:10px;height:10px;border-radius: 50%;"></span>&nbsp;在线
</span>
<span v-else>
<span style="background-color:#f74d0a;font-weight: 1000;font-size:14px;display: inline-block;width:10px;height:10px;border-radius: 50%;"></span>&nbsp;离线
</span>
</div>
<div v-if="item.onLineTime == '0分钟前'">-&nbsp;-</div>
<div style="color:#F3A600;" v-else>{{item.onLineTime}}</div>
<div style="flex:2;">
<el-button type="primary" icon="el-icon-location-outline" size="mini" @click="toPosition(item)"></el-button>
<el-button type="primary" icon="el-icon-position" size="mini" @click="toTrajectory(item)"></el-button>
</div>
</div>
</div>
<div class="page-container">
<el-pagination
size="mini"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="listQuery.page"
:page-size="listQuery.limit"
:page-sizes="[10, 20, 30, 50,100,200,500]"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</div>
<!-- <userlist @toTrajectory="toTrajectory" @toPosition="toPosition"></userlist> -->
</div>
<!-- 分页 -->
</div>
<div class="right-content">
<div class="map-container">
<Map v-if="mapShow" :routerLine="routerLine" :currentStreet="currentStreet" :lnglat="lnglat" :listUpdate="listUpdate" @addClockInPoint="addClockInPoint" :listQuery="listQuery" @lookClockInData="lookClockInData" @editClockInData="editClockInData" :flyCenter="flyCenter" :trajectory="trajectory" :trajectoryIdRandom="trajectoryIdRandom" :rangePhone="rangePhone" :rangePhoneRandom="rangePhoneRandom"></Map>
</div>
</div>
</div>
</template>
<script>
import { getMethodCommon, postMethodCommon } from '../../../api/common';
import Map from './widget/ditu.vue';
import clockInDia from './widget/clockIn.vue';
import { Main } from 'element-ui';
import { standardDeviationalEllipse } from '@turf/turf';
// import userlist from './widget/userlist.vue';
// import md5 from 'js-md5';
// alert(md5("fx13280580815").toUpperCase())
export default {
components:{
Map,
// userlist
},
data(){
return {
onlineInfo:{},
userlist:[],
listQuery:{
"page": 1,
"limit": 500,
"townname": "",
"isonline": "全部"
},
total:0,
clockInVisible:false,
detailInfo:{},
areaId:null,
tasklist:[],
clockDetail:{},
clocklnglat:null,
currentClockInfo:{
lng:null,
lat:null,
},
flyCenter:null,
trajectory:null,
trajectoryIdRandom:1,
rangePhone:null,
rangePhoneRandom:1,
currentRouters:[],
orgs:[],
orgId:null,
cascaderProps:{label:'name',value:'id',children:'child',checkStrictly: true},
listUpdate:1,
clockInList:[
],
tabActive:1,
cardDetailShow:false,
currentStreet:"费县",
onlineuserlistshow:false,
mapShow:false,
beginAndEndTime:[new Date(),new Date()],
lnglat:null,
routerLine:null,
stateOptions:[
{
label:"全部",
value:"全部"
},{
label:"在线",
value:"在线"
},{
label:"离线",
value:"离线"
}
],
userTimer:null,
}
},
created(){
let start = new Date();
let end = new Date(start.getTime()-1000*60*60*24)
this.beginAndEndTime = [end.getFullYear()+"-"+(end.getMonth()+1)+"-"+end.getDate()+" "+end.getHours()+":"+end.getMinutes()+":"+end.getSeconds(),start.getFullYear()+"-"+(start.getMonth()+1)+"-"+start.getDate()+" "+start.getHours()+":"+start.getMinutes()+":"+start.getSeconds()]
this.gethlyList();
if(this.userTimer){
clearInterval(this.userTimer)
}
let _this = this;
this.userTimer = setInterval(function(){
_this.getOnlineUserList();
},5000);
},
methods:{
getOnlineUserList(){ // 线
postMethodCommon("/FireManagement/GetPointUserOnLine",this.listQuery).then(res=>{
if(res.code == 200){
this.userlist = res.data.userinfo;
this.userlist.forEach((item,index)=>{
this.userlist[index].onLineTime = this.friendlyDate(item.onLineTime);
})
this.onlineInfo = res.data;
this.total = this.onlineInfo.offline + this.onlineInfo.online;
}
})
},
friendlyDate(time){
if(time>60){
return Math.ceil(time/60)+"小时前"
}else{
return time+"分钟前"
}
},
handleSizeChange(e){
this.listQuery.limit = e;
this.getOnlineUserList();
},
handleCurrentChange(e){
this.listQuery.page = e;
this.getOnlineUserList();
},
toPosition(lnglat){
this.lnglat = lnglat;
},
toTrajectory(userid){
this.userid = userid;
this.getRouteList(userid);
},
timeChange(e){
},
lookClockInData(val){
this.lookClockInfo(val);
},
editClockInData(val){
this.editClockInfo(val)
},
handleChange(e){
if(e.length>1){
this.listQuery.townname = e[1];
this.currentStreet = e[1];
}else if(e.length==1){
this.currentStreet = e[0];
this.listQuery.townname = "";
}
this.getOnlineUserList();
},
stateChange(e){
this.listQuery.isonline = e;
this.getOnlineUserList();
},
gethlyList(){ //
getMethodCommon("/FireGrid/LoadUsersArea").then(res =>{
this.orgs = res.data;
this.handleOrgs();
//
if(this.orgs[0].child.length == 1){
this.currentStreet = this.orgs[0].child[0].name;
this.listQuery.townname = this.currentStreet;
this.orgs[0].disabled = true;
this.areaId = ['费县',this.currentStreet]
}else{
this.currentStreet = this.orgs[0].name;
this.areaId = ['费县']
this.listQuery.townname = "";
}
// 线
this.getOnlineUserList();
//
this.mapShow = true;
})
},
handleOrgs(orgs){
for(let i=0;i<this.orgs[0].child.length;i++){
this.orgs[0].id = this.orgs[0].name
if(this.orgs[0].child[i]){
this.orgs[0].child[i].id = this.orgs[0].child[i].name
if(this.orgs[0].child[i].child){
this.orgs[0].child[i].child = null;
}
// for(let j=0;j<this.orgs[0].child[i].child.length;j++){
// }
}
}
},
getTrajectoryData(item){
this.trajectory = item;
this.trajectoryIdRandom = Math.random();
},
getRange(phone){
this.rangePhone = phone;
this.rangePhoneRandom = Math.random();
},
clockInSuccess(){
this.listUpdate = Math.random();
this.clockInVisible = false;
this.getTaskList();
},
addClockInPoint(e){
this.clocklnglat = e;
this.clockDetail = null;
this.clockInVisible = true;
},
addSuccess(){
},
editClockInfo(item){
this.clockDetail = item;
this.clockInVisible = true;
},
lookClockInfo(item){
this.currentClockInfo = item;
this.flyCenter = [this.currentClockInfo.lng,this.currentClockInfo.lat];
this.currentClockInfo.phones = item.userinfo && item.userinfo.split(",")
this.currentClockInfo.users = item.usernames && item.usernames.split(",")
this.currentRouters = [];
// this.currentClockInfo.phones.forEach((item,index)=>{
// this.getRouteList(item);
// })
// this.getRouteList(item.userid);
this.getClockInList(this.currentClockInfo.id);
this.cardDetailShow = true;
},
getTaskList(){
getMethodCommon("/FireGrid/GetCheckPoint",this.listQuery).then(res=>{
if(res.code == 200){
this.tasklist = res.data;
if(this.tasklist.length>0){
this.currentClockInfo = this.tasklist[0];
// this.lookClockInfo(this.currentClockInfo);
this.flyCenter = [this.currentClockInfo.lng,this.currentClockInfo.lat];
this.currentClockInfo.phones = this.currentClockInfo.userinfo && this.currentClockInfo.userinfo.split(",")
this.currentClockInfo.users = this.currentClockInfo.usernames && this.currentClockInfo.usernames.split(",")
}
this.total = res.count;
}
})
},
getRouteList(item){
let start = new Date();
let end = new Date(start.getTime())
let SAETime = [end.getFullYear()+"-"+(end.getMonth()+1)+"-"+end.getDate()+" 00:00:00",start.getFullYear()+"-"+(start.getMonth()+1)+"-"+start.getDate()+" "+start.getHours()+":"+start.getMinutes()+":"+start.getSeconds()]
let query = {
userId:item.createId,
// userId:"8099b685-2477-45e1-abfe-1a49ce6a4fc3",
beginTime:SAETime[0],
endTime:SAETime[1],
}
getMethodCommon("/Patrol/LoadPatrolPointByTime",query).then(res=>{
if(res.code == 200){
this.routerLine = res.data;
if(res.data.length==0){
this.$message({
type:"warning",
message:"暂无1小时内轨迹"
})
return null;
}
}
})
},
resetListQuery(){
this.listQuery.page = 1;
this.listQuery.limit = 50;
},
}
}
</script>
<style scoped>
.clockin-content{
width:100%;
height: calc(100vh - 70px);
padding:15px;
}
.sum-button{
position:absolute;
top:-30px;
left:280px;
}
.left-content{
width:42%;
height:100%;
background:#272d39;
float:left;
border-right:1px solid #636262;
position:relative;
}
.filter-container{
width:100%;
padding:20px 20px 30px 20px;
border-bottom:1px solid #636262;
}
.clock-item-container{
width: calc( 100% - 10px);
height: calc( 100% - 161px);
padding:0px 15px;
margin:15px 0px;
color:#efefef;
overflow: auto;
}
.clock-item{
width:100%;
height:150px;
margin:10px 0px;
padding:10px 15px;
background:rgba(0,0,0,0.25);
}
.clock-item-icon{
width:100px;
height:80px;
float:left;
}
.clock-item-icon img{
width:80px;
height:80px;
margin-top:6px;
}
.clock-item-info{
float:left;
width: calc( 100% - 100px);
height:100px;
line-height:18px;
font-size:12px;
}
.clock-item-info p{
margin-bottom:0px;
margin-top:10px;
}
.right-content{
width: calc(58% - 1px);
height:100%;
float:right;
}
.online-user-list-container{
width:400px;
height:100px;
overflow: hidden;
position:absolute;
bottom:15px;
right:15px;
z-index:10000;
}
.operation-button{
width:80px;
height:40px;
position:absolute;
top:0px;
right:0px;
color:#999;
text-align: center;
line-height:40px;
cursor:pointer;
}
.addform-container{
width:500px;
height:400px;
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%)
}
.map-container{
width:100%;
height: 100%;
background:#272d39;
margin-bottom:15px;
}
.item-container{
width:100%;
height: 100%;
float:left;
background:#272d39;
padding:30px;
border-right:1px solid #636262;
position:absolute;
top:0px;
left:0px;
}
.item-container-left{
width:100%;
}
.item-container-right{
width:100%;
margin:0px 0px;
padding:0px;
position:relative;
}
.users-container{
width:100%;
padding-right:15px;
height: calc(100vh - 440px);
overflow-y:auto;
margin-top:15px;
}
.clockIn-box{
width:100%;
height:80px;
/* background:rgba(0,0,0,0.25); */
border-bottom:1px solid #76838f;
padding:5px;
color:#efefef;
border-radius:0px;
margin-bottom:10px;
}
.item-container-right div{
float:left;
}
.user-item{
width:100%;
padding:0px 0px;
color:#fff;
line-height:50px;
}
.history-line{
width:100%;
line-height:20px;
margin-bottom:20px;
text-indent:0px;
cursor:pointer;
}
.history-line-button:hover{
color:#108eff;
}
.history-line-button{
}
.user-item::after{
content:"";
clear:both;
display:block;
visibility:hidden;
height:0;
}
.user-photo{
float:left;
width:36px;
height:36px;
margin-top:6px;
background-color:rgb(255, 255, 255);
border-radius: 50%;
line-height: 36px;
text-align: center;
}
.user-photo img{
width:32px;
height:32px;
margin:0px;
}
.user-name{
width:70px;
text-align: center;
color:#fff;
}
.user-phone{
width:100px;
text-align: center;
}
.user-operation{
float:right;
}
::v-deep .el-pagination__total{
color:#fff;
}
::v-deep .el-pagination__jump{
color:#fff;
}
::v-deep .el-descriptions__body{
background:none;
color:#fff;
}
::v-deep .el-descriptions-item__label.is-bordered-label{
background:none;
}
::v-deep .el-descriptions .is-bordered .el-descriptions-item__cell{
border-color: #272d39;
}
::v-deep .el-divider__text{
background:#272d39;
color:#fff;
}
::-webkit-scrollbar {
height: 10px;
width: 10px;
background: transparent;
border-radius: 5px;
}
::-webkit-scrollbar-thumb {
padding-top: 100px;
-webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1),
inset -1px -1px 0 rgba(0, 0, 0, 0.07);
background-color: rgba(0,0,0,0.2);
min-height: 28px;
border-radius: 4px;
background-clip: padding-box;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
border: 0;
}
::-webkit-scrollbar-thumb:hover {
-webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25);
background-color: rgba(0, 0, 0, 0.4);
}
::-webkit-scrollbar-thumb:active {
-webkit-box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.35);
background-color: rgba(0, 0, 0, 0.5);
}
::v-deep .el-descriptions-item__label.is-bordered-label{
color:#efefef;
}
::v-deep .dialog-mini .el-dialog__header {
background: rgba(10, 39, 78, 1);
}
::v-deep .dialog-mini .el-dialog__header .el-dialog__title {
color: #fff;
}
::v-deep .el-dialog {
background: rgba(10, 39, 78, 1);
}
::v-deep .el-loading-mask {
background: rgba(0, 9, 34, 0.9);
}
::v-deep .el-input__inner {
background: none;
color: #fff;
border-radius: 0px !important;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
::v-deep .el-button{
border-radius:0px;
}
.userlist-container{
width:100%;
height:100%;
background:#272d39;
}
.all-count{
width:100%;
padding:20px 20px;
padding-bottom:60px;
background:#1d222b;
color:#eee;
}
.all-count div{
width:40%;
height:32px;
line-height:32px;
border-left:3px solid #409eff;
float:left;
margin-left:20px;
text-indent: 20px;
box-shadow: 0px 0px 5px #1d222b;
}
.table-header{
width:100%;
height:40px;
background:#272d39;
display: flex;
flex-direction:row;
margin:12px 0px;
}
.table-header div{
flex:1;
text-align: center;
line-height:40px;
}
.user-list-content {
width:100%;
height: calc(100% - 155px);
overflow-y: auto;
padding:0px 10px;
}
.user-list-content .user-item{
width:100%;
height:60px;
background:#1d222b;
display: flex;
flex-direction:row;
margin:6px 0px;
position: relative;
}
.user-list-content .user-item::after{
content:"";
position:absolute;
bottom:0px;
right:0px;
border-left:8px solid #1d222b;
border-top:8px solid #1d222b;
border-right:8px solid #409eff;
border-bottom:8px solid #409eff;
width:0px;
height:0px;
}
.user-list-content .user-item div{
flex:1;
text-align: center;
line-height:60px;
color:#fff;
font-size:12px;
}
::-webkit-scrollbar {
height: 10px;
width: 10px;
background: transparent;
border-radius: 5px;
}
::-webkit-scrollbar-thumb {
padding-top: 100px;
-webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1),
inset -1px -1px 0 rgba(0, 0, 0, 0.07);
background-color: rgba(0,0,0,0.2);
min-height: 28px;
border-radius: 4px;
background-clip: padding-box;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
border: 0;
}
::-webkit-scrollbar-thumb:hover {
-webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25);
background-color: rgba(0, 0, 0, 0.4);
}
::-webkit-scrollbar-thumb:active {
-webkit-box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.35);
background-color: rgba(0, 0, 0, 0.5);
}
.page-container{
width: calc( 100% - 24px);
margin:0px auto;
height:70px;
border-top:1px solid #636262;
padding:20px 0px;
overflow-x: auto;
overflow-y:hidden;
}
</style>

View File

@ -0,0 +1,222 @@
<template>
<div style="width:100%;height:40vh;padding:0px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="addForm" :rules="rules" label-width="140px">
<el-form-item label="姓名: " prop="Name">
<el-input v-model="addForm.Name" style="width:300px ;"></el-input>
</el-form-item>
<el-form-item label="性别: " prop="Sex">
<el-radio-group v-model="addForm.Sex">
<el-radio label="男"></el-radio>
<el-radio label="女"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item :label="'所属自然村'">
<!-- <treeselect :options="orgsTree" :default-expand-level="3" :multiple="true" :flat="true" :open-on-click="true"
:open-on-focus="true" :clear-on-select="true" v-model="selectOrgs" style="z-index: 2026;">
</treeselect> -->
<treeselect :options="orgsTree" :default-expand-level="3" :multiple="true" :flat="true" :open-on-click="true"
:open-on-focus="true" :clear-on-select="true" v-model="selectOrgs" style="z-index: 2026;">
</treeselect>
</el-form-item>
<el-form-item style="margin-top: 16%;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="submitForm('form')" v-if="detailInfo.length == 0"></el-button>
<el-button type="primary" @click="createForm('form')" v-else></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { listToTreeSelect } from '@/utils'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { postMethodCommon, getMethodCommon } from '../../../../api/common';
import { validateMobile, validID, validateStock } from './validate.js'
import form from '../../../../store/modules/form';
let BASE_IMAGE_URL = process.env.VUE_APP_BASE_IMG_URL;
// let BASE_IMAGE_URL = BASE_IMAGE_API_URL;
export default {
name: "AddForm",
props: ['detailInfo'],
components: {
Treeselect,
},
data() {
return {
BASE_IMAGE_URL: BASE_IMAGE_URL,
addForm: {
gender: "男"
},
rules: {
name: [
{ required: true, message: '姓名不能为空', trigger: 'blur' },
],
phone: [
{ required: true, message: '电话不能为空', trigger: 'blur' },
{ validator: validateMobile.bind(this), trigger: 'blur' }
],
gender: [
{ required: true, message: '性别不能为空', trigger: 'blur' },
],
},
dialogFormVisible: false,
orgsTree: [], // 访
selectRoles: [], //
selectRoleNames: '',
}
},
created() {
console.log(this.detailInfo)
if (this.detailInfo.length == 1) {
this.getDetail()
} else {
this.addForm = {
gender: "男"
}
}
},
computed: {
selectOrgs: {
get: function () {
if (this.detailInfo.length == 1) {
return this.addForm.areaId
} else {
return []
}
},
set: function (v) {
var _this = this
_this.addForm.areaId = v
}
}
},
mounted() {
let _this = this;
var querys = {
regionName: localStorage.getItem("areaENName")
}
getMethodCommon("/Grid/LoadAllGrid", querys).then(res => {
console.log("data", res.data);
if (res.code == 200) {
var list = res.data
var arr = this.traverse(list)
_this.orgsTree = arr;
}
})
},
methods: {
getDetail() {
getMethodCommon("/FireCodeApp/GetForestryUserById?id=" + this.detailInfo[0].Id, {}).then(res => {
if (res.code == 200) {
this.addForm = res.data[0]
if(this.addForm.areaId){
var areaId = this.addForm.areaId.split(',')
this.addForm.areaId = turnNum(areaId)
}
var turnNum = function (nums) {
return nums.map(Number);
}
if (this.addForm.Sex == 0) {
this.addForm.Sex = '男'
} else {
this.addForm.Sex = '女'
}
}
})
},
traverse(arr) {
if (arr && arr.length > 0) {
var list = []
arr.forEach(childelement => {
list.push({
id: childelement.id,
label: childelement.areaName,
parentId: childelement.pId || null,
children: this.traverse(childelement.child)
})
});
return list
}
},
submitForm() {
var _this = this
this.$refs['form'].validate((valid) => {
if (valid) {
console.log(_this.addForm)
if (this.addForm.Sex == '男') {
this.addForm.Sex = 0
} else {
this.addForm.Sex = 1
}
postMethodCommon("/FireCodeApp/AddFireFighter", _this.addForm).then(response => {
if (response.code == 200) {
// shp
this.$emit("addSuccess");
this.$message({
type: "success",
message: "添加成功"
})
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
createForm() {
var _this = this
this.$refs['form'].validate((valid) => {
if (valid) {
console.log(_this.addForm)
if (this.addForm.Sex == '男') {
this.addForm.Sex = 0
} else {
this.addForm.Sex = 1
}
// delete this.addForm.zrclist
postMethodCommon("/FireCodeApp/EditForestryUser ", _this.addForm).then(response => {
if (response.code == 200) {
// shp
this.$emit("addSuccess");
this.$message({
type: "success",
message: "编辑成功"
})
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
close() {
this.$emit("close");
}
}
}
</script>
<style scoped>
::v-deep .vue-treeselect__control {
background: rgba(0, 9, 34, 0.6);
}
::v-deep .el-form-item__label {
color: #fff;
}
::v-deep .el-radio {
color: #fff;
}
.service-type-btn {
width: 100%;
height: 180px;
text-align: center;
margin-top: 100px;
}
</style>

View File

@ -0,0 +1,218 @@
<template>
<div style="width:100%;padding:10px 23px; z-index:10;background: rgba(0, 9, 34, 0.6);">
<el-form ref="form" size="mini" :model="paramForm" :rules="rules" label-width="140px" class="clockIn">
<el-form-item label="打卡点名称" prop="address">
<el-input v-model="paramForm.address" ></el-input>
</el-form-item>
<el-form-item label="行政区划" prop="user">
<el-cascader
v-model="orgId"
:options="orgs"
style="width:100%;"
:props="cascaderProps"
:key="orgIdRandom"
></el-cascader>
</el-form-item>
<el-form-item label="责任人" prop="user">
<treeselect :options="hlyList" :normalizer="normalizer" v-model="paramForm.user" :multiple="true" :disable-branch-nodes="true" placeholder="请选择责任人">
</treeselect>
</el-form-item>
<el-form-item style="margin-top: 16%;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="submitForm('form')"></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { postMethodCommon, getMethodCommon } from '../../../../api/common';
export default {
name: "AddForm",
props: ['lnglat','clockdata'],
components: {
Treeselect
},
data() {
return {
hlyList:[],
paramForm:{
address: '',
user: []
},
rules: {
user: [
{ required: true, message: '责任人不能为空', trigger: 'blur' },
]
},
orgs:[],
cascaderProps:{label:'name',value:'id',children:'child'},
orgId:[],
orgIdRandom:1,
}
},
watch:{
},
created() {
console.log('clockdata',this.clockdata)
this.treelist = []
this.gethlyList()
},
mounted() {
},
methods: {
getDetailInfo(){
getMethodCommon("/FireGrid/GetSingleCheckPoint?id="+this.clockdata.id).then(res=>{
if(res.code == 200){
this.orgId = this.getOrgsIds(res.result.areaid[0]);
this.orgIdRandom = Math.random();
console.log("ORGSID",this.orgId);
}
})
},
normalizer(node) {
node['isDisabled'] = true;
if(node.type == '护林员' || node.child.length > 0){
node['isDisabled'] = false;
}
return {
id: node.id,
label: node.name,
children: node.child && node.child.length > 0 ? node.child: 0,
}
},
gethlyList(){
getMethodCommon("/FireGrid/LoadUsers").then(res =>{
this.hlyList = res.data
console.log("orgsorgsorgs",this.orgs)
if(this.clockdata){
this.paramForm.address = this.clockdata.pointname
this.paramForm.user = this.clockdata.userid.split(',')
}
console.log('this.paramForm',this.hlyList)
})
getMethodCommon("/FireGrid/LoadUsersArea").then(res =>{
[...this.orgs] =res.data;
this.handleOrgs();
if(this.clockdata.id){
this.getDetailInfo();
}
})
},
handleOrgs(orgs){
for(let i=0;i<this.orgs[0].child.length;i++){
if(this.orgs[0].child[i]){
for(let j=0;j<this.orgs[0].child[i].child.length;j++){
if(this.orgs[0].child[i].child[j].child){
this.orgs[0].child[i].child[j].child = null;
}
}
}
}
},
getOrgsIds(id){
for(let i=0;i<this.orgs[0].child.length;i++){
if(this.orgs[0].child[i]){
for(let j=0;j<this.orgs[0].child[i].child.length;j++){
if(this.orgs[0].child[i].child[j]){
if(this.orgs[0].child[i].child[j].id == id){
return [this.orgs[0].id,this.orgs[0].child[i].id,`${id}`]
}
}
}
}
}
},
submitForm(){
this.$refs['form'].validate((valid) => {
if (valid) {
if(this.clockdata){
let param = {
id: this.clockdata.id,
lng: this.clockdata.lng,
lat: this.clockdata.lat,
pointname: this.paramForm.address,
userid: this.paramForm.user,
areaId:[this.orgId && this.orgId[2]],
}
postMethodCommon("/FireGrid/EditCheckPoint", param).then(response => {
if (response.code == 200) {
this.$emit("clockInSuccess");
this.$emit("close");
this.$message({
type: "success",
message: response.message
})
}
})
}else{
let param = {
id: 0,
lng: this.lnglat.lng,
lat: this.lnglat.lat,
pointname: this.paramForm.address,
userid: this.paramForm.user,
areaId:[this.orgId && this.orgId[2]],
}
postMethodCommon("/FireGrid/AddCheckPoint", param).then(response => {
if (response.code == 200) {
this.$emit("clockInSuccess");
this.$emit("close");
this.$message({
type: "success",
message: response.message
})
}
})
}
} else {
console.log('error submit!!');
return false;
}
});
},
close() {
this.$emit("close");
}
}
}
</script>
<style scoped>
::v-deep .el-form-item__label {
color: #fff;
}
::v-deep .vue-treeselect__control{
background: rgba(0, 9, 34, 1);
color: #fff;
}
::v-deep .vue-treeselect__single-value{
color: #fff;
}
::v-deep .el-input__inner {
background: rgba(0, 9, 34, 1);
color: #fff;
height: 36px;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,253 @@
<template>
<div class='userlist-container'>
<div class="all-count">
<div class="online-user-count">
在线人数 <span style="font-size:24px;color:#108eff;margin-left:12px;">{{onlineInfo.online}}</span>
</div>
<div class="online-user-count">
离线人数 <span style="font-size:24px;color:#108eff;margin-left:12px;">{{onlineInfo.offline}}</span>
</div>
</div>
<div class="table-header">
<div>乡镇/村庄</div>
<div>护林员姓名</div>
<div>在线状态</div>
<div>离线时长</div>
<div>操作</div>
</div>
<div class="user-list-content">
<div class="user-item" v-for="(item,index) in userlist" :key="index">
<div>{{item.townName}}</div>
<div>{{item.name}}</div>
<div>
<span v-if="item.state == '在线'">
<span style="color:greenyellow;font-weight: 1000;font-size:14px;">·</span> 在线
</span>
<span v-else>
<span style="color:rgb(247, 77, 10);font-weight: 1000;font-size:14px;">·</span> 离线
</span>
</div>
<div style="color:#F3A600;">{{item.onLineTime}}分钟</div>
<div>
<el-button type="primary" size="mini" @click="toPosition(item)"></el-button>
<el-button type="primary" size="mini" @click="toTrajectory(item)"></el-button>
</div>
</div>
</div>
<div class="page-container">
<el-pagination
size="mini"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="listQuery.page"
:page-sizes="[10, 20, 30, 50]"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</div>
</template>
<script>
import { postMethodCommon } from '../../../../api/common';
export default {
components: {},
data() {
return {
onlineInfo:{},
userlist:[],
listQuery:{
"page": 1,
"limit": 10,
"townname": "",
"isonline": "全部"
},
total:0,
};
},
computed: {},
watch: {},
methods: {
toPosition(item){
this.$emit("toPosition",[parseFloat(item.lng),parseFloat(item.lat)]);
},
toTrajectory(item){
this.$emit("toTrajectory",item.createId);
this.getRouteList(item.createId);
},
getRouteList(userid){
let query = {
userId:userid,
beginTime:this.beginAndEndTime[0],
endTime:this.beginAndEndTime[1],
}
getMethodCommon("/Patrol/LoadPatrolInfoByUserIdNew",query).then(res=>{
if(res.code == 200){
console.log("routerrouter",res);
}
})
},
getOnlineUserList(){ // 线
postMethodCommon("/FireManagement/GetPointUserOnLine",this.listQuery).then(res=>{
if(res.code == 200){
this.userlist = res.data.userinfo;
this.userlist.forEach((item,index)=>{
// this.userlist[index].onLineTime = this.friendlyDate(item.onLineTime);
})
this.onlineInfo = res.data;
this.total = this.onlineInfo.offline + this.onlineInfo.online;
}
})
},
handleSizeChange(e){
this.listQuery.limit = e;
this.getOnlineUserList();
},
handleCurrentChange(e){
this.listQuery.page = e;
this.getOnlineUserList();
},
friendlyDate(time) {
console.log(time);
if(time>60){
return Math.ceil(time/60)+"时"+time%60+"分前";
}
}
},
created() {
},
mounted() {
this.getOnlineUserList();
},
destroyed() {
},
}
</script>
<style scoped>
.userlist-container{
width:100%;
height:100%;
background:#272d39;
}
.all-count{
width:100%;
padding:20px 20px;
padding-bottom:60px;
background:#1d222b;
color:#eee;
}
.all-count div{
width:40%;
height:32px;
line-height:32px;
border-left:3px solid #409eff;
float:left;
margin-left:20px;
text-indent: 20px;
box-shadow: 0px 0px 5px #1d222b;
}
.table-header{
width:100%;
height:40px;
background:#272d39;
display: flex;
flex-direction:row;
margin:12px 0px;
}
.table-header div{
flex:1;
text-align: center;
line-height:40px;
}
.user-list-content {
width:100%;
height: calc(100% - 155px);
overflow-y: auto;
padding:0px 10px;
}
.user-list-content .user-item{
width:100%;
height:60px;
background:#1d222b;
display: flex;
flex-direction:row;
margin:6px 0px;
position: relative;
}
.user-list-content .user-item::after{
content:"";
position:absolute;
bottom:0px;
right:0px;
border-left:8px solid #1d222b;
border-top:8px solid #1d222b;
border-right:8px solid #409eff;
border-bottom:8px solid #409eff;
width:0px;
height:0px;
}
.user-list-content .user-item div{
flex:1;
text-align: center;
line-height:60px;
color:#fff;
font-size:12px;
}
::-webkit-scrollbar {
height: 10px;
width: 10px;
background: transparent;
border-radius: 5px;
}
::-webkit-scrollbar-thumb {
padding-top: 100px;
-webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1),
inset -1px -1px 0 rgba(0, 0, 0, 0.07);
background-color: rgba(0,0,0,0.2);
min-height: 28px;
border-radius: 4px;
background-clip: padding-box;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb {
border: 0;
}
::-webkit-scrollbar-thumb:hover {
-webkit-box-shadow: inset 1px 1px 1px rgba(0, 0, 0, 0.25);
background-color: rgba(0, 0, 0, 0.4);
}
::-webkit-scrollbar-thumb:active {
-webkit-box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.35);
background-color: rgba(0, 0, 0, 0.5);
}
.page-container{
width: calc( 100% - 24px);
margin:0px auto;
height:70px;
border-top:1px solid #636262;
padding:20px 0px;
overflow-x: auto;
overflow-y:hidden;
}
</style>

View File

@ -0,0 +1,28 @@
const validateMobile = function (rule, value, callback) {
let newValue = value.replace(/[^0-9]/gi, '')
if (value !== newValue) {
callback(new Error('请输入正确的手机号'))
} else if (newValue.length !== 11) {
callback(new Error('请输入正确的手机号'))
} else {
callback()
}
}
const validID = function(rule, value, callback) {
// 身份证号码为15位或者18位15位时全为数字18位前17位为数字最后一位是校验位可能为数字或字符X
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
if (reg.test(value)) {
callback();
} else {
callback(new Error("请输入正确的身份证号码"));
}
}
var validateStock = (rule, value, callback) => {
if (!value || value == 0) {
callback(new Error("不能为空"));
} else {
callback();
}
};
export { validateMobile ,validID,validateStock}

View File

@ -8,28 +8,26 @@
size="mini"
style="width: calc(25% - 15px);margin-right:15px;"
:props="cascaderProps"
placeholder="请选择行政区划"
@change="handleChange">
</el-cascader>
<el-date-picker
size="mini"
style="width: calc(25% - 15px);margin-right:15px;"
v-model="beginEndTime"
@change="timeChange"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
size="mini"
style="width: calc(25% - 15px);margin-right:15px;"
v-model="beginEndTime"
@change="timeChange"
type="datetimerange"
format="yyyy-MM-dd HH:mm:ss"
value-format="yyyy-MM-dd HH:mm:ss"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
<!-- <el-input type="text" v-model="listQuery.name" placeholder="请输入搜索关键字" style="width: calc(25% - 15px);margin-right:15px;" size="mini" round></el-input> -->
<div style="float:right;text-align:center;">
<el-button type="default" size="mini" @click="resetListQuery"><i class="el-icon el-icon-refresh-left"></i> 重置</el-button>
<el-button type="primary" size="mini" icon="el-icon-search" @click="getList();getAllData();"></el-button>
<el-button type="primary" size="mini" icon="el-icon-download" @click="downloadExcel" >导出</el-button>
</div>
@ -100,13 +98,13 @@
</div>
<div class="list-container-scroll">
<div class="list-item" v-for="(item,index) in list" :key="index">
<div class="list-item-box">{{item.AreaName}}</div>
<div class="list-item-box">{{item.Name}}</div>
<div class="list-item-box">{{item.Account}}</div>
<div class="list-item-box">{{item.areaName}}</div>
<div class="list-item-box">{{item.name}}</div>
<div class="list-item-box">{{item.account}}</div>
<div class="list-item-box">{{item.dakacishu}}</div>
<div class="list-item-box">{{item.xunjian}}</div>
<div class="list-item-box">{{item.dakadian}}</div>
<div class="list-item-box" @click="getGuiji(item.Account)">
<div class="list-item-box" @click="getGuiji(item.id)">
<el-link type="primary"> <i class="el-icon el-icon-tickets"></i>巡查轨迹</el-link>
</div>
</div>
@ -125,7 +123,7 @@
</el-pagination>
</div>
<div class="personal-container animation-scale-up" v-if="personalInfoShow">
<personalInfo @close="personalInfoShow = false;" :currentPeople="currentPeople"></personalINfo>
<personalInfo @close="personalInfoShow = false;" :currentStreet="currentStreet" :userid="currentPeople"></personalINfo>
</div>
</div>
</template>
@ -158,6 +156,7 @@ export default {
list:[],
total:null,
currentPeople:null,
currentStreet:null,
};
},
computed: {
@ -168,10 +167,15 @@ export default {
},
methods: {
downloadExcel(){
let query = {
areaid:this.listQuery.areaid,
begintime:this.listQuery.begintime,
endtime:this.listQuery.endtime
}
axios({
method:"get",
url:process.env.VUE_APP_BASE_API +"/FireGrid/ExportStatistics",
params:this.listQuery,
url:process.env.VUE_APP_BASE_API +"/FireGrid/ExportStatisticsNew",
params:query,
headers:{
"X-Token":localStorage.getItem("X-Token")
},
@ -200,6 +204,17 @@ export default {
getMethodCommon("/FireGrid/LoadUsersArea").then(res =>{
this.orgs = res.data;
this.handleOrgs();
if(this.orgs[0].child.length == 1){
this.currentStreet = this.orgs[0].child[0].name;
this.areaId = [this.orgs[0].id,this.orgs[0].child[0].id]
}else if(this.orgs[0].child.length != 1){
this.currentStreet = "费县";
this.areaId = [this.orgs[0].id]
}
this.listQuery.areaid = this.areaId
this.getAllData();
})
},
handleOrgs(orgs){
@ -227,7 +242,9 @@ export default {
begintime:this.listQuery.begintime,
endtime:this.listQuery.endtime
}
getMethodCommon("/FireGrid/GetStatisticsCount",param).then(res=>{
console.log("param",param);
getMethodCommon("/FireGrid/GetStatisticsCountNew",param).then(res=>{
if(res.code == 200){
this.allData = res.data;
}
@ -242,7 +259,7 @@ export default {
this.getList();
},
getList(){
getMethodCommon("/FireGrid/GetStatistics",this.listQuery).then(res=>{
getMethodCommon("/FireGrid/GetStatisticsNew",this.listQuery).then(res=>{
if(res.code == 200){
this.total = res.count;
this.list = res.data;
@ -259,15 +276,24 @@ export default {
}
},
created() {
let start = new Date();
let end = new Date()
this.beginEndTime = [end.getFullYear()+"-"+(end.getMonth()+1)+"-"+end.getDate()+" 00:00:00",start.getFullYear()+"-"+(start.getMonth()+1)+"-"+start.getDate()+" "+start.getHours()+":"+start.getMinutes()+":"+start.getSeconds()]
this.listQuery.begintime = this.beginEndTime[0];
this.listQuery.endtime = this.beginEndTime[1];
this.gethlyList();
this.getAllData();
this.getList();
},
mounted() {
},
destroyed() {
},
}
</script>
@ -380,14 +406,12 @@ export default {
}
.personal-container{
width:96%;
height:96%;
width:100%;
height: calc( 100vh - 100px);
position:absolute;
left:2%;
top:2%;
/* left:50%;
top:50%;
transform:translate(-50%,-50%); */
left:0px;
top:0px;
padding:20px 40px;
background:rgba(43,45,60,1);
box-shadow:0px 0px 30px rgba(0,0,0,0.5);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,32 @@
<template>
<div class='personal-info-container'>
<div class="header">
护林员信息
<span style="float:right;" @click="$emit('close')">
<span :style="{'color':tabActive == 1 ? '#409eff':'#fff','cursor':'pointer'}" @click="tabActive=1"></span>
&nbsp;&nbsp;&nbsp;&nbsp;
<span :style="{'color':tabActive == 2 ? '#409eff':'#fff','cursor':'pointer'}" @click="tabActive=2"></span>
<el-date-picker
v-model="beginAndEndTime"
size="mini"
type="datetimerange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="timeChange"
style="width:360px;margin-left:100px;"
value-format="yyyy-MM-dd HH:mm:ss"
>
</el-date-picker>
<span style="float:right;font-size:22px;" @click="$emit('close')">
<i class="el-icon el-icon-close"></i>
</span>
</div>
<div class="content-container">
<div class="list-container">
<div class="users-container">
<div class="users-container" v-show="tabActive == 1">
<div class="history-line" v-for="(it,idx) in list" :key="idx">
<div class="user-item">
<div class="user-photo">
@ -17,7 +35,7 @@
<div class="user-name">{{it.name}}</div>
<div class="user-phone">{{it.phone}}</div>
<el-button type="primary" size="mini" round @click="getTrajectoryData(it.id)" style="float:right;">轨迹</el-button>
<el-button type="primary" size="mini" round @click="getTrajectoryData(it)" style="float:right;">轨迹</el-button>
<!-- <el-button type="primary" size="mini" round @click="getRange(it.phone)" style="float:right;position:relative;top:8px;left:-12px;">范围</el-button> -->
</div>
@ -26,7 +44,14 @@
{{it.endAddress}} <span style="color:#ccc;font-size:12px;">({{it.endTime}})</span>
</div>
</div>
<div class="page-container">
<div class="users-container" v-show="tabActive == 2">
<div class="clockIn-box" v-for="(item,idx) in clockInList" :key="idx">
<p><span style="color:rgb(204, 204, 204)"><i class="el-icon el-icon-user-solid"></i> 打卡人员</span>{{ item.Name }} <span style="color:rgb(204, 204, 204)">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i class="el-icon el-icon-time"></i>打卡时间</span>{{ item.clockontime }}</p>
<p><span style="color:rgb(204, 204, 204)"><i class="el-icon el-icon-location"></i> 打卡位置</span>{{ parseFloat(item.lng).toFixed(6) }},{{ parseFloat(item.lat).toFixed(6) }}</p>
</div>
</div>
<!-- <div class="page-container">
<el-pagination
background
@size-change="handleSizeChange"
@ -37,11 +62,12 @@
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</div> -->
</div>
<div class="map-contianer">
<Map :trajectoryIdRandom="trajectoryIdRandom" :trajectoryId="trajectoryId"></Map>
<!-- <Map :trajectoryIdRandom="trajectoryIdRandom" :trajectoryId="trajectoryId"></Map> -->
<Map v-if="mapShow" :currentStreet="currentStreet" :listQuery="listQuery" :flyCenter="flyCenter" :trajectory="trajectory" :trajectoryIdRandom="trajectoryIdRandom"></Map>
</div>
</div>
</div>
@ -54,9 +80,11 @@ export default {
components: {
Map
},
props:["currentPeople"],
props:["userid","currentStreet"],
data() {
return {
tabActive:1,
flyCenter:null,
list:[],
listQuery:{
pageIndex:1,
@ -66,23 +94,46 @@ export default {
total:null,
trajectoryId:null,
trajectoryIdRandom:1,
beginAndEndTime:[new Date(),new Date()],
mapShow:true,
clockInList:[],
};
},
computed: {},
watch: {},
methods: {
getList(){
this.listQuery.phone = this.currentPeople;
postMethodCommon("/Patrol/LoadPatrolInfoByPhone?pageIndex="+this.listQuery.pageIndex+"&pageSIze="+this.listQuery.pageSize+"&phone="+this.listQuery.phone).then(res=>{
//
getClockInList(pointid){
let query = {
userid:this.userid,
beginTime:this.beginAndEndTime[0],
endTime:this.beginAndEndTime[1],
}
getMethodCommon("/FireGrid/GetCheckInfoByUserId",query).then(res=>{
if(res.code == 200){
this.list = res.data;
this.total = res.count;
this.clockInList = res.data
}
})
},
getTrajectoryData(id){
this.trajectoryId = id;
this.trajectoryIdRandom = Math.random()*100;
timeChange(e){
this.getRouteList();
this.getClockInList();
},
getRouteList(){
let query = {
userId:this.userid,
beginTime:this.beginAndEndTime[0],
endTime:this.beginAndEndTime[1],
}
getMethodCommon("/Patrol/LoadPatrolInfoByUserIdNew",query).then(res=>{
if(res.code == 200){
this.list = res.data;
}
})
},
getTrajectoryData(item){
this.trajectory = item;
this.trajectoryIdRandom = Math.random();
},
handleSizeChange(e){
this.listQuery.pageSize = e;
@ -94,7 +145,12 @@ export default {
}
},
created() {
this.getList();
let start = new Date();
let end = new Date()
this.beginAndEndTime = [end.getFullYear()+"-"+(end.getMonth()+1)+"-"+end.getDate()+" 00:00:00",start.getFullYear()+"-"+(start.getMonth()+1)+"-"+start.getDate()+" "+start.getHours()+":"+start.getMinutes()+":"+start.getSeconds()]
this.getRouteList();
this.getClockInList();
},
mounted() {
@ -112,14 +168,17 @@ export default {
}
.header{
width:100%;
height:50px;
height:70px;
background:#2d3041;
border-bottom:1px solid #777;
line-height:50px;
line-height:70px;
color:#fff;
padding:0px 15px;
}
.page-container{
padding-top:20px;
}
.content-container{
width:100%;
padding:20px;
@ -238,4 +297,29 @@ export default {
background-color: rgba(0, 0, 0, 0.5);
}
::v-deep .el-input__inner {
background: none;
color: #fff;
border-radius: 0px !important;
}
::v-deep .el-range-editor--mini .el-range-input{
background:none;
color:#fff;
}
::v-deep .el-button{
border-radius:0px;
}
.clockIn-box{
width:100%;
height:80px;
/* background:rgba(0,0,0,0.25); */
border-bottom:1px solid #76838f;
padding:5px;
color:#efefef;
border-radius:0px;
margin-bottom:10px;
}
</style>

View File

@ -24,7 +24,6 @@
props:["phone"],
data(){
return {
list:[
],
@ -48,7 +47,6 @@
this.getListData();
},
mounted(){
},
methods:{

View File

@ -67,7 +67,8 @@
</template>
<script>
import {md5} from '../../utils/md5'
import {encode} from '../../utils/base64'
import md5 from 'js-md5'
import waves from '@/directive/waves' //
import {
mapGetters,
@ -149,7 +150,7 @@ import {md5} from '../../utils/md5'
if (valid) {
this.loading = true
let form = {...this.loginForm}
form.password = md5(form.password);
form.password = md5(form.password).toUpperCase();
this.$store.dispatch('Login', form).then(() => {
this.loading = false
this.$router.push({

View File

@ -0,0 +1,564 @@
<template>
<div class="site-content">
<sticky :className="'sub-navbar'">
<div class="filter-container">
<el-input
@keyup.enter.native="handleFilter"
size="mini"
prefix-icon="el-icon-search"
style="width: 200px; margin-bottom: 0; margin: 0px 12px"
class="filter-item"
:placeholder="'名称'"
v-model="listQuery.name"
>
</el-input>
<el-button type="primary" size="mini" @click="getList()" icon="el-icon-search"
>查询</el-button
>
<el-button type="primary" size="mini" @click="add()" icon="el-icon-plus">添加</el-button>
<el-button type="warning" size="mini" @click="react()" icon="el-icon-edit">编辑</el-button>
<el-button type="danger" size="mini" @click="del()" icon="el-icon-delete">删除</el-button>
<permission-btn
moduleName="modulemanager"
:size="'mini'"
v-on:btn-event="onBtnClicked"
></permission-btn>
</div>
</sticky>
<div class="app-container flex-item">
<div class="fh">
<div class="flex jc-sb" style="height: calc(100% - 100px)">
<div class="mr-1 max-h" style="width:100%;">
<el-table
ref="mainTable"
:key="tableKey"
:data="tableData"
v-loading="listLoading"
border
fit
highlight-current-row
style="width: 100%"
height="100%"
@row-click="rowClick"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" align="center" width="55">
</el-table-column>
<el-table-column
prop="id"
label="ID"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="code"
label="代码"
show-overflow-tooltip
align="center"
>
</el-table-column>
<el-table-column
prop="codeValue"
label="值"
show-overflow-tooltip
align="center"
>
</el-table-column>
</el-table>
</div>
</div>
<pagination
v-show="total > 0"
:total="total"
:page.sync="listQuery.pageIndex"
:limit.sync="listQuery.pageSize"
@pagination="handleCurrentChange"
/>
</div>
</div>
<el-dialog
width="40%"
height="60%"
top=" calc(50vh - 340px)"
class="dialog-mini body-small addWindow"
v-el-drag-dialog
:title="titleStr"
:close-on-click-modal="false"
:close-on-press-escape="false"
:visible.sync="addServiceVisible"
>
<AddForm
v-if="addServiceVisible"
@addSuccess="addSuccess"
:detailInfo="detailInfo"
@close="addServiceVisible = false"
></AddForm>
</el-dialog>
<el-dialog
width="40%"
height="60%"
top=" calc(50vh - 340px)"
class="dialog-mini body-small addWindow"
v-el-drag-dialog
:title="titleStr"
:close-on-click-modal="false"
:close-on-press-escape="false"
:visible.sync="editServiceVisible"
>
<EditForm
v-if="editServiceVisible"
@addSuccess="editSuccess"
:editForm="editForm"
@close="editServiceVisible = false"
></EditForm>
</el-dialog>
<!-- 导入护林员 -->
<el-dialog
width="400px"
height="60%"
top=" calc(50vh - 340px)"
class="dialog-mini body-small addWindow"
v-el-drag-dialog
:title="'导入信息'"
:close-on-click-modal="false"
:close-on-press-escape="false"
:visible.sync="importVisible"
>
<ImportForestranger v-if="importVisible" @importSuccess="importSuccess"></ImportForestranger>
</el-dialog>
</div>
</template>
<script>
import AppConfigInfo from "/public/config/app.json";
import Pagination from "@/components/Pagination";
import { listToTreeSelect } from "@/utils";
import extend from "@/extensions/delRows.js";
import * as modules from "@/api/modules";
import * as login from "@/api/login";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import waves from "@/directive/waves"; //
import permissionBtn from "@/components/PermissionBtn";
import elDragDialog from "@/directive/el-dragDialog";
import iconData from "@/assets/public/css/comIconfont/iconfont/iconfont.json";
import { getMethodCommon, postMethodCommon } from "@/api/common";
import AddForm from "./widget/AddForm";
import Sticky from "@/components/Sticky";
import ImportForestranger from './widget/ImportForestranger.vue'
import EditForm from './widget/EditForm.vue'
export default {
name: "module",
components: {
permissionBtn,
Pagination,
AddForm,
Sticky,
ImportForestranger,
EditForm
},
mixins: [extend],
directives: {
waves,
elDragDialog,
},
data() {
return {
areaId:null,
orgs:[],
cascaderProps:{label:'name',value:'id',children:'child',checkStrictly: true},
importVisible:false,
rowdata: {},
tableKey: 0,
titleStr: "添加",
tableData: [],
addServiceVisible: false,
editServiceVisible:false,
total: 0,
listQuery: {
//
pageIndex: 1,
pageSize: 20,
name: null,
},
detailInfo: [],
clocklnglat: "",
clockInList: [],
clockInName: "",
clockInVisible: false,
rowdataKey: 1,
flyCenter: [],
clockDetail: {},
};
},
computed: {},
filters: {},
created() {
this.gethlyList();
this.getList();
this.getClockInList();
},
mounted() {},
methods: {
handleChange(e){
this.listQuery.areaId = e && e[e.length-1];
this.getList();
},
gethlyList(){
getMethodCommon("/FireGrid/LoadUsers").then(res =>{
this.orgs = res.data;
this.handleOrgs();
})
},
handleOrgs(orgs){
for(let i=0;i<this.orgs[0].child.length;i++){
if(this.orgs[0].child[i]){
if(this.orgs[0].child[i].child){
this.orgs[0].child[i].child = null;
}
// for(let j=0;j<this.orgs[0].child[i].child.length;j++){
// }
}
}
},
importSuccess(){
this.importVisible = false;
this.getList();
},
rightClick(e) {
console.log("rightClick", e);
this.clockInVisible = true;
this.clocklnglat = e;
this.clockDetail = null;
},
editClock(e) {
console.log("223311", e);
this.clockDetail = e;
this.clockInVisible = true;
},
gofly(item) {
console.log("iii", item);
this.flyCenter = [item.lng, item.lat];
},
delItem(item) {
console.log("123", item);
let param = {
id: item.id,
};
this.$confirm("确定删除本条数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
postMethodCommon("/FireGrid/DeleteCheckPoint?id=" + param.id).then(
(res) => {
if (res.code == 200) {
this.$message({
type: "success",
message: "删除成功",
});
}
this.rowdataKey++;
this.getClockInList();
}
);
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
clockInSuccess() {
console.log("231321");
this.rowdataKey++;
this.getClockInList();
},
getClockInList() {
let param = {
name: this.clockInName,
};
getMethodCommon("/FireGrid/GetTotalCheckPoint", param).then((res) => {
this.clockInList = res.result;
});
},
add() {
this.addServiceVisible = true;
this.detailInfo = [];
this.titleStr = "添加";
},
addSuccess() {
this.addServiceVisible = false;
this.getList();
},
editSuccess(){
this.editServiceVisible = false;
this.getList();
},
del() {
var _this = this;
if (this.multipleSelection.length != 1) {
this.$message({
type: "info",
message: "请选择一条数据进行删除",
});
return;
}
this.$confirm("确定删除所选数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
postMethodCommon("/FireManagement/DeleteSettingInfo?id=" +
_this.multipleSelection[0].id,
{}
).then((res) => {
if (res.code == 200) {
this.$message({
type: "success",
message: "删除成功",
});
}
_this.getList();
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除",
});
});
},
react() {
if (this.multipleSelection.length != 1) {
this.$message({
type: "info",
message: "请选择一条数据进行编辑",
});
return;
}
this.editForm = this.multipleSelection[0];
this.editServiceVisible = true;
this.titleStr = "编辑";
},
rowClick(row) {
this.$refs.mainTable.clearSelection();
this.$refs.mainTable.toggleRowSelection(row);
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
onBtnClicked: function (domId) {
console.log("you click:" + domId);
switch (domId) {
case "btnAdd":
this.addServiceVisible = true;
break;
case "btnEdit":
if (this.multipleSelection.length != 1) {
this.$message({
message: "只能选中一个进行编辑",
type: "error",
});
return;
}
this.handleUpdate();
break;
case "btnDel":
if (this.multipleSelection.length < 1) {
this.$message({
message: "至少删除一个",
type: "error",
});
return;
}
this.handleDelete();
break;
case "btnAddMenu":
this.handleAddMenu();
break;
case "btnEditMenu":
if (this.selectMenus.length !== 1) {
this.$message({
message: "只能选中一个进行编辑",
type: "error",
});
return;
}
this.handleEditMenu(this.selectMenus[0]);
break;
case "btnDelMenu":
if (this.selectMenus.length < 1) {
this.$message({
message: "至少删除一个",
type: "error",
});
return;
}
this.handleDelMenus(this.selectMenus);
break;
default:
break;
}
},
getList() {
this.listLoading = true;
getMethodCommon("/FireManagement/LoadSettingInfo", {"code":"TimeSlot"}).then(
(res) => {
if (res.code == 200) {
this.tableData = res.data;
this.total = res.count;
this.listLoading = false;
}
}
);
},
handleFilter() {
this.listQuery.pageIndex = 1;
this.getList();
},
handleSizeChange(val) {
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageIndex = val.page;
this.listQuery.pageSize = val.limit;
this.getList();
},
handleUpdate() {
this.editForm = this.multipleSelection[0];
this.editServiceVisible = true;
},
},
};
</script>
<style lang="scss" scoped>
.filter-container {
text-align: right;
}
.site-container {
width: 100%;
height: 100%;
background-size: 100% 100%;
}
.site-header {
width: 100%;
height: 99px;
background-image: url(/img/gridman/header.png);
background-size: 100% 100%;
text-align: center;
color: #fff;
line-height: 90px;
font-size: 36px;
letter-spacing: 5px;
}
.header-btn {
width: 100px;
height: 50px;
position: absolute;
top: 4%;
left: 2%;
}
.site-content {
width: 100%;
height: 94%;
background: rgba(0, 9, 34, 0.6);
}
.app-container {
height: 100%;
}
.text {
font-size: 14px;
}
.item {
margin-bottom: 18px;
}
.clearfix:before,
.clearfix:after {
display: table;
content: "";
}
.clearfix:after {
clear: both;
}
.el-card__header {
padding: 12px 20px;
}
.selectIcon-box {
text-align: center;
border: 1px solid #eeeeee;
border-right: 0;
border-bottom: 0;
.el-col {
padding: 10px 0;
border-right: 1px solid #eeeeee;
border-bottom: 1px solid #eeeeee;
&.active {
.iconfont {
color: #409eff;
}
}
}
.iconfont {
cursor: pointer;
font-size: 20px;
}
}
.custom-icon-input::before {
font-size: 18px;
position: absolute;
right: 10px;
top: 0;
}
.forestlistbox {
height: calc(100% - 30px);
padding: 10px;
overflow: auto;
}
.forestUl {
margin-bottom: 10px;
padding: 10px 20px;
}
</style>

View File

@ -0,0 +1,217 @@
<template>
<div style="width:100%;height:200px;padding:30px 23px; z-index:10;">
<el-form ref="form" size="mini" :model="addForm" :rules="rules" label-width="120px">
<el-form-item label="选择时间段: " prop="codeValue">
<el-time-picker
is-range
v-model="addForm.codeValue"
range-separator="-"
value-format="HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
style="width:100%;margin-bottom:5px;"
size="mini"
@change="codeValueChange"
>
</el-time-picker>
</el-form-item>
<el-form-item style="margin-top:0px;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="submitForm('form')" v-if="detailInfo.length == 0"></el-button>
<el-button type="primary" @click="createForm('form')" v-else></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { encode } from '../../../utils/base64';
import { listToTreeSelect } from '@/utils'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { postMethodCommon, getMethodCommon } from '../../../api/common';
import { validateMobile, validID, validateStock } from './validate.js'
import form from '../../../store/modules/form';
let BASE_IMAGE_URL = process.env.VUE_APP_BASE_IMG_URL;
// let BASE_IMAGE_URL = BASE_IMAGE_API_URL;
export default {
name: "AddForm",
props: ['detailInfo'],
components: {
},
data() {
return {
BASE_IMAGE_URL: BASE_IMAGE_URL,
rules: {
codeValue: [
{ required: true, message: '不能为空', trigger: 'blur' },
],
phone: [
{ required: true, message: '电话不能为空', trigger: 'blur' },
{ validator: validateMobile.bind(this), trigger: 'blur' }
],
gender: [
{ required: true, message: '性别不能为空', trigger: 'blur' },
],
},
dialogFormVisible: false,
orgsTree: [], // 访
selectRoles: [], //
selectRoleNames: '',
level:0,
addForm:{
code:"TimeSlot",
codeValue:"",
}
}
},
created() {
// if (this.detailInfo.length == 1) {
// // this.addForm = this.detailInfo[0];
// this.getDetail()
// } else {
// }
},
computed: {
selectOrgs: {
get: function () {
if (this.detailInfo.length == 1) {
return this.addForm.areaId
} else {
return []
}
},
set: function (v) {
var _this = this
_this.addForm.areaId = v
}
}
},
mounted() {
let _this = this;
var querys = {
regionName: localStorage.getItem("areaENName")
}
getMethodCommon("/Grid/LoadAllTown", querys).then(res => {
console.log("data", res.data);
if (res.code == 200) {
var list = res.data
var arr = this.traverse(list)
console.log(arr)
_this.orgsTree = arr;
}
})
},
methods: {
getDetail() {
getMethodCommon("/FireCodeApp/GetForestryUserById?id=" + this.detailInfo[0].Id, {}).then(res => {
if (res.code == 200) {
let detail = {...res.data[0]};
this.addForm.id = detail.Id;
this.addForm.name = detail.Name;
this.addForm.account = detail.Account;
this.addForm.sex = detail.Sex;
this.addForm.userRole = detail.UserRole;
this.addForm.areaId = detail.areaId;
// if(this.addForm.areaId){
// var areaId = this.addForm.areaId.split(',')
// this.addForm.areaId = turnNum(areaId)
// }
// var turnNum = function (nums) {
// return nums.map(Number);
// }
}
})
},
traverse(arr) {
this.level++;
if(this.level<3){
if (arr && arr.length > 0) {
var list = []
arr.forEach(childelement => {
list.push({
id: childelement.id,
label: childelement.areaName,
parentId: childelement.pId || null,
children: this.traverse(childelement.child)
})
});
return list
}
}
},
submitForm() {
var _this = this
this.$refs['form'].validate((valid) => {
if (valid) {
//
_this.addForm.codeValue = _this.addForm.codeValue.join("-");
postMethodCommon("/FireManagement/AddSettingInfo", _this.addForm).then(response => {
if (response.code == 200) {
// shp
this.$emit("addSuccess");
this.$message({
type: "success",
message: "添加成功"
})
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
createForm() {
var _this = this
this.$refs['form'].validate((valid) => {
if (valid) {
// delete this.addForm.zrclist
postMethodCommon("/FireCodeApp/EditForestryUser ", _this.addForm).then(response => {
if (response.code == 200) {
// shp
this.$emit("addSuccess");
this.$message({
type: "success",
message: "编辑成功"
})
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
close() {
this.$emit("close");
}
}
}
</script>
<style scoped>
::v-deep .vue-treeselect__control {
background: rgba(0, 9, 34, 0);
}
::v-deep .el-form-item__label {
color: #333;
}
::v-deep .el-radio {
color: #333;
}
.service-type-btn {
width: 100%;
height: 180px;
text-align: center;
margin-top: 100px;
}
</style>

View File

@ -0,0 +1,215 @@
<template>
<div style="width:100%;height:200px;padding:30px 23px; z-index:10;">
<el-form ref="form" size="mini" :model="editForm" :rules="rules" label-width="120px">
<el-form-item label="选择时间段: " prop="codeValue">
<el-time-picker
is-range
v-model="editForm.codeValue"
range-separator="-"
value-format="HH:mm:ss"
start-placeholder="开始时间"
end-placeholder="结束时间"
placeholder="选择时间范围"
style="width:100%;margin-bottom:5px;"
size="mini"
>
</el-time-picker>
</el-form-item>
<el-form-item style="margin-top:0px;">
<el-button @click="close()"></el-button>
<el-button type="primary" @click="createForm('form')"></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { encode } from '../../../utils/base64';
import { listToTreeSelect } from '@/utils'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { postMethodCommon, getMethodCommon } from '../../../api/common';
import { validateMobile, validID, validateStock } from './validate.js'
import form from '../../../store/modules/form';
let BASE_IMAGE_URL = process.env.VUE_APP_BASE_IMG_URL;
// let BASE_IMAGE_URL = BASE_IMAGE_API_URL;
export default {
name: "AddForm",
props: ['editForm'],
components: {
},
data() {
return {
BASE_IMAGE_URL: BASE_IMAGE_URL,
rules: {
codeValue: [
{ required: true, message: '不能为空', trigger: 'blur' },
],
phone: [
{ required: true, message: '电话不能为空', trigger: 'blur' },
{ validator: validateMobile.bind(this), trigger: 'blur' }
],
gender: [
{ required: true, message: '性别不能为空', trigger: 'blur' },
],
},
dialogFormVisible: false,
orgsTree: [], // 访
selectRoles: [], //
selectRoleNames: '',
level:0,
addForm:{
code:"TimeSlot",
codeValue:"",
}
}
},
created() {
console.log("editForm",this.editForm);
this.editForm.codeValue = this.editForm.codeValue.split("-")
},
computed: {
selectOrgs: {
get: function () {
if (this.detailInfo.length == 1) {
return this.addForm.areaId
} else {
return []
}
},
set: function (v) {
var _this = this
_this.addForm.areaId = v
}
}
},
mounted() {
let _this = this;
var querys = {
regionName: localStorage.getItem("areaENName")
}
getMethodCommon("/Grid/LoadAllTown", querys).then(res => {
console.log("data", res.data);
if (res.code == 200) {
var list = res.data
var arr = this.traverse(list)
console.log(arr)
_this.orgsTree = arr;
}
})
},
methods: {
getDetail() {
getMethodCommon("/FireCodeApp/GetForestryUserById?id=" + this.detailInfo[0].Id, {}).then(res => {
if (res.code == 200) {
let detail = {...res.data[0]};
this.addForm.id = detail.Id;
this.addForm.name = detail.Name;
this.addForm.account = detail.Account;
this.addForm.sex = detail.Sex;
this.addForm.userRole = detail.UserRole;
this.addForm.areaId = detail.areaId;
// if(this.addForm.areaId){
// var areaId = this.addForm.areaId.split(',')
// this.addForm.areaId = turnNum(areaId)
// }
// var turnNum = function (nums) {
// return nums.map(Number);
// }
}
})
},
traverse(arr) {
this.level++;
if(this.level<3){
if (arr && arr.length > 0) {
var list = []
arr.forEach(childelement => {
list.push({
id: childelement.id,
label: childelement.areaName,
parentId: childelement.pId || null,
children: this.traverse(childelement.child)
})
});
return list
}
}
},
submitForm() {
alert(111)
var _this = this
this.$refs['form'].validate((valid) => {
if (valid) {
//
console.log("editForm:::",_this.editForm.codeValue);
// _this.editForm.codeValue = _this.editForm.codeValue.join("-");
postMethodCommon("/FireManagement/AddSettingInfo", _this.addForm).then(response => {
if (response.code == 200) {
// shp
this.$emit("addSuccess");
this.$message({
type: "success",
message: "添加成功"
})
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
createForm() {
var _this = this
this.$refs['form'].validate((valid) => {
if (valid) {
_this.editForm.codeValue = _this.editForm.codeValue.join("-");
// delete this.addForm.zrclist
postMethodCommon("/FireManagement/EditSettingInfo ", _this.editForm).then(response => {
if (response.code == 200) {
// shp
this.$emit("addSuccess");
this.$message({
type: "success",
message: "编辑成功"
})
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
close() {
this.$emit("close");
}
}
}
</script>
<style scoped>
::v-deep .vue-treeselect__control {
background: rgba(0, 9, 34, 0);
}
::v-deep .el-form-item__label {
color: #333;
}
::v-deep .el-radio {
color: #333;
}
.service-type-btn {
width: 100%;
height: 180px;
text-align: center;
margin-top: 100px;
}
</style>

View File

@ -0,0 +1,132 @@
<template>
<div class=''>
<el-upload
size="mini"
class="upload-demo"
action="#"
drag
:limit="limit"
:on-preview="handlePreview"
:file-list="fileList"
:auto-upload="false"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:on-change="handleChange"
:on-success="handleSuccess"
:on-error="handleError"
>
<i class="el-icon-upload" style="font-size:60px;line-height:0px;"></i>
<div class="el-upload__text">将Excel文件拖到此处<em>点击上传</em></div>
</el-upload>
<p style="text-align: right;margin-top:18px;">
<el-button type="primary" size="mini" @click="onSubmit"></el-button>
</p>
</div>
</template>
<script>
import { postMethodCommon } from '../../../api/common';
export default {
components: {},
props:[],
data() {
return {
limit:1,
fileList:[],
form:{},
};
},
computed: {},
watch: {},
methods: {
//
handlePreview(file) {
},
//
handleRemove(file, fileList) {
this.fileList = fileList
},
//
handleSuccess(res, file, fileList) {
this.$message.success('文件上传成功')
},
//
handleExceed(files, fileList) {
this.$message.warning(`只能选择 ${this.limit} 个文件进行上传!!`)
},
//
handleChange(file, fileList) {
this.form.name = file.name.split(".")[0]
if (file) {
this.fileList = fileList
}
},
//
handleError(err, file, fileList) {
this.$message.error('文件上传失败')
},
beforeUpload(file) {
let extension = file.name.substring(file.name.lastIndexOf('.') + 1)
let size = file.size / 1024 / 1024;
if (extension !== 'apk') {
this.$message.warning('只能上传后缀是.apk的文件')
return false
}
if (size > 100) {
this.$message.warning('文件大小不得超过100M')
return false
}
return true
},
onSubmit() {
let _this = this
let formData = new FormData();
this.fileList.forEach(item => {
formData.append("files", item.raw);
});
if (this.fileList.length === 0) {
this.$message.warning(`请选择上传文件!!`)
return
}
postMethodCommon("/Files/Upload", formData).then(res => {
if (res.code === 200) {
_this.form.filepath = res.result[0].filePath
let param = {
"file_path": res.result[0].filePath,
"token": ""
}
postMethodCommon('/FireCodeApp/BatchExportRanger',param).then(res2 => {
_this.$emit("importSuccess")
_this.fileList = []
})
} else {
_this.$message.warning(`接口错误!!`)
}
})
},
},
created() {
},
mounted() {
},
destroyed() {
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,28 @@
const validateMobile = function (rule, value, callback) {
let newValue = value.replace(/[^0-9]/gi, '')
if (value !== newValue) {
callback(new Error('请输入正确的手机号'))
} else if (newValue.length !== 11) {
callback(new Error('请输入正确的手机号'))
} else {
callback()
}
}
const validID = function(rule, value, callback) {
// 身份证号码为15位或者18位15位时全为数字18位前17位为数字最后一位是校验位可能为数字或字符X
let reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
if (reg.test(value)) {
callback();
} else {
callback(new Error("请输入正确的身份证号码"));
}
}
var validateStock = (rule, value, callback) => {
if (!value || value == 0) {
callback(new Error("不能为空"));
} else {
callback();
}
};
export { validateMobile ,validID,validateStock}