Quellcode durchsuchen

考勤打卡,扫码开门

zouling vor 7 Monaten
Ursprung
Commit
4f57d6bc80
100 geänderte Dateien mit 6239 neuen und 228 gelöschten Zeilen
  1. 18 4
      api/mine/order.js
  2. 8 0
      api/system/user.js
  3. 233 0
      api/work/check.js
  4. 47 23
      components/order/list.vue
  5. 570 0
      components/selectMorePicker.vue
  6. 56 0
      components/selectPicker.vue
  7. 408 0
      components/timepick/dataTimePicke.vue
  8. 329 0
      components/timepick/timepick.vue
  9. 40 0
      components/timepick/util/util.js
  10. 4 1
      config.js
  11. 25 11
      manifest.json
  12. 71 3
      pages.json
  13. 54 15
      pages/index/index.vue
  14. 12 9
      pages/login.vue
  15. 37 1
      pages/mine/index.vue
  16. 24 97
      pages/order/info.vue
  17. 0 1
      pages/video/index.vue
  18. 0 0
      plugins/amap-wx.js
  19. BIN
      static/images/addry.png
  20. BIN
      static/images/adress.png
  21. BIN
      static/images/chosebm.png
  22. BIN
      static/images/close.png
  23. BIN
      static/images/home/htabk.png
  24. BIN
      static/images/home/htabl.png
  25. BIN
      static/images/icon_kqdk_jrfw.png
  26. BIN
      static/images/icon_rqxz.png
  27. BIN
      static/images/krules.png
  28. BIN
      static/images/map.png
  29. BIN
      static/images/mine/minek.png
  30. BIN
      static/images/mine/minel.png
  31. BIN
      static/images/mine/minem.png
  32. BIN
      static/images/moico.png
  33. BIN
      static/images/nhead.png
  34. BIN
      static/images/photo.png
  35. BIN
      static/images/pic_mine_hp_normal.png
  36. BIN
      static/images/pimg.png
  37. BIN
      static/images/right.png
  38. BIN
      static/images/serch.png
  39. BIN
      static/images/stepa.png
  40. BIN
      static/images/stepb.png
  41. BIN
      static/images/stepc.png
  42. BIN
      static/images/success.png
  43. BIN
      static/images/time.png
  44. BIN
      static/images/up.png
  45. BIN
      static/images/upimg.png
  46. 8 0
      static/index.html
  47. 4 4
      static/scss/global.scss
  48. 1 0
      static/style.css
  49. 1 0
      store/getters.js
  50. 7 0
      store/modules/user.js
  51. 6 0
      uni.scss
  52. 1 0
      utils/constant.js
  53. 2 2
      utils/initmap.js
  54. 32 0
      utils/location.js
  55. 1 1
      utils/storage.js
  56. 393 0
      work/components/clock/cardlist.vue
  57. 49 10
      work/components/lunc-calendar/lunc-calendar.vue
  58. 19 4
      work/components/yuyue/list.vue
  59. 209 0
      work/pages/clock/abnormal.vue
  60. 73 0
      work/pages/clock/cardSupple.vue
  61. 851 0
      work/pages/clock/clock.vue
  62. 619 0
      work/pages/clock/kaorules.vue
  63. 419 0
      work/pages/clock/outside.nvue
  64. 388 0
      work/pages/clock/personnel.vue
  65. 414 0
      work/pages/clock/setswork.vue
  66. 521 0
      work/pages/clock/setwoek.nvue
  67. 50 0
      work/pages/clock/success.vue
  68. 7 7
      work/pages/record/clockin.vue
  69. 224 30
      work/pages/record/detail.vue
  70. 1 1
      work/pages/yyorder/eat.vue
  71. 0 1
      work/pages/yyorder/eatlistday.vue
  72. 1 1
      work/pages/yyorder/limitdetail.vue
  73. 1 1
      work/pages/yyorder/meetadd.vue
  74. 1 1
      work/pages/yyorder/meeting.vue
  75. BIN
      work/static/clock/addry.png
  76. BIN
      work/static/clock/adress.png
  77. BIN
      work/static/clock/chosebm.png
  78. BIN
      work/static/clock/close.png
  79. BIN
      work/static/clock/down.png
  80. BIN
      work/static/clock/icon_kqdk_jrfw.png
  81. BIN
      work/static/clock/icon_rqxz.png
  82. BIN
      work/static/clock/krules.png
  83. BIN
      work/static/clock/map.png
  84. BIN
      work/static/clock/moico.png
  85. BIN
      work/static/clock/nhead.png
  86. BIN
      work/static/clock/noiconp.png
  87. BIN
      work/static/clock/photo.png
  88. BIN
      work/static/clock/pic_mine_hp_normal.png
  89. BIN
      work/static/clock/pimg.png
  90. BIN
      work/static/clock/rest.png
  91. BIN
      work/static/clock/right.png
  92. BIN
      work/static/clock/serch.png
  93. BIN
      work/static/clock/stepa.png
  94. BIN
      work/static/clock/stepb.png
  95. BIN
      work/static/clock/stepc.png
  96. BIN
      work/static/clock/stepd.png
  97. BIN
      work/static/clock/success.png
  98. BIN
      work/static/clock/successw.png
  99. BIN
      work/static/clock/up.png
  100. BIN
      work/static/clock/updata.png

+ 18 - 4
api/mine/order.js

@@ -15,7 +15,7 @@ export function getReservatAdd(data) {
 	'data':data
   })
 }
