diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 68386de44..01703f679 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -469,6 +469,23 @@ class AdminController < ApplicationController end end + #最近登录老师列表 + def latest_login_teachers + scope = User.find_by_sql("SELECT * FROM users,user_extensions WHERE users.id = user_extensions.user_id AND user_extensions.identity=0 ORDER BY last_login_on DESC") + if params[:startdate].present? + scope = User.find_by_sql("SELECT * FROM users,user_extensions WHERE users.id = user_extensions.user_id AND user_extensions.identity=0 and last_login_on>= '#{params[:startdate]} 00:00:00' ORDER BY last_login_on DESC") + end + if params[:enddate].present? + scope = User.find_by_sql("SELECT * FROM users,user_extensions WHERE users.id = user_extensions.user_id AND user_extensions.identity=0 and last_login_on <= '#{params[:enddate]} 23:59:59' ORDER BY last_login_on DESC") + end + @teachers = scope + @teachers = paginateHelper @teachers,30 + @page = (params['page'] || 1).to_i - 1 + respond_to do |format| + format.html + end + end + #作业 def homework @homework = HomeworkCommon.order('end_time desc') diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 36060d41c..be96124c2 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -450,6 +450,93 @@ class CoursesController < ApplicationController #copy avatar copy_avatar(@course, copy_course) + if params[:course_content_type] + params[:course_content_type].each do |type| + case type + when "0" + homeworks = copy_course.homework_commons + homeworks.each do |homework| + new_homework = HomeworkCommon.new + new_homework.name = homework.name + new_homework.user_id = User.current.id + new_homework.description = homework.description + new_homework.publish_time = Date.today + 30 + new_homework.end_time = Date.today + 60 + new_homework.homework_type = homework.homework_type + new_homework.late_penalty = homework.late_penalty + new_homework.course_id = @course.id + new_homework.teacher_priority = homework.teacher_priority + new_homework.anonymous_comment = homework.anonymous_comment + new_homework.quotes = 0 + new_homework.is_open = homework.is_open + homework.attachments.each do |attachment| + att = attachment.copy + att.container_id = nil + att.container_type = nil + att.copy_from = attachment.id + att.save + new_homework.attachments << att + end + homework_detail_manual = homework.homework_detail_manual + homework_detail_programing = homework.homework_detail_programing + homework_detail_group = homework.homework_detail_group + if homework_detail_manual + new_homework.homework_detail_manual = HomeworkDetailManual.new + new_homework_detail_manual = new_homework.homework_detail_manual + new_homework_detail_manual.ta_proportion = homework_detail_manual.ta_proportion + new_homework_detail_manual.comment_status = 0 + new_homework_detail_manual.evaluation_start = Date.today + 67 + new_homework_detail_manual.evaluation_end = Date.today + 74 + new_homework_detail_manual.evaluation_num = homework_detail_manual.evaluation_num + new_homework_detail_manual.absence_penalty = homework_detail_manual.absence_penalty + end + if homework_detail_programing + new_homework.homework_detail_programing = HomeworkDetailPrograming.new + new_homework.homework_detail_programing.ta_proportion = homework_detail_programing.ta_proportion + new_homework.homework_detail_programing.language = homework_detail_programing.language + homework.homework_tests.each_with_index do |homework_test| + new_homework.homework_tests << HomeworkTest.new( + input: homework_test.input, + output: homework_test.output + ) + end + end + + if homework_detail_group + new_homework.homework_detail_group = HomeworkDetailGroup.new + new_homework.homework_detail_group.min_num = homework_detail_group.min_num + new_homework.homework_detail_group.max_num = homework_detail_group.max_num + new_homework.homework_detail_group.base_on_project = homework_detail_group.base_on_project + end + if new_homework.save + new_homework_detail_manual.save if new_homework_detail_manual + new_homework.homework_detail_programing.save if new_homework.homework_detail_programing + new_homework.homework_detail_group.save if new_homework.homework_detail_group + end + homework.update_attribute(:quotes, homework.quotes+1) + end + when "1" + attachments = copy_course.attachments + attachments.each do |attachment| + attach_copied_obj = attachment.copy + attach_copied_obj.tag_list.add(attachment.tag_list) # tag关联 + attach_copied_obj.container = @course + attach_copied_obj.created_on = Time.now + attach_copied_obj.author_id = User.current.id + attach_copied_obj.copy_from = attachment.copy_from.nil? ? attachment.id : attachment.copy_from + attach_copied_obj.is_publish = 0 + attach_copied_obj.publish_time = Date.today + 30 + if attach_copied_obj.attachtype == nil + attach_copied_obj.attachtype = 4 + end + attach_copied_obj.save + update_quotes attach_copied_obj + end + end + end + end + +=begin if params[:checkAll] attachments = copy_course.attachments attachments.each do |attachment| @@ -513,6 +600,7 @@ class CoursesController < ApplicationController end end end +=end end if @course respond_to do |format| diff --git a/app/controllers/homework_common_controller.rb b/app/controllers/homework_common_controller.rb index a891d3354..00b11323b 100644 --- a/app/controllers/homework_common_controller.rb +++ b/app/controllers/homework_common_controller.rb @@ -6,8 +6,8 @@ class HomeworkCommonController < ApplicationController include StudentWorkHelper before_filter :find_course, :only => [:index,:new,:create] - before_filter :find_homework, :only => [:edit,:update,:alert_anonymous_comment,:start_anonymous_comment,:stop_anonymous_comment,:destroy,:start_evaluation_set,:set_evaluation_attr,:score_rule_set,:alert_forbidden_anonymous_comment] - before_filter :teacher_of_course, :only => [:new, :create, :edit, :update, :destroy, :start_anonymous_comment, :stop_anonymous_comment, :alert_anonymous_comment,:start_evaluation_set,:set_evaluation_attr,:score_rule_set,:alert_forbidden_anonymous_comment] + before_filter :find_homework, :only => [:edit,:update,:alert_anonymous_comment,:start_anonymous_comment,:stop_anonymous_comment,:destroy,:start_evaluation_set,:set_evaluation_attr,:score_rule_set,:alert_forbidden_anonymous_comment,:alert_open_student_works,:open_student_works] + before_filter :teacher_of_course, :only => [:new, :create, :edit, :update, :destroy, :start_anonymous_comment, :stop_anonymous_comment, :alert_anonymous_comment,:start_evaluation_set,:set_evaluation_attr,:score_rule_set,:alert_forbidden_anonymous_comment,:alert_open_student_works,:open_student_works] before_filter :member_of_course, :only => [:index] def index @@ -261,6 +261,30 @@ class HomeworkCommonController < ApplicationController end end + def open_student_works + if @homework.is_open == 0 + @homework.update_attribute(:is_open, 1) + else + @homework.update_attribute(:is_open, 0) + end + @user_activity_id = params[:user_activity_id] + @is_in_course = params[:is_in_course] if params[:is_in_course] + @course_activity = params[:course_activity] if params[:course_Activity] + end + + def alert_open_student_works + if params[:user_activity_id] + @user_activity_id = params[:user_activity_id] + else + @user_activity_id = -1 + end + @is_in_course = params[:is_in_course] if params[:is_in_course] + @course_activity = params[:course_activity] if params[:course_Activity] + respond_to do |format| + format.js + end + end + def programing_test test = {language:params[:language],src:Base64.encode64(params[:src]),input:[params[:input]],output:[params[:output]]} @index = params[:index] diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 707e87fd1..7655f1eb4 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -34,7 +34,7 @@ class RepositoriesController < ApplicationController before_filter :find_repository, :only => [:edit, :update, :destroy, :committers] before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo, :to_gitlab, :forked] before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] - before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked] + before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab, :forked, :commit_diff] accept_rss_auth :revisions # hidden repositories filter // 隐藏代码过滤器 before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ] @@ -521,6 +521,13 @@ update end end + # 每次提交对应的文件差异 + def commit_diff + @commit_diff = $g.commit_diff(@project.gpid, params[:changeset]) + @commit_details = $g.commit(@project.gpid, params[:changeset]) + render :layout => 'base_projects' + end + def diff if params[:format] == 'diff' @diff = @repository.diff(@path, @rev, @rev_to) diff --git a/app/controllers/student_work_controller.rb b/app/controllers/student_work_controller.rb index 7ccb3177c..a38d83851 100644 --- a/app/controllers/student_work_controller.rb +++ b/app/controllers/student_work_controller.rb @@ -6,9 +6,10 @@ class StudentWorkController < ApplicationController require "base64" before_filter :find_homework, :only => [:new, :index, :create, :student_work_absence_penalty, :absence_penalty_list, :evaluation_list, :program_test,:set_score_rule,:forbidden_anonymous_comment,:delete_work,:new_student_work_project,:student_work_project,:cancel_relate_project,:search_course_students] before_filter :find_work, :only => [:edit, :update, :show, :destroy, :add_score, :praise_student_work,:retry_work,:revise_attachment] - before_filter :member_of_course, :only => [:index, :new, :create, :show, :add_score, :praise_student_work] + before_filter :member_of_course, :only => [:new, :create, :show, :add_score, :praise_student_work] before_filter :author_of_work, :only => [:edit, :update, :destroy] before_filter :teacher_of_course, :only => [:student_work_absence_penalty, :absence_penalty_list, :evaluation_list, :set_score_rule, :forbidden_anonymous_comment] + before_filter :is_logged, :only => [:index] ### def program_test @@ -91,101 +92,119 @@ class StudentWorkController < ApplicationController student_in_group = '(' + group_students.map{|user| user.id}.join(',') + ')' end #老师 || 超级管理员 || 禁用匿评&&作业截止&&已提交作品 显示所有列表 - if @is_teacher || @homework.homework_detail_manual.nil? || - (@homework.anonymous_comment == 1 && Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d") && !@homework.student_works.where(:user_id => User.current.id).empty?) + if @homework.is_open == 1 @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name @show_all = true - elsif @homework.homework_detail_manual.comment_status == 1 #学生 && 未开启匿评 只看到自己的 - if @homework.homework_type == 3 - pro = @homework.student_work_projects.where(:user_id => User.current.id).first - if pro.nil? - @stundet_works = [] + elsif @homework.is_open == 0 && User.current.member_of_course?(@course) || User.current.admin? + if @is_teacher || @homework.homework_detail_manual.nil? || + (@homework.anonymous_comment == 1 && Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d") && !@homework.student_works.where(:user_id => User.current.id).empty?) + @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name + @show_all = true + elsif @homework.homework_detail_manual.comment_status == 1 #学生 && 未开启匿评 只看到自己的 + if @homework.homework_type == 3 + pro = @homework.student_work_projects.where(:user_id => User.current.id).first + if pro.nil? + @stundet_works = [] + else + @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + end else - @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) end - else - @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) - end - elsif @homework.homework_detail_manual.comment_status == 2 #学生 && 开启匿评 看到匿评列表 - if @homework.homework_type == 3 - pro = @homework.student_work_projects.where(:user_id => User.current.id).first - if pro.nil? - my_work = [] + elsif @homework.homework_detail_manual.comment_status == 2 #学生 && 开启匿评 看到匿评列表 + if @homework.homework_type == 3 + pro = @homework.student_work_projects.where(:user_id => User.current.id).first + if pro.nil? + my_work = [] + else + my_work = @homework.student_works.where(:id => pro.student_work_id) + end else - my_work = @homework.student_works.where(:id => pro.student_work_id) + my_work = @homework.student_works.where(:user_id => User.current.id) end - else - my_work = @homework.student_works.where(:user_id => User.current.id) - end - @stundet_works = my_work + User.current.student_works_evaluation_distributions.map(&:student_work).select { |work| work.homework_common_id == @homework.id} - elsif @homework.homework_detail_manual.comment_status == 3 #学生 && 关闭匿评 未提交作品之前列表为空,提交了作品看到所有的 - if @homework.homework_type == 3 - pro = @homework.student_work_projects.where(:user_id => User.current.id).first - if pro.nil? - my_work = [] + @stundet_works = my_work + User.current.student_works_evaluation_distributions.map(&:student_work).select { |work| work.homework_common_id == @homework.id} + elsif @homework.homework_detail_manual.comment_status == 3 #学生 && 关闭匿评 未提交作品之前列表为空,提交了作品看到所有的 + if @homework.homework_type == 3 + pro = @homework.student_work_projects.where(:user_id => User.current.id).first + if pro.nil? + my_work = [] + else + my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + end else - my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) + end + if my_work.empty? + @stundet_works = [] + else + @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name + @show_all = true end else - my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) - end - if my_work.empty? @stundet_works = [] - else - @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name - @show_all = true end else - @stundet_works = [] + render_403 + return end + @student_work_count = (search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name).count else - if @is_teacher || @homework.homework_detail_manual.nil? || (@homework.anonymous_comment == 1 && Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d") && !@homework.student_works.where(:user_id => User.current.id).empty?) #老师 || 超级管理员 显示所有列表 + if @homework.is_open == 1 @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name @show_all = true - elsif @homework.homework_detail_manual.comment_status == 1 #学生 && 未开启匿评 只看到自己的 - if @homework.homework_type == 3 - pro = @homework.student_work_projects.where(:user_id => User.current.id).first - if pro.nil? - @stundet_works = [] + elsif @homework.is_open == 0 && User.current.member_of_course?(@course) || User.current.admin? + if @is_teacher || @homework.homework_detail_manual.nil? || (@homework.anonymous_comment == 1 && Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d") && !@homework.student_works.where(:user_id => User.current.id).empty?) #老师 || 超级管理员 显示所有列表 + @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name + @show_all = true + elsif @homework.homework_detail_manual.comment_status == 1 #学生 && 未开启匿评 只看到自己的 + if @homework.homework_type == 3 + pro = @homework.student_work_projects.where(:user_id => User.current.id).first + if pro.nil? + @stundet_works = [] + else + @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + end else - @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) end - else - @stundet_works = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) - end - elsif @homework.homework_detail_manual.comment_status == 2 #学生 && 开启匿评 看到匿评列表 - if @homework.homework_type == 3 - pro = @homework.student_work_projects.where(:user_id => User.current.id).first - if pro.nil? - my_work = [] + elsif @homework.homework_detail_manual.comment_status == 2 #学生 && 开启匿评 看到匿评列表 + if @homework.homework_type == 3 + pro = @homework.student_work_projects.where(:user_id => User.current.id).first + if pro.nil? + my_work = [] + else + my_work = @homework.student_works.where(:id => pro.student_work_id) + end else - my_work = @homework.student_works.where(:id => pro.student_work_id) + my_work = @homework.student_works.where(:user_id => User.current.id) end - else - my_work = @homework.student_works.where(:user_id => User.current.id) - end - @stundet_works = my_work + User.current.student_works_evaluation_distributions.map(&:student_work).select { |work| work.homework_common_id == @homework.id} - elsif @homework.homework_detail_manual.comment_status == 3 #学生 && 关闭匿评 未提交作品之前列表为空,提交了作品看到所有的 - if @homework.homework_type == 3 - pro = @homework.student_work_projects.where(:user_id => User.current.id).first - if pro.nil? - my_work = [] + @stundet_works = my_work + User.current.student_works_evaluation_distributions.map(&:student_work).select { |work| work.homework_common_id == @homework.id} + elsif @homework.homework_detail_manual.comment_status == 3 #学生 && 关闭匿评 未提交作品之前列表为空,提交了作品看到所有的 + if @homework.homework_type == 3 + pro = @homework.student_work_projects.where(:user_id => User.current.id).first + if pro.nil? + my_work = [] + else + my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + end else - my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:id => pro.student_work_id) + my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) + end + if my_work.empty? + @stundet_works = [] + else + @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name + @show_all = true end else - my_work = @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").where(:user_id => User.current.id) - end - if my_work.empty? @stundet_works = [] - else - @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name - @show_all = true end else - @stundet_works = [] + render_403 + return end + @student_work_count = (search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name).count end @@ -802,6 +821,10 @@ class StudentWorkController < ApplicationController render_403 unless User.current.allowed_to?(:as_teacher,@course) || User.current.admin? end + def is_logged + redirect_to signin_path unless User.current.logged? + end + #根据条件过滤作业结果 def search_homework_member homeworks,name if name == "" diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 507dada24..2c390025e 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -1,695 +1,695 @@ -# encoding: utf-8 -# This controller was added by william -class TagsController < ApplicationController - layout "base_tags" - - before_filter :require_admin,:only => :show - - include CoursesHelper - include ProjectsHelper - include IssuesHelper - include UsersHelper - include BidsHelper - include ForumsHelper - include AttachmentsHelper - include ContestsHelper - include ActsAsTaggableOn::TagsHelper - include TagsHelper - include FilesHelper - helper :projects - helper :courses - helper :tags - include OpenSourceProjectsHelper - - before_filter :require_admin,:only => [:delete,:show_all] - before_filter :require_login,:only => [:tag_save] - - # $selected_tags = Array.new - # $related_tags = Array.new - NUMBERS = Setting.tags_show_search_results - - # 预设几个可以添加的tag - #@preTags = %w|预设A 预设B 预设C 预设D 预设E 预设F | - - # 接收参数解释: - # params[:q]这是在其他页面点击tag,跳转到该页面后的结果显示 ;params[:selected_tags],这是在过滤页面增删tag进行过滤传过来的参数 - # 最后是2个过滤何种数据,显示结果的控制参数params[:obj_id],params[:object_falg] - # 0代表删除tag 1代表增加tag - def index - - @obj_id = params[:obj_id] - @obj_flag = params[:object_flag] - - @selected_tags = Array.new - @related_tags = nil - - if params[:q] - @selected_tags << params[:q] - else - @do_what = params[:do_what] - @tag = params[:tag] - @selected_tags = params[:current_selected_tags] - @selected_tags = @selected_tags.nil? ? Array.new : @selected_tags - - case @do_what - when '0' then - @selected_tags.delete @tag #数组中删除有多方式 可以改用shift,pop - when '1' then - # 判断是否已存在该tag 主要用来处理分页的情况 - unless @selected_tags.include? @tag - @selected_tags << @tag - end - end - end - - @users_tags_num,@projects_tags_num,@issues_tags_num,@bids_tags_num,@contests_tags_num, - @forum_tags_num, @attachments_tags_num, @open_source_projects_num = get_tags_size - - # 获取搜索结果 - @obj, - @obj_pages, - @results_count, - @users_results, - @projects_results, - @issues_results, - @bids_results, - @forums_results, - @attachments_results, - @contests_results, - @courses_results, - @open_source_projects_results= refresh_results(@obj_id,@obj_flag,@selected_tags) - - # 这里是做tag推荐用的, 用来生产推荐的tags - unless @obj.nil? - @tags = @obj.tag_list - @tags -= @selected_tags - # @selected_tags.each do |i| - # @tags.delete(i) - # end - @related_tags = @tags - else - return - end - - end - - # 增加已选的tag - def add_tag - @tag = params[:tag] - @show_flag = params[:show_flag] - - $selected_tags << @tag - $related_tags.delete(@tag) - - # 获取搜索结果 - @obj, - @obj_pages, - @results_count, - @users_results, - @projects_results, - @issues_results, - @bids_results, - @forums_results, - @attachments_results, - @contests_results, - @courses_results, - @open_source_projects_results= refresh_results(@obj_id,@show_flag) - end - - # 删除已选tag - def delete_tag - @tag = params[:tag] - @show_flag = params[:show_flag] - - $related_tags << @tag - $selected_tags.delete(@tag) - - # 获取搜索结果 - @obj, - @obj_pages, - @results_count, - @users_results, - @projects_results, - @issues_results, - @bids_results, - @forums_results, - @attachments_results, - @contests_results, - @courses_results, - @open_source_projects_results= refresh_results(@obj_id,@show_flag) - end - - def show_all - @tags = ActsAsTaggableOn::Tag.find(:all) - end - - # 完全从数据库删除tag - # 这种删除方式是针对 印有该 tag所有对象来做删除的 - # 这样是从整个系统数据库中把该tag删除了 - def delete - if params[:q] - @tag = ActsAsTaggableOn::Tag.find_by_id(params[:q]) - @tag.delete - @taggings = ActsAsTaggableOn::Tagging.find_all_by_tag_id(@tag.id) - @taggings.each do |tagging| - tagging.delete - end - end - end - - # 只删除某个对象的该tag - def remove_tag - @obj = nil - @object_flag = nil - - if request.get? - # 获取传过来的tag_id taggable_id 和 taggable_type,通过2者确定要删除tag的对象 - @tag_name = params[:tag_name] - @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id - @taggable_id = params[:taggable_id] # 当做参数传时对象会变成字符串 - @taggable_type = numbers_to_object_type(params[:taggable_type]) - - @obj = get_object(@taggable_id,params[:taggable_type]) - @object_flag = params[:taggable_type] - - # if can_remove_tag?(User.current,@taggable_id,@taggable_type) - - @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) - - unless @taggings.nil? - @taggings.delete - end - - # 是否还有其他记录 引用了 tag_id - @tagging = ActsAsTaggableOn::Tagging.find_by_tag_id(@tag_id) - # 如果taggings表中记录已经不存在 ,那么检查tags表 作删除动作 - if @tagging.nil? - @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) - @tag.delete unless @tag.nil? - end - # end - end - end - - # 只删除某个对象的该tag - def remove_tag_new - @obj = nil - @object_flag = nil - - if request.get? - # 获取传过来的tag_id taggable_id 和 taggable_type,通过2者确定要删除tag的对象 - @tag_name = params[:tag_name] - @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id - @taggable_id = params[:taggable_id] # 当做参数传时对象会变成字符串 - @taggable_type = numbers_to_object_type(params[:taggable_type]) - - @obj = get_object(@taggable_id,params[:taggable_type]) - @object_flag = params[:taggable_type] - - # if can_remove_tag?(User.current,@taggable_id,@taggable_type) - - @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) - - unless @taggings.nil? - @taggings.delete - end - - # 是否还有其他记录 引用了 tag_id - @tagging = ActsAsTaggableOn::Tagging.find_by_tag_id(@tag_id) - # 如果taggings表中记录已经不存在 ,那么检查tags表 作删除动作 - if @tagging.nil? - @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) - @tag.delete unless @tag.nil? - end - - if @obj && @object_flag == '6' && @obj.container.kind_of?(Course) - @course = @obj.container - @tag_list = get_course_tag_list @course - @select_tag_name = params[:select_tag_name] - end - - if @obj && @object_flag == '6' && @obj.container.kind_of?(Project) - @project = @obj.container - @tag_list = get_course_tag_list @project - @select_tag_name = params[:select_tag_name] - end - - if @obj && @object_flag == '6' && @obj.container.kind_of?(OrgSubfield) - @org_subfield = @obj.container - @tag_list = get_org_subfield_tag_list @org_subfield - @select_tag_name = params[:select_tag_name] - end - # end - end - end - - #更新某个tag名称 - def update_tag_name - @tag_name = params[:tagName] - @rename_tag_name = params[:renameName] - @taggable_id = params[:taggableId] - @taggable_type = numbers_to_object_type(params[:taggableType]) - @course_id = params[:courseId] - - @rename_tag = (ActsAsTaggableOn::Tag.find_by_name(@rename_tag_name)) #查找重命名后的tag - @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id #重命名前的tag_id - @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) unless @taggable_id.blank? - @obj = get_object(@taggable_id,params[:taggableType]) unless @taggable_id.blank? - if @taggable_id.blank? #如果没有传tag_id,那么直接更新tag_name就好了。但是要防止 重命名后的tag存在。 - if @course_id - course = Course.find @course_id - if course - course.attachments.each do |attachment| - taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,attachment.id,attachment.class) - if taggings - taggings.delete - attachment.tag_list.add(@rename_tag_name.split(",")) - attachment.save - end - end - end - end - else - if(@rename_tag.nil?) #这次命名的是新的tag - - # 是否还有其他记录 引用了 tag_id - @tagging = ActsAsTaggableOn::Tagging.where("tag_id = #{@tag_id}") - # 如果taggings表中记录为 1 ,那么改变@tag_id对应的tag的名字 - if @tagging.count == 1 - @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) - @tag.update_attributes({:name=>@rename_tag_name}) - else #如果tagging表中的记录大于1,那么就要新增tag记录 - - unless @obj.nil? - @obj.tag_list.add(@rename_tag_name.split(",")) - @obj.save - end - #删除原来的对应的taggings的记录 - unless @taggings.nil? - @taggings.delete - end - end - else #这是已有的tag - # 更改taggings记录里的tag_id - unless @taggings.nil? - @taggings.update_attributes({:tag_id=>@rename_tag.id}) - end - end - end - - @obj_flag = params[:taggableType] - if @obj && @obj_flag == '6' && @obj.container.kind_of?(Course) - @course = @obj.container - @tag_list = @tag_list = get_course_tag_list @course - elsif @course_id - @course = Course.find(@course_id) - @tag_list = get_course_tag_list @course - - #这里要引用FilesController里的逻辑了。将资源库当前的文件列表刷新一遍。 - @flag = params[:flag] || false - sort = "" - @sort = "" - @order = "" - @is_remote = false - @isproject = false - - sort = "#{Attachment.table_name}.created_on desc" - - @containers = [ Course.includes(:attachments).reorder(sort).find(@course.id)] - - show_attachments @containers - elsif @obj && @obj_flag == '5' - @forum = @obj - end - respond_to do |format| - format.js - end - end - - def update_project_tag_name - @tag_name = params[:tagName] - @rename_tag_name = params[:renameName] - @taggable_id = params[:taggableId] - @taggable_type = numbers_to_object_type(params[:taggableType]) - @project_id = params[:projectId] - - @rename_tag = (ActsAsTaggableOn::Tag.find_by_name(@rename_tag_name)) #查找重命名后的tag - @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id #重命名前的tag_id - @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) unless @taggable_id.blank? - @obj = get_object(@taggable_id,params[:taggableType]) unless @taggable_id.blank? - if @taggable_id.blank? #如果没有传tag_id,那么直接更新tag_name就好了。但是要防止 重命名后的tag存在。 - if @project_id - project = Project.find @project_id - if project - project.attachments.each do |attachment| - taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,attachment.id,attachment.class) - if taggings - taggings.delete - attachment.tag_list.add(@rename_tag_name.split(",")) - attachment.save - end - end - end - end - else - if(@rename_tag.nil?) #这次命名的是新的tag - - # 是否还有其他记录 引用了 tag_id - @tagging = ActsAsTaggableOn::Tagging.where("tag_id = #{@tag_id}") - # 如果taggings表中记录为 1 ,那么改变@tag_id对应的tag的名字 - if @tagging.count == 1 - @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) - @tag.update_attributes({:name=>@rename_tag_name}) - else #如果tagging表中的记录大于1,那么就要新增tag记录 - - unless @obj.nil? - @obj.tag_list.add(@rename_tag_name.split(",")) - @obj.save - end - #删除原来的对应的taggings的记录 - unless @taggings.nil? - @taggings.delete - end - end - else #这是已有的tag - # 更改taggings记录里的tag_id - unless @taggings.nil? - @taggings.update_attributes({:tag_id=>@rename_tag.id}) - end - end - end - - @obj_flag = params[:taggableType] - if @obj && @obj_flag == '6' && @obj.container.kind_of?(Project) - @project = @obj.container - @tag_list = @tag_list = get_course_tag_list @project - elsif @project_id - @project = Project.find(@project_id) - @tag_list = get_project_tag_list @project - - #这里要引用FilesController里的逻辑了。将资源库当前的文件列表刷新一遍。 - @flag = params[:flag] || false - sort = "" - @sort = "" - @order = "" - @is_remote = false - @isproject = false - - sort = "#{Attachment.table_name}.created_on desc" - - @containers = [ Project.includes(:attachments).reorder(sort).find(@project.id)] - - show_attachments @containers - elsif @obj && @obj_flag == '5' - @forum = @obj - end - respond_to do |format| - format.js - end - end - - def update_org_subfield_tag_name - @tag_name = params[:tagName] - @rename_tag_name = params[:renameName] - @taggable_id = params[:taggableId] - @taggable_type = numbers_to_object_type(params[:taggableType]) - @rename_tag = (ActsAsTaggableOn::Tag.find_by_name(@rename_tag_name)) #查找重命名后的tag - @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id #重命名前的tag_id - @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) unless @taggable_id.blank? - @obj = get_object(@taggable_id,params[:taggableType]) unless @taggable_id.blank? - if @taggable_id.blank? #如果没有传tag_id,那么直接更新tag_name就好了。但是要防止 重命名后的tag存在。 - if params[:org_subfield_id] - org_subfield = OrgSubfield.find params[:org_subfield_id] - if org_subfield - org_subfield.attachments.each do |attachment| - taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,attachment.id,attachment.class) - if taggings - taggings.delete - attachment.tag_list.add(@rename_tag_name.split(",")) - attachment.save - end - end - end - end - else - if(@rename_tag.nil?) #这次命名的是新的tag - - # 是否还有其他记录 引用了 tag_id - @tagging = ActsAsTaggableOn::Tagging.where("tag_id = #{@tag_id}") - # 如果taggings表中记录为 1 ,那么改变@tag_id对应的tag的名字 - if @tagging.count == 1 - @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) - @tag.update_attributes({:name=>@rename_tag_name}) - else #如果tagging表中的记录大于1,那么就要新增tag记录 - - unless @obj.nil? - @obj.tag_list.add(@rename_tag_name.split(",")) - @obj.save - end - #删除原来的对应的taggings的记录 - unless @taggings.nil? - @taggings.delete - end - end - else #这是已有的tag - # 更改taggings记录里的tag_id - unless @taggings.nil? - @taggings.update_attributes({:tag_id=>@rename_tag.id}) - end - end - end - - @obj_flag = params[:taggableType] - if @obj && @obj_flag == '6' && @obj.container.kind_of?(OrgSubfield) - @org_subfield = @obj.container - @tag_list = @tag_list = get_org_subfield_tag_list @org_subfield - elsif params[:org_subfield_id] - @org_subfield = OrgSubfield.find(params[:org_subfield_id]) - @tag_list = get_org_subfield_tag_list @org_subfield - - #这里要引用FilesController里的逻辑了。将资源库当前的文件列表刷新一遍。 - @flag = params[:flag] || false - sort = "" - @sort = "" - @order = "" - @is_remote = false - @isproject = false - - sort = "#{Attachment.table_name}.created_on desc" - - @containers = [ OrgSubfield.includes(:attachments).reorder(sort).find(@org_subfield.id)] - - show_attachments @containers - elsif @obj && @obj_flag == '5' - @forum = @obj - end - respond_to do |format| - format.js - end - end - - def show_attachments obj - @attachments = [] - obj.each do |container| - @attachments += container.attachments - end - @all_attachments = User.current.admin? ? @attachments : visable_attachemnts(@attachments) - @limit = 10 - @feedback_count = @all_attachments.count - @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] - @offset ||= @feedback_pages.offset - #@curse_attachments_all = @all_attachments[@offset, @limit] - @obj_attachments = paginateHelper @all_attachments,10 - end - - def tag_save - @select_tag_name = params[:tag_for_save][:tag_name] - @tags = params[:tag_for_save][:name] - @obj_id = params[:tag_for_save][:object_id] - @obj_flag = params[:tag_for_save][:object_flag] - - case @obj_flag - when '1' then - @obj = User.find_by_id(@obj_id) - when '2' then - @obj = Project.find_by_id(@obj_id) - when '3' then - @obj = Issue.find_by_id(@obj_id) - when '4' then - @obj = Bid.find_by_id(@obj_id) - when '5' then - @obj = Forum.find_by_id(@obj_id) - when '6' - @obj = Attachment.find_by_id(@obj_id) - when '7' then - @obj = Contest.find_by_id(@obj_id) - when '8' - @obj = OpenSourceProject.find_by_id(@obj_id) - when '9' - @obj = Course.find_by_id(@obj_id) - when '10' - @obj = Attachment.find_by_id(@obj_id) - else - @obj = nil - end - unless @obj.nil? - @obj.tag_list.add(@tags.split(",")) - else - return - end - if @obj.save - logger.debug "#{__FILE__}:#{__LINE__} ===> #{@obj.to_json}" - else - logger.error "#{__FILE__}:#{__LINE__} ===> #{@obj.errors.try(:full_messages)}" - end - if @obj && @obj_flag == '6' && @obj.container.kind_of?(Course) - @course = @obj.container - @tag_list = @tag_list = get_course_tag_list @course - end - if @obj && @obj_flag == '6' && @obj.container.kind_of?(Project) - @project = @obj.container - @tag_list = @tag_list = get_project_tag_list @project - end - if @obj && @obj_flag == '6' && @obj.container.kind_of?(OrgSubfield) - @org_subfield = @obj.container - @tag_list = @tag_list = get_org_subfield_tag_list @org_subfield - end - respond_to do |format| - format.js - format.html - end - end - - private - # 这里用来刷新搜索结果的区域 - # 函数的返回值 前2字段用来处理获取其他tag和分页 ,另外4个返回值为过滤结果 - def refresh_results(obj_id,obj_flag,selected_tags) - @users_results = nil - @projects_results = nil - @issues_results = nil - @bids_results = nil - @contests_results = nil - @forums_results = nil - @attachments_results = nil - @open_source_projects_results = nil - @obj_pages = nil - @obj = nil - @result = nil - @courses_results = nil - - # 这里为了提高系统的响应速度 把搜索结果放到case中去了 - case obj_flag - when '1' then - @obj = User.find_by_id(obj_id) - @obj_pages,@users_results,@results_count = for_pagination(get_users_by_tag(selected_tags)) - when '2' then - @obj = Project.find_by_id(obj_id) - @obj_pages,@projects_results,@results_count = for_pagination(get_projects_by_tag(selected_tags)) - when '3' then - @obj = Issue.find_by_id(obj_id) - @obj_pages,@issues_results,@results_count = for_pagination(get_issues_by_tag(selected_tags)) - when '4' then - @obj_pages,@bids_results,@results_count = for_pagination(get_bids_by_tag(selected_tags)) - @obj = Bid.find_by_id(obj_id) - when '5' - @obj = Forum.find_by_id(obj_id) - @obj_pages,@forums_results,@results_count = for_pagination(get_forums_by_tag(selected_tags)) - when '6' - @obj = Attachment.find_by_id(obj_id) - - # modifed by Long Jun - # this is used to find the attachments that came from the same project and tagged with the same tag. - #@result = get_attachments_by_project_tag(selected_tags, @obj) - @result = get_attachments_by_tag(selected_tags) - @obj_pages, @attachments_results, @results_count = for_pagination(@result) - when '7' - @obj = Contest.find_by_id(obj_id) - @obj_pages,@contests_results,@results_count = for_pagination(get_contests_by_tag(selected_tags)) - when '8' - @obj = OpenSourceProject.find_by_id(obj_id) - @obj_pages, @open_source_projects_results, @results_count = for_pagination(get_open_source_projects_by_tag(selected_tags)) - when '10' - @obj = Attachment.find_by_id(obj_id) - - # modifed by Long Jun - # this is used to find the attachments that came from the same project and tagged with the same tag. - #@result = get_attachments_by_project_tag(selected_tags, @obj) - @result = get_attachments_by_tag(selected_tags) - @obj_pages, @attachments_results, @results_count = for_pagination(@result) - when '9' then - @obj = Course.find_by_id(obj_id) - @obj_pages, @courses_results, @results_count = for_pagination(get_courses_by_tag(selected_tags)) - else - @obj = nil - end - return [@obj, - @obj_pages, - @results_count, - @users_results, - @projects_results, - @issues_results, - @bids_results, - @forums_results, - @attachments_results, - @contests_results, - @courses_results, - @open_source_projects_results] - end - - def for_pagination(results) - @offset, @limit = api_offset_and_limit({:limit => NUMBERS }) # 设置每页显示的个数 - @results_count = results.count - @obj_pages = Paginator.new @results_count, @limit, params['page'] # 3个参数分别是:总数,每页显示数目,第几页 - @offset ||= @obj_pages.offset - results = results.offset(@offset).limit(@limit).all # 这里默认设置为按时间排序 - return @obj_pages,results, @results_count - end - - # 获取有某类对象的tag总数 - def get_tags_size - @issues_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Issue").count - @projects_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Project").count - @users_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"User").count - @bids_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Bid").count - forum_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Forum").count - attachment_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Attachment").count - @open_source_projects_num = ActsAsTaggableOn::Tagging.where(taggable_type:"OpenSourceProject").count - @contests_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Contest").count - return @users_tags_num,@projects_tags_num,@issues_tags_num,@bids_tags_num, forum_tags_num, attachment_tags_num, @contests_tags_num, @open_source_projects_num - end - - # 通过数字 来转换出对象的类型 - # 1代表是user类型 2代表是project类型 3代表是issue类型 4代表需求 - # 这个函数 重构是可以移动到application_helper中去 - # 当做一个全局的函数使用,有好几个地方使用到了 - def numbers_to_object_type(num) - case num - when '1' - return 'Principal' - when '2' - return 'Project' - when '3' - return 'Issue' - when '4' - return 'Bid' - when '5' - return 'Forum' - when '6' - return 'Attachment' - when '7' - return 'Contest' - when '8' - return 'OpenSourceProject' - when '9' - return 'Course' - when '10' - return 'Attachment' - else - render_error :message => e.message - return - end - end - - - -end +# encoding: utf-8 +# This controller was added by william +class TagsController < ApplicationController + layout "base_tags" + + before_filter :require_admin,:only => :show + + include CoursesHelper + include ProjectsHelper + include IssuesHelper + include UsersHelper + include BidsHelper + include ForumsHelper + include AttachmentsHelper + include ContestsHelper + include ActsAsTaggableOn::TagsHelper + include TagsHelper + include FilesHelper + helper :projects + helper :courses + helper :tags + include OpenSourceProjectsHelper + + before_filter :require_admin,:only => [:delete,:show_all] + before_filter :require_login,:only => [:tag_save] + + # $selected_tags = Array.new + # $related_tags = Array.new + NUMBERS = Setting.tags_show_search_results + + # 预设几个可以添加的tag + #@preTags = %w|预设A 预设B 预设C 预设D 预设E 预设F | + + # 接收参数解释: + # params[:q]这是在其他页面点击tag,跳转到该页面后的结果显示 ;params[:selected_tags],这是在过滤页面增删tag进行过滤传过来的参数 + # 最后是2个过滤何种数据,显示结果的控制参数params[:obj_id],params[:object_falg] + # 0代表删除tag 1代表增加tag + def index + + @obj_id = params[:obj_id] + @obj_flag = params[:object_flag] + + @selected_tags = Array.new + @related_tags = nil + + if params[:q] + @selected_tags << params[:q] + else + @do_what = params[:do_what] + @tag = params[:tag] + @selected_tags = params[:current_selected_tags] + @selected_tags = @selected_tags.nil? ? Array.new : @selected_tags + + case @do_what + when '0' then + @selected_tags.delete @tag #数组中删除有多方式 可以改用shift,pop + when '1' then + # 判断是否已存在该tag 主要用来处理分页的情况 + unless @selected_tags.include? @tag + @selected_tags << @tag + end + end + end + + @users_tags_num,@projects_tags_num,@issues_tags_num,@bids_tags_num,@contests_tags_num, + @forum_tags_num, @attachments_tags_num, @open_source_projects_num = get_tags_size + + # 获取搜索结果 + @obj, + @obj_pages, + @results_count, + @users_results, + @projects_results, + @issues_results, + @bids_results, + @forums_results, + @attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results= refresh_results(@obj_id,@obj_flag,@selected_tags) + + # 这里是做tag推荐用的, 用来生产推荐的tags + unless @obj.nil? + @tags = @obj.tag_list + @tags -= @selected_tags + # @selected_tags.each do |i| + # @tags.delete(i) + # end + @related_tags = @tags + else + return + end + + end + + # 增加已选的tag + def add_tag + @tag = params[:tag] + @show_flag = params[:show_flag] + + $selected_tags << @tag + $related_tags.delete(@tag) + + # 获取搜索结果 + @obj, + @obj_pages, + @results_count, + @users_results, + @projects_results, + @issues_results, + @bids_results, + @forums_results, + @attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results= refresh_results(@obj_id,@show_flag) + end + + # 删除已选tag + def delete_tag + @tag = params[:tag] + @show_flag = params[:show_flag] + + $related_tags << @tag + $selected_tags.delete(@tag) + + # 获取搜索结果 + @obj, + @obj_pages, + @results_count, + @users_results, + @projects_results, + @issues_results, + @bids_results, + @forums_results, + @attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results= refresh_results(@obj_id,@show_flag) + end + + def show_all + @tags = ActsAsTaggableOn::Tag.find(:all) + end + + # 完全从数据库删除tag + # 这种删除方式是针对 印有该 tag所有对象来做删除的 + # 这样是从整个系统数据库中把该tag删除了 + def delete + if params[:q] + @tag = ActsAsTaggableOn::Tag.find_by_id(params[:q]) + @tag.delete + @taggings = ActsAsTaggableOn::Tagging.find_all_by_tag_id(@tag.id) + @taggings.each do |tagging| + tagging.delete + end + end + end + + # 只删除某个对象的该tag + def remove_tag + @obj = nil + @object_flag = nil + + if request.get? + # 获取传过来的tag_id taggable_id 和 taggable_type,通过2者确定要删除tag的对象 + @tag_name = params[:tag_name] + @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id + @taggable_id = params[:taggable_id] # 当做参数传时对象会变成字符串 + @taggable_type = numbers_to_object_type(params[:taggable_type]) + + @obj = get_object(@taggable_id,params[:taggable_type]) + @object_flag = params[:taggable_type] + + # if can_remove_tag?(User.current,@taggable_id,@taggable_type) + + @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) + + unless @taggings.nil? + @taggings.delete + end + + # 是否还有其他记录 引用了 tag_id + @tagging = ActsAsTaggableOn::Tagging.find_by_tag_id(@tag_id) + # 如果taggings表中记录已经不存在 ,那么检查tags表 作删除动作 + if @tagging.nil? + @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) + @tag.delete unless @tag.nil? + end + # end + end + end + + # 只删除某个对象的该tag + def remove_tag_new + @obj = nil + @object_flag = nil + + if request.get? + # 获取传过来的tag_id taggable_id 和 taggable_type,通过2者确定要删除tag的对象 + @tag_name = params[:tag_name] + @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id + @taggable_id = params[:taggable_id] # 当做参数传时对象会变成字符串 + @taggable_type = numbers_to_object_type(params[:taggable_type]) + + @obj = get_object(@taggable_id,params[:taggable_type]) + @object_flag = params[:taggable_type] + + # if can_remove_tag?(User.current,@taggable_id,@taggable_type) + + @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) + + unless @taggings.nil? + @taggings.delete + end + + # 是否还有其他记录 引用了 tag_id + @tagging = ActsAsTaggableOn::Tagging.find_by_tag_id(@tag_id) + # 如果taggings表中记录已经不存在 ,那么检查tags表 作删除动作 + if @tagging.nil? + @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) + @tag.delete unless @tag.nil? + end + + if @obj && @object_flag == '6' && @obj.container.kind_of?(Course) + @course = @obj.container + @tag_list = get_course_tag_list @course + @select_tag_name = params[:select_tag_name] + end + + if @obj && @object_flag == '6' && @obj.container.kind_of?(Project) + @project = @obj.container + @tag_list = get_course_tag_list @project + @select_tag_name = params[:select_tag_name] + end + + if @obj && @object_flag == '6' && @obj.container.kind_of?(OrgSubfield) + @org_subfield = @obj.container + @tag_list = get_org_subfield_tag_list @org_subfield + @select_tag_name = params[:select_tag_name] + end + # end + end + end + + #更新某个tag名称 + def update_tag_name + @tag_name = params[:tagName] + @rename_tag_name = params[:renameName] + @taggable_id = params[:taggableId] + @taggable_type = numbers_to_object_type(params[:taggableType]) + @course_id = params[:courseId] + + @rename_tag = (ActsAsTaggableOn::Tag.find_by_name(@rename_tag_name)) #查找重命名后的tag + @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id #重命名前的tag_id + @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) unless @taggable_id.blank? + @obj = get_object(@taggable_id,params[:taggableType]) unless @taggable_id.blank? + if @taggable_id.blank? #如果没有传tag_id,那么直接更新tag_name就好了。但是要防止 重命名后的tag存在。 + if @course_id + course = Course.find @course_id + if course + course.attachments.each do |attachment| + taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,attachment.id,attachment.class) + if taggings + taggings.delete + attachment.tag_list.add(@rename_tag_name.split(",")) + attachment.save + end + end + end + end + else + if(@rename_tag.nil?) #这次命名的是新的tag + + # 是否还有其他记录 引用了 tag_id + @tagging = ActsAsTaggableOn::Tagging.where("tag_id = #{@tag_id}") + # 如果taggings表中记录为 1 ,那么改变@tag_id对应的tag的名字 + if @tagging.count == 1 + @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) + @tag.update_attributes({:name=>@rename_tag_name}) + else #如果tagging表中的记录大于1,那么就要新增tag记录 + + unless @obj.nil? + @obj.tag_list.add(@rename_tag_name.split(",")) + @obj.save + end + #删除原来的对应的taggings的记录 + unless @taggings.nil? + @taggings.delete + end + end + else #这是已有的tag + # 更改taggings记录里的tag_id + unless @taggings.nil? + @taggings.update_attributes({:tag_id=>@rename_tag.id}) + end + end + end + + @obj_flag = params[:taggableType] + if @obj && @obj_flag == '6' && @obj.container.kind_of?(Course) + @course = @obj.container + @tag_list = @tag_list = get_course_tag_list @course + elsif @course_id + @course = Course.find(@course_id) + @tag_list = get_course_tag_list @course + + #这里要引用FilesController里的逻辑了。将资源库当前的文件列表刷新一遍。 + @flag = params[:flag] || false + sort = "" + @sort = "" + @order = "" + @is_remote = false + @isproject = false + + sort = "#{Attachment.table_name}.created_on desc" + + @containers = [ Course.includes(:attachments).reorder(sort).find(@course.id)] + + show_attachments @containers + elsif @obj && @obj_flag == '5' + @forum = @obj + end + respond_to do |format| + format.js + end + end + + def update_project_tag_name + @tag_name = params[:tagName] + @rename_tag_name = params[:renameName] + @taggable_id = params[:taggableId] + @taggable_type = numbers_to_object_type(params[:taggableType]) + @project_id = params[:projectId] + + @rename_tag = (ActsAsTaggableOn::Tag.find_by_name(@rename_tag_name)) #查找重命名后的tag + @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id #重命名前的tag_id + @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) unless @taggable_id.blank? + @obj = get_object(@taggable_id,params[:taggableType]) unless @taggable_id.blank? + if @taggable_id.blank? #如果没有传tag_id,那么直接更新tag_name就好了。但是要防止 重命名后的tag存在。 + if @project_id + project = Project.find @project_id + if project + project.attachments.each do |attachment| + taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,attachment.id,attachment.class) + if taggings + taggings.delete + attachment.tag_list.add(@rename_tag_name.split(",")) + attachment.save + end + end + end + end + else + if(@rename_tag.nil?) #这次命名的是新的tag + + # 是否还有其他记录 引用了 tag_id + @tagging = ActsAsTaggableOn::Tagging.where("tag_id = #{@tag_id}") + # 如果taggings表中记录为 1 ,那么改变@tag_id对应的tag的名字 + if @tagging.count == 1 + @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) + @tag.update_attributes({:name=>@rename_tag_name}) + else #如果tagging表中的记录大于1,那么就要新增tag记录 + + unless @obj.nil? + @obj.tag_list.add(@rename_tag_name.split(",")) + @obj.save + end + #删除原来的对应的taggings的记录 + unless @taggings.nil? + @taggings.delete + end + end + else #这是已有的tag + # 更改taggings记录里的tag_id + unless @taggings.nil? + @taggings.update_attributes({:tag_id=>@rename_tag.id}) + end + end + end + + @obj_flag = params[:taggableType] + if @obj && @obj_flag == '6' && @obj.container.kind_of?(Project) + @project = @obj.container + @tag_list = @tag_list = get_course_tag_list @project + elsif @project_id + @project = Project.find(@project_id) + @tag_list = get_project_tag_list @project + + #这里要引用FilesController里的逻辑了。将资源库当前的文件列表刷新一遍。 + @flag = params[:flag] || false + sort = "" + @sort = "" + @order = "" + @is_remote = false + @isproject = false + + sort = "#{Attachment.table_name}.created_on desc" + + @containers = [ Project.includes(:attachments).reorder(sort).find(@project.id)] + + show_attachments @containers + elsif @obj && @obj_flag == '5' + @forum = @obj + end + respond_to do |format| + format.js + end + end + + def update_org_subfield_tag_name + @tag_name = params[:tagName] + @rename_tag_name = params[:renameName] + @taggable_id = params[:taggableId] + @taggable_type = numbers_to_object_type(params[:taggableType]) + @rename_tag = (ActsAsTaggableOn::Tag.find_by_name(@rename_tag_name)) #查找重命名后的tag + @tag_id = (ActsAsTaggableOn::Tag.find_by_name(@tag_name)).id #重命名前的tag_id + @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,@taggable_id,@taggable_type) unless @taggable_id.blank? + @obj = get_object(@taggable_id,params[:taggableType]) unless @taggable_id.blank? + if @taggable_id.blank? #如果没有传tag_id,那么直接更新tag_name就好了。但是要防止 重命名后的tag存在。 + if params[:org_subfield_id] + org_subfield = OrgSubfield.find params[:org_subfield_id] + if org_subfield + org_subfield.attachments.each do |attachment| + taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,attachment.id,attachment.class) + if taggings + taggings.delete + attachment.tag_list.add(@rename_tag_name.split(",")) + attachment.save + end + end + end + end + else + if(@rename_tag.nil?) #这次命名的是新的tag + + # 是否还有其他记录 引用了 tag_id + @tagging = ActsAsTaggableOn::Tagging.where("tag_id = #{@tag_id}") + # 如果taggings表中记录为 1 ,那么改变@tag_id对应的tag的名字 + if @tagging.count == 1 + @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id) + @tag.update_attributes({:name=>@rename_tag_name}) + else #如果tagging表中的记录大于1,那么就要新增tag记录 + + unless @obj.nil? + @obj.tag_list.add(@rename_tag_name.split(",")) + @obj.save + end + #删除原来的对应的taggings的记录 + unless @taggings.nil? + @taggings.delete + end + end + else #这是已有的tag + # 更改taggings记录里的tag_id + unless @taggings.nil? + @taggings.update_attributes({:tag_id=>@rename_tag.id}) + end + end + end + + @obj_flag = params[:taggableType] + if @obj && @obj_flag == '6' && @obj.container.kind_of?(OrgSubfield) + @org_subfield = @obj.container + @tag_list = @tag_list = get_org_subfield_tag_list @org_subfield + elsif params[:org_subfield_id] + @org_subfield = OrgSubfield.find(params[:org_subfield_id]) + @tag_list = get_org_subfield_tag_list @org_subfield + + #这里要引用FilesController里的逻辑了。将资源库当前的文件列表刷新一遍。 + @flag = params[:flag] || false + sort = "" + @sort = "" + @order = "" + @is_remote = false + @isproject = false + + sort = "#{Attachment.table_name}.created_on desc" + + @containers = [ OrgSubfield.includes(:attachments).reorder(sort).find(@org_subfield.id)] + + show_attachments @containers + elsif @obj && @obj_flag == '5' + @forum = @obj + end + respond_to do |format| + format.js + end + end + + def show_attachments obj + @attachments = [] + obj.each do |container| + @attachments += container.attachments + end + @all_attachments = User.current.admin? ? @attachments : visable_attachemnts(@attachments) + @limit = 10 + @feedback_count = @all_attachments.count + @feedback_pages = Paginator.new @feedback_count, @limit, params['page'] + @offset ||= @feedback_pages.offset + #@curse_attachments_all = @all_attachments[@offset, @limit] + @obj_attachments = paginateHelper @all_attachments,10 + end + + def tag_save + @select_tag_name = params[:tag_for_save][:tag_name] + @tags = params[:tag_for_save][:name] + @obj_id = params[:tag_for_save][:object_id] + @obj_flag = params[:tag_for_save][:object_flag] + + case @obj_flag + when '1' then + @obj = User.find_by_id(@obj_id) + when '2' then + @obj = Project.find_by_id(@obj_id) + when '3' then + @obj = Issue.find_by_id(@obj_id) + when '4' then + @obj = Bid.find_by_id(@obj_id) + when '5' then + @obj = Forum.find_by_id(@obj_id) + when '6' + @obj = Attachment.find_by_id(@obj_id) + when '7' then + @obj = Contest.find_by_id(@obj_id) + when '8' + @obj = OpenSourceProject.find_by_id(@obj_id) + when '9' + @obj = Course.find_by_id(@obj_id) + when '10' + @obj = Attachment.find_by_id(@obj_id) + else + @obj = nil + end + unless @obj.nil? + @obj.tag_list.add(@tags.split(",")) + else + return + end + if @obj.save + logger.debug "#{__FILE__}:#{__LINE__} ===> #{@obj.to_json}" + else + logger.error "#{__FILE__}:#{__LINE__} ===> #{@obj.errors.try(:full_messages)}" + end + if @obj && @obj_flag == '6' && @obj.container.kind_of?(Course) + @course = @obj.container + @tag_list = @tag_list = get_course_tag_list @course + end + if @obj && @obj_flag == '6' && @obj.container.kind_of?(Project) + @project = @obj.container + @tag_list = @tag_list = get_project_tag_list @project + end + if @obj && @obj_flag == '6' && @obj.container.kind_of?(OrgSubfield) + @org_subfield = @obj.container + @tag_list = @tag_list = get_org_subfield_tag_list @org_subfield + end + respond_to do |format| + format.js + format.html + end + end + + private + # 这里用来刷新搜索结果的区域 + # 函数的返回值 前2字段用来处理获取其他tag和分页 ,另外4个返回值为过滤结果 + def refresh_results(obj_id,obj_flag,selected_tags) + @users_results = nil + @projects_results = nil + @issues_results = nil + @bids_results = nil + @contests_results = nil + @forums_results = nil + @attachments_results = nil + @open_source_projects_results = nil + @obj_pages = nil + @obj = nil + @result = nil + @courses_results = nil + + # 这里为了提高系统的响应速度 把搜索结果放到case中去了 + case obj_flag + when '1' then + @obj = User.find_by_id(obj_id) + @obj_pages,@users_results,@results_count = for_pagination(get_users_by_tag(selected_tags)) + when '2' then + @obj = Project.find_by_id(obj_id) + @obj_pages,@projects_results,@results_count = for_pagination(get_projects_by_tag(selected_tags)) + when '3' then + @obj = Issue.find_by_id(obj_id) + @obj_pages,@issues_results,@results_count = for_pagination(get_issues_by_tag(selected_tags)) + when '4' then + @obj_pages,@bids_results,@results_count = for_pagination(get_bids_by_tag(selected_tags)) + @obj = Bid.find_by_id(obj_id) + when '5' + @obj = Forum.find_by_id(obj_id) + @obj_pages,@forums_results,@results_count = for_pagination(get_forums_by_tag(selected_tags)) + when '6' + @obj = Attachment.find_by_id(obj_id) + + # modifed by Long Jun + # this is used to find the attachments that came from the same project and tagged with the same tag. + #@result = get_attachments_by_project_tag(selected_tags, @obj) + @result = get_attachments_by_tag(selected_tags) + @obj_pages, @attachments_results, @results_count = for_pagination(@result) + when '7' + @obj = Contest.find_by_id(obj_id) + @obj_pages,@contests_results,@results_count = for_pagination(get_contests_by_tag(selected_tags)) + when '8' + @obj = OpenSourceProject.find_by_id(obj_id) + @obj_pages, @open_source_projects_results, @results_count = for_pagination(get_open_source_projects_by_tag(selected_tags)) + when '10' + @obj = Attachment.find_by_id(obj_id) + + # modifed by Long Jun + # this is used to find the attachments that came from the same project and tagged with the same tag. + #@result = get_attachments_by_project_tag(selected_tags, @obj) + @result = get_attachments_by_tag(selected_tags) + @obj_pages, @attachments_results, @results_count = for_pagination(@result) + when '9' then + @obj = Course.find_by_id(obj_id) + @obj_pages, @courses_results, @results_count = for_pagination(get_courses_by_tag(selected_tags)) + else + @obj = nil + end + return [@obj, + @obj_pages, + @results_count, + @users_results, + @projects_results, + @issues_results, + @bids_results, + @forums_results, + @attachments_results, + @contests_results, + @courses_results, + @open_source_projects_results] + end + + def for_pagination(results) + @offset, @limit = api_offset_and_limit({:limit => NUMBERS }) # 设置每页显示的个数 + @results_count = results.count + @obj_pages = Paginator.new @results_count, @limit, params['page'] # 3个参数分别是:总数,每页显示数目,第几页 + @offset ||= @obj_pages.offset + results = results.offset(@offset).limit(@limit).all # 这里默认设置为按时间排序 + return @obj_pages,results, @results_count + end + + # 获取有某类对象的tag总数 + def get_tags_size + @issues_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Issue").count + @projects_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Project").count + @users_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"User").count + @bids_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Bid").count + forum_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Forum").count + attachment_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Attachment").count + @open_source_projects_num = ActsAsTaggableOn::Tagging.where(taggable_type:"OpenSourceProject").count + @contests_tags_num = ActsAsTaggableOn::Tagging.where(taggable_type:"Contest").count + return @users_tags_num,@projects_tags_num,@issues_tags_num,@bids_tags_num, forum_tags_num, attachment_tags_num, @contests_tags_num, @open_source_projects_num + end + + # 通过数字 来转换出对象的类型 + # 1代表是user类型 2代表是project类型 3代表是issue类型 4代表需求 + # 这个函数 重构是可以移动到application_helper中去 + # 当做一个全局的函数使用,有好几个地方使用到了 + def numbers_to_object_type(num) + case num + when '1' + return 'Principal' + when '2' + return 'Project' + when '3' + return 'Issue' + when '4' + return 'Bid' + when '5' + return 'Forum' + when '6' + return 'Attachment' + when '7' + return 'Contest' + when '8' + return 'OpenSourceProject' + when '9' + return 'Course' + when '10' + return 'Attachment' + else + render_error :message => e.message + return + end + end + + + +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index fb35d8495..d1f98668c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -532,9 +532,10 @@ class UsersController < ApplicationController if @student_work.nil? @student_work = StudentWork.new end + @course = @homework.course respond_to do |format| format.js - format.html {render :layout => 'new_base_user'} + format.html {render :layout => 'base_courses'} end else render_403 diff --git a/app/controllers/words_controller.rb b/app/controllers/words_controller.rb index 351be4e64..d1aa67483 100644 --- a/app/controllers/words_controller.rb +++ b/app/controllers/words_controller.rb @@ -74,9 +74,10 @@ class WordsController < ApplicationController # render 'test/index' # } format.js { + #@reply_type = params[:reply_type] @user_activity_id = params[:user_activity_id] @activity = JournalsForMessage.find(parent_id) - @is_activity = params[:is_activity] + @is_activity = params[:is_activity] if params[:is_activity] } end @@ -98,6 +99,10 @@ class WordsController < ApplicationController @user_activity_id = params[:user_activity_id] if params[:user_activity_id] @is_activity = params[:is_activity].to_i if params[:is_activity] @activity = @journal_destroyed.parent if @journal_destroyed.parent + unless @activity + redirect_to feedback_path(@user) + return + end elsif @journal_destroyed.jour_type == 'HomeworkCommon' @homework = HomeworkCommon.find @journal_destroyed.jour_id if params[:user_activity_id] diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 412c3f889..4ad3cb49d 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -1,463 +1,463 @@ -# encoding: utf-8 -# -# Redmine - project management software -# Copyright (C) 2006-2013 Jean-Philippe Lang -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -module IssuesHelper - include ApplicationHelper - - def issue_list(issues, &block) - ancestors = [] - issues.each do |issue| - while (ancestors.any? && !issue.is_descendant_of?(ancestors.last)) - ancestors.pop - end - yield issue, ancestors.size - ancestors << issue unless issue.leaf? - end - end - - # Renders a HTML/CSS tooltip - # - # To use, a trigger div is needed. This is a div with the class of "tooltip" - # that contains this method wrapped in a span with the class of "tip" - # - #
<%= link_to_issue(issue) %> - # <%= render_issue_tooltip(issue) %> - #
- # - def render_issue_tooltip(issue) - @cached_label_status ||= l(:field_status) - @cached_label_start_date ||= l(:field_start_date) - @cached_label_due_date ||= l(:field_due_date) - @cached_label_assigned_to ||= l(:field_assigned_to) - @cached_label_priority ||= l(:field_priority) - @cached_label_project ||= l(:field_project) - - link_to_issue(issue) + "

