clockStats.vue 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. <template>
  2. <view class="page-view">
  3. <top-return text="打卡详情" color="#FFF"></top-return>
  4. <!-- 背景 -->
  5. <view class="bg-box2"></view>
  6. <!-- 月统计卡片信息 -->
  7. <view class="card-view" style="margin-top: 140rpx;">
  8. <view class="card-item" style="width: 100%;">
  9. <view class="card-title" style="margin:10rpx 0 0 10rpx;">
  10. <view class="title">{{currentTodayData.month}}月 打卡汇总</view>
  11. </view>
  12. <view class="clock-stats">
  13. <view class="flex-column" style="align-items: center;">
  14. <view class="number" style="color: #4169E1;">{{isClockStats}}</view>
  15. <view class="number-detail">打卡次数</view>
  16. </view>
  17. <view class="flex-column" style="align-items: center;">
  18. <view class="number" style="color: #ff5959;">{{noClockStats}}</view>
  19. <view class="number-detail">缺卡次数</view>
  20. </view>
  21. <view class="flex-column" style="align-items: center;">
  22. <view class="number"
  23. :style="{color: clockStatsQuality==='优秀'?'#4169E1':(clockStatsQuality === '较差'?'#ff5959':'#f9c752')}">
  24. {{clockStatsQuality}}
  25. </view>
  26. <view class="number-detail">出勤质量</view>
  27. </view>
  28. </view>
  29. </view>
  30. <!-- 打卡记录日历 -->
  31. <view class="card-item" style="width: 100%;">
  32. <view class="calendar-container">
  33. <zsyCalendar :sundayIndex="6" @chooseDate="chooseDate" @change="change" />
  34. </view>
  35. <view class="state-box">
  36. <view class="state"
  37. :style="{backgroundColor: clockState==='已打卡'?'#4169E1':(clockState === '未打卡'?'#ff5959':'#bebebe')}">
  38. <view class="state-text">{{clockState}}</view>
  39. </view>
  40. <view class="msg-box">
  41. <view class="flex">
  42. <text class="msg-text" style="font-weight: normal;font-size: 28rpx;">打卡时间:</text>
  43. <text class="msg-text">{{clockTime.replace('0','')}}</text>
  44. </view>
  45. <view class="flex">
  46. <text class="msg-text" style="font-weight: normal;font-size: 28rpx;">出勤效率:</text>
  47. <text class="msg-text"
  48. :style="{color: clockQuality==='优秀'?'#4169E1':(clockQuality === '良好'?'#f9c752':'#3B4144')}">{{clockQuality}}</text>
  49. </view>
  50. </view>
  51. <!-- 图片信息 -->
  52. <view class="image" v-if="currentTodayData.isAttend === 1"
  53. :style="{backgroundImage:`url(${imageWorkday})`}"></view>
  54. <view class="image" v-if="currentTodayData.isAttend === 7"
  55. :style="{backgroundImage:`url(${imageWeekend})`}"></view>
  56. <view class="image" v-if="currentTodayData.isAttend === 0"
  57. :style="{backgroundImage:`url(${imageNoAttend})`}"></view>
  58. <view class="image" v-if="currentTodayData.isAttend === -1"
  59. :style="{backgroundImage:`url(${imageNoArrive})`}"></view>
  60. </view>
  61. </view>
  62. </view>
  63. </view>
  64. </template>
  65. <script>
  66. import {
  67. mapState
  68. } from 'vuex'
  69. import zsyCalendar from '@/components/z-calendar/zsy-calendar.vue'
  70. export default {
  71. name: 'Calendar',
  72. components: {
  73. zsyCalendar
  74. },
  75. computed: {
  76. ...mapState('m_children', ['clockData']),
  77. },
  78. data() {
  79. return {
  80. //月打卡统计数据
  81. isClockStats: '',
  82. noClockStats: '',
  83. clockStatsQuality: '',
  84. //日打卡数据
  85. clockState: '',
  86. clockTime: '',
  87. clockQuality: '',
  88. //日历月份
  89. calendarMonth: '',
  90. //点击当日信息
  91. currentTodayData: '',
  92. //控制事件参数
  93. isFirst: false,
  94. //当日时间参数
  95. todayData: '',
  96. //图片
  97. imageWorkday: 'https://ouch-cdn2.icons8.com/z39mAYlsJUS2hKCBbkK_ktOIjma_qhkc5J0ANdyfiKU/rs:fit:912:912/czM6Ly9pY29uczgu/b3VjaC1wcm9kLmFz/c2V0cy9zdmcvMTA3/L2FlZjQ4NmM4LTAz/NTYtNGRhNS04ZWQ2/LTBhMGIzMzdhZjNm/Mi5zdmc.png',
  98. imageWeekend: 'https://ouch-cdn2.icons8.com/NJDdGibHzZkGZzgqe55ESzJ6_BrcgHO2bkz_vFG6PoY/rs:fit:912:912/czM6Ly9pY29uczgu/b3VjaC1wcm9kLmFz/c2V0cy9zdmcvNTg2/L2RlMmJhZDI4LTAz/NTQtNDMwNS1hNmQ2/LTU3Y2Y1ODJjNjc3/YS5zdmc.png',
  99. imageNoAttend: 'https://ouch-cdn2.icons8.com/ehPeP69ypvrLonk6YkqIzV_WfKM1G-Ls9J7PuZvxRr8/rs:fit:912:912/czM6Ly9pY29uczgu/b3VjaC1wcm9kLmFz/c2V0cy9zdmcvMzY3/L2QzZGNmODA5LTY3/ODUtNGFkOC1hOWVi/LWI4OWYyM2ZiMzNi/Yi5zdmc.png',
  100. imageNoArrive: 'https://ouch-cdn2.icons8.com/WfSBIzy4iTGDtprvhW0wA2S8lPNRoqeZqvFsNbKsraw/rs:fit:912:912/czM6Ly9pY29uczgu/b3VjaC1wcm9kLmFz/c2V0cy9zdmcvODQ3/LzI1NDY1ZDdhLTVj/NDEtNGIzMy1iN2Q1/LTRhYjgwOGU2NDk5/OS5zdmc.png'
  101. }
  102. },
  103. watch: {
  104. calendarMonth() {
  105. this.getClockStatsQuality()
  106. }
  107. },
  108. onLoad() {
  109. this.init()
  110. },
  111. methods: {
  112. init() {
  113. this.getClockStatsQuality()
  114. this.getTodayAttendance()
  115. },
  116. //判断本月出勤质量
  117. getClockStatsQuality() {
  118. this.clockStatsQuality = this.noClockStats / 30 <= 0.1 ? '优秀' : (this.noClockStats / 30 <= 0.2 ? '良好' :
  119. '较差')
  120. if (this.noClockStats === '暂无' && this.isClockStats === '暂无') {
  121. this.clockStatsQuality = '暂无'
  122. }
  123. },
  124. //今日打卡
  125. getTodayAttendance() {
  126. //获得当前时间时间戳
  127. let timeArr = (new Date()).format("yyyy-M-dd").split("-")
  128. let val = this.clockData.filter(x => x.year == timeArr[0] && x.month == timeArr[1] && x.date == timeArr[2])
  129. if (val.length === 0) {
  130. //出勤状况
  131. this.clockState = '未打卡',
  132. //打卡时间
  133. this.clockTime = '无记录',
  134. //出勤质量
  135. this.clockQuality = '无记录'
  136. } else {
  137. this.clockState = '已打卡'
  138. this.clockTime = val[0].time
  139. this.clockQuality = val[0].time <= '08:15' ? '优秀' : (val[0].time <= '08:25' ? '良好' : '较差')
  140. }
  141. },
  142. //选择日期
  143. chooseDate(dateInfo, dateIndex) {
  144. if (dateInfo.isAttend === 1) {
  145. this.clockState = '已打卡'
  146. this.clockTime = this.clockData.filter(x => x.date === dateInfo.date && x.month === dateInfo
  147. .month && x.year === x.year)[0].time
  148. this.clockQuality = this.clockTime <= '08:15' ? '优秀' : (this.clockTime <= '08:25' ?
  149. '良好' : '较差')
  150. }
  151. if (dateInfo.isAttend === 0) {
  152. this.clockState = '未打卡'
  153. this.clockTime = '无记录'
  154. this.clockQuality = '无记录'
  155. }
  156. if (dateInfo.isAttend === -1) {
  157. this.clockState = '时间未到'
  158. this.clockTime = '无记录'
  159. this.clockQuality = '无记录'
  160. }
  161. if (dateInfo.isAttend === 7) {
  162. this.clockState = '周末休息'
  163. this.clockTime = '无记录'
  164. this.clockQuality = '无记录'
  165. }
  166. },
  167. //选中日期改变回调
  168. change(e) {
  169. //存入当前时间
  170. if (this.isFirst === false) {
  171. this.todayData = e
  172. this.isFirst = true
  173. }
  174. //点击当日信息
  175. this.currentTodayData = e
  176. console.log("日历点击",this.currentTodayData);
  177. //日历月份
  178. this.calendarMonth = e.month
  179. //当前日历月份打卡数
  180. this.isClockStats = this.clockData.filter(x => x.month === e.month && x.year === e.year).length
  181. // 当前日历月天数
  182. let monthDays = new Date(e.year, e.month, 0).getDate()
  183. //在本年当前月之前
  184. if (e.year === this.todayData.year && e.month < this.todayData.month) {
  185. let weekendDates = 0
  186. for (let i = 1; i <= monthDays; i++) {
  187. if (new Date(`${e.year}-${e.month}-${i}`).getDay() === 0 ||
  188. new Date(`${e.year}-${e.month}-${i}`).getDay() === 6) {
  189. weekendDates++
  190. }
  191. }
  192. //当前日历月份未打卡数
  193. this.noClockStats = monthDays - this.isClockStats - weekendDates
  194. }
  195. //之前年份
  196. if (e.year < this.todayData.year) {
  197. let weekendDates = 0
  198. for (let i = 1; i <= monthDays; i++) {
  199. if (new Date(`${e.year}-${e.month}-${i}`).getDay() === 0 ||
  200. new Date(`${e.year}-${e.month}-${i}`).getDay() === 6) {
  201. weekendDates++
  202. }
  203. }
  204. //当前日历月份未打卡数
  205. this.noClockStats = monthDays - this.isClockStats - weekendDates
  206. }
  207. //在本月
  208. if (e.year === this.todayData.year && e.month === this.todayData.month) {
  209. let weekendDates = 0
  210. for (let i = 1; i <= this.todayData.date; i++) {
  211. if (new Date(`${e.year}-${e.month}-${i}`).getDay() === 0 ||
  212. new Date(`${e.year}-${e.month}-${i}`).getDay() === 6) {
  213. weekendDates++
  214. }
  215. }
  216. this.noClockStats = this.todayData.date - this.isClockStats - weekendDates
  217. }
  218. //在本年当月之后
  219. if (e.year === this.todayData.year && e.month > this.todayData.month) {
  220. this.noClockStats = '暂无'
  221. this.isClockStats = '暂无'
  222. }
  223. //之后年份
  224. if (e.year > this.todayData.year) {
  225. this.noClockStats = '暂无'
  226. this.isClockStats = '暂无'
  227. }
  228. },
  229. }
  230. }
  231. </script>
  232. <style lang="scss">
  233. .number {
  234. font-size: 50rpx;
  235. font-weight: bold;
  236. color: $title;
  237. }
  238. .number-detail {
  239. margin-top: 10rpx;
  240. font-size: 30rpx;
  241. color: $subtitle;
  242. }
  243. .state-box {
  244. display: flex;
  245. align-items: center;
  246. height: 200rpx;
  247. width: 100%;
  248. .state {
  249. display: flex;
  250. align-items: center;
  251. justify-content: center;
  252. border-radius: 100%;
  253. margin: 20rpx;
  254. height: 150rpx;
  255. width: 150rpx;
  256. .state-text {
  257. font-size: 32rpx;
  258. font-weight: bold;
  259. color: #FFF;
  260. }
  261. }
  262. .msg-box {
  263. display: flex;
  264. flex-direction: column;
  265. justify-content: space-around;
  266. height: 150rpx;
  267. width: auto;
  268. .msg-text {
  269. color: $title;
  270. font-weight: bold;
  271. font-size: 36rpx;
  272. margin-left: 15rpx;
  273. }
  274. }
  275. }
  276. .calendar-container {
  277. height: 100%;
  278. width: 100%;
  279. background-color: #FFF;
  280. margin: 0 auto;
  281. box-sizing: border-box;
  282. border-radius: $border-radius;
  283. }
  284. .image {
  285. margin-left: auto;
  286. margin-right: 20rpx;
  287. width: 200rpx;
  288. height: 200rpx;
  289. border-radius: $border-radius;
  290. background-size: 100%;
  291. background-repeat: no-repeat;
  292. }
  293. .box_tag{
  294. margin-right: 20rpx;
  295. height: 100%;
  296. width: 10rpx;
  297. background-color: $title;
  298. z-index: 99;
  299. }
  300. .clock-stats{
  301. display: flex;
  302. align-items: center;
  303. justify-content: space-around;
  304. height: 180rpx;
  305. margin-bottom: 20rpx;
  306. }
  307. </style>