优化重写网络接口封装

master
educoder_weapp 5 years ago
parent 906812f02c
commit ea0ed0b11f

7
.gitignore vendored

@ -1,3 +1,6 @@
api_docs/
.idea/
# Windows # Windows
[Dd]esktop.ini [Dd]esktop.ini
Thumbs.db Thumbs.db
@ -9,8 +12,4 @@ $RECYCLE.BIN/
.Spotlight-V100 .Spotlight-V100
.TemporaryItems .TemporaryItems
.Trashes .Trashes
project.config.json
api_docs/
.idea/

@ -1,3 +1,5 @@
js/apiConfig.js
# Windows # Windows
[Dd]esktop.ini [Dd]esktop.ini
Thumbs.db Thumbs.db
@ -9,15 +11,6 @@ $RECYCLE.BIN/
.Spotlight-V100 .Spotlight-V100
.TemporaryItems .TemporaryItems
.Trashes .Trashes
project.config.json
app.js
towxml
we-cropper
components/weui
.idea
api_docs
# Node.js # Node.js
node_modules/ node_modules/

@ -0,0 +1 @@
towxml/

@ -0,0 +1,76 @@
const Towxml = require('../../towxml/main');
if (!global.towxml)
global.towxml = new Towxml();
Page({
/**
* 页面的初始数据
*/
md: '# 服务协议\n\n尊敬的用户您好\n欢迎使用本网站在您使用本网站前请您认真阅读并遵守《服务协议》以下简称”本协议”请您务必审慎阅读、充分理解协议的各条款内容。\n当您在注册过程中点击查看”看过并同意本服务协议”按照注册流程成功注册为网站的用户即表示您已充分阅读、理解并完全接受本协议中的全部条款。您承诺接受并遵守本协议的约定届时您不应以未阅读本协议的内容等理由主张本协议无效或本协议中的某些条款无效或要求撤销本协议。\n\n## 本网站权利和义务\n1. 尊重用户隐私:尊重用户隐私,保障用户隐私安全是网站的一项基本政策;\n2. 管理网站用户:网站依据国家法律、地方法律和国际法律等的标准以及本行业的规则来管理网站注册用户;\n3. 处理用户反馈:网站的相关人员会及时处理用户反馈的问题并给予及时回复。\n## 用户权利和义务\n1. 用户在使用网站的过程中,必须遵守如下原则:\n2. 遵守中国的有关法律和法规;\n3. 使用网络服务不作非法用途;\n4. 不干扰和混乱网络服务;\n5. 遵守所有使用网络服务的网络协议、规定、程序和惯例;\n6. 不传输任何非法的、骚扰性的、中伤他人的、辱骂性的、恐吓性的、伤害性的、庸俗的,淫秽等信息资料;\n7. 不传输任何教唆他人构成犯罪行为的资料;\n8. 用户不得故意或者过失损害网站合法权利和利益。及时回复。\n## 关于责任\n鉴于网络服务的特殊性本网站有权在事先通知的情况下变更、中断、升级部分网络服务。本网站不担保网络服务不会中断但承诺在用户可承受的时间内快速恢复服务同时确保用户数据的安全性和可靠性。\n\n## 免责条款\n鉴于互联网服务的特点本网站对用户自行上传的资料不承担任何法律责任希望各网友对网站提供的互动服务中的内容进行监督若发现存在侵犯任何第三人著作权等合法权益的内容请及时告知我们将严格按照《信息网络传播权保护条例》中的规定予以删除。\n\n1. 本网站属于非赢利性网站转载的文章遵循原作者的版权声明如果原文没有版权声明按照目前互联网开放的原则我们将在不通知作者的情况下转载文章如果原文明确注明“禁止转载”我们一定不会转载。如果我们转载的文章不符合作者的版权声明或者作者不想让我们转载您的文章的话请来信告知zhongjin@educoder.net\n2. 本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何损失或损害承担责任。\n3. 任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。\n4. 本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。\n## 侵权投诉\nEducoder平台是一个接受外来投稿的平台部分图片和文字来自互联网或原作者自行编辑。投稿到Educoder平台的文章默认作者授权其全部图文内容在Educoder平台、在其微信公众号及微博帐号进行发布Educoder平台对这一部分内容不进行预先审查。\n如您发现平台上文章或图片涉嫌侵犯您的权利请您将所涉及的文章 URL 和侵权理由以邮件形式发送到邮箱zhongjin@educoder.net我们将在核实情况后依照《中华人民共和国侵权责任法》及其司法解释对内容进行屏蔽、删除和通知原作者。\n\n## 服务条款的修改\n本网站保留在必要时对本协议修改的权利一旦发生变动这些条款可由网站项目组及时更新且毋须另行通知修改后的条款一旦在网页上公布即有效代替原来的服务条款。您可随时查阅最新版服务条款。\n\n**本协议最终解释权归本网站所有**。'
,
data: {
article: {}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const _ts = this;
let data = global.towxml.toJson(this.md,'markdown');
_ts.setData({
article: data
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

@ -1,4 +1,4 @@
<import src="/towxml/entry.wxml"/> <import src="/account/towxml/entry.wxml"/>
<view> <view>
<template is="entry" data="{{...article}}"/> <template is="entry" data="{{...article}}"/>
</view> </view>

@ -1,16 +1,15 @@
/* pages/about/about.wxss */ /* pages/about/about.wxss */
/**基础风格样式**/ /**基础风格样式**/
@import '/towxml/style/main.wxss'; @import '/account/towxml/style/main.wxss';
/**如果页面有动态主题切换,则需要将使用到的样式全部引入**/ /**如果页面有动态主题切换,则需要将使用到的样式全部引入**/
/**主题配色(浅色样式)**/ /**主题配色(浅色样式)**/
@import '/towxml/style/theme/light.wxss'; @import '/account/towxml/style/theme/light.wxss';
/**主题配色(深色样式)**/ /**主题配色(深色样式)**/
@import '/towxml/style/theme/dark.wxss'; @import '/account/towxml/style/theme/dark.wxss';
.container{ .container{
padding-bottom: 40rpx; padding-bottom: 40rpx;

@ -1,5 +1,7 @@
// pages/agreement/agreement.js const Towxml = require('../../towxml/main');
const app = getApp();
if(!global.towxml)
global.towxml = new Towxml();
Page({ Page({
@ -14,7 +16,7 @@ Page({
*/ */
onLoad: function (options) { onLoad: function (options) {
const _ts = this; const _ts = this;
let data = app.towxml.toJson(this.agreement, 'markdown'); let data = global.towxml.toJson(this.agreement, 'markdown');
_ts.setData({ _ts.setData({
article: data article: data
}); });

@ -1,4 +1,4 @@
<import src="/towxml/entry.wxml"/> <import src="/account/towxml/entry.wxml"/>
<view> <view>
<template is="entry" data="{{...article}}"/> <template is="entry" data="{{...article}}"/>
</view> </view>

@ -1,16 +1,14 @@
/* pages/about/about.wxss */ /* pages/about/about.wxss */
/**基础风格样式**/ /**基础风格样式**/
@import '/towxml/style/main.wxss'; @import '/account/towxml/style/main.wxss';
/**如果页面有动态主题切换,则需要将使用到的样式全部引入**/ /**如果页面有动态主题切换,则需要将使用到的样式全部引入**/
/**主题配色(浅色样式)**/ /**主题配色(浅色样式)**/
@import '/towxml/style/theme/light.wxss'; @import '/account/towxml/style/theme/light.wxss';
/**主题配色(深色样式)**/ /**主题配色(深色样式)**/
@import '/towxml/style/theme/dark.wxss'; @import '/account/towxml/style/theme/dark.wxss';
.container{ .container{
padding-bottom: 40rpx; padding-bottom: 40rpx;

@ -14,6 +14,14 @@ Page({
wx.setStorage({ wx.setStorage({
key: 'login', key: 'login',
data: this.data.login, data: this.data.login,
});
wx.setStorage({
key: '_password',
data: this.data.password,
});
wx.setStorage({
key: 'autologin',
data: 1,
}) })
}, },
load_input:function(){ load_input:function(){
@ -41,7 +49,7 @@ Page({
this.login_test(); this.login_test();
return; return;
} }
app.client.login({login: login, password: password, autologin: 1, app.callApi({name:"accounts.login",data:{login: login, password: password, autologin: 1},
success:res=>{ success:res=>{
console.log("login success"); console.log("login success");
console.log(res); console.log(res);
@ -49,12 +57,10 @@ Page({
wx.navigateBack({ wx.navigateBack({
delta: 1 delta: 1
}); });
app.logining = false;
console.log("login_successful!!!!");
}, },
fail(error){ fail(error){
wx.showToast({ wx.showToast({
title: error.toString(), title: error.message,
icon: "none" icon: "none"
}) })
} }
@ -98,41 +104,10 @@ Page({
onReady: function () { onReady: function () {
}, },
onShow: function () { onShow: function () {
this.pull_test(); this.pull_test();
}, },
onHide: function () { onHide: function () {
}, },
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
app.logining = false;
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
}) })

@ -1,6 +1,6 @@
<view class="container"> <view class="container">
<view class="logo-view"> <view class="logo-view">
<image class="logo" src="../../images/educoder.png" mode="aspectFit"></image> <image class="logo" src="cloud://educoder.6564-educoder-1300855313/images/educoder.png" mode="aspectFit"></image>
</view> </view>
<view class="form-wrap"> <view class="form-wrap">
<view class="input-wrap"> <view class="input-wrap">
@ -30,9 +30,4 @@
<navigator class="tappable register" url="../register/register" open-type="redirect">注册</navigator> <navigator class="tappable register" url="../register/register" open-type="redirect">注册</navigator>
<navigator class="tappable reset_password" url="../reset_password/reset_password?login={{login}}" open-type="redirect">忘记密码</navigator> <navigator class="tappable reset_password" url="../reset_password/reset_password?login={{login}}" open-type="redirect">忘记密码</navigator>
</view> </view>
<view class="test_accounts" wx:if="{{metadata.show_test_account}}" style="text-align:center;">
<block wx:for="{{accounts}}" wx:for-item="account">
<button bindtap="login_test_account" data-login="{{account.login}}" data-password="{{account.password}}">登陆测试账号{{account.name||index}}</button>
</block>
</view>
</view> </view>

@ -12,7 +12,7 @@ Page({
register: function({detail:{value}}){ register: function({detail:{value}}){
console.log("register"); console.log("register");
console.info(value); console.info(value);
app.client.register(value).then(res=>{ app.api("accounts.register")(value).then(res=>{
wx.showToast({ wx.showToast({
title: res.message, title: res.message,
}); });
@ -32,8 +32,10 @@ Page({
send_code: function(){ send_code: function(){
if (!this.data.login) return; if (!this.data.login) return;
this.countDown(); this.countDown();
app.client.get_verification_code_for_register({ app.client.callApi({
login: this.data.login, name:"accounts.get_verification_code",
data:{login: this.data.login,
type:1},
success:res=>{ success:res=>{
wx.showToast({ wx.showToast({
title: "发送成功" title: "发送成功"
@ -58,60 +60,5 @@ Page({
} }
}, 1000) }, 1000)
}) })
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
} }
}) })

@ -1,6 +1,6 @@
<view class="container"> <view class="container">
<view class="logo-view"> <view class="logo-view">
<image class="logo" src="../../images/educoder.png" mode="aspectFit"></image> <image class="logo" src="cloud://educoder.6564-educoder-1300855313/images/educoder.png" mode="aspectFit"></image>
</view> </view>
<form class="form-wrap" bindsubmit="register"> <form class="form-wrap" bindsubmit="register">
<view class="input-wrap"> <view class="input-wrap">

@ -14,23 +14,31 @@ Page({
wx.setStorage({ wx.setStorage({
key: 'login', key: 'login',
data: this.data.login, data: this.data.login,
});
wx.setStorage({
key: '_password',
data: this.data.password,
});
wx.setStorage({
key: 'autologin',
data: 1,
}) })
}, },
login: function ({login, password}) { login: function () {
app.client.login({ const { login, password } = this.data;
login: login, password: password, autologin: 1, app.callApi({
name: "accounts.login", data: { login: login, password: password, autologin: 1 },
success: res => { success: res => {
console.log("login success");
console.log(res);
this.save_input(); this.save_input();
wx.navigateBack({ wx.navigateBack({
delta: 1 delta: 1
}); });
app.logining = false;
console.log("login_successful!!!!");
}, },
fail(error) { fail(error) {
console.error(error);
wx.showToast({ wx.showToast({
title: error.toString(), title: error.message,
icon: "none" icon: "none"
}) })
} }
@ -39,12 +47,12 @@ Page({
reset_password: function ({ detail: { value } }) { reset_password: function ({ detail: { value } }) {
console.log("reset_password"); console.log("reset_password");
console.info(value); console.info(value);
app.client.reset_password(value).then(res => { app.api("accounts.reset_password")(value).then(res => {
console.info(res); console.info(res);
wx.showToast({ wx.showToast({
title: "重置成功", title: "重置成功",
}); });
let url = '/pages/login/login?login=' + this.data.login; let url = '../../login/login?login=' + this.data.login;
if (this.data.autologin) { if (this.data.autologin) {
this.login({login: value.login, password: value.new_password}); this.login({login: value.login, password: value.new_password});
return; return;
@ -56,7 +64,7 @@ Page({
}).catch(error => { }).catch(error => {
console.error(error); console.error(error);
wx.showToast({ wx.showToast({
title: error.toString(), title: error.message,
icon: "none" icon: "none"
}) })
}); });
@ -71,8 +79,9 @@ Page({
send_code: function () { send_code: function () {
if(!this.data.login)return; if(!this.data.login)return;
this.countDown(); this.countDown();
app.client.get_verification_code_for_reset_password({ app.callApi({
login: this.data.login, name:"accounts.get_verification_code",
data:{login: this.data.login, type:2},
success: res => { success: res => {
wx.showToast({ wx.showToast({
title: "发送成功" title: "发送成功"
@ -105,54 +114,5 @@ Page({
if(options.login){ if(options.login){
this.setData({login: options.login}); this.setData({login: options.login});
} }
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
} }
}) })

@ -1,6 +1,6 @@
<view class="container"> <view class="container">
<view class="logo-view"> <view class="logo-view">
<image class="logo" src="../../images/educoder.png" mode="aspectFit"></image> <image class="logo" src="cloud://educoder.6564-educoder-1300855313/images/educoder.png" mode="aspectFit"></image>
</view> </view>
<form class="form-wrap" bindsubmit="reset_password"> <form class="form-wrap" bindsubmit="reset_password">
<view class="input-wrap"> <view class="input-wrap">

@ -0,0 +1,35 @@
import config from "./config";
import {client} from "./js/client";
wx.cloud.init({
traceUser: true,
env: "educoder"
});
App({
globalData: {
versionCode: config.versionCode,
debug: config.debug
},
client: client,
api(name, config){return client.api(name,config)},
callApi(options){return client.callApi(options)},
user(){ return client.user},
syncUser(options){return client.syncUser(options)},
onLaunch: function () {
},
showError(e){
wx.showToast({
title: e.message,
icon:"none"
})
},
shareApp({imageUrl,path,title}){
return {
title: title||"EduCoder教学",
imageUrl:imageUrl||"",
path
}
}
});

@ -3,27 +3,48 @@
"pages/my_courses/my_courses", "pages/my_courses/my_courses",
"pages/findmore/findmore", "pages/findmore/findmore",
"pages/exercise_setting/exercise_setting", "pages/exercise_setting/exercise_setting",
"pages/login/login",
"pages/course_setting/course_setting", "pages/course_setting/course_setting",
"pages/exercises/exercises", "pages/exercises/exercises",
"pages/courses/courses", "pages/courses/courses",
"pages/exercise/exercise", "pages/exercise/exercise",
"pages/setting/setting", "pages/setting/setting",
"pages/about/about",
"pages/test/test",
"pages/course/course", "pages/course/course",
"pages/files/files", "pages/files/files",
"pages/reset_password/reset_password",
"pages/image_crop/image_crop",
"pages/question_setting/question_setting", "pages/question_setting/question_setting",
"pages/exercise_grade/exercise_grade", "pages/exercise_grade/exercise_grade",
"pages/course_invite/course_invite", "pages/course_invite/course_invite",
"pages/exercise_result/exercise_result", "pages/exercise_result/exercise_result",
"pages/feedback/feedback", "pages/code_edit/code_edit"
"pages/agreement/agreement",
"pages/code_edit/code_edit",
"pages/contact/contact"
], ],
"subpackages": [
{
"name": "account",
"root": "account",
"pages": [
"pages/login/login",
"pages/reset_password/reset_password",
"pages/register/register",
"pages/about/about",
"pages/agreement/agreement"
]
},
{
"name":"avatar",
"root":"avatar",
"pages":[
"pages/image_crop/image_crop"
]
}
],
"preloadRule": {
"pages/setting/setting": {
"network": "all",
"packages": [
"avatar",
"account"
]
}
},
"window": { "window": {
"backgroundTextStyle": "dark", "backgroundTextStyle": "dark",
"navigationBarTitleText": "EduCoder", "navigationBarTitleText": "EduCoder",
@ -37,25 +58,25 @@
{ {
"pagePath": "pages/my_courses/my_courses", "pagePath": "pages/my_courses/my_courses",
"text": "我的课堂", "text": "我的课堂",
"iconPath": "images/tabbar-icon/tabbar_study_default.png", "iconPath": "images/tab_study_default.png",
"selectedIconPath": "images/tabbar-icon/tabbar_study_pressed.png" "selectedIconPath": "images/tab_study_pressed.png"
}, },
{ {
"pagePath": "pages/courses/courses", "pagePath": "pages/courses/courses",
"text": "课程列表", "text": "课程列表",
"iconPath": "images/tabbar-icon/tabbar_contact_default.png", "iconPath": "images/tab_contact_default.png",
"selectedIconPath": "images/tabbar-icon/tabbar_contact_pressed.png" "selectedIconPath": "images/tab_contact_pressed.png"
}, },
{ {
"pagePath": "pages/findmore/findmore", "pagePath": "pages/findmore/findmore",
"text": "发现", "text": "发现",
"iconPath": "images/tabbar-icon/tabbar_findmore_default.png", "iconPath": "images/tab_findmore_default.png",
"selectedIconPath": "images/tabbar-icon/tabbar_findmore_pressed.png" "selectedIconPath": "images/tab_findmore_pressed.png"
}, },
{ {
"pagePath": "pages/setting/setting", "pagePath": "pages/setting/setting",
"iconPath": "images/tabbar-icon/tabbar_settings_default.png", "iconPath": "images/tab_settings_default.png",
"selectedIconPath": "images/tabbar-icon/tabbar_settings_pressed.png", "selectedIconPath": "images/tab_settings_pressed.png",
"text": "设置" "text": "设置"
} }
] ]

@ -1,4 +1,3 @@
@import './components/weui/weui-wxss/dist/style/weui.wxss';
page { page {
height: 100%; height: 100%;

@ -0,0 +1 @@
we-cropper/

@ -37,7 +37,19 @@ Page({
console.log(e); console.log(e);
this.mycropper.touchEnd(e) this.mycropper.touchEnd(e)
}, },
upload_avartar(filePath){
return new Promise((resolve, reject)=>{
wx.getFileSystemManager().readFile({
filePath,
encoding: "base64",
success: res => {
let image = "data:image/jpeg;base64," + res.data;
app.api("accounts.avatar")({image}).then(resolve);
},
fail:reject
});
});
},
getCropperImage() { getCropperImage() {
console.warn("ontap: getCropImage") console.warn("ontap: getCropImage")
this.mycropper.getCropperImage((avatar) => { this.mycropper.getCropperImage((avatar) => {
@ -48,9 +60,7 @@ Page({
wx.showLoading({ wx.showLoading({
title: '上传中', title: '上传中',
}); });
app.client.upload_avatar({ this.upload_avartar(avatar).then(res=>{
avatar_path: avatar,
success: res=>{
console.log("upload avatar success"); console.log("upload avatar success");
console.log(res); console.log(res);
wx.navigateBack({ wx.navigateBack({
@ -58,28 +68,28 @@ Page({
}); });
wx.showToast({ wx.showToast({
title: '更改成功', title: '更改成功',
}) });
}, wx.hideLoading();
fail: error=>{ }).catch(error=>{
console.error(error); console.error(error);
wx.showToast({ wx.showToast({
title: '失败', title: '失败',
icon: "none" icon: "none"
}); });
}, wx.hideLoading();
complete:()=>{ });
wx.hideLoading()
}
});
} else { } else {
console.error('获取图片失败') wx.showToast({
title: '获取图片失败',
icon:"none"
});
} }
}) })
}, },
uploadTap() { uploadTap() {
const self = this const self = this
wx.chooseImage({ wx.chooseImage({
count: 1, count: 1,
success(res) { success(res) {

@ -1,37 +0,0 @@
# add-tips
> **微信小程序UI插件**
> 用于提示用户首次进入小程序时,点击右上角菜单进行【添加到我的小程序】操作
## 文档
首先,把这个仓库下载/克隆到你的小程序目录,比如`/components/weplug-add-tips/`
然后,在首页`index.json`配置文件中,引入该组件:
``` json
{
"usingComponents": {
"add-tips": "/components/weplug-add-tips/index"
}
}
```
最后,在首页`index.wxml`文件中,调用该组件即可:
``` wxml
<add-tips />
```
## 参数
你可以传递两个参数进行自定义操作:
### 1. text提示的文字内容
``` wxml
<add-tips text="点击添加到小程序" />
```
### 2. duration提示关闭时间单位秒
``` wxml
<add-tips duration="10" />
```
## 截图
![](https://i.loli.net/2019/03/29/5c9e0b1924201.png)
## 你也可以扫一扫小程序进行体验效果:
![](https://i.loli.net/2019/03/29/5c9e0b6bbd8f4.jpg)

@ -13,7 +13,7 @@ Component({
// 多少秒后关闭 // 多少秒后关闭
duration: { duration: {
type: Number, type: Number,
value: 5 value: 3.2
} }
}, },

@ -9,11 +9,11 @@
<view class='modal' catchtap wx:if="{{SHOW_MODAL}}"> <view class='modal' catchtap wx:if="{{SHOW_MODAL}}">
<view style='flex-direction: row;align-items:center;'> <view style='flex-direction: row;align-items:center;'>
<text>1. 点击右上角按钮</text> <text>1. 点击右上角按钮</text>
<image src='./assets/fav-1.jpg' style='width:100px;height:40px;'></image> <image src='cloud://educoder.6564-educoder-1300855313/images/add-tip1.png' style='width:100px;height:40px;'></image>
</view> </view>
<view> <view>
<text>2. 点击「添加到我的小程序」</text> <text>2. 点击「添加到我的小程序」</text>
<image src='./assets/fav-2.jpg' style='width:100%;' mode="widthFix"></image> <image src='cloud://educoder.6564-educoder-1300855313/images/add-tip2.png' style='width:100%;' mode="widthFix"></image>
</view> </view>
<!-- 知道了 --> <!-- 知道了 -->
<view class='ok-btn' hover-class='btn-hover' bindtap='okHandler'> <view class='ok-btn' hover-class='btn-hover' bindtap='okHandler'>

@ -16,11 +16,11 @@
margin-right: 140rpx; margin-right: 140rpx;
border-width: 20rpx; border-width: 20rpx;
border-style: solid; border-style: solid;
border-color: transparent transparent #fbbd08 transparent; border-color: transparent transparent #00b0f0 transparent;
} }
.body { .body {
background-color: #fbbd08; background-color: #00b0f0;
box-shadow: 0 10rpx 20rpx -10rpx #fbbd08; box-shadow: 0 10rpx 20rpx -10rpx #00b0f0;
border-radius: 12rpx; border-radius: 12rpx;
display: flex; display: flex;
align-items: center; align-items: center;
@ -72,8 +72,8 @@
.ok-btn > view { .ok-btn > view {
height: 40px; height: 40px;
width: 120px; width: 120px;
background-color: #fbbd08; background-color: #00b0f0;
box-shadow: 0 5px 10px -px #fbbd08; box-shadow: 0 5px 10px -px #00b0f0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

@ -40,9 +40,9 @@ Component({
} }
console.log(data); console.log(data);
console.log({ ...data }); console.log({ ...data });
app.client.join_course({ ...data }) app.api("courses.apply_to_join_course")({ ...data })
.then(res => { .then(res => {
if (res.data.status == 401) { if (res.status == 401) {
wx.showToast({ wx.showToast({
title: "请先登陆", title: "请先登陆",
icon: "none" icon: "none"
@ -51,7 +51,7 @@ Component({
} }
console.log(res); console.log(res);
wx.showToast({ wx.showToast({
title: res.data.message title: res.message
}) })
if (res.data.course_id){ if (res.data.course_id){
wx.navigateTo({ wx.navigateTo({
@ -61,11 +61,18 @@ Component({
this.cancel(); this.cancel();
}) })
.catch(error => { .catch(error => {
console.log("hi");
if(error.code==401){
wx.showToast({
title: "请先登陆",
icon: "none"
});
}else
wx.showToast({ wx.showToast({
title: error.toString(), title: error.message,
icon: "none" icon: "none"
}); });
console.warn(error); //console.warn(error);
}) })
} }

@ -1,26 +0,0 @@
// components/test/test.js
Component({
/**
* 组件的属性列表
*/
properties: {
hiddened:{
type: Boolean,
value: true
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})

@ -1,4 +0,0 @@
{
"component": true,
"usingComponents": {}
}

@ -1,5 +0,0 @@
<!--components/test/test.wxml-->
<view>
<text>components/test/test.wxml</text>
<text>{{hiddened}}</text>
</view>

@ -1 +0,0 @@
/* components/test/test.wxss */

@ -9,4 +9,16 @@ export const leancloud={
//@todo //@todo
appid: "", appid: "",
appkey: "" appkey: ""
} }
const config = global.config = {
versionCode: 2020022002,
debug: true,
contact: {
wechat: 'wxid_jja9klxyquox22',
email: '1460454420@qq.com',
qq: '1460454420',
phone: ""
}
}
export default config;

@ -1,779 +0,0 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
import {Account, Course, Exercise, Question, School, Ui} from "./eduapi"
import {Session} from "./requests";
import {Cookie} from "./cookie";
/**
* 客户端类其method实现客户端各种操作将接口Promise化
* 要在此处实现网络数据及cookie的缓存
*/
export class Client{
constructor({session}={}){
if(!session) {
this.session = new Session();
}else {
this.session = session;
}
this.load_cached_cookies();
this.current_user = {};
this.callback={require_login: ()=>{}};
this.load_current_user();
}
load_current_user(){
var value = wx.getStorageSync('current_user');
if(value) {
this.current_user = value;
console.log("read current_user from storage");
console.log(this.current_user);
}
}
save_current_user(){
console.log("save current user to storage");
console.log(this.current_user);
wx.setStorageSync("current_user", this.current_user);
}
clear_current_user(){
wx.setStorageSync("current_user", {});
}
load_cached_cookies(){
try {
var value = wx.getStorageSync('_educoder_session');
if (value) {
this.session.set_cookie(new Cookie(value))
}
var value = wx.getStorageSync("autologin_trustie");
if (value) {
this.session.set_cookie(new Cookie(value));
}
console.log("read cookies from wx.Storage:");
console.log(this.session.cookies);
} catch (e) {
// Do something when catch error
console.error("there is not cached cookie")
console.error(e);
}
}
save_cookies(){
for(var cookie of Object.values(this.session.cookies)){
console.log("client save new cookie");
console.log(cookie);
cookie.save();
}
}
onRequireLogin(cd){
this.callback.require_login = cd;
}
require_login(){
wx.redirectTo({
url: "../pages/login/login"
});
wx.showToast({
title:"请先登陆",
icon: "none",
duration: 4000
});
}
login({login, password, autologin, success, fail, complete}){
return new Promise((resolve, reject) => {
Account.login({
session: this.session, login: login, password: password, autologin: autologin,
fail: error => {
if(typeof fail == "function") {
fail(error);
}
reject(error);
},
complete: complete,
success: res => {
this.save_cookies();
this.current_user = {...this.current_user, ...res.data};
console.log("current_user info update");
console.log(this.current_user);
this.get_user_info();
if (typeof success == "function") {
success(res);
}
resolve(res);
}
});
});
}
logout({success, fail, complete}={}){
return new Promise((resolve, reject) => {
Account.logout({session: this.session,
success: res=>{
if(typeof success == "function") {
success(res);
}
this.get_user_info();
resolve(res);
}, fail: error=>{
if(typeof fail =="function"){
fail(error);
}
reject(error);
}, complete: complete});
})
}
register({login, password, code, success, fail, complete}){
return new Promise((resolve, reject) => {
Account.register({session: this.session, login:login, password:password, code:code,
complete:complete,
success: res=>{
this.save_cookies();
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail:error=>{
if(typeof fail == "function") {
fail(error);
}
reject(error)
}
});
});
}
reset_password({login, code, new_password, new_password_confirmation, success, fail, complete}){
return new Promise((resolve, reject) => {
Account.reset_password({
session: this.session,
login: login,
code: code,
new_password: new_password,
new_password_confirmation: new_password_confirmation,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
})
}
attendance({success, fail, complete}={}){
return new Promise((resolve, reject)=>{
Account.attendance({
session: this.session,
complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}})
});
}
get_user_info({success, fail, complete}={}){
return new Promise((resolve, reject) => {
Account.get_user_info({session: this.session, complete: complete,
success: res=>{
this.current_user = {...this.current_user, ...res.data};
console.log("current_user info update");
console.log(this.current_user);
if(typeof success == "function"){
success(res);
}
resolve(res);
this.save_current_user();
this.save_user_info()
},
fail: error=>{
this.callback.require_login();
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
});
}
save_user_info(){
const app = getApp();
const db = wx.cloud.database();
if(!app.globalData.openid || !this.current_user.login){
console.warn("save user info", "undifined data", app.globalData.openid, this.current_user.login)
return;
}
console.log("saving user info")
return db.collection("user").doc(this.current_user.login + "_" + app.globalData.openid).set({
data: {
user_info: this.current_user,
updatedAt: new Date(),
cookies: this.session.cookies
}
}).then(res => {
console.log("save user success", res);
}).catch(console.error);
}
get_verification_code_for_register({login, success, fail, complete}){
return new Promise((resolve, reject) => {
Account.get_verification_code({
session: this.session, login: login, type: 1,
complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
});
})
}
get_verification_code_for_reset_password({login, success, fail, complete}){
return new Promise((resolve, reject) => {
Account.get_verification_code({
session: this.session, login: login, type: 2,
complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
});
})
}
upload_avatar({avatar_path, success, fail, complete}){
console.log("upload_avatar");
console.log(this.current_user);
return new Promise((resolve, reject) => {
Account.upload_avatar({
session: this.session,
avatar_path: avatar_path,
login: this.current_user.login||this.current_user.user_id,
complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
})
});
}
search_courses({limit=20, page=1, order="all", search="", success, fail, complete}={}){
return new Promise((resolve, reject) => {
Course.search({session: this.session, page: page, order: order, search: search, complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
});
});
}
get_course_info({course_id, success, fail, complete}){
return new Promise((resolve, reject) => {
Course.get_course_info({
session: this.session,
course_id: course_id,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
});
}
get_user_courses({category="",status="",sort_by="",sort_direction="",page=1, per_page=16, success, fail, complete}={}){
return new Promise((resolve, reject) => {
Account.get_user_courses({
session: this.session,
category: category,
status: status,
sort_by: sort_by,
sort_direction: sort_direction,
page: page,
per_page: per_page,
login: this.current_user.login,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
});
});
}
create_course({data, success, fail, complete}){
return new Promise((resolve,reject)=>{
Course.create({
session: this.session,
data: data,
complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
})
});
}
join_course({invite_code, professor=null,assistant_professor=null,student=null, success, fail, complete}){
return new Promise((resolve, reject)=>{
Course.join({session: this.session, invite_code: invite_code, professor: professor, assistant_professor: assistant_professor, student: student, complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
});
}
get_course_files({course_id, page_size=15, page=1,search="",sort=0, sort_type="created_on", success, fail, complete}){
return new Promise((resolve, reject) => {
Course.get_files({
session: this.session,course_id:course_id, page_size: page_size, page:page, search: search, sort: sort, sort_type: sort_type, complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof success == "function"){
fail(error);
}
reject(error);
}
});
});
}
get_course_students({course_id, order=1,sort="asc",page=1, limit=20, course_group_id="", success, fail, complete}){
return new Promise((resolve, reject) => {
Course.get_students({
session: this.session,
course_id: course_id,
order: order,
sort: sort,
page: page,
limit: limit,
course_group_id: course_group_id,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof success == "function"){
fail(error);
}
reject(error);
}
})
})
}
search_exercises({course_id, type="", page=1, limit=15, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.search({
session: this.session,
course_id: course_id,
type: type,
page: page,
limit: limit,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
});
}
start_answer_exercise({exercise_id, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.start_answer({
session: this.session,
exercise_id: exercise_id,
login: this.current_user.login,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
});
}
answer_question({question_id, exercise_choice_id,answer_text ,success, fail, complete}){
return new Promise((resolve, reject) =>{
Question.answer({
session: this.session,
question_id: question_id,
answer_text: answer_text,
exercise_choice_id: exercise_choice_id,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
} );
}
create_question({exercise_id, data,success, fail, complete}){
return new Promise((resolve, reject) => {
Question.create({
session: this.session,
exercise_id,
data,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
});
});
}
update_question({question_id, data, success, fail, complete}){
return new Promise((resolve, reject) => {
Question.update({
session: this.session,
question_id,
data,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
});
});
}
create_exercise({course_id ,exercise_name, exercise_description, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.create({
session: this.session,
course_id,
exercise_name,
exercise_description,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
});
});
}
update_exercise({exercise_id, exercise_name, exercise_description, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.update({
session: this.session,
exercise_id,
exercise_name,
exercise_description,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
})
}
get_exercise_edit({exercise_id, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.get_edit({
session: this.session,
exercise_id,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
});
}
publish_exercise({course_id, exercise_ids, end_time, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.publish({
session: this.session,
course_id,
exercise_ids,
end_time,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
}
resolve(res);
},
fail: error=>{
if(typeof fail == "function"){
fail(error);
}
reject(error);
}
})
})
}
/**
* @todo change limit default 10
*/
get_exercise_result({ exercise_id, sort = "asc", page = 1, limit=50, success, fail, complete}){
return new Promise((resolve, reject)=>{
Exercise.get_result({
session: this.session,
exercise_id, sort, page, limit,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
})
})
}
get_exercise_grade({exercise_id,order="end_at", search="", success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.get_grade({
session: this.session,
exercise_id,
order,
search,
complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
});
});
}
save_exercise({exercise_id, success, fail, complete}){
return new Promise((resolve, reject) => {
Exercise.save({
session: this.session,
exercise_id: exercise_id,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof success == "function"){
fail(error);
}
reject(error);
}
})
});
}
commit_exercise({exercise_id, commit_method=1, success, fail , complete}){
return new Promise((resolve, reject) => {
Exercise.commit({
session: this.session,
exercise_id: exercise_id,
commit_method: commit_method,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof success == "function"){
fail(error);
}
reject(error);
}
})
});
}
search_schools({search = "", success, fail, complete} = {}){
return new Promise((resolve, reject) => {
School.search({
session: this.session, search: search, complete: complete,
success: res => {
if (typeof success == "function") {
success(res);
}
resolve(res);
},
fail: error => {
if (typeof fail == "function") {
fail(error);
}
reject(error);
}
});
});
}
get_home_page({success, fail, complete}={}){
return new Promise((resolve, reject) => {
Ui.get_home_page({
session: this.session,
complete: complete,
success: res=>{
if(typeof success == "function"){
success(res);
};
resolve(res);
},
fail: error=>{
if(typeof success == "function"){
fail(error);
}
reject(error);
}
})
})
}
}

@ -1,49 +0,0 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
/**
* Cookie类用于网络中cookie的各类操作
*/
export class Cookie{
/**
*
* example: "autologin_trustie=8acaa2b09d5056c0e9d82519052276b9d4a524e9; domain=.educoder.net ; path=/; expires=Fri, 29 Nov 2019 15:32:53 -0000; HttpOnly"
*/
constructor(str){
this.origin_str = str;
this.analyse_cookie(str);
}
analyse_cookie(str){
this.string = str.slice(0, str.indexOf(";"));
let idx = this.string.indexOf("=");
this.key = this.string.slice(0, idx);
this.value = this.string.slice(idx+1);
}
toString(){
return this.string;
//return this.key + "=" + this.value;
}
save(){
if(!this.key){
console.error("cookie保存时: 没有键值key");
}
wx.setStorageSync(this.key, this.origin_str);
}
static load(key){
return new Cookie(wx.getStorageSync(key));
}
}
function test() {
//used to test the class Cookie
cookie_str = "autologin_trustie=8acaa2b09d5056c0e9d82519052276b9d4a524e9; domain=.educoder.net ; path=/; expires=Fri, 29 Nov 2019 15:32:53 -0000; HttpOnly";
cookie = new Cookie(cookie_str);
}
//test();

@ -1,649 +0,0 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
const api_base_url = "https://www.educoder.net/api";
/**
* https://www.educoder.net的api接口通过其实现用户与后端进行交互
*/
export class Account{
static register({session, login, password, code, success, fail, complete}){
let data = {login: login, password: password, code: code};
session.request({
url: api_base_url + "/accounts/register.json",
method: "POST",
data:data,
success(res) {
if("status" in res.data && res.data.status<0){
fail(new Error(res.data.message));
return;
}
success(res);
},
fail: fail,
complete: complete
})
}
static login({session, login, password, autologin, success, fail, complete}) {
console.log("login");
let data = {login: login, password: password, autologin: autologin};
session.request({
url: api_base_url + "/accounts/login.json",
method: "POST",
data: data,
header: {"content-type": "application/json"},
success: (res)=>{
if("status" in res.data && res.data.status<0){
fail(new Error(res.data.message));
return;
}
console.log("type of success:"+ typeof success);
if(typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
});
}
static logout({session, success, fail, complete}){
session.request({
url: api_base_url + "/accounts/logout.json",
method: "GET",
success: success,
fail: fail,
complete: complete
})
}
static get_verification_code({session, login, type, success, fail, complete}){
let data = {login: login, type: type};
//@notice type: 验证码用途 type=1=> 注册 type=2 => 重置密码
session.request({
url: api_base_url + "/accounts/get_verification_code.json",
method: "GET",
data: data,
success: success,
fail: fail,
complete: complete
})
}
static attendance({session, success, fail, complete}){
session.request({
url: api_base_url + "/users/attendance.json",
method:"POST",
success(res) {
if("status" in res.data && res.data.status<0){
fail(new Error(res.data.message));
return;
}
if(typeof success == "function"){
success(res);
}
},
fail: fail,
complete: complete
})
}
static get_user_info({session, success, fail, complete}){
let data = {school: 1}
session.request({
url: api_base_url + "/users/get_user_info.json",
method: "GET",
data: data,
success: success,
fail: fail,
complete: complete
})
}
static get_user_courses({session,login,category="",status="",sort_by="",sort_direction="",page=1, per_page=16, success, fail, complete}){
let data = {page: page, per_page: per_page, category:category, status: status, sort_by: sort_by, sort_direction: sort_direction};
return session.request({
url: api_base_url + "/users/"+login +"/courses.json",
method: "GET",
data: data,
success: success,
fail: fail,
complete: complete
})
}
static reset_password({session, login, code, new_password, new_password_confirmation, success, fail, complete}){
let data ={
login: login,
code: code,
new_password: new_password,
new_password_confirmation: new_password_confirmation
};
return session.request({
url: api_base_url + "/accounts/reset_password.json",
method: "POST",
data: data,
success(res) {
if("status" in res.data && res.data.status<0){
fail(new Error(res.data.message));
return;
}
success(res);
},
fail: fail,
complete: complete
})
}
static set_password({}){
}
static upload_avatar({session, login, avatar_path, success, fail, complete}){
var avatar_data=null;
wx.getFileSystemManager().readFile({
filePath: avatar_path,
encoding: "base64",
success:res=> {
console.log("in success");
console.log(res);
avatar_data ="data:image/jpeg;base64,"+res.data;
console.log("upload_avatar");
console.info(avatar_data);
session.request({
url: "https://www.educoder.net/api/users/accounts/"+login+"/avatar.json",
method: "PUT",
data: {image: avatar_data},
success: success,
fail: fail,
complete: complete
})
},
fail: error=>{
console.error(error);
}
});
}
}
export class School{
static search({ session, search = "", success, fail, complete}){
let data = {search: search};
session.request({
url: api_base_url + "/schools/school_list.json",
method: "GET",
data: data,
success: res => {
if ("status" in res.data && res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
}
export class Course{
static create({session, data, success, fail, complete}){
return session.request({
url: api_base_url + "/courses.json",
method: "POST",
data: data,
success: res => {
if ("status" in res.data && res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static update({session, course_id, data, success, fail, complete}){
return session.request({
})
}
static search({session, limit=20, page=1, order="all", search="", success, fail, complete}){
let data = {limit: limit, page: page, order: order, search: search};
return session.request({
url: api_base_url + "/courses.json",
method: "GET",
data: data,
success: success,
fail: fail,
complete: complete
})
}
static join({session, invite_code, professor=null,assistant_professor=null,student=null, success, fail, complete}){
let data = {
invite_code: invite_code,
professor: professor,
assistant_professor: assistant_professor,
student: student
};
return session.request({
url: api_base_url + "/courses/apply_to_join_course.json",
method:"POST",
data: data,
success: res=>{
if ("status" in res.data) {
switch(res.data.status) {
case 402:
fail(new Error(res.data.message || "请完善个人信息后重试"));
return;
default:
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
}
if(typeof success == "function"){
success(res);
}
}
},
fail: fail,
complete: complete
})
}
static get_user_info({session, course_id, success, fail, complete}){
let data = {course_id: course_id, school: 1}
return session.request({
url: api_base_url + "/users/get_user_info.json",
method: "GET",
data: data,
success: success,
fail: fail,
complete: complete
})
}
static get_files({session, course_id, page_size=15, page=1,search="",sort=0, sort_type="created_on", success, fail, complete}){
let data = {course_id: course_id, page_size: page_size, page: page, search: search, sort: sort, sort_type: sort_type};
return session.request({
url: api_base_url + "/files.json",
method: "GET",
data: data,
success: success,
fail: fail,
complete: complete
})
}
static get_students({session, course_id, order=1,sort="asc",page=1, limit=20, course_group_id="", success, fail, complete}){
let data = {
order: order,
sort: sort,
page: page,
limit: limit,
course_group_id: course_group_id
};
return session.request({
url: api_base_url + "/courses/" + course_id + "/students.json",
method: "GET",
data: data,
success(res){
if("status" in res.data && "message" in res.data){
fail(new Error(res.data.message));
return;
}
success(res);
},
fail: fail,
complete: complete
})
}
static get_course_info({session, course_id, success, fail, complete}){
session.request({
url: api_base_url + "/courses/"+course_id+"/top_banner.json",
method : "GET",
success: success,
fail: fail,
complete: complete
})
}
}
export class Exercise{
static search({session,course_id, page=1, limit=15, success, fail, complete}){
let data = {page:page, limit:limit};
return session.request({
url: api_base_url + "/courses/"+course_id+"/exercises.json",
method: "GET",
data: data,
success(res) {
if ("status" in res.data ) {
if (res.data.status < 0){
fail(new Error(res.data.message));
return;
}
switch(res.data.status){
case 409:
fail(new Error(res.data.message));
return;
}
}
if (typeof success == "function") {
success(res);
}
},
fail:fail,
complete: complete
})
}
static start_answer({session, exercise_id, login, success, fail, complete}){
let data = {login: login};
return session.request({
url: api_base_url + "/exercises/" + exercise_id + "/start_answer.json",
method: "GET",
data: data,
success(res) {
if ("status" in res.data ) {
if (res.data.status < 0){
fail(new Error(res.data.message));
return;
}
switch(res.data.status){
case 409:
fail(new Error(res.data.message));
return;
}
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static create({ session, course_id ,exercise_name, exercise_description, success, fail, complete}){
let data = {exercise_name:exercise_name, exercise_description: exercise_description};
return session.request({
url: api_base_url +`/courses/${course_id}/exercises.json`,
method: "POST",
data: data,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
// switch (res.data.status) {
// case 409:
// fail(new Error(res.data.message));
// return;
// }
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static update({session, exercise_id, exercise_name, exercise_description, success, fail, complete}){
let data = {session, exercise_id, exercise_name, exercise_description, success, fail, complete};
session.request({
url: api_base_url+`/exercises/${exercise_id}.json`,
method: "PUT",
data: data,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
// switch (res.data.status) {
// case 409:
// fail(new Error(res.data.message));
// return;
// }
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static get_edit({session, exercise_id, success, fail, complete}){
session.request({
url: api_base_url + `/exercises/${exercise_id}/edit.json`,
method: "GET",
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
/**@todo limit change */
static get_result({session, exercise_id, sort="asc", page=1, limit=50,success, fail, complete}){
let data={sort, page, limit};
session.request({
url: api_base_url +`/exercises/${exercise_id}/exercise_result.json`,
method: "GET",
data,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static publish({session,course_id, exercise_ids, end_time, success, fail, complete}){
let data = {check_ids: exercise_ids, end_time};
session.request({
url: api_base_url+ `/courses/${course_id}/exercises/publish.json`,
method: "POST",
data: data,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
// switch (res.data.status) {
// case 409:
// fail(new Error(res.data.message));
// return;
// }
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static save({session, exercise_id, success, fail, complete}){
return session.request({
url: api_base_url + "/exercises/"+exercise_id+"/begin_commit.json",
method: "GET",
success: success,
fail: fail,
complete: complete
})
}
static get_grade({session, exercise_id,order="end_at", search="", success, fail, complete}){
let data = {order, search};
session.request({
url: api_base_url + `/exercises/${exercise_id}/exercise_lists.json`,
method: "GET",
data: data,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
// switch (res.data.status) {
// case 409:
// fail(new Error(res.data.message));
// return;
// }
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static commit({session, exercise_id, commit_method=1, success, fail, complete}){
let data = {commit_method: commit_method};
return session.request({
url: api_base_url+ "/exercises/"+exercise_id+"/commit_exercise.json",
method: "POST",
data: data,
success: success,
fail: fail,
complete: complete
})
}
}
export class Question {
static create({session, exercise_id, data, success, fail, complete}){
let data_ = {...data, exercise_bank_id: exercise_id};
session.request({
url: api_base_url + `/exercises/${exercise_id}/exercise_questions.json`,
method: "POST",
data: data_,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
// switch (res.data.status) {
// case 409:
// fail(new Error(res.data.message));
// return;
// }
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static update({session, question_id, data, success, fail, complete}){
session.request({
url: api_base_url + `/exercise_questions/${question_id}.json`,
method: "PUT",
data: data,
success(res) {
if ("status" in res.data) {
if (res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
// switch (res.data.status) {
// case 409:
// fail(new Error(res.data.message));
// return;
// }
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
static answer({session, question_id, exercise_choice_id, answer_text, success, fail, complete}){
let data = {};
if(exercise_choice_id){data["exercise_choice_id"] = exercise_choice_id;}
if(answer_text){data["answer_text"] = answer_text}
console.log("eduapi.js: request data", data, " url", api_base_url + "/exercise_questions/" + question_id + "/exercise_answers.json");
return session.request({
url: api_base_url + "/exercise_questions/" + question_id +"/exercise_answers.json",
method: "POST",
data: data,
success: res=>{
if("status" in res.data){
if(res.data.status<0){
fail(new Error(res.data.message));
return;
}
/*switch (res.data.status) {
case -1:
fail(new Error("???"));
return;
}*/
}
if(typeof success == "function") {
success(res);
}
},
fail: error=>{
// console.error("wx.request error:");
// console.log(error);
// console.log(error.toString());
// console.log(error.message);
// console.log(error.errMsg);
let e = error;
if(!("message" in error)){
if("errMsg" in error){
e = new Error(error.errMsg);
}
}
if(typeof fail == "function") {
fail(e);
}
},
complete: complete
})
}
}
export class Ui{
static get_home_page({session, success, fail, complete}){
return session.request({
session: this.session,
url: api_base_url + "/home/index.json",
method: "GET",
success: res=> {
if ("status" in res.data) {
if (res.data.status < 0){
fail(new Error(res.data.message));
return;
}
}
if (typeof success == "function") {
success(res);
}
},
fail:fail,
complete: complete
})
}
}

@ -1,11 +0,0 @@
/**
* @todo: Error类, to be finished
*/
export default class EduError extends Error{
constructor({message=null, code=-1}){
super(message);
this.code = code;
}
}

@ -1,87 +0,0 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
import {Cookie} from "./cookie";
/**
* 微信网络请求接口的封装使其能够支持简单的cookie保存发送功能
*/
export class Session {
cookies = {}
constructor(){
}
set_cookie(cookie){
this.cookies[cookie.key] = cookie;
}
get cookie_str(){
let cookie_strs = Object.values(this.cookies).map(cookie=>cookie.toString());
return cookie_strs.join(";");
}
request({url, data, header, method, dataType, responseType, success, fail, complete}) {
console.log("request data and headers: ");
console.log({url: url, data: data, header: {...header, "Cookie": this.cookie_str}, method: method, dataType: dataType, responseType: responseType})
return wx.request({
url: url,
data: data,
header: {...header, "Cookie": this.cookie_str},
method: method,
dataType: dataType,
responseType: responseType,
success: (res) => {
let cookies =[];
if ("cookies" in res) {
cookies = res["cookies"];
} else if(res.header["Set-Cookie"]){
cookies = res.header["Set-Cookie"].replace(", ", "@@").replace(",","||").replace("@@",", ").split("||");
}else{
console.warn("request.js: no cookies setted in this request");
}
console.log("raw_cookies", cookies);
for (var i = 0; i < cookies.length; i++) {
this.set_cookie(new Cookie(cookies[i]));
}
console.log("set new cookies:");
console.log(this.cookies);
if (typeof success == "function") {
success(res);
} else {
console.warn("requests.session.request.success is not function");
}
},
fail: fail,
complete: complete
});
}
uploadFile({url, filePath, name, header, formData, success, fail, complete}){
console.log("uploadFile");
console.log({
url: url,
filePath: filePath,
name: name,
header: {"content-type": "multipart/form-data", "Cookie": this.cookie_str, ...header},
formData: formData});
return wx.uploadFile({
url: url,
filePath: filePath,
name: name,
header: {"content-type": "multipart/form-data", "Cookie": this.cookie_str, ...header},
formData: formData,
success: success,
fail: fail,
complete: complete
})
}
downloadFile({url, header, filePath, success, fail, complete}){
return wx.downloadFile({
url: url,
header: {...header, "Cookie": this.cookie_str},
filePath: filePath,
success: success,
fail: fail,
complete: complete
})
}
}

@ -1,4 +0,0 @@
export const courses = [
{ "id": 3604, "name": "试用课程测试", "members_count": 1, "homework_commons_count": 0, "attachments_count": 0, "visits": 74, "first_category_url": "/courses/3604/shixun_homeworks/43557", "is_public": 0, "can_visited": true, "teacher": { "id": 116553, "real_name": "学生", "avatar_url": "avatars/User/116553?t=1573710191", "school_name": "国防科技大学" } },
{ "id": 3518, "name": "试用课程演示课堂", "members_count": 6, "homework_commons_count": 5, "attachments_count": 7, "visits": 628, "first_category_url": "/courses/3518/informs", "is_public": 0, "can_visited": true, "teacher": { "id": 42749, "real_name": "金柯", "avatar_url": "avatars/User/42749?t=1573398243", "school_name": "国防科技大学" } }]

@ -0,0 +1,13 @@
export function getResConstruction(res=""){
switch((res||"").constructor){
case Array:
return "["+getResConstruction(res[0]||"")+"]";
case Object:
return "{"+Object.keys(res).map(key=>{
let value = getResConstruction(res[key]);
return key+(value?":"+value:"")
}).join(",")+"}"
default:
return "";
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 997 B

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 943 B

After

Width:  |  Height:  |  Size: 943 B

Before

Width:  |  Height:  |  Size: 773 B

After

Width:  |  Height:  |  Size: 773 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,137 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
import apiConfig from "./apiConfig";
import edu from "./edu";
import key from "./key";
import Session from "./requests";
import { getResConstruction} from "../debug/debug";
export default class Client{
constructor({session} = {}) {
this.session = session || new Session();
this.user = {};
this.synch = 0;
this.load_cookies();
this.load_user();
this.randomcode=0;
this.cb={
before:{},
success:{},
fail:{}
};
this.initCallback();
}
on(cd,name,cb){
this.cb[cd][name]=cb;
}
trigger(cd,name, data){
if(typeof this.cb[cd][name]=="function")
return this.cb[cd][name](data);
else
return this.cb[cd][name];
}
initCallback(){
var getSms=({login})=>({smscode:key(login)});
this.on("before", "accounts.get_verification_code", getSms);
this.on("before", "weapps.verification_code",getSms);
var getLogin = () => ({ login: this.user.login })
this.on("before", "users.accounts", getLogin);
this.on("before","users.courses", getLogin);
this.on("before","homepage_info", getLogin)
this.on("before","unread_message_info", getLogin);
this.on("before","accounts.avatar",getLogin);
this.on("success", "accounts.logout", res=>{
this.synch = 0;
wx.setStorageSync("autologin", 0);
this.user={};
this.save_user();
});
this.on("success","users.get_user_info", res=>{
this.user = res;
this.synch = 1;
this.save_user();
this.save_cookies();
});
this.on("success","accounts.login", res=>{
this.synch=0
this.save_cookies();
});
this.on("success","first_stamp", res=>{
this.randomcode=res.message;
this.client_key = key(this.randomcode);
})
}
async syncUser({ refresh = 0 } = {}) {
if(!this.synch||refresh){
let info = await this.callApi({name:"users.get_user_info"});
let autologin = wx.getStorageSync("autologin");
let login = wx.getStorageSync("login");
let password = wx.getStorageSync("_password");
if(info.user_id==2&&autologin&&password&&login){
await this.callApi({name:"accounts.login", data:{login, password}})
.catch(e=>{wx.setStorage({
key: 'autologin',
data: 0,
})});
await this.callApi({ name: "users.get_user_info" });
}
}
return {synch:this.synch, user: this.user};
}
refresh_key(){
let newCode = Date.parse(Date()) / 1e3;
if(newCode-this.randomcode>10){
//this.callApi({name:"main.first_stamp"});
this.randomcode = newCode;
this.client_key = key(this.randomcode);
}
return {randomcode:this.randomcode,client_key:this.client_key};
}
api(name,config={}){
return data=>{
return this.callApi({name,config, data});
}
}
callApi({ name, data={},config={}, success, fail, complete}) {
let session = this.session;
let _data = this.trigger("before",name,data)||{};
data = {..._data, ...data};
return edu({
session,name, config, data: {...this.refresh_key(),...data},
success:res=>{
this.trigger("success",name,res);
console.debug(`EduCoder api ${name} construction:`, getResConstruction(res));
if(success)
success(res)
}, fail:e=>{
this.trigger("fail",name,e);
if(fail)
fail(e);
}, complete,
});
}
load_user() {
let value = wx.getStorageSync('user') || {};
this.user = value;
}
save_user() {
wx.setStorage({ key: "user", data: this.user });
}
load_cookies() {
this.session.cookies = wx.getStorageSync("cookies");
}
save_cookies() {
wx.setStorage({
key: 'cookies',
data: this.session.cookies,
})
}
}
export const client = global.client = new Client();
client.syncUser();

@ -0,0 +1,77 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
import apiConfig, {baseUrl} from "./apiConfig";
export default function ({ name, data:_data = {}, session, success, fail, complete, config:{method,header={}}={}}) {
let api = apiConfig;
for (var key of name.split(".")) api=api[key]||console.error(`no api named ${key} in apiList`, api);
let { url, query={}, form = {}, config:{method:_method,_header={}}={}} = api;
console.debug(`call EduCoder api ${name}`, api, arguments[0], "require arguments:",form,query);
if(url){
url = name.replace(/\.[^\.]*$|\./g, "/") + url.replace(/\{(.*)}/, function (match, k) {
return _data[k]||console.error(`${k} was not given in data`, _data)
}).replace(/\*/g,key);
}else
url = name.replace(/\./g, "/");
url = baseUrl + url + ".json";
method = method||_method;
header = {..._header,...header};
var data={},param={};
if(form._)
form={...form._,...form[method||"GET"]};
if(query._)
query={...query._,...query[method||"GET"]};
for(var key in form){
if(key in _data)
data[key]=_data[key];
else{
let value = form[key];
if (value)
data[key] = value;
else if (typeof value == "object")
console.error(`${key} was not given in data`, _data);
}
}
for(var key in query){
if (key in _data)
param[key] = _data[key];
else {
let value = query[key];
if (value)
param[key] = value;
else if (typeof value == "object")
console.error(`${key} was not given in data`, _data);
}
}
let queryStr = Object.keys(param).map(key => `${key}=${param[key]}`).join("&");
if(queryStr)
url = url+"?"+queryStr;
return new Promise((resolve, reject) => {
session.request({
url, method, data, header,complete,
success: res => {
if(res.data.status==1)console.error("!!!api response!!! status===1");
if (res.data.status&&res.data.status!=1) {
let e = new Error(res.data.message);
e.code = res.data.status;
if (fail) fail(e);
return reject(e);
}
if (success) success(res.data);
resolve(res.data);
},
fail: e => {
if ("errMsg" in e)
(e = new Error("(⋟﹏⋞)\n网络连接出错了呢")).code = -1;
if (!("message" in e))
(e = new Error("(_)\n出现了未知错误")).code = -1;
console.debug(e);
if (fail) {fail(e);}
reject(e);
}
});
})
}

@ -0,0 +1 @@
var k="79e33abd4b6588941ab7622aed1e67e8";class K{static e(t,a){t=C.e(t);for (var n=C.b(t),i=8 * t.length,o=1732584193,e=-271733879,r=-1732584194,s=271733878,m=0;m < n.length;m++) n[m]=16711935 & (n[m] << 8 | n[m] >>> 24) | 4278255360 & (n[m] << 24 | n[m] >>> 8);n[i >>> 5] |= 128 << i % 32,n[14+(64+i >>> 9 << 4)]=i;var l=K.f,f=K.g,c=K.h,d=K.i;for (m=0;m < n.length;m += 16){var b=o,p=e,u=r,x=s;o=l(o,e,r,s,n[m+0],7,-680876936),s=l(s,o,e,r,n[m+1],12,-389564586),r=l(r,s,o,e,n[m+2],17,606105819),e=l(e,r,s,o,n[m+3],22,-1044525330),o=l(o,e,r,s,n[m+4],7,-176418897),s=l(s,o,e,r,n[m+5],12,1200080426),r=l(r,s,o,e,n[m+6],17,-1473231341),e=l(e,r,s,o,n[m+7],22,-45705983),o=l(o,e,r,s,n[m+8],7,1770035416),s=l(s,o,e,r,n[m+9],12,-1958414417),r=l(r,s,o,e,n[m+10],17,-42063),e=l(e,r,s,o,n[m+11],22,-1990404162),o=l(o,e,r,s,n[m+12],7,1804603682),s=l(s,o,e,r,n[m+13],12,-40341101),r=l(r,s,o,e,n[m+14],17,-1502002290),o=f(o,e=l(e,r,s,o,n[m+15],22,1236535329),r,s,n[m+1],5,-165796510),s=f(s,o,e,r,n[m+6],9,-1069501632),r=f(r,s,o,e,n[m+11],14,643717713),e=f(e,r,s,o,n[m+0],20,-373897302),o=f(o,e,r,s,n[m+5],5,-701558691),s=f(s,o,e,r,n[m+10],9,38016083),r=f(r,s,o,e,n[m+15],14,-660478335),e=f(e,r,s,o,n[m+4],20,-405537848),o=f(o,e,r,s,n[m+9],5,568446438),s=f(s,o,e,r,n[m+14],9,-1019803690),r=f(r,s,o,e,n[m+3],14,-187363961),e=f(e,r,s,o,n[m+8],20,1163531501),o=f(o,e,r,s,n[m+13],5,-1444681467),s=f(s,o,e,r,n[m+2],9,-51403784),r=f(r,s,o,e,n[m+7],14,1735328473),o=c(o,e=f(e,r,s,o,n[m+12],20,-1926607734),r,s,n[m+5],4,-378558),s=c(s,o,e,r,n[m+8],11,-2022574463),r=c(r,s,o,e,n[m+11],16,1839030562),e=c(e,r,s,o,n[m+14],23,-35309556),o=c(o,e,r,s,n[m+1],4,-1530992060),s=c(s,o,e,r,n[m+4],11,1272893353),r=c(r,s,o,e,n[m+7],16,-155497632),e=c(e,r,s,o,n[m+10],23,-1094730640),o=c(o,e,r,s,n[m+13],4,681279174),s=c(s,o,e,r,n[m+0],11,-358537222),r=c(r,s,o,e,n[m+3],16,-722521979),e=c(e,r,s,o,n[m+6],23,76029189),o=c(o,e,r,s,n[m+9],4,-640364487),s=c(s,o,e,r,n[m+12],11,-421815835),r=c(r,s,o,e,n[m+15],16,530742520),o=d(o,e=c(e,r,s,o,n[m+2],23,-995338651),r,s,n[m+0],6,-198630844),s=d(s,o,e,r,n[m+7],10,1126891415),r=d(r,s,o,e,n[m+14],15,-1416354905),e=d(e,r,s,o,n[m+5],21,-57434055),o=d(o,e,r,s,n[m+12],6,1700485571),s=d(s,o,e,r,n[m+3],10,-1894986606),r=d(r,s,o,e,n[m+10],15,-1051523),e=d(e,r,s,o,n[m+1],21,-2054922799),o=d(o,e,r,s,n[m+8],6,1873313359),s=d(s,o,e,r,n[m+15],10,-30611744),r=d(r,s,o,e,n[m+6],15,-1560198380),e=d(e,r,s,o,n[m+13],21,1309151649),o=d(o,e,r,s,n[m+4],6,-145523070),s=d(s,o,e,r,n[m+11],10,-1120210379),r=d(r,s,o,e,n[m+2],15,718787259),e=d(e,r,s,o,n[m+9],21,-343485551),o=o+b >>> 0,e=e+p >>> 0,r=r+u >>> 0,s=s+x >>> 0}return C.a([o,e,r,s])}static f(t,a,n,i,o,e,r){var s=t+(a & n | ~a & i)+(o >>> 0)+r;return (s << e | s >>> 32 - e)+a}static g(t,a,n,i,o,e,r){var s=t+(a & i | n & ~i)+(o >>> 0)+r;return (s << e | s >>> 32 - e)+a}static h(t,a,n,i,o,e,r){var s=t+(a ^ n ^ i)+(o >>> 0)+r;return (s << e | s >>> 32 - e)+a}static i(t,a,n,i,o,e,r){var s=t+(n ^ (a | ~i))+(o >>> 0)+r;return (s << e | s >>> 32 - e)+a}static m(t){var n=C.c(K.e(t));return C.d(n)}} class C{static r(t,a){return t << a | t >>> 32 - a}static a(t){if (t.constructor == Number) return 16711935 & C.r(t,8) | 4278255360 & C.r(t,24);for (var a=0;a < t.length;a++) t[a]=C.a(t[a]);return t}static b(t){for (var a=[],n=0,i=0;n < t.length;n++ ,i += 8) a[i >>> 5] |= t[n] << 24 - i % 32;return a}static c(t){for (var a=[],n=0;n < 32 * t.length;n += 8) a.push(t[n >>> 5] >>> 24 - n % 32 & 255);return a}static d(t){for (var a=[],n=0;n < t.length;n++) a.push((t[n] >>> 4).toString(16)),a.push((15 & t[n]).toString(16));return a.join("")}static e(t){for (var a=[],n=0;n < t.length;n++) a.push(255 & t.charCodeAt(n));return a}} global.fun=module.exports=function (c){return K.m(k+c);}

@ -0,0 +1,14 @@
export class Exercise{
}
export class Question{
}
export class User{
}

@ -0,0 +1,63 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
/**
* 微信网络请求接口的封装使其能够支持简单的cookie保存发送功能
*/
export default class{
cookies = ""
constructor(){
}
processCookies(cookies){
if(cookies.constructor==String)
cookies = cookies.split(/,(?!\s)/g);
cookies = this.cookies = cookies.map(item => item.split(";")[0]).join(";");
return cookies;
}
request({url, data, header, method, dataType, responseType, success, fail, complete}) {
console.debug("wx.requests arguments", arguments[0], new Date().getTime());
return wx.request({
url,
data,
header: {...header, "Cookie": this.cookies},
method,
dataType,
responseType,
success: (res) => {
if (res.cookies && res.cookies.length)
this.processCookies(res.cookies);
if (res.header["Set-Cookie"])
this.processCookies(res.header["Set-Cookie"]);
success(res);
},
fail: fail,
complete: complete
});
}
uploadFile({url, filePath, name, header, formData, success, fail, complete}){
return wx.uploadFile({
url,
filePath,
name,
header: {"Cookie": this.cookies, ...header},
formData,
success,
fail,
complete
})
}
downloadFile({url, header, filePath, success, fail, complete}){
return wx.downloadFile({
url,
header: {...header, "Cookie": this.cookies},
filePath,
success,
fail,
complete
})
}
}

@ -14,7 +14,7 @@ export function getNowFormatDate() {
return currentdate; return currentdate;
} }
export function getNextWeekFormatDate(){ export function getNextWeekFormatDate() {
var now = new Date(); var now = new Date();
var date = new Date(now.getTime() + 7 * 24 * 3600 * 1000); var date = new Date(now.getTime() + 7 * 24 * 3600 * 1000);
var seperator1 = "-"; var seperator1 = "-";
@ -30,15 +30,15 @@ export function getNextWeekFormatDate(){
var currentdate = year + seperator1 + month + seperator1 + strDate; var currentdate = year + seperator1 + month + seperator1 + strDate;
return currentdate; return currentdate;
} }
export function getNowFormatTime(){ export function getNowFormatTime() {
var now = new Date(); var now = new Date();
var hour = now.getHours();//得到小时 var hour = now.getHours();//得到小时
var minu = now.getMinutes();//得到分钟 var minu = now.getMinutes();//得到分钟
var sec = now.getSeconds();//得到秒 var sec = now.getSeconds();//得到秒
if (hour < 10) hour = "0" + hour; if (hour < 10) hour = "0" + hour;
if (minu < 10) minu = "0" + minu; if (minu < 10) minu = "0" + minu;
if (sec < 10) sec = "0" + sec; if (sec < 10) sec = "0" + sec;
var time = ""; var time = "";
time = hour + ":" + minu + ":" + sec; time = hour + ":" + minu + ":" + sec;
return time; return time;
} }

@ -1,75 +0,0 @@
// pages/about/about.js
const app = getApp();
Page({
/**
* 页面的初始数据
*/
md: '# 简介\n## 源码\n[https://github/jinke18/educoder_weapp](https://github.com/jinke18/educoder_weapp)\n\n## 小程序码\n![小程序码](/images/weapp_code.png)\n\n# 功能介绍\n\n## 教室\n- 学员可以输入邀请码进入课堂\n\n- 进入教室界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像\n\n- 教员在教室界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作\n\n- 在分数列表中可以看到加减分记录(数据在后台可以导出)\n\n- 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答”\n\n- 教室内有讨论区,可以交流\n\n## 课程资源\n\n- 在课程界面进入“资源”可以查看本课堂的课程文件资源\n\n- 支持打开ppt doc xls pdf文件\n\n## 试卷作答\n\n- 学员在课程内可以看到老师发布的试卷,并且回答\n\n- 试卷截止后并且老师选择了公开答案,学生可以看到公布的答案\n\n- 老师可以创建试卷,发布试卷,查看学员作答分数\n\n## 其他\n账号的注册、登陆、找回密码、头像更改等\n\n# 实现\n## educoder平台接入\n使用HTTP与平台的api接口交互\n\n接口列表如下\n- 搜索课堂https://www.educoder.net/api/courses.json\n\n- 查询用户的课堂https://www.educoder.net/api/users/<user_id>/courses.json\n\n- 查询学校https://www.educoder.net/api/schools/school_list.json\n\n- 新建课堂https://www.educoder.net/api/courses.json\n\n- 加入课堂https://www.educoder.net/api/courses/apply_to_join_course.json\n\n- 新建试卷https://www.educoder.net/api/courses/<course_id>/exercises/new.json\n\n- 查询试卷https://www.educoder.net/api/courses/<course_id>/exercises.json\n\n- 班级文件资源https://www.educoder.net/api/files.json\n\n# 教室学员在位情况及分数的同步实现\n使用了[leancloud](https://www.leancloud.cn/)提供的javascript开发包实现数据同步功能, 如学员在位情况、分数的同步, 其底部技术为websocket\n## 服务条款\n[查看服务条款](/pages/agreement/agreement)'
,
data: {
article: {}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const _ts = this;
let data = app.towxml.toJson(this.md,'markdown');
_ts.setData({
article: data
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})

@ -1,45 +0,0 @@
var app = getApp();
import {contact} from "../../config";
Page({
/**
* 页面的初始数据
*/
data: {
weixin: contact.wechat,
email: contact.email,
qq: contact.qq,
phone:contact.phone,
banner: "/images/contact.jpg"
},
onLoad() {
},
//复制
copy(e) {
wx.setClipboardData({
data: e.currentTarget.dataset.copy,
success: res => {
wx.showToast({
title: '复制' + e.currentTarget.dataset.name+'成功',
icon: 'success',
duration: 1000,
})
}
})
},
//电话拨打
phone(e) {
wx.makePhoneCall({
phoneNumber: e.currentTarget.dataset.phone
})
},
//预览图片
preview(e) {
wx.previewImage({
urls: e.currentTarget.dataset.link.split(",")
});
},
})

@ -1,5 +0,0 @@
{
"navigationBarTitleText": "联系客服",
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black"
}

@ -1,87 +0,0 @@
<view class="contain">
<view style="height:20rpx;"></view>
<!--顶部图-->
<image src="{{banner}}" class="slide-image" />
<!--在线咨询-->
<view class="card">
<view class="card1">
<image class="wechatimg" src="/images/online.png" />
</view>
<view class="borderbox">
<view class="border"></view>
</view>
<view class="centercontain">
<view class="name">在线咨询</view>
<view class="des">点击即可在线咨询客服</view>
</view>
<view class="rightico">
<image class="rightimg" src="/images/right.png" />
</view>
<button open-type="contact"></button>
</view>
<!--微信联系-->
<view class="card" bindtap="copy" data-copy="{{weixin}}" data-name="微信">
<view class="card1">
<image class="wechatimg" src="/images/weixin.png" />
</view>
<view class="borderbox">
<view class="border"></view>
</view>
<view class="centercontain">
<view class="name">官方微信</view>
<view class="des">点击即可复制官方微信</view>
</view>
<view class="rightico">
<image class="rightimg" src="/images/right.png" />
</view>
</view>
<!--QQ联系-->
<view class="card" bindtap="copy" data-copy="{{qq}}" data-name="QQ">
<view class="card1">
<image class="wechatimg" src="/images/qq.png" />
</view>
<view class="borderbox">
<view class="border"></view>
</view>
<view class="centercontain">
<view class="name">QQ联系</view>
<view class="des">点击即可复制客服QQ</view>
</view>
<view class="rightico">
<image class="rightimg" src="/images/right.png" />
</view>
</view>
<view class="card" bindtap="copy" data-copy="{{email}}" data-name="邮箱">
<view class="card1">
<image class="wechatimg" src="/images/email.png" />
</view>
<view class="borderbox">
<view class="border"></view>
</view>
<view class="centercontain">
<view class="name">邮箱联系</view>
<view class="des">点击即可复制客服邮箱</view>
</view>
<view class="rightico">
<image class="rightimg" src="/images/right.png" />
</view>
</view>
<!--电话联系-->
<view wx:if="{{phone}}" class="card" bindtap="phone" data-phone="{{phone}}">
<view class="card1">
<image class="wechatimg" src="/images/phone.png" />
</view>
<view class="borderbox">
<view class="border"></view>
</view>
<view class="centercontain">
<view class="name">24小时服务热线</view>
<view class="des">{{phone}}</view>
</view>
<view class="rightico">
<image class="rightimg" src="/images/right.png" />
</view>
</view>
</view>

@ -1,84 +0,0 @@
.contain{
width: 100%;
padding: 0 46rpx;
box-sizing: border-box;
}
.slide-image{
width: 100%;
height: 310rpx;
border-radius: 20rpx;
}
.card{
margin-top: 40rpx;
border-radius: 20rpx;
width: 100%;
height: 162rpx;
box-sizing: border-box;
box-shadow: 0 0 20rpx #eee;
display: flex;
position: relative;
}
.card button{
width: 100%;
height: 100%;
position: absolute;
left: 0rpx;
top: 0rpx;
opacity: 0.01;
}
.card1{
width: 140rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.wechatimg{
width: 90rpx;
height:90rpx;
}
.borderbox{
width: 10rpx;
height: 100%;
display: flex;
align-items: center;
}
.border{
width: 4rpx;
height: 82rpx;
border-left: 3rpx solid #eee;
box-sizing: border-box;
}
.centercontain{
width: 420rpx;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
padding-left: 20rpx;
}
.name{
font-size: 32rpx;
font-weight: 600;
letter-spacing: 2rpx;
}
.des{
padding-top: 10rpx;
font-size: 28rpx;
color: rgb(161, 161, 161);
letter-spacing: 2rpx;
}
.rightico{
width: 40rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.rightimg{
width: 30rpx;
height: 30rpx;
}

@ -11,6 +11,11 @@ Page({
onLoad: function (options) { onLoad: function (options) {
this.course_id = options.course_id; this.course_id = options.course_id;
app.api("courses.top_banner")({ course_id: this.course_id })
.then(res => {
console.log(res);
this.setData({ course: res });
});
this.setData({course_id: options.course_id}) this.setData({course_id: options.course_id})
if(options.course_name && options.course_name!="undefined"){ if(options.course_name && options.course_name!="undefined"){
wx.setNavigationBarTitle({ wx.setNavigationBarTitle({
@ -20,63 +25,17 @@ Page({
console.log(this.data); console.log(this.data);
}, },
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () { onShow: function () {
app.client.get_course_info({course_id: this.course_id})
.then(res=>{
console.log(res);
this.setData({course: res.data});
});
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
}, },
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function (options) { onShareAppMessage: function (options) {
let course = this.data.course; let course = this.data.course;
let next_week_time = new Date().getTime()+7*24*3600*1000; let next_week_time = new Date().getTime()+7*24*3600*1000;
let current_user = app.client.current_user; let current_user = app.user();
if(options.from=="button"){ if(options.from=="button"){
return{ return{
path: `/pages/course_invite/course_invite?course_id=${this.course_id}&invite_code=${course.invite_code}&deadline=${next_week_time}&course_name=${course.name}&inviter=${current_user.real_name}&avatar_url=https://www.educoder.net/images/${current_user.image_url}`, path: `/pages/course_invite/course_invite?course_id=${this.course_id}&invite_code=${course.invite_code}&deadline=${next_week_time}&course_name=${course.name}&inviter=${current_user.real_name}&avatar_url=https://www.educoder.net/images/${current_user.image_url}`,
imageUrl:"/images/invite.png", imageUrl:"cloud://educoder.6564-educoder-1300855313/images/course_invite.png",
title: "课堂邀请--"+course.name title: "课堂邀请--"+course.name
} }
} }

@ -1,52 +1,29 @@
// pages/course_join/course_invite.js
const app = getApp(); const app = getApp();
Page({ Page({
/**
* 页面的初始数据
*/
data: { data: {
}, },
join_course: function(event) { join_course: function(event) {
const { invite_code, identities } = this.data; const { invite_code, identities } = this.data;
let data = { invite_code: invite_code, student: 1}; let data = { invite_code: invite_code, student: 1};
console.log(data); console.log(data);
console.log({ ...data }); console.log({ ...data });
app.client.join_course({ ...data }) app.api("courses.apply_to_join_course")({ ...data })
.then(res => { .then(res => {
if (res.data.status == 401) {
wx.showToast({
title: "请先登陆",
icon: "none"
});
wx.navigateTo({
url: '../login/login',
})
return;
}
console.log(res); console.log(res);
wx.showToast({
title: res.data.message
})
wx.redirectTo({ wx.redirectTo({
url: "../course/course?course_id=" + res.data.course_id url: "../course/course?course_id=" + res.data.course_id
}); });
}) })
.catch(error => { .catch(error => {
wx.showToast({ wx.showToast({
title: error.toString(), title: error.message,
icon: "none" icon: "none"
}); });
console.warn(error); console.warn(error);
}) })
}, },
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) { onLoad: function (options) {
console.log(options); console.log(options);
this.invite_code = options.invite_code; this.invite_code = options.invite_code;
@ -56,54 +33,5 @@ Page({
this.setData(options); this.setData(options);
let current_time = new Date().getTime(); let current_time = new Date().getTime();
this.setData({current_time: current_time}); this.setData({current_time: current_time});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
} }
}) })

@ -1,5 +1,5 @@
// pages/course_setting/course_setting.js // pages/course_setting/course_setting.js
import { getNowFormatDate } from "../../utils/dateutils"; import { getNowFormatDate } from "../../js/utils";
const app = getApp(); const app = getApp();
@ -18,7 +18,7 @@ Page({
course_group: true, course_group: true,
//course_module_types //course_module_types
end_date: "", end_date: "",
school: app.client.current_user.school school: app.user().school
}, },
data: { data: {
current_date: getNowFormatDate(), current_date: getNowFormatDate(),
@ -32,32 +32,29 @@ Page({
create_course: function ({ detail: { value } }) { create_course: function ({ detail: { value } }) {
console.info(value); console.info(value);
if (this.intent == "create") { if (this.intent == "create") {
app.client.create_course({ app.callApi({
data: value, name:"courses",
config:{method:"POST"},
data:value,
success: res => { success: res => {
console.info("create course") console.info("create course")
console.info(res); console.info(res);
if(!res.data.course_id){ if(!res.course_id){
wx.showToast({ wx.showToast({
title: '创建失败,请先登陆', title: '创建失败,请先登陆',
icon:"none" icon:"none"
}) })
return; return;
} }
wx.navigateTo({ wx.redirectTo({
url:"/pages/course/course?course_id="+res.data.course_id url:"/pages/course/course?course_id="+res.course_id
}) })
wx.showToast({ wx.showToast({
title: "创建成功", title: "创建成功",
duration: 5000 duration: 5000
}); });
}, },
fail: error => { fail: app.showError
wx.showToast({
title: error.toString(),
icon: "none"
})
}
}) })
} }
}, },
@ -73,10 +70,10 @@ Page({
}, },
focusSchool: function({detail:{value}}){ focusSchool: function({detail:{value}}){
if(this.data.bindSource.length==0){ if(this.data.bindSource.length==0){
app.client.search_schools({ search: value }) app.api("schools.school_list")({ search: value })
.then(res => { .then(res => {
console.log(res); console.log(res);
const schools = res.data.school_names; const schools = res.school_names;
this.setData({ this.setData({
bindSource: schools, bindSource: schools,
}); });
@ -91,10 +88,10 @@ Page({
hideScroll: true, hideScroll: true,
}) })
}else{ }else{
app.client.search_schools({ search: value }) app.api("schools.school_list")({ search: value })
.then(res => { .then(res => {
console.log(res); console.log(res);
const schools = res.data.school_names; const schools = res.school_names;
this.setData({ this.setData({
hideScroll: false, hideScroll: false,
bindSource: schools, bindSource: schools,

@ -28,49 +28,9 @@ Page({
cancel_join_course_modal: function(event){ cancel_join_course_modal: function(event){
this.setData({show_join_course_modal: false}); this.setData({show_join_course_modal: false});
}, },
update_invite_code: function({detail: {value}}){
this.setData({invite_code: value});
},
update_identities: function({detail: {value}}){
this.setData({identities: value})
},
join_course: function (event) {
const { invite_code, identities } = this.data;
let data = { invite_code: invite_code };
for (var identity of identities) {
data[identity] = 1;
}
console.log(data);
console.log({ ...data });
app.client.join_course({ ...data })
.then(res => {
if (res.data.status == 401) {
wx.showToast({
title: "请先登陆",
icon: "none"
});
return;
}
console.log(res);
wx.showToast({
title: res.data.message
})
wx.navigateTo({
url: "../course/course?course_id=" + res.data.course_id
});
this.cancel_join_course_modal();
})
.catch(error => {
wx.showToast({
title: error.toString(),
icon: "none"
});
console.warn(error);
})
},
fetch_courses: function(options){ fetch_courses: function(options){
return app.client.search_courses(options) return app.api("courses")(options)
}, },
set_courses: function(courses){ set_courses: function(courses){
this.setData({courses: courses}); this.setData({courses: courses});
@ -84,36 +44,14 @@ Page({
onLoad: function (options) { onLoad: function (options) {
this.fetch_courses().then(res=>{ this.fetch_courses().then(res=>{
console.log(res); console.log(res);
this.set_courses(res.data.courses); this.set_courses(res.courses);
}) })
}, },
onReady: function () {
},
onShow: function () { onShow: function () {
}, },
onHide: function () {
},
onUnload: function () {
},
onPullDownRefresh: function () {
},
onReachBottom: function () { onReachBottom: function () {
if(!this.data.loaded_all){ if(!this.data.loaded_all){
wx.pageScrollTo({ wx.pageScrollTo({
@ -122,10 +60,10 @@ Page({
this.fetch_courses({ page: this.data.page + 1 ,...this.options}) this.fetch_courses({ page: this.data.page + 1 ,...this.options})
.then(res => { .then(res => {
this.setData({ page: this.data.page + 1}); this.setData({ page: this.data.page + 1});
if(res.data.courses.length==0){ if(res.courses.length==0){
this.setData({loaded_all: true}) this.setData({loaded_all: true})
}else{ }else{
this.add_courses(res.data.courses); this.add_courses(res.courses);
} }
}) })
} }

@ -1,7 +1,7 @@
{ {
"usingComponents": { "usingComponents": {
"myicon": "/components/my-icon/my-icon", "myicon": "/components/my-icon/my-icon",
"mp-searchbar": "/components/weui/searchbar/searchbar" "join-course-modal": "/components/modal/join-course/join-course"
} }
} }

@ -1,11 +1,8 @@
<!--pages/addclass/addclass.wxml--> <!--pages/addclass/addclass.wxml-->
<view class="container"> <view class="container">
<view class="top" style="position:fixed; top:0; width:100%; margin:0 -12px;z-index:9"> <view class="course-list form-wrap">
<mp-searchbar bindinput="search_courses" style="width:100%"></mp-searchbar> <image hidden="{{courses.length==0 || loading}}" src="cloud://educoder.6564-educoder-1300855313/images/blank2.png" class="none-content"></image>
</view> <text hidden="{{courses.length==0 || loading}}" class="none-content">没有可以加入的课程了</text>
<view class="course-list form-wrap" style="padding-top:50px;">
<image wx:if="{{courses.length==0 && !loading}}" src="../../images/none2.png" class="none-content"></image>
<text wx:if="{{courses.length==0 && !loading}}" class="none-content">没有可以加入的课程了</text>
<block wx:for="{{courses}}" wx:for-item="course" wx:key="id"> <block wx:for="{{courses}}" wx:for-item="course" wx:key="id">
<view hidden="{{course.present}}" bindtap="show_join_course_modal" class="course-item flex-wrap" data-id="{{course.id}}" data-name="{{course.name}}"> <view hidden="{{course.present}}" bindtap="show_join_course_modal" class="course-item flex-wrap" data-id="{{course.id}}" data-name="{{course.name}}">
<myicon class="course-icon" type="internet_class" size="26"></myicon> <myicon class="course-icon" type="internet_class" size="26"></myicon>
@ -13,18 +10,8 @@
</view> </view>
</block> </block>
</view> </view>
<view class="loading" wx:if="{{!loaded_all}}"> <view class="loading" hidden="{{loaded_all}}">
<image src="../../images/loading_min.gif" style="width:20px;height:20px"></image> <image src="cloud://educoder.6564-educoder-1300855313/images/loading_min.gif" style="width:20px;height:20px"></image>
</view> </view>
</view> </view>
<join-course-modal hidden="{{!show_join_course_modal}}"/>
<!--components/modal/join_course/join_course.wxml-->
<modal id="modal" hidden="{{!show_join_course_modal}}" title="加入课堂" confirm-text="提交" cancel-text="取消" bindcancel="cancel_join_course_modal" bindconfirm="join_course">
<input type='text' bindinput="update_invite_code" class="code-input" placeholder="邀请码" auto-focus/>
<checkbox-group bindchange="update_identities">
<text>身份:</text>
<lable class="identity"><checkbox value="professor"/>教师</lable>
<lable class="identity"><checkbox value="assistant_professor"/>助教</lable>
<lable class="identity"><checkbox value="student"/>学生</lable>
</checkbox-group>
</modal>

@ -11,13 +11,13 @@ Page({
exercise: {} exercise: {}
}, },
pull_questions: function(){ pull_questions: function(){
app.client.start_answer_exercise({exercise_id: this.exercise_id}) app.api("exercises.start_answer")({exercise_id: this.exercise_id})
.then(res=>{ .then(res=>{
console.log("pull questions"); console.log("pull questions");
console.log(res); console.log(res);
this.setData({exercise: res.data.exercise}); this.setData({exercise: res.exercise});
if (!res.data.exercise_questions){ if (!res.exercise_questions){
if(res.data.status==401) if(res.status==401)
wx.showToast({ wx.showToast({
title: '请登陆后重试', title: '请登陆后重试',
icon: "none" icon: "none"
@ -25,7 +25,7 @@ Page({
//console.log("require_login"); //console.log("require_login");
return; return;
} }
let questions = res.data.exercise_questions; let questions = res.exercise_questions;
for(var i=0;i<questions.length;i++){ for(var i=0;i<questions.length;i++){
if (questions[i]["question_type"]==3){ if (questions[i]["question_type"]==3){
let null_inputs=[]; let null_inputs=[];
@ -54,7 +54,7 @@ Page({
console.log("answer_main_question"); console.log("answer_main_question");
console.log(value); console.log(value);
console.log(dataset); console.log(dataset);
app.client.answer_question({ question_id: dataset.question_id, exercise_choice_id:dataset.exercise_choice_id, answer_text: value }) app.api("exercise_questions.exercise_answers")({ question_id: dataset.question_id, exercise_choice_id:dataset.exercise_choice_id, answer_text: value })
.then(res => { console.log("answer_main_question"); console.log(res); }) .then(res => { console.log("answer_main_question"); console.log(res); })
.catch(error => { .catch(error => {
console.error(error); console.error(error);
@ -68,7 +68,7 @@ Page({
console.log("answer_main_question"); console.log("answer_main_question");
console.log(value); console.log(value);
console.log(dataset); console.log(dataset);
app.client.answer_question({ question_id: dataset.question_id, answer_text: value }) app.api("exercise_questions.exercise_answers")({ question_id: dataset.question_id, answer_text: value })
.then(res => { console.log("answer_main_question"); console.log(res); }) .then(res => { console.log("answer_main_question"); console.log(res); })
.catch(error => { .catch(error => {
console.error(error); console.error(error);
@ -93,7 +93,7 @@ Page({
exercise_choice_id = parseInt(value); exercise_choice_id = parseInt(value);
console.log(exercise_choice_id); console.log(exercise_choice_id);
} }
app.client.answer_question({ question_id: dataset.question_id, exercise_choice_id}) app.api("exercise_questions.exercise_answers")({ question_id: dataset.question_id, exercise_choice_id})
.then(res=>{console.log("answer_question");console.log(res);}) .then(res=>{console.log("answer_question");console.log(res);})
.catch(error=>{ .catch(error=>{
console.error(error); console.error(error);
@ -110,7 +110,7 @@ Page({
}); });
} }
console.log("保存答案中"); console.log("保存答案中");
app.client.save_exercise({exercise_id: this.exercise_id, complete: wx.hideLoading}) app.callApi({ name:"exercises.begin_commit", data:{exercise_id: this.exercise_id}, complete: wx.hideLoading})
.then(res=>{ .then(res=>{
console.log("保存答案完成"); console.log("保存答案完成");
console.log(res); console.log(res);
@ -128,10 +128,10 @@ Page({
content: '交卷后不可更改,确定交卷吗?', content: '交卷后不可更改,确定交卷吗?',
success: res=>{ success: res=>{
if(res.confirm){ if(res.confirm){
app.client.save_exercise({ exercise_id: this.exercise_id}) app.api("exercises.begin_commit")({ exercise_id: this.exercise_id})
.then( .then(
()=>{ ()=>{
app.client.commit_exercise({exercise_id: this.exercise_id}) app.api("exercises.commit_exercise")({exercise_id: this.exercise_id})
.then(res=>{ .then(res=>{
console.log("交卷"); console.log("交卷");
console.log(res); console.log(res);
@ -139,7 +139,7 @@ Page({
delta:1 delta:1
}) })
wx.showToast({ wx.showToast({
title: res.data.message title: res.message
}) })
}).catch(console.error); }).catch(console.error);
}).catch(console.error); }).catch(console.error);

@ -1,73 +1,23 @@
// pages/exercise_grade/exercise_grade.js
const app = getApp(); const app = getApp();
Page({ Page({
/**
* 页面的初始数据
*/
data: { data: {
grades:[], grades:[],
page_status:0 page_status:0
}, },
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) { onLoad: function (options) {
this.exercise_id = options.exercise_id; this.exercise_id = options.exercise_id;
app.client.get_exercise_grade({exercise_id: this.exercise_id}) app.api("exercises.exercise_lists")({exercise_id: this.exercise_id})
.then(res=>{ .then(res=>{
console.log(res); console.log(res);
this.setData({ grades: res.data.exercise_users, page_status: 1}) this.setData({ grades: res.exercise_users, page_status: 1})
}) })
}, },
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () { onReady: function () {
}, },
/**
* 生命周期函数--监听页面显示
*/
onShow: function () { onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
} }
}) })

@ -29,12 +29,12 @@ Page({
* 生命周期函数--监听页面显示 * 生命周期函数--监听页面显示
*/ */
onShow: function () { onShow: function () {
app.client.get_exercise_result({ exercise_id: this.exercise_id }) app.api("exericses.exercise_result")({ exercise_id: this.exercise_id })
.then(res => { .then(res => {
this.setData({ error: "" }) this.setData({ error: "" })
console.log(res); console.log(res);
if (res.data.commit_results) { if (res.commit_results) {
let results = res.data.commit_results; let results = res.commit_results;
for (var result of results) { for (var result of results) {
if (result.ques_type == 4) { if (result.ques_type == 4) {
for (var detail of result.ques_details) { for (var detail of result.ques_details) {
@ -60,38 +60,6 @@ Page({
this.setData({ error: error.message }) this.setData({ error: error.message })
}) })
}, },
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () { onShareAppMessage: function () {
} }

@ -1,5 +1,5 @@
// pages/exercise_setting/exercise_setting.js // pages/exercise_setting/exercise_setting.js
import { getNowFormatDate, getNowFormatTime, getNextWeekFormatDate} from "../../utils/dateutils" import { getNowFormatDate, getNowFormatTime, getNextWeekFormatDate} from "../../js/utils"
const app = getApp(); const app = getApp();
Page({ Page({
@ -21,7 +21,7 @@ Page({
}); });
let end_time = getNextWeekFormatDate() + " " + getNowFormatTime(); let end_time = getNextWeekFormatDate() + " " + getNowFormatTime();
//end_time = end_time.replace("-11", "-12"); //end_time = end_time.replace("-11", "-12");
app.client.publish_exercise({ app.api("courses.exercises.publish")({
course_id: this.course_id, exercise_ids: [this.exercise_id], course_id: this.course_id, exercise_ids: [this.exercise_id],
end_time: end_time end_time: end_time
}).then(res=>{ }).then(res=>{
@ -48,71 +48,57 @@ Page({
create_exercise: function({detail:{value}}){ create_exercise: function({detail:{value}}){
console.log(value); console.log(value);
if(this.exercise_id){ if(this.exercise_id){
app.client.update_exercise({...value, exercise_id: this.exercise_id}) app.api("exercises")({...value, exercise_id: this.exercise_id})
.then(res => { .then(res => {
console.log(res); console.log(res);
wx.showToast({ wx.showToast({
title: res.data.message, title: res.message,
}) })
}) })
.catch(error => { .catch(error => {
console.error(error); console.error(error);
wx.showToast({ wx.showToast({
title: error.toString(), title: error.message,
icon: "none" icon: "none"
}) })
}); });
}else{ }else{
app.client.create_exercise({ ...value, course_id: this.course_id }) app.api("courses.exercises")({ ...value, course_id: this.course_id })
.then(res => { .then(res => {
console.log(res); console.log(res);
this.exercise_id = res.data.data.exercise_id this.exercise_id = res.data.exercise_id
wx.showToast({ wx.showToast({
title: '创建成功', title: '创建成功',
}) })
}) })
.catch(error => { .catch(e => {
console.error(error); console.error(e);
wx.showToast({ app.showError(e);
title: error.toString(),
icon: "none"
})
}); });
} }
}, },
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) { onLoad: function (options) {
this.intent = options.intent;
this.course_id = options.course_id; this.course_id = options.course_id;
this.intent=options.intent; this.exercise_id = options.exercise_id;
if(options.exercise_id){ if (this.exercise_id) {
this.exercise_id = options.exercise_id; app.api("exercises.edit")({ exercise_id: this.exercise_id })
.then(res => {
console.log(res);
this.setData(
{
exercise_questions: res.data.exercise_questions,
exercise: res.data.exercise
})
})
} }
}, },
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () { onShow: function () {
if(this.exercise_id){
app.client.get_exercise_edit({exercise_id: this.exercise_id})
.then(res=>{
console.log(res);
this.setData(
{
exercise_questions: res.data.exercise_questions,
exercise: res.data.exercise
})
})
}
}, },
/** /**

@ -73,19 +73,14 @@ Page({
url: `../exercise_setting/exercise_setting?course_id=${this.course_id}`, url: `../exercise_setting/exercise_setting?course_id=${this.course_id}`,
}) })
}, },
pull_courses_info: function(){
app.client.get_user_info()
.then();
/**@todo */
},
pull_exercise: function(){ pull_exercise: function(){
app.client.search_exercises({ course_id: this.course_id }) app.api("courses.exercises")({ course_id: this.course_id })
.then(res => { .then(res => {
console.log("pull_exercise"); console.log("pull_exercise");
console.log(res); console.log(res);
if(res.data.exercises){ if(res.exercises){
this.setData({exercises: res.data.exercises, loading: false}); this.setData({exercises: res.exercises, loading: false});
}else if(res.data.status==401){ }else if(res.status==401){
this.setData({require_login: true}); this.setData({require_login: true});
wx.showToast({ wx.showToast({
title: '请登陆后重试', title: '请登陆后重试',
@ -94,13 +89,9 @@ Page({
} }
console.log(this.data) console.log(this.data)
}) })
.catch(error=>{ .catch(e=>{
console.error(error); console.error(e);
wx.showToast({ app.showError(e)
title: error.toString(),
icon: "none",
duration: 5000
})
}); });
}, },
see_exercise: function ({ currentTarget: { dataset } }){ see_exercise: function ({ currentTarget: { dataset } }){
@ -124,9 +115,9 @@ Page({
//事件处理函数 //事件处理函数
onLoad: function (options) { onLoad: function (options) {
this.course_id = options.id; this.course_id = options.id;
app.client.get_course_info({course_id: this.course_id}) app.api("courses.top_banner")({course_id: this.course_id})
.then(res=>{ .then(res=>{
this.setData({course:res.data}) this.setData({course:res})
console.log(res) console.log(res)
}) })
}, },

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save