-// 查询陵园预约信息列表
+// 查询预约信息列表
 export function getReservatList(data) {
   return request({
     'url': '/system/reservat/list',
@@ -33,7 +33,7 @@ export function getReservatSh(data) {
 }
 // end
 
-// 查询陵园预约配置信息列表
+// 查询预约配置信息列表
 export function getConfigList(data) {
   return request({
     'url': '/reservat/config/list',
@@ -184,8 +184,22 @@ export function getMenuRecordList(data) {
 }
 
 
-
-
+// 获取验证码
+export function sendSmskmFn(data) {
+  return request({
+    'url': '/sendSms/sendRegisterSms',
+    'method': 'post',
+	'data':data,
+  })
+}
+// 控制设备列表-打开
+export function getOpenDzFn(data) {
+  return request({
+    'url': '/camera/yzm/openDz',
+    'method': 'get',
+	'data':data,
+  })
+}
 
 
 

+ 8 - 0
api/system/user.js

@@ -63,3 +63,11 @@ export function findVersion(data) {
     data: data
   })
 }
+// 上传图片
+export function uploadPhoto(data) {
+  return upload({
+    url: '/common/upload',
+    name: data.name,
+    filePath: data.filePath
+  })
+}

+ 233 - 0
api/work/check.js

@@ -0,0 +1,233 @@
+import request from '@/utils/request'
+
+
+// // 获取考勤信息
+// export function getRecord(data) {
+//   return request({
+//     url: '/kaoQin/daKa',
+//     method: 'get',
+//     data: data,
+// 	type:true
+//   })
+// }
+// // 考勤列表
+export function getRecordList(data) {
+  return request({
+    url: '/system/clock/list',
+    method: 'get',
+    data: data
+  })
+}
+// 考勤列表 一周打卡信息-时间自定义
+export function getRecordDayList(data) {
+  return request({
+    url: '/system/clock/info',
+    method: 'get',
+    data: data
+  })
+}
+// 查询打卡人员打卡信息列表system:info:record:list
+export function getRecordPeoList(data) {
+  return request({
+    url: '/system/info/record/list',
+    method: 'get',
+    data: data
+  })
+}
+// 打卡统计-全部system:clock:all:month
+export function getClockCountall(data) {
+  return request({
+    url: '/system/clock/all/month',
+    method: 'get',
+    data: data
+  })
+}
+// 打卡统计-个人system:clock:personage:month
+export function getClockCountper(data) {
+  return request({
+    url: '/system/clock/personage/month',
+    method: 'get',
+    data: data
+  })
+}
+// 打卡
+export function getPunchFn(data) {
+  return request({
+    url: '/system/clock',
+    method: 'post',
+    data: data
+  })
+}
+// // 覆盖打卡
+// export function getPunchputFn(data) {
+//   return request({
+//     url: '/record/put',
+//     method: 'post',
+//     data: data
+//   })
+// }
+// // 打卡类别
+// export function getNormalFn(data) {
+//   return request({
+//     url: '/system/dict/data/type/'+data,
+//     method: 'get',
+// 	type:true
+//   })
+// }
+// //今日考勤统计
+// export function getBackstage(data) {
+//   return request({
+//     url: '/index/backstage',
+//     method: 'post',
+// 	data:data
+//   })
+// }
+// // -获取考勤异常数据信息
+// export function getAbnormalFn(data) {
+//   return request({
+//     url: '/kaoQin/abnormal',
+//     method: 'get',
+// 	data:data,
+// 	type:true
+//   })
+// }
+// //考勤日历
+// export function getCalendarFn(data) {
+//   return request({
+//     url: '/kaoQin/calendar',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+
+// //查询考勤配置system:schedule:query
+export function getMapconfig(data) {
+  return request({
+    url: '/system/schedule/'+data,
+    method: 'get',
+  })
+}
+//保存考勤配置system:schedule:add
+export function getBaoconfig(data) {
+  return request({
+    url: '/system/schedule',
+    method: 'post',
+	data:data
+  })
+}
+//修改考勤配置system:schedule:edit
+export function getXiuconfig(data) {
+  return request({
+    url: '/system/schedule/put',
+    method: 'post',
+	data:data
+  })
+}
+
+// //获取部门用户列表
+// export function getsubordinateList(data) {
+//   return request({
+//     url: '/system/user/subordinateList',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //获取的部门
+// export function getdeptTreeNow(data) {
+//   return request({
+//     url: '/system/user/deptTreeNow',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //获取角色列表
+// export function getoptionselect(data) {
+//   return request({
+//     url: '/system/role/optionselect',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //根据用户编号获取详细信息
+// export function getopuser(data) {
+//   return request({
+//     url: '/system/user/'+data,
+//     method: 'get',
+//   })
+// }
+
+// //部门负责人申请人员划入自己部门
+// export function geapplyFor(data) {
+//   return request({
+//     url: '/system/user/applyFor',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //修改 人员
+// export function getoptionput(data) {
+//   return request({
+//     url: '/system/user/app/put',
+//     method: 'post',
+// 	data:data
+//   })
+// }
+// //删除人员
+// export function getoptionreset(data) {
+//   return request({
+//     url: '/system/user/reset',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //获取可分配的部门人员
+// export function getallocationList(data) {
+//   return request({
+//     url: '/system/user/allocationOne',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //人员对划入部门请求做出回应
+// export function getreply(data) {
+//   return request({
+//     url: '/system/user/reply',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //查询记录信息列表
+// export function getInfolist(data) {
+//   return request({
+//     url: '/system/info/list',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+// //查询未读消息
+// export function getInfoNum(data) {
+//   return request({
+//     url: '/system/info/numberInfo',
+//     method: 'get',
+// 	data:data
+//   })
+// }
+
+
+// //考勤统计
+// export function clockRecord(data) {
+//   return request({
+//     url: '/kaoQin/clockRecord',
+//     method: 'post',
+// 	data:data
+//   })
+// }
+// //考勤规则
+export function clocklist(data) {
+  return request({
+    url: '/system/schedule/list',
+    method: 'get',
+	data:data
+  })
+}
+

+ 47 - 23
components/order/list.vue

@@ -44,27 +44,32 @@
 				<view class="rtop mb15 flexcj">
 					<view class="rlistl flexc">
 						<image :src="time"></image>
-						<view>{{ite.recordTime}} / {{ite.week}}</view>
+						<view>{{ite.date}}</view>
+						 / {{kaWeek(ite.date)}}
 					</view>
-					<view class="right" v-if="ite.type=='N'">
+					<view class="right" v-if="ite.amex>1&&ite.amex<5||ite.pmex>1&&ite.pmex<5">
 						<image :src="ybga"></image>
-						<view>缺卡</view>
-						<!-- <view>迟到</view> -->
+						<view v-if="ite.amex==2 ||ite.pmex==2">外勤</view>
+						<view v-else-if="ite.amex==3 ||ite.pmex==3">迟到</view>
+						<view v-else-if="ite.amex==4||ite.pmex==4">早退</view>
 					</view>	
 				</view>
 				<view class="rbox flexcj">
 					<view class="rboxa">
 						<image :src="bgaimg" class="rbg"></image>
 						<view class="rboxb">
-							<view class="tit">上班08:30</view>
+							<view class="tit">上班{{workTime[0]}}
+							<view class="tips" v-if="ite.amex>1&&ite.amex<5">
+								<block v-if="ite.amex==2">外勤</block>
+								<block v-if="ite.amex==3">迟到</block>
+								<block v-if="ite.amex==4">早退</block>
+							</view>
+							</view>
 							<view class="time flexc">
-								<block v-if="ite.workingTime">
-									<image :src="chose"></image>
-									{{ite.workingTime}}已打卡
-								</block>
-								<block v-else>
-									<image :src="close"></image>
-									未打卡
+								<image :src="chose" v-if="ite.amex!=5"></image>
+								{{ite.am}}
+								<block v-if="ite.amex!=5">
+									已打卡
 								</block>
 							</view>
 						</view>
@@ -72,17 +77,19 @@
 					<view class="rboxa">
 						<image :src="bgbimg" class="rbg"></image>
 						<view class="rboxb">
-							<view class="tit">下班17:30</view>
+							<view class="tit">下班{{workTime[1]}}
+								<view class="tips" v-if="ite.pmex>1&&ite.pmex<5">
+									<block v-if="ite.pmex==2">外勤</block>
+									<block v-if="ite.pmex==3">迟到</block>
+									<block v-if="ite.pmex==4">早退</block>
+								</view>
+							</view>
 							<view class="time flexc">
-								<block v-if="ite.dutyTime">
-									<image :src="chose"></image>
-									{{ite.dutyTime}}已打卡
+								<image :src="chose" v-if="ite.pmex!=5"></image>
+								{{ite.pm}}
+								<block v-if="ite.pmex!=5">
+									已打卡
 								</block>
-								<block v-else>
-									<image :src="close"></image>
-									未打卡
-								</block>
-								<!-- 缺卡 -->
 							</view>
 						</view>
 					</view>
@@ -121,6 +128,12 @@
 				return ''
 			}
 		},
+		workTime:{
+			type: Array,
+			default () {
+				return []
+			}
+		},
 		type:{
 			type: [String,Number],
 			default () {
@@ -151,6 +164,12 @@
 		kaType(data, list) {
 			return selectDictValue(list, data);
 		},
+		kaWeek(data){
+			var weeks = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
+			var date = new Date(data);
+			var week = date.getDay(); //获取当前星期X(0-6,0代表星期天)
+			return weeks[week]
+		},
 		getDelFn(id){
 			var that=this;
 			uni.showModal({
@@ -287,7 +306,10 @@ color: #FFFFFF;position: absolute;left: 0;top: 0;right: 0;bottom: 0;text-align:
 				.rbg{width: 100%;height: 100%;}
 				.rboxb{box-sizing: border-box;padding:14rpx 0 16rpx 28rpx;
 					position: absolute;left: 0;top: 0;right: 0;bottom: 0;
-					.tit{font-weight: 500;font-size: 26rpx;color: #161616;margin-bottom: 10rpx;}
+					.tit{font-weight: 500;font-size: 26rpx;color: #161616;margin-bottom: 10rpx;
+						display: flex;align-items: center;
+						view{flex:0 0 auto;}
+					}
 					.time{font-weight: 500;font-size: 22rpx;color: #666666;
 						image{width: 18rpx;height: 18rpx;margin-right: 14rpx;flex: 0 0 auto;}
 					}
@@ -297,5 +319,7 @@ color: #FFFFFF;position: absolute;left: 0;top: 0;right: 0;bottom: 0;text-align:
 		
 	}
 }
-
+.tips{border-radius: 12rpx;font-weight: 500;font-size: 16rpx;color: #F87C29;border: 2rpx solid #F87C29;height: 28rpx;box-sizing: border-box;
+				display: flex;align-items: center;padding: 0 8rpx;margin-left: 12rpx;flex: 0 0 auto;margin-top: 6rpx;
+			}
 </style>

+ 570 - 0
components/selectMorePicker.vue

@@ -0,0 +1,570 @@
+<template name="aui-picker">
+	<view class="aui-picker" v-if="SHOW" :class="{
+		'aui-picker-in': FADE==1,
+		'aui-picker-out': FADE==0}">
+
+		<view class="aui-picker-main">
+			<view class="aui-mask" @click.stop="close"></view>
+			<view class="aui-picker-header">
+				<view @click.stop="close" class="aui-picker-close">取消</view>
+				<view class="aui-picker-title" v-if="title">{{title}}</view>
+				<!-- <view class="aui-picker-close iconfont iconclose" ></view> -->
+				<!-- <view class="aui-picker-sure" @click.stop="getSure" v-if="titflag">确定</view> -->
+				<view class="aui-picker-sure" @click.stop="getSure">确定</view>
+			</view>
+			<view class="aui-picker-nav">
+				<view class="aui-picker-navitem" v-if="nav.length>0" v-for="(item, index) in nav" :key="index"
+					:data-index="index" :class="[index==navCurrentIndex ? 'active' : '', 'aui-picker-navitem-'+index]"
+					@click.stop="_changeNav($event)">{{item.label}}</view>
+				<!-- :style="{margin: nav.length>2 ? '0 10px 0 0' : '0 30px 0 0'}" -->
+				<view class="aui-picker-navitem" :key="nav.length" :data-index="nav.length"
+					:class="[nav.length==navCurrentIndex ? 'active' : '', 'aui-picker-navitem-'+nav.length]"
+					@click.stop="_changeNav($event)">请选择</view>
+				<!-- :style="{margin: nav.length>2 ? '0 10px 0 0' : '0 30px 0 0'}" -->
+				<view class="aui-picker-navborder" :style="{left: navBorderLeft+'px'}"></view>
+			</view>
+			<view class="aui-picker-content">
+				<view class="aui-picker-lists">
+					<view class="aui-picker-list" v-for="(list, index) in queryItems.length + 1" :key="index"
+						:data-index="index" :class="[index==navCurrentIndex ? 'active' : '']">
+						<view class="aui-picker-list-warp" v-if="index == 0">
+							<view class="aui-picker-item" v-for="(item, key) in items" :key="key" :data-pindex="index"
+								:data-index="key" :data-id="item.id" :data-label="item.label"
+								:class="{'active': result.length>index && result[index].id==item.id}"
+								:style="{'background': touchConfig.index==key && touchConfig.pindex==index ? touchConfig.style.background : ''}"
+								@click.stop="_chooseItem($event)" @touchstart="_btnTouchStart($event)"
+								@touchmove="_btnTouchEnd($event)" @touchend="_btnTouchEnd($event)">{{item.label}}</view>
+						</view>
+						<view class="aui-picker-list-warp" v-else>
+							<view class="aui-picker-item" v-for="(item, key) in queryItems[index-1]" :key="key"
+								:data-pindex="index" :data-index="key" :data-id="item.id" :data-label="item.label"
+								:class="{'active': result.length>index && result[index].id==item.id}"
+								:style="{'background': touchConfig.index==key && touchConfig.pindex==index ? touchConfig.style.background : ''}"
+								@click.stop="_chooseItem($event)" @touchstart="_btnTouchStart($event)"
+								@touchmove="_btnTouchEnd($event)" @touchend="_btnTouchEnd($event)">{{item.label}}</view>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		label: 'aui-picker',
+		props: {
+			title: { //标题
+				type: String,
+				default: ''
+			},
+			titflag: {
+				type: Boolean,
+				default: false,
+			},
+			layer: { //控制几级联动,默认无限级(跟随数据有无下级)
+				type: Number,
+				default: null
+			},
+			data: { //数据 如:[{id: '', label: '', children: [{id: '', label: ''}]}]
+				type: Array,
+				default () {
+					return [
+						// [{id: '', label: '', children: [{id: '', label: ''}]}]
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				SHOW: false,
+				FADE: -1,
+				nav: [],
+				items: [],
+				queryItems: [],
+				navCurrentIndex: 0,
+				navBorderLeft: 25,
+				result: [],
+				touchConfig: {
+					index: -1,
+					pindex: -1,
+					style: {
+						color: '#197DE0',
+						background: '#EFEFEF'
+					}
+				},
+				loadflag: false
+			}
+		},
+		created() {
+			const _this = this;
+		},
+		watch: {
+			data() {
+
+				const _this = this;
+				const data = _this.data;
+				// _this.items = _this._flatten(data, '0')
+				_this.items = data
+			}
+		},
+		mounted() {
+
+		},
+		methods: {
+			// 打开
+			open(e) {
+				const _this = this;
+				if (e == 1) {
+					_this.reset(); //打开时重置picker
+				}
+
+				return new Promise(function(resolve, reject) {
+					_this.SHOW = true;
+					_this.FADE = 1;
+					resolve();
+				});
+			},
+			// 关闭
+			close() {
+				const _this = this;
+				return new Promise(function(resolve, reject) {
+					_this.FADE = 0;
+					const _hidetimer = setTimeout(() => {
+						_this.SHOW = false;
+						_this.FADE = -1;
+						clearTimeout(_hidetimer);
+						resolve();
+					}, 100)
+				});
+			},
+			//重置
+			reset() {
+				const _this = this;
+				_this.queryItems = [];
+				_this.nav = [];
+				_this.navBorderLeft = 25;
+				_this.navCurrentIndex = 0;
+				_this.result = [];
+			},
+			//导航栏切换
+			_changeNav(e) {
+				const _this = this;
+				const index = Number(e.currentTarget.dataset.index);
+				_this.navCurrentIndex = index;
+				const _el = uni.createSelectorQuery().in(this).select(".aui-picker-navitem-" + index);
+				_el.boundingClientRect(data => {
+					_this.navBorderLeft = data.left + 15;
+				}).exec();
+			},
+			//数据选择
+			_chooseItem(e) {
+				console.log(e,88)
+				// 加载的时候禁止点击
+				// if (this.loadflag) {
+				// 	return
+				// }
+				// this.loadflag = true;
+				const _this = this;
+				const id = e.currentTarget.dataset.id;
+				const label = e.currentTarget.dataset.label;
+				// const deptId = e.currentTarget.dataset.deptId;
+				const _arr = [];
+				// 获取新数据
+				// _this.result[_this.navCurrentIndex] = {id: id, label: label, deptId: deptId};
+				// _this.$http.post('boman-system/chinaArea/treeSelect',{deptId: id}).then(res=>{
+				// 	this.loadflag=false;
+				// 	if(res.data.length>0){
+				// 		if(_this.navCurrentIndex == _this.queryItems.length)
+				// 		{ //选择数据
+				// 			_this.queryItems.push(res.data);
+				// 			_this.nav.push({label: label});
+				// 		}
+				// 		else
+				// 		{ //重新选择数据
+				// 			_this.queryItems.splice(_this.navCurrentIndex+1);
+				// 			_this.nav.splice(_this.navCurrentIndex+1);
+				// 			_this.queryItems.splice(_this.navCurrentIndex, 1, res.data);
+				// 			_this.nav.splice(_this.navCurrentIndex, 1, {label: label});
+				// 			//清空后面的选择
+				// 			_this.result.splice(Number(_this.navCurrentIndex+1))
+				// 		}
+				// 		_this.navCurrentIndex = _this.navCurrentIndex + 1;
+				// 		const _el = uni.createSelectorQuery().in(this).select(".aui-picker-navitem-"+_this.navCurrentIndex);
+				// 		setTimeout(()=>{
+				// 			_el.boundingClientRect(data => {
+				// 				_this.navBorderLeft = data.left + 15;
+				// 			}).exec();
+				// 		},100)
+				// 	}else{
+				// 		//无下级数据
+				// 		_this.close().then(()=>{
+				// 			_this.$emit("callback", {status: 0, data: _this.result});
+				// 		});
+				// 	}
+				// })
+				_this.result.splice(Number(_this.navCurrentIndex+1))
+				_this.result[_this.navCurrentIndex] = {
+					id: id,
+					label: label,
+				};
+				if (
+					(!_this._isDefine(_this.layer) && _this._isDefine(_this._deepQuery(_this.data, id).children)) ||
+					(_this.navCurrentIndex < (Number(_this.layer) - 1) && _this._isDefine(_this._deepQuery(_this.data, id)
+						.children))
+				) { //有下级数据
+					_this._deepQuery(_this.data, id).children.forEach(function(item, index) {
+						_arr.push({
+							id: item.id,
+							label: item.label,
+						});
+					});
+					if (_this.navCurrentIndex == _this.queryItems.length) { //选择数据
+						_this.queryItems.push(_arr);
+						_this.nav.push({
+							label: label
+						});
+					} else { //重新选择数据
+						_this.queryItems.splice(_this.navCurrentIndex + 1, 1);
+						_this.nav.splice(_this.navCurrentIndex + 1, 1);
+						_this.queryItems.splice(_this.navCurrentIndex, 1, _arr);
+						_this.nav.splice(_this.navCurrentIndex, 1, {
+							label: label
+						});
+					}
+					_this.navCurrentIndex = _this.navCurrentIndex + 1;
+					const _el = uni.createSelectorQuery().in(this).select(".aui-picker-navitem-" + _this.navCurrentIndex);
+					setTimeout(() => {
+						_el.boundingClientRect(data => {
+							_this.navBorderLeft = data.left + 20;
+						}).exec();
+					}, 100)
+				} else { //无下级数据
+					// _this.close().then(() => {
+					// 	_this.$emit("callback", {
+					// 		status: 0,
+					// 		data: _this.result
+					// 	});
+					// });
+				}
+			},
+			getSure() {
+				this.close().then(() => {
+					this.$emit("callback", {
+						status: 0,
+						data: this.result
+					});
+				});
+			},
+			//递归遍历——将树形结构数据转化为数组格式
+			_flatten(tree, deptId) {
+				return tree.reduce((arr, {
+						id,
+						label,
+						children = []
+					}) =>
+					arr.concat([{
+						id,
+						label,
+					}], this._flatten(children, id)), [])
+			},
+			//根据id查询对应的数据(如查询id=10100对应的对象)
+			_deepQuery(tree, id) {
+				let isGet = false;
+				let retNode = null;
+
+				function deepSearch(tree, id) {
+					for (let i = 0; i < tree.length; i++) {
+						if (tree[i].children && tree[i].children.length > 0) {
+							deepSearch(tree[i].children, id);
+						}
+						if (id === tree[i].id || isGet) {
+							isGet || (retNode = tree[i]);
+							isGet = true;
+							break;
+						}
+					}
+				}
+				deepSearch(tree, id);
+				return retNode;
+			},
+			/***判断字符串是否为空
+			   @param {string} str 变量
+			   @example: aui.isDefine("变量");
+			*/
+			_isDefine(str) {
+				if (str == null || str == "" || str == "undefined" || str == undefined || str == "null" || str ==
+					"(null)" || str == 'NULL' || typeof(str) == 'undefined') {
+					return false;
+				} else {
+					str = str + "";
+					str = str.replace(/\s/g, "");
+					if (str == "") {
+						return false;
+					}
+					return true;
+				}
+			},
+			_btnTouchStart(e) {
+				const _this = this,
+					index = Number(e.currentTarget.dataset.index),
+					pindex = Number(e.currentTarget.dataset.pindex);
+				_this.touchConfig.index = index;
+				_this.touchConfig.pindex = pindex;
+			},
+			_btnTouchEnd(e) {
+				const _this = this,
+					index = Number(e.currentTarget.dataset.index),
+					pindex = Number(e.currentTarget.dataset.pindex);
+				_this.touchConfig.index = -1;
+				_this.touchConfig.pindex = -1;
+			},
+		}
+	}
+</script>
+
+<style scoped>
+	/* ====================
+		多级联动弹窗
+	 =====================*/
+	.aui-picker {
+		width: 100vw;
+		height: 100vh;
+		/* opacity: 0;		 */
+		position: fixed;
+		top: 0;
+		left: 0;
+		z-index: 1200;
+		background: rgba(0, 0, 0, 0.5);
+		/* display: none; */
+	}
+
+	.aui-picker.aui-picker-in {
+		-moz-animation: aui-fade-in .1s ease-out forwards;
+		-ms-animation: aui-fade-in .1s ease-out forwards;
+		-webkit-animation: aui-fade-in .1s ease-out forwards;
+		animation: aui-fade-in .1s ease-out forwards;
+	}
+
+	.aui-picker.aui-picker-out {
+		-moz-animation: aui-fade-out .1s ease-out forwards;
+		-ms-animation: aui-fade-out .1s ease-out forwards;
+		-webkit-animation: aui-fade-out .1s ease-out forwards;
+		animation: aui-fade-out .1s ease-out forwards;
+	}
+
+	.aui-picker-main {
+		width: 100vw;
+		height: 50vh;
+		background: #FFF;
+		border-radius: 15px 15px 0 0;
+		position: absolute;
+		left: 0px;
+		/* bottom: -50vh;		 */
+		bottom: 0vh;
+		z-index: 999;
+	}
+
+	.aui-picker.aui-picker-in .aui-picker-main {
+		-moz-animation: aui-slide-up-screen .2s ease-out forwards;
+		-ms-animation: aui-slide-up-screen .2s ease-out forwards;
+		-webkit-animation: aui-slide-up-screen .2s ease-out forwards;
+		animation: aui-slide-up-screen .2s ease-out forwards;
+	}
+
+	.aui-picker.aui-picker-out .aui-picker-main {
+		-moz-animation: aui-slide-down-screen .2s ease-out forwards;
+		-ms-animation: aui-slide-down-screen .2s ease-out forwards;
+		-webkit-animation: aui-slide-down-screen .2s ease-out forwards;
+		animation: aui-slide-down-screen .2s ease-out forwards;
+	}
+
+	.aui-picker-header {
+		width: 100%;
+		height: 50px;
+		position: relative;
+		z-index: 999;
+		background: #F2F2F2;
+		border-radius: 15px 15px 0 0;
+		display: flex;
+		align-items: center;
+	}
+
+	.aui-picker-header::after {
+		content: '';
+		width: 100%;
+		height: 1px;
+		background: rgba(100, 100, 100, .3);
+		-moz-transform: scaleY(.3);
+		-ms-transform: scaleY(.3);
+		-webkit-transform: scaleY(.3);
+		transform: scaleY(.3);
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		z-index: 999;
+	}
+
+	.aui-picker-title {
+		line-height: 20px;
+		text-align: center;
+		font-size: 17px;
+		color: #333;
+		padding: 15px;
+		box-sizing: border-box;
+		flex: 1;
+		text-align: center;
+		/* position: absolute;
+		left: 50px;
+		right: 50px;
+		top: 0; */
+	}
+
+	.aui-picker-close {
+		font-size: 15px;
+		color: #333333;
+		flex: 0 0 auto;
+		height: 50px;
+		width: 60px;
+		text-align: center;
+		line-height: 50px;
+	}
+
+	.aui-picker-sure {
+		flex: 0 0 auto;
+		font-size: 15px;
+		color: #197DE0;
+		height: 50px;
+		width: 60px;
+		text-align: center;
+		line-height: 50px;
+	}
+
+	/* .aui-picker-close.iconfont{
+		width: 50px;
+		height: 50px;
+		line-height: 50px;
+		text-align: center;
+		font-size: 20px;
+		color: #aaa;
+		border-radius: 0 10px 0 0;
+		position: absolute;
+		right: 0;
+		top: 0;
+	} */
+	.aui-picker-content {
+		width: 100%;
+		height: -webkit-calc(100% - 100px);
+		height: calc(100% - 100px);
+	}
+
+	.aui-picker-nav {
+		width: 100%;
+		height: 50px;
+		text-align: left;
+		padding: 0 20rpx;
+		margin: 0 0 1px 0;
+		justify-content: flex-start;
+		white-space: nowrap;
+		box-sizing: border-box;
+		position: relative;
+		display: flex;
+		align-items: center;
+	}
+
+	.aui-picker-nav::after {
+		content: '';
+		width: 100%;
+		height: 1px;
+		background: rgba(100, 100, 100, .3);
+		-moz-transform: scaleY(.3);
+		-ms-transform: scaleY(.3);
+		-webkit-transform: scaleY(.3);
+		transform: scaleY(.3);
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		z-index: 999;
+	}
+
+	.aui-picker-navitem {
+		flex: 1;
+		max-width: 70px;
+		/* width: 80px; */
+		line-height: 50px;
+		font-size: 16px;
+
+		text-align: center;
+		display: inline-block;
+		overflow: hidden;
+		white-space: nowrap;
+		text-overflow: ellipsis;
+	}
+
+	.aui-picker-navitem.active {
+		color: #197DE0;
+	}
+
+	.aui-picker-navborder {
+		width: 40px;
+		height: 3px;
+		background: #197DE0;
+		border-radius: 5px;
+		transition: left .15s;
+		position: absolute;
+		left: 25px;
+		bottom: 0;
+	}
+
+	.aui-picker-lists {
+		width: 100%;
+		height: 100%;
+		justify-content: space-around;
+		white-space: nowrap;
+	}
+
+	.aui-picker-list {
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+		overflow-y: scroll;
+		display: none;
+		vertical-align: top;
+	}
+
+	.aui-picker-list.active {
+		display: inline-block;
+	}
+
+	.aui-picker-list-warp {
+		width: 100%;
+		height: auto;
+		box-sizing: border-box;
+		padding: 15px 0;
+		display: inline-block;
+	}
+
+	.aui-picker-item {
+		width: 100%;
+		height: 50px;
+		line-height: 50px;
+		padding: 0 15px;
+		box-sizing: border-box;
+		font-size: 15px;
+		color: #333;
+		position: relative;
+	}
+
+	.aui-picker-item.active {
+		color: #197DE0;
+	}
+
+	.aui-picker-item.active::after {
+		content: '✔';
+		font-size: 15px;
+		color: #197DE0;
+		position: absolute;
+		top: 0px;
+		right: 10px;
+	}
+</style>

+ 56 - 0
components/selectPicker.vue

@@ -0,0 +1,56 @@
+<template>
+	<!-- 单列选择器 -->
+	<u-select v-model="is_show" mode="single-column" :value_name="value_name" :label_name="label_name" :list="list"
+		@confirm="confirm" :default-value="selectDefault"></u-select>
+</template>
+
+<script>
+	export default {
+		props: {
+			list: {
+				default () {
+					return []
+				}
+			},
+			title: {
+				default () {
+					return ''
+				}
+			},
+			value_name: {
+				default () {
+					return 'value'
+				}
+			},
+			label_name: {
+				default () {
+					return 'label'
+				}
+			}
+		},
+		data() {
+			return {
+				is_show: false,
+				selectDefault: [0],
+			}
+		},
+		methods: {
+			show() {
+				this.is_show = true
+				// console.log(this.list)
+			},
+			hide() {
+				this.is_show = false
+			},
+			confirm(e) {
+				// console.log(e)
+				// 将默认下标赋值为当前选中的下标
+				this.selectDefault = [this.list.findIndex(item => item.value === e[0].value)] || [0];
+				this.$emit('vacChange', e)
+			}
+		},
+	}
+</script>
+
+<style>
+</style>

+ 408 - 0
components/timepick/dataTimePicke.vue

@@ -0,0 +1,408 @@
+<template>
+<!--    https://ext.dcloud.net.cn/plugin?id=2400    -->
+	<view class="date-time-picker" v-if="visible">
+		<view class="date-time-mask" @click.stop="hide"></view>
+		<view class="date-time-container" @click.stop="handleEvent">
+			<view class="time-picker-tool" v-if='isShowToolBar'>
+				<view :class="[cancelButtonClass]" @click.stop="cancel">
+					<text>{{cancelButtonText}}</text>
+				</view>
+				<view :class="[toolBarTitleClass]">
+					<text>{{toolBarTitle}}</text>
+				</view>
+				<view :class="[confirmButtonClass]" @click.stop="confirm">
+					<text>{{confirmButtonText}}</text>
+				</view>
+			</view>
+			<picker-view class="picker-view" :indicator-style="indicatorStyleString" :value="dateTime" @change="dateTimePickerChange">
+				<picker-view-column data-id='year' v-if='isShowYear'>
+					<view class="item" v-for="(item,index) in years" :key="index">{{item}}年</view>
+				</picker-view-column>
+				<picker-view-column data-id='month' v-if='isShowMonth'>
+					<view class="item" v-for="(item,index) in months" :key="index">{{item}}月</view>
+				</picker-view-column>
+				<picker-view-column data-id='day' v-if='isShowDay'>
+					<view class="item" v-for="(item,index) in days" :key="index">{{item}}日</view>
+				</picker-view-column>
+				<picker-view-column data-id='hour' v-if='isShowHour'>
+					<view class="item" v-for="(item,index) in hours" :key="index">{{item}}时</view>
+				</picker-view-column>
+				<picker-view-column data-id='minute' v-if='isShowMinute'>
+					<view class="item" v-for="(item,index) in minutes" :key="index">{{item}}分</view>
+				</picker-view-column>
+				<picker-view-column data-id='second' v-if='isShowSecond'>
+					<view class="item" v-for="(item,index) in seconds" :key="index">{{item}}秒</view>
+				</picker-view-column>
+			</picker-view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import {
+		getOneMonthDays,
+		getTimeArray,
+		addZero,
+		getIndexOfArray
+	} from '@/components/timepick/util/util.js'
+	export default {
+		name: 'DateTimePicker',
+		props: {
+			startYear: {
+				type: Number,
+				default: 1900
+			},
+			endYear: {
+				type: Number,
+				default: new Date().getFullYear()+10
+			},
+			isShowToolBar: {
+				type: Boolean,
+				default: true
+			},
+			cancelButtonText: {
+				type: String,
+				default: '取消'
+			},
+			cancelButtonClass: {
+				type: String,
+				default: 'cancel-btn'
+			},
+			toolBarTitle: {
+				type: String,
+				default: '请选择'
+			},
+			toolBarTitleClass: {
+				type: String,
+				default: 'tool-title'
+			},
+			confirmButtonText: {
+				type: String,
+				default: '确定'
+			},
+			confirmButtonClass: {
+				type: String,
+				default: 'confirm-btn'
+			},
+			datestring: {
+				type: String,
+				default: ''
+			},
+			type: {
+				/**
+				 * date 年月日
+				 * year-month 年月
+				 * year 年
+				 * datetime 年月日 时分
+				 * datetime-all 年月日 时分秒
+				 * time 时分秒
+				 * hour-minute 时分
+				 */
+				type: String,
+				default: 'date'
+			},
+			indicatorStyle: {
+				type: Object,
+				default: null
+			}
+		},
+		data() {
+			return {
+				visible: false,
+				dateTime: [],
+				days: [],
+				indicatorStyleString: ''
+			}
+		},
+		watch: {
+			indicatorStyle(val){
+				this.getIndicatorStyle();
+			},
+			type() {
+				this.initDateTime()
+			},
+			datestring(){
+				this.initDateTime()
+			}
+		},
+		computed: {
+			years() {
+				return this.initTimeData(this.endYear, this.startYear);
+			},
+			isShowYear() {
+				return this.type !== 'time' && this.type !== 'hour-minute';
+			},
+			months() {
+				return this.initTimeData(12, 1);
+			},
+			isShowMonth() {
+				return this.type !== 'year' && this.type !== 'time' && this.type !== 'hour-minute';
+			},
+			isShowDay() {
+				return this.type === 'date' || this.type === 'datetime' || this.type === 'datetime-all';
+			},
+			hours() {
+				return this.initTimeData(23, 0);
+			},
+			isShowHour() {
+				return this.type !== 'date' && this.type !== 'year-month' && this.type !== 'year';
+			},
+			minutes() {
+				return this.initTimeData(59, 0);
+			},
+			isShowMinute() {
+				return this.type !== 'date' && this.type !== 'year-month' && this.type !== 'year';
+			},
+			seconds() {
+				return this.initTimeData(59, 0);
+			},
+			isShowSecond() {
+				return this.type === 'datetime-all' || this.type === 'time';
+			}
+		},
+		methods: {
+			getIndicatorStyle(){
+				if(this.indicatorStyle){
+					for(let key in this.indicatorStyle){
+						this.indicatorStyleString += `${key}:${this.indicatorStyle[key]};`
+					}
+				}
+			},
+			handleEvent() {
+				return;
+			},
+			cancel() {
+				this.hide();
+			},
+			confirm() {
+				this.formatDate();
+				this.hide();
+			},
+			show() {
+				this.visible = true;
+			},
+			hide() {
+				this.visible = false;
+			},
+			initDateTime() {
+				let value;
+				if (this.datestring.length > 0) {
+					if (this.type === 'year') {
+						value = new Date(this.datestring, 0);
+					} else if (this.type === 'time' || this.type === 'hour-minute') {
+						let date = new Date();
+						let ary = this.datestring.split(':');
+						ary.forEach((item, index) => {
+							if (index == 0) {
+								date.setHours(item)
+							} else if (index == 1) {
+								date.setMinutes(item)
+							} else if (index == 2) {
+								date.setSeconds(item)
+							}
+						})
+						value = date;
+					} else {
+						value = new Date(this.datestring.replace(/-/g, '/'));
+					}
+
+				} else {
+					value = new Date();
+				}
+				let len, timeArray, index;
+				let array = getTimeArray(value);
+				let [year, month, day, hour, minute, second] = array;
+				this.days = this.initTimeData(getOneMonthDays(year, month-1), 1);
+				let names = ['year', 'month', 'day', 'hour', 'minute', 'second'];
+				switch (this.type) {
+					case "date":
+						len = 3;
+						break;
+					case "year-month":
+						len = 2;
+						break;
+					case "year":
+						len = 1;
+						break;
+					case "datetime":
+						len = 5;
+						break;
+					case "datetime-all":
+						len = 6;
+						break;
+					case "time":
+						len = 3;
+						break;
+					case "hour-minute":
+						len = 2;
+						break;
+				}
+				timeArray = new Array(len).fill(0);
+				if (this.type === 'time' || this.type === 'hour-minute') {
+					names = names.slice(3);
+					array = array.slice(3);
+				}
+				timeArray = timeArray.map((item, index) => {
+					const name = names[index];
+					return getIndexOfArray(array[index], this[name + 's'])
+				})
+				this.dateTime = timeArray;
+			},
+			initTimeData(end, start) {
+				let timeArray = [];
+				while (start <= end) {
+					timeArray.push(start);
+					start++;
+				}
+				return timeArray;
+			},
+			formatDate() {
+				let names = ['year', 'month', 'day', 'hour', 'minute', 'second'];
+				let dateString, formatDateArray = [];
+				if (this.type === 'date' || this.type === 'year-month' || this.type === 'year') {
+					formatDateArray = this.dateTime.map((item, index) => {
+						return this[names[index] + 's'][item] < 10 ? addZero(this[names[index] + 's'][item]) : this[names[index] + 's'][item];
+					})
+					dateString = formatDateArray.join('-');
+				} else if (this.type === 'time' || this.type === 'hour-minute') {
+					names = names.splice(3);
+					formatDateArray = this.dateTime.map((item, index) => {
+						return this[names[index] + 's'][item] < 10 ? addZero(this[names[index] + 's'][item]) : this[names[index] + 's'][item];
+					})
+					dateString = formatDateArray.join(':');
+				} else {
+					let name1 = names.splice(0, 3);
+					formatDateArray = this.dateTime.map((item, index) => {
+						if (index > 2) {
+							return this[names[index - 3] + 's'][item] < 10 ? addZero(this[names[index - 3] + 's'][item]) : this[names[index - 3] + 's'][item];
+						} else {
+							return this[name1[index] + 's'][item] < 10 ? addZero(this[name1[index] + 's'][item]) : this[name1[index] + 's'][item];
+						}
+					})
+					dateString = formatDateArray.splice(0, 3).join('-') + ' ' + formatDateArray.join(':');
+				}
+				this.$emit('change', dateString)
+			},
+			dateTimePickerChange(e) {
+				let columns = e.target.value;
+				if (this.type === 'date' || this.type === 'datetime' || this.type === 'datetime-all') {
+					this.dateTime.splice(0, 1, columns[0]);
+					if (columns[0] != this.dateTime[0]) {
+						this.days = this.initTimeData(getOneMonthDays(this.years[this.dateTime[0]], this.months[this.dateTime[1]]), 1);
+						if (this.dateTime[1] == 1) {
+							if (this.dateTime[2] === this.days.length - 1) {
+								if (getOneMonthDays(this.years[columns[0]], this.dateTime[1]) < getOneMonthDays(this.years[this.dateTime[0]],this.dateTime[1])) {
+									this.dateTime.splice(2, 1, this.days.length - 1)
+								}
+							}
+						}
+					} else {
+						this.dateTime.splice(1, 1, columns[1]);
+						this.days = this.initTimeData(getOneMonthDays(this.years[this.dateTime[0]], this.dateTime[1]), 1);
+						if (columns[1] != this.dateTime[1]) {
+							if (this.dateTime[1] == 1) {
+								if (this.dateTime[2] === this.days.length - 1) {
+									if (getOneMonthDays(this.years[columns[0]], this.dateTime[1]) < getOneMonthDays(this.years[this.dateTime[0]],
+											this.dateTime[1])) {
+										this.dateTime.splice(2, 1, this.days.length - 1)
+									}
+								}
+							} else {
+								if (this.dateTime[2] > this.days.length - 1) {
+									this.dateTime.splice(2, 1, this.days.length - 1)
+								} else {
+									this.dateTime.splice(2, 1, columns[2])
+								}
+							}
+						} else {
+							this.dateTime.splice(2, 1, columns[2])
+						}
+					}
+					if (columns.length > 2) {
+						columns.splice(3).forEach((column, index) => {
+							this.dateTime.splice(index + 3, 1, column);
+						})
+					}
+				} else {
+					columns.forEach((column, index) => {
+						this.dateTime.splice(index, 1, column);
+					})
+				}
+				if (!this.isShowToolBar) {
+					this.formatDate();
+				}
+			},
+		},
+		mounted() {
+			this.getIndicatorStyle();
+			this.initDateTime();
+		}
+	}
+</script>
+
+<style lang='scss' scoped>
+	.date-time-picker {
+		.date-time-mask {
+			position: fixed;
+			top: 0;
+			bottom: 0;
+			left: 0;
+			right: 0;
+			background-color: rgba($color: #000000, $alpha: .5);
+			z-index: 1110;
+		}
+
+		.date-time-container {
+			position: fixed;
+			height: 50%;
+			bottom: 0;
+			right: 0;
+			left: 0;
+			background-color: #f6f6f6;
+			z-index: 1200;
+			display: flex;
+			flex-direction: column;
+
+			.time-picker-tool {
+				height: 80rpx;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				font-size: 28rpx;
+
+				.cancel-btn {
+					padding: 0 28rpx;
+					box-sizing: border-box;
+					color: #969799;
+				}
+
+				.tool-title {
+					font-weight: 500;
+					font-size: 16px;
+					max-width: 50%;
+					overflow: hidden;
+					white-space: nowrap;
+					text-overflow: ellipsis;
+				}
+
+				.confirm-btn {
+					padding: 0 28rpx;
+					box-sizing: border-box;
+					color: #576b95;
+				}
+			}
+
+			.picker-view {
+				width: 100%;
+				flex: 1;
+
+				.item {
+					font-size: 34rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+			}
+		}
+	}
+</style>

+ 329 - 0
components/timepick/timepick.vue

@@ -0,0 +1,329 @@
+<template>
+	<view :show="show && !disabled" mode="bottom" :round="round">
+		<view class="time-content">
+			<view class="header-top">
+				<slot name="header">
+					<view class="cancel" @click="cancel">{{cancelText}}</view>
+					<view class="title">{{title}}</view>
+					<view class="confirm" @click="confirm">{{confirmText}}</view>
+				</slot>
+			</view>
+			<view class="time-wrapper">
+				<picker-view
+					:value="pickerValue" 
+					indicator-class="picker-box"
+					:indicator-style="indicatorStyle"
+					@change="bindChange"
+				>
+					<picker-view-column v-for="(item,index) in innerColumns" :key="index">
+					    <view class="item" v-for="(item1,index1) in item.values" :key="index1">
+							{{item1}}{{item.label}}
+						</view>
+					</picker-view-column>
+				</picker-view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+	export default {
+		name: 'GDatepicker',
+		/**
+		 * 插槽
+		 * header  自定义头部样式
+		 */
+		props:{
+			value:{
+				type: [String,Number],
+				default:''
+			},
+			show: {
+				type:[Boolean,String],
+				default:false
+			},
+			cancelText: {
+				type:String,
+				default:'取消'
+			},
+			confirmText: {
+				type:String,
+				default:'确定'
+			},
+			title: {
+				type:String,
+				default:'时间选择'
+			},
+			/**
+			 * 是否格式化时间
+			 * format 格式同 uView timeFormat API,如:"yyyy-mm-dd"
+			 * 格式可以自由搭配: 年为"yyyy",月为"mm",日为"dd",时为"hh",分为"MM",秒为"ss",
+			 * 注意分为 大写M
+			  */
+			format: {
+				type:String,
+				default:''
+			},
+			// 是否转换成json格式数据 如:2020-01-01T19:19:20.253Z
+			formatToJson: {
+				type: Boolean,
+				default: false
+			},
+			/**
+			 * 时间模式(选择器可选时间格式)(如果mode为date,则format不应包含时分秒格式)
+			 * datetime  全时间:年月日时分秒
+			 * date  只包含年月日
+			 */
+			mode: {
+				type: String,
+				default: 'datetime'
+			},
+			// 可选的最大时间 时间戳毫秒 默认后十年
+			maxDate: {
+				type: [String, Number],
+				default: new Date(new Date().getFullYear() + 10, 0, 1).getTime(),
+			},
+			// 可选的最小时间 时间戳毫秒 默认前十年
+			minDate: {
+				type: [String, Number],
+				default: new Date(new Date().getFullYear() - 10, 0, 1).getTime(),
+			},
+			minMonth: {
+				type: [String, Number],
+				default: 1
+			},
+			maxMonth: {
+				type: [String, Number],
+				default: 12
+			},
+			minDay: {
+				type: [String, Number],
+				default: 1
+			},
+			maxDay: {
+				type: [String, Number],
+				default: 31
+			},
+			// 弹窗圆角值
+			round: {
+				type: [String, Number],
+				default:0
+			},
+			disabled:{
+				type:Boolean,
+				default:false
+			}
+		},
+        model: {
+			prop: 'value',
+			event: 'input'
+		},
+		data() {
+			return {
+				year: 2022,
+				month: 0,
+				day: 0,
+				hour: 0,
+				minute: 0,
+				second: 0,
+				pickerValue: [], // picker-view绑定值
+				innerColumns: [],
+				indicatorStyle: `color: red;!important`
+			}
+		},
+		watch:{
+			show(val) { 
+				if(val) {
+                    this.initData()
+					if(this.value) {
+						this.setData(this.value)
+					} else {
+						this.setData()
+					}
+				}
+			}
+		},
+		// mounted() {
+			// this.initData()
+		// },
+		methods: {
+			initData() {
+				const startYear = new Date(Number(this.minDate)).getFullYear()
+				const endYear = new Date(Number(this.maxDate)).getFullYear()
+				let result = [
+					{
+						type: 'year',
+						label: '年',
+						range: [startYear, endYear]
+					},
+					{
+						type: 'month',
+						label: '月',
+						range: [this.minMonth, this.maxMonth]
+					},
+					{
+						type: 'day',
+						label: '日',
+						range: [this.minDay, this.maxDay]
+					},
+					{
+						type: 'hour',
+						label: '时',
+						range: [0,23]
+					},
+					{
+						type: 'minute',
+						label: '分',
+						range: [0, 59]
+					},
+					{
+						type: 'secode',
+						label: '秒',
+						range: [0, 59]
+					}
+				]
+				this.innerColumns = result.map(({ type, label, range }) => {
+					const num = range[1] - range[0] + 1;
+					let values = this.getColumnTimes(num, (index) => {
+					    let value = range[0] + index
+					    value = type === 'year' ? `${value}` : this.padZero(value)
+					    return value
+					})
+					return { type, label, values }
+				})
+				if(this.mode === "date") {
+					this.innerColumns.splice(3,3)
+				}
+			},
+			bindChange (e) {
+			    const val = e.detail.value;
+				const date = new Date();
+				this.year = this.getCurrCol(0)[val[0]] || date.getFullYear()
+				this.month = this.getCurrCol(1)[val[1]] ||date.getMonth() + 1;
+				this.day = this.getCurrCol(2)[val[2]] || date.getDate()
+				this.hour = this.getCurrCol(3)[val[3]] || date.getHours();
+				this.minute = this.getCurrCol(4)[val[4]] || date.getMinutes();
+				this.second = this.getCurrCol(5)[val[5]] || date.getSeconds();
+				/* // change事件 需要启用取消注释
+				const currentTime = new Date(this.year,this.month - 1,this.day,this.hour,this.minute,this.second).getTime()
+				if(this.format) {
+					this.$emit('change',uni.$u.timeFormat(currentTime,this.format))
+				} else {
+					this.$emit('change',currentTime)
+				} */
+			},
+			getCurrCol(index) {
+				if(!this.innerColumns[index]) {
+					return []
+				}
+				return this.innerColumns[index].values
+			},
+			cancel() {
+				this.$emit('cancel')
+				this.$emit('update:show',false)
+			},
+			confirm() {
+				const str = `${this.year}/${this.month}/${this.day} ${this.hour}:${this.minute}:${this.second}`
+				const time = new Date(str).getTime()
+				this.$emit('confirm',this.formatDate(time))
+                this.$emit('input', this.formatDate(time));
+			},
+			// set data
+			setData(value) {
+				let date;
+				if(value) {
+					const n = isNaN(value) ? value : Number(value)
+					date = new Date(n)
+				} else {
+					date = new Date()
+				}
+				const startYear = new Date(Number(this.minDate)).getFullYear()
+				this.year = date.getFullYear()
+				// 绑定时间小于当前时间列表的开始时间则取第一项
+				const yearColumnIndex = this.year > startYear ? this.year - startYear : 0
+				this.day = date.getDate()
+				this.month = date.getMonth() + 1
+				this.hour = date.getHours()
+				this.minute = date.getMinutes()
+				this.second = date.getSeconds()
+				// pickerValue数组中的项依次表示 picker-view 内的 picker-view-column 选择的第几项
+				this.pickerValue = [yearColumnIndex,this.month - 1,this.day - 1,this.hour,this.minute,this.second]
+				this.$nextTick(() => {
+					if(this.mode === "date") {
+						this.pickerValue.splice(3,3)
+					}
+				})
+			},
+			formatDate(time) {
+				if(this.format) {
+					return uni.$u.timeFormat(time,this.format)
+				} else if(this.formatToJson) {
+					return new Date(time).toJSON()
+				} else {
+					return time
+				}
+			},
+			// 设置列数据
+			getColumnTimes(n, iteratee) {
+			    let index = -1
+			    const result = Array(n < 0 ? 0 : n)
+			    while (++index < n) {
+			        result[index] = iteratee(index)
+			    }
+			    return result
+			},
+			// 字符串转换
+			padZero(num, targetLength = 2) {
+			    let str = `${num}`
+			    while (str.length < targetLength) {
+			        str = `0${str}`
+			    }
+			    return str
+			}
+		}
+	}
+</script>
+<style lang="scss" scoped>
+	picker-view {
+	  width: 100%;
+		height: 100%;
+	}
+	
+	.time-content {
+		height: 280px;
+		.header-top {
+			height: 44px;
+			line-height: 44px;
+			display: flex;
+			padding: 0 16px;
+			font-size: 15px;
+			border-bottom: 1px solid #EEEEEE;
+			overflow: hidden;
+			.cancel {
+				color: #999999;
+			}
+			.title {
+				flex: 1;
+				text-align: center;
+				color: #666666;
+			}
+			.confirm {
+				color: #27B57D;
+			}
+		}
+		.time-wrapper {
+			height: calc(100% - 44px);
+			box-sizing: border-box;
+			text-align: center;
+			.picker-box {
+				height: 44px;
+				font-size: 18px!important;
+				font-weight: 800!important;
+				color: #333333!important;
+			}
+			.item {
+			    line-height: 44px;
+			    text-align: center;
+			}
+		}
+	}
+</style>

+ 40 - 0
components/timepick/util/util.js

@@ -0,0 +1,40 @@
+/**
+ * 获取某年某月有多少天
+ */
+export const getOneMonthDays = (year,month)=>{
+	month = Number(month);
+	const baseMonthsDays = [31,28,31,30,31,30,31,31,30,31,30,31];
+	if(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)){
+		if(month === 1){
+			baseMonthsDays[month] = 29;
+		}
+	}
+	return baseMonthsDays[month];
+}
+
+/**
+ * 获取日期的年月日时分秒
+ */
+export const getTimeArray = (date)=>{
+	const year = date.getFullYear();
+	const month = date.getMonth()+1;
+	const day = date.getDate();
+	const hour = date.getHours();
+	const minute = date.getMinutes();
+	const second = date.getSeconds();
+	return [year,month,day,hour,minute,second];
+}
+/**
+ * 小于10的数字前面补0
+ */
+export const addZero = (num)=>{
+	return num < 10 ? '0' + num : num;
+}
+
+/**
+ * 获取当前值在数组中的索引
+ */
+export const getIndexOfArray = (value,array)=>{
+	let index = array.findIndex(item => item == value);
+	return index > -1 ? index : 0;
+}

+ 4 - 1
config.js

@@ -1,12 +1,15 @@
 // 应用全局配置
 module.exports = {
   // baseUrl: 'https://zxyyq.qs163.cn/prod-api',
-  baseUrl: 'http://47.99.82.249:5010/prod-api',
+  
+  // baseUrl: 'https://zxyclmjy.qs163.cn/prod-api',
+  baseUrl: 'http://47.99.82.249:5012/prod-api',
   // baseUrl: 'http://192.168.101.168:8065',
   // baseUrl: 'http://192.168.101.245:8065',
   // baseUrlimg: 'http://114.99.127.243:2001',
   Clientid:'428a8310cd442757ae699df5d894f051',//
  // https://xygl.cnzxy.cn h5链接地址
+  webUrl: 'https://www.baidu.com',
   confirmflag:false,//是否有弹窗
   // 应用信息
   appInfo: {

+ 25 - 11
manifest.json

@@ -19,25 +19,30 @@
         },
         "modules" : {
             "Geolocation" : {},
-            "VideoPlayer" : {}
+            "VideoPlayer" : {},
+            "Maps" : {}
         },
         "distribute" : {
             "android" : {
                 "permissions" : [
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                     "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
                     "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                     "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                     "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                     "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
                     "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                 ]
             },
@@ -48,8 +53,8 @@
                 "ad" : {},
                 "maps" : {
                     "amap" : {
-                        "appkey_ios" : "",
-                        "appkey_android" : ""
+                        "appkey_ios" : "b85f0c64b3c9a082d740912cf3019c88",
+                        "appkey_android" : "b85f0c64b3c9a082d740912cf3019c88"
                     }
                 },
                 "geolocation" : {
@@ -97,6 +102,15 @@
         "devServer" : {
             "https" : false,
             "port" : 9090
+        },
+        "sdkConfigs" : {
+            "maps" : {
+                "amap" : {
+                    "key" : "fba818d626f91cf5a13cd61943a7667e",
+                    "securityJsCode" : "b06df55c66884ce2c9a3f3281c2c5ca9",
+                    "serviceHost" : ""
+                }
+            }
         }
     }
 }

+ 71 - 3
pages.json

@@ -326,9 +326,77 @@
 				"path": "pages/record/visitor",
 				"style": {
 					"navigationBarTitleText": "访客记录",
-					"h5":{
-						"titleNView":false
-					}
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/abnormal",
+				"style": {
+					"navigationBarTitleText": "异常考勤记录",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/cardSupple",
+				"style": {
+					"navigationBarTitleText": "补卡申请",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/kaorules",
+				"style": {
+					"navigationBarTitleText": "考勤规则",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/clock",
+				"style": {
+					"navigationBarTitleText": "考勤打卡",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/outside",
+				"style": {
+					"navigationBarTitleText": "外勤打卡",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/personnel",
+				"style": {
+					"navigationBarTitleText": "打卡记录统计",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/setswork",
+				"style": {
+					"navigationBarTitleText": "考勤设置",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/setwoek",
+				"style": {
+					"navigationBarTitleText": "考勤设置",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/success",
+				"style": {
+					"navigationBarTitleText": "打卡成功",
+					"h5":{"titleNView":false}
+				}
+			},
+			{
+				"path": "pages/clock/abnormal",
+				"style": {
+					"navigationBarTitleText": "访客记录",
+					"h5":{"titleNView":false}
 				}
 			}
 		]

+ 54 - 15
pages/index/index.vue

@@ -37,10 +37,14 @@
 				</view>
 				<view class="pdlr2">
 					<view class="yqcbox">
-						<view class="yqcba" v-if="checkPermi(['system:clock:list'])" @click="getClockFn">
+						<view class="yqcba"  @click="getClockFn" v-if="checkPermi(['system:clock:add'])">
+							<view class="aimg"><image :src="htabkimg" class="imgk"></image></view>
+							<view class="atit">考勤打卡</view>
+						</view>
+						<!-- <view class="yqcba" v-if="checkPermi(['system:clock:list'])" @click="getClockFn">
 							<view class="aimg"><image :src="htabaimg" class="imga"></image></view>
 							<view class="atit">打卡记录</view>
-						</view>
+						</view> -->
 						<view class="yqcba" v-if="checkPermi(['system:order:add'])" @click="getMeetFn">
 							<view class="aimg"><image :src="htabbimg" class="imgb"></image></view>
 							<view class="atit">会议预订</view>
@@ -77,6 +81,18 @@
 							<view class="aimg"><image :src="htabjimg" class="imgj"></image></view>
 							<view class="atit">食谱记录</view>
 						</view>
+						<view class="yqcba" @click="getClockSetFn" v-if="checkPermi(['system:schedule:add'])">
+							<view class="aimg"><image :src="htablimg" class="imgk"></image></view>
+							<view class="atit">考勤设置</view>
+						</view>
+						<view class="yqcba" @click="getClockjlFn" v-if="checkPermi(['system:info:record:list'])">
+							<view class="aimg"><image :src="htablimg" class="imgk"></image></view>
+							<view class="atit">考勤记录</view>
+						</view>
+						<view class="yqcba" @click="getClockcontFn" v-if="checkPermi(['system/clock/all/month'])">
+							<view class="aimg"><image :src="htablimg" class="imgk"></image></view>
+							<view class="atit">考勤统计</view>
+						</view>
 						<view class="yqcba">
 							<view class="aimg"><image :src="htabhimg" class="imgh"></image></view>
 							<view class="atit">敬请期待</view>
@@ -88,8 +104,8 @@
 			<view class="mb10">
 				<notice :noticelist="noticelist" :activeColor="activeColor" :nactiveColor="nactiveColor" :autoplay='autoplay' @getNoticeDet="getNoticeDet"></notice>
 			</view>
-			<!-- 普通用户看到的 -->
-			<template v-if="!checkRole(['manager'])">
+			<!-- 普通用户看到的 v-if="!checkRole(['manager'])"-->
+			<template v-if="!checkRole(['administrators'])">
 				<view class="yqcont" >
 					<view class="yqcb">
 						<image :src="hbgfimg" class="cbgimg"></image>
@@ -111,7 +127,7 @@
 						<view class="right" @click="getmClockFn">查看更多 >></view>
 					</view>
 					<view>
-						<y-list type='record' :datalist="list" :wtdt="wtdt" @getDetail='getClockDetailFn' :adrlist="adrlist" @getDelFn="getDelFn" @gettypeFn="gettypeFn"></y-list>
+						<y-list type='record' :workTime="workTime" :datalist="list" :wtdt="wtdt" @getDetail='getClockDetailFn' :adrlist="adrlist" @getDelFn="getDelFn" @gettypeFn="gettypeFn"></y-list>
 					</view>
 				</view>
 			</template>
@@ -170,7 +186,7 @@
 				</view>
 				
 				<!-- 管理员 -->
-				<view class="yylists">
+				<view class="yylists" v-if="checkPermi(['system:reservat:sh'])">
 					<view class="yyltab flexcj">
 						<view class="left flexc">待审批列表<image :src="listline"></image></view>
 						<view class="right" @click="getMoreFn">查看更多 >></view>
@@ -197,7 +213,7 @@
 	import {getReservatcountl,getReservatList,getReservatDel,getReservatSh,getYydcCont} from "@/api/mine/order.js"
 	import {getDictionaryFn} from "@/api/mine/register.js"
 	import {getNoticeList} from "@/api/common.js"
-	import {getClockList} from "@/api/mine/work.js"
+	import {getRecordDayList} from "@/api/work/check.js"
 	import footers from '@/components/footer/footer.vue'
   export default {
 	components:{notice,yList,footers},
@@ -217,6 +233,8 @@
 			htabhimg:require("@/static/images/home/htabh.png"),
 			htabiimg:require("@/static/images/home/htabi.png"),
 			htabjimg:require("@/static/images/home/htabj.png"),
+			htabkimg:require("@/static/images/home/htabk.png"),
+			htablimg:require("@/static/images/home/htabl.png"),
 			hbgaimg:require("@/static/images/home/hbga.png"),
 			hbgbimg:require("@/static/images/home/hbgb.png"),
 			hbgcimg:require("@/static/images/home/hbgc.png"),
@@ -250,11 +268,12 @@
 			lunar:'',
 			weathericon:require("@/static/images/weather/weaionf.png"),
 			userId:this.$store.state.user.userId,
-			name:this.$store.state.user.name,
+			name:this.$store.state.user.nickName,
 			startDate:'',
 			endDate:'',
 			kaTime:'',
 			conuntinfo:{},
+			workTime:[],
 		}
 	},
 	onPageScroll(e) {
@@ -359,8 +378,22 @@
 		},
 		//打卡记录
 		getClockFn(){
+			// this.$tab.navigateTo("/work/pages/clock/setwoek")
+			this.$tab.navigateTo("/work/pages/clock/clock")
+			// this.$tab.navigateTo("/work/pages/clock/clockin")
+		},
+		//打卡设置
+		getClockSetFn(){
+			this.$tab.navigateTo("/work/pages/clock/setswork")
+		},
+		// 考勤记录
+		getClockjlFn(){
 			this.$tab.navigateTo("/work/pages/record/clockin")
 		},
+		// 考勤统计
+		getClockcontFn(){
+			this.$tab.navigateTo("/work/pages/clock/personnel")
+		},
 		// 就餐预定
 		getEatFn(){
 			this.$tab.navigateTo("/work/pages/yyorder/eat")
@@ -519,7 +552,7 @@
 		getClockDetailFn(){
 			var obj={
 				userId:this.userId,
-				recordTime:this.kaTime
+				recordDate:this.kaTime
 			}
 			this.$tab.navigateTo('/work/pages/record/detail?data='+encodeURIComponent(JSON.stringify(obj)))
 		},
@@ -527,7 +560,6 @@
 			var params={
 				pageSize:this.pageSize,
 				pageNum: this.pageNum,
-				visitType:1
 			}
 			
 			if(!checkRole(['administrators'])){
@@ -535,13 +567,19 @@
 				params.userId=this.userId;
 				params.startTime=this.startDate;
 				params.endTime=this.endDate;
-				getClockList(params).then(res=>{
+				getRecordDayList(params).then(res=>{
 					if (res.code == 200) {
-						if (res.rows.length < this.pageSize) {
+						var data=res.data;
+						var rows=[];
+						this.workTime=data.workTime.split('-')
+						if(data.rlData&&data.rlData.length){
+							rows=data.rlData;
+						}
+						if (rows.length < this.pageSize) {
 							this.reachflag = false
 							this.wtdt = '到底了~';
 						} else {
-							var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -
+							var num = parseInt(rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -
 								1)
 							if (num < res.total) {
 								this.reachflag = true
@@ -552,9 +590,9 @@
 							}
 						}
 						if (this.pageNum == 1) {
-							this.list = res.rows;
+							this.list = rows;
 						} else {
-							this.list = this.list.concat(res.rows)
+							this.list = this.list.concat(rows)
 						}
 					} else {
 						this.$toast(res.msg)
@@ -640,6 +678,7 @@
 				.imgh{width: 54rpx;height: 60rpx;}
 				.imgi{width: 50rpx;height: 60rpx;}
 				.imgj{width: 60rpx;height: 48rpx;}
+				.imgk{width: 62rpx;height: 62rpx;}
 			}
 			.atit{font-weight: 500;font-size: 22rpx;color: #161616;}
 		}

+ 12 - 9
pages/login.vue

@@ -41,8 +41,9 @@
 					</view>
 		  			
 		  			 <view class="login_box">
-		  				 <input v-if="checkeye" v-model="loginForm.password" type="text"  class="input" placeholder="请输入密码" maxlength="20" />
-		  				 <input v-else v-model="loginForm.password" type="password"  class="input" placeholder="请输入密码" maxlength="20" />
+						 <uni-easyinput :inputBorder="false" type="password" v-model="loginForm.password" placeholder="请输入密码" />
+		  				<!-- <input v-if="checkeye" v-model="loginForm.password" type="text"  class="input" placeholder="请输入密码" maxlength="20" />
+		  				 <input v-else v-model="loginForm.password" type="password"  class="input" placeholder="请输入密码" maxlength="20" /> -->
 						 <view class="line flex0"></view>
 						 <view class="login_txt" @click="getForget"><text>忘记密码</text></view>
 		  			 </view>
@@ -110,7 +111,7 @@
 			rimg:require('@/static/images/mine/rimg.png'),
 			pcicon:require('@/static/images/mine/pcicon.png'),
 			pnicon:require('@/static/images/mine/pnicon.png'),
-			checkflag:false,
+			checkflag:true,
 			typeflag: false,
 			loginflag:false,
 			captchaEnabled: false,
@@ -306,11 +307,11 @@
 		} else {
 			this.loginflag=true;
 			// this.getCode()
-			if(uni.getStorageSync('lcheckflag')){
-				this.checkflag=true
-			}else{
-				this.checkflag=false
-			}
+			// if(uni.getStorageSync('lcheckflag')){
+			// 	this.checkflag=true
+			// }else{
+			// 	this.checkflag=false
+			// }
 		  if(uni.getStorageSync('account')){
 		  	var newObj=JSON.parse(JSON.stringify(uni.getStorageSync('account')))
 		  	this.loginForm.username=newObj.username;
@@ -326,6 +327,8 @@
 <style lang="scss" scoped>
 .headimg{width: 136rpx;height: 136rpx;margin:0 auto 36rpx;}
 .mzimg{width: 100rpx;height: 44rpx;margin: 0 auto ;}
+.regbox /deep/ .uni-easyinput__content-input{font-size: 32rpx !important;padding-left: 0 !important;line-height: 80rpx;height: 80rpx;}
+.regbox /deep/ .uni-input-placeholder{font-size: 32rpx !important;padding-left: 0 !important;color: #808080;}
 .rtxt{font-size: 32rpx;font-weight: 500;
 color: $com-cd3;text-align: center;}
 .bbcode{position: absolute;width: 100%;text-align: center;left: 0;bottom: -80rpx;font-size: 24rpx;color: #666666;}
@@ -373,7 +376,7 @@ color: $com-cd3;text-align: center;}
 		}
         .input {
           width: 100%;
-          font-size: 34rpx;
+          font-size: 32rpx;
 		  height: 80rpx;
 		  line-height: 80rpx;
         }

+ 37 - 1
pages/mine/index.vue

@@ -44,6 +44,20 @@
 				</view> -->
 			</view>
 			<view class="mbgbox">
+				<view class="flexc mine_list" @click="getClockjlFn" v-if="checkPermi(['system:info:record:list'])">
+					<view class="limg">
+						<image :src="listimgl" class="imga"></image>
+					</view>
+					<view class="tit flex1">考勤记录</view>
+					<image :src="rimg" class="rimg"></image>
+				</view>
+				<view class="flexc mine_list" @click="getClockcontFn" v-if="checkPermi(['system:clock:all:month'])">
+					<view class="limg">
+						<image :src="listimgm" class="imga"></image>
+					</view>
+					<view class="tit flex1">考勤统计</view>
+					<image :src="rimg" class="rimg"></image>
+				</view>
 				<view class="flexc mine_list" @click="getYqMeetFn">
 					<view class="limg">
 						<image :src="listimgj" class="imge"></image>
@@ -72,6 +86,13 @@
 					<view class="tit flex1">访客预约</view>
 					<image :src="rimg" class="rimg"></image>
 				</view> -->
+				<view class="flexc mine_list" @click="handleToKq" v-if="checkPermi(['system:schedule:add'])">
+					<view class="limg">
+						<image :src="listimgk" class="imgc"></image>
+					</view>
+					<view class="tit flex1">考勤设置</view>
+					<image :src="rimg" class="rimg"></image>
+				</view>
 				<view class="flexc mine_list" @click="handleToSetting">
 					<view class="limg">
 						<image :src="listimgg" class="imga"></image>
@@ -133,6 +154,9 @@
 				listimgh: require('@/static/images/mine/mineh.png'),
 				listimgi: require('@/static/images/mine/minei.png'),
 				listimgj: require('@/static/images/mine/minej.png'),
+				listimgk: require('@/static/images/mine/minek.png'),
+				listimgl: require('@/static/images/mine/minel.png'),
+				listimgm: require('@/static/images/mine/minem.png'),
 
 				head:require('@/static/images/mine/head.png'),
 				// wrimg:require("@/static/images/mine/wrimg.png"),
@@ -140,7 +164,7 @@
 				border: false,
 				backgroundColor: 'transparent',
 
-				name: this.$store.state.user.name,
+				name: this.$store.state.user.nickName,
 				deptName:this.$store.state.user.deptName,
 				// version: getApp().globalData.config.appInfo.version,
 				footerindex: 'mine',
@@ -215,6 +239,18 @@
 			handleToMysb(){
 				// this.$tab.navigateTo("/work/pages/business/list?from=my&type=0")
 			},
+			// 考勤设置
+			handleToKq(){
+				this.$tab.navigateTo('/work/pages/clock/kaorules')
+			},
+			// 考勤记录
+			getClockjlFn(){
+				this.$tab.navigateTo("/work/pages/record/clockin")
+			},
+			// 考勤统计
+			getClockcontFn(){
+				this.$tab.navigateTo("/work/pages/clock/personnel")
+			},
 			// 设置
 			handleToSetting() {
 			  this.$tab.navigateTo('/pages/mine/setting/index')

+ 24 - 97
pages/order/info.vue

@@ -19,60 +19,29 @@
       
       <view class="rbtn" @click="submit">开门</view>
     </uni-forms>
-	<!-- 列表 -->
-	<view class="searchlist" v-if="listflag">
-		<y-list :datalist="list" :wtdt="wtdt" :type="type" @getDetail='getDetail'></y-list>
-	</view>
-	
   </view>
 </template>
 
 <script>
 	import * as base64 from "base-64"
-	import { getReservatList } from "@/api/mine/order.js"
-	import {sendSmsFn} from "@/api/login.js"
-	import yList from "@/components/order/list.vue"
+	import { getOpenDzFn,sendSmskmFn } from "@/api/mine/order.js"
   export default {
-	  components:{yList},
+	  components:{},
     data() {
       return {
 		timefalg:false,
 		time:'',
 		username:'',
-		phonenumber:'17856919066',
+		phonenumber:'',
 		code:'',
-		newcode:'',//验证码1419
 		user:{},
-		list:[],
-		type:'order',
-		pageSize: 10,
-		pageNum: 1,
-		reachflag: true,
-		wtdt:'',
-		listflag:false,
-		backflag:false
+		equipmentName:"",//设备id
       }
     },
     onReady() {
     },
-	onLoad:function(){
-		// uni.$on('refreshrelist',(e) => {
-		// 	this.reachflag=true;
-		// 	this.pageNum=1;
-		// 	this.list=[];
-		// 	this.backflag=true;
-		// 	this.getDataFn();
-		// })
-	},
-	onUnload() {
-		uni.$off('refreshrelist')
-	},
-	// 上拉触底加载更多触发事件
-	onReachBottom() {
-		// if (this.reachflag) {
-		// 	this.pageNum++
-		// 	this.getDataFn()
-		// }
+	onLoad:function(e){
+		this.equipmentName=e.adr;
 	},
     methods: {
 		submit() {
@@ -81,7 +50,7 @@
 				that.$toast("请输入姓名")
 				return
 			}
-			if (!this.phonenumber ) {
+			if (!this.phonenumber) {
 				that.$toast("请输入手机号")
 				return
 			}
@@ -89,10 +58,6 @@
 				that.$toast("请输入验证码")
 				return
 			}
-			// if(this.code!=this.newcode){
-			// 	that.$toast("验证码错误,请重新输入")
-			// 	return
-			// }
 			let regphone = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
 			if (this.phonenumber && !regphone.test(this.phonenumber)) {
 				that.$toast("请输入正确的手机号")
@@ -101,7 +66,18 @@
 			that.timefalg=false;
 			that.time=60;
 			clearInterval(that.timer)
-			// this.getDataFn()
+			var params={
+				"equipmentName":this.equipmentName,
+				"loginName":this.username,
+				"phoneNumber":this.phonenumber,
+				"code": this.code
+			}
+			getOpenDzFn(params).then(res=>{
+				if(res.code==200){
+					that.$toast('已开门');
+					that.code='';
+				}
+			})
 		},
 		// getDetail(data){
 		// 	var s=base64.encode(data)
@@ -109,7 +85,7 @@
 		// },
 		getCode(){
 			var that=this;
-			if (!this.phonenumber ) {
+			if (!this.phonenumber) {
 				that.$toast("请输入手机号")
 				return
 			}
@@ -118,18 +94,13 @@
 				that.$toast("请输入正确的手机号")
 				return
 			}
-			that.$toast("发送成功")
-			that.newcode='1234'
-			that.time=60;
-			that.timefalg=true;
-			that.setTimein()
-			return
-			
-			sendSmsFn(this.phonenumber).then(res=>{
+			var params={
+				username:this.phonenumber
+			}
+			sendSmskmFn(params).then(res=>{
 				if (res.code == 200) {
 					// 发送验证码
 					that.$toast("发送成功")
-					that.newcode=res.msg
 					that.time=60;
 					that.timefalg=true;
 					that.setTimein()
@@ -153,50 +124,6 @@
 				that.time=that.time-1;
 			},1000)
 		},
-		// getDataFn(){
-		// 	var params={
-		// 		visitPhone:this.phonenumber,
-		// 		pageSize:this.pageSize,
-		// 		pageNum: this.pageNum,
-		// 	}
-		// 	getReservatList(params).then(res=>{
-		// 		if(res.code==200){
-		// 			var list=res.rows;
-		// 			this.listflag=true;
-		// 			if(list&&list.length){
-		// 				var len=list.length;
-		// 				if(len==1&&!this.backflag&&this.pageNum==1){
-		// 					var id=list[0].reservatId
-		// 					this.$tab.navigateTo('/pages/order/comedetail?id='+base64.encode(id))
-		// 				}else{
-		// 					if (res.rows.length < this.pageSize) {
-		// 						this.reachflag = false
-		// 						this.wtdt = '到底了~';
-		// 					} else {
-		// 						var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -	1)
-		// 						if (num < res.total) {
-		// 							this.reachflag = true
-		// 							this.wtdt = '上拉加载更多'
-		// 						} else {
-		// 							this.reachflag = false
-		// 							this.wtdt = '到底了~';
-		// 						}
-		// 					}
-		// 					if (this.pageNum == 1) {
-		// 						this.list = res.rows;
-		// 					} else {
-		// 						this.list = this.list.concat(res.rows)
-		// 					}
-		// 				}
-		// 			}else{
-		// 				this.$toast('暂无预约信息')
-		// 			}
-		// 		}else{
-		// 			this.$toast(res.msg)
-		// 		}
-		// 	})
-		// },
-      
     }
   }
 </script>

+ 0 - 1
pages/video/index.vue

@@ -201,7 +201,6 @@
 				this.tabscheight=Number(this.nvaHeight)*2+100;
 			}
 		})
-		// 3c8cadac11af4f1298a2882addc8788d
 	},
 	onUnload() {
 		uni.$off('refreshdatalist')

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
plugins/amap-wx.js


BIN
static/images/addry.png


BIN
static/images/adress.png


BIN
static/images/chosebm.png


BIN
static/images/close.png


BIN
static/images/home/htabk.png


BIN
static/images/home/htabl.png


BIN
static/images/icon_kqdk_jrfw.png


BIN
static/images/icon_rqxz.png


BIN
static/images/krules.png


BIN
static/images/map.png


BIN
static/images/mine/minek.png


BIN
static/images/mine/minel.png


BIN
static/images/mine/minem.png


BIN
static/images/moico.png


BIN
static/images/nhead.png


BIN
static/images/photo.png


BIN
static/images/pic_mine_hp_normal.png


BIN
static/images/pimg.png


BIN
static/images/right.png


BIN
static/images/serch.png


BIN
static/images/stepa.png


BIN
static/images/stepb.png


BIN
static/images/stepc.png


BIN
static/images/success.png


BIN
static/images/time.png


BIN
static/images/up.png


BIN
static/images/upimg.png


+ 8 - 0
static/index.html

@@ -10,6 +10,14 @@
 			var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))
 			document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')
 		</script>
+		<!-- <script type="text/javascript">
+			window._AMapSecurityConfig = {
+				securityJsCode:'b06df55c66884ce2c9a3f3281c2c5ca9',
+			}
+		</script>
+		<script src="https://webapi.amap.com/maps?v=1.4.15&key=fba818d626f91cf5a13cd61943a7667e&plugin=AMap.Autocomplete,AMap.Geocoder">
+		</script>
+		<script type="text/javascript" src="https://cache.amap.com/lbs/static/addToolbar.js"></script> -->
 		<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
 	</head>
 	<body>

+ 4 - 4
static/scss/global.scss

@@ -69,12 +69,12 @@
   
   .menu-list {
     margin: 15px 15px;
-  
+  }
     .menu-item-box {
       width: 100%;
       display: flex;
       align-items: center;
-  
+  }
       .menu-icon {
         color: #007AFF;
         font-size: 16px;
@@ -86,5 +86,5 @@
         margin-right: 34rpx;
         color: #999;
       }
-    }
-  }
+    
+  

+ 1 - 0
static/style.css

@@ -22,6 +22,7 @@
 .wordb{word-break: break-all;}
 .fsi{font-style: italic;}
 .w50{width: 50%;}
+.tc{text-align: center;}
 
 .txr{text-align: right;}
 .txc{text-align: center;}

+ 1 - 0
store/getters.js

@@ -2,6 +2,7 @@ const getters = {
   token: state => state.user.token,
   avatar: state => state.user.avatar,
   name: state => state.user.name,
+  nickName: state => state.user.nickName,
   roles: state => state.user.roles,
   permissions: state => state.user.permissions,
   wgtcode:state => state.user.wgtcode,

+ 7 - 0
store/modules/user.js

@@ -10,6 +10,7 @@ const user = {
   state: {
     token: getToken(),
     name: storage.get(constant.name),
+    nickName: storage.get(constant.nickName),
     avatar: storage.get(constant.avatar),
     roles: storage.get(constant.roles),
     permissions: storage.get(constant.permissions),
@@ -29,6 +30,10 @@ const user = {
       state.name = name
       storage.set(constant.name, name)
     },
+	SET_NICKNAME: (state, nickName) => {
+	  state.nickName = nickName
+	  storage.set(constant.nickName, nickName)
+	},
     SET_AVATAR: (state, avatar) => {
       state.avatar = avatar
       storage.set(constant.avatar, avatar)
@@ -120,6 +125,7 @@ const user = {
           const user = res.user
           const avatar = (user == null || user.avatar == "" || user.avatar == null) ? require("@/static/images/profile.jpg") : baseUrl + user.avatar
           const username = (user == null || user.userName == "" || user.userName == null) ? "" : user.userName
+          const nickName = (user == null || user.nickName == "" || user.nickName == null) ? "" : user.nickName
           const deptId = (user == null || user.deptId == "" || user.deptId == null) ? "" : user.deptId
           const deptName = (user == null ||user.dept==null|| user.dept == ""||user.dept.deptName == "" || user.dept.deptName == null) ? "" : user.dept.deptName
           const userId = (user == null || user.userId == "" || user.userId == null) ? "" : user.userId
@@ -132,6 +138,7 @@ const user = {
             commit('SET_ROLES', ['ROLE_DEFAULT'])
           }
           commit('SET_NAME', username)
+          commit('SET_NICKNAME', nickName)
           commit('SET_AVATAR', avatar)
 		  commit('SET_DEPID', deptId)
 		  commit('SET_DEPTNAME', deptName)

+ 6 - 0
uni.scss

@@ -3,6 +3,12 @@
  */
 //公共的颜色
 $com-cd3: #0391FD;
+// 迟到早退颜色
+$uni-katype1: #1678FF !default;//正常
+$uni-katype2: #FF6A17 !default;//迟到
+$uni-katype3: #00B034 !default;//外勤
+$uni-katype4: #888888 !default;//早退
+$uni-katype5: #FF3636 !default;//旷工
 /* 行为相关颜色 */
 $uni-color-primary: #007aff;
 $uni-color-success: #4cd964;

+ 1 - 0
utils/constant.js

@@ -1,6 +1,7 @@
 const constant = {
    avatar: 'vuex_avatar',
    name: 'vuex_name',
+   nickName: 'vuex_nickName',
    roles: 'vuex_roles',
    permissions: 'vuex_permissions',
    scorknow: 'vuex_scorknow',

+ 2 - 2
utils/initmap.js

@@ -5,10 +5,10 @@ var key='';
 key='fba818d626f91cf5a13cd61943a7667e'
 // #endif
 // #ifdef APP-PLUS
-key='ff70a5409eacd8b16a26fca91ee3aea3'
+key='ccbe52b1ec5f66295fa4609c90a819b7'
 // #endif
 // #ifdef MP-WEIXIN
-key='ff70a5409eacd8b16a26fca91ee3aea3'
+key='ccbe52b1ec5f66295fa4609c90a819b7'
 // #endif
 const myAmapFun =new amap.AMapWX({
 	key:key

+ 32 - 0
utils/location.js

@@ -84,6 +84,38 @@ function getLocation(callback) {
 	
 	callback = typeof(callback) == 'function' ? callback : function(res) {};
 		var num=1;
+		var that = this;
+		// #ifdef H5
+		
+		var lng = '117.211954';
+		var lat = '31.839676';
+		that.__CFG.lng = lng;
+		that.__CFG.lat = lat;
+		callback();
+		return
+		
+		uni.getLocation({
+			type: 'gcj02',
+			geocode: true,
+			success: function(res) {
+				// console.log(res)
+				// var lng=res.longitude;
+				// var lat=res.latitude;
+				// that.user.lng=res.longitude;
+				// that.user.lat=res.latitude;
+				var lng = '117.211954';
+				var lat = '31.839676';
+				that.__CFG.lng = lng;
+				that.__CFG.lat = lng;
+				callback();
+				//  console.log('当前位置的经度:' + res.longitude);
+				// console.log('当前位置的纬度:' + res.latitude);
+			},
+			fail: function(red) {
+				console.log(red,88)
+			},
+		})
+		// #endif
 		// #ifdef MP-WEIXIN
 		uni.getSetting({
 			success(res) {

+ 1 - 1
utils/storage.js

@@ -4,7 +4,7 @@ import constant from './constant'
 let storageKey = 'storage_data'
 
 // 存储节点变量名
-let storageNodeKeys = [constant.autologin,constant.scorknow,constant.avatar, constant.name, constant.roles, constant.permissions,constant.wgtcode,constant.deptId,constant.deptName,constant.userId,constant.phonenumber,]
+let storageNodeKeys = [constant.autologin,constant.scorknow,constant.avatar, constant.name,constant.nickName, constant.roles, constant.permissions,constant.wgtcode,constant.deptId,constant.deptName,constant.userId,constant.phonenumber,]
 
 const storage = {
   set: function(key, value) {

+ 393 - 0
work/components/clock/cardlist.vue

@@ -0,0 +1,393 @@
+<template>
+<view class="cardbox">
+		<!-- 第一种样式  人员管理-->
+	<block v-if="datainfo.length>0">
+		<block v-if="type==1">
+		<view class="clist flex" v-for="(ite,idx) in datainfo" :key="idx">
+			<!-- <image :src="ite.avatar?ite.avatar:headimg" class="clist_head"></image> -->
+			<view class="clist_head">
+				{{ite.nickName.substring(0, 1)}}
+			</view>
+			<!-- <image :src="ite.avatar?ite.avatar:headimg" class="clist_head"></image> -->
+			<view class="flex1">
+				<view class="flex mb14">
+					<view class="tit">{{ite.nickName}}</view>
+					<!-- <view class="trole">普通用户</view> -->
+				</view>
+				<view class="txt">所在部门:<block v-if="ite.dept">{{ite.dept.deptName}}</block></view>
+				<view class="txt">手机号码:{{ite.phonenumber}}</view>
+				<view class="txt">角色:
+				<text v-for="(it,ids) in ite.roles">
+					{{it.roleName}}<block v-if="ids!=ite.roles.length-1">/</block>
+				</text>
+				</view>
+			</view>
+			<view class="clistr" @click="getDetail(ite.userId)">
+				<image :src="updataimg"></image>
+			</view>
+		</view>
+		</block>
+		<!-- 考勤记录 -->
+		<block v-if="type==2">
+			<!-- 记录详情 -->
+			<view class="cardb" v-for="(ite,idx) in datainfo" :key="idx" @click="getDetail(ite)">
+				<view class="mb10 flexc">
+					<view class="cardb_ta">{{ite.kaTime}}</view>
+					<view class="line"></view>
+					<view class="cardb_tb">{{weeks[ite.kaWeek]}}</view>
+				</view>
+				<view class="cardb_b">
+					<view>
+						<text class="time">{{ite.kaTimeAmIn||'上班'}}</text>
+						<block v-if="ite.kaTypeAmIn==2"><text class="cor2">迟到</text>打卡</block>
+						<block v-else-if="ite.kaTypeAmIn==3"><text class="cor3">外勤</text>打卡</block>
+						<block v-else-if="ite.kaTypeAmIn==4"><text class="cor4">早退</text>打卡</block>
+						<text v-else-if="ite.kaTypeAmIn==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text>
+					</view>
+					<view><text class="time">{{ite.kaTimeAmOut||'下班'}}</text>
+						<block v-if="ite.kaTypeAmOut==2"><text class="cor2">迟到</text>打卡</block>
+						<block v-else-if="ite.kaTypeAmOut==3"><text class="cor3">外勤</text>打卡</block>
+						<block v-else-if="ite.kaTypeAmOut==4"><text class="cor4">早退</text>打卡</block>
+						<text v-else-if="ite.kaTypeAmOut==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text>
+					</view>
+					<view><text class="time">{{ite.kaTimePmIn||'上班'}}</text>
+						<block v-if="ite.kaTypePmIn==2"><text class="cor2">迟到</text>打卡</block>
+						<block v-else-if="ite.kaTypePmIn==3"><text class="cor3">外勤</text>打卡</block>
+						<block v-else-if="ite.kaTypePmIn==4"><text class="cor4">早退</text>打卡</block>
+						<text v-else-if="ite.kaTypePmIn==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text></view>
+					<view><text class="time">{{ite.kaTimePmOut||'下班'}}</text>
+						<block v-if="ite.kaTypePmOut==2"><text class="cor2">迟到</text>打卡</block>
+						<block v-else-if="ite.kaTypePmOut==3"><text class="cor3">外勤</text>打卡</block>
+						<block v-else-if="ite.kaTypePmOut==4"><text class="cor4">早退</text>打卡</block>
+						<text v-else-if="ite.kaTypePmOut==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text>
+					</view>
+				</view>
+			</view>
+		</block>
+		
+		
+		<!-- 部门管理 -->
+		<view class="cardc" v-if="type=='3'">
+			<view v-for="(ite,idx) in datainfo">
+				<view class="cardc_ta flexc">
+					<view class="flexc flex1">
+						<view class="cardc_tb">{{ite.deptName}}</view>
+						<view class="cardc_tc" @click="getDetail(ite)">
+							<image :src="supdataimg" class="cardc_timg"></image>
+						</view>
+					</view>
+					<view class="cardc_tc" @click.stop="getFold(idx)">
+						<image :src="upimg" class="cardc_timga" :style="foldidx==idx?'transform: rotate(0deg);':''"></image>
+					</view>
+				</view>
+				<!-- 下级部门 -->
+				<view class="cardc_td" :style="foldidx==idx?'height:auto':''">
+					<view   class="cardc_ta flexc nextb" v-for="(it,ix) in ite.children">
+						<view class="cardc_tb nexta flex1">{{it.deptName}}</view>
+						<view class="cardc_tc" @click="getDetail(it)">
+							<image :src="updataimg" class="cardc_timgb"></image>
+						</view>
+					</view>
+				</view>	
+			</view>
+		</view>
+		
+		
+		<!-- 打卡记录统计 -->
+		<block v-if="type=='count'">
+		<view class="clist"  v-for="(ite,idx) in datainfo" style="padding-left: 28rpx;padding-right: 28rpx;">
+			<view class="clistc flex">
+				<view class="flex  flex1">
+					<view class="tit">{{ite.name}}</view>
+					<!-- <view class="trole">普通用户</view> -->
+				</view>
+				<view class="clistr" @click="getDetail(ite)">
+					<image :src="updataimg"></image>
+				</view>
+			</view>
+				<view class="flexc">
+					<view class="cont_tflex flex1" >
+						<view class="cont_tftit tc">迟到</view>
+						<view class="cont_tftxt tc">{{ite.cd||0}}</view>
+					</view>
+					<view class="cont_tflex flex1" >
+						<view class="cont_tftit tc">早退</view>
+						<view class="cont_tftxt tc">{{ite.zt||0}}</view>
+					</view>
+					<view class="cont_tflex flex1" >
+						<view class="cont_tftit tc">外勤</view>
+						<view class="cont_tftxt tc">{{ite.wq||0}}</view>
+					</view>
+					<view class="cont_tflex flex1" >
+						<view class="cont_tftit tc">未打卡</view>
+						<view class="cont_tftxt tc">{{ite.wdk||0}}</view>
+					</view>
+				</view>
+		</view>
+		</block>
+		<!-- 考勤规则 -->
+		<block v-if="type=='rule'">
+		<view class="clist" v-for="(ite,idx) in datainfo" :key="idx" style="padding-left: 20rpx;padding-rignt:20rpx"> 
+			<view class="flexc">
+				<view class="tit flex1">{{ite.locations}}</view>
+				<view class="clistr" @click="getDetail(ite.dutyId)">
+					<image :src="updataimg"></image>
+				</view>
+			</view>
+			<view class="flex clista">
+				<view class="flex0">考勤规则:</view>
+				<view class="flex1 clistat">
+					<view>上班时间{{ite.startWorkTime}}</view>
+					<!-- <view v-if="ite.kaNum==4">下班时间{{ite.kaTimeAmOut}}</view>
+					<view v-if="ite.kaNum==4">上班时间{{ite.kaTimePmIn}}</view> -->
+					<view>下班时间{{ite.endWorkTime}}</view>
+				</view>
+			</view>
+		</view>
+		</block>
+		<!-- 打卡详情 -->
+		<block v-if="type==6">
+		<view class="cardb"  v-for="(ite,idx) in datainfo" :key="idx">
+			<view class="flexc">
+				<view class="cardb_ta">{{ite.kaTime}}</view>
+				<view class="line"></view>
+				<view class="cardb_tb">{{weeks[ite.kaWeek]}}</view>
+			</view>
+			<view class="flex clista">
+				<view class="flex0">打卡时间:</view>
+				<view class="flex1 clistat">
+					<view>
+						<text class="time">{{ite.kaTimeAmIn||'上班'}}</text>
+						<block v-if="ite.kaTypeAmIn==2"><text class="cor2">迟到</text></block>
+						<block v-else-if="ite.kaTypeAmIn==3"><text class="cor3">外勤</text></block>
+						<block v-else-if="ite.kaTypeAmIn==4"><text class="cor4">早退</text></block>
+						<text v-else-if="ite.kaTypeAmIn==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text>
+					</view>
+					<view><text class="time">{{ite.kaTimeAmOut||'下班'}}</text>
+						<block v-if="ite.kaTypeAmOut==2"><text class="cor2">迟到</text></block>
+						<block v-else-if="ite.kaTypeAmOut==3"><text class="cor3">外勤</text></block>
+						<block v-else-if="ite.kaTypeAmOut==4"><text class="cor4">早退</text></block>
+						<text v-else-if="ite.kaTypeAmOut==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text>
+					</view>
+					<view><text class="time">{{ite.kaTimePmIn||'上班'}}</text>
+						<block v-if="ite.kaTypePmIn==2"><text class="cor2">迟到</text></block>
+						<block v-else-if="ite.kaTypePmIn==3"><text class="cor3">外勤</text></block>
+						<block v-else-if="ite.kaTypePmIn==4"><text class="cor4">早退</text></block>
+						<text v-else-if="ite.kaTypePmIn==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text></view>
+					<view><text class="time">{{ite.kaTimePmOut||'下班'}}</text>
+						<block v-if="ite.kaTypePmOut==2"><text class="cor2">迟到</text></block>
+						<block v-else-if="ite.kaTypePmOut==3"><text class="cor3">外勤</text></block>
+						<block v-else-if="ite.kaTypePmOut==4"><text class="cor4">早退</text></block>
+						<text v-else-if="ite.kaTypePmOut==5" class="cor5">未打卡</text>
+						<text v-else class="cor5">未打卡</text>
+					</view>
+				</view>
+			</view>
+		</view>
+		</block>
+		<!-- 角色管理 -->
+		<!-- <block v-if="type==7">
+			
+			<view class=" flexc mb10 rolebox" :class="checkflag?'roleboxtrans':''" v-for="(ite,idx) in datainfo" :key="idx" @click="getChose(idx)">
+				<view class="datachek flex0" v-if="checkflag">
+					<image :src="choseimg" v-if="ite.check"></image>
+					<image :src="chosenimg" v-else></image>
+				</view>
+			
+				<view class="clist  flex"  style="margin-bottom: 0;width: 682rpx;flex: 1 0 auto;">
+				<view class="flex1">
+					<view class="flex mb16">
+						<view class="tit">{{ite.roleName}}</view>
+					</view>
+					<view class="txt">角色编号:{{ite.roleId}}</view>
+					<view class="txt">角色权限:{{ite.roleKey}}</view>
+					<view class="txt">状态:{{ite.status == null? '' : ite.status=='0'?'正常':'停用' }}
+					</view>
+				</view>
+				<view class="clistr" @click.stop="getDetail(ite)">
+					<image :src="updataimg"></image>
+				</view>
+			</view>
+			</view>
+		</block> -->
+		<view class="shax">{{wtdt}}</view>
+	</block>
+	<!-- 无数据 -->
+	<view class="nodata" v-else>
+		<image :src="noiconpimg"></image>
+		<view>
+			暂无数据
+		</view>
+	</view>
+</view>
+</template>
+
+<script>
+	export default{
+		props:{
+			datainfo: {
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			rolelist:{   //角色
+				type: Array,
+				default () {
+					return []
+				}
+			},
+			wtdt:{
+				type:String,
+				default () {
+					return ''
+				}
+			},
+			type:{
+				type:String,
+				default () {
+					return 0
+				}
+			},
+			checkflag:{
+				type:Boolean,
+				default () {
+					return false
+				}
+			}
+		},
+		data(){
+			return{
+				headimg:require("@/work/static/clock/nhead.png"),
+				updataimg:require("@/work/static/clock/upimg.png"),
+				noiconpimg:require("@/work/static/clock/noiconp.png"),
+				supdataimg:require("@/work/static/clock/updata.png"),
+				upimg:require("@/work/static/clock/upe.png"),
+				downimg:require("@/work/static/clock/down.png"),
+				foldidx:-1,
+				list:[{tit:'董事会',children:[{tit:'行政部'},{tit:'行政部1'}]},{tit:'董事会1',children:[{tit:'行政部'},{tit:'行政部1'}]}],
+				weeks: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+				
+			}
+		},
+		mounted() {
+			console.log(this.datainfo)
+		},
+		methods:{
+			getDetail(e){
+				this.$emit('getdetail',e)
+			},
+			getFold(idx){
+				if(this.foldidx==idx){
+					this.foldidx=-1
+				}else{
+					this.foldidx=idx
+				}
+			},
+			getChose(idx){
+				this.datainfo[idx].check=!this.datainfo[idx].check;
+				var newKarr=[]
+				var newArr=this.datainfo;
+				newArr.forEach((ite,idx)=>{
+					if(ite.check){
+						newKarr.push(ite.roleId)
+					}
+				})
+				this.$emit("getChose",newKarr)
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.cardbox{padding:32rpx 34rpx 0;}
+.flex{display: flex;}
+.flexc{display: flex;align-items: center;}
+.mb10{margin-bottom: 20rpx;}
+
+.clist{background: #FFFFFF;
+box-shadow: 0px 4rpx 6rpx 0px rgba(189,189,189,0.35);margin-bottom: 20rpx;
+border-radius: 10rpx;padding: 32rpx 24rpx 20rpx 36rpx;
+	.clist_head{width: 56rpx;height: 56rpx;margin-right: 26rpx;flex: 0 0 auto;background: #1678FF;display: flex;align-items: center;justify-content: center;font-size: 32rpx;color: #FFFFFF;border-radius: 12rpx;}
+
+	.mb16{margin-bottom: 32rpx;}
+	.mb14{margin-bottom: 28rpx;}
+	.tit{font-size: 30rpx;font-weight: bold;color: #343434;}
+	.trole{margin-left: 20rpx;height: 38rpx;background: #E9EFFD;font-size: 30rpx;font-weight: 500;color: #667087;padding: 0 12rpx;line-height: 38rpx;}
+	.txt{font-size: 30rpx;color: #343434;line-height: 32rpx;margin-bottom: 16rpx;}
+
+	.clistr{width: 48rpx;height: 48rpx;display: flex;justify-content: center;
+	image{width: 8rpx;height: 32rpx;}
+	}
+}
+.clista{padding:20rpx 0 12rpx;
+	.clistat{display: flex;flex-wrap: wrap;
+		view{width: 50%;}
+	}
+	view{font-size: 30rpx;color: #343434;line-height: 48rpx;}
+}
+
+.cardb{background: #FFFFFF;box-shadow: 0px 4rpx 6rpx 0px rgba(189,189,189,0.35);border-radius: 10rpx;padding:36rpx 30rpx 20rpx;margin-bottom: 20rpx;
+	.cardb_ta{font-weight: bold;color: #343434;font-size: 32rpx;}
+	.line{margin: 0 22rpx;width: 2rpx;height: 26rpx;background-color: #CDCDCD;}
+	.cardb_tb{height: 38rpx;background: #00B034;border-radius: 6rpx;min-width: 98rpx;padding: 0 12rpx;box-sizing: border-box;font-size: 32rpx;color: #FFFFFF;line-height: 38rpx;}
+	.cardb_b{display: flex;flex-wrap: wrap;
+		view{padding: 10rpx 0;font-size: 30rpx;color: #343434;width: 50%;}
+		.cor4{color: $uni-katype4;}
+		.cor3{color: $uni-katype3;}
+		.cor2{color: $uni-katype2;}
+		.cor5{color: $uni-katype5;}
+		.cor34{color: #343434;}
+		.time{display: inline-block;}
+	}
+}
+
+.cardc{
+	.cardc_ta{background: #FFFFFF;box-shadow: 0px 4rpx 6rpx 0px rgba(189,189,189,0.35);border-radius: 10rpx;padding: 0 24rpx 0 36rpx;min-height: 84rpx;box-sizing: border-box;margin-bottom: 24rpx;
+	&.nextb{background: #D6E2F2;}
+	.cardc_tb{font-weight: 500;font-size: 34rpx;color: #343434;margin-right: 6rpx;
+		&.nexta{padding-left: 20rpx;font-weight: 500;}
+	}
+	.cardc_tc{width: 48rpx;height: 48rpx;display: flex;justify-content: center;align-items: center;
+		.cardc_timg{width: 28rpx;height: 28rpx;}
+		.cardc_timga{width: 24rpx;height: 16rpx; transform: rotate(180deg);
+			  transition: all .5s;}
+		.cardc_timgb{width: 10rpx;height: 38rpx;}
+	}
+	
+	}
+	.cardc_td{height: 0rpx;overflow: hidden;}
+}
+
+
+
+
+.cont_tflex{padding:20rpx 0 14rpx;justify-content: center;
+	.cont_tftit{font-size: 28rpx;color: #666666;margin-bottom: 20rpx;}
+	.cont_tftxt{font-size: 34rpx;
+	 &.cor1{color:$uni-katype1;}
+	 &.cor2{color:$uni-katype2;}
+	 &.cor3{color:$uni-katype3;}
+	 &.cor4{color:$uni-katype4;}
+	 &.cor5{color:$uni-katype5;}
+	}
+}
+.datachek{width: 40rpx;height: 40rpx;display: flex;align-items: center;justify-content: center;margin-right: 32rpx;position: absolute;left: -60rpx;top:50%;margin-top: -20rpx;
+	image{width: 40rpx;height: 40rpx;}
+}
+.rolebox{transition: all .5s;margin-left: 0rpx;position: relative;}
+.roleboxtrans{margin-left: 60rpx;}
+// 无数据
+.nodata{
+	padding-top: 200rpx;display: flex;flex-direction: column;align-items: center;
+	image{width: 472rpx;height: 308rpx;margin-bottom: 48rpx;}
+	view{font-size: 30rpx;color: #343434;font-weight: bold;}
+}
+</style>

+ 49 - 10
work/components/lunc-calendar/lunc-calendar.vue

@@ -8,7 +8,7 @@
 			<text class="head-icon head-pre-month" v-if="showChangeBtn" @click="changeMonthOrWeek('prev')"></text>
 			<text class="head-month">{{selDate.year+'年'+(selDate.month<10?'0'+selDate.month:selDate.month)+'月'}}</text>
 			<text class="head-icon head-next-month" v-if="showChangeBtn" @click="changeMonthOrWeek('next')"></text>
-			<text class="go-to-today" v-if="showToday" @click="goToday">今天</text>
+			<!-- <text class="go-to-today" v-if="showToday" @click="goToday">今天</text> -->
 		</view>
 		<!-- 星期 -->
 		<view class="week-area" :class="firstDayOfWeek=='sunday'?'week-tit':''">
@@ -25,18 +25,25 @@
 							<!-- 之前日期不可约 c.isBefore?'day-infoa':''-->
 							<view class="day-info" :class="[c.dayClass, getIsSelDay(c)&&'is-sel', c.dayType!='normal'&&'un-month',
 							]">
-								<text class="day-solar">{{ c.day }}</text>
 								<template v-if="c.sign&&c.sign.length">
-									<view class="cirs">
-										<view class="cir bga" v-if="c.sign[0].amex=='2'&&c.sign[0].pmex=='2'"></view>
-										<view class="cir bga" v-else-if="c.sign[0].amex=='2'||c.sign[0].pmex=='2'"></view>
-										<view class="cir" v-else></view>
+									<template v-if="c.sign[0].holidaytype">
+										<text class="day-solar" :class="c.sign[0].holidaytype=='YES'?'co16':'coa'">{{ c.day }}</text>
+									</template>
+									<text class="day-solar" v-else>{{ c.day }}</text>
+									<view class="cirs" v-if="(c.isBefore||c.isToday)&&(c.sign[0].holidaytype!='NO'||!c.sign[0].holidaytype)">
+										<block v-if="c.week!=0&&c.week!=6||c.sign[0].holidaytype=='YES'">
+											<view class="cir bga" v-if="c.sign[0].amex=='5'&&c.sign[0].pmex=='5'"></view>
+											<view class="cir" v-else-if="c.sign[0].amex=='1'&&c.sign[0].pmex=='1'"></view>
+											<view class="cir bgb" v-else></view>
+										</block>
+										
 										<!-- <block v-else>
 											<view class="cir" :class="c.sign[0].amex=='2'?'bgb':''"></view>
 											<view class="cir" :class="c.sign[0].pmex=='2'?'bgb':''"></view>
 										</block> -->
 									</view>
 								</template>
+								<text class="day-solar" v-else>{{ c.day }}</text>
 							</view>
 						</view>
 					</view>
@@ -137,6 +144,13 @@
 					return 'Y'
 				}
 			},
+			// 选中的日期
+			recordDate:{
+				type: String,
+				default () {
+					return ''
+				}
+			}
 		},
 		data() {
 			return {
@@ -156,6 +170,7 @@
 				isshowPrev:false,//切换当月的上一个月
 				shrinkType: false, // 收缩状态,true:收起(显示周),false展开(显示月)
 				deterChange: true, // 防止切换月份过快
+				redtoday:{}
 			}
 		},
 		created() {
@@ -165,6 +180,14 @@
 				month: nd.getMonth() + 1,
 				day: nd.getDate()
 			}
+			if(this.recordDate){
+				let rednd = new Date(this.recordDate);
+				this.redtoday = {
+					year: rednd.getFullYear(),
+					month: rednd.getMonth() + 1,
+					day: rednd.getDate()
+				}
+			}
 			if (this.firstDayOfWeek == "sunday") this.weekArr = ['日', '一', '二', '三', '四', '五', '六'];
 			this.initDate();
 		},
@@ -202,7 +225,12 @@
 		},
 		methods: {
 			initDate() { // 初始化日期
-				this.selDate = JSON.parse(JSON.stringify(this.today));
+				if(this.recordDate){
+					this.selDate = JSON.parse(JSON.stringify(this.redtoday));
+				}else{
+					this.selDate = JSON.parse(JSON.stringify(this.today));
+				}
+				
 				let monthList = this.getMonthData(this.selDate); // 获取当月数据
 				let prevMonthList = this.getMonthData(this.getMonthDate(this.selDate, -1)); // 上月数据
 				let nextMonthList = this.getMonthData(this.getMonthDate(this.selDate)); // 下月数据
@@ -251,8 +279,13 @@
 				let isToday = false; //是否今天
 				let isBefore=false;//是否今天之前
 				if (year == this.today.year && month == this.today.month && day == this.today.day) isToday = true;
-				if(year==this.today.year&&month == this.today.month && day < this.today.day) isBefore=true;
-				
+				if(year==this.today.year&&month == this.today.month && day < this.today.day){
+					isBefore=true; 
+				}else if(year==this.today.year&&month < this.today.month){
+					isBefore=true;
+				}else if(year<this.today.year){
+					isBefore=true; 
+				}
 				let week = new Date(year + "/" + month + "/" + day).getDay(); //星期数
 				let lunar = calendar.solar2lunar(year, month, day); //农历
 				let dayLunar = lunar.IDayCn == '初一' ? lunar.IMonthCn + lunar.IDayCn : lunar.IDayCn;
@@ -818,6 +851,8 @@
 									// background:#ffffff;
 									display: block;
 									// font-weight: bold;
+									&.coa{color: #AAAAAA !important;}
+									&.co16{color: #161616 !important;}
 								}
 
 								.day-lunar,
@@ -861,6 +896,7 @@
 							// 周末
 							.week-end .day-solar {
 								// color: #FF9595;
+								color: #AAAAAA;
 							}
 
 							// 法定假日
@@ -883,7 +919,10 @@
 							.is-sel {
 								background-color: $com-cd3;
 								border-radius: 16rpx;
-								.day-solar{color: #ffffff !important}
+								.day-solar{color: #ffffff !important;
+									&.coa{color: #ffffff !important;}
+									&.co16{color: #ffffff !important;}
+								}
 								.day-sign{color: #ffffff !important;}
 							}
 						}

+ 19 - 4
work/components/yuyue/list.vue

@@ -84,19 +84,34 @@
 					<view class="tit" v-if="ite.userName">{{ite.userName.charAt(0)}}</view>
 					<view class="cent">
 						<view class="ctit">{{ite.userName}}的打卡记录</view>
-						<view class="ctime">最新打卡:{{ite.recordTime}}</view>
+						<view class="ctime">最新打卡:{{ite.clockMap.date}}</view>
 					</view>
 					<view class="rights" v-if="ite.type=='N'">
 						<image :src="ybga"></image>
 						<view>缺卡</view>
 						<!-- <view>迟到</view> -->
 					</view>
+					<view class="rights" v-if="ite.clockMap.amex>1&&ite.clockMap.amex<5||ite.clockMap.pmex>1&&ite.clockMap.pmex<5">
+						<image :src="ybga"></image>
+						<view v-if="ite.clockMap.amex==2 ||ite.clockMap.pmex==2">外勤</view>
+						<view v-else-if="ite.clockMap.amex==3 ||ite.clockMap.pmex==3">迟到</view>
+						<view v-else-if="ite.clockMap.amex==4||ite.clockMap.pmex==4">早退</view>
+					</view>	
 				</view>
 				<view class="ybox">
-					<view class="yblist mw50 line"><text>上班打卡</text>{{ite.workingTime}}
-						<!-- <view class="tip">迟到</view> -->
+					<view class="yblist mw50 line"><text>上班打卡</text>{{ite.clockMap.am}}
+						<view class="tip" v-if="ite.clockMap.amex>1&&ite.clockMap.amex<5">
+							<block v-if="ite.clockMap.amex==2">外勤</block>
+							<block v-if="ite.clockMap.amex==3">迟到</block>
+							<block v-if="ite.clockMap.amex==4">早退</block>
+						</view>
 					</view>
-					<view class="yblist mw50"><text>下班打卡</text>{{ite.dutyTime}}
+					<view class="yblist mw50"><text>下班打卡</text>{{ite.clockMap.pm}}
+						<view class="tip" v-if="ite.clockMap.pmex>1&&ite.clockMap.pmex<5">
+							<block v-if="ite.clockMap.pmex==2">外勤</block>
+							<block v-if="ite.clockMap.pmex==3">迟到</block>
+							<block v-if="ite.clockMap.pmex==4">早退</block>
+						</view>
 					</view>
 				</view>
 			</view>

+ 209 - 0
work/pages/clock/abnormal.vue

@@ -0,0 +1,209 @@
+<template>
+	<view class="abbox">
+		<block v-for="(ite,idx) in recordList" :key='idx'>
+			<view class="ablist" v-if="ite.kaTypeAmIn&&ite.kaTypeAmIn!=1">
+				<view class="ablistop">
+					<view>{{ite.kaTime}} {{weeks[ite.kaWeek]}}</view>
+					<view>上午上班
+						<text v-if="ite.kaTypeAmIn==2">迟到</text>
+						<text v-if="ite.kaTypeAmIn==3">外勤</text>
+						<text v-if="ite.kaTypeAmIn==4">早退</text>
+						<text v-if="ite.kaTypeAmIn==5">旷工</text>
+					
+					</view>
+				</view>
+				<!-- <view class="ablistr bg1" v-if="ite.kaTypeAmIn==2||ite.kaTypeAmIn==4||ite.kaTypeAmIn==5">补卡</view>
+				<view class="ablistr bg6" v-if="ite.kaTypeAmIn==3">外勤</view> -->
+				<view class="ablistr cicr2" v-if="ite.kaTypeAmIn==2">迟到</view>
+				<view class="ablistr cicr3" v-if="ite.kaTypeAmIn==3">外勤</view>
+				<view class="ablistr cicr4" v-if="ite.kaTypeAmIn==4">早退</view>
+				<view class="ablistr cicr5" v-if="ite.kaTypeAmIn==5">旷工</view>
+			</view>
+			<view class="ablist" v-if="ite.kaTypeAmOut&&ite.kaTypeAmOut!=1">
+				<view class="ablistop">
+					<view>{{ite.kaTime}} {{weeks[ite.kaWeek]}}</view>
+					<view>上午下班
+						<text v-if="ite.kaTypeAmOut==2">迟到</text>
+						<text v-if="ite.kaTypeAmOut==3">外勤</text>
+						<text v-if="ite.kaTypeAmOut==4">早退</text>
+						<text v-if="ite.kaTypeAmOut==5">旷工</text>
+					
+					</view>
+				</view>
+				<!-- <view class="ablistr bg1" v-if="ite.kaTypeAmOut==2||ite.kaTypeAmOut==4||ite.kaTypeAmOut==5">补卡</view>
+				<view class="ablistr bg6" v-if="ite.kaTypeAmOut==3">外勤</view> -->
+				<view class="ablistr cicr2" v-if="ite.kaTypeAmOut==2">迟到</view>
+				<view class="ablistr cicr3" v-if="ite.kaTypeAmOut==3">外勤</view>
+				<view class="ablistr cicr4" v-if="ite.kaTypeAmOut==4">早退</view>
+				<view class="ablistr cicr5" v-if="ite.kaTypeAmOut==5">旷工</view>
+			</view>
+			<view class="ablist" v-if="ite.kaTypePmIn&&ite.kaTypePmIn!=1">
+				<view class="ablistop">
+					<view>{{ite.kaTime}} {{weeks[ite.kaWeek]}}</view>
+					<view>下午上班
+						<text v-if="ite.kaTypePmIn==2">迟到</text>
+						<text v-if="ite.kaTypePmIn==3">外勤</text>
+						<text v-if="ite.kaTypePmIn==4">早退</text>
+						<text v-if="ite.kaTypePmIn==5">旷工</text>
+					
+					</view>
+				</view>
+				<!-- <view class="ablistr bg1" v-if="ite.kaTypePmIn==2||ite.kaTypePmIn==4||ite.kaTypePmIn==5">补卡</view>
+				<view class="ablistr bg6" v-if="ite.kaTypePmIn==3">外勤</view> -->
+				<view class="ablistr cicr2" v-if="ite.kaTypePmIn==2">迟到</view>
+				<view class="ablistr cicr3" v-if="ite.kaTypePmIn==3">外勤</view>
+				<view class="ablistr cicr4" v-if="ite.kaTypePmIn==4">早退</view>
+				<view class="ablistr cicr5" v-if="ite.kaTypePmIn==5">旷工</view>
+			</view>
+			<view class="ablist" v-if="ite.kaTypePmOut&&ite.kaTypePmOut!=1">
+				<view class="ablistop">
+					<view>{{ite.kaTime}} {{weeks[ite.kaWeek]}}</view>
+					<view>下午下班
+						<text v-if="ite.kaTypePmOut==2">迟到</text>
+						<text v-if="ite.kaTypePmOut==3">外勤</text>
+						<text v-if="ite.kaTypePmOut==4">早退</text>
+						<text v-if="ite.kaTypePmOut==5">旷工</text>
+					
+					</view>
+				</view>
+				<!-- <view class="ablistr bg1" v-if="ite.kaTypePmOut==2||ite.kaTypePmOut==4||ite.kaTypePmOut==5">补卡</view> -->
+				<view class="ablistr cicr2" v-if="ite.kaTypePmOut==2">迟到</view>
+				<view class="ablistr cicr3" v-if="ite.kaTypePmOut==3">外勤</view>
+				<view class="ablistr cicr4" v-if="ite.kaTypePmOut==4">早退</view>
+				<view class="ablistr cicr5" v-if="ite.kaTypePmOut==5">旷工</view>
+			</view>
+			
+		</block>
+		<view class="shax" v-if="recordList.length>0">{{wtdt}}</view>
+		<view class="nodata" v-else>
+			<image :src="noiconpimg"></image>
+			<view>
+				暂无数据
+			</view>
+		</view>
+		<!-- <block v-else>
+			<view class="shax">
+				暂无数据
+			</view>
+		</block> -->
+		<!-- <view class="ablist">
+			<view class="ablistop">
+				<view>2021-05-12 星期一</view>
+				<view>临时请假 1小时32分钟</view>
+				<view class="ablistopt">请假时间:09:06-10:38</view>
+			</view>
+			<view class="ablistr bg0" @click="getNoFan">销假</view>
+		</view>
+		<view class="ablist">
+			<view class="ablistop">
+				<view>2021-05-12 星期一</view>
+				<view>下午上班打卡 未打卡</view>
+				<view class="ablistopt">打卡时间:09:01</view>
+			</view>
+			<view class="ablistr bg6">请假</view>
+		</view> -->
+	</view>
+</template>
+
+<script>
+	import {
+		getRecordList} from "@/api/work/check.js"
+	export default{
+		data(){
+			return{
+				noiconpimg:require("@/work/static/clock/noiconp.png"),
+				pageNum:1,
+				pageSize:10,
+				reachflag:true,
+				wtdt:'上拉加载更多',
+				recordList:[],
+				userId: this.$store.state.user.userId,
+				deptId: this.$store.state.user.deptId,
+				weeks: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+			}
+		},
+		onLoad() {
+			// this.formatDateTime()
+			// this.getDataFn()
+		},
+		methods:{
+			getNoFan(){
+				this.$tab.navigateTo("/pages/noleave")
+			},
+			formatDateTime() {
+				var date=new Date()
+			  let y = date.getFullYear();
+			  let m = date.getMonth() + 1;
+			  m = m < 10 ? "0" + m : m;
+			  let d = date.getDate();
+			  d = d < 10 ? "0" + d : d;
+			  const time = y + "-" + m ;
+			  this.kaYear=y;
+			  this.kaMonth=m;
+			  return `${y}-${m}`;
+			
+			},
+			getDataFn() {
+			var params = {
+					deptId: this.deptId,
+					userId: this.userId,
+					pageSize: this.pageSize,
+					pageNum: this.pageNum,
+					kaYear: this.kaYear,
+					kaMonth: this.kaMonth,
+					kaStatus:2
+					}
+					getRecordList(params).then(res => {
+						if (res.code == 200) {
+							if (res.rows.length < this.pageSize) {
+								this.reachflag = false
+								this.wtdt = '到底了~';
+							} else {
+								var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -
+									1)
+								if (num < res.total) {
+									this.reachflag = true
+									this.wtdt = '上拉加载更多'
+								} else {
+									this.reachflag = false
+									this.wtdt = '到底了~';
+								}
+							}
+							if (this.pageNum == 1) {
+								this.recordList = res.rows;
+							} else {
+								this.recordList = this.recordList.concat(res.rows)
+							}
+								
+						} else {
+							this.$toast(res.msg)
+						}
+					})		
+			},
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+.nodata{
+		padding-top: 200rpx;display: flex;flex-direction: column;align-items: center;
+		image{width: 472rpx;height: 308rpx;margin-bottom: 48rpx;}
+		view{font-size: 26rpx;color: #343434;font-weight: bold;}
+	}
+.abbox{padding: 32rpx 32rpx 4rpx;background-color: #f2f2f2;box-sizing: border-box;min-height: 100vh;}
+
+.ablist{background: #FFFFFF;
+box-shadow: 0px 4rpx 6rpx 0px rgba(189,189,189,0.35);margin-bottom: 20rpx;
+border-radius: 10rpx;padding: 36rpx 24rpx 20rpx 36rpx;display: flex;align-items: center;
+	.ablistop{font-size: 28rpx;color: #343434;flex: 1;line-height: 40rpx;
+		.ablistopt{font-size: 28rpx;color: #666666;margin-top: 6rpx;}
+	}
+	.ablistr{min-width: 138rpx;height: 48rpx;background: #6CBC0A;border-radius: 24rpx;font-size: 26rpx;color: #FFFFFF;line-height: 48rpx;text-align: center;padding: 0 12rpx;box-sizing: border-box;flex: 0 0 auto;margin-left: 20rpx;
+
+	&.cicr2{background-color: $uni-katype2 !important;}//迟到
+	&.cicr3{background-color: $uni-katype3 !important;}//外勤
+	&.cicr4{background-color: $uni-katype4 !important;}//早退
+	&.cicr5{background-color: $uni-katype5 !important;}//旷工
+	}
+}
+</style>

+ 73 - 0
work/pages/clock/cardSupple.vue

@@ -0,0 +1,73 @@
+<template>
+	<view class="lists">
+
+			<view class="list" @click="showDatePicker">
+				<view class="listl"><text>*</text>补卡时间</view>
+				<view class="listi" :style="formData.applicationTime?'':'color: #AAAAAA;'">{{formData.applicationTime||"请选择补卡时间"}}</view>
+				<image :src="rimg"></image>
+			</view>
+			<view class="list lista" >
+				<view class="listl"><text>*</text>补卡原因</view>
+				<textarea placeholder="请输入补卡原因" maxlength="1000" class="listia" v-model="formData.reason"></textarea>
+				<view class="listib">{{formData.reason.length}}/1000</view>
+			</view>
+
+		<view class="listbtn" @click="getSure">提交</view>
+		<dataTimePicke ref="timeicker" type="datetime-all" toolBarTitle="请选择时间" @change="timeChange"></dataTimePicke>
+
+	</view>
+</template>
+
+<script>
+	import dataTimePicke from "@/components/timepick/dataTimePicke.vue"
+	import {getMapconfig} from "@/api/work/check.js"
+	export default{
+		data(){
+			return{
+				rimg:require("@/work/static/clock/right.png"),
+				formData:{
+					applicationTime:'',
+					reason:''
+				}
+				
+			}
+		},
+		components:{
+			dataTimePicke
+		},
+		onLoad(e) {
+
+			
+		},
+		mounted() {
+
+		},
+		methods:{
+			showDatePicker(){
+				this.$refs.timeicker.show();	
+			},
+			timeChange(e){
+				that.formData.applicationTime=e
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss">
+page{background-color: #FFFFFF;}
+	.lists{padding: 20rpx 34rpx;
+		.list{padding:30rpx 0;display: flex;align-items: center;
+		&.lista{flex-direction: column;align-items: flex-start;}
+			.listl{font-size:28rpx;font-weight: bold;color: #343434;flex:0 0 auto;margin-right: 26rpx;
+			text{font-size: 28rpx;color: #FF0000;margin-right: 8rpx;}
+}
+			.listr{font-size: 28rpx;color: #1678FF;flex: 1 ;text-decoration: underline;text-align: right;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
+			.listi{font-size:28rpx;color: #343434;flex:1;text-align: right;}
+			.listia{font-size:28rpx;color: #343434;text-align: left;margin-top: 24rpx;width: 100%;}
+			.listib{font-size: 28rpx;color: #666666;text-align: right;margin-top: 20rpx;width: 100%;}
+			image{width: 10rpx;height: 18rpx;flex: 0 0 auto;margin-left: 26rpx;}
+		}
+		.listbtn{width: 100%;height: 76rpx;background: #1678FF;border-radius: 6px;font-size: 28rpx;color: #FFFFFF;margin-top:70rpx;line-height: 76rpx;text-align: center;}
+	}
+	.boxtopbb{text-decoration: none;}
+</style>

+ 851 - 0
work/pages/clock/clock.vue

@@ -0,0 +1,851 @@
+<template>
+	<view>
+		<view class="lock">
+			<view class="lock_header">
+				<view class="limgs">
+					<image :src="juehg.avatar" alt="" v-if="juehg.avatar"></image>
+					<image :src="headimg" alt="" v-else></image>
+				</view>
+				<view class="toptxt">
+					<view class="tit">{{ juehg.nickName}}</view>
+					<view class="txt">{{ kaTime }}</view>
+				</view>
+				<view class="topr" @click="getRecondFn">查看考勤记录 ></view>
+			</view>
+			<view class="bottom">
+				<view class="olp mb24">
+					<text>当前位置</text>
+					<text @click="shuiux">点击刷新</text>
+				</view>
+				<view class="bott_nav">
+					<image :src="adrimg"></image>
+					<view>{{ address || '获取地址中' }}</view>
+				</view>
+				<!-- 休息 -->
+				<!-- <view  class="restbox">
+					<image :src="restimg"></image>
+					<view>今日休息</view>
+					<view>无需打卡哟~</view>
+				</view> -->
+				<!-- 第二部分 -->
+				<view class="lock_navebut">
+					<block v-if="ruleflag">
+						<view class="cbtn" :class="[kaRadfalg == false ? 'bgb' : '']" @click="getPunchFn">
+							<text class="time">{{ gettime }}</text>
+							<text class="ctimea" v-if="kaRadfalg">{{ timetext }}</text>
+							<text class="ctimea" v-else>外勤打卡</text>
+						</view>
+						<view class="ctips" v-if="kaRadfalg" @click="getSuccessFn">
+							<image :src="yk1img"></image>
+							<text>已进入考勤范围</text>
+						</view>
+						<view class="ctips" v-else>
+							<image :src="noimg"></image>
+							<text>未进入考勤范围</text>
+						</view>
+					</block>
+					<view v-else class="cbtn bga"><text class="ctimea">暂无考勤规则</text></view>
+				</view>
+				<!-- 第三部分 -->
+				<view class="lockbom_nam">
+					<!-- 步骤条 -->
+					<view class="steps">
+						<view class="stepsa" v-for="(item, idx) in recordList" :key="idx">
+							<image :src="stepa" class="stepstb"></image>
+							<view class="stepst">
+								{{item.type==1?'上班':'下班'}}打卡
+								<text class="co1" v-if="item.isOutwork == 3">迟到</text>
+								<text class="co2" v-else-if="item.isOutwork == 2">外勤</text>
+								<text class="co3" v-else-if="item.isOutwork == 4">早退</text>
+								<!-- <text class="co4" >旷工</text> -->
+							</view>
+							<view class="stepstc">
+								<view class="stepstimg"><image :src="stepb" class="imagea"></image></view>
+								<view class="stepstxt">{{ item.recordTime }} 打卡成功</view>
+							</view>
+							<view class="stepstc">
+								<view class="stepstimg"><image :src="stepc" class="imageb"></image></view>
+								<view class="stepstxt">{{ item.recordLocations }}</view>
+							</view>
+							<!-- 图片 -->
+							<view class="stepstc" v-if="item.pictureUrl">
+								<view class="stepstimg"><image :src="pimg" class="imagec"></image></view>
+								<image :src="baseUrl+item.pictureUrl" class="pimgs" @click="getpreviewImage(baseUrl+item.pictureUrl)"></image>
+							</view>
+							<!-- 情况说明 -->
+							<view class="stepstc" v-if="item.remark">
+								<view class="stepstimg"><image :src="stepd" class="imagea"></image></view>
+								<view class="stepstxt">{{ item.remark }}</view>
+							</view>
+						</view>
+						<!-- <view class="stepsa">
+							<image :src="stepa" class="stepstb"></image>
+							<view class="stepst">下班打卡</view>
+						</view> -->
+					</view>
+				</view>
+			</view>
+			<!-- 迟到打卡 -->
+			<view class="bgbox" v-if="chiflag" @click="getClose"></view>
+			<view class="bgfixed" v-if="chiflag">
+				<!-- <view class="bgfixed"  @click="getClose"> -->
+				<view class="tit mb16">
+					<image :src="closeimg" @click="getClose"></image>
+					<view>
+						<block v-if="!kaRadfalg">外勤</block>
+						<block v-if="datainfo.isOutwork==3">迟到</block>
+						<block v-if="datainfo.isOutwork==4">早退</block>
+					打卡</view>
+				</view>
+				<!--  -->
+				<view class="txt" style="flex-direction: column;" >
+					<view class="txta">
+						<view>拍照</view>
+						<image :src="photoimg" class="photoimg" @click="getphotoFn"></image>
+					</view>
+					<view class="imgsur" v-if="imgurlshow"><image :src="imgurlshow" class="txtimg" @click="getpreviewImage(imgurlshow)"></image></view>
+				</view>
+				<view class="txt" style="align-items: flex-start;">
+					<view>备注</view>
+					<uni-easyinput class="input" :inputBorder="false" type="textarea" autoHeight  v-model="chitext"
+						placeholder="请填写原因">
+					</uni-easyinput>
+					<!-- <input placeholder="请填写原因" v-model="chitext" /> -->
+				</view>
+				<view class="btn" @click="getPunchFnchi()">确认打卡</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+// import BMap from 'BMap'
+// import AMap from 'AMap'
+import amapPlugin from '@/utils/initmap.js';
+import self from '@/utils/location.js';
+import store from '@/store';
+import { clocklist, getRecordList, getNormalFn, getPunchFn, getPunchputFn } from '@/api/work/check.js';
+import { uploadPhoto } from '@/api/system/user.js';
+import { selectDictLabel } from '@/utils/common';
+import amapFile from '@/plugins/amap-wx.js';
+import config from '@/config.js';
+const baseUrl = config.baseUrl;
+// #ifdef APP
+var myAmapFun = new amapFile.AMapWX({
+	key: 'ccbe52b1ec5f66295fa4609c90a819b7',
+	batch: true
+});
+// #endif
+export default {
+	// name: 'AMap',
+	data() {
+		return {
+			baseUrl:'',
+			stepa: require('@/work/static/clock/stepa.png'),
+			stepb: require('@/work/static/clock/stepb.png'),
+			stepc: require('@/work/static/clock/stepc.png'),
+			stepd: require('@/work/static/clock/stepd.png'),
+			noimg: require('@/work/static/clock/moico.png'),
+			closeimg: require('@/work/static/clock/close.png'),
+			photoimg: require('@/work/static/clock/photo.png'),
+			pimg: require('@/work/static/clock/pimg.png'),
+			adrimg: require('@/work/static/clock/adress.png'),
+			headimg: require('@/work/static/clock/pic_mine_hp_normal.png'),
+			yk1img: require('@/work/static/clock/icon_kqdk_jrfw.png'),
+			noimg: require('@/work/static/clock/moico.png'),
+			
+			restimg:require('@/work/static/clock/rest.png'),
+			
+			address: '',
+			timefn: '',
+			gettime: '',
+			juehg: {
+				deptName: '暂无数据',
+				userName: '暂无数据',
+				avatar: ''
+			},
+			timetext: '',
+			loading: false,
+			text: '选择日期',
+			place: {
+				lng: '',
+				lat: ''
+			},
+			center: {
+				lng: '',
+				lat: ''
+			},
+			kaNum: 2, //打卡次数
+			kaRadius: '',
+			rulelist:[],//考勤规则
+			kaRadfalg: false,
+			kaTime: '',
+			kaYear: '',
+			kaMonth: '',
+			kaDay: '',
+			kaWeek: 0,
+			recordList: [],
+			userId: this.$store.state.user.userId,
+			deptId: this.$store.state.user.deptId,
+			// kaSort: 1, //打卡分类 1:上午上班 2:上午下班 3:下午上班 4:下午下班,
+			kaType: 1, //打卡类别 1正常 2:迟到 3:外勤 4:早退
+			kaStatus: 1, //打卡状态 1正常 2:异常
+			chiflag: false,
+			recordId: '', //覆盖式打卡
+			daKainfo: {
+				"recordDt": "",//打卡记录完整时间(yyyy-MM-dd HH:mm:ss)
+				"recordDate": "",//打卡记录日期(yyyy-mm-dd)
+				"recordTime": "",//打卡记录时间(HH:mm:ss)
+				"recordLocations": "",//打卡地点
+				"week": "",//周几(1:星期一,2:星期二,3:星期三,4:星期四,5:星期五,6:星期六,7:星期日)
+				"isOutwork":"",//打卡情况  1:正常打卡,2:外勤打卡,3:迟到,4:早退
+				"pictureUrl":"",//图片地址
+				"type":"",//上班,下班打卡 1:上班,2:下班
+			},
+			//打卡参数
+			formData: {
+				startWorkTime:"",
+				endWorkTime:'',
+			},
+			datainfo:{},
+			imgurl: '',
+			imgurlshow:'',
+			chitit: '',
+			chitext: '',
+			chitype: '',
+			ruleflag:true,
+			shuatime:30,
+			refreshflag:true,
+			yestday:'',
+			yestkaTime:'',
+			yestkaYear:'',
+			yestkaMonth:'',
+			yestkaDay:'',
+			yestkaWeek:'',
+			recordYestList:[],
+			guoflag:false,
+		};
+	},
+	created() {
+		this.baseUrl=baseUrl;
+		this.init();
+	},
+	mounted() {
+		this.datainfo.userId = this.$store.state.user.userId;
+		// this.formData.deptId = this.$store.state.user.deptId;
+		// this.formData.ancestors = this.$store.state.user.ancestors;
+		// this.formData.deptName = this.$store.state.user.deptName;
+		// this.datainfo.userName = this.$store.state.user.nickName;
+		this.juehg = this.$store.state.user;
+	},
+	onUnload() {
+		clearInterval(this.timefn)
+	},
+	methods: {
+		init() {
+			var that=this;
+			// 时间
+			this.gettimeFn();
+			// 规则
+			this.getRuleFn();
+			// that.getRecordYestList();
+			setTimeout(function(){
+				that.getRecordList();
+			},1000)
+			//加个拍照,考勤设置,加个是否启用拍照
+			// this.getAbnormal();
+		},
+		getClose(){
+			this.chiflag=false;
+		},
+		gettimeFn() {
+			var that = this;
+			clearInterval(this.timefn)
+			that.time();
+			var stime=this.shuatime
+			that.timefn = setInterval(function() {
+				if(stime<=1){
+					// that.shuiux()
+					stime=that.shuatime
+				}
+				stime=stime-1;
+				that.time();
+			}, 1000);
+		},
+		// 日期
+		time() {
+			var date = new Date();
+			var y = date.getFullYear();
+			var m = date.getMonth() + 1;
+			var d = date.getDate();
+			var h = date.getHours();
+			var min = date.getMinutes();
+			var s = date.getSeconds();
+			var week = date.getDay(); //获取当前星期X(0-6,0代表星期天)
+			var weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
+			var yearStr = y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d);
+			var timeStr = (h < 10 ? '0' + h : h) + ':' + (min < 10 ? '0' + min : min) + ':' + (s < 10 ? '0' + s : s);
+			
+			// 获取昨天的
+			let yesterday_milliseconds=date.getTime()-1000*60*60*24;
+			let yesterday=new Date();
+			 yesterday.setTime(yesterday_milliseconds);
+			 let year=yesterday.getFullYear();
+			 let day=yesterday.getDate();
+			 let month=yesterday.getMonth()+1;
+			 var yestweek = yesterday.getDay(); //获取当前星期X(0-6,0代表星期天)
+			 var yestday= year + '-' + (month < 10 ? '0' + month : month) + '-' + (day < 10 ? '0' + day : day);
+			 var yesttimeStr = (h < 10 ? '0' + h : h) + ':' + (min < 10 ? '0' + min : min) + ':' + (s < 10 ? '0' + s : s);
+			 this.yestday=yestday;
+			 this.yestkaTime=yestday;
+			 this.yestkaYear = year;
+			 this.yestkaMonth = month < 10 ? '0' + month : month;
+			 this.yestkaDay = day < 10 ? '0' + day : day;
+			 this.yestkaWeek = yestweek;
+			
+			
+			this.kaTime = yearStr;
+			this.kaYear = y;
+			this.kaMonth = m < 10 ? '0' + m : m;
+			this.kaDay = d < 10 ? '0' + d : d;
+			this.kaWeek = week;
+			this.gettime = timeStr;
+			// 年,月,日, 星期几 时分秒
+		},
+		shuiux() {
+			if(this.refreshflag){
+				this.refreshflag=false;
+				this.getLocation();
+				// this.getRecordList();
+				
+				// this.getRuleFn();//不至于每次都改打卡规则
+				var that=this;
+				setTimeout(function(){
+					that.refreshflag=true;
+					that.loctiotimeup();
+				},2000)
+			}else{
+				this.refreshflag=true;
+			}
+			
+		},
+		// 时间比较
+		getsort(beginTime, endTime, type) {
+			if(!beginTime||!endTime){
+				return false
+			}
+			var type = type || '';
+			var nowDate = new Date();
+			// var nowDate = new Date('2023/02/21 02:02:02');
+			var beginDate = new Date(nowDate);
+			var endDate = new Date(nowDate);
+			var beginIndex = beginTime.indexOf('\:');
+			var beginIndexs = beginTime.lastIndexOf('\:');
+			var beginHour = beginTime.substring(0, beginIndex);
+			var beginMinue = beginTime.substring(beginIndex + 1, beginIndexs);
+			var beginSecend = beginTime.substring(beginIndexs + 1, beginTime.length);
+			beginDate.setHours(beginHour, beginMinue, beginSecend, 0);
+			var endIndex = endTime.indexOf('\:');
+			var endIndexs = endTime.lastIndexOf('\:');
+			var endHour = endTime.substring(0, endIndex);
+			var endMinue = endTime.substring(endIndex + 1, endIndexs);
+			var endSecend = endTime.substring(endIndexs + 1, endTime.length);
+			endDate.setHours(endHour, endMinue, endSecend, 0);
+			if (type == 'guo') {
+				if (beginDate.getTime() - endDate.getTime() > 0) {
+					return true;
+				} else {
+					return false;
+				}
+			} else {
+				return nowDate.getTime() - beginDate.getTime() >= 0 && nowDate.getTime() <= endDate.getTime();
+			}
+		},
+		// 判断是上班还是下班
+		loctiotimeup() {
+			var a = this.daKainfo.startWorkTime;
+			var b = this.daKainfo.endWorkTime;
+			var kata =this.formData.startWorkTime;
+			var katb = '';
+			if (this.getsort('00:00:00', a)) {
+				// 上班卡
+				if(!kata){
+					this.timetext = '上班打卡';
+					this.datainfo.type = 1;
+					this.datainfo.isOutwork=1;
+				}else if(kata){
+					// 早退
+					this.timetext = '下班打卡';
+					this.datainfo.type = 2;
+					this.datainfo.isOutwork=4;
+				}
+			}else if (this.getsort(a, b)) {
+				if(!kata){
+					// 迟到打卡
+					this.timetext = '上班打卡';
+					this.datainfo.type = 1;
+					this.datainfo.isOutwork=3;
+					
+				}else if(kata){	
+					// 早退打卡
+					this.timetext = '下班打卡';
+					this.datainfo.type = 2;
+					this.datainfo.isOutwork=4;
+				}
+			}else if(this.getsort(b, '23:59:59')){
+				this.timetext = '下班打卡';
+				this.datainfo.type = 2;
+				this.datainfo.isOutwork = 1;
+			}	
+		},
+		getRuleFn() {
+			clocklist().then(res => {
+				if (res.rows) {
+					this.ruleflag=true;
+					this.rulelist=res.rows;
+					this.getLocation();
+				}else{
+					// 暂无考勤信息
+					this.ruleflag=false;
+					this.getLocation();
+				}
+			});
+		},
+		// 打卡信息
+		getRecordList() {
+			var params = {
+				// deptId: this.deptId,
+				userId: this.userId,
+				recordDate: this.kaTime
+			};
+			var a=0;
+			getRecordList(params).then(res => {
+				if (res.code == 200) {
+					this.recordList = JSON.parse(JSON.stringify(res.rows));
+					// 循环处理,获取上班时间,下班时间
+					var newArr=this.recordList;
+					if(newArr&&newArr.length){
+						Object.keys(newArr).some((key) => {
+							// 去重
+							var type=newArr[key].type||'';
+							var recordTime=newArr[key].recordTime||'';
+							if(type==1&&recordTime){
+								a=1;
+								this.formData.startWorkTime=recordTime
+								return
+							}
+							
+						})
+					}
+					
+					this.loctiotimeup();
+				} else {
+					this.$toast(res.msg);
+				}
+			});
+			// this.$toast("登录中,请耐心等待...")
+		},
+		// 获取当前定位
+		getLocation() {
+			var that = this;
+			// #ifdef H5
+			that.place.lng = '117.212214';
+			that.place.lat = '31.839812';
+			that.address = '安徽省合肥市蜀山区高新技术产业开发区黄山路597号时代数码港';
+			that.datainfo.recordLocations=that.address;
+			that.distancefor();
+			// // 解析编码
+			// that.address = res.addr + res.name;
+			// self.getLocation(function() {
+			// 	that.place.lng = self.__CFG.lng;
+			// 	that.place.lat = self.__CFG.lat;
+			// 	// 解析编码
+			// 	self.getGeocoder(self.__CFG.lng, self.__CFG.lat, function(res) {
+			// 		that.address = res.addr + res.name;
+			// 	});
+			// 	// 判断是不是在范围
+			// 	that.distance();
+			// });
+			// #endif
+			// #ifndef H5
+			this.getlocationapp();
+			// #endif
+		},
+		// 获取定位
+		getlocationapp() {
+			var that = this;
+			uni.getLocation({
+				type: 'gcj02',
+				geocode: true,
+				success: function(res) {
+					that.place.lng = res.longitude;
+					that.place.lat = res.latitude;
+					// #ifdef H5
+					var adr = address.province + address.city + address.district + address.street + address.streetNum + address.poiName;
+					// that.address=res.longitude
+					that.address = adr;
+					that.datainfo.recordLocations=adr;
+					// #endif
+					// #ifdef APP
+					// 判断是不是在范围
+					that.distancefor();
+					that.getCity(res.latitude, res.longitude);
+					// #endif
+				},
+				fail: function(red) {
+					uni.showToast({
+						title: '获取定位失败'
+					});
+				}
+			});
+		},
+		// 循环判断是不是在中心点
+		distancefor(lat1, lng1) {
+			var that = this;
+			var a=0;
+			// 中心点
+			var rules=JSON.parse(JSON.stringify(this.rulelist))
+			if(this.ruleflag){
+				Object.keys(rules).some((key) => {
+					// 去重
+					var lng=rules[key].lon||'';
+					var lat=rules[key].lat||'';
+					var distance=rules[key].distance
+					if(lng&&lat&&distance){
+						var type=that.getjiSort(lat,lng,distance);
+						if(type=='dk'){
+							this.kaRadfalg = true;
+							this.daKainfo=rules[key];
+							a=1;
+							return
+						}
+					}
+				})
+				if(a==0){
+					this.timetext = '外勤打卡';
+					this.kaRadfalg = false;
+					this.daKainfo=rules[0];
+				}
+			}	
+		},
+		getjiSort(clat,clng,distance){
+			// 中心点
+			var lat1 = clat;
+			var lng1 = clng;
+			// 自己点
+			let lat2 = this.place.lat;
+			let lng2 = this.place.lng;
+			let rad1 = (lat1 * Math.PI) / 180.0;
+			let rad2 = (lat2 * Math.PI) / 180.0;
+			let a = rad1 - rad2;
+			let b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
+					
+			let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)));
+			s = s * 6378.137;
+			s = Math.round(s * 10000) / 10;
+			s = s.toString();
+			s = s.substring(0, s.indexOf('.') + 2);
+			if (Number(s) < Number(distance)) {
+				return "dk"
+			} else {
+				return 'wq'
+			}
+		},
+		// 是否在打卡范围
+		distance(lat1, lng1) {
+			var that = this;
+			// 中心点
+			var lat1 = that.center.lat;
+			var lng1 = that.center.lng;
+			// 自己点
+			let lat2 = this.place.lat;
+			let lng2 = this.place.lng;
+			let rad1 = (lat1 * Math.PI) / 180.0;
+			let rad2 = (lat2 * Math.PI) / 180.0;
+			let a = rad1 - rad2;
+			let b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
+		
+			let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)));
+			s = s * 6378.137;
+			s = Math.round(s * 10000) / 10;
+			s = s.toString();
+			s = s.substring(0, s.indexOf('.') + 2);
+			if (Number(s) < Number(this.kaRadius)) {
+				this.kaRadfalg = true;
+			} else {
+				this.timetext = '外勤打卡';
+				this.kaRadfalg = false;
+			}
+			console.log(this.kaRadfalg)
+		},
+		getCity(latitude, longitude) {
+			var that = this;
+			that.location = `${longitude},${latitude}`;
+		
+			myAmapFun.getRegeo({
+				//如果经纬度有问题会导致不进入回调方法,从而报错
+				location: that.location,
+				success: function(e) {
+					//成功回调
+					that.address = '';
+					that.address = e[0].regeocodeData.formatted_address; //详细地址
+					that.datainfo.recordLocations=that.address;
+				},
+				fail: function(info) {
+					//失败回调
+					console.log(info);
+				}
+			});
+		},
+		getPunchFnchi() {
+			console.log(this.daKainfo)
+			if (this.daKainfo.isPicture == 'Y' && !this.imgurl) {
+				this.$toast('请拍照上传');
+				return;
+			}
+			// if(this.chitext==''){
+			// 	 this.$toast("请填写备注")
+			// 	 return
+			// }
+			// var parmas=JSON.parse(JSON.stringify(this.daKainfo))
+			
+			this.$nextTick(function() {
+				// 打卡
+				this.chiflag = false;
+				this.getPunchFnes();
+			});
+		},
+		// 打卡
+		getPunchFnes() {
+			var that = this;
+			var params = JSON.parse(JSON.stringify(this.datainfo));
+			params.recordDate=this.kaTime;
+			params.recordTime=this.gettime;
+			params.week=this.kaWeek;
+			params.recordDt=this.kaTime+' '+this.gettime;
+				
+			if(this.imgurl){
+				params.pictureUrl=this.imgurl;
+			}
+			if(this.chitext){
+				params.remark=this.chitext;
+			}	
+			if(!this.kaRadfalg){
+				params.isOutwork=2;
+			}
+			console.log(params)
+			// return
+			getPunchFn(params).then(res => {
+				if (res.code == 200) {
+					// 打卡成功
+					// this.getRecordList()
+					this.$tab.navigateTo('/work/pages/clock/success?tit=' + this.timetext);
+				} else {
+					this.$toast(res.msg);
+				}
+			});
+			return
+
+			// return
+			if (newArr.length) {
+				var len = newArr.length - 1;
+				// params['recordId'] = newArr[0].recordId;
+				// // 覆盖打卡
+				getPunchputFn(params).then(res => {
+					if (res.code == 200) {
+						// 打卡成功
+						// this.getRecordList()
+						this.$tab.navigateTo('/work/pages/clock/success?tit=' + this.timetext);
+					} else {
+						this.$toast(res.msg);
+					}
+				});
+			} else {
+				// params['recordId'] = '';
+				getPunchFn(params).then(res => {
+					if (res.code == 200) {
+						// 打卡成功
+						// this.getRecordList()
+						this.$tab.navigateTo('/work/pages/clock/success?tit=' + this.timetext);
+					} else {
+						this.$toast(res.msg);
+					}
+				});
+			}
+		},
+		getRecondFn(){
+			var obj={
+				userId:this.userId,
+				recordDate:this.kaTime
+				// recordDate:'2024-10-12'
+			}
+			this.$tab.navigateTo('/work/pages/record/detail?data='+encodeURIComponent(JSON.stringify(obj)))
+		},
+		getPunchFn(){
+			var that=this;
+			var parmas=JSON.parse(JSON.stringify(this.datainfo))
+			if (parmas.isOutwork ==3||parmas.isOutwork==4||!this.kaRadfalg) {
+				this.chiflag = true;
+				return
+			}
+			this.$nextTick(function() {
+				// 打卡
+				this.chiflag = false;
+				this.getPunchFnes();
+			});
+		},
+		getphotoFn() {
+			var that = this;
+			uni.chooseImage({
+				count: 1, //默认9
+				sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+				sourceType: ['camera'], //从相册选择
+				success: function(res) {
+					const tempFilePaths = res.tempFilePaths;
+					// 文件上传
+					let data = { name: 'file', filePath: res.tempFilePaths[0] };
+					uploadPhoto(data).then(response => {
+						that.imgurlshow = baseUrl + response.fileName;
+						that.imgurl =  response.fileName;
+						// if (!that.chiflag) {
+						// 	that.getPunchFnes();
+						// }
+					});
+				}
+			});
+		},
+		getpreviewImage(url) {
+			var urlArr = [];
+			urlArr[0] = url;
+			uni.previewImage({
+				urls: urlArr,
+				success: function(data) {
+					
+				},
+				fail: function(err) {
+					console.log(err.errMsg);
+				}
+			});
+		},
+		getSuccessFn(){
+			this.$tab.navigateTo("/work/pages/clock/success?tit=上班打卡")
+		},
+	}
+};
+</script>
+<style lang="less">
+page {
+	background: #ffffff;
+}
+</style>
+
+<style scoped lang="scss">
+.bgfixed /deep/ .uni-easyinput__content-textarea{min-height: 84rpx;margin: 0;} 
+	.steps {
+		padding: 0 60rpx;
+		.stepsa {position: relative;padding-bottom: 20rpx;
+			&::after {position: absolute;width: 2rpx;height: calc(100% - 16rpx);background: #DADADA;position: absolute;left: -30rpx;top: 28rpx;content: '';}
+			&:last-child::after {display: none;}
+			.stepstb {width: 16rpx;height: 16rpx;position: absolute;left: -36rpx;top: 12rpx;}
+			.stepst {font-size: 26rpx;font-weight: bold;color: #343434;
+				text{
+					font-size: 22rpx;padding: 0 6rpx;line-height: 20rpx;margin-left: 12rpx;border-radius: 4rpx;min-width: 64rpx;
+					&.co1{border: 2rpx solid $uni-katype2;color: $uni-katype2;}
+					&.co2{border: 2rpx solid $uni-katype3;color: $uni-katype3;}
+					&.co3{border: 2rpx solid $uni-katype4;color: $uni-katype4;}
+					&.co4{border: 2rpx solid $uni-katype5;color: $uni-katype5;}
+				}
+			}
+			.stepstc {padding-left: 12rpx;display: flex;padding: 6rpx 0;
+				.stepstimg {width: 22rpx;margin-right: 8rpx;height: 30rpx;flex: 0 0 auto;display: flex;align-items: center;
+					.imagea {width: 22rpx;height: 22rpx;}
+					.imageb {width: 18rpx;height: 18rpx;}
+					.imagec {width: 20rpx;height: 20rpx;}	
+				}
+				.pimgs{width: 70rpx;height: 70rpx;margin: 0 12rpx 12rpx 0;}
+				.stepstxt {font-size: 22rpx;color: #343434;flex: 1;}
+			}
+		}
+	}
+
+	.lock {background: #fff;padding: 50rpx 34rpx 54rpx;
+		.van-step--finish {
+			color: #07c160;
+		}
+
+		.lock_header {padding: 42rpx 40rpx;display: flex;align-items: center;box-shadow: 0px 0px 12rpx 0px rgba(153, 152, 152, 0.39);border-radius: 6rpx;
+			.limgs{width: 84rpx;height: 84rpx;margin-right: 24rpx;flex: 0 0 auto;
+				image{width: 100%;height: 100%;border-radius: 50%;}
+			}
+			.toptxt{flex: 1;
+				.tit{font-weight: bold;font-size: 28rpx;color: #343434;margin-bottom: 6rpx;}
+				.txt{font-weight: 400;font-size: 26rpx;color: #666666;}
+			}
+			.topr{font-weight: 400;font-size: 26rpx;color: #009FE8;flex: 0 0 auto;margin-left: 12rpx;}
+		}
+
+		//   第二部分样式
+		.bottom {box-shadow: 0px 0px 12rpx 0px rgba(153, 152, 152, 0.39);border-radius: 6rpx;margin-top: 30rpx;padding: 46rpx 34rpx 40rpx;
+
+
+			.olp {font-size: 28rpx;font-weight: bold;color: #343434;display: flex;justify-content: space-between;width: 100%;}
+
+			.bott_nav {
+				display: flex;margin-bottom: 100rpx;
+				image {width: 26rpx;height: 28rpx;margin-right: 12rpx;flex: 0 0 auto;margin-top: 4rpx;}
+				
+				view {flex: 1;font-size: 28rpx;font-weight: 400;color: #343434;
+				}
+			}
+		}
+
+		//   按钮样式
+		.lock_navebut {display: flex;flex-direction: column;justify-content: center;align-items: center;margin-bottom: 72rpx;
+			.cbtn {width: 368rpx;height: 194rpx;background: #1678ff;box-shadow: 0px 6rpx 6rpx 0px rgba(3, 141, 204, 0.39);border-radius: 96rpx;
+				display: flex;flex-direction: column;justify-content: center;align-items: center;margin-bottom: 40rpx;
+				&.bga{background-color: #999;box-shadow: 0px 6rpx 6rpx 0px rgba(153, 152, 152, 0.39)}
+				&.bgb{background-color: #39b54a;box-shadow: 0px 6rpx 6rpx 0px rgba(4, 147, 52, 0.39)}
+				.time{font-size: 30rpx;font-weight: bold;color: #ffffff;margin-bottom: 8rpx;}
+				.ctimea{
+					font-weight: 500;font-size: 28rpx;color: #ffffff;
+				}
+			}
+			.ctips{display: flex;
+				image {width: 20rpx;height: 20rpx;margin-top: 6rpx;}
+				text {font-size: 26rpx;font-weight: 400;color: #666666;margin-left: 14rpx;}
+			}
+		}
+	}
+	// 异常弹窗
+	.bgbox {position: fixed;left: 0;right: 0;top: 0;bottom: 0;background: rgba(0, 0, 0, 0.5);z-index: 2;}
+
+	.bgfixed {position: fixed;left: 0;right: 0;bottom: 0;padding: 52rpx 32rpx 26rpx;background: #ffffff;z-index: 10;
+
+		.tit {
+			display: flex;
+			align-items: center;
+			image {width: 28rpx;height: 28rpx;flex: 0 0 auto;}
+			view {font-size: 28rpx;font-weight: bold;color: #000000;padding-right: 28rpx;flex: 1;text-align: center;}
+		}
+
+		.txt {display: flex;align-items: center;margin-top: 20rpx;
+			view {font-size: 28rpx;color: #343434;font-weight: bold;flex: 0 0 auto;}
+			.input {font-size:28rpx;flex: 1;text-align: right;font-weight: 500;}
+			.photoimg{width: 46rpx;height: 40rpx;}
+			.txta{display: flex;align-items: center;width: 100%;justify-content: space-between;margin-bottom: 20rpx;}
+			.imgsur{width: 100%;padding-left: 80rpx;display: flex;justify-content: flex-end;
+				.txtimg{
+					width: 80rpx;height: 80rpx;margin: 0 12rpx 12rpx 0;
+				}
+			}
+			
+		}
+
+		.btn {width: 100%;height: 84rpx;background: #1678FF;border-radius: 6rpx;text-align: center;line-height: 84rpx;font-size: 28rpx;color: #FFFFFF;margin-top: 60rpx;}
+
+	}
+.restbox{display: flex;flex-direction: column;align-items: center;margin-bottom: 48rpx;
+	image{width: 396rpx;height: 264rpx;margin-bottom: 20rpx;}
+	view{font-weight: 500;font-size: 26rpx;color: #343434;}
+}
+</style>

+ 619 - 0
work/pages/clock/kaorules.vue

@@ -0,0 +1,619 @@
+<template>
+	<view class="box">
+		<view class="boxtop">
+			<view class="boxtopb">
+				<!-- <view class="boxflex" @click="getChoseFn">
+					<image :src="buimg" class="boxtopba"></image>
+					<view class="boxtopbb" :style="role?'':'color:#AAAAAA;'">{{role||'选择部门'}}</view>
+					<image :src="upimg" class="boxtopbc"></image>
+				</view> -->
+				<view class="boxflex" @click="getAddFn">
+					<image :src="rulesimg" class="boxtopbd"></image>
+					<view class="boxtopbe">添加考勤设置</view>
+				</view>
+			</view>
+		</view>
+		
+		
+		<card-list :datainfo="prolist" type='rule' :wtdt="wtdt"   @getdetail='goDetail'></card-list>
+		
+		<view>
+			<view class="exele">
+				<view class="box" style="padding-top: 0;display: none;">
+					<table @change="change">
+						<tr class="tr_one">
+							<th style="width: 120upx; text-align: center;">部门</th>
+							<th style="width: 280upx; text-align: center;">打卡距离</th>
+							<th style="width: 240upx; text-align: center;">打卡次数</th>
+							<th style="width: 110upx; text-align: center;">操作</th>
+						</tr>
+						<scroll-view scroll-y class="scroll-view" upper-threshold="40" lower-threshold="40"
+							@scrolltolower="bot_btn">
+							<tr v-for="(item,index) in prolist" :key="index"
+								:class=" [index%2  ==0 ? 'two_tr two_trtwo':'two_tr']" @click="chakn(item)">
+								<td style="width: 120upx; text-align: center;">
+									{{ item.deptName == null ? '暂无信息' :  item.deptName}}
+								</td>
+								<td style="width: 280upx; text-align: center;">
+									<!-- 	{{ item.dept&&item.dept.deptName == null ? '暂无信息' :  item.dept.deptName}}</td> -->
+									{{ item.kaRadius==null ? '暂无信息' :  item.kaRadius}}
+								</td>
+								<!-- <td style="width: 40upx; text-align: center;">{{item.gender == null? '暂无信息' : item.gender }}</td> -->
+								<td style="width: 240upx; text-align: center;">
+									{{item.kaNum == null? '暂无信息' : item.kaNum }}
+								</td>
+								<td style="width: 110upx; color: #1678FF;text-align: center;text-decoration: underline;"
+									@click.stop="goDetail(item.kaoqinId)">详情</td>
+							</tr>
+							<view class="shax" v-if="prolist.length>0">
+								{{wtdt}}
+							</view>
+							<view class="zanwu " v-else><text>暂无数据</text></view>
+						</scroll-view>
+
+					</table>
+				</view>
+
+			</view>
+		</view>
+		<!-- 部门 -->
+		<selectMorePicker ref="picker" :title="auiPicker.title" :layer="auiPicker.layer" :titflag='auiPicker.titflag'
+			:data="auiPicker.data" @callback="pickerCallback"></selectMorePicker>	
+	</view>
+</template>
+
+<script>
+	import {getdeptTreeNow,clocklist} from "@/api/work/check.js"
+	import selectMorePicker from "@/components/selectMorePicker.vue"
+	import selectPicker from '@/components/selectPicker.vue'
+	import {
+		selectDictLabel
+	} from '@/utils/common.js'
+	import cardList from "@/work/components/clock/cardlist.vue"
+	export default {
+		data() {
+			return {
+				rulesimg: require("@/work/static/clock/krules.png"),
+				buimg: require("@/work/static/clock/chosebm.png"),
+				addimg: require("@/work/static/clock/addry.png"),
+				upimg: require("@/work/static/clock/up.png"),
+				closeimg: require("@/work/static/clock/close.png"),
+				rimg: require("@/work/static/clock/right.png"),
+				prolist: [{deptName:'人事部',kaTimeAmIn:'08:00',kaTimePmOut:'19:00'}],
+				wtdt: '',
+				nickName: '',
+				auiPicker: {
+					title: '选择部门',
+					layer: null,
+					titflag: true,
+					data: []
+				},
+				uplatflag: false,
+				listite: {
+					"roleName": '',
+					"roleId": ''
+				},
+				rolelist: [],
+				role: '',
+				deptId: this.$store.state.user.deptId,
+				roleId: '',
+				rangekey: "dictLabel",
+				pageNum: 1,
+				pageSize: 10,
+				reachflag: true,
+				deptName: '',
+				rolefalg: true,
+				rolevalue:[]
+			}
+		},
+		components: {
+			selectMorePicker,
+			selectPicker,
+			cardList
+		},
+		onShow() {
+			
+		},
+		onLoad() {
+			uni.$on('reashlist',(res)=>{
+				this.pageNum = 1;
+				this.prolist = [];
+				this.reachflag=true;
+				this.clocklist()
+			})
+			this.clocklist()
+			// this.getdeptTreeNow();
+			
+		},
+		onUnload() {
+			uni.$off('reashlist')
+		},
+		onReachBottom() {
+			if (this.reachflag) {
+				this.pageNum++
+				this.clocklist()
+			}
+		},
+		methods: {
+			getClose() {
+				this.uplatflag = false;
+			},
+			
+
+			getSearch() {
+				this.pageNum = 1;
+				this.prolist = [];
+				this.reachflag=true;
+				this.clocklist()
+			},
+			getChoseFn() {
+				this.$refs.picker.open().then(function() {
+					console.log('picker打开');
+				});
+				// this.$tab.navigateTo("/work/pages/lock")
+			},
+			change(){
+				
+			},
+			vacRolChange(e) {
+				// this.params.houseType=e[0].label;
+			},
+			goDetail(e) {
+				this.$tab.navigateTo("/work/pages/clock/setswork?id="+e)
+			},
+			getAddFn() {
+				this.$tab.navigateTo("/work/pages/clock/setswork?fromurl=rule")
+			},
+			pickerCallback(e) {
+				const _this = this;
+				let result = '';
+				e.data.forEach(function(item, index) {
+					if (index == 0) {
+						result += item.label;
+					} else {
+						result += '/' + item.label;
+					}
+				});
+				var len = e.data.length - 1
+				if (_this.uplatflag) {
+					_this.deptName = e.data[len].label;
+					_this.deptId = e.data[len].id;
+				} else {
+					_this.role = result;
+					this.deptId = e.data[len].id;
+					this.pageNum = 1;
+					this.prolist = [];
+					this.reachflag=true;
+					this.clocklist()
+				}
+			},
+			clocklist() {
+				var that = this;
+				var params = {
+					// nickName: this.nickName,
+					// deptId: this.deptId,
+					pageSize: this.pageSize,
+					pageNum: this.pageNum,
+				}
+				clocklist(params).then(res => {
+					if (res.code == 200) {
+						if (res.rows.length < this.pageSize) {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						} else {
+							var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum -
+								1)
+							if (num < res.total) {
+								this.reachflag = true
+								this.wtdt = '上拉加载更多'
+							} else {
+								this.reachflag = false
+								this.wtdt = '到底了~';
+							}
+						}
+						if (this.pageNum == 1) {
+							this.prolist = res.rows;
+						} else {
+							this.prolist = this.prolist.concat(res.rows)
+						}
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			getdeptTreeNow() {
+				getdeptTreeNow().then(res => {
+					if (res.code == 200) {
+						this.auiPicker.data = res.data
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.box {
+		padding-top: 100rpx;background-color: #F2F2F2;min-height: 100vh;box-sizing: border-box;
+	}
+
+	.boxtop {
+		padding: 0 34rpx;
+		position: fixed;left:0;right:0;top: 0;z-index: 5;background-color: #FFFFFF;
+		.boxtopa {
+			padding: 14rpx 0;
+			display: flex;
+			align-items: center;
+
+			input {
+				height: 64rpx;
+				background: #E6E6E6;
+				border-radius: 28rpx;
+				flex: 1;
+				background: #E6E6E6;
+				padding: 0 30rpx;
+				line-height: 64rpx;
+				border-radius: 28rpx;
+				font-size: 32rpx;
+			}
+
+			view {
+				width: 120rpx;
+				height: 64rpx;
+				background: #1678FF;
+				border-radius: 28rpx;
+				font-size: 32rpx;
+				color: #FFFFFF;
+				margin-left: 8rpx;
+				flex: 0 0 auto;
+				text-align: center;
+				line-height: 64rpx;
+			}
+		}
+
+		.boxtopb {
+			display: flex;
+			align-items: center;
+			justify-content: space-between;
+			padding: 32rpx 0;
+
+			.boxflex {
+				display: flex;
+				align-items: center;
+
+				.boxtopba {
+					width: 26rpx;
+					height: 24rpx;
+					margin-right: 16rpx;
+				}
+
+				.boxtopbb {
+					font-size: 32rpx;
+					color: #1678FF;
+					margin-right: 16rpx;
+				}
+
+				.boxtopbc {
+					width: 14rpx;
+					height: 14rpx;
+				}
+
+				.boxtopbd {
+					width: 28rpx;
+					height: 28rpx;
+					margin-right: 16rpx;
+				}
+
+				.boxtopbe {
+					font-size: 30rpx;
+					color: #6CBC0A;
+				}
+			}
+		}
+	}
+
+	.tab {
+		.tabs {
+			.one_tab {
+				color: #1678FF !important;
+
+			}
+
+			.one_tabqie {
+				border-bottom: 8rpx solid #1678FF;
+
+			}
+		}
+	}
+
+	.exele {
+		.box {
+			table {
+				border-spacing: 0rpx;
+			}
+
+			.tr_one {
+				display: flex;
+				// padding: 0 20rpx;
+				box-sizing: border-box;
+				justify-content: space-between;
+
+				th {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #000000;
+					overflow: hidden;
+					text-overflow: ellipsis;
+					white-space: nowrap;
+					line-height: 78rpx;
+					height: 78rpx;
+					box-sizing: border-box;
+				}
+			}
+
+			.two_tr {
+				display: flex;
+				// padding: 0 20rpx;
+				box-sizing: border-box;
+				justify-content: space-between;
+
+				td {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #343434;
+
+					min-height: 82rpx;
+					padding: 20rpx 0;
+					box-sizing: border-box;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+
+				}
+
+				// .tdse {
+				// 	color: #E60012 !important;
+				// }
+				// .apply_span_xl{
+				// 	color: #32B16C !important;
+				// }
+				// .apply_span_xltwo{
+				// 	color: #ffa200 !important;
+				// }
+				// .apply_span_xlfive{
+				// 	color: #4c4b4b !important;
+				// }
+				// .apply_span_xlthreo{
+				// 	color: #f00404 !important;
+				// }
+				// .apply_span_xlforu{
+				// 	color: #aaaaaa !important;
+				// }
+				// .coiu {
+				// 	color: #EC1717;
+				// }
+			}
+
+			.two_trtwo {
+				background-color: #F2F2F2;
+			}
+		}
+
+	}
+
+	.zanwu {
+		text-align: center;
+		padding-top: 20upx;
+
+		span {
+			font-size: 30upx;
+		}
+	}
+
+	// 搜索条件width: 562rpx;
+	.bgbox {
+		position: fixed;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+		z-index: 19;
+		background: rgba(0, 0, 0, 0.5);
+	}
+
+	.sfixed {
+		min-height: 760rpx;
+		background: #FFFFFF;
+		border-radius: 14rpx;
+		padding: 40rpx 34rpx;
+		box-sizing: border-box;
+		position: fixed;
+		left: 60rpx;
+		right: 60rpx;
+		top: 50%;
+		transform: translateY(-50%);
+		z-index: 29;
+		max-height: calc(100vh - 280rpx);
+		overflow-y: auto;
+
+		.sfixed_tit {
+			font-size: 32rpx;
+			font-weight: bold;
+			color: #343434;
+			line-height: 44rpx;
+			text-align: center;
+		}
+
+		.sfixed_clo {
+			width: 20rpx;
+			height: 20rpx;
+			position: absolute;
+			left: 34rpx;
+			top: 44rpx;
+		}
+
+		.sfixed_box {
+			padding-top: 20rpx;
+			margin-bottom: 80rpx;
+
+			.sfixed_inp {
+				width: 100%;
+				height: 76rpx;
+				background: #F2F2F2;
+				padding: 0 34rpx;
+				box-sizing: border-box;
+				font-size: 32rpx;
+				color: #333333;
+				margin-top: 30rpx;
+			}
+		}
+
+		.sfixed_btn {
+			width: 100%;
+			height: 76rpx;
+			border: 0px solid #00B034;
+			border-radius: 6rpx;
+			font-size: 34rpx;
+			color: #FFFFFF;
+			text-align: center;
+			line-height: 76rpx;
+
+			&.btn1 {
+				background: #1678FF;
+				color: #FFFFFF;
+			}
+
+			&.btn2 {
+				border: 2rpx solid #F02828;
+				color: #F02828;
+				margin-top: 28rpx;
+			}
+
+
+		}
+
+	}
+
+	.address {
+		display: flex;
+		align-items: center;
+		padding: 24rpx 0;
+
+		.addtita {
+			flex: 0 0 auto;
+			font-size: 34rpx;
+			font-weight: bold;
+			color: #343434;
+		}
+
+		.addressa {
+			display: flex;
+			align-items: center;
+			flex: 1;
+			display: flex;
+			align-items: center;
+			justify-content: flex-end;
+			overflow: hidden;
+
+			.addsa {
+				font-size: 30rpx;
+				color: #333333;
+				overflow: hidden;
+				white-space: nowrap;
+				text-overflow: ellipsis;
+				flex: 1;
+				text-align: right;
+			}
+
+			.addsimg {
+				width: 10rpx;
+				height: 18rpx;
+				margin-left: 10rpx;
+				flex: 0 0 auto;
+			}
+
+			// .adds{
+			// 	display: flex;align-items: center;justify-content: flex-start;padding:10rpx 20rpx;min-width: 220rpx;box-sizing: border-box;}
+		}
+
+		.addclear {
+			color: #EA2929;
+			font-size: 32rpx;
+			flex: 0 0 auto;
+			height: 60rpx;
+			line-height: 60rpx;
+			width: 128rpx;
+			text-align: center
+		}
+	}
+
+	.delbox {
+		width: 580rpx;
+		background: #FFFFFF;
+		border-radius: 14px;
+		position: fixed;
+		top: 50%;
+		left: 80rpx;
+		right: 80rpx;
+		padding: 48rpx 34rpx 72rpx;
+		box-sizing: border-box;
+		z-index: 5;
+		margin-top: -210rpx;
+
+		.deltit {
+			font-size: 34rpx;
+			font-weight: bold;
+			color: #343434;
+			text-align: center;
+			line-height: 40rpx;
+		}
+
+		.del_img {
+			width: 34rpx;
+			height: 34rpx;
+			position: absolute;
+			right: 34rpx;
+			top: 44rpx;
+		}
+
+		.del_btn {
+			width: 100%;
+			height: 76rpx;
+			background: #00B034;
+			border-radius: 6rpx;
+			font-size: 34rpx;
+			font-weight: bold;
+			color: #FFFFFF;
+			text-align: center;
+			line-height: 76rpx;
+		}
+
+		.del_list {
+			display: flex;
+			padding: 60rpx 0 40rpx;
+			flex-wrap: wrap;
+
+			.del_lista {
+				width: 116rpx;
+				height: 64rpx;
+				background: #CACACA;
+				border-radius: 32rpx;
+				font-size: 32rpx;
+				font-weight: 500;
+				color: #FFFFFF;
+				text-align: center;
+				line-height: 64rpx;
+				margin: 0 10rpx 20rpx 0;
+
+				&.act {
+					background-color: #019FE8;
+				}
+			}
+		}
+	}
+	
+</style>

+ 419 - 0
work/pages/clock/outside.nvue

@@ -0,0 +1,419 @@
+<template>
+	<view class="setbox">
+		<map
+			id="container"
+			class="map"
+			:latitude="center.lat"
+			:longitude="center.lng"
+			:markers="covers"
+			scale="15"
+			:style="'width: 750rpx;height:' + mapheight + 'px;'"
+		></map>
+		<view class="mapfot">
+			<view class="txt" style="flex-direction: column;" v-if="isPhoto=='Y'">
+				<view class="txta">
+					<view><text class="txtaa">拍照</text></view>
+					<image :src="photoimg" class="photoimg" @click="getphotoFn"></image>
+				</view>
+				<view class="imgsur" v-if="imgurlshow">
+					<image :src='imgurlshow' class="txtimg" @click="getpreviewImage"></image>
+				</view>
+			</view>
+			<view class="txt" style="align-items: flex-start;">
+				<view><text class="txtaa">备注</text></view>
+				<uni-easyinput class="input" :inputBorder="false" type="textarea" autoHeight  v-model="chitext"
+					placeholder="请填写原因">
+				</uni-easyinput>
+			</view>
+			<view>
+				<view class="mapfott"><text class="mapfotta">当前位置</text></view>
+				<view class="mapfotx">
+					<image :src="adrimg" class="mapfotxi"></image>
+					<view class="mapfotxa"><text class="mapfotxaa" v-if="address">{{address}}</text></view>
+				</view>
+			</view>
+			<view class="mapfotn" @click="getPunchFnes"><text class="mapfotna">确认打卡</text></view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import self from "@/utils/location.js"
+	import {getRecordList,getPunchFn,getPunchputFn} from "@/api/work/check.js"
+	import amapFile from '@/plugins/amap-wx.js';
+	import {uploadPhoto} from "@/api/system/user.js"
+	import config from '@/config.js'
+	const baseUrl = config.baseUrl
+	// #ifdef APP
+	var myAmapFun = new amapFile.AMapWX({
+		key: 'ccbe52b1ec5f66295fa4609c90a819b7',
+		batch: true
+		});
+	// #endif
+	export default{
+		data(){
+			return{
+				serimg:require("@/work/static/clock/serch.png"),
+				adrimg:require("@/work/static/clock/adress.png"),
+				photoimg: require("@/work/static/clock/photo.png"),
+				place:{
+					lng:'',
+					lat:'',
+				},
+				address:'',
+				kaTime:'',
+				kaYear:'',
+				kaMonth:'',
+				kaDay:'',
+				kaWeek:'',
+				gettime:'',
+				timefn:'',
+				isPhoto:'N',
+				dakatype:'',
+				recordList:[],
+				mapheight:0,
+				mapContext:'',
+				covers: [{
+					latitude: '',
+					longitude: '',
+					iconPath: require("@/work/static/clock/map.png"),
+					anchor:{x: 0.5, y: 0.5}
+				}],
+				mapimg:require("@/work/static/clock/map.png"),
+				center:{
+					lng:'',
+					lat:'',
+				},
+				location:'',
+				imgurl:'',
+				imgurlshow:'',
+				//打卡参数
+				formData: {
+					"userId": '',
+					"deptId": '',
+					"ancestors":'',
+					"deptName": "",
+					"userName": "",
+					"ancestors": "",
+					"kaLog": "",
+					"kaLat": "",
+					"kaYear": "",
+					"kaMonth": "",
+					"kaDay": "",
+					"kaWeek": "",
+					"kaTime": "",
+					"kaSort": "",
+					"kaTimeAmIn": "", //打卡时间 -上午上班
+					"kaTimeAmOut": "",
+					"kaTimePmIn": "",
+					"kaTimePmOut": "",
+					"kaAddressAmIn": "", //打卡地点 上午上班
+					"kaAddressAmOut": "",
+					"kaAddressPmIn": "",
+					"kaAddressPmOut": "",
+					"kaTypeAmIn": "", //打卡类别-上午上班 1正常 2:迟到 3:外勤 4:早退
+					"kaTypeAmOut": "",
+					"kaTypesPmIn": "",
+					"kaTypePmOut": "",
+					"remarkAmIn": "", //备注 上午上班
+					"remarkAmOut": "",
+					"remarkPmIn": "",
+					"remarkPmOut": "",
+					"kaType": "",
+					"kaStatus": "1", //打卡状态 1正常 2:异常
+				},
+				chitext:'',
+			}
+		},
+		onLoad(e) {
+			// this.isPhoto=e.isPhoto;
+			// this.dakatype=e.dakatype;
+			this.getcreateMap()
+			// #ifdef H5
+			this.center.lng=117.211954;
+			this.center.lat=31.839676;
+			this.covers = [];
+			this.covers = [{
+				latitude: '31.839676',
+				longitude: '117.211954',
+				iconPath: this.mapimg,
+				anchor:{x: 0.5, y: 0.5}
+			}]
+			// #endif
+		},
+		onUnload() {
+			clearInterval(this.timefn)
+		},
+		mounted() {
+			this.formData.userId= this.$store.state.user.userId;
+			this.formData.deptId= this.$store.state.user.deptId;
+			this.formData.ancestors=this.$store.state.user.ancestors;
+			this.formData.deptName=this.$store.state.user.deptName
+			this.formData.userName=this.$store.state.user.userName
+			this.getinfo()
+			this.getlocation()
+			// this.getRecordList();
+			this.gettimeFn();
+		},
+		methods:{
+			getcreateMap(){
+				//mapId 就是你在 map 标签中定义的 id
+				this.mapContext = uni.createMapContext('container', this);
+			},
+			// 获取当前屏幕信息
+			getinfo(){
+				var that=this;
+				uni.getSystemInfo({
+					success(e) {
+						that.mapheight=e.windowHeight;
+					},
+				})
+			},
+			getCity(latitude, longitude) {
+				var that = this;
+				that.location = `${longitude},${latitude}`
+			
+				myAmapFun.getRegeo({
+				//如果经纬度有问题会导致不进入回调方法,从而报错
+					location: that.location,
+					success: function(e) {
+						//成功回调
+						that.address='';
+						that.address = e[0].regeocodeData.formatted_address; //详细地址
+					},
+					fail: function(info) {
+						//失败回调
+						console.log(info)
+					}
+				})
+			},
+			// 获取定位
+			getlocation(){
+				var that = this;
+				uni.getLocation({
+					type: 'gcj02',
+					geocode: true,
+					success: function(res) {
+						that.center.lng=res.longitude;
+						that.center.lat=res.latitude;
+						that.covers = [];
+						that.covers = [{
+							latitude: res.latitude,
+							longitude: res.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+						// #ifdef H5
+						var adr= address.province+address.city+address.district+address.street+address.streetNum+address.poiName
+						// that.address=res.longitude
+						that.address=adr
+						// #endif
+						// #ifdef APP
+			
+						that.getCity(res.latitude,  res.longitude)
+						// #endif
+			
+					},
+					fail: function(red) {
+						uni.showToast({
+							title:"获取定位失败"
+						})
+					},
+				})
+			},
+			gettimeFn() {
+				var that = this;
+				that.time()
+				that.timefn = setInterval(function() {
+					that.time()
+				}, 1000)
+			},
+			getRecordList() {
+				var params = {
+					deptId: this.$store.state.user.deptId,
+					userId: this.$store.state.user.userId,
+					kaTime: this.kaTime
+				}
+				getRecordList(params).then(res => {
+					if (res.code == 200) {
+						this.recordList=res.rows;
+						if(res.rows.length){
+							this.formData=res.rows[0]
+						}
+					} else {
+						this.$modal.confirm(res.msg)
+					}
+				})
+				// this.$toast("登录中,请耐心等待...")
+			},
+			// 打卡
+			getPunchFnes(){
+				var that=this;
+				uni.redirectTo({
+					url: '/work/pages/clock/success?tit=外勤打卡'
+				});
+				return
+				
+				if(that.isPhoto=='Y'&&!that.imgurl){
+					uni.showToast({
+						title:'请拍照上传',
+						icon:'none'
+					})
+					return
+				}
+				var params=this.formData;
+				params.kaTime=this.kaTime;
+				params.kaYear=this.kaYear;
+				params.kaMonth=this.kaMonth;
+				params.kaDay=this.kaDay;
+				params.kaWeek=this.kaWeek;
+				params.deptName=this.$store.state.user.deptName
+				params.userName=this.$store.state.user.name
+				params.kaStatus=2
+				var imgurl=this.imgurl;
+				if(this.dakatype==1){
+					params.kaTimeAmIn=this.gettime;
+					params.kaAddressAmIn=this.address;
+					params.kaAmInPhoto=imgurl;
+					params.kaTypeAmIn=3
+					params.kaSort=1;
+				}else if(this.dakatype==2){
+					params.kaSort=2;
+					params.kaTimeAmOut=this.gettime;
+					params.kaAddressAmOut=this.address;
+					params.kaTypeAmOut=3
+					params.kaAmOutPhoto=imgurl;
+				}else if(this.dakatype==3){
+					params.kaSort=3;
+					params.kaTypePmIn=3
+					params.kaTimePmIn=this.gettime;
+					params.kaAddressPmIn=this.address;
+					params.kaPmInPhoto=imgurl;
+				}else{
+					params.kaSort=4;
+					params.kaTypePmOut=3
+					params.kaTimePmOut=this.gettime;
+					params.kaAddressPmOut=this.address;
+					params.kaPmOutPhoto=imgurl;
+				}
+				if (this.recordList.length) {
+					var len = this.recordList.length - 1
+					params["recordId"] = this.recordList[0].recordId;
+					// // 覆盖打卡
+					getPunchputFn(params).then(res => {
+						if (res.code == 200) {
+							// 打卡成功
+							// this.getRecordList()
+							uni.redirectTo({
+								url: '/work/pages/clock/success?tit=外勤打卡'
+							});
+						} else {
+							this.$toast(res.msg)
+						}
+					})
+				
+				} else {
+					params["recordId"] = '';
+					getPunchFn(params).then(res => {
+						if (res.code == 200) {
+							// 打卡成功
+							// this.getRecordList()
+							uni.redirectTo({
+								url: '/work/pages/clock/success?tit=外勤打卡'
+							});
+						} else {
+							that.$modal.msgError(res.msg)
+						}
+					})
+				}
+			},
+			time() {
+				var date = new Date();
+				var y = date.getFullYear();
+				var m = date.getMonth() + 1;
+				var d = date.getDate();
+				var h = date.getHours();
+				var min = date.getMinutes();
+				var s = date.getSeconds();
+				var week = date.getDay(); //获取当前星期X(0-6,0代表星期天)
+				var weeks = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
+				var yearStr = y + '-' + (m < 10 ? ('0' + m) : m) + '-' + (d < 10 ? ('0' + d) : d) 
+				var timeStr = (h < 10 ? ('0' + h) : h) + ':' + (min < 10 ? ('0' + min) : min) + ':' + (s < 10 ? (
+					'0' + s) : s);
+				this.kaTime = yearStr;
+				this.kaYear = y;
+				this.kaMonth = m < 10 ? "0" + m : m;
+				this.kaDay = d < 10 ? "0" + d : d;
+				this.kaWeek = week;
+				this.gettime = timeStr
+				// 年,月,日, 星期几 时分秒
+			},
+			getpreviewImage(e){
+				var urlArr=[];
+				urlArr[0]=this.imgurlshow;
+				uni.previewImage({
+							urls: urlArr,
+							success: function(data) {
+								console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
+								},
+							fail: function(err) {
+								console.log(err.errMsg);
+							}
+				});
+			},
+			// 拍照
+			getphotoFn(){
+				var that=this;
+				uni.chooseImage({
+					count: 1, //默认9
+					sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
+					sourceType: ['camera'], //拍照
+					success: function (res) {
+						const tempFilePaths = res.tempFilePaths;
+						// 文件上传
+						let data = {name: 'file', filePath: res.tempFilePaths[0]}
+						uploadPhoto(data).then(response => {
+							that.imgurlshow=baseUrl+response.fileName;
+							that.imgurl=response.fileName;
+							// if(!that.chiflag){
+							// 	that.getPunchFnes()
+							// }
+						})
+					}
+				});
+			},
+			
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	// .maptop{width:684rpx;height: 84rpx;background: #FFFFFF;box-shadow: 0px 0px 12rpx 0px rgba(75,75,75,0.35);border-radius: 6rpx;position: fixed;left: 34rpx;right: 34rpx;top: 24rpx;display: flex;align-items: center;padding: 0 32rpx;box-sizing: border-box;
+	// image{width: 36rpx;height: 38rpx;margin-right: 16rpx;flex: 0 0 auto;}
+	// input{font-size: 26rpx;color: #666666;flex: 1;}
+	// }
+.mapfot /deep/ .uni-easyinput__content-textarea{min-height: 84rpx;margin: 0;} 
+.mapfot{position: fixed;left: 34rpx;right: 34rpx;bottom: 24rpx;background: #FFFFFF;
+box-shadow: 0px 0px 12rpx 0px rgba(75,75,75,0.35);
+border-radius: 6rpx;padding: 40rpx 32rpx 32rpx;min-height:300rpx;}
+.mapfott{margin-bottom: 28rpx;}
+.mapfotta{font-size: 28rpx;font-weight: bold;color: #343434;}
+.mapfotx{display: flex;margin-bottom: 32rpx;flex-direction: row;min-height: 70rpx;}
+.mapfotxi{width: 26rpx;height: 28rpx;flex: 0 0 auto;margin-right: 12rpx;}
+.mapfotxa{flex: 1;line-height: 32rpx;}
+.mapfotxaa{font-size: 26rpx;color: #343434;}
+.photoimg{width: 46rpx;height: 40rpx;}
+.txta{display: flex;align-items: center;width: 610rpx;justify-content: space-between;margin-bottom: 20rpx;flex-direction: row;}
+.imgsur{width: 100%;padding-left: 80rpx;}			
+.txtimg{width: 80rpx;height: 80rpx;margin: 0 12rpx 12rpx 0;}
+.mapfotn{width: 610rpx;height:76rpx;background: #1678ff;border-radius: 6rpx;display: flex;align-items: center;justify-content: center;}
+.mapfotna{font-size: 28rpx;color: #FFFFFF;}
+.txt {
+			display: flex;
+			align-items: center;
+			margin-bottom: 28rpx;
+			flex-direction: row;
+		}
+.txtaa {font-size: 28rpx;color: #343434;font-weight: bold;flex: 0 0 auto;margin-right: 20rpx;}
+.input {font-size: 28rpx;flex: 1;text-align: right;}
+</style>

+ 388 - 0
work/pages/clock/personnel.vue

@@ -0,0 +1,388 @@
+<template>
+	<view class="box">
+		<view class="boxtop">
+			<view class="boxtopa">
+				<input placeholder="请输入人员姓名查询"  v-model="userName"/>
+				<view @click="getSearch">查询</view>
+			</view>
+			<view class="boxtopb">
+				<!-- 日期选择器 -->
+				<view class="approva_header">
+					<picker mode="date" :value="selectDate" fields="month" @change="bindDateChange">
+						<view class="flexc">
+							<image :src="timg"></image>
+							<text class="uni-calendar__header-text">{{selectDate||'选择日期'}}</text>
+							<image :src="uimg"></image>
+						</view>
+					</picker>
+				</view>
+			</view>
+		</view>	
+		<card-list :datainfo="prolist" type='count'   @getdetail='goDetail'></card-list>
+			<!-- <view class="exele" style="padding-top: 0;display: none;">
+					<table @change="change">
+						<tr class="tr_one">
+							<th style="width: 100upx; text-align: center;">姓名</th>
+							<th style="width: 125upx; text-align: center;">部门</th>
+							<th style="width: 100upx; text-align: center;">外勤</th>
+							<th style="width:100upx; text-align: center;">迟到</th>
+							<th style="width: 100upx; text-align: center;">早退</th>
+							<th style="width: 100upx; text-align: center;">缺卡</th>
+							<th style="width: 125upx; text-align: center;">打卡详情</th>
+						</tr>
+						<scroll-view scroll-y class="scroll-view" upper-threshold="40" lower-threshold="40"
+							@scrolltolower="bot_btn">
+							<tr v-for="(item,index) in prolist" :key="index"
+								:class=" [index%2  ==0 ? 'two_tr two_trtwo':'two_tr']" @click="chakn(item)">
+								<td style="width: 100upx; text-align: center;">
+									{{ item.userName == null ? '暂无信息' :  item.userName}}</td>
+								<td style="width: 125upx; text-align: center;">
+									{{ item.deptName == null ? '暂无信息' :  item.deptName}}</td>
+									<td style="width: 100upx; text-align: center;">
+										{{item.外勤 == null? '暂无信息' : item.外勤 }}</td>
+								<td style="width: 100upx; text-align: center;">
+									{{item.迟到 == null? '暂无信息' : item.迟到 }}</td>
+										<td style="width: 100upx; text-align: center;">
+											{{item.早退 == null? '暂无信息' : item.早退 }}</td>
+											<td style="width: 100upx; text-align: center;">
+											{{item.缺卡 == null? '暂无信息' : item.缺卡 }}</td>
+								<td style="width: 125upx; color: #1678FF;text-align: center;text-decoration: underline;" @click.stop="goDetail(item)">查看详情</td>
+							</tr>
+							<div class="shax" v-if="prolist.length>0">
+								{{wtdt}}
+							</div>
+							<div class="zanwu " v-else><span>暂无数据</span></div>
+						</scroll-view>
+
+					</table>
+	
+
+			</view> -->
+
+	</view>
+</template>
+
+<script>
+	import {getClockCountall} from "@/api/work/check.js"
+	import selectPicker from '@/components/selectPicker.vue'
+	import cardList from "@/work/components/clock/cardlist.vue"
+	// import {selectDictLabel} from '@/utils/common.js'
+	export default {
+		data() {
+			return {
+				timg:require("@/static/images/time.png"),
+				uimg:require("@/static/images/up.png"),
+				buimg: require("@/static/images/chosebm.png"),
+				addimg: require("@/static/images/addry.png"),
+				upimg: require("@/static/images/up.png"),
+				closeimg:require("@/static/images/close.png"),
+				rimg:require("@/static/images/right.png"),
+				prolist:  [],
+				wtdt: '',
+				userName:'',
+				listite:{
+					"roleName":'',
+					"roleId":''
+				},
+				rolelist:[],
+				role:'',
+				deptId:this.$store.state.user.deptId,
+				roindex:-1,
+				roleId:'',
+				rangekey:"label",
+				pageNum: 1,
+				pageSize: 10,
+				reachflag:true,
+				deptName:'',
+				kaYear:'',
+				kaMonth:'',
+				selectDate: '',
+			}
+		},
+		components:{
+			selectPicker,cardList
+		},
+		onLoad() {
+			this.selectDate = this.formatDateTime();
+			this.getsubordinateList()
+		},
+		onReachBottom() {
+				if (this.reachflag) {
+					this.pageNum++
+					this.getsubordinateList()
+				}
+		},
+		methods:{
+			formatDateTime() {
+			var date=new Date()
+			  let y = date.getFullYear();
+			  let m = date.getMonth() + 1;
+			  m = m < 10 ? "0" + m : m;
+			  let d = date.getDate();
+			  d = d < 10 ? "0" + d : d;
+			  const time = y + "-" + m ;
+			  this.kaYear=y;
+			  this.kaMonth=m;
+			  return `${y}-${m}`;
+			
+			},
+			bindDateChange(e) {
+				this.selectDate = e.detail.value
+				var val=e.detail.value.split('-')
+				this.pageNum=1;
+				this.prolist=[];
+				this.kaYear=val[0];
+				this.kaMonth=val[1]
+				this.reachflag=true;
+				this.getsubordinateList()
+			},
+			
+			getSearch(){
+				this.pageNum=1;
+				this.prolist=[];
+				this.reachflag=true;
+				this.getsubordinateList()
+			},
+			goDetail(e){
+				var obj={
+					userId:e.userId,
+					recordDate:this.selectDate+'-01'
+				}
+				// var obj={
+				// 	userId:3,
+				// 	recordDate:'2024-10-20'
+				// }
+				this.$tab.navigateTo('/work/pages/record/detail?data='+encodeURIComponent(JSON.stringify(obj)))
+				
+			},
+			getsubordinateList(){
+				var that = this;
+				var params={
+					// "ancestors":this.$store.state.user.ancestors,
+					// "kaYear":this.kaYear,
+					// "kaMonth":this.kaMonth,
+					// name:this.userName,
+					pageSize: this.pageSize,
+					pageNum: this.pageNum,
+					// deptId:this.$store.state.user.deptId
+					recordDate:this.selectDate
+				}
+				if(this.userName){
+					params.name=this.userName
+				}
+				getClockCountall(params).then(res => {
+					if (res.code == 200) {
+						if (res.rows.length < this.pageSize) {
+							this.reachflag = false
+							this.wtdt = '到底了~';
+						} else {
+							var num = parseInt(res.rows.length) + parseInt(this.pageSize) * parseInt(this.pageNum - 1)
+							if (num < res.total) {
+								this.reachflag = true
+								this.wtdt = '上拉加载更多'
+							} else {
+								this.reachflag = false
+								this.wtdt = '到底了~';
+							}
+						}
+						if (this.pageNum == 1) {
+							this.prolist = res.rows;
+						} else {
+							this.prolist = this.prolist.concat(res.rows)
+							}
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.box{height: 100vh;display: flex;flex-direction: column;padding-top: 188rpx;box-sizing: border-box;background-color: #f2f2f2;}
+	
+	.boxtop{
+		flex: 0 0 auto;position: fixed;left:0;right: 0;top: 0;z-index: 5;background-color: #FFFFFF;
+		// padding: 0 34rpx;
+		.boxtopa{
+			padding: 14rpx 34rpx;display: flex;align-items: center;box-shadow: 0px 6rpx 12rpx 0px rgba(210,210,210,0.35);
+			input{height: 64rpx;background: #E6E6E6;border-radius: 28rpx;flex: 1;background: #E6E6E6;padding: 0 30rpx;line-height: 64rpx;
+border-radius: 28rpx;font-size: 28rpx;}
+			view{width: 120rpx;height: 64rpx;background: #1678FF;border-radius: 28rpx;font-size: 28rpx;color: #FFFFFF;margin-left: 8rpx;flex: 0 0 auto;text-align: center;line-height: 64rpx;}
+		}
+		.boxtopb{
+			display: flex;align-items: center;justify-content: space-between;padding: 12rpx 0;
+			.boxflex{display: flex;align-items: center;
+				.boxtopba{width: 26rpx;height: 24rpx;margin-right: 16rpx;}
+				.boxtopbb{font-size: 28rpx;color:#1678FF;margin-right: 16rpx;}
+				.boxtopbc{width: 14rpx;height: 14rpx;}
+				.boxtopbd{width: 28rpx;height: 28rpx;margin-right: 16rpx;}
+				.boxtopbe{font-size: 28rpx;color:#6CBC0A;}
+			}
+		}
+	}
+	.tab {
+		.tabs {
+			.one_tab {
+				color: #1678FF !important;
+	
+			}
+	
+			.one_tabqie {
+				border-bottom: 8rpx solid #1678FF;
+	
+			}
+		}
+	}
+	.exele {
+		flex: 1;display: flex;flex-direction: column;overflow: hidden;
+
+			table{border-spacing: 0rpx;height: 100%;display: flex;flex-direction: column;}
+			.tr_one {
+				display: flex;
+				flex: 0 0 auto;
+				// padding: 0 20rpx;
+				box-sizing: border-box;
+				justify-content: space-between;
+				th {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #000000;
+					overflow: hidden;
+					text-overflow: ellipsis;
+					white-space: nowrap;
+					line-height: 78rpx;
+					height: 78rpx;
+					box-sizing: border-box;
+				}
+			}
+	
+			.two_tr {
+				display: flex;
+				// padding: 0 20rpx;
+				box-sizing: border-box;
+				justify-content: space-between;
+	
+				td {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #343434;
+					
+					min-height: 82rpx;
+					padding: 20rpx 0;
+					box-sizing: border-box;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+	
+				}
+	
+				// .tdse {
+				// 	color: #E60012 !important;
+				// }
+				// .apply_span_xl{
+				// 	color: #32B16C !important;
+				// }
+				// .apply_span_xltwo{
+				// 	color: #ffa200 !important;
+				// }
+				// .apply_span_xlfive{
+				// 	color: #4c4b4b !important;
+				// }
+				// .apply_span_xlthreo{
+				// 	color: #f00404 !important;
+				// }
+				// .apply_span_xlforu{
+				// 	color: #aaaaaa !important;
+				// }
+				// .coiu {
+				// 	color: #EC1717;
+				// }
+			}
+	
+			.two_trtwo {
+				background-color: #F2F2F2;
+			}
+			.scroll-view{flex: 1;overflow-y: auto;}
+	
+	}
+	.zanwu {text-align: center;
+		padding-top: 20upx;
+
+		span {
+			font-size: 30upx;
+		}}
+	// 搜索条件width: 562rpx;
+	.bgbox{position: fixed;left: 0;right: 0;top: 0;bottom: 0;z-index: 19;
+	background: rgba(0,0,0,0.5);}
+		.sfixed{min-height: 760rpx;background: #FFFFFF;border-radius: 14rpx;padding: 40rpx 34rpx;box-sizing: border-box;position: fixed;left: 60rpx;right: 60rpx;top: 50%;transform: translateY(-50%);
+		z-index: 29;max-height: calc(100vh - 280rpx);overflow-y: auto;
+			.sfixed_tit{font-size: 28rpx;font-weight: bold;color: #343434;line-height: 44rpx;text-align: center;}
+			.sfixed_clo{width: 20rpx;height: 20rpx;position: absolute;left: 34rpx;top: 44rpx;}
+			.sfixed_box{
+				padding-top: 20rpx;
+				margin-bottom: 80rpx;
+				.sfixed_inp{width: 100%;height: 76rpx;background:#F2F2F2;padding: 0 34rpx;box-sizing: border-box;font-size: 34rpx;color: #333333;margin-top: 30rpx;}
+			}
+			.sfixed_btn{width: 100%;height: 76rpx;border: 0px solid #00B034;border-radius: 6rpx;font-size: 28rpx;
+	color: #FFFFFF;text-align: center;line-height: 76rpx;
+			&.btn1{background: #1678FF;color: #FFFFFF;}
+			&.btn2{border: 2rpx solid #F02828;color: #F02828;margin-top: 28rpx;}
+	
+	
+	}
+			
+		}
+		.address{
+				display: flex;align-items: center;
+				padding: 24rpx 0;
+				.addtita{flex: 0 0 auto;font-size: 28rpx;font-weight: bold;
+		color: #343434;}
+				.addressa{
+					display: flex;align-items: center;
+					flex: 1;
+					display: flex;align-items: center;justify-content: flex-end;
+					overflow: hidden;
+					.addsa{font-size: 28rpx;color: #333333;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;
+					flex: 1;text-align: right;
+					}
+					.addsimg{width: 10rpx;height: 18rpx;margin-left: 10rpx;flex: 0 0 auto;}
+					// .adds{
+					// 	display: flex;align-items: center;justify-content: flex-start;padding:10rpx 20rpx;min-width: 220rpx;box-sizing: border-box;}
+				}
+				
+				.addclear{color: #EA2929;font-size: 28rpx;flex: 0 0 auto;height: 60rpx;line-height: 60rpx;width: 128rpx;text-align:center}
+			}
+		.approva_header {
+			height: 80rpx;
+		
+			picker {
+				padding: 0 34rpx;
+				display: flex;
+				align-items: center;
+				height: 40px;
+		
+				image:nth-child(1) {
+					width: 26rpx;
+					height: 26rpx;
+				}
+		
+				image:nth-child(3) {
+					width: 14rpx;
+					height: 14rpx;
+		
+				}
+		
+				text {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: 400;
+					color: #1678FF;
+					margin: 0 14rpx;
+				}
+			}
+		}
+</style>

+ 414 - 0
work/pages/clock/setswork.vue

@@ -0,0 +1,414 @@
+<template>
+	<view class="lists">
+		<view class="lbox">
+			<view class="list" @click="getAdres">
+				<view class="listl">考勤地址</view>
+				<view class="listr">{{formData.locations||'请选择考勤地址'}}</view>
+			</view>
+			<view class="list">
+				<view class="listl">考勤范围(米)</view>
+				<input class="listi" v-model="formData.distance" placeholder-style="color:#aaaaaa" placeholder="请输入半径米数(单位默认:米)"/>
+				<image :src="rimg"></image>
+			</view>
+			<!-- <view class="list" @click="getDeptname">
+				<view class="listl">考勤部门</view>
+				<view class="listi" :style="formData.deptName?'':'color:#AAAAAA;'">{{formData.deptName||'选择部门'}}</view>
+				<image :src="rimg"></image>
+			</view> -->
+			<view class="list" >
+				<view class="listl">是否开启考勤拍照</view>
+				<!-- <view class="listi" > -->
+			<picker @change="bindPickerChanges" range-key='label' :value="indexs" :range="surelist" class="listi">
+				<view class="f15" :style="isPicture?'':'color: #AAAAAA;'">{{isPicture||"请选择是否开启考勤拍照"}}</view>
+			</picker>
+					<image :src="rimg"></image>
+			</view>
+		</view>
+		<view class="lbox">
+			<!-- <view class="list">
+				<view class="listl">打卡次数</view>
+				<picker @change="bindPickerChange"  :value="index" :range="array" class="listi">
+					<view :style="formData.kaNum?'':'color: #AAAAAA;'">{{formData.kaNum||"请选择打卡次数"}}</view>
+				</picker>
+				<image :src="rimg"></image>
+			</view>
+			<block v-if="formData.kaNum==4">
+				<view class="list" @click="showDatePicker(0)">
+					<view class="listl">上午上班时间</view>
+					<view class="listi" :style="formData.kaTimeAmIn?'':'color: #AAAAAA;'">{{formData.kaTimeAmIn||"请选择上班时间"}}</view>
+					<image :src="rimg"></image>
+				</view>
+				<view class="list" @click="showDatePicker(1)">
+					<view class="listl">上午下班时间</view>
+					<view class="listi" :style="formData.kaTimeAmOut?'':'color: #AAAAAA;'">{{formData.kaTimeAmOut||"请选择上班时间"}}</view>
+					<image :src="rimg"></image>
+				</view>
+				<view class="list" @click="showDatePicker(2)">
+					<view class="listl">下午上班时间</view>
+					<view class="listi" :style="formData.kaTimePmIn?'':'color: #AAAAAA;'">{{formData.kaTimePmIn||"请选择上班时间"}}</view>
+					<image :src="rimg"></image>
+				</view>
+				<view class="list" @click="showDatePicker(3)">
+					<view class="listl">下午下班时间</view>
+					<view class="listi" :style="formData.kaTimePmOut?'':'color: #AAAAAA;'">{{formData.kaTimePmOut||"请选择下班时间"}}</view>
+					<image :src="rimg"></image>
+				</view>
+			</block>
+			<block v-else> -->
+				<view class="list" @click="showDatePicker(0)">
+					<view class="listl">上班时间</view>
+					<view class="listi"  :style="formData.startWorkTime?'':'color: #AAAAAA;'">{{formData.startWorkTime||"请选择上班时间"}}</view>
+					<image :src="rimg"></image>
+				</view>
+				<view class="list" @click="showDatePicker(3)">
+					<view class="listl">下班时间</view>
+					<view class="listi"  :style="formData.endWorkTime?'':'color: #AAAAAA;'">{{formData.endWorkTime||"请选择下班时间"}}</view>
+					<image :src="rimg"></image>
+				</view>
+			<!-- </block> -->
+		</view>
+		
+		
+		<view class="listbtn" @click="getSure">确认</view>
+		<dataTimePicke ref="setpicker" type="time" toolBarTitle="请选择时间" @change="timeChange"></dataTimePicke>
+		<!-- 部门 -->
+		<selectMorePicker ref="picker" :title="auiPicker.title" :layer="auiPicker.layer" :titflag='auiPicker.titflag'
+			:data="auiPicker.data" @callback="pickerCallback"></selectMorePicker>
+	</view>
+</template>
+
+<script>
+	import dataTimePicke from "@/components/timepick/dataTimePicke.vue"
+	import selectMorePicker from "@/components/selectMorePicker.vue"
+	import {getMapconfig,getBaoconfig,getXiuconfig,getdeptTreeNow} from "@/api/work/check.js"
+	export default{
+		data(){
+			return{
+				rimg:require("@/work/static/clock/right.png"),
+				type:'add',
+				kaTimeAmIn:'',
+				formData:{
+					"locations": "",
+					"lon": "",
+					"lat": "",
+					"isPicture":'Y',
+					"distance": "100",
+					"startWorkTime": "09:00:00",
+					"endWorkTime": "18:00:00",
+				},
+				deptName:"",
+				array: ['2', '4',],
+				index: 0,
+				deptId:this.$store.state.user.deptId,
+				typetime:"time",
+				show:false,
+				value:'',
+				timeidx:-1,
+				auiPicker: {
+					title: '选择部门',
+					layer: null,
+					titflag: true,
+					data: []
+				},
+				indexs:1,
+				isPicture:'是',
+				surelist:[{
+					"label": '是',
+					"value":'Y'
+				},{
+					"label": '否',
+					"value":'N'
+				}],
+				dutyId:'',
+				fromurl:'rule',//从哪来的
+				
+			}
+		},
+		components:{
+			dataTimePicke,selectMorePicker
+		},
+		onLoad(e) {
+			var that=this;
+			// 判断是否修改
+			uni.$on('refreshaddr',(e) => {
+				const value = uni.getStorageSync('location');
+				that.formData.locations=value.address;
+				that.formData.lon=value.lng;
+				that.formData.lat=value.lat;
+			})
+			// 考勤列表
+			if(e.id){
+				this.dutyId=e.id
+				this.type='update'
+				this.getMapconfig();
+			}else{
+				this.type='add';
+				this.formData.locations=e.address||"";
+				this.formData.lon=e.lng||'';
+				this.formData.lat=e.lat||"";
+			}
+			if(e.fromurl){
+				this.fromurl=e.fromurl
+			}
+			
+		},
+		onUnload(){
+			uni.$off('refreshaddr')
+		},
+		
+		mounted() {
+			// this.getdeptTreeNow();
+		},
+		methods:{
+			//是否拍照
+			showNucleic(){
+				this.$refs.nucleinselet.show();
+			},
+			vacSureChange(e){
+				this.formData.isPicture=e[0].value;
+			},
+			showDatePicker (e) {
+				this.timeidx=e;
+				this.$refs.setpicker.show();					
+			},
+			getDeptname(){
+				this.$refs.picker.open().then(function() {
+				});
+			},
+			pickerCallback(e) {
+				const _this = this;
+				let result = '';
+				e.data.forEach(function(item, index) {
+					if (index == 0) {
+						result += item.label;
+					} else {
+						result += '/' + item.label;
+					}
+				});
+				var len = e.data.length - 1
+				_this.deptName = e.data[len].label;
+				_this.formData.deptId = e.data[len].id;
+				_this.formData.deptName = e.data[len].label;
+			},
+			getdeptTreeNow() {
+				getdeptTreeNow().then(res => {
+					if (res.code == 200) {
+						if(res.data){
+							this.auiPicker.data = res.data;
+							// this.formData.deptName=res.data[0].label
+							// this.formData.deptId=res.data[0].id
+						}
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
+			timeChange(e){
+				var that=this;
+				if(this.timeidx==0){
+					var endTime=this.formData.endWorkTime;
+					if(endTime){
+						var flag=this.getTimeFn(e,endTime)
+						if(flag!=1){
+							this.$toast('上班时间晚于下班时间')
+							this.formData.endWorkTime=''
+						}
+					}
+					this.formData.startWorkTime=e
+				}else if(this.timeidx==3){
+					var startt=this.formData.startWorkTime;
+					if(!startt){
+						this.$toast('请选择上班时间')
+						setTimeout(function(){
+							that.formData.endWorkTime='';
+						},200)
+						return
+					}
+					var flag=this.getTimeFn(startt,e)
+					if(flag!=1){
+						setTimeout(function(){
+							that.formData.endWorkTime='';
+						},200)
+						this.$toast('下班时间早于上班时间')
+						return
+					}
+					this.formData.endWorkTime=e
+				}
+			},
+			// 时间比较
+			getTimeFn(start,end){
+				var timea=new Date();
+				var timeb=new Date();
+				var timeArra=start.split(':');
+				timea.setHours(timeArra[0], timeArra[1], timeArra[2], 0);
+				var timestra=timea.getTime();
+				var timeArrb=end.split(':');
+				timeb.setHours(timeArrb[0], timeArrb[1], timeArrb[2], 0);
+				var timestrb=timeb.getTime();
+				if(timestra>timestrb){
+					return 0
+				}else{
+					return 1
+				}	
+			},
+			cancelFn() {
+				this.show = false;
+			},
+			confirmFn(e) {
+				// this.inputValue = this.value
+				this.show = false;
+			},
+			getAdres(){
+this.$tab.navigateTo("/work/pages/clock/setwoek?address="+this.formData.locations+'&lng='+this.formData.lon+"&lat="+this.formData.lat+'&type='+this.type+'&fromurl='+this.fromurl)
+			},
+			bindPickerChange(e){
+				var val=e.detail.value
+				this.formData.kaNum=this.array[val];
+			},
+			bindPickerChanges(e){
+				var val=e.detail.value;
+				this.indexs=val
+				this.isPicture=this.surelist[val].label
+				this.formData.isPicture=this.surelist[val].value;
+			},
+			bindStartTimeChange(e){
+				this.formData.kaTimeAmIn = e.detail.value
+			},
+			bindStartTimeChanges(e){
+				this.formData.kaTimeAmOut = e.detail.value
+			},
+			bindEndTimeChanges(e){
+				this.formData.kaTimePmIn = e.detail.value
+			},
+			bindEndTimeChange(e){
+				this.formData.kaTimePmOut = e.detail.value
+			},
+			
+			getMapconfig(){
+				getMapconfig(this.dutyId).then(res=>{
+					if(res.code==200){
+						var that=this;
+						this.formData=res.data
+						var isPicture=res.data.isPicture
+						if(isPicture=='Y'){
+							this.isPicture='是'
+						}else{
+							this.isPicture='否'
+						}	
+					}else{
+						 this.$toast(res.msg)
+					}
+					
+				})
+			},
+			getSure(){
+				if (this.formData.locations === "") {
+					this.$toast('请选择考勤地址')
+					return
+				} 
+				 if (this.formData.distance === "") {
+					this.$toast('请输入打卡半径')
+					return
+				}  
+				// if (this.formData.deptId === "") {
+				// 	this.$toast('请选择打卡部门')
+				// 	return
+				// } 
+				 if (this.formData.isPicture === "") {
+					this.$toast('请选择是否开启拍照打卡')
+					return
+				}
+				if(this.formData.startWorkTime === ""){
+					this.$toast('请选择上班时间')
+					return
+				}
+				if(this.formData.endWorkTime === ""){
+					this.$toast('请选择下班时间')
+					return
+				}
+				// if(this.formData.kaNum==2){
+				// 	if(this.formData.kaTimeAmIn === ""){
+				// 		this.$toast('请选择上班时间')
+				// 		return
+				// 	}
+				// 	if(this.formData.kaTimePmOut === ""){
+				// 		this.$toast('请选择下班班时间')
+				// 		return
+				// 	}
+				// 	this.formData.kaTimeAmOut='';
+				// 	this.formData.kaTimePmIn='';
+				// }else{
+				// 	if(this.formData.kaTimeAmIn === ""){
+				// 		this.$toast('请选择上午上班时间')
+				// 		return
+				// 	}
+				// 	if(this.formData.kaTimeAmOut === ""){
+				// 		this.$toast('请选择上午下班时间')
+				// 		return
+				// 	}
+				// 	if(this.formData.kaTimePmIn === ""){
+				// 		this.$toast('请选择下午上班时间')
+				// 		return
+				// 	}
+				// 	if(this.formData.kaTimePmOut === ""){
+				// 		this.$toast('请选择下午下班时间')
+				// 		return
+				// 	}
+				// }
+				// 保存
+				if(this.type=='add'){
+					getBaoconfig(this.formData).then(res=>{
+						if(res.code==200){
+							var that=this;
+							 this.$toast("保存成功")
+							 setTimeout(function(){
+								uni.$emit('reashlist')
+							 	uni.navigateBack({
+							 		delta:1
+							 	})
+							 },1200)
+						}else{
+							 this.$toast(res.msg)
+						}
+						
+					})
+				}else{
+					// 修改
+					getXiuconfig(this.formData).then(res=>{
+						if(res.code==200){
+							var that=this;
+							this.$toast("修改成功")
+							setTimeout(function(){
+								 uni.$emit('reashlist')
+								uni.navigateBack({
+									delta:1
+								})
+							},1200)
+						}else{
+							 this.$toast(res.msg)
+						}
+						
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style scoped lang="scss"> 
+.lbox{background: #FFFFFF;padding: 0 32rpx;margin-bottom: 28rpx;
+box-shadow: 0px 4rpx 6rpx 0px rgba(189,189,189,0.35);
+border-radius: 10rpx;}
+	.lists{padding: 20rpx 32rpx;
+		.list{padding:30rpx 0;display: flex;align-items: center;
+			.listl{font-size:30rpx;font-weight: bold;
+color: #343434;flex:0 0 auto;margin-right: 26rpx;}
+			.listr{font-size: 30rpx;color: #1678FF;flex: 1 ;text-decoration: underline;text-align: right;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
+			.listi{font-size:30rpx;color: #343434;flex:1;text-align: right;}
+			image{width: 10rpx;height: 18rpx;flex: 0 0 auto;margin-left: 26rpx;}
+		}
+		.listbtn{width: 100%;height: 76rpx;background: #1678FF;
+border-radius: 6px;font-size: 30rpx;color: #FFFFFF;margin-top:70rpx;line-height: 76rpx;text-align: center;}
+	}
+	.boxtopbb{text-decoration: none;}
+</style>

+ 521 - 0
work/pages/clock/setwoek.nvue

@@ -0,0 +1,521 @@
+<template>
+	<view class="setbox">
+		<map
+			id="container"
+			class="map"
+			:latitude="center.lat"
+			:longitude="center.lng"
+			@poitap="onClcikImgMap"
+			@tap="onClcikImgMap"
+			:markers="covers"
+			scale="15"
+			:style="'width: 750rpx;height:' + mapheight + 'px;'"
+		></map>
+
+		<view class="maptop">
+			<view class="maptopflex">
+				<image :src="serimg" class="maptopimg"></image>
+				<input ref='input' class="maptopint" id="tipInputs" v-model="searchtxt" @input="searchKeyword" placeholder="请输入地点进行查找" />
+			</view>
+			<!-- 地图联想 -->
+			<view class="addrSearch_list" >
+				<view class="addrSearch_item" v-for="(item, index) in searchList" :key="index" @click="handleAddrClick(item)" @blur='getblur'>
+					<view class="wrap_name">
+						<!-- #ifdef H5 -->
+						<text class="wrap_text">{{item.name.substring(0, item.name.indexOf(searchtxt))}}</text>
+							<text class="wrap_text" style="color: #2797FF;">{{searchtxt}}</text>
+							<text class="wrap_text">{{item.name.substring(item.name.indexOf(searchtxt) + searchtxt.length)}}</text>
+						<!-- #endif -->
+						<!-- #ifndef H5 -->
+						<rich-text :nodes="richNodes(item)"></rich-text>
+						<!-- #endif -->
+					</view>
+					<view class="wrap_addr">
+						<text class="wrap_addrs">{{ item.addr }}</text>
+					</view>
+				</view>
+			</view>
+		</view>
+
+		<view class="mapfot">
+			<view class="mapfott"><text class="mapfottit">标点位置</text></view>
+			<view class="mapfotx">
+				<image :src="adrimg" class="mapfotimg"></image>
+				<text class="mapfottxt" v-if="address">{{ address }}</text>
+			</view>
+			<view class="mapfotn" @click="getNextFn"><text class="mapfotntit">下一步</text></view>
+		</view>
+	</view>
+</template>
+
+<script>
+import amapFile from '@/plugins/amap-wx.js';
+import self from "@/utils/location.js"
+// #ifdef APP
+var myAmapFun = new amapFile.AMapWX({
+	key: 'ccbe52b1ec5f66295fa4609c90a819b7',
+	batch: true
+	});
+// #endif
+
+
+	export default{
+		data(){
+			return{
+				serimg:require("@/work/static/clock/serch.png"),
+				adrimg:require("@/work/static/clock/adress.png"),
+				mapimg:require("@/work/static/clock/map.png"),
+				center:{
+					lng:'',
+					lat:'',
+				},
+				mapflag:false,
+				// userId: this.$store.state.user.userId,
+				// deptId: this.$store.state.user.deptId,
+				address:'',
+				searchtxt:'',
+				type:'add',//新增还是修改,
+				placeSearchComponent:'',
+				autoCompleteComponent:'',
+				map:'',
+				//117.212232,31.83982
+				// {
+				// 	latitude: 31.839676,
+				// 	longitude: 117.211954,
+				// 	iconPath: require("@/work/static/clock/map.png"),
+				// 	anchor:{x: 0.5, y: 0.5}
+				// }
+				covers: [],
+				mapheight:0,
+				mapContext:"",
+				searchList:[],
+				focus:false,
+				location:'',
+			}
+		},
+		onReady() {
+			this.getcreateMap()
+		},
+		onLoad(e) {
+			if(e.type=='update'){
+				this.type='update'
+				this.center.lng=e.lng;
+				this.center.lat=e.lat;
+				this.address=e.address;
+			}else{
+				if(e.address){
+					this.type='update'
+					this.center.lng=e.lng;
+					this.center.lat=e.lat;
+					this.address=e.address;
+				}else{
+					this.type='add';
+				}
+				
+			}
+			if(e.fromurl){
+				this.fromurl=e.fromurl
+			}
+			console.log(this.type)
+		},
+		mounted() {
+			var that=this;
+			this.getinfo();
+			if(this.type=='add'){
+				this.getlocation()
+			}else{				
+				var lng=this.center.lng;
+				var lat=this.center.lat;
+				that.covers = [];
+				that.covers = [{
+					latitude: lat,
+					longitude: lng,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef APP
+				that.getCity(lat,  lng)
+				// #endif
+			}
+		},
+		methods:{
+			getNextFn(){
+				if(this.type=='add'){
+					if(this.fromurl&&this.fromurl=='rule'){
+						var address={
+							address:this.address,
+							lng:this.center.lng,
+							lat:this.center.lat,
+						}
+						uni.setStorageSync('location', address);
+						uni.$emit('refreshaddr');
+						uni.navigateBack({delta: 1});
+					}else{
+						uni.redirectTo({
+							url: '/work/pages/clock/setswork?type=add&address='+this.address+'&lng='+this.center.lng+'&lat='+this.center.lat
+						});
+					}
+					
+				}else{
+					var address={
+						address:this.address,
+						lng:this.center.lng,
+						lat:this.center.lat,
+					}
+					uni.setStorageSync('location', address);
+					uni.$emit('refreshaddr');
+					uni.navigateBack({delta: 1});
+				}
+				
+			},
+			searchKeyword(){
+				var that=this;
+				if(this.searchtxt){
+					// #ifdef H5
+					AMap.plugin('AMap.PlaceSearch', function(){
+						let autoOptions = {
+							city:'全国',
+							citylimit: true,
+							pageIndex: 1,
+							pageSize: 20,
+						}
+						let placeSearch = new AMap.PlaceSearch(autoOptions);
+						placeSearch.search(that.searchtxt, function(status, result) {
+							// 搜索成功时,result即是对应的匹配数据
+							if (status === 'complete' && result.info === 'OK') {
+								let items = result.poiList.pois;
+								console.log(items,122)
+								if(items.length > 0){
+									var pois = [];
+									for (let i in items) {
+										var obj = {
+											"name": items[i].name,
+											"addr": items[i].address,
+											"lng": items[i].location.lng,
+											"lat": items[i].location.lat
+										};
+										pois.push(obj);
+									}
+									that.searchList = pois;
+								}
+							}else{
+								that.searchList = [];
+							}
+						})
+					})
+					// #endif
+
+					// #ifndef H5
+					myAmapFun.getInputtips({
+						keywords: that.searchtxt,
+						city: '全国',
+						citylimit: true,
+						success: function(result){
+							if(result.tips.length > 0){
+								let pois = [];
+								let items = result.tips;
+								for (let i in items) {
+									var lnglat = items[i].location.split(',');
+									var obj = {
+										"name": items[i].name,
+										"addr": items[i].district + items[i].address,
+										"lng": lnglat[0],
+										"lat": lnglat[1]
+									};
+									pois.push(obj);
+								}
+								that.searchList = pois;
+							}else{
+								that.searchList = [];
+							}
+						},
+						fail: function(info){
+							that.searchList = [];
+							console.log('fail-search', info)
+						}
+					})
+					// #endif
+				}
+			},
+			handleAddrClick(addr){
+				console.log(this.$refs.input)
+				var that=this;
+				var lng=addr.lng;
+				var lat=addr.lat;
+				that.center.lng=lng;
+				that.center.lat=lat;
+				that.covers = [];
+				that.covers = [{
+					latitude: addr.lat,
+					longitude: addr.lng,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				that.address=addr.name || addr.addr;
+				that.searchList=[];
+				that.$refs.input.blur()
+				// #ifdef APP
+				that.getCity(lat,  lng)
+				// #endif
+			},
+			richNodes(item){
+			return [{
+				children: [
+					{
+				type: 'text',
+				attrs: {
+				class:'wrap_text'
+				},
+				text: item.name.substring(0, item.name.indexOf(this.searchtxt))
+				},
+				{
+				type: 'text',
+				attrs: {
+				class:'wrap_texts'
+				},
+				text: this.searchtxt
+				},
+				{
+				type: 'text',
+				attrs: {
+				class:'wrap_text'
+				},
+				text: item.name.substring(item.name.indexOf(this.searchtxt) + this.searchtxt.length)
+				}
+				]
+			}]
+			},
+			// 获取当前屏幕信息
+			getinfo(){
+				var that=this;
+				uni.getSystemInfo({
+					success(e) {
+						that.mapheight=e.windowHeight;
+					},
+				})
+			},
+			getcreateMap(){
+				//mapId 就是你在 map 标签中定义的 id
+				this.mapContext = uni.createMapContext('container', this);
+			},
+			onClcikImgMap(e) {
+				console.log(e,123)
+				var that=this;
+				var lng=e.detail.longitude;
+				var lat=e.detail.latitude;
+				that.center.lng=lng;
+				that.center.lat=lat;
+				that.covers = [];
+				that.covers = [{
+					latitude: e.detail.latitude,
+					longitude: e.detail.longitude,
+					iconPath: that.mapimg,
+					anchor:{x: 0.5, y: 0.5}
+				}]
+				// #ifdef APP
+				that.getCity(lat,  lng)
+				// #endif
+			},
+			//获取中心点
+			getCenterLanLat() {
+				var that = this;
+					this.mapContext.getCenterLocation({
+					  type: 'gcj02',
+					  success: res => {
+					    that.center.lng=res.longitude;
+					    that.center.lat=res.latitude;
+						that.covers = [];
+						that.covers = [{
+							latitude: e.detail.latitude,
+							longitude: e.detail.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+					    // #ifdef APP
+						
+					    that.getCity(res.latitude,  res.longitude)
+					    // #endif
+					  },
+					  fail: err => {
+					    console.log('获取当前地图中心的经纬度2', err);
+					  },
+					});
+
+			},
+			getCity(latitude, longitude) {
+				var that = this;
+				that.location = `${longitude},${latitude}`
+				console.log(that.location)
+				myAmapFun.getRegeo({
+				//如果经纬度有问题会导致不进入回调方法,从而报错
+					location: that.location,
+					success: function(e) {
+						//成功回调
+						that.address='';
+						that.address = e[0].regeocodeData.formatted_address; //详细地址
+						console.log(that.address)
+					},
+					fail: function(info) {
+						//失败回调
+						console.log(info)
+					}
+				})
+			},
+			// 获取定位
+			getlocation(){
+				var that = this;
+				uni.getLocation({
+					type: 'gcj02',
+					geocode: true,
+					success: function(res) {
+						that.center.lng=res.longitude;
+						that.center.lat=res.latitude;
+						// 设置中心点
+						that.covers = [];
+						that.covers = [{
+							latitude: res.latitude,
+							longitude: res.longitude,
+							iconPath: that.mapimg,
+							anchor:{x: 0.5, y: 0.5}
+						}]
+
+						// #ifdef H5
+						var adr= address.province+address.city+address.district+address.street+address.streetNum+address.poiName
+						// that.address=res.longitude
+						that.address=adr
+						// #endif
+						// #ifdef APP
+						that.getCity(res.latitude,  res.longitude)
+						// #endif
+
+					},
+					fail: function(red) {
+						uni.showToast({
+							title:"获取定位失败"
+						})
+					},
+				})
+			},
+			// 点击刷新方法
+			refresh(e){
+				this.getlocation();
+			},
+
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+.maptop {
+	position: fixed;
+	left: 34rpx;
+	right: 34rpx;
+	top: 24rpx;
+	max-height: calc(100vh - 400rpx);
+	display: flex;flex-direction: column;
+}
+.maptopflex {
+	flex: 0 0 auto;
+	display: flex;
+	align-items: center;
+	padding: 0 32rpx;
+	box-sizing: border-box;
+	flex-direction: row;
+	width: 684rpx;
+	height: 84rpx;
+	background: #ffffff;
+	box-shadow: 0px 0px 12rpx 0px rgba(75, 75, 75, 0.35);
+	border-radius: 6rpx;
+	margin-bottom: 10rpx;
+}
+.maptopimg {
+	width: 36rpx;
+	height: 38rpx;
+	margin-right: 16rpx;
+}
+.maptopint {
+	font-size: 26rpx;
+	color: #666666;
+	flex: 1;
+	height: 84rpx;
+}
+.mapfot {
+	position: fixed;
+	left: 34rpx;
+	right: 34rpx;
+	bottom: 24rpx;
+	background: #fff;
+	box-shadow: 0px 0px 12rpx 0px rgba(75, 75, 75, 0.35);
+	border-radius: 6rpx;
+	padding: 40rpx 32rpx 32rpx;
+	height: 300rpx;
+}
+.mapfott {
+	margin-bottom: 28rpx;
+}
+.mapfottit {
+	font-size: 28rpx;
+	font-weight: bold;
+	color: #343434;
+}
+.mapfotx {
+	display: flex;
+	margin-bottom: 32rpx;
+	min-height: 70rpx;
+	flex-direction: row;
+}
+
+.mapfotimg {
+	width: 26rpx;
+	height: 28rpx;
+	flex: 0 0 auto;
+	margin-right: 12rpx;
+}
+.mapfottxt {
+	flex: 1;
+	font-size: 26rpx;
+	color: #343434;
+	line-height: 32rpx;
+}
+.mapfotn {
+	width: 618rpx;
+	height: 76rpx;
+	background: #1678ff;
+	border-radius: 6rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+.mapfotntit {
+	font-size: 28rpx;
+	color: #fff;
+}
+.addrSearch_list{flex: 1;overflow: auto;}
+.addrSearch_item {
+	border-bottom: 2upx solid #f5f5f5;
+	padding: 4upx 12rpx;
+	background: #ffffff;
+}
+.addrSearch_item .wrap_name {
+	display: flex;
+	flex-direction: row !important;
+}
+.wrap_text {
+	font-size: 30upx;
+	color: #151515;
+	line-height: 40upx;
+}
+.wrap_texts{
+	font-size: 34upx;
+	color: #2797FF;
+	line-height: 40upx;
+}
+.addrSearch_item .wrap_addr {
+	margin-top: 2upx;
+}
+.wrap_addrs {
+	font-size: 26upx;
+	color: #999;
+	line-height: 32upx;
+}
+</style>

+ 50 - 0
work/pages/clock/success.vue

@@ -0,0 +1,50 @@
+<template>
+    <view class="sucbox">
+        <view class="ubmit">
+			<image :src="sucimg"></image>
+            <view class="bottom">
+                <view>今日{{tit}}已成功</view>
+				<view v-if="type!=1">祝您工作顺利</view>
+            </view>
+			<text class="home" @click="fanhu ">返回首页</text>
+        </view>
+    </view>
+</template>
+
+<script>
+export default {
+  props: ["detailitem"],
+  data(){
+	  return{
+		  sucimg:require("@/work/static/clock/success.png"),
+		  tit:'上班打卡',
+		  type:0
+	  }
+  },
+  onLoad(e) {
+  	this.tit=e.tit
+	if(e.type){
+		this.type=e.type
+	}
+	uni.setNavigationBarTitle({
+		title:e.tit
+	})
+  },
+  methods: {
+    fanhu(){
+     this.$tab.reLaunch('/pages/index/index')
+    }
+  }
+};
+</script>
+
+<style scoped lang="less">
+.sucbox{padding: 24rpx 34rpx 70rpx;display: flex;height: 100vh;box-sizing: border-box;}
+.ubmit {flex: 1;background: #fff;padding: 140rpx 0 130rpx;display: flex;flex-direction: column;align-items: center;overflow: auto;
+  image{width:438rpx;height: 422rpx;margin-bottom:48rpx;}
+  .home {font-size: 26rpx;font-weight: 500;color: #aaaaaa;}
+  .bottom {flex: 1;display: flex;flex-direction: column;align-items: center;
+	view {font-size: 30rpx;font-weight: 600;color: #343434;text-align: center;margin-bottom: 4rpx;}
+  }
+}
+</style>

+ 7 - 7
work/pages/record/clockin.vue

@@ -13,12 +13,12 @@
 				<view class="lbtab flexc">
 					<image :src="licoimg" class="limg"  @click='getResetFn'></image>
 					<view class="lbtabs flexc">
-						<picker class="pickbox" range-key='dictLabel' 	:range="adrlist" @change="bindTimeChangea">
+						<!-- <picker class="pickbox" range-key='dictLabel' 	:range="adrlist" @change="bindTimeChangea">
 							<view class="pickboxa">
 								<view class="tit overtwo" >{{deptName||'考勤类型'}}</view>
 								<image :src="wupimg" class="hupimg"></image>
 							</view>
-						</picker>
+						</picker> -->
 						<picker mode="date" class="pickbox"  
 							 @change="bindTimeChangea">
 							<view class="pickboxa">
@@ -42,7 +42,7 @@
 <script>
 	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
 	import yList from "@/work/components/yuyue/list.vue"
-	import {getClockList} from "@/api/mine/work.js"
+	import {getRecordPeoList} from "@/api/work/check.js"
 	import {getDictionaryFn} from "@/api/mine/register.js"
 	export default {
 		components: {yList},
@@ -124,7 +124,7 @@
 			getDetail(ite){
 				var obj={
 					userId:ite.userId,
-					recordTime:ite.recordTime
+					recordDate:ite.clockMap.date
 				}
 				this.$tab.navigateTo('/work/pages/record/detail?data='+encodeURIComponent(JSON.stringify(obj)))
 			},
@@ -155,12 +155,12 @@
 					params.userId=this.userId
 				}
 				if(this.time){
-					params.recordTime=this.time
+					params.recordDate=this.time
 				}
 				if(this.title){
 					params.userName=this.title
 				}
-				getClockList(params).then(res => {
+				getRecordPeoList(params).then(res => {
 					if (res.code == 200) {
 						if (res.rows.length < this.pageSize) {
 							this.reachflag = false
@@ -208,7 +208,7 @@
 .lbtab{padding: 0 56rpx;
 	.limg{width: 24rpx;height: 24rpx;margin-right: 16rpx;flex:0 0 auto;}
 	.lbtabs{overflow: auto;flex-wrap: nowrap;flex:1;
-		.pickbox{text-align: right;font-weight: 500;font-size: 28rpx;color: #161616;min-height:88rpx;margin: 0 20rpx;flex:1;
+		.pickbox{text-align: right;font-weight: 500;font-size: 28rpx;color: #161616;min-height:88rpx;margin: 0 20rpx;
 			.pickboxa{justify-content: center;	
 				min-height: 88rpx;display: flex;align-items: center;	
 			}

+ 224 - 30
work/pages/record/detail.vue

@@ -7,30 +7,79 @@
 		</view>
 		<image :src="navbg" class="navbg"></image>
 		<view class="zxmain">
+			<!-- <view class="locktop" @click="getNormal">
+				<view class="locktopl">本月异常考勤</view>
+				<view class="locktopr">
+					您有
+					<text>{{ abnormainfo.count||0 }}</text>
+					条考勤异常记录,去处理
+				</view>
+				<image :src="rimg" class="locktopi"></image>
+			</view> -->
+			<view class="lock_header" v-if="checkPermi(['system:clock:personage:month'])">
+				<view class="lock_headerth">
+					<view class="tit">本月考勤记录</view>
+					<!-- <view class="txt" @click="cords">
+						<text>详细记录</text>
+					</view> -->
+				</view>
+				<view class="lock_headerthbt">
+					<view>
+						<text class="tit cicr2">{{countinfo.cd}}</text>
+						<text class="txt">迟到</text>
+					</view>
+					<view>
+						<text class="tit cicr4">{{countinfo.zt}}</text>
+						<text class="txt">早退</text>
+					</view>
+					<view>
+						<text class="tit cicr3">{{countinfo.wq}}</text>
+						<text class="txt">外勤</text>
+					</view>
+					<view>
+						<text class="tit cicr5">{{countinfo.wdk}}</text>
+						<text class="txt">未打卡</text>
+					</view>
+				</view>
+			</view>
 			<view class="ytbox">
 				<view class="ytop flexc">
 					<view class="tit" v-if="dataobj.name">{{dataobj.name.charAt(0)}}</view>
 					<view class="cent">
 						<view class="ctit">{{dataobj.name}}</view>
-						<view class="ctime">最新打卡:{{dataobj.time}}</view>
+						<view class="ctime">最新打卡:{{timeday}}</view>
 					</view>
 				</view>
 				<!-- 日历 -->
 				<view class="mb24">
-					<lunc-calendar ref="calendar" :showLunar="false" :configWeek="configWeek" :configHoliday="configHoliday" :firstDayOfWeek="firstDayOfWeek" :showMonthBg="false" :showShrink="true" :signList="signList"
+					<lunc-calendar ref="calendar" :recordDate="recordDate"  :showLunar="false" :configWeek="configWeek" :configHoliday="configHoliday" :firstDayOfWeek="firstDayOfWeek" :showMonthBg="false" :showShrink="true" :signList="signList" 
 						@dayChange="dayChange" weekType="" @monthChange="monthChange" @getIsSelDayFn="getIsSelDayFn" @shrinkClick="shrinkClick">
 					</lunc-calendar>
 				</view>
-				<view class="tips">出勤统计:打卡2次,上下班时间:{{dataobj.workTime}}</view>
+				<view class="tips">出勤统计:打卡
+				<block v-if="datainfo.am&&datainfo.pm">2</block>
+				<block v-else-if="datainfo.am||datainfo.pm">1</block>
+				<block v-else>0</block>次,上下班时间:{{dataobj.workTime}}</view>
+				<!-- 休息 -->
+				<view  class="restbox" v-if="datainfo.holidaytype=='NO'||weekflag&&datainfo.holidaytype!='YES'">
+					<image :src="restimg"></image>
+					<view>今日休息</view>
+					<view>无需打卡哟~</view>
+				</view>
 				<!-- 步骤条 -->
-				<view class="mb16 plr18">
+				<view class="mb16 plr18" v-if="!datainfo.holidaytype||datainfo.holidaytype!='NO'||datainfo.holidaytype=='NO'&&(!datainfo.am||!datainfo.pm)">
 					<view class="steps">
 						<view class="cir"></view>
 						<view class="stepsa">
 							<view class="steptit">上班打卡</view>
 							<view class="steptxt">
 								<image :src="cirimg"></image>
-								<view>08:27已打卡</view>
+								<view v-if="datainfo.am">{{datainfo.am}}<block v-if="datainfo.amex!=5">已打卡</block></view>
+								<view class="tip" v-if="datainfo.amex>1&&datainfo.amex<5">
+									<block v-if="datainfo.amex==2">外勤</block>
+									<block v-if="datainfo.amex==3">迟到</block>
+									<block v-if="datainfo.amex==4">早退</block>
+								</view>
 							</view>
 						</view>
 					</view>
@@ -40,13 +89,18 @@
 							<view class="steptit">下班打卡</view>
 							<view class="steptxt">
 								<image :src="cirimg"></image>
-								<view>17:41已打卡</view>
+								<view v-if="datainfo.pm">{{datainfo.pm}}<block v-if="datainfo.pmex!=5">已打卡</block></view>
+								<view class="tip" v-if="datainfo.pmex>1&&datainfo.pmex<5">
+									<block v-if="datainfo.pmex==2">外勤</block>
+									<block v-if="datainfo.pmex==3">迟到</block>
+									<block v-if="datainfo.pmex==4">早退</block>
+								</view>	
 							</view>
 						</view>
 					</view>
 				</view>
 				
-				<view class="tips">统计截至 2024-07-18 16:13</view>
+				<view class="tips">统计截至 {{kaTime}}</view>
 			</view>
 		</view>
 	</view>
@@ -56,6 +110,7 @@
 	import {checkPermi,checkRole} from "@/utils/permission"; // 权限判断函数
 	import {getDictionaryFn} from "@/api/mine/register.js"
 	import {getClockRl} from "@/api/mine/work.js"
+	import {getClockCountper} from "@/api/work/check.js"
 	import luncCalendar from "@/work/components/lunc-calendar/lunc-calendar.vue"
 	export default {
 		components: {luncCalendar},
@@ -63,13 +118,15 @@
 			return {
 				cirimg:require("@/static/images/home/chose.png"),
 				navbg:require("@/static/images/navbg.png"),
+				restimg:require('@/work/static/clock/rest.png'),
 				backgroundColor: "transparent",
 				datainfo:{},
 				dataobj:{},
+				abnormainfo:[0,2,3,5],
 				nvaHeight: 44,
 				marTop: 0, //距离顶部的距离
 				stubarHeight: 0, //
-				visitName:'林涵宇',
+				visitName:'',
 				
 				signList: [],
 				configWeek:[],
@@ -78,12 +135,14 @@
 				// dayflag:false,
 				// month:'',
 				// year:'',
-				// kaTime:'',
-				// changetime:'',//改变的日期
-				// timeday:'',//选择的日期
+				kaTime:'',
+				changetime:'',//改变的日期
+				timeday:'',//选择的日期
 				// visitDate:'',
 				userId:'',
-				recordTime:'',
+				recordDate:'',
+				countinfo:{},//统计,
+				weekflag:false,
 			}
 		},
 		onPageScroll(e) {
@@ -94,12 +153,13 @@
 				this.backgroundColor = 'transparent'
 			}
 		},
-		onLoad: function() {
+		onLoad: function(e) {
 			if(e.data){
 				var data=JSON.parse(decodeURIComponent(e.data))
 				this.userId=data.userId;
-				this.recordTime=data.recordTime;
+				this.recordDate=data.recordDate;
 				this.getCalendarList()
+				this.timeWeek(data.recordDate)
 			}
 			uni.getSystemInfo({
 				success: (e) => {
@@ -107,7 +167,10 @@
 					this.nvaHeight = Number(e.statusBarHeight) + 44;
 				}
 			})
-			// 3c8cadac11af4f1298a2882addc8788d
+			this.time();
+			if(checkPermi(['system:clock:personage:month'])){
+				this.getClockCountper()
+			}
 		},
 		onShow() {},
 		methods: {
@@ -118,38 +181,100 @@
 					delta: 1
 				})
 			},
+			getClockCountper(){
+				var params = {
+					userId: this.userId,
+					recordDate: this.recordDate,
+				}
+				if(this.changetime){
+					params.recordDate=this.changetime
+				}
+				getClockCountper(params).then(res => {
+					if (res.code == 200) {
+						this.countinfo=res.data;
+					} else {
+						this.$toast(res.msg)
+					}
+				})
+			},
 			dayChange(e){
+				var week=e.week;
+				// 周末标红
+				if (week == 0 || week == 6){
+					this.weekflag=true
+				}else{
+					this.weekflag=false
+				}
 				if(e.daySign&&e.daySign.length){
 					var daySign=e.daySign[0];
 					this.datainfo=JSON.parse(JSON.stringify(daySign))
 				}
 			},
+			time() {
+				var date = new Date();
+				var y = date.getFullYear();
+				var m = date.getMonth() + 1;
+				var d = date.getDate();
+				var h = date.getHours();
+				var min = date.getMinutes();
+				var s = date.getSeconds();
+				var week = date.getDay(); //获取当前星期X(0-6,0代表星期天)
+				var weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
+				var yearStr = y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d);
+				var timeStr = (h < 10 ? '0' + h : h) + ':' + (min < 10 ? '0' + min : min) + ':' + (s < 10 ? '0' + s : s);
+				
+				
+				this.timeday = yearStr;
+				this.kaTime =yearStr+' '+ timeStr;
+				// 年,月,日, 星期几 时分秒
+			},
+			timeWeek(data){
+				var date = new Date(data);
+				var week = date.getDay(); //获取当前星期X(0-6,0代表星期天)
+				if(week==0||week==6){
+					this.weekflag=true;
+				}else{
+					this.weekflag=false
+				}
+			},
 			monthChange(e){
 				var y=e.year;
 				var m=e.month;
-				if(y==this.year&&m==this.month){
-					this.getCalendarList()
-					this.changetime='';
-				}else{
-					var time=y + '-' + m + '-' + '01'
-					this.changetime=time
-					this.getCalendarList(time)
-				}
+				var time=y + '-' + m + '-' + '01'
+				this.changetime=time
+				this.getCalendarList(time)
+				this.getClockCountper()
+				// if(y==this.year&&m==this.month){
+				// 	this.getCalendarList()
+				// 	this.changetime='';
+				// }else{
+				// 	var time=y + '-' + m + '-' + '01'
+				// 	this.changetime=time
+				// 	this.getCalendarList(time)
+				// }
 			},
 			// 选中的日期
 			getIsSelDayFn(e){
 				if(e.sign&&e.sign.length){
 					var date=e.sign[0].date;
-					if(date==this.recordTime){
-						var daySign=e.sign[0];
-						this.datainfo=JSON.parse(JSON.stringify(daySign))
-					}
+					var daySign=e.sign[0];
+					this.datainfo=JSON.parse(JSON.stringify(daySign))
+					// if(date==this.recordDate){
+					// 	var daySign=e.sign[0];
+					// 	this.datainfo=JSON.parse(JSON.stringify(daySign))
+					// }
 				}
 				
 			},
 			shrinkClick(e){
 				console.log(e,3)
 			},
+			getNormal(){
+				this.$tab.navigateTo("/work/pages/clock/abnormal")
+			},
+			cords(){
+				// this.$tab.navigateTo("/work/pages/clock/abnormal")
+			},
 			init() {
 				// 门卫
 				// getDictionaryFn('is_read').then(res=>{
@@ -166,14 +291,43 @@
 			getCalendarList() {
 				var params = {
 					userId: this.userId,
-					recordTime: this.recordTime,
+					recordDate: this.recordDate,
+				}
+				if(this.changetime){
+					params.recordDate=this.changetime
 				}
 				getClockRl(params).then(res => {
 					if (res.code == 200) {
 						var data=res.data;
 						this.dataobj=res.data;
+						var holidays=[];
+						if(data.holidays&&data.holidays.length){
+							holidays=data.holidays
+						}
 						if(data.rlData&&data.rlData.length){
-							this.signList=data.rlData;
+							var newArr=JSON.parse(JSON.stringify(data.rlData))
+							var tree=[]
+							newArr.forEach(ite=>{
+								const matchingData = holidays.find(d => d.holidayDate == ite.date);
+								var obj=JSON.parse(JSON.stringify(ite))
+								if(matchingData){
+									obj.holidaytype=matchingData.type;
+									tree.push(obj)	
+								}else{
+									tree.push(obj)	
+								}
+								if(ite.date==this.recordDate){
+									this.datainfo=JSON.parse(JSON.stringify(obj))
+								}
+							})
+							this.signList=JSON.parse(JSON.stringify(tree));
+							// Object.keys(newArr).some((key) => {
+							// 	if(newArr[key].date==this.recordDate){
+							// 		this.datainfo=JSON.parse(JSON.stringify(newArr[key]))
+							// 		return
+							// 	}
+								
+							// })
 						}
 					} else {
 						this.$toast(res.msg)
@@ -193,7 +347,7 @@
 <style lang="scss" scoped>
 .navbox{position: fixed;left: 0;right: 0;top: 0;z-index: 4;	}
 .navbg{width: 100%;height: 692rpx;}	
-.zxmain{position: relative;padding: 20rpx 32rpx 40rpx;box-sizing: border-box;display: flex;}
+.zxmain{position: relative;padding: 20rpx 32rpx 40rpx;box-sizing: border-box;display: flex;flex-direction: column;}
 .ytbox{width: 684rpx;margin: 0 auto;padding-top: 24rpx;position: relative;flex: 1;overflow: auto;background-color: #ffffff;padding-bottom: 12rpx;border-radius: 14rpx;
 	.ytop{padding: 16rpx 0 24rpx 16rpx;
 		.tit{width: 62rpx;height: 62rpx;background: #0391FD;border-radius: 6rpx;font-weight: 500;
@@ -216,8 +370,48 @@
 			.steptxt{display: flex;
 				image{width: 20rpx;height: 20rpx;margin-right: 14rpx;flex: 0 0 auto;margin-top: 7rpx;}
 				view{font-weight: bold;font-size: 26rpx;color: #888888;}
+				.tip{border-radius: 12rpx;font-weight: 500;font-size: 16rpx;color: #F87C29;border: 2rpx solid #F87C29;height: 28rpx;box-sizing: border-box;display: flex;align-items: center;padding: 0 8rpx;margin-left: 12rpx;flex: 0 0 auto;margin-top: 6rpx;}
 			}
 		}
 	}
 }
+.locktop{
+	background: #FFFFFF;
+	box-shadow: 0px 0px 12rpx 0px rgba(153,152,152,0.39);
+	border-radius: 14rpx;display: flex;align-items: center;padding: 40rpx 32rpx;margin-bottom: 30rpx;
+	.locktopl{font-size: 26rpx;font-weight: bold;color: #343434;flex: 1 0 auto;margin-right: 16rpx;}
+	.locktopr{font-size: 22rpx;color: #1678ff;flex: 0 1 auto;
+		text{font-size: 28rpx;color: #F16435;font-weight: bold;}
+	}
+	.locktopi{width: 10rpx;height: 18rpx;flex: 0 0 auto;margin-left: 16rpx;}
+ }
+.cof{color: #ff0000 !important;}
+// 标识点
+.cicr2{colorr: $uni-katype2 !important;}//迟到
+.cicr3{color: $uni-katype3 !important;}//外勤
+.cicr4{color: $uni-katype4 !important;}//早退
+.cicr5{color: $uni-katype5 !important;}//旷工
+	 
+.lock_header {
+	background-color: #ffffff;
+	margin-bottom: 30rpx;min-height: 220rpx;padding: 32rpx 34rpx 20rpx;box-shadow: 0px 0px 12rpx 0px rgba(153, 152, 152, 0.39);border-radius: 14rpx;box-sizing: border-box;
+	.lock_headerth {display: flex;justify-content: space-between;align-items: center;
+	  .tit{font-size: 26rpx;font-weight: bold;color: #343434;}
+	 .txt{display: flex;align-items: center;
+	    text {font-size: 26rpx;font-weight: 400;color: #1678ff;}
+	    image {width: 10rpx; height: 18rpx;margin-left: 10rpx;}
+	  }
+	}
+	.lock_headerthbt {display: flex;justify-content: space-between;
+	  view {flex: 1;text-align: center;display: flex;flex-direction: column;align-items: center;padding: 26rpx 0 20rpx;
+	    .tit{margin-bottom: 16rpx;font-size: 34rpx;font-weight: bold;color: #343434;}
+	    .txt{font-size: 22rpx;font-weight: 400;color: #343434;
+	    }
+	  }
+    }
+  }
+.restbox{display: flex;flex-direction: column;align-items: center;margin-bottom: 48rpx;padding-top: 40rpx;
+	image{width: 396rpx;height: 264rpx;margin-bottom: 20rpx;}
+	view{font-weight: 500;font-size: 26rpx;color: #343434;}
+}
 </style>

+ 1 - 1
work/pages/yyorder/eat.vue

@@ -90,7 +90,7 @@
 				jclxlist:[],
 				ptype:'add',
 				id:'',
-				name:this.$store.state.user.name,
+				name:this.$store.state.user.nickName,
 				userId:this.$store.state.user.userId,
 				deptId:this.$store.state.user.deptId,
 				deptName:this.$store.state.user.deptName,

+ 0 - 1
work/pages/yyorder/eatlistday.vue

@@ -101,7 +101,6 @@
 					this.nvaHeight = Number(e.statusBarHeight) + 44;
 				}
 			})
-			// 3c8cadac11af4f1298a2882addc8788d
 		},
 		onShow() {},
 		methods: {

+ 1 - 1
work/pages/yyorder/limitdetail.vue

@@ -99,7 +99,7 @@
 				depTree:[],
 				ptype:'add',
 				id:'',
-				// name:this.$store.state.user.name,
+				// name:this.$store.state.user.nickName,
 				// userId:this.$store.state.user.userId,
 				// deptId:this.$store.state.user.deptId,
 				// deptName:this.$store.state.user.deptName,

+ 1 - 1
work/pages/yyorder/meetadd.vue

@@ -174,7 +174,7 @@
 				id:'',
 				filterable:true,
 				chooseValue:'',
-				name:this.$store.state.user.name,
+				name:this.$store.state.user.nickName,
 				userId:this.$store.state.user.userId,
 				bannerlist:[]
 			}

+ 1 - 1
work/pages/yyorder/meeting.vue

@@ -120,7 +120,7 @@
 				id:'',
 				filterable:true,
 				chooseValue:'',
-				name:this.$store.state.user.name,
+				name:this.$store.state.user.nickName,
 				userId:this.$store.state.user.userId,
 			}
 		},

BIN
work/static/clock/addry.png


BIN
work/static/clock/adress.png


BIN
work/static/clock/chosebm.png


BIN
work/static/clock/close.png


BIN
work/static/clock/down.png


BIN
work/static/clock/icon_kqdk_jrfw.png


BIN
work/static/clock/icon_rqxz.png


BIN
work/static/clock/krules.png


BIN
work/static/clock/map.png


BIN
work/static/clock/moico.png


BIN
work/static/clock/nhead.png


BIN
work/static/clock/noiconp.png


BIN
work/static/clock/photo.png


BIN
work/static/clock/pic_mine_hp_normal.png


BIN
work/static/clock/pimg.png


BIN
work/static/clock/rest.png


BIN
work/static/clock/right.png


BIN
work/static/clock/serch.png


BIN
work/static/clock/stepa.png


BIN
work/static/clock/stepb.png


BIN
work/static/clock/stepc.png


BIN
work/static/clock/stepd.png


BIN
work/static/clock/success.png


BIN
work/static/clock/successw.png


BIN
work/static/clock/up.png


BIN
work/static/clock/updata.png


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.