浏览代码

上下班

seimin 3 年之前
父节点
当前提交
dd1961caff
共有 4 个文件被更改,包括 216 次插入67 次删除
  1. 1 1
      src/router/index.js
  2. 16 16
      src/views/indes.vue
  3. 90 11
      src/views/my.vue
  4. 109 39
      src/views/workList.vue

+ 1 - 1
src/router/index.js

@@ -60,7 +60,7 @@ export default new Router({
60
       children: []
60
       children: []
61
     },
61
     },
62
     {
62
     {
63
-      path: '/main/workList',
63
+      path: '/main/workList/:type/:status',
64
       name: 'WorkList',
64
       name: 'WorkList',
65
       component: WorkList,
65
       component: WorkList,
66
       meta: {
66
       meta: {

+ 16 - 16
src/views/indes.vue

@@ -51,24 +51,24 @@
51
             <div>待处理</div>
51
             <div>待处理</div>
52
           </router-link>
52
           </router-link>
53
         </div>
53
         </div>
54
-        <router-link
55
-          class="attendance"
56
-          :to="{ path: '/main/workList' }"
57
-          tag="div"
58
-        >
59
-          <div class="attendanceItem">
54
+        <div class="attendance">
55
+          <router-link class="attendanceItem" :to="{ path: '/main/workList/1/0' }" tag="div">
60
             <div class="s_num">{{ newStatistics.usersCount }}</div>
56
             <div class="s_num">{{ newStatistics.usersCount }}</div>
61
-            <div>今日上班应到</div>
62
-          </div>
63
-          <div class="attendanceItem">
57
+            <div>应到</div>
58
+          </router-link>
59
+          <router-link class="attendanceItem" :to="{ path: '/main/workList/1/1' }" tag="div">
64
             <div class="s_num">{{ newStatistics.onlineCount }}</div>
60
             <div class="s_num">{{ newStatistics.onlineCount }}</div>
65
-            <div>今日上班实到</div>
66
-          </div>
67
-          <div class="attendanceItem">
68
-            <div class="s_num">{{ newStatistics.errorCount }}</div>
69
-            <div>今日迟到</div>
70
-          </div>
71
-        </router-link>
61
+            <div>实到</div>
62
+          </router-link>
63
+          <router-link class="attendanceItem" :to="{ path: '/main/workList/1/4' }" tag="div">
64
+            <div class="s_num">{{ newStatistics.unOnlineCount }}</div>
65
+            <div>未打卡</div>
66
+          </router-link>
67
+          <router-link class="attendanceItem" :to="{ path: '/main/workList/2/3' }" tag="div">
68
+            <div class="s_num">{{newStatistics.errorOfflineCount}}</div>
69
+            <div>昨日早退</div>
70
+          </router-link>
71
+        </div>
72
       </div>
72
       </div>
73
       <!-- loading -->
73
       <!-- loading -->
74
       <div
74
       <div

+ 90 - 11
src/views/my.vue

@@ -121,6 +121,7 @@
121
 let sdk = new jssdk(3, "https://wx2.zuel.edu.cn"); // 域名更换为对应环境域名, 204 更换为对应环境wid
121
 let sdk = new jssdk(3, "https://wx2.zuel.edu.cn"); // 域名更换为对应环境域名, 204 更换为对应环境wid
122
 sdk.config(0); //1表示调试模式,生产环境传0
122
 sdk.config(0); //1表示调试模式,生产环境传0
123
 import "./../../static/css/iconfont.js";
123
 import "./../../static/css/iconfont.js";
124
+import { formatDate } from "./../components/js/date.js";
124
 export default {
125
 export default {
125
   data() {
126
   data() {
126
     return {
127
     return {
@@ -139,6 +140,15 @@ export default {
139
   methods: {
140
   methods: {
140
     //获取位置,经纬度
141
     //获取位置,经纬度
141
     getLocation(online) {
142
     getLocation(online) {
143
+      // 判断是否处于微信浏览器环境
144
+      if(!(/MicroMessenger/i.test(window.navigator.userAgent))){
145
+        this.$createToast({
146
+          txt: '请前往微信中上下班',
147
+          type: 'warn',
148
+          mask: true
149
+        }).show()
150
+        return;
151
+      }
142
       let _this = this;
152
       let _this = this;
143
       this.toast = this.$createToast({
153
       this.toast = this.$createToast({
144
         time: 0,
154
         time: 0,
@@ -172,10 +182,10 @@ export default {
172
     goToWork(online, address) {
182
     goToWork(online, address) {
173
       online = online == 1 ? 0 : 1;
183
       online = online == 1 ? 0 : 1;
174
       this.$http
184
       this.$http
175
-        .post("service/auth/online", { onlion: online, address })
185
+        .post("service/auth/online", { online: online, address })
176
         .then(res => {
186
         .then(res => {
177
           this.toast.hide();
187
           this.toast.hide();
178
-          if (res.status == 200) {
188
+          if (res.data.status == 200) {
179
             this.loginUser.online = online;
189
             this.loginUser.online = online;
180
             localStorage.setItem("loginUser", JSON.stringify(this.loginUser));
190
             localStorage.setItem("loginUser", JSON.stringify(this.loginUser));
181
             const t = this.$createToast({
191
             const t = this.$createToast({
@@ -187,14 +197,58 @@ export default {
187
               t.hide();
197
               t.hide();
188
             }, 1000);
198
             }, 1000);
189
           } else {
199
           } else {
190
-            const t = this.$createToast({
191
-              type: "txt",
192
-              txt: online == 1 ? "上班失败" : "下班失败"
193
-            });
194
-            t.show();
195
-            setTimeout(() => {
196
-              t.hide();
197
-            }, 1000);
200
+             this.$createDialog({
201
+              type: 'confirm',
202
+              icon: 'cubeic-alert',
203
+              title: '提示',
204
+              content: '您现在为非下班时间,您确认要进行下班操作吗?',
205
+              confirmBtn: {
206
+                text: '确定按钮',
207
+                active: true,
208
+                disabled: false,
209
+                href: 'javascript:;'
210
+              },
211
+              cancelBtn: {
212
+                text: '取消按钮',
213
+                active: false,
214
+                disabled: false,
215
+                href: 'javascript:;'
216
+              },
217
+              onConfirm: () => {
218
+                this.toast = this.$createToast({
219
+                  time: 0,
220
+                  mask: true,
221
+                  txt: "正在加载中"
222
+                });
223
+                this.toast.show();
224
+                this.$http
225
+                .post("service/auth/online", { online: online, address, confirm:'ok' })
226
+                .then(res => {
227
+                  this.toast.hide();
228
+                  if (res.data.status == 200) {
229
+                    this.loginUser.online = online;
230
+                    localStorage.setItem("loginUser", JSON.stringify(this.loginUser));
231
+                    const t = this.$createToast({
232
+                      type: "txt",
233
+                      txt: online == 1 ? "上班成功" : "下班成功"
234
+                    });
235
+                    t.show();
236
+                    setTimeout(() => {
237
+                      t.hide();
238
+                    }, 1000);
239
+                  }else{
240
+                    const t = this.$createToast({
241
+                      type: "txt",
242
+                      txt: online == 1 ? "上班失败" : "下班失败"
243
+                    });
244
+                    t.show();
245
+                    setTimeout(() => {
246
+                      t.hide();
247
+                    }, 1000);
248
+                  }
249
+                })
250
+              },
251
+            }).show()
198
           }
252
           }
199
         });
253
         });
200
     },
254
     },
@@ -243,10 +297,35 @@ export default {
243
       this.$http
297
       this.$http
244
         .post("service/bpm/data/fetchDataList/workOnlineConfig", {"idx":0,"sum":1000})
298
         .post("service/bpm/data/fetchDataList/workOnlineConfig", {"idx":0,"sum":1000})
245
         .then((res) => {
299
         .then((res) => {
246
-          this.isWorkLoading = false;
247
           if(res.status == 200){
300
           if(res.status == 200){
248
             let userList = res.data.list[0].userList.map(v=>v.id);//用户id列表
301
             let userList = res.data.list[0].userList.map(v=>v.id);//用户id列表
249
             this.isWorkOnline = userList.includes(this.loginUser.id);
302
             this.isWorkOnline = userList.includes(this.loginUser.id);
303
+            if(this.isWorkOnline){
304
+              let now = formatDate(new Date(), "yyyy-MM-dd");
305
+              this.$http
306
+                .post("service/auth/onlineInfo/"+now, {"idx":0,"sum":1000})
307
+                .then((res) => {
308
+                  this.isWorkLoading = false;
309
+                  if(res.data.status == 200){
310
+                    console.log(res.data)
311
+                    const {unOnlineList,unOfflineList} = res.data;//上班记录未打卡,下班记录未打卡
312
+                    let unOnlineList1 = unOnlineList.map(v=>v.userId);
313
+                    let unOfflineList1 = unOfflineList.map(v=>v.userId);
314
+                    let flag1 = unOnlineList1.includes(this.loginUser.id);
315
+                    let flag2 = unOfflineList1.includes(this.loginUser.id);
316
+                    if(flag1 && flag2){
317
+                      //上班未打卡,下班未打卡
318
+                      this.isWorkOnline = true;
319
+                    }else if(!flag1 && flag2){
320
+                      //上班打卡,下班未打卡
321
+                      this.isWorkOnline = true;
322
+                    }else if(!flag1 && !flag2){
323
+                      //上班打卡,下班打卡
324
+                      this.isWorkOnline = false;
325
+                    }
326
+                  }
327
+                });
328
+            }
250
           }
329
           }
251
         });
330
         });
252
     }
331
     }

+ 109 - 39
src/views/workList.vue

@@ -2,7 +2,10 @@
2
   <div class="bgColor">
2
   <div class="bgColor">
3
     <div slot="content" class="scroll-wrapper" style="height:100%;">
3
     <div slot="content" class="scroll-wrapper" style="height:100%;">
4
       <div class="demo" style="height:100%;">
4
       <div class="demo" style="height:100%;">
5
-        <div class="header">上下班记录查看</div>
5
+        <div class="header">
6
+          <div class="nav" :class="{active:searchType1 === '1'}" @click="tapClick('1')">上班记录</div>
7
+          <div class="nav" :class="{active:searchType1 === '2'}" @click="tapClick('2')">下班记录</div>
8
+        </div>
6
         <div class="stateSearch">
9
         <div class="stateSearch">
7
           <cube-button
10
           <cube-button
8
             light
11
             light
@@ -10,12 +13,12 @@
10
             @click="showDatePicker"
13
             @click="showDatePicker"
11
             >{{ nowDate | timeFormat("MM-dd") }}<i class="cube-select-icon"></i
14
             >{{ nowDate | timeFormat("MM-dd") }}<i class="cube-select-icon"></i
12
           ></cube-button>
15
           ></cube-button>
13
-          <cube-select
16
+          <!-- <cube-select
14
             class="stateSearch_item"
17
             class="stateSearch_item"
15
             v-model="searchType1"
18
             v-model="searchType1"
16
             :options="searchsType1"
19
             :options="searchsType1"
17
             @change="stateChange1()"
20
             @change="stateChange1()"
18
-          ></cube-select>
21
+          ></cube-select> -->
19
           <cube-select
22
           <cube-select
20
             class="stateSearch_item"
23
             class="stateSearch_item"
21
             v-model="searchType2"
24
             v-model="searchType2"
@@ -30,17 +33,15 @@
30
                 <div class="head">
33
                 <div class="head">
31
                   <div class="head_d">
34
                   <div class="head_d">
32
                     <span>{{ item.userName }}</span>
35
                     <span>{{ item.userName }}</span>
33
-                    <span
34
-                      :style="{
35
-                        color: item.extra2 === '正常' ? 'green' : 'red'
36
-                      }"
37
-                      >{{ item.extra2 }}</span
38
-                    >
36
+                    <span v-if="item.opValue" :style="{
37
+                        color: (item.extra2 === '正常' && item.opValue) ? 'green' : 'red'
38
+                      }">{{ item.extra2 }}</span>
39
+                    <span style="color:red" v-if="!item.opValue">未打卡</span>
39
                     <span>{{ item.opTime }}</span>
40
                     <span>{{ item.opTime }}</span>
40
                   </div>
41
                   </div>
41
                 </div>
42
                 </div>
42
                 <div class="center">
43
                 <div class="center">
43
-                  <div>{{ item.opValue == 1 ? "上班" : "下班" }}打卡</div>
44
+                  <!-- <div>{{ item.opValue == 1 ? "上班" : "下班" }}打卡</div> -->
44
                   <div style="word-break:break-all;text-align:justify;">
45
                   <div style="word-break:break-all;text-align:justify;">
45
                     打卡地址:{{ item.extra1 || "无" }}
46
                     打卡地址:{{ item.extra1 || "无" }}
46
                   </div>
47
                   </div>
@@ -66,6 +67,8 @@ export default {
66
     return {
67
     return {
67
       items: [],
68
       items: [],
68
       itemsSave: [],
69
       itemsSave: [],
70
+      itemsSaveNoOn: [],//未打卡-上班
71
+      itemsSaveNoOff: [],//未打卡-下班
69
       wushuju: false,
72
       wushuju: false,
70
       searchsType1: [
73
       searchsType1: [
71
         {
74
         {
@@ -81,21 +84,40 @@ export default {
81
           value: "2"
84
           value: "2"
82
         }
85
         }
83
       ],
86
       ],
84
-      searchsType2: [
87
+      searchsType2: [],
88
+      searchsType2_on:[
85
         {
89
         {
86
           text: "全部",
90
           text: "全部",
87
           value: "0"
91
           value: "0"
88
         },
92
         },
89
         {
93
         {
90
-          text: "到",
94
+          text: "到",
91
           value: "1"
95
           value: "1"
92
         },
96
         },
93
         {
97
         {
94
-          text: "早退",
98
+          text: "迟到",
95
           value: "2"
99
           value: "2"
96
-        }
100
+        },
101
+        {
102
+          text: "未打卡",
103
+          value: "4"
104
+        },
105
+      ],
106
+      searchsType2_off:[
107
+        {
108
+          text: "全部",
109
+          value: "0"
110
+        },
111
+        {
112
+          text: "早退",
113
+          value: "3"
114
+        },
115
+        {
116
+          text: "未打卡",
117
+          value: "4"
118
+        },
97
       ],
119
       ],
98
-      searchType1: "0",
120
+      searchType1: '1',
99
       searchType2: "0",
121
       searchType2: "0",
100
       stateClass: "",
122
       stateClass: "",
101
       loadShow: false,
123
       loadShow: false,
@@ -112,6 +134,13 @@ export default {
112
     }
134
     }
113
   },
135
   },
114
   methods: {
136
   methods: {
137
+    // 上班记录或者下班记录
138
+    tapClick(type){
139
+      this.searchType1 = type;
140
+      this.searchType2 = '0';
141
+      this.searchsType2 = this.searchType1 === '1' ? this.searchsType2_on : this.searchsType2_off;
142
+      this.stateChange();
143
+    },
115
     showDatePicker() {
144
     showDatePicker() {
116
       if (!this.datePicker) {
145
       if (!this.datePicker) {
117
         this.datePicker = this.$createDatePicker({
146
         this.datePicker = this.$createDatePicker({
@@ -129,29 +158,45 @@ export default {
129
     },
158
     },
130
     stateChange() {
159
     stateChange() {
131
       var arr = [];
160
       var arr = [];
132
-      if (this.searchType2 === "1") {
133
-        //迟到
134
-        arr = this.itemsSave.filter(v => v.extra2 == "迟到");
135
-      } else if (this.searchType2 === "2") {
136
-        //早退
137
-        arr = this.itemsSave.filter(v => v.extra2 == "早退");
138
-      } else if (this.searchType2 === "0") {
139
-        //全部
140
-        arr = JSON.parse(JSON.stringify(this.itemsSave));
141
-      }
142
       if (this.searchType1 === "1") {
161
       if (this.searchType1 === "1") {
143
         //上班
162
         //上班
144
-        this.items = arr.filter(v => v.opValue === "1");
145
-        this.wushuju = this.items.length === 0;
163
+        arr = this.itemsSave.filter(v => v.opValue === "1");
146
       } else if (this.searchType1 === "2") {
164
       } else if (this.searchType1 === "2") {
147
         //下班
165
         //下班
148
-        this.items = arr.filter(v => v.opValue === "0");
149
-        this.wushuju = this.items.length === 0;
166
+        arr = this.itemsSave.filter(v => v.opValue === "0");
150
       } else if (this.searchType1 === "0") {
167
       } else if (this.searchType1 === "0") {
151
         //全部
168
         //全部
152
-        this.items = arr;
153
-        this.wushuju = this.items.length === 0;
169
+        arr = JSON.parse(JSON.stringify(this.itemsSave));
154
       }
170
       }
171
+      if (this.searchType2 === "1") {
172
+        //实到
173
+        this.items = arr.filter(v => v.extra2 == "正常");
174
+      } else if (this.searchType2 === "2") {
175
+        //迟到
176
+        this.items = arr.filter(v => v.extra2 == "迟到");
177
+      } else if (this.searchType2 === "3") {
178
+        //早退
179
+        this.items = arr.filter(v => v.extra2 == "早退");
180
+      } else if (this.searchType2 === "4") {
181
+        //未打卡
182
+        if(this.searchType1 === '1'){
183
+          // 上班
184
+          this.items = JSON.parse(JSON.stringify(this.itemsSaveNoOn));
185
+        }else if(this.searchType1 === '2'){
186
+          // 下班
187
+          this.items = JSON.parse(JSON.stringify(this.itemsSaveNoOff));
188
+        }
189
+      } else if (this.searchType2 === "0") {
190
+        //全部
191
+        if(this.searchType1 === '1'){
192
+          // 上班
193
+          this.items = JSON.parse(JSON.stringify(arr.concat(this.itemsSaveNoOn)));
194
+        }else if(this.searchType1 === '2'){
195
+          // 下班
196
+          this.items = JSON.parse(JSON.stringify(arr.concat(this.itemsSaveNoOff)));
197
+        }
198
+      }
199
+      this.wushuju = this.items.length === 0;
155
     },
200
     },
156
     stateChange1() {
201
     stateChange1() {
157
       this.stateChange();
202
       this.stateChange();
@@ -173,10 +218,14 @@ export default {
173
           }
218
           }
174
           // this.items = res.data.data;
219
           // this.items = res.data.data;
175
           this.itemsSave = JSON.parse(JSON.stringify(res.data.data));
220
           this.itemsSave = JSON.parse(JSON.stringify(res.data.data));
221
+          this.itemsSaveNoOn = res.data.unOnlineList?JSON.parse(JSON.stringify(res.data.unOnlineList)):[];
222
+          this.itemsSaveNoOff = res.data.unOnlineList?JSON.parse(JSON.stringify(res.data.unOfflineList)):[];
176
           this.stateChange();
223
           this.stateChange();
177
         } else if (res.data.data.length === 0) {
224
         } else if (res.data.data.length === 0) {
178
           this.items = [];
225
           this.items = [];
179
           this.itemsSave = [];
226
           this.itemsSave = [];
227
+          this.itemsSaveNoOn = [];
228
+          this.itemsSaveNoOff = [];
180
           this.wushuju = true;
229
           this.wushuju = true;
181
         }
230
         }
182
         this.loadShow = false;
231
         this.loadShow = false;
@@ -184,17 +233,26 @@ export default {
184
     }
233
     }
185
   },
234
   },
186
   created() {
235
   created() {
236
+    console.log(this.$route)
237
+    const { type, status } = this.$route.params;//type是上班1还是下班2,status是具体的状态
238
+    this.searchType1 = type;
239
+    this.searchType2 = status;
240
+    if(status === '3'){
241
+      // 昨日早退
242
+      this.nowDate = new Date(new Date().getTime() - 24*60*60*1000);
243
+    }
244
+    this.searchsType2 = this.searchType1 === '1' ? this.searchsType2_on : this.searchsType2_off;
187
     this.getData();
245
     this.getData();
188
   }
246
   }
189
 };
247
 };
190
 </script>
248
 </script>
191
 <style lang="stylus" rel="stylesheet/stylus" scoped>
249
 <style lang="stylus" rel="stylesheet/stylus" scoped>
192
 .scroll-list-wrap {
250
 .scroll-list-wrap {
193
-  height: calc(100% - 1.76rem);
251
+  height: calc(100% - 1.81rem);
194
   border-radius: 5px;
252
   border-radius: 5px;
195
   transform: rotate(0deg); // fix 子元素超出边框圆角部分不隐藏的问题
253
   transform: rotate(0deg); // fix 子元素超出边框圆角部分不隐藏的问题
196
   overflow: hidden;
254
   overflow: hidden;
197
-  padding-top: 1.76rem;
255
+  padding-top: 1.81rem;
198
 }
256
 }
199
 
257
 
200
 .foods-wrapper {
258
 .foods-wrapper {
@@ -298,9 +356,6 @@ export default {
298
 .cont {
356
 .cont {
299
   margin-top: 1.86rem;
357
   margin-top: 1.86rem;
300
 }
358
 }
301
-.scroll-list-wrap {
302
-  padding-top: 1.76rem;
303
-}
304
 .header {
359
 .header {
305
   width: 100%;
360
   width: 100%;
306
   height: 0.88rem;
361
   height: 0.88rem;
@@ -308,15 +363,28 @@ export default {
308
   text-align: center;
363
   text-align: center;
309
   color: #fff;
364
   color: #fff;
310
   font-size: 0.37rem;
365
   font-size: 0.37rem;
311
-  background: linear-gradient(#2e2f32, #414246);
312
   position: fixed;
366
   position: fixed;
313
   top: 0;
367
   top: 0;
314
   z-index: 6;
368
   z-index: 6;
369
+  display: flex;
370
+  color: #2e2f32;
371
+  border-bottom: 0.05rem solid #2e2f32;
372
+}
373
+.header .nav{
374
+  flex: 1;
375
+  border-right: 0.02rem solid #2e2f32;
376
+}
377
+.header :last-child{
378
+  border-right: none;
379
+}
380
+.header .nav.active{
381
+  background: linear-gradient(#2e2f32, #414246);
382
+  color:#fff;
315
 }
383
 }
316
 .stateSearch {
384
 .stateSearch {
317
   width: 100%;
385
   width: 100%;
318
   position: fixed;
386
   position: fixed;
319
-  top: 0.88rem;
387
+  top: 0.93rem;
320
   z-index: 6;
388
   z-index: 6;
321
   display: flex;
389
   display: flex;
322
   justify-content: center;
390
   justify-content: center;
@@ -367,6 +435,9 @@ export default {
367
   color: #333333;
435
   color: #333333;
368
   background-color: #fff;
436
   background-color: #fff;
369
 }
437
 }
438
+.cube-btn{
439
+  border-top: 0.02rem solid #e5e5e5;
440
+}
370
 .title {
441
 .title {
371
   display: flex;
442
   display: flex;
372
   justify-content: space-between;
443
   justify-content: space-between;
@@ -483,7 +554,6 @@ export default {
483
     }
554
     }
484
     .center {
555
     .center {
485
       color: #333333;
556
       color: #333333;
486
-      border-bottom: 0.01rem solid #e6e6e6;
487
       div {
557
       div {
488
         padding: 0.12rem 0.48rem;
558
         padding: 0.12rem 0.48rem;
489
       }
559
       }