@ -0,0 +1 @@
|
|||||||
|
towxml/
|
@ -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,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;
|
@ -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">
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1 @@
|
|||||||
|
we-cropper/
|
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 79 KiB |
@ -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 */
|
|
@ -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,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 "";
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 947 B |
Before Width: | Height: | Size: 968 B |
Before Width: | Height: | Size: 997 B |
Before Width: | Height: | Size: 416 B After Width: | Height: | Size: 416 B |
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 222 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 |
Before Width: | Height: | Size: 719 B |
Before Width: | Height: | Size: 604 B |
Before Width: | Height: | Size: 53 KiB |
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 @@
|
|||||||
|
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{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
@ -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,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 () {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
})
|
})
|