zhangyujun 2 лет назад
Родитель
Сommit
2905343672

+ 9 - 1
src/api/modules/exam.js

@@ -169,8 +169,16 @@ const exam = {
 			params
 		})
 
-	}
+	},
+	//查询秘密卷
+	studentQuestionInfoSelectMiQuestionInfoList(params){
+		return request({
+			url: "student/question/info/selectMiQuestionInfoList",
+			method: "get",
+			params
+		})
 
+	}
 }
 
 export default exam

BIN
src/assets/img/diary-icon.png


BIN
src/assets/img/fire-icon.png


+ 63 - 7
src/components/m-do-topic/m-do-topic.vue

@@ -1,6 +1,10 @@
 <template>
   <view>
-    <countDown :time="examTime" @change="getUseTime" v-if="type == 'singleTest' || type == 'exam'"></countDown>
+    <countDown
+      :time="examTime"
+      @change="getUseTime"
+      v-if="type == 'singleTest' || type == 'exam'"
+    ></countDown>
     <view v-if="!hiddenMode" class="mode">
       <view
         @click="
@@ -60,6 +64,12 @@
       <span class="problem-type">{{
         problemList[problemListIndex].questionType | questionType
       }}</span>
+      <text
+        style="background: #9c5fed"
+        v-if="problemList[problemListIndex].isNew"
+        class="problem-type"
+        >新规题</text
+      >
       <!-- <text>{{ problemListIndex + 1 }}、</text> -->
       <text class="problem-issue"
         >{{ problemListIndex + 1 }}、{{
@@ -803,6 +813,7 @@ export default {
           issue: "将转向灯开关向上提,左转向灯亮。",
           issuemp3:
             "https://t1-1305573081.file.myqcloud.com/kt/issue_mp3/issue1389.mp3",
+          isNew: 0,
           liceBus: "1",
           liceCar: "1",
           liceMoto: null,
@@ -834,8 +845,8 @@ export default {
         mtc: "摩托车",
         kc: "客车",
       },
-      examTime:1000*60*45,
-      useTime:'',
+      examTime: 1000 * 60 * 45,
+      useTime: "",
       problemListTotal: 1,
       explainJqVisible: false,
       selectProblemListVisible: false,
@@ -857,8 +868,8 @@ export default {
     },
   },
   methods: {
-    getUseTime(leftTime,useTime){
-      this.useTime = useTime
+    getUseTime(leftTime, useTime) {
+      this.useTime = useTime;
     },
     stopAudio() {
       let audio = utils.wxUtils.getGlobAudio();
@@ -969,8 +980,7 @@ export default {
         success(res) {
           if (res.confirm) {
             let useTime = that.useTime;
-  
-      
+
             uni.navigateTo({
               url:
                 "/otherPages/mockExamEnd/index?" +
@@ -1485,6 +1495,47 @@ export default {
             uni.hideLoading();
           });
 
+        break;
+      case "mi":
+        api.exam
+          .studentQuestionInfoSelectMiQuestionInfoList({
+            category: this.query.category,
+            gs: this.query.gs,
+
+            kemu: this.query.subject,
+          })
+          .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
@@ -1674,6 +1725,11 @@ export default {
   padding: 15rpx;
   padding-bottom: 45px;
   background: #fff;
+  position: relative;
+  .new-rule {
+    color: red;
+    font-size: 16rpx;
+  }
   /deep/ .van-checkbox {
     padding-bottom: 15rpx;
   }

+ 75 - 3
src/otherPages/code/index.vue

@@ -8,19 +8,91 @@
         重新获取code
       </button>
     </view>
+    <view class="menu">
+      <button
+        @click="
+          downloadPdf(
+            'https://cos-admin.yizhiwechat.com/yizhiClassroom/saveLesson/material/20211201165322_rMiiDd.pdf'
+          )
+        "
+        style="background: red"
+      >
+        下载pdf
+      </button>
+      <button
+        @click="
+          openPdf(
+            'https://cos-admin.yizhiwechat.com/yizhiClassroom/saveLesson/material/20211201165322_rMiiDd.pdf'
+          )
+        "
+        style="background: red"
+      >
+        打开pdf
+      </button>
+    </view>
   </view>
 </template>
 
 <script>
-import countDown from '@/components/countDown/index'
+import countDown from "@/components/countDown/index";
 export default {
   data() {
     return {
       code: "",
-      time:1000*60*45
+      time: 1000 * 60 * 45,
     };
   },
   methods: {
+    downloadPdf(src) {
+      tt.downloadFile({
+        url: src,
+        success: (res) => {
+          console.log("临时文件下载成功,下载路径: " + res.tempFilePath);
+          tt.saveFile({
+            // 参数: 需传入文件临时路径tempFilePath
+            tempFilePath: res.tempFilePath,
+            success: (data) => {
+              // 返回参数中的savedFilePath属性为保存的本地文件路径
+              console.log("保存成功, 本地路径为: ", data.savedFilePath);
+              tt.showModal({
+                content: "临时文件保存成功",
+                showCancel: false,
+              });
+            },
+            fail: (res) => {
+              // 当 API 执行失败后调用, 预定义返回消息格式为${API_NAME}:fail
+              console.log("临时文件保存失败", res.errMsg);
+              tt.showModal({
+                content: "临时文件保存失败",
+                showCancel: false,
+              });
+            },
+            complete: (res) => {
+              // 当 API 执行完成(无论成功或者失败)后都会调用, 预定义返回消息格式为${API_NAME}:ok / fail
+              console.log("接口已调用", res.errMsg);
+            },
+          });
+        },
+        fail: (res) => {
+          console.log("下载失败: ", res.errMsg);
+        },
+      });
+    },
+    openPdf(src) {
+      tt.downloadFile({
+        // 仅为示例 url,并非真实地址
+        url: src,
+        success: function (res) {
+          const filePath = res.tempFilePath;
+          tt.openDocument({
+            filePath: filePath,
+            success: function (res) {
+              console.log("打开文档成功");
+            },
+          });
+        },
+      });
+    },
     freshCode() {
       let that = this;
       uni.login({
@@ -43,7 +115,7 @@ export default {
     this.freshCode();
   },
   components: {
-    countDown
+    countDown,
   },
 };
 </script>

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

+ 83 - 0
src/otherPages/exerciseMi/components/navBar.vue

@@ -0,0 +1,83 @@
+<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 {
+    font-size: 32rpx;
+    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>

+ 47 - 0
src/otherPages/exerciseMi/components/tabbar.vue

@@ -0,0 +1,47 @@
+<template>
+  <view
+    class="box"
+    :style="{
+      height: 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;
+    padding:0 30rpx;
+    border-top: 2rpx solid #d8d8d8;
+    padding-top: 5rpx;
+
+
+}
+
+
+</style>

+ 764 - 0
src/otherPages/exerciseMi/index.vue

@@ -0,0 +1,764 @@
+<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="mi"
+      :bottomFunc="['previous', 'next', 'score', 'explain', 'selectCatalogue']"
+      :midFunc="['collect', 'readQuestion', 'readQuestionAndAnswer', 'skill']"
+      :trueNum.sync="trueNum"
+      :falseNum.sync="falseNum"
+      :query="query"
+      :problemListIndex.sync="problemListIndex"
+    ></m-do-topic>
+    <!-- <view class="function-list">
+      <div class="function-item">
+        <van-icon name="star-o" size="25px" />
+        <span>收藏</span>
+      </div>
+      <div
+        @click="readQuestion(problemList[problemListIndex].issuemp3)"
+        class="function-item"
+      >
+        <van-icon name="bullhorn-o" size="25px" />
+        <span>读题</span>
+      </div>
+    </view> -->
+
+    <van-overlay
+      @click-overlay="
+        () => {
+          selectProblemListVisible = false;
+        }
+      "
+      :show="selectProblemListVisible"
+    >
+      <view class="select-problem">
+        <view class="problem-index">
+          <view class="problem-header">
+            <view class="problem-header-left">
+              <view class="problem-dui">
+                <icon
+                  class="icon-box-img"
+                  color="#06c05f"
+                  type="success"
+                  size="18"
+                ></icon>
+                <text
+                  style="color: #06c05f; font-size: 14px; margin-left: 8rpx"
+                  >{{ trueNum }}</text
+                >
+              </view>
+              <view class="problem-cuo" style="margin-left: 16rpx">
+                <icon class="icon-box-img" type="clear" size="18"></icon>
+                <text style="color: red; font-size: 14px; margin-left: 8rpx">{{
+                  falseNum
+                }}</text>
+              </view>
+            </view>
+            <view class="problem-header-right">
+              <van-icon size="18px" name="description" />
+              <view style="font-size: 14px; display: flex; align-items: center"
+                >{{ problemListIndex + 1 }}/{{ problemListTotal }}</view
+              >
+            </view>
+          </view>
+          <view class="problem-body">
+            <view class="problem-listBody">
+              <view
+                class="problem-listItem"
+                :key="index"
+                v-for="(item, index) in problemList"
+                :class="{
+                  'problem-listItem_dui':
+                    item.userAnswer.length && item.userAnswer == item.answer,
+                  'problem-listItem_cuo':
+                    item.userAnswer.length && item.userAnswer !== item.answer,
+                }"
+              >
+                {{ index + 1 }}
+              </view>
+            </view>
+          </view>
+          <view class="problem-bottom">
+            <view
+              @click="
+                () => {
+                  selectProblemListVisible = false;
+                }
+              "
+              class="problem-bottom-sure"
+              >确定
+            </view>
+            <view
+              @click="
+                () => {
+                  selectProblemListVisible = false;
+                }
+              "
+              class="problem-bottom-close"
+            >
+              关闭</view
+            >
+          </view>
+        </view>
+      </view>
+    </van-overlay>
+  </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";
+import mDoTopic from "@/components/m-do-topic/m-do-topic.vue";
+export default {
+  data() {
+    return {
+      query: {
+        cert: "",
+        vehicle: "",
+        subject: "",
+        title: "",
+      },
+      isGetQuery:false,
+      gsMap: {
+        xc: "小车",
+        hc: "货车",
+        mtc: "摩托车",
+        kc: "客车",
+      },
+      trueNum: 0,
+      falseNum: 0,
+      currentOptions: [
+        {
+          selected: false,
+          value: "",
+          isAnswer: false,
+        },
+        {},
+      ],
+      explainJsVisible: false,
+      selectProblemListVisible: 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) {
+      //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 `(${this.query.cert})/${subjectName}/${this.query.title}`;
+    },
+  },
+  watch: {
+    problemListIndex: {
+      handler(newValue, oldValue) {},
+      immediate: true,
+    },
+  },
+
+  components: {
+    mDoTopic,
+    navBar,
+    explainJs,
+    tabbar,
+    mRadio,
+    mRadioGroup,
+    mCheckbox,
+    mCheckboxGroup,
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.select-problem {
+  display: flex;
+  width: 100vw;
+  height: 100vh;
+  align-content: flex-end;
+  align-items: flex-end;
+  .problem-index {
+    width: 100vw;
+    height: 650rpx;
+    background: #fff;
+    border-radius: 16rpx;
+    padding-top: 50rpx;
+  }
+  .problem-bottom {
+    width: 100%;
+    display: flex;
+    height: 80rpx;
+    .problem-bottom-sure {
+      width: 50%;
+      height: 100%;
+      border-right: 2rpx solid #d8d8d8;
+      border-top: 2rpx solid #d8d8d8;
+      text-align: center;
+      color: #498ef5;
+      line-height: 80rpx;
+    }
+    .problem-bottom-close {
+      width: 50%;
+      height: 100%;
+      color: red;
+      text-align: center;
+      border-top: 2rpx solid #d8d8d8;
+      line-height: 80rpx;
+    }
+  }
+  .problem-header {
+    display: flex;
+    justify-content: space-between;
+    align-content: center;
+    align-items: center;
+    padding: 0rpx 30rpx;
+    .problem-header-left {
+      display: flex;
+
+      .problem-dui {
+        display: flex;
+        align-content: center;
+        align-items: center;
+      }
+      .problem-cuo {
+        display: flex;
+        align-content: center;
+        align-items: center;
+      }
+    }
+    .problem-header-right {
+      display: flex;
+      align-content: center;
+    }
+  }
+  .problem-body {
+    height: 480rpx;
+    padding-top: 30rpx;
+    overflow-y: scroll;
+
+    .problem-listBody {
+      display: inline-block;
+      overflow: hidden;
+      .problem-listItem {
+        display: inline-block;
+        width: 99rpx;
+        height: 99rpx;
+        line-height: 100rpx;
+        text-align: center;
+        border-radius: 50%;
+        border: 2rpx #d8d8d8 solid;
+        margin-bottom: 15rpx;
+        margin-left: 13rpx;
+        margin-right: 13rpx;
+      }
+      .problem-listItem_dui {
+        background: #01c18d;
+      }
+      .problem-listItem_cuo {
+        background: red;
+      }
+    }
+  }
+}
+.tabbar-item {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: center;
+  text-align: center;
+  align-content: space-around;
+  align-items: space-around;
+}
+.divider {
+  width: 100%;
+  height: 24rpx;
+  background-color: #f2f3f5;
+}
+.h-full {
+  height: 100%;
+}
+.inline-block {
+  display: inline-block;
+}
+.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>

+ 152 - 0
src/otherPages/pdfList/index.vue

@@ -0,0 +1,152 @@
+<template>
+  <div>
+    <div class="head">
+      <text class="head-text1">电子版答案</text>
+      <image class="head-text1-fire" :src="fireIcon"></image>
+      <div class="head-text2">共5个小节</div>
+    </div>
+    <div class="container">
+      <div @click="goPath('/pages/extraWeb/index')" class="cell">
+        <div class="flex">
+          <div class="cell-dot"></div>
+          <div class="cell-col2">
+            <div class="cell-text1">扣分题技巧口诀</div>
+            <div class="flex">
+              <div class="cell-text2">图文</div>
+              <image
+                style="width: 28rpx; height: 32rpx"
+                :src="diaryIcon"
+              ></image>
+            </div>
+          </div>
+        </div>
+        <div class="flex">
+          <div class="cell-button">开始学习</div>
+        </div>
+      </div>
+      <div  class="cell">
+        <div class="flex">
+          <div class="cell-dot"></div>
+          <div class="cell-col2">
+            <div class="cell-text1">扣分题技巧口诀</div>
+            <div class="flex">
+              <div class="cell-text2">图文</div>
+              <image
+                style="width: 28rpx; height: 32rpx"
+                :src="diaryIcon"
+              ></image>
+            </div>
+          </div>
+        </div>
+        <div class="flex">
+          <div class="cell-button">开始学习</div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import fireIcon from "@/assets/img/fire-icon.png";
+import diaryIcon from "@/assets/img/diary-icon.png";
+export default {
+  data() {
+    return {
+      fireIcon,
+      diaryIcon,
+    };
+  },
+  methods: {
+    goPath(url) {
+        uni.navigateTo({
+            url
+        })
+        
+    }
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.flex {
+  display: flex;
+}
+.head {
+  padding-left: 30px;
+  padding-right: 30px;
+  width: 100%;
+  height: 114rpx;
+  background: #fff;
+  display: flex;
+  align-content: center;
+  align-items: center;
+  flex-wrap: wrap;
+  border-bottom: 2px solid #e8e8e8;
+  .head-text1 {
+    color: #498ef5;
+    font-size: 34rpx;
+  }
+  .head-text1-fire {
+    width: 32rpx;
+    height: 37rpx;
+    margin-left: 10rpx;
+  }
+  .head-text2 {
+    width: 100%;
+    text-align: left;
+    color: #8a9099;
+    font-size: 26rpx;
+  }
+}
+.container {
+  width: 100%;
+  padding-left: 30rpx;
+  padding-right: 30rpx;
+  background: #fff;
+  .cell {
+    width: 100%;
+    display: flex;
+    padding-top: 20rpx;
+    height: 134rpx;
+    justify-content: space-between;
+    border-bottom: 2rpx solid #e8e8e8;
+
+    .cell-dot {
+      width: 20rpx;
+      height: 20rpx;
+      background: #498ef5;
+      border-radius: 50%;
+      margin-top: 10rpx;
+      margin-right: 20rpx;
+    }
+    .cell-col2 {
+      .cell-text1 {
+        font-size: 30rpx;
+      }
+      .cell-text2 {
+        width: 60rpx;
+        height: 32rpx;
+        background: #ffffff;
+        border-radius: 6rpx 6rpx 6rpx 6rpx;
+        opacity: 1;
+        border: 2rpx solid #8a9099;
+        font-size: 22rpx;
+        text-align: center;
+        margin-right: 12rpx;
+      }
+    }
+    .cell-button {
+      width: 144rpx;
+      height: 48rpx;
+      border-radius: 60rpx 60rpx 60rpx 60rpx;
+      opacity: 1;
+      border: 2rpx solid #498ef5;
+      font-size: 26rpx;
+      line-height: 48rpx;
+      color: #498ef5;
+      text-align: center;
+      margin-top: 24rpx;
+    }
+  }
+}
+</style>

+ 42 - 3
src/otherPages/selectRulePaper/index.vue

@@ -1,21 +1,60 @@
 <template>
-  <view style="display:flex">
+  <view style="display: flex">
     <image class="bg" mode="widthFix" :src="bg"></image>
     <view class="buttons">
-      <view class="buttons-left">进入秘卷一</view>
-      <view class="buttons-right">进入秘卷二</view>
+      <view
+        @click="
+          goExerciseMi({
+            category: 3,
+             title:'新规秘卷一'
+          })
+        "
+        class="buttons-left"
+        >进入秘卷一</view
+      >
+      <view
+        @click="
+          goExerciseMi({
+            category: 4,
+            title:'新规秘卷二'
+          })
+        "
+        class="buttons-right"
+        >进入秘卷二</view
+      >
     </view>
   </view>
 </template>
 
 <script>
 //试卷
+import utils from "@/utils/index";
 export default {
   data() {
     return {
       bg: "https://t1-1305573081.cos.ap-shanghai.myqcloud.com/wxapp/static/imgs/selectRulePaperBg/selectRulePaperBg.png",
+      query: {},
     };
   },
+  onLoad(query) {
+    this.query = query;
+  },
+  methods: {
+    goExerciseMi(extraQuery) {
+      let query = Object.assign({}, this.query);
+      if (extraQuery) {
+        query = {
+          ...query,
+          ...extraQuery,
+        };
+      } else {
+      }
+
+      uni.navigateTo({
+        url: "/otherPages/exerciseMi/index?" + utils.mapToUrlQuery(query),
+      });
+    },
+  },
 };
 </script>
 

+ 15 - 0
src/pages.json

@@ -191,6 +191,10 @@
           "path": "exerciseSpecify/index",
           "style": {}
         },
+        {
+          "path": "exerciseMi/index",
+          "style": {}
+        },
         {
           "path": "exerciseFree/index",
           "style": {
@@ -307,6 +311,13 @@
             "navigationBarTitleText":"科一考前秘卷",
             "enablePullDownRefresh": false
           }
+        },
+        {
+          "path":"pdfList/index",
+          "style":{
+            "navigationBarTitleText":"电子版答案",
+            "enablePullDownRefresh": false
+          }
         }
       ]
     }
@@ -417,6 +428,10 @@
         "name": "获取code",
         "path": "otherPages/code/index"
       },
+      {
+        "name": "查看网页",
+        "path": "pages/webview/webview"
+      },
       {
         "name": "购买vip",
         "path": "otherPages/buyVip/index"

+ 13 - 4
src/pages/carVideo/index.vue

@@ -276,7 +276,7 @@
       </swiper>
     </view>
     <!-- #endif -->
-    <view v-if="active == 0" class="two">
+    <view v-if="active == 0 || active == 3" class="two">
       <view
         @click="
           goPath('/otherPages/exerciseFree/index', {
@@ -290,9 +290,9 @@
       </view>
       <view
         @click="
-          goPath('/otherPages/exerciseFree/index', {
+          goPath('/otherPages/selectRulePaper/index', {
             title: '新规秘卷',
-          })
+          },true)
         "
         class="two-item"
       >
@@ -546,6 +546,7 @@ export default {
 
   async mounted() {
     let { data } = await this.$api.carVideo.getTreeList();
+    console.log(data);
     this.typeList = data;
     this.loading = false;
     this.$store.dispatch("GetInfo");
@@ -555,7 +556,15 @@ export default {
     // });
   },
   methods: {
-    goPath(url, extraQuery = {}) {
+    goPath(url, extraQuery = {}, needVip = false) {
+      console.log(this.$store.getters.isVip)
+      if (needVip && !this.$store.getters.isVip) {
+        uni.showToast({
+          title:"需要vip才能使用该功能",
+          icon:"none"
+        })
+        return;
+      }
       uni.navigateTo({
         url:
           url + "?" + utils.mapToUrlQuery({ ...this.tabQuery, ...extraQuery }),

+ 18 - 5
src/pages/extraWeb/index.vue

@@ -1,5 +1,5 @@
 <template>
-  <div>
+  <div class="box">
     <web-view :src="src"></web-view>
   </div>
 </template>
@@ -8,19 +8,32 @@
 export default {
   data() {
     return {
-      query: {},
-      src: "",
+      query: {
+        url: "",
+        file: "",
+      },
+      src: "https://mn1.zzxcx.net/#/pdf/preview",
     };
   },
   methods: {
     name() {},
   },
   onLoad(query) {
-    this.query = query;
-    this.src = this.query.src;
+    // this.query = query;
+    // this.src = this.query.url + "?file=" + this.query.file;
+    // console.log(query);
   },
 };
 </script>
 
 <style lang="scss" scoped>
+.box {
+  position: relative;
+}
+.menu {
+  position: absolute;
+  top: 0;
+  z-index: 9999;
+  background: red;
+}
 </style>