新建课程功能完成

This commit is contained in:
guange 2016-07-04 16:19:05 +08:00
parent 3c295ba5a1
commit 60367415fa
16 changed files with 266 additions and 36 deletions

View File

@ -1 +1 @@
{"access_token":"0wlw4Hi6bX0ifpmwJ9iO4tOED-8ekIYplhlPcG9vFSQLYC0iW8tPE0MBfuWWnr5SRDVoSQwAmMbeU40QeHXdK7NkBruRSVT9hhFwWef01do3OkFwMr2M3atVCGjRDY_hFUSbAFAMBZ","expires_in":7200,"got_token_at":1467531769}
{"access_token":"vEA6yE7AclWpSWvnRngP7PHl7t8xOexEJS73mWtpEYCCtT6otLnxGV71YQIACEChH5jTZteXhgeuqfbVNB_f0HOYyF0yZpVmiMHANI2BqFVyKqqDOppujvyzF7JHk6TMEGLfAFAHJO","expires_in":7200,"got_token_at":1467618773}

View File

@ -19,6 +19,7 @@ module Mobile
require_relative 'apis/new_comment'
require_relative 'apis/praise'
require_relative 'apis/resources'
require_relative 'apis/syllabuses'
class API < Grape::API
version 'v1', using: :path
@ -73,6 +74,7 @@ module Mobile
mount Apis::NewComment
mount Apis::Praise
mount Apis::Resources
mount Apis::Syllabuses
add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?

View File

@ -0,0 +1,50 @@
#coding=utf-8
module Mobile
module Apis
class Syllabuses < Grape::API
resources :syllabuses do
desc "获取大纲列表"
params do
requires :token, type: String
end
get do
authenticate!
cs = SyllabusesService.new
courses = cs.user_syllabus(current_user)
present :data, courses, with: Mobile::Entities::Syllabus
present :status, 0
end
desc "新建大纲"
params do
requires :token, type: String
requires :title, type: String, desc: '大纲标题'
requires :courses, type: Array[String], desc: '课程名'
end
post do
authenticate!
ss = SyllabusesService.new
sy = ss.create(current_user, params[:title],
params[:courses].map{|c| {name: c} })
if sy.new_record?
{status:-1, message: '创建大纲失败' }
else
present :data, sy, with: Mobile::Entities::Syllabus
present :status, 0
end
end
end
end
end
end

View File

@ -15,6 +15,8 @@ module Mobile
#f.img_url if f.respond_to?(:img_url)
elsif field == :created_at || field == :updated_at
(format_time(c[field]) if (c.is_a?(Hash) && c.key?(field))) || (format_time(c.send(field)) if c.respond_to?(field))
elsif field == :member_count
::Course===c ? c.members.count : 0
else
(c[field] if (c.is_a?(Hash) && c.key?(field))) || (c.send(field) if c.respond_to?(field))
end
@ -49,6 +51,7 @@ module Mobile
course_expose :qrcode
course_expose :updated_at
course_expose :course_student_num
course_expose :member_count
expose :teacher, using: Mobile::Entities::User do |c, opt|
if c.is_a? ::Course
c.teacher

View File

@ -0,0 +1,12 @@
module Mobile
module Entities
class Syllabus < Grape::Entity
include ApplicationHelper
expose :title
expose :id
expose :courses, using: Mobile::Entities::Course
end
end
end

View File

@ -388,6 +388,21 @@ module UsersHelper
return result
end
#获取指定用户的课程大纲
def user_syllabus(user)
results = []
courses = user_courses_list(user)
other = Syllabus.new(title: '未命名课程')
courses.each do |c|
other << c unless c.syllabus
end
user.syllabuses.to_a << other
end
#获取用户参与的公开的课程列表
def user_public_course_list user
membership = user.coursememberships.all#@user.coursememberships.all(:conditions => Course.visible_condition(User.current))

View File

@ -4,6 +4,8 @@ require 'elasticsearch/model'
class Course < ActiveRecord::Base
include Redmine::SafeAttributes
include CoursesHelper
STATUS_ACTIVE = 1
STATUS_CLOSED = 5
STATUS_ARCHIVED = 9
@ -22,7 +24,7 @@ class Course < ActiveRecord::Base
end
end
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name, :is_delete
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name, :is_delete, :syllabus_id
#belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher该方法通过tea_id来调用User表
belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school该方法通过school_id来调用School表
@ -69,8 +71,10 @@ class Course < ActiveRecord::Base
validates_presence_of :term,:name
validates_format_of :class_period, :with =>/^[1-9]\d*$/
validates_format_of :time, :with => /^\d{4}$/
validates_format_of :name,:with =>/^[^ ]+[a-zA-Z0-9_\u4e00-\u9fa5\s\S]+$/
validates_length_of :description, :maximum => 10000
before_save :self_validate
# 公开课程变成私有课程,所有资源都变成私有
after_update :update_files_public,:update_course_ealasticsearch_index
@ -296,6 +300,13 @@ class Course < ActiveRecord::Base
end
end
def update_default_value
self.time = Time.now.year unless time
self.term = cur_course_term unless term
self.class_period = 10 unless class_period
end
# 创建课程讨论区
def create_board_sync
@board = self.boards.build

