This commit is contained in:
yuanke 2016-07-25 15:20:01 +08:00
parent 216d590140
commit b9b9a867f4
12 changed files with 533 additions and 9 deletions

View File

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

View File

@ -0,0 +1,123 @@
#coding=utf-8
module Mobile
module Apis
class Projects < Grape::API
resources :projects do
desc "获取项目列表"
params do
requires :token, type: String
end
get do
authenticate!
ps = ProjectsService.new
projects = ps.user_projects(current_user)
present :data, projects, with: Mobile::Entities::Project,user: current_user
present :status, 0
end
desc "返回单个项目"
params do
requires :id, type: Integer
requires :token,type:String
end
route_param :id do
get do
# course = Course.find(params[:id])
ps = ProjectsService.new
project = ps.show_project(params,current_user)
if project[:status] != 9
{status:-1, message: '该项目不存在或已被删除啦' }
else
present :data, project, with: Mobile::Entities::Project,user: current_user
present :status, 0
end
end
end
desc "获取项目动态"
params do
requires :token, type: String
end
post 'auth' do
authenticate!
auth = 0
if (current_user.user_extensions && current_user.user_extensions.identity == 0 && current_user.allowed_to?(:add_course, nil, :global => true))
auth = 1
end
present :auth, auth
end
desc "获取项目"
params do
requires :token, type: String
end
post 'auth' do
authenticate!
auth = 0
if (current_user.user_extensions && current_user.user_extensions.identity == 0 && current_user.allowed_to?(:add_course, nil, :global => true))
auth = 1
end
present :auth, auth
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,user: current_user
present :status, 0
end
end
desc '编辑大纲'
params do
requires :token, type: String
requires :title, type: String, desc: '大纲标题'
# requires :add_courses, type: Array[String], desc: '课程名'
# requires :modify_courses, type: Array[Integer,String], desc: '课程名'
end
post ':id/edit' do
authenticate!
ss = SyllabusesService.new
#修改课程大纲
status = ss.edit(current_user, params)
if status == -1
{status:status, message: '修改课程信息失败' }
else
present :status, status
end
end
end
end
end
end

View File

@ -0,0 +1,18 @@
module Mobile
module Entities
class Project < Grape::Entity
expose :name
expose :id
expose :can_setting, if: lambda { |instance, options| options[:user] } do |instance, options|
current_user = options[:user]
can_setting = instance.user_id == current_user.id ? true : false
can_setting = false if instance.id.nil?
can_setting
end
expose :member_count, if: lambda { |instance, options| options[:user] } do |instance, options|
instance.members.count
end
end
end
end

View File

