diff --git a/Gemfile b/Gemfile
index 3027c16cd..0125e9d60 100644
--- a/Gemfile
+++ b/Gemfile
@@ -30,11 +30,21 @@ gem 'rails_kindeditor',path:'lib/rails_kindeditor'
#gem "rmagick", ">= 2.0.0"
gem 'binding_of_caller'
gem 'chinese_pinyin'
+# gem 'sunspot_rails', '~> 1.3.3'
+# gem 'sunspot_solr'
+# gem 'sunspot'
+# gem 'progress_bar'
+gem 'ansi'
+
+gem 'kaminari'
+gem 'elasticsearch-model'
+gem 'elasticsearch-rails'
group :development do
gem 'grape-swagger'
gem 'better_errors', '~> 1.1.0'
gem 'rack-mini-profiler', '~> 0.9.3'
+ gem 'win32console'
end
group :development, :test do
diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb
index cd1de16fc..0c61c449e 100644
--- a/app/controllers/courses_controller.rb
+++ b/app/controllers/courses_controller.rb
@@ -374,6 +374,7 @@ class CoursesController < ApplicationController
def settings
if User.current.allowed_to?(:as_teacher,@course)
+ @select_tab = params[:tab]
@issue_custom_fields = IssueCustomField.sorted.all
@issue_category ||= IssueCategory.new
@member ||= @course.members.new
diff --git a/app/controllers/exercise_controller.rb b/app/controllers/exercise_controller.rb
index 6d6d429b6..a99ab32ec 100644
--- a/app/controllers/exercise_controller.rb
+++ b/app/controllers/exercise_controller.rb
@@ -6,6 +6,18 @@ class ExerciseController < ApplicationController
include ExerciseHelper
def index
+ publish_exercises = Exercise.where("publish_time is not null and exercise_status = 1 and publish_time <=?",Time.now)
+ publish_exercises.each do |exercise|
+ exercise.update_column('exercise_status', 2)
+ course = exercise.course
+ course.members.each do |m|
+ exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 2)
+ end
+ end
+ end_exercises = Exercise.where("end_time <=? and exercise_status = 2",Time.now)
+ end_exercises.each do |exercise|
+ exercise.update_column('exercise_status', 3)
+ end
if @course.is_public == 0 && !User.current.member_of_course?(@course)
render_403
return
@@ -24,6 +36,18 @@ class ExerciseController < ApplicationController
end
def show
+ publish_exercises = Exercise.where("publish_time is not null and exercise_status = 1 and publish_time <=?",Time.now)
+ publish_exercises.each do |exercise|
+ exercise.update_column('exercise_status', 2)
+ course = exercise.course
+ course.members.each do |m|
+ exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 2)
+ end
+ end
+ end_exercises = Exercise.where("end_time <=? and exercise_status = 2",Time.now)
+ end_exercises.each do |exercise|
+ exercise.update_column('exercise_status', 3)
+ end
unless User.current.member_of_course?(@course)
render_403
return
@@ -316,6 +340,9 @@ class ExerciseController < ApplicationController
@exercise.exercise_status = 2
@exercise.publish_time = Time.now
if @exercise.save
+ @exercise.course.members.each do |m|
+ @exercise.course_messages << CourseMessage.create(:user_id =>m.user_id, :course_id => @exercise.course.id, :viewed => false,:status=>2)
+ end
#redirect_to exercise_index_url(:course_id=> @course.id)
respond_to do |format|
format.js
@@ -331,6 +358,7 @@ class ExerciseController < ApplicationController
@exercise.exercise_questions.each do |exercise_question|
exercise_question.exercise_answers.destroy_all
end
+ @exercise.course_messages.destroy_all
@exercise.exercise_users.destroy_all
@exercise.exercise_status = 1
@exercise.publish_time = nil
@@ -484,6 +512,10 @@ class ExerciseController < ApplicationController
@exercise.update_attributes(:show_result => params[:show_result])
@exercise.update_attributes(:exercise_status => 2)
@exercise.update_attributes(:publish_time => Time.now)
+ course = @exercise.course
+ course.members.each do |m|
+ @exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 2)
+ end
redirect_to exercise_url(@exercise)
return
elsif @exercise.publish_time > Time.now
diff --git a/app/controllers/memos_controller.rb b/app/controllers/memos_controller.rb
index 4181090a5..2d2c058d4 100644
--- a/app/controllers/memos_controller.rb
+++ b/app/controllers/memos_controller.rb
@@ -73,6 +73,7 @@ class MemosController < ApplicationController
end
end
#end
+ format.js
format.html { redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}" }
format.json { render json: @memo, status: :created, location: @memo }
else
@@ -152,6 +153,7 @@ class MemosController < ApplicationController
end
def update
+ @flag = false
respond_to do |format|
if( #@memo.update_column(:subject, params[:memo][:subject]) &&
@memo.update_column(:content, params[:memo][:content]) &&
@@ -159,10 +161,12 @@ class MemosController < ApplicationController
@memo.update_column(:lock, params[:memo][:lock]) &&
@memo.update_column(:subject,params[:memo][:subject]))
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
- @memo.save
+ @flag = @memo.save
# @memo.root.update_attribute(:updated_at, @memo.updated_at)
+ format.js
format.html {redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}"}
else
+ format.js
format.html { render action: "edit" }
format.json { render json: @person.errors, status: :unprocessable_entity }
end
diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb
index 2bd54954a..c1e124063 100644
--- a/app/controllers/repositories_controller.rb
+++ b/app/controllers/repositories_controller.rb
@@ -64,32 +64,53 @@ class RepositoriesController < ApplicationController
end
def forked
- # 被forked的标识如果不满足单个用户唯一性,则不执行fork
- if is_sigle_identifier?(User.current, @repository.identifier)
- # REDO: 那些人有权限forked项目
- g = Gitlab.client
- gproject = g.post ("/projects/fork/#{@project.gpid}?user_id=#{User.current.gid}")
- if gproject
- copy_project(@project, gproject)
- end
+ # 如果当前用户已经fork过该项目,不会新fork项目,则跳至已fork的项
+ unless has_forked?(@project, User.current)
+ project = project_from_current_project(@project.id, User.current.id)
+ redirect_to project_path(project)
else
- flash[:notice] = l(:project_gitlab_fork_double_message)
- redirect_to settings_project_url(@project, :tab => 'repositories')
+ # 单个用户只能拥有一个名字一样的版本库,否则不能fork
+ # if is_sigle_identifier?(User.current, @repository.identifier)
+ # REDO: 那些人有权限forked项目
+ g = Gitlab.client
+ gproject = g.fork(@project.gpid, User.current.gid)
+ if gproject
+ copy_project(@project, gproject)
+ forked_count = @project.forked_count.to_i + 1
+ @project.update_attributes(:forked_count => forked_count)
+ end
+ # else
+ # flash[:notice] = l(:project_gitlab_fork_double_message)
+ # redirect_to settings_project_url(@project, :tab => 'repositories')
+ # end
end
+
+ end
+
+ # 判断用户是否已经fork过该项目
+ def has_forked?(project, user)
+ projects = Project.where("user_id =?", user)
+ projects.map(&:forked_from_project_id).detect{|s| s == @project.id}.nil? ? true : false
+ end
+
+ # 获取当前用户fork过的项目
+ def project_from_current_project(project, user)
+ project = Project.where("user_id =? and forked_from_project_id =?",user, project).first
end
# copy a project for fork
- def copy_project(project, gproject)
+ def copy_project(tproject, gproject)
project = Project.new
- project.name = @project.name
- project.is_public = @project.is_public
- project.status = @project.status
- project.description = @project.description
- project.hidden_repo = @project.hidden_repo
+ project.name = tproject.name
+ project.is_public = tproject.is_public
+ project.status = tproject.status
+ project.description = tproject.description
+ project.hidden_repo = tproject.hidden_repo
project.user_id = User.current.id
project.project_type = 0
- project.project_new_type = @project.project_new_type
+ project.project_new_type = tproject.project_new_type
project.gpid = gproject.id
+ project.forked_from_project_id = tproject.id
if project.save
r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
m = Member.new(:user => User.current, :roles => [r])
@@ -124,16 +145,16 @@ class RepositoriesController < ApplicationController
def copy_repository(project, gproject)
# 避免
- if is_sigle_identifier?(project.user_id, gproject.name)
+ # if is_sigle_identifier?(project.user_id, gproject.name)
repository = Repository.factory('Git')
repository.project_id = project.id
repository.type = 'Repository::Gitlab'
repository.url = gproject.name
repository.identifier = gproject.name
repository = repository.save
- else
- flash[:notice] = l(:project_gitlab_create_double_message)
- end
+ # else
+ # flash[:notice] = l(:project_gitlab_create_double_message)
+ # end
end
def newrepo
diff --git a/app/controllers/student_work_controller.rb b/app/controllers/student_work_controller.rb
index d2aba1386..5e71b0114 100644
--- a/app/controllers/student_work_controller.rb
+++ b/app/controllers/student_work_controller.rb
@@ -3,8 +3,8 @@ class StudentWorkController < ApplicationController
include StudentWorkHelper
require 'bigdecimal'
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]
- before_filter :find_work, :only => [:edit, :update, :show, :destroy, :add_score, :praise_student_work]
+ 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]
+ 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 :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]
@@ -222,7 +222,7 @@ class StudentWorkController < ApplicationController
def edit
@user = User.current
- if !User.current.admin? && @homework.homework_type == 2 #编程作业不能修改作业
+ if (!User.current.admin? && @homework.homework_type == 2) || Time.parse(@homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d") #编程作业不能修改作业|| 截止日期已到不能修改作业
render_403
else
respond_to do |format|
@@ -284,6 +284,23 @@ class StudentWorkController < ApplicationController
end
end
+ def delete_work
+ @work = StudentWork.where("user_id =? and homework_common_id =?", User.current.id, @homework.id).first
+ if @work
+ @work.destroy
+ end
+ redirect_to user_homeworks_user_path(User.current.id)
+ end
+
+ def retry_work
+ if @work.destroy
+ @student_work = StudentWork.new
+ respond_to do |format|
+ format.js
+ end
+ end
+ end
+
#添加评分,已评分则为修改评分
def add_score
@is_last = params[:is_last] == "true"
@@ -510,6 +527,18 @@ class StudentWorkController < ApplicationController
@course_activity = params[:course_activity].to_i
end
+ def revise_attachment
+ Attachment.attach_filesex(@work, params[:attachments], params[:attachment_type])
+ revise_attachments = @work.attachments.where("attachtype = 7").reorder("created_on desc")
+ if revise_attachments.count == 2
+ revise_attachments.last.destroy
+ end
+ #@attachment = @work.attachments.where("attachtype = 7").order("created_on desc").first
+ respond_to do |format|
+ format.js
+ end
+ end
+
private
def hsd_committed_work?(user, homework)
sw = StudentWork.where("user_id =? and homework_common_id =?", user, homework).first
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 776e6b7d5..834009d71 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -92,7 +92,7 @@ class UsersController < ApplicationController
end
# 用户消息
- # 说明: homework 发布作业;message:讨论区; news:新闻; poll:问卷;works_reviewers:作品评阅;works_reply:作品回复
+ # 说明: homework 发布作业;message:讨论区; news:新闻; poll:问卷;works_reviewers:作品评阅;works_reply:作品回复,exercise:课程测验
# issue:问题;journal:缺陷状态更新; forum:公共贴吧: user_feedback: 用户留言; new_reply:新闻回复(comment)
def user_messages
if !User.current.logged?
@@ -128,7 +128,7 @@ class UsersController < ApplicationController
#课程相关消息
when 'homework'
- @message_alls = CourseMessage.where("course_message_type in ('HomeworkCommon','StudentWorksScore','JournalsForMessage','StudentWork') and user_id =?", @user).order("created_at desc")
+ @message_alls = CourseMessage.where("course_message_type in ('HomeworkCommon','StudentWorksScore','JournalsForMessage','StudentWork','Exercise') and user_id =?", @user).order("created_at desc")
when 'course_message'
@message_alls = CourseMessage.where("course_message_type =? and user_id =?", "Message", @user).order("created_at desc")
when 'course_news'
@@ -1367,7 +1367,7 @@ class UsersController < ApplicationController
end
end
- if(params[:type].blank? || params[:type] == "1") #全部
+ if(params[:type].nil? || params[:type].blank? || params[:type] == "1" || params[:type] == 'all') #全部
if User.current.id.to_i == params[:id].to_i
user_course_ids = User.current.courses.map { |c| c.id} #我的资源库的话,那么应该是我上传的所有资源 加上 我加入的课程的所有资源
@attachments = Attachment.where("(author_id = #{params[:id]} and container_type in('Project','Principal','Course','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+
@@ -1429,6 +1429,7 @@ class UsersController < ApplicationController
@course = @user.courses
.select { |course| @user.allowed_to?(:as_teacher,course)}
end
+ @search = params[:search]
#这里仅仅是传递需要发送的资源id
@send_id = params[:send_id]
@send_ids = params[:checkbox1] || params[:send_ids]
@@ -1445,6 +1446,7 @@ class UsersController < ApplicationController
else
@projects = @user.projects
end
+ @search = params[:search]
#这里仅仅是传递需要发送的资源id
@send_id = params[:send_id]
@send_ids = params[:checkbox1] || params[:send_ids] #搜索的时候 和 直接 用表格提交的时候的send_ids
@@ -1856,7 +1858,7 @@ class UsersController < ApplicationController
# 根据资源关键字进行搜索
def resource_search
search = params[:search].to_s.strip.downcase
- if(params[:type].nil? || params[:type] == "1") #全部
+ if(params[:type].nil? || params[:type].blank? || params[:type] == "1" || params[:type] == 'all') #全部
if User.current.id.to_i == params[:id].to_i
user_course_ids = User.current.courses.map { |c| c.id} #我的资源库的话,那么应该是我上传的所有资源 加上 我加入的课程的所有资源 取交集并查询
@attachments = Attachment.where("((author_id = #{params[:id]} and container_type in('Project','Principal','Course','Issue','Document','Message','News','StudentWorkScore','HomewCommon')) "+
diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb
index 784066378..815a44839 100644
--- a/app/controllers/welcome_controller.rb
+++ b/app/controllers/welcome_controller.rb
@@ -151,36 +151,104 @@ class WelcomeController < ApplicationController
end
def search
- search_condition = params[:q]
- search_type = params[:search_type].to_sym unless search_condition.blank?
- search_by = params[:search_by]
+ @name = params[:q]
+ @search_type = params[:search_type]
+ case params[:search_type]
+ when 'all'
+ @alls = Elasticsearch::Model.search({
+ query: {
+ multi_match: {
+ query: @name,
+ type:"most_fields",
+ operator: "or",
+ fields: ['login', 'firstname','lastname','name','description^0.5','filename']
+ }
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ login: {},
+ firstname: {},
+ lastname: {},
+ name:{},
+ description:{},
+ filename:{}
+ }
+ }
+ },[User,Course,Attachment,Project] ).page(params[:page] || 1).per(20).results
+ when 'user'
+ @users = User.search(@name).page(params[:page] || 1).per(20)
+ when 'project'
+ @projects = Project.search(@name).page(params[:page] || 1).per(20).results
+ when 'course'
+ @courses = Course.search(@name).page(params[:page] || 1).per(20).results
+ when 'attachment'
+ @attachments = Attachment.search(@name).page(params[:page] || 1).per(20).results
+ else
+ @alls = Elasticsearch::Model.search({
+ query: {
+ multi_match: {
+ query: @name,
+ type:"most_fields",
+ operator: "or",
+ fields: ['login', 'firstname','lastname','name','description^0.5','filename']
+ }
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ login: {},
+ firstname: {},
+ lastname: {},
+ name:{},
+ description:{},
+ filename:{}
+ }
+ }
+ },[User,Course,Attachment,Project] ).page(params[:page] || 1).per(20).results
- if search_type.nil? && params[:contests_search] && params[:name] != ""
- search_type = :contests
- search_condition = params[:name]
end
+ @users_count = User.search(@name).results.total
+
+ @course_count = Course.search(@name).results.total
+ @attach_count = Attachment.search(@name).results.total
+ @project_count = Project.search(@name).results.total
+ @total_count = Elasticsearch::Model.search({
+ query: {
+ multi_match: {
+ query: @name,
+ type:"most_fields",
+ operator: "or",
+ fields: ['login', 'firstname','lastname','name','description^0.5','filename']
+ }
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ login: {},
+ firstname: {},
+ lastname: {},
+ name:{},
+ description:{},
+ filename:{}
+ }
+ }
+ },[User,Course,Attachment,Project] ).results.total
+ # search_type = params[:search_type].to_sym unless search_condition.blank?
+ # search_by = params[:search_by]
+ #
+ # if search_type.nil? && params[:contests_search] && params[:name] != ""
+ # search_type = :contests
+ # search_condition = params[:name]
+ # end
+
respond_to do |format|
- format.html{
- case search_type
- when :projects
- redirect_to projects_search_url(:name => search_condition,
- :project_type => Project::ProjectType_project)
- when :courses
- redirect_to courses_search_url(:name => search_condition)
- when :contests
- redirect_to contests_url(:name => search_condition)
- when :users
- redirect_to users_search_url(:name => search_condition,:search_by => search_by)
- when :users_teacher
- redirect_to users_search_url(:name => search_condition, :search_by => search_by, :role => :teacher)
- when :users_student
- redirect_to users_search_url(:name => search_condition, :search_by => search_by, :role => :student)
- else
- #redirect_to home_path, :alert => l(:label_sumbit_empty)
- (redirect_to signin_path, :notice => l(:label_sumbit_empty);return) #if params[:name].blank?
- end
- }
+ format.js
+ format.html{ render :layout=>'users_base'}
end
end
diff --git a/app/controllers/words_controller.rb b/app/controllers/words_controller.rb
index 6cc622c49..c9c4dcce3 100644
--- a/app/controllers/words_controller.rb
+++ b/app/controllers/words_controller.rb
@@ -3,6 +3,8 @@
class WordsController < ApplicationController
include ApplicationHelper
before_filter :find_user, :only => [:new, :create, :destroy, :more, :back]
+ before_filter :require_login, :only => [:create_reply]
+
def create
if params[:new_form][:user_message].size>0 && User.current.logged?
unless params[:user_id].nil?
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 046e0c5a0..cbc646eac 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1869,6 +1869,23 @@ module ApplicationHelper
s
end
+ def get_user_identity identity
+ s = ""
+ case identity
+ when 0
+ s = '教师'
+ when 1
+ s = '学生'
+ when 2
+ s = '组织'
+ when 3
+ s= '开发者'
+ else
+ s = '学生'
+ end
+ s
+ end
+
def get_memo
@new_memo = Memo.new
@public_forum = Forum.find(1) rescue ActiveRecord::RecordNotFound
diff --git a/app/helpers/student_work_helper.rb b/app/helpers/student_work_helper.rb
index e1cf3464e..df5c872f8 100644
--- a/app/helpers/student_work_helper.rb
+++ b/app/helpers/student_work_helper.rb
@@ -126,4 +126,15 @@ module StudentWorkHelper
end
type
end
+
+ def revise_attachment_status homework, attach
+ date = Time.parse(format_time(attach.created_on.to_s)).strftime("%Y-%m-%d")
+ status = ""
+ if homework.homework_detail_manual && ((homework.anonymous_comment == 0 &&homework.homework_detail_manual.evaluation_start.to_s <= date) || (homework.anonymous_comment == 1 && homework.end_time < date))
+ status = "此时其他同学作品已公开"
+ else
+ status = "此时其他同学作品尚未公开"
+ end
+ return status
+ end
end
\ No newline at end of file
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 9c6bb9cb1..999cefdaa 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -17,7 +17,7 @@
require "digest/md5"
require "fileutils"
-
+require 'elasticsearch/model'
class Attachment < ActiveRecord::Base
belongs_to :container, :polymorphic => true
belongs_to :project, foreign_key: 'container_id', conditions: "attachments.container_type = 'Project'"
@@ -38,6 +38,18 @@ class Attachment < ActiveRecord::Base
validates :description, length: {maximum: 254}
validate :validate_max_file_size
+ #elasticsearch
+ include Elasticsearch::Model
+ #elasticsearch kaminari init
+ Kaminari::Hooks.init
+ Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
+ settings index: { number_of_shards: 5 } do
+ mappings dynamic: 'false' do
+ indexes :filename, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :downloads, analyzer: 'smartcn',index_options: 'offsets'
+ end
+ end
+
acts_as_taggable
acts_as_event :title => :filename,
@@ -74,9 +86,9 @@ class Attachment < ActiveRecord::Base
@@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails")
before_save :files_to_final_location,:act_as_course_activity
- after_create :office_conver, :be_user_score,:act_as_forge_activity
- after_update :office_conver, :be_user_score
- after_destroy :delete_from_disk,:down_user_score
+ 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
# add by nwb
# 获取所有可公开的资源文件列表
@@ -92,7 +104,35 @@ class Attachment < ActiveRecord::Base
" LEFT JOIN #{News.table_name} ON #{Attachment.table_name}.container_type='News' AND (#{News.table_name}.project_id in "+self.public_project_id + " OR #{News.table_name}.course_id in " + self.public_course_id + ")" +
" LEFT JOIN #{HomeworkAttach.table_name} ON #{Attachment.table_name}.container_type='HomeworkAttach' AND #{HomeworkAttach.table_name}.bid_id in "+self.public_bid_id)
}
-
+ scope :indexable,lambda { where('is_public = 1 and ((container_type in ("Principal")) ' +
+ 'or (container_type = "Course" and container_id in( SELECT `courses`.id FROM `courses` WHERE (courses.status <> 9 AND courses.is_public = 1)) )'+
+ 'or (container_type = "Project" and container_id in(SELECT `projects`.id FROM `projects` WHERE (projects.status <> 9 AND projects.is_public = 1) ))' +')')} #用于elastic建索引的scope
+ def self.search(query)
+ __elasticsearch__.search(
+ {
+ query: {
+ multi_match: {
+ query: query,
+ type:"most_fields",
+ operator: "or",
+ fields: ['filename']
+ }
+ },
+ sort:{
+ _score:{order:"desc"},
+ downloads: {order:"desc"}
+
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ filename: {}
+ }
+ }
+ }
+ )
+ end
# add by nwb
# 公开的项目id列表
def self.public_project_id
@@ -561,4 +601,46 @@ class Attachment < ActiveRecord::Base
end
end
+ def create_attachment_ealasticsearch_index
+ if self.is_public == 1 && ( (self.container_type == 'Project' && Project.find(self.container_id).is_public == 1) ||
+ ( self.container_type == 'Course' && Course.find(self.container_id).is_public == 1) ||
+ self.container_type == 'Principal')
+ self.__elasticsearch__.index_document
+ end
+ end
+ def update_attachment_ealasticsearch_index
+ if self.is_public == 1 && ( (self.container_type == 'Project' && Project.find(self.container_id).is_public == 1) ||
+ ( self.container_type == 'Course' && Course.find(self.container_id).is_public == 1) ||
+ self.container_type == 'Principal')
+ begin
+ self.__elasticsearch__.update_document
+ rescue => e
+ end
+ else
+ begin
+ self.__elasticsearch__.delete_document
+ rescue => e
+ end
+ end
+ end
+ def delete_attachment_ealasticsearch_index
+ begin
+ self.__elasticsearch__.delete_document
+ rescue => e
+ end
+ end
end
+
+# Delete the previous articles index in Elasticsearch
+# Attachment.__elasticsearch__.client.indices.delete index: Attachment.index_name rescue nil
+#
+# # Create the new index with the new mapping
+# Attachment.__elasticsearch__.client.indices.create \
+# index: Attachment.index_name,
+# body: { settings: Attachment.settings.to_hash, mappings: Attachment.mappings.to_hash }
+
+# Index all article records from the DB to Elasticsearch
+#暂时只做公开课程/项目里的公开资源 和其他的公开资源
+#Attachment.where('is_public = 1 and ((container_type in ("Principal")) ' +
+# 'or (container_type = "Course" and container_id in( SELECT `courses`.id FROM `courses` WHERE (courses.status <> 9 AND courses.is_public = 1)) )'+
+# 'or (container_type = "Project" and container_id in(SELECT `projects`.id FROM `projects` WHERE (projects.status <> 9 AND projects.is_public = 1) ))' +')').import :force=>true
diff --git a/app/models/board.rb b/app/models/board.rb
index edcbe0c9d..67d59e599 100644
--- a/app/models/board.rb
+++ b/app/models/board.rb
@@ -17,8 +17,8 @@
class Board < ActiveRecord::Base
include Redmine::SafeAttributes
- belongs_to :project
- belongs_to :course
+ belongs_to :project,:touch => true
+ belongs_to :course,:touch=>true
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
diff --git a/app/models/comment.rb b/app/models/comment.rb
index 9de25c50d..69753d81c 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -31,7 +31,7 @@ class Comment < ActiveRecord::Base
:title=>Proc.new {|o| "RE: #{o.commented.title}" },
:url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.commented.id} }
- belongs_to :commented, :polymorphic => true, :counter_cache => true
+ belongs_to :commented, :polymorphic => true, :counter_cache => true,:touch => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
validates_presence_of :commented, :author, :comments
safe_attributes 'comments'
@@ -81,8 +81,10 @@ class Comment < ActiveRecord::Base
# 课程成员得分(英雄榜)
def act_as_student_score
- unless self.author.allowed_to?(:as_teacher, self.commented.course)
- course_member_score(self.commented.course.id, self.author_id, "NewReply")
+ if self.commented.course
+ unless self.author.allowed_to?(:as_teacher, self.commented.course)
+ course_member_score(self.commented.course.id, self.author_id, "NewReply")
+ end
end
end
diff --git a/app/models/course.rb b/app/models/course.rb
index 143358abe..1c1bedb3b 100644
--- a/app/models/course.rb
+++ b/app/models/course.rb
@@ -1,10 +1,24 @@
-
+require 'elasticsearch/model'
class Course < ActiveRecord::Base
include Redmine::SafeAttributes
STATUS_ACTIVE = 1
STATUS_CLOSED = 5
STATUS_ARCHIVED = 9
+
+ #elasticsearch
+ include Elasticsearch::Model
+
+ #elasticsearch kaminari init
+ Kaminari::Hooks.init
+ Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
+ settings index: { number_of_shards: 5 } do
+ mappings dynamic: 'false' do
+ indexes :name, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :description, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :updated_at, analyzer: 'smartcn',index_options: 'offsets',type:"date"
+ end
+ end
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period, :open_student, :enterprise_name
#belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
@@ -56,9 +70,9 @@ class Course < ActiveRecord::Base
validates_length_of :description, :maximum => 10000
before_save :self_validate
# 公开课程变成私有课程,所有资源都变成私有
- after_update :update_files_public
- after_create :create_board_sync, :act_as_course_activity, :act_as_course_message
- before_destroy :delete_all_members
+ after_update :update_files_public,:update_course_ealasticsearch_index
+ after_create :create_board_sync, :act_as_course_activity, :act_as_course_message,:create_course_ealasticsearch_index
+ before_destroy :delete_all_members,:delete_course_ealasticsearch_index
safe_attributes 'extra',
'time',
@@ -100,6 +114,34 @@ class Course < ActiveRecord::Base
where(" LOWER(name) LIKE :p ", :p => pattern)
end
}
+ scope :indexable,lambda { where('is_public = 1') }
+ def self.search(query)
+ __elasticsearch__.search(
+ {
+ query: {
+ multi_match: {
+ query: query,
+ type:"most_fields",
+ operator: "or",
+ fields: ['name', 'description^0.5']
+ }
+ },
+ sort: {
+ _score:{order: "desc" },
+ updated_at:{order:"desc"}
+
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ name: {},
+ description: {}
+ }
+ }
+ }
+ )
+ end
def visible?(user=User.current)
user.allowed_to?(:view_course, self)
@@ -344,6 +386,57 @@ class Course < ActiveRecord::Base
#def name
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
#end
+
+ # after_commit on: [:create] do
+ # __elasticsearch__.index_document
+ # end
+ #
+ # after_commit on: [:update] do
+ # __elasticsearch__.update_document
+ # end
+ #
+ # after_commit on: [:destroy] do
+ # __elasticsearch__.delete_document
+ # end
+ def create_course_ealasticsearch_index
+ if self.is_public == 1
+ self.__elasticsearch__.index_document
+ end
+ end
+ def update_course_ealasticsearch_index
+ if self.is_public == 1 #如果是初次更新成为公开的情况,会报错,那么这条记录尚未被索引过。没有报错就是更新的其他属性
+ begin
+ self.__elasticsearch__.update_document
+ rescue => e
+ self.__elasticsearch__.index_document
+ end
+ else #如果是更新成为私有的,那么索引就要被删除
+ begin
+ self.__elasticsearch__.delete_document
+ rescue => e
+
+ end
+ end
+ end
+
+ def delete_course_ealasticsearch_index
+ begin
+ self.__elasticsearch__.delete_document
+ rescue => e
+
+ end
+ end
end
+# Delete the previous articles index in Elasticsearch
+# Course.__elasticsearch__.client.indices.delete index: Course.index_name rescue nil
+#
+# # Create the new index with the new mapping
+# Course.__elasticsearch__.client.indices.create \
+# index: Course.index_name,
+# body: { settings: Course.settings.to_hash, mappings: Course.mappings.to_hash }
+
+# Index all article records from the DB to Elasticsearch
+#Course.where('is_public = 1').import :force=>true
+
diff --git a/app/models/document.rb b/app/models/document.rb
index 37983d6d4..b45a74775 100644
--- a/app/models/document.rb
+++ b/app/models/document.rb
@@ -17,7 +17,7 @@
class Document < ActiveRecord::Base
include Redmine::SafeAttributes
- belongs_to :project
+ belongs_to :project,:touch=>true
belongs_to :user
belongs_to :category, :class_name => "DocumentCategory", :foreign_key => "category_id"
include UserScoreHelper
diff --git a/app/models/exercise.rb b/app/models/exercise.rb
index e4295971e..c91e59fd9 100644
--- a/app/models/exercise.rb
+++ b/app/models/exercise.rb
@@ -2,7 +2,22 @@ class Exercise < ActiveRecord::Base
#exercise_status: 1,新建;2,发布;3,关闭
include Redmine::SafeAttributes
belongs_to :user
+ belongs_to :course ,:touch => true
has_many :exercise_questions, :dependent => :destroy,:order => "#{ExerciseQuestion.table_name}.question_number"
has_many :exercise_users, :dependent => :destroy
has_many :users, :through => :exercise_users #该测试被哪些用户提交答案过
+ # 课程消息
+ has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
+ after_create :acts_as_course_message
+ def acts_as_course_message
+ if self.course
+ if self.exercise_status == 2 #未发布
+ #self.course.members.each do |m|
+ self.course_messages << CourseMessage.create(:user_id => User.current.id, :course_id => self.course_id, :viewed => false,:status=>2)
+ #end
+ # else
+ # self.course_messages.destroy_all 这里的destory_all值得商榷。因为我这里是通过status来控制不同的status的
+ end
+ end
+ end
end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 2a6da44c5..edce3310a 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -19,7 +19,7 @@ class Issue < ActiveRecord::Base
include Redmine::SafeAttributes
include Redmine::Utils::DateCalculation
include UserScoreHelper
- belongs_to :project
+ belongs_to :project,:touch=> true
belongs_to :tracker
belongs_to :status, :class_name => 'IssueStatus', :foreign_key => 'status_id'
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb
index eaece95ce..ec6390408 100644
--- a/app/models/journals_for_message.rb
+++ b/app/models/journals_for_message.rb
@@ -21,9 +21,10 @@ class JournalsForMessage < ActiveRecord::Base
after_destroy :delete_kindeditor_assets
belongs_to :project,
:foreign_key => 'jour_id',
- :conditions => "#{self.table_name}.jour_type = 'Project' "
+ :conditions => "#{self.table_name}.jour_type = 'Project' ",:touch => true
+
belongs_to :course,
- :foreign_key => 'jour_id'
+ :foreign_key => 'jour_id',:touch=>true
belongs_to :jour, :polymorphic => true
diff --git a/app/models/message.rb b/app/models/message.rb
index 21e5e1c71..92ec0235e 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -20,7 +20,7 @@ class Message < ActiveRecord::Base
include UserScoreHelper
include ApplicationHelper
has_many_kindeditor_assets :assets, :dependent => :destroy
- belongs_to :board
+ belongs_to :board,:touch => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
@@ -287,13 +287,15 @@ class Message < ActiveRecord::Base
# 课程成员得分(英雄榜)
def act_as_student_score
- unless self.author.allowed_to?(:as_teacher, self.course)
- if self.parent_id.nil?
- # 发帖
- course_member_score(self.course.id, self.author_id, "Message")
- else
- # 回帖
- course_member_score(self.course.id, self.author_id, "MessageReply")
+ if self.course
+ unless self.author.allowed_to?(:as_teacher, self.course)
+ if self.parent_id.nil?
+ # 发帖
+ course_member_score(self.course.id, self.author_id, "Message")
+ else
+ # 回帖
+ course_member_score(self.course.id, self.author_id, "MessageReply")
+ end
end
end
end
diff --git a/app/models/news.rb b/app/models/news.rb
index e9b8b5314..53581a536 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -17,11 +17,11 @@
class News < ActiveRecord::Base
include Redmine::SafeAttributes
- belongs_to :project
+ belongs_to :project,:touch => true
include ApplicationHelper
has_many_kindeditor_assets :assets, :dependent => :destroy
#added by nwb
- belongs_to :course
+ belongs_to :course,:touch => true
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
has_many :comments, :as => :commented, :dependent => :destroy, :order => "created_on"
# fq
diff --git a/app/models/project.rb b/app/models/project.rb
index 0b0420920..ff546e098 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -14,7 +14,7 @@
# 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.
-
+require 'elasticsearch/model'
class Project < ActiveRecord::Base
include Redmine::SafeAttributes
ProjectType_project = 0
@@ -30,6 +30,19 @@ class Project < ActiveRecord::Base
# Specific overidden Activities
+ #elasticsearch
+ include Elasticsearch::Model
+ #elasticsearch kaminari init
+ Kaminari::Hooks.init
+ Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
+ settings index: { number_of_shards: 5 } do
+ mappings dynamic: 'false' do
+ indexes :name, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :description, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :updated_on, analyzer: 'smartcn',index_options: 'offsets', type:'date'
+ end
+ end
+
has_many :student_works
has_many :time_entry_activities
has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
@@ -138,8 +151,9 @@ class Project < ActiveRecord::Base
#ActiveModel::Dirty 这里有一个changed方法。对任何对象都可以用
after_save :update_inherited_members, :if => Proc.new {|project| project.inherit_members_changed?}
# 创建project之后默认创建一个board,之后的board去掉了board的概念
- after_create :create_board_sync,:acts_as_forge_activities
- before_destroy :delete_all_members
+ after_create :create_board_sync,:acts_as_forge_activities,:create_project_ealasticsearch_index
+ before_destroy :delete_all_members,:delete_project_ealasticsearch_index
+ after_update :update_project_ealasticsearch_index
def remove_references_before_destroy
return if self.id.nil?
Watcher.delete_all ['watchable_id = ?', id]
@@ -172,7 +186,33 @@ class Project < ActiveRecord::Base
}
scope :project_entities, -> { where(project_type: ProjectType_project) }
scope :course_entities, -> { where(project_type: ProjectType_course) }
-
+ scope :indexable,lambda { where('is_public = 1')} #用于elastic建索引的scope
+ def self.search(query)
+ __elasticsearch__.search(
+ {
+ query: {
+ multi_match: {
+ query: query,
+ type:"most_fields",
+ operator: "or",
+ fields: ['name','description^0.5']
+ }
+ },
+ sort: {
+ _score:{order: "desc" },
+ updated_on:{order: "desc" }
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ name: {},
+ description: {}
+ }
+ }
+ }
+ )
+ end
def new_course
self.where('project_type = ?', 1)
end
@@ -1176,5 +1216,36 @@ class Project < ActiveRecord::Base
end
+ def create_project_ealasticsearch_index
+ if self.is_public
+ self.__elasticsearch__.index_document
+ end
+ end
+ def update_project_ealasticsearch_index
+ if self.is_public #如果是初次更新成为公开的情况,会报错,那么这条记录尚未被索引过。没有报错就是更新的其他属性
+ begin
+ self.__elasticsearch__.update_document
+ rescue => e
+ self.__elasticsearch__.index_document
+ end
+ else #如果是更新成为私有的,那么索引就要被删除
+ begin
+ self.__elasticsearch__.delete_document
+ rescue => e
+
+ end
+ end
+ end
+ def delete_project_ealasticsearch_index
+ begin
+ self.__elasticsearch__.delete_document
+ rescue => e
+
+ end
+ end
+
+
end
+#Project.where('is_public = 1').import :force=>true
+
diff --git a/app/models/project_tags.rb b/app/models/project_tags.rb
index 16de1ea45..bcf666fb5 100644
--- a/app/models/project_tags.rb
+++ b/app/models/project_tags.rb
@@ -2,7 +2,7 @@
class ProjectTags < ActiveRecord::Base
attr_accessible :description, :project_id, :tag_id, :user_id
####################################################################################################添加代码
- belongs_to :project
+ belongs_to :project,:touch => true
belongs_to :tag
belongs_to :user
diff --git a/app/models/student_work.rb b/app/models/student_work.rb
index 010ede635..884f4a089 100644
--- a/app/models/student_work.rb
+++ b/app/models/student_work.rb
@@ -10,6 +10,7 @@ class StudentWork < ActiveRecord::Base
has_many :student_work_tests, order: 'id desc'
# course's message
has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
+ has_many :attachments, :dependent => :destroy
before_destroy :delete_praise
before_save :set_program_score, :set_src
diff --git a/app/models/user.rb b/app/models/user.rb
index cd8b96d47..9c437a186 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -16,7 +16,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
require "digest/sha1"
-
+require 'elasticsearch/model'
class User < Principal
TEACHER = 0
STUDENT = 1
@@ -25,6 +25,20 @@ class User < Principal
include Redmine::SafeAttributes
seems_rateable_rater
+ #elasticsearch
+ include Elasticsearch::Model
+ #elasticsearch kaminari init
+ Kaminari::Hooks.init
+ Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
+ settings index: { number_of_shards: 5 } do
+ mappings dynamic: 'false' do
+ indexes :login, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :firstname, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :lastname, analyzer: 'smartcn',index_options: 'offsets'
+ indexes :last_login_on, analyzer: 'smartcn',index_options: 'offsets',type: 'date'
+ end
+ end
+
# Different ways of displaying/sorting users
USER_FORMATS = {
:firstname_lastname => {
@@ -64,6 +78,7 @@ class User < Principal
},
}
+
#每日一报、一事一报、不报
MAIL_NOTIFICATION_OPTIONS = [
#['week', :label_user_mail_option_week],
@@ -162,6 +177,7 @@ class User < Principal
#####
has_many :shares ,:dependent => :destroy
+
# add by zjc
has_one :level, :class_name => 'UserLevels', :dependent => :destroy
has_many :memos , :foreign_key => 'author_id'
@@ -222,12 +238,12 @@ class User < Principal
# validates_email_realness_of :mail
before_create :set_mail_notification
before_save :update_hashed_password
- before_destroy :remove_references_before_destroy
+ before_destroy :remove_references_before_destroy,:delete_user_ealasticsearch_index
# added by fq
- after_create :act_as_activity, :add_onclick_time, :act_as_principal_activity
+ after_create :act_as_activity, :add_onclick_time, :act_as_principal_activity,:create_user_ealasticsearch_index
# end
# 更新邮箱用户或用户名的同事,同步更新邀请信息
- after_update :update_invite_list
+ after_update :update_invite_list,:update_user_ealasticsearch_index
include Trustie::Gitlab::ManageUser
@@ -240,7 +256,7 @@ class User < Principal
where("#{User.table_name}.id NOT IN (SELECT gu.user_id FROM #{table_name_prefix}groups_users#{table_name_suffix} gu WHERE gu.group_id = ?)", group_id)
}
scope :sorted, lambda { order(*User.fields_for_order_statement)}
-
+ scope :indexable,lambda { where('id not in (2,4)')} #用于elastic建索引的scope,id为2是匿名用户,4是管理员,不能被索引
scope :like, lambda {|arg, type|
if arg.blank?
where(nil)
@@ -258,7 +274,33 @@ class User < Principal
end
end
}
-
+ def self.search(query)
+ __elasticsearch__.search(
+ {
+ query: {
+ multi_match: {
+ query: query,
+ type:"most_fields",
+ operator: "or",
+ fields: ['login', 'firstname','lastname']
+ }
+ },
+ sort:{
+ _score:{order:"desc"},
+ last_login_on: {order:"desc"}
+ },
+ highlight: {
+ pre_tags: [''],
+ post_tags: [' '],
+ fields: {
+ login: {},
+ firstname: {},
+ lastname: {}
+ }
+ }
+ }
+ )
+ end
# ======================================================================
@@ -435,7 +477,7 @@ class User < Principal
end
if user
# user is already in local database
- #return nil unless user.active?
+ return nil if user.locked?
return nil unless user.check_password?(password)
else
# user is not yet registered, try to authenticate with available sources
@@ -1119,6 +1161,23 @@ class User < Principal
end
end
+
+ def create_user_ealasticsearch_index
+ if self.id != 2 && self.id != 4
+ self.__elasticsearch__.index_document
+ end
+ end
+ def update_user_ealasticsearch_index
+ if self.id != 2 && self.id != 4
+ self.__elasticsearch__.update_document
+ end
+ end
+ def delete_user_ealasticsearch_index
+ if self.id != 2 && self.id != 4
+ self.__elasticsearch__.delete_document
+ end
+ end
+
end
class AnonymousUser < User
@@ -1153,4 +1212,17 @@ class AnonymousUser < User
def destroy
false
end
+
end
+
+# Delete the previous articles index in Elasticsearch
+# User.__elasticsearch__.client.indices.delete index: User.index_name rescue nil
+#
+# # Create the new index with the new mapping
+# User.__elasticsearch__.client.indices.create \
+# index: User.index_name,
+# body: { settings: User.settings.to_hash, mappings: User.mappings.to_hash }
+
+# Index all article records from the DB to Elasticsearch
+# 匿名用户 角色 和 管理员角色不能被索引
+#User.where('id not in (2,4)').import :force=>true
diff --git a/app/views/attachments/destroy.js.erb b/app/views/attachments/destroy.js.erb
index d23422e24..cfbe68085 100644
--- a/app/views/attachments/destroy.js.erb
+++ b/app/views/attachments/destroy.js.erb
@@ -1,5 +1,9 @@
<% if @is_destroy%>
$("#attachment_<%= @attachment.id%>").remove();
+ if(document.getElementById("uploadReviseBox")) {
+ $("#uploadReviseBox").removeClass('disable_link');
+ $("#choose_revise_attach").attr("onclick","_file.click();");
+ }
<%else%>
var attachment_html_obj = $('#attachments_<%= j params[:attachment_id] %>');
//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 start
@@ -26,5 +30,10 @@
$('#upload_file_count'+containerid).html(""+count+" "+"个文件"+"已上传");
}
}
+
+ if(document.getElementById("uploadReviseBox")) {
+ $("#uploadReviseBox").removeClass('disable_link');
+ $("#choose_revise_attach").attr("onclick","_file.click();");
+ }
//modify by yutao 2015-5-14 当1个页面存在多个上传控件时此块代码存在bug 故改之 end
<% end%>
\ No newline at end of file
diff --git a/app/views/courses/member.html.erb b/app/views/courses/member.html.erb
index ce336373b..3aa7d4b57 100644
--- a/app/views/courses/member.html.erb
+++ b/app/views/courses/member.html.erb
@@ -1,9 +1,14 @@
-
-
<%= @subPage_title%>
-
-<% if @subPage_title == l(:label_student_list)%>
- <%= render :partial => 'course_student', :locals => {:members => @members} %>
-<% else%>
- <%= render :partial => 'course_teacher', :locals => {:members => @members} %>
-<% end%>
-
+
+
<%= @subPage_title%>
+ <% if User.current.allowed_to?(:as_teacher,@course) %>
+
+ <%=link_to "修改角色", :controller => 'courses', :action => 'settings', :id => @course.id, :tab=>'member' %>
+
+ <% end %>
+
+<% if @subPage_title == l(:label_student_list)%>
+ <%= render :partial => 'course_student', :locals => {:members => @members} %>
+<% else%>
+ <%= render :partial => 'course_teacher', :locals => {:members => @members} %>
+<% end%>
+
diff --git a/app/views/courses/settings.html.erb b/app/views/courses/settings.html.erb
index 5c3918f00..3456634d5 100644
--- a/app/views/courses/settings.html.erb
+++ b/app/views/courses/settings.html.erb
@@ -1,6 +1,13 @@
<%= l(:label_course_modify_settings)%>
+
@@ -118,4 +125,4 @@
}
$("#time_selected").click(select);
$("#term_selected").click(select);
-
+
diff --git a/app/views/exercise/_edit_head.html.erb b/app/views/exercise/_edit_head.html.erb
index b69f52a56..a071904ce 100644
--- a/app/views/exercise/_edit_head.html.erb
+++ b/app/views/exercise/_edit_head.html.erb
@@ -20,7 +20,7 @@
保存
-
+
<%= l(:button_cancel)%>
@@ -35,6 +35,5 @@
$("#exercise_time").val("<%=exercise.time if exercise.time!= -1 %>");
$("#exercise_publish_time").val("<%= Time.parse(format_time(exercise.publish_time)).strftime("%Y-%m-%d") if !exercise.publish_time.nil?%>");
/*$("#exercise_description").text("<%#=exercise.exercise_description.html_safe %>");*/
- document.getElementById("exercise_description").innerText = <%=exercise.exercise_description.html_safe %>;
}
\ No newline at end of file
diff --git a/app/views/forums/_show_topics.html.erb b/app/views/forums/_show_topics.html.erb
index bb8a91b69..dc3a20482 100644
--- a/app/views/forums/_show_topics.html.erb
+++ b/app/views/forums/_show_topics.html.erb
@@ -16,7 +16,7 @@
<%= format_date(topic.last_reply.created_at)%>
<% end%>
-
+
更新时间:<%= format_date(topic.updated_at)%>
diff --git a/app/views/forums/show.html.erb b/app/views/forums/show.html.erb
index 05c086ed4..ad9195804 100644
--- a/app/views/forums/show.html.erb
+++ b/app/views/forums/show.html.erb
@@ -3,7 +3,7 @@
error
- <%= labelled_form_for(@memo, :url => forum_memos_path(@forum)) do |f| %>
+ <%= labelled_form_for(@memo, :url => forum_memos_path(@forum),:remote=>true) do |f| %>
diff --git a/app/views/student_work/_revise_attachment.html.erb b/app/views/student_work/_revise_attachment.html.erb
new file mode 100644
index 000000000..968a4853b
--- /dev/null
+++ b/app/views/student_work/_revise_attachment.html.erb
@@ -0,0 +1,28 @@
+<% revise_attachment = work.attachments.where("attachtype = 7").first %>
+<% if @homework.end_time < Date.today %>
+ <% if revise_attachment && @is_teacher %>
+
+ 追加修订附件
+
+
+ 追加附件:
+ <%= render :partial => 'work_attachments_status', :locals => {:attachments => work.attachments.where("attachtype = 7"), :status => 2} %>
+ 追加时间: <%=format_time revise_attachment.created_on.to_s %> (<%=revise_attachment_status @homework,revise_attachment %>)
+
+ <% end %>
+ <% if work.user == User.current %>
+
+ 追加修订附件
+
+ <% if revise_attachment %>
+
+ 追加附件:
+ <%= render :partial => 'work_attachments_status', :locals => {:attachments => work.attachments.where("attachtype = 7"), :status => 1} %>
+ 追加时间: <%=format_time revise_attachment.created_on.to_s %>
+
+ <% end %>
+
+ <% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/views/student_work/_show.html.erb b/app/views/student_work/_show.html.erb
index 1b0202536..993b0f2aa 100644
--- a/app/views/student_work/_show.html.erb
+++ b/app/views/student_work/_show.html.erb
@@ -41,17 +41,18 @@
附件:
- <% if work.attachments.empty?%>
+ <% com_attachments = work.attachments.where("attachtype IS NULL OR attachtype <> 7") %>
+ <% if com_attachments.empty?%>
尚未提交附件
<% else%>
- <%= render :partial => 'work_attachments_status', :locals => {:attachments => work.attachments, :status => @homework.homework_detail_manual.comment_status} %>
+ <%= render :partial => 'work_attachments_status', :locals => {:attachments => com_attachments, :status => @homework.homework_detail_manual.comment_status} %>
<% end%>
- <% if @is_teacher || (@homework.homework_detail_manual.comment_status == 2 && work.user != User.current )%>
+ <% if @is_teacher || (@homework.homework_detail_manual.comment_status == 2 && work.user != User.current)%>
<%= render :partial => 'add_score',:locals => {:work => work,:score => score}%>
@@ -61,6 +62,11 @@
+
+ <%= render :partial => 'student_work/revise_attachment', :locals => {:work => work} %>
+
+
+
<%student_work_scores.each do |student_score|%>
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/app/views/student_work/_upload_attachment.html.erb b/app/views/student_work/_upload_attachment.html.erb
new file mode 100644
index 000000000..d9c69fc17
--- /dev/null
+++ b/app/views/student_work/_upload_attachment.html.erb
@@ -0,0 +1,50 @@
+
+
上传附件
+
+
+ <%= form_tag(revise_attachment_student_work_path(work.id), :multipart => true,:remote => !ie8?,:name=>"upload_form",:id=>'upload_form') do %>
+
+
+
+
+
+
+
+ 选择文件
+ <%= file_field_tag 'attachments[dummy][file]',
+ :id => '_file',
+ :class => ie8? ? '':'file_selector',
+ :multiple => true,
+ :onchange => 'addReviseInputFiles(this,"'+'upload_files_submit_btn'+'");',
+ :style => ie8? ? '': 'display:none',
+ :data => {
+ :max_file_size => Setting.attachment_max_size.to_i.kilobytes,
+ :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
+ :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
+ :upload_path => uploads_path(:format => 'js'),
+ :description_placeholder => l(:label_optional_description),
+ :field_is_public => l(:field_is_public),
+ :are_you_sure => l(:text_are_you_sure),
+ :file_count => l(:label_file_count),
+ :lebel_file_uploding => l(:lebel_file_uploding),
+ :delete_all_files => l(:text_are_you_sure_all)
+ } %>
+
+
+
+
+
+
+
+
+ <%= submit_tag '确定',:onclick=>'submit_files();',:onfocus=>'this.blur()',:id=>'upload_files_submit_btn',:class=>'sendSourceText' %>
+
+
+
+ <% end %>
+
+
diff --git a/app/views/student_work/_work_edit_information.html.erb b/app/views/student_work/_work_edit_information.html.erb
new file mode 100644
index 000000000..38670d9e4
--- /dev/null
+++ b/app/views/student_work/_work_edit_information.html.erb
@@ -0,0 +1,33 @@
+
+
+
请您确认刚刚上传的作品信息
+
+ 作品名称: <%=@student_work.name%>
+
+
+ 作品描述: <%=@student_work.description%>
+
+
+ 附 件:
+ <% if @student_work.attachments.empty? %>
+ <%= "无附件"%>
+ <% else %>
+
+ <%= render :partial => 'work_attachments_status', :locals => {:attachments => @student_work.attachments, :status => 2} %>
+
+ <% end %>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/student_work/_work_information.html.erb b/app/views/student_work/_work_information.html.erb
index f8a55a03d..90d749af1 100644
--- a/app/views/student_work/_work_information.html.erb
+++ b/app/views/student_work/_work_information.html.erb
@@ -19,9 +19,10 @@
-
+
确 定
+ <%= link_to("重试", retry_work_student_work_path(@student_work.id),:class => "tijiao",:style =>"margin-bottom: 15px;margin-top:15px;",:remote => true)%>
diff --git a/app/views/student_work/create.js.erb b/app/views/student_work/create.js.erb
index afd8617aa..67a1ccb50 100644
--- a/app/views/student_work/create.js.erb
+++ b/app/views/student_work/create.js.erb
@@ -11,7 +11,7 @@
showModal('ajax-modal', '500px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("
" +
- " ");
+ "
");
$('#ajax-modal').parent().css("top","").css("left","");
$('#ajax-modal').parent().addClass("anonymos");
<% else %>
diff --git a/app/views/student_work/new.html.erb b/app/views/student_work/new.html.erb
index 4f9999277..ee0dd7e9b 100644
--- a/app/views/student_work/new.html.erb
+++ b/app/views/student_work/new.html.erb
@@ -99,7 +99,7 @@
@@ -111,9 +111,9 @@
-
确定
+
提交
或
- <%= link_to "取消", user_homeworks_user_path(User.current.id), :class => "fr mr10 mt3"%>
+ <%= link_to "取消", delete_work_student_work_index_path(:homework =>@homework.id), :class => "fr mr10 mt3"%>
<% end%>
diff --git a/app/views/student_work/retry_work.js.erb b/app/views/student_work/retry_work.js.erb
new file mode 100644
index 000000000..c5fca76d4
--- /dev/null
+++ b/app/views/student_work/retry_work.js.erb
@@ -0,0 +1,2 @@
+hideModal('#popbox02');
+$("#homework_attachments").html("<%= escape_javascript(render :partial => 'users/user_homework_attachment', :locals => {:container => @student_work, :has_program=>false})%>");
\ No newline at end of file
diff --git a/app/views/student_work/revise_attachment.js.erb b/app/views/student_work/revise_attachment.js.erb
new file mode 100644
index 000000000..74813d27b
--- /dev/null
+++ b/app/views/student_work/revise_attachment.js.erb
@@ -0,0 +1,2 @@
+closeModal();
+$("#revise_attachment").html('<%= escape_javascript( render :partial => 'revise_attachment' ,:locals=>{ :work => @work})%>');
\ No newline at end of file
diff --git a/app/views/student_work/update.js.erb b/app/views/student_work/update.js.erb
index 79733db31..f485cb8cc 100644
--- a/app/views/student_work/update.js.erb
+++ b/app/views/student_work/update.js.erb
@@ -1,5 +1,5 @@
<% if @submit_result%>
-$('#ajax-modal').html('<%= escape_javascript(render :partial => 'student_work/work_information') %>');
+$('#ajax-modal').html('<%= escape_javascript(render :partial => 'student_work/work_edit_information') %>');
showModal('ajax-modal', '500px');
$('#ajax-modal').siblings().remove();
$('#ajax-modal').before("
" +
diff --git a/app/views/users/_resource_search_form.html.erb b/app/views/users/_resource_search_form.html.erb
index 376007fec..c629f9f32 100644
--- a/app/views/users/_resource_search_form.html.erb
+++ b/app/views/users/_resource_search_form.html.erb
@@ -1,7 +1,7 @@
<%= form_tag( url_for(:controller => 'users',:action => 'resource_search',:id=>user.id),
:remote=>true ,:method => 'get',:class=>'resourcesSearchloadBox',:id=>'resource_search_form') do %>
- <%= hidden_field_tag(:type,type) %>
+ <%= hidden_field_tag(:type,type.nil? ? 1 : type) %>
<%= submit_tag '',:class=>'homepageSearchIcon',:onfocus=>'this.blur();',:style=>'border-style:none' %>
<% end %>
\ No newline at end of file
diff --git a/app/views/users/_resource_share_for_project_popup.html.erb b/app/views/users/_resource_share_for_project_popup.html.erb
index 40bbd5e7c..ba136899c 100644
--- a/app/views/users/_resource_share_for_project_popup.html.erb
+++ b/app/views/users/_resource_share_for_project_popup.html.erb
@@ -17,7 +17,10 @@
:remote=>true,:id=>'search_user_project_form',:class=>'resourcesSearchBox' do %>
<%= hidden_field_tag(:send_id, send_id) %>
<%= hidden_field_tag(:send_ids, send_ids) %>
-
+
+
<%= submit_tag '',:class=>'searchIconPopup',:onfocus=>"this.blur();",:style=>'border-style:none' %>
<% end %>
diff --git a/app/views/users/_resource_share_popup.html.erb b/app/views/users/_resource_share_popup.html.erb
index ed2ed44a6..53fb6673b 100644
--- a/app/views/users/_resource_share_popup.html.erb
+++ b/app/views/users/_resource_share_popup.html.erb
@@ -17,7 +17,10 @@
:remote=>true,:id=>'search_user_course_form',:class=>'resourcesSearchBox' do %>
<%= hidden_field_tag(:send_id, send_id) %>
<%= hidden_field_tag(:send_ids, send_ids) %>
-
+
+
<%= submit_tag '',:class=>'searchIconPopup',:onfocus=>"this.blur();",:style=>'border-style:none' %>
<% end %>
diff --git a/app/views/users/_resources_list.html.erb b/app/views/users/_resources_list.html.erb
index 156da0f07..ef6397ec0 100644
--- a/app/views/users/_resources_list.html.erb
+++ b/app/views/users/_resources_list.html.erb
@@ -5,7 +5,7 @@
<% else %>
<% attachments.each do |attach| %>
-
-
+
diff --git a/app/views/users/_user_message_course.html.erb b/app/views/users/_user_message_course.html.erb
index c2b1b509f..640f98b1f 100644
--- a/app/views/users/_user_message_course.html.erb
+++ b/app/views/users/_user_message_course.html.erb
@@ -126,7 +126,7 @@
<% end %>
- 截止时间快到了!
+ 截止时间快到啦
<%= time_tag(ma.created_at).html_safe %>
<% end %>
@@ -158,7 +158,7 @@
匿评截止:<%= ma.course_message.homework_detail_manual.evaluation_end %> 23:59
<% unless User.current.allowed_to?(:as_teacher, ma.course_message.course)%>
- 请您尽早完成匿评!如果您在截止日期前未完成匿评,您的最终成绩将被扣除<%= ma.course_message.homework_detail_manual.absence_penalty %>分乘以缺评份数。
+ 请您尽早完成匿评,如果您在截止日期前未完成匿评,您的最终成绩将被扣除<%= ma.course_message.homework_detail_manual.absence_penalty %>分乘以缺评份数。
例如,您缺评了两份作品,则您的最终成绩将被扣除 <%= ma.course_message.homework_detail_manual.absence_penalty %> * 2 = <%= ma.course_message.homework_detail_manual.absence_penalty * 2 %>分
<% end%>
@@ -209,7 +209,7 @@
<%= User.current.lastname + User.current.firstname %><%= User.current.allowed_to?(:as_teacher, ma.course_message.course) ? '老师':'同学'%>您好!
- <%= User.current.eql?(ma.course_message.user) ?"您":(ma.course_message.user.lastname + ma.course_message.user.firstname + "老师") %>启动作业匿评失败!
+ <%= User.current.eql?(ma.course_message.user) ?"您":(ma.course_message.user.lastname + ma.course_message.user.firstname + "老师") %>启动作业匿评失败啦
如需获得最终成绩,请您联系主讲老师对您的作品进行单独评分!
- 您迟交了作品!
+ 您成功提交了作品(但被标记为迟交啦)
<%= time_tag(ma.created_at).html_safe %>
<% end %>
@@ -579,7 +579,7 @@
<% end %>
-
+
<% if ma.course_message_type == "RemoveFromCourse" %>
@@ -612,4 +612,74 @@
<%= time_tag(ma.created_at).html_safe %>
<% end %>
+
+
+ <% if ma.course_message_type == "Exercise" && ma.status == 2 %>
+
+ <%=link_to image_tag(url_to_avatar(ma.course_message.user), :width => "30", :height => "30"), user_path(ma.course_message.user) %>
+
+ <%=link_to ma.course_message.user.lastname + ma.course_message.user.firstname + "老师",
+ user_path(ma.course_message.user), :class => "newsBlue homepageNewsPublisher" %> ">发布了课程测验 :
+
+ <%= link_to "测验题目:" + ma.course_message.exercise_name, exercise_path(:id => ma.course_message.id), :class =>"#{ma.viewed == 0 ? "newsBlack" : "newsGrey"}",
+ :onmouseover =>"message_titile_show($(this),event)",
+ :onmouseout => "message_titile_hide($(this))"%>
+
+
+
+
+ <%= User.current.lastname + User.current.firstname %><%= User.current.allowed_to?(:as_teacher,ma.course_message.course) ? '老师':'同学'%>您好!
+ <%= User.current.eql?(ma.course_message.user)?"您":(ma.course_message.user.lastname + ma.course_message.user.firstname+"老师") %>发布了课程测验 ,测验详情如下:
+
+
+ 课程名称:<%= ma.course_message.course.name %>(<%= ma.course_message.course.time.to_s + '年'+ ma.course_message.course.term %>)
+ 测验标题:<%= ma.course_message.exercise_name %>
+
+
+
+
+
+ 截止时间:<%= ma.course_message.end_time.to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S") %>
+ 答题时长:<%= ma.course_message.time == -1 ? '不限时' : ma.course_message.time.to_s + '分钟' %>
+ <% if !User.current.allowed_to?(:as_teacher,ma.course_message.course)%>
+ 请记得在截止时间前完成测验噢,辛苦啦!
+ <% end %>
+
+
+ <%= time_tag(ma.created_at).html_safe %>
+
+ <% end %>
+
+
+ <% if ma.course_message_type == "Exercise" && ma.status == 3 %>
+
+ <%=link_to image_tag(url_to_avatar(ma.course_message.user), :width => "30", :height => "30"), user_path(ma.course_message.user) %>
+
+ <%=link_to ma.course_message.user.lastname + ma.course_message.user.firstname + "老师",
+ user_path(ma.course_message.user), :class => "newsBlue homepageNewsPublisher" %> ">发布的测验:
+
+ <%= link_to "测验题目:" + ma.course_message.exercise_name, exercise_path(:id => ma.course_message.id), :class =>"#{ma.viewed == 0 ? "newsBlack" : "newsGrey"}",
+ :onmouseover =>"message_titile_show($(this),event)",
+ :onmouseout => "message_titile_hide($(this))"%>
+
+
+
+
+
+ <%= User.current.lastname + User.current.firstname %><%= User.current.allowed_to?(:as_teacher,ma.course_message.course) ? '老师':'同学'%>您好!
+ <%= User.current.eql?(ma.course_message.user)?"您":(ma.course_message.user.lastname + ma.course_message.user.firstname+"老师") %>发布的课程测验截止时间快到了,测验详情如下:
+
+
+
+ 课程名称:<%= ma.course_message.course.name %>(<%= ma.course_message.course.time.to_s + '年'+ ma.course_message.course.term %>)
+ 测验标题:<%= ma.course_message.exercise_name %>
+ 截止时间:<%= ma.course_message.end_time.to_s.gsub("+0800","").to_datetime.strftime("%Y-%m-%d %H:%M:%S") %>
+ 答题时长:<%= ma.course_message.time == -1 ? '无限制' : ma.course_message.time.to_s + '分钟' %>
+ 请及时完成课程测验,辛苦啦!
+
+
+ 截止时间快到啦
+ <%= time_tag(ma.created_at).html_safe %>
+
+ <% end %>
<% end %>
\ No newline at end of file
diff --git a/app/views/users/add_exist_file_to_course.js.erb b/app/views/users/add_exist_file_to_course.js.erb
index c61790c40..95f7784f7 100644
--- a/app/views/users/add_exist_file_to_course.js.erb
+++ b/app/views/users/add_exist_file_to_course.js.erb
@@ -5,5 +5,6 @@ $("#res_count").html(0);
$("#checkboxAll").attr('checked',false);
$("#res_all_count").html(<%= @atta_count%>);
closePopUp();
+alert("发送成功")
<% else%>
<% end %>
\ No newline at end of file
diff --git a/app/views/users/add_exist_file_to_project.js.erb b/app/views/users/add_exist_file_to_project.js.erb
index c61790c40..95f7784f7 100644
--- a/app/views/users/add_exist_file_to_project.js.erb
+++ b/app/views/users/add_exist_file_to_project.js.erb
@@ -5,5 +5,6 @@ $("#res_count").html(0);
$("#checkboxAll").attr('checked',false);
$("#res_all_count").html(<%= @atta_count%>);
closePopUp();
+alert("发送成功")
<% else%>
<% end %>
\ No newline at end of file
diff --git a/app/views/users/user_resource.html.erb b/app/views/users/user_resource.html.erb
index 4fd4d0cb9..a6d8d18c7 100644
--- a/app/views/users/user_resource.html.erb
+++ b/app/views/users/user_resource.html.erb
@@ -143,7 +143,7 @@
//资源名称的链接
var res_link;
var id; //资源id
- var sendType; //发送到课程 1 发送到项目 2
+ var sendType = '1'; //发送到课程 1 发送到项目 2
var lastSendType; //保存上次发送的发送类型
$("#resources_list").mousedown(function(e) {
//如果是右键的话
@@ -309,15 +309,15 @@
document.oncontextmenu = function() {return true;}
line.children().css("background-color",'white');
id = line.children().last().html();
- if (lastSendType === '1'){ //如果已经发送过一次了,那么就应该沿用上次发送的类型。
+ if (lastSendType === '2'){ //如果已经发送过一次了,那么就应该沿用上次发送的类型。
$.ajax({
type: 'get',
- url: '<%= search_user_course_user_path(@user)%>' + '?send_id=' + id
+ url: '<%= search_user_project_user_path(@user)%>' + '?send_id=' + id
});
}else{
$.ajax({
type: 'get',
- url: '<%= search_user_project_user_path(@user)%>' + '?send_id=' + id
+ url: '<%= search_user_course_user_path(@user)%>' + '?send_id=' + id
});
}
}
@@ -327,16 +327,17 @@
alert('暂时不支持多页选择,您当前页没有选择任何资源');
return ;
}
- if (lastSendType === '1'){ //如果已经发送过一次了,那么就应该沿用上次发送的类型。
+ if (lastSendType === '2'){ //如果已经发送过一次了,那么就应该沿用上次发送的类型。
$.ajax({
type: 'get',
- url: '<%= search_user_course_user_path(@user)%>' + '?'+ $("#resources_list_form").serialize()
+ url: '<%= search_user_project_user_path(@user)%>' + '?' + $("#resources_list_form").serialize()
});
}else{
$.ajax({
type: 'get',
- url: '<%= search_user_project_user_path(@user)%>' + '?' + $("#resources_list_form").serialize()
+ url: '<%= search_user_course_user_path(@user)%>' + '?'+ $("#resources_list_form").serialize()
});
+
}
}
@@ -480,54 +481,36 @@
lastSendType = sendType;
}
- // var iWidth = document.documentElement.clientWidth;
- // var iHeight = document.documentElement.clientHeight;
- // var moveX = 0;
- // var moveY = 0;
- // var moveTop = 0;
- // var moveLeft = 0;
- // var moveable = false;
- // var docMouseMoveEvent = document.onmousemove;
- // var docMouseUpEvent = document.onmouseup;
- // $("#upload_box").mousedown(function() {
- // var evt = getEvent();
- // moveable = true;
- // moveX = evt.clientX;
- // moveY = evt.clientY;
- //
- // moveTop = parseInt($("#upload_box").css('top'));
- // moveLeft = parseInt($("#upload_box").css('left'));
- //
- // $(document).mousemove( function() {
- // if (moveable) {
- // var evt = getEvent();
- // var x = moveLeft + evt.clientX - moveX;
- // var y = moveTop + evt.clientY - moveY;
- // if ( x > 0 &&( x + 322 < iWidth) && y > 0 && (y + 257 < iHeight) ) {
- // $("#upload_box").css('left', x + "px");
- // $("#upload_box").css('top', y + "px");
- // console.log( moveX)
- // console.log( moveY)
- // }
- // }
- // });
- // $(document).mouseup (function () {
- // if (moveable) {
- // document.onmousemove = docMouseMoveEvent;
- // document.onmouseup = docMouseUpEvent;
- // moveable = false;
- // moveX = 0;
- // moveY = 0;
- // moveTop = 0;
- // moveLeft = 0;
- // }
- // });
- // });
- //
- // // 获得事件Event对象,用于兼容IE和FireFox
- // function getEvent() {
- // return window.event || arguments.callee.caller.arguments[0];
- // }
+
+ function observeSearchfieldOnInput(fieldId, url,send_id,send_ids) {
+ $('#'+fieldId).each(function() {
+ var $this = $(this);
+ $this.addClass('autocomplete');
+ $this.attr('data-value-was', $this.val());
+ var check = function() {
+ var val = $this.val();
+ if ($this.attr('data-value-was') != val){
+ $this.attr('data-value-was', val);
+ $.ajax({
+ url: url,
+ type: 'get',
+ data: {search: $this.val(),send_id:send_id,send_ids:send_ids},
+ success: function(data){ },
+ beforeSend: function(){ $this.addClass('ajax-loading'); },
+ complete: function(){ $this.removeClass('ajax-loading'); }
+ });
+ }
+ };
+ var reset = function() {
+ if (timer) {
+ clearInterval(timer);
+ timer = setInterval(check, 300);
+ }
+ };
+ var timer = setInterval(check, 300);
+ $this.bind('keyup click mousemove', reset);
+ });
+ }
diff --git a/app/views/welcome/_search_all_results.html.erb b/app/views/welcome/_search_all_results.html.erb
new file mode 100644
index 000000000..014c6b487
--- /dev/null
+++ b/app/views/welcome/_search_all_results.html.erb
@@ -0,0 +1,80 @@
+<% unless all_results.nil? || all_results.empty?%>
+<% all_results.each do |item|%>
+ <% case item.type %>
+ <% when 'user'%>
+
+ <% when 'course'%>
+
+ <% when 'attachment'%>
+
+ <% when 'project'%>
+
+ <%end %>
+<% end %>
+
+<% end %>
diff --git a/app/views/welcome/_search_attachment_results.html.erb b/app/views/welcome/_search_attachment_results.html.erb
new file mode 100644
index 000000000..36c4fcbab
--- /dev/null
+++ b/app/views/welcome/_search_attachment_results.html.erb
@@ -0,0 +1,24 @@
+<% unless attachments.nil? || attachments.empty?%>
+ <% attachments.each do |attachment|%>
+
+ <% end %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/welcome/_search_course_results.html.erb b/app/views/welcome/_search_course_results.html.erb
new file mode 100644
index 000000000..89567063d
--- /dev/null
+++ b/app/views/welcome/_search_course_results.html.erb
@@ -0,0 +1,24 @@
+<% unless courses.nil? || courses.empty?%>
+ <% courses.each do |course|%>
+
+
+ <%= link_to image_tag(url_to_avatar(Course.find(course.id)), :width => "75", :height => "75",:class=>'searchCourseImage'), course_path(course.id), :alt => "课程图片" %>
+
+
+
+
+
+
+ <% end %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/welcome/_search_project_results.html.erb b/app/views/welcome/_search_project_results.html.erb
new file mode 100644
index 000000000..b3ed44654
--- /dev/null
+++ b/app/views/welcome/_search_project_results.html.erb
@@ -0,0 +1,24 @@
+<% unless projects.nil? || projects.empty?%>
+ <% projects.each do |project|%>
+
+
+
+ <%= link_to image_tag(url_to_avatar(Project.find(project.id)), :width => "75", :height => "75",:class=>'searchCourseImage'), project_path(project.id), :alt => "项目图片" %>
+
+
+
+
+
+
+ <% end %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/welcome/_search_user_results.html.erb b/app/views/welcome/_search_user_results.html.erb
new file mode 100644
index 000000000..459d3a27b
--- /dev/null
+++ b/app/views/welcome/_search_user_results.html.erb
@@ -0,0 +1,24 @@
+<% unless users.nil? || users.empty?%>
+<% users.each do |user|%>
+
+
+
+ <%= link_to image_tag(url_to_avatar(User.find(user.id)), :width => "75", :height => "75",:class=>'searchCourseImage'), user_path(user.id), :alt => "用户头像" %>
+
+
+
+
+
+
+<% end %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/views/welcome/search.html.erb b/app/views/welcome/search.html.erb
new file mode 100644
index 000000000..c25d7bfb1
--- /dev/null
+++ b/app/views/welcome/search.html.erb
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+ <%#= render :partial => 'search_user_results',:locals => {:users=>@users}%>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/views/welcome/search.js.erb b/app/views/welcome/search.js.erb
new file mode 100644
index 000000000..c53c5d219
--- /dev/null
+++ b/app/views/welcome/search.js.erb
@@ -0,0 +1,13 @@
+<% case @search_type%>
+<% when 'all'%>
+$("#searchContent_1").html('<%= escape_javascript(render :partial => 'search_all_results',:locals => {:all_results=> @alls})%>');
+<% when 'user'%>
+$("#searchContent_2").html('<%= escape_javascript(render :partial => 'search_user_results',:locals => {:users=>@users})%>');
+<% when 'course'%>
+$("#searchContent_3").html('<%= escape_javascript(render :partial => 'search_course_results',:locals => {:courses=>@courses})%>');
+<% when 'project'%>
+$("#searchContent_5").html('<%= escape_javascript(render :partial => 'search_project_results',:locals => {:projects=>@projects})%>');
+<% when 'attachment'%>
+$("#searchContent_4").html('<%= escape_javascript(render :partial => 'search_attachment_results',:locals => {:attachments=>@attachments})%>');
+<%else%>
+<%end %>
\ No newline at end of file
diff --git a/config/application.rb b/config/application.rb
index 6e4a2983a..9e6d41abe 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -2,7 +2,7 @@ require File.expand_path('../boot', __FILE__)
require 'rails/all'
require 'sprockets/railtie'
-
+require 'elasticsearch/model'
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
@@ -73,6 +73,17 @@ module RedmineApp
end
config.after_initialize do
+ if RbConfig::CONFIG['target_os'] == 'mingw32'
+ Elasticsearch::Client.new hosts: ['localhost:9200'], retry_on_failure: true,log:true
+ elsif RbConfig::CONFIG['target_os'] == 'linux' && ["fast76"].include?(`hostname`.gsub("\n",""))
+ Elasticsearch::Client.new hosts: ['localhost:9200'], retry_on_failure: true,log:true
+ elsif RbConfig::CONFIG['target_os'] == 'linux' && ["testtrustie11","agent12"].include?(`hostname`.gsub("\n",""))
+ Elasticsearch::Client.new hosts: ['localhost:9200','192.168.80.11:9200','192.168.80.12:9200'], retry_on_failure: true
+ elsif RbConfig::CONFIG['target_os'] == 'linux' && ["trustie168","trustieserver14","trustieserver16","Trustie18"].include?(`hostname`.gsub("\n",""))
+ Elasticsearch::Client.new hosts: ['localhost:9200','192.168.80.168:9200'], retry_on_failure: true
+ else
+ Elasticsearch::Client.new hosts: ['localhost:9200'], retry_on_failure: true
+ end
end
if File.exists?(File.join(File.dirname(__FILE__), 'additional_environment.rb'))
diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb
index 1f07c0af5..5d1c9b6ad 100644
--- a/config/initializers/kaminari_config.rb
+++ b/config/initializers/kaminari_config.rb
@@ -23,10 +23,10 @@
Kaminari.configure do |config|
# config.default_per_page = 25
# config.max_per_page = nil
- config.window = 0
+ config.window = 1
# config.outer_window = 3
- # config.left = 2
- # config.right = 2
+ config.left = 2
+ config.right = 2
# config.page_method_name = :page
# config.param_name = :page
end
diff --git a/config/locales/mailers/zh.yml b/config/locales/mailers/zh.yml
index 1d432cbff..7b56011b1 100644
--- a/config/locales/mailers/zh.yml
+++ b/config/locales/mailers/zh.yml
@@ -26,6 +26,6 @@ zh:
mail_attention: "请您关注!"
mail_homework_endtime: "作业截止时间快到了!"
mail_homework: "作业:"
- mail_anonymous_comment_close: "作业匿评已经关闭!"
- mail_anonymous_comment_open: "作业匿评已经开启!"
- mail_anonymous_comment_failed: "作业匿评开启失败!"
\ No newline at end of file
+ mail_anonymous_comment_close: "作业匿评已经关闭,请您关注!"
+ mail_anonymous_comment_open: "作业匿评已经开启,请您关注!"
+ mail_anonymous_comment_failed: "作业匿评开启失败,请您关注!"
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 27e9d7861..4e64ca505 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -109,7 +109,7 @@ RedmineApp::Application.routes.draw do
resources :homework_users
resources :no_uses
delete 'no_uses', :to => 'no_uses#delete'
-
+ match 'site_search', :to => 'users#site_search', :as => 'site_search', :via => [:get, :post, :put]
resources :apply_project_masters
delete 'apply_project_masters', :to => 'apply_project_masters#delete'
@@ -211,11 +211,14 @@ RedmineApp::Application.routes.draw do
resources :student_work do
member do
post 'add_score'
+ post 'revise_attachment'
+ get 'retry_work'
get 'praise_student_work'
get 'forbidden_anonymous_comment'
end
collection do
post 'add_score_reply'
+ get 'delete_work'
get 'destroy_score_reply'
get 'student_work_absence_penalty'
get 'absence_penalty_list'
@@ -502,6 +505,11 @@ RedmineApp::Application.routes.draw do
end
end
end
+ resources :blog_comments do
+ collection do
+ get :search
+ end
+ end
match 'users/:id/user_newfeedback', :to => 'users#user_newfeedback', :via => :get, :as => "feedback"
match 'users/:id/user_projects', :to => 'users#user_projects', :via => :get
#消息
diff --git a/db/migrate/20151130031446_add_index_to_homework_commons.rb b/db/migrate/20151130031446_add_index_to_homework_commons.rb
new file mode 100644
index 000000000..f0a0b86d5
--- /dev/null
+++ b/db/migrate/20151130031446_add_index_to_homework_commons.rb
@@ -0,0 +1,5 @@
+class AddIndexToHomeworkCommons < ActiveRecord::Migration
+ def change
+ add_index :homework_commons, [:course_id, :id]
+ end
+end
diff --git a/db/migrate/20151130033906_add_index_to_student_works.rb b/db/migrate/20151130033906_add_index_to_student_works.rb
new file mode 100644
index 000000000..2f990f5a7
--- /dev/null
+++ b/db/migrate/20151130033906_add_index_to_student_works.rb
@@ -0,0 +1,5 @@
+class AddIndexToStudentWorks < ActiveRecord::Migration
+ def change
+ add_index :student_works, [:homework_common_id, :user_id]
+ end
+end
diff --git a/db/migrate/20151203030635_add_attachment_type.rb b/db/migrate/20151203030635_add_attachment_type.rb
new file mode 100644
index 000000000..2c41aa5f2
--- /dev/null
+++ b/db/migrate/20151203030635_add_attachment_type.rb
@@ -0,0 +1,9 @@
+# encoding: utf-8
+class AddAttachmentType < ActiveRecord::Migration
+ def up
+ Attachmentstype.create(typeId:3,typeName:'修订附件')
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20151203072815_add_forked_from_project_id_to_projects.rb b/db/migrate/20151203072815_add_forked_from_project_id_to_projects.rb
new file mode 100644
index 000000000..f679eaecd
--- /dev/null
+++ b/db/migrate/20151203072815_add_forked_from_project_id_to_projects.rb
@@ -0,0 +1,5 @@
+class AddForkedFromProjectIdToProjects < ActiveRecord::Migration
+ def change
+ add_column :projects, :forked_from_project_id, :integer
+ end
+end
diff --git a/db/migrate/20151204062220_add_forked_count_to_projects.rb b/db/migrate/20151204062220_add_forked_count_to_projects.rb
new file mode 100644
index 000000000..79fdc2573
--- /dev/null
+++ b/db/migrate/20151204062220_add_forked_count_to_projects.rb
@@ -0,0 +1,5 @@
+class AddForkedCountToProjects < ActiveRecord::Migration
+ def change
+ add_column :projects, :forked_count, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 55a97ee20..6cc6b90c4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20151126160252) do
+ActiveRecord::Schema.define(:version => 20151204062220) do
create_table "activities", :force => true do |t|
t.integer "act_id", :null => false
@@ -543,26 +543,23 @@ ActiveRecord::Schema.define(:version => 20151126160252) do
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
+ create_table "dts", :force => true do |t|
+ t.string "IPLineCode"
t.string "Description"
- t.text "PreConditions", :limit => 2147483647
- t.text "TraceInfo", :limit => 2147483647
- t.text "Code", :limit => 2147483647
+ t.string "Num"
+ t.string "Variable"
+ t.string "TraceInfo"
+ t.string "Method"
+ t.string "File"
+ t.string "IPLine"
+ t.string "Review"
+ t.string "Category"
+ t.string "Defect"
+ t.string "PreConditions"
+ t.string "StartLine"
t.integer "project_id"
- t.datetime "created_at"
- t.datetime "updated_at"
- t.integer "id", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
end
create_table "enabled_modules", :force => true do |t|
@@ -736,6 +733,8 @@ ActiveRecord::Schema.define(:version => 20151126160252) do
t.integer "anonymous_comment", :default => 0
end
+ add_index "homework_commons", ["course_id", "id"], :name => "index_homework_commons_on_course_id_and_id"
+
create_table "homework_detail_manuals", :force => true do |t|
t.float "ta_proportion"
t.integer "comment_status"
@@ -892,6 +891,16 @@ ActiveRecord::Schema.define(:version => 20151126160252) do
add_index "journal_details", ["journal_id"], :name => "journal_details_journal_id"
+ create_table "journal_details_copy", :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_copy", ["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"
@@ -961,6 +970,7 @@ ActiveRecord::Schema.define(:version => 20151126160252) do
t.integer "course_group_id", :default => 0
end
+ add_index "members", ["course_id"], :name => "index_members_on_course_id"
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"
@@ -1294,27 +1304,29 @@ ActiveRecord::Schema.define(:version => 20151126160252) do
end
create_table "projects", :force => true do |t|
- t.string "name", :default => "", :null => false
+ t.string "name", :default => "", :null => false
t.text "description"
- t.string "homepage", :default => ""
- t.boolean "is_public", :default => true, :null => false
+ 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 "status", :default => 1, :null => false
t.integer "lft"
t.integer "rgt"
- t.boolean "inherit_members", :default => false, :null => false
+ 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.boolean "hidden_repo", :default => false, :null => false
+ t.integer "attachmenttype", :default => 1
t.integer "user_id"
- t.integer "dts_test", :default => 0
+ 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"
end
add_index "projects", ["lft"], :name => "index_projects_on_lft"
@@ -1506,6 +1518,8 @@ ActiveRecord::Schema.define(:version => 20151126160252) do
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"
diff --git a/lib/gitlab-cli/lib/gitlab/client/projects.rb b/lib/gitlab-cli/lib/gitlab/client/projects.rb
index 3fab4347f..8d91edd06 100644
--- a/lib/gitlab-cli/lib/gitlab/client/projects.rb
+++ b/lib/gitlab-cli/lib/gitlab/client/projects.rb
@@ -241,8 +241,9 @@ class Gitlab::Client
# Forks a project into the user namespace of the authenticated user.
# @param [Integer] - The ID of the project to be forked
- def fork(id)
- post("/projects/fork/#{id}")
+ def fork(gpid, gid)
+ post ("/projects/fork/#{gpid}?user_id=#{gid}")
+ # post("/projects/fork/#{id}")
end
# Mark this project as forked from the other
diff --git a/lib/tasks/elasticsearch.rake b/lib/tasks/elasticsearch.rake
new file mode 100644
index 000000000..1242abc60
--- /dev/null
+++ b/lib/tasks/elasticsearch.rake
@@ -0,0 +1 @@
+require 'elasticsearch/rails/tasks/import'
\ No newline at end of file
diff --git a/lib/tasks/elasticsearch_batch_op.rake b/lib/tasks/elasticsearch_batch_op.rake
new file mode 100644
index 000000000..fb2c638bc
--- /dev/null
+++ b/lib/tasks/elasticsearch_batch_op.rake
@@ -0,0 +1,31 @@
+namespace :importer do
+ task :importuser do
+ ENV['CLASS']='User'
+ ENV['SCOPE']='indexable'
+ ENV['FORCE']='y'
+ ENV['BATCH']='1000'
+ Rake::Task["elasticsearch:import:model"].invoke
+ end
+ task :importproject do
+
+ ENV['CLASS']='Project'
+ ENV['SCOPE']='indexable'
+ ENV['FORCE']='y'
+ ENV['BATCH']='1000'
+ Rake::Task["elasticsearch:import:model"].invoke
+ end
+ task :importcourse do
+ ENV['CLASS']='Course'
+ ENV['SCOPE']='indexable'
+ ENV['FORCE']='y'
+ ENV['BATCH']='1000'
+ Rake::Task["elasticsearch:import:model"].invoke
+ end
+ task :importattachment do
+ ENV['CLASS']='Attachment'
+ ENV['SCOPE']='indexable'
+ ENV['FORCE']='y'
+ ENV['BATCH']='1000'
+ Rake::Task["elasticsearch:import:model"].invoke
+ end
+end
\ No newline at end of file
diff --git a/lib/tasks/exercise_close_to_deadline_warn.rake b/lib/tasks/exercise_close_to_deadline_warn.rake
new file mode 100644
index 000000000..e2808818f
--- /dev/null
+++ b/lib/tasks/exercise_close_to_deadline_warn.rake
@@ -0,0 +1,21 @@
+#coding=utf-8
+#需要在0点以后执行
+namespace :exercise_deadline_warn do
+ desc "exercise deadline warn"
+ task :deadline_warn => :environment do
+ #exercise_status 1 未发布 2 已发布 3已截止
+ exercises = Exercise.where("exercise_status = 2 and date_format(end_time,'%Y-%m-%d')= '#{Date.today}'") #截止日期都是当天 23.59分,所以年月日相等的一定是今晚会截止的测验
+ exercises.each do |exercise|
+ course = exercise.course
+ course.members.each do |m|
+ #CourseMessage status 1 未发布 status 2 已发布 status 3 已发布快截止了
+ exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 3) unless m.user.allowed_to?(:as_teacher,m)
+ end
+ # if homework.course_acts.size == 0
+ # homework.course_acts << CourseActivity.new(:user_id => homework.user_id,:course_id => homework.course_id)
+ # end
+ # 邮件通知
+ #Mailer.run.homework_added(homework)
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/tasks/exercise_publish.rake b/lib/tasks/exercise_publish.rake
new file mode 100644
index 000000000..a27c6a6fb
--- /dev/null
+++ b/lib/tasks/exercise_publish.rake
@@ -0,0 +1,22 @@
+#coding=utf-8
+
+namespace :exercise_publish do
+ desc "publish exercise and end exercise"
+ task :publish => :environment do
+ exercises = Exercise.where("publish_time is not null and exercise_status = 1 and publish_time <=?",Time.now)
+ exercises.each do |exercise|
+ exercise.update_column('exercise_status', 2)
+ course = exercise.course
+ course.members.each do |m|
+ exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 2)
+ end
+ end
+ end
+
+ task :end => :environment do
+ exercises = Exercise.where("end_time <=? and exercise_status = 2",Time.now)
+ exercises.each do |exercise|
+ exercise.update_column('exercise_status', 3)
+ end
+ end
+end
diff --git a/lib/tasks/homework_evaluation.rake b/lib/tasks/homework_evaluation.rake
index bf5f32dfe..84082eb9b 100644
--- a/lib/tasks/homework_evaluation.rake
+++ b/lib/tasks/homework_evaluation.rake
@@ -60,7 +60,7 @@ namespace :homework_evaluation do
work_ids = "(" + homework_common.student_works.map(&:id).join(",") + ")"
homework_common.student_works.each do |student_work|
absence_penalty_count = student_work.user.student_works_evaluation_distributions.where("student_work_id IN #{work_ids}").count - student_work.user.student_works_scores.where("student_work_id IN #{work_ids}").count
- student_work.absence_penalty = absence_penalty_count > 0 ? absence_penalty_count * homework_detail_manuals.absence_penalty : 0
+ student_work.absence_penalty = absence_penalty_count > 0 ? absence_penalty_count * homework_detail_manual.absence_penalty : 0
student_work.save
end
homework_detail_manual.update_column('comment_status', 3)
diff --git a/lib/tasks/homework_publishtime.rake b/lib/tasks/homework_publishtime.rake
index 8e231fafd..5eaeb37cb 100644
--- a/lib/tasks/homework_publishtime.rake
+++ b/lib/tasks/homework_publishtime.rake
@@ -22,7 +22,7 @@ namespace :homework_publishtime do
end
task :end => :environment do
- homework_commons = HomeworkCommon.where("end_time < '#{Date.today}'")
+ homework_commons = HomeworkCommon.where("end_time = '#{Date.today}'")
homework_commons.each do |homework|
if homework.anonymous_comment == 1
homework_detail_manual = homework.homework_detail_manual
diff --git a/lib/tasks/sync_gitlab_user.rake b/lib/tasks/sync_gitlab_user.rake
index c932ca36c..fb84f5f08 100644
--- a/lib/tasks/sync_gitlab_user.rake
+++ b/lib/tasks/sync_gitlab_user.rake
@@ -6,24 +6,30 @@ namespace :gitlab do
users = User.find_by_sql("select * from users where gid is null")
s = Trustie::Gitlab::Sync.new
g = Gitlab.client
+ logger = Logger.new('./log/add_gid.log', 'daily') #按天生成
users.each do |user|
- us = g.get("/users?search=#{user.mail}")
- puts user.mail
- if us.blank?
- puts "55555555555555555"
- s.sync_user(user)
- else
- # 解决查询的时候出现多值的情况,比如:123@163.com和g123@163.com
- puts "66666666666666666666"
- puts user.id
- if Array === us
- us.each do |u|
- if u.email == user.mail
- user.gid = u.id
- user.save
+ begin
+ us = g.get("/users?search=#{user.mail}")
+ puts user.mail
+ if us.blank?
+ puts "55555555555555555"
+ s.sync_user(user)
+ else
+ # 解决查询的时候出现多值的情况,比如:123@163.com和g123@163.com
+ puts "66666666666666666666"
+ puts user.id
+ if Array === us
+ us.each do |u|
+ if u.email == user.mail
+ user.gid = u.id
+ user.save
+ end
end
end
end
+ rescue => e
+ logger.error("userid=#{user.id},mail=#{user.mail},login=#{user.login},error=#{e}")
+ puts e
end
end
end
diff --git a/lib/tasks/sync_sigle_rep.rake b/lib/tasks/sync_sigle_rep.rake
index e68e37ee8..57aaaabcb 100644
--- a/lib/tasks/sync_sigle_rep.rake
+++ b/lib/tasks/sync_sigle_rep.rake
@@ -9,7 +9,7 @@ namespace :sync_rep do
if project.repositories && project.repositories.count == 1 && project.repositories.first.type == "Repository::Git"
rep = project.repositories.first
count = Repository.find_by_sql("SELECT * FROM `repositories` where identifier = '#{rep.identifier}'").count
- puts count
+ puts project.id
unless count > 1
rep.identifier
s = Trustie::Gitlab::Sync.new
diff --git a/public/images/course/hwork_icon.png b/public/images/course/hwork_icon.png
new file mode 100644
index 000000000..82c78ac60
Binary files /dev/null and b/public/images/course/hwork_icon.png differ
diff --git a/public/images/course/right-arrow.png b/public/images/course/right-arrow.png
new file mode 100644
index 000000000..b152e9ce9
Binary files /dev/null and b/public/images/course/right-arrow.png differ
diff --git a/public/images/search_icon_03.png b/public/images/search_icon_03.png
new file mode 100644
index 000000000..15ff587eb
Binary files /dev/null and b/public/images/search_icon_03.png differ
diff --git a/public/javascripts/attachments.js b/public/javascripts/attachments.js
index d7b49c8be..b60b6ad28 100644
--- a/public/javascripts/attachments.js
+++ b/public/javascripts/attachments.js
@@ -154,6 +154,73 @@ function addFile(inputEl, file, eagerUpload,btnId) {
}
addFile.nextAttachmentId = 1;
+function addReviseFile(inputEl, file, eagerUpload,btnId) {
+
+ var attachments_frame = '#attachments_fields';
+ if ($(attachments_frame).children().length < 30) {
+ deleteallfiles = $(inputEl).data('deleteAllFiles');
+ var attachmentId = addFile.nextAttachmentId++;
+
+ var fileSpan = $('', {
+ 'id': 'attachments_' + attachmentId,
+ 'class': 'attachment'
+ });
+
+ fileSpan.append(
+ $(' ', {
+ 'type': 'text',
+ 'class': 'upload_filename readonly',
+ 'name': 'attachments[' + attachmentId + '][filename]',
+ 'readonly': 'readonly'
+ }).val(file.name),
+// $(' ', {
+// 'type': 'text',
+// 'class': 'description',
+// 'name': 'attachments[' + attachmentId + '][description]',
+// 'maxlength': 254,
+// 'placeholder': $(inputEl).data('descriptionPlaceholder')
+// }).toggle(!eagerUpload),
+// $('' + $(inputEl).data('fieldIsPublic') + ': ').attr({
+// 'class': 'ispublic-label'
+// }),
+// $(' ', {
+// 'type': 'checkbox',
+// 'class': 'is_public_checkbox',
+// 'value': 1,
+// 'name': 'attachments[' + attachmentId + '][is_public_checkbox]',
+// checked: 'checked'
+// }).toggle(!eagerUpload),
+ $('  ').attr({
+ 'href': "#",
+ 'class': 'remove-upload'
+ }).click(function() {
+ if (confirm($(inputEl).data('areYouSure'))) {
+ removeReviseFile();
+ if (!eagerUpload) {
+ (function(e) {
+ reload(e);
+ })(fileSpan);
+ }
+ }
+
+ }).toggle(!eagerUpload),
+ $('', {
+ 'class': 'div_attachments',
+ 'name': 'div_' + 'attachments_' + attachmentId
+ })
+ ).appendTo('#attachments_fields');
+
+ $("#uploadReviseBox").addClass('disable_link');
+ $("#choose_revise_attach").attr("onclick","return false;");
+
+ if (eagerUpload) {
+ ajaxUpload(file, attachmentId, fileSpan, inputEl,btnId);
+ }
+ return attachmentId;
+ }
+ return null;
+}
+
function ajaxUpload(file, attachmentId, fileSpan, inputEl,btnId) {
//上传开始调用函数
function onLoadstart(e) {
@@ -293,6 +360,13 @@ function removeFile() {
return false;
}
+function removeReviseFile() {
+ $(this).parent('span').remove();
+ $("#uploadReviseBox").removeClass('disable_link');
+ $("#choose_revise_attach").attr("onclick","_file.click();");
+ return false;
+}
+
//gcm delete all file
//modify by yutao 2015-5-14 ��1��ҳ����ڶ���ϴ��ؼ�ʱ�˿�������bug �ʸ�֮ start
function removeAll(containerid) {
@@ -346,6 +420,30 @@ function uploadBlob(blob, uploadUrl, attachmentId, options) {
});
}
+function addReviseInputFiles(inputEl,btnId) {
+ // var clearedFileInput = $(inputEl).clone().val('');
+ if (inputEl.files) {
+ uploadAndAttachReviseFiles(inputEl.files, inputEl,btnId);
+ // $(inputEl).remove();
+ } else {
+ // browser not supporting the file API, upload on form submission
+ var attachmentId;
+ var aFilename = inputEl.value.split(/\/|\\/);
+ var count = $('#attachments_fields>span').length;
+ attachmentId = addReviseFile(inputEl, {
+ name: aFilename[aFilename.length - 1]
+ }, false);
+ if (attachmentId) {
+ $(inputEl).attr({
+ name: 'attachments[' + attachmentId + '][file]'
+ }).hide();
+ if (count <= 0) count = 1;
+ }
+ }
+
+ //clearedFileInput.insertAfter('#attachments_fields');
+}
+
function addInputFiles(inputEl,btnId) {
// var clearedFileInput = $(inputEl).clone().val('');
if (inputEl.files) {
@@ -405,6 +503,26 @@ function addInputFiles_board(inputEl, id,btnId) {
//clearedFileInput.insertAfter('#attachments_fields');
}
+function uploadAndAttachReviseFiles(files, inputEl,btnId) {
+
+ var maxFileSize = $(inputEl).data('max-file-size');
+ var maxFileSizeExceeded = $(inputEl).data('max-file-size-message');
+
+ var sizeExceeded = false;
+ $.each(files, function() {
+ if (this.size && maxFileSize != null && this.size > parseInt(maxFileSize)) {
+ sizeExceeded = true;
+ }
+ });
+ if (sizeExceeded) {
+ window.alert(maxFileSizeExceeded);
+ } else {
+ $.each(files, function() {
+ addReviseFile(inputEl, this, true,btnId);
+ });
+ }
+}
+
function uploadAndAttachFiles(files, inputEl,btnId) {
var maxFileSize = $(inputEl).data('max-file-size');
diff --git a/public/javascripts/blog.js b/public/javascripts/blog.js
index feaab0100..65dbfecba 100644
--- a/public/javascripts/blog.js
+++ b/public/javascripts/blog.js
@@ -34,7 +34,7 @@ function submit_article()
function regexTopicDescription()
{
var name = message_content_editor.html();
- if(name.length ==0)
+ if(message_content_editor.isEmpty())
{
$("#message_content_span").text("描述不能为空");
$("#message_content_span").css('color','#ff0000');
@@ -55,7 +55,7 @@ function regexTopicDescription()
function MessageReplayVevify() {
var content = message_content_editor.html();//$.trim($("#message_content").val());
- if (content.length == 0) {
+ if (message_content_editor.isEmpty()) {
$("#message_content_span").text("回复不能为空");
$("#message_content_span").css('color', '#ff0000');
return false;
diff --git a/public/javascripts/homework.js b/public/javascripts/homework.js
index f1b6e1814..468548179 100644
--- a/public/javascripts/homework.js
+++ b/public/javascripts/homework.js
@@ -19,7 +19,7 @@ $(function(){
return false;
}
return true;
- }
+ };
var test_program = function(cb){
var homework_id = $('#test-program-btn').attr('data-homework-id');
@@ -171,7 +171,7 @@ $(function(){
$("input[name=homework_type]").after(html);
}
return valid;
- }
+ };
$("#BluePopupBox a.BlueCirBtn").live('click', function(){
if(saveProgramAnswers()){
diff --git a/public/stylesheets/courses.css b/public/stylesheets/courses.css
index 2fb32e2d0..54e550426 100644
--- a/public/stylesheets/courses.css
+++ b/public/stylesheets/courses.css
@@ -1175,4 +1175,42 @@ a:hover.testEdit{ background:url(images/icons.png) -21px -272px no-repeat;}
.rankList li p {width:100%; overflow:hidden; white-space:normal; 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;}
+.font_cus {font-family: "微软雅黑","宋体"; font-size: 12px; line-height: 1.5;}
+/*20151130课程项目集成Tim*/
+a.testBtn{background: url(/images/course/hwork_icon.png) -2px -5px no-repeat !important; height:20px; display:block; padding-left:20px; color:#888888; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a:hover.testBtn{background: url(/images/course/hwork_icon.png) -81px -5px no-repeat !important; color:#3598db; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a.groupBtn{ background: url(/images/course/hwork_icon.png) -2px -61px no-repeat !important; height:20px; display:block; padding-left:20px; color:#888888; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a:hover.groupBtn{background: url(/images/course/hwork_icon.png) -80px -61px no-repeat !important; color:#3598db; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+.markInput { outline:none; border:1px solid #e6e6e6; height:30px; width:50px; color:#3d3c3c; margin-right:5px; text-align:center; padding-left:0px;}
+.groupPopUp {width:290px; height:auto; padding:15px; background-color:#ffffff; z-index:1000; position:relative;}
+.popClose {background:url(/images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block; position: absolute; z-index: 1000; right:2px; top:3px;}
+a.memberBtn{ background: url(/images/course/hwork_icon.png) -7px -90px no-repeat !important; height:20px; display:block; padding-left:20px; color:#888888; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a:hover.memberBtn{background: url(/images/course/hwork_icon.png) -80px -90px no-repeat !important; color:#3598db; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+.addMemberC {float:left; max-height:150px; margin-bottom:10px; overflow:auto; overflow-x:hidden; width:227px; background-color:#f1f1f1; min-height:150px; padding-top:10px;}
+.addMemberC li {padding-left:10px; line-height:18px;}
+.addMemberC li:hover {cursor:pointer; background-color:#cccccc;}
+.addMemberCP {width:514px; height:auto; border:3px solid #269ac9; padding-left:16px; padding-bottom:16px; background-color:#ffffff; position:absolute; z-index:1000;}
+.rightArrow {margin:50px 15px 0px 15px; float:left;}
+.relateText {font-size:16px; color:#269ac9; line-height:16px; padding-top:20px; display:inline-block; font-weight: bold;}
+
+.resubAtt {border-top:1px solid #dddddd; position:relative; margin-top:15px;}
+.resubTitle {position:absolute; top:-10px; left:5px; background-color:#ffffff; display:block; font-weight:bold; padding:0px 2px;}
+a.blueCir{ display:inline-block; padding:2px 5px; background-color:#ffffff;border:1px solid #3598db; color:#3598db; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px;}
+a:hover.blueCir{ background:#3598db; color:#fff;}
+
+/*上传资源弹窗*/
+.resourceUploadPopup {width:400px; height:auto; border:3px solid #269ac9 !important; padding-left:16px; padding-bottom:16px; background-color:#ffffff; position:absolute; top:50%; left:50%; margin-left:-200px; z-index:1000;}
+.uploadDialogText {font-size:16px; color:#269ac9; line-height:16px; padding-top:20px; width:140px; display:inline-block; font-weight: bold;}
+.uploadBoxContainer {height:33px; line-height:33px; margin-top:10px; position:relative}
+.uploadBox {width:100px; height:33px; line-height:33px; text-align:center; vertical-align:middle; background-color:#269ac9; border-radius:3px; float:left; margin-right:12px;}
+a.uploadBoxIcon {background:url(images/resource_icon_list.png) -35px 10px no-repeat; float:left; display:block; width:81px; height:30px; padding-left:22px; font-size:14px; color:#ffffff;}
+a.uploadIcon {background:url(images/resource_icon_list.png) 8px -60px no-repeat; width:100px; height:33px;}
+.chooseFile {color:#ffffff; display:block; margin-left:32px;}
+.uploadResourceIntr {width:250px; height:33px; float:left; line-height:33px; font-size:12px;}
+.uploadResourceName {width:250px; display:inline-block; line-height:15px; font-size:12px; color:#444444; margin-bottom:2px;}
+.uploadResourceIntr2 {width:250px; display:inline-block; line-height:15px; font-size:12px; color:#444444;}
+.uploadType {margin:10px 0; border:1px solid #e6e6e6; width:100px; height:30px; outline:none; font-size:12px; color:#888888;}
+.uploadKeyword {margin-bottom:10px; outline:none; border:1px solid #e6e6e6; height:30px; width:280px;}
+.mb10 {margin-bottom: 10px}
+.mb15 {margin-bottom: 15px}
+div.disable_link {background-color: #c1c1c1 !important;}
\ No newline at end of file
diff --git a/public/stylesheets/new_user.css b/public/stylesheets/new_user.css
index 01e149bfb..ad07259d3 100644
--- a/public/stylesheets/new_user.css
+++ b/public/stylesheets/new_user.css
@@ -1329,3 +1329,39 @@ a:hover.link_file_a{ background:url(../images/pic_file.png) 0 -25px no-repeat; c
span.author { font-size: 0.9em; color: #888; }
.ReplyToMessageInputContainer {width: 582px;float: left;}
+/*全站搜索*/
+.blocks {padding:15px; background-color:#ffffff; border:1px solid #dddddd;}
+#searchBanner {border-bottom:1px solid #d0d0d0;}
+#searchBanner li {float:left; width:88px; margin-right:3px; text-align:center; padding-bottom:10px; font-weight:bold;}
+#searchTips {padding:10px 5px; background-color:#f5f6f7;}
+.searchBannerActive {border-bottom:3px solid #3498db !important;}
+.searchBannerNormal {border-bottom:none !important;}
+.searchContent {min-height:74px; border-bottom:1px solid #ededed; padding:13px 0px;}
+.searchCourseware {min-height:44px; border-bottom:1px solid #ededed; padding:13px 0px; width:968px;}
+.searchCourseImage {width:75px; margin-right:10px;}
+.searchContentDes {width:883px;}
+.searchTag {font-size:12px; color:#ffffff; background-color:#7ec8e4; height:16px; min-height:16px; max-height:16px; float:left; line-height:16px; padding:0px 3px;}
+.undis {display:none;}
+.dis {display:inline-block;}
+.numRed {color:#FF6600;}
+.pageRoll {float:right; border-left:1px solid #dddddd; margin-top:15px;}
+.pageCell {border:1px solid #dddddd; padding:5px 12px; float:left; margin-left:-1px; position:relative;}
+.pageCell:hover {border:1px solid #3498db; z-index:10;}
+.pageCellActive {background-color:#3498db; border:1px solid #3498db !important; position:relative; color:#ffffff;}
+
+/*20151130课程项目集成Tim*/
+a.testBtn{background: url(/images/course/hwork_icon.png) -2px -5px no-repeat !important; height:20px; display:block; padding-left:20px; color:#888888; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a:hover.testBtn{background: url(/images/course/hwork_icon.png) -81px -5px no-repeat !important; color:#3598db; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a.groupBtn{ background: url(/images/course/hwork_icon.png) -2px -61px no-repeat !important; height:20px; display:block; padding-left:20px; color:#888888; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a:hover.groupBtn{background: url(/images/course/hwork_icon.png) -80px -61px no-repeat !important; color:#3598db; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+.markInput { outline:none; border:1px solid #e6e6e6; height:30px; width:50px; color:#3d3c3c; margin-right:5px; text-align:center; padding-left:0px;}
+.groupPopUp {width:290px; height:auto; padding:15px; background-color:#ffffff; z-index:1000; position:relative;}
+.popClose {background:url(/images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block; position: absolute; z-index: 1000; right:2px; top:3px;}
+a.memberBtn{ background: url(/images/course/hwork_icon.png) -7px -90px no-repeat !important; height:20px; display:block; padding-left:20px; color:#888888; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+a:hover.memberBtn{background: url(/images/course/hwork_icon.png) -80px -90px no-repeat !important; color:#3598db; -moz-transition :all 0s linear 0s; -webkit-transition :all 0s linear 0s; -o-transition:all 0s linear 0s; transition:all 0s linear 0s;}
+.addMemberC {float:left; max-height:150px; margin-bottom:10px; overflow:auto; overflow-x:hidden; width:227px; background-color:#f1f1f1; min-height:150px; padding-top:10px;}
+.addMemberC li {padding-left:10px; line-height:18px;}
+.addMemberC li:hover {cursor:pointer; background-color:#cccccc;}
+.addMemberCP {width:514px; height:auto; border:3px solid #269ac9; padding-left:16px; padding-bottom:16px; background-color:#ffffff; position:absolute; z-index:1000;}
+.rightArrow {margin:50px 15px 0px 15px; float:left;}
+.relateText {font-size:16px; color:#269ac9; line-height:16px; padding-top:20px; display:inline-block; font-weight: bold;}
diff --git a/public/stylesheets/public.css b/public/stylesheets/public.css
index a1dfe3f4d..70aad2cbe 100644
--- a/public/stylesheets/public.css
+++ b/public/stylesheets/public.css
@@ -410,7 +410,7 @@ a:hover.search_btn{ background: #0fa9bb;}
.resourcesSendTo {float:left; height:20px; margin-top:15px;}
.resourcesSendType {border:1px solid #e6e6e6; width:60px; height:24px; outline:none; font-size:14px; color:#888888;}
.resourcePopupClose {width:20px; height:20px; display:inline-block; float:right;}
-.resourceClose {background:url(../images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block;}
+.resourceClose {background:url(images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block; position: absolute; z-index: 1000;}
.resourcesSearchBox {border:1px solid #e6e6e6; width:225px; height:25px; background-color:#ffffff; margin-top:12px; margin-bottom:15px;}
.searchResourcePopup {border:none; outline:none; background-color:#ffffff; width:184px; height:25px; padding-left:10px; display:inline-block; float:left;}
.courseSend {width:260px; height:15px; line-height:15px; margin-bottom:10px;}
diff --git a/public/stylesheets/public_new.css b/public/stylesheets/public_new.css
index db2d021d9..c60adf460 100644
--- a/public/stylesheets/public_new.css
+++ b/public/stylesheets/public_new.css
@@ -566,7 +566,7 @@ a.uploadIcon {background:url(images/resource_icon_list.png) 8px -60px no-repeat;
.resourceSharePopup {width:300px; height:auto; border:3px solid #15bccf; padding-left:16px; padding-bottom:16px; background-color:#ffffff; position:absolute; top:50%; left:50%; margin-left:-150px; z-index:1000;}
.sendText {font-size:16px; color:#15bccf; line-height:16px; padding-top:20px; width:100px; display:inline-block;}
.resourcePopupClose {width:20px; height:20px; display:inline-block; float:right;}
-.resourceClose {background:url(images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block;}
+.resourceClose {background:url(images/resource_icon_list.png) 0px -40px no-repeat; width:20px; height:20px; display:inline-block; position: absolute; z-index: 1000;}
.resourcesSearchBox {border:1px solid #e6e6e6; width:225px; height:25px; background-color:#ffffff; margin-top:12px; margin-bottom:15px;}
.searchResourcePopup {border:none; outline:none; background-color:#ffffff; width:184px; height:25px; padding-left:10px; display:inline-block; float:left;}
.searchIconPopup{width:31px; height:25px; background-color:#ffffff; background:url(images/resource_icon_list.png) -40px -18px no-repeat; display:inline-block; float:left;}