".html_safe + - "#{@cached_label_project}: #{link_to_project(issue.project)}
".html_safe + - "#{@cached_label_status}: #{h(issue.status.name)}
".html_safe + - "#{@cached_label_start_date}: #{format_date(issue.start_date)}
".html_safe + - "#{@cached_label_due_date}: #{format_date(issue.due_date)}
".html_safe + - "#{@cached_label_assigned_to}: #{h(issue.assigned_to)}
".html_safe + - "#{@cached_label_priority}: #{h(issue.priority.name)}".html_safe - end - - def issue_heading(issue) - #h("#{issue.tracker} ##{issue.id}") - # h("#{issue.tracker} #{issue.source_from}") - s = '' - s << link_to(@issue.project.name, project_issues_path(@issue.project), :class => "pro_page_top") - s << " > " - s << link_to("#" + @issue.project_index, project_issues_path(@issue.project), :class => "pro_page_top") - s.html_safe - end - - #获取跟踪类型及样式 - def get_issue_type(value) - issuetype = [] - if value == "缺陷" || value == 1 - issuetype << "issues fl" - issuetype << "缺陷" - elsif value == "任务" || value == 4 - issuetype << "duty fl" - issuetype << "任务" - elsif value == "支持" || value == 3 - issuetype << "support fl" - issuetype << "支持" - elsif value == "功能" || value == 2 - issuetype << "function fl" - issuetype << "功能" - else - issuetype << "weekly fl" - issuetype << "周报" - end - end - - # 获取优先级样式 value值1 2 低 - def get_issue_priority(value) - issuetype = [] - if value == "紧急" || value == 4 - issuetype << "red_btn_cir ml10" - issuetype << "紧急" - elsif value == "正常" || value == 2 - issuetype << "green_btn_cir ml10" - issuetype << "正常" - elsif value == "高" || value == 3 - issuetype << "orange_btn_cir ml10" - issuetype << "高" - elsif value == "低" || value == 1 - issuetype << "bgreen_btn_cir ml10" - issuetype << "低" - else - issuetype << "red_btn_cir ml10" - issuetype << "立刻" - end - end - - def principals_options_for_isuue_list(project) - if User.current.member_of?(project) - project.members.order("lower(users.login)").map{|c| [c.name, c.user_id]}.unshift(["<< #{l(:label_me)} >>", User.current.id]).unshift(["指派给", 0]) - else - project.members.order("lower(users.login)").map{|c| [c.name, c.user_id]}.unshift(["指派给", 0]) - end - end - - def render_issue_subject_with_tree(issue) - s = '' - ancestors = issue.root? ? [] : issue.ancestors.visible.all - ancestors.each do |ancestor| - s << '
' + content_tag('p', link_to_issue(ancestor, :project => (issue.project_id != ancestor.project_id))) - end - s << '
' - subject = h(issue.subject) - if issue.is_private? - subject = content_tag('span', l(:field_is_private), :class => 'private') + ' ' + subject - end - s << content_tag('h3', subject) - s << '
' * (ancestors.size + 1) - s.html_safe - end - - def render_descendants_tree(issue) - s = '
' - issue_list(issue.descendants.visible.sort_by(&:lft)) do |child, level| - css = "issue issue-#{child.id} hascontextmenu" - css << " idnt idnt-#{level}" if level > 0 - s << content_tag('tr', - content_tag('td', check_box_tag("ids[]", child.id, false, :id => nil), :class => 'checkbox') + - content_tag('td', link_to_issue(child, :truncate => 60, :project => (issue.project_id != child.project_id)), :class => 'subject') + - content_tag('td', h(child.status)) + - content_tag('td', link_to_user(child.assigned_to)) + - content_tag('td', progress_bar(child.done_ratio, :width => '80px')), - :class => css) - end - s << '
' - s.html_safe - end - - # Returns a link for adding a new subtask to the given issue - def link_to_new_subtask(issue) - attrs = { - :tracker_id => issue.tracker, - :parent_issue_id => issue - } - link_to(l(:button_add), new_project_issue_path(issue.project, :issue => attrs)) - end - - class IssueFieldsRows - include ActionView::Helpers::TagHelper - - def initialize - @left = [] - @right = [] - end - - def left(*args) - args.any? ? @left << cells(*args) : @left - end - - def right(*args) - args.any? ? @right << cells(*args) : @right - end - - def size - @left.size > @right.size ? @left.size : @right.size - end - - def to_html - html = ''.html_safe - blank = content_tag('th', '') + content_tag('td', '') - size.times do |i| - left = @left[i] || blank - right = @right[i] || blank - html << content_tag('tr', left + right) - end - html - end - - def cells(label, text, options={}) - content_tag('th', "#{label}:", options) + content_tag('td', text, options) - end - end - - def issue_fields_rows - r = IssueFieldsRows.new - yield r - r.to_html - end - - def render_custom_fields_rows(issue) - return if issue.custom_field_values.empty? - ordered_values = [] - half = (issue.custom_field_values.size / 2.0).ceil - half.times do |i| - ordered_values << issue.custom_field_values[i] - ordered_values << issue.custom_field_values[i + half] - end - s = "\n" - n = 0 - ordered_values.compact.each do |value| - s << "\n\n" if n > 0 && (n % 2) == 0 - s << "\t#{ h(value.custom_field.name) }:#{ simple_format_without_paragraph(h(show_value(value))) }\n" - n += 1 - end - s << "\n" - s.html_safe - end - - def issues_destroy_confirmation_message(issues) - issues = [issues] unless issues.is_a?(Array) - message = l(:text_issues_destroy_confirmation) - descendant_count = issues.inject(0) {|memo, i| memo += (i.right - i.left - 1)/2} - if descendant_count > 0 - issues.each do |issue| - next if issue.root? - issues.each do |other_issue| - descendant_count -= 1 if issue.is_descendant_of?(other_issue) - end - end - if descendant_count > 0 - message << "\n" + l(:text_issues_destroy_descendants_confirmation, :count => descendant_count) - end - end - message - end - - def sidebar_queries - unless @sidebar_queries - @sidebar_queries = IssueQuery.visible.all( - :order => "#{Query.table_name}.name ASC", - # Project specific queries and global queries - :conditions => (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]) - ) - end - @sidebar_queries - end - - def query_links(title, queries) - # links to #index on issues/show - url_params = controller_name == 'issues' ? {:controller => 'issues', :action => 'index', :project_id => @project} : params - - content_tag('h3', h(title)) + - queries.collect {|query| - css = 'query' - css << ' selected' if query == @query - link_to(h(query.name), url_params.merge(:query_id => query), :class => css) - }.join('
').html_safe - end - - def render_sidebar_queries - out = ''.html_safe - queries = sidebar_queries.select {|q| !q.is_public?} - out << query_links(l(:label_my_queries), queries) if queries.any? - queries = sidebar_queries.select {|q| q.is_public?} - out << query_links(l(:label_query_plural), queries) if queries.any? - out - end - - # Returns the textual representation of a journal details - # as an array of strings - def details_to_strings(details, no_html=false, options={}) - options[:only_path] = (options[:only_path] == false ? false : true) - options[:token] = options[:token] if options[:token] - strings = [] - values_by_field = {} - details.each do |detail| - - if detail.property == 'cf' - field_id = detail.prop_key - field = CustomField.find_by_id(field_id) - if field && field.multiple? - values_by_field[field_id] ||= {:added => [], :deleted => []} - if detail.old_value - values_by_field[field_id][:deleted] << detail.old_value - end - if detail.value - values_by_field[field_id][:added] << detail.value - end - next - end - end - strings << show_detail(detail, no_html, options) - - end - values_by_field.each do |field_id, changes| - detail = JournalDetail.new(:property => 'cf', :prop_key => field_id) - if changes[:added].any? - detail.value = changes[:added] - strings << show_detail(detail, no_html, options) - elsif changes[:deleted].any? - detail.old_value = changes[:deleted] - strings << show_detail(detail, no_html, options) - end - end - strings - end - - # Returns the textual representation of a single journal detail - def show_detail(detail, no_html=false, options={}) - multiple = false - case detail.property - when 'attr' - field = detail.prop_key.to_s.gsub(/\_id$/, "") - label = l(("field_" + field).to_sym) - case detail.prop_key - when 'due_date', 'start_date' - value = format_date(detail.value.to_date) if detail.value - old_value = format_date(detail.old_value.to_date) if detail.old_value - - when 'project_id', 'status_id', 'tracker_id', 'assigned_to_id', - 'priority_id', 'category_id', 'fixed_version_id' - value = find_name_by_reflection(field, detail.value) - old_value = find_name_by_reflection(field, detail.old_value) - - when 'estimated_hours' - value = "%0.02f" % detail.value.to_f unless detail.value.blank? - old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank? - - when 'parent_id' - label = l(:field_parent_issue) - value = "##{detail.value}" unless detail.value.blank? - old_value = "##{detail.old_value}" unless detail.old_value.blank? - - when 'is_private' - value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank? - old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank? - end - when 'cf' - custom_field = CustomField.find_by_id(detail.prop_key) - if custom_field - multiple = custom_field.multiple? - label = custom_field.name - value = format_value(detail.value, custom_field.field_format) if detail.value - old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value - end - when 'attachment' - label = l(:label_attachment) - end - call_hook(:helper_issues_show_detail_after_setting, - {:detail => detail, :label => label, :value => value, :old_value => old_value }) - - label ||= detail.prop_key - value ||= detail.value - old_value ||= detail.old_value - - unless no_html - label = content_tag('strong', label) - old_value = content_tag("i", h(old_value)) if detail.old_value - old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank? - if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key) - # Link to the attachment if it has not been removed - if options[:token].nil? - value = atta.filename - else - value = atta.filename - end - # 放大镜搜索功能 - # if options[:only_path] != false && atta.is_text? - # value += link_to( - # image_tag('magnifier.png'), - # :controller => 'attachments', :action => 'show', - # :id => atta, :filename => atta.filename - # ) - # end - else - value = content_tag("i", h(value)) if value - end - end - # 缺陷更新结果在消息中显示样式 - if no_html == "message" - label = content_tag(:span, label, :class => "issue_update_message") - old_value = content_tag("span", h(old_value)) if detail.old_value - old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank? - if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key) - # Link to the attachment if it has not been removed - if options[:token].nil? - value = atta.filename - else - value = atta.filename - end - else - value = content_tag(:span, h(value), :class => "issue_update_message_value") if value - end - end - - if detail.property == 'attr' && detail.prop_key == 'description' - s = l(:text_journal_changed_no_detail, :label => label) - unless no_html - diff_link = link_to l(:label_diff), - {:controller => 'journals', :action => 'diff', :id => detail.journal_id, - :detail_id => detail.id, :only_path => options[:only_path]}, - :title => l(:label_view_diff) - s << " (#{ diff_link })" - end - s.html_safe - elsif detail.value.present? - case detail.property - when 'attr', 'cf' - if detail.old_value.present? - l(:text_journal_changed, :label => label, :old => old_value, :new => value).html_safe - elsif multiple - l(:text_journal_added, :label => label, :value => value).html_safe - else - l(:text_journal_set_to, :label => label, :value => value).html_safe - end - when 'attachment' - l(:text_journal_added, :label => label, :value => value).html_safe - end - else - l(:text_journal_deleted, :label => label, :old => old_value).html_safe - end - end - - # Find the name of an associated record stored in the field attribute - def find_name_by_reflection(field, id) - unless id.present? - return nil - end - association = Issue.reflect_on_association(field.to_sym) - if association - record = association.class_name.constantize.find_by_id(id) - if record - record.name.force_encoding('UTF-8') if record.name.respond_to?(:force_encoding) - return record.name - end - end - end - - # Renders issue children recursively - def render_api_issue_children(issue, api) - return if issue.leaf? - api.array :children do - issue.children.each do |child| - api.issue(:id => child.id) do - api.tracker(:id => child.tracker_id, :name => child.tracker.name) unless child.tracker.nil? - api.subject child.subject - render_api_issue_children(child, api) - end - end - end - end - - # this method is used to get all projects that tagged one tag - # added by william - def get_issues_by_tag(tag_name) - Issue.tagged_with(tag_name).order('updated_on desc') - end - -end +# encoding: utf-8 +# +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +module IssuesHelper + include ApplicationHelper + + def issue_list(issues, &block) + ancestors = [] + issues.each do |issue| + while (ancestors.any? && !issue.is_descendant_of?(ancestors.last)) + ancestors.pop + end + yield issue, ancestors.size + ancestors << issue unless issue.leaf? + end + end + + # Renders a HTML/CSS tooltip + # + # To use, a trigger div is needed. This is a div with the class of "tooltip" + # that contains this method wrapped in a span with the class of "tip" + # + #
<%= link_to_issue(issue) %> + # <%= render_issue_tooltip(issue) %> + #
+ # + def render_issue_tooltip(issue) + @cached_label_status ||= l(:field_status) + @cached_label_start_date ||= l(:field_start_date) + @cached_label_due_date ||= l(:field_due_date) + @cached_label_assigned_to ||= l(:field_assigned_to) + @cached_label_priority ||= l(:field_priority) + @cached_label_project ||= l(:field_project) + + link_to_issue(issue) + "

