diff --git a/.bowerrc b/.bowerrc deleted file mode 100644 index 7c05067..0000000 --- a/.bowerrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "directory": "vendors" -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 154f96c..d9e1198 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ $RECYCLE.BIN/ .Trashes lib_refer +towxml project.config.json # Node.js diff --git a/README.md b/README.md index 7b7a1c0..7b96e6a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,19 @@ -使用说明 -======== +# 功能介绍 -使用代码前,请先修改 `app.js` 里面的域名配置。 \ No newline at end of file +- 学员可以在点击右下角”加入课堂”选择课程加入,教员可以在“加入课堂中”新建课程 + +- 长按相应课程可以退出学习 + +- 进入课堂界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像 + +- 教员在课堂界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作 + +- 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答” + +- 在课堂界面右下角进入“更多”可以查看本课堂的课程文件资源 + +- 教员可以在课程的设置界面中更新课程的名称,还可以将学员移除本课程的学习 + +## 其他 + +- 用户可以在设置中更改姓名、用户名 \ No newline at end of file diff --git a/app.json b/app.json index 2969b24..0d211d2 100644 --- a/app.json +++ b/app.json @@ -1,28 +1,38 @@ { "pages": [ - "pages/classes/classes", "pages/changeuser/changeuser", - "pages/index/index", - "pages/config/config", - "pages/https/https", - "pages/session/session", - "pages/websocket/websocket", - "pages/game/game", - "pages/shouquan/shouquan", - "pages/outside/outside", "pages/setting/setting", "pages/user/user", "pages/addclass/addclass", "pages/classdetail/classdetail", "pages/classroom/classroom", - "pages/classsetting/classsetting" + "pages/classsetting/classsetting", + "pages/about/about", + "pages/createclass/createclass" ], "window": { "backgroundTextStyle": "light", - "navigationBarBackgroundColor": "#fff", - "navigationBarTitleText": " ", + "navigationBarBackgroundColor": "#f2f2f2", + "navigationBarTitleText": "积分教室", "navigationBarTextStyle": "black" }, + "tabBar": { + "selectedColor": "#00C7B7", + "list": [ + { + "pagePath": "pages/classes/classes", + "text": "学习", + "iconPath": "images/tabbar-icon/tabbar_contact_default.png", + "selectedIconPath": "images/tabbar-icon/tabbar_contact_pressed.png" + }, + { + "pagePath": "pages/setting/setting", + "iconPath": "images/tabbar-icon/tabbar_settings_default.png", + "selectedIconPath": "images/tabbar-icon/tabbar_settings_pressed.png", + "text": "设置" + } + ] + }, "sitemapLocation": "sitemap.json" } \ No newline at end of file diff --git a/components/icon/myicon.wxss b/components/icon/myicon.wxss index 2091f3b..c1f795e 100644 --- a/components/icon/myicon.wxss +++ b/components/icon/myicon.wxss @@ -1,11 +1,10 @@ @font-face {font-family: "iconfont"; - src: url('iconfont.eot?t=1571919948950'); /* IE9 */ - src: url('iconfont.eot?t=1571919948950#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), - url('iconfont.woff?t=1571919948950') format('woff'), - url('iconfont.ttf?t=1571919948950') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ - url('iconfont.svg?t=1571919948950#iconfont') format('svg'); /* iOS 4.1- */ - + src: url('iconfont.eot?t=1572072148156'); /* IE9 */ + src: url('iconfont.eot?t=1572072148156#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), + url('iconfont.woff?t=1572072148156') format('woff'), + url('iconfont.ttf?t=1572072148156') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('iconfont.svg?t=1572072148156#iconfont') format('svg'); /* iOS 4.1- */ } .iconfont { @@ -27,7 +26,7 @@ content: "\e647"; } .myicon-question:before { - content: "\e670"; + content: "\e648"; } .myicon-internet_class:before { @@ -38,6 +37,10 @@ content: "\e637"; } +.myicon-add:before { + content: "\e600"; +} + .myicon__info { color: #fff; left: 100%; diff --git a/constants/api.js b/constants/api.js deleted file mode 100644 index e69de29..0000000 diff --git a/constants/appconstants.js b/constants/appconstants.js deleted file mode 100644 index e69de29..0000000 diff --git a/images/1.png b/images/1.png deleted file mode 100644 index 11b1459..0000000 Binary files a/images/1.png and /dev/null differ diff --git a/images/2.png b/images/2.png deleted file mode 100644 index 021b865..0000000 Binary files a/images/2.png and /dev/null differ diff --git a/images/3.png b/images/3.png deleted file mode 100644 index 99de040..0000000 Binary files a/images/3.png and /dev/null differ diff --git a/images/avatar.png b/images/avatar.png new file mode 100644 index 0000000..05d6370 Binary files /dev/null and b/images/avatar.png differ diff --git a/images/course.png b/images/course.png deleted file mode 100644 index 277c5c2..0000000 Binary files a/images/course.png and /dev/null differ diff --git a/images/cry.png b/images/cry.png new file mode 100644 index 0000000..2f26b84 Binary files /dev/null and b/images/cry.png differ diff --git a/images/none.png b/images/none.png new file mode 100644 index 0000000..f6b5fbb Binary files /dev/null and b/images/none.png differ diff --git a/images/none2.png b/images/none2.png new file mode 100644 index 0000000..e4b3318 Binary files /dev/null and b/images/none2.png differ diff --git a/images/tabbar-icon/tabbar_contact_default.png b/images/tabbar-icon/tabbar_contact_default.png new file mode 100644 index 0000000..b82076f Binary files /dev/null and b/images/tabbar-icon/tabbar_contact_default.png differ diff --git a/images/tabbar-icon/tabbar_contact_pressed.png b/images/tabbar-icon/tabbar_contact_pressed.png new file mode 100644 index 0000000..67a9791 Binary files /dev/null and b/images/tabbar-icon/tabbar_contact_pressed.png differ diff --git a/images/tabbar-icon/tabbar_record_default.png b/images/tabbar-icon/tabbar_record_default.png new file mode 100644 index 0000000..cfeba63 Binary files /dev/null and b/images/tabbar-icon/tabbar_record_default.png differ diff --git a/images/tabbar-icon/tabbar_record_pressed.png b/images/tabbar-icon/tabbar_record_pressed.png new file mode 100644 index 0000000..af3e6be Binary files /dev/null and b/images/tabbar-icon/tabbar_record_pressed.png differ diff --git a/images/tabbar-icon/tabbar_settings_default.png b/images/tabbar-icon/tabbar_settings_default.png new file mode 100644 index 0000000..71d3407 Binary files /dev/null and b/images/tabbar-icon/tabbar_settings_default.png differ diff --git a/images/tabbar-icon/tabbar_settings_pressed.png b/images/tabbar-icon/tabbar_settings_pressed.png new file mode 100644 index 0000000..d5f1aa7 Binary files /dev/null and b/images/tabbar-icon/tabbar_settings_pressed.png differ diff --git a/images/tabbar-icon/tabbar_sign_default.png b/images/tabbar-icon/tabbar_sign_default.png new file mode 100644 index 0000000..62bafa4 Binary files /dev/null and b/images/tabbar-icon/tabbar_sign_default.png differ diff --git a/images/tabbar-icon/tabbar_sign_pressed.png b/images/tabbar-icon/tabbar_sign_pressed.png new file mode 100644 index 0000000..916b658 Binary files /dev/null and b/images/tabbar-icon/tabbar_sign_pressed.png differ diff --git a/images/topic.png b/images/topic.png deleted file mode 100644 index f3da4cb..0000000 Binary files a/images/topic.png and /dev/null differ diff --git a/pages/shouquan/shouquan.js b/pages/about/about.js similarity index 75% rename from pages/shouquan/shouquan.js rename to pages/about/about.js index 485ea80..33d4897 100644 --- a/pages/shouquan/shouquan.js +++ b/pages/about/about.js @@ -1,17 +1,6 @@ -// pages/shouquan.js +// pages/about/about.js Page({ - bindGetUserInfo: function (e) { - var that = this; - //此处授权得到userInfo - console.log(e.detail.userInfo); - //接下来写业务代码 - - //最后,记得返回刚才的页面 - wx.navigateBack({ - delta: 1 - }) - }, /** * 页面的初始数据 */ diff --git a/pages/outside/outside.json b/pages/about/about.json similarity index 100% rename from pages/outside/outside.json rename to pages/about/about.json diff --git a/pages/about/about.wxml b/pages/about/about.wxml new file mode 100644 index 0000000..bd81eec --- /dev/null +++ b/pages/about/about.wxml @@ -0,0 +1,24 @@ + + +# 功能介绍 + +- 学员可以在点击右下角”加入课堂”选择课程加入,教员可以在“加入课堂中”新建课程 + +- 长按相应课程可以退出学习 + +- 进入课堂界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像 + +- 教员在课堂界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作 + +- 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答” + +- 在课堂界面右下角进入“更多”可以查看本课堂的课程文件资源 + +- 教员可以在课程的设置界面中更新课程的名称,还可以将学员移除本课程的学习 + +## 其他 + +- 用户可以在设置中更改姓名、用户名 + + + \ No newline at end of file diff --git a/pages/about/about.wxss b/pages/about/about.wxss new file mode 100644 index 0000000..0d61e08 --- /dev/null +++ b/pages/about/about.wxss @@ -0,0 +1 @@ +/* pages/about/about.wxss */ \ No newline at end of file diff --git a/pages/addclass/addclass.js b/pages/addclass/addclass.js index 2d5c12f..57fb704 100644 --- a/pages/addclass/addclass.js +++ b/pages/addclass/addclass.js @@ -10,52 +10,12 @@ Page({ * 页面的初始数据 */ classes: [], + current_user: null, data: { - new_classname:'', - new_class_teacher_username: '', + loading: true, classes: [] }, - updateName: function ({detail: {value}}){ - this.setData({new_classname:value}); - }, - create_class: function(event){ - let {new_classname} = this.data; - new_classname = new_classname.trim(); - if(new_classname==""){ - wx.showToast({ - title:"课程名称不能为空", - icon: "none" - }) - return; - } - class_ = new Class({ - name: new_classname, - teacher: AV.User.current() - }) - presence = new Presence({ - user: AV.User.current(), - class: class_ - }); - wx.showLoading({ - title: '请稍候', - }) - presence.save().then(()=>{ - wx.hideLoading(); - wx.showToast({ - title: '创建成功,可在首页课程列表以教师身份进入课堂', - icon:"none", - duration: 4000 - }); - this.setData({new_classname: ""}); - }, - ()=>{ - wx.hideLoading(); - wx.showToast({ - title: '操作失败', - icon: "none" - }); - }); - }, + add_class:function(event){ class_id = event.currentTarget.dataset.id; class_name = event.currentTarget.dataset.name; @@ -101,29 +61,36 @@ Page({ query = new AV.Query("Presence"); query.equalTo("user", AV.User.current()); query.include("class"); - query.find().then(this.set_presences.bind(this)); + return query.find().then(this.set_presences.bind(this)); }, set_presences: function(presences){ console.log("set_presences"); console.log(presences); present_class_ids = presences.map(presence=>presence.get("class").id); - classes =this.classes.map(class_=>{ - if(present_class_ids.indexOf(class_.id)>-1){ + classes = []; + current_user = this.current_user; + this.classes.map(class_=>{ + teacher = class_.get("teacher"); + if(present_class_ids.indexOf(class_.id)>-1 || current_user.id==teacher.id){ class_.set("present", true); }else{ class_.set("present", false); + classes.push(class_); } - return class_; }); console.log(classes); this.setData(jsonify({classes})); + this.setData({loading: false}); }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { - this.pull_classes().then(this.pull_presences); - this.setData({new_class_teacher_username: AV.User.current().get("username")}); + wx.showLoading({ + title: '加载中', + }) + this.current_user = AV.User.current(); + this.pull_classes().then(this.pull_presences).then(wx.hideLoading); }, /** diff --git a/pages/addclass/addclass.wxml b/pages/addclass/addclass.wxml index d63e6fa..b47f841 100644 --- a/pages/addclass/addclass.wxml +++ b/pages/addclass/addclass.wxml @@ -1,18 +1,9 @@ - - 创建我的课程 - - 课程名称: - - - - 教师用户名: - - - + - 可加入学习: + + 没有可以加入的课程了 - \ No newline at end of file diff --git a/pages/addclass/addclass.wxss b/pages/addclass/addclass.wxss index 4713583..b65d64d 100644 --- a/pages/addclass/addclass.wxss +++ b/pages/addclass/addclass.wxss @@ -16,7 +16,7 @@ position: relative; } .class-item:after { - content: '加入学习>'; + content: '加入 >'; display: block; position: absolute; right: 3rpx; @@ -31,35 +31,16 @@ vertical-align: middle; } -.input-wrap { - background: #fff; - border-bottom: 1px solid #eee; - margin: 0 -12px; - padding: 0 12px; - height: 46px; - line-height: 46px; +.none-content{ + align-self: center; } - -.info-input { - font-size: 18px; - line-height: 100%; - height: 100%; -} - -.disabled{ - color: #999; +text.none-content{ + font-size: 16px; + margin-top: 32rpx; } -.label { - color: #999; - display: inline; +image.none-content{ + margin-top: 120rpx; + height: 160rpx; + width: 180rpx; } - -.create-class{ - bottom: 0; -} - -button{ - margin: 4px 26px; - font-size: 14px; -} \ No newline at end of file diff --git a/pages/classdetail/classdetail.js b/pages/classdetail/classdetail.js index 9972e17..a9ff2d6 100644 --- a/pages/classdetail/classdetail.js +++ b/pages/classdetail/classdetail.js @@ -11,6 +11,7 @@ Page({ class: null, pic_urls: [], data: { + loading: true, files:[] }, @@ -26,7 +27,40 @@ Page({ }) }, del_file: function(event){ - + objectid = event.currentTarget.dataset.id; + fileid = event.currentTarget.dataset.fileid; + pull_files = this.pull_files.bind(this); + wx.showModal({ + title: '确认', + content: '删除该资源吗?', + success(res){ + if(res.confirm){ + file = new AV.Object.createWithoutData("File_", objectid); + file.destroy().then(()=>{ + wx.cloud.deleteFile({ + fileList:[fileid], + success:()=>{ + wx.showToast({ + title: '删除成功', + }); + pull_files(); + }, + fail:()=>{ + wx.showToast({ + title: '删除失败', + icon: "none" + }) + } + }); + + },()=>{ + wx.showToast({ + title: '操作失败', + icon:"none" + }) + })} + } + }) }, download: function(event){ console.log(event); @@ -141,6 +175,7 @@ Page({ return file; }) this.setData(jsonify({files})); + this.setData({loading: false}); console.log(this.data); }, /** diff --git a/pages/classdetail/classdetail.wxml b/pages/classdetail/classdetail.wxml index 6768c45..d85075f 100644 --- a/pages/classdetail/classdetail.wxml +++ b/pages/classdetail/classdetail.wxml @@ -2,10 +2,13 @@ 课堂资源 + + + - + {{file.filename}} 上传者:{{file.uploader_username}} diff --git a/pages/classdetail/classdetail.wxss b/pages/classdetail/classdetail.wxss index f57e050..82cc1e7 100644 --- a/pages/classdetail/classdetail.wxss +++ b/pages/classdetail/classdetail.wxss @@ -29,7 +29,19 @@ button{ vertical-align: center; font-size: 14px; } -.upload-file{ - background: white; - -} \ No newline at end of file + +.no-file-view{ + width: 100%; +} +text.no-file{ + font-size: 16px; + margin-top: 32rpx; + vertical-align: center; +} + +image.no-file{ + margin-top: 120rpx; + height: 160rpx; + width: 180rpx; + vertical-align: center; +} diff --git a/pages/classes/classes.js b/pages/classes/classes.js index 3533bdc..e0fafdc 100644 --- a/pages/classes/classes.js +++ b/pages/classes/classes.js @@ -18,16 +18,25 @@ Page({ class.name 课程名称 */ data: { - //classes: [{objectId: "232323", "name":"测试"}] - classes: [] + classes: [], + loading: true, }, presences: [], classes: [], + add_class:function(event){ + wx.navigateTo({ + url: '../addclass/addclass', + }) + }, del_class: function(event){ class_id = event.currentTarget.dataset.class_id; class_name = event.currentTarget.dataset.class_name; presence = this.presences.filter(presence=>presence.get("class").id==class_id)[0]; - pull_classes = this.pull_classes.bind(this); + if(presence==null){ + console.warn("presence not in list, is it the teacher's classroom?") + return; + } + pull_presences = this.pull_presences.bind(this); wx.showModal({ title: '退出学习', content: '退出学习会清零你该门课程的分数', @@ -37,7 +46,7 @@ Page({ title: '请稍候', }) presence.destroy().then(() => { - pull_classes(); + pull_presences(); wx.hideLoading(); wx.showToast({ title: '退出成功', @@ -76,16 +85,22 @@ Page({ }, - pull_classes: function(){ - console.log("classes.pull_classes"); + pull_presences: function(){ + console.log("classes.pull_presences"); var query = new AV.Query("Presence"); query.equalTo("user", AV.User.current()); query.include("class"); - query.find().then((presences) => { + return query.find().then((presences) => { this.presences = presences; - this.classes = presences.map((presence) => {return presence.get("class")}); - console.log(this.classes); - this.setData(jsonify({ classes: this.classes })); + classes = presences.map((presence) => {return presence.get("class")}); + query = new AV.Query("Class_"); + query.equalTo("teacher", AV.User.current()); + query.include("teacher"); + query.find().then(myclasses=>{ + this.setData(jsonify({classes: classes.concat(myclasses), loading: false})); + }) + console.log(classes); + }) }, /** @@ -93,7 +108,12 @@ Page({ */ onShow: function () { console.log("classes.onShow()"); - this.pull_classes(); + if(this.data.loading){ + wx.showLoading({ + title: '加载中', + }) + } + this.pull_presences().then(wx.hideLoading); }, /** @@ -114,7 +134,7 @@ Page({ * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { - this.pull_classes(); + this.pull_presences(); }, /** diff --git a/pages/classes/classes.wxml b/pages/classes/classes.wxml index 8bf3225..909f1c7 100644 --- a/pages/classes/classes.wxml +++ b/pages/classes/classes.wxml @@ -6,43 +6,18 @@ classes: 课程列表 type: Array class.name 课程名称 --> + - 你还没有加入任何课堂 + + 你的课程表空空如也 - + {{class.name}} - - # 项目简介 - - ## 学员可以在点击右下角”加入课堂”选择课程加入,教员可以在“加入课堂中”新建课程 - - ## 长按相应课程可以退出学习 - - ## 进入课堂界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像 - - ## 教员在课堂界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作 - - ## 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答” - - ## 在课堂界面右下角进入“更多”可以查看本课堂的课程文件资源 - - ## 教员可以在课程的设置界面中更新课程的名称,还可以将学员移除本课程的学习 - - ## 其他 - - ### 用户可以在设置中更改姓名、用户名 - - ### 为方便测试,在设置中可以选择测试用户登陆 + + - - - - - 设置 - 加入课堂 - diff --git a/pages/classes/classes.wxss b/pages/classes/classes.wxss index 5aab06c..3865df4 100644 --- a/pages/classes/classes.wxss +++ b/pages/classes/classes.wxss @@ -33,30 +33,27 @@ .classroom-icon{ margin-left: 2px; margin-right: 10px; + } -.footer { +.add-class{ position: fixed; + right: 0; + margin-right: 48rpx; + margin-bottom: 36rpx; bottom: 0; - height: 44px; - width: 100%; - line-height: 44px; - color: #666; - border-top: 1px solid #eee; - background: #fff; - font-size: 16px; - text-align: center; } -.tappable{ - color: #1aad19; - padding: 0 12px; - position: absolute; +.none-content{ + align-self: center; } - -.addclass{ - right:0; +text.none-content{ + font-size: 16px; } -.setting{ - left:0; + +image.none-content{ + margin-top: 120rpx; + height: 240rpx; + width: 220rpx; } + diff --git a/pages/classroom/classroom.js b/pages/classroom/classroom.js index e1db95e..a74252f 100644 --- a/pages/classroom/classroom.js +++ b/pages/classroom/classroom.js @@ -22,8 +22,9 @@ Page({ asking_presence: null, idStudentMap: {}, data: { - //以下数据的同步由该代码文件实现,数据的呈现由classroom.wxml实现 + loading: true, students: [], // 该课程所有的学生, 元素类型见上文中的student + student_num: 0, current_user: null, //目前登陆的用户,类型为对象,属性有objectId,username, name teacher: null, select_stu_id: '', @@ -79,6 +80,8 @@ Page({ }).catch(console.error); }, close_conversation: function(event){ + console.log("close conversation"); + console.log(event); this.setData({show_conversation: false}); this.messageSubscription.unsubscribe(); this.messageUnbind(); @@ -159,6 +162,7 @@ Page({ set_presence: function(presences){ console.log("set_presence"); console.log(presences); + pull_presence = this.pull_presence.bind(this); this.presences = presences; students = this.presences.map((presence)=>{ student = presence.get("user"); @@ -167,7 +171,9 @@ Page({ if(students.length==1){ student = students[0]; }else{ - student.fetch(); + console.warn("pull_presence because new student join"); + pull_presence(); + return; } } this.idStudentMap[student.id]=student; @@ -182,6 +188,7 @@ Page({ }); this.students = students; this.setData(jsonify({students})); + this.setData({loading:false}) return presences; }, diff --git a/pages/classroom/classroom.wxml b/pages/classroom/classroom.wxml index 5ed07e1..2b60ea2 100644 --- a/pages/classroom/classroom.wxml +++ b/pages/classroom/classroom.wxml @@ -1,6 +1,6 @@ - - - + + + @@ -19,7 +19,12 @@ 发送 - 课程名称:{{class_name}} 教员姓名:{{teacher.name}} + + 课程名称:{{class_name}} 教员姓名:{{teacher.name}} + + + 还没有学员加入 + - - + diff --git a/pages/classroom/classroom.wxss b/pages/classroom/classroom.wxss index a961e3a..62a50b5 100644 --- a/pages/classroom/classroom.wxss +++ b/pages/classroom/classroom.wxss @@ -38,10 +38,7 @@ movable-view{ .send-message:hover{ opacity: 0.6; } -.classroom{ - width: 100%; - height: 100%; -} + .student-list{ display: -webkit-flex; @@ -100,3 +97,20 @@ button{ .white{ background: white; } + +.no-student-view{ + vertical-align: center; + align-items: center; + align-self: center; + +} +text.no-student{ + font-size: 16px; + margin-top: 32rpx; +} + +image.no-student{ + margin-top: 120rpx; + height: 160rpx; + width: 180rpx; +} diff --git a/pages/classsetting/classsetting.js b/pages/classsetting/classsetting.js index 2a9a8ec..b5aa4b3 100644 --- a/pages/classsetting/classsetting.js +++ b/pages/classsetting/classsetting.js @@ -24,7 +24,7 @@ Page({ wx.showToast({ title:"更新成功" }); - this.setData({classname: new_classname}); + this.setData({classname: new_classname, new_classname: ""}); },()=>{ wx.showToast({ title:"操作失败", diff --git a/pages/classsetting/classsetting.wxss b/pages/classsetting/classsetting.wxss index ba47c04..f37cc36 100644 --- a/pages/classsetting/classsetting.wxss +++ b/pages/classsetting/classsetting.wxss @@ -48,6 +48,5 @@ button{ .footer{ position: fixed; bottom: 0; - background: white; width: 100%; } \ No newline at end of file diff --git a/pages/config/config.js b/pages/config/config.js deleted file mode 100644 index 6ebcd28..0000000 --- a/pages/config/config.js +++ /dev/null @@ -1,24 +0,0 @@ -const app = getApp(); -const config = app.config; -const lab = require('../../lib/lab'); - -const done = config.host != '<请配置访问域名>'; - - -Page({ - data: { - done, - status: done ? 'success' : 'waiting', - host: config.host, - hintLine1: done ? '域名已配置' : '请修改小程序源码 app.js', - hintLine2: done ? '小程序实验将使用下面域名进行' : '配置小程序使用的服务器域名' - }, - goBack() { - wx.navigateBack(); - }, - onShow() { - if (done) { - lab.finish('config'); - } - } -}); \ No newline at end of file diff --git a/pages/config/config.json b/pages/config/config.json deleted file mode 100644 index 9e26dfe..0000000 --- a/pages/config/config.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/pages/config/config.wxml b/pages/config/config.wxml deleted file mode 100644 index 9094a34..0000000 --- a/pages/config/config.wxml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - {{hintLine1}} - {{hintLine2}} - - - {{host}} - - - \ No newline at end of file diff --git a/pages/config/config.wxss b/pages/config/config.wxss deleted file mode 100644 index 93bf0aa..0000000 --- a/pages/config/config.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/config/config.wxss */ \ No newline at end of file diff --git a/pages/createclass/createclass.js b/pages/createclass/createclass.js new file mode 100644 index 0000000..9c07459 --- /dev/null +++ b/pages/createclass/createclass.js @@ -0,0 +1,108 @@ +// pages/createclass/createclass.js +const AV = require("../../lib/av-live-query-weapp-min") +const Presence = require("../../model/presence") +const Class = require("../../model/class") + + +Page({ + + /** + * 页面的初始数据 + */ + data: { + new_classname: '', + new_class_teacher_username: '', + }, + updateName: function ({ detail: { value } }) { + this.setData({ new_classname: value }); + }, + create_class: function (event) { + let { new_classname } = this.data; + new_classname = new_classname.trim(); + if (new_classname == "") { + wx.showToast({ + title: "课程名称不能为空", + icon: "none" + }) + return; + } + class_ = new Class({ + name: new_classname, + teacher: AV.User.current() + }) + wx.showLoading({ + title: '请稍候', + }) + class_.save().then(() => { + wx.hideLoading(); + wx.showToast({ + title: '创建成功,可在首页课程列表以教师身份进入课堂', + icon: "none", + duration: 4000 + }); + this.setData({ new_classname: "" }); + }, + () => { + wx.hideLoading(); + wx.showToast({ + title: '操作失败', + icon: "none" + }); + }); + }, + /** + * 生命周期函数--监听页面加载 + */ + onLoad: function (options) { + this.setData({ new_class_teacher_username: AV.User.current().get("username") }); + }, + + /** + * 生命周期函数--监听页面初次渲染完成 + */ + onReady: function () { + + }, + + /** + * 生命周期函数--监听页面显示 + */ + onShow: function () { + + }, + + /** + * 生命周期函数--监听页面隐藏 + */ + onHide: function () { + + }, + + /** + * 生命周期函数--监听页面卸载 + */ + onUnload: function () { + + }, + + /** + * 页面相关事件处理函数--监听用户下拉动作 + */ + onPullDownRefresh: function () { + + }, + + /** + * 页面上拉触底事件的处理函数 + */ + onReachBottom: function () { + + }, + + /** + * 用户点击右上角分享 + */ + onShareAppMessage: function () { + + } +}) \ No newline at end of file diff --git a/pages/shouquan/shouquan.json b/pages/createclass/createclass.json similarity index 100% rename from pages/shouquan/shouquan.json rename to pages/createclass/createclass.json diff --git a/pages/createclass/createclass.wxml b/pages/createclass/createclass.wxml new file mode 100644 index 0000000..bbc27b1 --- /dev/null +++ b/pages/createclass/createclass.wxml @@ -0,0 +1,13 @@ + + + 创建我的课程 + + 课程名称: + + + + 教师用户名: + + + + \ No newline at end of file diff --git a/pages/createclass/createclass.wxss b/pages/createclass/createclass.wxss new file mode 100644 index 0000000..9529f2b --- /dev/null +++ b/pages/createclass/createclass.wxss @@ -0,0 +1,30 @@ + +.input-wrap { + background: #fff; + border-bottom: 1px solid #eee; + margin: 0 -12px; + padding: 0 12px; + height: 46px; + line-height: 46px; +} + +.info-input { + font-size: 18px; + line-height: 100%; + height: 100%; +} + +.disabled{ + color: #999; +} + +.label { + color: #999; + display: inline; +} + + +button{ + margin: 4px 26px; + font-size: 16px; +} \ No newline at end of file diff --git a/pages/game/game.js b/pages/game/game.js deleted file mode 100644 index 5ea0b56..0000000 --- a/pages/game/game.js +++ /dev/null @@ -1,253 +0,0 @@ -"use strict"; - -require('../../lib/regenerator-runtime'); - -const regeneratorRuntime = global.regeneratorRuntime; - -// 引入 co 和 promisify 帮助我们进行异步处理 -const co = require('../../lib/co'); -const promisify = require('../../lib/promisify'); - -// 引入 Wafer 客户端 SDK 支持会话 -const wafer = require('../../vendors/wafer-client-sdk/index'); - -// 简单的小程序 WebSocket 信道封装 -const Tunnel = require('../../lib/tunnel'); - -// 登录接口转成返回 Promise 形式 -const login = promisify(wafer.login); - -// 获得小程序实例 -const app = getApp(); - -// 用于记录实验成功 -const lab = require('../../lib/lab'); - -// 设置会话登录地址 -wafer.setLoginUrl(`https://${app.config.host}/login`); - -// 文案 -const WIN_TEXTS = ['很棒', '秒杀', '赢了', 'Winner', '胜利', '不要大意', '无敌啊']; -const LOSE_TEXTS = ['失误', '卧槽', '不可能', 'Loser', '行不行啊', '加油', '大侠再来']; -const EQ_TEXTS = ['平局', '平分秋色', '对方学你', '照镜子', '半斤八两', '换一个', '一样的']; -const pickText = texts => texts[Math.floor(texts.length * Math.random())]; - -// 定义页面 -Page({ - data: { - // 是否已经和服务器连接 - connected: false, - - // 游戏是否进行中 - playing: false, - - // 当前需要展示的游戏信息 - gameInfo: "", - - // 开始游戏按钮文本 - startButtonText: "开始", - - //「我」的信息,包括昵称、头像、分数、选择 - myName: "", - myAvatar: null, - myScore: 0, - myStreak: 0, - myChoice: Math.floor(Math.random() * 10000) % 3 + 1, - - //「你」的信息 - youHere: false, - yourName: "", - yourAvatar: null, - yourScore: 0, - yourStreak: 0, - yourChoice: 1, - yourMove: 0, - - // 取得胜利的是谁 - win: null - }, - - // 页面显示后,开始连接 - onShow: function() { - this.begin(); - }, - - // 进行登录和链接,完成后开始启动游戏服务 - begin: co.wrap(function *() { - try { - this.setData({ gameInfo: "正在登陆" }); - yield login(); - - this.setData({ gameInfo: "正在连接"}); - yield this.connect(); - } catch (error) { - console.error('error on login or connect: ', error); - } - this.serve(); - }), - - // 链接到服务器后进行身份识别 - connect: co.wrap(function *() { - - const tunnel = this.tunnel = new Tunnel(); - try { - yield tunnel.connect(`wss://${app.config.host}/game`, wafer.buildSessionHeader()); - } catch (connectError) { - console.error({ connectError }); - this.setData({ gameInfo: "连接错误" }); - throw connectError; - } - tunnel.on('close', () => { - this.setData({ - connected: false, - gameInfo: "连接已中断" - }); - }); - this.setData({ - gameInfo: "准备", - connected: true, - gameState: 'connected' - }); - return new Promise((resolve, reject) => { - // 10 秒后超时 - const timeout = setTimeout(() => reject, 10000); - tunnel.on('id', ({ uname, uid, uavatar }) => { - this.uid = uid; - this.setData({ - myName: uname, - myAvatar: uavatar - }); - resolve(tunnel); - clearTimeout(timeout); - }); - }); - }), - - // 开始进行游戏服务 - serve: co.wrap(function *() { - const tunnel = this.tunnel; - - // 游戏开始,初始化对方信息,启动计时器 - tunnel.on('start', packet => { - const you = packet.players.filter(user => user.uid !== this.uid).pop(); - - this.setData({ - playing: false, - done: false, - finding: true, - gameInfo: '正在寻找玩伴...' - }); - setTimeout(() => { - this.setData({ - youHere: true, - yourName: you.uname, - yourAvatar: you.uavatar, - finding: false, - playing: true, - gameInfo: "准备" - }); - }, 10); - - let gameTime = packet.gameTime; - clearInterval(this.countdownId); - this.countdownId = setInterval(() => { - if (gameTime > 0) { - this.setData({ gameInfo: --gameTime }); - } else { - clearInterval(this.countdownId); - } - }, 1000); - - this.tunnel.emit('choice', { choice: this.data.myChoice }); - }); - - // 对方有动静的时候,触发提醒 - let movementTimer = 0; - const movementTimeout = 300; - tunnel.on('movement', packet => { - const lastMove = this.lastMove; - - this.setData({ yourMove: lastMove == 1 ? 2 : 1 }); - - clearTimeout(movementTimer); - movementTimer = setTimeout(() => { - this.lastMove = this.data.yourMove; - this.setData({ yourMove: 0 }); - }, 300); - }); - - // 服务器通知结果 - tunnel.on('result', packet => { - - // 清除计时器 - clearInterval(this.countdownId); - - // 双方结果 - const myResult = packet.result.find(x => x.uid == this.uid); - const yourResult = packet.result.find(x => x.uid != this.uid); - - // 本局结果 - let gameInfo, win = 'nobody'; - - if (myResult.roundScore == 0 && yourResult.roundScore == 0) { - gameInfo = pickText(EQ_TEXTS); - } - else if (myResult.roundScore > 0) { - gameInfo = pickText(WIN_TEXTS); - win = 'me'; - } - else { - gameInfo = pickText(LOSE_TEXTS); - win = 'you' - } - - // 更新到视图 - this.setData({ - gameInfo, - myScore: myResult.totalScore, - myStreak: myResult.winStreak, - yourChoice: yourResult.choice, - yourScore: yourResult.totalScore, - yourStreak: yourResult.winStreak, - gameState: 'finish', - win, - startButtonText: win == 'you' ? "不服" : "再来", - done: true - }); - - lab.finish('game'); - setTimeout(() => this.setData({ playing: false }), 1000); - }); - }), - - requestComputer() { - if (this.tunnel) { - this.tunnel.emit('requestComputer'); - } - }, - - // 点击开始游戏按钮,发送加入游戏请求 - startGame: co.wrap(function *() { - if (this.data.playing) return; - if (!this.data.connected) return; - - this.setData({ - playing: false, - done: false, - finding: true, - gameInfo: '正在寻找玩伴...' - }); - this.tunnel.emit('join'); - }), - - // 点击手势,更新选择是石头、剪刀还是布 - switchChoice(e) { - if (!this.data.playing) return; - let myChoice = this.data.myChoice + 1; - if (myChoice == 4) { - myChoice = 1; - } - this.setData({ myChoice }); - this.tunnel.emit('choice', { choice: myChoice }); - } -}); diff --git a/pages/game/game.json b/pages/game/game.json deleted file mode 100644 index 9e26dfe..0000000 --- a/pages/game/game.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/pages/game/game.wxml b/pages/game/game.wxml deleted file mode 100644 index 8595afb..0000000 --- a/pages/game/game.wxml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - {{myName}} - 得分 {{myScore}} - - - 连胜 {{myStreak}} - - - - - - - - - {{yourName}} - 得分 {{yourScore}} - - - 连胜 {{yourStreak}} - - - - {{gameInfo}} - - - - \ No newline at end of file diff --git a/pages/game/game.wxss b/pages/game/game.wxss deleted file mode 100644 index 9787c90..0000000 --- a/pages/game/game.wxss +++ /dev/null @@ -1,191 +0,0 @@ -.root { - overflow: hidden; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; -} - -.my-side { - width: 1500rpx; - height: 1500rpx; - position: absolute; - bottom: -1125rpx; - left: -375rpx; - border-radius: 100%; - background: lightskyblue; - overflow: visible; -} - -.your-side { - width: 1500rpx; - height: 1500rpx; - position: absolute; - top: -1500rpx; - left: -375rpx; - border-radius: 100%; - background: lightpink; - overflow: visible; - transition: top ease 0.6s; -} - -.your-side.here { - top: -1125rpx; -} - -.avatar { - position: absolute; - width: 172rpx; - height: 172rpx; - border-radius: 100%; - border: 8rpx solid white; - background-color: #f0f0f0; -} - -.hand { - position: absolute; - width: 187rpx; - height: 187rpx; - border-radius: 100%; - overflow: visible; -} - -.score, .streak { - position: absolute; - color: #334567; - width: 225rpx; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -.streak { - text-align: right; -} - -.my-side .avatar { - left: 656.25rpx; - top: -93.75rpx; - transition: top ease .2s; -} - -.my-side .hand { - left: 656.25rpx; - top: 150rpx; - transition: top ease .2s; -} - -.root.playing .my-side .hand:active { - transform: scale(1.3); -} - -.root.done .my-side .avatar { - top: 168.75rpx; -} - -.root.done .my-side .hand { - top: -112.5rpx; -} - -.my-side .score { - left: 412.5rpx; - bottom: 1162.5rpx; -} - -.my-side .streak { - right: 412.5rpx; - bottom: 1162.5rpx; -} - -.your-side .avatar { - left: 656.25rpx; - bottom: -93.75rpx; - transition: all ease .2s; - opacity: 0; -} - -.your-side.here .avatar { - opacity: 1; -} -.your-side.move-1 .avatar { - transform: rotate(15deg); -} -.your-side.move-2 .avatar { - transform: rotate(-15deg); -} - -.your-side .hand { - left: 656.25rpx; - bottom: 150rpx; - opacity: 0; - transition: bottom ease .2s; - transform: rotate(180deg); -} - -.root.done .your-side .avatar { - bottom: 168.75rpx; -} - -.root.done .your-side .hand { - bottom: -93.75rpx; - opacity: 1; -} - -.your-side .score { - left: 412.5rpx; - top: 1106.25rpx; -} - -.your-side .streak { - right: 412.5rpx; - top: 1106.25rpx; -} - - -.start-game, .request-computer { - position: absolute; - width: 200rpx; - height: 80rpx; - line-height: 80rpx; - margin-left: -100rpx; - bottom: 500rpx; - left: 50%; - display: none; -} - -.request-computer { - width: 300rpx; - margin-left: -150rpx; -} - -.root.finding .request-computer { - display: block; -} - -.root.connected .start-game { - display: block; -} - -.root.connected.playing .start-game, -.root.finding .start-game { - display: none; -} - -.game-info { - font-size: 75rpx; - position: absolute; - width: 750rpx; - height: 112.5rpx; - line-height: 112.5rpx; - margin-top: -56.25rpx; - bottom: 600rpx; - left: 0; - text-align: center; - opacity: 1; -} - -.root.connected.root.playing .game-info, -.root.connected.root.done .game-info { - opacity: 1; -} diff --git a/pages/https/https.js b/pages/https/https.js deleted file mode 100644 index d51aa2e..0000000 --- a/pages/https/https.js +++ /dev/null @@ -1,54 +0,0 @@ -const app = getApp(); -const config = app.config; -const lab = require('../../lib/lab'); - -Page({ - data: { - status: 'waiting', - url: 'https://' + config.host + '/hello', - requesting: false, - hintLine1: '完成服务器开发,', - hintLine2: '使得下面的地址可以访问' - }, - request() { - this.setData({ - requesting: true, - status: 'waiting', - hintLine1: '正在发送', - hintLine2: '...' - }); - wx.request({ - url: this.data.url, - method: 'GET', - success: (res) => { - if (+res.statusCode == 200) { - this.setData({ - status: 'success', - hintLine1: '服务器响应成功', - hintLine2: '返回:' + res.data - }); - lab.finish('https'); - } else { - this.setData({ - status: 'warn', - hintLine1: '响应错误', - hintLine2: '响应码:' + res.statusCode - }); - } - }, - fail: (res) => { - console.log(res); - this.setData({ - status: 'warn', - hintLine1: '请求失败', - hintLine2: res.errMsg - }); - }, - complete: () => { - this.setData({ - requesting: false - }); - } - }); - } -}); \ No newline at end of file diff --git a/pages/https/https.json b/pages/https/https.json deleted file mode 100644 index 9e26dfe..0000000 --- a/pages/https/https.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/pages/https/https.wxml b/pages/https/https.wxml deleted file mode 100644 index ce75548..0000000 --- a/pages/https/https.wxml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - {{hintLine1}} - {{hintLine2}} - - - {{url}} - - - - - \ No newline at end of file diff --git a/pages/https/https.wxss b/pages/https/https.wxss deleted file mode 100644 index 8b52cef..0000000 --- a/pages/https/https.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/https/https.wxss */ \ No newline at end of file diff --git a/pages/index/index.js b/pages/index/index.js deleted file mode 100644 index 7d68f54..0000000 --- a/pages/index/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const lab = require('../../lib/lab'); - -Page({ - data: { - labs: [ - { id: 'config', title: '实验准备:配置请求域名' }, - { id: 'https', title: '实验一:HTTPS' }, - { id: 'session', title: '实验二:会话' }, - { id: 'websocket', title: '实验三:WebSocket' }, - { id: 'game', title: '实验四:剪刀石头布小游戏' }, - { id: "classes", title: "进入教室"} - ], - done: lab.getFinishLabs() - }, - - onShow() { - console.log({ done: lab.getFinishLabs() }); - this.setData({ done: lab.getFinishLabs() }); - }, - - clear() { - lab.clear(); - this.setData({ done: lab.getFinishLabs() }); - } -}); \ No newline at end of file diff --git a/pages/index/index.json b/pages/index/index.json deleted file mode 100644 index 834c3dd..0000000 --- a/pages/index/index.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "navigationBarTitleText": "积分教室" -} \ No newline at end of file diff --git a/pages/index/index.wxml b/pages/index/index.wxml deleted file mode 100644 index 2d696b0..0000000 --- a/pages/index/index.wxml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - {{lab.title}} - - - - - - \ No newline at end of file diff --git a/pages/index/index.wxss b/pages/index/index.wxss deleted file mode 100644 index a680707..0000000 --- a/pages/index/index.wxss +++ /dev/null @@ -1,41 +0,0 @@ -/* pages/index/index.wxss */ -.index { - font-family: 'PingFang SC'; -} - -.nav { - display: flex; - flex-direction: column; - padding: 0 50rpx; -} - -.nav navigator { - padding: 30rpx 0; - border-bottom: 1rpx solid #EEE; - position: relative; -} - -.nav navigator:after { - content: '>'; - display: block; - position: absolute; - right: 3rpx; - top: 50%; - height: 40rpx; - line-height: 40rpx; - margin-top: -20rpx; - color: #999; -} - -.nav navigator icon, -.nav navigator text { - vertical-align: middle; -} - -.nav navigator icon { - margin-right: 25rpx; -} - -.clear { - margin: 100rpx 50rpx; -} \ No newline at end of file diff --git a/pages/outside/outside.js b/pages/outside/outside.js deleted file mode 100644 index c0d981c..0000000 --- a/pages/outside/outside.js +++ /dev/null @@ -1,74 +0,0 @@ -// pages/outside/outside.js -Page({ - - /** - * 页面的初始数据 - */ - data: { - name: 'Hello World', - src: '/images/weixin.jpg' - }, - getMyInfo: function (e) { - console.log(e.detail.userInfo) - let info = e.detail.userInfo; - this.setData({ - name: info.nickName,//更新名称 - src: info.avatarUrl//更新图片来源 - }) - }, - /** - * 生命周期函数--监听页面加载 - */ - onLoad: function (options) { - - }, - - /** - * 生命周期函数--监听页面初次渲染完成 - */ - onReady: function () { - - }, - - /** - * 生命周期函数--监听页面显示 - */ - onShow: function () { - - }, - - /** - * 生命周期函数--监听页面隐藏 - */ - onHide: function () { - - }, - - /** - * 生命周期函数--监听页面卸载 - */ - onUnload: function () { - - }, - - /** - * 页面相关事件处理函数--监听用户下拉动作 - */ - onPullDownRefresh: function () { - - }, - - /** - * 页面上拉触底事件的处理函数 - */ - onReachBottom: function () { - - }, - - /** - * 用户点击右上角分享 - */ - onShareAppMessage: function () { - - } -}) \ No newline at end of file diff --git a/pages/outside/outside.wxml b/pages/outside/outside.wxml deleted file mode 100644 index 1ef6496..0000000 --- a/pages/outside/outside.wxml +++ /dev/null @@ -1,7 +0,0 @@ - - - {{name}} - - - - \ No newline at end of file diff --git a/pages/outside/outside.wxss b/pages/outside/outside.wxss deleted file mode 100644 index 4a0f3a2..0000000 --- a/pages/outside/outside.wxss +++ /dev/null @@ -1,18 +0,0 @@ -/* 样式设计 */ -.container{ - height: 90vh; /*高100视窗,这里写100%无效的*/ - display: flex; /*flex布局方法*/ - flex-direction: column;/*垂直布局*/ - align-items: center;/*水平方向居中*/ - justify-content: space-around;/*垂直方向分散布局*/ -} -.abc{ - width: 400rpx;/*图片宽度*/ - border-radius: 50%;/*4个角变为圆角形状*/ -} -text{ - font-size: 50rpx;/*字体大小*/ - color: red; - background-color: blue; - border:5rpx solid paleturquoise; -} diff --git a/pages/session/session.js b/pages/session/session.js deleted file mode 100644 index df218f7..0000000 --- a/pages/session/session.js +++ /dev/null @@ -1,67 +0,0 @@ -const app = getApp(); -const config = app.config; -const wafer = require('../../vendors/wafer-client-sdk/index'); -const lab = require('../../lib/lab'); - -wafer.setLoginUrl(`https://` + config.host + '/login'); - -Page({ - data: { - status: 'waiting', - url: 'https://' + config.host + '/me', - requesting: false, - hintLine1: '完成服务器开发,', - hintLine2: '让服务器可以识别小程序会话' - }, - request() { - this.setData({ - requesting: true, - status: 'waiting', - hintLine1: '正在发送', - hintLine2: '...' - }); - wafer.request({ - login: true, - url: this.data.url, - method: 'GET', - success: (res) => { - if (+res.statusCode == 200) { - if (res.data.openId) { - this.setData({ - status: 'success', - hintLine1: '成功获取会话', - hintLine2: res.data.nickName, - avatarUrl: res.data.avatarUrl - }); - lab.finish('session'); - } else { - this.setData({ - status: 'warn', - hintLine1: '会话获取失败', - hintLine2: '未获取到 openId' - }); - console.error('会话获取失败', res.data); - } - } else { - this.setData({ - status: 'warn', - hintLine1: '响应错误', - hintLine2: '响应码:' + res.statusCode - }); - } - }, - fail: (error) => { - this.setData({ - status: 'warn', - hintLine1: '获取失败', - hintLine2: error.message - }); - }, - complete: () => { - this.setData({ - requesting: false - }); - } - }); - } -}); \ No newline at end of file diff --git a/pages/session/session.json b/pages/session/session.json deleted file mode 100644 index 9e26dfe..0000000 --- a/pages/session/session.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/pages/session/session.wxml b/pages/session/session.wxml deleted file mode 100644 index f3a2b8c..0000000 --- a/pages/session/session.wxml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - {{hintLine1}} - {{hintLine2}} - - - {{url}} - - - - - \ No newline at end of file diff --git a/pages/session/session.wxss b/pages/session/session.wxss deleted file mode 100644 index 7aa605e..0000000 --- a/pages/session/session.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/session/session.wxss */ \ No newline at end of file diff --git a/pages/setting/setting.js b/pages/setting/setting.js index 3054f84..c2d9ae1 100644 --- a/pages/setting/setting.js +++ b/pages/setting/setting.js @@ -1,4 +1,20 @@ - +const AV = require("../../lib/av-live-query-weapp-min") Page({ - + data:{ + current_user: null + }, + enter_usersetting: function(event){ + wx.navigateTo({ + url: '../user/user' + }) + }, + enter_changeuser: function(event){ + console.log(event); + wx.navigateTo({ + url: '../changeuser/changeuser' + }) + }, + onShow: function(){ + this.setData({current_user: AV.User.current().toJSON()}) + } }) \ No newline at end of file diff --git a/pages/setting/setting.wxml b/pages/setting/setting.wxml index ea2bee9..c1136e4 100644 --- a/pages/setting/setting.wxml +++ b/pages/setting/setting.wxml @@ -1,4 +1,13 @@ - 登陆信息修改 - 更换登陆用户 + + + {{current_user.name}} | {{current_user.username}} + + + 登陆信息修改 + + 加入课程 + 创建课程 + 关于 + \ No newline at end of file diff --git a/pages/setting/setting.wxss b/pages/setting/setting.wxss index c758974..af1b29a 100644 --- a/pages/setting/setting.wxss +++ b/pages/setting/setting.wxss @@ -1,7 +1,27 @@ -.navigator { +.nav { background: white; border-bottom: 1px solid #eee; padding: 0 12px; height: 46px; line-height: 46px; } + +.user-view{ + display: flex; + flex-direction: column; +} + +.user{ + align-self: center; +} +text.user{ + font-size: 16px; + margin-top: 5px; + margin-bottom: 8px; +} + +image.user{ + margin-top: 10rpx; + height: 120rpx; + width: 120rpx; +} diff --git a/pages/shouquan/shouquan.wxml b/pages/shouquan/shouquan.wxml deleted file mode 100644 index f2d6e00..0000000 --- a/pages/shouquan/shouquan.wxml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/pages/shouquan/shouquan.wxss b/pages/shouquan/shouquan.wxss deleted file mode 100644 index e69de29..0000000 diff --git a/pages/websocket/websocket.js b/pages/websocket/websocket.js deleted file mode 100644 index 021915f..0000000 --- a/pages/websocket/websocket.js +++ /dev/null @@ -1,109 +0,0 @@ -const app = getApp(); -const config = app.config; -const wafer = require('../../vendors/wafer-client-sdk/index'); -const lab = require('../../lib/lab'); - -Page({ - data: { - status: 'waiting', - url: 'wss://' + config.host + '/ws', - connecting: false, - hintLine1: '完成服务器开发,', - hintLine2: '让服务器支持 WebSocket 连接' - }, - - /** - * WebSocket 是否已经连接 - */ - socketOpen: false, - - /** - * 开始连接 WebSocket - */ - connect() { - this.setData({ - status: 'waiting', - connecting: true, - hintLine1: '正在连接', - hintLine2: '...' - }); - this.listen(); - wafer.setLoginUrl(`https://${config.host}/login`); - wafer.login({ - success: () => { - const header = wafer.buildSessionHeader(); - const query = Object.keys(header).map(key => `${key}=${encodeURIComponent(header[key])}`).join('&'); - wx.connectSocket({ - // 小程序 wx.connectSocket() API header 参数无效,把会话信息附加在 URL 上 - url: `${this.data.url}?${query}`, - header - }); - }, - fail: (err) => { - this.setData({ - status: 'warn', - connecting: false, - hintLine1: '登录失败', - hintLine2: err.message || err - }); - } - }); - }, - - /** - * 监听 WebSocket 事件 - */ - listen() { - wx.onSocketOpen(() => { - this.socketOpen = true; - this.setData({ - status: 'success', - connecting: false, - hintLine1: '连接成功', - hintLine2: '现在可以通过 WebSocket 发送接收消息了' - }); - console.info('WebSocket 已连接'); - }); - wx.onSocketMessage((message) => { - this.setData({ - hintLine2: message.data - }); - lab.finish('websocket'); - }); - wx.onSocketClose(() => { - this.setData({ - status: 'waiting', - hintLine1: 'WebSocket 已关闭' - }); - console.info('WebSocket 已关闭'); - }); - wx.onSocketError(() => { - setTimeout(() => { - this.setData({ - status: 'warn', - connecting: false, - hintLine1: '发生错误', - hintLine2: 'WebSocket 连接建立失败' - }); - }); - console.error('WebSocket 错误'); - }); - }, - - /** - * 发送一个包含当前时间信息的消息 - */ - send() { - wx.sendSocketMessage({ - data: new Date().toTimeString().split(' ').shift() + '.' + (new Date().getMilliseconds()) - }); - }, - - /** - * 关闭 WebSocket 连接 - */ - close() { - this.socketOpen = false; - wx.closeSocket(); - } -}); \ No newline at end of file diff --git a/pages/websocket/websocket.json b/pages/websocket/websocket.json deleted file mode 100644 index 9e26dfe..0000000 --- a/pages/websocket/websocket.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/pages/websocket/websocket.wxml b/pages/websocket/websocket.wxml deleted file mode 100644 index 2c2af45..0000000 --- a/pages/websocket/websocket.wxml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - {{hintLine1}} - {{hintLine2}} - - - {{url}} - - - - - - - \ No newline at end of file diff --git a/pages/websocket/websocket.wxss b/pages/websocket/websocket.wxss deleted file mode 100644 index 36bb319..0000000 --- a/pages/websocket/websocket.wxss +++ /dev/null @@ -1 +0,0 @@ -/* pages/websocket/websocket.wxss */ \ No newline at end of file diff --git a/vendors/wafer-client-sdk/.bower.json b/vendors/wafer-client-sdk/.bower.json deleted file mode 100644 index 05d43a6..0000000 --- a/vendors/wafer-client-sdk/.bower.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "wafer-client-sdk", - "description": "QCloud 微信小程序客户端 SDK", - "main": "index.js", - "authors": [ - "Tencent Cloud" - ], - "license": "MIT", - "keywords": [ - "qcloud", - "weapp", - "wechat", - "sdk", - "client", - "auth", - "websocket" - ], - "homepage": "https://github.com/tencentyun/wafer-client-sdk", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests", - "typings.json", - "jsconfig.json", - "package.json", - ".npmignore", - ".travis.yml", - ".gitignore" - ], - "version": "0.8.4", - "_release": "0.8.4", - "_resolution": { - "type": "version", - "tag": "v0.8.4", - "commit": "3f605d1aa5bd0206bb9368586f4acb104f5f8ae5" - }, - "_source": "https://github.com/tencentyun/wafer-client-sdk.git", - "_target": "^0.8.3", - "_originalSource": "wafer-client-sdk" -} \ No newline at end of file diff --git a/vendors/wafer-client-sdk/LICENSE b/vendors/wafer-client-sdk/LICENSE deleted file mode 100644 index 7bb43b8..0000000 --- a/vendors/wafer-client-sdk/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -LICENSE - "MIT License" - -Copyright (c) 2016 by Tencent Cloud - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendors/wafer-client-sdk/README.md b/vendors/wafer-client-sdk/README.md deleted file mode 100644 index 5c4f392..0000000 --- a/vendors/wafer-client-sdk/README.md +++ /dev/null @@ -1,247 +0,0 @@ -# 微信小程序客户端腾讯云增强 SDK - -[![Build Status](https://travis-ci.org/tencentyun/wafer-client-sdk.svg?branch=master)](https://travis-ci.org/tencentyun/wafer-client-sdk) -[![Coverage Status](https://coveralls.io/repos/github/tencentyun/wafer-client-sdk/badge.svg?branch=master)](https://coveralls.io/github/tencentyun/wafer-client-sdk?branch=master) -[![License](https://img.shields.io/github/license/tencentyun/wafer-client-sdk.svg)](LICENSE) - -本 项目是 [Wafer](https://github.com/tencentyun/wafer-solution) 的组成部分,为小程序客户端开发提供 SDK 支持会话服务和信道服务。 - -## SDK 获取与安装 - -解决方案[客户端 Demo](https://github.com/tencentyun/wafer-client-demo) 已经集成并使用最新版的 SDK,需要快速了解的可以从 Demo 开始。 - -如果需要单独开始,本 SDK 已经发布为 bower 模块,可以直接安装到小程序目录中。 - -```sh -npm install -g bower -bower install wafer-client-sdk -``` - -安装之后,就可以使用 `require` 引用 SDK 模块: - -```js -var qcloud = require('./bower_components/wafer-client-sdk/index.js'); -``` - -## 会话服务 - -[会话服务](https://github.com/tencentyun/wafer-solution/wiki/%E4%BC%9A%E8%AF%9D%E6%9C%8D%E5%8A%A1)让小程序拥有会话管理能力。 - -### 登录 - -登录可以在小程序和服务器之间建立会话,服务器由此可以获取到用户的标识和信息。 - -```js -var qcloud = require('./bower_components/qcloud-weapp-client-sdk/index.js'); - -// 设置登录地址 -qcloud.setLoginUrl('https://199447.qcloud.la/login'); -qcloud.login({ - success: function (userInfo) { - console.log('登录成功', userInfo); - }, - fail: function (err) { - console.log('登录失败', err); - } -}); -``` -本 SDK 需要配合云端 SDK 才能提供完整会话服务。通过 [setLoginUrl](#setLoginUrl) 设置登录地址,云服务器在该地址上使用云端 SDK 处理登录请求。 - -> `setLoginUrl` 方法设置登录地址之后会一直有效,因此你可以在微信小程序启动时设置。 - -登录成功后,可以获取到当前微信用户的基本信息。 - -### 请求 - -如果希望小程序的网络请求包含会话,登录之后使用 [request](#request) 方法进行网络请求即可。 - -```js -qcloud.request({ - url: 'http://199447.qcloud.la/user', - success: function (response) { - console.log(response); - }, - fail: function (err) { - console.log(err); - } -}); -``` - -如果调用 `request` 之前还没有登录,则请求不会带有会话。`request` 方法也支持 `login` 参数支持在请求之前自动登录。 - -```js -// 使用 login 参数之前,需要设置登录地址 -qcloud.setLoginUrl('https://199447.qcloud.la/login'); -qcloud.request({ - login: true, - url: 'http://199447.qcloud.la/user', - success: function (response) { - console.log(response); - }, - fail: function (err) { - console.log(err); - } -}); -``` - -关于会话服务详细技术说明,请参考 [Wiki](https://github.com/tencentyun/wafer-solution/wiki/%E4%BC%9A%E8%AF%9D%E6%9C%8D%E5%8A%A1)。 - -## 信道服务 - -[信道服务](https://github.com/tencentyun/wafer-solution/wiki/%E4%BF%A1%E9%81%93%E6%9C%8D%E5%8A%A1)小程序支持利用腾讯云的信道资源使用 WebSocket 服务。 - -```js -// 创建信道,需要给定后台服务地址 -var tunnel = this.tunnel = new qcloud.Tunnel('https://199447.qcloud.la/tunnel'); - -// 监听信道内置消息,包括 connect/close/reconnecting/reconnect/error -tunnel.on('connect', () => console.log('WebSocket 信道已连接')); -tunnel.on('close', () => console.log('WebSocket 信道已断开')); -tunnel.on('reconnecting', () => console.log('WebSocket 信道正在重连...')); -tunnel.on('reconnect', () => console.log('WebSocket 信道重连成功')); -tunnel.on('error', error => console.error('信道发生错误:', error)); - -// 监听自定义消息(服务器进行推送) -tunnel.on('speak', speak => console.log('收到 speak 消息:', speak)); - -// 打开信道 -tunnel.open(); -// 发送消息 -tunnel.emit('speak', { word: "hello", who: { nickName: "techird" }}); -// 关闭信道 -tunnel.close(); -``` - -信道服务同样需要业务服务器配合云端 SDK 支持,构造信道实例的时候需要提供业务服务器提供的信道服务地址。通过监听信道消息以及自定义消息来通过信道实现业务。 - -关于信道使用的更完整实例,建议参考客户端 Demo 中的[三木聊天室应用源码](https://github.com/tencentyun/wafer-client-demo/blob/master/pages/chat/chat.js)。 - -关于信道服务详细技术说明,请参考 [Wiki](https://github.com/tencentyun/wafer-solution/wiki/%E4%BF%A1%E9%81%93%E6%9C%8D%E5%8A%A1)。 - -## API - - -### setLoginUrl -设置会话服务登录地址。 - -#### 语法 -```js -qcloud.setLoginUrl(loginUrl); -``` - -#### 参数 -|参数         |类型 |说明 -|-------------|---------------|-------------- -|loginUrl |string |会话服务登录地址 - -### login -登录,建立微信小程序会话。 - -#### 语法 -```js -qcloud.login(options); -``` - -#### 参数 -|参数         |类型 |说明 -|-------------|---------------|-------------- -|options     |PlainObject   |会话服务登录地址 -|options.success | () => void | 登录成功的回调 -|options.error | (error) => void | 登录失败的回调 - - -### request -进行带会话的请求。 - -#### 语法 -```js -qcloud.request(options); -``` - -#### 参数 -|参数         |类型 |说明 -|-------------|---------------|-------------- -|options     |PlainObject   | 会话服务登录地址 -|options.login | bool         | 是否自动登录以获取会话,默认为 false -|options.url   | string       | 必填,要请求的地址 -|options.header | PlainObject | 请求头设置,不允许设置 Referer -|options.method | string     | 请求的方法,默认为 GET -|options.success | (response) => void | 登录成功的回调。
  • `response.statusCode`:请求返回的状态码
  • `response.data`:请求返回的数据
