Просмотр исходного кода

任务功能相关主流程完成

yf_zhb 2 лет назад
Родитель
Сommit
964ef23024

+ 1 - 1
MingGaoApp/.hbuilderx/launch.json

@@ -16,7 +16,7 @@
             "type" : "uniCloud"
         },
         {
-            "playground" : "custom",
+            "playground" : "standard",
             "type" : "uni-app:app-android"
         }
     ]

+ 18 - 3
MingGaoApp/components/task-card/task-card.vue

@@ -37,7 +37,9 @@
 						<view class="actions__icon">
 							<image src="@/static/image/task/icon/tool.png" mode="aspectFit" class="img"></image>
 						</view>
-						<view class="actions__text">{{dataSource.walk_length}} km</view>
+						<view class="actions__text">
+							{{dataSource.walk_length/1000>=1?`${Math.ceil(dataSource.walk_length/1000)}km`:`${dataSource.walk_length}m`}}
+						</view>
 					</view>
 					<view class="actions__item right">
 						<view class="actions__icon">
@@ -55,13 +57,22 @@
 						<view class="actions__btn-text">开始</view>
 					</view>
 					<template v-else>
-						<view class="actions__btn" @click="handleBtnClick(TASK_ACTION_TYPE.PAUSE)">
+						<view class="actions__btn" @click="handleBtnClick(TASK_ACTION_TYPE.PAUSE)"
+							v-if="dataSource.walk_status === TASK_WALK_TYPE.IS_RECORDING">
 							<view class="actions__btn-icon">
 								<image src="@/static/image/task/icon/pause.svg" mode="aspectFit" class="img">
 								</image>
 							</view>
 							<view class="actions__btn-text">暂停</view>
 						</view>
+						<view class="actions__btn" @click="handleBtnClick(TASK_ACTION_TYPE.RESTART)"
+							v-if="dataSource.walk_status === TASK_WALK_TYPE.IS_PAUSED">
+							<view class="actions__btn-icon">
+								<image src="@/static/image/task/icon/play.svg" mode="aspectFit" class="img">
+								</image>
+							</view>
+							<view class="actions__btn-text">重新开始</view>
+						</view>
 						<view class="actions__btn" @click="handleBtnClick(TASK_ACTION_TYPE.CLOCK)">
 							<view class="actions__btn-icon">
 								<image src="@/static/image/task/icon/clockin.svg" mode="aspectFit" class="img">
@@ -78,7 +89,8 @@
 						</view>
 					</template>
 				</view>
-				<view class="actions__tips">(任务轨迹监测中,如需暂停请点击暂停任务…)</view>
+				<view class="actions__tips" v-if="dataSource.walk_status === TASK_WALK_TYPE.IS_RECORDING">
+					(任务轨迹监测中,如需暂停请点击暂停任务…)</view>
 			</template>
 		</view>
 		<view class="task-card__footer" v-else>
@@ -131,6 +143,9 @@
 			},
 			handleReceiveClick() {
 				this.$emit('confirm', this.dataSource.task_id);
+			},
+			handleResetRecordLocation() {
+				this.$emit('checkRecordStatus', this.dataSource.task_id)
 			}
 		}
 	}

+ 179 - 13
MingGaoApp/pages/index/clockDetail.vue

@@ -4,11 +4,11 @@
 			<view class="clock-details__title">
 				<uni-icons type="location-filled" color="#fff"></uni-icons>
 				<view class="text">
-					深圳市南山区西丽镇茶光村108号
+					{{address || '暂未获取到具体地址'}}
 				</view>
 			</view>
-			<view class="clock-details__title">
-				<uni-icons type="loop" color="#fff"></uni-icons>
+			<view class="clock-details__title fixed-width" @click="updateCurrentLocation">
+				<uni-icons :type="isPendingLocation?'spinner-cycle':'loop'" color="#fff"></uni-icons>
 				<view class="text">
 					重新定位
 				</view>
@@ -17,33 +17,190 @@
 		<view class="clock-details__body">
 			<view class="clock-details__img-container">
 				<view class="clock-details__imgs">
-					<view class="clock-details__upload">
-						<u-icon size="20" name="plus" color="#409eff"></u-icon>
-					</view>
-					<view class="clock-details__img">
+					<view class="clock-details__img" v-for="item,index in urllist" :key="index+item">
 						<view class="icon">
 							<u-icon name="close" color="#fff"></u-icon>
 						</view>
-						<image :src="baseUrl" mode="" class="img"></image>
+						<image :src="baseUrl+item" mode="" class="img"></image>
+					</view>
+					<view class="clock-details__upload" @click="chooseImage">
+						<u-icon size="20" name="plus" color="#409eff"></u-icon>
 					</view>
 				</view>
 			</view>
 			<view class="clock-details__area">
-				<view class="clock-details__edit-icon">
+				<view class="clock-details__edit-icon" v-if="!isEdit" @click="isEdit=!isEdit">
 					<uni-icons type="compose" color="#1B76FF"></uni-icons>
 				</view>
-				<u--textarea placeholder="" :maxlength="200" autoHeight border="none">
+				<u--textarea :focus="true" v-else v-model="message" placeholder="" :maxlength="200" autoHeight
+					border="none">
 				</u--textarea>
 			</view>
 		</view>
 		<view class="clock-details__footer">