@ -165,6 +165,7 @@ class Project < ActiveRecord::Base
scope :has_module, lambda {|mod|
where("#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s)
}
scope :not_deleted, lambda{where("status<>9")}
scope :active, lambda { where(:status => STATUS_ACTIVE) }
scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
scope :all_public, lambda { where(:is_public => true) }

View File

@ -0,0 +1,140 @@
#coding=utf-8
class ProjectsService
include ApplicationHelper
# include CoursesHelper
def judge_can_setting(sy,user)
sy[:can_setting] = sy[:user_id] == user.id ? true : false
sy[:can_setting] = false if sy[:id].nil?
sy.courses.each do |c|
c[:can_setting] = false
member = c.members.where("user_id=#{user.id} and course_id=#{c.id}")[0]
roleName = member.roles[0].name if member
if roleName && (roleName == "TeachingAsistant" || roleName == "Teacher" )
c[:can_setting] = true
end
if c.tea_id == user.id
c[:can_setting] = true
end
end
sy
end
#获取指定用户的项目列表
def user_projects(user)
projects = user.projects.not_deleted.select("projects.*,(SELECT MAX(updated_at) FROM `forge_activities` WHERE forge_activities.project_id = projects.id) AS updated_at ").order("updated_at desc")
projects
end
#显示项目
def show_project(params,current_user)
project = Project.find(params[:id])
# course.generate_invite_code
# course.generate_qrcode
# unless (course.is_public == 1 || current_user.member_of_course?(course) || current_user.admin?)
# raise '403'
# end
# {:course => course,:work_unit => work_unit, :img_url => url_to_avatar(course),:current_user_is_member => current_user.nil? ? false : current_user.member_of_course?(course),:current_user_is_teacher => current_user.nil? ? false : is_course_teacher(current_user,course),:course_student_num => course ? course.student.count.to_s : 0}
project
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
def send_wechat_create_class_notice user,course
count = ShieldWechatMessage.where("container_type='User' and container_id=#{user.id} and shield_type='Course' and shield_id=#{course.id}").count
if count == 0
ws = WechatService.new
title = "恭喜您创建班级成功。"
ws.create_class_notice user.id, "create_course_notice", course.id,title, course.name, user.show_name, 0, "点击查看班级详情。"
end
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!
send_wechat_create_class_notice user,course
elsif Hash === course
c = ::Course.new(course)
c.tea_id = user.id
c.syllabus_id = sy.id
c.update_default_value
c.is_public = 0
c.save!
after_create_course(c, user)
send_wechat_create_class_notice user,c
end
end
end
sy[:can_setting] = true
sy
end
#修改课程大纲的名称、班级名称、新增班级
def edit(user, option)
courses = []
status = -1
syllabus_id = option[:id]
sy = Syllabus.where("id=?",option[:id]).first
if sy && sy.user_id == user.id
syllabus_title = option[:title]
sy.title = syllabus_title
sy.save!
#修改班级名称
modify_courses = option[:modify_courses]
modify_courses.each do |c|
course = Course.where("id=?",c.id).first
if course && course.tea_id == user.id
course.name = c.name
!course.save
end
end
#新增班级
add_courses = option[:add_courses]
add_courses.each do |c|
course = Course.new()
course.name = c
course.tea_id = user.id
course.syllabus_id = sy.id
course.update_default_value
course.is_public = 0
course.save!
after_create_course(course, user)
send_wechat_create_class_notice user,course
end
status = 0
end
status
end
end

View File

@ -30,11 +30,11 @@ button:
type: "click"
name: "加入项目"
key: "JOIN_PROJECT"
-
type: "click"
name: "反馈"
key: "FEEDBACK"
-
type: "view"
name: "历史推文"
url: "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MzIwOTM2NDkxMA==#wechat_webview_type=1&wechat_redirect"
-
type: "click"
name: "联系我们"
key: "FEEDBACK"

View File

@ -13,7 +13,7 @@ button:
-
type: "click"
name: "我的项目"
key: "PROJECT"
url: "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxc09454f171153c2d&redirect_uri=https://test.forge.trustie.net/wechat/user_activities&response_type=code&scope=snsapi_base&state=project_list#wechat_redirect"
-
type: "view"
name: "我的宝库"
@ -30,11 +30,11 @@ button:
type: "click"
name: "加入项目"
key: "JOIN_PROJECT"
-
type: "click"
name: "反馈"
key: "FEEDBACK"
-
type: "view"
name: "历史推文"
url: "http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MzIwOTM2NDkxMA==#wechat_webview_type=1&wechat_redirect"
-
type: "click"
name: "联系我们"
key: "FEEDBACK"

View File

@ -0,0 +1,60 @@
<div class="post-container">
<div loading-spinner></div>
<div class="class-detail-name"><span class="course-name-width hidden inline-block">{{course.name}}</span><span ng-click="invite()" class="f13 blue-title-sub">邀请码</span></div>
<div class="tab-wrap">
<a ng-click="tab($index+1)" ng-repeat="menu in menus" id="class_tab_1" href="javascript:void(0);" ng-class="['weixin-tab', {'class-tab-active': currentTab == $index+1}]">{{menu}}</a>
</div>
<!--<div class="slice3 fl"></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 class="slice3 fl"></div>-->
<!--<div class="cl"></div>-->
<div class="class-search-wrap">
<div class="class-search-inner"> <img src="/images/wechat/search.png" width="18" class="class-search-icon" />
<input class="class-detail-search" ng-model="searchText" placeholder="输入关键词进行搜索" />
</div>
</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}]"><img src="/images/wechat/courseware.png" width="15" class="ml10 fl" /><span class="fl ml10 resource-width">{{r.filename}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2" ng-click="sendFile(r,1)">发送</a><div class="cl"></div></div>
<p ng-show="resources_tag == true && resources.length<=0" class="class-test-tip">暂无课件,<br />
请登录Trustie网站在PC浏览器中上传课件。</p>
</div>
<div ng-class="{'undis': !showClassMate}">
<div class="member-banner f13 c-grey3">授课老师</div>
<div class="class-member-row f13 c-grey3" ng-repeat="teacher in teachers|filter:searchText">
<img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.jpg" width="30" class="fl ml10 img-circle" /><span class="fl ml10 mt5">{{teacher.name}}</span><span class="fr mr10 c-grey2">{{teacher.role_name|identify}}</span><img ng-src="/images/wechat/{{teacher.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<div class="cl"></div>
</div>
<div class="member-banner f13 mt10 c-grey3">我的同学</div>
<div class="class-member-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" /><span class="fl ml10 mt5">{{student.name}}</span><img ng-src="/images/wechat/{{student.gender==0 ? 'male' : 'female'}}.png" width="15" class="fl ml10 mt5" />
<div class="cl"></div>
</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}]"><img src="/images/wechat/homework.png" width="15" class="ml10 fl" /><span class="fl ml10 resource-width">{{r.homework_name}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2 " ng-click="sendFile(r,2)">发送</a><div class="cl"></div></div>
<p ng-show="homeworks_tag == true && 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}]"><img src="/images/wechat/test.png" width="15" class="ml10 fl" /><span class="fl ml10 resource-width">{{r.exercise_name}}</span><a ng-show="isTeacher" herf="javascript:void(0);" class="fr mr10 link-blue2 undis" ng-click="sendFile(r,3)">发送</a><div class="cl"></div></div>
<p ng-show="exercises_tag == true && exercises.length<=0" class="class-test-tip">暂无小测验,<br />
请登录Trustie网站在PC浏览器中上传小测验。</p>
</div>
<my-alert message="alertService.message" title="alertService.title" visible="alertService.visible" cb="alertService.cb"></my-alert>
</div>

