Baozhangchao 3 年之前
父節點
當前提交
4ef1925c80

+ 11
- 6
package-lock.json 查看文件

@@ -2104,6 +2104,11 @@
2104 2104
       "integrity": "sha512-0FcBfdcmaumGPQ0qPn7Q5qTgz/ooXgIyp1rf8ik5bGX8mpE2YHjC0P/eyQvxu1GURYQgq9ozf2mteQ5ZD9YiyQ==",
2105 2105
       "dev": true
2106 2106
     },
2107
+    "animate.css": {
2108
+      "version": "4.1.1",
2109
+      "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-4.1.1.tgz",
2110
+      "integrity": "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="
2111
+    },
2107 2112
     "ansi-colors": {
2108 2113
       "version": "3.2.4",
2109 2114
       "resolved": "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-3.2.4.tgz",
@@ -6161,8 +6166,8 @@
6161 6166
     },
6162 6167
     "image-size": {
6163 6168
       "version": "0.5.5",
6164
-      "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
6165
-      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
6169
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
6170
+      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
6166 6171
       "dev": true,
6167 6172
       "optional": true
6168 6173
     },
@@ -6876,7 +6881,7 @@
6876 6881
     },
6877 6882
     "less": {
6878 6883
       "version": "4.1.2",
6879
-      "resolved": "https://registry.npmmirror.com/less/-/less-4.1.2.tgz",
6884
+      "resolved": "https://registry.npmjs.org/less/-/less-4.1.2.tgz",
6880 6885
       "integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==",
6881 6886
       "dev": true,
6882 6887
       "requires": {
@@ -6927,7 +6932,7 @@
6927 6932
     },
6928 6933
     "less-loader": {
6929 6934
       "version": "5.0.0",
6930
-      "resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-5.0.0.tgz",
6935
+      "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz",
6931 6936
       "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==",
6932 6937
       "dev": true,
6933 6938
       "requires": {
@@ -6938,8 +6943,8 @@
6938 6943
       "dependencies": {
6939 6944
         "clone": {
6940 6945
           "version": "2.1.2",
6941
-          "resolved": "https://registry.npmmirror.com/clone/-/clone-2.1.2.tgz",
6942
-          "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
6946
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
6947
+          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
6943 6948
           "dev": true
6944 6949
         }
6945 6950
       }

+ 4
- 1
package.json 查看文件

@@ -8,6 +8,7 @@
8 8
     "lint": "vue-cli-service lint"
9 9
   },
10 10
   "dependencies": {
11
+    "animate.css": "^4.1.1",
11 12
     "axios": "^0.26.0",
12 13
     "core-js": "^3.6.5",
13 14
     "vant": "^2.12.44",
@@ -39,7 +40,9 @@
39 40
     "parserOptions": {
40 41
       "parser": "babel-eslint"
41 42
     },
42
-    "rules": {}
43
+    "rules": {
44
+        "no-unused-vars":"off"
45
+    }
43 46
   },
44 47
   "browserslist": [
45 48
     "> 1%",

+ 17
- 2
src/App.vue 查看文件

@@ -6,14 +6,29 @@
6 6
 </template>
7 7
 
8 8
 <script>
9
-import Tabber from './components/Tabber.vue';
9
+import { UserLogin } from './util/api'
10
+
11
+import Tabber from './components/Tabber.vue'
10 12
 
11 13
 export default {
12 14
   name: 'App',
13 15
   components: {
14 16
     Tabber
17
+  },
18
+  mounted() {
19
+    // this.onLogin()
20
+  },
21
+  methods: {
22
+    // onLogin() {
23
+    //   UserLogin('123').then((e) => {
24
+    //     console.log(e)
25
+    //     console.log(22222222222222222222222)
26
+    //     let tokens = e.token
27
+    //     this.$store.commit('SET_USER_INFO', { token: tokens })
28
+    //   })
29
+    // }
15 30
   }
16
-};
31
+}
17 32
 </script>
18 33
 
19 34
 <style>

二進制
src/assets/basemap.png 查看文件


+ 1
- 0
src/assets/icon/courseIcon.svg 查看文件

@@ -0,0 +1 @@
1
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1645417710161" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="9196" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M113.371429 160.914286l519.314285-40.228572-3.657143 120.685715 179.2 3.657142-7.314285 738.742858H113.371429z" fill="#BFD5EC" p-id="9197"></path><path d="M800.914286 1002.057143l-687.542857-3.657143c-7.314286 0-14.628571-7.314286-14.628572-14.628571V160.914286c0-7.314286 3.657143-14.628571 14.628572-14.628572l519.314285-40.228571c3.657143 0 7.314286 0 10.971429 3.657143 3.657143 3.657143 3.657143 7.314286 3.657143 10.971428l-3.657143 102.4H804.571429c7.314286 0 14.628571 7.314286 14.628571 14.628572l-7.314286 742.4c3.657143 14.628571-3.657143 21.942857-10.971428 21.942857z m-669.257143-36.571429l654.628571 3.657143 7.314286-709.485714h-164.571429c-3.657143 0-7.314286-3.657143-10.971428-3.657143-3.657143-3.657143-3.657143-7.314286-3.657143-10.971429l3.657143-102.4-486.4 36.571429v786.285714z" fill="#BFD5EC" p-id="9198"></path><path d="M881.371429 1024H138.971429c-25.6 0-47.542857-21.942857-47.542858-47.542857V138.971429l512 18.285714v47.542857L138.971429 186.514286v789.942857h746.057142V186.514286H694.857143V138.971429h186.514286c25.6 0 47.542857 21.942857 47.542857 47.542857v789.942857c0 25.6-21.942857 47.542857-47.542857 47.542857z m0 0" fill="#4C8AC2" p-id="9199"></path><path d="M694.857143 186.514286V47.542857L138.971429 153.6v705.828571H91.428571V117.028571L694.857143 0c25.6 0 47.542857 21.942857 47.542857 47.542857v138.971429H694.857143z m0 0" fill="#4C8AC2" p-id="9200"></path><path d="M299.885714 164.571429v292.571428c0 10.971429 14.628571 18.285714 21.942857 10.971429l80.457143-73.142857c7.314286-7.314286 21.942857-7.314286 29.257143 0l76.8 73.142857c7.314286 7.314286 21.942857 3.657143 21.942857-10.971429v-292.571428H299.885714z m186.514286 226.742857l-54.857143-51.2c-7.314286-7.314286-21.942857-7.314286-29.257143 0l-54.857143 51.2V186.514286h138.971429v204.8z m0 0M277.942857 640H438.857143c14.628571 0 21.942857-10.971429 21.942857-21.942857 0-14.628571-10.971429-21.942857-21.942857-21.942857H277.942857c-14.628571 0-21.942857 10.971429-21.942857 21.942857-3.657143 10.971429 7.314286 21.942857 21.942857 21.942857z m248.685714 0h186.514286c14.628571 0 21.942857-10.971429 21.942857-21.942857 0-14.628571-10.971429-21.942857-21.942857-21.942857h-186.514286c-14.628571 0-21.942857 10.971429-21.942857 21.942857s10.971429 21.942857 21.942857 21.942857z m-248.685714 117.028571h347.428572c14.628571 0 21.942857-10.971429 21.942857-21.942857 0-14.628571-10.971429-21.942857-21.942857-21.942857H277.942857c-14.628571 0-21.942857 10.971429-21.942857 21.942857-3.657143 10.971429 7.314286 21.942857 21.942857 21.942857z m464.457143 69.485715H277.942857c-14.628571 0-21.942857 10.971429-21.942857 21.942857 0 14.628571 10.971429 21.942857 21.942857 21.942857h464.457143c10.971429 0 21.942857-10.971429 21.942857-21.942857s-7.314286-21.942857-21.942857-21.942857z m0 0" fill="#4C8AC2" p-id="9201"></path></svg>

+ 1
- 0
src/assets/icon/register.svg 查看文件

@@ -0,0 +1 @@
1
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1645423147426" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3049" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><defs><style type="text/css"></style></defs><path d="M472.7296 269.6704m-218.5728 0a218.5728 218.5728 0 1 0 437.1456 0 218.5728 218.5728 0 1 0-437.1456 0Z" fill="#80B7F9" p-id="3050"></path><path d="M554.8544 506.6752H390.656c-176.5888 0-319.744 143.1552-319.744 319.744 0 63.0784 51.1488 114.176 114.176 114.176h575.2832c63.0784 0 114.176-51.1488 114.176-114.176 0-176.5888-143.104-319.744-319.6928-319.744z" fill="#80B7F9" p-id="3051"></path><path d="M747.52 771.072m-202.2912 0a202.2912 202.2912 0 1 0 404.5824 0 202.2912 202.2912 0 1 0-404.5824 0Z" fill="#95C9FC" p-id="3052"></path><path d="M744.2944 568.8832c-110.1824 1.7408-199.0144 91.5456-199.0144 202.1888 0 71.0144 36.608 133.4272 92.0064 169.5232h123.136c63.0784 0 114.176-51.1488 114.176-114.176-0.0512-105.6768-51.3024-199.3216-130.304-257.536z" fill="#3E8BF8" p-id="3053"></path><path d="M810.4448 730.112H788.48v-21.9136c0-22.6304-18.3296-40.96-40.96-40.96s-40.96 18.3296-40.96 40.96v21.9136h-21.9136c-22.6304 0-40.96 18.3296-40.96 40.96s18.3296 40.96 40.96 40.96H706.56v21.9136c0 22.6304 18.3296 40.96 40.96 40.96s40.96-18.3296 40.96-40.96v-21.9136h21.9136c22.6304 0 40.96-18.3296 40.96-40.96s-18.3296-40.96-40.9088-40.96z" fill="#FFFFFF" p-id="3054"></path></svg>

+ 101
- 0
src/components/ClockIn.vue 查看文件

@@ -0,0 +1,101 @@
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>

+ 112
- 7
src/components/Course.vue 查看文件

@@ -1,15 +1,38 @@
1 1
 <template>
2
-  <div>
3
-    <van-cell-group v-for="(item, index) in courseList" :key="index">
4
-      <van-cell :title="item.name" icon="records" @click="handLogin()" is-link />
5
-    </van-cell-group>
2
+  <div class="Course-box">
3
+    <div>
4
+      <van-swipe :autoplay="3000">
5
+        <van-swipe-item v-for="(image, index) in images" :key="index">
6
+          <van-image width="100%" height="25vh" :src="image" />
7
+        </van-swipe-item>
8
+      </van-swipe>
9
+    </div>
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>
20
+        </div>
21
+      </div>
22
+      <div class="Card-box-botton">
23
+        <div>查看详情</div>
24
+        <van-icon name="arrow" />
25
+      </div>
26
+    </div>
6 27
   </div>
7 28
 </template>
8 29
 
9 30
 <script>
31
+import { getBanner } from '../util/api'
10 32
 export default {
11 33
   data() {
12 34
     return {
35
+      icon: require('../assets/icon/courseIcon.svg'),
13 36
       courseList: [
14 37
         { name: '课程阿斯达四方' },
15 38
         { name: 'dgdgdgdfgfds' },
@@ -17,12 +40,94 @@ export default {
17 40
         { name: '昂贵的法国电视公司提供' },
18 41
         { name: '认同感他如果' },
19 42
         { name: '课程阿斯好友和用户运营达四方' },
20
-        { name: '肉体和肉体和人' }
43
+        { name: '毛概' }
44
+      ],
45
+      images: [
46
+        'https://img.yzcdn.cn/vant/apple-1.jpg',
47
+        'https://img.yzcdn.cn/vant/apple-2.jpg',
48
+        'https://img.yzcdn.cn/vant/cat.jpeg'
21 49
       ]
22
-    };
50
+    }
51
+  },
52
+  mounted() {
53
+    this.onBanner()
54
+  },
55
+  methods: {
56
+    goQuestion() {
57
+      this.$router.push('/ClockIn')
58
+    },
59
+    onBanner() {
60
+      getBanner({ position: 'Training' }).then((e) => {
61
+        console.log(e)
62
+      })
63
+    }
23 64
   }
24
-};
65
+}
25 66
 </script>
26 67
 
27 68
 <style lang="less" scoped>
69
+.Course-box {
70
+  width: 100vw;
71
+  .van-swipe {
72
+    width: 100%;
73
+    border-radius: 20px;
74
+
75
+    height: 25vh;
76
+    .van-swipe-item {
77
+    }
78
+  }
79
+  .van-cell-group {
80
+    display: flex;
81
+  }
82
+
83
+  .Card-box {
84
+    width: 95%;
85
+    border-radius: 15px;
86
+    background-color: #fff;
87
+    margin: 2.4em auto 1em auto;
88
+    box-shadow: 0 0 15px rgb(214, 214, 214);
89
+
90
+    .Card-box-top {
91
+      display: flex;
92
+      align-items: center;
93
+      > img {
94
+        width: 20vw;
95
+        border-radius: 50%;
96
+
97
+        // padding: 20px;
98
+      }
99
+      &-box {
100
+        // width: 63vw;
101
+      }
102
+
103
+      &-title {
104
+        font-size: 16px;
105
+        font-weight: 700;
106
+        letter-spacing: 1px;
107
+        padding: 10px;
108
+      }
109
+      &-time {
110
+        font-size: 14px;
111
+        color: rgb(133, 133, 133);
112
+        padding: 0px 0 10px 10px;
113
+      }
114
+    }
115
+    .Card-box-botton {
116
+      width: 90%;
117
+      margin: 0 auto;
118
+      border-top: 1px solid rgb(238, 238, 238);
119
+      display: flex;
120
+      color: rgb(133, 133, 133);
121
+      justify-content: space-between;
122
+
123
+      > div {
124
+        padding: 10px 0 10px 0;
125
+      }
126
+      .van-icon {
127
+        position: relative;
128
+        top: 1.9vh;
129
+      }
130
+    }
131
+  }
132
+}
28 133
 </style>

+ 63
- 0
src/components/Question/Answer.vue 查看文件

@@ -0,0 +1,63 @@
1
+<template>
2
+  <div
3
+    class="answer-box animate__animated animate__bounceInUp"
4
+    :class="{active: active}"
5
+    @click="$emit('click')"
6
+  >
7
+    <div>{{opt}}</div>
8
+    <div class="answer-box-gutter">{{label}}</div>
9
+  </div>
10
+</template>
11
+
12
+<script>
13
+export default {
14
+  name: 'Answer',
15
+  props: {
16
+    active: Boolean,
17
+    option: String,
18
+    label: String
19
+  },
20
+  computed: {
21
+    opt() {
22
+      switch (this.option) {
23
+        case 'true':
24
+          return ''
25
+        case 'false':
26
+          return ''
27
+        default:
28
+          return this.option ? `${this.option}:` : ''
29
+      }
30
+    }
31
+  }
32
+}
33
+</script>
34
+
35
+<style lang="less" scoped>
36
+.answer-box {
37
+  background-color: #f6f6f8;
38
+  color: #4e5053;
39
+  border-radius: 100px;
40
+  display: flex;
41
+  align-items: center;
42
+  margin-bottom: 25px;
43
+  font-size: 14px;
44
+  font-weight: 400;
45
+  padding: 1em 2em;
46
+  // height: 40px;
47
+
48
+  & + & {
49
+    margin-top: 26px;
50
+    text-align-last: left;
51
+  }
52
+
53
+  &-gutter {
54
+    margin-left: 1em;
55
+    line-height: 1.4em;
56
+  }
57
+
58
+  &.active {
59
+    background-color: #409eff;
60
+    color: #fff;
61
+  }
62
+}
63
+</style>

+ 50
- 0
src/components/Question/Title.vue 查看文件

@@ -0,0 +1,50 @@
1
+<template>
2
+  <div class="question-title">
3
+    <span>{{`第${this.serialNo}题:`}}</span>
4
+    <span>{{title}}</span>
5
+    <span>({{ formatType(qType) }})</span>
6
+  </div>
7
+</template>
8
+
9
+<script>
10
+export default {
11
+  name: 'QuestionTitle',
12
+  props: {
13
+    serialNo: {
14
+      type: Number,
15
+      required: true
16
+    },
17
+    qType: String,
18
+    title: String
19
+  },
20
+  computed: {
21
+    content() {
22
+      return ` 第${this.serailNo}题: ${this.title} `
23
+    }
24
+  },
25
+  methods: {
26
+    formatType(typ) {
27
+      switch (typ) {
28
+        case 'single':
29
+          return '单选'
30
+        case 'many':
31
+          return '多选'
32
+        case 'judgment':
33
+          return '判断'
34
+        default:
35
+          return '未知题型'
36
+      }
37
+    }
38
+  }
39
+}
40
+</script>
41
+
42
+
43
+<style lang="less" scoped>
44
+.question-title {
45
+  margin: 1em 0;
46
+  font-weight: 700;
47
+  text-align-last: left;
48
+  letter-spacing: 2px;
49
+}
50
+</style>

+ 101
- 0
src/components/Question/index.vue 查看文件

@@ -0,0 +1,101 @@
1
+<template>
2
+  <div class="question-box">
3
+    <q-title v-bind="qTitleContent"></q-title>
4
+    <div style="margin-top:3em;">
5
+      <div class="scroll">
6
+        <answer
7
+          v-for="answer in question.answerList"
8
+          :key="answer.answerId"
9
+          :active="values.includes(answer.option)"
10
+          :option="answer.option"
11
+          :label="answer.content"
12
+          @click="handleAnswer(answer.option)"
13
+        ></answer>
14
+      </div>
15
+    </div>
16
+  </div>
17
+</template>
18
+
19
+<script>
20
+export default {
21
+  name: 'Question',
22
+  components: {
23
+    Answer: () => import('./Answer.vue'),
24
+    QTitle: () => import('./Title.vue')
25
+  },
26
+  props: {
27
+    value: {
28
+      type: [Array, String]
29
+    },
30
+    question: {
31
+      type: Object,
32
+      default: () => ({
33
+        rightAnswer: '',
34
+        answerList: []
35
+      })
36
+    },
37
+    serialNo: {
38
+      type: Number,
39
+      required: true
40
+    }
41
+  },
42
+  data() {
43
+    return {
44
+      answerValues: {}
45
+    }
46
+  },
47
+  computed: {
48
+    qTitleContent() {
49
+      return {
50
+        serialNo: this.serialNo,
51
+        title: this.question.title,
52
+        qType: this.question.optType
53
+      }
54
+    },
55
+    values() {
56
+      // 为了便捷处理, 不同的问题类型。所有的答案统一处理为数组
57
+      return Array.isArray(this.value) ? this.value : [this.value]
58
+    }
59
+  },
60
+  methods: {
61
+    handleAnswer(opt) {
62
+      const isChecked = this.values.includes(opt)
63
+
64
+      // 如果是多选
65
+      if (this.question.optType === 'many') {
66
+        if (isChecked) {
67
+          this.$emit(
68
+            'input',
69
+            this.values.filter((x) => x !== opt)
70
+          )
71
+        } else {
72
+          this.$emit('input', [...this.values, opt])
73
+        }
74
+      } else {
75
+        this.$emit('input', opt)
76
+      }
77
+    }
78
+  }
79
+}
80
+</script>
81
+
82
+<style lang="less" scoped>
83
+.question-box {
84
+  width: 80vw;
85
+  margin: 0 auto;
86
+  position: relative;
87
+  top: -15vh;
88
+  left: -4%;
89
+  background: white;
90
+  box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
91
+  border-radius: 12px;
92
+  padding: 1em 15px 2em 15px;
93
+
94
+  .scroll {
95
+    padding-top: 5px;
96
+    width: 100%;
97
+    height: 46vh;
98
+    overflow: auto;
99
+  }
100
+}
101
+</style>

+ 237
- 0
src/components/Questionnaire.vue 查看文件

@@ -0,0 +1,237 @@
1
+<template>
2
+  <div>
3
+    <!-- <img :src="backgeImg" class="ImagStyle" /> -->
4
+    <popup
5
+      :show="showPopup"
6
+      @confirm="submitForm(currentQuestion.rightAnswer)"
7
+      @cancel="cancelForm"
8
+      :showCancel="true"
9
+      :LoadingShow="LoadingShowAAA"
10
+      :title="'确定提交答案吗'"
11
+      :confirmText="`提交`"
12
+      :cancelText="`取消提交`"
13
+    >
14
+      <p>确定要提交答案吗?提交后内容不可更改!</p>
15
+    </popup>
16
+
17
+    <!-- 页面标题 -->
18
+    <div class="VSTD_box" v-if="question.length > 0">
19
+      <!-- 题的表单 -->
20
+      <!-- 绑定表单的数据 ruleForm -->
21
+      <!-- 绑定题的数组 ruleForm.resource[index] -->
22
+
23
+      <el-form class="demo-ruleForm">
24
+        <!-- 循环后端  的所有题 -->
25
+        <div class="VSTD_box_item">
26
+          <question
27
+            :question="currentQuestion"
28
+            :serial-no="netx + 1"
29
+            v-model="currentQuestion.rightAnswer"
30
+          ></question>
31
+
32
+          <div class="but-box">
33
+            <el-form-item class="but-box-form-item">
34
+              <el-button class="butsize" v-show="ButPrevious" @click="PreviousBut">上一题</el-button>
35
+              <el-button
36
+                type="primary"
37
+                class="butsize"
38
+                v-show="Butnetx"
39
+                @click="netxBut(currentQuestion.rightAnswer)"
40
+              >下一题</el-button>
41
+              <el-button type="primary" class="butsize" v-show="Butsubmit" @click="firstSubmit">提交</el-button>
42
+            </el-form-item>
43
+          </div>
44
+        </div>
45
+
46
+        <!-- 提交函数  -->
47
+      </el-form>
48
+    </div>
49
+
50
+    <!-- 如果没题就提示没题 -->
51
+
52
+    <div v-else>
53
+      <div class="none" style="margin-left: 0px">
54
+        <div class="none_img"></div>
55
+        <h3>暂无试题</h3>
56
+      </div>
57
+    </div>
58
+  </div>
59
+</template>
60
+
61
+<script>
62
+// import { getQuestionList, submitAnswer } from '@/util/api'
63
+// import query from '../util/query'
64
+
65
+export default {
66
+  name: 'Questionnaire',
67
+  components: {
68
+    Question: () => import('./Question'),
69
+    Popup: () => import('./Questionnaire/Popup.vue')
70
+  },
71
+  data() {
72
+    return {
73
+      showPopup: false,
74
+      LoadingShowAAA: false,
75
+      // backgeImg: require('../assets/bgc.png'),
76
+      netx: 0, //第一题第二题下标
77
+      startData: null,
78
+      endData: null,
79
+      ButPrevious: false, //上一题
80
+      Butsubmit: false, //提交
81
+      Butnetx: true, //下一题
82
+
83
+      indexSum: 0, //第indexSum题
84
+      // questionId: '', //试题的id
85
+      title: '', //返回的题目信息
86
+      question: [], //答题保存的数组
87
+
88
+      DSQ: null, //定时器,到时间自动提交
89
+      DSQTime: 0 //后端返回的结束时间
90
+    }
91
+  }
92
+  //   computed: {
93
+  //     currentQuestion: {
94
+  //       get: function () {
95
+  //         return this.question[this.netx]
96
+  //       },
97
+  //       set: function (val) {
98
+  //         this.$set(this.question, this.netx, val)
99
+  //       }
100
+  //     }
101
+  //   },
102
+  //   created() {
103
+  //     // findIndex 用来获取数组中第一个满足条件的元素下标
104
+  //     var v = this.question.findIndex((value, index, arr) => {
105
+  //       return value.a == '2'
106
+  //     })
107
+  //   },
108
+
109
+  //   mounted() {
110
+  //     this.onSearch()
111
+  //   },
112
+
113
+  //   methods: {
114
+  //     cancelForm() {
115
+  //       this.showPopup = false
116
+  //       console.log('点击了取消')
117
+  //     },
118
+
119
+  //     onSearch() {
120
+  //       getQuestionList(this.$store.state.user.appid, query('gameId')).then(
121
+  //         (res) => {
122
+  //           console.log('题目列表', res)
123
+  //           const { questionId, title, optType } = res
124
+  //           this.question = res
125
+  //           this.questionId = questionId
126
+  //           this.title = title
127
+  //           let NBMMSSD = res.map((obj) => {
128
+  //             let start = 0
129
+  //             let sum = obj.score
130
+  //             start += sum
131
+  //             return start
132
+  //           })
133
+  //           let oversum = eval(NBMMSSD.join('+'))
134
+  //           this.$store.commit('SET_USER_INFO', { totalScore: oversum })
135
+  //         }
136
+  //       )
137
+  //       // let sum = 0
138
+  //     },
139
+  //     firstSubmit() {
140
+  //       this.showPopup = true
141
+  //     },
142
+  //     submitForm(e) {
143
+  //       this.LoadingShowAAA = true
144
+  //       console.log('🚀 ~ f e', e)
145
+  //       // const { questionId, rightAnswer } = this.question
146
+  //       console.log(this.question)
147
+
148
+  //       let NEW_ARR = this.question.map((obj) => {
149
+  //         if (Array.isArray(obj.rightAnswer)) {
150
+  //           let sliceArray = obj.rightAnswer.slice(1)
151
+  //           let stringArray = sliceArray.sort().toLocaleString()
152
+
153
+  //           return { questionId: obj.questionId, answer: stringArray }
154
+  //         } else {
155
+  //           return { questionId: obj.questionId, answer: obj.rightAnswer }
156
+  //         }
157
+  //       })
158
+  //       console.log(NEW_ARR)
159
+
160
+  //       submitAnswer(this.$store.state.user.appid, query('gameId'), NEW_ARR).then(
161
+  //         (e) => {
162
+  //           console.log(e.score, e)
163
+  //           this.$store.commit('SET_USER_INFO', { scoreNumb: e.result.score })
164
+  //           this.$store.commit('SET_USER_INFO', { resultInfo: e.result.resultId })
165
+  //           this.LoadingShowAAA = false
166
+  //           this.showPopup = false
167
+
168
+  //           this.$router.replace('/Leaderboard') //replace  不记录页面 ,无法返回
169
+  //         }
170
+  //       )
171
+  //     },
172
+
173
+  //     netxBut(e) {
174
+  //       if (e !== null) {
175
+  //         if (this.netx >= this.question.length - 2) {
176
+  //           this.Butnetx = false
177
+  //           this.Butsubmit = true
178
+  //         }
179
+  //         if (this.netx <= this.question.length - 2) {
180
+  //           this.netx = this.netx + 1
181
+  //           this.ButPrevious = this.ButPrevious = true
182
+  //           this.indexSum = this.indexSum + 1
183
+  //         }
184
+  //       } else {
185
+  //         this.$message.warning('请选择至少一项')
186
+  //       }
187
+  //     },
188
+
189
+  //     PreviousBut() {
190
+  //       if (this.netx >= 1) {
191
+  //         this.Butnetx = true
192
+  //         this.Butsubmit = false
193
+  //       }
194
+  //       if (this.netx <= 1) {
195
+  //         this.ButPrevious = this.ButPrevious = false
196
+  //         this.Butnetx = true
197
+  //       }
198
+  //       if (this.netx <= 0) {
199
+  //         console.log('???', this.netx, this.question.length)
200
+  //       } else {
201
+  //         this.netx = this.netx - 1
202
+  //         this.indexSum = this.indexSum - 1
203
+  //       }
204
+  //     }
205
+  //   }
206
+}
207
+</script>
208
+
209
+
210
+
211
+
212
+<style lang="less" scoped>
213
+.ImagStyle {
214
+  width: 100%;
215
+}
216
+
217
+.VSTD_box {
218
+  .demo-ruleForm {
219
+    width: 80%;
220
+    display: flex;
221
+    margin: auto;
222
+    .VSTD_box_item {
223
+      .but-box {
224
+        position: absolute;
225
+        width: 80%;
226
+        align-items: center;
227
+        bottom: 10px;
228
+        margin: auto;
229
+        .butsize {
230
+          height: 43px;
231
+        }
232
+      }
233
+    }
234
+  }
235
+}
236
+</style>
237
+

+ 63
- 0
src/components/Questionnaire/Loading.vue 查看文件

@@ -0,0 +1,63 @@
1
+<template>
2
+  <div v-show="LoadingShow">
3
+    <svg
4
+      xmlns="http://www.w3.org/2000/svg"
5
+      xmlns:xlink="http://www.w3.org/1999/xlink"
6
+      :width="LoadingWidth"
7
+      :height="LoadingHeight"
8
+      viewBox="0 0 40 40"
9
+      enable-background="new 0 0 40 40"
10
+      xml:space="preserve"
11
+    >
12
+      <!-- loading背景灰色圆圈 -->
13
+      <path
14
+        opacity="0.2"
15
+        fill="#fff"
16
+        d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
17
+      s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
18
+      c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"
19
+      />
20
+      <!-- loading白色转动部分 -->
21
+      <path
22
+        fill="#fff"
23
+        d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
24
+      C22.32,8.481,24.301,9.057,26.013,10.047z"
25
+        transform="rotate(42.1171 20 20)"
26
+      >
27
+        <animateTransform
28
+          attributeType="xml"
29
+          attributeName="transform"
30
+          type="rotate"
31
+          from="0 20 20"
32
+          to="360 20 20"
33
+          dur="0.5s"
34
+          repeatCount="indefinite"
35
+        />
36
+      </path>
37
+    </svg>
38
+  </div>
39
+</template>
40
+
41
+<script>
42
+export default {
43
+  name: 'Loading',
44
+  props: {
45
+    LoadingWidth: {
46
+      type: String,
47
+      default: '30px'
48
+    },
49
+    LoadingHeight: {
50
+      type: String,
51
+      default: '30px'
52
+    },
53
+    LoadingShow: {
54
+      type: Boolean,
55
+      default: false,
56
+      required: true
57
+    }
58
+  }
59
+}
60
+</script>
61
+
62
+<style>
63
+</style>

+ 114
- 0
src/components/Questionnaire/Many.vue 查看文件

@@ -0,0 +1,114 @@
1
+<template>
2
+  <div class="div-box">
3
+    <div class="VSTD_box_item_title">
4
+      <!-- 题目的信息 -->
5
+
6
+      <p style="font-weight:700">
7
+        第{{ index + 1 }}题:{{ item.title
8
+        }}
9
+        <!-- <span>({{ item.stScore }}分)</span> -->
10
+        <span>(多选)</span>
11
+      </p>
12
+    </div>
13
+    <!-- v-model="ruleForm.ManyVal" -->
14
+    <div class="group-box">
15
+      <el-form-item label=" " class="Single-radio">
16
+        <el-checkbox-group :change="changeVaal" style="display:grid">
17
+          <el-checkbox
18
+            :class="`Single-elradio animate__animated animate__bounceInUp `"
19
+            v-for="(item, index) in item.answerList"
20
+            :label="item.option"
21
+            :key="index"
22
+          >{{ item.option }}:{{item.content}}</el-checkbox>
23
+          <!-- <el-checkbox label="F">{{ item.stSelectf }}</el-checkbox> -->
24
+        </el-checkbox-group>
25
+      </el-form-item>
26
+    </div>
27
+  </div>
28
+</template>
29
+
30
+<script>
31
+export default {
32
+  name: 'Many', //多选题
33
+  props: {
34
+    item: {
35
+      type: Object
36
+    },
37
+    ruleForm: {
38
+      type: Object || Array
39
+    },
40
+    index: {
41
+      type: Number || String,
42
+      required: true
43
+    }
44
+  },
45
+  data() {
46
+    return {
47
+      chilcLisat: []
48
+    }
49
+  },
50
+  methods: {
51
+    changeVaal(e, v) {
52
+      console.log(
53
+        '🚀 ~ file: Questionnaire.vue ~ line 213 ~ change ~ e,v',
54
+        e,
55
+        v
56
+      )
57
+      console.log('🚀 ~ file: Many.vue ~ line 18 ~ ruleForm', this.ruleForm)
58
+    }
59
+  }
60
+}
61
+</script>
62
+<style lang="less" >
63
+.div-box {
64
+  width: 87vw;
65
+  height: 70vh;
66
+  // border: 1px solid black;
67
+  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
68
+  border-radius: 10px;
69
+  position: relative;
70
+  top: -12vh;
71
+  left: -3vw;
72
+  .VSTD_box_item_title {
73
+    text-align-last: left;
74
+    letter-spacing: 2px;
75
+    background-color: #ffffff;
76
+    height: 12vh;
77
+    padding: 10px 20px 0px 20px;
78
+    position: relative;
79
+    top: -15px;
80
+    width: 87%;
81
+    margin: 0 auto;
82
+    border-radius: 10px;
83
+  }
84
+
85
+  .group-box {
86
+    .el-radio.is-bordered + .el-radio.is-bordered {
87
+      margin-left: 20px;
88
+    }
89
+    .Single-elradio {
90
+      border: 0px;
91
+      margin: 13px 20px;
92
+      background-color: #f6f6f8;
93
+      color: #4e5053;
94
+      border-radius: 100px;
95
+      .el-radio__input {
96
+        display: none;
97
+      }
98
+      .el-checkbox__input {
99
+        display: none;
100
+      }
101
+    }
102
+    .Single-elradio.is-checked {
103
+      background-color: #409eff;
104
+    }
105
+    .el-radio__input.is-checked + .el-radio__label {
106
+      color: #ffffff !important;
107
+    }
108
+
109
+    .el-checkbox__input.is-checked + .el-checkbox__label {
110
+      color: #ffffff !important;
111
+    }
112
+  }
113
+}
114
+</style>

+ 225
- 0
src/components/Questionnaire/Popup.vue 查看文件

@@ -0,0 +1,225 @@
1
+<template>
2
+  <div v-if="showSelf" class="dialog" :style="{'z-index': zIndex}">
3
+    <div class="dialog-mark" @click.self="closeMyself" :style="{'z-index': zIndex + 1}"></div>
4
+    <transition name="dialog">
5
+      <div class="dialog-sprite" :style="{'z-index': zIndex + 2}">
6
+        <!-- 标题 -->
7
+        <section v-if="title" class="header">{{ title }}</section>
8
+
9
+        <!-- 弹窗的主题内容 -->
10
+        <section class="dialog-body">
11
+          <slot></slot>
12
+        </section>
13
+
14
+        <!-- 按钮 -->
15
+        <div class="dialog-footer">
16
+          <button class="btn btn-confirm" @click="confirm" :disabled="LoadingShow">
17
+            {{confirmText}}
18
+            <v-loading
19
+              class="btn-confirm-loading"
20
+              :LoadingShow="LoadingShow"
21
+              LoadingWidth="25px"
22
+              LoadingHeight="25px"
23
+            />
24
+          </button>
25
+
26
+          <button v-if="showCancel" class="btn btn-refuse" @click="cancel">{{cancelText}}</button>
27
+        </div>
28
+      </div>
29
+    </transition>
30
+  </div>
31
+</template>
32
+
33
+<script>
34
+export default {
35
+  name: 'Popup',
36
+  props: {
37
+    show: {
38
+      type: Boolean,
39
+      default: false,
40
+      required: true
41
+    },
42
+    title: {
43
+      type: String,
44
+      required: true
45
+    },
46
+    showCancel: {
47
+      typs: Boolean,
48
+      default: false,
49
+      required: false
50
+    },
51
+    cancelText: {
52
+      type: String,
53
+      default: '取消',
54
+      required: false
55
+    },
56
+    confirmText: {
57
+      type: String,
58
+      default: '确定',
59
+      required: false
60
+    },
61
+    LoadingShow: {
62
+      type: Boolean,
63
+      default: false,
64
+      required: true
65
+    }
66
+  },
67
+
68
+  data() {
69
+    return {
70
+      name: 'dialog',
71
+      showSelf: false,
72
+      zIndex: this.getZIndex(),
73
+      bodyOverflow: ''
74
+    }
75
+  },
76
+  watch: {
77
+    show(val) {
78
+      console.log('🚀 ~ file: Popup.vue ~ line 78 ~ show ~ val', val)
79
+      this.showSelf = val
80
+
81
+      // if (!val) {
82
+      //   this.closeMyself()
83
+      // } else {
84
+      //   this.showSelf = val
85
+      // }
86
+    }
87
+  },
88
+  created() {
89
+    this.showSelf = this.show
90
+  },
91
+  mounted() {
92
+    this.forbidScroll()
93
+  },
94
+  methods: {
95
+    /** 禁止页面滚动 */
96
+    forbidScroll() {
97
+      this.bodyOverflow = document.body.style.overflow
98
+      document.body.style.overflow = 'hidden'
99
+    },
100
+
101
+    /**  每次获取之后 zindex 自动增加 */
102
+    getZIndex() {
103
+      let zIndexInit = 2022112
104
+      return zIndexInit++
105
+    },
106
+
107
+    /** 取消按钮操作 */
108
+    cancel() {
109
+      this.$emit('cancel', true)
110
+    },
111
+
112
+    /** 确认按钮操作 */
113
+    confirm() {
114
+      this.$emit('confirm', true)
115
+    },
116
+
117
+    /** 点击遮罩关闭弹窗 */
118
+    closeMyself() {
119
+      // this.sloveBodyOverflow()
120
+    },
121
+
122
+    /** 恢复页面的滚动 */
123
+    sloveBodyOverflow() {
124
+      document.body.style.overflow = this.bodyOverflow
125
+    }
126
+  }
127
+}
128
+</script>
129
+
130
+<style lang="less" scoped>
131
+// 弹窗动画
132
+.dialog-enter-active,
133
+.dialog-leave-active {
134
+  transition: opacity 1s;
135
+}
136
+
137
+.dialog-enter,
138
+.dialog-leave-to {
139
+  opacity: 0;
140
+}
141
+
142
+// 最外层 设置position定位
143
+// 遮罩 设置背景层,z-index值要足够大确保能覆盖,高度 宽度设置满 做到全屏遮罩
144
+.dialog {
145
+  position: fixed;
146
+  top: 0;
147
+  right: 0;
148
+  width: 100%;
149
+  height: 100%;
150
+  transition: opacity 1s;
151
+
152
+  // 内容层 z-index要比遮罩大,否则会被遮盖
153
+  .dialog-mark {
154
+    position: absolute;
155
+    top: 0;
156
+    height: 0;
157
+    width: 100%;
158
+    height: 100%;
159
+    background: rgba(0, 0, 0, 0.6);
160
+  }
161
+}
162
+
163
+.dialog-sprite {
164
+  position: absolute;
165
+  left: 5%;
166
+  right: 5%;
167
+  bottom: 25%;
168
+  display: flex;
169
+  flex-direction: column;
170
+  max-height: 75%;
171
+  min-height: 280px;
172
+
173
+  overflow: hidden;
174
+  z-index: 23456765435;
175
+  background: #fff;
176
+  border-radius: 8px;
177
+  .header {
178
+    padding: 15px;
179
+    text-align: center;
180
+    font-size: 18px;
181
+    font-weight: 700;
182
+    color: #333;
183
+  }
184
+  .dialog-body {
185
+    flex: 1;
186
+    overflow-x: hidden;
187
+    overflow-y: scroll;
188
+    padding: 0 15px 20px 15px;
189
+  }
190
+  .dialog-footer {
191
+    width: 100%;
192
+    padding-top: 1em;
193
+    .btn {
194
+      display: block;
195
+      width: 95%;
196
+      margin: auto;
197
+      margin-bottom: 1em;
198
+      border: 0;
199
+      line-height: 45px;
200
+      border-radius: 20px;
201
+      font-weight: 700;
202
+      font-size: 15px;
203
+      box-shadow: 0px 8px 28px 0px rgba(0, 0, 0, 0.12);
204
+    }
205
+    .btn-refuse {
206
+      background: #fff;
207
+      color: #5886fe;
208
+      height: 45px;
209
+    }
210
+    .btn-confirm {
211
+      color: white;
212
+      background-image: linear-gradient(to right, #3b5bea, #5886fe);
213
+      display: flex;
214
+      align-items: center;
215
+      justify-content: center;
216
+      height: 45px;
217
+      &-loading {
218
+        display: flex;
219
+        align-items: center;
220
+      }
221
+    }
222
+  }
223
+}
224
+</style>
225
+

+ 28
- 0
src/components/Questionnaire/index.js 查看文件

@@ -0,0 +1,28 @@
1
+import PlayGame from './PlayGame.vue'//简答(输入框)
2
+
3
+import Loading from './Loading.vue'//单选
4
+
5
+// import { component } from 'vue/types/umd'
6
+
7
+
8
+const compoents = [
9
+  PlayGame,
10
+  // UserScore,
11
+  // Many,
12
+  Loading,
13
+]
14
+
15
+
16
+
17
+const Questionnaire = {
18
+  install (Vue) {
19
+    console.log('组件打印');
20
+    compoents.forEach(compoents => {
21
+      Vue.component(compoents.name, compoents)
22
+
23
+    })
24
+  }
25
+}
26
+
27
+
28
+export default Questionnaire

+ 150
- 15
src/components/StrongPhoto.vue 查看文件

@@ -1,9 +1,45 @@
1 1
 <template>
2
-  <!-- <h1>StrongPhoto 精彩瞬间</h1> -->
3
-  <div>
4
-    <span v-for="(image, index) in imageList" :key="index">
5
-      <van-image width="200px" :src="image.a" />
6
-    </span>
2
+  <!-- <h1>StrongPhoto 精彩集锦</h1> -->
3
+  <div class="Photo-box">
4
+    <div>
5
+      <van-swipe :autoplay="3000">
6
+        <van-swipe-item v-for="(image, index) in title.imageList" :key="index">
7
+          <van-image width="100%" height="25vh" :src="image.a" />
8
+        </van-swipe-item>
9
+      </van-swipe>
10
+    </div>
11
+    <div style="display: flex; aline-itme:center;margin-top: 30px;padding-left: 15px;
12
+    ">
13
+      <!-- <div :class="`${classStyle?'Zhedie-box Donghua':'Zhedie-box'}`"> -->
14
+      <div :class="{'Zhedie-box': true, 'expand': classStyle}">
15
+        <!-- :class="`${clickStyle?'clickStyle':''}`" -->
16
+
17
+        <div
18
+          v-for="(item,i) in buttList"
19
+          :key="item"
20
+          @click="SeePhotos(i)"
21
+          :class="activeNum === i ? 'clickStyle':''"
22
+        >{{item}}</div>
23
+      </div>
24
+      <van-icon
25
+        v-show="iconShow"
26
+        style="left:0; top: 0.6vh;"
27
+        :name="`${classStyle?'arrow-up ':'arrow-down'}`"
28
+        @click="animations"
29
+      />
30
+    </div>
31
+
32
+    <div class="PhotoList-box">
33
+      <div class="PhotoList-box-text">
34
+        <div></div>
35
+        <span>{{title.name}}</span>
36
+      </div>
37
+      <div class="PhotoList-box-images">
38
+        <span v-for="(image, index) in title.imageList" :key="index">
39
+          <van-image width="31vw" :src="image.a" style="padding:0 3px 0 2px" />
40
+        </span>
41
+      </div>
42
+    </div>
7 43
   </div>
8 44
 </template>
9 45
 
@@ -11,18 +47,117 @@
11 47
 export default {
12 48
   data() {
13 49
     return {
14
-      imageList: [
15
-        { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
16
-        { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
17
-        { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
18
-        { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
19
-        { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
20
-        { a: 'https://img.yzcdn.cn/vant/cat.jpeg' }
21
-      ]
22
-    };
50
+      classStyle: false,
51
+      clickStyle: false,
52
+      iconShow: false,
53
+      activeNum: 0, //下标
54
+      buttList: [
55
+        '一期培训',
56
+        '二期培训',
57
+        '三期培训',
58
+        '四期345啊啊',
59
+        '四期44啊啊',
60
+        '四期2啊啊',
61
+        '四期0啊啊'
62
+      ],
63
+      title: {
64
+        name: '2022年02月22日',
65
+        imageList: [
66
+          { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
67
+          { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
68
+          { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
69
+          { a: 'https://img.yzcdn.cn/vant/cat.jpeg' },
70
+          { a: 'https://img.yzcdn.cn/vant/cat.jpeg' }
71
+          // { a: 'https://img.yzcdn.cn/vant/cat.jpeg' }
72
+        ]
73
+      }
74
+    }
75
+  },
76
+  mounted() {
77
+    if (this.buttList.length >= 5) {
78
+      this.iconShow = true
79
+    } else {
80
+      this.iconShow = false
81
+    }
82
+  },
83
+  methods: {
84
+    animations() {
85
+      this.classStyle = !this.classStyle
86
+    },
87
+    SeePhotos(i) {
88
+      console.log('🚀 ~ file: StrongPhoto.vue ~ line 64 ~ SeePhotos ~ i', i)
89
+      this.activeNum = i
90
+      // this.clickStyle = !this.clickStyle
91
+    }
23 92
   }
24
-};
93
+}
25 94
 </script>
26 95
 
27 96
 <style lang="less" scoped>
97
+.Photo-box {
98
+  width: 100vw;
99
+  height: 100%;
100
+  background-color: #fff;
101
+  .van-swipe {
102
+    width: 100%;
103
+    border-radius: 20px;
104
+    height: 25vh;
105
+  }
106
+  .Zhedie-box {
107
+    width: 90%;
108
+    overflow: hidden;
109
+    display: flex;
110
+    align-items: center;
111
+    flex-wrap: wrap;
112
+    height: 30px;
113
+    transition: height 0.2s ease;
114
+    &.expand {
115
+      height: 50vh;
116
+    }
117
+
118
+    > div {
119
+      width: 75px;
120
+      height: 30px;
121
+      color: rgb(128, 128, 128);
122
+      line-height: 28px;
123
+      text-align: center;
124
+      font-size: 10px;
125
+    }
126
+    .clickStyle {
127
+      color: #12a89f;
128
+      font-weight: 700;
129
+      background-color: #f3f3f3;
130
+      border-radius: 30px;
131
+    }
132
+  }
133
+  .Donghua {
134
+    animation: Donghua 0.2s 1 forwards;
135
+    overflow: scroll;
136
+  }
137
+  .PhotoList-box {
138
+    width: 100%;
139
+
140
+    .PhotoList-box-text {
141
+      display: flex;
142
+      align-items: center;
143
+      margin: 1.2em 0 0.8em 0;
144
+      > div {
145
+        width: 6px;
146
+        height: 6px;
147
+        border-radius: 50%;
148
+        background-color: #13c0b4;
149
+        margin: 0 13px 0 9px;
150
+      }
151
+      > span {
152
+        font-size: 12px;
153
+        letter-spacing: 1px;
154
+        color: rgb(128, 128, 128);
155
+      }
156
+    }
157
+    .PhotoList-box-images {
158
+      width: 97%;
159
+      margin: 0 auto;
160
+    }
161
+  }
162
+}
28 163
 </style>

+ 2
- 2
src/components/Tabber.vue 查看文件

@@ -1,8 +1,8 @@
1 1
 <template>
2 2
   <div class="tabbar">
3 3
     <van-tabbar class="van-tabbar" v-model="active" @change="onChange">
4
-      <van-tabbar-item icon="column">课程管理</van-tabbar-item>
5
-      <van-tabbar-item icon="photo">精彩瞬间</van-tabbar-item>
4
+      <van-tabbar-item icon="column">培训通知</van-tabbar-item>
5
+      <van-tabbar-item icon="photo">精彩集锦</van-tabbar-item>
6 6
       <van-tabbar-item icon="manager">个人中心</van-tabbar-item>
7 7
     </van-tabbar>
8 8
   </div>

+ 19
- 19
src/components/UserCenter.vue 查看文件

@@ -16,7 +16,8 @@
16 16
 
17 17
     <div class="button-box">
18 18
       <van-cell-group>
19
-        <van-cell class="user-button" title="注册" icon="contact" @click="handLogin()" is-link />
19
+        <img :src="register" alt width="25px" style=" margin: 0 0 0 10px;" />
20
+        <van-cell class="user-button" title="注册" @click="handLogin()" is-link />
20 21
       </van-cell-group>
21 22
       <!-- <button type="primary" @click="handLogin()">微信授权登录</button> -->
22 23
       <!-- <van-button class="user-button" type="info" @click="handLogin()">注册</van-button> -->
@@ -28,33 +29,31 @@
28 29
 export default {
29 30
   data() {
30 31
     return {
32
+      register: require('../assets/icon/register.svg'),
31 33
       code: '' // 前端获取 code 传给后端调用相应接口
32
-    };
34
+    }
33 35
   },
34 36
   created() {
35 37
     // 从 window.location.href 中截取 code 并且赋值
36 38
     if (window.location.href.indexOf('Code_state') !== -1) {
37
-      this.code = window.location.href
38
-        .split('?')[1]
39
-        .split('=')[1]
40
-        .split('&')[0];
41
-      this.$store.commit('SET_USER_INFO', { code: this.code });
39
+      this.code = window.location.href.split('?')[1].split('=')[1].split('&')[0]
40
+      this.$store.commit('SET_USER_INFO', { code: this.code })
42 41
     }
43 42
 
44 43
     if (this.$store.state.user.code) {
45 44
       // 存在 code 直接调用接口
46
-      this.handGetUserInfo(this.code);
45
+      this.handGetUserInfo(this.code)
47 46
     }
48 47
   },
49 48
   methods: {
50 49
     handLogin() {
51
-      this.$router.push('/SetUser');
50
+      this.$router.push('/SetUser')
52 51
       // this.$store.commit('SET_USER_INFO', { code: this.code })
53 52
 
54 53
       // 重定向地址重定到当前页面,在路径获取 code
55 54
       if (process.env.NODE_ENV === 'development') {
56
-        console.log(222);
57
-        return;
55
+        console.log(222)
56
+        return
58 57
       }
59 58
       /**
60 59
        * 获取 code
@@ -67,7 +66,7 @@ export default {
67 66
       //   }
68 67
       // }
69 68
 
70
-      const hrefUrl = window.location.href;
69
+      const hrefUrl = window.location.href
71 70
 
72 71
       // const originCode = localStorage.getItem('wxcode')
73 72
       // const queryCode = getCode()
@@ -82,15 +81,15 @@ export default {
82 81
 						&response_type=code
83 82
 						&scope=snsapi_userinfo
84 83
 						&state=Code_state#wechat_redirect
85
-					`;
84
+					`
86 85
       }
87 86
     },
88 87
     handGetUserInfo(code) {
89 88
       console.log(
90 89
         '🚀 ~ file: UserCenter.vue ~ line 44 ~ handGetUserInfo ~ code',
91 90
         code
92
-      );
93
-      // 调用后端接口,参数为 code 剩下工作量交给后端即可
91
+      )
92
+      // 调用后端接口,参数为 code
94 93
       // wxLogin({
95 94
       //   data: {
96 95
       //     code: code
@@ -105,7 +104,7 @@ export default {
105 104
       // })
106 105
     }
107 106
   }
108
-};
107
+}
109 108
 </script>
110 109
 
111 110
 <style lang="less" scoped>
@@ -141,7 +140,7 @@ export default {
141 140
       width: 30px;
142 141
       margin: 0 auto;
143 142
       position: relative;
144
-      left: 15vw;
143
+      left: 18.4vw;
145 144
       top: 7.7vh;
146 145
       // position: relative;
147 146
       // top: 9vh;
@@ -151,8 +150,9 @@ export default {
151 150
     width: 100%;
152 151
     margin: 0 auto;
153 152
     // box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
154
-    .user-button {
155
-      // box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
153
+
154
+    .van-cell-group {
155
+      display: flex;
156 156
     }
157 157
   }
158 158
 }

+ 52
- 32
src/components/userPages/SetUser.vue 查看文件

@@ -1,26 +1,29 @@
1 1
 <template>
2
-  <div class="setInfo">
3
-    <van-nav-bar title="修改个人信息" left-text="返回" left-arrow @click-left="onClickLeft" />
4
-    <van-form @submit="onSubmit">
5
-      <van-field
6
-        v-model="username"
7
-        name="username"
8
-        label="姓名"
9
-        placeholder="姓名"
10
-        :rules="[{ required: true, message: '请填写姓名' }]"
11
-      />
12
-      <van-field
13
-        v-model="phone"
14
-        type="number"
15
-        name="phone"
16
-        label="手机号"
17
-        placeholder="手机号"
18
-        :rules="[{ required: true, message: '请填写手机号码' }]"
19
-      />
20
-      <div style="margin: 20px; margin-top:3em;">
21
-        <van-button round block type="info" native-type="submit">提交</van-button>
22
-      </div>
23
-    </van-form>
2
+  <div class="setInfo-box">
3
+    <div class="setInfo">
4
+      <van-nav-bar title="修改个人信息" left-text="返回" left-arrow @click-left="onClickLeft" />
5
+      <van-form @submit="onSubmit">
6
+        <van-field
7
+          v-model="username"
8
+          name="username"
9
+          label="姓名"
10
+          placeholder="姓名"
11
+          :rules="[{ required: true, message: '请填写姓名' }]"
12
+        />
13
+        <van-field
14
+          v-model="phone"
15
+          type="number"
16
+          name="phone"
17
+          maxlength="11"
18
+          label="手机号"
19
+          placeholder="手机号"
20
+          :rules="[{ required: true, message: '请填写手机号码' }]"
21
+        />
22
+        <div style="margin: 20px; margin-top:3em;">
23
+          <van-button round block type="info" native-type="submit">提交</van-button>
24
+        </div>
25
+      </van-form>
26
+    </div>
24 27
   </div>
25 28
 </template>
26 29
 
@@ -30,26 +33,43 @@ export default {
30 33
     return {
31 34
       username: '',
32 35
       phone: ''
33
-    };
36
+    }
34 37
   },
35 38
   methods: {
36 39
     onClickLeft() {
37
-      this.$router.go(-1);
40
+      this.$router.go(-1)
38 41
     },
39 42
     onSubmit(values) {
40
-      console.log('submit', values);
41
-      this.$toast.success('提示文案');
43
+      console.log('submit', values)
44
+      this.$toast.success('提示文案')
42 45
     }
43 46
   }
44
-};
47
+}
45 48
 </script>
46 49
 
47 50
 <style lang="less" scoped>
48
-.setInfo {
49
-  width: 100%;
50
-  height: 33%;
51
-  border-bottom-left-radius: 20px;
52
-  border-bottom-right-radius: 20px;
51
+.setInfo-box {
53 52
   background-color: #fff;
53
+  height: 100%;
54
+
55
+  width: 100vw;
56
+  display: flex;
57
+  .setInfo {
58
+    align-items: center;
59
+    margin: 0 auto;
60
+    width: 100%;
61
+    height: 50vh;
62
+    // border-bottom-left-radius: 20px;
63
+    // border-bottom-right-radius: 20px;
64
+    .van-form {
65
+      position: relative;
66
+      top: 25vh;
67
+      .van-field {
68
+        margin-bottom: 2em;
69
+        font-size: 17px;
70
+        font-weight: 600;
71
+      }
72
+    }
73
+  }
54 74
 }
55 75
 </style>

+ 11
- 3
src/main.js 查看文件

@@ -1,5 +1,10 @@
1 1
 import Vue from 'vue'
2 2
 import App from './App.vue'
3
+import animated from 'animate.css'
4
+import { Login } from './util/initial'
5
+
6
+import Questionnaire from './components/Questionnaire'
7
+import Loading from './components/Questionnaire/Loading.vue';
3 8
 import router from './router/index'//路由
4 9
 import store from './store';//状态管理
5 10
 import {
@@ -14,8 +19,9 @@ import {
14 19
   Toast,
15 20
   Card,
16 21
   NavBar,
17
-  Image, SwipeItem, Tag, Swipe
22
+  Image, SwipeItem, Tag, Swipe, Divider
18 23
 } from 'vant';
24
+Vue.use(Divider);
19 25
 Vue.use(Swipe);
20 26
 Vue.use(Tag);
21 27
 Vue.use(NavBar);
@@ -31,11 +37,13 @@ Vue.use(Notify);
31 37
 Vue.use(Tabbar).use(TabbarItem);
32 38
 Vue.use(Button);
33 39
 Vue.use(Icon);
34
-
40
+Vue.component('v-loading', Loading);
41
+Vue.use(Questionnaire)
42
+Vue.use(animated)
35 43
 
36 44
 // Vue.use(Tabbar);
37 45
 // Vue.use(TabbarItem);
38
-
46
+// Login()
39 47
 
40 48
 Vue.config.productionTip = false
41 49
 

+ 26
- 8
src/router/index.js 查看文件

@@ -3,9 +3,11 @@
3 3
 import Vue from 'vue'
4 4
 import Router from 'vue-router'
5 5
 import Course from '../components/Course.vue'//课程
6
-import StrongPhoto from '../components/StrongPhoto.vue'
7
-import UserCenter from '../components/UserCenter.vue'
8
-import SetUser from '../components/userPages/SetUser.vue'
6
+import ClockIn from '../components/ClockIn.vue'//打卡
7
+import StrongPhoto from '../components/StrongPhoto.vue'//精彩集锦
8
+import UserCenter from '../components/UserCenter.vue'//我的页面
9
+import Questionnaire from '../components/Questionnaire.vue'
10
+import SetUser from '../components/userPages/SetUser.vue'//修改个人信息
9 11
 // // import Login from '../Login.vue'
10 12
 
11 13
 
@@ -19,7 +21,7 @@ export default new Router({
19 21
 
20 22
 
21 23
   routes: [
22
-    //课程管理
24
+    //培训通知
23 25
     {
24 26
       path: '/',
25 27
       name: 'Course',
@@ -30,7 +32,7 @@ export default new Router({
30 32
 
31 33
 
32 34
     },
33
-    //精彩瞬间
35
+    //精彩集锦
34 36
     {
35 37
       path: '/StrongPhoto',
36 38
       name: 'StrongPhoto',
@@ -58,9 +60,25 @@ export default new Router({
58 60
       meta: {
59 61
         requireAuth: true //是否登陆
60 62
       }
61
-    }
62
-
63
-
63
+    },
64
+    //问卷页面
65
+    {
66
+      path: '/Questionnaire',
67
+      name: 'Questionnaire',
68
+      component: Questionnaire,
69
+      meta: {
70
+        requireAuth: true //是否登陆
71
+      }
72
+    },
73
+    //打卡页面
74
+    {
75
+      path: '/ClockIn',
76
+      name: 'ClockIn',
77
+      component: ClockIn,
78
+      meta: {
79
+        requireAuth: true //是否登陆
80
+      }
81
+    },
64 82
 
65 83
 
66 84
 

+ 2
- 2
src/store/index.js 查看文件

@@ -12,8 +12,8 @@ const store = new Vuex.Store({
12 12
     user: {
13 13
 
14 14
       appid: 'wxd3bab568bc42d1de',
15
-
16
-      code: '',
15
+      token: '',
16
+      code: '123',
17 17
 
18 18
     }
19 19
   },

+ 20
- 0
src/util/api.js 查看文件

@@ -1 +1,21 @@
1 1
 import request from "./request";
2
+
3
+
4
+/**
5
+ * @getBanner
6
+ *
7
+ */
8
+//  /api/wx/login
9
+export const getBanner = (params, data,) => request(`/api/wx/banner`, data, 'GET')
10
+
11
+
12
+
13
+/**
14
+ * 登录
15
+ * @param {*} id 
16
+ * @returns 
17
+ * loginParam
18
+ */
19
+export const UserLogin = (code) => request(`/api/wx/login?code=${code}`, { method: 'post' })
20
+
21
+

+ 13
- 0
src/util/initial.js 查看文件

@@ -0,0 +1,13 @@
1
+/**
2
+ * 登陆
3
+ */
4
+import { UserLogin } from './api'
5
+
6
+export function Login () {
7
+  UserLogin('123',).then(e => {
8
+    console.log(e);
9
+    console.log(22222222222222222222222);
10
+    let tokens = e.token
11
+    this.$store.commit('SET_USER_INFO', { token: tokens })
12
+  })
13
+}

+ 10
- 0
src/util/query.js 查看文件

@@ -0,0 +1,10 @@
1
+// 获取url参数
2
+export default function getUrlKey (name) {
3
+  return (
4
+    decodeURIComponent(
5
+      (new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(
6
+        location.href
7
+      ) || [, ''])[1].replace(/\+/g, '%20')
8
+    ) || null
9
+  )
10
+}

+ 30
- 56
src/util/request.js 查看文件

@@ -1,72 +1,46 @@
1
-
2
-
3
-
4
-import axios from 'axios'
5
-
6
-import { Message } from 'element-ui'
7
-// import md5 from 'js-md5'
1
+import axios from "axios";
8 2
 import store from '../store'
9
-// import routerfrom from '../router'
10 3
 
4
+// import { getQueryString } from ".";
11 5
 
6
+export default (url, options) => {
7
+  const { params, header, ...leftOptions } = options || {}
8
+  // const queryStr = getQueryString(params)
9
+  const { code, token } = store.state.user
12 10
 
11
+  const authToken = token
13 12
 
14
-export default function (url, params, methodType = 'GET') {
15
-  return new Promise((resolve, reject) => {
16
-    // const { personId, phone, appid, totalScore } = store.state.user
17
-    // const timestamp = new Date().valueOf()
18
-    // const sign = md5(appid + personId + phone + timestamp)
13
+  const tokenHeader = authToken ? { 'X-Authorization-JWT': authToken } : {}
19 14
 
20
-    // let header = {
21
-    //   'x-appid': appid,
22
-    //   'x-personid': personId,
23
-    //   'x-timestamp': timestamp,
24
-    //   'x-sign': sign,
25
-    //   'totalScore': totalScore
26
-    // }
15
+  const nwHeader = {
16
+    ...(header || {}),
17
+    ...tokenHeader,
27 18
 
19
+  }
28 20
 
21
+  return new Promise((resolve, reject) => {
29 22
     axios.request({
23
+      ...leftOptions,
30 24
       url: url,
31
-      method: methodType,
32
-      data: params,
33
-      // headers: header,
34
-      timeout: 1000 * 60,
35
-    }).then(res => {
36
-      const { code, message, data, token } = res.data
37
-
38
-      if (code === 1000) {
39
-        resolve(data)
40
-      } else {
41
-        Message.error(message)
42
-
43
-        if (code === 1001) {
44
-          // Message.error('请重新登陆')
45
-
46
-          // routerfrom.push('../Login.vue')
47
-
48
-          // this.$router.replace('../Login.vue') //replace  不记录页面 ,无法返回
25
+      header: nwHeader,
26
+      success: (res) => {
27
+        const { code, message, data, token } = res.data
28
+        if (token || data?.token) {
29
+          axios.setStorage({ key: 'token', data: token || data?.token })
49 30
         }
50
-      }
51
-
52
-
53
-
54
-    }).catch(err => {
55
-      const message = err.message || err.errMsg || err
56
-      console.error("🚀 错误~ err", err)
57
-      Message.error('请求错误', err)
58
-
59
-
60
-
61
-
31
+        if (code === 1000) {
32
+          resolve(data)
33
+        } else {
34
+          console.error(res)
35
+          reject(message?.indexOf('java') > -1 ? '系统内部错误' : message)
36
+        }
37
+      },
38
+      fail: (err) => {
39
+        const message = err.message || err.errMsg || err
62 40
 
63
-      if (err.message.includes('timeout')) {
64
-        // 请求超时
65
-        Message.error('请求超时')
41
+        reject(message)
66 42
       }
67
-      reject(message)
68
-    }).finally(() => {
69
-      // 请求结束
70 43
     })
71 44
   })
45
+
72 46
 }

+ 32
- 0
vue.config.js 查看文件

@@ -0,0 +1,32 @@
1
+// vue.config.js
2
+
3
+
4
+// vue.config.js
5
+const path = require('path')
6
+const resolve = dir => path.join(__dirname, dir)
7
+
8
+
9
+module.exports = {
10
+
11
+  devServer: {
12
+    proxy: {
13
+      '/api': {
14
+        target: "http://192.168.89.147:8080/",
15
+        // ws: true,
16
+        changeOrigin: true,
17
+        // pathRewrite: {
18
+        //   // 路径重写
19
+        //   "/api": "" // 这个意思就是以api开头的,定向到哪里, 如果你的后边还有路径的话, 会自动拼接上
20
+        // }
21
+      },
22
+    },
23
+
24
+
25
+  },
26
+  lintOnSave: false,
27
+  publicPath: "./",//在vue-cli.3.3版本后 baseUrl被废除了,因此这边要写成 publicPath。 https://cli.vuejs.org/zh/config/#vue-config-js
28
+  runtimeCompiler: true,
29
+  chainWebpack: config => {
30
+    config.resolve.alias.set("@", resolve("src"));
31
+  }
32
+}