增加加载动画,输入框下拉联想

smart_class
educoder_weapp 5 years ago
parent 6706b92f9f
commit 8ed4f73a4b

@ -1,6 +1,9 @@
# 简介 # 简介
educoder微信小程序帮助使用[educoder平台](https://www.educoder.net)的应用方便在手机上使用。利用educoder网站的API搭建 educoder微信小程序帮助使用[educoder平台](https://www.educoder.net)的应用方便在手机上使用。利用educoder网站的API搭建
## 源码
[https://github/jinke18/smart_class](https://github.com/jinke18/smart_class)
## 小程序码 ## 小程序码
![小程序码](./images/weapp_code.png) ![小程序码](./images/weapp_code.png)

@ -1,4 +1,10 @@
import {Account, Course, Exercise, ExerciseQuestion, Ui} from "./eduapi" /**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
import {Account, Course, Exercise, ExerciseQuestion, School, Ui} from "./eduapi"
import {Session} from "./requests"; import {Session} from "./requests";
import {Cookie} from "./cookie"; import {Cookie} from "./cookie";
@ -507,7 +513,25 @@ 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);
}
});
});
}
get_home_page({success, fail, complete}={}){ get_home_page({success, fail, complete}={}){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Ui.get_home_page({ Ui.get_home_page({

@ -1,3 +1,9 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
/** /**
* Cookie类用于网络中cookie的各类操作 * Cookie类用于网络中cookie的各类操作
*/ */

@ -1,3 +1,9 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
const api_base_url = "https://www.educoder.net/api"; const api_base_url = "https://www.educoder.net/api";
/** /**
* https://www.educoder.net的api接口通过其实现用户与后端进行交互 * https://www.educoder.net的api接口通过其实现用户与后端进行交互
@ -154,7 +160,27 @@ export class Account{
} }
} }
export class School{
static search({ session, search = "", success, fail, complete}){
let data = {search: search};
session.request({
url: api_base_url + "/schools/school_list.json",
method: "GET",
data: data,
success: res => {
if ("status" in res.data && res.data.status < 0) {
fail(new Error(res.data.message));
return;
}
if (typeof success == "function") {
success(res);
}
},
fail: fail,
complete: complete
})
}
}
export class Course{ export class Course{
static create({session, data, success, fail, complete}){ static create({session, data, success, fail, complete}){
return session.request({ return session.request({

@ -1,3 +1,4 @@
/** /**
* @todo: Error类, to be finished * @todo: Error类, to be finished
*/ */

@ -1,3 +1,8 @@
/**
* https://github.com/jinke18/educoder_weapp
* @licence GPL-3.0
* @author jinke18
*/
import {Cookie} from "./cookie"; import {Cookie} from "./cookie";
/** /**

@ -0,0 +1 @@
<svg width='200px' height='200px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-default"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(0 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-1s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(30 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.9166666666666666s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(60 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.8333333333333334s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(90 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.75s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(120 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.6666666666666666s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(150 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.5833333333333334s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(180 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.5s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(210 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.4166666666666667s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(240 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.3333333333333333s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(270 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.25s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(300 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.16666666666666666s' repeatCount='indefinite'/></rect><rect x='46.5' y='40' width='7' height='20' rx='5' ry='5' fill='#1ed600' transform='rotate(330 50 50) translate(0 -30)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='-0.08333333333333333s' repeatCount='indefinite'/></rect></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@ -6,8 +6,7 @@ Page({
/** /**
* 页面的初始数据 * 页面的初始数据
*/ */
md: '# 功能介绍\n\n## 教室\n- 学员可以输入邀请码进入课堂\n\n- 进入教室界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像\n\n- 教员在教室界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作\n\n- 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答”\n\n- 教室内有讨论区,可以交流\n\n## 课程资源\n\n- 在课程界面进入“资源”可以查看本课堂的课程文件资源\n\n- 支持打开ppt doc xls pdf文件\n\n## 试卷作答\n\n- 学员在课程内可以看到老师发布的试卷,并且回答\n\n- 试卷截止后可以学生可以看到公布的答案' md: '# 简介\neducoder微信小程序帮助使用[educoder平台](https://www.educoder.net)的应用方便在手机上使用。利用educoder网站的API搭建\n\n## 源码\n[https://github/jinke18/smart_class](https://github.com/jinke18/smart_class)\n\n## 小程序码\n![小程序码](../../images/weapp_code.png)\n\n\n# 功能介绍\n\n## 教室\n- 学员可以输入邀请码进入课堂\n\n- 进入教室界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像\n\n- 教员在教室界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作\n\n- 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答”\n\n- 教室内有讨论区,可以交流\n\n## 课程资源\n\n- 在课程界面进入“资源”可以查看本课堂的课程文件资源\n\n- 支持打开ppt doc xls pdf文件\n\n## 试卷作答\n\n- 学员在课程内可以看到老师发布的试卷,并且回答\n\n- 试卷截止后可以学生可以看到公布的答案',
,
data: { data: {
article: {} article: {}

@ -18,11 +18,13 @@ Page({
course_group: true, course_group: true,
//course_module_types //course_module_types
end_date: "", end_date: "",
school: "" school: app.client.current_user.school
}, },
data: { data: {
current_date: getNowFormatDate(), current_date: getNowFormatDate(),
form_data: {} form_data: {},
bindSource: [], //绑定到页面的数据,根据用户输入动态变化
hideScroll: true,
}, },
reset: function () { reset: function () {
this.setData({ form_data: this.initial_form_data }); this.setData({ form_data: this.initial_form_data });
@ -52,6 +54,47 @@ Page({
}) })
} }
}, },
itemtap: function (e) {
console.log(e);
this.setData({
"form_data.school": e.currentTarget.id,
hideScroll: true
})
},
leaveSchool: function(){
},
focusSchool: function({detail:{value}}){
if(this.data.bindSource.length==0){
app.client.search_schools({ search: value })
.then(res => {
console.log(res);
const schools = res.data.school_names;
this.setData({
bindSource: schools,
});
})
}
this.setData({hideScroll: false});
},
updateSchool: function({detail:{value}}){
console.log("updateSchool");
if(!value){
this.setData({
hideScroll: true,
})
}else{
app.client.search_schools({ search: value })
.then(res => {
console.log(res);
const schools = res.data.school_names;
this.setData({
hideScroll: false,
bindSource: schools,
});
})
}
},
updateCourseListName({ detail: { value } }) { updateCourseListName({ detail: { value } }) {
this.setData({ "form_data.name": value }); this.setData({ "form_data.name": value });
}, },

