dkdetail.vue 11 KB

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