View File

@ -0,0 +1,36 @@
<div class="post-container" style="padding-bottom: 50px;">
<div loading-spinner></div>
<div class="blue-title">项目列表</div>
<div>
<div class="course-diff-row"><span class="c-blue f13 ml10">我创建的项目</span></div>
<div ng-repeat="project in projects" style="position:relative;">
<div ng-click="goProject(project.id)" ng-show="project.can_setting" class="course-list-row f13 c-grey3 border-top-none">
<span class="fl ml10 class-list-name hidden">{{project.name}}</span>
<span class="students-amount f12 fr mt10 mr10">{{project.member_count}}人&gt;</span>
</div>
</div>
</div>
<div>
<div class="course-diff-row mt10"><span class="c-blue f13 ml10">我参与的项目</span></div>
<div ng-click="goProject(project.id)" ng-repeat="project in projects" style="position:relative;">
<div ng-show="!project.can_setting" class="course-list-row f13 c-grey3 border-top-none">
<span class="fl ml10 class-list-name hidden">{{project.name}}</span>
<span class="students-amount f12 fr mt10 mr10">{{project.member_count}}人&gt;</span>
</div>
</div>
</div>
<div class="bottom-tab-wrap mt10">
<a ng-click="newProject()" href="javascript:void(0);" class="weixin-tab link-blue2 border-top">新建项目</a>
<a ng-click="joinProject()" href="javascript:void(0);" class="weixin-tab link-blue2 border-top">加入项目</a>
</div>
<my-alert message="alertService_1.message" title="alertService_1.title" visible="alertService_1.visible" cb="alertService_1.cb"></my-alert>
<my-alert3 message="alertService_3.message" title="alertService_3.title" visible="alertService_3.visible" cb="alertService_3.cb" invite="alertService_3.invite" ></my-alert3>
</div>

View File