@ -17,6 +17,27 @@
name="name"> name="name">
</input> </input>
</view> </view>
<view class="form-item form-wrap">
<text class="hint form-item">课堂所属单位</text>
<view>
<input class="form-item"
name="school"
bindinput="updateSchool"
bindblur="leaveSchool"
bindfocus="focusSchool"
hold-keyboard="1"
cursor-spacing="200"
value="{{form_data.school}}">
</input>
</view>
<scroll-view class="selector" scroll-y="true" hidden="{{hideScroll}}">
<block wx:for="{{bindSource}}">
<view id="{{item}}" bindtap="itemtap" class="selector-item">
<text>{{item}}</text>
</view>
</block>
</scroll-view>
</view>
<view class="form-item form-wrap"> <view class="form-item form-wrap">
<text class="hint form-item">总学时</text> <text class="hint form-item">总学时</text>
<input class="form-item" <input class="form-item"
@ -68,14 +89,6 @@
<text class="hint form-item">公开设置</text> <text class="hint form-item">公开设置</text>
<checkbox name="is_public">公开课堂</checkbox> <checkbox name="is_public">公开课堂</checkbox>
</view> </view>
<view class="form-item form-wrap">
<text class="hint form-item">课堂所属单位</text>
<input class="form-item"
name="school"
bindinput="updateSchool"
value="{{form_data.school}}">
</input>
</view>
<button class="submit" form-type="submit">提交</button> <button class="submit" form-type="submit">提交</button>
</form> </form>
</view> </view>

