Răsfoiți Sursa

feat:答题逻辑变更

钱新宇 2 luni în urmă
părinte
comite
511f826c97
5 a modificat fișierele cu 238 adăugiri și 92 ștergeri
  1. 8 7
      pages/user/index.vue
  2. 5 4
      pages/video/detail.vue
  3. 204 38
      pages/video/exam.vue
  4. 8 10
      pages/video/index.vue
  5. 13 33
      pages/video/record.vue

+ 8 - 7
pages/user/index.vue

@@ -36,19 +36,19 @@
     </view>
     <view class="navigator_list">
       <navigator class="navigator_item" url="/pages/orders/index">
-        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/icon/orders.png" mode=""></image>
+        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/user/orders.png" mode=""></image>
         <view class="navigator_title">预约</view>
       </navigator>
       <navigator class="navigator_item" url="/pages/coupon/index">
-        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/icon/coupon.png" mode=""></image>
+        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/user/coupon.png" mode=""></image>
         <view class="navigator_title">优惠券</view>
       </navigator>
       <navigator class="navigator_item" url="/pages/score/orders">
-        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/icon/score_gift.png" mode=""></image>
+        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/user/score.png" mode=""></image>
         <view class="navigator_title">积分订单</view>
       </navigator>
       <navigator class="navigator_item" url="/pages/recruitment/index">
-        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/icon/score_gift.png" mode=""></image>
+        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/user/newuser.png" mode=""></image>
         <view class="navigator_title">拉新活动</view>
       </navigator>
     </view>
@@ -58,7 +58,7 @@
         <view class="navigator_title">资讯</view>
       </navigator>
       <navigator class="navigator_item" url="/pages/video/index">
-        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/user/article.png" mode=""></image>
+        <image class="navigator_image" src="https://kailin-mp.oss-cn-shenzhen.aliyuncs.com/static/user/video.png" mode=""></image>
         <view class="navigator_title">学习</view>
       </navigator>
     </view>
@@ -255,8 +255,9 @@ export default {
     float: left;
     height: 160rpx;
     display: block;
-    margin: 0rpx auto;
+    // margin: 0rpx auto;
     text-align: center;
+    width: 25%;
     .navigator_image {
       width: 80rpx;
       height: 80rpx;
@@ -264,7 +265,7 @@ export default {
       border-radius: 5rpx;
     }
     .navigator_title {
-      width: 120rpx;
+      width: 100%;
       display: block;
       font-size: 30rpx;
       line-height: 40rpx;

+ 5 - 4
pages/video/detail.vue

@@ -245,7 +245,7 @@ export default {
         })
         .then((re) => {
           if (re.code == "success") {
-            console.log("上报成功");
+            console.log("上报成功", video_playtime, status);
           }
         });
     },
@@ -300,6 +300,7 @@ export default {
       const _this = this;
       this.videoContext.pause();
       this.videoContext.exitFullScreen();
+      this._postVideoDuration(this.currentTime, 1);
       uni.showModal({
         title: "学习结束",
         content: "恭喜您学习结束,是否查看报告?",
@@ -360,13 +361,13 @@ export default {
   }
   .bigScreen {
     position: absolute;
-    bottom: -60%;
+    bottom: -65%;
     z-index: 998;
     height: 20%;
     /* background-color: red; */
     background-color: rgba(255, 255, 255, 0.007);
-    margin-left: 70px;
-    width: 80%;
+    margin-left: 140px;
+    width: 65%;
   }
 }
 .video_title {

+ 204 - 38
pages/video/exam.vue

@@ -1,25 +1,65 @@
 <template>
   <view>
-    <swiper class="question_content">
-      <swiper-item v-for="(item, index) in question_Info.question_list" :key="index">
-        <view class="question_item">
-          <view class="question_content_text">{{ item.question_title }}</view>
-          <view class="question_options">
-            <view v-for="(option, cIndex) in item.answer_list" :key="index" :class="['question_answer', { active: item.checkAnswer == option.id }]" @click="_selectAnswer(index, option.id)">
-              <view :class="['question_index', { active: item.checkAnswer == option.id }]">{{ option.value.substring(0, 1) }}</view>
-              {{ option.value.substring(2) }}
-            </view>
+    <view class="question_content">
+      <view class="question_item">
+        <view class="question_title">第&nbsp;{{ currentQuestionIndex + 1 }}&nbsp;题&nbsp;/&nbsp;共&nbsp;{{ question_Info.question_total }}&nbsp;题</view>
+        <view class="question_content_text">{{ question_map.question_title }}</view>
+        <view class="question_tip"> 请从以下选项中选出正确答案 </view>
+        <view class="question_options">
+          <view
+            v-for="(option, cIndex) in question_map.answer_list"
+            :key="cIndex"
+            :class="[
+              'question_answer',
+              { active: question_map.selectAnswer == option.id },
+              { error: question_map.checkAnswer && question_map.checkAnswer == option.id && question_map.checkAnswer !== question_map.answer_id },
+            ]"
+            @click="_selectAnswer(option.id)"
+          >
+            <view
+              :class="[
+                'question_index',
+                { active: question_map.selectAnswer == option.id },
+                { error: question_map.checkAnswer && question_map.checkAnswer == option.id && question_map.checkAnswer !== question_map.answer_id },
+              ]"
+              >{{ option.value.substring(0, 1) }}</view
+            >
+            {{ option.value.substring(2) }}
           </view>
         </view>
-      </swiper-item>
-    </swiper>
-    <view class="bottom_btn">
-      <view class="answer_info"
+        <view class="question_result" v-if="question_map.checkAnswer">
+          <icon :type="question_map.answer_id == question_map.checkAnswer ? 'success' : 'cancel'" size="24" />
+          <view :class="['title', question_map.checkAnswer == question_map.answer_id ? 'green' : 'red']">{{
+            question_map.answer_id == question_map.checkAnswer ? "恭喜您,答对啦!" : "很遗憾,答错了"
+          }}</view>
+          <view class="tip">本题的正确选项为:{{ answer_number[question_map.answer_index] }}</view>
+        </view>
+      </view>
+    </view>
+    <view class="bottom_btn" v-if="question_Info.question_list.length !== 0">
+      <!-- <view class="answer_info"
         >已答&nbsp;<view style="color: #5045e6">{{ answeredCount }}</view
         >&nbsp;题,共&nbsp;{{ question_Info.question_total }}&nbsp;题</view
+      > -->
+      <!-- <view class="submit-btn" @click="_handleSubmit">交卷</view> -->
+      <view
+        :class="[
+          'submit-btn',
+          {
+            disabled: !question_map.selectAnswer,
+          },
+        ]"
+        @click="_handleSubmitAnswer"
+        v-if="!question_map.checkAnswer"
       >
-      <view class="submit-btn" @click="_handleSubmit">交卷</view>
+        提交
+      </view>
+      <view v-if="question_map.checkAnswer" style="display: flex; justify-content: space-between; width: 100%">
+        <view class="prev_btn" @click="_prevQuestion">上一题</view>
+        <view class="next_btn" @click="_nextQuestion">{{ currentQuestionIndex !== question_Info.question_list.length - 1 ? "下一题" : "查看报告" }}</view>
+      </view>
     </view>
+    <Empty v-if="question_Info.question_list.length == 0" text="----- 本课程还没有配置习题 -----" />
     <uni-popup ref="tipRef" type="center" @change="_changeTip">
       <view class="tip_content">
         <view code>&nbsp;{{ "<" }}&nbsp; &nbsp;{{ ">" }}&nbsp;</view>
@@ -30,11 +70,16 @@
 </template>
 
 <script>
+import Empty from "@/components/Empty/Empty.vue";
 export default {
+  components: { Empty },
   data() {
     return {
+      currentQuestionIndex: 0,
       course_id: null,
       question_Info: {},
+      question_map: {}, // 初始化 question_map
+      answer_number: ["A", "B", "C", "D", "E", "F"],
     };
   },
   onLoad(param) {
@@ -73,12 +118,31 @@ export default {
         })
         .then((re) => {
           if (re.code == "success") {
+            re.data.question_list.map((item) => {
+              item.answer_index = item.answer_list.findIndex((answer) => answer.is_answer == 1);
+              item.answer_id = item.answer_list.find((answer) => answer.is_answer == 1).id;
+              item.selectAnswer = null; // 初始化 selectAnswer 属性
+            });
+            console.log(re.data);
             this.question_Info = re.data;
+            this.question_map = re.data.question_list[this.currentQuestionIndex];
           }
         });
     },
-    _selectAnswer(index, id) {
-      this.question_Info.question_list[index].checkAnswer = id;
+    _selectAnswer(id) {
+      //已经回答的题目不能再答了
+      if (this.question_map.checkAnswer) {
+        return;
+      }
+      // this.question_map.selectAnswer = id;
+      this.$set(this.question_map, "selectAnswer", id);
+      console.log(this.question_map);
+    },
+    _handleSubmitAnswer() {
+      if (!this.question_map.selectAnswer) {
+        return;
+      }
+      this.question_map.checkAnswer = this.question_map.selectAnswer;
     },
     _handleSubmit() {
       if (this.answeredCount !== this.question_Info.question_total) {
@@ -98,7 +162,7 @@ export default {
       }
     },
     _handleIn() {
-      const _this = this
+      const _this = this;
       const question_list = this.question_Info.question_list.filter((item) => item.checkAnswer);
       const answer_list = question_list.map((item) => {
         return { question_id: item.question_id, answer_id: item.checkAnswer };
@@ -114,26 +178,58 @@ export default {
         )
         .then((re) => {
           if (re.code == "success") {
-            uni.showModal({
-              title: "完成测评",
-              content: "恭喜您完成测评,是否查看报告",
-              confirmText: "查看报告",
-              cancelText: "返回列表",
-              success(res) {
-                if (res.confirm) {
-                  uni.redirectTo({
-                    url: `/pages/video/record?type=exam&record_id=${_this.question_Info.record_id}`,
-                  });
-                } else {
-                  uni.redirectTo({
-                    url: `/pages/video/index`,
-                  });
-                }
-              },
+            uni.redirectTo({
+              url: `/pages/video/record?type=exam&record_id=${_this.question_Info.record_id}`,
             });
+            // uni.showModal({
+            //   title: "完成测评",
+            //   content: "恭喜您完成测评,是否查看报告",
+            //   confirmText: "查看报告",
+            //   cancelText: "返回列表",
+            //   success(res) {
+            //     if (res.confirm) {
+            //       uni.redirectTo({
+            //         url: `/pages/video/record?type=exam&record_id=${_this.question_Info.record_id}`,
+            //       });
+            //     } else {
+            //       uni.redirectTo({
+            //         url: `/pages/video/index`,
+            //       });
+            //     }
+            //   },
+            // });
           }
         });
     },
+    _prevQuestion() {
+      if (this.currentQuestionIndex === 0) {
+        uni.showToast({
+          title: "已是第一题啦!",
+          icon: "none",
+          duration: 2000,
+        });
+        return;
+      }
+      this.currentQuestionIndex--;
+      this.question_map = this.question_Info.question_list[this.currentQuestionIndex];
+    },
+    _nextQuestion() {
+      try {
+        if (this.currentQuestionIndex == this.question_Info.question_list.length - 1) {
+          this._handleIn();
+          return;
+        }
+        this.question_Info.question_list[this.currentQuestionIndex] = this.question_map;
+        this.currentQuestionIndex++;
+        this.question_map = this.question_Info.question_list[this.currentQuestionIndex];
+        console.clear();
+        console.log(this.currentQuestionIndex, "currentQuestionIndex");
+        console.log(this.question_map, "question_map");
+        console.log(this.question_Info.question_list, "this.question_Info.question_list");
+      } catch (error) {
+        console.log(error);
+      }
+    },
   },
 };
 </script>
@@ -150,20 +246,30 @@ export default {
   gap: 20rpx;
 }
 .question_content {
-  height: calc(100vh - 150rpx);
+  height: calc(100vh - 200rpx);
   background-color: #f2f2f2;
   width: 100%;
   box-sizing: border-box;
   padding: 30rpx 20rpx;
+  background-color: #f9fbfc;
   .question_item {
     width: 100%;
     padding: 30rpx 20rpx;
     box-sizing: border-box;
-    border: 2rpx solid #ddd;
+    // border: 2rpx solid #ddd;
     border-radius: 8rpx;
+    // background-color: #fff;
+    .question_title {
+      color: #999;
+      margin-bottom: 40rpx;
+    }
+    .question_tip {
+      color: #999999;
+      margin-bottom: 40rpx;
+    }
     .question_content_text {
       font-size: 32rpx;
-      margin-bottom: 80rpx;
+      margin-bottom: 40rpx;
       font-weight: bold;
     }
     .question_options {
@@ -171,6 +277,7 @@ export default {
       flex-direction: column;
       gap: 40rpx;
       width: 100%;
+
       .question_index {
         border: 2rpx solid #ddd;
         border-radius: 50%;
@@ -184,6 +291,10 @@ export default {
           background-color: #5045e6;
           color: #fff;
         }
+        &.error {
+          background-color: #ef4444;
+          border-color: #ef4444;
+        }
       }
       .question_answer {
         height: 80rpx;
@@ -191,11 +302,39 @@ export default {
         border-radius: 20rpx;
         display: flex;
         align-items: center;
+        border: 2rpx solid #ddd;
+        box-sizing: border-box;
+        padding: 20rpx 20rpx;
         &.active {
           color: #5045e6;
+          border-color: #5045e6;
+        }
+        &.error {
+          border-color: #ef4444;
+          background-color: #fef2f2;
+          color: #ef4444;
         }
       }
     }
+    .question_result {
+      display: flex;
+      flex-direction: column;
+      gap: 20rpx;
+      width: 100%;
+      justify-content: center;
+      align-items: center;
+      border: 2rpx solid #ddd;
+      margin-top: 40rpx;
+      padding: 36rpx;
+      box-sizing: border-box;
+      border-radius: 20rpx;
+      .red {
+        color: red;
+      }
+      .green {
+        color: green;
+      }
+    }
   }
 }
 .bottom_btn {
@@ -203,13 +342,35 @@ export default {
   bottom: 0;
   left: 0;
   width: 100%;
-  height: 150rpx;
+  height: 200rpx;
   border-top: 4rpx solid #ddd;
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 0 40rpx;
   box-sizing: border-box;
+  .prev_btn {
+    background-color: #fff;
+    color: #333;
+    font-size: 28rpx;
+    width: 45%;
+    height: 80rpx;
+    line-height: 80rpx;
+    border-radius: 8rpx;
+    box-shadow: 2rpx 2rpx 8rpx rgba(0, 0, 0, 0.1);
+    text-align: center;
+  }
+  .next_btn {
+    background-color: #5045e6;
+    color: #fff;
+    font-size: 28rpx;
+    width: 45%;
+    height: 80rpx;
+    line-height: 80rpx;
+    border-radius: 8rpx;
+    box-shadow: 2rpx 2rpx 8rpx rgba(0, 0, 0, 0.1);
+    text-align: center;
+  }
   .answer_info {
     display: flex;
     align-items: baseline;
@@ -218,12 +379,17 @@ export default {
     background-color: #5045e6;
     color: #fff;
     font-size: 28rpx;
-    width: 200rpx;
+    width: 100%;
     height: 80rpx;
     line-height: 80rpx;
     border-radius: 8rpx;
     box-shadow: 2rpx 2rpx 8rpx rgba(0, 0, 0, 0.1);
     text-align: center;
+    &.disabled {
+      background-color: #ccc;
+      color: #999;
+      cursor: not-allowed;
+    }
   }
 }
 </style>

+ 8 - 10
pages/video/index.vue

@@ -15,9 +15,6 @@
           </view>
         </view>
         <view class="video_btn">
-          <button class="to_learn" @click.stop="goDetail(item.id)">
-            开始学习
-          </button>
           <button
             class="after_exam"
             v-if="item.learn_status > 0"
@@ -25,6 +22,9 @@
           >
             {{ item.report_id > 0 ? "查看报告" : "课后评测" }}
           </button>
+          <button class="to_learn" @click.stop="goDetail(item.id)">
+            开始学习
+          </button>
         </view>
       </view>
     </view>
@@ -171,7 +171,7 @@ export default {
       margin-top: 10rpx;
       .to_learn {
         margin: 0;
-        color: #66b66a;
+        color: #fff;
         border: none;
         width: 140rpx;
         height: 50rpx;
@@ -180,14 +180,14 @@ export default {
         padding: 0rpx 0rpx;
         text-align: center;
         border-radius: 10rpx;
-        background-color: #e8f4e8;
+        background-color: #5045e6;
       }
       .to_learn::after {
         border: none;
       }
       .after_exam {
         margin: 0;
-        color: #66b66a;
+        color: #5045e6;
         border: none;
         width: 140rpx;
         height: 50rpx;
@@ -196,10 +196,8 @@ export default {
         padding: 0rpx 0rpx;
         text-align: center;
         border-radius: 10rpx;
-        background-color: #e8f4e8;
-      }
-      .after_exam::after {
-        border: none;
+        background-color: #fff;
+        border: 1px solid #5045e6;
       }
     }
 

+ 13 - 33
pages/video/record.vue

@@ -2,25 +2,14 @@
   <view class="report_content">
     <view class="header">
       <view class="header_content">
-        <view class="title"
-          >本次{{ type == "exam" ? "测评" : "学习" }}概览</view
-        >
+        <view class="title">本次{{ type == "exam" ? "测评" : "学习" }}概览</view>
         <view class="content">
           <view class="content_row">
-            <view class="main">{{
-              type == "exam"
-                ? reportInfo.exam_time
-                : (
-                    (reportInfo.video_lasttime - reportInfo.video_inittime) /
-                    60
-                  ).toFixed(2)
-            }}</view>
-            <view class="tip">学习时长(分钟)</view>
+            <view class="main">{{ type == "exam" ? formatTime(reportInfo.exam_time) : formatTime(reportInfo.video_lasttime - reportInfo.video_inittime) }}</view>
+            <view class="tip">学习时长</view>
           </view>
           <view class="content_row">
-            <view class="main">{{
-              reportInfo.isanswer_total + "/" + reportInfo.answer_total
-            }}</view>
+            <view class="main">{{ reportInfo.isanswer_total + "/" + reportInfo.answer_total }}</view>
             <view class="tip">答对题目</view>
           </view>
           <view class="content_row">
@@ -33,22 +22,10 @@
     <view class="content">
       <view class="title">答题情况</view>
       <view class="content_list">
-        <view
-          class="conent_main"
-          v-for="(item, index) in queston_list"
-          :key="index"
-        >
+        <view class="conent_main" v-for="(item, index) in queston_list" :key="index">
           <view class="item_num">
-            <view class="item_answer"
-              ><icon
-                :type="item.is_answer == 0 ? 'cancel' : 'success'"
-                size="20"
-              />
-              &nbsp;第{{ index + 1 }}题</view
-            >
-            <view :style="item.get_score > 0 ? 'color:green' : 'color:red'"
-              >+{{ item.get_score }}&nbsp;积分</view
-            >
+            <view class="item_answer"><icon :type="item.is_answer == 0 ? 'cancel' : 'success'" size="20" /> &nbsp;第{{ index + 1 }}题</view>
+            <view :style="item.get_score > 0 ? 'color:green' : 'color:red'">+{{ item.get_score }}&nbsp;积分</view>
           </view>
           <view class="item_title">{{ item.question_title }}</view>
         </view>
@@ -56,9 +33,7 @@
     </view>
     <view class="bottom_btn">
       <view class="submit_btn defult" @click="_backList">返回课程列表</view>
-      <view class="submit_btn" @click="_continue">{{
-        type == "exam" ? "重新练习" : "继续课后评测"
-      }}</view>
+      <view class="submit_btn" @click="_continue">{{ type == "exam" ? "重新练习" : "继续课后评测" }}</view>
     </view>
   </view>
 </template>
@@ -133,6 +108,11 @@ export default {
           }
         });
     },
+    formatTime(seconds) {
+      const minutes = Math.floor(seconds / 60);
+      const remainingSeconds = seconds % 60;
+      return `${String(minutes).padStart(2, "0")}:${String(remainingSeconds).padStart(2, "0")}`;
+    },
   },
 };
 </script>