-			<u-button type="primary" text="签到"></u-button>
+			<u-button type="primary" text="签到" @click="handleClockInSubmit"></u-button>
 		</view>
+		<ksp-image-cutter @ok="onok" @cancel="oncancle" :url="kpsurlL" :fixed="false" :blob="false" :maxWidth="500"
+			:maxHeight="500"></ksp-image-cutter>
+		<u-loading-page loading-text="加载中..." :loading="loading" font-size="16"></u-loading-page>
 	</view>
 </template>
 
 <script>
-	export default {}
+	import * as taskService from '@/service/task.js';
+	import {
+		Debounce
+	} from "@/util/anitthro.js"
+
+	export default {
+		data() {
+			return {
+				isEdit: false,
+				latitude: 39.909,
+				longitude: 116.39742,
+				address: '',
+				taskID: '',
+				message: "",
+				logs: [],
+				kpsurlL: '',
+				urllist: [],
+				loading: false,
+				isPendingLocation: false,
+			};
+		},
+		onLoad(options) {
+			console.warn('clock detail ', options)
+			this.taskID = options.taskID;
+		},
+		mounted() {
+			console.log('mounted clock detail')
+			this.updateCurrentLocation();
+		},
+		methods: {
+			updateCurrentLocation() {
+				console.log('updateCurrentLocation ')
+				if (this.isPendingLocation) {
+					return
+				}
+
+				this.isPendingLocation = true;
+				uni.getLocation({
+					type: 'gcj02',
+					// altitude: true, // 高度
+					geocode: true,
+					success: (res) => {
+						console.warn(res, 'get location')
+						console.log('当前位置的经度1:' + res.longitude);
+						console.log('当前位置的纬度1:' + res.latitude);
+
+						this.logs.push(`center-position:当前位置的经度${res.longitude};当前位置的纬度${res.latitude}`)
+
+						this.latitude = res.latitude;
+						this.longitude = res.longitude;
+
+						if (res.address) {
+							const {
+								country,
+								province,
+								city,
+								district,
+								street,
+								streetNum,
+								poiName
+							} = res.address || {};
+							this.address = province + city + district + street + streetNum + poiName;
+						}
+					},
+					fail(err) {
+						console.warn(err, 'get location error')
+					},
+					complete: () => {
+						console.log('complete get location')
+						this.isPendingLocation = false;
+					}
+				});
+			},
+			validate() {
+				if (!this.taskID) {
+					throw new Error('请返回重新进行打卡操作');
+				}
+
+				if (!this.latitude && !this.longitude) {
+					throw new Error('请重新获取下定位信息');
+				}
+
+				if (!this.urllist.length) {
+					throw new Error('请先拍摄图片再进行打卡');
+				}
+
+				if (!this.message) {
+					throw new Error('请输入内容');
+				}
+			},
+			// 签到提交
+			handleClockInSubmit() {
+				try {
+					this.validate();
+				} catch (error) {
+					uni.$u.toast(error.message);
+				}
+
+				this.loading = true;
+				console.log(this.urllist, '------------- clock in submit')
+				const payload = {
+					task_id: this.taskID,
+					message: this.message,
+					img_list: this.urllist,
+					address: this.address,
+					lng: this.longitude,
+					lat: this.latitude
+				}
+				console.warn(payload, 'clock in data');
+				taskService.addTaskClockInData(payload).then(res => {
+					uni.$u.toast('打卡成功');
+					// TODO 返回上一页
+					setTimeout(() => {
+						uni.navigateBack({
+							delta: 1
+						})
+					})
+				}).finally(() => {
+					this.loading = false;
+				})
+			},
+			chooseImage() {
+				uni.chooseImage({
+					count: 1, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['camera'], //从相册选择
+					success: (res) => {
+						console.log(res)
+						// this.urllist.push(res.tempFilePaths[0])
+						this.kpsurlL = res.tempFilePaths[0]
+					}
+				});
+			},
+			oncancle() {
+				this.kpsurlL = ""
+			},
+			onok(ev) {
+				Debounce(() => {
+					uni.uploadFile({
+						url: this.baseUrl +
+							'/api/api_gateway?method=monitor_manage.cbd_manage.add_img', //仅为示例,非真实的接口地址
+						filePath: ev.path,
+						name: 'img_file',
+						success: (uploadFileRes) => {
+							console.log(JSON.parse(uploadFileRes.data).data.src)
+							this.urllist.push(JSON.parse(uploadFileRes.data).data.src)
+							console.log(this.urllist, ' upload file')
+							this.kpsurlL = ""
+						}
+					});
+				}, 1000)()
+			},
+		}
+	}
 </script>
 
 <style lang="scss" scoped>