".html_safe + + "#{@cached_label_project}: #{link_to_project(issue.project)}
".html_safe + + "#{@cached_label_status}: #{h(issue.status.name)}
".html_safe + + "#{@cached_label_start_date}: #{format_date(issue.start_date)}
".html_safe + + "#{@cached_label_due_date}: #{format_date(issue.due_date)}
".html_safe + + "#{@cached_label_assigned_to}: #{h(issue.assigned_to)}
".html_safe + + "#{@cached_label_priority}: #{h(issue.priority.name)}".html_safe + end + + def issue_heading(issue) + #h("#{issue.tracker} ##{issue.id}") + # h("#{issue.tracker} #{issue.source_from}") + s = '' + s << link_to(@issue.project.name, project_issues_path(@issue.project), :class => "pro_page_top") + s << " > " + s << link_to("#" + @issue.project_index, project_issues_path(@issue.project), :class => "pro_page_top") + s.html_safe + end + + #获取跟踪类型及样式 + def get_issue_type(value) + issuetype = [] + if value == "缺陷" || value == 1 + issuetype << "issues fl" + issuetype << "缺陷" + elsif value == "任务" || value == 4 + issuetype << "duty fl" + issuetype << "任务" + elsif value == "支持" || value == 3 + issuetype << "support fl" + issuetype << "支持" + elsif value == "功能" || value == 2 + issuetype << "issues-function fl" + issuetype << "功能" + else + issuetype << "weekly fl" + issuetype << "周报" + end + end + + # 获取优先级样式 value值1 2 低 + def get_issue_priority(value) + issuetype = [] + if value == "紧急" || value == 4 + issuetype << "red_btn_cir ml10" + issuetype << "紧急" + elsif value == "正常" || value == 2 + issuetype << "green_btn_cir ml10" + issuetype << "正常" + elsif value == "高" || value == 3 + issuetype << "orange_btn_cir ml10" + issuetype << "高" + elsif value == "低" || value == 1 + issuetype << "bgreen_btn_cir ml10" + issuetype << "低" + else + issuetype << "red_btn_cir ml10" + issuetype << "立刻" + end + end + + def principals_options_for_isuue_list(project) + if User.current.member_of?(project) + project.members.order("lower(users.login)").map{|c| [c.name, c.user_id]}.unshift(["<< #{l(:label_me)} >>", User.current.id]).unshift(["指派给", 0]) + else + project.members.order("lower(users.login)").map{|c| [c.name, c.user_id]}.unshift(["指派给", 0]) + end + end + + def render_issue_subject_with_tree(issue) + s = '' + ancestors = issue.root? ? [] : issue.ancestors.visible.all + ancestors.each do |ancestor| + s << '
' + content_tag('p', link_to_issue(ancestor, :project => (issue.project_id != ancestor.project_id))) + end + s << '
' + subject = h(issue.subject) + if issue.is_private? + subject = content_tag('span', l(:field_is_private), :class => 'private') + ' ' + subject + end + s << content_tag('h3', subject) + s << '
' * (ancestors.size + 1) + s.html_safe + end + + def render_descendants_tree(issue) + s = '
' + issue_list(issue.descendants.visible.sort_by(&:lft)) do |child, level| + css = "issue issue-#{child.id} hascontextmenu" + css << " idnt idnt-#{level}" if level > 0 + s << content_tag('tr', + content_tag('td', check_box_tag("ids[]", child.id, false, :id => nil), :class => 'checkbox') + + content_tag('td', link_to_issue(child, :truncate => 60, :project => (issue.project_id != child.project_id)), :class => 'subject') + + content_tag('td', h(child.status)) + + content_tag('td', link_to_user(child.assigned_to)) + + content_tag('td', progress_bar(child.done_ratio, :width => '80px')), + :class => css) + end + s << '
' + s.html_safe + end + + # Returns a link for adding a new subtask to the given issue + def link_to_new_subtask(issue) + attrs = { + :tracker_id => issue.tracker, + :parent_issue_id => issue + } + link_to(l(:button_add), new_project_issue_path(issue.project, :issue => attrs)) + end + + class IssueFieldsRows + include ActionView::Helpers::TagHelper + + def initialize + @left = [] + @right = [] + end + + def left(*args) + args.any? ? @left << cells(*args) : @left + end + + def right(*args) + args.any? ? @right << cells(*args) : @right + end + + def size + @left.size > @right.size ? @left.size : @right.size + end + + def to_html + html = ''.html_safe + blank = content_tag('th', '') + content_tag('td', '') + size.times do |i| + left = @left[i] || blank + right = @right[i] || blank + html << content_tag('tr', left + right) + end + html + end + + def cells(label, text, options={}) + content_tag('th', "#{label}:", options) + content_tag('td', text, options) + end + end + + def issue_fields_rows + r = IssueFieldsRows.new + yield r + r.to_html + end + + def render_custom_fields_rows(issue) + return if issue.custom_field_values.empty? + ordered_values = [] + half = (issue.custom_field_values.size / 2.0).ceil + half.times do |i| + ordered_values << issue.custom_field_values[i] + ordered_values << issue.custom_field_values[i + half] + end + s = "\n" + n = 0 + ordered_values.compact.each do |value| + s << "\n\n" if n > 0 && (n % 2) == 0 + s << "\t#{ h(value.custom_field.name) }:#{ simple_format_without_paragraph(h(show_value(value))) }\n" + n += 1 + end + s << "\n" + s.html_safe + end + + def issues_destroy_confirmation_message(issues) + issues = [issues] unless issues.is_a?(Array) + message = l(:text_issues_destroy_confirmation) + descendant_count = issues.inject(0) {|memo, i| memo += (i.right - i.left - 1)/2} + if descendant_count > 0 + issues.each do |issue| + next if issue.root? + issues.each do |other_issue| + descendant_count -= 1 if issue.is_descendant_of?(other_issue) + end + end + if descendant_count > 0 + message << "\n" + l(:text_issues_destroy_descendants_confirmation, :count => descendant_count) + end + end + message + end + + def sidebar_queries + unless @sidebar_queries + @sidebar_queries = IssueQuery.visible.all( + :order => "#{Query.table_name}.name ASC", + # Project specific queries and global queries + :conditions => (@project.nil? ? ["project_id IS NULL"] : ["project_id IS NULL OR project_id = ?", @project.id]) + ) + end + @sidebar_queries + end + + def query_links(title, queries) + # links to #index on issues/show + url_params = controller_name == 'issues' ? {:controller => 'issues', :action => 'index', :project_id => @project} : params + + content_tag('h3', h(title)) + + queries.collect {|query| + css = 'query' + css << ' selected' if query == @query + link_to(h(query.name), url_params.merge(:query_id => query), :class => css) + }.join('
').html_safe + end + + def render_sidebar_queries + out = ''.html_safe + queries = sidebar_queries.select {|q| !q.is_public?} + out << query_links(l(:label_my_queries), queries) if queries.any? + queries = sidebar_queries.select {|q| q.is_public?} + out << query_links(l(:label_query_plural), queries) if queries.any? + out + end + + # Returns the textual representation of a journal details + # as an array of strings + def details_to_strings(details, no_html=false, options={}) + options[:only_path] = (options[:only_path] == false ? false : true) + options[:token] = options[:token] if options[:token] + strings = [] + values_by_field = {} + details.each do |detail| + + if detail.property == 'cf' + field_id = detail.prop_key + field = CustomField.find_by_id(field_id) + if field && field.multiple? + values_by_field[field_id] ||= {:added => [], :deleted => []} + if detail.old_value + values_by_field[field_id][:deleted] << detail.old_value + end + if detail.value + values_by_field[field_id][:added] << detail.value + end + next + end + end + strings << show_detail(detail, no_html, options) + + end + values_by_field.each do |field_id, changes| + detail = JournalDetail.new(:property => 'cf', :prop_key => field_id) + if changes[:added].any? + detail.value = changes[:added] + strings << show_detail(detail, no_html, options) + elsif changes[:deleted].any? + detail.old_value = changes[:deleted] + strings << show_detail(detail, no_html, options) + end + end + strings + end + + # Returns the textual representation of a single journal detail + def show_detail(detail, no_html=false, options={}) + multiple = false + case detail.property + when 'attr' + field = detail.prop_key.to_s.gsub(/\_id$/, "") + label = l(("field_" + field).to_sym) + case detail.prop_key + when 'due_date', 'start_date' + value = format_date(detail.value.to_date) if detail.value + old_value = format_date(detail.old_value.to_date) if detail.old_value + + when 'project_id', 'status_id', 'tracker_id', 'assigned_to_id', + 'priority_id', 'category_id', 'fixed_version_id' + value = find_name_by_reflection(field, detail.value) + old_value = find_name_by_reflection(field, detail.old_value) + + when 'estimated_hours' + value = "%0.02f" % detail.value.to_f unless detail.value.blank? + old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank? + + when 'parent_id' + label = l(:field_parent_issue) + value = "##{detail.value}" unless detail.value.blank? + old_value = "##{detail.old_value}" unless detail.old_value.blank? + + when 'is_private' + value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank? + old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank? + end + when 'cf' + custom_field = CustomField.find_by_id(detail.prop_key) + if custom_field + multiple = custom_field.multiple? + label = custom_field.name + value = format_value(detail.value, custom_field.field_format) if detail.value + old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value + end + when 'attachment' + label = l(:label_attachment) + end + call_hook(:helper_issues_show_detail_after_setting, + {:detail => detail, :label => label, :value => value, :old_value => old_value }) + + label ||= detail.prop_key + value ||= detail.value + old_value ||= detail.old_value + + unless no_html + label = content_tag('strong', label) + old_value = content_tag("i", h(old_value)) if detail.old_value + old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank? + if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key) + # Link to the attachment if it has not been removed + if options[:token].nil? + value = atta.filename + else + value = atta.filename + end + # 放大镜搜索功能 + # if options[:only_path] != false && atta.is_text? + # value += link_to( + # image_tag('magnifier.png'), + # :controller => 'attachments', :action => 'show', + # :id => atta, :filename => atta.filename + # ) + # end + else + value = content_tag("i", h(value)) if value + end + end + # 缺陷更新结果在消息中显示样式 + if no_html == "message" + label = content_tag(:span, label, :class => "issue_update_message") + old_value = content_tag("span", h(old_value)) if detail.old_value + old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank? + if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key) + # Link to the attachment if it has not been removed + if options[:token].nil? + value = atta.filename + else + value = atta.filename + end + else + value = content_tag(:span, h(value), :class => "issue_update_message_value") if value + end + end + + if detail.property == 'attr' && detail.prop_key == 'description' + s = l(:text_journal_changed_no_detail, :label => label) + unless no_html + diff_link = link_to l(:label_diff), + {:controller => 'journals', :action => 'diff', :id => detail.journal_id, + :detail_id => detail.id, :only_path => options[:only_path]}, + :title => l(:label_view_diff) + s << " (#{ diff_link })" + end + s.html_safe + elsif detail.value.present? + case detail.property + when 'attr', 'cf' + if detail.old_value.present? + l(:text_journal_changed, :label => label, :old => old_value, :new => value).html_safe + elsif multiple + l(:text_journal_added, :label => label, :value => value).html_safe + else + l(:text_journal_set_to, :label => label, :value => value).html_safe + end + when 'attachment' + l(:text_journal_added, :label => label, :value => value).html_safe + end + else + l(:text_journal_deleted, :label => label, :old => old_value).html_safe + end + end + + # Find the name of an associated record stored in the field attribute + def find_name_by_reflection(field, id) + unless id.present? + return nil + end + association = Issue.reflect_on_association(field.to_sym) + if association + record = association.class_name.constantize.find_by_id(id) + if record + record.name.force_encoding('UTF-8') if record.name.respond_to?(:force_encoding) + return record.name + end + end + end + + # Renders issue children recursively + def render_api_issue_children(issue, api) + return if issue.leaf? + api.array :children do + issue.children.each do |child| + api.issue(:id => child.id) do + api.tracker(:id => child.tracker_id, :name => child.tracker.name) unless child.tracker.nil? + api.subject child.subject + render_api_issue_children(child, api) + end + end + end + end + + # this method is used to get all projects that tagged one tag + # added by william + def get_issues_by_tag(tag_name) + Issue.tagged_with(tag_name).order('updated_on desc') + end + +end diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index ff4aa61fb..36187b460 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -41,6 +41,16 @@ module RepositoriesHelper identifiers.include?(iden) ? false :true end + # 获取diff内容行号 + def diff_line_num content + content.scan(/@@ -(\d+),\d+ \+\d+,\d+ @@/).first.join("").to_i + end + + # 处理内容 + def diff_content content + content.gsub!(/.*@@ -\d+,\d+ \+\d+,\d+ @@\n/m,'') + end + def format_revision(revision) if revision.respond_to? :format_identifier revision.format_identifier diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb index 4edfed578..efb67a2ac 100644 --- a/app/helpers/users_helper.rb +++ b/app/helpers/users_helper.rb @@ -85,6 +85,11 @@ module UsersHelper end end + def link_to_user_version(version, options = {}) + return '' unless version && version.is_a?(Version) + link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, :class => "linkBlue" + end + # 统计未读消息数 def unviewed_message(user) course_count = CourseMessage.where("user_id =? and viewed =?", user, 0).count diff --git a/app/models/attachment.rb b/app/models/attachment.rb index ea9ad2cc0..e29f8698f 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -28,6 +28,7 @@ class Attachment < ActiveRecord::Base belongs_to :attachmentstype, :foreign_key => "attachtype",:primary_key => "id" # 被ForgeActivity虚拟关联 has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy + has_many :forwards, :as => :from # 课程动态 has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy # end @@ -87,7 +88,8 @@ class Attachment < ActiveRecord::Base cattr_accessor :thumbnails_storage_path @@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails") - before_save :files_to_final_location,:act_as_course_activity + before_save :files_to_final_location + after_save :act_as_course_activity after_create :office_conver, :be_user_score,:act_as_forge_activity,:create_attachment_ealasticsearch_index after_update :office_conver, :be_user_score,:update_attachment_ealasticsearch_index after_destroy :delete_from_disk,:down_user_score,:delete_attachment_ealasticsearch_index, :decrease_attchments_count @@ -605,8 +607,14 @@ class Attachment < ActiveRecord::Base #课程动态公共表记录 def act_as_course_activity - if self.container_type == "Course" && self.course_acts.empty? - self.course_acts << CourseActivity.new(:user_id => self.author_id,:course_id => self.container_id) + if self.container_type == "Course" + if self.is_publish == 0 + self.course_acts.destroy_all + else + if self.is_publish == 1 && self.course_acts.empty? + self.course_acts << CourseActivity.new(:user_id => self.author_id,:course_id => self.container_id) + end + end end end @@ -643,8 +651,8 @@ class Attachment < ActiveRecord::Base def decrease_attchments_count if self.container_type == "Project" && !self.project.project_score.nil? - aatach_count = self.container.project_score.attach_num - 1 - self.container.project_score.update_attribute(:attach_num, aatach_count) + attach_count = self.container.project_score.attach_num - 1 + self.container.project_score.update_attribute(:attach_num, attach_count < 0 ? 0 : attach_count) end end end diff --git a/app/models/forward.rb b/app/models/forward.rb new file mode 100644 index 000000000..c0dffd5e8 --- /dev/null +++ b/app/models/forward.rb @@ -0,0 +1,4 @@ +class Forward < ActiveRecord::Base + validates_presence_of :from_id, :from_type, :to_id, :to_type + belongs_to :from, :polymorphic => true +end \ No newline at end of file diff --git a/app/models/issue.rb b/app/models/issue.rb index e1de4cd9e..c82f6f0be 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -184,7 +184,7 @@ class Issue < ActiveRecord::Base def decrease_issues_count unless self.project.project_score.nil? issue_count = self.project.project_score.issue_num - 1 - self.project.project_score.update_attribute(:issue_num, issue_count) + self.project.project_score.update_attribute(:issue_num, issue_count < 0 ? 0 : issue_count) end end diff --git a/app/models/journal.rb b/app/models/journal.rb index b184c82e6..c37b8d2c5 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -219,8 +219,9 @@ class Journal < ActiveRecord::Base # 减少留言数量统计 def decrease_issues_journal_count unless self.issue.project.nil? - project = self.issue.project - project.project_score.update_attribute(:issue_journal_num, project.project_score.issue_journal_num - 1) + journal_count = self.issue.project.project_score.issue_journal_num - 1 + # project = self.issue.project + self.issue.project.project_score.update_attribute(:issue_journal_num, journal_count < 0 ? 0 : journal_count) end end diff --git a/app/models/message.rb b/app/models/message.rb index 675d37790..6381f444f 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -146,10 +146,10 @@ class Message < ActiveRecord::Base # 讨论区 if self.parent_id.nil? count = self.project.project_score.board_num - 1 - self.project.project_score.update_attribute(:board_num, count) + self.project.project_score.update_attribute(:board_num, count < 0 ? 0 : count) else # 回复 count = self.project.project_score.board_message_num - 1 - self.project.project_score.update_attribute(:board_message_num, count) + self.project.project_score.update_attribute(:board_message_num, count < 0 ? 0 : count) end end end diff --git a/app/models/news.rb b/app/models/news.rb index fee5d2801..d0fccae17 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -126,7 +126,7 @@ class News < ActiveRecord::Base def decrease_news_count if self.project && !self.project.project_score.nil? count = self.project.project_score.news_num - 1 - self.project.project_score.update_attribute(:news_num, count) + self.project.project_score.update_attribute(:news_num, count < 0 ? 0 : count) end end diff --git a/app/services/courses_service.rb b/app/services/courses_service.rb index ef0c2eb16..2c8387349 100644 --- a/app/services/courses_service.rb +++ b/app/services/courses_service.rb @@ -252,6 +252,7 @@ class CoursesService def edit_course(params,course,current_user) course.send(:safe_attributes=, params[:course], current_user) #course.safe_attributes = params[:course] + course.password = params[:course][:password] course.time = params[:time] course.term = params[:term] course.end_time = params[:end_time] diff --git a/app/views/admin/_tab_users.erb b/app/views/admin/_tab_users.erb new file mode 100644 index 000000000..2cda0c61c --- /dev/null +++ b/app/views/admin/_tab_users.erb @@ -0,0 +1,7 @@ +
+
    +
  • <%= link_to '用户', {:action => 'latest_login_users'}, class: "#{current_page?(latest_login_users_path)? 'selected' : nil }" %>
  • +
  • <%= link_to '老师', {:action => 'latest_login_teachers'}, class: "#{current_page?(latest_login_teachers_path)? 'selected' : nil }" %>
  • + +
