移动端开发框架mui代码集成百度地图(网页版)实现考勤功能

开发工具
HBuilder X 3.8.12.20230817

注意:开发工具尽量用最新的或较新的。太旧的版本在开发调试过程中可能会出现莫名其妙的问题。

产品说明及开发文档
文档 - DCloud问答


说明
项目需要实现考勤功能,于是集成了百度地图以及结合 html5+plus 相关的api 完成此功能。

开发步骤1

查看官方文档 5+App部分,HTML5+ API Reference,找到定位接口相关说明:

注意定位方法还有额外的参数可以进行设置:

通过官方文档,可以看到使用定位功能,调用这个

plus.geolocation.getCurrentPosition(successCB, errorCB, option);

注意需要在 plus 环境中使用

plus.geolocation.getCurrentPosition(function(p){
		alert('Geolocation\nLatitude:' + p.coords.latitude + '\nLongitude:' + p.coords.longitude + '\nAltitude:' + p.coords.altitude);
	}, function(e){
		alert('Geolocation error: ' + e.message);
	} );

开发步骤2

项目中如何使用

1、项目文件配置

打开项目的配置文件 manifest.json ,找到模块配置项:选择 Geolocation(定位),

由于项目中计划集成百度地图,所以选择百度地图,并提供相应的 appkey 。当然您页可以使用高的地图 或 系统定位

看一下系统定位说明:
Geolocation定位 | uni-app官网

使用系统定位的弊端:
调用设备的操作系统提供的定位服务,只支持wgs84坐标系,不同设备对定位功能支持的情况有所差异。

只可以获取经纬度信息,不支持解析地址信息,即无法返回城市街道信息。
由于设备厂商适配的原因,在部分Android设备上定位服务可能不稳定,如需提升定位功能的稳定性建议使用高德定位腾讯定位

2、页面中使用百度地图
因为是html,所以可以直接在 js 标签中引入即可 (传统网页bs端引入方式)

	<head>
		<meta charset="utf-8">
		<title>考勤管理</title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.min.css" rel="stylesheet" />
		<link href="css/style.css" rel="stylesheet" />
		<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=百度地图平台申请的AK"></script>
	</head>

关于百度地图ak申请及使用方式,请参考这篇文章:

百度地图地图API(常用)_百度地图api用到的网址列表-优快云博客
注意:页面中使用bs方式引入的地图ak 跟 配置文件中配置百度定位的appkey 不是同一个东西
 

3、使用定位模块,获取位置信息

注意需要在 plus 环境中使用

