Baozhangchao 3 lat temu
rodzic
commit
e3d5536d95

BIN
public/images/Loading.png Wyświetl plik


+ 71
- 15
public/index.html Wyświetl plik

@@ -1,17 +1,73 @@
1 1
 <!DOCTYPE html>
2 2
 <html lang="">
3
-  <head>
4
-    <meta charset="utf-8">
5
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
7
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
8
-    <title><%= htmlWebpackPlugin.options.title %></title>
9
-  </head>
10
-  <body>
11
-    <noscript>
12
-      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13
-    </noscript>
14
-    <div id="app"></div>
15
-    <!-- built files will be auto injected -->
16
-  </body>
17
-</html>
3
+
4
+<head>
5
+  <meta charset="utf-8">
6
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
7
+  <meta name="viewport" content="width=device-width,initial-scale=1.0">
8
+  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
9
+  <title>
10
+    <%= htmlWebpackPlugin.options.title %>
11
+  </title>
12
+  <style>
13
+    .page-loading-wrapper {
14
+      position: absolute;
15
+      left: 0;
16
+      top: 0;
17
+      width: 100vw;
18
+      height: 100vh;
19
+      overflow: hidden;
20
+      z-index: 999;
21
+      /* background: url(./images/loadingBgc.jpg) no-repeat 100% 100%; */
22
+      display: flex;
23
+      /* display: none; */
24
+      justify-content: center;
25
+      align-items: center;
26
+    }
27
+
28
+    .page-loading {
29
+      width: 100vw;
30
+      /* height: 100vw; */
31
+    }
32
+
33
+    .page-loading .loading-image {
34
+      width: 25vw;
35
+      height: 25vw;
36
+      animation: loadingrotate 4.5s linear infinite;
37
+      margin: auto;
38
+    }
39
+
40
+    .page-loading .loading-tips {
41
+      width: 100%;
42
+      margin-top: 2em;
43
+    }
44
+
45
+    @keyframes loadingrotate {
46
+      100% {
47
+        transform: rotate(360deg);
48
+      }
49
+    }
50
+  </style>
51
+</head>
52
+
53
+<body>
54
+  <noscript>
55
+    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
56
+        Please enable it to continue.</strong>
57
+  </noscript>
58
+
59
+  <div class="page-loading-wrapper">
60
+    <div class="page-loading">
61
+      <div class="loading-image">
62
+        <img src="./images/Loading.png" width="100%" alt="">
63
+      </div>
64
+      <!-- <div class="loading-tips">
65
+        <img src="./images/Loading.png" width="100%" alt="">
66
+      </div> -->
67
+    </div>
68
+  </div>
69
+  <div id="app"></div>
70
+  <!-- built files will be auto injected -->
71
+</body>
72
+
73
+</html>

+ 10
- 0
public/js/vconsole.min.js
Plik diff jest za duży
Wyświetl plik


+ 4
- 0
src/App.vue Wyświetl plik

@@ -7,6 +7,7 @@
7 7
 
8 8
 <script>
9 9
 import { UserLogin } from './util/api'
10
+import { mapState } from 'vuex'
10 11
 
11 12
 import Tabber from './components/Tabber.vue'
12 13
 
