老师课程界面

This commit is contained in:
guange 2016-06-27 16:03:07 +08:00
parent 05f09c4595
commit 3b383dfa65
11 changed files with 203 additions and 54 deletions

View File

@ -1 +1 @@
{"access_token":"_-LoF1vaOEfUwHI2E5iF7IOIyhvTQAhdkyrwp0ISL0q2Nqb8QMcO9K4Z_kNXxporFsN3xJxOdd8EcCPLVxxzqbBm02m9gmGdp_ENBf9K5nHcneKNTpdoIII7B-9FXHRwCYPaADAJFW","expires_in":7200,"got_token_at":1466770839}
{"access_token":"oEEf8ZKAB8Y2G0o_xnTPkPJHKKk8iHkLC-f5ptvQ2nCMj9IpC86ivLD2-p38GfOkuG-HuQp3pWZqhs3NJXUMdPLWsr5k67hPZYuqg4ozLccx0xdLswapj0mn8ovZhK1tKIKiAFAOMO","expires_in":7200,"got_token_at":1467012449}

View File

@ -4,14 +4,13 @@ unless RUBY_PLATFORM =~ /w32/
# unix-like only
gem 'iconv'
gem "rmagick", ">= 2.0.0"
gem 'certified'
end
gem 'net-ssh', '2.9.1'
gem 'jenkins_api_client'
gem 'nokogiri'
# gem 'certified'
gem 'wechat',path: 'lib/wechat'
gem 'grack', path:'lib/grack'
gem 'gitlab', path: 'lib/gitlab-cli'

View File

@ -16,7 +16,7 @@ module Mobile
get do
authenticate!
cs = CoursesService.new
courses = cs.course_list(params,current_user)
courses = cs.user_courses_list(current_user)
present :data, courses, with: Mobile::Entities::Course
present :status, 0
end
@ -385,7 +385,16 @@ module Mobile
end
desc '获取测验列表'
params do
requires :token, type:String
end
get ':course_id/exercises' do
authenticate!
exercises = Course.find(params[:course_id]).exercises
present :data,exercises,with:Mobile::Entities::Exercise
present :status,0
end
end
end

View File

@ -0,0 +1,8 @@
module Mobile
module Entities
class Exercise < Grape::Entity
expose :exercise_name
expose :exercise_description
end
end
end

View File

@ -94,6 +94,7 @@ class Course < ActiveRecord::Base
acts_as_customizable
scope :not_deleted, lambda{where(is_delete: 0)}
scope :all_course
scope :active, lambda { where(:status => STATUS_ACTIVE) }
scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
@ -459,22 +460,17 @@ class Course < ActiveRecord::Base
# 延迟生成邀请码
def invite_code
code = read_attribute[:invite_code]
if !code || code.size < 5
code = generate_invite_code
end
return code
return generate_invite_code
end
# 生成邀请码
CODES = %W(2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z)
def generate_invite_code
code = invite_code
if !invite_code || invite_code.size <5
self.invite_code = CODES.sample(5).join
return generate_invite_code if Course.where(invite_code: invite_code).present?
code = read_attribute(:invite_code)
if !code || code.size <5
code = CODES.sample(5).join
return generate_invite_code if Course.where(invite_code: code).present?
save! && reload
code = invite_code
end
code
end

View File

@ -32,6 +32,18 @@ class CoursesService
course_list
end
def user_courses_list(current_user)
courses = current_user.courses.not_deleted
courses.inject([]) {|course_list, course|
course_list << {:course => course,:img_url => url_to_avatar(course),
:current_user_is_member => current_user.member_of_course?(course),
:current_user_is_teacher => is_course_teacher(current_user,course),
course_student_num: searchStudent(course).count
}
}
end
#搜索课程
def search_course params,current_user
courses_all = Course.all_course

View File

