diff --git a/app/api/mobile/apis/courses.rb b/app/api/mobile/apis/courses.rb index b2a2532bc..0900f0446 100644 --- a/app/api/mobile/apis/courses.rb +++ b/app/api/mobile/apis/courses.rb @@ -170,10 +170,26 @@ module Mobile desc "设置教辅" params do - + requires :token,type:String + requires :user_id,type:Integer,desc: '用户id' + requires :course_id,type:Integer,desc:'课程id' + end + get 'set_user_as_assitant' do + cs = CoursesService.new + cs.set_as_assitant_teacher params + present :status, 0 end - post 'set_user_as_assitant' do + desc "删除教辅" + params do + requires :token,type:String + requires :user_id,type:Integer,desc: '用户id' + requires :course_id,type:Integer,desc:'课程id' + end + get 'del_user_as_assitant' do + cs = CoursesService.new + cs.del_assitant_teacher params + present :status, 0 end desc "返回单个课程" @@ -187,7 +203,7 @@ module Mobile course = cs.show_course(params,(current_user.nil? ? User.find(2):current_user)) #course = Course.find(params[:id]) present :data, course, with: Mobile::Entities::Course - present :status, 0 + { status: 0} end end diff --git a/app/api/mobile/apis/homeworks.rb b/app/api/mobile/apis/homeworks.rb index 7a8c87987..5bf454e32 100644 --- a/app/api/mobile/apis/homeworks.rb +++ b/app/api/mobile/apis/homeworks.rb @@ -96,6 +96,21 @@ module Mobile present :status, 0 end + desc '创建作业' + params do + requires :token,type:String + requires :work_name,type:String,desc:'作业名称' + requires :work_desc,type:String,desc:'作业描述' + requires :work_deadline,type:String,desc:'截止日期' + requires :is_blind_appr,type:Integer,desc:'是否匿评' + requires :blind_appr_num,type:Integer,desc:'匿评分配数' + requires :course_id,type:Integer,desc: '课程id' + end + post 'create_home_work' do + Homeworks.get_service.create_home_work params,current_user + present :status, 0 + end + end end diff --git a/app/api/mobile/apis/users.rb b/app/api/mobile/apis/users.rb index 3ef2c3237..62c9c3926 100644 --- a/app/api/mobile/apis/users.rb +++ b/app/api/mobile/apis/users.rb @@ -84,6 +84,7 @@ module Mobile requires :name, type: String, desc: '用户名关键字' requires :search_by, type: String,desc: '搜索依据:0 昵称,1 用户名,2 邮箱,3 昵称和姓名' optional :is_search_assitant,type:Integer,desc:'是否搜索注册用户来作为助教' + optional :course_id,type:Integer,desc: '课程id,搜索注册用户不为该课程教师的其他用户' end get 'search/search_user' do us = UsersService.new diff --git a/app/api/mobile/entities/user.rb b/app/api/mobile/entities/user.rb index 6b0064036..aee687dc9 100644 --- a/app/api/mobile/entities/user.rb +++ b/app/api/mobile/entities/user.rb @@ -9,7 +9,7 @@ module Mobile u[f] elsif u.is_a?(::User) if u.respond_to?(f) - u.send(f) + u.send(f) unless u.user_extensions.nil? else case f when :img_url @@ -17,9 +17,9 @@ module Mobile when :gender u.nil? || u.user_extensions.nil? || u.user_extensions.gender.nil? ? 0 : u.user_extensions.gender when :work_unit - get_user_work_unit u + get_user_work_unit u unless u.user_extensions.nil? when :location - get_user_location u + get_user_location u unless u.user_extensions.nil? when :brief_introduction u.nil? || u.user_extensions.nil? ? "" : u.user_extensions.brief_introduction end diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 1d1212bf1..d616daadc 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -852,7 +852,7 @@ class CoursesController < ApplicationController #验证是否显示课程 def can_show_course @first_page = FirstPage.find_by_page_type('project') - if @first_page.show_course == 2 + if @first_page.try(:show_course) == 2 render_404 end end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index fd7ec55fb..36d542d58 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -473,6 +473,41 @@ class CoursesService result end + # 设置人员为课程教辅 + def set_as_assitant_teacher params + members = [] + #找到课程 + course = Course.find(params[:course_id]) + #新建课程人员 + + member = Member.new(:role_ids =>[7], :user_id => params[:user_id],:course_id=>params[:course_id]) + joined = StudentsForCourse.where('student_id = ? and course_id = ?', member.user_id,course.id) + joined.each do |join| + join.delete + end + member.course_group_id = 0 + members << member + course.members << members + #将课程人员设置为教辅 + end + + def del_assitant_teacher params + member = Member.where("user_id = ? and course_id = ?",params[:user_id],params[:course_id]) + member.each do |m| + m.destroy + end + user_admin = CourseInfos.where("user_id = ? and course_id = ?",params[:user_id], params[:course_id]) + if user_admin.size > 0 + user_admin.each do |user| + user.destroy + end + end + joined = StudentsForCourse.where('student_id = ? and course_id = ?', params[:user_id],params[:course_id]) + joined.each do |join| + join.delete + end + end + private def searchmember_by_name members, name #searchPeopleByRoles(project, StudentRoles) @@ -576,4 +611,6 @@ class CoursesService + + end \ No newline at end of file diff --git a/app/services/homework_service.rb b/app/services/homework_service.rb index d22c62a5a..2e7f59888 100644 --- a/app/services/homework_service.rb +++ b/app/services/homework_service.rb @@ -231,6 +231,29 @@ class HomeworkService anonymous_repy(jour) end end + + # 发布作业 + def create_home_work params,current_user + @bid = Bid.new + @bid.name = params[:work_name] + @bid.description = params[:work_desc] + # @bid.is_evaluation = params[:is_blind_appr] + @bid.evaluation_num = params[:blind_appr_num] + @bid.open_anonymous_evaluation = params[:is_blind_appr] + @bid.reward_type = 3 + @bid.deadline = params[:work_deadline] + @bid.budget = 0 + @bid.author_id = current_user.id + @bid.commit = 0 + @bid.homework_type = 1 + # @bid. + if @bid.save + HomeworkForCourse.create(:course_id => params[:course_id], :bid_id => @bid.id) + unless @bid.watched_by?(current_user) + @bid.add_watcher(current_user) + end + end + end # 学生匿评列表 def student_jour_list params diff --git a/app/services/users_service.rb b/app/services/users_service.rb index 17557872b..071820ba3 100644 --- a/app/services/users_service.rb +++ b/app/services/users_service.rb @@ -211,7 +211,8 @@ class UsersService search_by = params[:search_by] ? params[:search_by] : "0" scope = scope.where("id not in (?)",watcher).like(params[:name],search_by) if params[:name].present? else - scope = scope.like(params[:name],search_by) if params[:name].present? + teachers = searchTeacherAndAssistant(Course.find(params[:course_id])) + scope = scope.where("id not in (?)",teachers.map{|t| t.user_id}).like(params[:name],search_by) if params[:name].present? end scope end diff --git a/app/views/attachments/_form_course.html.erb b/app/views/attachments/_form_course.html.erb index 4a297fb7b..b0ab39b5a 100644 --- a/app/views/attachments/_form_course.html.erb +++ b/app/views/attachments/_form_course.html.erb @@ -2,26 +2,30 @@ <% if defined?(container) && container && container.saved_attachments %> <% if isReply %> <% container.saved_attachments.each_with_index do |attachment, i| %> - + + <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%> - <%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") + - link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> - <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> + <%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") %> <%= l(:field_is_public)%>: - <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%> + <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public_checkbox')%> + + <%= link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> <% end %> <% else %> <% container.attachments.each_with_index do |attachment, i| %> - + + <%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%> - <%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") + - link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> - <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> - <%= l(:field_is_public)%>: - <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%> - <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> + <%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") %> + <%= l(:field_is_public)%>: + <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public_checkbox')%> + + <%= link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> + <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> + + <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> <% end %> <% end %> @@ -56,7 +60,9 @@ :file_count => l(:label_file_count), :delete_all_files => l(:text_are_you_sure_all) } %> -<%= l(:label_no_file_uploaded)%> + <% if container.nil? %> + <%= l(:label_no_file_uploaded)%> + <% end %> (<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) diff --git a/app/views/attachments/_form_project.html.erb b/app/views/attachments/_form_project.html.erb index 515e307f6..998766b27 100644 --- a/app/views/attachments/_form_project.html.erb +++ b/app/views/attachments/_form_project.html.erb @@ -24,7 +24,7 @@ <%= l(:field_is_public)%>: <%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public_checkbox')%> - <%= link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %> + <%= link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), 'data-containerid'=>"#{container.id}",:method => 'delete', :remote => true, :class => 'remove-upload') %> <%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %> <%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %> @@ -41,7 +41,7 @@ // file.click(); // } - + <%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %> <%= button_tag "文件浏览", :type=>"button", :onclick=>"_file#{container.id}.click()", :class =>"sub_btn",:style => ie8? ? 'display:none' : '' %> @@ -60,7 +60,8 @@ :field_is_public => l(:field_is_public), :are_you_sure => l(:text_are_you_sure), :file_count => l(:label_file_count), - :delete_all_files => l(:text_are_you_sure_all) + :delete_all_files => l(:text_are_you_sure_all), + :containerid => "#{container.id}" } %> <%= l(:label_no_file_uploaded)%> (<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) @@ -124,7 +125,9 @@ :file_count => l(:label_file_count), :delete_all_files => l(:text_are_you_sure_all) } %> - <%= l(:label_no_file_uploaded)%> + <% if container.nil? %> + <%= l(:label_no_file_uploaded)%> + <% end %> (<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>) diff --git a/app/views/attachments/destroy.js.erb b/app/views/attachments/destroy.js.erb index d2a3a11a1..0b6cee0df 100644 --- a/app/views/attachments/destroy.js.erb +++ b/app/views/attachments/destroy.js.erb @@ -1,8 +1,26 @@ -$('#attachments_<%= j params[:attachment_id] %>').remove(); -var count=$('#attachments_fields>span').length; -if(count<=0){ - $("#upload_file_count").text(<%= l(:label_no_file_uploaded)%>); - $(".remove_all").remove(); +var attachment_html_obj = $('#attachments_<%= j params[:attachment_id] %>'); +//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 start +var containerid=$('.remove-upload',attachment_html_obj).data('containerid'); +if(containerid==undefined){ + $('#attachments_<%= j params[:attachment_id] %>').remove(); + var count=$('#attachments_fields>span').length; + if(count<=0){ + $("#upload_file_count").text('<%= l(:label_no_file_uploaded)%>'); + $(".remove_all").remove(); + }else{ + $("#upload_file_count").html(""+count+""+"个文件"+"已上传"); + } }else{ - $("#upload_file_count").html("已上传"+""+count+""+"个文件"); -} \ No newline at end of file + $('#attachments_<%= j params[:attachment_id] %>').remove(); + var count=$('#attachments_fields'+containerid+'>span').length; + if(count<=0){ + $('#upload_file_count'+containerid).text('<%= l(:label_no_file_uploaded)%>'); + var remove_all_html_obj = $(".remove_all").filter(function(index){ + return $(this).data('containerid')==containerid; + }); + remove_all_html_obj.remove(); + }else{ + $('#upload_file_count'+containerid).html(""+count+""+"个文件"+"已上传"); + } +} +//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 end \ No newline at end of file diff --git a/app/views/boards/_course_show.html.erb b/app/views/boards/_course_show.html.erb index 2d0bda162..2a078553c 100644 --- a/app/views/boards/_course_show.html.erb +++ b/app/views/boards/_course_show.html.erb @@ -68,6 +68,7 @@ +
<%= link_to_user_header message.author,false,:class => 'fl c_orange ' %>
-