@@ -60,9 +217,11 @@
 		}
 
 		&__title {
+			// width: 0;
+			flex: 1 1 auto;
 			padding: 48rpx 24rpx;
 			display: flex;
-			align-items: center;
+			align-items: flex-start;
 			font-size: 12px;
 			line-height: 18px;
 			color: #FFFFFF;
@@ -70,6 +229,11 @@
 			.text {
 				margin-left: 10rpx;
 			}
+
+			&.fixed-width {
+				width: 140rpx;
+				flex: 0 0 auto;
+			}
 		}
 
 		&__upload {
@@ -89,12 +253,14 @@
 		&__imgs {
 			position: relative;
 			display: flex;
+			flex-wrap: wrap;
 			align-items: center;
 			padding: 40rpx 0;
 			margin-left: -32rpx;
 		}
 
 		&__img {
+			flex: 0 0 auto;
 			width: 198rpx;
 			height: 198rpx;
 			margin-left: 32rpx;

+ 12 - 0
MingGaoApp/pages/index/components/EntrapmentAdd.vue

@@ -35,7 +35,13 @@
 						<uni-icons type="arrowright" size="12" color="#fff"></uni-icons>
 					</view>
 				</view>
+				<!-- #ifndef APP-NVUE -->
+				<u-input border="none" type="number" v-model="notwornlistdata.num[index]">
+				<!-- #endif -->
+				<!-- #ifdef APP-NVUE -->
 				<u--input border="none" type="number" v-model="notwornlistdata.num[index]">
+					<!-- #endif -->
+
 					<template slot="prefix">
 						<image src="@/static/image/task/pest/statistics.png" mode="aspectFit" class="icon">
 						</image>
@@ -43,7 +49,13 @@
 					<template slot="suffix">
 						<text>头</text>
 					</template>
+
+					<!-- #ifndef APP-NVUE -->
+				</u-input>
+				<!-- #endif -->
+				<!-- #ifdef APP-NVUE -->
 				</u--input>
+				<!-- #endif -->
 				<view class="entrapment-form__close" @click="selectdel(index)">
 					<uni-icons type="clear"></uni-icons>
 				</view>

+ 125 - 33
MingGaoApp/pages/index/components/Gis.vue

@@ -1,11 +1,14 @@
 <template>
-	<view class="gis-card" ref="mapContainer">
+	<view class="gis-card" ref="mapContainer" id="gis-card">
 		<map id="map" ref="map" :show-location="true" :style="{height:contentHeight+'px'}" class="gis-card__content"
 			:latitude="latitude" :longitude="longitude" :markers="covers" :polyline="polylines">
 		</map>
 		<view v-for="(item,index) in logs" :key="index+item">
 			{{item}}
 		</view>
+		<view class="gis-card__action">
+			<u-button text="回放" @click="handleTransformHistory" type="primary" size="mini"></u-button>
+		</view>
 	</view>
 </template>
 
@@ -14,8 +17,12 @@
 		forIn,
 		takeRight,
 		keys,
-		map
+		map,
+		first,
+		isEmpty
 	} from 'lodash-es';
+	import markerIcon from '@/static/pest.png';
+	//walk_lnglat_list 行走轨迹数组字段
 	export default {
 		props: {
 			dataSource: {
@@ -27,35 +34,29 @@
 			return {
 				latitude: 34.809478,
 				longitude: 113.666798,
+				/**
+				 * {
+					id: 1,
+					latitude: 34.809478,
+					longitude: 113.666798,
+					iconPath: '../../../static/location.png'
+				}
+				 */
 				covers: [{
 					id: 1,
 					latitude: 34.809478,
 					longitude: 113.666798,
-					// iconPath: '../../../static/location.png'
+					iconPath: markerIcon
 				}],
 				allLocationDatasource: {
 					'20230211': []
 				},
 				logs: [],
-				contentHeight: 0
+				contentHeight: 0,
+				polylines: [],
+				_mapContext: null
 			}
 		},
-		computed: {
-			polylines() {
-				let lines = []
-				forIn(this.allLocationDatasource, item => {
-					console.log(item, '--------- polylines')
-					lines.push({
-						points: item,
-						color: '#44b449'
-					})
-				})
-
-				console.log(this.allLocationDatasource, 'polylines')
-
-				return lines
-			},
-		},
 		onShow() {
 			console.warn('任务详情 --------- 更新')
 		},
@@ -65,17 +66,72 @@
 		},
 		mounted() {
 			console.warn('-------------------- mounted ------------121313313 gis')
-			console.log(this.$refs.map, 'on ready')
+			console.log(this.$refs.map, 'on ready', this.dataSource.walk_lnglat_list)
+			this.contentHeight = 600;
 			this._mapContext = uni.createMapContext('map', this);
-			this.contentHeight = this.$refs['mapContainer'].$el.clientHeight;
-			console.warn(this.contentHeight, 'warn =sdsafafasf')
-			this.setCenterPosition()
+			console.log(uni.createMapContext('map', this), '------------------ map context 1')
+			this.init();
+			this.$nextTick(() => {
+				console.log('next tick')
+				console.warn('------------------ map context')
+				// this.contentHeight = this.$refs['mapContainer'].$el && this.$refs['mapContainer'].$el
+				// 	.clientHeight || 300;
+				// this.contentHeight = 300;
+				// console.warn(this.contentHeight, 'warn =sdsafafasf')
+				// this.setCenterPosition()
+				
+			})
+
 		},
 		methods: {
+			init() {
+				const lines = map(this.dataSource.walk_lnglat_list, item => {
+					const paths = map(item, locationData => {
+						return {
+							latitude: locationData.lat,
+							longitude: locationData.lng,
+						}
+					})
+
+
+					return {
+						points: paths,
+						color: '#f00',
+						width: 10
+					}
+				})
+
+				console.warn(lines, 'polylines')
+				this.polylines = lines
+
+				this.updateStartLocation();
+			},
+			updateStartLocation() {
+				const {
+					lng,
+					lat
+				} = first(this.dataSource.walk_lnglat_list[0])
+
+				this.latitude = lat;
+				this.longitude = lng;
+
+				this._mapContext.moveToLocation({
+					latitude: lat,
+					longitude: lng
+				})
+
+				this.covers = [{
+					id: 1,
+					latitude: lat,
+					longitude: lng,
+					iconPath: markerIcon
+				}]
+			},
 			setCenterPosition() {
 				uni.getLocation({
 					type: 'gcj02',
 					altitude: true,
+					geocode: true,
 					success: (res) => {
 						console.warn(res, 'get location')
 						console.log('当前位置的经度1:' + res.longitude);
@@ -86,16 +142,16 @@
 						this.latitude = res.latitude;
 						this.longitude = res.longitude;
 
-						this._mapContext.moveToLocation({
-							latitude: res.latitude,
-							longitude: res.longitude
-						})
+						// this._mapContext.moveToLocation({
+						// 	latitude: res.latitude,
+						// 	longitude: res.longitude
+						// })
 
-						this.covers = [{
-							id: 1,
-							latitude: res.latitude,
-							longitude: res.longitude,
-						}]
+						// this.covers = [{
+						// 	id: 1,
+						// 	latitude: res.latitude,
+						// 	longitude: res.longitude,
+						// }]
 					},
 					fail: (err) => {
 						console.warn(err, 'get location error')
@@ -103,12 +159,42 @@
 					}
 				});
 			},
+			handleTransformHistory() {
+
+				const markerID = this.covers[0] && this.covers[0].id
+				console.log('--------------- transform history', markerID)
+
+				// const linePointDataList = map(this.dataSource.walk_lnglat_list[0] || [], item => {
+				// 	return {
+				// 		latitude: item.lat,
+				// 		longitude: item.lng,
+				// 	}
+				// })
+
+				// console.warn(linePointDataList, 'transform history', this._mapContext)
+
+				// this._mapContext.moveAlong({
+				// 	markerId: markerID,
+				// 	path: linePointDataList,
+				// 	duration: 30000,
+				// 	success() {
+				// 		console.log('scucess ----------------------121313')
+				// 	},
+				// 	fail(err) {
+				// 		console.error(err)
+				// 	},
+				// 	complete() {
+				// 		console.log('move complete ----------------------')
+				// 	}
+				// })
+			},
 		}
 	}
 </script>
 
 <style lang="scss" scoped>
 	.gis-card {
+		position: relative;
 		flex: 1 1 auto;
 		width: 100%;
 		height: 100%;
@@ -116,7 +202,13 @@
 
 		&__content {
 			width: 100%;
+			height: 100%;
 			// background-color: #00f;
 		}
+
+		&__action {
+			position: fixed;
+			bottom: 0;
+		}
 	}
 </style>

+ 125 - 5
MingGaoApp/pages/index/details.vue

@@ -18,6 +18,9 @@
 </template>
 
 <script>
+	import {
+		mapState
+	} from 'vuex';
 	import ClockInRecordComponent from './components/ClockInRecord.vue';
 	import EntrapmentComponent from './components/Entrapment.vue';
 	import GisComponent from './components/Gis.vue';
@@ -29,12 +32,21 @@
 			EntrapmentComponent,
 			GisComponent
 		},
