张延森 3 gadus atpakaļ
vecāks
revīzija
3d26f03f10

+ 4
- 2
src/main.js Parādīt failu

@@ -1,7 +1,8 @@
1 1
 import Vue from 'vue'
2 2
 import 'animate.css'
3 3
 import {
4
-  Cell, CellGroup,
4
+  Cell,
5
+  CellGroup,
5 6
   Icon,
6 7
   Notify,
7 8
   Form,
@@ -12,7 +13,7 @@ import {
12 13
   Toast,
13 14
   Card,
14 15
   NavBar,
15
-  Image, SwipeItem, Tag, Swipe, Divider, Picker, Popup, List,ImagePreview 
16
+  Image, SwipeItem, Tag, Swipe, Divider, Picker, Popup, Dialog, List,ImagePreview 
16 17
 } from 'vant';
17 18
 import App from './App.vue'
18 19
 import { Login, redirect } from './util/initial'
@@ -30,6 +31,7 @@ Vue.use(Popup);
30 31
 // Vue.use(parseTime);
31 32
 Vue.use(Picker);
32 33
 Vue.use(List);
34
+Vue.use(Dialog);
33 35
 Vue.use(Divider);
34 36
 Vue.use(Swipe);
35 37
 Vue.use(Tag);

+ 1
- 1
src/util/api.js Parādīt failu

@@ -205,5 +205,5 @@ export const getQuestionInfo = (id, data) => request(`/api/wx/question/${id}`, {
205 205
 * @returns 
206 206
 * 
207 207
 */
208
-export const getQuestionAnswer = (id, data) => request(`/api/wx/questionnaire/${id}/answer`, { method: 'post', data })
208
+export const answerQuestionnaire = (id, data) => request(`/api/wx/questionnaire/${id}/answer`, { method: 'post', data })
209 209
 

+ 1
- 1
src/views/MyCollection.vue Parādīt failu

@@ -1,6 +1,6 @@
1 1
 <template>
2 2
   <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
3
-    <div class="Card-box" v-for="(item, index) in shoucangList" :key="index">
3
+    <div class="Card-box" v-for="(item, index) in shoucangList" :key="index" @click="$router.push({ name: 'ClassInfo', query: { courseId: item.targetId } })">
4 4
       <div>
5 5
         <div class="Card-box-top">
6 6
           <!-- <img :src="item.content" alt /> -->

+ 62
- 138
src/views/Questionnaire.vue Parādīt failu

@@ -1,19 +1,15 @@
1 1
 <template>
2
-  <div>
3
-    <QuestionnHome />
4
-    <!-- <img :src="backgeImg" class="ImagStyle" /> -->
5
-    <popup
6
-      :show="showPopup"
7
-      @confirm="submitForm(currentQuestion.rightAnswer)"
8
-      @cancel="cancelForm"
9
-      :showCancel="true"
10
-      :LoadingShow="LoadingShowAAA"
11
-      :title="'确定提交答案吗'"
12
-      :confirmText="`提交`"
13
-      :cancelText="`取消提交`"
2
+  <div class="question-wrapper">
3
+    <QuestionnHome :show="showFirstScreen" :content="questionnaireContent" @confirm="showFirstScreen = false" />
4
+
5
+    <van-dialog
6
+      v-model="showPopup"
7
+      title="确定提交答案吗"
8
+      show-cancel-button
9
+      @confirm="submitForm()"
14 10
     >
15
-      <p>确定要提交答案吗?提交后内容不可更改!</p>
16
-    </popup>
11
+      <p style="margin: 2em">确定要提交答案吗?</p>
12
+    </van-dialog>
17 13
 
18 14
     <!-- 页面标题 -->
19 15
     <div class="VSTD_box" v-if="questionList.length > 0">
@@ -25,27 +21,14 @@
25 21
         <!-- 循环后端  的所有题 -->
26 22
         <div class="VSTD_box_item">
27 23
           <question
28
-            :types="questionList[netx].questionType"
29
-            :question="currentQuestion"
30
-            :serial-no="netx + 1"
31
-            v-model="currentQuestion.rightAnswer"
24
+            :step="step + 1"
25
+            :steps="total"
26
+            v-model="currentQuestion"
27
+            @next="step++"
28
+            @prev="step--"
29
+            @submit="showPopup = true"
32 30
           ></question>
33
-
34
-          <div class="but-box">
35
-            <van-form class="but-box-form-item">
36
-              <van-button class="butsize" v-show="ButPrevious" @click="PreviousBut">上一题</van-button>
37
-              <van-button
38
-                type="info"
39
-                class="butsize"
40
-                v-show="Butnetx"
41
-                @click="netxBut(currentQuestion.rightAnswer)"
42
-              >下一题</van-button>
43
-              <van-button type="info" class="butsize" v-show="Butsubmit" @click="firstSubmit">提交</van-button>
44
-            </van-form>
45
-          </div>
46 31
         </div>
47
-
48
-        <!-- 提交函数  -->
49 32
       </van-form>
50 33
     </div>
51 34
 
@@ -61,8 +44,8 @@
61 44
 </template>
62 45
 
63 46
 <script>
64
-import { getQuestion, getQuestionInfo, getQuestionAnswer } from '@/util/api'
65
-// import query from '@/util/query'
47
+import { Toast } from 'vant';
48
+import { getQuestionnaire, getQuestion, answerQuestionnaire } from '@/util/api'
66 49
 
67 50
 export default {
68 51
   name: 'QuestionDetail',
@@ -74,132 +57,66 @@ export default {
74 57
   props: {},
75 58
   data() {
76 59
     return {
60
+      showFirstScreen: true,
61
+      questionnaireContent: {},
62
+
77 63
       showPopup: false,
78
-      LoadingShowAAA: false,
79
-      // backgeImg: require('../assets/bgc.png'),
80
-      netx: 0, //第一题第二题下标
81
-      startData: null,
82
-      endData: null,
83
-      ButPrevious: false, //上一题
84
-      Butsubmit: false, //提交
85
-      Butnetx: true, //下一题
86
-
87
-      indexSum: 0, //第indexSum题
88
-      // questionId: '', //试题的id
89
-      title: '', //返回的题目信息
90
-      questionList: [], //答题保存的数组
91
-
92
-      DSQ: null, //定时器,到时间自动提交
93
-      DSQTime: 0 //后端返回的结束时间
64
+      step: 0,
65
+      total: 0,
66
+      questionList: []
94 67
     }
95 68
   },
96 69
   computed: {
97 70
     currentQuestion: {
98 71
       get: function () {
99
-        return this.questionList[this.netx]
72
+        return this.questionList[this.step]
100 73
       },
101 74
       set: function (val) {
102
-        this.$set(this.questionList, this.netx, val)
75
+        this.$set(this.questionList, this.step, val)
103 76
       }
104 77
     }
105 78
   },
106
-  created() {
107
-    // findIndex 用来获取数组中第一个满足条件的元素下标
108
-    var v = this.questionList.findIndex((value, index, arr) => {
109
-      return value.a == '2'
110
-    })
111
-  },
112
-
113
-  mounted() {
114
-    this.onSearch()
79
+  watch: {
80
+    '$route.query.id': {
81
+      handler(v) {
82
+        this.loadData(v)
83
+      },
84
+      immediate: true
85
+    }
115 86
   },
116
-
117 87
   methods: {
118
-    cancelForm() {
119
-      this.showPopup = false
120
-      console.log('点击了取消')
121
-    },
88
+    loadData(id) {
89
+      // 问卷信息
90
+      getQuestionnaire(id).then((e) => {
91
+        this.questionnaireContent = e || {}
92
+      })
122 93
 
123
-    onSearch() {
124
-      getQuestion('f5a47d178019bda33a370d7a6ed1e4c3').then((res) => {
94
+      // 问题列表
95
+      getQuestion(id).then((res) => {
125 96
         console.log('题目列表', res)
126 97
         const { records, total } = res
127 98
         this.questionList = records || []
99
+        this.total = total
128 100
       })
129 101
       // let sum = 0
130 102
     },
131
-    firstSubmit() {
132
-      this.showPopup = true
133
-    },
103
+  
134 104
     submitForm(e) {
135
-      this.LoadingShowAAA = true
136
-      console.log('🚀 ~ f e', e)
137
-      // const { questionId, rightAnswer } = this.question
138
-      console.log(this.questionList)
139
-
140
-      let NEW_ARR = this.questionList.map((obj) => {
141
-        if (Array.isArray(obj.rightAnswer)) {
142
-          let sliceArray = obj.rightAnswer.slice(1)
143
-          let stringArray = sliceArray.sort().toLocaleString()
144
-
145
-          return { questionId: obj.questionId, answer: stringArray }
146
-        } else {
147
-          return { questionId: obj.questionId, answer: obj.rightAnswer }
148
-        }
149
-      })
150
-      console.log(NEW_ARR)
151
-
152
-      getQuestionAnswer(
153
-        'f5a47d178019bda33a370d7a6ed1e4c3',
154
-        // answerOpt: '22',
155
-        // answerText: '1',
156
-        // personId: this.$store.state.user.personId,
157
-        // questionId: 'f5a47d178019bda33a370d7a6ed1e4c3',
158
-        // score: '1'
159
-        NEW_ARR
160
-      ).then((e) => {
161
-        console.log(e.score, e)
162
-        // this.$store.commit('SET_USER_INFO', { scoreNumb: e.result.score })
163
-        // this.$store.commit('SET_USER_INFO', { resultInfo: e.result.resultId })
164
-        this.LoadingShowAAA = false
165
-        this.showPopup = false
166
-
167
-        this.$router.go(-1) //replace  不记录页面 ,无法返回
105
+      const toast = Toast.loading({
106
+        duration: 0, // 持续展示 toast
107
+        forbidClick: true,
108
+        message: '请稍后...',
109
+      });
110
+      answerQuestionnaire(this.$route.query.id, this.questionList).then(e => {
111
+        toast.clear();
112
+        Toast.success('感谢您的参与');
113
+        this.questionnaireContent.isAnswered = true
114
+        this.showFirstScreen = true
115
+      }).catch(e => {
116
+        toast.clear();
117
+        Toast.fail(e.message);
168 118
       })
169 119
     },
170
-
171
-    netxBut(e) {
172
-      if (e !== null) {
173
-        if (this.netx >= this.questionList.length - 2) {
174
-          this.Butnetx = false
175
-          this.Butsubmit = true
176
-        }
177
-        if (this.netx <= this.questionList.length - 2) {
178
-          this.netx = this.netx + 1
179
-          this.ButPrevious = this.ButPrevious = true
180
-          this.indexSum = this.indexSum + 1
181
-        }
182
-      } else {
183
-        this.$message.warning('请选择至少一项')
184
-      }
185
-    },
186
-
187
-    PreviousBut() {
188
-      if (this.netx >= 1) {
189
-        this.Butnetx = true
190
-        this.Butsubmit = false
191
-      }
192
-      if (this.netx <= 1) {
193
-        this.ButPrevious = this.ButPrevious = false
194
-        this.Butnetx = true
195
-      }
196
-      if (this.netx <= 0) {
197
-        console.log('???', this.netx, this.questionList.length)
198
-      } else {
199
-        this.netx = this.netx - 1
200
-        this.indexSum = this.indexSum - 1
201
-      }
202
-    }
203 120
   }
204 121
 }
205 122
 </script>
@@ -208,6 +125,13 @@ export default {
208 125
 
209 126
 
210 127
 <style lang="less" scoped>
128
+
129
+.question-wrapper {
130
+  background-image: url('~@/assets/userImag/backImag.png');
131
+  background-size: 100%;
132
+  background-repeat: no-repeat;
133
+}
134
+
211 135
 .ImagStyle {
212 136
   width: 100%;
213 137
 }

+ 1
- 1
src/views/components/Question/Answer.vue Parādīt failu

@@ -56,7 +56,7 @@ export default {
56 56
   }
57 57
 
58 58
   &.active {
59
-    background-color: #409eff;
59
+    background-color: #2CB798;
60 60
     color: #fff;
61 61
   }
62 62
 }

+ 6
- 4
src/views/components/Question/Title.vue Parādīt failu

@@ -1,8 +1,8 @@
1 1
 <template>
2 2
   <div class="question-title">
3
-    <span>{{`第${this.serialNo+1}题:`}}</span>
3
+    <span>{{serialNum}}</span>
4
+    <span>({{ formatType(qType) }}): </span>
4 5
     <span>{{title}}</span>
5
-    <span>({{ formatType(qType) }})</span>
6 6
   </div>
7 7
 </template>
8 8
 
@@ -18,8 +18,10 @@ export default {
18 18
     title: String
19 19
   },
20 20
   computed: {
21
-    content() {
22
-      return ` 第${this.serailNo}题: ${this.title} `
21
+    serialNum() {
22
+      if (!this.serialNo) return ''
23
+
24
+      return ` 第${this.serialNo}题`
23 25
     }
24 26
   },
25 27
   methods: {

+ 60
- 47
src/views/components/Question/index.vue Parādīt failu

@@ -1,14 +1,17 @@
1 1
 <template>
2
-  <div class="question-box">
3
-    <q-title v-bind="qTitleContent"></q-title>
4
-    <div style="margin-top:3em;">
2
+  <div class="question-box flex flex-column">
3
+    <div class="flex-0">
4
+      <q-title v-bind="qTitleContent" :serial-no="step"></q-title>
5
+    </div>
6
+    <div class="flex-1">
5 7
       <div class="scroll">
6
-        <div v-if="types=='textarea'" class="textareass">
7
-          <textarea @input="handleTextArea"></textarea>
8
+        <div v-if="question.questionType === 'textarea'">
9
+          <div class="textarea" contenteditable="true"></div>
10
+          <textarea rows="10" :value="question.answerText" @input="handleTextArea"></textarea>
8 11
         </div>
9 12
         <div v-else v-for="answer in question.answerList" :key="answer.answerId">
10 13
           <answer
11
-            :active="values.includes(answer.optCode)"
14
+            :active="answerValues.includes(answer.optCode)"
12 15
             :option="answer.optCode"
13 16
             :label="answer.content"
14 17
             @click="handleAnswer(answer.optCode)"
@@ -16,6 +19,17 @@
16 19
         </div>
17 20
       </div>
18 21
     </div>
22
+    <div class="flex-0 flex">
23
+      <div class="flex-1 turn-btn" v-if="step > 1">
24
+        <van-button plain round block type="warning" @click="$emit('prev')">上一题</van-button>
25
+      </div>      
26
+      <div class="submit turn-btn flex-1" v-if="step === steps">
27
+        <van-button plain round block type="info" @click="$emit('submit')">提 交</van-button>
28
+      </div>
29
+      <div class="flex-1 turn-btn" v-if="step < steps">
30
+        <van-button plain round block type="info" @click="$emit('next')">下一题</van-button>
31
+      </div>
32
+    </div>
19 33
   </div>
20 34
 </template>
21 35
 
@@ -29,30 +43,23 @@ export default {
29 43
   },
30 44
   props: {
31 45
     value: {
32
-      type: [Array, String]
33
-    },
34
-    question: {
35 46
       type: Object,
36 47
       default: () => ({
37 48
         rightAnswer: '',
38 49
         answerList: []
39 50
       })
40 51
     },
41
-    serialNo: {
42
-      type: Number,
43
-      required: true
44
-    },
45
-    types: {
46
-      type: String
47
-    }
52
+    step: Number,
53
+    steps: Number,
48 54
   },
49 55
   data() {
50
-    return {
51
-      answerValues: {}
52
-    }
56
+    return {}
53 57
   },
54 58
 
55 59
   computed: {
60
+    question() {
61
+      return this.value;
62
+    },
56 63
     qTitleContent() {
57 64
       return {
58 65
         serialNo: this.question.sortNo,
@@ -61,34 +68,32 @@ export default {
61 68
       }
62 69
     },
63 70
 
64
-    values() {
71
+    answerValues() {
65 72
       // 为了便捷处理, 不同的问题类型。所有的答案统一处理为数组
66
-      return Array.isArray(this.value) ? this.value : [this.value]
73
+      return (this.value.answerOpt || '').split(',').filter(x => x !== '')
67 74
     }
68 75
   },
69 76
 
70 77
   methods: {
71 78
     handleTextArea(e) {
72
-      // console.log(e.target.value)
73
-      this.handleAnswer(e.target.value)
79
+      // 更新 answerText 字段
80
+      const data = { ...this.value, answerText: e.target.value }
81
+      this.$emit('input', data)
74 82
     },
75 83
     handleAnswer(opt) {
76
-      console.log('🚀 ~ file: index.vue ~ line 68 ~ handleAnswer ~ opt', opt)
77
-      const isChecked = this.values.includes(opt)
84
+      // 更新 answerOpt 字段
85
+      const isChecked = this.answerValues.includes(opt)
86
+      let data = { ...this.value }
78 87
 
79 88
       // 如果是多选
80 89
       if (this.question.questionType === 'checkBox') {
81
-        if (isChecked) {
82
-          this.$emit(
83
-            'input',
84
-            this.values.filter((x) => x !== opt)
85
-          )
86
-        } else {
87
-          this.$emit('input', [...this.values, opt])
88
-        }
90
+        const answers = isChecked ? this.answerValues.filter((x) => x !== opt) : this.answerValues.concat(opt);
91
+        data.answerOpt = answers.filter(x => x !== null && x !== undefined || x !== '').sort().join(',');
89 92
       } else {
90
-        this.$emit('input', opt)
93
+        data.answerOpt = opt;
91 94
       }
95
+      
96
+      this.$emit('input', data)
92 97
     }
93 98
   }
94 99
 }
@@ -97,29 +102,37 @@ export default {
97 102
 <style lang="less" scoped>
98 103
 .question-box {
99 104
   width: 80vw;
105
+  height: calc(100vh - 6em);
100 106
   margin: 0 auto;
107
+  margin-top: 3em;
101 108
   position: relative;
102
-  top: 5vh;
103
-  left: -4%;
104 109
   background: white;
105 110
   box-shadow: 0px 8px 38px 0px rgba(0, 0, 0, 0.12);
106 111
   border-radius: 12px;
107
-  padding: 1em 15px 2em 15px;
112
+  padding: 1em 2em;
113
+  box-sizing: border-box;
108 114
 
109 115
   .scroll {
110 116
     padding-top: 5px;
111 117
     width: 100%;
112
-    height: 46vh;
118
+    height: calc(100% - 6px);
113 119
     overflow: auto;
114
-    .textareass {
115
-      width: 93%;
116
-      > textarea {
117
-        width: 100%;
118
-        height: 20vh;
119
-        border: 1px solid rgb(192, 191, 191);
120
-        padding: 5px 8px;
121
-        font-size: 14px;
122
-      }
120
+
121
+    textarea {
122
+      width: 100%;
123
+      height: 90%;
124
+      border: 1px solid #2CB798;
125
+      padding: 1em;
126
+      box-sizing: border-box;
127
+      font-size: 14px;
128
+      overflow-y: auto;
129
+      overflow-x: hidden;
130
+    }
131
+  }
132
+
133
+  .turn-btn {
134
+    & + .turn-btn {
135
+      margin-left: 2em;
123 136
     }
124 137
   }
125 138
 }

+ 49
- 42
src/views/components/QuestionnHome.vue Parādīt failu

@@ -1,65 +1,72 @@
1 1
 <template>
2
-  <div :class="{'QuestionnHome-box':true,'actveBox':isActve}">
3
-    <h1>{{Content.name||''}}</h1>
4
-    <div @click="goTop">点我消失</div>
2
+  <div class="QuestionnHome-box" :class="{hideBox: !show}">
3
+    <div class="content">
4
+      <h3>{{content.name||''}}</h3>
5
+      <van-button
6
+        v-if="!content.isAnswered"
7
+        plain
8
+        round
9
+        block
10
+        type="primary"
11
+        size="normal"
12
+        @click="$emit('confirm')"
13
+      >开 始</van-button>
14
+      <div v-else style="text-align: center">
15
+        <p>您已完成当前问卷</p>
16
+        <p>欢迎继续参与我们后期的调研</p>
17
+      </div>
18
+    </div>
5 19
   </div>
6 20
 </template>
7 21
 
8 22
 <script>
9
-import { getQuestionnaire } from '@/util/api'
10
-
11 23
 export default {
12 24
   name: 'QuestionnHome',
13 25
   props: {
14
-    active: Boolean
15
-  },
16
-  data() {
17
-    return {
18
-      isActve: false,
19
-      Content: null
26
+    show: Boolean,
27
+    content: {
28
+      type: Object,
29
+      default: () => ({})
20 30
     }
21 31
   },
22
-  mounted() {
23
-    this.onLoadQuestionn()
24
-  },
25
-  methods: {
26
-    goTop() {
27
-      if (this.Content.isAnswered) {
28
-        this.$toast('您已回答过此问卷!')
29
-      } else {
30
-        this.isActve = true
31
-      }
32
-    },
33
-    onLoadQuestionn() {
34
-      getQuestionnaire('f5a47d178019bda33a370d7a6ed1e4c3').then((e) => {
35
-        this.Content = e
36
-      })
37
-    }
38
-  }
39 32
 }
40 33
 </script>
41 34
 
42 35
 <style lang="less" scoped>
43 36
 .QuestionnHome-box {
37
+  position: fixed;
38
+  top: 0;
39
+  left: 0;
40
+
44 41
   width: 100vw;
45 42
   height: 100vh;
46
-  z-index: 5000;
43
+  z-index: 999;
44
+  transition: top .6s ease;
45
+
47 46
   background-color: #fff;
48
-  display: flex;
49
-  position: absolute;
50
-  flex-direction: column;
51
-  top: 0;
52
-  transition: top 1.4s ease;
47
+  background-image: url('~@/assets/userImag/backImag.png');
48
+  background-size: 100%;
49
+  background-repeat: no-repeat;
53 50
 
51
+  display: flex;
52
+  justify-content: center;
54 53
   align-items: center;
55
-  & > div {
56
-    width: 100px;
57
-    height: 100px;
58
-    border: 1px solid red;
59
-    margin: 0 auto;
54
+
55
+  &.hideBox {
56
+    top: -150vh;
60 57
   }
58
+
59
+  .content {
60
+    width: 100%;
61
+    padding: 0 3em;
62
+    box-sizing: border-box;
63
+
64
+    & > h3 {
65
+      text-align: center;
66
+      margin-bottom: 10em;
67
+    }
68
+  }
69
+
61 70
 }
62
-.actveBox {
63
-  top: -250vh;
64
-}
71
+
65 72
 </style>

+ 1
- 1
src/views/userPages/SetUser.vue Parādīt failu

@@ -1,7 +1,7 @@
1 1
 <template>
2 2
   <div class="setInfo-box">
3 3
     <div class="setInfo">
4
-      <van-nav-bar title="修改个人信息" left-text="返回" left-arrow @click-left="onClickLeft" />
4
+      <!-- <van-nav-bar title="修改个人信息" left-text="返回" left-arrow @click-left="onClickLeft" /> -->
5 5
       <van-form @submit="onSubmit">
6 6
         <van-field
7 7
           v-model="personInfo.name"