@ -1,10 +1,21 @@
<div class="post-container">
<div class="post-container" style="padding-bottom: 50px;">
<div loading-spinner></div>
<div class="blue-title">课程列表</div>
<div class="course-list-row f13 c-grey3 mt10"><img src="/images/wechat/plus.png" width="15" class="fl ml10 mt11 spread-btn" /><img src="/images/wechat/minus.png" width="15" class="fl ml10 mt11 retract-btn undis" /><span class="fl ml10">未命名课程</span><img src="/images/wechat/setting.png" width="15" class="fr mr10 mt10" /></div>
<ul class="class-list f13 c-grey3">
<li ng-repeat="course in courses" ng-class="{'border-bottom-none': $last}"><img src="/images/wechat/dot.png" width="15px" class="class-list-dot" /><span class="fl ml10 class-list-name hidden">{{course.name}}</span><span class="fr c-grey4">&gt;</span><span class="students-amount f12 fr mt10">10人</span></li>
<!--<li><img src="/images/wechat/dot.png" width="15px" class="class-list-dot" /><span class="fl ml10 class-list-name hidden">分布式计算环境B班</span><span class="fr c-grey4">&gt;</span><span class="students-amount f12 fr mt10">10人</span></li>-->
<!--<li class="border-bottom-none"><img src="/images/wechat/dot.png" width="15px" class="class-list-dot" /><span class="fl ml10 class-list-name hidden">分布式计算环境C班</span><span class="fr c-grey4">&gt;</span><span class="students-amount f12 fr mt10">10人</span></li>-->
<li ng-click="goClass(course.id)" ng-repeat="course in courses" ng-class="{'border-bottom-none': $last}">
<img src="/images/wechat/dot.png" width="15px" class="class-list-dot" />
<span class="fl ml10 class-list-name hidden">{{course.name}}</span>
<span class="fr c-grey4">&gt;</span>
<span class="students-amount f12 fr mt10">{{course.course_student_num}}人</span>
</li>
</ul>
<div class="bottom-tab-wrap mt10">
<a href="javascript:void(0);" class="weixin-tab link-blue2 border-top">新建课程</a>
<a href="javascript:void(0);" class="weixin-tab link-blue2 border-top">加入班级</a>
<a href="javascript:void(0);" class="weixin-tab link-blue2 border-top">我的资源</a>
</div>
</div>

View File