+		computed: {
+			...mapState({
+				wornlist: state => state.wornlist
+			})
+		},
 		data() {
 			return {
 				currentComponent: ClockInRecordComponent,
 				taskID: '',
 				loading: false,
-				taskDetail: {}
+				taskDetail: {},
+				draft: [],
+				taskinfo: {},
+				task_type: false,
+				istask: 1 // 任务模块
 			}
 		},
 		onLoad(options) {
@@ -42,18 +54,72 @@
 			this.taskID = options.taskID;
 			this.getTaskDetail()
 		},
+		watch: {
+			wornlist(news, old) {
+				// console.log(this.taskinfo.trap_record_list)
+				console.log(news)
+				this.draft = []
+				this.draft.push(news)
+				for (var i = 0; i < this.taskinfo.trap_record_list.length; i++) {
+					for (var j = 0; j < news; j++) {
+						if (this.taskinfo.trap_record_list[i].id == news.record_id) {
+							this.taskinfo.trap_record_list[i].report_status = news.report_status
+						} else {
+							this.taskinfo.trap_record_list[i].report_status = ""
+						}
+					}
+				}
+				this.taskfillingdraft()
+			},
+			// kpsurlL(news, old) {
+			// 	if (this.istask == 1) {
+			// 		if (news != "") {
+			// 			let pages = getCurrentPages();
+			// 			var page = pages[pages.length - 1];
+			// 			var currentWebview = page.$getAppWebview();
+			// 			currentWebview.setTitleNViewButtonStyle(0, {
+			// 				text: " ",
+			// 			});
+			// 			this.$store.state.kpsurlL = 1
+			// 		} else {
+			// 			let pages = getCurrentPages();
+			// 			var page = pages[pages.length - 1];
+			// 			var currentWebview = page.$getAppWebview();
+			// 			currentWebview.setTitleNViewButtonStyle(0, {
+			// 				text: "提交",
+			// 			});
+			// 			this.$store.state.kpsurlL = 0
+			// 		}
+			// 	}
+
+			// }
+		},
 		methods: {
 			getTaskDetail() {
 				console.warn('get task detail start')
 				if (!this.taskID) {
-					return 
+					return
 				}
 				console.warn('get task detail fetch')
 				this.loading = true;
 				taskService.getTaskDetailByTaskID(this.taskID).then(res => {
 					console.warn(res, 'get task detail')
-					this.taskDetail = res;
-				}).finally(()=>{
+					this.taskDetail = this.taskinfo = res;
+
+					if (this.taskinfo.img_list == "" || this.taskinfo.img_list.length == 0) {
+						this.taskinfo.img_list = []
+					} else {
+						this.taskinfo.img_list = JSON.parse(this.taskinfo.img_list)
+					}
+
+					if (this.taskinfo.task_type == "有害生物监测") {
+						this.task_type = true
+					} else {
+						this.task_type = false
+					}
+
+					this.$store.state.worndatabase = JSON.parse(JSON.stringify(this.taskinfo.trap_record_list))
+				}).finally(() => {
 					this.loading = false;
 				})
 			},
@@ -69,7 +135,61 @@
 						this.currentComponent = GisComponent;
 						break;
 				}
