Browse Source

三力测试结构修改5

JXDS18FUJT 1 year ago
parent
commit
1a3daf8d04

+ 48 - 0
src/components/m-do-topic/m-do-topic.vue

@@ -1831,6 +1831,54 @@ export default {
           });
 
         break;
+      case "three":
+      storageName =
+        uni.getStorageSync("userInfo").xcxOpenid +
+        "_userThreeIds_" +
+        9;
+        api.exam
+          .studentQuestion2InfoGetQuestionInfoByIds({
+            ids: uni.getStorageSync(storageName)
+              ? uni
+                  .getStorageSync(storageName)
+                  .map((item) => {
+                    return item.id;
+                  })
+                 
+              : null,
+          })
+          .then((res) => {
+            console.log(res);
+            res.rows.forEach((element) => {
+              element.optsArr = [];
+              element.opts.split("-").forEach((item, index) => {
+                if (element.questionType == 3) {
+                  element.optsArr.push({
+                    selected: false,
+                    value: item,
+                    index: index,
+                    isAnswer: element.answer.split("-").includes(item),
+                  });
+                } else {
+                  element.optsArr.push({
+                    selected: false,
+                    value: item,
+                    index: index,
+                    isAnswer: item === element.answer,
+                  });
+                }
+              });
+              element.isCompleted = false;
+              element.userAnswer = [];
+            });
+            that.problemListTotal = res.total;
+            that.problemList = res.rows;
+            origProblemList = JSON.parse(JSON.stringify(res.rows));
+            that.$emit("update:problemListTotal", res.rows.length);
+
+            uni.hideLoading();
+          });
+        break;
       default:
         api.exam
           .studentQuestion2InfoList({

+ 177 - 16
src/otherPages/collection/index.vue

@@ -32,7 +32,7 @@
             () => {
               type = 'three';
             }
-          " style="left: 460rpx;color: #8a9099; background: #f2f3f5" class="choose-text1"> 三力收藏 </view>
+          " style="left: 460rpx; background: #f2f3f5;color: #8a9099;" class="choose-text1"> 三力收藏 </view>
         <view class="choose-text2" style="display: flex">
           <view class=""> 共 {{ wrongListCount }} 题 </view>
           <image
@@ -88,12 +88,12 @@
         >
           做错题
         </view>
-        <view style="left: 230rpx" class="choose-text1"> 收藏题 </view>
+        <view style="left: 230rpx;color: #00a748;" class="choose-text1"> 收藏题 </view>
         <view   @click="
             () => {
               type = 'three';
             }
-          " style="left: 460rpx;background: #f2f3f5;" class="choose-text1"> 三力收藏 </view>
+          " style="left: 460rpx;background: #f2f3f5;color: #8a9099;" class="choose-text1"> 三力收藏 </view>
 
         <view class="choose-text2" style="display: flex">
           <view class=""> 共 {{ collectionListCount }} 题 </view>
@@ -138,7 +138,7 @@
         <image
           style="width: 100%"
           mode="widthFix"
-          src="https://ndata.zzxcx.net/ctjk/mp-wx/collection/collectionBg3.png"
+          src="https://ndata.zzxcx.net/ctjk/mp-wx/collection/threeBg3.png"
         ></image>
         <view
           @click="
@@ -155,13 +155,13 @@
             () => {
               type = 'collect';
             }
-          " style="left: 230rpx;background: #f2f3f5;" class="choose-text1"> 收藏题 </view>
-        <view style="left: 460rpx;" class="choose-text1"> 三力收藏 </view>
+          " style="left: 230rpx;background: #f2f3f5;color: #8a9099;" class="choose-text1"> 收藏题 </view>
+        <view style="left: 460rpx;color: #FE7918;" class="choose-text1"> 三力收藏 </view>
 
         <view class="choose-text2" style="display: flex">
-          <view class=""> 共 {{ collectionListCount }} 题 </view>
+          <view class=""> 共 {{ threeListCount }} 题 </view>
           <image
-            @tap.stop="goExercise('collect')"
+            @tap.stop="goExercise('three')"
             mode="widthFix"
             class="goArrow"
             :src="goArrow"
@@ -171,8 +171,8 @@
           <view
             :hover-stop-propagation="true"
             data-type="collect"
-            @tap.stop="clearTopics('collect')"
-            style="color: #00a748"
+            @tap.stop="clearTopics('three')"
+            style="color: #FE7918;background-color: #FFE7D6;"
             class="clear"
           >
             清空收藏
@@ -182,10 +182,10 @@
             data-type="collect"
             @tap.stop="
               () => {
-                collectSyncShow = true;
+                threeSyncShow = true;
               }
             "
-            style="color: #00a748"
+            style="color: #FE7918;background-color: #FFE7D6;"
             class="sync"
           >
             同步收藏
@@ -246,7 +246,33 @@
         title="同步收藏"
       />
     </van-popup>
-    <view v-show="!wrongSyncShow && !collectSyncShow" class="wxad">
+    <van-popup
+      @close="
+        () => {
+          threeSyncShow = false;
+        }
+      "
+      zIndex="1001"
+      position="bottom"
+      :show="threeSyncShow"
+    >
+      <van-picker
+        @cancel="
+          () => {
+            threeSyncShow = false;
+          }
+        "
+        @confirm="syncThreeQuestion"
+        :columns="[
+          { text: '合并本机和云端三力收藏', type: 'three', value: 0 },
+          { text: '备份本机收藏到三力云端', type: 'three', value: 1 },
+          { text: '恢复云端收藏到三力本机', type: 'three', value: 2 },
+        ]"
+        show-toolbar
+        title="同步收藏"
+      />
+    </van-popup>
+    <view v-show="!wrongSyncShow && !collectSyncShow&&!threeSyncShow" class="wxad">
       <ad
         :ad-intervals="100"
         ad-type="video"
@@ -275,6 +301,7 @@ export default {
       goArrow: "https://ndata.zzxcx.net/ctjk/mp-wx/collection/right_arrow.png",
       collectionBg:
         "https://ndata.zzxcx.net/ctjk/mp-wx/collection/collectionBg3.png",
+        threeBg:"https://ndata.zzxcx.net/ctjk/mp-wx/collection/threeBg3.png",
       collectionHeader: "https://ndata.zzxcx.net/ctjk/mp-wx/carVideo/banner.png",
       query: {
         questionIds: "",
@@ -287,11 +314,14 @@ export default {
       },
       wrongSyncShow: false,
       collectSyncShow: false,
+      threeSyncShow:false,
       wrongList: [],
       wrongListCount: 0,
 
       collectionList: [],
       collectionListCount: 0,
+      threeList:[],
+      threeListCount:0
     };
   },
   onLoad(query) {
@@ -306,14 +336,19 @@ export default {
       uni.getStorageSync("userInfo").xcxOpenid +
       "_userCollectionIds_" +
       this.query.subject;
-
+      let storageName3 =
+      uni.getStorageSync("userInfo").xcxOpenid +
+      "_userThreeIds_" +
+      9;
     this.wrongListCount = uni.getStorageSync(storageName1)
       ? uni.getStorageSync(storageName1).length
       : 0;
     this.collectionListCount = uni.getStorageSync(storageName2)
       ? uni.getStorageSync(storageName2).length
       : 0;
-
+    this.threeListCount = uni.getStorageSync(storageName3)
+      ? uni.getStorageSync(storageName3).length
+      : 0;
     // api.exam
     //   .studentQuestionWrongWrongCountByUser({
     //     carType: this.gsMap[query.gs],
@@ -344,6 +379,84 @@ export default {
       : 0;
   },
   methods: {
+    syncThreeQuestion(e){
+      let select = e.detail.value;
+      let storageName =
+        uni.getStorageSync("userInfo").xcxOpenid +
+        "_userThreeIds_" +
+        9;
+      uni.getStorageSync(storageName)
+        ? ""
+        : uni.setStorageSync(storageName, []);
+      switch (select.value) {
+        case 0:
+          api.exam
+            .studentQuestionCollectionCollections({
+              km: 9,
+              cols: uni.getStorageSync(storageName).map((item) => item),
+            })
+            .then((res) => {
+              uni.showToast({
+                title: "合并成功",
+              });
+              api.exam
+                .studentQuestionCollectionCollectionByUser({
+                  km: 9,
+                })
+                .then((result) => {
+                  let userCollectionIds = result.data.map((item) => {
+                    return item;
+                  });
+                  uni.setStorageSync(storageName, userCollectionIds);
+                  this.collectionListCount = userCollectionIds.length;
+                });
+            });
+          break;
+        case 1:
+          api.exam
+            .studentQuestionCollectionBakCollections({
+              km:9,
+              cols: uni.getStorageSync(storageName).map((item) => item),
+            })
+            .then((res) => {
+              uni.showToast({
+                title: "备份成功",
+              });
+              api.exam
+                .studentQuestionCollectionCollectionByUser({
+                  km: 9,
+                })
+                .then((result) => {
+                  let userCollectionIds = result.data.map((item) => {
+                    return item;
+                  });
+                  uni.setStorageSync(storageName, userCollectionIds);
+                  this.collectionListCount = userCollectionIds.length;
+                });
+            });
+          break;
+        case 2:
+          api.exam
+            .studentQuestionCollectionCollectionByUser({
+              km: 9,
+            })
+            .then((result) => {
+              uni.showToast({
+                title: "恢复成功",
+              });
+              let userCollectionIds = result.data.map((item) => {
+                return item;
+              });
+              uni.setStorageSync(storageName, userCollectionIds);
+              this.collectionListCount = userCollectionIds.length;
+            });
+          break;
+        default:
+          break;
+      }
+      this.collectSyncShow = false;
+
+    },
     syncCollectQuestion(e) {
       let select = e.detail.value;
       let storageName =
@@ -527,6 +640,14 @@ export default {
         return;
       }
 
+      if (type == "three" && this.threeListCount == 0) {
+        uni.showToast({
+          title: "没有题目了",
+          icon: "none",
+        });
+        return;
+      }
+
       if (type == "wrong") {
         // query.questionIds =uni.getStorageSync(storageName1)? uni.getStorageSync(storageName1).map((item) => {
         //   return item.id;
@@ -544,12 +665,22 @@ export default {
             "/otherPages/exerciseCollect/index?" + utils.mapToUrlQuery(query),
         });
       }
+
+      if (type === "three") {
+        // query.questionIds =uni.getStorageSync(storageName2)? uni.getStorageSync(storageName2).map((item) => {
+        //   return item.id;
+        // }).join(','):'';
+        uni.navigateTo({
+          url:
+            "/otherPages/exerciseThree/index?" + utils.mapToUrlQuery({...query,subject:9}),
+        });
+      }
     },
     clearTopics(type) {
       let that = this;
       let storageName = "";
       if (type === "wrong") {
-        storageName = uni.showModal({
+        uni.showModal({
           title: "是否清空错题",
           success(res) {
             let storageName =
@@ -607,6 +738,36 @@ export default {
           },
         });
       }
+      else if(type=='three'){
+        uni.showModal({
+          title: "是否清空三力收藏题",
+          success(res) {
+            let storageName =
+              uni.getStorageSync("userInfo").xcxOpenid +
+              "_userThreeIds_" +
+              that.query.subject;
+            if (res.confirm) {
+              api.exam
+                .studentQuestionCollectionCancelAll({
+                  km: 9,
+                })
+                .then((res) => {
+                  uni.setStorageSync(storageName, []);
+                  api.exam
+                    .studentQuestionCollectionCollectionCountByUser({
+                      carType: that.gsMap[that.query.gs],
+                      km: 9,
+                      pageNum: 1,
+                      pageSize: 10000,
+                    })
+                    .then((res) => {
+                      that.threeListCount = res.data;
+                    });
+                });
+            }
+          },
+        });
+      }
     },
   },
 };

+ 23 - 0
src/otherPages/exerciseThree/components/checkbox.vue

@@ -0,0 +1,23 @@
+<template>
+  <view>
+    <slot v-if="useIconSlot" name="icon" />
+    <icon  v-else></icon>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  props: {
+    useIconSlot: {
+      type: Boolean,
+      default: false,
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 160 - 0
src/otherPages/exerciseThree/components/explainJs.vue

@@ -0,0 +1,160 @@
+<template>
+  <van-overlay z-index="10" :show="show">
+    <div class="skills-box">
+      <div class="skills">
+        <div class="title">官方解释</div>
+        <div class="text">{{ explainJs }}</div>
+        <div class="btn">
+          <span
+            @click="
+              () => {
+                $emit('close');
+              }
+            "
+          >
+            关闭
+          </span>
+          <span
+            @click="
+              () => {
+                playExplainjsmp3();
+              }
+            "
+          >
+            语音重播
+          </span>
+        </div>
+      </div>
+    </div>
+  </van-overlay>
+</template>
+
+<script>
+import utils from "@/utils/index";
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    playExplainjsmp3() {
+      let audio = utils.wxUtils.getGlobAudio();
+      audio.stop();
+      audio.src = this.explainjsmp3;
+      audio.onCanplay(() => {
+        console.log("onCanplay");
+      });
+      audio.onPlay(() => {
+        console.log("onPlay");
+      });
+      audio.onError((res) => {
+        console.log(res);
+      });
+      //体验比较好
+      setTimeout(() => {
+        audio.play();
+      }, 1000);
+    },
+  },
+  watch: {
+    show(newValue, oldValue) {
+      let audio = utils.wxUtils.getGlobAudio();
+      if (newValue) {
+        audio.src = this.explainjsmp3;
+        audio.play();
+      } else {
+        audio.stop();
+      }
+    },
+  },
+  props: {
+    show: {
+      type: Boolean,
+      default: false,
+    },
+    explainJs: {
+      type: String,
+      default: "",
+    },
+    explainjsmp3: {
+      type: String,
+      default: "",
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.skills-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+  .skills {
+    width: 290px;
+    background: #ffffff;
+    box-shadow: 0px 0px 8px rgba(124, 129, 136, 0.16);
+    border-radius: 10px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 20px 16px;
+    box-sizing: border-box;
+    .title {
+      font-size: 15px;
+      font-family: PingFang SC;
+      font-weight: bold;
+      line-height: 21px;
+      color: #0a1a33;
+    }
+    .img {
+      width: 258px;
+      height: 129px;
+      border: 1px solid #e8e8e8;
+      margin-top: 16px;
+    }
+    .divider {
+      margin-top: 20px;
+      color: #0a1a33;
+      background: #ffffff;
+    }
+    .text {
+      font-size: 13px;
+      font-family: PingFang SC;
+      font-weight: 400;
+      line-height: 19px;
+      color: #5c6066;
+      margin-top: 10px;
+    }
+    .btn {
+      width: 100%;
+      display: flex;
+      justify-content: space-between;
+      padding: 0 40px;
+      box-sizing: border-box;
+      margin-top: 20px;
+      span {
+        width: 76px;
+        height: 30px;
+        border-radius: 15px;
+        font-size: 13px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        &:active {
+          background-color: #afaaaa;
+          filter: brightness(50%);
+        }
+        &:nth-of-type(1) {
+          border: 1px solid #707070;
+          color: #5c6066;
+        }
+        &:nth-of-type(2) {
+          background: #498ef5;
+          border: 1px solid #498ef5;
+          color: #ffffff;
+        }
+      }
+    }
+  }
+}
+</style>

+ 82 - 0
src/otherPages/exerciseThree/components/navBar.vue

@@ -0,0 +1,82 @@
+<template>
+  <div
+    :style="{
+      height: (menuButton.height+8) + 'px',
+    }"
+    class="header"
+  >
+
+    <div class="header-title">
+      <text> {{title}}</text>
+    </div>
+  </div>
+</template>
+
+<script>
+
+export default {
+  data() {
+    return {
+      menuButton: {
+        bottom: 0,
+        height: 0,
+        left: 0,
+        right: 0,
+        top: 0,
+        width: 0,
+      },
+    };
+  },
+  props: {
+      title: {
+          type: String,
+          default:''
+      },
+      size:{
+          type:String,
+          default:'16px'
+      }
+  },
+  mounted() {
+    this.menuButton = uni.getMenuButtonBoundingClientRect();
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.header {
+  width: 100%;
+  overflow: hidden;
+  display: flex;
+  align-content: center;
+  align-items: center;
+  position: relative;
+  background: #fff;
+  .header-title {
+    width: 100%;
+    height: 100%;
+    text-align: center;
+    justify-content: center;
+    vertical-align: baseline;
+    display: flex;
+    align-content: center;
+    align-items: center;
+    text {
+      vertical-align: text-top;
+    }
+  }
+  .header-left {
+    position: absolute;
+    left: 0;
+    padding-left: 24rpx;
+    height: 100%;
+    display: flex;
+    align-content: center;
+    align-items: center;
+    .arrow-left {
+      color: #1989fa;
+      vertical-align: middle;
+    }
+  }
+}
+</style>

+ 45 - 0
src/otherPages/exerciseThree/components/tabbar.vue

@@ -0,0 +1,45 @@
+<template>
+  <view
+    class="box"
+    :style="{
+      height: height,
+      lineHeight:height
+    }"
+  >
+    <slot></slot>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    name() {},
+  },
+  props: {
+    height: {
+      type: String,
+      default: "0rpx",
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.box{
+    width: 100%;
+    display:flex;
+    justify-content: space-between;
+    overflow: scroll;
+    position: fixed;
+    bottom: 0;
+    font-size: 14px;
+    background: #fff;
+
+
+}
+
+
+</style>

+ 681 - 0
src/otherPages/exerciseThree/index.vue

@@ -0,0 +1,681 @@
+<template>
+  <view @touchstart="touchStart" @touchend="touchEnd" class="box">
+    <nav-bar :title="navTitle"> </nav-bar>
+    <!-- <view style="text-align:center;">
+      <van-count-down :time="time"></van-count-down>
+    </view> -->
+    <m-do-topic
+      v-if="isGetQuery"
+      type="three"
+      :bottomFunc="['previous', 'next', 'score', 'explain', 'skill']"
+      :midFunc="['collect', 'readQuestion', 'readQuestionAndAnswer']"
+      :trueNum.sync="trueNum"
+      :falseNum.sync="falseNum"
+      :query="query"
+      :problemListTotal.sync="problemListTotal"
+      :problemListIndex.sync="problemListIndex"
+    ></m-do-topic>
+
+    <explainJs
+      @close="
+        () => {
+          explainJsVisible = false;
+        }
+      "
+      :explainJs="problemList[problemListIndex].explainJs"
+      :explainjsmp3="problemList[problemListIndex].explainjsmp3"
+      :show="explainJsVisible"
+    ></explainJs>
+    <!-- #ifdef MP-WEIXIN -->
+    <!-- <van-tabbar height="20px">
+      <van-tabbar-item @click="goBeforeTopics"
+        ><van-icon
+          slot="icon"
+          custom-style="transform: rotate(90deg);"
+          custom-class="last-subject"
+          name="down"
+          size="18px"
+        />上一题
+      </van-tabbar-item>
+      <van-tabbar-item>
+        <icon slot="icon" class="icon-box-img" type="success" size="18px"></icon
+        >{{ trueNum }}</van-tabbar-item
+      >
+      <van-tabbar-item
+        ><icon
+          slot="icon"
+          class="icon-box-img"
+          type="cancel"
+          size="18px"
+        ></icon>
+        {{ falseNum }}
+      </van-tabbar-item>
+      <van-tabbar-item
+        ><van-icon slot="icon" size="18px" name="description" />{{
+          problemListIndex + 1
+        }}/{{ problemListTotal }}
+      </van-tabbar-item>
+      <van-tabbar-item
+        @click="
+          () => {
+            explainJsVisible = true;
+          }
+        "
+        ><icon slot="icon" type="warn" size="18px" />解释
+      </van-tabbar-item>
+      <van-tabbar-item @click="goNextTopics"
+        ><van-icon
+          slot="icon"
+          custom-style="transform: rotate(-90deg);"
+          custom-class="last-subject"
+          name="down"
+          size="18px"
+        />下一题
+      </van-tabbar-item>
+    </van-tabbar> -->
+    <!-- #endif -->
+    <!-- #ifdef MP-TOUTIAO -->
+    <tabbar height="35px">
+      <view @click="goBeforeTopics" class="flex-all-center h-full">
+        <van-icon
+          slot="icon"
+          custom-style="transform: rotate(90deg);"
+          custom-class="last-subject"
+          name="down"
+          size="18px"
+        /><text> 上一题 </text>
+      </view>
+      <view class="flex-all-center h-full">
+        <icon
+          class="icon-box-img"
+          color="#06c05f"
+          type="success"
+          size="18px"
+        ></icon
+        ><text style="margin-left: 5rpx">{{ trueNum }}</text>
+      </view>
+      <view class="flex-all-center h-full">
+        <icon class="icon-box-img" type="clear" size="18px"></icon>
+        <text style="margin-left: 5rpx">{{ falseNum }}</text>
+      </view>
+      <view class="flex-all-center h-full">
+        <van-icon size="18px" name="description" />{{ problemListIndex + 1 }}/{{
+          problemListTotal
+        }}
+      </view>
+
+      <view
+        @click="
+          () => {
+            explainJsVisible = true;
+          }
+        "
+        class="flex-all-center h-full"
+      >
+        <icon type="warn" size="18px" /><text style="margin-left: 5rpx"
+          >解释</text
+        >
+      </view>
+
+      <view @click="goNextTopics" class="flex-all-center h-full">
+        下一题
+        <van-icon
+          custom-style="transform: rotate(-90deg);"
+          custom-class="last-subject"
+          name="down"
+          size="18px"
+        />
+      </view>
+    </tabbar>
+    <!-- #endif -->
+  </view>
+</template>
+<script>
+import navBar from "./components/navBar.vue";
+import api from "@/api/index";
+import utils from "@/utils/index";
+import explainJs from "./components/explainJs.vue";
+import tabbar from "./components/tabbar.vue";
+import mDoTopic from "@/components/m-do-topic/m-do-topic.vue";
+export default {
+  data() {
+    return {
+      query: {
+        cert: "",
+        vehicle: "",
+        subject: "",
+        title: "",
+      },
+      gsMap: {
+        xc: "小车",
+        hc: "货车",
+        mtc: "摩托车",
+        kc: "客车",
+      },
+      trueNum: 0,
+      falseNum: 0,
+      currentOptions: [
+        {
+          selected: false,
+          value: "",
+          isAnswer: false,
+        },
+        {},
+      ],
+      isGetQuery: false,
+      explainJsVisible: false,
+      time: 45 * 60 * 1000,
+      problemListTotal: 1,
+      touchx: 0,
+      touchy: 0,
+      problemList: [
+        {
+          questionType: 2,
+          answer: "×",
+          answerkeyword: "",
+          answermp3:
+            "https://ndata.zzxcx.net/kt/answer_mp3/answer1389.mp3",
+          classIssue: "54",
+          classIssueName: "车内开关/装置",
+          classSort: 16,
+          createTime: "2022-04-21 13:33:46",
+          excellIssue: "23",
+          excellIssueName: "必学题三",
+          excellSort: 4,
+          explainGif:
+            "https://ndata.zzxcx.net/kt/explain_gif/explain1389.gif",
+          explainJq:
+            "看图答题:红色圆圈套在杆子中间.答对;不在中间或没有圆圈的.答错。",
+          explainJs:
+            "图中所示为左右转向灯开关转向灯操作:上提是右转向灯亮起,下压是左转向灯。",
+          explainMp3:
+            "https://ndata.zzxcx.net/kt/explain_mp3/explain1389.mp3",
+          explainjsmp3:
+            "https://ndata.zzxcx.net/kt/explain_js_mp3/explainJS1389.mp3",
+          id: 831,
+          idKt: 1389,
+          idYdt: 950,
+          image:
+            "https://ndata.zzxcx.net/kt/image/image1389.png",
+          imageYdt:
+            "https://ndata.zzxcx.net/kt/image_ydt/5eb4d75agw1e291vmniovj.jpg",
+          issue: "将转向灯开关向上提,左转向灯亮。",
+          issuemp3:
+            "https://ndata.zzxcx.net/kt/issue_mp3/issue1389.mp3",
+          liceBus: "1",
+          liceCar: "1",
+          liceMoto: null,
+          liceTruck: "1",
+          number: 831,
+          opts: "√-×",
+          optsArr: ["√", "×"],
+          placeIssue: null,
+          placeIssueName: null,
+          placeSort: null,
+          questionType: 1,
+          sequeIssue: "7",
+          sequeIssueName: "机械仪表",
+          sequeSort: 25,
+          skillkeyword: "没有圆圈-答错",
+          subject: 1,
+          titlekeyword: "",
+          updateTime: "2022-04-22 13:43:07",
+          userAnswer: [],
+        },
+      ],
+      problemListIndex: 0,
+    };
+  },
+  filters: {
+    questionType: function (value) {
+      let question = "";
+      switch (value) {
+        case 1:
+        case "1":
+          question = "判断题";
+          break;
+        case 2:
+        case "2":
+          question = "单选题";
+          break;
+        case 3:
+        case "3":
+          question = "多选题";
+          break;
+      }
+      return question;
+    },
+  },
+  methods: {
+    touchStart(e) {
+      var that = this;
+      (this.touchx = e.changedTouches[0].clientX),
+        (this.touchy = e.changedTouches[0].clientY);
+    },
+    touchEnd(e) {
+      console.log(e);
+      var that = this;
+      let x = e.changedTouches[0].clientX;
+      let y = e.changedTouches[0].clientY;
+      let turn = "";
+      if (x - that.touchx > 50 && Math.abs(y - that.touchy) < 50) {
+        //右滑
+        turn = "right";
+        this.problemListIndex <= 0
+          ? uni.showToast({
+              title: "到底了",
+              icon: "none",
+            })
+          : this.problemListIndex--;
+      } else if (x - that.touchx < -50 && Math.abs(y - that.touchy) < 50) {
+        //左滑
+        turn = "left";
+        this.problemListIndex >= this.problemListTotal - 1
+          ? uni.showToast({
+              title: "到底了",
+              icon: "none",
+            })
+          : this.problemListIndex++;
+      }
+      if (y - that.touchy > 50 && Math.abs(x - that.touchx) < 50) {
+        //下滑
+        turn = "down";
+      } else if (y - that.touchy < -50 && Math.abs(x - that.touchx) < 50) {
+        //上滑
+        turn = "up";
+      }
+      //根据方向进行操作
+      if (turn == "down") {
+        //下滑触发操作
+      }
+      console.log(turn);
+    },
+    isRightAnswer(item) {
+      if (
+        typeof item.userAnswer == "object" &&
+        Array.isArray(item.userAnswer)
+      ) {
+        let answerArr = item.answer.split("-");
+        answerArr.sort((a, b) => {
+          return a - b;
+        });
+        item.userAnswer.sort((a, b) => {
+          return a - b;
+        });
+        return answerArr.join("-") === item.userAnswer.join("-");
+      } else if (typeof item.userAnswer == "string") {
+        return item.answer === item.userAnswer;
+      }
+    },
+    submitExam(e) {
+      let score = 0;
+      let query = this.query;
+      this.problemList.forEach((item, index) => {
+        if (
+          typeof item.userAnswer == "object" &&
+          Array.isArray(item.userAnswer)
+        ) {
+          let answerArr = item.answer.split("-");
+          answerArr.sort((a, b) => {
+            return a - b;
+          });
+          item.userAnswer.sort((a, b) => {
+            return a - b;
+          });
+          if (answerArr.join("-") === item.userAnswer.join("-")) {
+            score = score + 1;
+          }
+        } else if (typeof item.userAnswer == "string") {
+          item.answer === item.userAnswer ? (score = score + 1) : "";
+        }
+      });
+      uni.showModal({
+        title: "是否交卷",
+        content: "交卷后不可再修改了",
+        success() {
+          uni.navigateTo({
+            url:
+              "/otherPages/mockExamEnd/index?" +
+              utils.mapToUrlQuery({
+                score,
+                ...query,
+              }),
+          });
+        },
+        fail() {},
+      });
+    },
+    goBeforeTopics() {
+      if (this.problemListIndex <= 0) {
+        uni.showToast({
+          title: "到底了",
+          icon: "none",
+        });
+        return;
+      }
+      this.problemListIndex = this.problemListIndex - 1;
+    },
+    goNextTopics() {
+      if (this.problemListIndex >= this.problemListTotal - 1) {
+        uni.showToast({
+          title: "到底了",
+          icon: "none",
+        });
+        return;
+      }
+      this.problemListIndex = this.problemListIndex + 1;
+    },
+    readQuestion(e) {
+      let globalAudio = utils.wxUtils.getGlobAudio();
+      if (globalAudio) {
+        globalAudio.src = e;
+        globalAudio.stop();
+        globalAudio.play();
+      }
+    },
+    confirmMult(e) {
+      this.$set(this.problemList[this.problemListIndex], "isCompleted", true);
+      if (
+        JSON.stringify(
+          this.problemList[this.problemListIndex].answer.split("-").sort()
+        ) ===
+        JSON.stringify(
+          this.problemList[this.problemListIndex].userAnswer.sort()
+        )
+      ) {
+        this.trueNum++;
+      } else {
+        this.falseNum++;
+        api.exam.studentQuestionWrong({
+          questionId: this.problemList[this.problemListIndex].id,
+          carType: this.gsMap[this.query.gs],
+          km: this.query.subject === "4" ? "科目四" : "科目一",
+        });
+      }
+      // this.problemList[this.problemListIndex]
+    },
+    changeCheckboxGroup(e) {
+      //console.log(e);
+      // this.$set()
+      // #ifdef MP-WEIXIN
+      this.$set(
+        this.problemList[this.problemListIndex],
+        "userAnswer",
+        e.detail
+      );
+      this.problemList[this.problemListIndex].optsArr.forEach((item) => {
+        if (e.detail.includes(item.value)) {
+          item.selected = true;
+        } else {
+          item.selected = false;
+        }
+      });
+      //#endif
+      // #ifdef MP-TOUTIAO
+      this.$set(
+        this.problemList[this.problemListIndex],
+        "userAnswer",
+        e.detail
+      );
+      this.problemList[this.problemListIndex].optsArr.forEach((item, index) => {
+        if (e.detail.includes(item.value)) {
+          item.selected = true;
+          this.$set(
+            this.problemList[this.problemListIndex].optsArr[index],
+            "selected",
+            true
+          );
+        } else {
+          item.selected = false;
+          this.$set(
+            this.problemList[this.problemListIndex].optsArr[index],
+            "selected",
+            false
+          );
+        }
+      });
+      //#endif
+      if (
+        this.problemList[this.problemListIndex].answer
+          .split("-")
+          .sort()
+          .toString() ===
+        this.problemList[this.problemListIndex].userAnswer.sort().toString()
+      ) {
+        this.trueNum = this.trueNum + 1;
+      } else {
+        this.falseNum = this.falseNum + 1;
+      }
+    },
+    changeRadioGroup(e) {
+      console.log(e, "changeRadioGroup");
+      // #ifdef MP-WEIXIN
+      this.$set(this.problemList[this.problemListIndex], "isCompleted", true);
+      this.$set(
+        this.problemList[this.problemListIndex],
+        "userAnswer",
+        e.detail.value
+      );
+      e.detail.selected = true;
+      this.$set(
+        this.problemList[this.problemListIndex].optsArr,
+        e.detail.index,
+        e.detail
+      );
+      e.detail.value === this.problemList[this.problemListIndex].answer
+        ? (this.trueNum = this.trueNum + 1)
+        : (this.falseNum = this.falseNum + 1);
+      //#endif
+
+      // #ifdef MP-TOUTIAO
+      this.$set(this.problemList[this.problemListIndex], "isCompleted", true);
+      this.$set(
+        this.problemList[this.problemListIndex],
+        "userAnswer",
+        e.detail
+      );
+      this.problemList[this.problemListIndex].optsArr.forEach((item, index) => {
+        if (e.detail === item.value) {
+          item.selected = true;
+          this.$set(
+            this.problemList[this.problemListIndex].optsArr[index],
+            "selected",
+            true
+          );
+        } else {
+          item.selected = false;
+          this.$set(
+            this.problemList[this.problemListIndex].optsArr[index],
+            "selected",
+            false
+          );
+        }
+      });
+      if (e.detail.value === this.problemList[this.problemListIndex].answer) {
+        this.trueNum = this.trueNum + 1;
+      } else {
+        this.falseNum = this.falseNum + 1;
+        api.exam.studentQuestionWrong({
+          questionId: this.problemList[this.problemListIndex].id,
+          carType: this.gsMap[this.query.gs],
+          km: this.query.subject === "4" ? "科目四" : "科目一",
+        });
+      }
+
+      //#endif
+    },
+    changeCheckbox(e) {
+      //specify
+      // console.log(e);
+    },
+    numberToLetter(index) {
+      index = Number(index);
+      return String.fromCharCode(index + 65);
+    },
+  },
+  onLoad(query) {
+    let that = this;
+    this.query = query;
+    // 获取到参数再进行渲染
+    this.isGetQuery = true;
+  },
+  computed: {
+    //liceCar=1&liceTruck=&liceBus=&liceMoto=&name=科目一&cert=C1/C2/C3&vehicle=轿车&subject=1&title=顺序练习&sort=3
+    navTitle() {
+      let subjectName = this.query.subject == 1 ? "科目一" : "科目四";
+      return `三力测试/收藏`;
+    },
+  },
+  watch: {
+    problemListIndex: {
+      handler(newValue, oldValue) {},
+      immediate: true,
+    },
+  },
+
+  components: {
+    mDoTopic,
+    navBar,
+    explainJs,
+    tabbar,
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.divider {
+  width: 100%;
+  height: 24rpx;
+  background-color: #f2f3f5;
+}
+.h-full {
+  height: 100%;
+}
+.flex-all-center {
+  display: flex;
+  justify-content: center;
+  align-content: center;
+  align-items: center;
+}
+.flex-center {
+  display: flex;
+  justify-content: center;
+  width: 100%;
+}
+.function-list {
+  width: 100%;
+  font-size: 13px;
+  display: flex;
+  justify-content: space-around;
+  flex-wrap: wrap;
+  padding: 15px;
+  box-sizing: border-box;
+  .function-item {
+    margin-bottom: 20px;
+    width: 30%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    font-size: 13px;
+    font-weight: 400;
+    color: #8a9099;
+    span {
+      margin-top: 5px;
+    }
+  }
+}
+.box {
+  width: 100%;
+  height: 100vh;
+  background: #fff;
+  .look-answer {
+    margin-top: 30rpx;
+    padding: 0 12rpx;
+    background: #f2f3f5;
+    font-size: 36rpx;
+    line-height: 62rpx;
+  }
+  .last-subject {
+    transform: rotate(90deg);
+  }
+
+  .problem-select {
+    display: flex;
+    align-content: center;
+    align-items: center;
+    margin-top: 15rpx;
+    padding-left: 30rpx;
+  }
+  .problem-box {
+    padding: 15rpx;
+    padding-bottom: 70rpx;
+    background: #fff;
+    /deep/ .van-checkbox {
+      padding-bottom: 15rpx;
+    }
+    /deep/ .van-radio {
+      padding-bottom: 15rpx;
+    }
+    .problem-type {
+      padding-left: 10rpx;
+      padding-right: 10rpx;
+      padding-top: 4rpx;
+      padding-bottom: 4rpx;
+      font-size: 24rpx;
+      border-radius: 16rpx 16rpx 0 16rpx;
+      background: #498ef5;
+      margin-right: 10rpx;
+      color: #fff;
+      font-size: 32rpx;
+    }
+    .problem-issue {
+      font-size: 42rpx;
+      font-weight: 600;
+    }
+    .problem-ops {
+      margin-top: 30rpx;
+      padding-left: 30rpx;
+      .problem-checkbox {
+        height: 100rpx;
+      }
+    }
+    .problem-op {
+      width: 75rpx;
+      height: 75rpx;
+      line-height: 75rpx;
+      border-radius: 50%;
+      text-align: center;
+      overflow: hidden;
+      background: #fff;
+      box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.16);
+    }
+    .problem-op_green {
+      width: 75rpx;
+      height: 75rpx;
+      line-height: 75rpx;
+      border-radius: 50%;
+      text-align: center;
+      overflow: hidden;
+      background: #01c18d;
+
+      box-shadow: 0px 4rpx 12rpx rgba(0, 0, 0, 0.16);
+    }
+    .problem-opAnswer {
+      font-size: 16px;
+      margin-left: 12rpx;
+    }
+    .problem-op_selected {
+      background: #498ef5;
+    }
+    .problem-img {
+      width: 100%;
+      margin-top: 20rpx;
+      display: flex;
+      justify-content: center;
+      image {
+        margin: 0 auto;
+      }
+    }
+  }
+}
+</style>

+ 64 - 0
src/otherPages/threeExam/index.vue

@@ -193,6 +193,20 @@
           </view>
         </van-radio-group>
       </view>
+      <view  v-if="query.showSubmit == '0'" @click="collectTopics" class="problem-collect">
+        <van-icon
+            v-if="!problemList[problemListIndex].isCollect"
+            name="star-o"
+            size="25px"
+          />
+          <van-icon
+            color="#ffde00ff"
+            v-if="problemList[problemListIndex].isCollect"
+            name="star"
+            size="25px"
+          />
+          <view>收藏</view>
+      </view>
 
     </view>
     <view class="bottom">
@@ -478,6 +492,51 @@ export default {
     }
   },
   methods: {
+    collectTopics(){
+      let storageName =
+        uni.getStorageSync("userInfo").xcxOpenid +
+        "_userThreeIds_" +
+        9;
+      let userThreeIds = uni.getStorageSync(storageName) || [];
+
+      if (!this.problemList[this.problemListIndex].isCollect) {
+        if (
+          !userThreeIds.some((item) => {
+            return item.id === this.problemList[this.problemListIndex].id;
+          })
+        ) {
+          userThreeIds.push({
+            id: this.problemList[this.problemListIndex].id,
+            timestamp: +new Date(),
+          });
+          uni.setStorageSync(storageName, userThreeIds);
+        }
+        this.$set(this.problemList[this.problemListIndex], "isCollect", true);
+        uni.showToast({
+          title: "收藏成功",
+        });
+      } else {
+        if (
+          userThreeIds.indexOf(
+            this.problemList[this.problemListIndex].id
+          ) > 0
+        ) {
+          userThreeIds.splice(
+            userThreeIds.indexOf(
+              this.problemList[this.problemListIndex].id
+            ),
+            1
+          );
+          uni.setStorageSync(storageName, userThreeIds);
+        }
+
+        this.$set(this.problemList[this.problemListIndex], "isCollect", false);
+        uni.showToast({
+          title: "取消收藏",
+          icon: "fail",
+        });
+      }
+    },
     goPath(url) {
       console.log(url);
 
@@ -789,6 +848,11 @@ export default {
       width: 100%;
     }
   }
+  .problem-collect{
+    width: 100rpx;
+    text-align: center;
+    padding-top: 15rpx;
+  }
 }
 
 .bottom {

+ 4 - 0
src/pages.json

@@ -331,6 +331,10 @@
           "path": "exerciseSpecify/index",
           "style": {}
         },
+        {
+          "path": "exerciseThree/index",
+          "style": {}
+        },
         {
           "path": "exerciseMi/index",
           "style": {}