feat(安全): 添加加密解密功能并更新考试组件
- 新增crypto-js依赖用于数据加密解密 - 添加decrypt.js工具文件实现AES解密功能 - 修改Exam.vue组件使用加密接口获取考试数据 - 清理main.js中多余空行并格式化代码
This commit is contained in:
parent
a3823b4735
commit
b20c4dc376
@ -19,6 +19,7 @@
|
||||
"console": "^0.7.2",
|
||||
"core-js": "^3.39.0",
|
||||
"crypto": "^1.0.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"cssnano": "^4.1.10",
|
||||
"exif-js": "^2.3.0",
|
||||
"font-awesome": "^4.7.0",
|
||||
|
@ -50,7 +50,7 @@
|
||||
<div class="lianxiTiMu" v-for="(item, index) in current_question_data.content" :key="index"
|
||||
@click="responseQ(item)">
|
||||
<span class="lianxiXueZe" v-bind:class="{ active: current_question_data.response == item }">{{ xuhao[index]
|
||||
}}</span>
|
||||
}}</span>
|
||||
<span class="lianxiXueZe1">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -62,7 +62,7 @@
|
||||
<div class="lianxiTiMu" v-for="(item, index) in current_question_data.content" :key="index"
|
||||
@click="responseQ(item)">
|
||||
<span class="lianxiXueZe" v-bind:class="{ active: current_question_data.response == item }">{{ xuhao[index]
|
||||
}}</span>
|
||||
}}</span>
|
||||
<span class="lianxiXueZe1">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -101,7 +101,7 @@
|
||||
<div class="lianxiBottomR" @click="popupVisible = true">
|
||||
<img src="../../../static/img/gengduo.png" alt="" /><span>{{
|
||||
current_question + 1
|
||||
}}</span>/{{ questions.length }}
|
||||
}}</span>/{{ questions.length }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -116,7 +116,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</mt-popup>
|
||||
<mt-popup v-model="popupVisible2" popup-transition="popup-fade" style="background-color: #5e5e5e; border-radius: 20px;">
|
||||
<mt-popup v-model="popupVisible2" popup-transition="popup-fade"
|
||||
style="background-color: #5e5e5e; border-radius: 20px;">
|
||||
<div style=" top: 5px; font-size: 20px; font-weight: bold; margin: 20px 0; color: white;">请选择要考试的课程</div>
|
||||
<div style=" margin: 30px; width: 250px;" v-for="(item, index) in courseData" :key="index">
|
||||
<mt-button @click="btn_courseID(item.id)" type="default" class=""
|
||||
@ -143,6 +144,7 @@ import { getStore } from "@/utils/storage";
|
||||
import { Toast } from "mint-ui";
|
||||
import { MessageBox } from "mint-ui";
|
||||
import WXTake from "../study/weixinTake.vue";
|
||||
import { decrypt } from "@/utils/decrypt";
|
||||
export default {
|
||||
name: "LiuYan",
|
||||
components: { Back, WXTake },
|
||||
@ -185,11 +187,11 @@ export default {
|
||||
token: getStore("token"),
|
||||
}).then((data) => {
|
||||
this.courseData = data.data;
|
||||
if(this.courseData.length === 1){
|
||||
if (this.courseData.length === 1) {
|
||||
this.btn_courseID(this.courseData[0].id);
|
||||
}else if(this.courseData.length > 1){
|
||||
} else if (this.courseData.length > 1) {
|
||||
this.popupVisible2 = true;
|
||||
}else {
|
||||
} else {
|
||||
Toast("暂无考试");
|
||||
}
|
||||
});
|
||||
@ -267,19 +269,20 @@ export default {
|
||||
var current_time_stamp = new Date().getTime();
|
||||
|
||||
//调用接口,获得正式考试的相关数据
|
||||
this.getData("/Question/getExamQuestions", {
|
||||
// this.getData("/Question/getExamQuestions", {
|
||||
this.getData("/Question/getExamQuestionsSecurity", {
|
||||
token: getStore("token"),
|
||||
course_id: this.courseID,
|
||||
}).then(
|
||||
(data) => {
|
||||
// console.log("data=>",data.data.exam_data);
|
||||
if (data.code == 1) {
|
||||
const questions = decrypt(data.data);
|
||||
let _this = this;
|
||||
this.is_start = 1;
|
||||
this.id = data.data.id;
|
||||
this.questions = data.data.question_data;
|
||||
this.current_question_data = data.data.question_data[0];
|
||||
this.exam_data = data.data.exam_data;
|
||||
this.id = questions.id;
|
||||
this.questions = questions.question_data;
|
||||
this.current_question_data = questions.question_data[0];
|
||||
this.exam_data = questions.exam_data;
|
||||
this.title = "正式考试";
|
||||
this.monishow = false;
|
||||
var count = 1;
|
||||
@ -873,6 +876,7 @@ export default {
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.mask-content {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
@ -881,6 +885,7 @@ export default {
|
||||
width: 80%;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.mask-content p {
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
|
@ -25,7 +25,6 @@ import "regenerator-runtime/runtime";
|
||||
let wx = require('weixin-js-sdk')
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
||||
// mintui模块
|
||||
Vue.component(Button.name, Button)
|
||||
Vue.component(Swipe.name, Swipe);
|
||||
|
29
src/utils/decrypt.js
Normal file
29
src/utils/decrypt.js
Normal file
@ -0,0 +1,29 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
|
||||
const SECRET_KEY = 'mIS*fo4T2ioFSw91Flaovn@ofiq89Fqe';
|
||||
|
||||
|
||||
export function decrypt(encryptedResponse) {
|
||||
// 1. Base64解码
|
||||
const iv = CryptoJS.enc.Base64.parse(encryptedResponse.iv)
|
||||
const payload = CryptoJS.enc.Base64.parse(encryptedResponse.payload)
|
||||
|
||||
// 2. 执行AES解密
|
||||
const decrypted = CryptoJS.AES.decrypt(
|
||||
{ ciphertext: payload },
|
||||
CryptoJS.enc.Utf8.parse(SECRET_KEY),
|
||||
{
|
||||
iv: iv,
|
||||
mode: CryptoJS.mode.CBC,
|
||||
padding: CryptoJS.pad.Pkcs7
|
||||
}
|
||||
)
|
||||
|
||||
// 3. 转为UTF-8字符串并解析JSON
|
||||
try {
|
||||
return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8))
|
||||
} catch (e) {
|
||||
console.error("解密失败: ", e)
|
||||
return null
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user