VUE:問卷調查、答題類總結


在vue開發中問卷調查、答題類總結

說明

  • 服務端返回的數據,以及需要提交給服務端的數據
  • 具體思路
  • 主要代碼

一、服務端返回的數據,以及需要提交給服務端的數據:

  • 服務端返回的數據:
//以下是服務端返回的試題列表數據
{
    "data": [
        {
            "id": 13,
            "type": 0,
            "title": "題目1?",
            "options": [
                {
                    "id": 1,// option_id
                    "question_id": 13,
                    "content": "選項1",
                    "score": 0,//分值
                    "ended": 0,// 是否結束題(0 否, 1 是)
                    "jump_id": null // 試題跳轉id  注意:選項優先於試題進行跳轉,如果都沒有跳轉id則進入下一題
                },
                {
                    "id": 2,
                    "question_id": 13,
                    "content": "選項2",
                    "score": 0,
                    "ended": 0,
                    "jump_id": 16
                },
                {
                    "id": 16,
                    "question_id": 13,
                    "content": "選項3",
                    "score": 0,
                    "ended": 0,
                    "jump_id": 16
                },
                {
                    "id": 22,
                    "question_id": 13,
                    "content": "選項4",
                    "score": 0,
                    "ended": 0,
                    "jump_id": null
                },
                {
                    "id": 23,
                    "question_id": 13,
                    "content": "選項5",
                    "score": 0,
                    "ended": 0,
                    "jump_id": null
                },
                {
                    "id": 25,
                    "question_id": 13,
                    "content": "選項6",
                    "score": 0,
                    "ended": 0,
                    "jump_id": null
                }
            ],
            "hint": null, // 提示信息
            "jump_id": null// 試題跳轉id
        },
        {
            "id": 17,
            "type": 0,
            "title": "題目2",
            "options": [
                {
                    "id": 32,
                    "question_id": 17,
                    "content": "選項1",
                    "score": 0,
                    "ended": 0,
                    "jump_id": 18
                },
                {
                    "id": 33,
                    "question_id": 17,
                    "content": "選項2",
                    "score": 2.5,
                    "ended": 0,
                    "jump_id": 18
                },
                {
                    "id": 34,
                    "question_id": 17,
                    "content": "選項3",
                    "score": 3.5,
                    "ended": 0,
                    "jump_id": 18
                },
                {
                    "id": 35,
                    "question_id": 17,
                    "content": "選項4",
                    "score": 4.5,
                    "ended": 0,
                    "jump_id": 18
                }
            ],
            "hint": null,
            "jump_id": null
        },
  • 需要提交給服務端的數據:
  "data": {
    "list": [
      {
        "id": 17,
        "type": 1,
        "title": "題目1",
        "options": [
          {
            "id": 32,
            "question_id": 17,
            "content": "選項1",
            "score": 0,
            "ended": 0,
            "jump_id": 18,
            "select": 0
          },
          {
            "id": 33,
            "question_id": 17,
            "content": "選項2",
            "score": 2.5,
            "ended": 0,
            "jump_id": 18,
            "select": 0
          },
          {
            "id": 34,
            "question_id": 17,
            "content": "選項3",
            "score": 3.5,
            "ended": 0,
            "jump_id": 18,
            "select": 1
          },
          {
            "id": 35,
            "question_id": 17,
            "content": "選項4",
            "score": 4.5,
            "ended": 0,
            "jump_id": 18,
            "select": 1
          }
        ],
        "hint": null,
        "jump_id": null
      },
      {
        "id": 18,
        "type": 0,
        "title": "題目2",
        "options": [
          {
            "id": 36,
            "question_id": 18,
            "content": "選項1",
            "score": 0,
            "ended": 0,
            "jump_id": null,
            "select": 0
          },
          {
            "id": 37,
            "question_id": 18,
            "content": "選項2",
            "score": 1.76,
            "ended": 0,
            "jump_id": null,
            "select": 0
          },
          {
            "id": 38,
            "question_id": 18,
            "content": "選項3",
            "score": 5.27,
            "ended": 0,
            "jump_id": null,
            "select": 1
          },
          {
            "id": 39,
            "question_id": 18,
            "content": "選項4",
            "score": 2.64,
            "ended": 0,
            "jump_id": null,
            "select": 1
          }
        ],
        "hint": "題目注釋",
        "jump_id": 17
      }
    ],
    "age": 21
  }

二、具體思路

1. 請求接口獲取試題列表,並創建一個數組(list)用於最后的提交。

2. 判斷第一題的類型(單、雙選)並渲染。

3. 選擇選項,在選中的選項中加入選中(select)屬性。同時將該題(包含選項)添加進list。

4. 點擊提交按鈕,進行判斷:

  • 判斷是否選擇了選項:是->繼續判斷;否->進行提示。
  • 判斷選項中的ended(是否結束):0->繼續判斷;1->結束答題。
  • 判斷選項中的jump_id(跳轉題目):null->繼續判斷;!null->跳轉到題目id為jump_id的題目。
  • 判斷題目中的jump_id(跳轉題目):null->跳轉到當前題目索引的下一題; !null->跳轉到題目id為jump_id的題目。

5. 結束答題時,將list進行提交

三、主要代碼

<template>
  <div class="exposure-rating">
    <header class="top-title" style="color: #fff">
      <h5>風險評估</h5>
    </header>
    <div class="container">
      <div class="container-wrap">
        <!-- 題目  start  -->
        <div class="container-wrap-title">
          {{ SelectType[showTopic.type] }}
        </div>
        <div class="container-wrap-topic">
          {{ showTopic.title }}
          <span v-if="showTopic.hint">(*{{ showTopic.hint }})</span>
        </div>
        <!-- 題目  end    -->

        <!-- 單選模式渲染的試題選項  start  -->
        <van-radio-group
          v-model="radio"
          v-if="!showTopic.type"
          icon-size="17px"
          checked-color="#ffa135"
          class="container-wrap-elect"
        >
          <van-radio
            :name="index"
            v-for="(item, index) in showTopic.options"
            :key="index"
            @click="choice(item)"
            >{{ item.content }}
          </van-radio>
        </van-radio-group>
        <!-- 單選模式渲染的試題選項  end  -->

        <!-- 多選模式渲染的試題選項 start -->
        <van-checkbox-group
          v-model="result"
          :max="0"
          class="container-wrap-elect"
          icon-size="17px"
          checked-color="#ffa135"
          v-if="showTopic.type"
        >
          <van-checkbox
            :name="index"
            v-for="(item, index) in showTopic.options"
            :key="index"
            @click="choice(item)"
            >{{ item.content }}</van-checkbox
          >
        </van-checkbox-group>
        <!-- 多選模式渲染的試題選項 end -->
      </div>
    </div>

    <!-- 提交  start -->
    <footer>
      <van-button
        round
        type="info"
        class="submit"
        color="#6a74ef"
        @click="submit"
        :disabled="isdisabled"
        >下 一 題</van-button
      >
    </footer>
    <!-- 提交  end -->
  </div>
</template>

<script>
import { ApiModel } from "../../assets/js/request/api";
import { Toast } from "vant";
const apimodel = new ApiModel();
export default {
  data() {
    return {
      pullList: [], //請求獲取的試題列表
      submitList: [], //最后提交需要的試題列表
      showTopic: {}, //渲染的試題
      index: 0, //題目索引
      radio: [], //單選
      result: [], //多選
      SelectType: {
        0: "單選",
        1: "多選",
      },
      jump_id: null, //選項跳轉id
      ended: null, //是否結束答題
      isdisabled: false, //是否禁止答題
    };
  },
  mounted() {
    this.GetList(); //獲取試題列表
  },
  methods: {
    // 1、獲取試題列表
    GetList() {
      apimodel.getQuestionLists().then(
        (res) => {
          this.pullList = res.data.data; //獲取到試題列表
          this.getTopic(); //渲染試題
        },
        (err) => {
          console.log(err, "錯誤原因");
        }
      );
    },
    // 2、渲染試題
    getTopic() {
      this.showTopic = this.pullList[this.index]; //獲取渲染的試題
      this.result = []; //清空選項
      this.radio = [];
      console.log(
        "題目跳轉id:",
        this.pullList[this.index].jump_id,
        "索引:",
        this.index
      );
    },
    // 3、選擇選項
    choice(item) {
      /* 試題為單選 */
      if (this.showTopic.type == 0) {
        this.showTopic.options.map((item1) => {
          item1.select = 0;
        });
        item.select = 1;
        this.ended = item.ended; //是否結束答題
        this.jump_id = item.jump_id; //選項跳轉id
        console.log(
          "(單選)",
          "是否結束答題:",
          this.ended,
          "選項跳轉id:",
          this.jump_id
        );
        return;
      }
      /* 試題為多選 */
      if (this.showTopic.type == 1) {
        item.select = !item.select;
        if (item.select) {
          item.select = 1;
        } else {
          item.select = 0;
        }
        //過濾出有jump_id的選項
        let arry = this.showTopic.options.filter((item) => {
          return item.jump_id !== null;
        });
        //選項跳轉id
        this.jump_id = arry[0].jump_id;
        //過濾出有ended的選項
        let arry1 = this.showTopic.options.filter((item) => {
          return item.ended !== null;
        });
        //是否結束答題
        this.ended = arry1[0].jump_id;
        console.log(
          "(多選)",
          "是否結束答題:",
          this.ended,
          "選項跳轉id:",
          this.jump_id
        );
        return;
      }
    },
    // 4、提交
    submit() {
      let select = {
        isSingle: this.radio.length, //單選
        unSingle: this.result.length, //多選
        isEnd: this.ended, //是否結束答題
        jump_id: this.jump_id, //選項跳轉id
        jumpId: this.showTopic.jump_id, //題目跳轉id
        joinList: this.submitList.push(this.showTopic), //加入最后提交需要的試題列表
      };
      // 4.1、判斷是否選擇選項
      if (select.isSingle == 0 && select.unSingle == 0) {
        Toast.fail("請選擇選項!");
        return;
      }
      // 4.2、判斷是否結束答題
      if (select.isEnd) {
        select.joinList;
        this.getSubmit(); //提交
        return;
      }
      // 4.3、判斷選項跳轉id
      if (select.jump_id) {
        console.log("根據選項跳轉");
        this.index = this.pullList.findIndex((item) => {
          return item.id == select.jump_id;
        });
        this.getTopic();
        return;
      }
      // 4.4、判斷題目跳轉id
      if (select.jumpId) {
        console.log("根據題目跳轉");
        this.index = this.pullList.findIndex((item) => {
          return item.id == select.jumpId;
        });
        this.getTopic();
        return;
      }
      //4.5、根據題目索引跳轉
      if (select.jump_id == null && select.jumpId == null) {
        console.log("根據題目索引跳轉");
        let indexed = this.pullList.findIndex((item) => {
          return item.id == this.showTopic.id;
        });
        this.index = indexed + 1;
        this.getTopic();
        return;
      }
    },
    // 提交請求
    getSubmit() {
      this.isdisabled = true;
      let additional = JSON.parse(this.$route.query.additional);
      let data = {
        data: {
          list: this.submitList,
          additional: additional,
        },
      };
      apimodel.postAddRiskRecord(data).then(
        (res) => {
          let resultStatus = JSON.stringify(res.data.result_snapshot);
          window.sessionStorage.setItem("resultStatus", resultStatus);
          Toast.success("完成測試!");
          setTimeout(() => {
            this.$router.push({
              path: "/riskDetail",
              query: {
                fromRating: "1",
              },
            });
          }, 1500);
        },
        (err) => {
          console.log(err, "返回錯誤");
          Toast.fail(err.data.message);
        }
      );
    },
  },
};
</script>
<style lang="scss" scoped>
.exposure-rating {
  position: relative;
  background-image: linear-gradient(to right, #4a66da, #a2abe0);
  height: 100vh;
  .container {
    position: relative;
    width: 352px;
    height: 230px;
    margin: 20px auto 0;
    .container-wrap {
      position: absolute;
      z-index: 99;
      top: 10px;
      width: 322px;
      margin: 20px auto 0;
      padding: 10px 15px;
      border-radius: 10px;
      background-color: #fff;
      box-shadow: 0px 4px 14px 1px rgba(89, 103, 232, 0.12);
      .container-wrap-title {
        position: absolute;
        top: -7px;
        left: 15px;
        text-align: center;
        line-height: 36px;
        width: 36px;
        height: 36px;
        color: #fff;
        font-size: 13px;
        background-image: url("../../assets/img/risk-choice-bg.png");
        background-size: cover;
      }
      .container-wrap-topic {
        font-size: 20px;
        line-height: 28px;
        color: #222;
        margin-top: 46px;
        span {
          color: red;
          font-size: 12px;
          line-height: 12px;
        }
      }
      .container-wrap-elect {
        margin: 10px 0;
        font-size: 17px;
        div {
          margin: 20px 0 !important;
        }
      }
    }
  }
  footer {
    position: absolute;
    bottom: 0;
    background-color: #f2f3ff;
    height: 440px;
    width: 100%;
    .submit {
      position: fixed;
      bottom: 5%;
      width: 80%;
      left: 10%;
    }
  }
}
</style>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM