dkdetail.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. <template>
  2. <view class="content">
  3. <view class="select-top">
  4. <view class="">
  5. 本月统计
  6. </view>
  7. <view class="top-right">
  8. <view class="select-time">
  9. <picker mode="date" @change="bindDateChange" fields="month">
  10. <view class="uni-input">{{showdate}}</view>
  11. </picker>
  12. <image src="../../static/img/downjian.png" mode="widthFix"></image>
  13. </view>
  14. </view>
  15. </view>
  16. <view class="dk-info">
  17. <view class="dk-day big">
  18. <view class="dk-left">
  19. {{dk_detail.clock_in}}
  20. </view>
  21. <view class="dk-center">
  22. /
  23. </view>
  24. <view class="dk-right err">
  25. {{dk_detail.no_clocking}}
  26. </view>
  27. </view>
  28. <view class="dk-tit">
  29. <view class="dk-left">
  30. 需要打卡次数
  31. </view>
  32. <view class="dk-center">
  33. /
  34. </view>
  35. <view class="dk-right">
  36. 缺卡次数
  37. </view>
  38. </view>
  39. <view class="dk-detail">
  40. <view class="detail-item green">
  41. <view class="">
  42. {{dk_detail.normal}}
  43. </view>
  44. <view class="item-tit">
  45. 正常打卡(次)
  46. </view>
  47. </view>
  48. <view class="detail-item">
  49. <view class="">
  50. {{dk_detail.early}}
  51. </view>
  52. <view class="item-tit">
  53. 早退(次)
  54. </view>
  55. </view>
  56. <view class="detail-item">
  57. <view class="err">
  58. {{dk_detail.late}}
  59. </view>
  60. <view class="item-tit">
  61. 迟到(次)
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. <scroll-view scroll-y="true" class="yg-list" :style="{'height': height}">
  67. <template v-for="item in list">
  68. <view class="yg-wrap">
  69. <view class="yg-name">
  70. {{ item.time + ' '+ item.name}}
  71. </view>
  72. <view class="dk-status" :class="{'err': item.status == -1 }" @click="openDetail(item)">
  73. {{item.status == 0 ? '正常': (item.status == -1 ? '异常': '正常')}}
  74. <image :src="item.open? '../../static/img/downup.png': '../../static/img/downxia.png' " mode="">
  75. </image>
  76. </view>
  77. </view>
  78. <template v-if="item.open">
  79. <view class="info-info">
  80. <view class="base-left">
  81. <view class="left-wrap" style="height: 267rpx;" v-for="itemt in item.time_slot">
  82. <view class="">
  83. {{itemt[0]}}
  84. </view>
  85. <view class="jg">
  86. </view>
  87. <view class="">
  88. {{itemt[1]}}
  89. </view>
  90. </view>
  91. </view>
  92. <view class="base-right">
  93. <view class="right-item" v-for="(clockitem,clockindex) in item.clock"
  94. :class="{err: clockitem.timeResult != 'Normal' && clockitem.timeResult != 'wks','hui': clockitem.timeResult== 'wks'}">
  95. <view class="item-tit">
  96. {{(clockindex%2 == 0) ? '上班':'下班'}}
  97. </view>
  98. <view class="" v-if="clockitem.timeResult != 'wks'">
  99. {{showDkTime(clockitem)}}
  100. </view>
  101. </view>
  102. </view>
  103. </view>
  104. </template>
  105. </template>
  106. </scroll-view>
  107. </view>
  108. </template>
  109. <script>
  110. import dkdetailVue from './dkdetail.vue';
  111. export default {
  112. data() {
  113. return {
  114. id: '',
  115. dk_detail: {},
  116. showdate: '',
  117. height: '',
  118. list: [
  119. ]
  120. }
  121. },
  122. onLoad(opt) {
  123. if (opt.type) {
  124. this.id = this.$store.state.userInfo.staffId
  125. console.log(this.$store.state.userInfo)
  126. this.getTime()
  127. } else {
  128. this.id = opt.id
  129. this.getTime()
  130. }
  131. },
  132. onShow() {},
  133. onReachBottom() {
  134. },
  135. onReady() {
  136. var obj = this;
  137. uni.getSystemInfo({
  138. success: resu => {
  139. const query = uni.createSelectorQuery();
  140. query.select('.yg-list').boundingClientRect();
  141. query.exec(function(res) {
  142. obj.height = resu.windowHeight - res[0].top + 'px';
  143. });
  144. },
  145. fail: res => {}
  146. });
  147. },
  148. methods: {
  149. showDkTime(item) {
  150. // Normal:正常
  151. // Early:早退
  152. // Late:迟到
  153. // SeriousLate:严重迟到
  154. // Absenteeism:旷工迟到
  155. //NotSigned : 未打卡
  156. let str = ''
  157. switch (item.timeResult) {
  158. case 'NotSigned':
  159. str = '缺卡'
  160. break;
  161. case 'Normal':
  162. str = '考勤机打卡(' + item.userCheckTime.split(' ')[1] + ')(正常打卡)'
  163. break;
  164. case 'Early':
  165. str = '考勤机打卡(' + item.userCheckTime.split(' ')[1] + ')(早退)'
  166. break;
  167. case 'Late':
  168. str = '考勤机打卡(' + item.userCheckTime.split(' ')[1] + ')(迟到)'
  169. break;
  170. case 'SeriousLate':
  171. str = '考勤机打卡(' + item.userCheckTime.split(' ')[1] + ')(严重迟到)'
  172. break;
  173. case 'Absenteeism':
  174. str = '考勤机打卡(' + item.userCheckTime.split(' ')[1] + ')(旷工迟到)'
  175. break;
  176. default:
  177. str = ''
  178. // break;
  179. }
  180. return str
  181. },
  182. openDetail(item) {
  183. item.open = !item.open
  184. },
  185. getTopDetail() {
  186. this.$u.api.ExaminationDetails({
  187. staffId: this.id,
  188. month: this.showdate //选择月份
  189. }).then(({
  190. data
  191. }) => {
  192. console.log(data,'打卡详情')
  193. this.dk_detail = data
  194. })
  195. },
  196. getBtmDetail() {
  197. this.$u.api.scheduling_details({
  198. month: this.showdate,
  199. staffId: this.id,
  200. }).then(({
  201. data
  202. }) => {
  203. this.list = []
  204. console.log('拿到打卡数据', data)
  205. this.list = data.reverse().map(item => {
  206. item.open = false
  207. let dk = item.time_slot.length
  208. let dkLength = dk * 2
  209. // 没有开始打卡
  210. if (item.status == 0) {
  211. try {
  212. // console.log(item.clock.length,'item.clock.length')
  213. if (item.clock) {
  214. if (item.clock.length < dkLength) {
  215. for (let i = 0; i < dkLength; i++) {
  216. console.log('进入到了这里')
  217. if (!item.clock[i]) {
  218. item.clock[i] = {
  219. baseCheckTime: "",
  220. userCheckTime: "",
  221. timeResult: "wks"
  222. }
  223. }
  224. console.log(item.clock, 'item.clock')
  225. }
  226. }
  227. } else {
  228. item.clock = []
  229. for (let i = 0; i < dkLength; i++) {
  230. item.clock[i] = {
  231. baseCheckTime: "",
  232. userCheckTime: "",
  233. timeResult: "wks"
  234. }
  235. }
  236. }
  237. } catch (e) {
  238. //TODO handle the exception
  239. console.log(e, '错误')
  240. }
  241. }
  242. // 打卡了但是异常
  243. if (item.status == -1) {
  244. // 一天全没打卡
  245. if (!item.clock) {
  246. item.clock = []
  247. for (let i = 0; i < dkLength; i++) {
  248. item.clock[i] = {
  249. baseCheckTime: "",
  250. userCheckTime: "",
  251. timeResult: "NotSigned"
  252. }
  253. }
  254. }
  255. // 打了但没打完
  256. if (item.clock.length < dkLength) {
  257. for (let i = 0; i < dkLength; i++) {
  258. if (!item.clock[i]) {
  259. item.clock[i] = {
  260. baseCheckTime: "",
  261. userCheckTime: "",
  262. timeResult: "NotSigned"
  263. }
  264. }
  265. }
  266. }
  267. }
  268. if (item.status == 1) {
  269. }
  270. return item
  271. })
  272. // console.log(res,'data')
  273. })
  274. },
  275. // 选择年月
  276. bindDateChange(e) {
  277. let time = e.detail.value.split('-')
  278. this.showdate = time[0] + '-' + time[1]
  279. this.getTopDetail()
  280. this.getBtmDetail()
  281. },
  282. // 获取当前年月
  283. getTime() {
  284. let date = new Date()
  285. let M = (date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : ('0' + (date.getMonth() + 1))
  286. console.log(M)
  287. this.showdate = date.getFullYear() + '-' + M
  288. this.getTopDetail()
  289. this.getBtmDetail()
  290. },
  291. }
  292. }
  293. </script>
  294. <style lang="scss">
  295. .err {
  296. color: #E05742;
  297. }
  298. .hui {
  299. color: #aaa;
  300. }
  301. .select-top {
  302. width: 100%;
  303. height: 100rpx;
  304. display: flex;
  305. justify-content: space-between;
  306. align-items: center;
  307. border: 1px solid #F5F5F5;
  308. font-size: 32rpx;
  309. font-weight: bold;
  310. color: #000000;
  311. padding: 0 30rpx;
  312. background-color: #fff;
  313. .top-right {
  314. font-size: 28rpx;
  315. font-weight: bold;
  316. color: #000000;
  317. display: flex;
  318. align-items: center;
  319. justify-content: flex-end;
  320. image {
  321. width: 19rpx;
  322. height: 11rpx;
  323. }
  324. }
  325. }
  326. .dk-info {
  327. height: 326rpx;
  328. width: 100%;
  329. display: flex;
  330. flex-direction: column;
  331. justify-content: center;
  332. align-items: center;
  333. background-color: #fff;
  334. margin-bottom: 20rpx;
  335. .big {
  336. font-size: 46rpx !important;
  337. font-weight: 800;
  338. color: #000000;
  339. margin-bottom: 10rpx;
  340. }
  341. .dk-day,
  342. .dk-tit {
  343. display: flex;
  344. flex-direction: row;
  345. justify-content: center;
  346. width: 100%;
  347. font-size: 26rpx;
  348. .dk-left {
  349. width: 48%;
  350. text-align: right;
  351. }
  352. .dk-center {
  353. width: 4%;
  354. flex-shrink: 0;
  355. text-align: center;
  356. color: #D7D7D7;
  357. }
  358. .dk-right {
  359. width: 48%;
  360. }
  361. }
  362. .dk-detail {
  363. display: flex;
  364. justify-content: center;
  365. width: 100%;
  366. margin-top: 50rpx;
  367. .detail-item {
  368. width: 30%;
  369. text-align: center;
  370. font-size: 28rpx;
  371. font-weight: bold;
  372. color: #000000;
  373. .item-tit {
  374. margin-top: 15rpx;
  375. font-size: 24rpx;
  376. font-weight: 500;
  377. color: #666666;
  378. }
  379. }
  380. }
  381. }
  382. .yg-list {
  383. background-color: #fff;
  384. width: 100%;
  385. .yg-wrap {
  386. display: flex;
  387. justify-content: space-between;
  388. align-items: center;
  389. padding: 0 40rpx 0 30rpx;
  390. height: 100rpx;
  391. border-bottom: 1px solid #F2F2F2;
  392. font-size: 28rpx;
  393. font-weight: bold;
  394. color: #000000;
  395. .yg-name {}
  396. .dk-status {
  397. display: flex;
  398. align-items: center;
  399. image {
  400. width: 19rpx;
  401. height: 11rpx;
  402. margin-left: 10rpx;
  403. }
  404. }
  405. }
  406. }
  407. .info-info {
  408. width: 100%;
  409. // height: 267rpx;
  410. background-color: #f8f8f8;
  411. display: flex;
  412. .base-left {
  413. flex-shrink: 0;
  414. width: 180rpx;
  415. height: 100%;
  416. // height: 267rpx;
  417. display: flex;
  418. flex-direction: column;
  419. justify-content: center;
  420. align-items: center;
  421. font-size: 30rpx;
  422. font-weight: 800;
  423. color: #000000;
  424. .left-wrap {
  425. display: flex;
  426. flex-direction: column;
  427. justify-content: center;
  428. align-items: center;
  429. }
  430. .jg {
  431. width: 5rpx;
  432. height: 75rpx;
  433. background: #ECECEC;
  434. margin: 20rpx 0;
  435. }
  436. }
  437. .base-right {
  438. flex-grow: 1;
  439. width: 100%;
  440. .right-wrap {
  441. // height: 135rpx;
  442. }
  443. .up {
  444. border-bottom: 1px solid #E4E4E4;
  445. }
  446. .right-item {
  447. // height: 50%;
  448. height: 135rpx;
  449. padding-top: 30rpx;
  450. font-size: 26rpx;
  451. font-weight: 500;
  452. border-bottom: 1px solid #E4E4E4;
  453. &:last-of-type {
  454. border-bottom: none;
  455. }
  456. .item-tit {
  457. font-size: 30rpx;
  458. font-weight: 800;
  459. }
  460. }
  461. }
  462. }
  463. .select-time {
  464. position: absolute;
  465. top: 30rpx;
  466. right: 30rpx;
  467. font-size: 28rpx;
  468. font-weight: 500;
  469. color: #000;
  470. display: flex;
  471. align-items: center;
  472. font-weight: bold;
  473. image {
  474. width: 17rpx;
  475. margin-left: 10rpx;
  476. }
  477. }
  478. </style>