-|options.error | (error) => void | 登录失败的回调 -|options.complete | () => void | 登录完成后回调,无论成功还是失败 - -### Tunnel - -表示一个信道。由于小程序的限制,同一时间只能有一个打开的信道。 - -#### constructor - -##### 语法 -```js -var tunnel = new Tunnel(tunnelUrl); -``` - -#### 参数 -|参数         |类型 |说明 -|-------------|---------------|-------------- -|tunnelUrl   |String   | 会话服务登录地址 - - -#### on -监听信道上的事件。信道上事件包括系统事件和服务器推送消息。 - -##### 语法 -```js -tunnel.on(type, listener); -``` - -##### 参数 -|参数         |类型 |说明 -|-------------|---------------|-------------- -|type       |string     | 监听的事件类型 -|listener     |(message?: any) => void | 监听器,具体类型的事件发生时调用监听器。如果是消息,则会有消息内容。 - -##### 事件 -|事件 |说明 -|-------------|------------------------------- -|connect |信道连接成功后回调 -|close |信道关闭后回调 -|reconnecting |信道发生重连时回调 -|reconnected |信道重连成功后回调 -|error |信道发生错误后回调 -|[message]   |信道服务器推送过来的消息类型,如果消息类型和上面内置的时间类型冲突,需要在监听的时候在消息类型前加 `@` -|\*           |监听所有事件和消息,监听器第一个参数接收到时间或消息类型  - -#### open -打开信道,建立连接。由于小程序的限制,同一时间只能有一个打开的信道。 - -##### 语法 -```js -tunnel.open(); -``` - -#### emit -向信道推送消息。 - -##### 语法 -```js -tunnel.emit(type, content); -``` - -##### 参数 -|参数         |类型 |说明 -|-------------|---------------|-------------- -|type       |string       | 要推送的消息的类型 -|content |any | 要推送的消息的内容 - -#### close -关闭信道 - -##### 语法 -```js -tunnel.close(); -``` - -## LICENSE - -[MIT](LICENSE) diff --git a/vendors/wafer-client-sdk/bower.json b/vendors/wafer-client-sdk/bower.json deleted file mode 100644 index 7019494..0000000 --- a/vendors/wafer-client-sdk/bower.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "wafer-client-sdk", - "description": "QCloud 微信小程序客户端 SDK", - "main": "index.js", - "authors": [ - "Tencent Cloud" - ], - "license": "MIT", - "keywords": [ - "qcloud", - "weapp", - "wechat", - "sdk", - "client", - "auth", - "websocket" - ], - "homepage": "", - "ignore": [ - "**/.*", - "node_modules", - "bower_components", - "test", - "tests", - "typings.json", - "jsconfig.json", - "package.json", - ".npmignore", - ".travis.yml", - ".gitignore" - ] -} diff --git a/vendors/wafer-client-sdk/index.js b/vendors/wafer-client-sdk/index.js deleted file mode 100644 index 709a172..0000000 --- a/vendors/wafer-client-sdk/index.js +++ /dev/null @@ -1,26 +0,0 @@ -var constants = require('./lib/constants'); -var login = require('./lib/login'); -var Session = require('./lib/session'); -var request = require('./lib/request'); -var Tunnel = require('./lib/tunnel'); - -var exports = module.exports = { - login: login.login, - setLoginUrl: login.setLoginUrl, - LoginError: login.LoginError, - - clearSession: Session.clear, - - request: request.request, - buildSessionHeader: request.buildSessionHeader, - RequestError: request.RequestError, - - Tunnel: Tunnel, -}; - -// 导出错误类型码 -Object.keys(constants).forEach(function (key) { - if (key.indexOf('ERR_') === 0) { - exports[key] = constants[key]; - } -}); \ No newline at end of file diff --git a/vendors/wafer-client-sdk/lib/constants.js b/vendors/wafer-client-sdk/lib/constants.js deleted file mode 100644 index fbede43..0000000 --- a/vendors/wafer-client-sdk/lib/constants.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - WX_HEADER_CODE: 'X-WX-Code', - WX_HEADER_ENCRYPTED_DATA: 'X-WX-Encrypted-Data', - WX_HEADER_IV: 'X-WX-IV', - WX_HEADER_ID: 'X-WX-Id', - WX_HEADER_SKEY: 'X-WX-Skey', - - WX_SESSION_MAGIC_ID: 'F2C224D4-2BCE-4C64-AF9F-A6D872000D1A', - - ERR_INVALID_PARAMS: 'ERR_INVALID_PARAMS', - - ERR_WX_LOGIN_FAILED: 'ERR_WX_LOGIN_FAILED', - ERR_WX_GET_USER_INFO: 'ERR_WX_GET_USER_INFO', - ERR_LOGIN_TIMEOUT: 'ERR_LOGIN_TIMEOUT', - ERR_LOGIN_FAILED: 'ERR_LOGIN_FAILED', - ERR_LOGIN_SESSION_NOT_RECEIVED: 'ERR_LOGIN_MISSING_SESSION', - - ERR_INVALID_SESSION: 'ERR_INVALID_SESSION', - ERR_CHECK_LOGIN_FAILED: 'ERR_CHECK_LOGIN_FAILED', -}; \ No newline at end of file diff --git a/vendors/wafer-client-sdk/lib/login.js b/vendors/wafer-client-sdk/lib/login.js deleted file mode 100644 index 3212d6a..0000000 --- a/vendors/wafer-client-sdk/lib/login.js +++ /dev/null @@ -1,175 +0,0 @@ -var utils = require('./utils'); -var constants = require('./constants'); -var Session = require('./session'); - -/*** - * @class - * 表示登录过程中发生的异常 - */ -var LoginError = (function () { - function LoginError(type, message) { - Error.call(this, message); - this.type = type; - this.message = message; - } - - LoginError.prototype = new Error(); - LoginError.prototype.constructor = LoginError; - - return LoginError; -})(); - -/** - * 微信登录,获取 code 和 encryptData - */ -var getWxLoginResult = function getLoginCode(callback) { - wx.login({ - success: function (loginResult) { - - wx.getUserInfo({ - withCredentials: true, - success: function (res) { - //此处为获取微信信息后的业务方法 - - callback(null, { - code: loginResult.code, - encryptedData: userResult.encryptedData, - iv: userResult.iv, - userInfo: userResult.userInfo, - }); - }, - fail: function () { - //获取用户信息失败后。请跳转授权页面 - wx.showModal({ - title: '警告', - content: '尚未进行授权,请点击确定跳转到授权页面进行授权。', - success: function (res) { - if (res.confirm) { - console.log('用户点击确定') - wx.navigateTo({ - url: '../shouquan/shouquan', - }) - } - } - }) - }, - }); - }, - - fail: function (loginError) { - var error = new LoginError(constants.ERR_WX_LOGIN_FAILED, '微信登录失败,请检查网络状态'); - error.detail = loginError; - callback(error, null); - }, - }); -}; - -var noop = function noop() {}; -var defaultOptions = { - method: 'GET', - success: noop, - fail: noop, - loginUrl: null, -}; - -/** - * @method - * 进行服务器登录,以获得登录会话 - * - * @param {Object} options 登录配置 - * @param {string} options.loginUrl 登录使用的 URL,服务器应该在这个 URL 上处理登录请求 - * @param {string} [options.method] 请求使用的 HTTP 方法,默认为 "GET" - * @param {Function} options.success(userInfo) 登录成功后的回调函数,参数 userInfo 微信用户信息 - * @param {Function} options.fail(error) 登录失败后的回调函数,参数 error 错误信息 - */ -var login = function login(options) { - options = utils.extend({}, defaultOptions, options); - - if (!defaultOptions.loginUrl) { - options.fail(new LoginError(constants.ERR_INVALID_PARAMS, '登录错误:缺少登录地址,请通过 setLoginUrl() 方法设置登录地址')); - return; - } - - var doLogin = () => getWxLoginResult(function (wxLoginError, wxLoginResult) { - if (wxLoginError) { - options.fail(wxLoginError); - return; - } - - var userInfo = wxLoginResult.userInfo; - - // 构造请求头,包含 code、encryptedData 和 iv - var code = wxLoginResult.code; - var encryptedData = wxLoginResult.encryptedData; - var iv = wxLoginResult.iv; - var header = {}; - - header[constants.WX_HEADER_CODE] = code; - header[constants.WX_HEADER_ENCRYPTED_DATA] = encryptedData; - header[constants.WX_HEADER_IV] = iv; - - // 请求服务器登录地址,获得会话信息 - wx.request({ - url: options.loginUrl, - header: header, - method: options.method, - data: options.data, - - success: function (result) { - var data = result.data; - - // 成功地响应会话信息 - if (data && data[constants.WX_SESSION_MAGIC_ID]) { - if (data.session) { - data.session.userInfo = userInfo; - Session.set(data.session); - options.success(userInfo); - } else { - var errorMessage = '登录失败(' + data.error + '):' + (data.message || '未知错误'); - var noSessionError = new LoginError(constants.ERR_LOGIN_SESSION_NOT_RECEIVED, errorMessage); - options.fail(noSessionError); - } - - // 没有正确响应会话信息 - } else { - var errorMessage = '登录请求没有包含会话响应,请确保服务器处理 `' + options.loginUrl + '` 的时候正确使用了 SDK 输出登录结果'; - var noSessionError = new LoginError(constants.ERR_LOGIN_SESSION_NOT_RECEIVED, errorMessage); - options.fail(noSessionError); - } - }, - - // 响应错误 - fail: function (loginResponseError) { - var error = new LoginError(constants.ERR_LOGIN_FAILED, '登录失败,可能是网络错误或者服务器发生异常'); - options.fail(error); - }, - }); - }); - - var session = Session.get(); - if (session) { - wx.checkSession({ - success: function () { - options.success(session.userInfo); - }, - - fail: function () { - Session.clear(); - doLogin(); - }, - }); - } else { - doLogin(); - } -}; - -var setLoginUrl = function (loginUrl) { - defaultOptions.loginUrl = loginUrl; -}; - -module.exports = { - LoginError: LoginError, - login: login, - setLoginUrl: setLoginUrl, -}; - diff --git a/vendors/wafer-client-sdk/lib/request.js b/vendors/wafer-client-sdk/lib/request.js deleted file mode 100644 index 1797283..0000000 --- a/vendors/wafer-client-sdk/lib/request.js +++ /dev/null @@ -1,125 +0,0 @@ -var constants = require('./constants'); -var utils = require('./utils'); -var Session = require('./session'); -var loginLib = require('./login'); - -var noop = function noop() {}; - -var buildSessionHeader = function buildSessionHeader() { - var session = Session.get(); - var header = {}; - - if (session && session.id && session.skey) { - header[constants.WX_HEADER_ID] = session.id; - header[constants.WX_HEADER_SKEY] = session.skey; - } - - return header; -}; - -/*** - * @class - * 表示请求过程中发生的异常 - */ -var RequestError = (function () { - function RequestError(type, message) { - Error.call(this, message); - this.type = type; - this.message = message; - } - - RequestError.prototype = new Error(); - RequestError.prototype.constructor = RequestError; - - return RequestError; -})(); - -function request(options) { - if (typeof options !== 'object') { - var message = '请求传参应为 object 类型,但实际传了 ' + (typeof options) + ' 类型'; - throw new RequestError(constants.ERR_INVALID_PARAMS, message); - } - - var requireLogin = options.login; - var success = options.success || noop; - var fail = options.fail || noop; - var complete = options.complete || noop; - var originHeader = options.header || {}; - - // 成功回调 - var callSuccess = function () { - success.apply(null, arguments); - complete.apply(null, arguments); - }; - - // 失败回调 - var callFail = function (error) { - fail.call(null, error); - complete.call(null, error); - }; - - // 是否已经进行过重试 - var hasRetried = false; - - if (requireLogin) { - doRequestWithLogin(); - } else { - doRequest(); - } - - // 登录后再请求 - function doRequestWithLogin() { - loginLib.login({ success: doRequest, fail: callFail }); - } - - // 实际进行请求的方法 - function doRequest() { - var authHeader = buildSessionHeader(); - - wx.request(utils.extend({}, options, { - header: utils.extend({}, originHeader, authHeader), - - success: function (response) { - var data = response.data; - - // 如果响应的数据里面包含 SDK Magic ID,表示被服务端 SDK 处理过,此时一定包含登录态失败的信息 - if (data && data[constants.WX_SESSION_MAGIC_ID]) { - // 清除登录态 - Session.clear(); - - var error, message; - if (data.error === constants.ERR_INVALID_SESSION) { - // 如果是登录态无效,并且还没重试过,会尝试登录后刷新凭据重新请求 - if (!hasRetried) { - hasRetried = true; - doRequestWithLogin(); - return; - } - - message = '登录态已过期'; - error = new RequestError(data.error, message); - - } else { - message = '鉴权服务器检查登录态发生错误(' + (data.error || 'OTHER') + '):' + (data.message || '未知错误'); - error = new RequestError(constants.ERR_CHECK_LOGIN_FAILED, message); - } - - callFail(error); - return; - } - - callSuccess.apply(null, arguments); - }, - - fail: callFail, - complete: noop, - })); - }; - -}; - -module.exports = { - RequestError: RequestError, - request: request, - buildSessionHeader: buildSessionHeader -}; \ No newline at end of file diff --git a/vendors/wafer-client-sdk/lib/session.js b/vendors/wafer-client-sdk/lib/session.js deleted file mode 100644 index eb37d82..0000000 --- a/vendors/wafer-client-sdk/lib/session.js +++ /dev/null @@ -1,18 +0,0 @@ -var constants = require('./constants'); -var SESSION_KEY = 'weapp_session_' + constants.WX_SESSION_MAGIC_ID; - -var Session = { - get: function () { - return wx.getStorageSync(SESSION_KEY) || null; - }, - - set: function (session) { - wx.setStorageSync(SESSION_KEY, session); - }, - - clear: function () { - wx.removeStorageSync(SESSION_KEY); - }, -}; - -module.exports = Session; \ No newline at end of file diff --git a/vendors/wafer-client-sdk/lib/tunnel.js b/vendors/wafer-client-sdk/lib/tunnel.js deleted file mode 100644 index e94c7df..0000000 --- a/vendors/wafer-client-sdk/lib/tunnel.js +++ /dev/null @@ -1,528 +0,0 @@ -var requestLib = require('./request'); -var wxTunnel = require('./wxTunnel'); - -/** - * 当前打开的信道,同一时间只能有一个信道打开 - */ -var currentTunnel = null; - -// 信道状态枚举 -var STATUS_CLOSED = Tunnel.STATUS_CLOSED = 'CLOSED'; -var STATUS_CONNECTING = Tunnel.STATUS_CONNECTING = 'CONNECTING'; -var STATUS_ACTIVE = Tunnel.STATUS_ACTIVE = 'ACTIVE'; -var STATUS_RECONNECTING = Tunnel.STATUS_RECONNECTING = 'RECONNECTING'; - -// 错误类型枚举 -var ERR_CONNECT_SERVICE = Tunnel.ERR_CONNECT_SERVICE = 1001; -var ERR_CONNECT_SOCKET = Tunnel.ERR_CONNECT_SOCKET = 1002; -var ERR_RECONNECT = Tunnel.ERR_RECONNECT = 2001; -var ERR_SOCKET_ERROR = Tunnel.ERR_SOCKET_ERROR = 3001; - -// 包类型枚举 -var PACKET_TYPE_MESSAGE = 'message'; -var PACKET_TYPE_PING = 'ping'; -var PACKET_TYPE_PONG = 'pong'; -var PACKET_TYPE_TIMEOUT = 'timeout'; -var PACKET_TYPE_CLOSE = 'close'; - -// 断线重连最多尝试 5 次 -var DEFAULT_MAX_RECONNECT_TRY_TIMES = 5; - -// 每次重连前,等待时间的增量值 -var DEFAULT_RECONNECT_TIME_INCREASE = 1000; - -function Tunnel(serviceUrl) { - if (currentTunnel && currentTunnel.status !== STATUS_CLOSED) { - throw new Error('当前有未关闭的信道,请先关闭之前的信道,再打开新信道'); - } - - currentTunnel = this; - - // 等确认微信小程序全面支持 ES6 就不用那么麻烦了 - var me = this; - - //========================================================================= - // 暴露实例状态以及方法 - //========================================================================= - this.serviceUrl = serviceUrl; - this.socketUrl = null; - this.status = null; - - this.open = openConnect; - this.on = registerEventHandler; - this.emit = emitMessagePacket; - this.close = close; - - this.isClosed = isClosed; - this.isConnecting = isConnecting; - this.isActive = isActive; - this.isReconnecting = isReconnecting; - - - //========================================================================= - // 信道状态处理,状态说明: - // closed - 已关闭 - // connecting - 首次连接 - // active - 当前信道已经在工作 - // reconnecting - 断线重连中 - //========================================================================= - function isClosed() { return me.status === STATUS_CLOSED; } - function isConnecting() { return me.status === STATUS_CONNECTING; } - function isActive() { return me.status === STATUS_ACTIVE; } - function isReconnecting() { return me.status === STATUS_RECONNECTING; } - - function setStatus(status) { - var lastStatus = me.status; - if (lastStatus !== status) { - me.status = status; - } - } - - // 初始为关闭状态 - setStatus(STATUS_CLOSED); - - - //========================================================================= - // 信道事件处理机制 - // 信道事件包括: - // connect - 连接已建立 - // close - 连接被关闭(包括主动关闭和被动关闭) - // reconnecting - 开始重连 - // reconnect - 重连成功 - // error - 发生错误,其中包括连接失败、重连失败、解包失败等等 - // [message] - 信道服务器发送过来的其它事件类型,如果事件类型和上面内置的事件类型冲突,将在事件类型前面添加前缀 `@` - //========================================================================= - var preservedEventTypes = 'connect,close,reconnecting,reconnect,error'.split(','); - var eventHandlers = []; - - /** - * 注册消息处理函数 - * @param {string} messageType 支持内置消息类型("connect"|"close"|"reconnecting"|"reconnect"|"error")以及业务消息类型 - */ - function registerEventHandler(eventType, eventHandler) { - if (typeof eventHandler === 'function') { - eventHandlers.push([eventType, eventHandler]); - } - } - - /** - * 派发事件,通知所有处理函数进行处理 - */ - function dispatchEvent(eventType, eventPayload) { - eventHandlers.forEach(function (handler) { - var handleType = handler[0]; - var handleFn = handler[1]; - - if (handleType === '*') { - handleFn(eventType, eventPayload); - } else if (handleType === eventType) { - handleFn(eventPayload); - } - }); - } - - /** - * 派发事件,事件类型和系统保留冲突的,事件名会自动加上 '@' 前缀 - */ - function dispatchEscapedEvent(eventType, eventPayload) { - if (preservedEventTypes.indexOf(eventType) > -1) { - eventType = '@' + eventType; - } - - dispatchEvent(eventType, eventPayload); - } - - - //========================================================================= - // 信道连接控制 - //========================================================================= - var isFirstConnection = true; - var isOpening = false; - - /** - * 连接信道服务器,获取 WebSocket 连接地址,获取地址成功后,开始进行 WebSocket 连接 - */ - function openConnect() { - if (isOpening) return; - isOpening = true; - - // 只有关闭状态才会重新进入准备中 - setStatus(isFirstConnection ? STATUS_CONNECTING : STATUS_RECONNECTING); - - requestLib.request({ - url: serviceUrl, - method: 'GET', - success: function (response) { - if (+response.statusCode === 200 && response.data && response.data.url) { - openSocket(me.socketUrl = response.data.url); - } else { - dispatchConnectServiceError(response); - } - }, - fail: dispatchConnectServiceError, - complete: () => isOpening = false, - }); - - function dispatchConnectServiceError(detail) { - if (isFirstConnection) { - setStatus(STATUS_CLOSED); - - dispatchEvent('error', { - code: ERR_CONNECT_SERVICE, - message: '连接信道服务失败,网络错误或者信道服务没有正确响应', - detail: detail || null, - }); - - } else { - startReconnect(detail); - } - } - } - - /** - * 打开 WebSocket 连接,打开后,注册微信的 Socket 处理方法 - */ - function openSocket(url) { - wxTunnel.listen({ - onOpen: handleSocketOpen, - onMessage: handleSocketMessage, - onClose: handleSocketClose, - onError: handleSocketError, - }); - - wx.connectSocket({ url: url }); - isFirstConnection = false; - } - - - //========================================================================= - // 处理消息通讯 - // - // packet - 数据包,序列化形式为 `${type}` 或者 `${type}:${content}` - // packet.type - 包类型,包括 message, ping, pong, close - // packet.content? - 当包类型为 message 的时候,会附带 message 数据 - // - // message - 消息体,会使用 JSON 序列化后作为 packet.content - // message.type - 消息类型,表示业务消息类型 - // message.content? - 消息实体,可以为任意类型,表示消息的附带数据,也可以为空 - // - // 数据包示例: - // - 'ping' 表示 Ping 数据包 - // - 'message:{"type":"speak","content":"hello"}' 表示一个打招呼的数据包 - //========================================================================= - - // 连接还没成功建立的时候,需要发送的包会先存放到队列里 - var queuedPackets = []; - - /** - * WebSocket 打开之后,更新状态,同时发送所有遗留的数据包 - */ - function handleSocketOpen() { - /* istanbul ignore else */ - if (isConnecting()) { - dispatchEvent('connect'); - - } - else if (isReconnecting()) { - dispatchEvent('reconnect'); - resetReconnectionContext(); - } - - setStatus(STATUS_ACTIVE); - emitQueuedPackets(); - nextPing(); - } - - /** - * 收到 WebSocket 数据包,交给处理函数 - */ - function handleSocketMessage(message) { - resolvePacket(message.data); - } - - /** - * 发送数据包,如果信道没有激活,将先存放队列 - */ - function emitPacket(packet) { - if (isActive()) { - sendPacket(packet); - } else { - queuedPackets.push(packet); - } - } - - /** - * 数据包推送到信道 - */ - function sendPacket(packet) { - var encodedPacket = [packet.type]; - - if (packet.content) { - encodedPacket.push(JSON.stringify(packet.content)); - } - - wx.sendSocketMessage({ - data: encodedPacket.join(':'), - fail: handleSocketError, - }); - } - - function emitQueuedPackets() { - queuedPackets.forEach(emitPacket); - - // empty queued packets - queuedPackets.length = 0; - } - - /** - * 发送消息包 - */ - function emitMessagePacket(messageType, messageContent) { - var packet = { - type: PACKET_TYPE_MESSAGE, - content: { - type: messageType, - content: messageContent, - }, - }; - - emitPacket(packet); - } - - /** - * 发送 Ping 包 - */ - function emitPingPacket() { - emitPacket({ type: PACKET_TYPE_PING }); - } - - /** - * 发送关闭包 - */ - function emitClosePacket() { - emitPacket({ type: PACKET_TYPE_CLOSE }); - } - - /** - * 解析并处理从信道接收到的包 - */ - function resolvePacket(raw) { - var packetParts = raw.split(':'); - var packetType = packetParts.shift(); - var packetContent = packetParts.join(':') || null; - var packet = { type: packetType }; - - if (packetContent) { - try { - packet.content = JSON.parse(packetContent); - } catch (e) {} - } - - switch (packet.type) { - case PACKET_TYPE_MESSAGE: - handleMessagePacket(packet); - break; - case PACKET_TYPE_PONG: - handlePongPacket(packet); - break; - case PACKET_TYPE_TIMEOUT: - handleTimeoutPacket(packet); - break; - case PACKET_TYPE_CLOSE: - handleClosePacket(packet); - break; - default: - handleUnknownPacket(packet); - break; - } - } - - /** - * 收到消息包,直接 dispatch 给处理函数 - */ - function handleMessagePacket(packet) { - var message = packet.content; - dispatchEscapedEvent(message.type, message.content); - } - - - //========================================================================= - // 心跳、断开与重连处理 - //========================================================================= - - /** - * Ping-Pong 心跳检测超时控制,这个值有两个作用: - * 1. 表示收到服务器的 Pong 相应之后,过多久再发下一次 Ping - * 2. 如果 Ping 发送之后,超过这个时间还没收到 Pong,断开与服务器的连接 - * 该值将在与信道服务器建立连接后被更新 - */ - let pingPongTimeout = 15000; - let pingTimer = 0; - let pongTimer = 0; - - /** - * 信道服务器返回 Ping-Pong 控制超时时间 - */ - function handleTimeoutPacket(packet) { - var timeout = packet.content * 1000; - /* istanbul ignore else */ - if (!isNaN(timeout)) { - pingPongTimeout = timeout; - ping(); - } - } - - /** - * 收到服务器 Pong 响应,定时发送下一个 Ping - */ - function handlePongPacket(packet) { - nextPing(); - } - - /** - * 发送下一个 Ping 包 - */ - function nextPing() { - clearTimeout(pingTimer); - clearTimeout(pongTimer); - pingTimer = setTimeout(ping, pingPongTimeout); - } - - /** - * 发送 Ping,等待 Pong - */ - function ping() { - /* istanbul ignore else */ - if (isActive()) { - emitPingPacket(); - - // 超时没有响应,关闭信道 - pongTimer = setTimeout(handlePongTimeout, pingPongTimeout); - } - } - - /** - * Pong 超时没有响应,信道可能已经不可用,需要断开重连 - */ - function handlePongTimeout() { - startReconnect('服务器已失去响应'); - } - - // 已经重连失败的次数 - var reconnectTryTimes = 0; - - // 最多允许失败次数 - var maxReconnectTryTimes = Tunnel.MAX_RECONNECT_TRY_TIMES || DEFAULT_MAX_RECONNECT_TRY_TIMES; - - // 重连前等待的时间 - var waitBeforeReconnect = 0; - - // 重连前等待时间增量 - var reconnectTimeIncrease = Tunnel.RECONNECT_TIME_INCREASE || DEFAULT_RECONNECT_TIME_INCREASE; - - var reconnectTimer = 0; - - function startReconnect(lastError) { - if (reconnectTryTimes >= maxReconnectTryTimes) { - close(); - - dispatchEvent('error', { - code: ERR_RECONNECT, - message: '重连失败', - detail: lastError, - }); - } - else { - wx.closeSocket(); - waitBeforeReconnect += reconnectTimeIncrease; - setStatus(STATUS_RECONNECTING); - reconnectTimer = setTimeout(doReconnect, waitBeforeReconnect); - } - - if (reconnectTryTimes === 0) { - dispatchEvent('reconnecting'); - } - - reconnectTryTimes += 1; - } - - function doReconnect() { - openConnect(); - } - - function resetReconnectionContext() { - reconnectTryTimes = 0; - waitBeforeReconnect = 0; - } - - /** - * 收到服务器的关闭请求 - */ - function handleClosePacket(packet) { - close(); - } - - function handleUnknownPacket(packet) { - // throw away - } - - var isClosing = false; - - /** - * 收到 WebSocket 断开的消息,处理断开逻辑 - */ - function handleSocketClose() { - /* istanbul ignore if */ - if (isClosing) return; - - /* istanbul ignore else */ - if (isActive()) { - // 意外断开的情况,进行重连 - startReconnect('链接已断开'); - } - } - - function close() { - isClosing = true; - closeSocket(); - setStatus(STATUS_CLOSED); - resetReconnectionContext(); - isFirstConnection = false; - clearTimeout(pingTimer); - clearTimeout(pongTimer); - clearTimeout(reconnectTimer); - dispatchEvent('close'); - isClosing = false; - } - - function closeSocket(emitClose) { - if (isActive() && emitClose !== false) { - emitClosePacket(); - } - - wx.closeSocket(); - } - - - //========================================================================= - // 错误处理 - //========================================================================= - - /** - * 错误处理 - */ - function handleSocketError(detail) { - switch (me.status) { - case Tunnel.STATUS_CONNECTING: - dispatchEvent('error', { - code: ERR_SOCKET_ERROR, - message: '连接信道失败,网络错误或者信道服务不可用', - detail: detail, - }); - break; - } - } - -} - -module.exports = Tunnel; \ No newline at end of file diff --git a/vendors/wafer-client-sdk/lib/utils.js b/vendors/wafer-client-sdk/lib/utils.js deleted file mode 100644 index 67fdcd4..0000000 --- a/vendors/wafer-client-sdk/lib/utils.js +++ /dev/null @@ -1,18 +0,0 @@ - -/** - * 拓展对象 - */ -exports.extend = function extend(target) { - var sources = Array.prototype.slice.call(arguments, 1); - - for (var i = 0; i < sources.length; i += 1) { - var source = sources[i]; - for (var key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - } - - return target; -}; \ No newline at end of file diff --git a/vendors/wafer-client-sdk/lib/wxTunnel.js b/vendors/wafer-client-sdk/lib/wxTunnel.js deleted file mode 100644 index a1d32be..0000000 --- a/vendors/wafer-client-sdk/lib/wxTunnel.js +++ /dev/null @@ -1,32 +0,0 @@ -/* istanbul ignore next */ -const noop = () => void(0); - -let onOpen, onClose, onMessage, onError; - -/* istanbul ignore next */ -function listen(listener) { - if (listener) { - onOpen = listener.onOpen; - onClose = listener.onClose; - onMessage = listener.onMessage; - onError = listener.onError; - } else { - onOpen = noop; - onClose = noop; - onMessage = noop; - onError = noop; - } -} - -/* istanbul ignore next */ -function bind() { - wx.onSocketOpen(result => onOpen(result)); - wx.onSocketClose(result => onClose(result)); - wx.onSocketMessage(result => onMessage(result)); - wx.onSocketError(error => onError(error)); -} - -listen(null); -bind(); - -module.exports = { listen }; \ No newline at end of file diff --git a/读我.txt b/读我.txt deleted file mode 100644 index 47dd6d7..0000000 --- a/读我.txt +++ /dev/null @@ -1,15 +0,0 @@ -# 后台数据交互部分日志 - -## 已完成-登录微信公众平台,前往 设置 > 开发设置 > 服务器配置 > 「修改」 链接,增加下述域名为白名单中的域名 -request合法域名 -fqcxn98z.api.lncldglobal.com -fqcxn98z.engine.lncldglobal.com -fqcxn98z.rtm.lncldglobal.com -fqcxn98z.push.lncldglobal.com -app-router.leancloud.cn -socket合法域名 -us-w1-backend2.leancloud.cn -us-w1-backend3.leancloud.cn -us-w1-backend4.leancloud.cn -us-w1-backend5.leancloud.cn -us-w1-backend6.leancloud.cn