diff --git a/.gitignore b/.gitignore index 18cb9a3..80be709 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ app.js towxml we-cropper +components/weui-miniprogram .idea api_docs diff --git a/README.md b/README.md index 857454f..169190d 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ educoder微信小程序,帮助使用[educoder平台](https://www.educoder.net) ## 小程序码 ![小程序码](./images/weapp_code.png) - # 功能介绍 ## 教室 @@ -17,6 +16,8 @@ educoder微信小程序,帮助使用[educoder平台](https://www.educoder.net) - 教员在教室界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作 +- 在分数列表中可以看到加减分记录(数据在后台可以导出) + - 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答” - 教室内有讨论区,可以交流 @@ -31,4 +32,33 @@ educoder微信小程序,帮助使用[educoder平台](https://www.educoder.net) - 学员在课程内可以看到老师发布的试卷,并且回答 -- 试卷截止后可以学生可以看到公布的答案 \ No newline at end of file +- 试卷截止后并且老师选择了公开答案,学生可以看到公布的答案 + +- 老师可以创建试卷,发布试卷,查看学员作答分数(developing) + +## 其他 +账号的注册、登陆、找回密码、头像更改等 + +# 实现 +## educoder平台接入 +使用HTTP与平台的api接口交互 + +接口列表如下 +- 搜索课堂https://www.educoder.net/api/courses.json + +- 查询用户的课堂https://www.educoder.net/api/users//courses.json + +- 查询学校https://www.educoder.net/api/schools/school_list.json + +- 新建课堂https://www.educoder.net/api/courses.json + +- 加入课堂https://www.educoder.net/api/courses/apply_to_join_course.json + +- 新建试卷https://www.educoder.net/api/courses//exercises/new.json + +- 查询试卷https://www.educoder.net/api/courses//exercises.json + +- 班级文件资源https://www.educoder.net/api/files.json + +# 教室学员在位情况及分数的同步实现 +使用了[leancloud](https://www.leancloud.cn/)提供的javascript开发包实现数据同步功能, 如学员在位情况、分数的同步, 其底部技术为websocket \ No newline at end of file diff --git a/app.json b/app.json index 9e39ef7..bd1752a 100644 --- a/app.json +++ b/app.json @@ -1,7 +1,9 @@ { "pages": [ - "pages/findmore/findmore", "pages/my_courses/my_courses", + "pages/findmore/findmore", + "pages/exercise_setting/exercise_setting", + "pages/login/login", "pages/course_setting/course_setting", "pages/exercises/exercises", @@ -10,13 +12,14 @@ "pages/setting/setting", "pages/classroom/classroom", "pages/about/about", - "pages/test/test", "pages/course/course", "pages/files/files", "pages/mark_detail/mark_detail", "pages/reset_password/reset_password", - "pages/image_crop/image_crop" + "pages/image_crop/image_crop", + "pages/question_setting/question_setting", + "pages/exercise_grade/exercise_grade" ], "window": { "backgroundTextStyle": "dark", @@ -34,18 +37,19 @@ "iconPath": "images/tabbar-icon/tabbar_study_default.png", "selectedIconPath": "images/tabbar-icon/tabbar_study_pressed.png" }, - { - "pagePath": "pages/findmore/findmore", - "text": "发现", - "iconPath": "images/tabbar-icon/tabbar_findmore_default.png", - "selectedIconPath": "images/tabbar-icon/tabbar_findmore_pressed.png" - }, + { "pagePath": "pages/courses/courses", "text": "课程列表", "iconPath": "images/tabbar-icon/tabbar_contact_default.png", "selectedIconPath": "images/tabbar-icon/tabbar_contact_pressed.png" }, + { + "pagePath": "pages/findmore/findmore", + "text": "发现", + "iconPath": "images/tabbar-icon/tabbar_findmore_default.png", + "selectedIconPath": "images/tabbar-icon/tabbar_findmore_pressed.png" + }, { "pagePath": "pages/setting/setting", "iconPath": "images/tabbar-icon/tabbar_settings_default.png", diff --git a/app.wxss b/app.wxss index bfd62ec..a2a6713 100644 --- a/app.wxss +++ b/app.wxss @@ -1,3 +1,5 @@ +@import './components/weui-miniprogram/weui-wxss/dist/style/weui.wxss'; + page { height: 100%; background-color: #f2f2f2; diff --git a/data/client.js b/data/client.js index fd98295..7627593 100644 --- a/data/client.js +++ b/data/client.js @@ -4,7 +4,7 @@ * @author jinke18 */ -import {Account, Course, Exercise, ExerciseQuestion, School, Ui} from "./eduapi" +import {Account, Course, Exercise, Question, School, Ui} from "./eduapi" import {Session} from "./requests"; import {Cookie} from "./cookie"; @@ -451,9 +451,9 @@ export class Client{ }) }); } - answer_exercise_question({question_id, exercise_choice_id,answer_text ,success, fail, complete}){ + answer_question({question_id, exercise_choice_id,answer_text ,success, fail, complete}){ return new Promise((resolve, reject) =>{ - ExerciseQuestion.answer({ + Question.answer({ session: this.session, question_id: question_id, answer_text: answer_text, @@ -474,6 +474,163 @@ export class Client{ }) } ); } + 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); + } + }) + }) + } + 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({ @@ -517,24 +674,24 @@ export class Client{ }) }); } - 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); - } + 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) => { diff --git a/data/eduapi.js b/data/eduapi.js index c773c27..477b199 100644 --- a/data/eduapi.js +++ b/data/eduapi.js @@ -200,7 +200,7 @@ export class Course{ complete: complete }) } - static setting({session, course_id, data, success, fail, complete}){ + static update({session, course_id, data, success, fail, complete}){ return session.request({ }) @@ -349,6 +349,103 @@ export class Exercise{ 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 + }) + } + 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", @@ -358,6 +455,32 @@ export class Exercise{ 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({ @@ -371,7 +494,58 @@ export class Exercise{ } } -export class ExerciseQuestion { +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;} diff --git a/images/avatar_blue.png b/images/avatar_blue.png deleted file mode 100644 index 05d6370..0000000 Binary files a/images/avatar_blue.png and /dev/null differ diff --git a/images/loading.svg b/images/loading.svg deleted file mode 100644 index e96fb5d..0000000 --- a/images/loading.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/weapp_code_smart_class.jpg b/images/weapp_code_smart_class.jpg new file mode 100644 index 0000000..e759663 Binary files /dev/null and b/images/weapp_code_smart_class.jpg differ diff --git a/lib/co.js b/lib/co.js deleted file mode 100644 index 87ba8ba..0000000 --- a/lib/co.js +++ /dev/null @@ -1,237 +0,0 @@ - -/** - * slice() reference. - */ - -var slice = Array.prototype.slice; - -/** - * Expose `co`. - */ - -module.exports = co['default'] = co.co = co; - -/** - * Wrap the given generator `fn` into a - * function that returns a promise. - * This is a separate function so that - * every `co()` call doesn't create a new, - * unnecessary closure. - * - * @param {GeneratorFunction} fn - * @return {Function} - * @api public - */ - -co.wrap = function (fn) { - createPromise.__generatorFunction__ = fn; - return createPromise; - function createPromise() { - return co.call(this, fn.apply(this, arguments)); - } -}; - -/** - * Execute the generator function or a generator - * and return a promise. - * - * @param {Function} fn - * @return {Promise} - * @api public - */ - -function co(gen) { - var ctx = this; - var args = slice.call(arguments, 1) - - // we wrap everything in a promise to avoid promise chaining, - // which leads to memory leak errors. - // see https://github.com/tj/co/issues/180 - return new Promise(function(resolve, reject) { - if (typeof gen === 'function') gen = gen.apply(ctx, args); - if (!gen || typeof gen.next !== 'function') return resolve(gen); - - onFulfilled(); - - /** - * @param {Mixed} res - * @return {Promise} - * @api private - */ - - function onFulfilled(res) { - var ret; - try { - ret = gen.next(res); - } catch (e) { - return reject(e); - } - next(ret); - } - - /** - * @param {Error} err - * @return {Promise} - * @api private - */ - - function onRejected(err) { - var ret; - try { - ret = gen.throw(err); - } catch (e) { - return reject(e); - } - next(ret); - } - - /** - * Get the next value in the generator, - * return a promise. - * - * @param {Object} ret - * @return {Promise} - * @api private - */ - - function next(ret) { - if (ret.done) return resolve(ret.value); - var value = toPromise.call(ctx, ret.value); - if (value && isPromise(value)) return value.then(onFulfilled, onRejected); - return onRejected(new TypeError('You may only yield a function, promise, generator, array, or object, ' - + 'but the following object was passed: "' + String(ret.value) + '"')); - } - }); -} - -/** - * Convert a `yield`ed value into a promise. - * - * @param {Mixed} obj - * @return {Promise} - * @api private - */ - -function toPromise(obj) { - if (!obj) return obj; - if (isPromise(obj)) return obj; - if (isGeneratorFunction(obj) || isGenerator(obj)) return co.call(this, obj); - if ('function' == typeof obj) return thunkToPromise.call(this, obj); - if (Array.isArray(obj)) return arrayToPromise.call(this, obj); - if (isObject(obj)) return objectToPromise.call(this, obj); - return obj; -} - -/** - * Convert a thunk to a promise. - * - * @param {Function} - * @return {Promise} - * @api private - */ - -function thunkToPromise(fn) { - var ctx = this; - return new Promise(function (resolve, reject) { - fn.call(ctx, function (err, res) { - if (err) return reject(err); - if (arguments.length > 2) res = slice.call(arguments, 1); - resolve(res); - }); - }); -} - -/** - * Convert an array of "yieldables" to a promise. - * Uses `Promise.all()` internally. - * - * @param {Array} obj - * @return {Promise} - * @api private - */ - -function arrayToPromise(obj) { - return Promise.all(obj.map(toPromise, this)); -} - -/** - * Convert an object of "yieldables" to a promise. - * Uses `Promise.all()` internally. - * - * @param {Object} obj - * @return {Promise} - * @api private - */ - -function objectToPromise(obj){ - var results = new obj.constructor(); - var keys = Object.keys(obj); - var promises = []; - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - var promise = toPromise.call(this, obj[key]); - if (promise && isPromise(promise)) defer(promise, key); - else results[key] = obj[key]; - } - return Promise.all(promises).then(function () { - return results; - }); - - function defer(promise, key) { - // predefine the key in the result - results[key] = undefined; - promises.push(promise.then(function (res) { - results[key] = res; - })); - } -} - -/** - * Check if `obj` is a promise. - * - * @param {Object} obj - * @return {Boolean} - * @api private - */ - -function isPromise(obj) { - return 'function' == typeof obj.then; -} - -/** - * Check if `obj` is a generator. - * - * @param {Mixed} obj - * @return {Boolean} - * @api private - */ - -function isGenerator(obj) { - return 'function' == typeof obj.next && 'function' == typeof obj.throw; -} - -/** - * Check if `obj` is a generator function. - * - * @param {Mixed} obj - * @return {Boolean} - * @api private - */ -function isGeneratorFunction(obj) { - var constructor = obj.constructor; - if (!constructor) return false; - if ('GeneratorFunction' === constructor.name || 'GeneratorFunction' === constructor.displayName) return true; - return isGenerator(constructor.prototype); -} - -/** - * Check for plain object. - * - * @param {Mixed} val - * @return {Boolean} - * @api private - */ - -function isObject(val) { - return Object == val.constructor; -} diff --git a/lib/emitter.js b/lib/emitter.js deleted file mode 100644 index 9beed1b..0000000 --- a/lib/emitter.js +++ /dev/null @@ -1,20 +0,0 @@ - -module.exports = { - setup(target) { - let listeners = []; - - Object.assign(target, { - on(type, handle) { - if (typeof handle == 'function') { - listeners.push([type, handle]); - } - }, - emit(type, ...params) { - listeners.forEach(([listenType, handle]) => type == listenType && handle(...params)); - }, - removeAllListeners() { - listeners = []; - } - }); - } -} \ No newline at end of file diff --git a/lib/lab.js b/lib/lab.js deleted file mode 100644 index 2746212..0000000 --- a/lib/lab.js +++ /dev/null @@ -1,19 +0,0 @@ -function getFinishLabs() { - const sto = wx.getStorageSync('finishLabs'); - if (sto) { - return JSON.parse(sto); - } - return {}; -} - -function finish(id) { - const current = getFinishLabs(); - current[id] = 1; - wx.setStorageSync('finishLabs', JSON.stringify(current)); -} - -function clear() { - wx.setStorageSync('finishLabs', ''); -} - -module.exports = { getFinishLabs, finish, clear }; \ No newline at end of file diff --git a/lib/promisify.js b/lib/promisify.js deleted file mode 100644 index cc269d4..0000000 --- a/lib/promisify.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (api) => - (options, ...params) => new Promise( - (resolve, reject) => api(Object.assign({}, options, { success: resolve, fail: reject }), ...params) - ); \ No newline at end of file diff --git a/lib/regenerator-runtime.js b/lib/regenerator-runtime.js deleted file mode 100644 index eedd8cd..0000000 --- a/lib/regenerator-runtime.js +++ /dev/null @@ -1,713 +0,0 @@ -!(function(global) { - "use strict"; - - var Op = Object.prototype; - var hasOwn = Op.hasOwnProperty; - var undefined; // More compressible than void 0. - var $Symbol = typeof Symbol === "function" ? Symbol : {}; - var iteratorSymbol = $Symbol.iterator || "@@iterator"; - var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag"; - - var inModule = typeof module === "object"; - var runtime = global.regeneratorRuntime; - if (runtime) { - if (inModule) { - // If regeneratorRuntime is defined globally and we're in a module, - // make the exports object identical to regeneratorRuntime. - module.exports = runtime; - } - // Don't bother evaluating the rest of this file if the runtime was - // already defined globally. - return; - } - - // Define the runtime globally (as expected by generated code) as either - // module.exports (if we're in a module) or a new, empty object. - runtime = global.regeneratorRuntime = inModule ? module.exports : {}; - - function wrap(innerFn, outerFn, self, tryLocsList) { - // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator. - var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator; - var generator = Object.create(protoGenerator.prototype); - var context = new Context(tryLocsList || []); - - // The ._invoke method unifies the implementations of the .next, - // .throw, and .return methods. - generator._invoke = makeInvokeMethod(innerFn, self, context); - - return generator; - } - runtime.wrap = wrap; - - // Try/catch helper to minimize deoptimizations. Returns a completion - // record like context.tryEntries[i].completion. This interface could - // have been (and was previously) designed to take a closure to be - // invoked without arguments, but in all the cases we care about we - // already have an existing method we want to call, so there's no need - // to create a new function object. We can even get away with assuming - // the method takes exactly one argument, since that happens to be true - // in every case, so we don't have to touch the arguments object. The - // only additional allocation required is the completion record, which - // has a stable shape and so hopefully should be cheap to allocate. - function tryCatch(fn, obj, arg) { - try { - return { type: "normal", arg: fn.call(obj, arg) }; - } catch (err) { - return { type: "throw", arg: err }; - } - } - - var GenStateSuspendedStart = "suspendedStart"; - var GenStateSuspendedYield = "suspendedYield"; - var GenStateExecuting = "executing"; - var GenStateCompleted = "completed"; - - // Returning this object from the innerFn has the same effect as - // breaking out of the dispatch switch statement. - var ContinueSentinel = {}; - - // Dummy constructor functions that we use as the .constructor and - // .constructor.prototype properties for functions that return Generator - // objects. For full spec compliance, you may wish to configure your - // minifier not to mangle the names of these two functions. - function Generator() {} - function GeneratorFunction() {} - function GeneratorFunctionPrototype() {} - - // This is a polyfill for %IteratorPrototype% for environments that - // don't natively support it. - var IteratorPrototype = {}; - IteratorPrototype[iteratorSymbol] = function () { - return this; - }; - - var getProto = Object.getPrototypeOf; - var NativeIteratorPrototype = getProto && getProto(getProto(values([]))); - if (NativeIteratorPrototype && - NativeIteratorPrototype !== Op && - hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) { - // This environment has a native %IteratorPrototype%; use it instead - // of the polyfill. - IteratorPrototype = NativeIteratorPrototype; - } - - var Gp = GeneratorFunctionPrototype.prototype = - Generator.prototype = Object.create(IteratorPrototype); - GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype; - GeneratorFunctionPrototype.constructor = GeneratorFunction; - GeneratorFunctionPrototype[toStringTagSymbol] = - GeneratorFunction.displayName = "GeneratorFunction"; - - // Helper for defining the .next, .throw, and .return methods of the - // Iterator interface in terms of a single ._invoke method. - function defineIteratorMethods(prototype) { - ["next", "throw", "return"].forEach(function(method) { - prototype[method] = function(arg) { - return this._invoke(method, arg); - }; - }); - } - - runtime.isGeneratorFunction = function(genFun) { - var ctor = typeof genFun === "function" && genFun.constructor; - return ctor - ? ctor === GeneratorFunction || - // For the native GeneratorFunction constructor, the best we can - // do is to check its .name property. - (ctor.displayName || ctor.name) === "GeneratorFunction" - : false; - }; - - runtime.mark = function(genFun) { - if (Object.setPrototypeOf) { - Object.setPrototypeOf(genFun, GeneratorFunctionPrototype); - } else { - genFun.__proto__ = GeneratorFunctionPrototype; - if (!(toStringTagSymbol in genFun)) { - genFun[toStringTagSymbol] = "GeneratorFunction"; - } - } - genFun.prototype = Object.create(Gp); - return genFun; - }; - - // Within the body of any async function, `await x` is transformed to - // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test - // `hasOwn.call(value, "__await")` to determine if the yielded value is - // meant to be awaited. - runtime.awrap = function(arg) { - return { __await: arg }; - }; - - function AsyncIterator(generator) { - function invoke(method, arg, resolve, reject) { - var record = tryCatch(generator[method], generator, arg); - if (record.type === "throw") { - reject(record.arg); - } else { - var result = record.arg; - var value = result.value; - if (value && - typeof value === "object" && - hasOwn.call(value, "__await")) { - return Promise.resolve(value.__await).then(function(value) { - invoke("next", value, resolve, reject); - }, function(err) { - invoke("throw", err, resolve, reject); - }); - } - - return Promise.resolve(value).then(function(unwrapped) { - // When a yielded Promise is resolved, its final value becomes - // the .value of the Promise<{value,done}> result for the - // current iteration. If the Promise is rejected, however, the - // result for this iteration will be rejected with the same - // reason. Note that rejections of yielded Promises are not - // thrown back into the generator function, as is the case - // when an awaited Promise is rejected. This difference in - // behavior between yield and await is important, because it - // allows the consumer to decide what to do with the yielded - // rejection (swallow it and continue, manually .throw it back - // into the generator, abandon iteration, whatever). With - // await, by contrast, there is no opportunity to examine the - // rejection reason outside the generator function, so the - // only option is to throw it from the await expression, and - // let the generator function handle the exception. - result.value = unwrapped; - resolve(result); - }, reject); - } - } - - if (typeof process === "object" && process.domain) { - invoke = process.domain.bind(invoke); - } - - var previousPromise; - - function enqueue(method, arg) { - function callInvokeWithMethodAndArg() { - return new Promise(function(resolve, reject) { - invoke(method, arg, resolve, reject); - }); - } - - return previousPromise = - // If enqueue has been called before, then we want to wait until - // all previous Promises have been resolved before calling invoke, - // so that results are always delivered in the correct order. If - // enqueue has not been called before, then it is important to - // call invoke immediately, without waiting on a callback to fire, - // so that the async generator function has the opportunity to do - // any necessary setup in a predictable way. This predictability - // is why the Promise constructor synchronously invokes its - // executor callback, and why async functions synchronously - // execute code before the first await. Since we implement simple - // async functions in terms of async generators, it is especially - // important to get this right, even though it requires care. - previousPromise ? previousPromise.then( - callInvokeWithMethodAndArg, - // Avoid propagating failures to Promises returned by later - // invocations of the iterator. - callInvokeWithMethodAndArg - ) : callInvokeWithMethodAndArg(); - } - - // Define the unified helper method that is used to implement .next, - // .throw, and .return (see defineIteratorMethods). - this._invoke = enqueue; - } - - defineIteratorMethods(AsyncIterator.prototype); - runtime.AsyncIterator = AsyncIterator; - - // Note that simple async functions are implemented on top of - // AsyncIterator objects; they just return a Promise for the value of - // the final result produced by the iterator. - runtime.async = function(innerFn, outerFn, self, tryLocsList) { - var iter = new AsyncIterator( - wrap(innerFn, outerFn, self, tryLocsList) - ); - - return runtime.isGeneratorFunction(outerFn) - ? iter // If outerFn is a generator, return the full iterator. - : iter.next().then(function(result) { - return result.done ? result.value : iter.next(); - }); - }; - - function makeInvokeMethod(innerFn, self, context) { - var state = GenStateSuspendedStart; - - return function invoke(method, arg) { - if (state === GenStateExecuting) { - throw new Error("Generator is already running"); - } - - if (state === GenStateCompleted) { - if (method === "throw") { - throw arg; - } - - // Be forgiving, per 25.3.3.3.3 of the spec: - // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume - return doneResult(); - } - - context.method = method; - context.arg = arg; - - while (true) { - var delegate = context.delegate; - if (delegate) { - var delegateResult = maybeInvokeDelegate(delegate, context); - if (delegateResult) { - if (delegateResult === ContinueSentinel) continue; - return delegateResult; - } - } - - if (context.method === "next") { - // Setting context._sent for legacy support of Babel's - // function.sent implementation. - context.sent = context._sent = context.arg; - - } else if (context.method === "throw") { - if (state === GenStateSuspendedStart) { - state = GenStateCompleted; - throw context.arg; - } - - context.dispatchException(context.arg); - - } else if (context.method === "return") { - context.abrupt("return", context.arg); - } - - state = GenStateExecuting; - - var record = tryCatch(innerFn, self, context); - if (record.type === "normal") { - // If an exception is thrown from innerFn, we leave state === - // GenStateExecuting and loop back for another invocation. - state = context.done - ? GenStateCompleted - : GenStateSuspendedYield; - - if (record.arg === ContinueSentinel) { - continue; - } - - return { - value: record.arg, - done: context.done - }; - - } else if (record.type === "throw") { - state = GenStateCompleted; - // Dispatch the exception by looping back around to the - // context.dispatchException(context.arg) call above. - context.method = "throw"; - context.arg = record.arg; - } - } - }; - } - - // Call delegate.iterator[context.method](context.arg) and handle the - // result, either by returning a { value, done } result from the - // delegate iterator, or by modifying context.method and context.arg, - // setting context.delegate to null, and returning the ContinueSentinel. - function maybeInvokeDelegate(delegate, context) { - var method = delegate.iterator[context.method]; - if (method === undefined) { - // A .throw or .return when the delegate iterator has no .throw - // method always terminates the yield* loop. - context.delegate = null; - - if (context.method === "throw") { - if (delegate.iterator.return) { - // If the delegate iterator has a return method, give it a - // chance to clean up. - context.method = "return"; - context.arg = undefined; - maybeInvokeDelegate(delegate, context); - - if (context.method === "throw") { - // If maybeInvokeDelegate(context) changed context.method from - // "return" to "throw", let that override the TypeError below. - return ContinueSentinel; - } - } - - context.method = "throw"; - context.arg = new TypeError( - "The iterator does not provide a 'throw' method"); - } - - return ContinueSentinel; - } - - var record = tryCatch(method, delegate.iterator, context.arg); - - if (record.type === "throw") { - context.method = "throw"; - context.arg = record.arg; - context.delegate = null; - return ContinueSentinel; - } - - var info = record.arg; - - if (! info) { - context.method = "throw"; - context.arg = new TypeError("iterator result is not an object"); - context.delegate = null; - return ContinueSentinel; - } - - if (info.done) { - // Assign the result of the finished delegate to the temporary - // variable specified by delegate.resultName (see delegateYield). - context[delegate.resultName] = info.value; - - // Resume execution at the desired location (see delegateYield). - context.next = delegate.nextLoc; - - // If context.method was "throw" but the delegate handled the - // exception, let the outer generator proceed normally. If - // context.method was "next", forget context.arg since it has been - // "consumed" by the delegate iterator. If context.method was - // "return", allow the original .return call to continue in the - // outer generator. - if (context.method !== "return") { - context.method = "next"; - context.arg = undefined; - } - - } else { - // Re-yield the result returned by the delegate method. - return info; - } - - // The delegate iterator is finished, so forget it and continue with - // the outer generator. - context.delegate = null; - return ContinueSentinel; - } - - // Define Generator.prototype.{next,throw,return} in terms of the - // unified ._invoke helper method. - defineIteratorMethods(Gp); - - Gp[toStringTagSymbol] = "Generator"; - - Gp.toString = function() { - return "[object Generator]"; - }; - - function pushTryEntry(locs) { - var entry = { tryLoc: locs[0] }; - - if (1 in locs) { - entry.catchLoc = locs[1]; - } - - if (2 in locs) { - entry.finallyLoc = locs[2]; - entry.afterLoc = locs[3]; - } - - this.tryEntries.push(entry); - } - - function resetTryEntry(entry) { - var record = entry.completion || {}; - record.type = "normal"; - delete record.arg; - entry.completion = record; - } - - function Context(tryLocsList) { - // The root entry object (effectively a try statement without a catch - // or a finally block) gives us a place to store values thrown from - // locations where there is no enclosing try statement. - this.tryEntries = [{ tryLoc: "root" }]; - tryLocsList.forEach(pushTryEntry, this); - this.reset(true); - } - - runtime.keys = function(object) { - var keys = []; - for (var key in object) { - keys.push(key); - } - keys.reverse(); - - // Rather than returning an object with a next method, we keep - // things simple and return the next function itself. - return function next() { - while (keys.length) { - var key = keys.pop(); - if (key in object) { - next.value = key; - next.done = false; - return next; - } - } - - // To avoid creating an additional object, we just hang the .value - // and .done properties off the next function object itself. This - // also ensures that the minifier will not anonymize the function. - next.done = true; - return next; - }; - }; - - function values(iterable) { - if (iterable) { - var iteratorMethod = iterable[iteratorSymbol]; - if (iteratorMethod) { - return iteratorMethod.call(iterable); - } - - if (typeof iterable.next === "function") { - return iterable; - } - - if (!isNaN(iterable.length)) { - var i = -1, next = function next() { - while (++i < iterable.length) { - if (hasOwn.call(iterable, i)) { - next.value = iterable[i]; - next.done = false; - return next; - } - } - - next.value = undefined; - next.done = true; - - return next; - }; - - return next.next = next; - } - } - - // Return an iterator with no values. - return { next: doneResult }; - } - runtime.values = values; - - function doneResult() { - return { value: undefined, done: true }; - } - - Context.prototype = { - constructor: Context, - - reset: function(skipTempReset) { - this.prev = 0; - this.next = 0; - // Resetting context._sent for legacy support of Babel's - // function.sent implementation. - this.sent = this._sent = undefined; - this.done = false; - this.delegate = null; - - this.method = "next"; - this.arg = undefined; - - this.tryEntries.forEach(resetTryEntry); - - if (!skipTempReset) { - for (var name in this) { - // Not sure about the optimal order of these conditions: - if (name.charAt(0) === "t" && - hasOwn.call(this, name) && - !isNaN(+name.slice(1))) { - this[name] = undefined; - } - } - } - }, - - stop: function() { - this.done = true; - - var rootEntry = this.tryEntries[0]; - var rootRecord = rootEntry.completion; - if (rootRecord.type === "throw") { - throw rootRecord.arg; - } - - return this.rval; - }, - - dispatchException: function(exception) { - if (this.done) { - throw exception; - } - - var context = this; - function handle(loc, caught) { - record.type = "throw"; - record.arg = exception; - context.next = loc; - - if (caught) { - // If the dispatched exception was caught by a catch block, - // then let that catch block handle the exception normally. - context.method = "next"; - context.arg = undefined; - } - - return !! caught; - } - - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - var record = entry.completion; - - if (entry.tryLoc === "root") { - // Exception thrown outside of any try block that could handle - // it, so set the completion value of the entire function to - // throw the exception. - return handle("end"); - } - - if (entry.tryLoc <= this.prev) { - var hasCatch = hasOwn.call(entry, "catchLoc"); - var hasFinally = hasOwn.call(entry, "finallyLoc"); - - if (hasCatch && hasFinally) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } else if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } - - } else if (hasCatch) { - if (this.prev < entry.catchLoc) { - return handle(entry.catchLoc, true); - } - - } else if (hasFinally) { - if (this.prev < entry.finallyLoc) { - return handle(entry.finallyLoc); - } - - } else { - throw new Error("try statement without catch or finally"); - } - } - } - }, - - abrupt: function(type, arg) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc <= this.prev && - hasOwn.call(entry, "finallyLoc") && - this.prev < entry.finallyLoc) { - var finallyEntry = entry; - break; - } - } - - if (finallyEntry && - (type === "break" || - type === "continue") && - finallyEntry.tryLoc <= arg && - arg <= finallyEntry.finallyLoc) { - // Ignore the finally entry if control is not jumping to a - // location outside the try/catch block. - finallyEntry = null; - } - - var record = finallyEntry ? finallyEntry.completion : {}; - record.type = type; - record.arg = arg; - - if (finallyEntry) { - this.method = "next"; - this.next = finallyEntry.finallyLoc; - return ContinueSentinel; - } - - return this.complete(record); - }, - - complete: function(record, afterLoc) { - if (record.type === "throw") { - throw record.arg; - } - - if (record.type === "break" || - record.type === "continue") { - this.next = record.arg; - } else if (record.type === "return") { - this.rval = this.arg = record.arg; - this.method = "return"; - this.next = "end"; - } else if (record.type === "normal" && afterLoc) { - this.next = afterLoc; - } - - return ContinueSentinel; - }, - - finish: function(finallyLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.finallyLoc === finallyLoc) { - this.complete(entry.completion, entry.afterLoc); - resetTryEntry(entry); - return ContinueSentinel; - } - } - }, - - "catch": function(tryLoc) { - for (var i = this.tryEntries.length - 1; i >= 0; --i) { - var entry = this.tryEntries[i]; - if (entry.tryLoc === tryLoc) { - var record = entry.completion; - if (record.type === "throw") { - var thrown = record.arg; - resetTryEntry(entry); - } - return thrown; - } - } - - // The context.catch method must only be called with a location - // argument that corresponds to a known catch block. - throw new Error("illegal catch attempt"); - }, - - delegateYield: function(iterable, resultName, nextLoc) { - this.delegate = { - iterator: values(iterable), - resultName: resultName, - nextLoc: nextLoc - }; - - if (this.method === "next") { - // Deliberately forget the last sent value so that we don't - // accidentally pass it on to the delegate. - this.arg = undefined; - } - - return ContinueSentinel; - } - }; -})( - // Among the various tricks for obtaining a reference to the global - // object, this seems to be the most reliable technique that does not - // use indirect eval (which violates Content Security Policy). - typeof global === "object" ? global : - typeof window === "object" ? window : - typeof self === "object" ? self : this -); \ No newline at end of file diff --git a/lib/tunnel.js b/lib/tunnel.js deleted file mode 100644 index c86804e..0000000 --- a/lib/tunnel.js +++ /dev/null @@ -1,44 +0,0 @@ - -const Emitter = require('./emitter'); - -/** - * 基于小程序 WebSocket 接口封装信道 - */ -module.exports = class Tunnel { - constructor() { - Emitter.setup(this.emitter = {}); - } - - connect(url, header) { - - // 小程序 wx.connectSocket() API header 参数无效,把会话信息附加在 URL 上 - const query = Object.keys(header).map(key => `${key}=${encodeURIComponent(header[key])}`).join('&'); - const seperator = url.indexOf('?') > -1 ? '&' : '?'; - url = [url, query].join(seperator); - - return new Promise((resolve, reject) => { - wx.onSocketOpen(resolve); - wx.onSocketError(reject); - wx.onSocketMessage(packet => { - try { - const { message, data } = JSON.parse(packet.data); - this.emitter.emit(message, data); - } catch (e) { - console.log('Handle packet failed: ' + packet.data, e); - } - }); - wx.onSocketClose(() => this.emitter.emit('close')); - wx.connectSocket({ url, header }); - }); - } - - on(message, handle) { - this.emitter.on(message, handle); - } - - emit(message, data) { - wx.sendSocketMessage({ - data: JSON.stringify({ message, data }) - }); - } -} \ No newline at end of file diff --git a/model/file.js b/model/file.js deleted file mode 100644 index 74a080a..0000000 --- a/model/file.js +++ /dev/null @@ -1,37 +0,0 @@ -const AV = require("../lib/av-live-query-weapp-min") - -class File extends AV.Object{ - get url(){ - return this.get("url"); - } - set url(value){ - this.set("url", value); - } - get fileid(){ - return this.get("fileid"); - } - set fileid(value){ - this.set("fileid", value); - } - get class(){ - return this.get("class"); - } - set class(value){ - this.set("class", value); - } - get filename(){ - return this.get("filename"); - } - set filename(value){ - this.set("filename", value); - } - get uploader(){ - return this.get("uploader"); - } - set uploader(value){ - this.set("uploader", value); - } -} - -AV.Object.register(File, "File_"); -module.exports = File; \ No newline at end of file diff --git a/model/studentclassmap.js b/model/studentclassmap.js deleted file mode 100644 index 79dbbb3..0000000 --- a/model/studentclassmap.js +++ /dev/null @@ -1,29 +0,0 @@ -const AV = require("../..//lib/av-live-query-weapp-min") - - -class StudentClassMap extends AV.Object{ - get class(){ - return this.get("class"); - } - set class(value){ - this.set("class", value); - } - get user(){ - return this.get("user"); - } - set user(value){ - this.set("user", value); - } - get mark() { - return this.get('done'); - } - set mark(value) { - this.set('mark', value); - } - add_mark(value) { - this.increment(value); - } -} - -AV.Object.register(StudentClassMap, "StudentClassMap"); -module.exports=StudentClassMap; \ No newline at end of file diff --git a/pages/classroom/classroom.js b/pages/classroom/classroom.js index bdc5146..75ec089 100644 --- a/pages/classroom/classroom.js +++ b/pages/classroom/classroom.js @@ -83,6 +83,7 @@ Page({ let login = event.currentTarget.dataset.login; let status = event.currentTarget.dataset.status; console.log("set_isasking"); + console.log(this.presences); let asking_presence = this.presences.filter(presence=>presence.get("edu_account_login")==login)[0]; console.log(asking_presence); asking_presence.isasking = status; @@ -169,6 +170,10 @@ Page({ } } console.log(students); + let stus = students.filter(student => student.login == app.client.current_user.login); + if(stus.length==1){ + this.setData({current_user: stus[0]}); + } this.setData({students: students}); return presences; }, diff --git a/pages/classroom/classroom.wxml b/pages/classroom/classroom.wxml index b669731..8099b25 100644 --- a/pages/classroom/classroom.wxml +++ b/pages/classroom/classroom.wxml @@ -45,10 +45,10 @@ diff --git a/pages/course/course.wxml b/pages/course/course.wxml index 41e6457..6f8e4e7 100644 --- a/pages/course/course.wxml +++ b/pages/course/course.wxml @@ -1,7 +1,14 @@ - - 进入教室 - 试卷 - 资源 + + + + + + + + + 进入教室 + 试卷 + 资源 \ No newline at end of file diff --git a/pages/courses/courses.js b/pages/courses/courses.js index ac68fed..c64d45f 100644 --- a/pages/courses/courses.js +++ b/pages/courses/courses.js @@ -2,7 +2,7 @@ const app = getApp(); Page({ - + options: {}, data: { courses: [], loading: true, @@ -10,6 +10,18 @@ Page({ show_join_course_modal:false, loaded_all: false, }, + search_courses: function({detail: {value}}){ + this.setData({ loaded_all: false }); + this.options.search = value; + this.fetch_courses(this.options).then(res => { + console.log(res); + this.set_courses(res.data.courses); + if (res.data.courses.length<=10) { + this.setData({ loaded_all: true }) + } + }) + + }, show_join_course_modal: function(event){ this.setData({show_join_course_modal: true}); }, @@ -100,14 +112,14 @@ Page({ wx.pageScrollTo({ selector: ".loading" }) - this.fetch_courses({ page: this.data.page + 1 }) + this.fetch_courses({ page: this.data.page + 1 ,...this.options}) .then(res => { this.setData({ page: this.data.page + 1}); if(res.data.courses.length==0){ this.setData({loaded_all: true}) }else{ this.add_courses(res.data.courses); - } + } }) } }, diff --git a/pages/courses/courses.json b/pages/courses/courses.json index feb3267..0cf83b4 100644 --- a/pages/courses/courses.json +++ b/pages/courses/courses.json @@ -1,5 +1,7 @@ { "usingComponents": { - "myicon": "/components/icon/myicon" + "myicon": "/components/icon/myicon", + "mp-searchbar": "/components/weui-miniprogram/searchbar/searchbar" } + } \ No newline at end of file diff --git a/pages/courses/courses.wxml b/pages/courses/courses.wxml index 9c80940..88076b2 100644 --- a/pages/courses/courses.wxml +++ b/pages/courses/courses.wxml @@ -1,6 +1,9 @@ - + + + + 没有可以加入的课程了 diff --git a/pages/exercise/exercise.js b/pages/exercise/exercise.js index f77120f..bd5b281 100644 --- a/pages/exercise/exercise.js +++ b/pages/exercise/exercise.js @@ -54,7 +54,7 @@ Page({ console.log("answer_main_question"); console.log(value); console.log(dataset); - app.client.answer_exercise_question({ question_id: dataset.question_id, exercise_choice_id:dataset.exercise_choice_id, answer_text: value }) + app.client.answer_question({ 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); }) .catch(error => { console.error(error); @@ -68,7 +68,7 @@ Page({ console.log("answer_main_question"); console.log(value); console.log(dataset); - app.client.answer_exercise_question({ question_id: dataset.question_id, answer_text: value }) + app.client.answer_question({ question_id: dataset.question_id, answer_text: value }) .then(res => { console.log("answer_main_question"); console.log(res); }) .catch(error => { console.error(error); @@ -82,7 +82,7 @@ Page({ console.log("answer_question"); console.log(value); console.log(dataset); - app.client.answer_exercise_question({ question_id: dataset.question_id, exercise_choice_id: value}) + app.client.answer_question({ question_id: dataset.question_id, exercise_choice_id: value}) .then(res=>{console.log("answer_question");console.log(res);}) .catch(error=>{ console.error(error); diff --git a/pages/exercise/exercise.wxml b/pages/exercise/exercise.wxml index 8236352..c999457 100644 --- a/pages/exercise/exercise.wxml +++ b/pages/exercise/exercise.wxml @@ -7,8 +7,10 @@ - {{choice.choice_text}} - 正确答案 + + {{choice.choice_text}} + 正确答案 + @@ -16,8 +18,10 @@ - {{choice.choice_text}} - 正确答案 + + {{choice.choice_text}} + 正确答案 + diff --git a/pages/exercise/exercise.wxss b/pages/exercise/exercise.wxss index adbb573..10fd0fb 100644 --- a/pages/exercise/exercise.wxss +++ b/pages/exercise/exercise.wxss @@ -36,11 +36,11 @@ display: flex; flex-direction: column; } -.choice{ +checkbox.choice{ margin-bottom: 12rpx; } -.choice-text{ - display: inline-block; + +view.choice{ width: 600rpx; } diff --git a/pages/exercise_grade/exercise_grade.js b/pages/exercise_grade/exercise_grade.js new file mode 100644 index 0000000..9d80d43 --- /dev/null +++ b/pages/exercise_grade/exercise_grade.js @@ -0,0 +1,72 @@ +// pages/exercise_grade/exercise_grade.js +const app = getApp(); +Page({ + + /** + * 页面的初始数据 + */ + data: { + grades:[] + }, + + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.exercise_id = options.exercise_id; + app.client.get_exercise_grade({exercise_id: this.exercise_id}) + .then(res=>{ + console.log(res); + this.setData({ grades: res.data.exercise_users}) + }) + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function () { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function () { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function () { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function () { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function () { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function () { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function () { + + } +}) \ No newline at end of file diff --git a/pages/exercise_grade/exercise_grade.json b/pages/exercise_grade/exercise_grade.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/pages/exercise_grade/exercise_grade.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/exercise_grade/exercise_grade.wxml b/pages/exercise_grade/exercise_grade.wxml new file mode 100644 index 0000000..bf66ac0 --- /dev/null +++ b/pages/exercise_grade/exercise_grade.wxml @@ -0,0 +1,14 @@ + + + + + {{grade.user_name}} + {{grade.score||'--'}} + + + + + 分数未公布 + + + diff --git a/pages/exercise_grade/exercise_grade.wxss b/pages/exercise_grade/exercise_grade.wxss new file mode 100644 index 0000000..4e32f27 --- /dev/null +++ b/pages/exercise_grade/exercise_grade.wxss @@ -0,0 +1,21 @@ +.container{ + height: 100%; +} + +.grade{ + background: white; + padding: 20rpx 10rpx; + border-bottom: 1rpx solid gray; +} + +.grade text{ + margin: 0rpx 20rpx; +} + +.mark{ + position: absolute; + right: 3rpx; + padding: 3rpx 23rpx; + width: 45rpx; + text-align: center; +} diff --git a/pages/exercise_setting/exercise_setting.js b/pages/exercise_setting/exercise_setting.js new file mode 100644 index 0000000..f3af882 --- /dev/null +++ b/pages/exercise_setting/exercise_setting.js @@ -0,0 +1,124 @@ +// pages/exercise_setting/exercise_setting.js +import { getNowFormatDate, getNowFormatTime} from "../../utils/dateutils" +const app = getApp(); +Page({ + + /** + * 页面的初始数据 + */ + data: { + exercise_id: null, + exercise: {}, + exercise_questions:[], + }, + start_publish: function(){ + if (!this.data.exercise_id) { + console.error("请先保存试卷"); + return; + } + console.log({ + course_id: this.course_id, exercise_ids: [this.data.exercise_id], + end_time: getNowFormatDate() + " " + getNowFormatTime() + }); + let end_time = getNowFormatDate() + " " + getNowFormatTime(); + end_time = end_time.replace("-11", "-12"); + app.client.publish_exercise({ + course_id: this.course_id, exercise_ids: [this.data.exercise_id], + end_time: end_time + }).then(res=>{ + console.log(res); + wx.navigateBack({ + delta: 1 + }) + } + ) + }, + create_question: function(){ + if(!this.data.exercise_id){ + console.error("请先保存试卷"); + return; + } + wx.navigateTo({ + url: `../question_setting/question_setting?exercise_id=${this.data.exercise_id}`, + }) + }, + create_exercise: function({detail:{value}}){ + console.log(value); + app.client.create_exercise({...value, course_id: this.course_id}) + .then(res=>{ + console.log(res); + this.setData({ exercise_id: res.data.data.exercise_id}); + }) + .catch(error=>{ + console.error(error); + }); + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.course_id = options.course_id; + this.intent=options.intent; + if(options.exercise_id){ + this.setData({exercise_id: options.exercise_id}); + } + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function () { + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function () { + if(this.data.exercise_id){ + app.client.get_exercise_edit({exercise_id: this.data.exercise_id}) + .then(res=>{ + console.log(res); + this.setData( + { + exercise_questions: res.data.exercise_questions, + exercise: res.data.exercise + }) + }) + } + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function () { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function () { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function () { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function () { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function () { + + } +}) \ No newline at end of file diff --git a/pages/exercise_setting/exercise_setting.json b/pages/exercise_setting/exercise_setting.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/pages/exercise_setting/exercise_setting.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/exercise_setting/exercise_setting.wxml b/pages/exercise_setting/exercise_setting.wxml new file mode 100644 index 0000000..4289961 --- /dev/null +++ b/pages/exercise_setting/exercise_setting.wxml @@ -0,0 +1,89 @@ + + +
+ + + + + + + + + + +
+ + + +
+ + + + 第{{question.q_position}}题 + + + + + + {{choice.choice_text}} + + + + + + 暂不支持填空题... + + + + + + + 暂不支持实训题... + + + + +
+ \ No newline at end of file diff --git a/pages/exercise_setting/exercise_setting.wxss b/pages/exercise_setting/exercise_setting.wxss new file mode 100644 index 0000000..4322211 --- /dev/null +++ b/pages/exercise_setting/exercise_setting.wxss @@ -0,0 +1,63 @@ +page{ + height: 100%; +} +.question{ + background: white; + margin: 20rpx -6rpx; + padding: 4rpx 20rpx 22rpx 22rpx; + border-radius: 18rpx; +} + +.question-title{ + display: inline-block; + margin: 5rpx 0rpx 12rpx 0rpx; +} + +.choices{ + display: flex; + flex-direction: column; +} +checkbox.choice{ + margin-bottom: 12rpx; +} + +view.choice{ + width: 600rpx; +} + +.main-input{ + height: 120rpx; + margin: 18rpx 0 4rpx 18rpx; + border: 1rpx solid lightgray; + border-radius: 12rpx; + padding: 12rpx 10rpx; +} + +view.null-input{ + align-items: center; +} + +input.null-input{ + border: 1rpx solid lightgray; + padding: 12rpx 6rpx; + margin: 6rpx 10rpx; + border-radius: 10rpx; +} + +.standard-choice{ + margin-left: 24rpx; +} + +standard-null-input{ + align-items: center; +} + +/**tmp*/ + + +textarea, input{ + border: 1rpx solid gray; + border-radius: 10rpx; + padding: 10rpx; + width: 100%; +} \ No newline at end of file diff --git a/pages/exercises/exercises.js b/pages/exercises/exercises.js index 37c4b44..306378a 100644 --- a/pages/exercises/exercises.js +++ b/pages/exercises/exercises.js @@ -44,10 +44,30 @@ Page({ exercise_status: 3, course_identities: [2, 5, 6] }, + { + text: "未发布", + exercise_status: 1, + course_identities: [2] + }, ], currentTab: 0, navScrollLeft: 0 }, + see_grade: function({currentTarget:{dataset}}){ + wx.navigateTo({ + url: `../exercise_grade/exercise_grade?exercise_id=${dataset.exercise_id}`, + }) + }, + edit_exercise: function({currentTarget:{dataset}}){ + wx.navigateTo({ + url: `../exercise_setting/exercise_setting?course_id=${this.course_id}&exercise_id=${dataset.exercise_id}`, + }) + }, + create_exercise: function(){ + wx.navigateTo({ + url: `../exercise_setting/exercise_setting?course_id=${this.course_id}`, + }) + }, pull_courses_info: function(){ app.client.get_user_info() .then(); @@ -99,6 +119,11 @@ Page({ //事件处理函数 onLoad: function (options) { this.course_id = options.id; + app.client.get_course_info({course_id: this.course_id}) + .then(res=>{ + this.setData({course:res.data}) + console.log(res) + }) }, onShow: function(){ this.setData({require_login: false}); diff --git a/pages/exercises/exercises.wxml b/pages/exercises/exercises.wxml index ae435a5..0779b6d 100644 --- a/pages/exercises/exercises.wxml +++ b/pages/exercises/exercises.wxml @@ -23,20 +23,24 @@
- + {{exercise.exercise_name}} 还有{{exercise.exercise_left_time||' '}}截止 {{exercise.exercise_tips[0]}} - 进入答题 - 查看答题 + 进入答题 + 查看答题 + 编辑 + + +
diff --git a/pages/mark_detail/mark_detail.wxss b/pages/mark_detail/mark_detail.wxss index 2ab8ed8..93897fd 100644 --- a/pages/mark_detail/mark_detail.wxss +++ b/pages/mark_detail/mark_detail.wxss @@ -44,12 +44,12 @@ margin: 0rpx 20rpx; } .time{ - position: fixed; + position: absolute; right: 180rpx; } .mark{ - position: fixed; + position: absolute; right: 3rpx; padding: 3rpx 23rpx; width: 45rpx; diff --git a/pages/question_setting/question_setting.js b/pages/question_setting/question_setting.js new file mode 100644 index 0000000..131c92b --- /dev/null +++ b/pages/question_setting/question_setting.js @@ -0,0 +1,78 @@ +// pages/question_setting/question_setting.js +const app = getApp(); +Page({ + + /** + * 页面的初始数据 + */ + data: { + + }, + create_question: function({detail:{value}}){ + console.log(value); + let data = { + question_title:value.question_title,question_type:0,question_score:5,question_choices:[value.question_choices_0, value.question_choices_1, value.question_choices_2, value.question_choices_3],standard_answers:value.standard_answers} + app.client.create_question({exercise_id: this.exercise_id, data}) + .then(res=>{ + console.log(res); + wx.navigateBack({ + delta: 1 + }) + }) + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.exercise_id = options.exercise_id; + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function () { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function () { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function () { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function () { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function () { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function () { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function () { + + } +}) \ No newline at end of file diff --git a/pages/question_setting/question_setting.json b/pages/question_setting/question_setting.json new file mode 100644 index 0000000..8835af0 --- /dev/null +++ b/pages/question_setting/question_setting.json @@ -0,0 +1,3 @@ +{ + "usingComponents": {} +} \ No newline at end of file diff --git a/pages/question_setting/question_setting.wxml b/pages/question_setting/question_setting.wxml new file mode 100644 index 0000000..1dccbb0 --- /dev/null +++ b/pages/question_setting/question_setting.wxml @@ -0,0 +1,14 @@ + +
+ + + + + + + + + + +
+
\ No newline at end of file diff --git a/pages/question_setting/question_setting.wxss b/pages/question_setting/question_setting.wxss new file mode 100644 index 0000000..3709995 --- /dev/null +++ b/pages/question_setting/question_setting.wxss @@ -0,0 +1,6 @@ +textarea, input{ + border: 1rpx solid gray; + border-radius: 10rpx; + padding: 10rpx; + width: 100%; +} \ No newline at end of file diff --git a/utils/dateutils.js b/utils/dateutils.js index ae4ef0a..6483c3e 100644 --- a/utils/dateutils.js +++ b/utils/dateutils.js @@ -12,4 +12,17 @@ export function getNowFormatDate() { } var currentdate = year + seperator1 + month + seperator1 + strDate; return currentdate; +} + +export function getNowFormatTime(){ + var now = new Date(); + var hour = now.getHours();//得到小时 + var minu = now.getMinutes();//得到分钟 + var sec = now.getSeconds();//得到秒 + if (hour < 10) hour = "0" + hour; + if (minu < 10) minu = "0" + minu; + if (sec < 10) sec = "0" + sec; + var time = ""; + time = hour + ":" + minu + ":" + sec; + return time; } \ No newline at end of file