-			}
+			},
+			async taskfillingdraft() { //任务填报接口
+				// this.gettaskinfo()
+
+				var arr = JSON.parse(JSON.stringify(this.$store.state.worndatabase))
+				console.log(this.draft)
+				console.log(arr)
+				for (var i = 0; i < arr.length; i++) {
+					for (var j = 0; j < this.draft.length; j++) {
+						if (arr[i].id == this.draft[j].record_id) {
+							arr.splice(i, 1)
+						}
+					}
+				}
+				for (var i = 0; i < this.taskinfo.trap_record_list.length; i++) {
+					for (var j = 0; j < this.draft.length; j++) {
+						if (this.taskinfo.trap_record_list[i].id == this.draft[j].record_id) {
+							// console.log(this.taskinfo.trap_record_list[i])
+							this.taskinfo.trap_record_list[i].report_status = this.draft[j].report_status
+						}
+					}
+				}
+				this.draft = this.draft.concat(arr)
+				this.$store.state.worndatabase = JSON.parse(JSON.stringify(this.draft))
+				// console.log(arr)
+				for (var i = 0; i < this.draft.length; i++) {
+					if (this.draft[i].id) {
+						this.draft[i]["record_id"] = this.draft[i].id
+					}
+				}
+				console.log(this.draft, "0000")
+				var data = {}
+				if (this.task_type) {
+					data = {
+						task_id: this.task_id, //            是       任务id
+						report_msg: this.textareavalue, //            是       任务汇报内容
+						img_list: JSON.stringify(this.urllist), //            是       图片列表					['http://www.c.com']
+						trap_record_list: JSON.stringify(this.draft),
+					}
+					console.log("有数据", data)
+				} else {
+					data = {
+						task_id: this.task_id, //            是       任务id
+						report_msg: this.textareavalue, //            是       任务汇报内容
+						img_list: JSON.stringify(this.urllist), //            是       图片列表					['http://www.c.com']
+					}
+					console.log("无数据", data)
+				}
+				console.log(data, 555)
+				const res = await this.$myRequest({
+					url: '/api/api_gateway?method=app.task.task_filling_draft',
+					data: data,
+				})
+				// console.log(res)
+			},
 		}
 	}
 </script>

+ 168 - 32
MingGaoApp/pages/index/index.vue

@@ -22,19 +22,36 @@
 			@confirm="handleModalConfirm" @cancel="handleModalCancel" :asyncClose="true">
 		</u-modal>
 		<u-notify ref="uNotify" message=""></u-notify>
+		<u-popup :show="show" @close="close" @open="open" :closeOnClickOverlay="true" :safeAreaInsetTop="true">
+			<view class="task-finished__area">
+				<u--textarea :focus="true" v-model="report_msg" placeholder="" :maxlength="200" autoHeight border="none"
+					style="margin-bottom: 24rpx;">
+				</u--textarea>
+
+				<u-button text="提交" type="primary" size="small" @click="handleSubmit" :disabled="loading"></u-button>
+			</view>
+
+		</u-popup>
 	</view>
 </template>
 
 <script>
+	import HeartBeat from '@/util/HeartBeat.js'
 	import * as taskService from '@/service/task.js';
 	import {
-		TASK_ACTION_TYPE
+		TASK_ACTION_TYPE,
+		TASK_WALK_TYPE
 	} from '@/util/constants.js';
 	import {
 		assign,
-		concat
+		concat,
 	} from 'lodash-es';
 