@ -2,11 +2,15 @@
<div loading-spinner></div>
<div class="class-detail-name">{{course.name}}<span ng-click="invite()" class="f13 blue-title-sub">邀请码</span></div>
<div class="slice3 fl"></div>
<div id="class_tab_1" ng-class="['class-detail-tab3',{'class-tab-active':currentTab==1}]" ng-click="tab(1);"><a herf="javascript:void(0);">课堂资源</a></div>
<div class="slice2 fl">
<div class="slice-line2"></div>
<div ng-repeat="menu in menus">
<div id="class_tab_1" ng-class="[{'class-detail-tab': isTeacher},{'class-detail-tab3': !isTeacher},{'class-tab-active':currentTab==$index+1}]" ng-click="tab($index+1);"><a herf="javascript:void(0);">{{menu}}</a></div>
<div ng-if="!$last" class="slice2 fl">
<div class="slice-line2"></div>
</div>
</div>
<div id="class_tab_2" ng-class="['class-detail-tab3',{'class-tab-active':currentTab==2}]" ng-click="tab(2);"><a herf="javascript:void(0);">我的同学</a></div>
<div class="slice3 fl"></div>
<div class="cl"></div>
<div class="class-search-wrap">
@ -14,10 +18,13 @@
<input class="class-detail-search" ng-model="searchText" placeholder="输入关键词进行搜索" />
</div>
</div>
<div ng-class="{'undis': currentTab!=1}">
<div ng-repeat="r in resources|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span></div>
<div ng-class="{'undis': !showResources}">
<div ng-repeat="r in resources|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.filename}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="resources.length<=0" class="class-test-tip">暂无课件,<br />
请登录Trustie网站,在PC浏览器中上传课件。</p>
</div>
<div ng-class="{'undis': currentTab!=2}">
<div ng-class="{'undis': !showClassMate}">
<div class="member-banner f13 c-grey3">授课老师</div>
<div class="class-detail-row f13 c-grey3" ng-repeat="teacher in teachers|filter:searchText">
@ -27,6 +34,22 @@
<div class="class-detail-row f13 c-grey3" ng-repeat="student in students|filter:searchText">
<img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle mt4" /><span class="fl ml10">{{student.name}}</span><img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt10" />
</div>
</div>
<div ng-class="{'undis': !showHomework}">
<div ng-repeat="r in homeworks|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.homework_name}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="homeworks.length<=0" class="class-test-tip">暂无作业,<br />
请登录Trustie网站,在PC浏览器中上传作业。</p>
</div>
<div ng-class="{'undis': !showTestcase}">
<div ng-repeat="r in exercises|filter:searchText" ng-class="['class-detail-row', 'f13', 'c-grey3', {'border-top': $first}]"><span class="fl ml10">{{r.exercise_name}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2">发送</a></div>
<p ng-show="exercises.length<=0" class="class-test-tip">暂无小测验,<br />
请登录Trustie网站,在PC浏览器中上传小测验。</p>
</div>
</div>

View File

@ -3,7 +3,7 @@
*/
app.controller('ClassListController', ['$scope','config','auth','$http', function($scope, config, auth, $http){
app.controller('ClassListController', ['$scope','config','auth','$http','$location', function($scope, config, auth, $http, $location){
var vm = $scope;
vm.courses = [];
@ -14,5 +14,10 @@ app.controller('ClassListController', ['$scope','config','auth','$http', functio
}
);
vm.goClass = function(course_id){
console.log(course_id);
$location.path("/myclass").search({id: course_id});
}
}]);

View File

@ -3,52 +3,126 @@ app.controller('MyClassController', ['$scope', 'config','$http', 'auth','$locati
var vm = $scope;
var courseid = $routeParams.id;
var getUsers = function(){
if(vm.teachers.length<=0){
$http.get(config.apiUrl + 'courses/teachers?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.teachers = response.data.data;
}
)
}
if(vm.students.length<=0){
$http.get(config.apiUrl + 'courses/students?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.students = response.data.data;
}
)
}
}
var getResources = function(){
if(vm.resources.length<=0){
$http.post(config.apiUrl + "courses/"+courseid+"/attachments",
{token: auth.token(), name: ''}
).then(function(response){
vm.resources = response.data.data;
});
}
}
var getHomeworks = function(){
if(vm.homeworks.length <=0){
$http.get(config.apiUrl + "courses/homeworks/"+courseid+"?token="+auth.token()).then(function(response){
vm.homeworks = response.data.data;
console.log(response.data);
});
}
}
var getExercises = function(){
if(vm.exercises.length <=0){
$http.get(config.apiUrl + "courses/"+courseid+"/exercises?token="+auth.token()).then(function(response){
vm.exercises = response.data.data;
console.log(response.data);
});
}
}
vm.isTeacher = false;
vm.currentTab = 1;
vm.tab = function(index){
vm.currentTab = index;
vm.searchText = '';
console.log(vm.currentTab);
if(index == 2){
if(vm.students.length<=0){
$http.get(config.apiUrl + 'courses/students?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.students = response.data.data;
}
)
vm.searchText = '';
vm.showClassMate = false;
vm.showResources = false;
vm.showHomework = false;
vm.showTestcase = false;
if(vm.isTeacher){
if(index == 1){ //课件
getResources();
vm.showResources = true;
} else if(index==2){ //作业
getHomeworks();
vm.showHomework = true;
} else if(index==3){ //小测验
getExercises();
vm.showTestcase = true;
} else if(index==4){ //学生管理
getUsers();
vm.showClassMate = true;
}
} else {
if(index == 2){
getUsers();
vm.showClassMate = true;
} else if(index==1){
getResources();
vm.showResources = true;
}
}
}
vm.course = {};
vm.students = [];
vm.teachers = [];
vm.resources = [];
vm.homeworks = [];
vm.exercises = [];
vm.invite = function(){
$location.path("/invite_code").search({id: courseid});
};
$http.post(config.apiUrl + "courses/"+courseid+"/attachments",
{token: auth.token(), name: ''}
).then(function(response){
vm.resources = response.data.data;
});
$http.get(config.apiUrl+ 'courses/'+courseid+"?token="+auth.token()).then(
function(response){
function(response) {
console.log(response.data);
vm.course = response.data.data;
vm.course = response.data.data;
resetMenu(vm.course.current_user_is_teacher);
vm.tab(1);
}
);
if(vm.teachers.length<=0){
$http.get(config.apiUrl + 'courses/teachers?token='+auth.token()+'&course_id='+courseid).then(
function(response) {
console.log(response.data);
vm.teachers = response.data.data;
}
)
var resetMenu = function(is_teacher){
vm.isTeacher = is_teacher;
if(is_teacher){
vm.menus = ["课件", "作业", "小测验", "学生管理"];
} else {
vm.menus = ['课堂资源', "我的同学"];
}
}
}]);

View File

@ -74,7 +74,19 @@ a.underline {text-decoration:underline;}
.bg-blue:not(.btn-disabled):active {background-color:#2780c2;}
.btn-disabled {background-color:#ccc;}
/*背景色*/
/*tab*/
.tab-wrap {position:relative; line-height:38px; display:flex; font-size:13px; background-color:#fff;}
.tab-wrap a {position:relative; display:block; flex:1;}
.tab-wrap a:first-child:after {display:none;}
.tab-wrap a:after {content:" "; position:absolute; left:0; top:0; width:1px; height:100%; border-left:1px solid #ccc; color:#707070;}
.weixin-tab {text-align:center; border-bottom:1px solid #ccc;}
/*bottom-tab*/
.bottom-tab-wrap {position:fixed; width:100%; bottom:0; line-height:38px; display:flex; font-size:13px; background-color:#fff;}
.bottom-tab-wrap a {display:block; flex:1; position:relative;}
.bottom-tab-wrap a:after {content:" "; position:absolute; left:0; top:0; width:1px; height:100%; border-left:1px solid #ccc; color:#707070;}
/*动态样式*/
.post-container {width:100%;}