<%= textAreailizable message,:content,:attachments => message.attachments %>

+

<%= textAreailizable message,:content,:attachments => message.attachments %>


<%= format_time(message.created_on) %> diff --git a/app/views/contests/_form_contest.html.erb b/app/views/contests/_form_contest.html.erb index 344d69571..0b9f1469d 100644 --- a/app/views/contests/_form_contest.html.erb +++ b/app/views/contests/_form_contest.html.erb @@ -33,20 +33,21 @@ %>

-

+

<%= f.text_area :description, - :rows => 5, - :class => 'wiki-edit', - :style => "font-size:small;width:490px;margin-left:10px;", + :size => 60, + :rows => 4, + :style => "width:490px;", :maxlength => Contest::DESCRIPTION_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_description)}" %>

-

+

<%= f.text_field :password, :size => 60, - :style => "width:488px;margin-left: 10px;" + :rows => 4, + :style => "width:490px;" %>

diff --git a/app/views/issues/_list.html.erb b/app/views/issues/_list.html.erb index 30bd06b9a..fa34ecb3b 100644 --- a/app/views/issues/_list.html.erb +++ b/app/views/issues/_list.html.erb @@ -31,5 +31,5 @@
<% end -%> \ No newline at end of file diff --git a/app/views/issues/show.html.erb b/app/views/issues/show.html.erb index 8fb63bd10..1d1802172 100644 --- a/app/views/issues/show.html.erb +++ b/app/views/issues/show.html.erb @@ -46,59 +46,52 @@
<%= issue_fields_rows do |rows| %> -
    - -
  • * 状态  : 

    - -

    <%= @issue.status.name %>

    -
  • -
    -
  • * 优先级  : 

    - <%= @issue.priority.name %> -
  • -
    +
      +
    •  状态  : 

      <%= @issue.status.name %>

      +
    • +
      <% unless @issue.disabled_core_fields.include?('assigned_to_id') %> -
    •  指派给  : 

      - <%= @issue.assigned_to ? link_to_isuue_user(@issue.assigned_to) : "-" %> -
    • +
    •  指派给  : 

      <%= @issue.assigned_to ? link_to_isuue_user(@issue.assigned_to) : "--" %> +
    • <% end %> -
      - <% unless @issue.disabled_core_fields.include?('fixed_version_id') %> -
    •  目标版本  : 

      - <%= (@issue.fixed_version ? link_to_version(@issue.fixed_version, :class => "pro_info_p") : "-") %> -
    • +
      +
    +
      +
    •  优先级  : 

      <%= @issue.priority.name %> +
    • +
      + <% unless @issue.disabled_core_fields.include?('done_ratio') %> +
    •  % 完成  : 

      <%= @issue.done_ratio %>% +
    • <% end %> -
      -
    -
      - <% unless @issue.disabled_core_fields.include?('start_date') %> -
    •  开始日期  : 

      +
      +
    -

    <%= format_date(@issue.start_date) %>

    - <% end %> -
    - <% unless @issue.disabled_core_fields.include?('due_date') %> -
  •  计划完成日期  : 

    - <%= format_date(@issue.due_date) %> -
  • +
      + <% unless @issue.disabled_core_fields.include?('start_date') %> +
    •  开始  : 

      <%= format_date(@issue.start_date) %>

      +
    • <% end %> -
      +
      <% unless @issue.disabled_core_fields.include?('estimated_hours') %> - -
    •  预期时间  : 

      - <%= l_hours(@issue.estimated_hours) %> -
    • - +
    •  周期  : 

      <%= l_hours(@issue.estimated_hours) %> +
    • <% end %> -
      - <% unless @issue.disabled_core_fields.include?('done_ratio') %> -
    •  % 完成  : 

      - <%= @issue.done_ratio %>% -
    • +
      +
    +
      + <% unless @issue.disabled_core_fields.include?('due_date') %> +
    •  计划完成  : 

      <%= format_date(@issue.due_date)? format_date(@issue.due_date) : "--" %> +
    • <% end %> -
      -
    - <% end %> +
    + <% unless @issue.disabled_core_fields.include?('fixed_version_id') %> +
  •  目标版本  : 

    <%= (@issue.fixed_version ? link_to_version(@issue.fixed_version, :class => "pro_info_p") : "--") %> +
  • + <% end %> +
    +