+
\ No newline at end of file diff --git a/app/views/admin/latest_login_teachers.html.erb b/app/views/admin/latest_login_teachers.html.erb new file mode 100644 index 000000000..06c0386f5 --- /dev/null +++ b/app/views/admin/latest_login_teachers.html.erb @@ -0,0 +1,84 @@ +<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', :media => 'all' %> +

+ <%=l(:label_latest_login_user_list)%> +

+<%= render 'tab_users' %> + +

+ 最近登录老师列表 +

+<%= form_tag({}, :method => :get) do %> +
+ + <%= l(:label_filter_plural) %> + + + <%= text_field_tag 'startdate', params[:startdate], :size => 15, :onchange=>"$('#ui-datepicker-div').hide()", :style=>"float:left"%> + <%= calendar_for('startdate')%>    + + <%= text_field_tag 'enddate', params[:enddate], :size => 15, :onchange =>"$('#ui-datepicker-div').hide()", :style=>"float:left"%> + <%= calendar_for('enddate')%>   + <%= submit_tag l(:button_apply), :class => "small", :name => nil %> + <%= link_to l(:button_clear), {:controller => 'admin', :action => 'latest_login_teachers'}, :class => 'icon icon-reload' %> +
+<% end %> +  +
+ + + + + + + + + + + + + <% @count=@page * 30 %> + <% for teacher in @teachers do %> + + <% @count +=1 %> + + + + + + + + <% end %> + +
+ 序号 + + 登录时间 + + 用户id + + 用户姓名 + + 用户登录名 + + 用户身份 +
+ <%=@count %> + + <%=format_time(teacher.last_login_on) %> + + <%=teacher.id %> + <%= teacher.login%><% else %><%=teacher.try(:realname) %><% end %>'> + <% if teacher.try(:realname) == ' '%> + <%= link_to(teacher.login, user_path(teacher)) %> + <% else %> + <%= link_to(teacher.try(:realname), user_path(teacher)) %> + <% end %> + + <%=link_to(teacher.login, user_path(teacher)) %> + + 老师 +
+
+ diff --git a/app/views/admin/latest_login_users.html.erb b/app/views/admin/latest_login_users.html.erb index 594f554b4..17680a8c8 100644 --- a/app/views/admin/latest_login_users.html.erb +++ b/app/views/admin/latest_login_users.html.erb @@ -2,7 +2,10 @@

