You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
zhishifufei_uniapp/pages/topic/question_result.vue

434 lines
12 KiB

<template>
<BaseContainer>
<NavBar title="练习结果" />
<view class="question-result-page" v-if="result.title">
<view class="head">
<view class="header">
<view class="avatar"><img :src="getImgPath(userInfo.avatar)"></view>
<view class="nickname">{{ userInfo.nickname }}</view>
<view class="circle-container">
<canvas canvas-id="circle" class="my-canvas"></canvas>
</view>
<view class="title">{{ result.title }}</view>
<view v-if="result.is_score" class="score">
<view class="item">
<view>
<image :src="getImgPath('/wap/first/zsff/images/result01.png')" />
<text>本次得分</text>
</view>
<view>{{ result.score }}</view>
</view>
<view class="item" v-if="result.grade">
<view>
<image :src="getImgPath('/wap/first/zsff/images/result02.png')" />
<text>评分标准</text>
</view>
<view>{{ result.grade }}</view>
</view>
</view>
<view class="basic">
<view class="item">
<view>题目数</view>
<view class="value">{{ result.test_paper_question.length }}</view>
</view>
<view class="item">
<view>错题数</view>
<view class="value">{{ result.wrong_question }}</view>
</view>
<view class="item">
<view>未答数</view>
<view class="value">{{ result.not_questions }}</view>
</view>
<view class="item">
<view>本次用时</view>
<view class="value">{{ result.duration_time }}</view>
</view>
</view>
</view>
</view>
<view class="result">
<view class="result-hd">
<view>答题情况</view>
<view class="list">
<view class="item"><text></text><text>正确</text></view>
<view class="item"><text></text><text>错误</text></view>
<view class="item"><text></text><text>未答</text></view>
</view>
</view>
<view class="result-bd">
<template v-for="(item, index) in result.test_paper_question">
<view :class="{ no: item.is_correct === 1, ok: item.is_correct === 2 }">{{ index + 1 }}</view>
</template>
<text class="answer-analysis" @click="openAnalysis">主观题答案解析</text>
</view>
<view v-if="!footerHidden" class="result-ft">
<navigator :url="`/pages/topic/question_sheet?is_analysis=1&test_id=${test_id}&record_id=${result.id}&check_analysis=1&special_id=${special_id}`">查看解析
</navigator>
<navigator open-type="redirect" :url="`/pages/special/question_index?id=${test_id}&special_id=${special_id}&is_analysis=${is_analysis}`">再考一次</navigator>
</view>
</view>
<view :class="{ mask: imgSrc }" @touchmove.prevent @click="imgSrc = ''"></view>
<image v-if="imgSrc" :src="imgSrc" class="certificate-image" />
<subject-analysis-dialog ref="subjectAnalysisDialog" :e_id="result.id || 0"/>
</view>
</BaseContainer>
</template>
<script>
import {
getCertificateInfo,
getExaminationResult,
getInspect,
getTheCertificate,
} from "@/api/topic";
import {
getUserBaseData,
} from "@/api/user";
import subjectAnalysisDialog from './subjectAnalysisDialog.vue';
export default {
components: {
subjectAnalysisDialog,
},
data() {
return {
test_id: 0,
result: {
title: "--",
score: 0,
grade: "--",
test_paper_question: [],
wrong_question: 0,
duration_time: "00:00:00",
},
fill: { gradient: ["rgba(44, 142, 255, 1)", "rgba(44, 142, 255, 0.05)"] },
footerHidden: false,
imgSrc: "",
userInfo: {},
special_id: 0,
is_analysis: 0,
};
},
onLoad({ test_id, from, is_analysis, special_id }) {
this.test_id = test_id;
this.special_id = special_id;
if (is_analysis && parseInt(is_analysis)) {
this.is_analysis = parseInt(is_analysis);
} else {
this.is_analysis = 0;
}
this.footerHidden = from === "question_user";
this.$util.removeStorage("exam_time");
this.getUserBaseData();
},
mounted() {
this.getResult();
},
methods: {
async getUserBaseData() {
try {
const { data } = await getUserBaseData();
const {
userInfo
} = data;
Object.assign(this, {
userInfo
});
} catch (error) { }
},
renderCircle() {
const { screenWidth } = this.$util.getSystemInfo();
const ctx = uni.createCanvasContext("circle");
const maxValue = this.result.accuracy;
let value = 0;
const render = () => {
ctx.clearRect(0, 0, screenWidth, 160);
let text = parseInt(value) + "%";
ctx.arc(screenWidth / 2, 80, 70, 0, 2 * Math.PI);
ctx.setFillStyle("rgba(213, 224, 236, 0.6)");
ctx.fill();
ctx.beginPath();
ctx.arc(
screenWidth / 2,
80,
70,
0,
2 * Math.PI * (maxValue / 100) * (value / maxValue)
);
ctx.setFillStyle("#2c8eff");
ctx.fill();
ctx.beginPath();
ctx.arc(screenWidth / 2, 80, 64, 0, 2 * Math.PI);
ctx.setFillStyle("#ffffff");
ctx.fill();
ctx.font =
'32px "PingFang SC", "STHeitiSC-Light", "Helvetica-Light", arial, sans-serif, "Droid Sans Fallback"';
ctx.setFillStyle("#2c8eff");
ctx.setTextBaseline("middle");
let textWidth = ctx.measureText(text);
ctx.fillText(text, screenWidth / 2 - textWidth.width / 2, 80);
ctx.font =
'11px "PingFang SC", "STHeitiSC-Light", "Helvetica-Light", arial, sans-serif, "Droid Sans Fallback"';
ctx.setFillStyle("#999999");
ctx.setTextBaseline("middle");
text = "正确率";
textWidth = ctx.measureText(text);
ctx.fillText(text, screenWidth / 2 - textWidth.width / 2, 80 + 32);
ctx.draw();
};
// #ifndef MP
/* const task = () => {
render();
if (value < maxValue) {
value += 2;
window.requestAnimationFrame(task);
}
};
window.requestAnimationFrame(task); */
// #endif
const flag = setInterval(() => {
render();
if (value < maxValue) {
value += 2;
} else {
clearInterval(flag);
}
}, 1000 / 60);
},
getResult() {
getExaminationResult({
test_id: this.test_id,
type: 2,
})
.then(({ data: result }) => {
let questions = result.test_paper_question;
let duration = result.duration;
let hours = Math.floor(duration / 3600000);
let minutes = Math.floor((duration - hours * 3600000) / 60000);
let seconds = Math.floor((duration - hours * 3600000 - minutes * 60000) / 1000);
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
result.duration_time = hours + ":" + minutes + ":" + seconds;
for (let i = questions.length; i--;) {
if (!Array.isArray(questions[i].userAnswer)) {
Object.assign(questions[i], questions[i].userAnswer);
}
}
this.result = result;
console.log(this.result);
this.renderCircle();
this.getInspect();
})
.catch((err) => {
console.log(err);
this.$util.showMsg(err);
uni.redirectTo({
url: "/pages/topic/question_user",
});
});
},
getInspect() {
getInspect(this.test_id).then(({ code }) => {
if (code === 200) {
uni.showModal({
title: "提示",
content: "恭喜您已达到证书发放标准\n是否领取?",
okText: "领取",
success: ({ confirm }) => {
if (!confirm) return;
this.getCertificate();
},
});
}
});
},
// 领取证书
getCertificate() {
getTheCertificate(this.test_id).then(({ msg }) => {
this.$util.showMsg("领取成功\n证书正在生成...");
this.getCertificateInfo(msg);
});
},
getCertificateInfo(id) {
getCertificateInfo({
id: id,
obtain: 2,
}).then(({ data }) => {
this.createCertificate(data);
});
},
// 加载图片
loadImage: function (path) {
return new Promise(function (resolve, reject) {
var image = new Image();
image.crossOrigin = "anonymous";
image.onload = function () {
resolve(image);
};
image.onerror = function () {
reject("error-image");
};
image.src = path + "?" + new Date().getTime();
});
},
// 生成证书图片
createCertificate: function (certificate) {
$h.loadFFF();
Promise.all([
this.loadImage(certificate.certificate.background),
this.loadImage(certificate.certificate.qr_code),
])
.then(function (images) {
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
canvas.width = images[0].width;
canvas.height = images[0].height;
context.drawImage(images[0], 0, 0);
context.drawImage(images[1], 220, 557, 160, 160);
context.fillStyle = "rgba(255, 255, 255, 1)";
context.fillRect(220, 724, 160, 36);
context.font = "20px sans-serif";
context.textAlign = "center";
context.fillStyle = "#666666";
context.fillText("长按二维码查看", 300, 748);
context.font = "bold 34px sans-serif";
context.fillStyle = "#29466D";
context.fillText(certificate.nickname, 300, 296);
context.font = "24px sans-serif";
context.fillText(
"颁发时间:" + moment(certificate.add_time * 1000).format("YYYY.MM.DD"),
300,
481
);
context.font = "28px sans-serif";
context.textAlign = "start";
context.fillStyle = "#333333";
for (var i = Math.ceil(certificate.certificate.explain.length % 16); i--;) {
context.fillText(
certificate.certificate.explain.substr(i * 16, 16),
83,
i * 40 + 370
);
}
vm.imgSrc = canvas.toDataURL("image/jpeg");
canvas = null;
$h.loadClear();
})
.catch(function (error) {
$h.loadClear();
console.error(error);
});
},
openAnalysis() {
this.$refs.subjectAnalysisDialog.show = true;
},
},
};
</script>
<style>
page{
background: #f5f5f5;
}
</style>
<style scoped lang="scss">
@import "@/static/style/result.scss";
.avatar {
position: absolute;
top: -46rpx;
left: 50%;
width: 134rpx;
height: 134rpx;
border: 10rpx solid #FFFFFF;
border-radius: 50%;
background-color: #E8D8B1;
overflow: hidden;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
}
.nickname {
text-align: center;
font-weight: 500;
font-size: 26rpx;
line-height: 37rpx;
color: #333333;
}
.my-canvas{
top:0rpx;
left:-40rpx;
}
.head {
margin-top: 80rpx;
.header {
position: relative;
width: 94%;
margin: auto;
height: 1000rpx;
border-radius: 12rpx;
background-color: #FFFFFF;
padding-top: 90rpx;
}
}
.result {
width: 94%;
border-radius: 12rpx;
margin: auto;
background: #ffffff;
}
.result-bd {
.answer-analysis {
display: flex;
white-space: nowrap;
height: 72rpx;
align-items: center;
color: #3293FF;
margin: 18rpx 18rpx;
}
}
.result-ft{
margin: 126rpx -12rpx 0 !important;
}
</style>