Browse Source

Merge branch 'master' of http://172.16.90.201:3000/parking/parking_pda

aleyds 4 years ago
parent
commit
e7628d57f1

+ 12 - 1
README.md

@@ -1,6 +1,17 @@
 ## 城市智慧停车PDA
-### H5调试,因为没有app方法,需要如下操作调试
+#### H5调试,因为没有app方法,需要如下操作调试
 - `login.vue中` 找到到 `handleLogin()` 设置设配编号为固定值
+- `App.vue`中 禁用安卓相关函数
+
+#### 安卓打包
+1. 确认安卓环境是最新的(git拉取)
+2. `HBuilder X`中  **发行>原生App-本地打包>生成本地打包App资源**
+3. 打包完成后点击控制台导出路径复制其内容
+4. 找到`Android Studio`中打开`D:\wwwroot\parking_web\android_hull\pda\pda\src\main\assets\apps\__UNI__29ECCC8\www`
+5. 粘贴复制内容覆盖到打开目录
+6. 数据线链接安卓手机并打开开发者模式
+7. `Android Studio`下按`shift+F10`在安卓手机上测试
+8. `Android Studio`下按`ctrl+F10`打包文件在`parking_web\android_hull\pda\pda\build\outputs\apk\release`
 
 
 

+ 5 - 0
common/apiurl.js

@@ -19,6 +19,11 @@ const apiurl = {
 	//收费员密码修改
 	modifyPwdUrl:'/payee/payeeinfo/modifyPwd',
 	
+	//收费员打卡路段信息
+	punchInfoUrl:'/payee/payeeinfo/punchInfo/',
+	//收费员打卡签到
+	punchInUrl:'/payee/payeeinfo/punchIn',
+	
 	//设备注册
 	deviceReg: '/device/pda/accept'
 

+ 7 - 1
common/http.api.js

@@ -23,6 +23,10 @@ const install = (Vue, vm) => {
 	
 	let deviceReg = (params = {}) => vm.$u.post(apiurl.deviceReg, params);
 	
+	let punchInfo = (params = {}) => vm.$u.get(apiurl.punchInfoUrl+params.roadNo);
+	
+	let punchIn = (params = {}) => vm.$u.post(apiurl.punchInUrl, params);	
+	
 	// 将各个定义的接口名称,统一放进对象挂载到vm.$u.api(因为vm就是this,也即this.$u.api)下
 	vm.$u.api = {
 		login,
@@ -33,7 +37,9 @@ const install = (Vue, vm) => {
 		baiduOcr,
 		entranceOutDetail,
 		modifyPwd,
-		deviceReg
+		deviceReg,
+		punchInfo,
+		punchIn
 	};
 }
 

+ 7 - 0
manifest.json

@@ -123,6 +123,13 @@
         "template" : "template.h5.html",
         "router" : {
             "mode" : "hash"
+        },
+        "sdkConfigs" : {
+            "maps" : {
+                "qqmap" : {
+                    "key" : "BOGBZ-2BZ33-O4L32-Y3QJR-PGN66-RFFEL"
+                }
+            }
         }
     }
 }

+ 7 - 0
pages.json

@@ -53,6 +53,13 @@
 				// "navigationStyle":"custom",// 隐藏系统导航栏
 				"navigationBarTitleText": "拍照取证"
 			}