<script>
(function($, doc) { 

    //其他代码
    ......
    ......
     $.plusReady(function() {

         //其他代码
         ......
         ......   
         function getCurrentPosition(){
					plus.geolocation.getCurrentPosition(function(p){
						// console.log("获取用户位置信息:" + JSON.stringify(p));
							// alert('Geolocation\nLatitude:' + p.coords.latitude + '\nLongitude:' + p.coords.longitude + '\nAltitude:' + p.coords.altitude);
					    map.clearOverlays();
						//获取位置成功
						addAddresses = p.addresses;
						addLongitudeLatitude = p.coords.latitude + ',' + p.coords.longitude;
						timestamp = p.timestamp;
						// console.log("gps-timestamp: " + timestamp + " , date-timestamp: " + new Date().getTime());
						document.getElementById("addresses").innerHTML = p.addresses;
						plus.nativeUI.toast("位置已刷新:" + p.addresses);
						var newPoint = new BMap.Point(p.coords.longitude, p.coords.latitude);
						//新建标注
						var mk = new BMap.Marker(newPoint);
						mk.disableDragging(); // 不可拖拽
						map.addOverlay(mk);
						map.centerAndZoom(newPoint, 18);
					}, function(e){
						// alert('Geolocation error: ' + e.message);
						plus.nativeUI.alert("请开启定位权限并设置始终允许!", function(){}, "系统提示", "确定");
					},{enableHighAccuracy: true,provider: 'baidu',coordsType: 'bd09ll', geocode: true} );	
				}   

      })

HTML5+ API Reference 获取定位参数配置

4、项目完整代码

这里有两个页面,一个考勤打卡,一个是考勤历史页面。

考勤打卡页源码:

<!doctype html>
<html>

	<head>
		<meta charset="utf-8">
		<title>考勤管理</title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<link href="css/mui.min.css" rel="stylesheet" />
		<link href="css/style.css" rel="stylesheet" />
		<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=LBkkaBHDcIAMRibnSo50spnl"></script>
	</head>

	<body>
		<br>
		<button type="button" class="mui-btn mui-btn-primary mui-btn-block" style="display: none;" id="onDutyClickButton" >上班打卡</button>
		<button type="button" class="mui-btn mui-btn-primary mui-btn-block" style="display: none;" id="offDutyClickButton" >下班打卡</button>
		<button type="button" class="mui-btn mui-btn-info mui-btn-block" id="refreshAddresesClickButton">刷新位置</button>
		<!-- <h3 id="dateTimeStr">当前时间获取中...</h3> -->
		<div id="dutyInfoHtml" style="display: none;padding-left: 10px;font-size: 20px;">
		</div>
		<div id="dateTimeStr" style="padding-left: 10px;font-size: 24px;font-weight: bold;;color: indigo;">
			当前时间获取中...
		</div>
		<div style="padding-left: 10px;font-size: 20px;padding-top: 10px;">
		当前位置:
		</div>
		<div id="addresses" style="padding-left: 10px;font-size: 20px;padding-top: 5px;;letter-spacing: 0px;color: blue">
		</div>
		<br>
		<div id="allmap" style="padding-top: 0px;;letter-spacing: 0px;width: 100%;height: 210px;">
		</div>
		<script src="js/CryptoJS/aes.js"></script>
		<script src="js/CryptoJS/md5.js"></script>
		<script src="js/mui.min.js"></script>
		<script src="js/mui.pullToRefresh.js"></script> 
		<script src="js/mui.pullToRefresh.material.js"></script>
		<script src="js/mui.picker.min.js"></script>
		<script src="js/mui.poppicker.js"></script>
		<script src="js/app.js"></script>
		<script src="js/mui.zoom.js"></script>
		<script src="js/mui.previewimage.js"></script>
		<script>
		(function($, doc) { 
			$.init({
				statusBarBackground: '#f7f7f7',
				swipeBack:false, //启用右滑关闭功能
				//该属性禁用了当前页面的返回功能,但是还是有双击退出app的功能
				keyEventBind: {
					// backbutton: false  //关闭back按键监听
				}
			}); 
			//阻尼系数
			var deceleration = mui.os.ios?0.003:0.0009;
			$('.mui-scroll-wrapper').scroll({
				scrollY: true, //是否竖向滚动
				bounce: false,
				indicators: true, //是否显示滚动条
				deceleration: 0.0005 //flick 减速系数,系数越大,滚动速度越慢,滚动距离越小,默认值0.0006
			});
			
			
			var settings = {};
			var loginInfo = {}; 
			var addAddresses = null;
			var addLongitudeLatitude = null;
			var timestamp = null;
			$.plusReady(function() {
				settings = app.getSettings();
				if (settings && settings.loginInfo){
					// loginInfo = JSON.parse(settings.loginInfo);
					loginInfo = settings.loginInfo;
				}else{
					plus.nativeUI.alert("用户信息未知,需重新登录", function(){
						plus.runtime.restart();
					}, "系统提示", "确定");
					return;
				}
						
				setInterval(function(){
					var dateTimeStr = getSysDateTimeStr();
					document.getElementById("dateTimeStr").innerHTML = dateTimeStr;
				},1000)
				
				var map = new BMap.Map("allmap");
				//初始化地图 默认加载北京天安门
				var point = new BMap.Point(116.331398, 39.897445);
				map.centerAndZoom(point, 16); //初始化地图,point为中心点,缩放级别为16
				
				findDutyInfo();
				
				// 检查用户是否手动开启权限
				// if (plus.geolocation.hasPermission()) {
				    // 用户已手动开启权限
				    // TODO: 结束
				// } else {
				    // 用户仍未手动开启权限
				    // TODO: 重复提示用户手动开启权限
					// plus.nativeUI.alert("请开启定位权限并设置为始终允许!", function(){
						// plus.runtime.restart();
					// }, "系统提示", "确定");
				// }
				function getCurrentPosition(){
					plus.geolocation.getCurrentPosition(function(p){
						// console.log("获取用户位置信息:" + JSON.stringify(p));
							// alert('Geolocation\nLatitude:' + p.coords.latitude + '\nLongitude:' + p.coords.longitude + '\nAltitude:' + p.coords.altitude);
					    map.clearOverlays();
						//获取位置成功
						addAddresses = p.addresses;
						addLongitudeLatitude = p.coords.latitude + ',' + p.coords.longitude;
						timestamp = p.timestamp;
						// console.log("gps-timestamp: " + timestamp + " , date-timestamp: " + new Date().getTime());
						document.getElementById("addresses").innerHTML = p.addresses;
						plus.nativeUI.toast("位置已刷新:" + p.addresses);
						var newPoint = new BMap.Point(p.coords.longitude, p.coords.latitude);
						//新建标注
						var mk = new BMap.Marker(newPoint);
						mk.disableDragging(); // 不可拖拽
						map.addOverlay(mk);
						map.centerAndZoom(newPoint, 18);
					}, function(e){
						// alert('Geolocation error: ' + e.message);
						plus.nativeUI.alert("请开启定位权限并设置始终允许!", function(){}, "系统提示", "确定");
					},{enableHighAccuracy: true,provider: 'baidu',coordsType: 'bd09ll', geocode: true} );	
				}
				
				function findDutyInfo(){
					var tokenData = localToken;
					var encryptedLoginId = app.GetEncryptData(loginInfo.loginId + "", tokenData, tokenData);
					var encryptedUserId = app.GetEncryptData(loginInfo.id + "", tokenData, tokenData);
					var dataUrl = "userId" + encryptedUserId + "loginToken" + encryptedLoginId + "csrftoken" + tokenData;
					var signData = app.GetSignData(dataUrl);
					var postData = {
						userId: encryptedUserId,
						loginToken: encryptedLoginId,
						sign: signData
					}
					app.ajaxJson(
						'/dayDutyFlow/findDutyInfo',
						postData,
						function(resultObject){
							//请求成功处理
							if (resultObject.code == 1000){
							  var dutyInfo = resultObject.data;
							  // console.log("dutyInfo: " + JSON.stringify(dutyInfo));
							  if (dutyInfo.onOffDutyAllowFlag === 1 && !dutyInfo.onDutyStatus){
								// if (dutyInfo.onDutyStatus === 0){
									document.getElementById("onDutyClickButton").style.display = "inline-block";
								// }
								getCurrentPosition();
							  }else if(dutyInfo.onOffDutyAllowFlag === 2 || dutyInfo.onOffDutyAllowFlag === 3){
									var dutyInfoHtml = "";
									if (dutyInfo.onDutyStatus === 1){
										dutyInfoHtml += '<span style="color:blue;">上班打卡</span>' + '<br>';
										dutyInfoHtml += '打卡时间:' + dutyInfo.onDutyTime + '<br>';
										dutyInfoHtml += '打卡地址:' + dutyInfo.onDutyAddress +'<br>';
										dutyInfoHtml += '<hr>';
									}
									if (dutyInfo.offDutyStatus === 1){
										dutyInfoHtml += '<span style="color:blue;">下班打卡</span>' + '<br>';
										dutyInfoHtml += '打卡时间:' + dutyInfo.offDutyTime + '<br>';
										dutyInfoHtml += '打卡地址:' + dutyInfo.offDutyAddress +'<br>';
										dutyInfoHtml += '<hr>';
									}
									var dutyInfoEl = document.getElementById("dutyInfoHtml");
									dutyInfoEl.innerHTML = dutyInfoHtml;
									dutyInfoEl.style.display = 'inline-block';
									getCurrentPosition();
								}
								if (dutyInfo.onOffDutyAllowFlag === 2 && !dutyInfo.offDutyStatus){
									 // if (dutyInfo.offDutyStatus === 0){
										 document.getElementById("offDutyClickButton").style.display = "inline-block";
									 // }
									 getCurrentPosition();
								}
							  
							}else if(resultObject.code == 1003){
								//登录超时,跳转到登录页面
								plus.nativeUI.alert(resultObject.msg, function(){
									app.clearAllCache();
									setTimeout(function(){
										app.restartApp();
									},1000);
								}, "系统提示", "确定");
							}
							else{
								plus.nativeUI.alert(resultObject.msg, function(){}, "系统提示", "确定");
								return;
							}
						},
						function(errorMsg){
							//请求失败处理
							plus.nativeUI.alert(errorMsg, function(){}, "系统提示", "确定");
						},
						""
					);
				}
				
				function saveDutyInfo(onOffDuty){
					var dateTimestamp = new Date().getTime();
					if (!addAddresses || !addLongitudeLatitude || !timestamp){
						plus.nativeUI.alert('未获取到位置,请刷新或开启定位权限', function(){}, "系统提示", "确定");
						return;
					}else if ((dateTimestamp - timestamp) > 120000){
						plus.nativeUI.alert('当前页面停留过久位置可能发生变化,请刷新位置', function(){}, "系统提示", "确定");
						return;
					}
					
					var tokenData = localToken;
					var encryptedLoginId = app.GetEncryptData(loginInfo.loginId + "", tokenData, tokenData);
					var encryptedUserId = app.GetEncryptData(loginInfo.id + "", tokenData, tokenData);
					var encryptedOnOffDuty = app.GetEncryptData(onOffDuty + "", tokenData, tokenData);
					var encryptedAddresses = app.GetEncryptData(addAddresses, tokenData, tokenData);
					var encryptedLongitudeLatitude = app.GetEncryptData(addLongitudeLatitude, tokenData, tokenData);
					var dataUrl = 
					"userId" + encryptedUserId + 
					"onOffDuty" + encryptedOnOffDuty + 
					"addresses" + encryptedAddresses +
					"longitudeLatitude" + encryptedLongitudeLatitude +
					"loginToken" + encryptedLoginId + 
					"csrftoken" + tokenData;
					var signData = app.GetSignData(dataUrl);
					var postData = {
						userId: encryptedUserId,
						onOffDuty: encryptedOnOffDuty,
						addresses: encryptedAddresses,
						longitudeLatitude: encryptedLongitudeLatitude,
						loginToken: encryptedLoginId,
						sign: signData
					}
					app.ajaxJson(
						'/dayDutyFlow/saveDutyInfo',
						postData,
						function(resultObject){
							//请求成功处理
							if (resultObject.code == 1000){
								addAddresses = null;
								addLongitudeLatitude = null;
								document.getElementById("addresses").innerHTML = '';
								var dutyInfo = resultObject.data;
								// console.log("dutyInfo: " + JSON.stringify(dutyInfo));
								var dutyInfoHtml = "";
								if(dutyInfo.onOffDutyAllowFlag === 2 ){
									if (dutyInfo.onDutyStatus === 1){
										dutyInfoHtml += '<span style="color:blue;">上班打卡</span>' + '<br>';
										dutyInfoHtml += '打卡时间:' + dutyInfo.onDutyTime + '<br>';
										dutyInfoHtml += '打卡地址:' + dutyInfo.onDutyAddress +'<br>';
										dutyInfoHtml += '<hr>';
										document.getElementById("onDutyClickButton").style.display = "none";
										document.getElementById("offDutyClickButton").style.display = "inline-block";
									}
								}else if(dutyInfo.onOffDutyAllowFlag === 3){
									if (dutyInfo.offDutyStatus === 1){
										dutyInfoHtml += '<span style="color:blue;">下班打卡</span>' + '<br>';
										dutyInfoHtml += '打卡时间:' + dutyInfo.offDutyTime + '<br>';
										dutyInfoHtml += '打卡地址:' + dutyInfo.offDutyAddress +'<br>';
										dutyInfoHtml += '<hr>';
										document.getElementById("offDutyClickButton").style.display = "none";
									}
								}
								var dutyInfoEl = document.getElementById("dutyInfoHtml");
								if (!dutyInfoEl.innerHTML){
									dutyInfoEl.innerHTML = dutyInfoHtml;
								}else{
									dutyInfoEl.insertAdjacentHTML("beforeend" , dutyInfoHtml); 	 
								}
								if (dutyInfoEl.style.display=='none' || !dutyInfoEl.style.display){
									dutyInfoEl.style.display = 'inline-block';
								}
								
								if (onOffDuty===1){
									plus.nativeUI.alert("上班打卡成功", function(){}, "系统提示", "确定");
									return;
								}else{
									plus.nativeUI.alert("下班打卡成功", function(){}, "系统提示", "确定");
									return;
								}
								
							}else if(resultObject.code == 1003){
								//登录超时,跳转到登录页面
								plus.nativeUI.alert(resultObject.msg, function(){
									app.clearAllCache();
									setTimeout(function(){
										app.restartApp();
									},1000);
								}, "系统提示", "确定");
							}
							else{
								plus.nativeUI.alert(resultObject.msg, function(){}, "系统提示", "确定");
								return;
							}
						},
						function(errorMsg){
							//请求失败处理
							plus.nativeUI.alert(errorMsg, function(){}, "系统提示", "确定");
						},
						""
					);
				}
				
				var refreshAddresesClickButton = document.getElementById('refreshAddresesClickButton');
				refreshAddresesClickButton.addEventListener('tap' , function(){
					getCurrentPosition();
				});
				
				var onDutyClickButton = document.getElementById('onDutyClickButton');
				onDutyClickButton.addEventListener('tap' , function(){
					plus.nativeUI.confirm("确定提交考勤信息?", function(e){
						if (e.index == 0){ 
							//处理数据
							saveDutyInfo(1);
						}	
					}, "系统提示", ["确定" , "取消"]);	
				});
				var offDutyClickButton = document.getElementById('offDutyClickButton');
				offDutyClickButton.addEventListener('tap' , function(){
					plus.nativeUI.confirm("确定提交考勤信息?", function(e){
						if (e.index == 0){ 
							//处理数据
							saveDutyInfo(2);
						}	
					}, "系统提示", ["确定" , "取消"]);	
				});
				
			})
				
			function getSysDateTimeStr(){
				var dateTimeStr = '';
				var date = new Date();
				var year = date.getFullYear();
				var month = date.getMonth() + 1;
				var myDate = date.getDate();
				var hours = date.getHours();
				var minutes = date.getMinutes();
				var seconds = date.getSeconds();
				var day = date.getDay();
				dateTimeStr += year + '年';
				if (month >= 10){
					dateTimeStr += month + '月';
				}else{
					dateTimeStr += "0" + month + '月';
				}
				if (myDate >= 10){
					dateTimeStr += myDate + '日';
				}else{
					dateTimeStr += "0" + myDate + '日';
				}
				dateTimeStr += ' '
				 dateTimeStr += ' 周' + '日一二三四五六'.charAt(day);
				dateTimeStr += '<br>';
				if (hours >= 10){
					dateTimeStr += hours + '时';
				}else{
					dateTimeStr += "0" + hours + '时';
				}
				if (minutes > 10){
					dateTimeStr += minutes + '分';
				}else{
					dateTimeStr += "0" + minutes + '分';
				}
				if (seconds >= 10){ 
					dateTimeStr += seconds + '秒';
				}else{
					dateTimeStr += "0" + seconds + '秒';
				}
				return dateTimeStr;
			}

	}(mui, document));
	</script>		
	</body>

</html>

考勤历史页源码:

<!doctype html>
<html>
<head>
	<meta charset="utf-8">
	<title>考勤历史</title>
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
	<link href="css/mui.min.css" rel="stylesheet" />
	<link href="css/style.css" rel="stylesheet" />
	<style>
			html,
			body {
				background-color: #efeff4;
			}
			.mui-bar~.mui-content .mui-fullscreen {
				top: 44px;
				height: auto;
			}
			.mui-pull-top-tips {
				position: absolute;
				top: -20px;
				left: 50%;
				margin-left: -25px;
				width: 40px;
				height: 40px;
				border-radius: 100%;
				z-index: 1000;
			}
			.mui-bar~.mui-pull-top-tips {
				top: 24px;
			}
			.mui-pull-top-wrapper {
				width: 42px;
				height: 42px;
				display: block;
				text-align: center;
				background-color: #efeff4;
				border: 1px solid #ddd;
				border-radius: 25px;
				background-clip: padding-box;
				box-shadow: 0 4px 10px #bbb;
				overflow: hidden;
			}
			.mui-pull-top-tips.mui-transitioning {
				-webkit-transition-duration: 200ms;
				transition-duration: 200ms;
			}
			.mui-pull-top-tips .mui-pull-loading {
				/*-webkit-backface-visibility: hidden;
				-webkit-transition-duration: 400ms;
				transition-duration: 400ms;*/
				
				margin: 0;
			}
			.mui-pull-top-wrapper .mui-icon,
			.mui-pull-top-wrapper .mui-spinner {
				margin-top: 7px;
			}
			.mui-pull-top-wrapper .mui-icon.mui-reverse {
				/*-webkit-transform: rotate(180deg) translateZ(0);*/
			}
			.mui-pull-bottom-tips {
				text-align: center;
				background-color: #efeff4;
				font-size: 15px;
				line-height: 40px;
				color: #777;
				margin-bottom: 100px;/** 显示加载提示信息: 没有更多数据了等等。 */
			}
			.mui-pull-top-canvas {
				overflow: hidden;
				background-color: #fafafa;
				border-radius: 40px;
				box-shadow: 0 4px 10px #bbb;
				width: 40px;
				height: 40px;
				margin: 0 auto;
			}
			.mui-pull-top-canvas canvas {
				width: 40px;
			}
			.mui-slider-indicator.mui-segmented-control {
				background-color: #efeff4;
			}
		</style>
</head>
<body  style="background-color: #FFFFFF;">
	<div class="mui-content" style="background-color:#fff;" >
		<div id="slider" class="mui-slider mui-fullscreen">
			<div class="mui-slider-group"> 
				<div id="item1" class="mui-slider-item mui-control-content">
					<div  class="mui-scroll-wrapper">
						<div class="mui-scroll">
							<ul class="mui-table-view mui-table-view-striped mui-table-view-condensed" id="itemList0">
							</ul>					
							<div id="tab-empty0" class="" wdith="100%" style="text-align: center;"><img src="img/icon_empty.png" style="width: 200px;height: 200px;"></div>
						</div>
					</div> 
				</div>
			</div>
		</div>	
	</div>	
	<script src="js/CryptoJS/aes.js"></script>
	<script src="js/CryptoJS/md5.js"></script>
	<script src="js/mui.min.js"></script>
	<script src="js/mui.pullToRefresh.js"></script> 
	<script src="js/mui.pullToRefresh.material.js"></script>
	<script src="js/app.js"></script>
	<script>
	(function($, doc) {
		$.init({
			statusBarBackground: '#f7f7f7',
			swipeBack:false //启用右滑关闭功能
		}); 
		//阻尼系数
		var deceleration = mui.os.ios?0.003:0.0009;
		$('.mui-scroll-wrapper').scroll({
			bounce: false,
			indicators: true, //是否显示滚动条
			deceleration:deceleration
		});
		//查询参数
		var loadRateObject = {
			pageNumber: 1, dataType: 0, userId: 0 , loginId: "", noMore: false
		};
		//初始化下拉刷新、上拉加载控件 
		/**
		 * 下拉刷新具体业务实现
		 */
		function pulldownRefresh(self) {
			loadRateObject.pageNumber = 1;
			loadRateObject.noMore = false;
			getAttendanceRecord(loadRateObject , true , self); 
		}
		/**
		 * 上拉加载具体业务实现
		 */
		function pullupRefresh(self) {
			if (loadRateObject.noMore == false){
				getAttendanceRecord(loadRateObject , false , self);
			}else{
				self.endPullUpToRefresh(true);//参数为true代表没有更多数据了。
			}
		}
		var settings = {};
		var loginInfo = {}; 
		$.plusReady(function() {
			settings = app.getSettings();
			if (settings && settings.loginInfo){
				// loginInfo = JSON.parse(settings.loginInfo);
				loginInfo = settings.loginInfo;
			}else{
				plus.nativeUI.alert("用户信息未知,需重新登录", function(){
					plus.runtime.restart();
				}, "系统提示", "确定");
				return;
			}
		    
			//循环初始化所有下拉刷新,上拉加载。 .mui-slider-group .mui-scroll
			$('.mui-scroll-wrapper .mui-scroll').pullToRefresh({
				down: {
					callback: function() {
						var self = this;
						setTimeout(function(){
							pulldownRefresh(self);
							self.endPullDownToRefresh();
						} , 500);
					}
				},
				up: {
					callback: function() {
						var self = this;
						setTimeout(function() {		
							self.endPullUpToRefresh(loadRateObject.noMore); //参数为true代表没有更多数据了。
							pullupRefresh(self);
							
							//alert("下拉刷新 index : " + index + " , 参数 " + JSON.stringify(loadAlarm0Object));
						}, 500);
					}
				}
			});
			
			//加载考勤修历史
			setTimeout( function(){ 
				//页面加载后,自动加载数据
				$('.mui-scroll-wrapper .mui-scroll').pullToRefresh().pullUpLoading();
			} , 1000);

		})	
		
		//加载考勤历史
		function getAttendanceRecord(loadRateObject , refreshFlag , self){
			var tokenData = localToken;
			var encryptedPageNumber = app.GetEncryptData(loadRateObject.pageNumber + "", tokenData, tokenData);
			var encryptedUserId = app.GetEncryptData(loginInfo.id + "", tokenData, tokenData);
			var encryptedLoginId = app.GetEncryptData(loginInfo.loginId, tokenData, tokenData);
			//var dataUrl = "pageNumber" + encryptedPageNumber + "userId" + encryptedUserId + "loginId" + encryptedLoginId + "searchType" + encryptedSearchType + "csrftoken" + tokenData;
			var dataUrl = "pageNumber" + encryptedPageNumber + "userId" + encryptedUserId + "loginToken" + encryptedLoginId  + "csrftoken" + tokenData;
			var signData = app.GetSignData(dataUrl);
			var postData = { 
				pageNumber: encryptedPageNumber,
				userId: encryptedUserId,
				loginToken: encryptedLoginId,
				sign: signData
			}
			app.ajaxJson(
				'/dayDutyFlow/findAll',
				postData,
				function(resultObject){
					document.getElementById("itemList0").innerHTML = '';
					//请求成功处理
					if (resultObject.code == 1000){ 
						//plus.nativeUI.alert(JSON.stringify(resultObject.data), function(){}, "系统提示: 结果", "确定");
						// console.log("考勤历史:" + JSON.stringify(resultObject.data));
						var pagerObject = resultObject.data;
						if (pagerObject.list && pagerObject.list.length > 0){
							var list = pagerObject.list;
							var totalCount = list.length;
							var tabEnpty =  document.getElementById('tab-empty0');
							if (totalCount > 0){
								tabEnpty.classList.add("mui-hidden");
							}else{
								tabEnpty.classList.remove("mui-hidden"); 
							}
							var htmlContent = '';
							for (var i = 0 ; i < list.length ; i++){
								var record = list[i];
								var id = record.id;
								var onDutyStateText = '完成打卡';

								var dutyDate = record.dutyDate;
								var onDutyTime = record.onDutyTime;
								var onDutyAddress = record.onDutyAddress;
								var onDutyStatus = record.onDutyStatus;
								var offDutyStatus = record.offDutyStatus;
								var offDutyTime = record.offDutyTime;
								var offDutyAddress = record.offDutyAddress;
								// if (offDutyStatus===0){
								// 	onDutyStateText = '下班未打卡';
								// }

								htmlContent += '<li class="mui-table-view-cell mui-collapse" style="font-weight: bold;font-size: 16px;">';
								if (offDutyStatus===0){
									onDutyStateText = '下班未打卡';
									htmlContent += '<a class="mui-navigate-right" style="color:red;" href="#">' + dutyDate + '[' + onDutyStateText + ']' + '</a>';
								}else{
									htmlContent += '<a class="mui-navigate-right" href="#">' + dutyDate + '[' + onDutyStateText + ']' + '</a>';
								}
								
								htmlContent += '<div class="mui-collapse-content">';
								if (onDutyStatus === 1){
									htmlContent += '<span style="color:blue;">上班打卡</span>' + '<br>';
									htmlContent += '打卡时间:' + onDutyTime + '<br>';
									htmlContent += '打卡地址:' + onDutyAddress +'<br>';
									htmlContent += '<hr>';
								}
								if (offDutyStatus === 1){
									htmlContent += '<span style="color:blue;">下班打卡</span>' + '<br>';
									htmlContent += '打卡时间:' + offDutyTime + '<br>';
									htmlContent += '打卡地址:' + offDutyAddress +'<br>';
									htmlContent += '<hr>';
								}
								htmlContent += '</div>';
								htmlContent += '</li>';
							}
							
							//判断是刷新 还是 加载更多
							var itemListObject = document.getElementById("itemList0");
							//判断是查询历史警情 还是报警信息
							if (refreshFlag == true){ 
								//self.endPullToRefresh(); //参数为true代表没有更多数据了。
								//self.pullToRefresh().endPullDownToRefresh();
								self.refresh(true);//重置控件:解决上拉分页查询所有数据后,下拉刷新显示的数据列表无法上拉操作(提示没有更多数据)
								itemListObject.innerHTML = htmlContent;
							}else{
								self.endPullUpToRefresh(false); //参数为true代表没有更多数据了。
								itemListObject.insertAdjacentHTML("beforeEnd" , htmlContent);
							}
							
							//处理加载信息: 当当前当前记录等于总记录
							if (pagerObject.pageNum == pagerObject.pages){ 
								loadRateObject.noMore = true;
							}else{
								var pageNumber = pagerObject.pageNum;
								loadRateObject.pageNumber = pageNumber + 1;
							}
							plus.nativeUI.toast("已为您加载 " + totalCount + " 条记录。");
						}
					
					}else if(resultObject.code == 1003){
						//登录超时,跳转到登录页面
						plus.nativeUI.alert(resultObject.msg, function(){
							app.clearAllCache();
							setTimeout(function(){
								app.restartApp();
							},1000);
						}, "系统提示", "确定");
					}
					else{
						plus.nativeUI.alert(resultObject.msg, function(){}, "系统提示", "确定");
						return;
					}
				},
				function(errorMsg){
					//请求失败处理
					plus.nativeUI.alert(errorMsg, function(){}, "系统提示", "确定");
				},
				""
			);
		}
		
	}(mui, document));	
	</script>
</body>

</html>

开发步骤3

实现效果图

数据库表

CREATE TABLE [dbo].[DayDutyFlow](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[user_id] [int] NULL,
	[user_name] [nvarchar](50) NULL,
	[user_tel] [varchar](50) NULL,
	[group_name] [nvarchar](50) NULL,
	[oper_date] [datetime] NULL,
	[gps_id] [int] NULL,
	[duty_date] [date] NULL,
	[on_duty_status] [tinyint] NOT NULL,
	[on_duty_time] [datetime] NULL,
	[on_duty_address] [nvarchar](200) NULL,
	[on_duty_lnglat] [varchar](100) NULL,
	[off_duty_status] [tinyint] NOT NULL,
	[off_duty_time] [datetime] NULL,
	[off_duty_address] [nvarchar](200) NULL,
	[off_duty_lnglat] [varchar](100) NULL,
 CONSTRAINT [PK__DayDutyF__3213E83FBFC0A971] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

项目总结

项目中这个考勤功能还是比较简单的, 本人实现的考勤只能先上班打卡再进行下班打卡,不打卡当天将无考勤记录,有些地方还不够完善:
1、打开页面获取位置时未做提醒用户打开GPS功能或打开设置指引,而不是调用获取位置时进行提示

2、考勤历史中,未统计未出勤的记录(某天未打卡)

3、没有考勤记录导出功能

4、考勤历史中,无法查看定位

 

问题汇总
 

1、注意配置文件中的定位appkey  和 页面中使用地图所引入的ak值 是不同的


2、注意开发工具从 4.28.2024092502 版本已经移除了百度地图定位,请注意!!!使用该版本或更高版本,将无法将项目打包。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值