+	import {
+		mapState,
+		mapActions
+	} from 'vuex'
+
 	export default {
 		data() {
 			return {
@@ -64,15 +81,22 @@
 				taskList: [],
 				confirmModalVisible: false,
 				content: '确认接收次任务?',
-				currentTaskID: ''
+				currentTaskID: '',
+				_heartBeat: null,
+				isUpdateLocation: false,
+				logs: [],
+				show: false,
+				report_msg: ''
 			}
 		},
 		onShow() {
 
 		},
+		onReady() {
+			this._heartBeat = HeartBeat.getInstance(this.recordRatio);
+		},
 		onLoad() {},
 		onReachBottom() {
-			console.log('each bottom ------- 12')
 			const hasMore = this.total > 0 && this.toal > this.page * this.pageSize
 
 			if (hasMore) {
@@ -99,9 +123,13 @@
 
 		},
 		computed: {
+			...mapState({
+				recordRatio: state => state.task.ratio
+			}),
 			offsetLeft() {
 				return
-			}
+			},
+
 		},
 		onShow() {
 			this.page = 1;
@@ -109,6 +137,7 @@
 			this.getTaskList();
 		},
 		methods: {
+			...mapActions(['addLocationData']),
 			click(item) {
 				console.log('item', item);
 			},
@@ -138,7 +167,7 @@
 				switch (type) {
 					case TASK_ACTION_TYPE.START:
 					case TASK_ACTION_TYPE.PAUSE:
-					case TASK_ACTION_TYPE.FINISHED:
+					case TASK_ACTION_TYPE.RESTART:
 						this.updateWalkStatus(type, taskID);
 						break;
 					case TASK_ACTION_TYPE.CLOCK:
@@ -146,6 +175,10 @@
 							url: '/pages/index/clockDetail?taskID=' + taskID
 						})
 						break;
+					case TASK_ACTION_TYPE.FINISHED:
+						this.currentTaskID = taskID;
+						this.show = true;
+						break;
 				}
 			},
 			updateWalkStatus(type, taskID) {
@@ -156,6 +189,9 @@
 					case TASK_ACTION_TYPE.START:
 						message = '任务已经开始';
 						break;
+					case TASK_ACTION_TYPE.RESTART:
+						message = '继续记录';
+						break;
 					case TASK_ACTION_TYPE.PAUSE:
 						message = '任务暂停成功';
 						break;
@@ -164,32 +200,85 @@
 						break;
 				}
 
-				this.$refs.uNotify.show({
-					top: 10,
-					type: 'success',
-					message,
-					duration: 1000 * 3,
-					fontSize: 16,
-					safeAreaInsetTop: true
+				const payload = {
+					task_id: taskID,
+					action: type
+				}
+				console.warn('update status', payload)
+				this.loading = true;
+				taskService.updateTaskWalkStatus(payload).then(() => {
+					this.$refs.uNotify.show({
+						top: 10,
+						type: 'success',
+						message,
+						duration: 1000 * 3,
+						fontSize: 16,
+						safeAreaInsetTop: true
+					})
+					this.getTaskList();
+					// 处理轨迹坐标点
+					this.updateRecordLocation(type, taskID);
+
+				}).finally(() => {
+					this.loading = false;
+				})
+			},
+			updateRecordLocation(type, taskID) {
+				switch (type) {
+					case TASK_ACTION_TYPE.START:
+					case TASK_ACTION_TYPE.RESTART:
+						this.isUpdateLocation = true;
+						this._heartBeat.handle({
+							type: 'record_' + taskID,
+							data: {
+								taskID
+							},
+							handler: this.getLocation
+						})
+						break;
+					case TASK_ACTION_TYPE.PAUSE:
+					case TASK_ACTION_TYPE.FINISHED:
+						this.isUpdateLocation = false;
+
+						this._heartBeat.clearByType('record_' + taskID)
+						break;
+				}
+
+			},
+			getLocation({
+				taskID
+			}) {
+				return new Promise((resolve, reject) => {
+					console.log('getlocation start', this.isUpdateLocation)
+					if (!this.isUpdateLocation) {
+						console.log('getlocation start 1 close')
+						resolve(true)
+						return
+					}
+
+					console.log('getlocation start 2 exec')
+
+					uni.getLocation({
+						type: 'gcj02',
+						success: (res) => {
+							console.log('当前位置的经度:' + res.longitude);
+							console.log('当前位置的纬度:' + res.latitude);
+							this.logs.push(`记录中:当前位置的经度${res.longitude};当前位置的纬度${res.latitude}`)
+							this.addLocationData({
+								id: Date.now(),
+								taskID,
+								latitude: res.latitude,
+								longitude: res.longitude
+							})
+
+							resolve(false)
+						},
+						fail(err) {
+							console.warn(err, 'get location error')
+						}
+					});
 				})
-				// this.loading = true;
-				// taskService.updateTaskWalkStatus({
-				// 	task_id: taskID,
-				// 	action: type
-				// }).then(() => {
-				// 	this.$refs.uNotify.show({
-				// 		top: 10,
-				// 		type: 'error',
-				// 		color: '#000',
-				// 		bgColor: '#e8e8e8',
-				// 		message: 'Hi uView',
-				// 		duration: 1000 * 3,
-				// 		fontSize: 20,
-				// 		safeAreaInsetTop: true
-				// 	})
-				// }).finally(() => {
-				// 	this.loading = false;
-				// })
+
 			},
 			resetTaskList() {
 				this.page = 1;
@@ -205,13 +294,28 @@
 					start_time: this
 						.start_time, //                              非必填                     开始时间
 					end_time: this.end_time,
-					operator_user_name: this.name
+					operator_user_name: this.searchKey
 				};
 
 				taskService.getTaskList(payload).then(res => {
 					console.log(res, 'get task list')
 					this.taskList = this.page === 1 ? res.page_list : concat(this.taskList, res.page_list);
 					this.total = this.total_item;
+
+					res.page_list.forEach(item => {
+						if (item.walk_status === TASK_WALK_TYPE.IS_RECORDING) {
+							this.isUpdateLocation = true;
+							if (!this._heartBeat.hasType('record_' + item.task_id)) {
+								this._heartBeat.handle({
+									type: 'record_' + item.task_id,
+									data: {
+										taskID: item.task_id
+									},
+									handler: this.getLocation
+								})
+							}
+						}
+					})
 					console.warn(this.taskList, 'task list 1345555')
 				}).finally(() => {
 					this.loading = false;
@@ -240,6 +344,32 @@
 				this.currentTaskID = '';
 				this.confirmModalVisible = false;
 			},
+			open() {
+				console.log('open');
+			},
+			close() {
+				this.show = false
+				console.log('close');
+			},
+			handleSubmit() {
+				if (!this.report_msg) {
+					uni.$u.toast('请输入描述');
+					return
+				}
+				this.loading = true;
+				taskService.taskSubmit({
+					task_id: this.currentTaskID,
+					report_msg: this.report_msg
+				}).then(res=>{
+					uni.$u.toast('提交成功');
+					// this.updateWalkStatus(TASK_ACTION_TYPE.FINISHED,this.currentTaskID);
+					this.getTaskList();
+					this.currentTaskID = '';
+				}).finally(()=>{
+					this.show = false;
+					this.loading = false
+				})
+			}
 		}
 	}
 </script>
