parent
c795112f0a
commit
7bbbe466c9
@ -1,21 +1,22 @@
|
||||
# 功能介绍
|
||||
|
||||
- 学员可以在点击右下角”加入课堂”选择课程加入,教员可以在“加入课堂中”新建课程
|
||||
## 教室
|
||||
- 学员可以输入邀请码进入课堂
|
||||
|
||||
- 长按相应课程可以退出学习
|
||||
- 进入教室界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像
|
||||
|
||||
- 进入课堂界面会显示在位,头像为彩色,若退出课堂界面则会显示灰色头像
|
||||
|
||||
- 教员在课堂界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作
|
||||
- 教员在教室界面中可以直观地看到学员在位情况,可以选择学员让其起立回答问题,并且对学员可以进行加分、减分操作
|
||||
|
||||
- 学员可以收到教员让其起立提问、回答的提示,还可以点击“我要提问、回答”
|
||||
|
||||
- 课堂内有讨论区,可以交流
|
||||
- 教室内有讨论区,可以交流
|
||||
|
||||
## 课程资源
|
||||
|
||||
- 在课堂界面右下角进入“资源”可以查看本课堂的课程文件资源 # 发布版要长按白色底部栏进入
|
||||
- 在课程界面进入“资源”可以查看本课堂的课程文件资源
|
||||
|
||||
- 教员可以在课程的设置界面中更新课程的名称,还可以将学员移除本课程的学习
|
||||
- 支持打开ppt doc xls pdf文件
|
||||
|
||||
## 其他
|
||||
## 试卷作答
|
||||
|
||||
- 用户可以在设置中更改姓名、用户名
|
||||
- 学员在课程内可以看到老师发布的试卷,并且回答
|
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @todo: Error类, to be finished
|
||||
*/
|
||||
|
||||
export default class EduError extends Error{
|
||||
constructor({message=null, code=-1}){
|
||||
super(message);
|
||||
this.code = code;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 5.7 KiB |
@ -1,4 +1,4 @@
|
||||
<import src="/towxml/entry.wxml"/>
|
||||
<view class="container">
|
||||
<template is="entry" data="{{...article}}" class="about"/>
|
||||
<template is="entry" data="{{...article}}"/>
|
||||
</view>
|
@ -1,2 +1,5 @@
|
||||
<!--pages/course_detail/course_detail.wxml-->
|
||||
<text>pages/course_detail/course_detail.wxml</text>
|
||||
<view class="nav-list">
|
||||
<navigator url="../classroom/classroom?id={{course.id}}" class="nav">进入教室</navigator>
|
||||
<navigator url="../exercises/exercises?id={{course.id}}" class="nav">试卷</navigator>
|
||||
<navigator url="../files/files?id={{course.id}}" class="nav">资源</navigator>
|
||||
</view>
|
@ -1 +1,8 @@
|
||||
/* pages/course_detail/course_detail.wxss */
|
||||
.nav {
|
||||
background: white;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 0 14px;
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
// pages/exercise/exercise.js
|
||||
const app = getApp();
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
exercise_questions: [],
|
||||
loading: true,
|
||||
exercise: {}
|
||||
},
|
||||
pull_questions: function(){
|
||||
app.client.start_answer_exercise({exercise_id: this.exercise_id})
|
||||
.then(res=>{
|
||||
console.log("pull questions");
|
||||
console.log(res);
|
||||
this.setData({ exercise: res.data.exercise});
|
||||
let questions = res.data.exercise_questions;
|
||||
for(var i=0;i<questions.length;i++){
|
||||
if (questions[i]["question_type"]==3){
|
||||
let null_inputs=[];
|
||||
for (var j = 1; j<= questions[i]["multi_count"];j++){
|
||||
var user_answer = questions[i]["user_answer"].filter(answer=>answer.choice_id==j)[0]||{};
|
||||
console.log(user_answer);
|
||||
null_inputs.push({choice_id:j, answer_text:user_answer.answer_text||""});
|
||||
console.log(null_inputs);
|
||||
}
|
||||
questions[i]["null_inputs"] = null_inputs;
|
||||
console.log(questions);
|
||||
}
|
||||
}
|
||||
this.setData({ exercise_questions: questions});
|
||||
console.log(this.data);
|
||||
}).catch(console.error)
|
||||
},
|
||||
answer_null_question: function ({ detail: { value }, currentTarget: { dataset } }){
|
||||
console.log("answer_main_question");
|
||||
console.log(value);
|
||||
console.log(dataset);
|
||||
app.client.answer_exercise_question({ question_id: dataset.question_id, exercise_choice_id:dataset.exercise_choice_id, answer_text: value })
|
||||
.then(res => { console.log("answer_main_question"); console.log(res); })
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
wx.showToast({
|
||||
title: error.toString(),
|
||||
icon: "none"
|
||||
})
|
||||
});
|
||||
},
|
||||
answer_main_question: function ({ detail: { value }, currentTarget: { dataset }}){
|
||||
console.log("answer_main_question");
|
||||
console.log(value);
|
||||
console.log(dataset);
|
||||
app.client.answer_exercise_question({ question_id: dataset.question_id, answer_text: value })
|
||||
.then(res => { console.log("answer_main_question"); console.log(res); })
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
wx.showToast({
|
||||
title: error.toString(),
|
||||
icon: "none"
|
||||
})
|
||||
});
|
||||
},
|
||||
answer_choice_question: function({detail: {value}, currentTarget: {dataset}}){
|
||||
console.log("answer_question");
|
||||
console.log(value);
|
||||
console.log(dataset);
|
||||
app.client.answer_exercise_question({ question_id: dataset.question_id, exercise_choice_id: value})
|
||||
.then(res=>{console.log("answer_question");console.log(res);})
|
||||
.catch(error=>{
|
||||
console.error(error);
|
||||
wx.showToast({
|
||||
title: error.toString(),
|
||||
icon: "none"
|
||||
})
|
||||
});
|
||||
},
|
||||
save_exercise: function({show_loading=true}={}){
|
||||
if(show_loading){
|
||||
wx.showLoading({
|
||||
title: '请稍候',
|
||||
});
|
||||
}
|
||||
app.client.save_exercise({exercise_id: this.exercise_id, complete: wx.hideLoading})
|
||||
.then(res=>{
|
||||
console.log("保存答案");
|
||||
console.log(res);
|
||||
if(show_loading){
|
||||
wx.showToast({
|
||||
title: "保存成功",
|
||||
});
|
||||
}
|
||||
}).catch(console.error)
|
||||
|
||||
},
|
||||
commit_exercise: function(){
|
||||
wx.showModal({
|
||||
title: '确认',
|
||||
content: '交卷后不可更改,确定交卷吗?',
|
||||
success: res=>{
|
||||
if(res.confirm){
|
||||
app.client.save_exercise({ exercise_id: this.exercise_id})
|
||||
.then(
|
||||
()=>{
|
||||
app.client.commit_exercise({exercise_id: this.exercise_id})
|
||||
.then(res=>{
|
||||
console.log("交卷");
|
||||
console.log(res);
|
||||
wx.navigateBack({
|
||||
delta:1
|
||||
})
|
||||
wx.showToast({
|
||||
title: res.data.message
|
||||
})
|
||||
}).catch(console.error);
|
||||
}).catch(console.error);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.exercise_id = options.exercise_id;
|
||||
this.pull_questions();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
onError: function(e){
|
||||
console.error(e);
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
this.save_exercise({show_loading: false});
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
<view class="container">
|
||||
<view class="question-list">
|
||||
<block wx:for="{{exercise_questions}}" wx:for-item="question" wx:key="question_id">
|
||||
<view class="question">
|
||||
<text class="hint">第{{question.q_position}}题</text>
|
||||
<text class="question-title">{{question.question_title}}</text>
|
||||
<view wx:if="{{question.question_type==0}}">
|
||||
<radio-group class="choices" bindchange="answer_choice_question" data-question_id="{{question.question_id}}">
|
||||
<radio disabled="{{exercise.user_exercise_status==1 || exercise.user_exercise_status==4}}" class="choice" wx:for="{{question.question_choices}}" wx:for-item="choice" wx:key="choice_id" checked="{{choice.user_answer_boolean}}" value="{{choice.choice_id}}">
|
||||
<text class="choice-text">{{choice.choice_text}}</text>
|
||||
<text wx:if="{{choice.standard_boolean}}" class="error standard-choice">正确答案</text>
|
||||
</radio>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view wx:elif="{{question.question_type==1}}">
|
||||
<checkbox-group class="choices" bindchange="answer_choice_question" data-question_id="{{question.question_id}}">
|
||||
<checkbox disabled="{{exercise.user_exercise_status==1 || exercise.user_exercise_status==4}}" class="choice" wx:for="{{question.question_choices}}" wx:for-item="choice" wx:key="choice_id" checked="{{choice.user_answer_boolean}}" value="{{choice.choice_id}}">
|
||||
<text class="choice-text">{{choice.choice_text}}</text>
|
||||
<text wx:if="{{choice.standard_boolean}}" class="error standard-choice">正确答案</text>
|
||||
</checkbox>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<view wx:elif="{{question.question_type==2}}">
|
||||
<radio-group class="choices" bindchange="answer_choice_question" data-question_id="{{question.question_id}}">
|
||||
<radio disabled="{{exercise.user_exercise_status==1 || exercise.user_exercise_status==4}}" class="choice" wx:for="{{question.question_choices}}" wx:for-item="choice" wx:key="choice_id" checked="{{choice.user_answer_boolean}}" value="{{choice.choice_id}}">
|
||||
<text class="choice-text">{{choice.choice_text}}</text>
|
||||
<text wx:if="{{choice.standard_boolean}}" class="error standard-choice">正确答案</text>
|
||||
</radio>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view wx:elif="{{question.question_type==3}}">
|
||||
<block wx:for="{{question.null_inputs}}" wx:for-item="null_input">
|
||||
<view class="null-input flex-wrap">
|
||||
<text class="hint">填空{{null_input.choice_id}}</text>
|
||||
<input disabled="{{exercise.user_exercise_status==1 || exercise.user_exercise_status==4}}" class="null-input"
|
||||
placeholder="输入填空{{null_input.choice_id}}答案"
|
||||
data-question_id="{{question.question_id}}"
|
||||
data-exercise_choice_id="{{null_input.choice_id}}"
|
||||
value="{{null_input.answer_text}}"
|
||||
bindblur="answer_null_question">
|
||||
</input>
|
||||
</view>
|
||||
</block>
|
||||
<view wx:if="{{question.standard_answer}}" class="standard-null-inputs">
|
||||
<view class="standard-null-input flex-wrap" wx:for="{{question.standard_answer}}" wx:for-item="answer">
|
||||
<text class="hint">第{{answer.choice_id}}空答案:</text>
|
||||
<text class="error" style="padding-top: 6rpx;">{{answer.answer_text}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{question.question_type==4}}">
|
||||
<textarea disabled="{{exercise.user_exercise_status==1 || exercise.user_exercise_status==4}}" class="main-input"
|
||||
placeholder="输入答案"
|
||||
bindblur="answer_main_question"
|
||||
value="{{question.user_answer[0]||''}}"
|
||||
data-question_id="{{question.question_id}}">
|
||||
</textarea>
|
||||
<view wx:if="{{question.standard_answer}}" class="standard-main-input">
|
||||
<text class="hint">参考答案:</text>
|
||||
<text class="error">{{question.standard_answer[0]||'暂无'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:elif="{{question.question_type==5}}">
|
||||
<text class="hint">暂不支持实训题...</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<cover-view wx:if="{{exercise.user_exercise_status!=1 && exercise.user_exercise_status!=4}}" class="foot flex-wrap" >
|
||||
<button bindtap="save_exercise">保存</button>
|
||||
<button bindtap="commit_exercise">交卷</button>
|
||||
</cover-view>
|
@ -0,0 +1,61 @@
|
||||
.foot{
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
background: white;
|
||||
padding-top: 1px;
|
||||
border-top: 1rpx solid gray;
|
||||
bottom: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
.container{
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
.question{
|
||||
background: white;
|
||||
margin: 20rpx -6rpx;
|
||||
padding: 4rpx 20rpx 20rpx 20rpx;
|
||||
}
|
||||
|
||||
.question-title{
|
||||
display: block;
|
||||
margin: 5rpx 0rpx 12rpx 0rpx;
|
||||
}
|
||||
|
||||
.choices{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.choice{
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
.choice-text{
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.main-input{
|
||||
height: 120rpx;
|
||||
margin: 18rpx 0 4rpx 18rpx;
|
||||
border: 1rpx solid lightgray;
|
||||
border-radius: 8rpx;
|
||||
padding-left: 12rpx;
|
||||
}
|
||||
|
||||
view.null-input{
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
input.null-input{
|
||||
border: 1rpx solid lightgray;
|
||||
padding: 14rpx 5rpx;
|
||||
margin-left: 8rpx;
|
||||
border-radius: 6rpx;
|
||||
}
|
||||
|
||||
.standard-choice{
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
standard-null-input{
|
||||
align-items: center;
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
const app = getApp()
|
||||
|
||||
Page({
|
||||
allnavData: [
|
||||
{
|
||||
text: "全部",
|
||||
exercise_status: "all",
|
||||
course_identities: [2, 5, 6]
|
||||
},
|
||||
{
|
||||
text: "未发布",
|
||||
exercise_status: 1,
|
||||
course_identities: [2]
|
||||
},
|
||||
{
|
||||
text: '提交中',
|
||||
exercise_status: 2,
|
||||
course_identities: [2, 5, 6]
|
||||
},
|
||||
{
|
||||
text: '已截止',
|
||||
exercise_status: 3,
|
||||
course_identities: [2, 5, 6]
|
||||
},
|
||||
],
|
||||
data: {
|
||||
loading: true,
|
||||
exercises: [],
|
||||
navData: [
|
||||
{
|
||||
text: "全部",
|
||||
exercise_status: "all",
|
||||
course_identities: [2, 5, 6]
|
||||
},
|
||||
{
|
||||
text: '提交中',
|
||||
exercise_status: 2,
|
||||
course_identities: [2, 5, 6]
|
||||
},
|
||||
{
|
||||
text: '已截止',
|
||||
exercise_status: 3,
|
||||
course_identities: [2, 5, 6]
|
||||
},
|
||||
],
|
||||
currentTab: 0,
|
||||
navScrollLeft: 0
|
||||
},
|
||||
pull_courses_info: function(){
|
||||
app.client.get_user_info()
|
||||
.then();
|
||||
/**@todo */
|
||||
},
|
||||
pull_courses: function(){
|
||||
app.client.search_exercises({ course_id: this.course_id })
|
||||
.then(res => {console.log("pull_courses");console.log(res); this.setData({ exercises: res.data.exercises, loading: false});console.log(this.data)})
|
||||
.catch(console.error);
|
||||
},
|
||||
see_exercise: function ({ currentTarget: { dataset } }){
|
||||
wx.navigateTo({
|
||||
url: '../exercise/exercise?exercise_id=' + dataset.exercise_id,
|
||||
});
|
||||
},
|
||||
enter_exercise: function({currentTarget:{dataset}}){
|
||||
wx.showModal({
|
||||
title: '确认',
|
||||
content: '开始作答吗?',
|
||||
success: res=>{
|
||||
if(res.confirm){
|
||||
wx.navigateTo({
|
||||
url: '../exercise/exercise?exercise_id='+dataset.exercise_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
//事件处理函数
|
||||
onLoad: function (options) {
|
||||
this.course_id = options.id;
|
||||
},
|
||||
onShow: function(){
|
||||
this.pull_courses();
|
||||
},
|
||||
switchNav(event) {
|
||||
var cur = event.currentTarget.dataset.current;
|
||||
//每个tab选项宽度占1/5
|
||||
var singleNavWidth = this.data.windowWidth / 3;
|
||||
//tab选项居中
|
||||
this.setData({
|
||||
navScrollLeft: (cur - 1) * singleNavWidth
|
||||
})
|
||||
if (this.data.currentTab == cur) {
|
||||
return false;
|
||||
} else {
|
||||
this.setData({
|
||||
currentTab: cur
|
||||
})
|
||||
}
|
||||
},
|
||||
switchTab(event) {
|
||||
var cur = event.detail.current;
|
||||
var singleNavWidth = this.data.windowWidth / 5;
|
||||
this.setData({
|
||||
currentTab: cur,
|
||||
navScrollLeft: (cur - 1) * singleNavWidth
|
||||
});
|
||||
},
|
||||
onPullDownRefresh: function(){
|
||||
this.pull_courses();
|
||||
}
|
||||
})
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"enablePullDownRefresh": true
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
<view class="container">
|
||||
<!-- tab导航栏 -->
|
||||
<!-- scroll-left属性可以控制滚动条位置 -->
|
||||
<!-- scroll-with-animation滚动添加动画过渡 -->
|
||||
<scroll-view scroll-x="true" class="nav" scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}">
|
||||
<block wx:for="{{navData}}" wx:for-index="idx" wx:for-item="navItem" wx:key="idx">
|
||||
<view class="nav-item {{currentTab == idx ?'active':''}}" data-current="{{idx}}" bindtap="switchNav">
|
||||
<text>{{navItem.text}}</text>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
<!-- 页面内容 -->
|
||||
<swiper class="tab-box" current="{{currentTab}}" duration="300" bindchange="switchTab">
|
||||
<block wx:for="{{navData}}" wx:for-item="navItem" wx:key="exercise_status">
|
||||
<swiper-item class="tab-content">
|
||||
<view class="no-content" wx:if="{{exercises.length==0&&!loading}}" class="no-content">
|
||||
<image class="no-content" src="../../images/none.png" mode="aspectFit"></image>
|
||||
</view>
|
||||
<block wx:for="{{exercises}}" wx:for-item="exercise" wx:key="id">
|
||||
<view class="exercise" wx:if="{{exercise.exercise_status==navItem.exercise_status||navItem.exercise_status=='all'}}" class="exercise" bindlongpress="enter_exercise" data-exercise_id="{{exercise.id}}">
|
||||
<view class="exercise-name">
|
||||
<text class="exercise-name">{{exercise.exercise_name}}</text>
|
||||
</view>
|
||||
<view class="exercise-info flex-wrap">
|
||||
<text class="hint" wx:if="{{exercise.exercise_status!=3&&(exercise.current_status==0 || exercise.current_status==2)}}">还有{{exercise.exercise_left_time||' '}}截止</text>
|
||||
<text class="exercise-tip">{{exercise.exercise_tips[0]}}</text>
|
||||
<text wx:if="{{exercise.exercise_status!=3&&(exercise.current_status==0 || exercise.current_status==2)}}" class="start-answer tappable" bindtap="enter_exercise" data-exercise_id="{{exercise.id}}">进入答题</text>
|
||||
<text wx:if="{{(exercise.current_status==1 || exercise.exercise_status==3)&&exercise.current_status!=3}}" class="start-answer tappable" bindtap="see_exercise" data-exercise_id="{{exercise.id}}">查看答题</text>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
|
@ -0,0 +1,72 @@
|
||||
.container{
|
||||
height: 100%;
|
||||
}
|
||||
.nav {
|
||||
height: 85rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
line-height: 70rpx;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
.nav-item {
|
||||
width: 25%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
.active{
|
||||
color: green;
|
||||
border-bottom: 3rpx solid green;
|
||||
}
|
||||
|
||||
.tab-box{
|
||||
padding-top: 85rpx;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.tab-content{
|
||||
overflow-y: scroll;
|
||||
width: 100%;
|
||||
}
|
||||
.tappable{
|
||||
color: #1aad19;
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
text.start-answer{
|
||||
position: fixed;
|
||||
right: 8rpx;
|
||||
}
|
||||
.exercise{
|
||||
background: white;
|
||||
padding: 17rpx 12rpx;
|
||||
margin: 14rpx 0rpx;
|
||||
}
|
||||
.exercise-info{
|
||||
margin-top: 4rpx;
|
||||
align-items: center;
|
||||
}
|
||||
.exercise-tip{
|
||||
color: white;
|
||||
font-size: 10px;
|
||||
height: 14px;
|
||||
background: lightblue;
|
||||
border-radius: 14rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
margin-left: 18rpx;
|
||||
}
|
||||
|
||||
view.no-content{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
image.no-content{
|
||||
width: 300rpx;
|
||||
height: 300rpx;
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
// pages/files/files.js
|
||||
const app = getApp();
|
||||
const base_url = "https://www.educoder.net";
|
||||
Page({
|
||||
|
||||
/**
|
||||
* 页面的初始数据
|
||||
*/
|
||||
data: {
|
||||
files: [],
|
||||
loading: true
|
||||
},
|
||||
pull_files:function(){
|
||||
wx.showLoading({
|
||||
title: '加载中',
|
||||
})
|
||||
app.client.get_course_files({course_id : this.course_id, complete: ()=>{wx.hideLoading();this.setData({loading: false})}})
|
||||
.then(res=>{
|
||||
console.log("pull_files");
|
||||
console.log(res);
|
||||
this.setData({files: res.data.data.files});
|
||||
})
|
||||
.catch(console.error);
|
||||
},
|
||||
|
||||
download:function({currentTarget:{dataset}}){
|
||||
const {url, id} = dataset;
|
||||
wx.showLoading({
|
||||
title: '下载中',
|
||||
})
|
||||
wx.downloadFile({
|
||||
url: base_url + url,
|
||||
success: (res)=> {
|
||||
wx.openDocument({
|
||||
filePath: res.tempFilePath,
|
||||
fail: console.error
|
||||
});
|
||||
},
|
||||
fail: function(error) {wx.showToast({
|
||||
title: error.toString(),
|
||||
icon:"none"
|
||||
});
|
||||
console.error(error);
|
||||
},
|
||||
complete: function (res) {
|
||||
wx.hideLoading();
|
||||
},
|
||||
})
|
||||
|
||||
},
|
||||
/**
|
||||
* 生命周期函数--监听页面加载
|
||||
*/
|
||||
onLoad: function (options) {
|
||||
this.course_id = options.id;
|
||||
console.log(this.course_id);
|
||||
this.pull_files();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面初次渲染完成
|
||||
*/
|
||||
onReady: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面显示
|
||||
*/
|
||||
onShow: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面隐藏
|
||||
*/
|
||||
onHide: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 生命周期函数--监听页面卸载
|
||||
*/
|
||||
onUnload: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面相关事件处理函数--监听用户下拉动作
|
||||
*/
|
||||
onPullDownRefresh: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 页面上拉触底事件的处理函数
|
||||
*/
|
||||
onReachBottom: function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 用户点击右上角分享
|
||||
*/
|
||||
onShareAppMessage: function () {
|
||||
|
||||
}
|
||||
})
|
@ -0,0 +1,3 @@
|
||||
{
|
||||
"usingComponents": {}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<view class="container">
|
||||
<text>课堂资源</text>
|
||||
<view class="no-file-view">
|
||||
<image wx:if="{{files.length==0 && !loading}}" src="../../images/none2.png" class="no-file"></image>
|
||||
</view>
|
||||
<view class="file-list form-wrap">
|
||||
<block wx:for="{{files}}" wx:for-item="file" wx:key="objectId">
|
||||
<image wx:if="{{file.ispic}}" src="{{file.fileid}}" bindtap="preview_pic" data-fileid="{{file.fileid}}"></image>
|
||||
<view class="file-item flex-wrap" bindtap="{{file.ispic?'preview_pic':'download'}}" data-id="{{file.id}}" data-url="{{file.url}}">
|
||||
<text>{{file.title}}</text>
|
||||
<text class="hint file-uploader">上传者:{{file.author.name}}</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<view wx:if="{{false}}" class="upload-file foot">
|
||||
<button type="primary" bindtap="upload">上传文件资源</button>
|
||||
</view>
|
@ -0,0 +1,48 @@
|
||||
/* pages/classdetail/classdetail.wxss */
|
||||
.file-list{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 -12px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
.file-item{
|
||||
background: white;
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 16rpx 16px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.file-item text{
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.file-uploader{
|
||||
font-size: 10px;
|
||||
}
|
||||
.foot{
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
}
|
||||
button{
|
||||
margin: 0px 36px;
|
||||
vertical-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.no-file-view{
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
}
|
||||
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;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"usingComponents": {},
|
||||
"navigationBarTitleText": "分数详情"
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
<view class="container">
|
||||
<!-- tab导航栏 -->
|
||||
<!-- scroll-left属性可以控制滚动条位置 -->
|
||||
<!-- scroll-with-animation滚动添加动画过渡 -->
|
||||
<scroll-view scroll-x="true" class="nav" scroll-left="{{navScrollLeft}}" scroll-with-animation="{{true}}">
|
||||
<block wx:for="{{navData}}" wx:for-index="idx" wx:for-item="navItem" wx:key="idx">
|
||||
<view class="nav-item {{currentTab == idx ?'active':''}}" data-current="{{idx}}" bindtap="switchNav">
|
||||
<text>{{navItem.text}}</text>
|
||||
</view>
|
||||
</block>
|
||||
</scroll-view>
|
||||
<!-- 页面内容 -->
|
||||
<swiper class="tab-box" current="{{currentTab}}" duration="300" bindchange="switchTab">
|
||||
<block wx:for="{{navData}}" wx:for-item="navItem" wx:key="exercise_status">
|
||||
<swiper-item class="tab-content">
|
||||
<view class="grade-list">
|
||||
<block wx:for="{{grades}}" wx:for-item="grade" wx:key="objectId">
|
||||
<view wx:if="{{grade.edu_account_login==navItem.login||navItem.login=='*'}}" class="grade flex-wrap">
|
||||
<text class="name">{{grade.name}}</text>
|
||||
<text class="time">{{grade.time}}</text>
|
||||
<text class="{{grade.mark<0?'mark delete':'mark add'}}">{{grade.mark}}</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</swiper-item>
|
||||
</block>
|
||||
</swiper>
|
||||
</view>
|
||||
|
@ -0,0 +1,68 @@
|
||||
.container{
|
||||
height: 100%;
|
||||
}
|
||||
.nav {
|
||||
height: 85rpx;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
line-height: 70rpx;
|
||||
font-size: 16px;
|
||||
white-space: nowrap;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
.nav-item {
|
||||
width: 33%;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
}
|
||||
.active{
|
||||
color: green;
|
||||
border-bottom: 3rpx solid green;
|
||||
}
|
||||
|
||||
.tab-box{
|
||||
padding-top: 85rpx;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.tab-content{
|
||||
overflow-y: scroll;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grade{
|
||||
background: white;
|
||||
padding: 20rpx 10rpx;
|
||||
border-bottom: 1rpx solid gray;
|
||||
}
|
||||
|
||||
.grade text{
|
||||
margin: 0rpx 20rpx;
|
||||
}
|
||||
.time{
|
||||
position: fixed;
|
||||
right: 180rpx;
|
||||
}
|
||||
|
||||
.mark{
|
||||
position: fixed;
|
||||
right: 3rpx;
|
||||
padding: 3rpx 23rpx;
|
||||
width: 45rpx;
|
||||
text-align: center;
|
||||
}
|
||||
.add{
|
||||
color: white;
|
||||
background: green;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
.delete{
|
||||
color: white;
|
||||
background: red;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
@ -1,23 +1,26 @@
|
||||
<!--
|
||||
所有的页面数据见同目录classes.js中Page.data定义部分
|
||||
classes: 课程列表 type: Array
|
||||
元素class: 课程信息 class.objectId 唯一
|
||||
class.objectId 唯一键
|
||||
class.name 课程名称
|
||||
-->
|
||||
<view class="container">
|
||||
|
||||
<view class="course-list">
|
||||
<image wx:if="{{classes.length==0 && !loading}}" class="none-content" src="../../images/none.png" mode="aspectFit"></image>
|
||||
<text wx:if="{{classes.length==0 && !loading}}" class="none-content hint">你的课程表空空如也</text>
|
||||
<block wx:for="{{classes}}" wx:for-item="class" wx:key="objectId">
|
||||
<view class="classroom flex-wrap" data-class_id="{{class.objectId}}" data-class_name="{{class.name}}" bindtap="enter_class" catchlongpress="del_class">
|
||||
<view wx:if="{{courses.length==0 && !loading}}" class="none-content">
|
||||
<image class="none-content" src="../../images/none.png" mode="aspectFit"></image>
|
||||
<text class="none-content hint">你的课程空空如也</text>
|
||||
</view>
|
||||
<block wx:for="{{courses}}" wx:for-item="course" wx:key="id">
|
||||
<view class="classroom flex-wrap" data-id="{{course.id}}" data-course_name="{{course.name}}" bindtap="enter_course">
|
||||
<!--icon type="success"></icon-->
|
||||
<myicon class="classroom-icon" type="internet_class" size="26" color="#2351e4"></myicon>
|
||||
<text>{{class.name}}</text>
|
||||
<text>{{course.name}}</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
<myicon class="add-class" type="add" color="#00C7B7" size="56" bindtap="add_class"></myicon>
|
||||
<myicon class="add-class" type="add" color="#00C7B7" size="56" bindtap="show_join_course_modal"></myicon>
|
||||
|
||||
<modal id="modal" hidden="{{!show_join_course_modal}}" title="加入课堂" confirm-text="提交" cancel-text="取消" bindcancel="cancel_join_course_modal" bindconfirm="join_course">
|
||||
<input type='text' bindinput="update_invite_code" class="code-input" placeholder="邀请码" auto-focus/>
|
||||
<checkbox-group bindchange="update_identities">
|
||||
<text>身份:</text>
|
||||
<lable class="identity"><checkbox value="professor"/>教师</lable>
|
||||
<lable class="identity"><checkbox value="assistant_professor"/>助教</lable>
|
||||
<lable class="identity"><checkbox value="student"/>学生</lable>
|
||||
</checkbox-group>
|
||||
</modal>
|
Loading…
Reference in new issue