parent
c30432d745
commit
f25c84d5e8
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"usingComponents": {
|
|
||||||
"rich-md": "/components/rich-md/rich-md"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
// miniprogram/dev/pages/dev/dev.js
|
|
||||||
Page({
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面的初始数据
|
|
||||||
*/
|
|
||||||
data: {
|
|
||||||
scrollTop:0,
|
|
||||||
re:false,
|
|
||||||
type:"secondary"
|
|
||||||
},
|
|
||||||
onScanCode(e){
|
|
||||||
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面加载
|
|
||||||
*/
|
|
||||||
onLoad: function (options) {
|
|
||||||
var p =this.selectComponent("#main")
|
|
||||||
p.onLoad();
|
|
||||||
p.onShow();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面初次渲染完成
|
|
||||||
*/
|
|
||||||
onReady: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面显示
|
|
||||||
*/
|
|
||||||
onShow: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面隐藏
|
|
||||||
*/
|
|
||||||
onHide: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生命周期函数--监听页面卸载
|
|
||||||
*/
|
|
||||||
onUnload: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面相关事件处理函数--监听用户下拉动作
|
|
||||||
*/
|
|
||||||
onPullDownRefresh: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面上拉触底事件的处理函数
|
|
||||||
*/
|
|
||||||
onReachBottom: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户点击右上角分享
|
|
||||||
*/
|
|
||||||
onShareAppMessage: function () {
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"usingComponents": {
|
|
||||||
"main":"/pages/home/home"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
<main id="main"/>
|
|
@ -1,3 +0,0 @@
|
|||||||
page{
|
|
||||||
background: white;
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"rich-md": "/components/rich-md/rich-md"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"rich-md": "/components/rich-md/rich-md"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"rich-md": "/components/rich-md/rich-md"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"component": true,
|
|
||||||
"usingComponents": {
|
|
||||||
"rich-md": "/components/rich-md/rich-md"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,192 +1,15 @@
|
|||||||
import {throttle} from "../../../js/utils";
|
|
||||||
|
|
||||||
const app = getApp();
|
|
||||||
Page({
|
Page({
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
exercise_questions: [],
|
|
||||||
loading: true,
|
|
||||||
exercise: {},
|
|
||||||
count_down:'试卷不限时'
|
|
||||||
},
|
|
||||||
scrollToAnswerSheet(){
|
|
||||||
wx.pageScrollTo({
|
|
||||||
selector:".exercise-status"
|
|
||||||
})
|
|
||||||
},
|
|
||||||
scrollToQues(e){
|
|
||||||
let {target: {dataset:{ques_id}}} = e;
|
|
||||||
;
|
|
||||||
if(!ques_id) return;
|
|
||||||
wx.pageScrollTo({
|
|
||||||
selector:"#q-"+ques_id
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onAnswer(e){
|
|
||||||
;
|
|
||||||
let {detail:{q_position,answered}} = e;
|
|
||||||
let key = "question_status[" + (q_position - 1) +"].ques_status"
|
|
||||||
this.setData({[key]: answered});
|
|
||||||
this.refreshAnsweredCount();
|
|
||||||
},
|
|
||||||
startCountDown({left_time}){
|
|
||||||
var left = left_time;
|
|
||||||
var setCountDown = (time)=>{
|
|
||||||
let s = time%60;
|
|
||||||
let m = parseInt(time/60)%60;
|
|
||||||
let h = parseInt(time/3600);
|
|
||||||
if(s<10)
|
|
||||||
s = '0' +s;
|
|
||||||
if(m<10)
|
|
||||||
m = '0' + m;
|
|
||||||
if(h<10)
|
|
||||||
h = '0' + h;
|
|
||||||
let count_down = h + ":" + m + ":" + s;
|
|
||||||
this.setData({count_down});
|
|
||||||
}
|
|
||||||
setCountDown(--left);
|
|
||||||
var id = setInterval(()=>{
|
|
||||||
if(left<=1){
|
|
||||||
return this.stopCountDown(id);
|
|
||||||
}
|
|
||||||
setCountDown(--left);
|
|
||||||
},1000);
|
|
||||||
},
|
|
||||||
stopCountDown(id){
|
|
||||||
clearInterval(id);
|
|
||||||
var showToast = throttle(wx.showToast, 800, {});//延时Toast
|
|
||||||
showToast({
|
|
||||||
title: '时间已到,系统自动为你提交中',icon:"none"
|
|
||||||
})
|
|
||||||
app.api("exercises.commit_exercise")({exercise_id:this.exercise_id, commit_method:2})
|
|
||||||
.then(res=>{
|
|
||||||
showToast({
|
|
||||||
title: "试卷提交成功!"
|
|
||||||
});
|
|
||||||
//this.pull_questions();
|
|
||||||
}).catch(e=>{
|
|
||||||
//app.showError(e);
|
|
||||||
var title = '提交失败';
|
|
||||||
//if(e.code==-2)
|
|
||||||
// title = '您未作答任何题';
|
|
||||||
showToast({
|
|
||||||
title,
|
|
||||||
icon:"none"
|
|
||||||
});
|
|
||||||
let db = wx.cloud.database();
|
|
||||||
db.collection("data").add({
|
|
||||||
data: {
|
|
||||||
name: "exercises.commit_exercise",
|
|
||||||
e,
|
|
||||||
createdAt: db.serverDate()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
this.setData({count_down: '考试时间已截止'});
|
|
||||||
},
|
|
||||||
refreshAnsweredCount(){
|
|
||||||
if(!this.data.question_status)
|
|
||||||
return;
|
|
||||||
let answered_count = 0;
|
|
||||||
this.data.question_status.map(i=>{
|
|
||||||
answered_count += i.ques_status;
|
|
||||||
});
|
|
||||||
this.setData({answered_count});
|
|
||||||
},
|
|
||||||
pull_questions: function(){
|
|
||||||
app.api("exercises.start_answer")({exercise_id: this.exercise_id})
|
|
||||||
.then(res=>{
|
|
||||||
;
|
|
||||||
this.setData(res);
|
|
||||||
this.setData({loading: false});
|
|
||||||
if(this.data.question_status)
|
|
||||||
this.refreshAnsweredCount();
|
|
||||||
if(res.exercise.left_time)
|
|
||||||
this.startCountDown({left_time: res.exercise.left_time});
|
|
||||||
}).catch(e => {
|
|
||||||
this.setData({status:e.code});
|
|
||||||
app.showError(e);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
save_exercise: function({show_loading=true}={}){
|
|
||||||
if(show_loading){
|
|
||||||
wx.showLoading({
|
|
||||||
title: '请稍候',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
app.callApi({ name:"exercises.begin_commit", data:{exercise_id: this.exercise_id}, complete: wx.hideLoading})
|
|
||||||
.then(res=>{
|
|
||||||
if(show_loading){
|
|
||||||
wx.showToast({
|
|
||||||
title: "保存成功",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).catch(e=>{
|
|
||||||
app.realTimeLog.error(e, "save exercise fail");
|
|
||||||
})
|
|
||||||
},
|
|
||||||
commit_exercise: function(){
|
|
||||||
//wx.showLoading({title: '检查作答情况中'});
|
|
||||||
app.api("exercises.begin_commit")({ exercise_id: this.exercise_id})
|
|
||||||
.then(resp=>{
|
|
||||||
let {question_undo, shixun_undo} = resp;
|
|
||||||
if(question_undo==0)
|
|
||||||
var content = "交卷后无法更改作答,是否确认?"
|
|
||||||
else {
|
|
||||||
var content = "您还有"+question_undo+"题未作答";
|
|
||||||
if(shixun_undo>0)
|
|
||||||
content += ",包含"+shixun_undo+"道实训题";
|
|
||||||
content +=",是否现在交卷呢?";
|
|
||||||
}
|
|
||||||
//wx.hideLoading();
|
|
||||||
wx.showModal({
|
|
||||||
title:"提示",
|
|
||||||
content,
|
|
||||||
success:res=>{
|
|
||||||
if(res.confirm){
|
|
||||||
app.api("exercises.commit_exercise")({exercise_id: this.exercise_id})
|
|
||||||
.then(res=>{
|
|
||||||
;
|
|
||||||
;
|
|
||||||
app.showMsg(res);
|
|
||||||
setTimeout(()=>{
|
|
||||||
wx.navigateBack({
|
|
||||||
delta:1
|
|
||||||
})
|
|
||||||
}, 800);
|
|
||||||
})
|
|
||||||
.catch(e=>{
|
|
||||||
app.showError(e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.catch(e=>{
|
|
||||||
app.showError(e);
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
},
|
||||||
onLoad: function (options) {
|
onLoad: function (options) {
|
||||||
this.exercise_id = options.exercise_id;
|
if(options)
|
||||||
this.course_name = options.exercise_name;
|
var query = "?" + Object.keys(options).map(i=>`${i}=${options[i]}`).join("&");
|
||||||
this.pull_questions();
|
else
|
||||||
},
|
var query = ""
|
||||||
|
wx.redirectTo({url: "/markdown/exercise/exercise/exercise" + query});
|
||||||
onShow: function () {
|
global.realTimeLog.error("unexpected page");
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
onHide: function () {
|
|
||||||
this.save_exercise({show_loading: false});
|
|
||||||
},
|
|
||||||
|
|
||||||
onUnload: function () {
|
|
||||||
this.save_exercise({ show_loading: false });
|
|
||||||
},
|
|
||||||
|
|
||||||
onPullDownRefresh: function () {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -1,9 +1,3 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {}
|
||||||
"choice-question":"/exercise/components/choice-question/choice-question",
|
|
||||||
"main-question": "/exercise/components/main-question/main-question",
|
|
||||||
"null-question": "/exercise/components/null-question/null-question",
|
|
||||||
"shixun-question":"/exercise/components/shixun-question/shixun-question"
|
|
||||||
},
|
|
||||||
"navigationBarTitleText": "试卷"
|
|
||||||
}
|
}
|
@ -1,62 +1,3 @@
|
|||||||
<page-meta>
|
<view>
|
||||||
<navigation-bar title="{{exercise.exercise_name}}" />
|
跳转中...
|
||||||
</page-meta>
|
|
||||||
|
|
||||||
<!--exercise-score wx:if="{{exercise.exercise_scores}}" data="{{exercise.exercise_scores}}"/-->
|
|
||||||
<block wx:if="{{question_status&&exercise.user_exercise_status!=1&&exercise.user_exercise_status!=4}}">
|
|
||||||
<view class="header">
|
|
||||||
<view class="left-time">倒计时:{{count_down}}</view>
|
|
||||||
<view class="count-down"></view>
|
|
||||||
<view bindtap="scrollToAnswerSheet" class="answer-count">
|
|
||||||
<view>答题卡</view>
|
|
||||||
<view class="answer-count-num">{{answered_count}}/{{question_status.length}}</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
|
||||||
<view class="header-place-holder"></view>
|
|
||||||
</block>
|
|
||||||
<view class="exercise-score" wx:if="{{exercise_scores}}">
|
|
||||||
<view class="user-score">总分
|
|
||||||
<text class="color-main total-score">{{user_score}}</text>/{{exercise_types.q_scores}}</view>
|
|
||||||
<block wx:if="{{exercise_scores.objective_scores.length>0}}">
|
|
||||||
<view>客观题</view>
|
|
||||||
<view class="scores" bindtap="scrollToQues">
|
|
||||||
<view class="score-item" data-ques_id="{{item.ques_id}}" wx:for="{{exercise_scores.objective_scores}}">
|
|
||||||
{{item.ques_position}}
|
|
||||||
<view class="score {{item.answer_status==1?'right':'wrong'}}">{{item.user_score||'未评分'}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
<block wx:if="{{exercise_scores.subjective_scores.length>0}}">
|
|
||||||
<view>主观题</view>
|
|
||||||
<view class="scores" bindtap="scrollToQues">
|
|
||||||
<view class="score-item" data-ques_id="{{item.ques_id}}" wx:for="{{exercise_scores.subjective_scores}}">
|
|
||||||
{{item.ques_position}}
|
|
||||||
<view class="score {{item.answer_status==1?'right':'wrong'}}">{{item.user_score||'未评分'}}</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
||||||
</view>
|
|
||||||
<view bindanswer="onAnswer">
|
|
||||||
<view class="question-wrap" wx:for="{{exercise_questions}}" wx:key="question_id">
|
|
||||||
<choice-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:if="{{item.question_type<3}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
|
||||||
<null-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:elif="{{item.question_type==3}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
|
||||||
<main-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:elif="{{item.question_type==4}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
|
||||||
<shixun-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:elif="{{item.question_type==5}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="end" wx:if="{{!loading}}">---- END ----</view>
|
|
||||||
<!--exercise-status wx:if="{{exercise.exercise_stauts}}" data="{{exercise.exercise_status}}"/-->
|
|
||||||
<block wx:if="{{question_status}}">
|
|
||||||
<view class="exercise-status">
|
|
||||||
<view>作答情况</view>
|
|
||||||
<view class="statuses" bindtap="scrollToQues">
|
|
||||||
<view data-ques_id="{{item.ques_id}}" class="status-item {{item.ques_status==1?'answered':''}}" wx:for="{{question_status}}">
|
|
||||||
{{item.ques_number}}
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="operations" wx:if="{{exercise.user_exercise_status!=1&&exercise.user_exercise_status!=4}}">
|
|
||||||
<button id="save-exercise" type="main" plain="1" catchtap="save_exercise">保存</button>
|
|
||||||
<button id="submit-exercise" type="main" catchtap="commit_exercise">交卷</button>
|
|
||||||
</view>
|
|
||||||
</block>
|
|
@ -1,118 +1 @@
|
|||||||
page{
|
/* miniprogram/exercise/pages/exercise/exercise.wxss */
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
.header{
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
background: white;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 40px;
|
|
||||||
width: 100%;
|
|
||||||
z-index: 1000;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
font-size: 15px;
|
|
||||||
box-shadow: 2px 2px 2px #dddddd;
|
|
||||||
}
|
|
||||||
.left-time{
|
|
||||||
padding: 0 8px 0 12px;
|
|
||||||
}
|
|
||||||
.count-down{
|
|
||||||
flex:auto;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.answer-count{
|
|
||||||
padding: 0 12px 0 8px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #0095f0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.answer-count-num{
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.header-place-holder{
|
|
||||||
height: 40px;
|
|
||||||
}
|
|
||||||
.user-score{
|
|
||||||
text-align: center;
|
|
||||||
font-size: 18px;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total-score{
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
.exercise-status,
|
|
||||||
.exercise-score{
|
|
||||||
background: white;
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
.statuses,
|
|
||||||
.scores{
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-item,
|
|
||||||
.score-item{
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 8px 0 8px 10px;
|
|
||||||
width: 44px;
|
|
||||||
height: 44px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
.status-item{
|
|
||||||
background: #cbcbcb;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.status-item.answered{
|
|
||||||
background: #00b0f0;
|
|
||||||
}
|
|
||||||
.score-item{
|
|
||||||
color: #00b0f0;
|
|
||||||
border: 1px #00b0f0 solid;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.score{
|
|
||||||
position: absolute;
|
|
||||||
bottom: -8px;
|
|
||||||
font-size: 10px;
|
|
||||||
color: white;
|
|
||||||
border-radius: 32px;
|
|
||||||
padding: 1.8px 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.score.right{
|
|
||||||
background: #00b0f0;
|
|
||||||
}
|
|
||||||
.score.wrong{
|
|
||||||
background: #fa5151;
|
|
||||||
}
|
|
||||||
|
|
||||||
.question-wrap{
|
|
||||||
margin: 8px 10px;
|
|
||||||
}
|
|
||||||
.end{
|
|
||||||
text-align: center;
|
|
||||||
margin: 10px;
|
|
||||||
color: dimgray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.operations{
|
|
||||||
display: flex;
|
|
||||||
padding: 2px;
|
|
||||||
}
|
|
||||||
.operations>button{
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
|||||||
export default class{
|
|
||||||
cookies = ""
|
|
||||||
constructor(){
|
|
||||||
|
|
||||||
}
|
|
||||||
saveCookies(cookies){
|
|
||||||
this.cookies = cookies.map(item => item.split(";")[0]).join("; ");
|
|
||||||
}
|
|
||||||
splitCookies(string){
|
|
||||||
let cookies = string.split(/,\s?(?=[^=,\;]*?\=)/ig);
|
|
||||||
return cookies;
|
|
||||||
}
|
|
||||||
request({ url, header, success,...options}) {
|
|
||||||
return wx.request({
|
|
||||||
...options,
|
|
||||||
url,
|
|
||||||
header: {...header, "Cookie": this.cookies},
|
|
||||||
success: (res) => {
|
|
||||||
if (res.cookies && res.cookies.length>0)
|
|
||||||
this.saveCookies(res.cookies);
|
|
||||||
else if (res.header["Set-Cookie"])
|
|
||||||
this.saveCookies(this.splitCookies(res.header["Set-Cookie"]));
|
|
||||||
else if(res.header["set-cookie"])
|
|
||||||
this.saveCookies(this.splitCookies(res.header["set-Cookie"]));
|
|
||||||
success(res);
|
|
||||||
if(url.indexOf("login.json")!=-1&&!res.data.status&&!this.cookies){
|
|
||||||
wx.reportMonitor("0",2);
|
|
||||||
global.realTimeLog.error(res, "login fail: fail parse cookies!!");
|
|
||||||
var db = wx.cloud.database();
|
|
||||||
db.collection("failCookies").add({
|
|
||||||
data:{
|
|
||||||
createdAt: db.serverDate(),
|
|
||||||
res,
|
|
||||||
header:res.header,
|
|
||||||
"Set-Cookies": res.header["Set-Cookie"],
|
|
||||||
"set-cookie":res.header["set-cookie"],
|
|
||||||
cookies:res.cookies
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
uploadFile({url, filePath, name, header, formData, success, fail, complete}){
|
|
||||||
return wx.uploadFile({
|
|
||||||
url,
|
|
||||||
filePath,
|
|
||||||
name,
|
|
||||||
header: {"Cookie": this.cookies, ...header},
|
|
||||||
formData,
|
|
||||||
success:res=>{
|
|
||||||
try{
|
|
||||||
res.data = JSON.parse(res.data);
|
|
||||||
}catch(e){
|
|
||||||
//@todo
|
|
||||||
}
|
|
||||||
;
|
|
||||||
if(success)
|
|
||||||
success(res)
|
|
||||||
},
|
|
||||||
fail,
|
|
||||||
complete
|
|
||||||
})
|
|
||||||
}
|
|
||||||
downloadFile({url, header, filePath, success, fail, complete}){
|
|
||||||
return wx.downloadFile({
|
|
||||||
url,
|
|
||||||
header: {...header, "Cookie": this.cookies},
|
|
||||||
filePath,
|
|
||||||
success,
|
|
||||||
fail,
|
|
||||||
complete
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md": "/markdown/components/rich-md/rich-md"
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"rich-md": "/components/rich-md/rich-md"
|
"rich-md": "/markdown/components/rich-md/rich-md"
|
||||||
},
|
},
|
||||||
"navigationBarTitleText": "服务协议"
|
"navigationBarTitleText": "服务协议"
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"rich-md":"/components/rich-md/rich-md",
|
"rich-md":"/markdown/components/rich-md/rich-md",
|
||||||
"iconfont":"/components/iconfont/iconfont"
|
"iconfont":"/components/iconfont/iconfont"
|
||||||
},
|
},
|
||||||
"navigationBarTitleText": "实名认证"
|
"navigationBarTitleText": "实名认证"
|
@ -0,0 +1,27 @@
|
|||||||
|
.form-item {
|
||||||
|
background: #fefefe;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 14px 12px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item>.value {
|
||||||
|
text-align: right;
|
||||||
|
flex: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item>.key {
|
||||||
|
display: inline-block;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item .tip {
|
||||||
|
font-size: 12px;
|
||||||
|
color: dimgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item>switch {
|
||||||
|
transform: scale(0.8);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"rich-md": "/components/rich-md/rich-md",
|
"rich-md": "/markdown/components/rich-md/rich-md",
|
||||||
"iconfont": "/components/iconfont/iconfont"
|
"iconfont": "/components/iconfont/iconfont"
|
||||||
},
|
},
|
||||||
"navigationBarTitleText": "职业认证"
|
"navigationBarTitleText": "职业认证"
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"component": true,
|
"component": true,
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"towxml":"/towxml/towxml"
|
"towxml":"/markdown/towxml/towxml"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md": "/markdown/components/rich-md/rich-md"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,192 @@
|
|||||||
|
import {throttle} from "../../../js/utils";
|
||||||
|
|
||||||
|
const app = getApp();
|
||||||
|
Page({
|
||||||
|
|
||||||
|
data: {
|
||||||
|
exercise_questions: [],
|
||||||
|
loading: true,
|
||||||
|
exercise: {},
|
||||||
|
count_down:'试卷不限时'
|
||||||
|
},
|
||||||
|
scrollToAnswerSheet(){
|
||||||
|
wx.pageScrollTo({
|
||||||
|
selector:".exercise-status"
|
||||||
|
})
|
||||||
|
},
|
||||||
|
scrollToQues(e){
|
||||||
|
let {target: {dataset:{ques_id}}} = e;
|
||||||
|
;
|
||||||
|
if(!ques_id) return;
|
||||||
|
wx.pageScrollTo({
|
||||||
|
selector:"#q-"+ques_id
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onAnswer(e){
|
||||||
|
;
|
||||||
|
let {detail:{q_position,answered}} = e;
|
||||||
|
let key = "question_status[" + (q_position - 1) +"].ques_status"
|
||||||
|
this.setData({[key]: answered});
|
||||||
|
this.refreshAnsweredCount();
|
||||||
|
},
|
||||||
|
startCountDown({left_time}){
|
||||||
|
var left = left_time;
|
||||||
|
var setCountDown = (time)=>{
|
||||||
|
let s = time%60;
|
||||||
|
let m = parseInt(time/60)%60;
|
||||||
|
let h = parseInt(time/3600);
|
||||||
|
if(s<10)
|
||||||
|
s = '0' +s;
|
||||||
|
if(m<10)
|
||||||
|
m = '0' + m;
|
||||||
|
if(h<10)
|
||||||
|
h = '0' + h;
|
||||||
|
let count_down = h + ":" + m + ":" + s;
|
||||||
|
this.setData({count_down});
|
||||||
|
}
|
||||||
|
setCountDown(--left);
|
||||||
|
var id = setInterval(()=>{
|
||||||
|
if(left<=1){
|
||||||
|
return this.stopCountDown(id);
|
||||||
|
}
|
||||||
|
setCountDown(--left);
|
||||||
|
},1000);
|
||||||
|
},
|
||||||
|
stopCountDown(id){
|
||||||
|
clearInterval(id);
|
||||||
|
var showToast = throttle(wx.showToast, 800, {});//延时Toast
|
||||||
|
showToast({
|
||||||
|
title: '时间已到,系统自动为你提交中',icon:"none"
|
||||||
|
})
|
||||||
|
app.api("exercises.commit_exercise")({exercise_id:this.exercise_id, commit_method:2})
|
||||||
|
.then(res=>{
|
||||||
|
showToast({
|
||||||
|
title: "试卷提交成功!"
|
||||||
|
});
|
||||||
|
//this.pull_questions();
|
||||||
|
}).catch(e=>{
|
||||||
|
//app.showError(e);
|
||||||
|
var title = '提交失败';
|
||||||
|
//if(e.code==-2)
|
||||||
|
// title = '您未作答任何题';
|
||||||
|
showToast({
|
||||||
|
title,
|
||||||
|
icon:"none"
|
||||||
|
});
|
||||||
|
let db = wx.cloud.database();
|
||||||
|
db.collection("data").add({
|
||||||
|
data: {
|
||||||
|
name: "exercises.commit_exercise",
|
||||||
|
e,
|
||||||
|
createdAt: db.serverDate()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
this.setData({count_down: '考试时间已截止'});
|
||||||
|
},
|
||||||
|
refreshAnsweredCount(){
|
||||||
|
if(!this.data.question_status)
|
||||||
|
return;
|
||||||
|
let answered_count = 0;
|
||||||
|
this.data.question_status.map(i=>{
|
||||||
|
answered_count += i.ques_status;
|
||||||
|
});
|
||||||
|
this.setData({answered_count});
|
||||||
|
},
|
||||||
|
pull_questions: function(){
|
||||||
|
app.api("exercises.start_answer")({exercise_id: this.exercise_id})
|
||||||
|
.then(res=>{
|
||||||
|
;
|
||||||
|
this.setData(res);
|
||||||
|
this.setData({loading: false});
|
||||||
|
if(this.data.question_status)
|
||||||
|
this.refreshAnsweredCount();
|
||||||
|
if(res.exercise.left_time)
|
||||||
|
this.startCountDown({left_time: res.exercise.left_time});
|
||||||
|
}).catch(e => {
|
||||||
|
this.setData({status:e.code});
|
||||||
|
app.showError(e);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
save_exercise: function({show_loading=true}={}){
|
||||||
|
if(show_loading){
|
||||||
|
wx.showLoading({
|
||||||
|
title: '请稍候',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
app.callApi({ name:"exercises.begin_commit", data:{exercise_id: this.exercise_id}, complete: wx.hideLoading})
|
||||||
|
.then(res=>{
|
||||||
|
if(show_loading){
|
||||||
|
wx.showToast({
|
||||||
|
title: "保存成功",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch(e=>{
|
||||||
|
app.realTimeLog.error(e, "save exercise fail");
|
||||||
|
})
|
||||||
|
},
|
||||||
|
commit_exercise: function(){
|
||||||
|
//wx.showLoading({title: '检查作答情况中'});
|
||||||
|
app.api("exercises.begin_commit")({ exercise_id: this.exercise_id})
|
||||||
|
.then(resp=>{
|
||||||
|
let {question_undo, shixun_undo} = resp;
|
||||||
|
if(question_undo==0)
|
||||||
|
var content = "交卷后无法更改作答,是否确认?"
|
||||||
|
else {
|
||||||
|
var content = "您还有"+question_undo+"题未作答";
|
||||||
|
if(shixun_undo>0)
|
||||||
|
content += ",包含"+shixun_undo+"道实训题";
|
||||||
|
content +=",是否现在交卷呢?";
|
||||||
|
}
|
||||||
|
//wx.hideLoading();
|
||||||
|
wx.showModal({
|
||||||
|
title:"提示",
|
||||||
|
content,
|
||||||
|
success:res=>{
|
||||||
|
if(res.confirm){
|
||||||
|
app.api("exercises.commit_exercise")({exercise_id: this.exercise_id})
|
||||||
|
.then(res=>{
|
||||||
|
;
|
||||||
|
;
|
||||||
|
app.showMsg(res);
|
||||||
|
setTimeout(()=>{
|
||||||
|
wx.navigateBack({
|
||||||
|
delta:1
|
||||||
|
})
|
||||||
|
}, 800);
|
||||||
|
})
|
||||||
|
.catch(e=>{
|
||||||
|
app.showError(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
.catch(e=>{
|
||||||
|
app.showError(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
onLoad: function (options) {
|
||||||
|
this.exercise_id = options.exercise_id;
|
||||||
|
this.course_name = options.exercise_name;
|
||||||
|
this.pull_questions();
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
onHide: function () {
|
||||||
|
this.save_exercise({show_loading: false});
|
||||||
|
},
|
||||||
|
|
||||||
|
onUnload: function () {
|
||||||
|
this.save_exercise({ show_loading: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
onPullDownRefresh: function () {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
"choice-question":"./choice-question/choice-question",
|
||||||
|
"main-question": "./main-question/main-question",
|
||||||
|
"null-question": "./null-question/null-question",
|
||||||
|
"shixun-question":"./shixun-question/shixun-question"
|
||||||
|
},
|
||||||
|
"navigationBarTitleText": "试卷"
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
<page-meta>
|
||||||
|
<navigation-bar title="{{exercise.exercise_name}}" />
|
||||||
|
</page-meta>
|
||||||
|
|
||||||
|
<!--exercise-score wx:if="{{exercise.exercise_scores}}" data="{{exercise.exercise_scores}}"/-->
|
||||||
|
<block wx:if="{{question_status&&exercise.user_exercise_status!=1&&exercise.user_exercise_status!=4}}">
|
||||||
|
<view class="header">
|
||||||
|
<view class="left-time">倒计时:{{count_down}}</view>
|
||||||
|
<view class="count-down"></view>
|
||||||
|
<view bindtap="scrollToAnswerSheet" class="answer-count">
|
||||||
|
<view>答题卡</view>
|
||||||
|
<view class="answer-count-num">{{answered_count}}/{{question_status.length}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="header-place-holder"></view>
|
||||||
|
</block>
|
||||||
|
<view class="exercise-score" wx:if="{{exercise_scores}}">
|
||||||
|
<view class="user-score">总分
|
||||||
|
<text class="color-main total-score">{{user_score}}</text>/{{exercise_types.q_scores}}</view>
|
||||||
|
<block wx:if="{{exercise_scores.objective_scores.length>0}}">
|
||||||
|
<view>客观题</view>
|
||||||
|
<view class="scores" bindtap="scrollToQues">
|
||||||
|
<view class="score-item" data-ques_id="{{item.ques_id}}" wx:for="{{exercise_scores.objective_scores}}">
|
||||||
|
{{item.ques_position}}
|
||||||
|
<view class="score {{item.answer_status==1?'right':'wrong'}}">{{item.user_score||'未评分'}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<block wx:if="{{exercise_scores.subjective_scores.length>0}}">
|
||||||
|
<view>主观题</view>
|
||||||
|
<view class="scores" bindtap="scrollToQues">
|
||||||
|
<view class="score-item" data-ques_id="{{item.ques_id}}" wx:for="{{exercise_scores.subjective_scores}}">
|
||||||
|
{{item.ques_position}}
|
||||||
|
<view class="score {{item.answer_status==1?'right':'wrong'}}">{{item.user_score||'未评分'}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<view bindanswer="onAnswer">
|
||||||
|
<view class="question-wrap" wx:for="{{exercise_questions}}" wx:key="question_id">
|
||||||
|
<choice-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:if="{{item.question_type<3}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
||||||
|
<null-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:elif="{{item.question_type==3}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
||||||
|
<main-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:elif="{{item.question_type==4}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
||||||
|
<shixun-question id="q-{{item.question_id}}" is_md="{{exercise.is_md}}" wx:elif="{{item.question_type==5}}" data="{{item}}" exercise_status="{{exercise.exercise_status}}" user_exercise_status="{{exercise.user_exercise_status}}"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="end" wx:if="{{!loading}}">---- END ----</view>
|
||||||
|
<!--exercise-status wx:if="{{exercise.exercise_stauts}}" data="{{exercise.exercise_status}}"/-->
|
||||||
|
<block wx:if="{{question_status}}">
|
||||||
|
<view class="exercise-status">
|
||||||
|
<view>作答情况</view>
|
||||||
|
<view class="statuses" bindtap="scrollToQues">
|
||||||
|
<view data-ques_id="{{item.ques_id}}" class="status-item {{item.ques_status==1?'answered':''}}" wx:for="{{question_status}}">
|
||||||
|
{{item.ques_number}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="operations" wx:if="{{exercise.user_exercise_status!=1&&exercise.user_exercise_status!=4}}">
|
||||||
|
<button id="save-exercise" type="main" plain="1" catchtap="save_exercise">保存</button>
|
||||||
|
<button id="submit-exercise" type="main" catchtap="commit_exercise">交卷</button>
|
||||||
|
</view>
|
||||||
|
</block>
|
@ -0,0 +1,118 @@
|
|||||||
|
page{
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.header{
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
background: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 40px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1000;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
font-size: 15px;
|
||||||
|
box-shadow: 2px 2px 2px #dddddd;
|
||||||
|
}
|
||||||
|
.left-time{
|
||||||
|
padding: 0 8px 0 12px;
|
||||||
|
}
|
||||||
|
.count-down{
|
||||||
|
flex:auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.answer-count{
|
||||||
|
padding: 0 12px 0 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #0095f0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.answer-count-num{
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.header-place-holder{
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.user-score{
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-score{
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exercise-status,
|
||||||
|
.exercise-score{
|
||||||
|
background: white;
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
.statuses,
|
||||||
|
.scores{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-item,
|
||||||
|
.score-item{
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 8px 0 8px 10px;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex: none;
|
||||||
|
}
|
||||||
|
.status-item{
|
||||||
|
background: #cbcbcb;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.status-item.answered{
|
||||||
|
background: #00b0f0;
|
||||||
|
}
|
||||||
|
.score-item{
|
||||||
|
color: #00b0f0;
|
||||||
|
border: 1px #00b0f0 solid;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score{
|
||||||
|
position: absolute;
|
||||||
|
bottom: -8px;
|
||||||
|
font-size: 10px;
|
||||||
|
color: white;
|
||||||
|
border-radius: 32px;
|
||||||
|
padding: 1.8px 5px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.score.right{
|
||||||
|
background: #00b0f0;
|
||||||
|
}
|
||||||
|
.score.wrong{
|
||||||
|
background: #fa5151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-wrap{
|
||||||
|
margin: 8px 10px;
|
||||||
|
}
|
||||||
|
.end{
|
||||||
|
text-align: center;
|
||||||
|
margin: 10px;
|
||||||
|
color: dimgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.operations{
|
||||||
|
display: flex;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
.operations>button{
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md": "/markdown/components/rich-md/rich-md"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md": "/markdown/components/rich-md/rich-md"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md": "/markdown/components/rich-md/rich-md"
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"usingComponents": {
|
"usingComponents": {
|
||||||
"nav-bar":"/components/nav-bar/nav-bar",
|
"nav-bar":"/components/nav-bar/nav-bar",
|
||||||
"rich-md":"/components/rich-md/rich-md",
|
"rich-md":"/markdown/components/rich-md/rich-md",
|
||||||
"mp-icon":"/weui-miniprogram/icon/icon"
|
"mp-icon":"/weui-miniprogram/icon/icon"
|
||||||
},
|
},
|
||||||
"navigationBarTitleText": "实践课程"
|
"navigationBarTitleText": "实践课程"
|
@ -0,0 +1,103 @@
|
|||||||
|
const app = getApp();
|
||||||
|
//status:[];
|
||||||
|
const cateTypes={
|
||||||
|
description:0,
|
||||||
|
task:1
|
||||||
|
}
|
||||||
|
Page({
|
||||||
|
data:{
|
||||||
|
shixun:{},
|
||||||
|
challenges:[],
|
||||||
|
list:[
|
||||||
|
{text:"简介"},{text:"任务"}
|
||||||
|
],
|
||||||
|
description:""
|
||||||
|
},
|
||||||
|
sendToCourse(){
|
||||||
|
let {id} = this.data.shixun;
|
||||||
|
this.setData({shixun_ids: [id], showSendDialog: true});
|
||||||
|
},
|
||||||
|
collect(){
|
||||||
|
let {id, is_collect} = this.data.shixun;
|
||||||
|
let api_name = is_collect?"collections.cancel":"collections";
|
||||||
|
app.api(api_name)({container_type:"Shixun", container_id:id})
|
||||||
|
.then(res=>{
|
||||||
|
;
|
||||||
|
this.pullShixun({showLoading: 0});
|
||||||
|
if(is_collect){
|
||||||
|
res.message = "已取消收藏";
|
||||||
|
var icon = "success";
|
||||||
|
var duration = 1500;
|
||||||
|
}else{
|
||||||
|
var icon = "none";
|
||||||
|
var duration = 3000;
|
||||||
|
}
|
||||||
|
wx.showToast({
|
||||||
|
title: res.message,
|
||||||
|
icon,
|
||||||
|
duration
|
||||||
|
})
|
||||||
|
}).catch(e=>{
|
||||||
|
;
|
||||||
|
app.showError(e);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
enterChallenge(){
|
||||||
|
wx.showLoading({
|
||||||
|
title: '开启中',
|
||||||
|
});
|
||||||
|
this.setData({loading: 1});
|
||||||
|
app.api("shixuns.shixun_exec")({ identifier:this.data.identifier})
|
||||||
|
.then(res=>{
|
||||||
|
app.navigateTo({ url: "{task}?identifier=" + res.game_identifier});
|
||||||
|
}).catch(e=>{
|
||||||
|
app.showError(e);
|
||||||
|
}).finally(e=>{
|
||||||
|
wx.hideLoading();
|
||||||
|
this.setData({loading:false})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scrollTo({scrollTop}){
|
||||||
|
wx.pageScrollTo({scrollTop,duration:200})
|
||||||
|
},
|
||||||
|
switchNav({detail:{current,source}}){
|
||||||
|
if(source=="touch")
|
||||||
|
this.setData({current});
|
||||||
|
},
|
||||||
|
apiChallenges: app.api("shixuns.challenges"),
|
||||||
|
apiShixun:app.api("shixuns"),
|
||||||
|
async pullChallenges(){
|
||||||
|
let {description, challenge_list:challenges} = await this.apiChallenges({identifier:this.data.identifier});
|
||||||
|
this.setData({description, challenges});
|
||||||
|
},
|
||||||
|
async pullShixun({showLoading=1}={}){
|
||||||
|
if(showLoading)
|
||||||
|
wx.showLoading({
|
||||||
|
title: '努力加载中'
|
||||||
|
})
|
||||||
|
let {identifier} = this.data;
|
||||||
|
let shixun = await this.apiShixun({identifier});
|
||||||
|
this.setData({shixun}, res=>{
|
||||||
|
if(showLoading)
|
||||||
|
wx.hideLoading()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onLoad: function (options) {
|
||||||
|
let {identifier,cate_type} = options;
|
||||||
|
let current = cateTypes[cate_type];
|
||||||
|
this.setData({identifier, current});
|
||||||
|
this.pullChallenges().catch(e=>{
|
||||||
|
|
||||||
|
});
|
||||||
|
this.pullShixun().catch(e=>{
|
||||||
|
app.showError(e);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onShareAppMessage: function () {
|
||||||
|
return app.shareApp({
|
||||||
|
title:this.data.shixun.name,
|
||||||
|
imageUrl: global.config.eduImgDir+"avatars/Shixun/"+this.data.shixun.id
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md":"/markdown/components/rich-md/rich-md",
|
||||||
|
"require-login":"/components/require-login/require-login",
|
||||||
|
"challenge-item":"./challenge-item/challenge-item",
|
||||||
|
"nav-bar":"/components/nav-bar/nav-bar",
|
||||||
|
"send-to-course":"/components/modal/send-to-course/send-to-course"
|
||||||
|
},
|
||||||
|
"navigationBarBackgroundColor": "#0080f0",
|
||||||
|
"navigationBarTextStyle": "white",
|
||||||
|
"navigationBarTitleText": "实训项目"
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
<!--page-meta>
|
||||||
|
<navigation-bar title="{{shixun.name}}"/>
|
||||||
|
</page-meta-->
|
||||||
|
<wxs src="./shixun.wxs" module="handler"/>
|
||||||
|
<view class="header">
|
||||||
|
<view class="shixun-title">{{shixun.name}}</view>
|
||||||
|
<view class="shixun-detail">
|
||||||
|
<view>
|
||||||
|
<view class="detail-key">学习人数</view>
|
||||||
|
<view class="detail-value">{{shixun.stu_num}}</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="detail-key">难度级别</view>
|
||||||
|
<view class="detail-value">{{shixun.diffcult}}</view>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<view class="detail-key">经验值</view>
|
||||||
|
<view class="detail-value">{{shixun.experience}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<require-login bg="#00b0f0" bindchange="pullShixun" message="点击登陆,可以获取更多内容哦"/>
|
||||||
|
<nav-bar list="{{list}}" current="{{current}}" type="line" bindchange="switchNav"/>
|
||||||
|
<swiper class="body" current="{{current}}" bindchange="switchNav" circular="1">
|
||||||
|
<swiper-item>
|
||||||
|
<scroll-view class="scroll-body" scroll-y="{{1}}" bindscroll="{{handler.scroll}}">
|
||||||
|
<rich-md my-class="desp" nodes="{{description}}" type="markdown"/>
|
||||||
|
</scroll-view>
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item>
|
||||||
|
<scroll-view class="scroll-body" scroll-y="1" bindscroll="{{handler.scroll}}">
|
||||||
|
<view class="cate">
|
||||||
|
<view class="cate-header">
|
||||||
|
<text class="square"/>
|
||||||
|
<text class="cate-name">全部任务</text>
|
||||||
|
</view>
|
||||||
|
<view class="challenges">
|
||||||
|
<view class="challenge-wrap" wx:for="{{challenges}}" wx:key="challenge_id">
|
||||||
|
<challenge-item data="{{item}}"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
||||||
|
<view wx:if="{{shixun.task_operation[0]}}" class="operations">
|
||||||
|
<button class="collect" bindtap="collect" type="main" plain>{{shixun.is_collect?'已收藏':'收藏'}}</button>
|
||||||
|
<button bindtap="enterChallenge" disabled="{{loading}}" type="main">{{shixun.task_operation[0]}}</button>
|
||||||
|
<button class="send" type="main" bindtap="sendToCourse" plain>发送至</button>
|
||||||
|
</view>
|
||||||
|
<send-to-course show="{{showSendDialog}}" shixun_ids="{{shixun_ids}}"/>
|
@ -0,0 +1,89 @@
|
|||||||
|
.header{
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
height: 138px;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.shixun-title{
|
||||||
|
background: #0080f0;
|
||||||
|
font-weight: bolder;
|
||||||
|
padding: 2px 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: white;
|
||||||
|
height: 84px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.shixun-detail{
|
||||||
|
position: absolute;
|
||||||
|
top: 60px;
|
||||||
|
height: 70px;
|
||||||
|
background:white;
|
||||||
|
box-shadow: 3px 3px 10px #e7e7e7;
|
||||||
|
display: flex;
|
||||||
|
border-radius: 6px;
|
||||||
|
width: 600rpx;
|
||||||
|
}
|
||||||
|
.shixun-detail>view{
|
||||||
|
flex:auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.shixun-detail>view>view{
|
||||||
|
flex: auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.detail-key{
|
||||||
|
color: dimgrey;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
.cate{
|
||||||
|
background: white;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.cate-header{
|
||||||
|
padding: 8px 8px 0px 8px;
|
||||||
|
}
|
||||||
|
.square{
|
||||||
|
width: 0;
|
||||||
|
height: 0px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border-left: 5px solid #00b0f0;
|
||||||
|
}
|
||||||
|
.cate-name{
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
.body{
|
||||||
|
height: calc(100vh - 76px);
|
||||||
|
}
|
||||||
|
.scroll-body{
|
||||||
|
height: 100%;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.operations{
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
display: flex;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.operations>button{
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
button.collect, button.send{
|
||||||
|
background: white!important;
|
||||||
|
}
|
||||||
|
/* tmp solution*/
|
||||||
|
.weui-half-screen-dialog__hd__side .weui-icon-btn.weui-icon-btn_more{
|
||||||
|
display: none;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"usingComponents": {
|
||||||
|
"rich-md":"/markdown/components/rich-md/rich-md",
|
||||||
|
"test-set":"./test_set/test_set",
|
||||||
|
"mp-toptips":"/weui-miniprogram/toptips/toptips"
|
||||||
|
},
|
||||||
|
"navigationBarTitleText": "实训关卡"
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
<page-meta>
|
||||||
|
<navigation-bar title="{{titles[current]}}"/>
|
||||||
|
</page-meta>
|
||||||
|
<mp-toptips bindtap="onTapTopTip" msg="夜深了,注意休息" type="info" show="{{showGoToSleep}}" delay="0"></mp-toptips>
|
||||||
|
<swiper class="body" circular="1" current="{{current}}" bindchange="onSwiperChange">
|
||||||
|
<swiper-item>
|
||||||
|
<scroll-view class="challenge-body {{theme}}" scroll-y="1">
|
||||||
|
<block wx:if="{{challenge}}">
|
||||||
|
<view class="subject {{theme}}">第{{challenge.position}}关:{{challenge.subject}}</view>
|
||||||
|
<view class="sub-header {{theme}}">
|
||||||
|
|
||||||
|
<!--path="pagesB/shixuntasks/shixuntasks?game_identifier={{identifier}}"
|
||||||
|
path="pagesB/trainingdetails/trainingdetails?identifier={{shixun.identifier}}&shixunid={{shixun.id}}"
|
||||||
|
-->
|
||||||
|
<navigator target="miniProgram" hover-class="none" app-id="wx2402d86a6b534f77"
|
||||||
|
path="pages/shiyan/shixun?shixunDetailsid={{shixun.id}}&shixunidentifier={{shixun.identifier}}"
|
||||||
|
class="nav-educoder">
|
||||||
|
<image src="{{attachDir}}888038" class="icon"></image>
|
||||||
|
用EduCoder云网实训(推荐)
|
||||||
|
</navigator>
|
||||||
|
<view class="switch-wrap">黑暗模式<switch class="theme-switch" bindchange="switchTheme" color="dimgrey" checked="{{theme=='dark'}}"></switch></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
<rich-md nodes="{{challenge.task_pass}}" type="markdown" theme="{{theme}}"/>
|
||||||
|
</scroll-view>
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item>
|
||||||
|
<view class="editor-body">
|
||||||
|
<form class="form-body" bindsubmit="buildGame">
|
||||||
|
<editor wx:if="{{can_use_editor}}" class="editor"
|
||||||
|
id="code-editor"
|
||||||
|
bindready="onEditorReady"
|
||||||
|
bindinput="onEditorInput"
|
||||||
|
bindblur="onEditorBlur"/>
|
||||||
|
<textarea wx:else class="editor" name="content" maxlength="-1"
|
||||||
|
value="{{content}}"
|
||||||
|
bindblur="onTextAreaBlur"
|
||||||
|
show-confirm-bar="{{false}}"
|
||||||
|
bindinput="onTextAreaInput">
|
||||||
|
</textarea>
|
||||||
|
<view class="operations">
|
||||||
|
<button class="button-challenge" plain="1" type="main" bindtap="enterChallenge">任务</button>
|
||||||
|
<button id="task-build" class="button-build" loading="{{building}}" disabled="{{building}}" type="main" form-type="submit">测评</button>
|
||||||
|
<button class="button-outcome" plain="1" type="main" bindtap="enterOutcome">测试集</button>
|
||||||
|
</view>
|
||||||
|
</form>
|
||||||
|
</view>
|
||||||
|
</swiper-item>
|
||||||
|
<swiper-item class="outcome-swiper">
|
||||||
|
<scroll-view class="outcome-body" scroll-y="1">
|
||||||
|
<view class="compile-output">
|
||||||
|
<rich-text wx:if="{{sets_error_count}}" nodes="{{last_compile_output}}"></rich-text>
|
||||||
|
<view wx:elif="{{test_sets_count}}" class="success">成功通过 {{test_sets_count-sets_error_count}}/{{test_sets_count}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="test-set-wrap" wx:for="{{test_sets}}">
|
||||||
|
<test-set data="{{item}}" index="{{index}}"/>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
<view class="operations" bindtap="enterTask">
|
||||||
|
<button wx:if="{{prev_game}}" data-identifier="{{prev_game}}" type="main" plain>上一关</button>
|
||||||
|
<button wx:if="{{next_game}}" data-identifier="{{next_game}}" type="main">下一关</button>
|
||||||
|
</view>
|
||||||
|
</swiper-item>
|
||||||
|
</swiper>
|
@ -0,0 +1,89 @@
|
|||||||
|
.body{
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
.sub-header{
|
||||||
|
display: flex;
|
||||||
|
padding-top: 14px;
|
||||||
|
margin-bottom: -10px;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.nav-educoder{
|
||||||
|
font-size: 12px;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
.nav-educoder>.icon{
|
||||||
|
height: 20px;
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
.dark{
|
||||||
|
background: black!important;
|
||||||
|
color: white;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
.switch-wrap{
|
||||||
|
text-align: right;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
.theme-switch{
|
||||||
|
transform: scale(0.6);
|
||||||
|
}
|
||||||
|
.challenge-body{
|
||||||
|
height: 100%;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.subject{
|
||||||
|
padding-left: 20px;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bolder;
|
||||||
|
|
||||||
|
}
|
||||||
|
.editor-body{
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.form-body{
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.editor{
|
||||||
|
width: auto;
|
||||||
|
background: #002B36;
|
||||||
|
color: #93A1A1;
|
||||||
|
font: 14px/normal 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', monospace;
|
||||||
|
white-space: pre;
|
||||||
|
padding: 0px 10px;
|
||||||
|
height: calc(100vh - 42px);
|
||||||
|
flex: auto;
|
||||||
|
}
|
||||||
|
.operations{
|
||||||
|
flex: none;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.operations>button{
|
||||||
|
flex: auto;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
.outcome-swiper{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.outcome-body{
|
||||||
|
flex: 1 1 1px;
|
||||||
|
height: 1px;
|
||||||
|
background: #111c24;
|
||||||
|
}
|
||||||
|
.compile-output{
|
||||||
|
max-height: 36vh;
|
||||||
|
overflow-y: scroll;
|
||||||
|
padding: 6px 10px;
|
||||||
|
color: #ff6545;
|
||||||
|
}
|
||||||
|
.success{
|
||||||
|
color: #12af25;
|
||||||
|
}
|
||||||
|
.test-set-wrap{
|
||||||
|
margin: 7px 8px;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"component": true,
|
||||||
|
"usingComponents": {
|
||||||
|
"decode": "./decode",
|
||||||
|
"latex": "./latex/latex",
|
||||||
|
"table": "./table/table",
|
||||||
|
"img": "./img/img"
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue