smart_class
educoder_weapp 5 years ago
parent e9e6b2ef5d
commit ecc2a42f69

@ -5,7 +5,7 @@ educoder微信小程序帮助使用[educoder平台](https://www.educoder.net)
[https://github/jinke18/smart_class](https://github.com/jinke18/smart_class) [https://github/jinke18/smart_class](https://github.com/jinke18/smart_class)
## 小程序码 ## 小程序码
![小程序码](/images/weapp_code.png) ![小程序码](/images/weapp_code_smart_class.png)
# 功能介绍 # 功能介绍

@ -8,7 +8,6 @@ const AV = require('./lib/av-live-query-weapp-min');
const Towxml = require('/towxml/main'); const Towxml = require('/towxml/main');
const login = require("./model/user"); const login = require("./model/user");
//初始化
AV.init({ AV.init({
appId: 'eVHYNBdT5D2lDxNj5jtJXsWT-MdYXbMMI', appId: 'eVHYNBdT5D2lDxNj5jtJXsWT-MdYXbMMI',
appKey: 'waM3bwf1ftpsMLjRBqqVyJIQ', appKey: 'waM3bwf1ftpsMLjRBqqVyJIQ',
@ -53,11 +52,12 @@ App({
console.warn("app.js: get user info fail"); console.warn("app.js: get user info fail");
} }
}).then(()=>{ }).then(()=>{
login().then(user=>{ login().then(localuser=>{
user.addUnique("edu_account_real_names", this.client.current_user.real_name); //save for autologin
user.addUnique("edu_account_names", this.client.current_user.name); localuser.addUnique("edu_account_real_names", this.client.current_user.real_name);
user.addUnique("edu_account_logins", this.client.current_user.login); localuser.addUnique("edu_account_names", this.client.current_user.name);
user.save(); localuser.addUnique("edu_account_logins", this.client.current_user.login);
localuser.set("cookies", this.client.session.cookies).save();
}); });
}); });
} }

@ -228,13 +228,21 @@ export class Course{
method:"POST", method:"POST",
data: data, data: data,
success: res=>{ success: res=>{
if("status" in res.data && res.data.status<0){ 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)); fail(new Error(res.data.message));
return; return;
} }
}
if(typeof success == "function"){ if(typeof success == "function"){
success(res); success(res);
} }
}
}, },
fail: fail, fail: fail,
complete: complete complete: complete