@ -8,3 +8,22 @@ input.form-item{
margin: 24rpx -12rpx; margin: 24rpx -12rpx;
padding: 2rpx 10rpx; padding: 2rpx 10rpx;
} }
.selector{
max-height:340rpx;
border-radius:6rpx;
margin-top:8rpx;
background: white;
box-shadow: 1px 2px 10px grey;
}
.selector-item{
padding: 8rpx 18rpx;
}
.selector-item text{
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

@ -8,6 +8,7 @@ Page({
loading: true, loading: true,
page: 1, page: 1,
show_join_course_modal:false, show_join_course_modal:false,
loaded_all: false,
}, },
show_join_course_modal: function(event){ show_join_course_modal: function(event){
this.setData({show_join_course_modal: true}); this.setData({show_join_course_modal: true});
@ -95,11 +96,20 @@ Page({
onReachBottom: function () { onReachBottom: function () {
this.fetch_courses({ page: this.data.page + 1 }) if(!this.data.loaded_all){
.then(res => { wx.pageScrollTo({
this.setData({ page: this.data.page + 1 }) selector: ".loading"
this.add_courses(res.data.courses);
}) })
this.fetch_courses({ page: this.data.page + 1 })
.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);
}
})
}
}, },

@ -10,6 +10,9 @@
</view> </view>
</block> </block>
</view> </view>
<view class="loading" wx:if="{{!loaded_all}}">
<image src="../../images/loading_min.gif" style="width:20px;height:20px"></image>
</view>
</view> </view>
<!--components/modal/join_course/join_course.wxml--> <!--components/modal/join_course/join_course.wxml-->

@ -61,3 +61,8 @@ image.none-content{
lable.identity{ lable.identity{
margin-right: 16rpx; margin-right: 16rpx;
} }
.loading{
padding-top: 16rpx;
text-align: center;
}

@ -11,8 +11,9 @@
<text>实训课程</text> <text>实训课程</text>
<text class="hint">TRAINING COURSE</text> <text class="hint">TRAINING COURSE</text>
</view> </view>
<view class="loading"> <view class="loading" wx:if="{{page_status==0}}">
<!----> <!---->
<image src="../../images/loading_big.gif" style="width:50px;height:50px"></image>
</view> </view>
<view class="grid-view"> <view class="grid-view">
<view class="grid-item" wx:for="{{page_info.subjects}}" wx:for-item="subject"> <view class="grid-item" wx:for="{{page_info.subjects}}" wx:for-item="subject">
@ -32,6 +33,7 @@
</view> </view>
<view class="loading" wx:if="{{page_status==0}}"> <view class="loading" wx:if="{{page_status==0}}">
<!----> <!---->
<image src="../../images/loading_big.gif" style="width:50px;height:50px"></image>
</view> </view>
<view class="grid-view"> <view class="grid-view">
<view class="grid-item" wx:for="{{page_info.shixuns}}" wx:for-item="practice"> <view class="grid-item" wx:for="{{page_info.shixuns}}" wx:for-item="practice">

@ -61,5 +61,8 @@ text.name{
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
} }
.loading{
text-align:center;
padding: 12px 0;
}
/**动画*/ /**动画*/

@ -3,7 +3,7 @@ import WeCropper from '../../we-cropper/dist/we-cropper.min.js'
const device = wx.getSystemInfoSync() const device = wx.getSystemInfoSync()
const width = device.windowWidth const width = device.windowWidth
const height = device.windowHeight - 30 const height = device.windowHeight - 40
const app = getApp(); const app = getApp();
Page({ Page({
@ -45,14 +45,30 @@ Page({
if (avatar) { if (avatar) {
console.info("avatar"); console.info("avatar");
console.log(avatar); console.log(avatar);
wx.showLoading({
title: '上传中',
});
app.client.upload_avatar({ app.client.upload_avatar({
avatar_path: avatar, avatar_path: avatar,
success: res=>{ success: res=>{
console.log("upload avatar success"); console.log("upload avatar success");
console.log(res); console.log(res);
wx.navigateBack({
delta: 1
});
wx.showToast({
title: '更改成功',
})
}, },
fail: error=>{ fail: error=>{
console.error(error); console.error(error);
wx.showToast({
title: '失败',
icon: "none"
});
},
complete:()=>{
wx.hideLoading()
} }
}); });
} else { } else {
@ -101,6 +117,7 @@ Page({
console.log(`before canvas draw,i can do something`) console.log(`before canvas draw,i can do something`)
console.log(`current canvas context:`, ctx) console.log(`current canvas context:`, ctx)
}) })
.updateCanvas();
} }
} }
}) })

@ -11,6 +11,7 @@ left: 0;
position: fixed; position: fixed;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
height: 50px;
align-items: center align-items: center
} }

Loading…
Cancel
Save