@ -0,0 +1,64 @@
app.controller('ProjectController', ['$scope', 'config','$http', 'auth','$location','$routeParams','alertService','rms', function($scope, config, $http, auth, $location, $routeParams,alertService,rms){
var vm = $scope;
var projectid = $routeParams.id;
vm.project_activities = [];
vm.project_activities_page = 0;
vm.project_members = [];
vm.project_members_page = 0;
vm.currentTab = 1;
vm.tab = function(index){
vm.currentTab = index;
vm.searchText = '';
if(index == 1){
$http.get(config.apiUrl + 'project/activities?token='+auth.token()+'&project_id='+projectid).then(
function(response) {
console.log(response.data);
vm.project_activities = response.data.data;
}
)
}
else if(index == 2){
$http.get(config.apiUrl + 'project/members?token='+auth.token()+'&project_id='+projectid).then(
function(response) {
console.log(response.data);
vm.project_activities = response.data.data;
}
)
}
};
$http.get(config.apiUrl+ 'project/'+projectid+"?token="+auth.token()).then(
function(response) {
console.log(response.data);
if (response.data.status == 0){
vm.project = response.data.data;
resetMenu(vm.project.can_setting);
vm.tab(1);
}
else{
vm.alertService.showMessage('提示', response.data.message);
}
}
);
var resetMenu = function(can_setting){
if(can_setting){
vm.menus = ["项目动态", "成员管理"];
} else {
vm.menus = ['项目动态', "我的伙伴"];
}
}
}]);

View File

@ -0,0 +1,78 @@
/**
* Created by guange on 16/6/27.
*/
app.controller('ProjectListController', ['$scope', 'config', 'auth', '$http', '$location', 'alertService','rms',
function ($scope, config, auth, $http, $location, alertService,rms) {
var vm = $scope;
vm.projects = rms.get('projects') || [];
vm.alertService_1 = alertService.create();
vm.alertService_3 = alertService.create();
var loadProjectList = function () {
$http.get(config.apiUrl + "projects?token=" + auth.token()).then(
function (response) {
console.log(response.data);
vm.projects = response.data.data;
rms.save('projects', vm.projects);
}
);
};
if(vm.projects.length<=0){
loadProjectList();
}
vm.goProject = function (project_id) {
console.log(project_id);
$location.path("/project").search({id: project_id});
}
vm.newProject = function () {
//先判断下权限
$http.post(config.apiUrl + "projects/auth",{token: auth.token()} ).then(
function (response) {
console.log(response.data);
if (response.data.auth == 0) {
vm.alertService_1.showMessage('提示', '非教师身份不能创建课程哦~');
}
else{
$location.path("/new_project");
}
}
);
}
vm.joinProject = function () {
vm.alertService_3.showMessage('提示', '请输入6位项目邀请码(不区分大小写)', function(){
if (vm.alertService_3.invite && vm.alertService_3.invite.length == 5) {
$http.post(config.apiUrl + "courses/join", {
token: auth.token(),
invite_code: vm.alertService_3.invite
}).then(function (response) {
console.log(response.data);
if (response.data.status != 0) {
vm.alertService_1.showMessage('提示', response.data.message);
} else {
vm.alertService_1.showMessage('提示', '加入项目成功');
vm.alertService_3.invite = "";
loadClassList();
}
});
} else {
if(vm.alertService_3.invite){
vm.alertService_1.showMessage('提示', '邀请码格式不正确');
}
}
});
};
vm.onSetting = function (project) {
console.log(project);
rms.save('current_edit_project', project);
$location.path("/edit_project").search({id: project.id});
}
}]);

View File

@ -37,6 +37,8 @@ app.config(['$routeProvider',"$httpProvider", "$locationProvider",'config', func
.when('/myresource', makeRoute('myresource.html', 'MyResourceController'))
.when('/invite_code', {templateUrl: rootPath + 'invite_code.html', controller: 'InviteCodeController'})
.when('/send_class_list', makeRoute('send_class_list.html', 'SendClassListController'))
.when('/project_list', makeRoute('project_list.html', 'ProjectListController'))
.when('/project', makeRoute('project.html', 'ProjectController'))
.otherwise({
redirectTo: '/activites'
});