View File

@ -9,8 +9,10 @@ class Syllabus < ActiveRecord::Base
belongs_to :user
has_many :courses
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
attr_accessible :description, :title, :eng_name, :syllabus_type, :credit, :hours, :theory_hours, :practice_hours, :applicable_major, :pre_course
safe_attributes 'title', 'description', 'eng_name', 'syllabus_type', 'credit', 'hours', 'theory_hours', 'practice_hours', 'credit', 'applicable_major', 'pre_course'
attr_accessible :description, :user_id, :title, :eng_name, :syllabus_type, :credit, :hours, :theory_hours, :practice_hours, :applicable_major, :pre_course
safe_attributes 'title','user', 'description', 'eng_name', 'syllabus_type', 'credit', 'hours', 'theory_hours', 'practice_hours', 'credit', 'applicable_major', 'pre_course'
validates :title, :user_id, presence: true
def delete_kindeditor_assets
delete_kindeditor_assets_from_disk self.id,OwnerTypeHelper::SYLLABUS

View File

@ -44,6 +44,8 @@ class CoursesService
}
end
#搜索课程
def search_course params,current_user
courses_all = Course.all_course

View File

@ -0,0 +1,59 @@
#coding=utf-8
class SyllabusesService
include ApplicationHelper
include CoursesHelper
#获取指定用户的课程大纲
def user_syllabus(user)
courses = CoursesService.new.user_courses_list(user)
other = Syllabus.new(title: '未命名课程')
courses.each do |c|
other.courses << c[:course] unless c[:course].syllabus
end
user.syllabuses.to_a << other
end
def after_create_course(course, user)
#unless User.current.admin?
r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
m = Member.new(:user => user, :roles => [r])
m.project_id = -1
course_info = CourseInfos.new(:user_id => user.id, :course_id => course.id)
#user_grades = UserGrade.create(:user_id => User.current.id, :course_id => @course.id)
course.members << m
course.course_infos << course_info
end
#创建大纲
# params {title: '大纲名称', [{course}, {course}]}
def create(user, title, courses = [])
sy = Syllabus.new(title: title, user_id: user.id)
ActiveRecord::Base.transaction() do
sy.save!
courses.each do |course|
if ::Course === course
course.syllabus_id = sy.id
course.save!
elsif Hash === course
c = ::Course.new(course)
c.tea_id = user.id
c.syllabus_id = sy.id
c.update_default_value
c.save!
after_create_course(c, user)
end
end
end
sy
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20160627090316) do
ActiveRecord::Schema.define(:version => 20160630112733) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@ -57,6 +57,18 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.integer "user_id", :null => false
end
create_table "apply_add_schools", :force => true do |t|
t.string "name"
t.string "province"
t.string "city"
t.string "address"
t.string "remarks"
t.integer "school_id"
t.integer "status", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "apply_homeworks", :force => true do |t|
t.integer "status"
t.integer "user_id"
@ -550,9 +562,9 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.integer "excellent_option", :default => 0
t.integer "is_copy", :default => 0
t.integer "visits", :default => 0
t.integer "syllabus_id"
t.string "invite_code"
t.string "qrcode"
t.integer "syllabus_id"
end
add_index "courses", ["invite_code"], :name => "index_courses_on_invite_code", :unique => true
@ -1633,10 +1645,11 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
create_table "schools", :force => true do |t|
t.string "name"
t.string "province"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "logo_link"
t.string "pinyin"
t.integer "school_type", :default => 0
end
create_table "secdomains", :force => true do |t|
@ -1849,8 +1862,18 @@ ActiveRecord::Schema.define(:version => 20160627090316) do
t.string "title"
t.text "description"
t.integer "user_id"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "eng_name"
t.integer "syllabus_type"
t.integer "credit"
t.integer "hours"
t.integer "theory_hours"
t.integer "practice_hours"
t.string "applicable_major"
t.string "pre_course"
t.integer "visits", :default => 0
t.integer "des_status", :default => 0
end
add_index "syllabuses", ["user_id"], :name => "index_syllabuses_on_user_id"

View File

@ -1,15 +1,20 @@
<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" ng-click="onSetting()" /></div>
<ul class="class-list f13 c-grey3">
<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 ng-repeat="syllabus in syllabuses">
<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">{{syllabus.title}}</span><img src="/images/wechat/setting.png" width="15" class="fr mr10 mt10" ng-click="onSetting()" /></div>
<ul class="class-list f13 c-grey3">
<li ng-click="goClass(course.id)" ng-repeat="course in syllabus.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.member_count}}人</span>
</li>
</ul>
</div>
<div class="bottom-tab-wrap mt10">

