+
liuyg
2021-10-09 df26c5424389cbd7fb1aa28a610b124cbac26c54
+
11 files modified
1315 ■■■■ changed files
src/api/exam/exam.js 15 ●●●● patch | view | raw | blame | history
src/api/exam/examscore.js 10 ●●●●● patch | view | raw | blame | history
src/components/Subjects/PracticalOperation/index.vue 319 ●●●● patch | view | raw | blame | history
src/page/index/top/index.vue 2 ●●● patch | view | raw | blame | history
src/page/login/userlogin.vue 334 ●●●● patch | view | raw | blame | history
src/store/getters.js 1 ●●●● patch | view | raw | blame | history
src/store/modules/exam.js 8 ●●●● patch | view | raw | blame | history
src/styles/element-ui.scss 152 ●●●●● patch | view | raw | blame | history
src/views/exam/startexam.vue 74 ●●●● patch | view | raw | blame | history
src/views/singleperformance/index.vue 94 ●●●●● patch | view | raw | blame | history
src/views/startexam/index.vue 306 ●●●● patch | view | raw | blame | history
src/api/exam/exam.js
@@ -34,16 +34,27 @@
    })
}
export const getSubjectIds = (param) => {
export const getSubjectIds = (scoreId) => {
    return request({
        url: '/api/exampaper/queryRandomSubject/',
        method: 'get',
        params: {
            ...param
            scoreId
        }
    })
}
export const getSubjectRefresh = (scoreId) => {
    return request({
        url: '/api/exampaper/getExamRefreshInfo/',
        method: 'get',
        params: {
            scoreId
        }
    })
}
export function anonymousUserGetSubjectIds(id, query) {
    return request({
        url: baseExaminationUrl + 'anonymousUser/' + id + '/subjectIds',
src/api/exam/examscore.js
@@ -8,4 +8,14 @@
            ...param
        }
    })
}
export const reselfExamScore = (scoreId) => {
    return request({
        url: '/api/examScore/refreshTrainExamInfo',
        method: 'post',
        data: {
            scoreId
        }
    })
}
src/components/Subjects/PracticalOperation/index.vue
@@ -1,189 +1,184 @@
<template>
    <div>
        <div class="subject-content">
            <div class="subject-title">
                {{ index }}
                <span class="subject-title-content"
                      v-html="subjectInfo.subjectName" />
                <span class="subject-title-content">
                    (&nbsp;实操题&nbsp;<span v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0">&nbsp;{{subjectInfo.score}}分&nbsp;</span>)
                </span>
            </div>
  <div>
    <div class="subject-content">
      <div class="subject-title">
        {{ index }}
        <span class="subject-title-content" v-html="subjectInfo.subjectName" />
        <span class="subject-title-content">
          (&nbsp;实操题&nbsp;<span
            v-if="subjectInfo.score !== undefined && subjectInfo.score !== 0"
            >&nbsp;{{ subjectInfo.score }}分&nbsp;</span
          >)
        </span>
      </div>
            <ul class="subject-options"
                v-for="(option, index) in options"
                :key="option.id">
                <li class="subject-option pbox">
      <ul
        class="subject-options"
        v-for="(option, index) in options"
        :key="option.id"
      >
        <li class="subject-option pbox">
          <span class="num" @click="selectCheckbox($event, option)">
            {{ userAnswer[index].value }}
          </span>
                    <span class="num"
                          @click="selectCheckbox($event, option)"> {{ userAnswer[index].value }} </span>
                    <label :for="'option' + option.id">
                        <span class="subject-option-prefix">{{ option.optionName + '.' }}&nbsp;</span>
                        <span v-html="option.optionContent"
                              class="subject-option-prefix" />
                    </label>
                </li>
            </ul>
        </div>
          <label :for="'option' + option.id">
            <span class="subject-option-prefix"
              >{{ option.optionName + "." }}&nbsp;</span
            >
            <span v-html="option.optionContent" class="subject-option-prefix" />
          </label>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
export default {
    name: 'MultipleChoices',
    data () {
        return {
            subjectCount: 0,
            subjectInfo: {
                subjectName: '',
                score: 0
            },
            options: [],
            userAnswer: [],
            index: ''
        }
  name: "MultipleChoices",
  data() {
    return {
      subjectCount: 0,
      subjectInfo: {
        subjectName: "",
        score: 0,
      },
      options: [],
      userAnswer: [],
      index: "",
    };
  },
  watch: {},
  methods: {
    getAnswer() {
      return this.userAnswer;
    },
    watch: {
    setAnswer(answer, option) {
      console.log(answer);
      if (answer != "") {
        this.userAnswer = answer;
      } else {
        this.userAnswer = [];
        option.forEach((item) => {
          this.userAnswer.push({ key: item.optionName, value: "" });
        });
      }
    },
    methods: {
        getAnswer () {
            return this.userAnswer
        },
        setAnswer (answer, option) {
            console.log(answer);
            if (answer != '') {
    setSubjectInfo(subject, subjectCount, index) {
      this.subjectCount = subjectCount;
      this.subjectInfo = subject;
      if (subject.hasOwnProperty("examSubjectOptions")) {
        this.options = subject.examSubjectOptions;
      }
      if (subject.hasOwnProperty("answer")) {
        this.setAnswer(subject.answer, subject.examSubjectOptions);
      }
      this.index = index + ".";
    },
    getSubjectInfo() {
      this.subjectInfo.options = this.options;
      return this.subjectInfo;
    },
                this.userAnswer = answer
    selectCheckbox($event, option) {
      var flag = false;
            } else {
                this.userAnswer = []
                option.forEach(item => {
                    this.userAnswer.push({ key: item.optionName, value: '' })
                })
            }
        },
        setSubjectInfo (subject, subjectCount, index) {
            this.subjectCount = subjectCount
            this.subjectInfo = subject
            if (subject.hasOwnProperty('examSubjectOptions')) {
                this.options = subject.examSubjectOptions
            }
            if (subject.hasOwnProperty('answer')) {
                this.setAnswer(subject.answer, subject.examSubjectOptions)
            }
            this.index = index + '.'
        },
        getSubjectInfo () {
            this.subjectInfo.options = this.options
            return this.subjectInfo
        },
        selectCheckbox ($event, option) {
            var flag = false;
            this.userAnswer.forEach(item => {
                if (item.value != "") {
                    flag = true
                }
            })
            this.userAnswer
            if (flag == true) {
                // 其中最少有一个有值的
                var onlyFlag = false;
                var onlyValue = '';
                var ind = 0;
                this.userAnswer.forEach(item => {
                    if (item.value != '' && item.value > ind) {
                        ind = item.value
                    }
                })
                this.userAnswer.forEach(item => {
                    if (item.key == option.optionName) {
                        if (item.value != '') {
                            onlyValue = item.value
                            onlyFlag = true
                            item.value = ''
                        } else {
                            item.value = ind + 1
                        }
                    }
                })
                this.userAnswer.forEach(item => {
                    if (onlyFlag == true) {
                        if (item.value > onlyValue) {
                            item.value -= 1
                        }
                    }
                })
            } else {
                // 全部都为空
                this.userAnswer.forEach(item => {
                    if (item.key == option.optionName) {
                        item.value = 1
                    }
                })
            }
            console.log(this.userAnswer)
        },
        isChecked (optionName) {
            return this.userAnswer.includes(optionName)
      this.userAnswer.forEach((item) => {
        if (item.value != "") {
          flag = true;
        }
    }
}
      });
      this.userAnswer;
      if (flag == true) {
        // 其中最少有一个有值的
        var onlyFlag = false;
        var onlyValue = "";
        var ind = 0;
        this.userAnswer.forEach((item) => {
          if (item.value != "" && item.value > ind) {
            ind = item.value;
          }
        });
        this.userAnswer.forEach((item) => {
          if (item.key == option.optionName) {
            if (item.value != "") {
              onlyValue = item.value;
              onlyFlag = true;
              item.value = "";
            } else {
              item.value = ind + 1;
            }
          }
        });
        this.userAnswer.forEach((item) => {
          if (onlyFlag == true) {
            if (item.value > onlyValue) {
              item.value -= 1;
            }
          }
        });
      } else {
        // 全部都为空
        this.userAnswer.forEach((item) => {
          if (item.key == option.optionName) {
            item.value = 1;
          }
        });
      }
      console.log(this.userAnswer, 123);
      for (var k in this.userAnswer) {
        console.log(this.userAnswer[k]);
      }
    },
    isChecked(optionName) {
      return this.userAnswer.includes(optionName);
    },
  },
};
</script>
<style lang="scss" scoped>
@import '../../../assets/css/subject.scss';
@import "../../../assets/css/subject.scss";
.pbox .num {
    // margin: 2px;
    // text-align: center;
    // vertical-align: middle;
    // display: inline-block;
    // width: 20px;
    // height: 20px;
    // border: 1px solid #999;
    width: 26px;
    height: 26px;
    position: absolute;
    top: 0;
    bottom: 0;
    margin: auto 0;
    // opacity: 0;
    text-align: center;
    font-size: 18px;
    font-weight: bold;
    border: 1px solid #cfcfcf;
    background-color: #ff9;
    cursor: pointer;
  // margin: 2px;
  // text-align: center;
  // vertical-align: middle;
  // display: inline-block;
  // width: 20px;
  // height: 20px;
  // border: 1px solid #999;
  width: 26px;
  height: 26px;
  position: absolute;
  top: 0;
  bottom: 0;
  margin: auto 0;
  // opacity: 0;
  text-align: center;
  font-size: 18px;
  font-weight: bold;
  border: 1px solid #cfcfcf;
  background-color: #ff9;
  cursor: pointer;
}
.subject-options > li label {
    line-height: 36px !important;
  line-height: 36px !important;
}
.pbox.checked {
    border: 1px solid #99f;
    background-color: #ccf;
  border: 1px solid #99f;
  background-color: #ccf;
}
.pbox.checked .num {
    border: 1px solid #ff0;
    background-color: #ff9;
  border: 1px solid #ff0;
  background-color: #ff9;
}
</style>
src/page/index/top/index.vue
@@ -108,7 +108,7 @@
              $t("navbar.userinfo")
            }}</router-link>
          </el-dropdown-item>
          <el-dropdown-item @click.native="logout" divided
          <el-dropdown-item @click.native="logout" divided class="LogOuts"
            >{{ $t("navbar.logOut") }}
          </el-dropdown-item>
        </el-dropdown-menu>
src/page/login/userlogin.vue
@@ -1,168 +1,194 @@
<template>
<div class="login-custom">
  <el-form class="login-form"
           status-icon
           :rules="loginRules"
           ref="loginForm"
           :model="loginForm"
           label-width="0">
    <el-form-item v-if="tenantMode" prop="tenantId" style="display:none">
      <el-input size="small"
                @keyup.enter.native="handleLogin"
                v-model="loginForm.tenantId"
                auto-complete="off"
                :placeholder="$t('login.tenantId')">
        <i slot="prefix" class="icon-quanxian"/>
      </el-input>
    </el-form-item>
    <el-form-item prop="username">
      <el-input size="small"
                @keyup.enter.native="handleLogin"
                v-model="loginForm.username"
                auto-complete="off"
                placeholder="请输入身份证号码">
        <i slot="prefix" class="icon-yonghu"/>
      </el-input>
    </el-form-item>
    <el-form-item prop="password">
      <el-input size="small"
                @keyup.enter.native="handleLogin"
                :type="passwordType"
                v-model="loginForm.password"
                auto-complete="off"
                placeholder="请输入密码,默认密码为身份证号后6位">
        <i class="el-icon-view el-input__icon" slot="suffix" @click="showPassword"/>
        <i slot="prefix" class="icon-mima"/>
      </el-input>
    </el-form-item>
    <el-form-item v-if="this.website.captchaMode" prop="code">
      <el-row :span="24">
        <el-col :span="16">
          <el-input size="small"
                    @keyup.enter.native="handleLogin"
                    v-model="loginForm.code"
                    auto-complete="off"
                    :placeholder="$t('login.code')">
            <i slot="prefix" class="icon-yanzhengma"/>
          </el-input>
        </el-col>
        <el-col :span="8">
          <div class="login-code">
            <img :src="loginForm.image" class="login-code-img" @click="refreshCode"
            />
          </div>
        </el-col>
      </el-row>
    </el-form-item>
    <el-form-item>
      <el-button type="primary"
                 size="small"
                 @click.native.prevent="handleLogin"
                 class="login-submit">{{$t('login.submit')}}
      </el-button>
    </el-form-item>
  </el-form>
</div>
  <div class="login-custom">
    <el-form
      class="login-form"
      status-icon
      :rules="loginRules"
      ref="loginForm"
      :model="loginForm"
      label-width="0"
    >
      <el-form-item v-if="tenantMode" prop="tenantId" style="display: none">
        <el-input
          size="small"
          @keyup.enter.native="handleLogin"
          v-model="loginForm.tenantId"
          auto-complete="off"
          :placeholder="$t('login.tenantId')"
        >
          <i slot="prefix" class="icon-quanxian" />
        </el-input>
      </el-form-item>
      <el-form-item prop="username">
        <el-input
          size="small"
          @keyup.enter.native="handleLogin"
          v-model="loginForm.username"
          auto-complete="off"
          placeholder="请输入身份证号码"
        >
          <i slot="prefix" class="icon-yonghu" />
        </el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input
          size="small"
          @keyup.enter.native="handleLogin"
          :type="passwordType"
          v-model="loginForm.password"
          auto-complete="off"
          placeholder="默认密码为身份证号后6位"
        >
          <i
            class="el-icon-view el-input__icon"
            slot="suffix"
            @click="showPassword"
          />
          <i slot="prefix" class="icon-mima" />
        </el-input>
      </el-form-item>
      <el-form-item v-if="this.website.captchaMode" prop="code">
        <el-row :span="24">
          <el-col :span="16">
            <el-input
              size="small"
              @keyup.enter.native="handleLogin"
              v-model="loginForm.code"
              auto-complete="off"
              :placeholder="$t('login.code')"
            >
              <i slot="prefix" class="icon-yanzhengma" />
            </el-input>
          </el-col>
          <el-col :span="8">
            <div class="login-code">
              <img
                :src="loginForm.image"
                class="login-code-img"
                @click="refreshCode"
              />
            </div>
          </el-col>
        </el-row>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          size="small"
          @click.native.prevent="handleLogin"
          class="login-submit"
          >{{ $t("login.submit") }}
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
  import {mapGetters} from "vuex";
  import {info} from "@/api/system/tenant";
  import {getCaptcha} from "@/api/user";
  import {getTopUrl} from "@/util/util";
import { mapGetters } from "vuex";
import { info } from "@/api/system/tenant";
import { getCaptcha } from "@/api/user";
import { getTopUrl } from "@/util/util";
  export default {
    name: "userlogin",
    data() {
      return {
        tenantMode: this.website.tenantMode,
        loginForm: {
          //租户ID
          tenantId: "000000",
          //用户名
          username: "",
          //密码
          password: "",
          //账号类型
          type: "account",
          //验证码的值
          code: "",
          //验证码的索引
          key: "",
          //预加载白色背景
          image: "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
        },
        loginRules: {
          tenantId: [
            {required: false, message: "请输入租户ID", trigger: "blur"}
          ],
          username: [
            {required: true, message: "请输入身份证号码", trigger: "blur"}
          ],
          password: [
            {required: true, message: "请输入密码,默认密码为身份证号后6位", trigger: "blur"},
            {min: 1, message: "密码长度最少为6位", trigger: "blur"}
          ]
        },
        passwordType: "password"
      };
    },
    created() {
      this.getTenant();
      this.refreshCode();
    },
    mounted() {
    },
    computed: {
      ...mapGetters(["tagWel"])
    },
    props: [],
    methods: {
      refreshCode() {
        getCaptcha().then(res => {
          const data = res.data;
          this.loginForm.key = data.key;
          this.loginForm.image = data.image;
        })
export default {
  name: "userlogin",
  data() {
    return {
      tenantMode: this.website.tenantMode,
      loginForm: {
        //租户ID
        tenantId: "000000",
        //用户名
        username: "",
        //密码
        password: "",
        //账号类型
        type: "account",
        //验证码的值
        code: "",
        //验证码的索引
        key: "",
        //预加载白色背景
        image:
          "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",
      },
      showPassword() {
        this.passwordType === ""
          ? (this.passwordType = "password")
          : (this.passwordType = "");
      loginRules: {
        tenantId: [
          { required: false, message: "请输入租户ID", trigger: "blur" },
        ],
        username: [
          { required: true, message: "请输入身份证号码", trigger: "blur" },
        ],
        password: [
          {
            required: true,
            message: "请输入密码,默认密码为身份证号后6位",
            trigger: "blur",
          },
          { min: 1, message: "密码长度最少为6位", trigger: "blur" },
        ],
      },
      handleLogin() {
        this.$refs.loginForm.validate(valid => {
          if (valid) {
            const loading = this.$loading({
              lock: true,
              text: '登录中,请稍后。。。',
              spinner: "el-icon-loading"
            });
            this.$store.dispatch("LoginByUsername", this.loginForm).then(() => {
              this.$router.push({path: this.tagWel.value});
      passwordType: "password",
    };
  },
  created() {
    this.getTenant();
    this.refreshCode();
  },
  mounted() {},
  computed: {
    ...mapGetters(["tagWel"]),
  },
  props: [],
  methods: {
    refreshCode() {
      getCaptcha().then((res) => {
        const data = res.data;
        this.loginForm.key = data.key;
        this.loginForm.image = data.image;
      });
    },
    showPassword() {
      this.passwordType === ""
        ? (this.passwordType = "password")
        : (this.passwordType = "");
    },
    handleLogin() {
      this.$refs.loginForm.validate((valid) => {
        if (valid) {
          const loading = this.$loading({
            lock: true,
            text: "登录中,请稍后。。。",
            spinner: "el-icon-loading",
          });
          this.$store
            .dispatch("LoginByUsername", this.loginForm)
            .then(() => {
              this.$router.push({ path: this.tagWel.value });
              loading.close();
            }).catch(() => {
            })
            .catch(() => {
              loading.close();
              this.refreshCode();
            });
          }
        });
      },
      getTenant() {
        let domain = getTopUrl();
        // 临时指定域名,方便测试
        //domain = "https://bladex.vip";
        info(domain).then(res => {
          const data = res.data;
          if (data.success && data.data.tenantId) {
            this.tenantMode = false;
            this.loginForm.tenantId = data.data.tenantId;
            this.$parent.$refs.login.style.backgroundImage = `url(${data.data.backgroundUrl})`;
          }
        })
      }
    }
  };
        }
      });
    },
    getTenant() {
      let domain = getTopUrl();
      // 临时指定域名,方便测试
      //domain = "https://bladex.vip";
      info(domain).then((res) => {
        const data = res.data;
        if (data.success && data.data.tenantId) {
          this.tenantMode = false;
          this.loginForm.tenantId = data.data.tenantId;
          this.$parent.$refs.login.style.backgroundImage = `url(${data.data.backgroundUrl})`;
        }
      });
    },
  },
};
</script>
<style>
src/store/getters.js
@@ -30,6 +30,7 @@
  subject: state => state.exam.subject,
  examRecord: state => state.exam.examRecord,
  incorrectRecord: state => state.exam.incorrectRecord,
  scoreId: state => state.exam.scoreId,
  examUserData: state => state.exam.examUserData,
}
src/store/modules/exam.js
@@ -17,9 +17,9 @@
      name: 'incorrectRecord'
    }) || {},
    examUserData: {},
    scoreId: '',
  },
  actions: {
    // 设置题目信息
    SetSubjectInfo({ commit, state }, subject) {
      commit('SET_SUBJECT', subject)
@@ -53,7 +53,13 @@
    }
  },
  mutations: {
    // 重置考试id赋值
    SetScoreId(state, data) {
      window.localStorage.setItem("scoreId", data)
      state.scoreId = data;
    },
    SetexamUserData(state, data) {
      window.localStorage.setItem("useInfo", JSON.stringify(data))
      state.examUserData = data;
    },
    SET_EXAM: (state, exam) => {
src/styles/element-ui.scss
@@ -20,7 +20,7 @@
}
.el-menu--display,
.el-menu--display+.el-submenu__icon-arrow {
.el-menu--display + .el-submenu__icon-arrow {
    display: none;
}
@@ -49,17 +49,17 @@
.el-dropdown-menu__item--divided:before,
.el-menu,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
.el-menu--horizontal > .el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal > .el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal > .el-submenu .el-submenu__title:hover {
    background-color: transparent;
}
.el-dropdown-menu__item--divided:before,
.el-menu,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
.el-menu--horizontal > .el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal > .el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal > .el-submenu .el-submenu__title:hover {
    background-color: transparent !important;
}
@@ -84,4 +84,140 @@
.login-form .el-input__inner {
    font-size: 15px;
}
}
//整体放大
* {
    font-size: x-large !important;
}
.el-form-item__error {
    font-size: 18px !important;
}
.login-left {
    .login-time {
        font-size: 35px !important;
    }
    .title {
        font-size: 40px !important;
    }
    .title,
    img {
        position: relative !important;
        top: 30px !important;
    }
}
.login-main {
    position: relative !important;
    top: -20px !important;
    width: 75% !important;
    .login-title {
        font-size: 40px !important;
    }
}
.LogOuts {
    font-size: 30px !important;
}
.startexam.avue-view {
    .startexam_heard {
        font-size: 50px !important;
    }
    .startexam_main {
        height: 460px !important;
        width: 1100px !important;
        .s_m_value {
            width: 61% !important;
            span {
                font-size: 35px !important;
            }
            .s_m_v_title {
                width: 180px !important;
            }
        }
    }
}
.exam-end {
    .startexam_heard {
        font-size: 50px !important;
    }
    .startexam_main {
        height: 460px !important;
        width: 1100px !important;
        .s_m_value {
            width: 61% !important;
            span {
                font-size: 35px !important;
            }
            .s_m_v_title {
                width: 180px !important;
            }
        }
    }
}
.exam-card-body {
    .subject-box-card {
        width: 100% !important;
    }
    div {
        font-size: 38px !important;
    }
    .time-remain,
    .current-progress,
    .answer-card {
        margin-bottom: 30px !important;
    }
    .time {
        span,
        i {
            font-size: 50px !important;
        }
    }
    .subject-exam-title {
        font-size: 30px !important;
    }
    .subject-content {
        span {
            font-size: 24px !important;
        }
        .subject-title {
            font-size: 24px !important;
            line-height: 24px !important;
            letter-spacing: 0.1rem !important;
        }
    }
    .subject-option-prefix {
        font-size: 24px !important;
    }
    .subject-options > li label {
        padding: 2px 10px 4px 45px;
    }
    .subject-buttons {
        top: 0px !important;
    }
    .subject-option.pbox {
        span {
            // display: flex;
            // align-items: center;
            // justify-content: center;
        }
    }
}
.datika {
    .answer-card-title {
        font-size: 23px !important;
    }
    .el-button {
        span {
            display: flex;
            align-items: center;
            justify-content: center;
            // position: relative !important;
            // left: -1 !important;
        }
    }
}
.login-custom {
}
src/views/exam/startexam.vue
@@ -1,8 +1,8 @@
/*
 * @Author: Morpheus
 * @Date: 2021-07-31 16:31:54
 * @Last Modified by: Morpheus
 * @Last Modified time: 2021-07-18 17:09:52
 * @Last Modified by: liu
 * @Last Modified time: 2021-10-09 16:08:06
 * menu-name 考试管理
 */
<template>
@@ -51,7 +51,7 @@
      resData: null,
      sex: "",
      pageDisable: false,
      isTime:2,
      isTime: 2,
      option: {
        span: 8,
        data: [
@@ -61,7 +61,6 @@
        ],
      },
    };
  },
  computed: {
    ...mapState({
@@ -89,18 +88,18 @@
    //开始考试跳转
    startExam() {
      //判断是否到了考试时间
      if(this.isTime==3){
      if (this.isTime == 3) {
        this.$message({
            type: "warning",
            message: "未到考试时间!"
          type: "warning",
          message: "未到考试时间!",
        });
        return;
      }
      //已超过考试截止时间
      if(this.isTime==1){
      if (this.isTime == 1) {
        this.$message({
            type: "warning",
            message: "已过考试时间!"
          type: "warning",
          message: "已过考试时间!",
        });
        return;
      }
@@ -111,9 +110,30 @@
        examType: this.resData.examType,
        examId: this.resData.id,
        userId: this.userInfo.user_id,
        candidateNo: this.resData.candidateNo,
      };
      // this.$notify({
      //   message:
      //     "考试期间切勿退出登入、关闭浏览器, 否则考试成绩无效, 如有问题及时联系管理人员!",
      //   duration: 6000,
      //   showClose: false,
      //   customClass: "beginS",
      //   // type: "warning",
      // });
      // return;
      updateApplyStatus(data).then((res) => {
        that.resData["examScoreId"] = res.data.id;
        this.$store.commit("SetScoreId", res.data.id);
        console.log(res.data.id, "ididididiidididididid");
        window.name = "";
        this.$notify({
          message:
            "考试期间切勿退出登入、关闭浏览器, 否则考试成绩无效, 如有问题及时联系管理人员!",
          duration: 6000,
          showClose: false,
          customClass: "beginS",
          // type: "warning",
        });
        that.$router.push({
          path: `/startexam/${that.resData.id}`,
          query: that.resData,
@@ -125,23 +145,24 @@
      getExamDetail(this.userInfo.user_id).then(
        (res) => {
          that.resData = res.data.data[0];
          var data = res.data.data[0];
          // console.log(data,333);
          //当前时间
          var nowD = new Date(),
          startD = new Date(data.startTime),
          //考试截止时间
          endD = new Date(data.endTime);
          var nowD = new Date(),
            startD = new Date(data.startTime),
            //考试截止时间
            endD = new Date(data.endTime);
          //对比时间
          //getTime() 方法可返回距 1970 年 1 月 1 日之间的毫秒数。
          if( nowD.getTime() > startD.getTime()){
              if(endD.getTime() < nowD.getTime()){
                  that.isTime = 1;
              }else{
                  that.isTime = 2;
              }
          }else{
              that.isTime = 3;
          if (nowD.getTime() > startD.getTime()) {
            if (endD.getTime() < nowD.getTime()) {
              that.isTime = 1;
            } else {
              that.isTime = 2;
            }
          } else {
            that.isTime = 3;
          }
          if (res.data.data.length > 0) {
            that.pageDisable = true;
@@ -253,4 +274,13 @@
    }
  }
}
.beginS {
  height: 180px;
  width: 500px;
}
.el-notification__content {
  font-size: 90px !important;
  line-height: 44px !important;
}
</style>
src/views/singleperformance/index.vue
@@ -1,8 +1,8 @@
/*
 * @Author: Morpheus
 * @Date: 2021-08-02 09:31:54
 * @Last Modified by: Morpheus
 * @Last Modified time: 2021-08-02 09:31:54
 * @Last Modified by: liu
 * @Last Modified time: 2021-10-09 16:22:20
 * menu-name 成绩管理
 */
<template>
@@ -21,14 +21,15 @@
            </div>
        </div> -->
    <div class="startexam_heard">
      {{ examUserData.title }}
      {{ UserData.title }}
    </div>
    <div class="startexam_main">
      <div class="s_m_img">
        <img src="/img/exam/startbg.jpg" alt="" />
      </div>
      <div class="s_m_value" v-if="examUserData.list.length != 0">
        <div v-for="(item, index) in examUserData.list" :key="index">
      <div class="s_m_value">
        <!-- <div class="s_m_value" v-if="examUserData.list.length != 0"> -->
        <div v-for="(item, index) in UserData.list" :key="index">
          <span class="s_m_v_title">{{ item.title }}</span>
          <span>{{ item.value }}</span>
        </div>
@@ -38,29 +39,66 @@
            <span style="font-size: 32px">{{ score }}</span> &nbsp;分</span
          >
        </div>
        <div>
          <el-button type="primary" round v-if="score <= 60" @click="reself"
            >重新考试</el-button
          >
        </div>
      </div>
    </div>
    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
      width="90%"
      :modal-append-to-body="false"
    >
      <el-form ref="form" :model="form" label-width="400px">
        <el-form-item label="请联系管理员,输入重新考试密码:">
          <el-input
            v-model="paddWord"
            placeholder="请输入密码"
            show-password
          ></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="reself(1)">开始重考</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import { getExamScore } from "@/api/exam/examscore";
import { getExamScore, reselfExamScore } from "@/api/exam/examscore";
import { mapState } from "vuex";
export default {
  data() {
    return {
      score: 0,
      dialogVisible: false,
      paddWord: "",
      UserData: window.localStorage.getItem("useInfo")
        ? JSON.parse(window.localStorage.getItem("useInfo"))
        : "",
    };
  },
  created() {},
  created() {
    console.log(this.UserData, "UserDataUserDataUserData");
  },
  computed: {
    ...mapState({
      examUserData: (state) => state.exam.examUserData,
      scoreId: (state) =>
        state.exam.scoreId
          ? state.exam.scoreId
          : window.localStorage.getItem("scoreId"),
    }),
  },
  mounted() {
    //获取考试成绩
    this.getExamScore();
    console.log(this.examUserData);
  },
  methods: {
    //退出登录
@@ -81,9 +119,49 @@
        examId: this.$route.query.examId,
      };
      getExamScore(data).then((res) => {
        this.score = res.data.data.theoryGrade;
        if (res.data.data.theoryGrade != undefined) {
          this.score = res.data.data.theoryGrade;
        }
        // console.log(this.score);
      });
    },
    reself(val) {
      //重新考试
      console.log(this.scoreId);
      // return;
      if (val == 1) {
        if (this.paddWord != "zhdn123") {
          //重置密码
          this.$message({
            showClose: true,
            message: "密码错误!请联系管理员",
            type: "warning",
          });
          return;
        }
        reselfExamScore(this.scoreId).then((res) => {
          if ((res.data.success = true)) {
            this.$message({
              showClose: true,
              message: "重置成功,返回主页重新点击开始考试!",
              type: "success",
            });
            this.paddWord = "";
            this.$router.push({
              path: `/exam/startexam`,
            });
          } else {
            this.$message({
              showClose: true,
              message: "重置错误!请联系管理员",
              type: "warning",
            });
          }
        });
      } else {
        this.dialogVisible = true;
      }
    },
  },
};
</script>
src/views/startexam/index.vue
@@ -39,13 +39,13 @@
                      >答题卡</el-button
                    >
                  </div>
                  <el-button
                  <!-- <el-button
                    type="success"
                    icon="el-icon-date"
                    @click="submitExam"
                    v-bind:disabled="disableSubmit"
                    >提交</el-button
                  >
                  > -->
                </div>
              </el-col>
              <el-col :span="18">
@@ -86,12 +86,18 @@
                      type="primary"
                      >下一题</el-button
                    >
                    <!-- :disabled="timesIT" -->
                    <el-button
                      type="success"
                      style="display: none"
                      @click="submitExam"
                      v-bind:disabled="disableSubmit"
                      >提交</el-button
                      :title="
                        timesIT
                          ? '根据国家考试要求,30分钟内不可提交! 剩(' +
                            timesITValue +
                            ')分钟'
                          : '点击完成考试'
                      "
                      >完成考试 {{ time }}</el-button
                    >
                  </div>
                </div>
@@ -104,6 +110,7 @@
              top="10vh"
              :modal="false"
              center
              class="datika"
            >
              <div class="answer-card-title">
                {{ exam.examinationName }}(共{{
@@ -127,6 +134,7 @@
                  :key="index"
                  >&nbsp;{{ index + 1 }}&nbsp;</el-button
                >
                <!-- @click="toSubject(value.everyID, value.type, index)" -->
              </el-row>
            </el-dialog>
          </div>
@@ -139,7 +147,7 @@
import { mapState } from "vuex";
import CountDown from "vue2-countdown";
import { saveAndNext } from "@/api/exam/answer";
import { getSubjectIds } from "@/api/exam/exam";
import { getSubjectIds, getSubjectRefresh } from "@/api/exam/exam";
import { getCurrentTime } from "@/api/exam/examRecord";
import { getSubjectResultInfo } from "@/api/exam/subject";
@@ -217,14 +225,36 @@
        newRecord: false,
      },
      firstFlag: true,
      times: ["30", "00"],
      timeOut: null,
      timeOTiv: null,
      timesIT: true,
      timesITValue: 0,
      first: true,
    };
  },
  computed: {
    ...mapState({
      userInfo: (state) => state.user.userInfo,
      scoreId: (state) =>
        state.exam.scoreId
          ? state.exam.scoreId
          : window.localStorage.getItem("scoreId"),
    }),
    time() {
      var d = [+this.times[0], +this.times[1]];
    },
  },
  created() {
    if (window.name == "") {
      // console.log("首次被加载");
      window.name = "first"; // 在首次进入页面时我们可以给window.name设置一个固定值
      this.first = true;
    } else if (window.name == "first") {
      // console.log("页面被刷新");
      this.first = false;
    }
    const examInfo = this.$route.params.id;
    if (isNotEmpty(examInfo)) {
@@ -253,6 +283,43 @@
      messageSuccess(this, "考试开始");
      this.startTime = this.getCurrentTimes();
    },
    bottonControl(time) {
      //倒计时循环
      let times = time * 60;
      var setTime = function (time) {
        let a, b, d;
        a = parseInt(time / 60);
        b = time - a * 60;
        d = a + ":" + b;
        return d;
      };
      if (this.timeOTiv == null) {
        this.timeOTiv = setInterval((res) => {
          times--;
          this.timesITValue = setTime(times);
        }, 1000);
      } else {
        clearTimeout(this.timeOTiv);
        this.timeOTiv = null;
        this.timeOTiv = setInterval((res) => {
          times--;
          this.timesITValue = setTime(times);
        }, 1000);
      }
      //倒计时定时
      if (this.timeOut == null) {
        this.timeOut = setTimeout((res) => {
          this.timesIT = false;
          this.timesITValue--;
        }, time * 3600);
      } else {
        clearTimeout(this.timeOut);
        this.timeOut = null;
        this.timeOut = setTimeout((res) => {
          this.timesIT = false;
        }, time * 3600);
      }
    },
    validateExamTime() {
      getCurrentTime()
        .then((response) => {
@@ -262,26 +329,188 @@
          } else if (currentTime.isBefore(this.exam.startTime)) {
            messageWarn(this, "考试未开始");
          } else {
            this.startExam();
            const current = currentTime.valueOf();
            this.currentTime = current;
            this.startTime = current;
            this.subjectStartTime = current;
            // this.endTime = moment(this.exam.endTime).valueOf()
            this.endTime = current + 60 * 60 * 1000;
            // this.endTime = current + 1 * 60 * 1000;
            this.disableSubmit = false;
            //判断是否是答过题
            this.startExam(currentTime);
            //判断是否是答过题
            if (this.first) {
              const current = currentTime.valueOf();
              // console.log(current, "首次");
              this.currentTime = current;
              this.startTime = current;
              this.subjectStartTime = current;
              //   // this.endTime = moment(this.exam.endTime).valueOf()
              this.endTime = current + 60 * 60 * 1000;
              this.bottonControl(60);
            }
            // this.disableSubmit = false;
          }
        })
        .catch(() => {
          messageFail(this, "开始考试失败!15");
        });
    },
    startExam() {
    startExam(currentTime) {
      var scoreId = window.localStorage.getItem("scoreId");
      console.log(scoreId, this.first, "scoreIdscoreIdscoreIdscoreId");
      this.subjectIds = [];
      // if (this.first) {
      //   const current = currentTime.valueOf();
      //   console.log(current, "首次");
      //   this.currentTime = current;
      //   this.startTime = current;
      //   this.subjectStartTime = current;
      //   //   // this.endTime = moment(this.exam.endTime).valueOf()
      //   this.endTime = current + 60 * 60 * 1000;
      // }
      if (!this.first) {
        getSubjectRefresh(scoreId).then((obj) => {
          const objs = obj.data.data;
          console.log(objs, "objobjobjobjobjobj");
          const subjectData = objs.examSubjectChoicesVOSList;
          if (subjectData.length > 0) {
            //重载题目
            for (let i = 0; i < subjectData.length; i++) {
              this.subjectIds.push({
                subjectId: 1,
                everyID: subjectData[i].id,
                type: subjectData[i].choicesType,
                index: i + 1,
                answered: false,
                answer: "",
                score: subjectData[i].score,
                color: "#fff",
                fontColor: "#000",
              });
            }
            //题目类型
            // this.query.type = parseInt(this.subjectIds[0].type);
            // 题目id
            // this.query.subjectId = this.subjectIds[0].everyID;
            this.updateSubjectIndex();
            // 获取当前题目信息
            getSubjectResultInfo({
              id: this.subjectIds[0].everyID,
            })
              .then((response) => {
                if (isNotEmpty(response.data.data)) {
                  response.data.data.answer = "";
                  this.setSubjectInfo(response.data.data);
                }
              })
              .catch(() => {
                messageFail(this, "获取题目失败!");
              });
            //重载到当前题目
            const nowObj = objs.examSubjectChoicesVO;
            for (var i = 0; i < this.subjectIds.length; i++) {
              if (nowObj.id == this.subjectIds[i].everyID) {
                //定位显示题目
                this.subjectIndex = i + 1;
                //题目类型
                this.query.type = parseInt(this.subjectIds[i].type);
                // 题目id
                this.query.subjectId = this.subjectIds[i].everyID;
              }
            }
            // 添加到答题卡
            const anSwer = objs.examAnswerRecordList;
            for (var i = 0; i < this.subjectIds.length; i++) {
              for (var n = 0; n < anSwer.length; n++) {
                // console.log(anSwer[i].subjectChoicesId);
                if (anSwer[n].subjectChoicesId == this.subjectIds[i].everyID) {
                  if (anSwer[n].answerResult == 1) {
                    this.subjectIds[i].color = "#67C23A";
                    this.subjectIds[i].fontColor = "#fff";
                  }
                  if (anSwer[n].answerResult == 2) {
                    this.subjectIds[i].color = "red";
                    this.subjectIds[i].fontColor = "#fff";
                  }
                  var test = /,/g;
                  if (test.test(anSwer[n].answerOption)) {
                    let ans = anSwer[n].answerOption.split(","),
                      anw = [];
                    for (var k = 0; k < ans.length; k++) {
                      anw.push({
                        key: k + 1,
                        value: ans[k],
                      });
                    }
                    this.subjectIds[i].answer = anw;
                  } else {
                    this.subjectIds[i].answer = anSwer[n].answerOption;
                  }
                  // console.log(anSwer[n].answerOption, 1);
                  // console.log(this.subjectIds[i].answer, 2);
                }
              }
            }
            //适应时间
            const datyTime = objs.examScore.examTime;
            var duibiTime = function (newTime, oldTime) {
              var newYear = newTime.split(" ")[0],
                newDat = newTime.split(" ")[1],
                oldYear = oldTime.split(" ")[0],
                oldDat = oldTime.split(" ")[1];
              if (newYear !== oldYear) {
                return false;
              } else {
                let newD = {
                  s: +newDat.split(":")[0],
                  f: +newDat.split(":")[1],
                  m: +newDat.split(":")[2],
                };
                let oldD = {
                  s: +oldDat.split(":")[0],
                  f: +oldDat.split(":")[1],
                  m: +oldDat.split(":")[2],
                };
                if (newD.s - oldD.s > 1) {
                  return false;
                } else if (newD.s - oldD.s == 1) {
                  if (newD.f < oldD.f) {
                    return oldD.f - newD.f;
                  } else {
                    return false;
                  }
                } else if (newD.s == oldD.s) {
                  return 60 - (newD.f - oldD.f);
                }
                return [newD, oldD];
              }
              // return false;
            };
            var listTime = duibiTime(currentTime._i, datyTime);
            // console.log(listTime, "listTimelistTimelistTime");
            const current = currentTime.valueOf();
            this.currentTime = current;
            this.startTime = current;
            this.subjectStartTime = current;
            // // this.endTime = moment(this.exam.endTime).valueOf()
            if (listTime) {
              this.endTime = current + listTime * 60 * 1000;
              this.bottonControl(listTime - 30);
            } else {
              this.endTime = current + 0 * 60 * 1000;
              this.bottonControl(0);
            }
            // console.log(datyTime, currentTime, "刷新");
          }
        });
        // this.first = true;
        return;
      }
      // console.log(this.subjectIds);
      // 获取题目ID列表
      getSubjectIds()
      getSubjectIds(scoreId)
        .then((subjectResponse) => {
          const subjectData = subjectResponse.data.data;
          console.log(
            subjectResponse,
            "subjectResponsesubjectResponsesubjectResponse"
          );
          console.log(subjectData, "subjectDatasubjectDatasubjectData");
          if (subjectData.length > 0) {
            for (let i = 0; i < subjectData.length; i++) {
              this.subjectIds.push({
@@ -357,7 +586,10 @@
      for (let i = 0; i < this.subjectIds.length; i++) {
        if (this.subjectIds[i].everyID == this.query.subjectId) {
          if (this.getAnswer() == "") {
            messageSuccess(this, "请选择答案");
            this.$message({
              message: "请选择答案",
              type: "warning",
            });
            return;
          }
@@ -388,35 +620,34 @@
    saveCurrentSubjectAndGetNextSubject(nextType, nextSubjectId, subjectIds) {
      this.startLoading(nextType);
      console.log()
      // console.log();
      var answerData = this.getAnswer();
      var str = '';
      var str = "";
      if (Array.isArray(answerData)) {
        answerData.forEach(item => {
          str += item.value + ','
        })
        answerData.forEach((item) => {
          str += item.value + ",";
        });
        str = str.substr(0, str.length - 1);
        answerData = str
        answerData = str;
      }
      var data = {
        id: nextSubjectId,
        preSubJectId: this.query.subjectId,
        preResult: answerData,
        scoreId: this.scoreId,
      };
      getSubjectResultInfo(data)
        .then((response) => {
          if (response.data.data !== null) {
            // 保存成功后更新答题卡状态
            const subject = response.data.data;
            console.log(subject.answer, 123456);
            //结果
            this.result = response.data.data.result;
@@ -538,9 +769,9 @@
      this.subjectIndex = index + 1;
      this.firstFlag = true;
      // 保存当前题目,同时加载下一题
      console.log(nextSubjectType.next,111);
      console.log(everyID,222);
      console.log(type,333);
      console.log(nextSubjectType.next, 111);
      console.log(everyID, 222);
      console.log(type, 333);
      this.saveCurrentSubjectAndGetNextSubject(
        nextSubjectType.next,
        everyID,
@@ -551,6 +782,7 @@
    },
    // 提交
    submitExam(val) {
      console.log(val);
      var ind = this.subjectIndex;
      if (this.firstFlag == false) {
@@ -596,8 +828,11 @@
        examResultVOS: null,
      };
      var arr = [];
      this.subjectIds.forEach((item) => {
        if (item.type == 3) {
      // console.log(this.subjectIds);
      for (var i = 0; i < this.subjectIds.length; i++) {
        let item = this.subjectIds[i];
        // console.log(item.answer, i);
        if (item.type == 3 || item.type == 1) {
          var str = "";
          if (item.answer.length > 0) {
@@ -622,9 +857,12 @@
            grade: item.score,
          });
        }
      });
      }
      console.log(arr);
      // return;
      obj.examResultVOS = arr;
      // console.log(this.subjectIds);
      // console.log(obj.examResultVOS);
      saveAndNext(obj)
        .then((response) => {