Browse Source

重构做题的模块,更加组件化1

zhangyujun 3 năm trước cách đây
mục cha
commit
36816164aa

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

@@ -0,0 +1,488 @@
+<template>
+  <view class="problem-box">
+    <span class="problem-type">{{
+      problemList[problemListIndex].questionType | questionType
+    }}</span>
+    <!-- <text>{{ problemListIndex + 1 }}、</text> -->
+    <text class="problem-issue"
+      >{{ problemListIndex + 1 }}.{{
+        problemList[problemListIndex].issue
+      }}</text
+    >
+    <view v-if="problemList[problemListIndex].image" class="problem-img">
+      <image mode="widthFix" :src="problemList[problemListIndex].image"></image>
+    </view>
+    <!-- #ifdef MP-WEIXIN -->
+    <!-- 单项选择 -->
+    <view
+      v-if="problemList[problemListIndex].questionType < 3"
+      class="problem-ops"
+    >
+      <van-radio-group
+        :value="problemList[problemListIndex].userAnswer"
+        :max="1"
+        @change="changeRadioGroup"
+      >
+        <van-radio
+          :value="problemList[problemListIndex].userAnswer === item.value"
+          class="problem-checkbox"
+          use-icon-slot
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          :name="item.value"
+        >
+          <text>{{ item.value }}</text>
+          <view
+            class="problem-op"
+            :class="{
+              'problem-op_selected':
+                problemList[problemListIndex].userAnswer === item.value,
+            }"
+            slot="icon"
+            >{{ numberToLetter(index) }}</view
+          >
+        </van-radio>
+      </van-radio-group>
+    </view>
+
+    <!-- 多项选择 -->
+    <view
+      v-if="problemList[problemListIndex].questionType == 3"
+      class="problem-ops"
+    >
+      <van-checkbox-group
+        :value="problemList[problemListIndex].userAnswer"
+        :max="4"
+        @change="changeCheckboxGroup"
+      >
+        <van-checkbox
+          :value="problemList[problemListIndex].userAnswer.includes(item.value)"
+          class="problem-checkbox"
+          use-icon-slot
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          :name="item.value"
+        >
+          <text>{{ item.value }}</text>
+          <view
+            class="problem-op"
+            :class="{
+              'problem-op_selected': item.selected,
+            }"
+            slot="icon"
+            >{{ numberToLetter(index) }}</view
+          >
+        </van-checkbox>
+      </van-checkbox-group>
+    </view>
+    <!-- #endif -->
+
+    <!-- 单选 -->
+    <!-- #ifdef MP-TOUTIAO -->
+    <view
+      v-if="
+        problemList[problemListIndex].questionType < 3 &&
+        !problemList[problemListIndex].isCompleted
+      "
+      class="problem-ops"
+    >
+      <m-radio-group
+        @change="changeRadioGroup"
+        :value.sync="problemList[problemListIndex].userAnswer"
+      >
+        <m-radio
+          :value="item.value"
+          :item="item"
+          :useIconSlot="true"
+          :key="index"
+          :name="numberToLetter(index)"
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+        >
+        </m-radio>
+      </m-radio-group>
+    </view>
+    <view
+      v-if="
+        problemList[problemListIndex].questionType < 3 &&
+        problemList[problemListIndex].isCompleted
+      "
+    >
+      <view
+        v-for="(item, index) in problemList[problemListIndex].optsArr"
+        :key="index"
+        class="problem-select"
+      >
+        <icon
+          v-if="item.isAnswer && item.selected"
+          class="icon-box-img"
+          type="success"
+          color="#06c05f"
+          size="37"
+        ></icon>
+        <icon
+          v-if="!item.isAnswer && item.selected"
+          class="icon-box-img"
+          type="clear"
+          size="37"
+        ></icon>
+        <text v-if="!item.isAnswer && !item.selected" class="problem-op">{{
+          numberToLetter(index)
+        }}</text>
+        <text
+          v-if="item.isAnswer && !item.selected"
+          class="problem-op problem-op_green"
+          >{{ numberToLetter(index) }}</text
+        >
+        <view style="width: 8px"></view>
+        <text class="problem-opAnswer">{{ item.value }}</text>
+      </view>
+    </view>
+
+    <!-- 多选 -->
+
+    <view
+      v-if="
+        problemList[problemListIndex].questionType == 3 &&
+        !problemList[problemListIndex].isCompleted
+      "
+      class="problem-ops"
+    >
+      <m-checkbox-group
+        @change="changeCheckboxGroup"
+        :value="problemList[problemListIndex].userAnswer"
+        :max="4"
+      >
+        <m-checkbox
+          @change="changeCheckbox"
+          :item="item"
+          :value="item.value"
+          class="problem-checkbox"
+          use-icon-slot
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          :name="numberToLetter(index)"
+        >
+        </m-checkbox>
+      </m-checkbox-group>
+      <view class="flex-center">
+        <van-button
+          @click="confirmMult"
+          color="#498ef5"
+          round
+          custom-style="width:600rpx"
+          type="primary"
+          >确定</van-button
+        >
+      </view>
+    </view>
+    <view
+      v-if="
+        problemList[problemListIndex].questionType == 3 &&
+        problemList[problemListIndex].isCompleted
+      "
+    >
+      <view
+        v-for="(item, index) in problemList[problemListIndex].optsArr"
+        :key="index"
+        class="problem-select"
+      >
+        <icon
+          v-if="item.isAnswer && item.selected"
+          class="icon-box-img"
+          type="success"
+          color="#06c05f"
+          size="37"
+        ></icon>
+        <icon
+          v-if="!item.isAnswer && item.selected"
+          class="icon-box-img"
+          type="clear"
+          size="37"
+        ></icon>
+        <text v-if="!item.isAnswer && !item.selected" class="problem-op">{{
+          numberToLetter(index)
+        }}</text>
+        <text
+          v-if="item.isAnswer && !item.selected"
+          class="problem-op problem-op_green"
+          >{{ numberToLetter(index) }}</text
+        >
+        <view style="width: 8px"></view>
+        <text class="problem-opAnswer">{{ item.value }}</text>
+      </view>
+    </view>
+
+    <!-- #endif -->
+    <view class="function-list">
+      <div class="function-item">
+        <van-icon name="star-o" size="25px" />
+        <span>收藏</span>
+      </div>
+      <!-- <div class="function-item" @click="answerAudioPlay">
+      <m-icon type="a-dtda" size="25px" />
+      <span>读题+答案</span>
+    </div> -->
+      <div
+        @click="readQuestion(problemList[problemListIndex].issuemp3)"
+        class="function-item"
+      >
+        <van-icon name="bullhorn-o" size="25px" />
+        <span>读题</span>
+      </div>
+      <!-- <div class="function-item" @click="currentAnswerIndexBack">
+      <m-icon type="shangyiti" size="25px" />
+      <span>上一题</span>
+    </div>
+    <div class="function-item" @click="skillsShow = true">
+      <m-icon type="zongtishu" size="25px" />
+      <span>1/100</span>
+    </div>
+    <div class="function-item" @click="currentAnswerIndexGo">
+      <m-icon type="xiayiti" size="25px" />
+      <span>下一题</span>
+    </div> -->
+    </view>
+  </view>
+</template>
+
+<script>
+import mRadio from "@/components/m-radio/m-radio.vue";
+import mRadioGroup from "@/components/m-radio-group/m-radio-group.vue";
+import mCheckbox from "@/components/m-checkbox/m-checkbox.vue";
+import mCheckboxGroup from "@/components/m-checkbox-group/m-checkbox-group.vue";
+export default {
+  created() {},
+  data() {
+    return {
+      problemList: [],
+    };
+  },
+  methods: {
+    numberToLetter(index) {
+      index = Number(index);
+      return String.fromCharCode(index + 65);
+    },
+    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
+    },
+  },
+  components: {
+    mRadio,
+    mRadioGroup,
+    mCheckbox,
+    mCheckboxGroup,
+  },
+
+  props: {
+    query: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.problem-box {
+  padding: 15rpx;
+  background: #fff;
+  /deep/ .van-checkbox {
+    padding-bottom: 15rpx;
+  }
+  /deep/ .van-radio {
+    padding-bottom: 15rpx;
+  }
+  .problem-issue {
+    font-size: 42rpx;
+  }
+  .problem-select {
+    display: flex;
+    align-content: center;
+    align-items: center;
+    margin-top: 15rpx;
+    padding-left: 30rpx;
+  }
+  .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-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-op_selected {
+    background: #498ef5;
+  }
+  .problem-img {
+    width: 100%;
+    margin-top: 20rpx;
+    display: flex;
+    justify-content: center;
+    image {
+      margin: 0 auto;
+    }
+  }
+}
+</style>

+ 8 - 0
src/otherPages/collection/index.vue

@@ -79,6 +79,14 @@ export default {
       .then((res) => {
         this.wrongList = res.rows;
       });
+    api.exam.studentQuestionCollectionList({
+      carType: this.gsMap[query.gs],
+      km: query.subject === "1" ? "科目一" : "科目四",
+      pageNum: 1,
+      pageSize: 10000,
+    }).then(res=>{
+      this.collectionList = res.rows
+    })
   },
   methods: {
     clearTopics(type) {

+ 23 - 0
src/otherPages/specifyExercise/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/specifyExercise/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>

+ 42 - 0
src/otherPages/specifyExercise/components/m-checkbox-group.vue

@@ -0,0 +1,42 @@
+<template>
+  <view class="checkboxGroup">
+    <view @tap.native="changeCheckboxGroup">
+      <slot></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    changeCheckboxGroup(e) {
+      console.log(e);
+      e.detail = e.target.dataset.item;
+      this.$emit("update:value", e.target.dataset.value);
+      this.$emit("change", e);
+    },
+  },
+  props: {
+    useIconSlot: {
+      type: Boolean,
+      default: false,
+    },
+    name: {
+      type: String,
+      default: "",
+    },
+    value: {
+      type: String,
+      default: "",
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.checkboxGroup {
+}
+</style>

+ 62 - 0
src/otherPages/specifyExercise/components/m-checkbox.vue

@@ -0,0 +1,62 @@
+<template>
+  <view @tap.native="clickCheckbox" :data-item="item" class="checkbox">
+    <view :data-item="item" class="custom-icon" v-if="useIconSlot">{{
+      name
+    }}</view>
+    <view :data-item="item" style="width: 8px"></view>
+    <text :data-item="item">{{ item.value }}</text>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    stopClick(e) {
+      e.stopPropagation();
+    },
+    clickCheckbox(e) {
+      console.log(e);
+      this.$emit("clickcheckbox", e);
+      e.stopPropagation();
+    },
+  },
+  props: {
+    useIconSlot: {
+      type: Boolean,
+      default: false,
+    },
+    name: {
+      type: String,
+      default: "",
+    },
+    item: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.checkbox {
+  display: flex;
+  align-content: center;
+  align-items: center;
+  padding: 8px 0;
+}
+.custom-icon {
+  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);
+}
+</style>

+ 42 - 0
src/otherPages/specifyExercise/components/m-radio-group.vue

@@ -0,0 +1,42 @@
+<template>
+  <view class="radioGroup">
+    <view @tap.native="changeRadioGroup">
+      <slot></slot>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    changeRadioGroup(e) {
+      console.log(e);
+      e.detail = e.target.dataset.item;
+      this.$emit("update:value", e.target.dataset.value);
+      this.$emit("change", e);
+    },
+  },
+  props: {
+    useIconSlot: {
+      type: Boolean,
+      default: false,
+    },
+    name: {
+      type: String,
+      default: "",
+    },
+    value: {
+      type: String,
+      default: "",
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.radioGroup {
+}
+</style>

+ 62 - 0
src/otherPages/specifyExercise/components/m-radio.vue

@@ -0,0 +1,62 @@
+<template>
+  <view @tap.native="clickRadio" :data-item="item" class="radio">
+    <view :data-item="item" class="custom-icon" v-if="useIconSlot">{{
+      name
+    }}</view>
+    <view :data-item="item" style="width: 8px"></view>
+    <text :data-item="item">{{ item.value }}</text>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {};
+  },
+  methods: {
+    stopClick(e) {
+      e.stopPropagation();
+    },
+    clickRadio(e) {
+      console.log(e);
+      this.$emit("clickRadio", e);
+      e.stopPropagation();
+    },
+  },
+  props: {
+    useIconSlot: {
+      type: Boolean,
+      default: false,
+    },
+    name: {
+      type: String,
+      default: "",
+    },
+    item: {
+      type: Object,
+      default: () => {
+        return {};
+      },
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.radio {
+  display: flex;
+  align-content: center;
+  align-items: center;
+  padding: 8px 0;
+}
+.custom-icon {
+  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);
+}
+</style>

+ 82 - 0
src/otherPages/specifyExercise/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/specifyExercise/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>

+ 1049 - 0
src/otherPages/specifyExercise/index.vue

@@ -0,0 +1,1049 @@
+<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> -->
+    <view class="divider"></view>
+    <view class="problem-box">
+      <span class="problem-type">{{
+        problemList[problemListIndex].questionType | questionType
+      }}</span>
+      <!-- <text>{{ problemListIndex + 1 }}、</text> -->
+      <text class="problem-issue"
+        >{{ problemListIndex + 1 }}.{{
+          problemList[problemListIndex].issue
+        }}</text
+      >
+      <view v-if="problemList[problemListIndex].image" class="problem-img">
+        <image
+          mode="widthFix"
+          :src="problemList[problemListIndex].image"
+        ></image>
+      </view>
+      <!-- 单选 -->
+      <!-- #ifdef MP-WEIXIN -->
+      <view
+        v-if="
+          problemList[problemListIndex].questionType < 3 &&
+          !problemList[problemListIndex].isCompleted
+        "
+        class="problem-ops"
+      >
+        <van-radio-group
+          @change="changeRadioGroup"
+          :value="problemList[problemListIndex].userAnswer"
+        >
+          <van-radio
+            @change="changeCheckbox"
+            :value="item.value"
+            class="problem-checkbox"
+            use-icon-slot
+            v-for="(item, index) in problemList[problemListIndex].optsArr"
+            :key="index"
+            :name="item"
+          >
+            <text>{{ item.value }}</text>
+            <view
+              class="problem-op"
+              :class="{
+                'problem-op_selected': item.selected,
+              }"
+              slot="icon"
+              name="icon"
+              >{{ numberToLetter(index) }}</view
+            >
+          </van-radio>
+        </van-radio-group>
+      </view>
+      <view
+        v-if="
+          problemList[problemListIndex].questionType < 3 &&
+          problemList[problemListIndex].isCompleted
+        "
+      >
+        <view
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          class="problem-select"
+        >
+          <icon
+            v-if="item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="success"
+            size="75rpx"
+          ></icon>
+          <icon
+            v-if="!item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="cancel"
+            size="75rpx"
+          ></icon>
+          <text v-if="!item.isAnswer && !item.selected" class="problem-op">{{
+            numberToLetter(index)
+          }}</text>
+          <text
+            v-if="item.isAnswer && !item.selected"
+            class="problem-op_green"
+            >{{ numberToLetter(index) }}</text
+          >
+          <text class="problem-opAnswer">{{ item.value }}</text>
+        </view>
+      </view>
+      <!-- 多选 -->
+      <view
+        v-if="
+          problemList[problemListIndex].questionType == 3 &&
+          !problemList[problemListIndex].isCompleted
+        "
+        class="problem-ops"
+      >
+        <van-checkbox-group
+          @change="changeCheckboxGroup"
+          :value="problemList[problemListIndex].userAnswer"
+          :max="4"
+        >
+          <van-checkbox
+            @change="changeCheckbox"
+            :value="item.selected"
+            class="problem-checkbox"
+            use-icon-slot
+            v-for="(item, index) in problemList[problemListIndex].optsArr"
+            :key="index"
+            :name="item.value"
+          >
+            <text>{{ item.value }}</text>
+            <view
+              class="problem-op"
+              :class="{
+                'problem-op_selected': problemList[
+                  problemListIndex
+                ].userAnswer.includes(item.value),
+              }"
+              slot="icon"
+              name="icon"
+              >{{ numberToLetter(index) }}</view
+            >
+          </van-checkbox>
+        </van-checkbox-group>
+        <view class="flex-center">
+          <van-button
+            @click="confirmMult"
+            color="#498ef5"
+            round
+            custom-style="width:600rpx"
+            type="primary"
+            >确定</van-button
+          >
+        </view>
+      </view>
+      <view
+        v-if="
+          problemList[problemListIndex].questionType == 3 &&
+          problemList[problemListIndex].isCompleted
+        "
+      >
+        <view
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          class="problem-select"
+        >
+          <icon
+            v-if="item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="success"
+            size="75rpx"
+          ></icon>
+          <icon
+            v-if="!item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="cancel"
+            size="75rpx"
+          ></icon>
+          <text v-if="!item.isAnswer && !item.selected" class="problem-op">{{
+            numberToLetter(index)
+          }}</text>
+          <text
+            v-if="item.isAnswer && !item.selected"
+            class="problem-op_green"
+            >{{ numberToLetter(index) }}</text
+          >
+          <text class="problem-opAnswer">{{ item.value }}</text>
+        </view>
+      </view>
+      <!-- #endif -->
+
+      <!-- 单选 -->
+      <!-- #ifdef MP-TOUTIAO -->
+      <view
+        v-if="
+          problemList[problemListIndex].questionType < 3 &&
+          !problemList[problemListIndex].isCompleted
+        "
+        class="problem-ops"
+      >
+        <m-radio-group
+          @change="changeRadioGroup"
+          :value.sync="problemList[problemListIndex].userAnswer"
+        >
+          <m-radio
+            :value="item.value"
+            :item="item"
+            :useIconSlot="true"
+            :key="index"
+            :name="numberToLetter(index)"
+            v-for="(item, index) in problemList[problemListIndex].optsArr"
+          >
+          </m-radio>
+        </m-radio-group>
+      </view>
+      <view
+        v-if="
+          problemList[problemListIndex].questionType < 3 &&
+          problemList[problemListIndex].isCompleted
+        "
+      >
+        <view
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          class="problem-select"
+        >
+          <icon
+            v-if="item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="success"
+            color="#06c05f"
+            size="37"
+          ></icon>
+          <icon
+            v-if="!item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="clear"
+            size="37"
+          ></icon>
+          <text v-if="!item.isAnswer && !item.selected" class="problem-op">{{
+            numberToLetter(index)
+          }}</text>
+          <text
+            v-if="item.isAnswer && !item.selected"
+            class="problem-op_green"
+            >{{ numberToLetter(index) }}</text
+          >
+          <text class="problem-opAnswer">{{ item.value }}</text>
+        </view>
+      </view>
+
+      <!-- #endif -->
+
+      <!-- 多选 -->
+      <!-- #ifdef MP-TOUTIAO -->
+      <view
+        v-if="
+          problemList[problemListIndex].questionType == 3 &&
+          !problemList[problemListIndex].isCompleted
+        "
+        class="problem-ops"
+      >
+        <m-checkbox-group
+          @change="changeCheckboxGroup"
+          :value="problemList[problemListIndex].userAnswer"
+          :max="4"
+        >
+          <m-checkbox
+            @change="changeCheckbox"
+            :item="item"
+            :value="item.value"
+            class="problem-checkbox"
+            use-icon-slot
+            v-for="(item, index) in problemList[problemListIndex].optsArr"
+            :key="index"
+            :name="numberToLetter(index)"
+          >
+          </m-checkbox>
+        </m-checkbox-group>
+        <view class="flex-center">
+          <van-button
+            @click="confirmMult"
+            color="#498ef5"
+            round
+            custom-style="width:600rpx"
+            type="primary"
+            >确定</van-button
+          >
+        </view>
+      </view>
+      <view
+        v-if="
+          problemList[problemListIndex].questionType == 3 &&
+          problemList[problemListIndex].isCompleted
+        "
+      >
+        <view
+          v-for="(item, index) in problemList[problemListIndex].optsArr"
+          :key="index"
+          class="problem-select"
+        >
+          <icon
+            v-if="item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="success"
+            color="#06c05f"
+            size="37"
+          ></icon>
+          <icon
+            v-if="!item.isAnswer && item.selected"
+            class="icon-box-img"
+            type="clear"
+            size="37"
+          ></icon>
+          <text v-if="!item.isAnswer && !item.selected" class="problem-op">{{
+            numberToLetter(index)
+          }}</text>
+          <text
+            v-if="item.isAnswer && !item.selected"
+            class="problem-op_green problem-op "
+            >{{ numberToLetter(index) }}</text
+          >
+          <text class="problem-opAnswer">{{ item.value }}</text>
+        </view>
+      </view>
+
+      <!-- #endif -->
+      <view class="function-list">
+        <div class="function-item">
+          <van-icon name="star-o" size="25px" />
+          <span>收藏</span>
+        </div>
+        <!-- <div class="function-item" @click="answerAudioPlay">
+      <m-icon type="a-dtda" size="25px" />
+      <span>读题+答案</span>
+    </div> -->
+        <div
+          @click="readQuestion(problemList[problemListIndex].issuemp3)"
+          class="function-item"
+        >
+          <van-icon name="bullhorn-o" size="25px" />
+          <span>读题</span>
+        </div>
+        <!-- <div class="function-item" @click="currentAnswerIndexBack">
+      <m-icon type="shangyiti" size="25px" />
+      <span>上一题</span>
+    </div>
+    <div class="function-item" @click="skillsShow = true">
+      <m-icon type="zongtishu" size="25px" />
+      <span>1/100</span>
+    </div>
+    <div class="function-item" @click="currentAnswerIndexGo">
+      <m-icon type="xiayiti" size="25px" />
+      <span>下一题</span>
+    </div> -->
+      </view>
+      <view
+        v-if="problemList[problemListIndex].isCompleted"
+        class="look-answer"
+      >
+        <view>答案是:{{ problemList[problemListIndex].answer }}</view>
+      </view>
+    </view>
+    <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 mRadio from "@/components/m-radio/m-radio.vue";
+import mRadioGroup from "@/components/m-radio-group/m-radio-group.vue";
+import mCheckbox from "@/components/m-checkbox/m-checkbox.vue";
+import mCheckboxGroup from "@/components/m-checkbox-group/m-checkbox-group.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,
+        },
+        {},
+      ],
+      explainJsVisible: false,
+      time: 45 * 60 * 1000,
+      problemListTotal: 1,
+      touchx: 0,
+      touchy: 0,
+      problemList: [
+        {
+          questionType: 2,
+          answer: "×",
+          answerkeyword: "",
+          answermp3:
+            "https://t1-1305573081.file.myqcloud.com/kt/answer_mp3/answer1389.mp3",
+          classIssue: "54",
+          classIssueName: "车内开关/装置",
+          classSort: 16,
+          createTime: "2022-04-21 13:33:46",
+          excellIssue: "23",
+          excellIssueName: "必学题三",
+          excellSort: 4,
+          explainGif:
+            "https://t1-1305573081.file.myqcloud.com/kt/explain_gif/explain1389.gif",
+          explainJq:
+            "看图答题:红色圆圈套在杆子中间.答对;不在中间或没有圆圈的.答错。",
+          explainJs:
+            "图中所示为左右转向灯开关转向灯操作:上提是右转向灯亮起,下压是左转向灯。",
+          explainMp3:
+            "https://t1-1305573081.file.myqcloud.com/kt/explain_mp3/explain1389.mp3",
+          explainjsmp3:
+            "https://t1-1305573081.file.myqcloud.com/kt/explain_js_mp3/explainJS1389.mp3",
+          id: 831,
+          idKt: 1389,
+          idYdt: 950,
+          image:
+            "https://t1-1305573081.file.myqcloud.com/kt/image/image1389.png",
+          imageYdt:
+            "https://t1-1305573081.file.myqcloud.com/kt/image_ydt/5eb4d75agw1e291vmniovj.jpg",
+          issue: "将转向灯开关向上提,左转向灯亮。",
+          issuemp3:
+            "https://t1-1305573081.file.myqcloud.com/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.problemList.length - 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.problemList.length - 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) {
+      // console.log(e);
+    },
+    numberToLetter(index) {
+      index = Number(index);
+      return String.fromCharCode(index + 65);
+    },
+  },
+  onLoad(query) {
+    let that = this;
+    this.query = query;
+    api.exam
+      .studentQuestionInfoList({
+        ...this.query,
+      })
+      .then((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;
+      });
+  },
+  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 `(${this.query.cert})/${subjectName}/${this.query.title}/${
+        this.query.classIssueName ||
+        this.query.placeIssueName ||
+        this.query.excellIssueName ||
+        this.query.sequeIssueName
+      }`;
+    },
+  },
+  watch: {
+    problemListIndex: {
+      handler(newValue, oldValue) {},
+      immediate: true,
+    },
+  },
+
+  components: {
+    navBar,
+    explainJs,
+    tabbar,
+    mRadio,
+    mRadioGroup,
+    mCheckbox,
+    mCheckboxGroup,
+  },
+};
+</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%;
+}
+
+.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);
+  }
+  .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;
+      }
+    }
+  }
+  .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>