@@ -333,6 +463,12 @@
 			}
 		}
 	}
+
+	.task-finished {
+		&__area {
+			padding: 24rpx;
+		}
+	}
 </style>
 <style>
 	page {

+ 3 - 0
MingGaoApp/pages/login/login.vue

@@ -119,8 +119,11 @@
 						})
 					}
 				}
+				
+				// #ifdef APP-PLUS
 				plus.runtime.restart(); // 重启App
 				console.log1p('重启App啦')
+				// #endif
 			},
 			async login() {
 				this.isloading = true

+ 26 - 1
MingGaoApp/service/task.js

@@ -30,7 +30,7 @@ export function updateTaskWalkStatus(data) {
 export function getTaskDetailByTaskID(taskID) {
 	return myRequest({
 		url: '/api/api_gateway?method=control_center.task.task_info',
-		data: { 
+		data: {
 			task_id: taskID
 		}
 	})
@@ -42,4 +42,29 @@ export function addTaskClockInData(data) {
 		url: '/api/api_gateway?method=app.task.task_clock_in',
 		data
 	})
+}
+
+// 获取任务记录轨迹频率配置
+export function fetchTaskRecordRatio() {
+	return myRequest({
+		url: '/api/api_gateway?method=app.task.get_walk_rate',
+	})
+}
+
+// 更新任务行走坐标点
+
+export function addTaskRecordLocation(data) {
+	return myRequest({
+		url: '/api/api_gateway?method=app.task.task_walk_lnt_lat',
+		data
+	})
+}
+
+// 任务填报
+
+export function taskSubmit(data) {
+	return myRequest({
+		url: '/api/api_gateway?method=app.task.task_filling',
+		data
+	})
 }

+ 4 - 0
MingGaoApp/store/index.js

@@ -5,6 +5,7 @@ import {
 	slice,
 	isEmpty
 } from 'lodash-es'
+import task from './modules/task.js'
 
 Vue.use(Vuex)
 
@@ -47,6 +48,9 @@ const store = new Vuex.Store({
 		list: () => {
 
 		}
+	},
+	modules:{
+		task
 	}
 })
 

+ 70 - 0
MingGaoApp/store/modules/task.js

@@ -0,0 +1,70 @@
+import Vue from 'vue'
+import dayjs from 'dayjs'
+import {
+	assign,
+	concat,
+	takeRight
+} from 'lodash-es'
+const locationKey = 'gaode_location_data'
+
+import * as taskService from '@/service/task.js'
+
+
+export default {
+	state: {
+		locationDataSource: {},
+		ratio: 60000,
+	},
+	getters: {
+		currentLocationList(state) {
+			const locationDataKey = dayjs().format('YYYYMMDD');
+			return takeRight(state.locationDataSource[locationDataKey] || [], 5)
+		}
+	},
+	mutations: {
+		refreshLocationInfo(state) {
+			uni.getStorage({
+				key: locationKey,
+				success(res) {
+					console.log(res, 'success')
+					Vue.set(state, 'locationDataSource', res.data)
+				},
+				fail(err) {
+					console.log(err, 'fail ---------------222')
+				}
+			})
+		},
+		updateLocationData(state, payload) {
+			const locationDataKey = payload.taskID + dayjs().format('YYYYMMDD');
+			console.log(locationDataKey, 'update location data 1')
+			if (!state.locationDataSource[locationDataKey]) {
+				console.log(locationDataKey, 'update location data 2')
+				Vue.set(state.locationDataSource, locationDataKey, [payload])
+			} else {
+				Vue.set(state.locationDataSource, locationDataKey, concat(state.locationDataSource[locationDataKey] ||
+				[], payload))
+			}
+
+			uni.setStorage({
+				key: locationKey,
+				data: state.locationDataSource,
+			})
+		}
+	},
+	actions: {
+		addLocationData({
+			commit,
+			dispatch
+		}, data) {
+			const payload = {
+				task_id: data.taskID,
+				lng: data.longitude,
+				lat: data.latitude
+			}
+
+			commit('updateLocationData', data);
+			console.warn('add record location', payload)
+			taskService.addTaskRecordLocation(payload)
+		}
+	}
+}

Разница между файлами не показана из-за своего большого размера
+ 17348 - 15749
MingGaoApp/unpackage/dist/dev/app-plus/app-service.js


Разница между файлами не показана из-за своего большого размера
+ 11138 - 10014
MingGaoApp/unpackage/dist/dev/app-plus/app-view.js


Разница между файлами не показана из-за своего большого размера
+ 419 - 49
MingGaoApp/unpackage/dist/dev/app-plus/pages/response/video.js


+ 99 - 0
MingGaoApp/util/HeartBeat.js

@@ -0,0 +1,99 @@
+import {
+	map,
+	remove
+} from 'lodash-es';
+
+class HeartBeatClass {
+	static _instance = null;
+	handlers = [];
+	time = 1000;
+	maxHandlerTimes = 1;
+	_initTimes = 0;
+	timer = 0;
+	instance = null;
+
+	constructor(time = 2000, maxHandlerTimes = 3000) {
+		this.time = time;
+		this.maxHandlerTimes = maxHandlerTimes;
+	}
+
+	static getInstance() {
+		if (!HeartBeatClass._instance) {
+			HeartBeatClass._instance = new HeartBeatClass(...arguments);
+		}
+		return HeartBeatClass._instance;
+	}
+
+	hasType(type) {
+		if (!type) {
+			return
+		}
+
+		return this.handlers.findIndex(item => item.type === type) > -1
+	}
+
+	handle({
+		type,
+		handler,
+		data
+	}) {
+		clearInterval(this.timer);
+		const hasType = this.handlers.findIndex(item => item.type === type) > -1;
+		if (hasType) {
+			remove(this.handlers, item => {
+				return item.type === type;
+			});
+		}
+
+		this.handlers.push({
+			type,
+			data,
+			handler
+		});
+
+		if (!this.handlers.length) {
+			return;
+		}
+
+		this.timer = setInterval(() => {
+			if (this._initTimes < this.maxHandlerTimes) {
+				this._initTimes++;
+
+				Promise.all(
+					map(this.handlers, handleItem => {
+						return handleItem.handler(handleItem.data || {});
+					})
+				).then(res => {
+					remove(this.handlers, (item, index) => {
+						return res[index];
+					});
+
+					if (!this.handlers.length) {
+						clearInterval(this.timer);
+					}
+				});
+			}
+		}, this.time);
+	}
+	
+	clearByType(type){
+		const hasType = this.handlers.findIndex(item => item.type === type) > -1;
+		if (hasType) {
+			remove(this.handlers, item => {
+				return item.type === type;
+			});	
+		}
+	}
+
+	destory() {
+		this._instance = null;
+		this.handlers = [];
+		clearInterval(this.timer);
+	}
+}
+
+const HeartBeat = {
+	getInstance: HeartBeatClass.getInstance
+};
+
+export default HeartBeat;

+ 28 - 25
MingGaoApp/util/api.js

@@ -1,45 +1,48 @@
 import config from "./url.js"
 
-export const myRequest=(options)=>{
+export const myRequest = (options) => {
 	let BASE_URL = config.baseUrl
-	console.log(BASE_URL) 
-	var session_key=""
-	session_key=uni.getStorageSync('session_key')
-	let url=options.url
-	let data=options.data||{}
-	  if (url != 'sysmenage.usermanager.user_login' && url != 'pest.pests.insect_discern') {
-			data.token=session_key
-	  }
+	console.log(BASE_URL)
+	var session_key = ""
+	session_key = uni.getStorageSync('session_key')
+	let url = options.url
+	let data = options.data || {}
+	if (url != 'sysmenage.usermanager.user_login' && url != 'pest.pests.insect_discern') {
+		data.token = session_key
+	}
 	
-	return new Promise((resolve,reject)=>{
+	console.log(data,'---------- my request')
+
+	return new Promise((resolve, reject) => {
 		uni.request({
-			url:BASE_URL+options.url,
-			method:options.method||'POST',
-			header:{
+			url: BASE_URL + options.url,
+			method: options.method || 'POST',
+			header: {
 				"Content-Type": "application/x-www-form-urlencoded",
-				},
-			data:data,
-			success:(res)=>{
+			},
+			data: data,
+			success: (res) => {
 				console.log(res)
-				if(res.data.message!=""){
+				if (res.data.message != "") {
 					console.log(111)
 					uni.showToast({
-						title:res.data.message || '请求接口失败',
-						icon:"none"
+						title: res.data.message || '请求接口失败',
+						icon: "none"
 					})
-					if(res.data.errorCode == 403){
-						setTimeout(()=>{
+					if (res.data.errorCode == 403) {
+						uni.setStorageSync('session_key', '')
+						setTimeout(() => {
 							uni.navigateTo({
-								url:"/pages/login/login"
+								url: "/pages/login/login"
 							})
-						},2000)
+						}, 2000)
 					}
 				}
 				resolve(res.data.data)
 			},
-			fail:(err)=>{
+			fail: (err) => {
 				uni.showToast({
-					title:'请求接口失败'
+					title: '请求接口失败'
 				})
 				reject(err)
 			}

+ 3 - 2
MingGaoApp/util/constants.js

@@ -1,6 +1,7 @@
 export const TASK_ACTION_TYPE = {
-	START: 'START',
-	PAUSE: 'PAUSE',
+	START: 'start',
+	PAUSE: 'stop',
+	RESTART:'restart',
 	CLOCK: 'CLOCK',
 	FINISHED: 'FINISHED',
 }