@ -11,7 +11,6 @@ import {Cookie} from "./cookie";
export class Session { export class Session {
cookies = {} cookies = {}
constructor(){ constructor(){
} }
set_cookie(cookie){ set_cookie(cookie){
this.cookies[cookie.key] = cookie; this.cookies[cookie.key] = cookie;
@ -23,7 +22,6 @@ export class Session {
request({url, data, header, method, dataType, responseType, success, fail, complete}) { request({url, data, header, method, dataType, responseType, success, fail, complete}) {
console.log("request data and headers: "); console.log("request data and headers: ");
console.log({url: url, data: data, header: {...header, "Cookie": this.cookie_str}, method: method, dataType: dataType, responseType: responseType}) console.log({url: url, data: data, header: {...header, "Cookie": this.cookie_str}, method: method, dataType: dataType, responseType: responseType})
return wx.request({ return wx.request({
url: url, url: url,
data: data, data: data,

@ -2,10 +2,12 @@ module.exports = (subscription, initialStats, onChange) => {
console.log("query_bingding"); console.log("query_bingding");
let stats = [...initialStats] let stats = [...initialStats]
const remove = value => { const remove = value => {
console.log("remove");
stats = stats.filter(target => target.id !== value.id) stats = stats.filter(target => target.id !== value.id)
return onChange(stats) return onChange(stats)
} }
const upsert = value => { const upsert = value => {
console.log("upsert");
let existed = false; let existed = false;
stats = stats.map(target => (target.id === value.id ? ((existed = true), value) : target)) stats = stats.map(target => (target.id === value.id ? ((existed = true), value) : target))
if (!existed) stats = [...stats,value] if (!existed) stats = [...stats,value]

@ -6,7 +6,7 @@ Page({
/** /**
* 页面的初始数据 * 页面的初始数据
*/ */
md: '# 简介\neducoder微信小程序帮助使用[educoder平台](https://www.educoder.net)的应用方便在手机上使用。利用educoder网站的API搭建\n\n## 源码\n[https://github/jinke18/smart_class](https://github.com/jinke18/smart_class)\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- 老师可以创建试卷,发布试卷,查看学员作答分数(developing)\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' md: '# 简介\n## 源码\n[https://github/jinke18/smart_class](https://github.com/jinke18/smart_class)\n\n## 小程序码\n![小程序码](/images/weapp_code_smart_class.jpg)\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'
, ,
data: { data: {

@ -18,7 +18,7 @@ Page({
select_stu_login:"", select_stu_login:"",
message_text: "", message_text: "",
messages: [], messages: [],
show_conversation: true show_conversation: false
}, },
enter_mark_detail({currentTarget:{dataset}}){ enter_mark_detail({currentTarget:{dataset}}){
wx.navigateTo({ wx.navigateTo({
@ -67,6 +67,7 @@ Page({
console.log("close conversation"); console.log("close conversation");
console.log(event); console.log(event);
this.setData({show_conversation: false}); this.setData({show_conversation: false});
console.log(this.data);
this.messageSubscription.unsubscribe(); this.messageSubscription.unsubscribe();
this.messageUnbind(); this.messageUnbind();
}, },
@ -233,8 +234,7 @@ Page({
}) })
}); });
}); });
//this.pull_messages();
this.pull_messages();
}, },
/** /**
@ -271,8 +271,8 @@ Page({
console.log("onUnload"); console.log("onUnload");
this.presenceSubscription.unsubscribe(); this.presenceSubscription.unsubscribe();
this.presenceUnbind(); this.presenceUnbind();
this.messageSubscription.unsubscribe(); //this.messageSubscription.unsubscribe();
this.messageUnbind(); //this.messageUnbind();
}, },
/** /**
@ -303,7 +303,7 @@ Page({
}) })
}); });
}); });
this.pull_messages(); //this.pull_messages();
}, },
/** /**

@ -1,8 +1,8 @@
<movable-area bindtap="select_stu" data-login=""> <movable-area bindtap="select_stu" data-login="">
<view class="classroom"> <view class="classroom">
<movable-view wx:if="{{show_conversation&&!loading}}" direction="all" y="{{240}}"> <movable-view wx:if="{{show_conversation&&!loading}}" direction="all" y="{{240}}">
<scroll-view scroll-y="{{true}}" class="message-list">
<myicon type="close" class="close" bindtap="close_conversation"></myicon> <myicon type="close" class="close" bindtap="close_conversation"></myicon>
<scroll-view wx:if="{{show_conversation}}" scroll-y="{{true}}" class="message-list">
<block wx:for="{{messages}}" wx:for-item="message" wx:key="objectId"> <block wx:for="{{messages}}" wx:for-item="message" wx:key="objectId">
<view class="message flex-wrap"> <view class="message flex-wrap">
<text>{{message.sender_name}}</text><text>{{message.text}}</text> <text>{{message.sender_name}}</text><text>{{message.text}}</text>

@ -31,7 +31,7 @@ Page({
wx.showToast({ wx.showToast({
title: res.data.message title: res.data.message
}) })
wx.navigateTo({ wx.redirectTo({
url: "../course/course?course_id=" + res.data.course_id url: "../course/course?course_id=" + res.data.course_id
}); });
}) })
@ -42,7 +42,6 @@ Page({
}); });
console.warn(error); console.warn(error);
}) })
}, },
/** /**

@ -6,8 +6,8 @@
<text style="font-size:24px;">{{course_name}}\n</text> <text style="font-size:24px;">{{course_name}}\n</text>
</view> </view>
<view style="text-align:center;"> <view style="text-align:center;">
<button type="primary" wx:if="{{current_time<=deadline}}" bindtap="join_course">加入 <button type="primary" disabled="{{current_time>deadline}}" bindtap="join_course">加入
</button> </button>
<view class="error" disabled="{{current_time>deadline}}">该邀请链接已失效</view> <view class="error" wx:if="{{current_time>deadline}}">该邀请链接已失效</view>
</view> </view>
</view> </view>

@ -28,14 +28,6 @@
</block> </block>
</checkbox-group> </checkbox-group>
</view> </view>
<!--view wx:elif="{{question.question_type==2}}">
<radio-group class="choices" bindchange="answer_choice_question" data-question_id="{{question.question_id}}">
<radio class="choice" disabled="{{exercise.user_exercise_status==1 || exercise.user_exercise_status==4}}" wx:for="{{question.question_choices}}" wx:for-item="choice" wx:key="choice_id" checked="{{choice.user_answer_boolean}}" value="{{choice.choice_id}}">
<text class="choice-text">{{choice.choice_text}}</text>
<text wx:if="{{choice.standard_boolean}}" class="error standard-choice">正确答案</text>
</radio>
</radio-group>
</view-->
<view wx:elif="{{question.question_type==3}}"> <view wx:elif="{{question.question_type==3}}">
<block wx:for="{{question.null_inputs}}" wx:for-item="null_input"> <block wx:for="{{question.null_inputs}}" wx:for-item="null_input">
<view class="null-input flex-wrap"> <view class="null-input flex-wrap">

@ -16,7 +16,6 @@ Page({
*/ */
onLoad: function (options) { onLoad: function (options) {
this.exercise_id = options.exercise_id; this.exercise_id = options.exercise_id;
this.exercise_id = 2996;
}, },
/** /**

@ -65,4 +65,4 @@ text.name{
text-align:center; text-align:center;
padding: 12px 0; padding: 12px 0;
} }
/**动画*/

@ -1,4 +1,6 @@
// pages/login/login.js // pages/login/login.js
const AV = require('../../lib/av-live-query-weapp-min');
const {jsonify} = require('../../utils/leancloudutils');
const app = getApp(); const app = getApp();
Page({ Page({
@ -63,6 +65,23 @@ Page({
} }
}) })
}, },
login_test_account({currentTarget:{dataset}}){
console.log(dataset);
const {login, password} = dataset;
this.setData({login,password});
this.login();
},
pull_test: function(){
let query = new AV.Query("MetaData");
query.find().then(metadatas=>{
this.setData({metadata: metadatas[0].toJSON()})
});
let test_query = new AV.Query("TestAccount")
test_query.find()
.then(accounts=>{
this.setData(jsonify({accounts}));
})
},
/** /**
* 生命周期函数--监听页面加载 * 生命周期函数--监听页面加载
*/ */
@ -91,7 +110,7 @@ Page({
* 生命周期函数--监听页面显示 * 生命周期函数--监听页面显示
*/ */
onShow: function () { onShow: function () {
this.pull_test();
}, },
/** /**

@ -26,6 +26,13 @@
</view> </view>
<button class="login-submit" type="primary" bindtap="login" bindlongpress="login_test">登陆</button> <button class="login-submit" type="primary" bindtap="login" bindlongpress="login_test">登陆</button>
</view> </view>
<view style="height:36px;">
<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 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>

Loading…
Cancel
Save