开发工具
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 版本已经移除了百度地图定位,请注意!!!使用该版本或更高版本,将无法将项目打包。