<%=l(:label_latest_login_user_list)%>

- +<%= render 'tab_users' %> +

+ <%=l(:label_latest_login_user_list)%> +

<%= form_tag({}, :method => :get) do %>
diff --git a/app/views/common/_file.html.erb b/app/views/common/_file.html.erb index 97443beea..486c760f1 100644 --- a/app/views/common/_file.html.erb +++ b/app/views/common/_file.html.erb @@ -8,7 +8,7 @@ <%= line_num %> -
<%= line.html_safe %>
+
<%= line.html_safe %>
<% line_num += 1 %> diff --git a/app/views/courses/_copy_course.html.erb b/app/views/courses/_copy_course.html.erb index c7547adcd..68184d352 100644 --- a/app/views/courses/_copy_course.html.erb +++ b/app/views/courses/_copy_course.html.erb @@ -92,16 +92,23 @@ (选中后课外用户可见该课程,否则仅对课内成员可见)
-
  • - -
      -
    • - +
    • + +
        +
      • + + 复制到新课中的作业将在1个月后发布、2个月后提交截止,请您调整作业的发布时间、截止时间等时间节点。 +
      • +
      • + + 复制到新课的资源将在1个月后发布,请您调整资源的发布时间,否则学生可能看不到资源。
      -
        +
        <% end %> diff --git a/app/views/courses/copy_course.js.erb b/app/views/courses/copy_course.js.erb index ca9e3c1f2..83dc80717 100644 --- a/app/views/courses/copy_course.js.erb +++ b/app/views/courses/copy_course.js.erb @@ -3,7 +3,7 @@ if(document.getElementById("popbox02")) { } $('#ajax-modal').html('<%= escape_javascript(render :partial => 'copy_course') %>'); showModal('ajax-modal', '730px'); -$('#ajax-modal').css('height','530px').css('width','730px'); +$('#ajax-modal').css('height','auto').css('width','730px'); $('#ajax-modal').siblings().remove(); $('#ajax-modal').before("
        " + "
        "); diff --git a/app/views/courses/settings/_join_org.html.erb b/app/views/courses/settings/_join_org.html.erb index fff0f807c..f7b4d7551 100644 --- a/app/views/courses/settings/_join_org.html.erb +++ b/app/views/courses/settings/_join_org.html.erb @@ -15,8 +15,8 @@
          - 关联 - 取消 + 关联 + 取消 <% end %>
    • diff --git a/app/views/files/search_org_subfield_tag_attachment.js.erb b/app/views/files/search_org_subfield_tag_attachment.js.erb index deed2d5d3..fe4aed937 100644 --- a/app/views/files/search_org_subfield_tag_attachment.js.erb +++ b/app/views/files/search_org_subfield_tag_attachment.js.erb @@ -1,2 +1,3 @@ $("#org_subfield_list").html("<%= escape_javascript(render :partial => 'org_subfield_list', - :locals => {org_subfield: @org_subfield,all_attachments: @result,sort:@sort,order:@order,org_subfield_attachments:@searched_attach})%>"); \ No newline at end of file + :locals => {org_subfield: @org_subfield,all_attachments: @result,sort:@sort,order:@order,org_subfield_attachments:@searched_attach})%>"); +$("#attachment_count").html("<%= @result.count %>"); \ No newline at end of file diff --git a/app/views/homework_common/_alert_open_student_works.html.erb b/app/views/homework_common/_alert_open_student_works.html.erb new file mode 100644 index 000000000..ef8fe3d08 --- /dev/null +++ b/app/views/homework_common/_alert_open_student_works.html.erb @@ -0,0 +1,23 @@ +
      +
      + <% if @homework.is_open == 0 %> +

      公开作品

      +

      + 本次作业的所有作品将对Trustie平台所有注册用户开放,请问是否确定公开作品? +

      + <% else %> +

      取消公开作品

      +

      + 您将取消“公开作品”的功能,本次作业的作品将不对Trustie平台其他未加入本课程的用户开放,请问是否确定? +

      + <% end %> + +
      +
      \ No newline at end of file diff --git a/app/views/homework_common/alert_open_student_works.js.erb b/app/views/homework_common/alert_open_student_works.js.erb new file mode 100644 index 000000000..591d34028 --- /dev/null +++ b/app/views/homework_common/alert_open_student_works.js.erb @@ -0,0 +1,6 @@ +$("#ajax-modal").html("<%=escape_javascript(render :partial => 'alert_open_student_works') %>"); +showModal('ajax-modal', '500px'); +$('#ajax-modal').siblings().remove(); +$('#ajax-modal').before("" + + ""); +$('#ajax-modal').parent().css("top","30%").css("left","30%").css("position","fixed").css("border","3px solid #269ac9"); \ No newline at end of file diff --git a/app/views/homework_common/open_student_works.js.erb b/app/views/homework_common/open_student_works.js.erb new file mode 100644 index 000000000..e171e65d1 --- /dev/null +++ b/app/views/homework_common/open_student_works.js.erb @@ -0,0 +1,7 @@ +<% if @user_activity_id.to_i == -1 %> +$("#homework_common_<%= @homework.id %>").replaceWith("<%= escape_javascript(render :partial => "users/user_homework_detail",:locals => {:homework_common => @homework, :is_in_course => @is_in_course})%>"); +sd_create_editor_from_data(<%= @homework.id%>,"","100%", "<%=@homework.class.to_s%>"); +<% else %> +$("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/course_homework', :locals => {:activity => @homework,:user_activity_id =>@user_activity_id,:course_activity=>@course_activity}) %>"); +sd_create_editor_from_data(<%= @user_activity_id%>,"","100%", "UserActivity"); +<% end %> \ No newline at end of file diff --git a/app/views/issues/_detail.html.erb b/app/views/issues/_detail.html.erb index 00aa341fe..92021f728 100644 --- a/app/views/issues/_detail.html.erb +++ b/app/views/issues/_detail.html.erb @@ -8,7 +8,7 @@ <% when 1%> <% when 2%> - + <% when 3%> <% when 4%> diff --git a/app/views/layouts/base_courses.html.erb b/app/views/layouts/base_courses.html.erb index 138616fda..8dfda10bd 100644 --- a/app/views/layouts/base_courses.html.erb +++ b/app/views/layouts/base_courses.html.erb @@ -1,6 +1,11 @@ <%# course_model %> <% course_file_num = visable_attachemnts_incourse(@course).count%> <% is_teacher = User.current.logged? && (User.current.admin? || User.current.allowed_to?(:as_teacher,@course)) %> +<% if User.current.admin? || User.current.allowed_to?(:as_teacher,@course) %> + <% homework_num = @course.homework_commons.count %> +<% else %> + <% homework_num = @course.homework_commons.where("publish_time <= '#{Date.today}'").count %> +<% end %> @@ -74,7 +79,7 @@ <% unless show_nav?(@course.homework_commons.count) %> <% end %> @@ -176,7 +181,7 @@ <% if student_score.score.to_i != 0 %>
    • <%=link_to image_tag(url_to_avatar(student_score.user), :width => "35", :height => "35", :class=> "rankPortrait"),user_path(student_score.user) %>

      <%=link_to student_score.user.show_name, user_path(student_score.user), :title => student_score.user.show_name %>

      -

      <%= student_score.score.to_i %>

      +

      "><%= student_score.score<0 ? 0 : student_score.score.to_i %>

    • <% end %> <% end %> diff --git a/app/views/layouts/base_org.html.erb b/app/views/layouts/base_org.html.erb index 6062d760b..f810dd1d6 100644 --- a/app/views/layouts/base_org.html.erb +++ b/app/views/layouts/base_org.html.erb @@ -46,12 +46,12 @@ <% else %> - - + + <% end %> <% if @repository.report_last_commit %> -<%= link_to_revision(entry.changeset, @repository) if entry.changeset %> -<%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %> -<%= entry.author %> -<%=h truncate(entry.changeset.comments, :length => 50) if entry.changeset %> + <%= link_to_revision(entry.changeset, @repository) if entry.changeset %> + <%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %> + <%= entry.author %> + <%=h truncate(entry.changeset.comments, :length => 50) if entry.changeset %> <% end %> <% end %> diff --git a/app/views/repositories/_revisions.html.erb b/app/views/repositories/_revisions.html.erb index 4d6e39f88..a27789dc1 100644 --- a/app/views/repositories/_revisions.html.erb +++ b/app/views/repositories/_revisions.html.erb @@ -20,27 +20,13 @@
      • -
        - <% if !user_commit_rep(changeset.author_email).nil? %> - - <%= image_tag(url_to_avatar(user_commit_rep(changeset.author_email)), :width => "20", :height => "20", :class => "fl portraitRadius mt2 ml4 mr5") %> - <%= link_to user_commit_rep(changeset.author_email), user_path(user_commit_rep(changeset.author_email)), :length => 30 %>提交于 -
        -   -
        - <% else %> - <%= changeset.author_email %>提交于 -
        -   -
        - <% end %> -
        + <%= render :partial => 'commit_details', :locals => {:changeset => changeset} %>
        <%= textilizable(truncate_at_line_break(changeset.message)) %>
        - <%= h truncate(changeset.short_id.to_s, :length => 20) %> + <%= link_to truncate(changeset.short_id.to_s, :length => 20), {:controller => 'repositories', :action => 'commit_diff', :id => project.id, :changeset => changeset.id} %>
        diff --git a/app/views/repositories/changes.html.erb b/app/views/repositories/changes.html.erb index 3780df172..726d5d19d 100644 --- a/app/views/repositories/changes.html.erb +++ b/app/views/repositories/changes.html.erb @@ -15,7 +15,7 @@
        - <%= render(:partial => 'revisions', :locals => {:project => @project, :path => @path ,:revisions => @commits, :entry => @entry ,:commits_pages =>@commits_pages , :commits_count => @commits_count}) unless @commits.empty? %> + <%= render(:partial => 'revisions', :locals => {:project => @project, :path => @path , :revisions => @commits, :entry => @entry , :commits_pages => @commits_pages , :commits_count => @commits_count}) unless @commits.empty? %>
        <% content_for :header_tags do %> diff --git a/app/views/repositories/commit_diff.html.erb b/app/views/repositories/commit_diff.html.erb new file mode 100644 index 000000000..5ebeec09a --- /dev/null +++ b/app/views/repositories/commit_diff.html.erb @@ -0,0 +1,55 @@ +
        +

        <%= render :partial => 'breadcrumbs', :locals => {:path => @path, :kind => 'dir', :revision => @rev} %>

        +
        + + + + + + + +
      • + <%= render :partial => 'commit_details', :locals => {:changeset => @commit_details} %> +
      • +
      +
      <%= @commit_details.message %>
      + + + + + + + + +<% @commit_diff.each do |cd| %> + +
      + + + <% line_num = diff_line_num(cd.diff) %> + <% diff_content = diff_content(cd.diff) %> + <% syntax_highlight_lines(cd.new_path, Redmine::CodesetUtil.to_utf8_by_setting(diff_content)).each do |line| %> + + + <% if line[0,1] == "-" %> + + <% elsif line[0,1] == "+" %> + + <% else%> + + <% end %> + + <% line_num += 1 %> + <% end %> + +
      + <%= line_num %> +
      <%= line.html_safe %>
      <%= line.html_safe %>
      <%= line.html_safe %>
      +
      +<% end %> \ No newline at end of file diff --git a/app/views/student_work/_student_work_list.html.erb b/app/views/student_work/_student_work_list.html.erb index df89f31eb..1eea8f1c2 100644 --- a/app/views/student_work/_student_work_list.html.erb +++ b/app/views/student_work/_student_work_list.html.erb @@ -4,15 +4,16 @@ (<%= @student_work_count%>人已交) - <% if !@is_teacher && @stundet_works.empty?%> + <% my_work = @homework.student_works.where("user_id = #{User.current.id}").first %> + <% if !@is_teacher && my_work.nil? && User.current.member_of_course?(@course) %> 您尚未提交作品 - <% elsif !@is_teacher &&Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.parse(Time.now.to_s).strftime("%Y-%m-%d") && !@stundet_works.empty?%> + <% elsif !@is_teacher && my_work &&Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.parse(Time.now.to_s).strftime("%Y-%m-%d") && !@stundet_works.empty?%> 您已提交且不可再修改,因为截止日期已过 - <% elsif !@is_teacher &&Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.parse(Time.now.to_s).strftime("%Y-%m-%d") && !@stundet_works.empty?%> + <% elsif !@is_teacher && my_work &&Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.parse(Time.now.to_s).strftime("%Y-%m-%d") && !@stundet_works.empty?%> 您已提交,您还可以修改 <% end %> - <%if @is_teacher || @homework.homework_detail_manual.comment_status == 3%> + <%if @is_teacher || @homework.homework_detail_manual.comment_status == 3 || @homework.is_open == 1%>
      diff --git a/app/views/tags/update_project_tag_name.js.erb b/app/views/tags/update_project_tag_name.js.erb index c1d181e35..1dc5d58fa 100644 --- a/app/views/tags/update_project_tag_name.js.erb +++ b/app/views/tags/update_project_tag_name.js.erb @@ -1,11 +1,11 @@ -<% if @obj %> -$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").empty(); -$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").html('<%= escape_javascript(render :partial => 'tags/tag_list', - :locals => {:obj => @obj,:object_flag => @obj_flag,:select_tag_name => @select_tag_name}) %>'); -$("#tags_name_<%=@obj.id%>").val(""); -$("#add_tag_<%=@obj.id%>").hide(); -<% else %> -$("#course_list").html("<%= escape_javascript(render :partial => 'files/project_list', - :locals => {project: @project,all_attachments: @all_attachments,sort:@sort,order:@order,project_attachments:@obj_attachments}) %>"); -<% end %> +<% if @obj %> +$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").empty(); +$("#tags_show-<%=@obj.class%>-<%=@obj.id%>").html('<%= escape_javascript(render :partial => 'tags/tag_list', + :locals => {:obj => @obj,:object_flag => @obj_flag,:select_tag_name => @select_tag_name}) %>'); +$("#tags_name_<%=@obj.id%>").val(""); +$("#add_tag_<%=@obj.id%>").hide(); +<% else %> +$("#course_list").html("<%= escape_javascript(render :partial => 'files/project_list', + :locals => {project: @project,all_attachments: @all_attachments,sort:@sort,order:@order,project_attachments:@obj_attachments}) %>"); +<% end %> $("#files_tag_project").html("<%= escape_javascript(render :partial => "files/tag_yun_project", :locals => {:tag_list => @tag_list,:project => @project,:tag_name => @select_tag_name}) %>"); \ No newline at end of file diff --git a/app/views/users/_course_homework.html.erb b/app/views/users/_course_homework.html.erb index d508fe1af..b43951c08 100644 --- a/app/views/users/_course_homework.html.erb +++ b/app/views/users/_course_homework.html.erb @@ -114,9 +114,11 @@
      -
      - 缺评扣分:<%= activity.homework_detail_manual.absence_penalty%>分/作品 -
      + <% if activity.anonymous_comment == 0%> +
      + 缺评扣分:<%= activity.homework_detail_manual.absence_penalty%>分/作品 +
      + <% end %> <% if activity.anonymous_comment == 0%>
      匿评关闭时间:<%= activity.homework_detail_manual.evaluation_end%> 23:59 @@ -239,6 +241,15 @@ <%= link_to("禁用匿评", alert_forbidden_anonymous_comment_homework_common_path(activity,:user_activity_id => user_activity_id,:course_activity=>course_activity),:class => "postOptionLink", :remote => true)%> <% end %> + <% if (activity.anonymous_comment == 1 && activity.is_open == 0) || (activity.anonymous_comment == 0 && comment_status == 3 && activity.is_open == 0) %> +
    • + <%= link_to("公开作品", alert_open_student_works_homework_common_path(activity,:user_activity_id => user_activity_id, :is_in_course => -1,:course_activity=>course_activity),:class => "postOptionLink", :remote => true)%> +
    • + <% elsif activity.is_open == 1 %> +
    • + <%= link_to("取消公开", alert_open_student_works_homework_common_path(activity,:user_activity_id => user_activity_id, :is_in_course => -1,:course_activity=>course_activity),:class => "postOptionLink", :remote => true)%> +
    • + <% end %> diff --git a/app/views/users/_project_issue.html.erb b/app/views/users/_project_issue.html.erb index c5d93e0a5..1ce03da17 100644 --- a/app/views/users/_project_issue.html.erb +++ b/app/views/users/_project_issue.html.erb @@ -18,7 +18,7 @@ <% when 1%> <% when 2%> - + <% when 3%> <% when 4%> diff --git a/app/views/users/_user_homework_detail.html.erb b/app/views/users/_user_homework_detail.html.erb index 01673d164..4c980d7fc 100644 --- a/app/views/users/_user_homework_detail.html.erb +++ b/app/views/users/_user_homework_detail.html.erb @@ -115,9 +115,11 @@
      -
      - 缺评扣分:<%= homework_common.homework_detail_manual.absence_penalty%>分/作品 -
      + <% if homework_common.anonymous_comment == 0 %> +
      + 缺评扣分:<%= homework_common.homework_detail_manual.absence_penalty%>分/作品 +
      + <% end %> <% if homework_common.anonymous_comment == 0%>
      匿评关闭时间:<%= homework_common.homework_detail_manual.evaluation_end%> 23:59 @@ -243,6 +245,15 @@ <%= link_to("禁用匿评", alert_forbidden_anonymous_comment_homework_common_path(homework_common,:is_in_course => is_in_course),:class => "postOptionLink", :remote => true)%> <% end %> + <% if (homework_common.anonymous_comment == 1 && homework_common.is_open == 0) || (homework_common.anonymous_comment == 0 && comment_status == 3 && homework_common.is_open == 0) %> +
    • + <%= link_to("公开作品", alert_open_student_works_homework_common_path(homework_common, :is_in_course => is_in_course,:course_activity=> -1),:class => "postOptionLink", :remote => true)%> +
    • + <% elsif homework_common.is_open == 1 %> +
    • + <%= link_to("取消公开", alert_open_student_works_homework_common_path(homework_common, :is_in_course => is_in_course,:course_activity=> -1),:class => "postOptionLink", :remote => true)%> +
    • + <% end %> diff --git a/app/views/users/_user_journalsformessage.html.erb b/app/views/users/_user_journalsformessage.html.erb index 4b2fcb486..f49a65262 100644 --- a/app/views/users/_user_journalsformessage.html.erb +++ b/app/views/users/_user_journalsformessage.html.erb @@ -47,7 +47,7 @@
    • <%= link_to(l(:label_bid_respond_delete), {:controller => 'words', :action => 'destroy', :object_id => activity, :user_id => activity.user,:user_activity_id => user_activity_id,:is_activity=>is_activity}, - :remote => true, :confirm => l(:text_are_you_sure), :method => 'delete', + :confirm => l(:text_are_you_sure), :method => 'delete', :class => "postOptionLink", :title => l(:button_delete)) %>
    • diff --git a/app/views/users/new_user_commit_homework.html.erb b/app/views/users/new_user_commit_homework.html.erb index eed789a29..02bfc9203 100644 --- a/app/views/users/new_user_commit_homework.html.erb +++ b/app/views/users/new_user_commit_homework.html.erb @@ -4,7 +4,12 @@ <%= stylesheet_link_tag "/assets/codemirror/codemirror" %> <% end %> - + -
      +
      @@ -91,7 +96,9 @@
      测试代码 - <% unless @is_test %> + <% if @is_test %> + <%=link_to '返 回',course_path(@course),:class=>'fr mt6' %> + <% else @is_test %> 提交代码 <% end %>
      diff --git a/app/views/words/create_reply.js.erb b/app/views/words/create_reply.js.erb index a5c572049..ded05887f 100644 --- a/app/views/words/create_reply.js.erb +++ b/app/views/words/create_reply.js.erb @@ -1,11 +1,11 @@ <% if @save_succ %> <% if @user_activity_id %> - <% if @reply_type == 'user' %> + <% if @is_activity %> $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/user_journalsformessage', :locals => {:activity => @activity,:user_activity_id =>@user_activity_id,:is_activity=>@is_activity}) %>"); <% else %> $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/course_journalsformessage', :locals => {:activity => @activity,:user_activity_id =>@user_activity_id}) %>"); <% end %> - #init_activity_KindEditor_data('<%= @user_activity_id%>', "", "87%", "UserActivity"); + //init_activity_KindEditor_data('<%#= @user_activity_id%>', "", "87%", "UserActivity"); sd_create_editor_from_data('<%= @user_activity_id%>', "", "100%", "UserActivity"); <% else %> <% if !@jfm.nil? && @jfm.jour_type == 'Principal' %> diff --git a/app/views/words/destroy.js.erb b/app/views/words/destroy.js.erb index 819936f9f..a2d606e76 100644 --- a/app/views/words/destroy.js.erb +++ b/app/views/words/destroy.js.erb @@ -4,7 +4,8 @@ <% if @is_user%> <% if @activity %> $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/user_journalsformessage', :locals => {:activity => @activity,:user_activity_id =>@user_activity_id,:is_activity=>@is_activity}) %>"); - init_activity_KindEditor_data('<%= @user_activity_id%>', "", "87%", "UserActivity"); + //init_activity_KindEditor_data('<%#= @user_activity_id%>', "", "87%", "UserActivity"); + sd_create_editor_from_data('<%= @user_activity_id%>', "", "100%", "UserActivity"); <% else %> $("#user_activity_<%= @user_activity_id%>").hide(); <% end %> diff --git a/config/routes.rb b/config/routes.rb index bd17a9011..45d6e8c47 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -238,6 +238,8 @@ RedmineApp::Application.routes.draw do get 'stop_anonymous_comment' get 'alert_anonymous_comment' get 'alert_forbidden_anonymous_comment' + get 'alert_open_student_works' + get 'open_student_works' get 'start_evaluation_set' get 'score_rule_set' post 'set_evaluation_attr' @@ -832,7 +834,7 @@ RedmineApp::Application.routes.draw do :controller => 'repositories', :format => false, :constraints => { - :action => /(browse|show|entry|raw|annotate|diff)/, + :action => /(browse|show|entry|raw|annotate|diff|commit_diff)/, :rev => /[a-z0-9\.\-_]+/ } @@ -851,15 +853,15 @@ RedmineApp::Application.routes.draw do :controller => 'repositories', :format => false, :constraints => { - :action => /(browse|show|entry|raw|annotate|diff)/, + :action => /(browse|show|entry|raw|annotate|diff|commit_diff)/, :rev => /[a-z0-9\.\-_]+/ } get 'projects/:id/repository/:repository_id/:action(/*path(.:ext))', :controller => 'repositories', - :action => /(browse|show|entry|raw|changes|annotate|diff)/ + :action => /(browse|show|entry|raw|changes|annotate|diff|commit_diff)/ get 'projects/:id/repository/:action(/*path(.:ext))', :controller => 'repositories', - :action => /(browse|show|entry|raw|changes|annotate|diff)/ + :action => /(browse|show|entry|raw|changes|annotate|diff|commit_diff)/ get 'projects/:id/repository/:repository_id', :to => 'repositories#show', :path => nil get 'projects/:id/repository', :to => 'repositories#show', :path => nil @@ -952,7 +954,8 @@ RedmineApp::Application.routes.draw do match 'admin/project_messages', as: :project_messages match'admin/course_messages', as: :course_messages get 'admin/notices' - get 'admin/latest_login_users' + match 'admin/latest_login_users', as: :latest_login_users + match 'admin/latest_login_teachers', as: :latest_login_teachers get 'admin/homework' resources :auth_sources do diff --git a/db/migrate/20160223021012_add_index_to_secdomain.rb b/db/migrate/20160223021012_add_index_to_secdomain.rb deleted file mode 100644 index 928dfdbab..000000000 --- a/db/migrate/20160223021012_add_index_to_secdomain.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIndexToSecdomain < ActiveRecord::Migration - def change - add_index(:secdomains, :subname, unique: true) - end -end diff --git a/db/migrate/20160224032046_create_forwards.rb b/db/migrate/20160224032046_create_forwards.rb new file mode 100644 index 000000000..4404dc300 --- /dev/null +++ b/db/migrate/20160224032046_create_forwards.rb @@ -0,0 +1,15 @@ +class CreateForwards < ActiveRecord::Migration + def up + create_table :forwards do|t| + t.integer :from_id + t.string :from_type + t.integer :to_id + t.string :to_type + t.timestamp :created_at + end + end + + def down + drop_table :forwards + end +end diff --git a/db/migrate/20160224074034_update_one_student_score.rb b/db/migrate/20160224074034_update_one_student_score.rb new file mode 100644 index 000000000..6e1930652 --- /dev/null +++ b/db/migrate/20160224074034_update_one_student_score.rb @@ -0,0 +1,38 @@ +class UpdateOneStudentScore < ActiveRecord::Migration + def up + student_work_score = StudentWorksScore.where("user_id = 11688 AND student_work_id = 34414").first + student_work_score.score = 100 + student_work_score.save + student_works = StudentWork.where("user_id = 6456") + student_works.each do |work| + unless work.student_works_scores.empty? + if work.student_works_scores.where(:reviewer_role => 2).empty? + work.teaching_asistant_score = nil + else + work.teaching_asistant_score = work.student_works_scores.where(:reviewer_role => 2).average(:score).try(:round, 2).to_f + end + if work.student_works_scores.where(:reviewer_role => 3).empty? + work.student_score = nil + else + work.student_score = work.student_works_scores.where(:reviewer_role => 3).average(:score).try(:round, 2).to_f + end + end + if work.teaching_asistant_score.nil? + work.final_score = work.student_score + elsif work.student_score.nil? + work.final_score = work.teaching_asistant_score + else + homework = HomeworkCommon.find work.homework_common_id + ta_proportion = homework.homework_detail_manual.ta_proportion + final_ta_score = BigDecimal.new("#{work.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}") + final_s_score = BigDecimal.new("#{work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}")) + final_score = final_ta_score + final_s_score + work.final_score = format("%.2f",final_score.to_f) + end + work.save + end + end + + def down + end +end diff --git a/db/migrate/20160225024759_add_is_open_to_homewrok_common.rb b/db/migrate/20160225024759_add_is_open_to_homewrok_common.rb new file mode 100644 index 000000000..760205e26 --- /dev/null +++ b/db/migrate/20160225024759_add_is_open_to_homewrok_common.rb @@ -0,0 +1,5 @@ +class AddIsOpenToHomewrokCommon < ActiveRecord::Migration + def change + add_column :homework_commons, :is_open, :integer, :default => 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 334766d9e..d47a676fb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,12 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -<<<<<<< HEAD ActiveRecord::Schema.define(:version => 20160119034447) do -======= -ActiveRecord::Schema.define(:version => 20160223073859) do ->>>>>>> origin/szzh - create_table "activities", :force => true do |t| t.integer "act_id", :null => false t.string "act_type", :null => false @@ -2116,3 +2111,2056 @@ ActiveRecord::Schema.define(:version => 20160223073859) do end end +======= +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20160225024759) do + + create_table "activities", :force => true do |t| + t.integer "act_id", :null => false + t.string "act_type", :null => false + t.integer "user_id", :null => false + t.integer "activity_container_id" + t.string "activity_container_type", :default => "" + t.datetime "created_at" + end + + add_index "activities", ["act_id", "act_type"], :name => "index_activities_on_act_id_and_act_type" + add_index "activities", ["user_id", "act_type"], :name => "index_activities_on_user_id_and_act_type" + add_index "activities", ["user_id"], :name => "index_activities_on_user_id" + + create_table "activity_notifies", :force => true do |t| + t.integer "activity_container_id" + t.string "activity_container_type" + t.integer "activity_id" + t.string "activity_type" + t.integer "notify_to" + t.datetime "created_on" + t.integer "is_read" + end + + add_index "activity_notifies", ["activity_container_id", "activity_container_type"], :name => "index_an_activity_container_id" + add_index "activity_notifies", ["created_on"], :name => "index_an_created_on" + add_index "activity_notifies", ["notify_to"], :name => "index_an_notify_to" + + create_table "api_keys", :force => true do |t| + t.string "access_token" + t.datetime "expires_at" + t.integer "user_id" + t.boolean "active", :default => true + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "api_keys", ["access_token"], :name => "index_api_keys_on_access_token" + add_index "api_keys", ["user_id"], :name => "index_api_keys_on_user_id" + + create_table "applied_projects", :force => true do |t| + t.integer "project_id", :null => false + t.integer "user_id", :null => false + end + + create_table "apply_project_masters", :force => true do |t| + t.integer "user_id" + t.string "apply_type" + t.integer "apply_id" + t.integer "status" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "at_messages", :force => true do |t| + t.integer "user_id" + t.integer "at_message_id" + t.string "at_message_type" + t.boolean "viewed", :default => false + t.string "container_type" + t.integer "container_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sender_id" + end + + add_index "at_messages", ["user_id"], :name => "index_at_messages_on_user_id" + + create_table "attachment_histories", :force => true do |t| + t.integer "container_id" + t.string "container_type" + t.string "filename", :default => "" + t.string "disk_filename", :default => "" + t.integer "filesize", :default => 0 + t.string "content_type", :default => "" + t.string "digest", :limit => 40, :default => "" + t.integer "downloads", :default => 0 + t.integer "author_id" + t.datetime "created_on" + t.string "description" + t.string "disk_directory" + t.integer "attachtype" + t.integer "is_public" + t.integer "copy_from" + t.integer "quotes" + t.integer "version" + t.integer "attachment_id" + t.integer "is_publish", :default => 1 + t.date "publish_time" + end + + create_table "attachments", :force => true do |t| + t.integer "container_id" + t.string "container_type", :limit => 30 + t.string "filename", :default => "", :null => false + t.string "disk_filename", :default => "", :null => false + t.integer "filesize", :default => 0, :null => false + t.string "content_type", :default => "" + t.string "digest", :limit => 40, :default => "", :null => false + t.integer "downloads", :default => 0, :null => false + t.integer "author_id", :default => 0, :null => false + t.datetime "created_on" + t.string "description" + t.string "disk_directory" + t.integer "attachtype", :default => 1 + t.integer "is_public", :default => 1 + t.integer "copy_from" + t.integer "quotes" + t.integer "is_publish", :default => 1 + t.date "publish_time" + end + + add_index "attachments", ["author_id"], :name => "index_attachments_on_author_id" + add_index "attachments", ["container_id", "container_type"], :name => "index_attachments_on_container_id_and_container_type" + add_index "attachments", ["created_on"], :name => "index_attachments_on_created_on" + + create_table "attachmentstypes", :force => true do |t| + t.integer "typeId", :null => false + t.string "typeName", :limit => 50 + end + + create_table "auth_sources", :force => true do |t| + t.string "type", :limit => 30, :default => "", :null => false + t.string "name", :limit => 60, :default => "", :null => false + t.string "host", :limit => 60 + t.integer "port" + t.string "account" + t.string "account_password", :default => "" + t.string "base_dn" + t.string "attr_login", :limit => 30 + t.string "attr_firstname", :limit => 30 + t.string "attr_lastname", :limit => 30 + t.string "attr_mail", :limit => 30 + t.boolean "onthefly_register", :default => false, :null => false + t.boolean "tls", :default => false, :null => false + t.string "filter" + t.integer "timeout" + end + + add_index "auth_sources", ["id", "type"], :name => "index_auth_sources_on_id_and_type" + + create_table "biding_projects", :force => true do |t| + t.integer "project_id" + t.integer "bid_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + end + + create_table "bids", :force => true do |t| + t.string "name" + t.string "budget", :null => false + t.integer "author_id" + t.date "deadline" + t.text "description" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.integer "commit" + t.integer "reward_type" + t.integer "homework_type" + t.integer "parent_id" + t.string "password" + t.integer "is_evaluation" + t.integer "proportion", :default => 60 + t.integer "comment_status", :default => 0 + t.integer "evaluation_num", :default => 3 + t.integer "open_anonymous_evaluation", :default => 1 + end + + create_table "blog_comments", :force => true do |t| + t.integer "blog_id", :null => false + t.integer "parent_id" + t.string "title", :default => "", :null => false + t.text "content" + t.integer "author_id" + t.integer "comments_count", :default => 0, :null => false + t.integer "last_comment_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + t.integer "reply_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "blogs", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.integer "position", :default => 1 + t.integer "article_count", :default => 0, :null => false + t.integer "comments_count", :default => 0, :null => false + t.integer "last_comments_id" + t.integer "parent_id" + t.integer "author_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "homepage_id" + end + + create_table "boards", :force => true do |t| + t.integer "project_id", :null => false + t.string "name", :default => "", :null => false + t.string "description" + t.integer "position", :default => 1 + t.integer "topics_count", :default => 0, :null => false + t.integer "messages_count", :default => 0, :null => false + t.integer "last_message_id" + t.integer "parent_id" + t.integer "course_id" + t.integer "org_subfield_id" + end + + add_index "boards", ["last_message_id"], :name => "index_boards_on_last_message_id" + add_index "boards", ["project_id"], :name => "boards_project_id" + + create_table "bug_to_osps", :force => true do |t| + t.integer "osp_id" + t.integer "relative_memo_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "changes", :force => true do |t| + t.integer "changeset_id", :null => false + t.string "action", :limit => 1, :default => "", :null => false + t.text "path", :null => false + t.text "from_path" + t.string "from_revision" + t.string "revision" + t.string "branch" + end + + add_index "changes", ["changeset_id"], :name => "changesets_changeset_id" + + create_table "changeset_parents", :id => false, :force => true do |t| + t.integer "changeset_id", :null => false + t.integer "parent_id", :null => false + end + + add_index "changeset_parents", ["changeset_id"], :name => "changeset_parents_changeset_ids" + add_index "changeset_parents", ["parent_id"], :name => "changeset_parents_parent_ids" + + create_table "changesets", :force => true do |t| + t.integer "repository_id", :null => false + t.string "revision", :null => false + t.string "committer" + t.datetime "committed_on", :null => false + t.text "comments" + t.date "commit_date" + t.string "scmid" + t.integer "user_id" + end + + add_index "changesets", ["committed_on"], :name => "index_changesets_on_committed_on" + add_index "changesets", ["repository_id", "revision"], :name => "changesets_repos_rev", :unique => true + add_index "changesets", ["repository_id", "scmid"], :name => "changesets_repos_scmid" + add_index "changesets", ["repository_id"], :name => "index_changesets_on_repository_id" + add_index "changesets", ["user_id"], :name => "index_changesets_on_user_id" + + create_table "changesets_issues", :id => false, :force => true do |t| + t.integer "changeset_id", :null => false + t.integer "issue_id", :null => false + end + + add_index "changesets_issues", ["changeset_id", "issue_id"], :name => "changesets_issues_ids", :unique => true + + create_table "code_review_assignments", :force => true do |t| + t.integer "issue_id" + t.integer "change_id" + t.integer "attachment_id" + t.string "file_path" + t.string "rev" + t.string "rev_to" + t.string "action_type" + t.integer "changeset_id" + end + + create_table "code_review_project_settings", :force => true do |t| + t.integer "project_id" + t.integer "tracker_id" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "updated_by" + t.boolean "hide_code_review_tab", :default => false + t.integer "auto_relation", :default => 1 + t.integer "assignment_tracker_id" + t.text "auto_assign" + t.integer "lock_version", :default => 0, :null => false + t.boolean "tracker_in_review_dialog", :default => false + end + + create_table "code_review_user_settings", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.integer "mail_notification", :default => 0, :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "code_reviews", :force => true do |t| + t.integer "project_id" + t.integer "change_id" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "line" + t.integer "updated_by_id" + t.integer "lock_version", :default => 0, :null => false + t.integer "status_changed_from" + t.integer "status_changed_to" + t.integer "issue_id" + t.string "action_type" + t.string "file_path" + t.string "rev" + t.string "rev_to" + t.integer "attachment_id" + t.integer "file_count", :default => 0, :null => false + t.boolean "diff_all" + end + + create_table "comments", :force => true do |t| + t.string "commented_type", :limit => 30, :default => "", :null => false + t.integer "commented_id", :default => 0, :null => false + t.integer "author_id", :default => 0, :null => false + t.text "comments" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + add_index "comments", ["author_id"], :name => "index_comments_on_author_id" + add_index "comments", ["commented_id", "commented_type"], :name => "index_comments_on_commented_id_and_commented_type" + + create_table "contest_notifications", :force => true do |t| + t.text "title" + t.text "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "contesting_projects", :force => true do |t| + t.integer "project_id" + t.string "contest_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + end + + create_table "contesting_softapplications", :force => true do |t| + t.integer "softapplication_id" + t.integer "contest_id" + t.integer "user_id" + t.string "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + end + + create_table "contestnotifications", :force => true do |t| + t.integer "contest_id" + t.string "title" + t.string "summary" + t.text "description" + t.integer "author_id" + t.integer "notificationcomments_count" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "contests", :force => true do |t| + t.string "name" + t.string "budget", :default => "" + t.integer "author_id" + t.date "deadline" + t.string "description" + t.integer "commit" + t.string "password" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + create_table "course_activities", :force => true do |t| + t.integer "user_id" + t.integer "course_id" + t.integer "course_act_id" + t.string "course_act_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "course_attachments", :force => true do |t| + t.string "filename" + t.string "disk_filename" + t.integer "filesize" + t.string "content_type" + t.string "digest" + t.integer "downloads" + t.string "author_id" + t.string "integer" + t.string "description" + t.string "disk_directory" + t.integer "attachtype" + t.integer "is_public" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "container_id", :default => 0 + end + + create_table "course_contributor_scores", :force => true do |t| + t.integer "course_id" + t.integer "user_id" + t.integer "message_num" + t.integer "message_reply_num" + t.integer "news_reply_num" + t.integer "resource_num" + t.integer "journal_num" + t.integer "journal_reply_num" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "total_score" + end + + create_table "course_groups", :force => true do |t| + t.string "name" + t.integer "course_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "course_infos", :force => true do |t| + t.integer "course_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "course_messages", :force => true do |t| + t.integer "user_id" + t.integer "course_id" + t.integer "course_message_id" + t.string "course_message_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "content" + t.integer "status" + end + + create_table "course_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "course_id" + t.float "grade", :default => 0.0 + t.integer "course_ac_para", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "courses", :force => true do |t| + t.integer "tea_id" + t.string "name" + t.integer "state" + t.string "code" + t.integer "time" + t.string "extra" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "location" + t.string "term" + t.string "string" + t.string "password" + t.string "setup_time" + t.string "endup_time" + t.string "class_period" + t.integer "school_id" + t.text "description" + t.integer "status", :default => 1 + t.integer "attachmenttype", :default => 2 + t.integer "lft" + t.integer "rgt" + t.integer "is_public", :limit => 1, :default => 1 + t.integer "inherit_members", :limit => 1, :default => 1 + t.integer "open_student", :default => 0 + t.integer "outline", :default => 0 + t.integer "publish_resource", :default => 0 + t.integer "is_delete", :default => 0 + t.integer "end_time" + t.string "end_term" + t.integer "is_excellent", :default => 0 + t.integer "excellent_option", :default => 0 + t.integer "is_copy", :default => 0 + end + + create_table "custom_fields", :force => true do |t| + t.string "type", :limit => 30, :default => "", :null => false + t.string "name", :limit => 30, :default => "", :null => false + t.string "field_format", :limit => 30, :default => "", :null => false + t.text "possible_values" + t.string "regexp", :default => "" + t.integer "min_length", :default => 0, :null => false + t.integer "max_length", :default => 0, :null => false + t.boolean "is_required", :default => false, :null => false + t.boolean "is_for_all", :default => false, :null => false + t.boolean "is_filter", :default => false, :null => false + t.integer "position", :default => 1 + t.boolean "searchable", :default => false + t.text "default_value" + t.boolean "editable", :default => true + t.boolean "visible", :default => true, :null => false + t.boolean "multiple", :default => false + end + + add_index "custom_fields", ["id", "type"], :name => "index_custom_fields_on_id_and_type" + + create_table "custom_fields_projects", :id => false, :force => true do |t| + t.integer "custom_field_id", :default => 0, :null => false + t.integer "project_id", :default => 0, :null => false + end + + add_index "custom_fields_projects", ["custom_field_id", "project_id"], :name => "index_custom_fields_projects_on_custom_field_id_and_project_id", :unique => true + + create_table "custom_fields_trackers", :id => false, :force => true do |t| + t.integer "custom_field_id", :default => 0, :null => false + t.integer "tracker_id", :default => 0, :null => false + end + + add_index "custom_fields_trackers", ["custom_field_id", "tracker_id"], :name => "index_custom_fields_trackers_on_custom_field_id_and_tracker_id", :unique => true + + create_table "custom_values", :force => true do |t| + t.string "customized_type", :limit => 30, :default => "", :null => false + t.integer "customized_id", :default => 0, :null => false + t.integer "custom_field_id", :default => 0, :null => false + t.text "value" + end + + add_index "custom_values", ["custom_field_id"], :name => "index_custom_values_on_custom_field_id" + add_index "custom_values", ["customized_type", "customized_id"], :name => "custom_values_customized" + + create_table "delayed_jobs", :force => true do |t| + t.integer "priority", :default => 0, :null => false + t.integer "attempts", :default => 0, :null => false + t.text "handler", :null => false + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by" + t.string "queue" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority" + + create_table "discuss_demos", :force => true do |t| + t.string "title" + t.text "body" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "documents", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.integer "category_id", :default => 0, :null => false + t.string "title", :limit => 60, :default => "", :null => false + t.text "description" + t.datetime "created_on" + t.integer "user_id", :default => 0 + t.integer "is_public", :default => 1 + end + + add_index "documents", ["category_id"], :name => "index_documents_on_category_id" + add_index "documents", ["created_on"], :name => "index_documents_on_created_on" + add_index "documents", ["project_id"], :name => "documents_project_id" + + create_table "dts", :primary_key => "Num", :force => true do |t| + t.string "Defect", :limit => 50 + t.string "Category", :limit => 50 + t.string "File" + t.string "Method" + t.string "Module", :limit => 20 + t.string "Variable", :limit => 50 + t.integer "StartLine" + t.integer "IPLine" + t.string "IPLineCode", :limit => 200 + t.string "Judge", :limit => 15 + t.integer "Review", :limit => 1 + t.string "Description" + t.text "PreConditions", :limit => 2147483647 + t.text "TraceInfo", :limit => 2147483647 + t.text "Code", :limit => 2147483647 + t.integer "project_id" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "id", :null => false + end + + create_table "editor_of_documents", :force => true do |t| + t.integer "editor_id" + t.integer "org_document_comment_id" + t.datetime "created_at" + end + + create_table "enabled_modules", :force => true do |t| + t.integer "project_id" + t.string "name", :null => false + t.integer "course_id" + end + + add_index "enabled_modules", ["project_id"], :name => "enabled_modules_project_id" + + create_table "enumerations", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "is_default", :default => false, :null => false + t.string "type" + t.boolean "active", :default => true, :null => false + t.integer "project_id" + t.integer "parent_id" + t.string "position_name", :limit => 30 + end + + add_index "enumerations", ["id", "type"], :name => "index_enumerations_on_id_and_type" + add_index "enumerations", ["project_id"], :name => "index_enumerations_on_project_id" + + create_table "exercise_answers", :force => true do |t| + t.integer "user_id" + t.integer "exercise_question_id" + t.integer "exercise_choice_id" + t.text "answer_text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "exercise_choices", :force => true do |t| + t.integer "exercise_question_id" + t.text "choice_text" + t.integer "choice_position" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "exercise_questions", :force => true do |t| + t.text "question_title" + t.integer "question_type" + t.integer "question_number" + t.integer "exercise_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "question_score" + end + + create_table "exercise_standard_answers", :force => true do |t| + t.integer "exercise_question_id" + t.integer "exercise_choice_id" + t.text "answer_text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "exercise_users", :force => true do |t| + t.integer "user_id" + t.integer "exercise_id" + t.integer "score" + t.datetime "start_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.datetime "end_at" + t.integer "status" + end + + create_table "exercises", :force => true do |t| + t.text "exercise_name" + t.text "exercise_description" + t.integer "course_id" + t.integer "exercise_status" + t.integer "user_id" + t.integer "time" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.datetime "publish_time" + t.datetime "end_time" + t.integer "show_result" + end + + create_table "first_pages", :force => true do |t| + t.string "web_title" + t.string "title" + t.text "description" + t.string "page_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sort_type" + t.integer "image_width", :default => 107 + t.integer "image_height", :default => 63 + t.integer "show_course", :default => 1 + t.integer "show_contest", :default => 1 + end + + create_table "forge_activities", :force => true do |t| + t.integer "user_id" + t.integer "project_id" + t.integer "forge_act_id" + t.string "forge_act_type" + t.integer "org_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "forge_activities", ["forge_act_id"], :name => "index_forge_activities_on_forge_act_id" + + create_table "forge_messages", :force => true do |t| + t.integer "user_id" + t.integer "project_id" + t.integer "forge_message_id" + t.string "forge_message_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "secret_key" + t.integer "status" + end + + create_table "forums", :force => true do |t| + t.string "name", :null => false + t.text "description" + t.integer "topic_count", :default => 0 + t.integer "memo_count", :default => 0 + t.integer "last_memo_id", :default => 0 + t.integer "creator_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "sticky" + t.integer "locked" + end + + create_table "forwards", :force => true do |t| + t.integer "from_id" + t.string "from_type" + t.integer "to_id" + t.string "to_type" + t.datetime "created_at" + end + + create_table "groups_users", :id => false, :force => true do |t| + t.integer "group_id", :null => false + t.integer "user_id", :null => false + end + + add_index "groups_users", ["group_id", "user_id"], :name => "groups_users_ids", :unique => true + + create_table "homework_attaches", :force => true do |t| + t.integer "bid_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "reward" + t.string "name" + t.text "description" + t.integer "state" + t.integer "project_id", :default => 0 + t.float "score", :default => 0.0 + t.integer "is_teacher_score", :default => 0 + end + + add_index "homework_attaches", ["bid_id"], :name => "index_homework_attaches_on_bid_id" + + create_table "homework_commons", :force => true do |t| + t.string "name" + t.integer "user_id" + t.text "description" + t.date "publish_time" + t.date "end_time" + t.integer "homework_type", :default => 1 + t.string "late_penalty" + t.integer "course_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "teacher_priority", :default => 1 + t.integer "anonymous_comment", :default => 0 + t.integer "quotes", :default => 0 + t.integer "is_open", :default => 0 + end + + add_index "homework_commons", ["course_id", "id"], :name => "index_homework_commons_on_course_id_and_id" + + create_table "homework_detail_groups", :force => true do |t| + t.integer "homework_common_id" + t.integer "min_num" + t.integer "max_num" + t.integer "base_on_project" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "homework_detail_groups", ["homework_common_id"], :name => "index_homework_detail_groups_on_homework_common_id" + + create_table "homework_detail_manuals", :force => true do |t| + t.float "ta_proportion" + t.integer "comment_status" + t.date "evaluation_start" + t.date "evaluation_end" + t.integer "evaluation_num" + t.integer "absence_penalty", :default => 1 + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "homework_detail_programings", :force => true do |t| + t.string "language" + t.text "standard_code", :limit => 2147483647 + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.float "ta_proportion", :default => 0.1 + t.integer "question_id" + end + + create_table "homework_evaluations", :force => true do |t| + t.string "user_id" + t.string "homework_attach_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "homework_for_courses", :force => true do |t| + t.integer "course_id" + t.integer "bid_id" + end + + add_index "homework_for_courses", ["bid_id"], :name => "index_homework_for_courses_on_bid_id" + add_index "homework_for_courses", ["course_id"], :name => "index_homework_for_courses_on_course_id" + + create_table "homework_tests", :force => true do |t| + t.text "input" + t.text "output" + t.integer "homework_common_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "result" + t.text "error_msg" + end + + create_table "homework_users", :force => true do |t| + t.string "homework_attach_id" + t.string "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "invite_lists", :force => true do |t| + t.integer "project_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "mail" + end + + create_table "issue_categories", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "name", :limit => 30, :default => "", :null => false + t.integer "assigned_to_id" + end + + add_index "issue_categories", ["assigned_to_id"], :name => "index_issue_categories_on_assigned_to_id" + add_index "issue_categories", ["project_id"], :name => "issue_categories_project_id" + + create_table "issue_relations", :force => true do |t| + t.integer "issue_from_id", :null => false + t.integer "issue_to_id", :null => false + t.string "relation_type", :default => "", :null => false + t.integer "delay" + end + + add_index "issue_relations", ["issue_from_id", "issue_to_id"], :name => "index_issue_relations_on_issue_from_id_and_issue_to_id", :unique => true + add_index "issue_relations", ["issue_from_id"], :name => "index_issue_relations_on_issue_from_id" + add_index "issue_relations", ["issue_to_id"], :name => "index_issue_relations_on_issue_to_id" + + create_table "issue_statuses", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.boolean "is_closed", :default => false, :null => false + t.boolean "is_default", :default => false, :null => false + t.integer "position", :default => 1 + t.integer "default_done_ratio" + end + + add_index "issue_statuses", ["is_closed"], :name => "index_issue_statuses_on_is_closed" + add_index "issue_statuses", ["is_default"], :name => "index_issue_statuses_on_is_default" + add_index "issue_statuses", ["position"], :name => "index_issue_statuses_on_position" + + create_table "issues", :force => true do |t| + t.integer "tracker_id", :null => false + t.integer "project_id", :null => false + t.string "subject", :default => "", :null => false + t.text "description" + t.date "due_date" + t.integer "category_id" + t.integer "status_id", :null => false + t.integer "assigned_to_id" + t.integer "priority_id", :null => false + t.integer "fixed_version_id" + t.integer "author_id", :null => false + t.integer "lock_version", :default => 0, :null => false + t.datetime "created_on" + t.datetime "updated_on" + t.date "start_date" + t.integer "done_ratio", :default => 0, :null => false + t.float "estimated_hours" + t.integer "parent_id" + t.integer "root_id" + t.integer "lft" + t.integer "rgt" + t.boolean "is_private", :default => false, :null => false + t.datetime "closed_on" + t.integer "project_issues_index" + end + + add_index "issues", ["assigned_to_id"], :name => "index_issues_on_assigned_to_id" + add_index "issues", ["author_id"], :name => "index_issues_on_author_id" + add_index "issues", ["category_id"], :name => "index_issues_on_category_id" + add_index "issues", ["created_on"], :name => "index_issues_on_created_on" + add_index "issues", ["fixed_version_id"], :name => "index_issues_on_fixed_version_id" + add_index "issues", ["priority_id"], :name => "index_issues_on_priority_id" + add_index "issues", ["project_id"], :name => "issues_project_id" + add_index "issues", ["root_id", "lft", "rgt"], :name => "index_issues_on_root_id_and_lft_and_rgt" + add_index "issues", ["status_id"], :name => "index_issues_on_status_id" + add_index "issues", ["tracker_id"], :name => "index_issues_on_tracker_id" + + create_table "join_in_competitions", :force => true do |t| + t.integer "user_id" + t.integer "competition_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "join_in_contests", :force => true do |t| + t.integer "user_id" + t.integer "bid_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "journal_details", :force => true do |t| + t.integer "journal_id", :default => 0, :null => false + t.string "property", :limit => 30, :default => "", :null => false + t.string "prop_key", :limit => 30, :default => "", :null => false + t.text "old_value" + t.text "value" + end + + add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id" + + create_table "journal_replies", :id => false, :force => true do |t| + t.integer "journal_id" + t.integer "user_id" + t.integer "reply_id" + end + + add_index "journal_replies", ["journal_id"], :name => "index_journal_replies_on_journal_id" + add_index "journal_replies", ["reply_id"], :name => "index_journal_replies_on_reply_id" + add_index "journal_replies", ["user_id"], :name => "index_journal_replies_on_user_id" + + create_table "journals", :force => true do |t| + t.integer "journalized_id", :default => 0, :null => false + t.string "journalized_type", :limit => 30, :default => "", :null => false + t.integer "user_id", :default => 0, :null => false + t.text "notes" + t.datetime "created_on", :null => false + t.boolean "private_notes", :default => false, :null => false + end + + add_index "journals", ["created_on"], :name => "index_journals_on_created_on" + add_index "journals", ["journalized_id", "journalized_type"], :name => "journals_journalized_id" + add_index "journals", ["journalized_id"], :name => "index_journals_on_journalized_id" + add_index "journals", ["user_id"], :name => "index_journals_on_user_id" + + create_table "journals_for_messages", :force => true do |t| + t.integer "jour_id" + t.string "jour_type" + t.integer "user_id" + t.text "notes" + t.integer "status" + t.integer "reply_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.string "m_parent_id" + t.boolean "is_readed" + t.integer "m_reply_count" + t.integer "m_reply_id" + t.integer "is_comprehensive_evaluation" + t.integer "private", :default => 0 + end + + create_table "kindeditor_assets", :force => true do |t| + t.string "asset" + t.integer "file_size" + t.string "file_type" + t.integer "owner_id" + t.string "asset_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "owner_type", :default => 0 + end + + create_table "member_roles", :force => true do |t| + t.integer "member_id", :null => false + t.integer "role_id", :null => false + t.integer "inherited_from" + end + + add_index "member_roles", ["member_id"], :name => "index_member_roles_on_member_id" + add_index "member_roles", ["role_id"], :name => "index_member_roles_on_role_id" + + create_table "members", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.integer "project_id", :default => 0 + t.datetime "created_on" + t.boolean "mail_notification", :default => false, :null => false + t.integer "course_id", :default => -1 + t.integer "course_group_id", :default => 0 + end + + add_index "members", ["project_id"], :name => "index_members_on_project_id" + add_index "members", ["user_id", "project_id", "course_id"], :name => "index_members_on_user_id_and_project_id", :unique => true + add_index "members", ["user_id"], :name => "index_members_on_user_id" + + create_table "memo_messages", :force => true do |t| + t.integer "user_id" + t.integer "forum_id" + t.integer "memo_id" + t.string "memo_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "memos", :force => true do |t| + t.integer "forum_id", :null => false + t.integer "parent_id" + t.string "subject", :null => false + t.text "content", :null => false + t.integer "author_id", :null => false + t.integer "replies_count", :default => 0 + t.integer "last_reply_id" + t.boolean "lock", :default => false + t.boolean "sticky", :default => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "viewed_count", :default => 0 + end + + create_table "message_alls", :force => true do |t| + t.integer "user_id" + t.integer "message_id" + t.string "message_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "messages", :force => true do |t| + t.integer "board_id", :null => false + t.integer "parent_id" + t.string "subject", :default => "", :null => false + t.text "content" + t.integer "author_id" + t.integer "replies_count", :default => 0, :null => false + t.integer "last_reply_id" + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + t.integer "reply_id" + t.integer "quotes" + t.integer "status", :default => 0 + end + + add_index "messages", ["author_id"], :name => "index_messages_on_author_id" + add_index "messages", ["board_id"], :name => "messages_board_id" + add_index "messages", ["created_on"], :name => "index_messages_on_created_on" + add_index "messages", ["last_reply_id"], :name => "index_messages_on_last_reply_id" + add_index "messages", ["parent_id"], :name => "messages_parent_id" + + create_table "news", :force => true do |t| + t.integer "project_id" + t.string "title", :limit => 60, :default => "", :null => false + t.string "summary", :default => "" + t.text "description" + t.integer "author_id", :default => 0, :null => false + t.datetime "created_on" + t.integer "comments_count", :default => 0, :null => false + t.integer "course_id" + t.integer "sticky", :default => 0 + t.integer "org_subfield_id" + end + + add_index "news", ["author_id"], :name => "index_news_on_author_id" + add_index "news", ["created_on"], :name => "index_news_on_created_on" + add_index "news", ["project_id"], :name => "news_project_id" + + create_table "no_uses", :force => true do |t| + t.integer "user_id", :null => false + t.string "no_use_type" + t.integer "no_use_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "notificationcomments", :force => true do |t| + t.string "notificationcommented_type" + t.integer "notificationcommented_id" + t.integer "author_id" + t.text "notificationcomments" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "onclick_times", :force => true do |t| + t.integer "user_id" + t.datetime "onclick_time" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "open_id_authentication_associations", :force => true do |t| + t.integer "issued" + t.integer "lifetime" + t.string "handle" + t.string "assoc_type" + t.binary "server_url" + t.binary "secret" + end + + create_table "open_id_authentication_nonces", :force => true do |t| + t.integer "timestamp", :null => false + t.string "server_url" + t.string "salt", :null => false + end + + create_table "open_source_projects", :force => true do |t| + t.string "name" + t.text "description" + t.integer "commit_count", :default => 0 + t.integer "code_line", :default => 0 + t.integer "users_count", :default => 0 + t.date "last_commit_time" + t.string "url" + t.date "date_collected" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "option_numbers", :force => true do |t| + t.integer "user_id" + t.integer "memo" + t.integer "messages_for_issues" + t.integer "issues_status" + t.integer "replay_for_message" + t.integer "replay_for_memo" + t.integer "follow" + t.integer "tread" + t.integer "praise_by_one" + t.integer "praise_by_two" + t.integer "praise_by_three" + t.integer "tread_by_one" + t.integer "tread_by_two" + t.integer "tread_by_three" + t.integer "changeset" + t.integer "document" + t.integer "attachment" + t.integer "issue_done_ratio" + t.integer "post_issue" + t.integer "score_type" + t.integer "total_score" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "project_id" + end + + create_table "org_activities", :force => true do |t| + t.integer "user_id" + t.integer "org_act_id" + t.string "org_act_type" + t.integer "container_id" + t.string "container_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "org_courses", :force => true do |t| + t.integer "organization_id" + t.integer "course_id" + t.datetime "created_at" + end + + create_table "org_document_comments", :force => true do |t| + t.text "title" + t.text "content" + t.integer "organization_id" + t.integer "creator_id" + t.integer "parent_id" + t.integer "reply_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "locked", :default => false + t.integer "sticky", :default => 0 + t.integer "org_subfield_id" + end + + create_table "org_member_roles", :force => true do |t| + t.integer "org_member_id" + t.integer "role_id" + end + + create_table "org_members", :force => true do |t| + t.integer "user_id" + t.integer "organization_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "org_messages", :force => true do |t| + t.integer "user_id" + t.integer "sender_id" + t.integer "organization_id" + t.string "message_type" + t.integer "message_id" + t.integer "viewed" + t.string "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "status", :default => 0 + end + + create_table "org_projects", :force => true do |t| + t.integer "organization_id" + t.integer "project_id" + t.datetime "created_at" + end + + create_table "org_subfield_messages", :force => true do |t| + t.integer "org_subfield_id" + t.integer "message_id" + t.string "message_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "org_subfields", :force => true do |t| + t.integer "organization_id" + t.integer "priority" + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "field_type" + t.integer "hide", :default => 0 + end + + create_table "organizations", :force => true do |t| + t.string "name" + t.text "description" + t.integer "creator_id" + t.integer "home_id" + t.boolean "is_public" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "allow_guest_download", :default => true + end + + create_table "phone_app_versions", :force => true do |t| + t.string "version" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "poll_answers", :force => true do |t| + t.integer "poll_question_id" + t.text "answer_text" + t.integer "answer_position" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "poll_questions", :force => true do |t| + t.string "question_title" + t.integer "question_type" + t.integer "is_necessary" + t.integer "poll_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "question_number" + end + + create_table "poll_users", :force => true do |t| + t.integer "user_id" + t.integer "poll_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "poll_votes", :force => true do |t| + t.integer "user_id" + t.integer "poll_question_id" + t.integer "poll_answer_id" + t.text "vote_text" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "polls", :force => true do |t| + t.string "polls_name" + t.string "polls_type" + t.integer "polls_group_id" + t.integer "polls_status" + t.integer "user_id" + t.datetime "published_at" + t.datetime "closed_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "polls_description" + t.integer "show_result", :default => 1 + end + + create_table "praise_tread_caches", :force => true do |t| + t.integer "object_id", :null => false + t.string "object_type" + t.integer "praise_num" + t.integer "tread_num" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "praise_treads", :force => true do |t| + t.integer "user_id", :null => false + t.integer "praise_tread_object_id" + t.string "praise_tread_object_type" + t.integer "praise_or_tread" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "principal_activities", :force => true do |t| + t.integer "user_id" + t.integer "principal_id" + t.integer "principal_act_id" + t.string "principal_act_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "project_infos", :force => true do |t| + t.integer "project_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "project_scores", :force => true do |t| + t.string "project_id" + t.integer "score" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "issue_num", :default => 0 + t.integer "issue_journal_num", :default => 0 + t.integer "news_num", :default => 0 + t.integer "documents_num", :default => 0 + t.integer "changeset_num", :default => 0 + t.integer "board_message_num", :default => 0 + t.integer "board_num", :default => 0 + t.integer "attach_num", :default => 0 + t.datetime "commit_time" + end + + create_table "project_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "project_id" + t.integer "project_type" + t.float "grade", :default => 0.0 + t.integer "course_ac_para", :default => 0 + end + + add_index "project_statuses", ["grade"], :name => "index_project_statuses_on_grade" + + create_table "projecting_softapplictions", :force => true do |t| + t.integer "user_id" + t.integer "softapplication_id" + t.integer "project_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "projects", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.string "homepage", :default => "" + t.boolean "is_public", :default => true, :null => false + t.integer "parent_id" + t.datetime "created_on" + t.datetime "updated_on" + t.string "identifier" + t.integer "status", :default => 1, :null => false + t.integer "lft" + t.integer "rgt" + t.boolean "inherit_members", :default => false, :null => false + t.integer "project_type" + t.boolean "hidden_repo", :default => false, :null => false + t.integer "attachmenttype", :default => 1 + t.integer "user_id" + t.integer "dts_test", :default => 0 + t.string "enterprise_name" + t.integer "organization_id" + t.integer "project_new_type" + t.integer "gpid" + t.integer "forked_from_project_id" + t.integer "forked_count" + t.integer "commits_count", :default => 0 + t.integer "publish_resource", :default => 0 + t.integer "issues_count", :default => 0 + t.integer "attachments_count", :default => 0 + t.integer "boards_count", :default => 0 + t.integer "news_count", :default => 0 + t.integer "acts_count", :default => 0 + t.integer "journals_count", :default => 0 + t.integer "boards_reply_count", :default => 0 + end + + add_index "projects", ["lft"], :name => "index_projects_on_lft" + add_index "projects", ["rgt"], :name => "index_projects_on_rgt" + + create_table "projects_trackers", :id => false, :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.integer "tracker_id", :default => 0, :null => false + end + + add_index "projects_trackers", ["project_id", "tracker_id"], :name => "projects_trackers_unique", :unique => true + add_index "projects_trackers", ["project_id"], :name => "projects_trackers_project_id" + + create_table "queries", :force => true do |t| + t.integer "project_id" + t.string "name", :default => "", :null => false + t.text "filters" + t.integer "user_id", :default => 0, :null => false + t.boolean "is_public", :default => false, :null => false + t.text "column_names" + t.text "sort_criteria" + t.string "group_by" + t.string "type" + end + + add_index "queries", ["project_id"], :name => "index_queries_on_project_id" + add_index "queries", ["user_id"], :name => "index_queries_on_user_id" + + create_table "relative_memo_to_open_source_projects", :force => true do |t| + t.integer "osp_id" + t.integer "relative_memo_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "relative_memos", :force => true do |t| + t.integer "osp_id" + t.integer "parent_id" + t.string "subject", :null => false + t.text "content", :limit => 16777215, :null => false + t.integer "author_id" + t.integer "replies_count", :default => 0 + t.integer "last_reply_id" + t.boolean "lock", :default => false + t.boolean "sticky", :default => false + t.boolean "is_quote", :default => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "viewed_count_crawl", :default => 0 + t.integer "viewed_count_local", :default => 0 + t.string "url" + t.string "username" + t.string "userhomeurl" + t.date "date_collected" + t.string "topic_resource" + end + + create_table "repositories", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "url", :default => "", :null => false + t.string "login", :limit => 60, :default => "" + t.string "password", :default => "" + t.string "root_url", :default => "" + t.string "type" + t.string "path_encoding", :limit => 64 + t.string "log_encoding", :limit => 64 + t.text "extra_info" + t.string "identifier" + t.boolean "is_default", :default => false + t.boolean "hidden", :default => false + end + + add_index "repositories", ["project_id"], :name => "index_repositories_on_project_id" + + create_table "rich_rich_files", :force => true do |t| + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "rich_file_file_name" + t.string "rich_file_content_type" + t.integer "rich_file_file_size" + t.datetime "rich_file_updated_at" + t.string "owner_type" + t.integer "owner_id" + t.text "uri_cache" + t.string "simplified_type", :default => "file" + end + + create_table "roles", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.integer "position", :default => 1 + t.boolean "assignable", :default => true + t.integer "builtin", :default => 0, :null => false + t.text "permissions" + t.string "issues_visibility", :limit => 30, :default => "default", :null => false + end + + 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.string "logo_link" + t.string "pinyin" + end + + create_table "secdomains", :force => true do |t| + t.integer "sub_type" + t.string "subname" + t.integer "pid", :default => 0 + t.string "desc" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "seems_rateable_cached_ratings", :force => true do |t| + t.integer "cacheable_id", :limit => 8 + t.string "cacheable_type" + t.float "avg", :null => false + t.integer "cnt", :null => false + t.string "dimension" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "seems_rateable_rates", :force => true do |t| + t.integer "rater_id", :limit => 8 + t.integer "rateable_id" + t.string "rateable_type" + t.float "stars", :null => false + t.string "dimension" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "is_teacher_score", :default => 0 + end + + create_table "settings", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "value" + t.datetime "updated_on" + end + + add_index "settings", ["name"], :name => "index_settings_on_name" + + create_table "shares", :force => true do |t| + t.date "created_on" + t.string "url" + t.string "title" + t.integer "share_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "project_id" + t.integer "user_id" + t.string "description" + end + + create_table "shield_activities", :force => true do |t| + t.string "container_type" + t.integer "container_id" + t.string "shield_type" + t.integer "shield_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "softapplications", :force => true do |t| + t.string "name" + t.text "description" + t.integer "app_type_id" + t.string "app_type_name" + t.string "android_min_version_available" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "contest_id" + t.integer "softapplication_id" + t.integer "is_public" + t.string "application_developers" + t.string "deposit_project_url" + t.string "deposit_project" + t.integer "project_id" + end + + create_table "student_work_projects", :force => true do |t| + t.integer "homework_common_id" + t.integer "student_work_id" + t.integer "project_id" + t.integer "user_id" + t.integer "is_leader" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "student_work_projects", ["homework_common_id"], :name => "index_student_work_projects_on_homework_common_id" + add_index "student_work_projects", ["project_id"], :name => "index_student_work_projects_on_project_id" + add_index "student_work_projects", ["student_work_id"], :name => "index_student_work_projects_on_student_work_id" + add_index "student_work_projects", ["user_id"], :name => "index_student_work_projects_on_user_id" + + create_table "student_work_tests", :force => true do |t| + t.integer "student_work_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "status", :default => 9 + t.text "results" + t.text "src" + end + + create_table "student_works", :force => true do |t| + t.string "name" + t.text "description", :limit => 2147483647 + t.integer "homework_common_id" + t.integer "user_id" + t.float "final_score" + t.float "teacher_score" + t.float "student_score" + t.float "teaching_asistant_score" + t.integer "project_id", :default => 0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "late_penalty", :default => 0 + t.integer "absence_penalty", :default => 0 + t.float "system_score", :default => 0.0 + t.boolean "is_test", :default => false + end + + add_index "student_works", ["homework_common_id", "user_id"], :name => "index_student_works_on_homework_common_id_and_user_id" + + create_table "student_works_evaluation_distributions", :force => true do |t| + t.integer "student_work_id" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "student_works_scores", :force => true do |t| + t.integer "student_work_id" + t.integer "user_id" + t.integer "score" + t.text "comment" + t.integer "reviewer_role" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "students_for_courses", :force => true do |t| + t.integer "student_id" + t.integer "course_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "students_for_courses", ["course_id"], :name => "index_students_for_courses_on_course_id" + add_index "students_for_courses", ["student_id"], :name => "index_students_for_courses_on_student_id" + + create_table "subfield_subdomain_dirs", :force => true do |t| + t.integer "org_subfield_id" + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "system_messages", :force => true do |t| + t.integer "user_id" + t.string "content" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "description" + t.string "subject" + end + + create_table "taggings", :force => true do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context", :limit => 128 + t.datetime "created_at" + end + + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + add_index "taggings", ["taggable_type"], :name => "index_taggings_on_taggable_type" + + create_table "tags", :force => true do |t| + t.string "name" + end + + create_table "teachers", :force => true do |t| + t.string "tea_name" + t.string "location" + t.integer "couurse_time" + t.integer "course_code" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "extra" + end + + create_table "time_entries", :force => true do |t| + t.integer "project_id", :null => false + t.integer "user_id", :null => false + t.integer "issue_id" + t.float "hours", :null => false + t.string "comments" + t.integer "activity_id", :null => false + t.date "spent_on", :null => false + t.integer "tyear", :null => false + t.integer "tmonth", :null => false + t.integer "tweek", :null => false + t.datetime "created_on", :null => false + t.datetime "updated_on", :null => false + end + + add_index "time_entries", ["activity_id"], :name => "index_time_entries_on_activity_id" + add_index "time_entries", ["created_on"], :name => "index_time_entries_on_created_on" + add_index "time_entries", ["issue_id"], :name => "time_entries_issue_id" + add_index "time_entries", ["project_id"], :name => "time_entries_project_id" + add_index "time_entries", ["user_id"], :name => "index_time_entries_on_user_id" + + create_table "tokens", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.string "action", :limit => 30, :default => "", :null => false + t.string "value", :limit => 40, :default => "", :null => false + t.datetime "created_on", :null => false + end + + add_index "tokens", ["user_id"], :name => "index_tokens_on_user_id" + add_index "tokens", ["value"], :name => "tokens_value", :unique => true + + create_table "trackers", :force => true do |t| + t.string "name", :limit => 30, :default => "", :null => false + t.boolean "is_in_chlog", :default => false, :null => false + t.integer "position", :default => 1 + t.boolean "is_in_roadmap", :default => true, :null => false + t.integer "fields_bits", :default => 0 + end + + create_table "user_activities", :force => true do |t| + t.string "act_type" + t.integer "act_id" + t.string "container_type" + t.integer "container_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "user_id" + end + + create_table "user_extensions", :force => true do |t| + t.integer "user_id", :null => false + t.date "birthday" + t.string "brief_introduction" + t.integer "gender" + t.string "location" + t.string "occupation" + t.integer "work_experience" + t.integer "zip_code" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "technical_title" + t.integer "identity" + t.string "student_id" + t.string "teacher_realname" + t.string "student_realname" + t.string "location_city" + t.integer "school_id" + t.string "description", :default => "" + end + + create_table "user_feedback_messages", :force => true do |t| + t.integer "user_id" + t.integer "journals_for_message_id" + t.string "journals_for_message_type" + t.integer "viewed" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_grades", :force => true do |t| + t.integer "user_id", :null => false + t.integer "project_id", :null => false + t.float "grade", :default => 0.0 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "user_grades", ["grade"], :name => "index_user_grades_on_grade" + add_index "user_grades", ["project_id"], :name => "index_user_grades_on_project_id" + add_index "user_grades", ["user_id"], :name => "index_user_grades_on_user_id" + + create_table "user_levels", :force => true do |t| + t.integer "user_id" + t.integer "level" + end + + create_table "user_preferences", :force => true do |t| + t.integer "user_id", :default => 0, :null => false + t.text "others" + t.boolean "hide_mail", :default => false + t.string "time_zone" + end + + add_index "user_preferences", ["user_id"], :name => "index_user_preferences_on_user_id" + + create_table "user_score_details", :force => true do |t| + t.integer "current_user_id" + t.integer "target_user_id" + t.string "score_type" + t.string "score_action" + t.integer "user_id" + t.integer "old_score" + t.integer "new_score" + t.integer "current_user_level" + t.integer "target_user_level" + t.integer "score_changeable_obj_id" + t.string "score_changeable_obj_type" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_scores", :force => true do |t| + t.integer "user_id", :null => false + t.integer "collaboration" + t.integer "influence" + t.integer "skill" + t.integer "active" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "user_statuses", :force => true do |t| + t.integer "changesets_count" + t.integer "watchers_count" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.float "grade", :default => 0.0 + end + + add_index "user_statuses", ["changesets_count"], :name => "index_user_statuses_on_changesets_count" + add_index "user_statuses", ["grade"], :name => "index_user_statuses_on_grade" + add_index "user_statuses", ["watchers_count"], :name => "index_user_statuses_on_watchers_count" + + create_table "users", :force => true do |t| + t.string "login", :default => "", :null => false + t.string "hashed_password", :limit => 40, :default => "", :null => false + t.string "firstname", :limit => 30, :default => "", :null => false + t.string "lastname", :default => "", :null => false + t.string "mail", :limit => 60, :default => "", :null => false + t.boolean "admin", :default => false, :null => false + t.integer "status", :default => 1, :null => false + t.datetime "last_login_on" + t.string "language", :limit => 5, :default => "" + t.integer "auth_source_id" + t.datetime "created_on" + t.datetime "updated_on" + t.string "type" + t.string "identity_url" + t.string "mail_notification", :default => "", :null => false + t.string "salt", :limit => 64 + t.integer "gid" + end + + add_index "users", ["auth_source_id"], :name => "index_users_on_auth_source_id" + add_index "users", ["id", "type"], :name => "index_users_on_id_and_type" + add_index "users", ["type"], :name => "index_users_on_type" + + create_table "versions", :force => true do |t| + t.integer "project_id", :default => 0, :null => false + t.string "name", :default => "", :null => false + t.string "description", :default => "" + t.date "effective_date" + t.datetime "created_on" + t.datetime "updated_on" + t.string "wiki_page_title" + t.string "status", :default => "open" + t.string "sharing", :default => "none", :null => false + end + + add_index "versions", ["project_id"], :name => "versions_project_id" + add_index "versions", ["sharing"], :name => "index_versions_on_sharing" + + create_table "visitors", :force => true do |t| + t.integer "user_id" + t.integer "master_id" + t.datetime "updated_on" + t.datetime "created_on" + end + + add_index "visitors", ["master_id"], :name => "index_visitors_master_id" + add_index "visitors", ["updated_on"], :name => "index_visitors_updated_on" + add_index "visitors", ["user_id"], :name => "index_visitors_user_id" + + create_table "watchers", :force => true do |t| + t.string "watchable_type", :default => "", :null => false + t.integer "watchable_id", :default => 0, :null => false + t.integer "user_id" + end + + add_index "watchers", ["user_id", "watchable_type"], :name => "watchers_user_id_type" + add_index "watchers", ["user_id"], :name => "index_watchers_on_user_id" + add_index "watchers", ["watchable_id", "watchable_type"], :name => "index_watchers_on_watchable_id_and_watchable_type" + + create_table "web_footer_companies", :force => true do |t| + t.string "name" + t.string "logo_size" + t.string "url" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "web_footer_oranizers", :force => true do |t| + t.string "name" + t.text "description" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "wiki_content_versions", :force => true do |t| + t.integer "wiki_content_id", :null => false + t.integer "page_id", :null => false + t.integer "author_id" + t.binary "data", :limit => 2147483647 + t.string "compression", :limit => 6, :default => "" + t.string "comments", :default => "" + t.datetime "updated_on", :null => false + t.integer "version", :null => false + end + + add_index "wiki_content_versions", ["updated_on"], :name => "index_wiki_content_versions_on_updated_on" + add_index "wiki_content_versions", ["wiki_content_id"], :name => "wiki_content_versions_wcid" + + create_table "wiki_contents", :force => true do |t| + t.integer "page_id", :null => false + t.integer "author_id" + t.text "text", :limit => 2147483647 + t.string "comments", :default => "" + t.datetime "updated_on", :null => false + t.integer "version", :null => false + end + + add_index "wiki_contents", ["author_id"], :name => "index_wiki_contents_on_author_id" + add_index "wiki_contents", ["page_id"], :name => "wiki_contents_page_id" + + create_table "wiki_pages", :force => true do |t| + t.integer "wiki_id", :null => false + t.string "title", :null => false + t.datetime "created_on", :null => false + t.boolean "protected", :default => false, :null => false + t.integer "parent_id" + end + + add_index "wiki_pages", ["parent_id"], :name => "index_wiki_pages_on_parent_id" + add_index "wiki_pages", ["wiki_id", "title"], :name => "wiki_pages_wiki_id_title" + add_index "wiki_pages", ["wiki_id"], :name => "index_wiki_pages_on_wiki_id" + + create_table "wiki_redirects", :force => true do |t| + t.integer "wiki_id", :null => false + t.string "title" + t.string "redirects_to" + t.datetime "created_on", :null => false + end + + add_index "wiki_redirects", ["wiki_id", "title"], :name => "wiki_redirects_wiki_id_title" + add_index "wiki_redirects", ["wiki_id"], :name => "index_wiki_redirects_on_wiki_id" + + create_table "wikis", :force => true do |t| + t.integer "project_id", :null => false + t.string "start_page", :null => false + t.integer "status", :default => 1, :null => false + end + + add_index "wikis", ["project_id"], :name => "wikis_project_id" + + create_table "workflows", :force => true do |t| + t.integer "tracker_id", :default => 0, :null => false + t.integer "old_status_id", :default => 0, :null => false + t.integer "new_status_id", :default => 0, :null => false + t.integer "role_id", :default => 0, :null => false + t.boolean "assignee", :default => false, :null => false + t.boolean "author", :default => false, :null => false + t.string "type", :limit => 30 + t.string "field_name", :limit => 30 + t.string "rule", :limit => 30 + end + + add_index "workflows", ["new_status_id"], :name => "index_workflows_on_new_status_id" + add_index "workflows", ["old_status_id"], :name => "index_workflows_on_old_status_id" + add_index "workflows", ["role_id", "tracker_id", "old_status_id"], :name => "wkfs_role_tracker_old_status" + add_index "workflows", ["role_id"], :name => "index_workflows_on_role_id" + + create_table "works_categories", :force => true do |t| + t.string "category" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "zip_packs", :force => true do |t| + t.integer "user_id" + t.integer "homework_id" + t.string "file_digest" + t.string "file_path" + t.integer "pack_times", :default => 1 + t.integer "pack_size", :default => 0 + t.text "file_digests" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + +end +>>>>>>> origin/szzh diff --git a/public/images/vlicon/file.png b/public/images/vlicon/file.png new file mode 100644 index 000000000..bbfa6078d Binary files /dev/null and b/public/images/vlicon/file.png differ diff --git a/public/javascripts/des_kindEditor.js b/public/javascripts/des_kindEditor.js index 206448044..f8aff0be7 100644 --- a/public/javascripts/des_kindEditor.js +++ b/public/javascripts/des_kindEditor.js @@ -90,7 +90,9 @@ function init_form(params){ } function nh_reset_form(params){ params.form[0].reset(); - params.texttitle.empty(); + $("#document_title").val(""); + $('#org_document_editor').hide(); + $('#doc_title_hint').hide(); params.textarea.empty(); if(params.editor != undefined){ params.editor.html(params.textarea.html()); @@ -134,4 +136,8 @@ function init_des_data(){ } }); }); + + div_form = $("div[nhname='new_topic_form']"); + $(".ke-edit", div_form).css("height","150px"); + $(".ke-edit-iframe",div_form).css("height","150px"); } \ No newline at end of file diff --git a/public/stylesheets/courses.css b/public/stylesheets/courses.css index 9dfa32ccf..3840fd892 100644 --- a/public/stylesheets/courses.css +++ b/public/stylesheets/courses.css @@ -1186,7 +1186,7 @@ a:hover.testEdit{ background:url(images/icons.png) -21px -272px no-repeat;} .courseMenuSetting:hover {background:url(../images/homepage_icon2.png) -190px -407px no-repeat;} .rankList {width:220px; padding:10px; background-color:#ffffff; margin-top:10px;} .rankList li {width:73px; padding:8px 0px 0px 0px; text-align:center; float:left; position:relative;} -.rankList li p {width:100%; overflow:hidden; white-space:normal; text-overflow:ellipsis; color:#585858;word-wrap: normal; word-break: normal;} +.rankList li p {width:100%; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; color:#585858;word-wrap: normal; word-break: normal;} .rankPortrait {border-radius:50%; width:35px; height:35px;} .numIntro {position:absolute; text-align:left; z-index:999; box-shadow:0px 2px 8px rgba(146, 153, 169, 0.5); border:1px solid #eaeaea; background-color:#ffffff; padding:3px 5px; left:15px; color:#585858; white-space: nowrap;} .font_cus {font-family: "微软雅黑","宋体"; font-size: 12px; line-height: 1.5;} diff --git a/public/stylesheets/new_user.css b/public/stylesheets/new_user.css index b9e1b40f7..289cb2699 100644 --- a/public/stylesheets/new_user.css +++ b/public/stylesheets/new_user.css @@ -1405,7 +1405,7 @@ span.at a{color:#269ac9;text-decoration: none;} .issues{ background:url(../images/public_icon.png) -66px 5px no-repeat; width:18px; height:21px;} .duty{ background:url(../images/public_icon.png) -66px -18px no-repeat; width:18px; height:21px;} .support{ background:url(../images/public_icon.png) -66px -45px no-repeat; width:18px; height:21px;} -.function{ background:url(../images/public_icon.png) -66px -70px no-repeat; width:18px; height:21px;} +.issues-function{ background:url(../images/public_icon.png) -66px -70px no-repeat; width:18px; height:21px;} .weekly{ background:url(../images/public_icon.png) -66px -95px no-repeat; width:18px; height:21px;} /*资源发送到org*/ diff --git a/public/stylesheets/org.css b/public/stylesheets/org.css index 06c8022c6..aa2d0be18 100644 --- a/public/stylesheets/org.css +++ b/public/stylesheets/org.css @@ -40,6 +40,8 @@ a.org_member_btn{ padding:1px 5px; background:#15bccf; color:#fff;} .searchOrg {height:24px; width:200px; color:#9b9b9b; border:1px solid #15bccf;} a.cancelBtn {padding:3px 5px; background-color:#D9D9D9; color:#656565;} a.cancelBtn:hover {background-color:#717171; color:#ffffff;} +a.org-cancel-btn {padding:3px 5px; background-color:#D9D9D9; color:#656565;} +a.org-cancel-btn:hover {background-color:#717171; color:#ffffff;} .relatedList ul li {border-bottom:1px solid #e4e4e4; width:320px; height:22px; vertical-align:middle; line-height:22px;} .relatedListName {width:240px; text-align:left; max-width:240px; overflow:hidden; white-space:nowrap; text-overflow:ellipsis;} .relatedListOption {width:80px; text-align:center;} diff --git a/public/stylesheets/project.css b/public/stylesheets/project.css index 11c01aa09..1dc5556d3 100644 --- a/public/stylesheets/project.css +++ b/public/stylesheets/project.css @@ -200,12 +200,6 @@ a.pro_mes_w_news{ height:20px; float:right;display:block; color:#999999;} .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;} -/*问题状态图片*/ -.issues{ background:url(../images/public_icon.png) -66px 5px no-repeat; width:16px; height:21px;} -.duty{ background:url(../images/public_icon.png) -66px -18px no-repeat; width:16px; height:21px;} -.support{ background:url(../images/public_icon.png) -66px -45px no-repeat; width:16px; height:21px;} -.function{ background:url(../images/public_icon.png) -66px -70px no-repeat; width:16px; height:21px;} -.weekly{ background:url(../images/public_icon.png) -66px -95px no-repeat; width:16px; height:21px;} /****翻页***/ ul.wlist{ float:right; border-bottom:none; height:30px; margin-top:20px; } ul.wlist li{float: left;} @@ -694,7 +688,7 @@ p.other-formats { text-align: right; font-size:0.9em; color: #666; } /*pre标签换行*/ .break_word{word-break: break-all;word-wrap: break-word;} -.break_word_firefox{white-space: pre-wrap;word-break: break-all;} +.break_word_firefox{white-space: pre-wrap !important;word-break: break-all;} /*问题跟踪attachment显示*/ div.attachments { margin-top: 12px; } @@ -896,9 +890,9 @@ a:hover.Reply_pic{border:1px solid #64bdd9;} /*end*/ /***** Diff *****/ .diff_out { background: #fcc; } -.diff_out span { background: #faa; } +/*.diff_out span { background: #faa; }*/ .diff_in { background: #cfc; } -.diff_in span { background: #afa; } +/*.diff_in span { background: #afa; }*/ .text-diff { padding: 1em; @@ -1084,7 +1078,7 @@ a:hover.link_file_a{ background:url(../images/pic_file.png) 0 -25px no-repeat; c .issues{ background:url(../images/public_icon.png) -66px 5px no-repeat; width:18px; height:21px;} .duty{ background:url(../images/public_icon.png) -66px -18px no-repeat; width:18px; height:21px;} .support{ background:url(../images/public_icon.png) -66px -45px no-repeat; width:18px; height:21px;} -.function{ background:url(../images/public_icon.png) -66px -70px no-repeat; width:18px; height:21px;} +.issues-function{ background:url(../images/public_icon.png) -66px -70px no-repeat; width:18px; height:21px;} .weekly{ background:url(../images/public_icon.png) -66px -95px no-repeat; width:18px; height:21px;} .upload_img img{max-width: 100%;} @@ -1169,3 +1163,18 @@ div.disable_link {background-color: #c1c1c1 !important;} .proInfoBox2{ border:1px solid #dddddd; height:45px; padding:10px 0; background-color:#f1f1f1;} .proInfoBox2 ul li{ height:24px; position:relative;} .maxwidth150{max-width: 150px;} + +/*版本库diff*/ +.showing-changes-info {width:650px; padding:10px; padding-top: 0px; background-color:#ffffff; line-height:2;} +.showing-changes-project {width:650px; padding:10px; border-top:1px solid #dce0e6; border-bottom:1px solid #dce0e6; background-color:#f1f1f1;} +.showing-changes-row {width:650px; padding:10px; border-bottom:1px solid #dce0e6; background-color:#f1f1f1;} +#changed-files-detail {display:none;} +#changed-files-detail li {list-style-type:disc; margin-left:15px;} +.showing-changes-detail {width:670px; border-bottom:1px solid #dce0e6; background-color:#f1f1f1;} +.changes-detail-chart {width:100%; overflow:auto; border-collapse:collapse; margin:0px; padding:0px; background-color:#f1f1f1;} +.diff-line-number {width:35px; min-width:35px; max-width:50px; border-right:1px solid #c1c1c1; padding:0px 5px; text-align:right; background-color:#f1f1f1;} +.code-line-old {background-color:#ffecec;} +.number-line-old {background-color:#ffdddd; border-color:#f1c0c0;} +.code-line-new {background-color:#eaffea;} +.number-line-new {background-color:#dbffdb; border-color:#c1e9c1;} +.branch-label {padding-right: 5px; border-radius:2px; color:#888888; display:inline-block; background-color:#f8fafc;} diff --git a/public/stylesheets/public.css b/public/stylesheets/public.css index 80c219350..8df561d1a 100644 --- a/public/stylesheets/public.css +++ b/public/stylesheets/public.css @@ -113,6 +113,7 @@ h4{ font-size:14px; color:#3b3b3b;} .mt0 {margin-top:0px !important;} .mt3{ margin-top:3px;} .mt5{ margin-top:5px;} +.mt6{ margin-top:6px;} .mt8{ margin-top:8px;} .mt10{ margin-top:10px !important;} .mt20{margin-top: 20px;} @@ -156,6 +157,7 @@ h4{ font-size:14px; color:#3b3b3b;} .w430{ width:470px;} .w455{width:455px !important;} .w465{width:465px !important;} +.w490{width:490px;} .w520{ width:520px;} .w543{ width:543px;} .w557{ width:557px;}