电子巡更over

master
Tuzki 2 years ago
parent ec7b2193c8
commit e0e1ca0e85
  1. 9
      manifest.json
  2. 27
      pages.json
  3. 10
      pages/work/electronicPatrol/electronicPatrol.vue
  4. 189
      pages/work/electronicPatrol/nightWatchman.vue
  5. 267
      pages/work/electronicPatrol/patrolTrack.vue
  6. 169
      pages/work/electronicPatrol/taskDetails.vue
  7. BIN
      static/activity_pin.png
  8. BIN
      static/images/icons/luxian.png
  9. BIN
      static/images/icons/ren.png
  10. BIN
      static/people_pin.png

@ -69,7 +69,14 @@
"title" : "RuoYi-App",
"router" : {
"mode" : "hash",
"base" : "./"
"base" : ""
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "XYGBZ-VKOWU-KAIVJ-GRJNV-CINQ5-6RFFD"
}
}
}
},
"fallbackLocale" : "zh-Hans"

@ -381,6 +381,33 @@
}
}
,{
"path" : "pages/work/electronicPatrol/taskDetails",
"style" :
{
"navigationBarTitleText": "任务详情",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/work/electronicPatrol/nightWatchman",
"style" :
{
"navigationBarTitleText": "巡更人员",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/work/electronicPatrol/patrolTrack",
"style" :
{
"navigationBarTitleText": "巡更轨迹",
"enablePullDownRefresh": false
}
}
],
"tabBar": {
"color": "#000000",

@ -14,7 +14,7 @@
<view class="j-d-item">开始时间{{ item.startDate }}</view>
<view class="j-d-item">完成度{{ item.completeness }}</view>
</view>
<button size="mini" :class="item.statusDesign == '即将开始' ? 'job-btn-off' : 'job-btn-on'">{{ item.statusDesign }}</button>
<button @click="signIn(item)" size="mini" :class="item.statusDesign == '即将开始' ? 'job-btn-off' : 'job-btn-on'">{{ item.statusDesign }}</button>
</view>
</view>
</view>
@ -42,6 +42,14 @@ export default {
this.getList();
},
methods: {
//
signIn(val){
if(val.statusDesign == '巡更打卡'){
uni.navigateTo({
url:'taskDetails'
})
}
},
showData(e) {
console.log(e);
},

@ -0,0 +1,189 @@
<template>
<view class="detail-container">
<view class="g-body">
<view class="content-box">
<movable-refresh ref="movableRefresh" :scrollHeight="scrollHeight" :noMore="noMore" @refresh="refresh" @loadMore="loadMore">
<view>
<view class="card" v-for="(item, index) in list" v-if="list.length > 0" :key="index" @click.stop="goDetail(item)">
<view class="card-content">
<view class="images" v-if="item.imageUrl">
<image style="width: 200px; height: 200px; background-color: #eeeeee" :mode="'center'" :src="baseUrls + item.imageUrl.split(',')[0]"></image>
</view>
<view class="images" v-else>暂无图片</view>
<view class="introduce">
<view class="">{{ item.name || '/' }}</view>
<view class="small-font">电话{{ item.phone || '/' }}</view>
</view>
</view>
</view>
</view>
</movable-refresh>
</view>
</view>
</view>
</template>
<script>
import movableRefresh from '@/components/zyq-movableRefresh/zyq-movableRefresh.vue';
export default {
components: {
movableRefresh
},
data() {
return {
list: [],
page: 1,
scrollHeight: 300,
noMore: false
};
},
onLoad() {
let system = uni.getSystemInfoSync();
this.scrollHeight = system.windowHeight - system.statusBarHeight;
console.log(this.scrollHeight);
this.refresh();
},
methods: {
refresh() {
this.page = 1;
this.noMore = false;
let list = [];
//
let obj = {
name: '李晓明',
id: '4',
phone: '1521241234'
};
for (let i = 0; i < 15; i++) {
list.push(obj);
}
this.list = list;
this.page++
console.log(this.list);
if (this.$refs.movableRefresh) {
let that = this;
setTimeout(function () {
that.$refs.movableRefresh.endLoad(); //
}, 1000);
}
},
loadMore() {
if (this.noMore) {
return;
}
let list = this.list;
let page = this.page;
let that = this;
let start = (page - 1) * 15;
//
let obj = {
name: '李晓明',
id: '4',
phone: '1521241234'
};
setTimeout(function () {
for (let i = 0; i < 15; i++) {
list.push(obj);
}
that.page++;
that.list = list;
that.$refs.movableRefresh.endLoad(); //
if (that.page > 3) {
that.noMore = true;
}
}, 1000);
},
//
goDetail(val) {
uni.navigateTo({
url: '../../index/addressBook/datails'
});
}
}
};
</script>
<style lang="scss" scoped>
.card {
width: 100%;
height: 130rpx;
background-color: white;
margin: 0 auto 6rpx auto;
background: #ffffff;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.1);
border-radius: 5px;
position: relative;
.card-content {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 32rpx;
.images {
width: 90rpx;
height: 90rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
background-color: #eee;
}
.introduce {
flex: 1;
color: #000;
margin-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
.big-font {
display: flex;
align-items: center;
.start {
display: inline-block;
border: solid 1px rgb(241, 150, 83);
border-radius: 20rpx;
color: rgb(241, 150, 83);
margin-left: 20rpx;
margin-top: 0;
padding: 2rpx 20rpx;
}
}
.small-font {
color: #909090;
margin-top: 6rpx;
}
}
}
}
.noCard {
width: 100%;
height: 200rpx;
margin: auto;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
color: #999999;
box-shadow: 0 0 10rpx 0 rgba(0, 0, 0, 0.1);
border-radius: 10rpx;
}
</style>

@ -0,0 +1,267 @@
<template>
<view>
<map @markertap="markertap" class="mapV" :include-points="coversline" :polyline="polylineList" :markers="covers" show-location="false"></map>
<uni-popup ref="popup" background-color="#fff" mask-background-color="rgba(0,0,0,0.4)" class="popup-box">
<view class="line-detail">
<view class="title-box">
<text class="detail-title big-font">{{ pointDetail.patrolPointName }}</text>
<text class="detail-status small-font" :class="pointDetail.checkDate != ''?'detail-status-on':'detail-status'">{{ pointDetail.checkDate != '' ? '已打卡' : '未打卡' }}</text>
</view>
<view class="detail-box">
<view>开始时间{{ pointDetail.patrolDate }}</view>
<view>开始时间{{ pointDetail.checkDate }}</view>
<view>打卡方式{{ pointDetail.checkInWay }}</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
data() {
return {
type: 'bottom',
//
covers: [],
coversline: [],
pointDetail: {
patrolDate: '',
patrolPointName: '',
checkDate: '',
longitude: '',
dimension: '',
checkInWay: ''
},
//
infoDict: {
lon: '116.39742',
lat: '39.909'
},
polylineList: [
{
color: '#39abffe6',
width: 8,
points: []
}
],
polyline: [],
//
myPinInfo: {},
//
distance: -9999,
distanceStr: '',
lineArr: [],
datas: []
};
},
mounted() {
//
// this.getlocation();
//
this.getData();
},
methods: {
//
getData() {
let this_ = this;
setTimeout(() => {
this_.datas = [
{
patrolDate: '2023-03-03 09:10',
patrolPointName: '嵩山打卡点1',
checkDate: '2023-03-03 15:31:24',
longitude: '114.54',
dimension: '38.12',
checkInWay: '扫码,刷脸'
},
{
patrolDate: '2023-03-03 09:10',
patrolPointName: '嵩山打卡点2',
checkDate: '2023-03-03 15:31:24',
longitude: '114.34',
dimension: '38.22',
checkInWay: '扫码,刷脸'
},
{
patrolDate: '2023-03-03 09:10',
patrolPointName: '嵩山打卡点3',
checkDate: '2023-03-03 15:31:24',
longitude: '114.14',
dimension: '38.52',
checkInWay: '扫码,刷脸'
}
];
let arr = [];
let linearr = [];
let obj = {};
let lineobj = {};
this_.datas.forEach((item, index) => {
obj = {
latitude: item.dimension,
longitude: item.longitude,
width: 20,
height: 30,
id: index + 1,
alpha: 0.7,
// #ifdef H5
iconPath: '../../../static/activity_pin.png'
// #endif
};
lineobj = {
latitude: item.dimension,
longitude: item.longitude
};
arr.push(obj);
linearr.push(lineobj);
});
console.log(arr);
console.log(linearr);
this_.polylineList[0].points = linearr;
this_.covers = arr;
this_.coversline = linearr;
}, 500);
},
getlocation() {
let myThis = this;
console.log('获取位置开始');
uni.getLocation({
type: 'gcj02',
success: function (res) {
myThis.myPinInfo = res;
console.log('当前位置的经度:' + res.longitude);
console.log('当前位置的纬度:' + res.latitude);
myThis.covers = [
{
latitude: myThis.infoDict.lat,
longitude: myThis.infoDict.lon,
width: 30,
height: 30,
id: 20000,
iconPath: '../../../static/activity_pin.png',
alpha: 0.7
},
{
latitude: myThis.myPinInfo.latitude,
longitude: myThis.myPinInfo.longitude,
width: 30,
height: 30,
id: 20001,
iconPath: '../../../static/people_pin.png',
alpha: 0.7
}
];
myThis.distance = myThis.getDistance(myThis.infoDict.lat, myThis.infoDict.lon, myThis.myPinInfo.latitude, myThis.myPinInfo.longitude);
myThis.distanceStr = '(当前距离' + myThis.distance + '米)';
}
});
},
//
getDistance(lat1, lng1, lat2, lng2) {
let EARTH_RADIUS = 6378.137;
let radLat1 = this.rad(lat1);
let radLat2 = this.rad(lat2);
let a = radLat1 - radLat2;
let b = this.rad(lng1) - this.rad(lng2);
let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
s = s * EARTH_RADIUS;
//s = Math.round(s * 10000d) / 10000d;
s = Math.round(s * 10000) / 10000;
s = s * 1000; //1000
return s;
},
//
rad(d) {
return (d * Math.PI) / 180.0;
},
//
goSignIn(e) {
if (this.distance > 10000) {
uni.showModal({
title: '温馨提示',
content: '您的当前位置距离目的地太远, 无法打卡',
showCancel: false
});
return;
} else if (this.distance < 0) {
uni.showModal({
title: '温馨提示',
content: '您的定位权限未打开, 请点击小程序右上角···菜单按钮, 然后点击设置,打开定位权限',
showCancel: false
});
return;
}
},
markertap(val) {
console.log(val);
//
this.pointDetail = {
patrolDate: '2023-03-03 09:10',
patrolPointName: '嵩山打卡点3',
checkDate: '2023-03-03 15:31:24',
longitude: '114.14',
dimension: '38.52',
checkInWay: '扫码,刷脸'
};
this.$refs.popup.open('bottom');
}
}
};
</script>
<style lang="scss" scoped>
.mapV {
width: 100%;
height: 100vh;
}
.line-detail {
width: 100%;
padding: 20rpx;
height: 20vh;
.title-box{
display: flex;
justify-content: space-between;
margin-bottom: 20rpx;
align-items: center;
.detail-status{
padding: 10rpx 20rpx;
background-color: #f2f2f2;
border-radius: 10rpx;
}
.detail-status-on{
padding: 10rpx 20rpx;
background-color: rgb(54, 127, 255);
color: #eee;
border-radius: 10rpx;
}
}
.detail-box{
color: #4f4f4f;
}
}
</style>

@ -0,0 +1,169 @@
<template>
<view class="detail-container">
<view class="g-body">
<view class="body-item">
<view class="job-list">
<view class="job-title-box">
<text class="job-title big-font">{{ job.patrolTaskName }}</text>
<text class="job-status small-font">{{ job.taskState }}</text>
</view>
<view class="job-detail">
<view class="j-d-item">开始时间{{ job.startDate }}</view>
<view class="j-d-item">完成度{{ job.completeness }}</view>
</view>
<view class="job-btn-box">
<view @click="goPerson(job.id)" class="job-person">
<image class="job-icon" src="../../../static/images/icons/ren.png" mode="widthFix"></image>
<text>值守人员</text>
</view>
<view @click="goLine(job.id)" class="job-person">
<image class="job-icon" src="../../../static/images/icons/luxian.png" mode="widthFix"></image>
<text>巡更轨迹</text>
</view>
</view>
</view>
</view>
<view class="body-item">
<common-title :title="'巡更点位'" ></common-title>
<view class="task-item" v-for="item in job.list">
<view class="job-title">
{{item.patrolPointName}}
</view>
<view class="job-detail">
开始时间{{item.startDate}}
</view>
<view >
<button :class="[item.finishDate==''?'unfinish-btn':'finish-btn','task-btn']">{{item.finishDate==''?'打卡':'已打卡'}}</button>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
job: {
id: '12',
patrolTaskName: '任务点1',
startDate: '08:20',
completeness: '100.0%',
taskState: '未完成',
list: [
{
id: '2',
startDate: '08:20',
patrolPointName: '嵩山打卡点1',
finishDate: '2023-04-13 16:17:24'
},
{
id: '3',
startDate: '09:10',
patrolPointName: '嵩山打卡点2',
finishDate: '2023-04-13 16:17:24'
}
]
}
};
},
methods:{
goPerson(val){
uni.navigateTo({
url:'nightWatchman'
})
},
goLine(val){
uni.navigateTo({
url:'patrolTrack'
})
}
}
};
</script>
<style lang="scss" scoped>
.job-list {
width: 95%;
margin: 0 2.5%;
padding: 20rpx;
border-bottom: solid 1px #eee;
position: relative;
.job-title-box {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
.job-status {
color: #4f4f4f;
}
}
.job-detail {
color: #8f8f8f;
}
.job-btn-off,
.job-btn-on {
position: absolute;
right: 7px;
top: 6vh;
}
.job-btn-on {
background-color: rgb(54, 127, 255);
color: #eee;
}
.job-btn-box{
display: flex;
align-items: center;
margin-top: 30rpx;
.job-person{
display: flex;
align-items: center;
margin-right: 30rpx;
}
.job-icon{
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
}
}
.task-item{
margin-bottom: 30rpx;
padding:0 20rpx 20rpx;
border-bottom: solid 1rpx #eee;
position: relative;
.job-title{
margin-bottom: 10rpx;
font-size: 32rpx;
}
.job-detail{
font-size: 28rpx;
color: #7f7f7f;
}
.task-btn{
width: 100rpx;
height: 50rpx;
font-size: 20rpx;
padding: 2rpx 10rpx;
position: absolute;
right: 20rpx;
top: 2vh;
}
.finish-btn{
background-color: #eee;
}
.unfinish-btn{
background-color: rgb(54, 127, 255);
color: #eee;
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Loading…
Cancel
Save