+ <% end %> <%#= render_custom_fields_rows(@issue) %> <%#= call_hook(:view_issues_show_details_bottom, :issue => @issue) %>
diff --git a/db/migrate/20150514133640_add_host_config_to_settings.rb b/db/migrate/20150514133640_add_host_config_to_settings.rb new file mode 100644 index 000000000..bac9e0bf4 --- /dev/null +++ b/db/migrate/20150514133640_add_host_config_to_settings.rb @@ -0,0 +1,8 @@ +class AddHostConfigToSettings < ActiveRecord::Migration + def change + Setting.create(name: 'host_course', value: 'course.trustie.net') + Setting.create(name: 'host_contest', value: 'contest.trustie.net') + Setting.create(name: 'host_user', value: 'user.trustie.net') + Setting.create(name: 'host_repository', value: 'repository.trustie.net') + end +end diff --git a/public/javascripts/attachments.js b/public/javascripts/attachments.js index 6eb73182d..3df755a7f 100644 --- a/public/javascripts/attachments.js +++ b/public/javascripts/attachments.js @@ -1,10 +1,10 @@ /* Redmine - project management software - Copyright (C) 2006-2013 Jean-Philippe Lang */ + Copyright (C) 2006-2013 Jean-Philippe Lang */ function postUpMsg(attachmentId) { $.ajax({ - url: '/attachments/renderTag', + url: '/attachments/renderTag', type: "GET", data: { attachmentId: attachmentId @@ -25,39 +25,39 @@ function reload(fileSpan) { function addFile_board(inputEl, file, eagerUpload, id) { - var attachments_frame = '#attachments_fields' + id; - if ($(attachments_frame).children().length < 30) { - deleteallfiles = $(inputEl).data('deleteAllFiles'); - var attachmentId = addFile.nextAttachmentId++; - - var fileSpan = $('', { 'id': 'attachments_' + attachmentId, 'class':'attachment' }); - - fileSpan.append( - $('', { 'type': 'text', 'class': 'filename readonly', 'name': 'attachments[' + attachmentId + '][filename]', 'readonly': 'readonly'} ).val(file.name), - $('', { 'type': 'text', 'class': 'description', 'name': 'attachments[' + attachmentId + '][description]', 'maxlength': 254, 'placeholder': $(inputEl).data('descriptionPlaceholder') } ).toggle(!eagerUpload), - $(''+$(inputEl).data('fieldIsPublic')+':').attr({ 'class': 'ispublic-label' }) , - $('', { 'type': 'checkbox', 'class': 'is_public_checkbox','value':1, 'name': 'attachments[' + attachmentId + '][is_public_checkbox]', checked:'checked' } ).toggle(!eagerUpload), - $(' ').attr({ 'href': "#", 'class': 'remove-upload' }).click(function(){ - if(confirm($(inputEl).data('areYouSure'))){ - removeFile(); - if(!eagerUpload){ - (function(e){ - reload(e); - })(fileSpan); + var attachments_frame = '#attachments_fields' + id; + if ($(attachments_frame).children().length < 30) { + deleteallfiles = $(inputEl).data('deleteAllFiles'); + var attachmentId = addFile.nextAttachmentId++; + + var fileSpan = $('', { 'id': 'attachments_' + attachmentId, 'class':'attachment' }); + + fileSpan.append( + $('', { 'type': 'text', 'class': 'filename readonly', 'name': 'attachments[' + attachmentId + '][filename]', 'readonly': 'readonly'} ).val(file.name), + $('', { 'type': 'text', 'class': 'description', 'name': 'attachments[' + attachmentId + '][description]', 'maxlength': 254, 'placeholder': $(inputEl).data('descriptionPlaceholder') } ).toggle(!eagerUpload), + $(''+$(inputEl).data('fieldIsPublic')+':').attr({ 'class': 'ispublic-label' }) , + $('', { 'type': 'checkbox', 'class': 'is_public_checkbox','value':1, 'name': 'attachments[' + attachmentId + '][is_public_checkbox]', checked:'checked' } ).toggle(!eagerUpload), + $(' ').attr({ 'href': "#", 'class': 'remove-upload', 'data-containerid':id }).click(function(){ + if(confirm($(inputEl).data('areYouSure'))){ + removeFile(); + if(!eagerUpload){ + (function(e){ + reload(e); + })(fileSpan); + } } - } - }).toggle(!eagerUpload), - $('
', { 'class': 'div_attachments', 'name': 'div_'+'attachments_' + attachmentId} ) - ).appendTo(attachments_frame); + }).toggle(!eagerUpload), + $('
', { 'class': 'div_attachments', 'name': 'div_'+'attachments_' + attachmentId} ) + ).appendTo(attachments_frame); - if(eagerUpload) { - ajaxUpload(file, attachmentId, fileSpan, inputEl); + if(eagerUpload) { + ajaxUpload(file, attachmentId, fileSpan, inputEl); + } + return attachmentId; } - return attachmentId; - } - return null; + return null; } function addFile(inputEl, file, eagerUpload) { @@ -99,132 +99,166 @@ addFile.nextAttachmentId = 1; function ajaxUpload(file, attachmentId, fileSpan, inputEl) { - function onLoadstart(e) { - fileSpan.removeClass('ajax-waiting'); - fileSpan.addClass('ajax-loading'); - $('input:submit', $(this).parents('form')).attr('disabled', 'disabled'); - } - - function onProgress(e) { - if(e.lengthComputable) { - this.progressbar( 'value', e.loaded * 100 / e.total ); + function onLoadstart(e) { + fileSpan.removeClass('ajax-waiting'); + fileSpan.addClass('ajax-loading'); + $('input:submit', $(this).parents('form')).attr('disabled', 'disabled'); } - } - - function actualUpload(file, attachmentId, fileSpan, inputEl) { - - ajaxUpload.uploading++; - - uploadBlob(file, $(inputEl).data('upload-path'), attachmentId, { - loadstartEventHandler: onLoadstart.bind(progressSpan), - progressEventHandler: onProgress.bind(progressSpan) - }) - .done(function(result) { - progressSpan.progressbar( 'value', 100 ).remove(); - fileSpan.find('input.description, a').css('display', 'inline-block'); - fileSpan.find('input.is_public_checkbox, a').css('display', 'inline-block'); - }) - .fail(function(result) { - progressSpan.text(result.statusText); - if($("#network_issue")) - { - $("#network_issue").show(); + + function onProgress(e) { + if(e.lengthComputable) { + this.progressbar( 'value', e.loaded * 100 / e.total ); } - }).always(function() { - ajaxUpload.uploading--; - fileSpan.removeClass('ajax-loading'); - var form = fileSpan.parents('form'); - if (form.queue('upload').length == 0 && ajaxUpload.uploading == 0) { - $('input:submit', form).removeAttr('disabled'); + } + + function actualUpload(file, attachmentId, fileSpan, inputEl) { + + ajaxUpload.uploading++; + + uploadBlob(file, $(inputEl).data('upload-path'), attachmentId, { + loadstartEventHandler: onLoadstart.bind(progressSpan), + progressEventHandler: onProgress.bind(progressSpan) + }) + .done(function(result) { + progressSpan.progressbar( 'value', 100 ).remove(); + fileSpan.find('input.description, a').css('display', 'inline-block'); + fileSpan.find('input.is_public_checkbox, a').css('display', 'inline-block'); + }) + .fail(function(result) { + progressSpan.text(result.statusText); + if($("#network_issue")) + { + $("#network_issue").show(); + } + }).always(function() { + ajaxUpload.uploading--; + fileSpan.removeClass('ajax-loading'); + var form = fileSpan.parents('form'); + if (form.queue('upload').length == 0 && ajaxUpload.uploading == 0) { + $('input:submit', form).removeAttr('disabled'); + } + form.dequeue('upload'); + }); + + //gcm files count and add delete_all link + + //modify by yutao 2015-5-14 1ҳڶϴؼʱ˿bug ʸ֮ start + var containerid=$(inputEl).data('containerid'); + if(containerid==undefined){ + var count=$('#attachments_fields>span').length; + $('#upload_file_count').html(""+count+""+$(inputEl).data('fileCount')); + if(count>=1){ + var add_attachs=$('.add_attachment'); + var delete_all=$('.remove_all'); + if(delete_all.length<1){ + add_attachs.append($(" ").attr({"href":"javascript:void(0)", 'class': 'remove_all',"onclick": "removeAll()"})); + } + } + }else{ + var count=$('#attachments_fields'+containerid+'>span').length; + $('#upload_file_count'+containerid).html(""+count+""+$(inputEl).data('fileCount')); + if(count>=1){ + var add_attachs=$('.add_attachment').filter(function(index){ + return $(this).data('containerid')==containerid; + }); + var delete_all=$('.remove_all').filter(function(index){ + return $(this).data('containerid')==containerid; + }); + if(delete_all.length<1){ + add_attachs.append($(" ").attr({ + "href":"javascript:void(0)", + 'class': 'remove_all', + 'data-containerid': containerid, + "onclick": "removeAll('"+containerid+"')" + })); + } + } + //modify by yutao 2015-5-14 1ҳڶϴؼʱ˿bug ʸ֮ end } - form.dequeue('upload'); - }); - - //gcm files count and add delete_all link - - var count=$('#attachments_fields>span').length; - $('#upload_file_count').html(""+count+""+$(inputEl).data('fileCount')); - if(count>=1){ - var add_attachs=$('.add_attachment'); - var delete_all=$('.remove_all'); - if(delete_all.length<1){ - add_attachs.append($(" ").attr({"href":"javascript:void(0)", 'class': 'remove_all',"onclick": "removeAll()"})); - } - } - - //gcm - - } - - var progressSpan = $('
').insertAfter(fileSpan.find('input.filename')); - progressSpan.progressbar(); - fileSpan.addClass('ajax-waiting'); - - var maxSyncUpload = $(inputEl).data('max-concurrent-uploads'); - - if(maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload) - actualUpload(file, attachmentId, fileSpan, inputEl); - else - $(inputEl).parents('form').queue('upload', actualUpload.bind(this, file, attachmentId, fileSpan, inputEl)); + + //gcm + + } + + var progressSpan = $('
').insertAfter(fileSpan.find('input.filename')); + progressSpan.progressbar(); + fileSpan.addClass('ajax-waiting'); + + var maxSyncUpload = $(inputEl).data('max-concurrent-uploads'); + + if(maxSyncUpload == null || maxSyncUpload <= 0 || ajaxUpload.uploading < maxSyncUpload) + actualUpload(file, attachmentId, fileSpan, inputEl); + else + $(inputEl).parents('form').queue('upload', actualUpload.bind(this, file, attachmentId, fileSpan, inputEl)); } ajaxUpload.uploading = 0; function removeFile() { - $(this).parent('span').remove(); - return false; + $(this).parent('span').remove(); + return false; } //gcm delete all file -function removeAll(){ - if(confirm(deleteallfiles)){ - $(".remove-upload").removeAttr("data-confirm"); - $(".remove-upload").click(); - } +//modify by yutao 2015-5-14 1ҳڶϴؼʱ˿bug ʸ֮ start +function removeAll(containerid){ + if(confirm(deleteallfiles)){ + if(containerid==undefined){ + $(".remove-upload").removeAttr("data-confirm"); + $(".remove-upload").click(); + }else{ + var arr = $(".remove-upload").filter(function(){ + return $(this).data('containerid')==containerid; + }); + arr.removeAttr("data-confirm"); + arr.click(); + } + } // return false; } +//modify by yutao 2015-5-14 1ҳڶϴؼʱ˿bug ʸ֮ end //gcm function uploadBlob(blob, uploadUrl, attachmentId, options) { - var actualOptions = $.extend({ - loadstartEventHandler: $.noop, - progressEventHandler: $.noop - }, options); - if(uploadUrl.indexOf('?') > 0){ - uploadUrl = uploadUrl + '&attachment_id=' + attachmentId; - }else{ - uploadUrl = uploadUrl + '?attachment_id=' + attachmentId; - } - if (blob instanceof window.File) { - uploadUrl += '&filename=' + encodeURIComponent(blob.name); - } - - return $.ajax(uploadUrl, { - type: 'POST', - contentType: 'application/octet-stream', - beforeSend: function(jqXhr) { - jqXhr.setRequestHeader('Accept', 'application/js'); - }, - xhr: function() { - var xhr = $.ajaxSettings.xhr(); - xhr.upload.onloadstart = actualOptions.loadstartEventHandler; - xhr.upload.onprogress = actualOptions.progressEventHandler; - return xhr; - }, - data: blob, - cache: false, - processData: false - }); + var actualOptions = $.extend({ + loadstartEventHandler: $.noop, + progressEventHandler: $.noop + }, options); + if(uploadUrl.indexOf('?') > 0){ + uploadUrl = uploadUrl + '&attachment_id=' + attachmentId; + }else{ + uploadUrl = uploadUrl + '?attachment_id=' + attachmentId; + } + if (blob instanceof window.File) { + uploadUrl += '&filename=' + encodeURIComponent(blob.name); + } + + return $.ajax(uploadUrl, { + type: 'POST', + contentType: 'application/octet-stream', + beforeSend: function(jqXhr) { + jqXhr.setRequestHeader('Accept', 'application/js'); + }, + xhr: function() { + var xhr = $.ajaxSettings.xhr(); + xhr.upload.onloadstart = actualOptions.loadstartEventHandler; + xhr.upload.onprogress = actualOptions.progressEventHandler; + return xhr; + }, + data: blob, + cache: false, + processData: false + }); } function addInputFiles(inputEl) { - // var clearedFileInput = $(inputEl).clone().val(''); + // var clearedFileInput = $(inputEl).clone().val(''); if (inputEl.files) { // upload files using ajax uploadAndAttachFiles(inputEl.files, inputEl); - // $(inputEl).remove(); + // $(inputEl).remove(); } else { // browser not supporting the file API, upload on form submission var attachmentId; @@ -260,18 +294,18 @@ function addInputFiles_board(inputEl, id) { } function uploadAndAttachFiles(files, inputEl) { - var maxFileSize = $(inputEl).data('max-file-size'); - var maxFileSizeExceeded = $(inputEl).data('max-file-size-message'); - - var sizeExceeded = false; - $.each(files, function() { - if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {sizeExceeded=true;} - }); - if (sizeExceeded) { - window.alert(maxFileSizeExceeded); - } else { - $.each(files, function() {addFile(inputEl, this, true);}); - } + var maxFileSize = $(inputEl).data('max-file-size'); + var maxFileSizeExceeded = $(inputEl).data('max-file-size-message'); + + var sizeExceeded = false; + $.each(files, function() { + if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {sizeExceeded=true;} + }); + if (sizeExceeded) { + window.alert(maxFileSizeExceeded); + } else { + $.each(files, function() {addFile(inputEl, this, true);}); + } } function uploadAndAttachFiles_board(files, inputEl, id) { @@ -290,37 +324,63 @@ function uploadAndAttachFiles_board(files, inputEl, id) { } function handleFileDropEvent(e) { - $(this).removeClass('fileover'); - blockEventPropagation(e); + $(this).removeClass('fileover'); + blockEventPropagation(e); - if ($.inArray('Files', e.dataTransfer.types) > -1) { - uploadAndAttachFiles(e.dataTransfer.files, $('input:file.file_selector')); - } + if ($.inArray('Files', e.dataTransfer.types) > -1) { + uploadAndAttachFiles(e.dataTransfer.files, $('input:file.file_selector')); + } } function dragOverHandler(e) { - $(this).addClass('fileover'); - blockEventPropagation(e); + $(this).addClass('fileover'); + blockEventPropagation(e); } function dragOutHandler(e) { - $(this).removeClass('fileover'); - blockEventPropagation(e); + $(this).removeClass('fileover'); + blockEventPropagation(e); } function setupFileDrop() { - if (window.File && window.FileList && window.ProgressEvent && window.FormData) { + if (window.File && window.FileList && window.ProgressEvent && window.FormData) { - $.event.fixHooks.drop = { props: [ 'dataTransfer' ] }; + $.event.fixHooks.drop = { props: [ 'dataTransfer' ] }; - $('form div.box').has('input:file').each(function() { - $(this).on({ - dragover: dragOverHandler, - dragleave: dragOutHandler, - drop: handleFileDropEvent - }); - }); - } + $('form div.box').has('input:file').each(function() { + $(this).on({ + dragover: dragOverHandler, + dragleave: dragOutHandler, + drop: handleFileDropEvent + }); + }); + } } $(document).ready(setupFileDrop); +$(function(){ + $(".file_selector").each(function() { + deleteallfiles = $(this).data('deleteAllFiles'); + var containerid = $(this).data('containerid'); + if (containerid == undefined)containerid = ''; + var count = $('#attachments_fields' + containerid + '>span').length; + if (count >= 1) { + $('#upload_file_count' + containerid).html("" + count + "" + $(this).data('fileCount')); + var add_attachs = $('.add_attachment').filter(function (index) { + return $(this).data('containerid') == containerid; + }); + var delete_all = $('.remove_all').filter(function (index) { + return $(this).data('containerid') == containerid; + }); + if (delete_all.length < 1) { + add_attachs.append($(" ").attr({ + "href": "javascript:void(0)", + 'class': 'remove_all', + 'data-containerid': containerid, + "onclick": "removeAll('" + containerid + "')" + })); + } + + } + }); +}); \ No newline at end of file diff --git a/public/stylesheets/project.css b/public/stylesheets/project.css index 3b04e23bf..74d7c58b3 100644 --- a/public/stylesheets/project.css +++ b/public/stylesheets/project.css @@ -87,11 +87,11 @@ a.pro_mes_w{ height:20px; float:left;display:block; color:#999999;} .pro_page_top{ font-size:14px; border-bottom:2px solid #64bdd9; margin-bottom:10px; padding-bottom:5px;} .pro_page_tit{color:#3e4040; font-weight:bold;width:480px; float:left; font-size:14px; margin-bottom:5px;} .pro_pic_box{ margin-left:60px; } -.pro_pic{ width:100px; height:75px;line-height:73px;border:2px solid #CCC; margin:10px 0; text-align: center;} -.pro_info_box{ margin-left:60px; background:#f0fbff; height:80px; padding:10px 0;} +.pro_pic{ width:100px; border:2px solid #CCC; margin:10px 0;} +.pro_info_box{ margin-left:60px; border:1px dashed #CCC; height:45px; padding:10px 0;} .pro_info_box ul{} -.pro_info_box ul li{ margin-bottom:10px;} -.pro_info_p{ color:#0781b4 !important; float:left; width:160px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;padding-top:2.5px;} +.pro_info_box ul li{ height:24px;} +.pro_info_p{color:#0781b4 !important; float:left; width:80px; overflow:hidden; white-space: nowrap; text-overflow:ellipsis; } .edit_pro_box{overflow:hidden;display:none; margin-bottom:30px; border-bottom:1px dashed #CCC; padding-bottom:10px;} /****翻页***/ ul.wlist{ float:right; border-bottom:none; height:30px; margin-top:20px; } @@ -354,6 +354,9 @@ a:hover.st_add{ color:#ff8e15;} .newpro_box textarea{ height:150px; float:left; margin-bottom:10px;} .newpro_box select{ height:29px; float:left; margin-bottom:10px;} /*.label{ width:80px; text-align:right; font-size:14 background-image: url(../images/true.png); }*/ +.label02{ width:110px; text-align:right; font-size:14px; display:block; float:left;} +.label03{ width:70px; text-align:right; display:block; float:left;} +.collapsible{ border-left:none;border-right:none;border-bottom:none; border-top:1px solid #e4e4e4; padding-top:10px; } .icon-reload { background-image: url(../images/reload.png); } .icon { background-position: 0% 50%; diff --git a/spec/factories/courses.rb b/spec/factories/courses.rb new file mode 100644 index 000000000..bcdfa99fa --- /dev/null +++ b/spec/factories/courses.rb @@ -0,0 +1,13 @@ +FactoryGirl.define do + factory :course do + name '课程名' + time '2015' + term '春季课程' + period 1 + password '111' + description '课程描述' + is_public 1 + open_student 1 + association :teacher, factory: :user + end +end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index fe6d423ac..2c695b920 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -1,9 +1,9 @@ FactoryGirl.define do factory :user do - login "ExampleUser" + login "factoryuser" mail "user@example.com" - password "foobar" - password_confirmation "foobar" + password "foobar111" + password_confirmation "foobar111" end end diff --git a/spec/requests/account_request_spec.rb b/spec/requests/account_request_spec.rb index 75a5a9bc0..8b45ea096 100644 --- a/spec/requests/account_request_spec.rb +++ b/spec/requests/account_request_spec.rb @@ -1,6 +1,22 @@ require 'rails_helper' +require 'shared_account_spec' RSpec.describe "Account request", :type => :request do + + describe "注册用户" do + include_context "create user" + it "正常注册可以成功" do + shared_register + expect(response).to redirect_to(my_account_url) + end + + it "修改用户资料" do + shared_register + shared_update_user + expect(response).to redirect_to(user_url(session[:user_id])) + end + end + describe "用户登录" do let(:user){FactoryGirl.create(:user)} @@ -10,7 +26,7 @@ RSpec.describe "Account request", :type => :request do end context "正常登录" do - before{post signin_path, username: user.login, password: user.password} + before{ post signin_path, username: user.login, password: user.password } it "登录成功,正常跳转" do expect(response).to redirect_to(my_account_url) end diff --git a/spec/requests/course_request_spec.rb b/spec/requests/course_request_spec.rb new file mode 100644 index 000000000..8360a0bd4 --- /dev/null +++ b/spec/requests/course_request_spec.rb @@ -0,0 +1,46 @@ +require 'rails_helper' +require 'shared_account_spec' + +RSpec.describe "课程", :type => :request do + let(:course){FactoryGirl.attributes_for(:course)} + describe "创建课程" do + include_context "create user" + before { + shared_register + shared_update_user + } + context "参数正确,成功创建课程" do + before{ + uu = current_user + allow(User).to receive(:current).and_return(uu) + allow(uu).to receive(:allowed_to?).and_return(123) + post courses_path, + "course[name]"=> course[:name], + "class_period"=> course[:period], + "time"=> course[:time], + "term"=> course[:term], + "course[password]"=>course[:password], + "course[description]"=> course[:description], + "course[is_public]"=> course[:is_public], + "course[open_student]"=> course[:open_student] + } + it{ + puts User.current.allowed_to?(1,2) + binding.pry + } + it{expect(response).to have_http_status(:success)} + it{expect(assigns(:course)).to be_a_new(Course)} + it{expect(response).to redirect_to(course_url(assigns(:course)))} + end + end + + describe "配置课程" do + context "修改课程图片" do + it "正常图片上传成功" do + end + + it "不是图片,上传失败" + end + end + +end diff --git a/spec/requests/zipdown_request_spec.rb b/spec/requests/zipdown_request_spec.rb index e69de29bb..eb179f104 100644 --- a/spec/requests/zipdown_request_spec.rb +++ b/spec/requests/zipdown_request_spec.rb @@ -0,0 +1,6 @@ +require 'rails_helper' + +RSpec.describe "作业打包下载", :type => :request do + describe "单独下载某学生作业" do + end +end diff --git a/spec/seeds.rb b/spec/seeds.rb new file mode 100644 index 000000000..e69de29bb diff --git a/spec/shared_account_spec.rb b/spec/shared_account_spec.rb new file mode 100644 index 000000000..046aa2392 --- /dev/null +++ b/spec/shared_account_spec.rb @@ -0,0 +1,42 @@ +require 'rails_helper' + +RSpec.shared_context "create user" do + let(:user) {FactoryGirl.attributes_for(:user)} + def shared_register + post register_path, user: user + end + + def shared_update_user + post my_account_url, + login: user[:login], + identity: 0, + technical_title: "教授", + no: '', + "user[lastname]" => 'lastname', + "user[firstname]" => 'firstname', + enterprise_name: '', + gender: 1, + province: '', + occupation: "", + "user[mail]" => user[:mail], + "user[language]" => "zh", + province: '', + city: '', + "user[mail_notification]" => "all", + "user_extensions[birthday]" => '', + "user_extensions[gender]" => 1, + "user_extensions[brief_introduction]" => '', + "user_extensions[location]" => '', + "user_extensions[occupation]" => '', + "user_extensions[work_experience]" => '', + "user_extensions[zip_code]" => '' + end + + def shared_login + post signin_path, username: user[:login], password: user[:password] + end + + def current_user + User.find(session[:user_id]) + end +end