@@ -15,6 +16,9 @@ export default {
15 16
   components: {
16 17
     Tabber
17 18
   },
19
+  computed: {
20
+    ...mapState(['LOADING'])
21
+  },
18 22
   mounted() {
19 23
     // this.onLogin()
20 24
   },

BIN
src/assets/Collection/off.png Wyświetl plik


BIN
src/assets/Collection/on.png Wyświetl plik


+ 112
- 0
src/components/ClassInfo.vue Wyświetl plik

@@ -0,0 +1,112 @@
1
+<template>
2
+  <div class="class-box">
3
+    <img width="100%" height="200vh" :src="ClassContent.thumb" alt />
4
+    <div class="class-box-body">
5
+      <div class="class-box-body-top">
6
+        <div class="class-box-body-top-title">{{ClassContent.title}}</div>
7
+        <div class="class-box-body-top-Info">
8
+          <div
9
+            class="class-box-body-top-Info-Time"
10
+          >课程时间:{{parseTime(ClassContent.startDate,'{m}月{d}日 {h}:{i}')}}~{{parseTime(ClassContent.endDate,'{m}月{d}日 {h}:{i}')}}</div>
11
+          <div class="class-box-body-top-Info-Shoucang">
12
+            <img src="../assets/Collection/off.png" alt />
13
+            <span>已收藏</span>
14
+          </div>
15
+        </div>
16
+      </div>
17
+      <div class="class-box-body-box">
18
+        <div>{{ClassContent.subTitle}}</div>
19
+        <img :src="ClassContent.content" alt />
20
+      </div>
21
+    </div>
22
+  </div>
23
+</template>
24
+
25
+<script>
26
+import { getCourseInfof } from '../util/api'
27
+import { parseTime, SignInTime } from '../util/formattingData'
28
+
29
+export default {
30
+  data() {
31
+    return {
32
+      ClassContent: null
33
+    }
34
+  },
35
+  mounted() {
36
+    this.onloadClass()
37
+  },
38
+  methods: {
39
+    parseTime,
40
+    onloadClass() {
41
+      getCourseInfof(this.$route.params.courseId).then((e) => {
42
+        this.ClassContent = e
43
+        console.log(e)
44
+      })
45
+    }
46
+  }
47
+}
48
+</script>
49
+
50
+<style lang="less" scoped>
51
+.class-box {
52
+  width: 100vw;
53
+  height: 100%;
54
+  &-body {
55
+    width: 99%;
56
+    border: 1px solid red;
57
+    border-radius: 30px;
58
+    background-color: #fff;
59
+    position: absolute;
60
+    top: 26vh;
61
+    height: 68vh;
62
+    &-top {
63
+      width: 100%;
64
+      height: 10vh;
65
+
66
+      &-title {
67
+        padding: 10px 20px 8px 20px;
68
+        width: 70%;
69
+        font-size: 14px;
70
+        font-weight: 700;
71
+      }
72
+      &-Info {
73
+        padding: 0px 20px;
74
+
75
+        display: flex;
76
+        align-items: center;
77
+        justify-content: space-between;
78
+
79
+        &-Time {
80
+          font-size: 8px;
81
+          color: #999;
82
+        }
83
+        &-Shoucang {
84
+          display: flex;
85
+          align-items: center;
86
+
87
+          > img {
88
+            width: 18px;
89
+            padding-right: 5px;
90
+          }
91
+          & > span {
92
+            font-size: 10px;
93
+          }
94
+        }
95
+      }
96
+    }
97
+    &-box {
98
+      margin: 0 auto;
99
+      box-shadow: 0 0 15px rgb(214, 214, 214);
100
+      min-height: 67vh;
101
+      border-radius: 30px;
102
+      background-color: #fff;
103
+      position: absolute;
104
+      top: 13vh;
105
+      padding: 1.5em;
106
+      > img {
107
+        width: 100%;
108
+      }
109
+    }
110
+  }
111
+}
112
+</style>

+ 0
- 101
src/components/ClockIn.vue Wyświetl plik

@@ -1,101 +0,0 @@
1
-<template>
2
-  <div class="Clockln-box">
3
-    <div class="box1">
4
-      <img src="https://static.zcool.cn/git_z/z/images/girl.png" alt />
5
-      <div class="box1-title">2022年度上半年第一期架空线路工程培训课程</div>
6
-      <div class="box1-time">课程时间</div>
7
-      <div class="box1-time">2022年2月21日9:00-11:00</div>
8
-    </div>
9
-    <div class="myDIV">
10
-      <div>上课打卡</div>
11
-      <span>24:00:00</span>
12
-    </div>
13
-
14
-    <img src="../assets/basemap.png" alt width="100%" />
15
-  </div>
16
-</template>
17
-
18
-<script>
19
-export default {}
20
-</script>
21
-
22
-<style lang="less" scoped>
23
-.Clockln-box {
24
-  background-color: #fff;
25
-  height: 100%;
26
-  width: 100vw;
27
-  .box1 {
28
-    width: 100%;
29
-    > img {
30
-      width: 80px;
31
-      border-radius: 50%;
32
-      margin: 0 auto;
33
-      display: block;
34
-      padding: 35px 0 20px 0;
35
-    }
36
-    &-title {
37
-      width: 90%;
38
-      margin: 0 auto;
39
-      text-align: center;
40
-      color: #000;
41
-      font-size: 17px;
42
-      font-weight: 700;
43
-      margin-bottom: 30px;
44
-    }
45
-    &-time {
46
-      width: 90%;
47
-      margin: 0 auto;
48
-      text-align: center;
49
-      color: rgb(133, 133, 133);
50
-      font-size: 13px;
51
-      line-height: 26px;
52
-      letter-spacing: 2px;
53
-    }
54
-  }
55
-  .myDIV {
56
-    margin: 6vh auto auto auto;
57
-    width: 140px;
58
-    height: 140px;
59
-    // margin: 0 auto;
60
-    border-radius: 100%;
61
-    background-color: #42a9aa;
62
-    display: flex;
63
-    animation: qiandao 3s infinite;
64
-    flex-direction: column;
65
-    justify-content: center;
66
-    text-align: center;
67
-    > div {
68
-      width: 100%;
69
-      margin: 0 auto;
70
-      color: white;
71
-      font-size: 19px;
72
-      margin-bottom: 10px;
73
-      font-weight: 600;
74
-    }
75
-
76
-    > span {
77
-      color: white;
78
-      display: block;
79
-      font-size: 15px;
80
-    }
81
-  }
82
-  > img {
83
-    position: fixed;
84
-    bottom: 7vh;
85
-  }
86
-}
87
-
88
-@keyframes qiandao {
89
-  0% {
90
-    box-shadow: 0 0 10px #0d888a;
91
-  }
92
-
93
-  50% {
94
-    box-shadow: 0 0 20px #7bdadb;
95
-  }
96
-
97
-  100% {
98
-    box-shadow: 0 0 10px #0d888a;
99
-  }
100
-}
101
-</style>

+ 85
- 37
src/components/Course.vue Wyświetl plik

@@ -1,62 +1,104 @@
1 1
 <template>
2 2
   <div class="Course-box">
3
-    <div>
3
+    <div style="banner-box-top">
4 4
       <van-swipe :autoplay="3000">
5 5
         <van-swipe-item v-for="(image, index) in HomeBannerImages" :key="index">
6
-          <van-image width="100%" height="25vh" :src="image.thumb" />
6
+          <van-image width="100%" height="100%" :src="image.thumb" />
7 7
         </van-swipe-item>
8 8
       </van-swipe>
9 9
     </div>
10 10
     <!-- list -->
11
-    <div class="Card-box">
12
-      <div class="Card-box-top">
13
-        <img
14
-          src="https://iknow-pic.cdn.bcebos.com/5ab5c9ea15ce36d316933f0437f33a87e950b16b?x-bce-process%3Dimage%2Fresize%2Cm_lfit%2Cw_600%2Ch_800%2Climit_1%2Fquality%2Cq_85%2Fformat%2Cf_jpg"
15
-          alt
16
-        />
17
-        <div class="Card-box-top-box">
18
-          <div class="Card-box-top-title">2022年度上半年第一期架空线路工程培训课程</div>
19
-          <div class="Card-box-top-time">课程时间:2022年2月21日9:00-11:00</div>
11
+    <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
12
+      <div class="Card-box" v-for="(item, index) in courseList" :key="index">
13
+        <!-- <van-cell v-for="item in list" :key="item" :title="item" /> -->
14
+        <div>
15
+          <div class="Card-box-top">
16
+            <img :src="item.content" alt />
17
+            <div class="Card-box-top-box">
18
+              <div class="Card-box-top-title">{{item.title}}</div>
19
+              <div
20
+                class="Card-box-top-time"
21
+              >课程时间:{{parseTime(item.startDate, '{m}月{d}日 {h}:{i}')}}~{{parseTime(item.endDate, '{m}月{d}日 {h}:{i}')}}</div>
22
+            </div>
23
+          </div>
24
+          <div class="Card-box-botton" @click="goQuestion(item.courseId)">
25
+            <div>查看详情</div>
26
+            <van-icon name="arrow" />
27
+          </div>
20 28
         </div>
21 29
       </div>
22
-      <div class="Card-box-botton">
23
-        <div>查看详情</div>
24
-        <van-icon name="arrow" />
25
-      </div>
26
-    </div>
30
+    </van-list>
27 31
   </div>
28 32
 </template>
29 33
 
30 34
 <script>
31
-import { getBanner } from '../util/api'
35
+import { parseTime } from '../util/formattingData'
36
+
37
+import { getBanner, getCourse } from '../util/api'
32 38
 export default {
33 39
   data() {
34 40
     return {
35 41
       icon: require('../assets/icon/courseIcon.svg'),
36
-      courseList: [
37
-        { name: '课程阿斯达四方' },
38
-        { name: 'dgdgdgdfgfds' },
39
-        { name: '啊飒飒的给' },
40
-        { name: '昂贵的法国电视公司提供' },
41
-        { name: '认同感他如果' },
42
-        { name: '课程阿斯好友和用户运营达四方' },
43
-        { name: '毛概' }
44
-      ],
42
+      loading: false,
43
+      finished: true,
44
+      currentPage: 1,
45
+      pageSize: 10,
46
+      courseList: [],
45 47
       HomeBannerImages: []
46 48
     }
47 49
   },
48 50
   mounted() {
49 51
     this.onBanner()
52
+    this.kecheng()
50 53
   },
54
+
51 55
   methods: {
52
-    goQuestion() {
53
-      this.$router.push('/ClockIn')
56
+    goQuestion(courseId) {
57
+      this.$router.push({ name: 'ClassInfo', params: { courseId: courseId } })
58
+      // this.$router.push('/signIn')
59
+    },
60
+    parseTime, //时间格式化
61
+
62
+    kecheng() {
63
+      getCourse().then((e) => {
64
+        // console.log(parseTime(aTime, '{y}年{m}月{d}日 {h}:{i}'))
65
+
66
+        this.courseList = e.records
67
+      })
54 68
     },
55 69
     onBanner() {
56 70
       getBanner('Training').then((e) => {
57 71
         this.HomeBannerImages = e.records
72
+
58 73
         console.log(e)
59 74
       })
75
+    },
76
+    onLoad() {
77
+      // 异步更新数据
78
+      let params = {
79
+        // type: this.selectedType,
80
+        index: this.currentPage, //页数
81
+        size: this.pageSize //每页个数
82
+      }
83
+      xxxxxxx(params).then((res) => {
84
+        console.log(res)
85
+        this.dataTotal = res.total
86
+        //进行判断
87
+        if (this.dataTotal <= this.pageSize) {
88
+          this.Array = res.data.list
89
+          console.log(this.Array)
90
+        } else {
91
+          this.currentPage++
92
+          let arr = res.data.data.list
93
+          this.Array = this.Array.concat(arr)
94
+        }
95
+        // 加载状态结束
96
+        this.loading = false
97
+        // 数据全部加载完成
98
+        if (this.Array.length >= this.dataTotal) {
99
+          this.finished = true //结束,显示我也是有底线的
100
+        }
101
+      })
60 102
     }
61 103
   }
62 104
 }
@@ -65,11 +107,14 @@ export default {
65 107
 <style lang="less" scoped>
66 108
 .Course-box {
67 109
   width: 100vw;
110
+
68 111
   .van-swipe {
69
-    width: 100%;
70
-    border-radius: 20px;
112
+    width: 95%;
113
+    border-radius: 10px;
114
+    margin: 10px auto;
115
+    box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.2);
71 116
 
72
-    height: 25vh;
117
+    height: 33vh;
73 118
     .van-swipe-item {
74 119
     }
75 120
   }
@@ -79,16 +124,18 @@ export default {
79 124
 
80 125
   .Card-box {
81 126
     width: 95%;
82
-    border-radius: 15px;
127
+    border-radius: 10px;
83 128
     background-color: #fff;
84
-    margin: 2.4em auto 1em auto;
129
+    margin: 1.8em auto 1em auto;
85 130
     box-shadow: 0 0 15px rgb(214, 214, 214);
86 131
 
87 132
     .Card-box-top {
88 133
       display: flex;
89 134
       align-items: center;
135
+      padding: 0.8em 0 0.6em 0.4em;
90 136
       > img {
91
-        width: 20vw;
137
+        width: 65px;
138
+        height: 65px;
92 139
         border-radius: 50%;
93 140
 
94 141
         // padding: 20px;
@@ -101,12 +148,12 @@ export default {
101 148
         font-size: 16px;
102 149
         font-weight: 700;
103 150
         letter-spacing: 1px;
104
-        padding: 10px;
151
+        padding: 0 0 12px 10px;
105 152
       }
106 153
       &-time {
107
-        font-size: 14px;
154
+        font-size: 12px;
108 155
         color: rgb(133, 133, 133);
109
-        padding: 0px 0 10px 10px;
156
+        padding: 0px 0 0px 10px;
110 157
       }
111 158
     }
112 159
     .Card-box-botton {
@@ -116,6 +163,7 @@ export default {
116 163
       display: flex;
117 164
       color: rgb(133, 133, 133);
118 165
       justify-content: space-between;
166
+      font-size: 10px;
119 167
 
120 168
       > div {
121 169
         padding: 10px 0 10px 0;

+ 26
- 0
src/components/MyCollection.vue Wyświetl plik

@@ -0,0 +1,26 @@
1
+<template>
2
+  <h1>2</h1>
3
+</template>
4
+
5
+<script>
6
+import { getCollection, deleteCollection } from '../util/api'
7
+
8
+export default {
9
+  data() {
10
+    return {}
11
+  },
12
+  mounted() {
13
+    this.onLoadCollertion()
14
+  },
15
+  methods: {
16
+    onLoadCollertion() {
17
+      getCollection().then((e) => {
18
+        console.log('收藏列表', e)
19
+      })
20
+    }
21
+  }
22
+}
23
+</script>
24
+
25
+<style lang="less" scoped>
26
+</style>

+ 7
- 4
src/components/StrongPhoto.vue Wyświetl plik

@@ -4,7 +4,7 @@
4 4
     <div>
5 5
       <van-swipe :autoplay="3000">
6 6
         <van-swipe-item v-for="(image, index) in photoBannerImages" :key="index">
7
-          <van-image width="100%" height="25vh" :src="image.thumb" />
7
+          <van-image width="100%" height="100%" :src="image.thumb" />
8 8
         </van-swipe-item>
9 9
       </van-swipe>
10 10
     </div>
@@ -109,9 +109,12 @@ export default {
109 109
   height: 100%;
110 110
   background-color: #fff;
111 111
   .van-swipe {
112
-    width: 100%;
113
-    border-radius: 20px;
114
-    height: 25vh;
112
+    width: 95%;
113
+    border-radius: 10px;
114
+    margin: 10px auto;
115
+    box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.2);
116
+
117
+    height: 33vh;
115 118
   }
116 119
   .Zhedie-box {
117 120
     width: 90%;

+ 2
- 0
src/components/Tabber.vue Wyświetl plik

@@ -23,6 +23,8 @@ export default {
23 23
   created() {
24 24
     //由于 vant 标签栏路由模式,无法自动加载页面,所以这里需要初始化
25 25
     console.log(this.$route) //打印当前路由属性
26
+    this.active = 0
27
+
26 28
     switch (this.$route.name) {
27 29
       case 'Course':
28 30
         this.active = 0

+ 103
- 28
src/components/UserCenter.vue Wyświetl plik

@@ -1,26 +1,37 @@
1 1
 <template>
2 2
   <div class="User-box">
3 3
     <!-- <h1>UserCenter 个人中心</h1> -->
4
+    <img class="User-box-backImage" src="../assets/userImag/backImag.png" />
4 5
     <div class="user-info">
5
-      <img src="../assets/userImag/userImag.jpg" />
6
-      <div class="info-name">
6
+      <img src="../assets/userImag/userImag.jpg" v-show="divShow" />
7
+      <div class="info-name" v-show="divShow">
7 8
         <div>
8 9
           <span>{{name}}</span>
9 10
         </div>
10 11
         <div>
11
-          <span>{{phone}}</span>
12
+          <span style="font-weight: 100;">{{phone}}</span>
12 13
         </div>
14
+        <div class="userInfo-button">一期架空线路工1班</div>
13 15
       </div>
14
-      <van-icon name="arrow" @click="handLogin()" />
15
-    </div>
16 16
 
17
+      <div v-show="buttonShow" class="userInfo-button-zhuce" @click="seeUserInfo()">注册</div>
18
+    </div>
17 19
     <div class="button-box">
18
-      <van-cell-group>
19
-        <img :src="register" alt width="25px" style=" margin: 0 0 0 10px;" />
20
-        <van-cell class="user-button" title="注册" @click="handLogin()" is-link />
21
-      </van-cell-group>
22
-      <!-- <button type="primary" @click="handLogin()">微信授权登录</button> -->
23
-      <!-- <van-button class="user-button" type="info" @click="handLogin()">注册</van-button> -->
20
+      <div class="button-box-div" @click="seeUserInfo()">
21
+        <img src="../assets/userImag/userInfo.png" alt />
22
+        <div>我的信息</div>
23
+        <van-icon name="arrow" />
24
+      </div>
25
+      <div class="button-box-div" @click="goMyCollection">
26
+        <img src="../assets/userImag/shoucang.png" alt />
27
+        <div>我的收藏</div>
28
+        <van-icon name="arrow" />
29
+      </div>
30
+      <div class="button-box-div">
31
+        <img src="../assets/userImag/wenjuan.png" alt />
32
+        <div>我的问卷</div>
33
+        <van-icon name="arrow" />
34
+      </div>
24 35
     </div>
25 36
   </div>
26 37
 </template>
@@ -32,18 +43,32 @@ export default {
32 43
     return {
33 44
       register: require('../assets/icon/register.svg'),
34 45
       name: '',
35
-      phone: ''
46
+      phone: '',
47
+      divShow: false,
48
+      buttonShow: true
36 49
     }
37 50
   },
38 51
   mounted() {
39 52
     this.name = this.$store.state.user.name
40 53
     this.phone = this.$store.state.user.phone
54
+    if (this.$store.state.user.phone) {
55
+      this.divShow = true
56
+      this.buttonShow = false
57
+    } else {
58
+      this.divShow = false
59
+      this.buttonShow = true
60
+    }
41 61
   },
42 62
   methods: {
43
-    handLogin() {
63
+    seeUserInfo() {
44 64
       this.$router.push('/SetUser')
45 65
       // this.$store.commit('SET_USER_INFO', { code: this.code })
46 66
     },
67
+    goMyCollection() {
68
+      this.$router.push('/MyCollection')
69
+
70
+      // this.$store.commit('SET_USER_INFO', { code: this.code })
71
+    },
47 72
 
48 73
     handGetUserInfo() {}
49 74
   }
@@ -54,48 +79,98 @@ export default {
54 79
 .User-box {
55 80
   width: 100%;
56 81
   height: 100%;
82
+  background-color: #fff;
83
+
84
+  &-backImage {
85
+    width: 100%;
86
+  }
57 87
   .user-info {
58
-    background-color: #fff;
59 88
     margin-bottom: 10px;
60 89
     display: flex;
61 90
     height: 20%;
62 91
     padding-left: 24px;
92
+    position: relative;
93
+    top: -25vh;
63 94
     > img {
64 95
       width: 70px;
65 96
       height: 70px;
66 97
       border-radius: 50%;
67 98
       position: relative;
68 99
       top: 5vh;
100
+      box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.2);
69 101
     }
70 102
     .info-name {
103
+      font-weight: 600;
104
+      top: 5vh;
105
+      left: 6vw;
71 106
       position: relative;
72 107
       font-size: 17px;
73 108
       height: 20%;
74
-      font-weight: 700;
75
-      top: 5vh;
76
-      left: 6vw;
77 109
       > div {
78 110
         margin-top: 10px;
111
+        color: #fff;
112
+      }
113
+      .userInfo-button {
114
+        // border: 1px solid red;
115
+        width: 120px;
116
+        color: rgb(255, 255, 255);
117
+        font-weight: 100;
118
+        border-top-left-radius: 20px; /* 左上角 */
119
+        border-bottom-left-radius: 20px; /* 左下角 */
120
+        position: absolute;
121
+        padding: 8px 0;
122
+        right: -41vw;
123
+        top: 0vh;
124
+        font-size: 5px;
125
+        text-align: center;
126
+        background-color: #2cb698;
79 127
       }
80 128
     }
81
-    .van-icon {
82
-      height: 55px;
83
-      width: 30px;
84
-      margin: 0 auto;
129
+    .userInfo-button-zhuce {
130
+      width: 80px;
131
+      letter-spacing: 4px;
85 132
       position: relative;
86
-      left: 18.4vw;
87
-      top: 7.7vh;
88
-      // position: relative;
89
-      // top: 9vh;
133
+      top: 5vh;
134
+      text-align: center;
135
+      color: #fff;
136
+      font-weight: 700;
137
+      margin: 0 auto;
138
+      border-radius: 20px;
139
+      line-height: 30px;
140
+      height: 30px;
141
+      background-color: #2cb798;
90 142
     }
91 143
   }
92 144
   .button-box {
93
-    width: 100%;
145
+    width: 90%;
146
+    border-radius: 20px;
94 147
     margin: 0 auto;
95
-    // box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
148
+    box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
149
+    background-color: #fff;
150
+
151
+    height: 80vh;
152
+    position: relative;
153
+    top: -28vh;
154
+    display: flex;
155
+
156
+    flex-direction: column;
96 157
 
97
-    .van-cell-group {
158
+    &-div {
98 159
       display: flex;
160
+      margin: 20px auto;
161
+
162
+      width: 80%;
163
+      padding-bottom: 30px;
164
+      align-items: center;
165
+      border-bottom: 1px solid rgb(235, 235, 235);
166
+      > img {
167
+        width: 22px;
168
+        margin-right: 2em;
169
+      }
170
+      .van-icon {
171
+        position: absolute;
172
+        right: 20px;
173
+      }
99 174
     }
100 175
   }
101 176
 }

+ 181
- 0
src/components/signIn.vue Wyświetl plik

@@ -0,0 +1,181 @@
1
+<template>
2
+  <div class="Clockln-box">
3
+    <div class="box1">
4
+      <img src="../assets/userImag/userImag.jpg" alt />
5
+      <div class="box1-title">{{title}}</div>
6
+      <div class="box1-time">签到结束时间</div>
7
+      <div class="box1-time">{{parseTime(endTime, '{y}年{m}月{d}日 {h}:{i}')}}</div>
8
+    </div>
9
+    <div :class="{'myDIV':true, 'disabled':ok}" @click="goSign">
10
+      <div>上课打卡</div>
11
+      <span>{{SignInTime(nowTime)}}</span>
12
+    </div>
13
+
14
+    <img src="../assets/basemap.png" alt width="100%" />
15
+  </div>
16
+</template>
17
+
18
+<script>
19
+import { getSignInInfof, getSignIn } from '../util/api'
20
+import query from '../util/query'
21
+import { parseTime, SignInTime } from '../util/formattingData'
22
+export default {
23
+  data() {
24
+    return {
25
+      signId: '',
26
+      phone: '',
27
+      ok: false,
28
+      endTime: '',
29
+      title: '',
30
+      nowTime: new Date()
31
+    }
32
+  },
33
+  mounted() {
34
+    this.signId = query('signId')
35
+    this.phone = this.$store.state.user.phone
36
+
37
+    this.onLoadSinInO()
38
+    let that = this
39
+    this.timer = setInterval(function () {
40
+      that.nowTime = new Date().toLocaleString()
41
+    })
42
+  },
43
+  //离开当前页面后执行
44
+  destroyed: function () {
45
+    // 销毁时清除计时器
46
+    this.beforeDestroy()
47
+  },
48
+  methods: {
49
+    SignInTime,
50
+    parseTime,
51
+    // 销毁时清除计时器
52
+    beforeDestroy: function () {
53
+      console.log('销毁时清除计时器')
54
+      if (this.timer) {
55
+        clearInterval(this.timer)
56
+      }
57
+    },
58
+    //首先判断他有没有资格
59
+    //  this.$toast.success('修改成功!')
60
+    onLoadSinInO() {
61
+      getSignInInfof().then((e) => {
62
+        const { canSign, endTime, startTime, isSigned, name } = e
63
+        this.endTime = endTime
64
+        this.title = name
65
+
66
+        let starDtat = new Date(startTime) - new Date()
67
+        let endDtat = new Date(endTime) - new Date()
68
+
69
+        if (this.phone) {
70
+          if (canSign) {
71
+            if (starDtat < 0) {
72
+              if (endDtat < 0) {
73
+                if (!isSigned) {
74
+                  this.ok = true
75
+                } else {
76
+                  this.$toast.fail('您已签到过')
77
+                }
78
+              }
79
+            } else {
80
+              this.$toast.fail('未到签到时间')
81
+            }
82
+          }
83
+        } else {
84
+          this.$toast.fail('请维护手机号')
85
+        }
86
+      })
87
+    },
88
+    goSign() {
89
+      getSignIn().then((e) => {
90
+        console.log(e)
91
+        this.$toast('签到成功')
92
+      })
93
+    }
94
+  }
95
+}
96
+</script>
97
+
98
+<style lang="less" scoped>
99
+.Clockln-box {
100
+  background-color: #fff;
101
+  height: 100%;
102
+  width: 100vw;
103
+  .box1 {
104
+    width: 100%;
105
+    > img {
106
+      width: 80px;
107
+      border-radius: 50%;
108
+      margin: 0 auto;
109
+      display: block;
110
+      padding: 35px 0 20px 0;
111
+    }
112
+    &-title {
113
+      width: 90%;
114
+      margin: 0 auto;
115
+      text-align: center;
116
+      color: #000;
117
+      font-size: 17px;
118
+      font-weight: 700;
119
+      margin-bottom: 30px;
120
+    }
121
+    &-time {
122
+      width: 90%;
123
+      margin: 0 auto;
124
+      text-align: center;
125
+      color: rgb(133, 133, 133);
126
+      font-size: 13px;
127
+      line-height: 26px;
128
+      letter-spacing: 2px;
129
+    }
130
+  }
131
+  .myDIV {
132
+    margin: 6vh auto auto auto;
133
+    width: 140px;
134
+    height: 140px;
135
+    // margin: 0 auto;
136
+    border-radius: 100%;
137
+    background-color: #42a9aa;
138
+    display: flex;
139
+    animation: qiandao 3s infinite;
140
+    flex-direction: column;
141
+    justify-content: center;
142
+    text-align: center;
143
+    > div {
144
+      width: 100%;
145
+      margin: 0 auto;
146
+      color: white;
147
+      font-size: 19px;
148
+      margin-bottom: 10px;
149
+      font-weight: 600;
150
+    }
151
+
152
+    > span {
153
+      color: white;
154
+      display: block;
155
+      font-size: 15px;
156
+    }
157
+  }
158
+  .disabled {
159
+    pointer-events: none;
160
+    background-color: #d1d1d1ec;
161
+  }
162
+  > img {
163
+    position: fixed;
164
+    bottom: 7vh;
165
+  }
166
+}
167
+
168
+@keyframes qiandao {
169
+  0% {
170
+    box-shadow: 0 0 10px #0d888a;
171
+  }
172
+
173
+  50% {
174
+    box-shadow: 0 0 20px #7bdadb;
175
+  }
176
+
177
+  100% {
178
+    box-shadow: 0 0 10px #0d888a;
179
+  }
180
+}
181
+</style>

+ 65
- 0
src/layout/index.vue Wyświetl plik

@@ -0,0 +1,65 @@
1
+<template>
2
+  <div class="layout-container">
3
+    <!-- 子路由出口 -->
4
+    <router-view />
5
+
6
+    <!-- 底部导航栏 -->
7
+    <van-tabbar v-model="active">
8
+      <van-tabbar-item
9
+        v-for="item in tabbar"
10
+        @click="goto(item.path)"
11
+        :key="item.path"
12
+        :icon="item.icon"
13
+      >{{ item.text }}</van-tabbar-item>
14
+    </van-tabbar>
15
+  </div>
16
+</template>
17
+
18
+<script>
19
+import Vue from 'vue'
20
+import { Tabbar, TabbarItem } from 'vant'
21
+
22
+Vue.use(Tabbar)
23
+Vue.use(TabbarItem)
24
+
25
+export default {
26
+  name: 'Layout',
27
+  data() {
28
+    return {
29
+      active: 0,
30
+      tabbar: [
31
+        {
32
+          path: '/Course',
33
+          text: '培训通知',
34
+          icon: 'home-o'
35
+        },
36
+        {
37
+          path: '/StrongPhoto',
38
+          text: '精彩集锦',
39
+          icon: 'search'
40
+        },
41
+        {
42
+          path: '/UserCenter',
43
+          text: '个人中心1',
44
+          icon: 'volume-o'
45
+        }
46
+      ]
47
+    }
48
+  },
49
+  created() {
50
+    this.tabbar.map((item, idx) => {
51
+      if (item.path === this.$route.path) {
52
+        this.active = idx
53
+      }
54
+    })
55
+  },
56
+  methods: {
57
+    goto(path) {
58
+      this.$router.push(path)
59
+    }
60
+  },
61
+  components: {}
62
+}
63
+</script>
64
+<style lang="scss" scoped>
65
+</style>

+ 19
- 9
src/main.js Wyświetl plik

@@ -1,7 +1,7 @@
1 1
 import Vue from 'vue'
2 2
 import App from './App.vue'
3 3
 import animated from 'animate.css'
4
-import { Login } from './util/initial'
4
+import { Login, redirect } from './util/initial'
5 5
 
6 6
 import Questionnaire from './components/Questionnaire'
7 7
 import Loading from './components/Questionnaire/Loading.vue';
@@ -19,10 +19,14 @@ import {
19 19
   Toast,
20 20
   Card,
21 21
   NavBar,
22
-  Image, SwipeItem, Tag, Swipe, Divider, Picker, Popup
22
+  Image, SwipeItem, Tag, Swipe, Divider, Picker, Popup, List
23 23
 } from 'vant';
24
+Vue.config.productionTip = false
25
+
24 26
 Vue.use(Popup);
27
+// Vue.use(parseTime);
25 28
 Vue.use(Picker);
29
+Vue.use(List);
26 30
 Vue.use(Divider);
27 31
 Vue.use(Swipe);
28 32
 Vue.use(Tag);
@@ -45,12 +49,18 @@ Vue.use(animated)
45 49
 
46 50
 // Vue.use(Tabbar);
47 51
 // Vue.use(TabbarItem);
48
-Login()
52
+redirect()
53
+
54
+Login().then(e => {
55
+
56
+
57
+  new Vue({
58
+    router,
59
+    store,
60
+    render: h => h(App),
61
+  }).$mount('#app')
62
+
63
+})
64
+
49 65
 
50
-Vue.config.productionTip = false
51 66
 
52
-new Vue({
53
-  router,
54
-  store,
55
-  render: h => h(App),
56
-}).$mount('#app')

+ 47
- 6
src/router/index.js Wyświetl plik

@@ -2,8 +2,13 @@
2 2
 
3 3
 import Vue from 'vue'
4 4
 import Router from 'vue-router'
5
+
6
+import store from '../store'
7
+
5 8
 import Course from '../components/Course.vue'//课程
6
-import ClockIn from '../components/ClockIn.vue'//打卡
9
+import MyCollection from '../components/MyCollection.vue'//收藏
10
+import signIn from '../components/signIn.vue'//打卡
11
+import ClassInfo from '../components/ClassInfo.vue'//课堂详情
7 12
 import StrongPhoto from '../components/StrongPhoto.vue'//精彩集锦
8 13
 import UserCenter from '../components/UserCenter.vue'//我的页面
9 14
 import Questionnaire from '../components/Questionnaire.vue'
@@ -15,12 +20,14 @@ Vue.use(Router)
15 20
 
16 21
 
17 22
 
18
-export default new Router({
23
+const router = new Router({
19 24
 
20 25
   mode: "history",
21 26
 
22 27
 
23 28
   routes: [
29
+
30
+
24 31
     //培训通知
25 32
     {
26 33
       path: '/',
@@ -72,17 +79,51 @@ export default new Router({
72 79
     },
73 80
     //打卡页面
74 81
     {
75
-      path: '/ClockIn',
76
-      name: 'ClockIn',
77
-      component: ClockIn,
82
+      path: '/signIn',
83
+      name: 'signIn',
84
+      component: signIn,
78 85
       meta: {
79 86
         requireAuth: true //是否登陆
80 87
       }
81 88
     },
89
+    //课程详情页面
90
+    {
91
+      path: '/ClassInfo',
92
+      name: 'ClassInfo',
93
+      component: ClassInfo,
94
+      meta: {
95
+        requireAuth: true,//是否登陆
96
+        showBottomTabBar: true
97
+      }
98
+    },
99
+    //收藏
100
+    {
101
+      path: '/MyCollection',
102
+      name: 'MyCollection',
103
+      component: MyCollection,
82 104
 
83
-
105
+    },
84 106
 
85 107
 
86 108
   ]
109
+
87 110
 })
111
+router.beforeEach((to, from, next) => {
112
+  const { personId } = store.state.user
113
+
114
+
115
+  console.log('-----person.personId---->', personId)
116
+
117
+  // 未登录
118
+  if (!personId) {
119
+    console.log(2222222);
120
+  } else {
121
+    console.log('登陆了');
122
+  }
123
+
124
+  next()
125
+})
126
+
127
+
88 128
 
129
+export default router;

+ 3
- 4
src/store/index.js Wyświetl plik

@@ -20,7 +20,8 @@ const store = new Vuex.Store({
20 20
       Semester: '',
21 21
       sex: '',
22 22
       termId: '',
23
-      Classs: ''
23
+      Classs: '',
24
+      LOADING: false,
24 25
     }
25 26
   },
26 27
 
@@ -32,12 +33,10 @@ const store = new Vuex.Store({
32 33
         ...state.user,
33 34
         ...value
34 35
       }
35
-
36 36
       console.log('SET_USER_INFO被修改为:', state.user);
37
-
38
-
39 37
     },
40 38
 
39
+
41 40
   },
42 41
   //Getter用于对Store中的数据进行加工处理,形成新的数据
43 42
   getters: {

+ 78
- 0
src/util/api.js Wyświetl plik

@@ -49,3 +49,81 @@ export const getSchoolterm = (id) => request(`/api/wx/school-term`, { method: 'g
49 49
  */
50 50
 export const getSchoolClass = (params) => request(`/api/wx/school-class?termId=${params}`, { method: 'get' })
51 51
 
52
+
53
+
54
+
55
+/**
56
+ * 获取课程表
57
+ * @param 
58
+ * @returns 
59
+ * 
60
+ */
61
+export const getCourse = (params) => request(`/api/wx/course`, { method: 'get' })
62
+
63
+/**
64
+ * 获取课程表详情
65
+ * @param 
66
+ * @returns 
67
+ * 
68
+ */
69
+export const getCourseInfof = (id) => request(`/api/wx/course/${id}`, { method: 'get' })
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+// -------------------------------------------------------
78
+
79
+
80
+
81
+
82
+
83
+
84
+/**
85
+ * 获取签到详情
86
+ * @param手机号不能空时间范围
87
+ * @returns 
88
+ * 
89
+ */
90
+export const getSignInInfof = (id) => request(`/api/wx/sign-in/c54e0d34b35e2b93e1dd45e87724d9bd`, { method: 'get' })
91
+
92
+
93
+
94
+/**
95
+ * 签到
96
+ * @param
97
+ * @returns 
98
+ * 
99
+ */
100
+export const getSignIn = (id) => request(`/api/wx/sign-in/c54e0d34b35e2b93e1dd45e87724d9bd`, { method: 'post' })
101
+
102
+
103
+
104
+
105
+
106
+/**
107
+ * 收藏
108
+ * @param
109
+ * @returns 
110
+ * 
111
+ */
112
+export const getCollection = () => request(`/api/wx/favorite`, { method: 'get' })
113
+
114
+/**
115
+ * 增加收藏
116
+ * @param
117
+ * @returns 
118
+ * 
119
+ */
120
+export const addCollection = (data) => request(`/api/wx/favorite`, { method: 'post', data })
121
+
122
+
123
+/**
124
+* 删除收藏
125
+* @param
126
+* @returns 
127
+* 
128
+*/
129
+export const deleteCollection = (id) => request(`/api/wx/favorite/${id}`, { method: 'delete' })

+ 73
- 0
src/util/formattingData.js Wyświetl plik

@@ -0,0 +1,73 @@
1
+
2
+
3
+
4
+// 日期格式化
5
+export function parseTime (time, pattern) {
6
+  let aTime = time
7
+    .toLocaleString()
8
+    .replace(/T/g, ' ')
9
+    .replace(/\.[\d]{3}Z/, '')
10
+
11
+  console.log("🚀 ~ file: formattingData.js ~ line 6 ~ parseTime ~ time", aTime)
12
+
13
+  if (arguments.length === 0 || !aTime) {
14
+    return null
15
+  }
16
+  const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
17
+  let date
18
+  if (typeof aTime === 'object') {
19
+    date = aTime
20
+  } else {
21
+    if ((typeof aTime === 'string') && (/^[0-9]+$/.test(aTime))) {
22
+      aTime = parseInt(aTime)
23
+    } else if (typeof aTime === 'string') {
24
+      aTime = aTime.replace(new RegExp(/-/gm), '/');
25
+    }
26
+    if ((typeof aTime === 'number') && (aTime.toString().length === 10)) {
27
+      aTime = aTime * 1000
28
+    }
29
+    date = new Date(aTime)
30
+  }
31
+  const formatObj = {
32
+    y: date.getFullYear(),
33
+    m: date.getMonth() + 1,
34
+    d: date.getDate(),
35
+    h: date.getHours(),
36
+    i: date.getMinutes(),
37
+    s: date.getSeconds(),
38
+    a: date.getDay()
39
+  }
40
+  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
41
+    let value = formatObj[key]
42
+    // Note: getDay() returns 0 on Sunday
43
+    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
44
+    if (result.length > 0 && value < 10) {
45
+      value = '0' + value
46
+    }
47
+    return value || 0
48
+  })
49
+  return time_str
50
+}
51
+
52
+
53
+export function SignInTime (time, pattern) {
54
+  var date = new Date()
55
+  // var year = date.getFullYear()
56
+  // var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
57
+  // var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
58
+  var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
59
+  var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
60
+  var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
61
+  let week = date.getDay() // 星期
62
+  let weekArr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
63
+  // 拼接 时间格式处理
64
+  return hours + ':' + minutes + ':' + seconds + ' ' + weekArr[week]
65
+
66
+  //  * 在日期格式中,月份是从0开始的
67
+  //  * 使用三元表达式在小于10的前面加0,以达到格式统一  如 09:11:05
68
+
69
+}
70
+
71
+
72
+
73
+

+ 36
- 5
src/util/initial.js Wyświetl plik

@@ -1,9 +1,7 @@
1 1
 /**
2 2
  * 登陆
3 3
  */
4
-import Vue from 'vue'
5 4
 
6
-import Vuex from 'vuex'
7 5
 import store from '../store'
8 6
 
9 7
 import { UserLogin } from './api'
@@ -14,21 +12,26 @@ import { UserLogin } from './api'
14 12
 export function Login () {
15 13
   console.log(store);
16 14
 
17
-  UserLogin('123',).then(e => {
15
+  return UserLogin('123',).then(e => {
18 16
     console.log(e);
19 17
     let userInfo = {
20 18
       token: e.token,
21 19
       name: e.person.name,
22 20
       phone: e.person.phone,
23 21
       personId: e.person.personId,
24
-
25
-
26 22
     }
27 23
     store.commit('SET_USER_INFO', userInfo)
24
+    hideLoading()
25
+
26
+    return;
28 27
   })
29 28
 
30 29
 }
31 30
 
31
+export function hideLoading () {
32
+  document.getElementsByClassName('page-loading-wrapper')[0].style = "display: none"
33
+}
34
+
32 35
 // export function GetCode () {
33 36
 
34 37
 //   // 从 window.location.href 中截取 code 并且赋值
@@ -73,3 +76,31 @@ export function Login () {
73 76
 // 					`
74 77
 //   }
75 78
 // }
79
+
80
+/**
81
+ * 获取 code
82
+ * @returns 
83
+ */
84
+function getCode () {
85
+  const matched = /[?&]*code=([^&]+)/.exec(location.search)
86
+  if (matched) {
87
+    return decodeURIComponent(matched[1])
88
+  }
89
+}
90
+/**
91
+ * 跳转授权页面
92
+ */
93
+export function redirect (force) {
94
+  if (process.env.NODE_ENV === 'development') return;
95
+
96
+  const originCode = localStorage.getItem('wxcode');
97
+  const queryCode = getCode();
98
+  localStorage.setItem('wxcode', queryCode)
99
+
100
+  if (force || !queryCode || queryCode === originCode) {
101
+
102
+    const local = encodeURIComponent(location.origin + location.pathname)
103
+    const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd3bab568bc42d1de&redirect_uri=${local}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`
104
+    window.location.href = url;
105
+  }
106
+}

+ 6
- 4
src/util/request.js Wyświetl plik

@@ -5,7 +5,11 @@ import axios from 'axios'
5 5
 
6 6
 import store from '../store'
7 7
 
8
+import {
8 9
 
10
+  Toast,
11
+
12
+} from 'vant';
9 13
 
10 14
 
11 15
 export default function (url, options) {
@@ -26,12 +30,13 @@ export default function (url, options) {
26 30
       // header: header,
27 31
       headers: header,
28 32
     }).then(res => {
29
-      const { code, data, } = res.data
33
+      const { code, data, message } = res.data
30 34
 
31 35
       if (code === 1000) {
32 36
         resolve(data)
33 37
       } else {
34 38
         // Message.error(message)
39
+        // alert(message)
35 40
 
36 41
         if (code === 1001) {
37 42
           // Message.error('请重新登陆')
@@ -50,9 +55,6 @@ export default function (url, options) {
50 55
       // Message.error('请求错误', err)
51 56
 
52 57
 
53
-
54
-
55
-
56 58
       if (err.message.includes('timeout')) {
57 59
         // 请求超时
58 60
         // Message.error('请求超时')