View File

@ -1,10 +1,14 @@
<div class="post-container">
<div class="blue-title">新建课程</div>
<div class="course-list-row f13 c-grey3 mt30"><span class="fl ml15 c-grey3">课程</span><input class="new-class-input ml25" placeholder="请输入课程名" /></div>
<div class="course-list-row f13 c-grey3 mt10"><span class="fl ml15 c-grey3">班级</span><input class="new-class-input ml25" placeholder="请输入班级名" /></div>
<div class="tac"><a herf="javascript:void(0);" class="link-blue2 f13 mt15 inline-block add-class-link">+新增班级</a></div>
<a ng-click="newClass()" class="finish-btn">完成</a>
<div loading-spinner></div>
<div class="blue-title">新建课程</div>
<form novalidate name="classForm">
<div class="course-list-row f13 c-grey3 mt30"><span class="fl ml15 c-grey3">课程</span><input class="new-class-input ml25" ng-model="syllabus.title" required placeholder="请输入课程名" /></div>
<div class="course-list-row f13 c-grey3 mt10" ng-repeat="course in syllabus.courses"><span class="fl ml15 c-grey3">班级</span><input required class="new-class-input ml25" ng-model="course.name" placeholder="请输入班级名" /><a ng-click="deleteClass($index)" ng-show="!$first" class="fr mr10 c-grey6 delete-class-link">删除</a></div>
<div class="tac"><a ng-click="addClass()" class="link-blue2 f13 mt15 inline-block add-class-link">+新增班级</a></div>
<a ng-click="newClass(classForm, syllabus)" ng-class="['finish-btn', {'btn-disabled':!classForm.$valid} ]" >完成</a>
</form>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

View File

@ -3,25 +3,28 @@
*/
app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$location', 'alertService',
function ($scope, config, auth, $http, $location, alertService) {
app.controller('ClassListController', ['$scope', 'config', 'auth', '$http', '$location', 'alertService','rms',
function ($scope, config, auth, $http, $location, alertService,rms) {
var vm = $scope;
vm.courses = [];
vm.syllabuses = rms.get('syllabuses') || [];
vm.alertService = alertService.create();
var loadClassList = function () {
$http.get(config.apiUrl + "courses?token=" + auth.token() + "&per_page_count=10&page=1").then(
$http.get(config.apiUrl + "syllabuses?token=" + auth.token()).then(
function (response) {
console.log(response.data);
vm.courses = response.data.data;
vm.syllabuses = response.data.data;
rms.save('syllabuses', vm.syllabuses);
}
);
};
loadClassList();
if(vm.syllabuses.length<=0){
loadClassList();
}
vm.goClass = function (course_id) {
console.log(course_id);
$location.path("/class").search({id: course_id});

View File

@ -1,12 +1,51 @@
app.controller('NewClassController', ['$scope', '$http', 'auth', 'config', 'alertService', function($scope, $http, auth, config, alertService){
app.controller('NewClassController', ['$scope', '$http', 'auth', 'config', 'alertService','$location', function($scope, $http, auth, config, alertService, $location){
var vm = $scope;
vm.alertService = alertService.create();
vm.newClass = function () {
vm.alertService.showMessage('提示', '此功能正在开发中');
vm.syllabus = {
courses: [{name: ''}],
};
vm.addClass = function(){
vm.syllabus.courses.push({});
};
vm.deleteClass = function(index){
vm.syllabus.courses.splice(index, 1);
}
vm.newClass = function (frm, syllabus) {
frm.$setSubmitted();
console.log(syllabus);
if(!frm.$valid){
console.log(frm.$error);
return;
}
var courses = [];
for(var i in vm.syllabus.courses){
courses .push(vm.syllabus.courses[i].name);
}
$http.post(config.apiUrl+"syllabuses", {
token: auth.token(),
title: syllabus.title,
courses: courses
}).then(function(response){
if(response.data.status!=0){
vm.alertService.showMessage('出错了', response.data.message);
} else {
vm.alertService.showMessage('提示', '新建课程成功', function(){
window.history.back();
});
}
console.log(response.data.data);
});
}
}] );

View File

@ -77,7 +77,7 @@ a.underline {text-decoration:underline;}
/*按钮样式*/
.btn1 {width:100%; height:40px; line-height:40px; vertical-align:middle; text-align:center; color:#fff; display:block; border-radius:5px;}
.bg-blue:not(.btn-disabled):active {background-color:#2780c2;}
.btn-disabled {background-color:#ccc;}
.btn-disabled {background-color:#ccc !important;}
.btn2 {width:145px; height:35px; color:#fff; font-size:15px; line-height:35px; text-align:center; vertical-align:middle; margin:18px auto 20px auto; border-radius:50px; display:block;}
/*tab*/