A 试卷答题时网络不好情况处理

master
educoder_weapp 5 years ago
parent f25c84d5e8
commit 8dc7062136

@ -1,3 +1,6 @@
## v0.16.3
* U 优化项目结构,主包压缩一半
## v0.16.2
* A 支持选用实践课程
* A 网络请求缓存

@ -2,5 +2,6 @@
"usingComponents": {
"iconfont":"/components/iconfont/iconfont"
},
"navigationBarTitleText": "账号"
"navigationBarTitleText": "账号",
"navigationBarBackgroundColor": "#ffffff"
}

@ -15,7 +15,7 @@
<view class="input-wrap {{action!='login'?'':'hidden'}}">
<input name="code" placeholder="验证码">
</input>
<button id="code" type="main" size="mini" form-type="submit" loading="{{code_status==2}}" disabled="{{code_status||hasError}}" class="obtain-code">
<button id="code" type="secondary" size="mini" form-type="submit" loading="{{code_status==2}}" disabled="{{code_status||hasError}}" class="obtain-code">
{{code_button_text}}
</button>
</view>

@ -1,6 +1,7 @@
page{
min-height: 100%;
overflow: hidden;
background: white;
}
.head-error{
position: fixed;
@ -91,7 +92,7 @@ switch.no-login{
}
.pos1>button[disabled]{
background-color: #00b0f0aa!important;
color: white;
color: white!important;
}
.actions>.pos2{
top:64px;
@ -99,6 +100,7 @@ switch.no-login{
.pos2>button{
color: #00b0f0;
border:#00b0f0 1px solid;
background: white;
}
.actions>.pos3{
top: 0px;

@ -32,8 +32,9 @@ App({
global.accountManager.setCurrentAccount(account);
});
wx.reportMonitor('1', 1);
global.realTimeLog.info("爬虫访问");
global.realTimeLog.setFilterMsg("wxcrawl");
}
if (options.referrerInfo && options.referrerInfo.appId) {
var db = wx.cloud.database();
let { appId, extraData } = options.referrerInfo;

@ -16,12 +16,20 @@ Component({
}
},
attached(){
deprecate("require-login");
this.refresh().finally(()=>{
this.loaded = true;
})
},
pageLifetimes:{
show:function(){
app.syncUser()
.then(res=>{
if(!this.loaded)
return;
this.refresh();
}
},
methods:{
refresh(){
return app.syncUser().then(res=>{
if(this.data.user_id!=res.user.user_id){
if(this.data.user_id!=-1)
this.triggerEvent("change",{});

@ -5,10 +5,11 @@ const developUrl = "https://test-newweb.educoder.net";
const trialUrl = "https://pre-newweb.educoder.net";
const releaseUrl = "https://www.educoder.net";
let _version = "0.16.3";
let _version = "0.16.4";
var eduUrl = releaseUrl;
/**
* U 优化项目结构主包压缩一半
* A 试卷答题时网络不好情况处理
* A 课堂界面兼容iphone X
*/
export function switchEnv(env) {

@ -101,6 +101,9 @@ Component({
flag = true;
}
}
// @temp: 检查使用人数
global.realTimeLog.error("switch course module: "+type);
global.realTimeLog.setFilterMsg("course_module");
if(!flag)
return flag;
for (var i = 0; i < this.data.list.length; i++) {

@ -119,7 +119,7 @@ text.sep{
}
.tabbar{
flex: none;
transition: 2s ease all;
padding-bottom: env(safe-area-inset-bottom); /*兼容Iphone X*/
}
.modules{

@ -4,7 +4,7 @@
flex: none;
}
.status-bar{
transition: all ease-out 0.6s
transition: all ease-out 0.4s
}
.navigation-bar{
height: 44px;

@ -73,7 +73,7 @@ class Client{
let index = 2;
this.tidingGet = 1;
const handler = {
fail: res=>{this.tidingGet=0}
fail: ()=>{this.tidingGet=0}
};
return this.api("users.unread_message_info")({login}).then(res => {
if (res.unread_message_count)
@ -90,7 +90,7 @@ class Client{
});
}
syncUser({refresh=0}={}){
if(!this.synching||!this.tmp_promise||!this.synch||refresh){
if(!this.synching&&!this.synch||!this.tmp_promise||refresh){
this.synching = 1;
this.tmp_promise = this._syncUser({refresh});
}
@ -133,7 +133,6 @@ class Client{
return {randomcode:this.randomcode,client_key:this.client_key};
}
api(name,config={},data={}){
global.realTimeLog.error("call desprated method!!!");
return ({success, fail, complete,..._data}={})=>{
return this.callApi({name,config, data:{...data,..._data}, success, fail, complete});
}

@ -1,5 +1,6 @@
{
"usingComponents": {
"rich-md": "/markdown/components/rich-md/rich-md"
}
},
"navigationBarTitleText": "关于EduCoder"
}

@ -2,5 +2,5 @@
"usingComponents": {
"rich-md": "/markdown/components/rich-md/rich-md"
},
"navigationBarTitleText": "服务协议"
"navigationBarTitleText": "EduCoder服务协议"
}

@ -16,14 +16,12 @@ Page({
},
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});
@ -114,19 +112,23 @@ Page({
title: '请稍候',
});
}
app.callApi({ name:"exercises.begin_commit", data:{exercise_id: this.exercise_id}, complete: wx.hideLoading})
app.callApi({ name:"exercises.begin_commit", data:{exercise_id: this.exercise_id}})
.then(res=>{
wx.hideLoading();
if(show_loading){
wx.showToast({
title: "保存成功",
});
wx.showToast({
title: "保存成功",
});
}
}).catch(e=>{
wx.hideLoading();
app.showError(e);
app.realTimeLog.error(e, "save exercise fail");
})
},
commit_exercise: function(){
//wx.showLoading({title: '检查作答情况中'});
this.setData({committing: true});
app.api("exercises.begin_commit")({ exercise_id: this.exercise_id})
.then(resp=>{
let {question_undo, shixun_undo} = resp;
@ -146,8 +148,6 @@ Page({
if(res.confirm){
app.api("exercises.commit_exercise")({exercise_id: this.exercise_id})
.then(res=>{
;
;
app.showMsg(res);
setTimeout(()=>{
wx.navigateBack({
@ -165,7 +165,9 @@ Page({
})
.catch(e=>{
app.showError(e);
});
}).finally(()=>{
this.setData({committing: false});
});
},
onLoad: function (options) {

@ -57,6 +57,6 @@
</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>
<button loading="{{committing}}" disabled="{{committing}}" id="submit-exercise" type="main" catchtap="commit_exercise">交卷</button>
</view>
</block>

@ -17,20 +17,29 @@ Component({
this.answered = answered;
}
},
answer_main_question: function ({detail: {value}, currentTarget: { dataset } }) {
;
;
;
app.api("exercise_questions.exercise_answers")({ question_id: dataset.question_id, answer_text: value })
resubmit(){
let {fail_answer} = this.data;
this.answer_main_question({answer_text:fail_answer,showMsg:1});
},
onBlur: function(e){
let {detail:{value}} = e;
this.answer_main_question({answer_text:value});
},
answer_main_question: function ({answer_text, showMsg=0}) {
let {question_id} = this.data.data;
app.api("exercise_questions.exercise_answers")({question_id, answer_text })
.then(res => {
if (value)
if (answer_text)
this.triggerAnswer({answered:1});
else
this.triggerAnswer({answered:0});
; ;
if(showMsg)
app.showMsg(res);
this.setData({fail_answer: ""});
})
.catch(e => {
app.showError(e);
this.setData({fail_answer: answer_text});
});
},
}

@ -1,12 +1,15 @@
<view class="question">
<view class="index hint"><text class="gap">第{{data.q_position}}题</text><text class="ques-score">{{data.question_score}}分</text></view>
<rich-md my-class="title" nodes="{{data.question_title}}"/>
<textarea disabled="{{user_exercise_status==1 || user_exercise_status==4}}" class="main-input"
placeholder="输入答案"
bindblur="answer_main_question"
value="{{data.user_answer[0]||''}}"
data-question_id="{{data.question_id}}">
</textarea>
<view class="input-wrp">
<textarea disabled="{{user_exercise_status==1 || user_exercise_status==4}}"
class="main-input"
placeholder="输入答案"
bindblur="onBlur"
value="{{data.user_answer[0]||''}}">
</textarea>
<icon type="warn" wx:if="{{fail_answer}}" bindtap="resubmit"></icon>
</view>
<view class="outcome" wx:if="{{data.user_score}}">
得分:<text class="score-num">{{data.user_score}}</text>/{{data.question_score}}
</view>

@ -1,10 +1,15 @@
@import "../question-common.wxss";
.input-wrp{
display: flex;
align-items: center;
}
.main-input{
height: 180rpx;
margin: 18rpx 0 4rpx 18rpx;
border: 1rpx solid lightgray;
border-radius: 12rpx;
padding: 12rpx 10rpx;
flex: auto;
}

@ -5,7 +5,6 @@ Component({
type:Object,
observer:function(data){
this.answers = data.user_answer.map(i=>i.answer_text);
;
}
},
is_md: Boolean,
@ -13,7 +12,7 @@ Component({
user_exercise_status: Number,
},
data: {
failed_answers:[]
},
methods: {
triggerAnswer() {
@ -31,19 +30,33 @@ Component({
}
return 0;
},
answer_null_question: function ({ detail: { value }, currentTarget: { dataset:{question_id, exercise_choice_id}} }) {
;
;
;
app.api("exercise_questions.exercise_answers")({ question_id, exercise_choice_id, answer_text: value })
resubmit(e){
console.log(e);
let {currentTarget:{dataset:{exercise_choice_id}}} = e;
let answer_text = this.data.failed_answers[exercise_choice_id-1];
this.answer_null_question({exercise_choice_id, answer_text, showMsg:1});
},
onBlur(e){
let { detail: { value } } = e;
let {currentTarget: { dataset:{exercise_choice_id}} } = e;
if(value==this.answers[exercise_choice_id-1])
return;
this.answer_null_question({exercise_choice_id, answer_text: value});
},
answer_null_question: function ({exercise_choice_id, answer_text, showMsg=0}) {
let {question_id} = this.data.data;
let key = `failed_answers[${exercise_choice_id-1}]`;
app.api("exercise_questions.exercise_answers")({ question_id, exercise_choice_id, answer_text})
.then(res => {
this.answers[exercise_choice_id-1] = value;
;
this.triggerAnswer();
; ;
this.answers[exercise_choice_id-1] = answer_text;
this.triggerAnswer();
if(showMsg)
app.showMsg(res);
this.setData({[key]: ""});
})
.catch(e => {
app.showError(e);
this.setData({[key]: answer_text});
});
},
}

@ -4,12 +4,12 @@
<view wx:for="{{data.multi_count}}" class="input-wrap">
<text class="hint">第{{index+1}}空</text>
<input class="null-input" disabled="{{user_exercise_status==1 || user_exercise_status==4}}"
placeholder="输入第{{index+1}}空的答案"
data-question_id="{{data.question_id}}"
data-exercise_choice_id="{{index+1}}"
value="{{data.user_answer[index].answer_text||''}}"
bindblur="answer_null_question">
placeholder="输入第{{index+1}}空的答案"
data-exercise_choice_id="{{index+1}}"
value="{{data.user_answer[index].answer_text||''}}"
bindblur="onBlur">
</input>
<icon type="warn" bindtap="resubmit" wx:if="{{failed_answers[index]}}" data-exercise_choice_id="{{index+1}}"></icon>
</view>
<view class="outcome" wx:if="{{data.user_score}}">
得分:<text class="score-num">{{data.user_score}}</text><text class="gap">/{{data.question_score}}</text>

@ -1,10 +1,10 @@
<view class="question">
<view class="index hint"><text class="gap">第{{data.q_position}}题</text><text class="ques-score">{{data.question_score}}分</text></view>
<rich-md c-class="title" nodes="{{data.question_title}}"/>
<view class="shixun-detail">
<button class="button-shixun" size="mini" type="main" plain bindtap="enterShixun">进入该实训</button>
<view class="shixun-detail">
<view>{{data.shixun_name}}</view>
<button class="button-shixun" size="mini" type="secondary" bindtap="enterShixun">进入该实训</button>
</view>
<rich-md c-class="title" nodes="{{data.question_title}}"/>
<view class="outcome" wx:if="{{data.user_score}}">
得分:<text class="score-num">{{data.user_score}}</text><text class="gap">/{{data.question_score}}</text>
</view>

@ -6,6 +6,7 @@
}
.button-shixun{
flex:none;
margin-left: 4px;
}
.shixun-name{
padding: 0 10px;

@ -14,8 +14,8 @@
</checkbox-group>
</scroll-view>
<view class="operations">
<view class="operation">
<radio color="#00b0f0" checked="{{isSelectAll}}" bindtap="onTapSelectAll">全选</radio>
<view class="operation" bindtap="onTapSelectAll">
<radio color="#00b0f0" checked="{{isSelectAll}}">全选</radio>
</view>
<button class="operation" form-type="submit">确认选用({{selectCount}})</button>
</view>

@ -1,4 +1,4 @@
<navigator bindtap="onTap" hover-class="{{select?'none':'navigator-hover'}}" class="shixun-item" url="{{select?'':('markdown/shixun/shixun/shixun?identifier='+data.identifier)}}">
<navigator bindtap="onTap" hover-class="{{select?'none':'navigator-hover'}}" class="shixun-item" url="{{select?'':('/markdown/shixun/shixun/shixun?identifier='+data.identifier)}}">
<image class="image" lazy-load src="{{eduUrl}}/{{data.pic}}"></image>
<view class="detail">
<view class="name"><rich-text nodes="{{data.title}}"/></view>

@ -5,7 +5,6 @@ statuses:[]
Component({
data: {
imgDir: global.config.imgDir,
attachDir: global.config.attachDir,
categories: [{ text: "我学习的", value: "study" }, { text: "我管理的", value: "manage" }],
statuses: [{ text: "正在进行", value: "processing" }, { text: "已结束", value: "end" }],
@ -30,30 +29,43 @@ Component({
this.pullCourses({refresh:1})
.then(res=>{
if(res.courses){
var user = app.user();
wx.setStorageSync(key, res.courses);
}
this.loaded = 1;
});
this.setData({current_cate});
},
pageLifetimes: {
show: function () {
if (this.data.current_cate >= 0) {
if (this.loaded >= 0) {
console.log("show pull")
this.pullCourses({ refresh: 2, showError:0 });
}
this.setData({user_id: app.user().user_id});
}
},
methods: {
onTapButton(){
if(this.data.user_id==2)
app.navigateTo({url:"{account}"});
else
this.setData({showModal:1});
},
onCategoryChange: function ({ detail: { current, value, source } }) {
if(source!='touch') return;
this.options["category"] = value.value;
this.pullCourses({ refresh: 1 });
this.setData({current_cate: current});
},
onStatusChange: function ({ detail: { value } }) {
this.options["status"] = value.value;
this.pullCourses({ refresh: 1 });
},
addCourse() {
if(app.user().user_id==2)
return wx.showToast({
title: '请先登录'
});
return this.setData({ showModal: 1 });
/*
if (app.user().user_identity == "学生") {
@ -105,7 +117,9 @@ Component({
this.setData({ courses, loading: false });
return res;
}).catch(e => {
if(showError)
if(e.code==401&&refresh)
this.setData({courses:[]});
if(showError&&e.code!=401)
app.showError(e);
this.setData({loading: false });
return e;

@ -6,14 +6,14 @@
<nav-bar list="{{statuses}}" width="300" itemWidth="140" cancellable="1" current="-1" type="plain" bg='' bindchange="onStatusChange"/>
</view>
<view wx:if="{{courses.length==0&&!loading}}" class="none-content">
<image class="none-content" src="{{imgDir}}blank1.png" mode="aspectFit"></image>
<text class="none-content hint">空空如也!</text>
<image class="none-image" src="{{attachDir}}908959" mode="aspectFit"></image>
<text class="none-text">暂时没有课堂</text>
<button bindtap="onTapButton" wx:if="{{user_id==2||current_cate==0}}" type="main" class="login-button">{{user_id==2?'登录':'加入课堂'}}</button>
</view>
<view wx:for="{{courses}}" wx:key="id" class="course-wrap">
<course-item data="{{item}}" category="{{categories[current_cate].value}}"/>
</view>
</scroll-view>
<!-- {{imgDir}}add.png -->
<view class="add-course" bindtap="addCourse">
<mp-icon icon="add" type="field" color="#0080f0" size="32"/>
</view>

@ -25,15 +25,22 @@
flex-direction: column;
align-items: center;
}
text.none-content{
.none-text{
font-size: 16px;
font-size: 13px;
color: dimgray;
padding: 20px 12px;
}
image.none-content{
.none-image{
margin-top: 120rpx;
height: 240rpx;
width: 220rpx;
}
.login-button{
width: 120px!important;
}
.add-course{
position: fixed;
@ -50,7 +57,3 @@ image.none-content{
justify-content: center;
align-items: center;
}
.add-course:hover{
opacity: 0.72;
}

@ -1,5 +1,5 @@
<navigator class="path" url="/markdown/path/path/path?subject_id={{id}}">
<image class="path-img" mode="aspectFill" src="{{eduUrl}}/{{image_url}}"></image>
<image class="path-img" mode="aspectFill" src="{{eduUrl}}/{{image_url}}" lazy-load></image>
<view class="detail">
<view class="name">
{{name}}

@ -33,7 +33,7 @@ Component({
app.syncUser()
.then(res => {
if (res.user.user_id != this.user_id) {
if(res.user_id==2)
if(res.user.user_id==2)
this.setData({shixuns:[]})
else
this.pullShixuns({ refresh: 1, showError })

@ -1,5 +1,5 @@
<navigator class="shixun" url="/markdown/shixun/shixun/shixun?identifier={{identifier}}">
<image class="shixun-img" mode="aspectFill" src="{{eduUrl}}/{{image_url}}"></image>
<image class="shixun-img" mode="aspectFill" src="{{eduUrl}}/{{image_url}}" lazy-load></image>
<view class="detail">
<view class="name">
{{name}}

@ -1,6 +1,5 @@
{
"component": true,
"usingComponents": {
"rich-md":"/components/rich-md/rich-md"
}
}

@ -59,6 +59,8 @@ Page({
this.setData({ tidings,course_apply_count ,loading:0});
return res;
}).catch(e=>{
if(e.code==401&&refresh)
this.setData({tidings:[]});
if(showError)
app.showError(e);
this.setData({loading:0});

@ -1,6 +1,7 @@
<page-meta>
<navigation-bar loading="{{loading}}"/>
</page-meta>
<require-login message="点击登录后查看消息通知"/>
<nav-bar bar-class="navbar" current="{{current}}" list="{{list}}" itemWidth="0" type="cap" bg="transparent" mg="8" bindchange="changeType"/>
<scroll-view class="tidings" refresher-enabled="1" scroll-y="1" bindrefresherrefresh="onPullDownRefresh" bindscrolltolower="_onReachBottom" lower-threshold="120" scroll-top="{{scrollTop}}">
<view class="message" wx:if="{{course_apply_count}}" bindtap="onTapMessage">

@ -123,7 +123,7 @@
"scene": null
},
{
"id": -1,
"id": 8,
"name": "爬虫访问",
"pathName": "pages/main/main",
"query": "course_id=7582&module_type=students",
@ -196,6 +196,21 @@
"id": -1,
"name": "account/pages/accounts/accounts",
"pathName": "account/pages/accounts/accounts",
"query": "",
"scene": null
},
{
"id": -1,
"name": "markdown/exercise/exercise/exercise",
"pathName": "markdown/exercise/exercise/exercise",
"query": "exercise_id=6450",
"scene": null
},
{
"id": -1,
"name": "account/pages/account/account",
"pathName": "account/pages/account/account",
"query": "exercise_id=6450",
"scene": null
}
]

Loading…
Cancel
Save