+		},
+		{
+			"path": "pages/attence/attence",
+			"style": {
+				"navigationStyle":"custom",// 隐藏系统导航栏
+				"navigationBarTitleText": "考勤"
+			}
 		}
 	],
 	"globalStyle": {

+ 146 - 0
pages/attence/attence.scss

@@ -0,0 +1,146 @@
+page{
+	background-color: #F4F4F4;
+}
+.wrap{margin-top: 30rpx;}
+.payeeinfo{
+	height: 143rpx;
+	background: #FFFFFF;
+	border-radius: 20rpx;
+	padding-left: 30rpx;
+	margin-bottom: 20rpx;
+	.payeeinfo-text{
+		margin-left: 19rpx;
+		.name{
+			font-size: 30rpx;
+			font-weight: 500;
+			color: #5B5B5B;
+			line-height: 42rpx;
+			letter-spacing: 1px;
+		}
+		.id{
+			font-size: 24rpx;
+			font-weight: 400;
+			color: #5B5B5B;
+			line-height: 33rpx;
+			letter-spacing: 1px;
+		}
+	}
+}
+
+.attence-block{
+	background: #FFFFFF;
+	border-radius: 20rpx;
+	padding: 38rpx 30rpx 69rpx;
+	margin-bottom: 20rpx;
+}
+
+.today-attence{
+	margin-bottom: 71rpx;
+	.today-attence-item{
+		flex: 1;
+		height: 105rpx;
+		padding: 20rpx 23rpx 0;
+		background: #F4F4F4;
+		border-radius: 10rpx;
+		font-weight: 400;
+		letter-spacing: 1px;
+		.u-icon{margin-right: 7rpx;}
+		.work-time{
+			font-size: 28rpx;
+			color: #515151;
+			line-height: 40rpx;
+		}
+		.my-time{
+			font-size: 24rpx;
+			color: #515151;
+			line-height: 33rpx;
+		}
+	}
+	.today-attence-item + .today-attence-item{
+		margin-left: 19rpx;
+	}
+}
+
+.attence-button{
+	width: 249rpx;
+	height: 249rpx;
+	margin: 0 auto 30rpx;
+	border-radius: 50%;
+	border: 20rpx solid #EAF3FE;
+	align-content: center;
+	justify-content: center;
+	background: linear-gradient(180deg, #56ABFF 0%, #0062D5 100%);
+	.attence-button-type{
+		font-size: 36rpx;
+		font-weight: 400;
+		color: #FFFFFF;
+		line-height: 50rpx;
+	}
+	.attence-button-time{
+		font-size: 28rpx;
+		font-weight: 400;
+		color: #A7CCF5;
+		line-height: 40rpx;
+	}
+}
+
+.position-tip{
+	text-align: center;
+	font-size: 24rpx;
+	font-weight: 400;
+	color: #7D7D7D;
+	line-height: 33rpx;	
+	margin-bottom: 37rpx;
+	.u-icon{
+		margin-right: 11rpx;
+	}
+}
+
+.statistics{
+	padding-top: 45rpx;
+	border-top: 1px solid #EAEAEA;
+	.statistics-item{
+		flex: 1;
+		text-align: center;
+		.statistics-item-til{
+			font-size: 30rpx;
+			font-weight: 400;
+			color: #5C5C5C;
+			line-height: 42rpx;
+		}
+		.statistics-item-con{
+			font-size: 30rpx;
+			font-weight: 400;
+			color: #0667D8;
+			line-height: 42rpx;
+			.number{
+				font-size: 50rpx;
+				line-height: 70rpx;
+				letter-spacing: 2px;
+			}
+		}
+	}
+}
+
+.bottom{
+	position: fixed;
+	left: 0;
+	right: 0;
+	bottom: 76rpx;
+}
+
+.remark{
+	.submit-btn{
+		position: absolute;
+		right: 40rpx;
+		top:40rpx;
+	}
+	.content{
+		padding: 40rpx;
+	}
+	.remark-tip{
+		margin-top: 24rpx;
+		font-size: 26rpx;
+		color: #333;
+	}
+}

+ 288 - 0
pages/attence/attence.vue

@@ -0,0 +1,288 @@
+<template>
+	<view>
+		<u-navbar 
+		title="城市智慧停车有限公司" 
+		title-color="#fff" 
+		:custom-back="customBack" 
+		:border-bottom="false"
+		back-icon-color="#CCE8FF" 
+		:background="{background: '#008CFF' }">
+		</u-navbar>
+		
+		<view class="wrap">
+			<view class="payeeinfo u-flex">
+				<u-image src="../../static/img/default-portrait.png" width="87" height="87"></u-image>
+				<view class="payeeinfo-text">
+					<view class="name">{{payeeinfo.payeeName||'智慧停车'}}</view>
+					<view class="id">工号:{{payeeinfo.payeeNo}}</view>
+				</view>
+			</view>
+			<view class="attence-block">
+				<view class="today-attence u-flex">
+					<view class="today-attence-item">
+						<view class="work-time">上班:{{payeeinfo.workStartTime?payeeinfo.workStartTime.slice(11):''}}</view>
+						<view class="my-time" v-if="payeeinfo.isPunchIn">
+							<u-icon name="checkmark-circle-fill" color="#2979ff" size="28"></u-icon>
+							{{payeeinfo.punchInTime?payeeinfo.punchInTime.slice(11):''}}已打卡
+						</view>
+						<view class="my-time" v-else>未打卡</view>
+					</view>
+					<view class="today-attence-item">
+						<view class="work-time">下班:{{payeeinfo.workEndTime?payeeinfo.workEndTime.slice(11):''}}</view>
+						<view class="my-time" v-if="payeeinfo.isPunchOut">
+							<u-icon name="checkmark-circle-fill" color="#2979ff" size="28"></u-icon>
+							{{payeeinfo.punchOutTime?payeeinfo.punchOutTime.slice(11):''}}已打卡
+						</view>
+						<view class="my-time" v-else>未打卡</view>
+					</view>
+				</view>
+				<view class="attence-button u-flex u-flex-wrap" @click="handlePunchIn">
+					<view class="attence-button-type">{{workType|filterWorkType}}打卡</view>
+					<view class="attence-button-time">{{ $u.timeFormat(currentTime, 'hh:MM:ss') }}</view>
+				</view>
+				<view class="position-tip" v-if="!outPosition&&positionInfo">
+					<u-icon name="checkmark-circle-fill" color="#21CF3D" size="28"></u-icon>
+					您已进入考勤范围:{{payeeinfo.roadName}}
+				</view>
+				<view class="position-tip" v-else-if="outPosition&&positionInfo">
+					<u-icon name="checkmark-circle-fill" color="#da0808" size="28"></u-icon>
+					您已超出考勤范围:{{payeeinfo.roadName}}
+				</view>
+				<view class="statistics u-flex">
+					<view class="statistics-item">
+						<view class="statistics-item-til">本月已打卡</view>
+						<view class="statistics-item-con">
+							<span class="number">{{payeeinfo.punched}}</span>
+							天
+						</view>
+					</view>
+					<view class="statistics-item">
+						<view class="statistics-item-til">月目标打卡</view>
+						<view class="statistics-item-con">
+							<span class="number">{{payeeinfo.punchTotal}}</span>
+							天
+						</view>
+					</view>
+				</view>
+			</view>
+			
+		</view>
+		<u-bottom color="#949494">
+			<view class="bottom" slot="content">
+				城市智慧停车 版权所有
+			</view>
+		</u-bottom>
+		
+		<u-popup class="remark" v-model="remarkPopupShow" @close="remarkClose" mode="bottom">
+			<u-button class="submit-btn" type="primary" size="mini" @click="getPunchIn">打卡</u-button>
+			<view class="content">
+				<u-form-item 
+					label="备注" 
+					:label-style="{fontSize:'36rpx'}"
+					label-position="top">
+					<u-input v-model="remark" type="textarea" />
+				</u-form-item>
+				<view class="remark-tip" v-if="remarkTip">{{remarkTip}}</view>
+			</view>
+		</u-popup>
+		<u-toast ref="uToast" />
+	</view>
+</template>
+
+<script>
+	var ALog = uni.requireNativePlugin("AndroidLog")
+	var location = uni.requireNativePlugin("Location")
+	export default{
+		data(){
+			return{
+				roadNo:'',
+				payeeinfo:[],
+				theRoad:[],
+				currentTime: new Date().getTime(), // 获取当前时间
+				outPosition:true,//是否超出打卡范围
+				positionInfo:false,//是否线上位置关系信息
+				remarkPopupShow:false,//备注弹框
+				remarkTip:'',
+				remark:'',
+				workType:1,
+			}
+		},
+		onLoad(){
+			
+		},
+		onShow() {
+			let that = this;
+				
+			setInterval(function () {
+				that.currentTime = new Date().getTime()//修改数据让他可以实时更新
+			}, 1000);
+				
+			this.payeeinfo = this.$store.state.vuex_user;
+			this.roadNo = this.payeeinfo?.roadList?.[0]?.roadNo;
+			// console.log(' this.payeeinfo1', this.payeeinfo);
+			this.getPunchInfo(this.roadNo);
+		},
+		methods:{
+			getLocation(){
+				ALog.info({msg:'请求定位'});
+				uni.showLoading({ title: '定位中'});
+				let that = this;
+				uni.getLocation({
+					type:"gcj02",
+					success : function (res) {
+						uni.hideLoading();
+						console.log("定位返回信息:", res)
+						// alert(res.longitude + "," + res.latitude )
+						ALog.info({msg:res})
+						that.payeeinfo.longitude = res.longitude;
+						that.payeeinfo.latitude = res.latitude;
+						var dst = `${that.payeeinfo.longitude},${that.payeeinfo.latitude}`;
+						var src = res.latitude + ',' + res.longitude;
+						var locRet = location?.distance?.(src, dst);
+						that.positionInfo = true;
+						// console.log('locRet',locRet);
+						ALog.info({msg:locRet.distance})
+						if(locRet<=that.payeeinfo.workDistance){//在打卡范围内
+							that.outPosition = false;
+							console.log('that.workType',that.workType);
+							// debugger;
+							if(that.workType==1){
+								let workStartTime = new Date(that.payeeinfo.workStartTime.replace(/-/g,'/'));
+								if(that.currentTime<=workStartTime.getTime()){
+									
+								}else{//迟到
+									that.remarkTip = '您已迟到!';
+									that.remarkPopupShow = true;
+									return;
+								}
+								console.log('workStartTime',workStartTime.getTime())
+							}else if(that.workType==2){
+								if(that.payeeinfo.isPunchOut){
+									that.$refs.uToast.show({
+										title: '已经打过下班卡!',
+										type: 'error',
+									});
+									return;
+								};
+								let workEndTime = new Date(that.payeeinfo.workEndTime.replace(/-/g,'/'));
+								if(that.currentTime<=workEndTime.getTime()){//
+									that.remarkTip = '还未到下班时间,现在打卡将视为早退!';
+									that.remarkPopupShow = true;
+									return;
+								}
+								console.log('workEndTime',workEndTime.getTime())
+								
+							}
+							that.getPunchIn();
+						}else{//不在打卡范围内
+							that.outPosition = true;
+							// that.remarkPopupShow = true;
+							// console.table({locRet:locRet,workDistance:that.payeeinfo.workDistance,r:locRet<=that.payeeinfo.workDistance});
+							that.$refs.uToast.show({
+								title: '超出打卡范围!',
+								type: 'error',
+							});
+						};
+						
+						
+						
+						
+					},
+					fail: function(res){
+						uni.hideLoading();
+						console.log('getLocation err',res)					
+						ALog.info({msg:'请求错误',err:res})
+					}
+				})
+			},
+			handlePunchIn(){
+				this.getLocation();
+			},
+			remarkClose(){
+				this.remark = '';
+			},
+			getPunchIn(){
+				let that = this;
+				let param ={
+					latitude:that.payeeinfo.latitude,
+					longitude:that.payeeinfo.longitude,
+					remark:that.remark,
+					roadNo:that.payeeinfo.roadNo,
+					workType:that.workType
+				}
+				that.$u.api.punchIn(param)
+				.then(res=>{
+					this.$refs.uToast.show({
+						title: res.msg,
+						type: 'success',
+					});
+					this.remarkPopupShow = false;
+					
+					this.getPunchInfo(this.roadNo);
+					console.log('this.punchIn',res)
+				}).catch(err=>{
+					if(err.errMsg){
+						this.$refs.uToast.show({
+							title: '请检查网络',
+							type: 'error',
+						});
+						return false;
+					};
+					this.$refs.uToast.show({
+						title: err.msg,
+						type: 'error',
+					});
+					console.log('punchIn ',err)
+				});
+			},
+			customBack(){
+				this.$u.route({
+					// type:'switchTab',
+					url: 'pages/index/index'
+				});
+			},
+			getPunchInfo(roadNo){
+				this.$u.api.punchInfo({roadNo:roadNo})
+				.then(res=>{
+					// this.$refs.uToast.show({
+					// 	title: res.msg,
+					// 	type: 'success',
+					// });
+					this.payeeinfo ={...this.payeeinfo,...res.data};
+					
+					if(!res.data.isPunchIn){//还未打上班卡
+						this.workType = 1;
+					}
+					else{//已打上班卡
+						this.workType = 2;
+					}
+					
+					// console.log('this.payeeinfo',this.payeeinfo)
+				}).catch(err=>{
+					if(err.errMsg){
+						this.$refs.uToast.show({
+							title: '请检查网络',
+							type: 'error',
+						});
+						return false;
+					};
+					this.$refs.uToast.show({
+						title: err.msg,
+						type: 'error',
+					});
+					console.log('punchInfo ',err)
+				});
+			}
+			
+		},
+		filters:{
+			filterWorkType(WorkType){
+				return (WorkType==1)?'上班':'下班'
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import  './attence.scss'
+</style>

+ 5 - 3
pages/getout/getout.vue

@@ -134,11 +134,13 @@
 				var days = Math.floor(i_total_secs / (24 * 3600 * 1000))
 					 
 				//计算出小时数
-				var leave1 = i_total_secs % (24 * 3600 * 1000)    //计算天数后剩余的毫秒数
-				var hours = Math.floor(leave1 / (3600 * 1000))
+				// var leave1 = i_total_secs % (24 * 3600 * 1000)    //计算天数后剩余的毫秒数
+				// var hours = Math.floor(leave1 / (3600 * 1000))
+				
+				var hours = Math.floor(i_total_secs / (3600 * 1000))
 				
 				//计算相差分钟数
-				var leave2 = leave1 % (3600 * 1000)        //计算小时数后剩余的毫秒数
+				var leave2 = i_total_secs % (3600 * 1000)        //计算小时数后剩余的毫秒数
 				var minutes = Math.floor(leave2 / (60 * 1000))
 				//计算相差秒数
 				var leave3 = leave2 % (60 * 1000)      //计算分钟数后剩余的毫秒数

+ 2 - 2
pages/getout/getoutpage/getoutpage.vue

@@ -147,10 +147,10 @@
 					 
 				//计算出小时数
 				var leave1 = i_total_secs % (24 * 3600 * 1000)    //计算天数后剩余的毫秒数
-				var hours = Math.floor(leave1 / (3600 * 1000))
+				var hours = Math.floor(i_total_secs / (3600 * 1000))
 				
 				//计算相差分钟数
-				var leave2 = leave1 % (3600 * 1000)        //计算小时数后剩余的毫秒数
+				var leave2 = i_total_secs % (3600 * 1000)        //计算小时数后剩余的毫秒数
 				var minutes = Math.floor(leave2 / (60 * 1000))
 				//计算相差秒数
 				var leave3 = leave2 % (60 * 1000)      //计算分钟数后剩余的毫秒数

+ 1 - 1
pages/index/index.vue

@@ -33,7 +33,7 @@
 				</view>
 			</view>
 			<view class="feature-list u-flex u-flex-wrap u-row-between">
-				<view class="feature-item" @click="$refs.uToast.show({title: '建设中'})">
+				<view class="feature-item" @click="openPage('pages/attence/attence')">
 					<u-image width="120rpx" height="120rpx" src="/static/img/index-feature-01.png"></u-image>
 					<view class="feature-item-text">签到</view>
 				</view>

BIN
static/img/default-portrait.png


+ 2 - 1
uview-ui/components/u-bottom/u-bottom.vue

@@ -1,9 +1,10 @@
 <template>
 	<view class="bottom-wrap" :style="[{customStyle,'color': color || 'rgba(255, 255, 255, 0.5)'}]">
-		<view class="bottom" :style="[customStyle]">
+		<view v-if="!$slots.content" class="bottom" :style="[customStyle]">
 			<view class="bottom-p">如您有任何问题,欢迎拨打服务热线</view>
 			<view class="bottom-p">400-5555-8888</view>
 		</view>
+		<slot name="content" v-else />
 	</view>
 </template>