diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb
index a44b58789..25536615a 100644
--- a/app/controllers/admin_controller.rb
+++ b/app/controllers/admin_controller.rb
@@ -395,4 +395,74 @@ class AdminController < ApplicationController
end
+ #留言列表
+ def leave_messages
+ @jour = JournalsForMessage.where("jour_type = 'Principal' or jour_type = 'Course'").reorder('created_on desc')
+ case params[:format]
+ when 'xml', 'json'
+ @offset, @limit = api_offset_and_limit({:limit => 30})
+ else
+ @limit = 30#per_page_option
+ end
+
+ @jour_count = @jour.count
+ @jour_pages = Paginator.new @jour_count, @limit, params['page']
+ @offset ||= @jour_pages.offset
+ @jour = @jour.limit(@limit).offset(@offset).all
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ #帖子
+ def messages_list
+ @memo = Memo.reorder("created_at desc")
+
+=begin
+ case params[:format]
+ when 'xml', 'json'
+ @offset, @limit = api_offset_and_limit({:limit => 30})
+ else
+ @limit = 30#per_page_option
+ end
+
+ @memo_count = @memo.count
+ @memo_pages = Paginator.new @memo_count, @limit, params['page']
+ @offset ||= @memo_pages.offset
+ @memo = @memo.limit(@limit).offset(@offset).all
+=end
+
+ respond_to do |format|
+ format.html
+ end
+ end
+
+ #课程讨论区的帖子
+ def course_messages
+ #@boards=Board.where('course_id is NULL')
+ #@course_ms = Message.reorder('created_on desc')
+ @course_ms=Message.joins("join boards on messages.board_id=boards.id where boards.course_id is not NULL").reorder('created_on desc')
+ end
+
+ #项目讨论区的帖子
+ def project_messages
+ @project_ms=Message.joins("join boards on messages.board_id=boards.id where boards.project_id != -1").reorder('created_on desc')
+ end
+
+ #通知
+ def notices
+ @news = News.where('course_id is not NULL').order('created_on desc')
+ end
+
+ #最近登录用户列表
+ def latest_login_users
+ @user = User.order('last_login_on desc')
+ end
+
+ #作业
+ def homework
+ @homework = HomeworkCommon.order('end_time desc')
+ end
+
end
diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb
index 1623979f0..29f2e00f4 100644
--- a/app/controllers/courses_controller.rb
+++ b/app/controllers/courses_controller.rb
@@ -39,9 +39,14 @@ class CoursesController < ApplicationController
else
@state = 5 #未登录
end
- respond_to do |format|
- format.js { render :partial => 'set_join', :locals => {:user => user, :course => course, :object_id => params[:object_id]} }
- end
+ # if @state == 1 || @state == 3
+ # respond_to course_path(course.id)
+ # else
+ respond_to do |format|
+ format.js { render :partial => 'set_join', :locals => {:user => user, :course => course, :object_id => params[:object_id]} }
+ end
+ #end
+
rescue Exception => e
@state = 4 #已经加入了课程
respond_to do |format|
@@ -101,74 +106,17 @@ class CoursesController < ApplicationController
# 课程搜索
# add by nwb
def search
- courses_all = Course.all_course
- name = params[:name]
- if name.blank?
- @courses = []
- @courses_all = []
- @course_count = 0
- @course_pages = Paginator.new @course_count, per_page_option, params['page']
+ if params[:name].empty?
+ courses = Course.visible
+ @courses = paginateHelper courses,10
else
- @courses = courses_all.visible
- if params[:name].present?
- @courses_all = @courses.like(params[:name])
- else
- @courses_all = @courses;
- end
- @course_count = @courses_all.count
- @course_pages = Paginator.new @course_count, per_page_option, params['page']
-
- # 课程的动态数
- @course_activity_count=Hash.new
- @courses_all.each do |course|
- @course_activity_count[course.id]=0
- end
-
- case params[:course_sort_type]
- when '0'
- @courses = @courses_all.order("created_at desc")
- @s_type = 0
- @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page)
-
- @course_activity_count=get_course_activity @courses,@course_activity_count
-
- when '1'
- @courses = @courses_all.order("course_ac_para desc")
- @s_type = 1
- @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page)
-
- @course_activity_count=get_course_activity @courses,@course_activity_count
-
- when '2'
- @courses = @courses_all.order("watchers_count desc")
- @s_type = 2
- @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page)
-
- @course_activity_count=get_course_activity @courses,@course_activity_count
-
- when '3'
- @course_activity_count=get_course_activity @courses_all,@course_activity_count_array
- @courses=handle_course @courses_all,@course_activity_count
- @s_type = 3
- @courses = @courses[@course_pages.offset, @course_pages.per_page]
-
- else
- @s_type = 0
- @courses = @courses_all.order("created_at desc")
- @courses = @courses.offset(@course_pages.offset).limit(@course_pages.per_page)
-
- @course_activity_count=get_course_activity @courses,@course_activity_count
-
- end
+ courses = Course.visible.where("LOWER(name) like '%#{params[:name].to_s.downcase}%'")
+ @courses = paginateHelper courses,10
end
respond_to do |format|
format.html {
render :layout => 'course_base'
- scope = Course
- unless params[:closed]
- scope = scope.active
- end
}
format.atom {
courses = Course.visible.order('created_on DESC').limit(Setting.feeds_limit.to_i).all
@@ -658,92 +606,9 @@ class CoursesController < ApplicationController
end
def show
- if params[:jump] && redirect_to_course_menu_item(@course, params[:jump])
- return
- end
- @users_by_role = @course.users_by_role
- if(User.find_by_id(CourseInfos.find_by_course_id(@course.id).try(:user_id)))
- @user = User.find_by_id(CourseInfos.find_by_course_id(@course.id).user_id)
- end
- @key = User.current.rss_key
- #新增内容
- @days = Setting.activity_days_default.to_i
- if params[:from]
- begin; @date_to = params[:from].to_date + 1; rescue; end
- end
- has = {
- "show_course_files" => true,
- "show_course_news" => true,
- "show_course_messages" => true,
- #"show_course_journals_for_messages" => true,
- # "show_bids" => true,
- # "show_homeworks" => true,
- "show_polls" => true
- }
- @date_to ||= Date.today + 1
- @date_from = (@date_to - @days) > @course.created_at.to_date ? (@date_to - @days) : @course.created_at.to_date
- @author = (params[:user_id].blank? ? nil : User.active.find(params[:user_id]))
- if @author.nil?
- # 显示老师和助教的活动
- # @authors = searchTeacherAndAssistant(@course)
- @authors = course_all_member(@course)
- events = []
- key = "course_events_#{@course.id}".to_sym
- if Rails.env.production? && Setting.course_cahce_enabled?
- events = Rails.cache.read(key) || []
- end
- if events.empty?
- @authors.each do |author|
- @activity = Redmine::Activity::Fetcher.new(User.current, :course => @course,
- :with_subprojects => false,
- :author => author.user)
-
- @activity.scope_select {|t| has["show_#{t}"]}
- # modify by nwb
- # 添加私密性判断
- if User.current.member_of_course?(@course)|| User.current.admin?
- events += @activity.events(@days, @course.created_at)
- else
- events += @activity.events(@days, @course.created_at, :is_public => 1)
- end
- end
- Rails.cache.write(key, events) if Rails.env.production? && Setting.course_cahce_enabled?
- end
- else
- # @author = @course.teacher
- @activity = Redmine::Activity::Fetcher.new(User.current, :course => @course,
- :with_subprojects => false,
- :author => @author)
-
- @activity.scope_select {|t| has["show_#{t}"]}
- # modify by nwb
- # 添加私密性判断
- if User.current.member_of_course?(@course)|| User.current.admin?
- events = @activity.events(@days, @course.created_at)
- else
- events = @activity.events(@days, @course.created_at, :is_public => 1)
- end
- end
-
- # 无新动态时,显示老动态
- if events.count == 0
- if User.current.member_of_course?(@course)|| User.current.admin?
- events = @activity.events
- else
- events = @activity.events(:is_public => 1)
- end
- end
- @sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
- if(User.find_by_id(CourseInfos.find_by_course_id(@course.id).try(:user_id)))
- @user = User.find_by_id(CourseInfos.find_by_course_id(@course.id).user_id)
- end
-
- sorted_events = sort_activity_events_course(events)
- events = paginateHelper sorted_events,10
- @events_by_day = events.group_by {|event| User.current.time_to_date(event.event_datetime)}
- # documents
-
-
+ course_activities = @course.course_activities.order("created_at desc")
+ @canShowRealName = User.current.member_of_course? @course
+ @course_activities = paginateHelper course_activities,10
respond_to do |format|
format.html{render :layout => 'base_courses'}
format.api
diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb
index 19c1214e2..7b81d12db 100644
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -177,11 +177,11 @@ class FilesController < ApplicationController
def index
@flag = params[:flag] || false
#sort_init 'filename', 'asc'
- sort_init 'created_on', 'desc'
- sort_update 'created_on' => "#{Attachment.table_name}.created_on",
- 'filename' => "#{Attachment.table_name}.filename",
- 'size' => "#{Attachment.table_name}.filesize",
- 'downloads' => "#{Attachment.table_name}.downloads"
+ # sort_init 'created_on', 'desc'
+ # sort_update 'created_on' => "#{Attachment.table_name}.created_on",
+ # 'filename' => "#{Attachment.table_name}.filename",
+ # 'size' => "#{Attachment.table_name}.filesize",
+ # 'downloads' => "#{Attachment.table_name}.downloads"
sort = ""
@sort = ""
@order = ""
diff --git a/app/controllers/homework_common_controller.rb b/app/controllers/homework_common_controller.rb
index 21f781a1a..87c1e288b 100644
--- a/app/controllers/homework_common_controller.rb
+++ b/app/controllers/homework_common_controller.rb
@@ -19,28 +19,28 @@ class HomeworkCommonController < ApplicationController
end
def new
- # @homework_type = "1"
- #
- # @homework = HomeworkCommon.new
- # @homework.safe_attributes = params[:homework_common]
- # @homework.late_penalty = 2
- # @homework.end_time = (Time.now + 3600 * 24).strftime('%Y-%m-%d')
- # @homework.publish_time = Time.now.strftime('%Y-%m-%d')
- #
- # if @homework_type == "1"
- # #匿评作业相关属性
- # @homework_detail_manual = HomeworkDetailManual.new
- # @homework_detail_manual.ta_proportion = 0.6
- # @homework_detail_manual.absence_penalty = 2
- # @homework_detail_manual.evaluation_num = 3
- # @homework_detail_manual.evaluation_start = Time.now.strftime('%Y-%m-%d')
- # @homework_detail_manual.evaluation_end = (Time.now + 3600 * 24).strftime('%Y-%m-%d')
- # @homework.homework_detail_manual = @homework_detail_manual
- # elsif @homework_type == "2"
- # #编程作业相关属性
- # @homework_detail_programing = HomeworkDetailPrograming.new
- # @homework.homework_detail_programing = @homework_detail_programing
- # end
+ @homework_type = "1"
+
+ @homework = HomeworkCommon.new
+ @homework.safe_attributes = params[:homework_common]
+ @homework.late_penalty = 2
+ @homework.end_time = (Time.now + 3600 * 24).strftime('%Y-%m-%d')
+ @homework.publish_time = Time.now.strftime('%Y-%m-%d')
+
+ if @homework_type == "1"
+ #匿评作业相关属性
+ @homework_detail_manual = HomeworkDetailManual.new
+ @homework_detail_manual.ta_proportion = 0.6
+ @homework_detail_manual.absence_penalty = 2
+ @homework_detail_manual.evaluation_num = 3
+ @homework_detail_manual.evaluation_start = Time.now.strftime('%Y-%m-%d')
+ @homework_detail_manual.evaluation_end = (Time.now + 3600 * 24).strftime('%Y-%m-%d')
+ @homework.homework_detail_manual = @homework_detail_manual
+ elsif @homework_type == "2"
+ #编程作业相关属性
+ @homework_detail_programing = HomeworkDetailPrograming.new
+ @homework.homework_detail_programing = @homework_detail_programing
+ end
respond_to do |format|
format.html
end
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index 539d84e65..0995d1304 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -112,7 +112,19 @@ class IssuesController < ApplicationController
end
def show
-
+ # 当前用户查看指派给他的缺陷消息,则设置消息为已读
+ query = @issue.forge_messages
+ if User.current.id == @issue.assigned_to_id
+ query.update_all(:viewed => true)
+ end
+ # 缺陷状态更新
+ query_journals = @issue.journals
+ if User.current.id == @issue.author_id
+ query_journals.each do |query_journal|
+ query_journal.forge_messages.update_all(:viewed => true)
+ end
+ end
+ #
@journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all
@journals.each_with_index {|j,i| j.indice = i+1}
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
diff --git a/app/controllers/news_controller.rb b/app/controllers/news_controller.rb
index 185e7128e..1a8e75b54 100644
--- a/app/controllers/news_controller.rb
+++ b/app/controllers/news_controller.rb
@@ -72,7 +72,7 @@ class NewsController < ApplicationController
@news_count = scope.count
@q = params[:subject]
- if params[:subject].nil?
+ if params[:subject].nil? || params[:subject].blank?
scope_order = scope.all(:include => [:author, :course],
:order => "#{News.table_name}.created_on DESC")
else
diff --git a/app/controllers/poll_controller.rb b/app/controllers/poll_controller.rb
index dda5b81b2..edf8c2259 100644
--- a/app/controllers/poll_controller.rb
+++ b/app/controllers/poll_controller.rb
@@ -1,3 +1,4 @@
+#encoding utf-8
class PollController < ApplicationController
before_filter :find_poll_and_course, :only => [:edit,:update,:destroy,:show,:statistics_result,:create_poll_question,:commit_poll,:commit_answer,:publish_poll,:republish_poll,:poll_result,:close_poll,:export_poll]
before_filter :find_container, :only => [:new,:create, :index]
@@ -410,6 +411,70 @@ class PollController < ApplicationController
end
end
+ # 将其他地方的问卷导出来
+ def other_poll
+ # 查作者是我,或者作者是当前课程的老师,且不在当前课程内的问卷 进行导入
+ tea_ids = '('
+ tea_ids << Course.find(params[:polls_group_id]).tea_id.to_s << ','<< User.current.id.to_s << ')'
+ @polls = Poll.where("user_id in #{tea_ids} and polls_type = 'course' and polls_group_id != #{params[:polls_group_id]}")
+ @polls_group_id = params[:polls_group_id]
+ respond_to do |format|
+ format.js
+ end
+ end
+
+ # 将问卷导入本课程
+ def import_other_poll
+ course_id = params[:course_id]
+ @course = Course.find(course_id)
+ params[:polls].each_with_index do |p,i|
+ poll = Poll.find(p)
+ option = {
+ :polls_name => poll.polls_name || l(:label_poll_new),
+ :polls_type => 'Course',
+ :polls_group_id => course_id,
+ :polls_status => 1,
+ :user_id => User.current.id,
+ :published_at => Time.now,
+ :closed_at => Time.now,
+ :show_result => 1,
+ :polls_description => poll.polls_description
+ }
+ @poll = Poll.create option
+
+ poll.poll_questions.each do | q|
+ #question_title = params[:poll_questions_title].nil? || params[:poll_questions_title].empty? ? l(:label_enter_single_title) : params[:poll_questions_title]
+ option = {
+ :is_necessary => q[:is_necessary],
+ :question_title => q[:question_title],
+ :question_type => q[:question_type] || 1,
+ :question_number => q[:question_number]
+ }
+ @poll_questions = @poll.poll_questions.new option
+
+ for i in 1..q.poll_answers.count
+ answer = q.poll_answers[i-1].nil? ? l(:label_new_answer) : q.poll_answers[i-1][:answer_text]
+ question_option = {
+ :answer_position => i,
+ :answer_text => answer
+ }
+ @poll_questions.poll_answers.new question_option
+ end
+ end
+ @poll.save
+ end
+ @is_teacher = User.current.allowed_to?(:as_teacher,@course)
+ if @is_teacher
+ polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id}")
+ else
+ polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id} and polls_status = 2")
+ end
+ @polls = paginateHelper polls,20 #分页
+ respond_to do |format|
+ format.js
+ end
+ end
+
private
def find_poll_and_course
@poll = Poll.find params[:id]
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 3dfae3432..f042bba50 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -86,8 +86,14 @@ class ProjectsController < ApplicationController
@project_pages = Project.project_entities.visible.like(params[:name]).page(params[:page]).per(10)
else
@project_pages = Project.project_entities.visible.page(params[:page] ).per(10)
+ @project_pages = Project.project_entities.visible.page(params[:page] ).per(10)
end
@projects = @project_pages.order("created_on desc")
+ @limit = 10#per_page_option
+
+ @project_count = Project.project_entities.visible.like(params[:name]).page(params[:page]).count
+ @project_pages = Paginator.new @project_count, @limit, params['page']
+
respond_to do |format|
format.html {
render :layout => 'base'
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 0c5b441d4..bc155dbbe 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -28,6 +28,7 @@ class UsersController < ApplicationController
# menu_item :requirement_focus, :only => :watch_bids
menu_item :requirement_focus, :only => :watch_contests
menu_item :user_newfeedback, :only => :user_newfeedback
+ menu_item :user_messages, :only => :user_messages
#Ended by young
@@ -40,14 +41,14 @@ class UsersController < ApplicationController
:user_watchlist, :user_fanslist,:update, :user_courses, :user_homeworks, :watch_projects, :show_score, :topic_score_index, :project_score_index,
:activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index,
:activity_new_score_index, :influence_new_score_index, :score_new_index,:update_score,:user_activities,:user_projects_index,
- :user_courses4show,:user_projects4show,:user_course_activities,:user_project_activities,:user_feedback4show,:user_visitorlist]
+ :user_courses4show,:user_projects4show,:user_course_activities,:user_project_activities,:user_feedback4show,:user_visitorlist,:user_messages]
#edit has been deleted by huang, 2013-9-23
before_filter :find_user, :only => [:user_fanslist, :user_watchlist, :show, :edit, :update, :destroy, :edit_membership, :user_courses,
:user_homeworks, :destroy_membership, :user_activities, :user_projects, :user_newfeedback, :user_comments,
:watch_contests, :info, :watch_projects, :show_score, :topic_score_index, :project_score_index,
:activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index,
:activity_new_score_index, :influence_new_score_index, :score_new_index,:user_projects_index,
- :user_courses4show,:user_projects4show,:user_course_activities,:user_project_activities,:user_feedback4show,:user_visitorlist]
+ :user_courses4show,:user_projects4show,:user_course_activities,:user_project_activities,:user_feedback4show,:user_visitorlist,:user_messages]
before_filter :auth_user_extension, only: :show
#before_filter :rest_user_score, only: :show
#before_filter :select_entry, only: :user_projects
@@ -95,6 +96,41 @@ class UsersController < ApplicationController
end
end
+ # 用户消息
+ def user_messages
+ unless User.current.logged?
+ render_403
+ return
+ end
+ # 当前用户查看消息,则设置消息为已读
+ querys = @user.course_messages
+ if User.current.id == @user.id
+ querys.update_all(:viewed => true)
+ end
+ if @user.course_messages
+ if params[:type].nil?
+ @user_course_messages = @user.course_messages
+ @user_project_messges = @user.forge_messages
+ else
+ case params[:type]
+ when 'homework'
+ @user_course_messages = @user.course_messages.select{|x| x.course_message_type == "HomeworkCommon"}
+ #@user_course_messages = ForgeMessage.find_by_sql("select * from course_messages where user_id='#{@user.id}' and course_message_type = 'HomeworkCommon' order by created_at desc;")
+ when 'message'
+ @user_course_messages = @user.course_messages.select{|x| x.course_message_type == "Message"}
+ when 'news'
+ @user_course_messages = @user.course_messages.select{|x| x.course_message_type == "News"}
+ when 'poll'
+ @user_course_messages = @user.course_messages.select{|x| x.course_message_type == "Poll"}
+ end
+ end
+ respond_to do |format|
+ format.html{render :layout=>'base_users_new'}
+ format.api
+ end
+ end
+ end
+
def user_projects_index
if User.current.admin?
memberships = @user.memberships.all(conditions: "projects.project_type = #{Project::ProjectType_project}").first
@@ -118,7 +154,7 @@ class UsersController < ApplicationController
return
end
end
- projects = @user.projects.visible.order("updated_on desc")
+ projects = @user.projects.visible.select("projects.*,(SELECT MAX(created_at) FROM `forge_activities` WHERE forge_activities.project_id = projects.id) AS a").order("a desc")
if(params[:status] == '1')
projects = projects.where("projects.user_id = ?",@user.id)
elsif(params[:status] == '2')
@@ -248,7 +284,7 @@ class UsersController < ApplicationController
return
end
end
- courses = @user.courses.visible.order("created_at desc")
+ courses = @user.courses.visible.select("courses.*,(SELECT MAX(created_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a").order("a desc")
if(params[:status] == '1')
courses = courses.where("endup_time >= ? or endup_time is null or endup_time=''",Time.now)
elsif(params[:status] == '2')
@@ -262,9 +298,11 @@ class UsersController < ApplicationController
# modified by fq
def user_newfeedback
jours = @user.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
- jours.update_all(:is_readed => true, :status => false)
- jours.each do |journal|
- fetch_user_leaveWord_reply(journal).update_all(:is_readed => true, :status => false)
+ if User.current == @user
+ jours.update_all(:is_readed => true, :status => false)
+ jours.each do |journal|
+ fetch_user_leaveWord_reply(journal).update_all(:is_readed => true, :status => false)
+ end
end
@jour = paginateHelper jours,10
@state = false
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index d82db77b2..9b9bf5f76 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1812,7 +1812,7 @@ module ApplicationHelper
#获取用户未过期的课程
def get_user_course user
courses_doing = []
- user.courses.each do |course|
+ user.courses.select("courses.*,(SELECT MAX(created_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a").order("a desc").each do |course|
if !course_endTime_timeout?(course)
courses_doing.push course
end
diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb
index 597d5749c..f9fb31969 100644
--- a/app/helpers/courses_helper.rb
+++ b/app/helpers/courses_helper.rb
@@ -676,4 +676,61 @@ module CoursesHelper
end
result
end
+
+ #生成课程相关动态的链接
+ def course_activity_link activity
+ # activity = CourseActivity.first
+ title = ""
+ url = ""
+ if activity.course_act
+ case activity.course_act_type
+ when "Course"
+ title = activity.course_act.name
+ url = course_path activity.course
+ when "HomeworkCommon"
+ title = "作业 " + activity.course_act.name
+ url = student_work_index_path(:homework => activity.course_act.id)
+ when "News"
+ title = "通知公告 " + activity.course_act.title
+ url = course_news_index_path(activity.course)
+ when "Attachment"
+ title = "课件 " + activity.course_act.filename
+ url = course_files_path(activity.course)
+ when "Message"
+ title = "课程讨论区 " + activity.course_act.subject
+ url = course_boards_path(activity.course,:parent_id => activity.course_act.parent_id ? activity.course_act.parent_id : activity.course_act.id, :topic_id => activity.course_act.id)
+ when "JournalsForMessage"
+ title = "留言 " + activity.course_act.notes
+ url = course_feedback_path(activity.course)
+ when "Poll"
+ title = "问卷 " + activity.course_act.polls_name
+ url = poll_path(activity.course_act_id)
+ end
+ end
+ link_to title.gsub(/<(?!img)[^>]*>/,'').html_safe, url, :class => "problem_tit c_dblue fl fb"
+ end
+
+ #课程动态的描述
+ def course_activity_desc activity
+ desc = ""
+ if activity.course_act
+ case activity.course_act_type
+ when "Course"
+ desc = ""
+ when "HomeworkCommon"
+ desc = activity.course_act.description
+ when "News"
+ desc = activity.course_act.description
+ when "Attachment"
+ desc = ""
+ when "Message"
+ desc = activity.course_act.content
+ when "JournalsForMessage"
+ desc = ""
+ when "Poll"
+ desc = activity.course_act.polls_description
+ end
+ end
+ desc.html_safe
+ end
end
diff --git a/app/helpers/poll_helper.rb b/app/helpers/poll_helper.rb
index 3156f1b3a..22ee21936 100644
--- a/app/helpers/poll_helper.rb
+++ b/app/helpers/poll_helper.rb
@@ -74,4 +74,13 @@ module PollHelper
end
end
+ #带勾选框的问卷列表
+ def poll_check_box_tags(name,polls,current_poll)
+ s = ''
+ polls.each do |poll|
+ s << "#{ check_box_tag name, poll.id, false, :id => nil } #{h poll.polls_name.blank? ? l(:label_poll_new) : poll.polls_name } [#{ h Course.find(poll.polls_group_id).name}] "
+ end
+ s.html_safe
+ end
+
end
\ No newline at end of file
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index f999e27d6..f7fb9b1aa 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -27,6 +27,8 @@ class Attachment < ActiveRecord::Base
belongs_to :attachmentstype, :foreign_key => "attachtype",:primary_key => "id"
# 被ForgeActivity虚拟关联
has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
# end
include UserScoreHelper
@@ -71,8 +73,8 @@ class Attachment < ActiveRecord::Base
cattr_accessor :thumbnails_storage_path
@@thumbnails_storage_path = File.join(Rails.root, "tmp", "thumbnails")
- before_save :files_to_final_location
- after_create :office_conver, :be_user_score,:act_as_forge_activity# user_score
+ 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
@@ -552,4 +554,10 @@ class Attachment < ActiveRecord::Base
end
end
+ #课程动态公共表记录
+ def act_as_course_activity
+ if self.container_type == "Course" && self.course_acts.empty?
+ self.course_acts << CourseActivity.new(:user_id => self.author_id,:course_id => self.container_id)
+ end
+ end
end
diff --git a/app/models/course.rb b/app/models/course.rb
index 6d71ad967..26220f245 100644
--- a/app/models/course.rb
+++ b/app/models/course.rb
@@ -33,6 +33,11 @@ class Course < ActiveRecord::Base
has_many :student_works, :through => :homework_commons, :dependent => :destroy
has_many :course_groups, :dependent => :destroy
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
+
+ has_many :course_activities
+ has_many :course_messages
acts_as_taggable
acts_as_nested_set :order => 'name', :dependent => :destroy
@@ -44,7 +49,7 @@ class Course < ActiveRecord::Base
validates_format_of :name,:with =>/^[^ ]+[a-zA-Z0-9_\u4e00-\u9fa5\s\S]+$/
validates_length_of :description, :maximum => 10000
before_save :self_validate
- after_create :create_board_sync
+ after_create :create_board_sync, :act_as_course_activity
before_destroy :delete_all_members
safe_attributes 'extra',
@@ -310,6 +315,11 @@ class Course < ActiveRecord::Base
end
end
+ #课程动态公共表记录
+ def act_as_course_activity
+ self.course_acts << CourseActivity.new(:user_id => self.tea_id,:course_id => self.id)
+ end
+
#项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题
#def name
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
diff --git a/app/models/course_activity.rb b/app/models/course_activity.rb
new file mode 100644
index 000000000..02b6dacf1
--- /dev/null
+++ b/app/models/course_activity.rb
@@ -0,0 +1,7 @@
+class CourseActivity < ActiveRecord::Base
+ attr_accessible :user_id, :course_act_id,:course_act_type,:course_id
+ # 虚拟关联
+ belongs_to :course_act ,:polymorphic => true
+ belongs_to :course
+ belongs_to :user
+end
diff --git a/app/models/course_message.rb b/app/models/course_message.rb
new file mode 100644
index 000000000..59089829d
--- /dev/null
+++ b/app/models/course_message.rb
@@ -0,0 +1,12 @@
+class CourseMessage < ActiveRecord::Base
+ attr_accessible :course_id, :course_message_id, :course_message_type, :user_id, :viewed
+
+ # 多态 虚拟关联
+ belongs_to :course_message ,:polymorphic => true
+ belongs_to :course
+ belongs_to :user
+ validates :user_id,presence: true
+ validates :course_id,presence: true
+ validates :course_message_id,presence: true
+ validates :course_message_type, presence: true
+end
diff --git a/app/models/forge_message.rb b/app/models/forge_message.rb
new file mode 100644
index 000000000..1543fab58
--- /dev/null
+++ b/app/models/forge_message.rb
@@ -0,0 +1,20 @@
+class ForgeMessage < ActiveRecord::Base
+ # 公共表中活动类型,命名规则:TYPE_OF_{类名}_ACT
+ TYPE_OF_ISSUE_ACT = "Issue"
+ TYPE_OF_MESSAGE_ACT = "Message"
+ TYPE_OF_ATTACHMENT_ACT = "Attachment"
+ TYPE_OF_DOCUMENT_ACT = "Document"
+ TYPE_OF_JOURNAL_ACT = "Journal"
+ TYPE_OF_WIKI_ACT = "Wiki"
+ TYPE_OF_NEWS_ACT = "News"
+
+ attr_accessible :forge_message_id, :forge_message_type, :project_id, :user_id, :viewed
+
+ belongs_to :forge_message ,:polymorphic => true
+ belongs_to :project
+ belongs_to :user
+ validates :user_id,presence: true
+ validates :project_id,presence: true
+ validates :forge_message_id,presence: true
+ validates :forge_message_type, presence: true
+end
diff --git a/app/models/homework_common.rb b/app/models/homework_common.rb
index 291c14563..217c7d770 100644
--- a/app/models/homework_common.rb
+++ b/app/models/homework_common.rb
@@ -13,17 +13,40 @@ class HomeworkCommon < ActiveRecord::Base
has_many :student_works, :dependent => :destroy
has_many :student_works_evaluation_distributions, :through => :student_works #一个作业的分配的匿评列表
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy #用户活动
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
+ # 课程消息
+ has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
acts_as_attachable
acts_as_event :title => Proc.new {|o| "#{l(:label_course_homework)} ##{o.id}: #{o.name}" },
:description => :description,
:author => :author,
:url => Proc.new {|o| {:controller => 'student_work', :action => 'index', :homework => o.id}}
- after_create :act_as_activity, :send_mail
+ after_create :act_as_activity, :send_mail, :act_as_course_activity, :act_as_course_message
after_destroy :delete_kindeditor_assets
def act_as_activity
self.acts << Activity.new(:user_id => self.user_id)
end
+
+ #课程动态公共表记录
+ def act_as_course_activity
+ if self.course
+ self.course_acts << CourseActivity.new(:user_id => self.user_id,:course_id => self.course_id)
+ end
+ end
+
+ #课程作业消息记录
+ def act_as_course_message
+ if self.course
+ self.course.members.each do |m|
+ if m.user_id != self.user_id
+ self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.course_id, :viewed => false)
+ end
+ end
+ end
+ end
+
#删除对应的图片
def delete_kindeditor_assets
delete_kindeditor_assets_from_disk self.id,OwnerTypeHelper::HOMEWORKCOMMON
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 147e26cef..66627c00a 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -49,6 +49,8 @@ class Issue < ActiveRecord::Base
has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy
# end
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
+ # ForgeMessage虚拟关联(多态)
+ has_many :forge_messages, :class_name => 'ForgeMessage',:as =>:forge_message ,:dependent => :destroy
acts_as_nested_set :scope => 'root_id', :dependent => :destroy
@@ -80,7 +82,7 @@ class Issue < ActiveRecord::Base
attr_reader :current_journal
# fq
- after_create :act_as_activity,:be_user_score_new_issue,:act_as_forge_activity
+ after_create :act_as_activity,:be_user_score_new_issue,:act_as_forge_activity, :act_as_forge_message
after_update :be_user_score
after_destroy :down_user_score
# after_create :be_user_score
@@ -138,6 +140,16 @@ class Issue < ActiveRecord::Base
:project_id => self.project_id)
end
# end
+
+ # 发布缺陷forge_messages中添加记录
+ def act_as_forge_message
+ # 指派给自己的缺陷不提示消息
+ unless self.author_id == self.assigned_to_id
+ self.forge_messages << ForgeMessage.new(:user_id => self.assigned_to_id,
+ :project_id => self.project_id,
+ :viewed => false)
+ end
+ end
# Returns a SQL conditions string used to find all issues visible by the specified user
diff --git a/app/models/journal.rb b/app/models/journal.rb
index 3b660132e..c705b1a09 100644
--- a/app/models/journal.rb
+++ b/app/models/journal.rb
@@ -29,6 +29,8 @@ class Journal < ActiveRecord::Base
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
# 被ForgeActivity虚拟关联
has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy
+ # 被ForgeMessage虚拟关联
+ has_many :forge_messages, :class_name => 'ForgeMessage',:as =>:forge_message ,:dependent => :destroy
# end
attr_accessor :indice
@@ -48,7 +50,7 @@ class Journal < ActiveRecord::Base
before_create :split_private_notes
# fq
- after_save :act_as_activity,:be_user_score,:act_as_forge_activity
+ after_save :act_as_activity,:be_user_score,:act_as_forge_activity, :act_as_forge_message
# end
#after_destroy :down_user_score
#before_save :be_user_score
@@ -163,10 +165,17 @@ class Journal < ActiveRecord::Base
# Description 公共表中需要保存一份该记录
def act_as_forge_activity
self.forge_acts << ForgeActivity.new(:user_id => self.user_id,
- :project_id => self.issue.project.id)
+ :project_id => self.issue.project.id)
end
+ # 缺陷状态更改,消息提醒
+ def act_as_forge_message
+ self.forge_messages << ForgeMessage.new(:user_id => self.issue.author_id,
+ :project_id => self.issue.project_id,
+ :viewed => false)
+ end
+
# 更新用户分数 -by zjc
def be_user_score
#新建了缺陷留言且留言不为空,不为空白
diff --git a/app/models/journals_for_message.rb b/app/models/journals_for_message.rb
index b15c9b2d1..bcae58174 100644
--- a/app/models/journals_for_message.rb
+++ b/app/models/journals_for_message.rb
@@ -56,9 +56,11 @@ class JournalsForMessage < ActiveRecord::Base
acts_as_attachable
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
validates :notes, presence: true, if: :is_homework_jour?
- after_create :act_as_activity #huang
+ after_create :act_as_activity, :act_as_course_activity
after_create :reset_counters!
after_destroy :reset_counters!
after_save :be_user_score
@@ -177,4 +179,11 @@ class JournalsForMessage < ActiveRecord::Base
def delete_kindeditor_assets
delete_kindeditor_assets_from_disk self.id,7
end
+
+ #课程动态公共表记录
+ def act_as_course_activity
+ if self.jour_type == 'Course'
+ self.course_acts << CourseActivity.new(:user_id => self.user_id,:course_id => self.jour_id)
+ end
+ end
end
diff --git a/app/models/message.rb b/app/models/message.rb
index 15d358789..aa62cd625 100644
--- a/app/models/message.rb
+++ b/app/models/message.rb
@@ -32,7 +32,12 @@ class Message < ActiveRecord::Base
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
# 被ForgeActivity虚拟关联
has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
# end
+ # 课程消息
+ has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
+ #end
has_many :ActivityNotifies,:as => :activity, :dependent => :destroy
@@ -68,7 +73,7 @@ class Message < ActiveRecord::Base
after_update :update_messages_board
after_destroy :reset_counters!,:down_user_score,:delete_kindeditor_assets
- after_create :act_as_activity,:be_user_score,:act_as_forge_activity, :send_mail
+ after_create :act_as_activity,:act_as_course_activity,:be_user_score,:act_as_forge_activity, :act_as_course_message, :send_mail
#before_save :be_user_score
scope :visible, lambda {|*args|
@@ -185,6 +190,61 @@ class Message < ActiveRecord::Base
:project_id => self.board.project.id)
end
end
+
+ #课程动态公共表记录
+ def act_as_course_activity
+ if self.course
+ self.course_acts << CourseActivity.new(:user_id => self.author_id,:course_id => self.board.course_id)
+ end
+ end
+
+ # 课程讨论区添加消息
+ # 老师发帖所有人都能收到消息
+ # 学生发帖,有人回复则给该学生消息,没回复则不给其它人发送消息
+ # 帖子被回复的可以收到消息通知
+ def act_as_course_message
+ if self.course
+ if self.parent_id.nil? #主贴
+ self.course.members.each do |m|
+ if self.author.allowed_to?(:as_teacher, self.course) # 老师
+ if m.user_id != self.author_id # 自己的帖子不给自己发送消息
+ self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.board.course_id, :viewed => false)
+ end
+ end
+ end
+ else # 回帖
+ #if self.author.allowed_to?(:as_teacher, self.course) # 老师
+ self.course.members.each do |m|
+ if m.user_id == Message.find(self.parent_id).author_id && m.user_id != self.author_id # 只针对主贴回复,回复自己的帖子不发消息
+ self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.board.course_id, :viewed => false)
+ end
+ end
+ #end
+ end
+ end
+ # if self.author.allowed_to?(:as_teacher, self.course) # 如果发帖人是老师
+ # self.course.members.each do |m|
+ # if self.parent_id.nil? # 主贴
+ # if m.user_id != self.author_id # 自己的帖子不给自己发送消息
+ # self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.board.course_id, :viewed => false)
+ # end
+ # else # 回帖只针对主贴发送消息
+ # if m.user_id == Message.find(self.parent_id).author_id
+ # self.course_messages << CourseMessage.new(:user_id => self.parent_id, :course_id => self.board.course_id, :viewed => false)
+ # end
+ # end
+ # end
+ # else # 学生只针对主贴回复
+ # unless self.parent_id.nil?
+ # self.course.members.each do |m|
+ # if m.user_id == Message.find(self.parent_id).author_id && m.user_id != self.author_id # 只针对主贴回复,回复自己的帖子不发消息
+ # self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.board.course_id, :viewed => false)
+ # end
+ # end
+ # end
+ # end
+ #end
+ end
#更新用户分数 -by zjc
def be_user_score
diff --git a/app/models/news.rb b/app/models/news.rb
index 7d33d760e..99d26d456 100644
--- a/app/models/news.rb
+++ b/app/models/news.rb
@@ -28,7 +28,12 @@ class News < ActiveRecord::Base
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
# 被ForgeActivity虚拟关联
has_many :forge_acts, :class_name => 'ForgeActivity',:as =>:forge_act ,:dependent => :destroy
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
# end
+ # 课程消息
+ has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
+ #end
has_many :ActivityNotifies,:as => :activity, :dependent => :destroy
@@ -49,7 +54,7 @@ class News < ActiveRecord::Base
:author_key => :author_id
acts_as_watchable
- after_create :act_as_activity,:act_as_forge_activity,:add_author_as_watcher, :send_mail
+ after_create :act_as_activity,:act_as_forge_activity, :act_as_course_activity,:act_as_course_messge, :add_author_as_watcher, :send_mail
after_destroy :delete_kindeditor_assets
@@ -121,6 +126,25 @@ class News < ActiveRecord::Base
end
end
+ #课程动态公共表记录
+ def act_as_course_activity
+ if self.course
+ self.course_acts << CourseActivity.new(:user_id => self.author_id,:course_id => self.course_id)
+ end
+ end
+
+ #课程通知 消息发送
+ #消息发送原则:除了消息的发布者,课程的其它成员都能收到消息提醒
+ def act_as_course_messge
+ if self.course
+ self.course.members.each do |m|
+ if m.user_id != self.author_id
+ self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.course_id, :viewed => false)
+ end
+ end
+ end
+ end
+
# Time 2015-03-31 13:50:54
# Author lizanle
# Description 删除news后删除对应的资源
@@ -132,4 +156,4 @@ class News < ActiveRecord::Base
Mailer.run.news_added(self) if Setting.notified_events.include?('news_added')
end
-end
+end
\ No newline at end of file
diff --git a/app/models/poll.rb b/app/models/poll.rb
index 64e9df79a..62f91380b 100644
--- a/app/models/poll.rb
+++ b/app/models/poll.rb
@@ -8,7 +8,12 @@ class Poll < ActiveRecord::Base
has_many :users, :through => :poll_users #该文件被哪些用户提交答案过
# 添加课程的poll动态
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
- after_create :act_as_activity
+ # 课程动态
+ has_many :course_acts, :class_name => 'CourseActivity',:as =>:course_act ,:dependent => :destroy
+ after_create :act_as_activity, :act_as_course_activity
+ # 课程消息
+ has_many :course_messages, :class_name =>'CourseMessage', :as => :course_message, :dependent => :destroy
+ after_create :act_as_activity, :act_as_course_activity, :act_as_course_message
acts_as_event :title => Proc.new {|o| "#{l(:label_course_poll)}: #{o.polls_name}" },
:description => :polls_description,
@@ -27,4 +32,26 @@ class Poll < ActiveRecord::Base
self.acts << Activity.new(:user_id => self.user_id)
end
+ #课程动态公共表记录
+ def act_as_course_activity
+ if self.polls_type == "Course"
+ if self.polls_status == 2 #问卷是发布状态
+ self.course_acts << CourseActivity.new(:user_id => self.user_id,:course_id => self.polls_group_id)
+ elsif self.polls_status == 1 #问卷是新建状态
+ self.course_acts.destroy_all
+ end
+ end
+ end
+
+ # 发布问卷,出了发布者外,其他人都能收到消息通知
+ def act_as_course_message
+ if self.polls_type == "Course"
+ Course.find(self.polls_group_id).members.each do |m|
+ if m.user_id != self.user_id
+ self.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => self.polls_group_id, :viewed => false)
+ end
+ end
+ end
+ end
+
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 8ab377ccc..77711edff 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -91,6 +91,8 @@ class Project < ActiveRecord::Base
has_many :tags, :through => :project_tags, :class_name => 'Tag'
has_many :project_tags, :class_name => 'ProjectTags'
+ # 关联虚拟表
+ has_many :forge_messages
belongs_to :organization
diff --git a/app/models/user.rb b/app/models/user.rb
index 2271adc18..9f88ff53a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -109,7 +109,6 @@ class User < Principal
has_many :contests, :foreign_key => 'author_id', :dependent => :destroy
has_many :softapplications, :foreign_key => 'user_id', :dependent => :destroy
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
- has_many :new_jours, :as => :jour, :class_name => 'JournalsForMessage', :conditions => "status=1"
has_many :journal_replies, :dependent => :destroy
has_many :activities, :dependent => :destroy
has_many :students_for_courses
@@ -128,8 +127,15 @@ class User < Principal
has_many :messages, :foreign_key => 'author_id'
has_one :user_score, :dependent => :destroy
has_many :documents # 项目中关联的文档再次与人关联
+# 关联虚拟表
+ has_many :forge_messages
+ has_many :course_messages
# end
+# 虚拟转换
+ has_many :new_jours, :as => :jour, :class_name => 'JournalsForMessage', :conditions => "status=1"
+ has_many :issue_assigns, :class_name => 'ForgeMessage', :conditions => 'viewed=0 and forge_message_type="Issue"'
+ has_many :status_updates, :class_name => 'ForgeMessage', :conditions => 'viewed=0 and forge_message_type="Journal"'
# 邮件邀请状态
# has_many :invite_lists
# end
@@ -235,6 +241,28 @@ class User < Principal
# ======================================================================
+ # 查询用户未读过的记录
+ # 用户留言记录
+ def count_new_jour
+ count = self.new_jours.count
+ # count = self.journals_for_messages(:conditions => ["status=? and is_readed = ? " ,1, 0]).count
+ end
+
+ # 查询指派给我的缺陷记录
+ def count_new_issue_assign_to
+ self.issue_assigns
+ end
+
+ # 新消息统计
+ def count_new_message
+ count = CourseMessage.where("user_id =? and viewed =?", User.current.id, 0).count
+ end
+ # 查询指派给我的缺陷记录
+ def issue_status_update
+ self.status_updates
+ end
+ # end
+
def extensions
self.user_extensions ||= UserExtensions.new
end
@@ -258,7 +286,7 @@ class User < Principal
###添加留言 fq
def add_jour(user, notes, reference_user_id = 0, options = {})
if options.count == 0
- self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id, :status => true)
+ self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id, :status => true, :is_readed => false)
else
jfm = self.journals_for_messages.build(options)
jfm.save
@@ -291,11 +319,7 @@ class User < Principal
name
end
## end
-
- def count_new_jour
- count = self.new_jours.count
- end
-
+
#added by nie
def count_new_journal_reply
count = self.journal_reply.count
diff --git a/app/views/admin/_tab_messages.erb b/app/views/admin/_tab_messages.erb
new file mode 100644
index 000000000..ec04246ba
--- /dev/null
+++ b/app/views/admin/_tab_messages.erb
@@ -0,0 +1,8 @@
+
+
+ <%= link_to l(:label_forum), {:action => 'messages_list'}, class: "#{current_page?(messages_list_path)? 'selected' : nil }" %>
+ <%= link_to l(:label_borad_course), {:action => 'course_messages'}, class: "#{current_page?(course_messages_path)? 'selected' : nil }" %>
+ <%= link_to l(:label_borad_project), {:action => 'project_messages'}, class: "#{current_page?(project_messages_path)? 'selected' : nil }" %>
+
+
+
\ No newline at end of file
diff --git a/app/views/admin/course_messages.html.erb b/app/views/admin/course_messages.html.erb
new file mode 100644
index 000000000..8564d13dc
--- /dev/null
+++ b/app/views/admin/course_messages.html.erb
@@ -0,0 +1,66 @@
+
+ <%=l(:label_message_plural)%>
+
+
+<%= render 'tab_messages' %>
+<%=l(:label_borad_course) %>
+
+
+<% html_title(l(:label_message_plural)) -%>
diff --git a/app/views/admin/homework.html.erb b/app/views/admin/homework.html.erb
new file mode 100644
index 000000000..360ca4e39
--- /dev/null
+++ b/app/views/admin/homework.html.erb
@@ -0,0 +1,62 @@
+
+ <%=l(:label_user_homework)%>
+
+
+
+
+<% html_title(l(:label_user_homework)) -%>
diff --git a/app/views/admin/latest_login_users.html.erb b/app/views/admin/latest_login_users.html.erb
new file mode 100644
index 000000000..dc35daec8
--- /dev/null
+++ b/app/views/admin/latest_login_users.html.erb
@@ -0,0 +1,73 @@
+
+ <%=l(:label_latest_login_user_list)%>
+
+
+
+
+<% html_title(l(:label_latest_login_user_list)) -%>
diff --git a/app/views/admin/leave_messages.html.erb b/app/views/admin/leave_messages.html.erb
new file mode 100644
index 000000000..975c60b15
--- /dev/null
+++ b/app/views/admin/leave_messages.html.erb
@@ -0,0 +1,79 @@
+
+ <%=l(:label_leave_message_list)%>
+
+
+
+
+
+
+<% html_title(l(:label_leave_message_list)) -%>
diff --git a/app/views/admin/messages_list.html.erb b/app/views/admin/messages_list.html.erb
new file mode 100644
index 000000000..77cdbbc69
--- /dev/null
+++ b/app/views/admin/messages_list.html.erb
@@ -0,0 +1,69 @@
+
+ <%=l(:label_message_plural)%>
+
+
+<%= render 'tab_messages' %>
+<%=l(:label_forum) %>
+
+
+
+<% html_title(l(:label_message_plural)) -%>
diff --git a/app/views/admin/notices.html.erb b/app/views/admin/notices.html.erb
new file mode 100644
index 000000000..56f212720
--- /dev/null
+++ b/app/views/admin/notices.html.erb
@@ -0,0 +1,74 @@
+
+ <%=l(:label_notification_list)%>
+
+
+
+
+<% html_title(l(:label_notification_list)) -%>
diff --git a/app/views/admin/project_messages.html.erb b/app/views/admin/project_messages.html.erb
new file mode 100644
index 000000000..af2978422
--- /dev/null
+++ b/app/views/admin/project_messages.html.erb
@@ -0,0 +1,66 @@
+
+ <%=l(:label_message_plural)%>
+
+
+<%= render 'tab_messages' %>
+<%=l(:label_borad_project) %>
+
+
+<% html_title(l(:label_message_plural)) -%>
diff --git a/app/views/boards/_form.html.erb b/app/views/boards/_form.html.erb
index 47ae0672d..a4f58dcc3 100644
--- a/app/views/boards/_form.html.erb
+++ b/app/views/boards/_form.html.erb
@@ -1,7 +1,7 @@
<%= error_messages_for @board %>
-
+
<%= f.text_field :name, :required => true %>
diff --git a/app/views/boards/show.html.erb b/app/views/boards/show.html.erb
index 5520f526d..609294161 100644
--- a/app/views/boards/show.html.erb
+++ b/app/views/boards/show.html.erb
@@ -1,12 +1,5 @@
\ No newline at end of file
diff --git a/app/views/poll/_poll.html.erb b/app/views/poll/_poll.html.erb
index 180fed0f0..1828ede6d 100644
--- a/app/views/poll/_poll.html.erb
+++ b/app/views/poll/_poll.html.erb
@@ -2,11 +2,13 @@
<% poll_name = poll.polls_name.empty? ? l(:label_poll_new) : poll.polls_name%>
<% if @is_teacher%>
- <% if has_commit %>
- <%= link_to poll_name, poll_result_poll_path(poll.id), :class => "polls_title polls_title_w fl c_dblue"%>
- <% else %>
- <%= link_to poll_name, poll_path(poll.id), :class => "polls_title polls_title_w fl c_dblue" %>
- <% end %>
+
+ <% if has_commit %>
+ <%= link_to poll_name, poll_result_poll_path(poll.id), :class => "polls_title polls_title_w fl c_dblue"%>
+ <% else %>
+ <%= link_to poll_name, poll_path(poll.id), :class => "polls_title polls_title_w fl c_dblue" %>
+ <% end %>
+
<% if poll.polls_status == 1%>
@@ -41,6 +43,7 @@
导出
<% elsif poll.polls_status == 2 || poll.polls_status == 3 %>
<%= link_to "导出", export_poll_poll_path(poll.id,:format => "xls"), :class => "polls_de fr ml5"%>
+
<% end%>
diff --git a/app/views/poll/_poll_list.html.erb b/app/views/poll/_poll_list.html.erb
index becfc32a5..fb8b765a3 100644
--- a/app/views/poll/_poll_list.html.erb
+++ b/app/views/poll/_poll_list.html.erb
@@ -3,20 +3,14 @@
(<%= @obj_count%>)
<% if @is_teacher%>
+ <%= link_to "导入", other_poll_poll_index_path(:polls_group_id => @course.id), :remote=>true,:class => "newbtn"%>
<%= link_to l(:label_new_poll), new_poll_path(:polls_type => "Course",:polls_group_id => @course.id), :class => "newbtn" %>
<% end%>
-
- <% @polls.each do |poll|%>
-
- <%= render :partial => 'poll', :locals => {:poll => poll} %>
-
-
- <% end%>
+
+
+ <%= render :partial => 'polls_list', :locals => {:polls => @polls,:obj_pages=>@obj_pages,:obj_count=>@obj_count} %>
-
- <%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false, :remote => false, :flag => true%>
-
\ No newline at end of file
diff --git a/app/views/poll/_polls_list.html.erb b/app/views/poll/_polls_list.html.erb
new file mode 100644
index 000000000..c096f396d
--- /dev/null
+++ b/app/views/poll/_polls_list.html.erb
@@ -0,0 +1,10 @@
+<% polls.each do |poll|%>
+
+ <%= render :partial => 'poll', :locals => {:poll => poll} %>
+
+
+<% end%>
+
+
+ <%= pagination_links_full obj_pages, obj_count, :per_page_links => false, :remote => false, :flag => true%>
+
\ No newline at end of file
diff --git a/app/views/poll/import_other_poll.js.erb b/app/views/poll/import_other_poll.js.erb
new file mode 100644
index 000000000..f60cea1c5
--- /dev/null
+++ b/app/views/poll/import_other_poll.js.erb
@@ -0,0 +1 @@
+$('#polls_list').html('<%= escape_javascript(render :partial => 'polls_list', :locals => {:polls => @polls,:obj_pages=>@obj_pages,:obj_count=>@obj_count}) %>
');
\ No newline at end of file
diff --git a/app/views/poll/index.html.erb b/app/views/poll/index.html.erb
index bede915b4..92a42cbac 100644
--- a/app/views/poll/index.html.erb
+++ b/app/views/poll/index.html.erb
@@ -80,6 +80,11 @@
$('#ajax-modal').parent().css("top","").css("left","");
$('#ajax-modal').parent().addClass("popbox_polls");
}
+
+ function closeModal()
+ {
+ hideModal($("#popbox_upload"));
+ }
<%= render :partial => 'poll_list'%>
diff --git a/app/views/poll/other_poll.js.erb b/app/views/poll/other_poll.js.erb
new file mode 100644
index 000000000..eee4ed4a1
--- /dev/null
+++ b/app/views/poll/other_poll.js.erb
@@ -0,0 +1,13 @@
+
+<% if @polls.empty? %>
+ alert('您目前还没有自己新建的问卷');
+<% else %>
+ $('#ajax-modal').html('<%= escape_javascript(render :partial => 'other_poll',:locals => {:polls => @polls,:polls_group_id=>@polls_group_id}) %>');
+
+
+ showModal('ajax-modal', '513px');
+ $('#ajax-modal').siblings().remove();
+ $('#ajax-modal').before("
");
+ $('#ajax-modal').parent().css("top","").css("left","");
+ $('#ajax-modal').parent().addClass("popbox_polls");
+<% end %>
\ No newline at end of file
diff --git a/app/views/projects/search.html.erb b/app/views/projects/search.html.erb
index b77b3fda6..c5edc4667 100644
--- a/app/views/projects/search.html.erb
+++ b/app/views/projects/search.html.erb
@@ -104,9 +104,13 @@
<% end %>
+
-
-<%= paginate @project_pages %>
+<%#= paginate @project_pages %>
diff --git a/app/views/users/_user_show.html.erb b/app/views/users/_user_show.html.erb
index 8e3d27666..7cbb20e40 100644
--- a/app/views/users/_user_show.html.erb
+++ b/app/views/users/_user_show.html.erb
@@ -23,8 +23,19 @@
- <%= l(:label_x_has_fans,:count=>user.watcher_users.count)%>
- <%= l(:label_has_watchers,:count=>User.watched_by(user.id).count) %>
+ <%= l(:label_x_has_fans,:count=>user.watcher_users.count, :remote => true)%>
+ <%= l(:label_has_watchers,:count=>User.watched_by(user.id).count, :remote => true) %>
+ <% if User.current.logged?%>
+ <% if User.current == user%>
+ 编辑资料
+ <%else%>
+ <%if(user.watched_by?(User.current))%>
+ 取消关注
+ <% else %>
+ 添加关注
+ <% end %>
+ <% end%>
+ <% end %>
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index e53d734c6..b2e6258ee 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -5,14 +5,14 @@
<% if @user.allowed_to?(:add_project, nil, :global => true) %>
新建项目
<% else %>
-
加入项目
+
加入项目
<% end %>
<% if @user.user_extensions.identity == 0 && @user.allowed_to?(:add_course, nil, :global => true) %>
-
新建课程
+
新建课程
<% else %>
-
加入课程
+
加入课程
<% end %>
diff --git a/app/views/users/user_messages.html.erb b/app/views/users/user_messages.html.erb
new file mode 100644
index 000000000..a61342cc6
--- /dev/null
+++ b/app/views/users/user_messages.html.erb
@@ -0,0 +1,79 @@
+
+
+
diff --git a/config/locales/my/zh.yml b/config/locales/my/zh.yml
index 4220aceca..25a949df4 100644
--- a/config/locales/my/zh.yml
+++ b/config/locales/my/zh.yml
@@ -33,7 +33,6 @@ zh:
label_account_identity_studentID: 请输入学号
field_brief_introduction_my: 个人签名
- field_description: 个人简介
field_is_required: 必填
field_firstname: 名字或组织名
firstname_empty: 名字不能为空
diff --git a/config/locales/projects/en.yml b/config/locales/projects/en.yml
index b142c6ca8..703e0878e 100644
--- a/config/locales/projects/en.yml
+++ b/config/locales/projects/en.yml
@@ -42,10 +42,10 @@ en:
label_member: "Members"
project_module_attachments: "Resources"
- label_project_mail_attachments: Project Resources
- label_project_mail_upload: had uploaded project resources
+ label_project_mail_attachments: "Project Resources"
+ label_project_mail_upload: "had uploaded project resources"
- label_invite: Invitation
+ label_invite: "Invitation"
label_invite_new_user: "Send email to invite new user"
label_invite_trustie_user: "Invite the Trustie registered user"
diff --git a/config/locales/projects/zh.yml b/config/locales/projects/zh.yml
index e47cd476c..fe26aee1d 100644
--- a/config/locales/projects/zh.yml
+++ b/config/locales/projects/zh.yml
@@ -67,6 +67,13 @@ zh:
label_project_mail_upload: 上传了资源
label_invite: 邀请
+
+ # 项目消息通知
+ label_forge_message: 消息
+ label_issue_message: 问题
+ label_course_message: 课程消息
+ label_project_message: 项目消息
+
label_issue_tracking: 问题跟踪
label_release_issue: 发布问题
@@ -363,7 +370,6 @@ zh:
#
label_project_new_description: '项目可以是软件开发项目,也可以是协作研究项目。'
field_name: 名称
- field_description: 描述
field_identifier: 标识
field_enterprise_name: 组织名称
label_organization_choose: --请选择组织--
diff --git a/config/locales/zh.yml b/config/locales/zh.yml
index c47976275..c2c558cf5 100644
--- a/config/locales/zh.yml
+++ b/config/locales/zh.yml
@@ -552,6 +552,7 @@ zh:
label_registered_on: 注册于
label_overall_activity: 活动概览
label_new: 新建
+ label_latest_login_user_list: 最近登录用户列表
label_logged_as: 登录为
label_environment: 环境
@@ -690,7 +691,7 @@ zh:
label_sort_lowest: 置底
label_roadmap_due_in: "截止日期到 %{value}"
label_roadmap_overdue: "%{value} 延期"
- label_roadmap_no_issues: 该版本还没有对应的缺陷,可以在“发布问题”的“目标版本”中设置!
+ label_roadmap_no_issues: 该版本还没有对应的缺陷,可以在“发布问题”的“目标版本”中指定版本!
label_user_search_type: 搜索类型
label_search_by_login: 登录名
label_search_by_name: 名字
@@ -1252,6 +1253,7 @@ zh:
label_leave_message_to: 给用户 %{name}留言
label_leave_message: 留言内容
label_message: 留言板
+ label_leave_message_list: 留言列表
field_add: 添加于 %{time} 之前
label_student_response: 作业答疑 # modified by bai
@@ -1748,6 +1750,7 @@ zh:
cancel_apply: 取消申请
apply_master: 申请成为版主
you_are_master: 您是该项目的版主
+ label_notification_list: 通知
#add by linchun (竞赛相关)
label_upload_softwarepackage: 上传软件包
diff --git a/config/routes.rb b/config/routes.rb
index c89c4e6c6..7c0c381bc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -83,10 +83,13 @@ RedmineApp::Application.routes.draw do
get 'close_poll'
get 'export_poll'
get 'import_poll'
+
end
collection do
delete 'delete_poll_question'
post 'update_poll_question'
+ get 'other_poll'
+ post 'import_other_poll'
end
end
@@ -319,6 +322,7 @@ RedmineApp::Application.routes.draw do
match 'user_visitorlist', :to => 'users#user_visitorlist', :via => :get
match 'user_homeworks', :to => 'users#user_homeworks', :via => :get
match 'watch_projects', :to => 'users#watch_projects', :via => :get
+
# added by bai
match 'show_score', :to => 'users#show_score', :via => :get
match 'topic_score_index', :to => 'users#topic_score_index', :via => [:get, :post]
@@ -346,6 +350,7 @@ RedmineApp::Application.routes.draw do
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
+ match 'users/:id/user_messages', :to => 'users#user_messages', :via => :get
#end
match 'my/account', :via => [:get, :post]
@@ -676,6 +681,13 @@ RedmineApp::Application.routes.draw do
match 'admin/default_configuration', :via => :post
get 'admin/organization'
get 'admin/schools'
+ get 'admin/leave_messages'
+ match 'admin/messages_list', as: :messages_list
+ match 'admin/project_messages', as: :project_messages
+ match'admin/course_messages', as: :course_messages
+ get 'admin/notices'
+ get 'admin/latest_login_users'
+ get 'admin/homework'
resources :auth_sources do
member do
diff --git a/db/migrate/20150810064247_add_created_at_to_activities.rb b/db/migrate/20150810064247_add_created_at_to_activities.rb
new file mode 100644
index 000000000..864ed82d6
--- /dev/null
+++ b/db/migrate/20150810064247_add_created_at_to_activities.rb
@@ -0,0 +1,8 @@
+class AddCreatedAtToActivities < ActiveRecord::Migration
+ def up
+ add_column :activities, :created_at, :timestamp
+ end
+ def end
+ remove_column :activities, :created_at
+ end
+end
diff --git a/db/migrate/20150811010817_update_activities_data.rb b/db/migrate/20150811010817_update_activities_data.rb
new file mode 100644
index 000000000..de4a080f2
--- /dev/null
+++ b/db/migrate/20150811010817_update_activities_data.rb
@@ -0,0 +1,21 @@
+class UpdateActivitiesData < ActiveRecord::Migration
+ def up
+ count = Activity.all.count / 10 + 1
+ transaction do
+ for i in 1 ... count do i
+ Activity.all.each do |activity|
+ type = activity.act_type
+ if type=='Contest' || type=='Message' || type=='News'|| type=='Journal'|| type=='Issue'|| type=='Principal'||type=='JournalsForMessage'
+ activity.created_at = activity.act.created_on if activity.act
+ elsif type=='Contestnotification' || type=='HomeworkCommon' || type=='Poll'
+ activity.created_at = activity.act.created_at if activity.act
+ end
+ activity.save
+ end
+ end
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20150811065543_add_course_activities.rb b/db/migrate/20150811065543_add_course_activities.rb
new file mode 100644
index 000000000..03ec7e354
--- /dev/null
+++ b/db/migrate/20150811065543_add_course_activities.rb
@@ -0,0 +1,15 @@
+class AddCourseActivities < ActiveRecord::Migration
+ def up
+ create_table :course_activities do |t|
+ t.integer :user_id
+ t.integer :course_id
+ t.integer :course_act_id
+ t.string :course_act_type
+ t.timestamps
+ end
+ end
+
+ def down
+ drop_table :course_activities
+ end
+end
diff --git a/db/migrate/20150811080754_course_activities.rb b/db/migrate/20150811080754_course_activities.rb
new file mode 100644
index 000000000..a4cae915d
--- /dev/null
+++ b/db/migrate/20150811080754_course_activities.rb
@@ -0,0 +1,40 @@
+#encoding=UTF-8
+class CourseActivities < ActiveRecord::Migration
+ def up
+ Course.all.each do |course|
+ transaction do
+ course.course_acts << CourseActivity.new(:user_id => course.tea_id,:course_id => course.id)
+ #作业
+ course.homework_commons.each do |homework_common|
+ homework_common.course_acts << CourseActivity.new(:user_id => homework_common.user_id,:course_id => course.id)
+ end
+ #通知
+ course.news.each do |new|
+ new.course_acts << CourseActivity.new(:user_id => new.author_id,:course_id => course.id)
+ end
+ #资源
+ course.attachments.each do |attachment|
+ attachment.course_acts << CourseActivity.new(:user_id => attachment.author_id,:course_id => course.id)
+ end
+ #讨论区
+ if course.boards.first
+ course.boards.first.messages.each do |message|
+ message.course_acts << CourseActivity.new(:user_id => message.author_id,:course_id => course.id)
+ end
+ end
+ #留言
+ course.journals_for_messages.each do |jour|
+ jour.course_acts << CourseActivity.new(:user_id => jour.user_id,:course_id => course.id)
+ end
+ #问卷
+ Poll.where("polls_type = 'Course' and polls_group_id = #{course.id}").each do |poll|
+ poll.course_acts << CourseActivity.new(:user_id => poll.user_id,:course_id => course.id)
+ end
+ end
+ end
+ end
+
+ def down
+ CourseActivity.destroy_all
+ end
+end
diff --git a/db/migrate/20150811083322_create_forge_messages.rb b/db/migrate/20150811083322_create_forge_messages.rb
new file mode 100644
index 000000000..f81b68712
--- /dev/null
+++ b/db/migrate/20150811083322_create_forge_messages.rb
@@ -0,0 +1,13 @@
+class CreateForgeMessages < ActiveRecord::Migration
+ def change
+ create_table :forge_messages do |t|
+ t.integer :user_id
+ t.integer :project_id
+ t.integer :forge_message_id
+ t.string :forge_message_type
+ t.integer :viewed
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20150814011838_create_course_messages.rb b/db/migrate/20150814011838_create_course_messages.rb
new file mode 100644
index 000000000..266f2b075
--- /dev/null
+++ b/db/migrate/20150814011838_create_course_messages.rb
@@ -0,0 +1,13 @@
+class CreateCourseMessages < ActiveRecord::Migration
+ def change
+ create_table :course_messages do |t|
+ t.integer :user_id
+ t.integer :course_id
+ t.integer :course_message_id
+ t.string :course_message_type
+ t.integer :viewed
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20150814024425_change_attachment_time.rb b/db/migrate/20150814024425_change_attachment_time.rb
new file mode 100644
index 000000000..fd1ffb7a7
--- /dev/null
+++ b/db/migrate/20150814024425_change_attachment_time.rb
@@ -0,0 +1,13 @@
+class ChangeAttachmentTime < ActiveRecord::Migration
+ def up
+ Attachment.where("container_type = 'Course'").each do |attachment|
+ if attachment.container && attachment.container.created_at.to_i > attachment.created_on.to_i
+ attachment.created_on = attachment.container.created_at + 3600 * 24
+ attachment.save
+ end
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20150814031258_update_course_activity_time.rb b/db/migrate/20150814031258_update_course_activity_time.rb
new file mode 100644
index 000000000..155e212a3
--- /dev/null
+++ b/db/migrate/20150814031258_update_course_activity_time.rb
@@ -0,0 +1,22 @@
+class UpdateCourseActivityTime < ActiveRecord::Migration
+ def up
+ count = CourseActivity.all.count / 10 + 1
+ transaction do
+ for i in 1 ... count do i
+ CourseActivity.page(i).per(10).each do |activity|
+ if activity.course_act
+ if activity.course_act.respond_to?("created_at")
+ activity.created_at = activity.course_act.created_at
+ elsif activity.course_act.respond_to?("created_on")
+ activity.created_at = activity.course_act.created_on
+ end
+ activity.save
+ end
+ end
+ end
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20150815030833_add_system_score_to_student_work.rb b/db/migrate/20150815030833_add_system_score_to_student_work.rb
new file mode 100644
index 000000000..1f2df648e
--- /dev/null
+++ b/db/migrate/20150815030833_add_system_score_to_student_work.rb
@@ -0,0 +1,9 @@
+class AddSystemScoreToStudentWork < ActiveRecord::Migration
+ def up
+ add_column :student_works,:system_score,:integer
+ end
+
+ def down
+ remove_column :student_works,:system_score
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 30ca29d12..db9b9ff9b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,14 +11,15 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20150801034945) do
+ActiveRecord::Schema.define(:version => 20150810064247) do
create_table "activities", :force => true do |t|
- t.integer "act_id", :null => false
- t.string "act_type", :null => false
- t.integer "user_id", :null => false
- t.integer "activity_container_id"
- t.string "activity_container_type", :default => ""
+ t.integer "act_id", :null => false
+ t.string "act_type", :null => false
+ t.integer "user_id", :null => false
+ t.integer "activity_container_id"
+ t.string "activity_container_type", :default => ""
+ t.datetime "created_at"
end
add_index "activities", ["act_id", "act_type"], :name => "index_activities_on_act_id_and_act_type"
@@ -454,13 +455,6 @@ ActiveRecord::Schema.define(:version => 20150801034945) do
add_index "delayed_jobs", ["priority", "run_at"], :name => "delayed_jobs_priority"
- create_table "discuss_demos", :force => true do |t|
- t.string "title"
- t.text "body"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
- end
-
create_table "documents", :force => true do |t|
t.integer "project_id", :default => 0, :null => false
t.integer "category_id", :default => 0, :null => false
@@ -863,6 +857,7 @@ ActiveRecord::Schema.define(:version => 20150801034945) do
t.datetime "created_on"
t.integer "comments_count", :default => 0, :null => false
t.integer "course_id"
+ t.datetime "updated_on"
end
add_index "news", ["author_id"], :name => "index_news_on_author_id"
diff --git a/lib/redmine.rb b/lib/redmine.rb
index 0f6c14b8a..99b7ea22f 100644
--- a/lib/redmine.rb
+++ b/lib/redmine.rb
@@ -386,6 +386,11 @@ Redmine::MenuManager.map :admin_menu do |menu|
:html => {:class => 'server_authentication'}
menu.push :plugins, {:controller => 'admin', :action => 'plugins'}, :last => true
menu.push :info, {:controller => 'admin', :action => 'info'}, :caption => :label_information_plural, :last => true
+ menu.push :leave_messages, {:controller => 'admin', :action => 'leave_messages'}, :caption => :label_leave_message_list
+ menu.push :messages_list, {:controller => 'admin', :action => 'messages_list'}, :caption => :label_message_plural
+ menu.push :notices, {:controller => 'admin', :action => 'notices'}, :caption => :label_notification_list
+ menu.push :latest_login_users, {:controller => 'admin', :action => 'latest_login_users'}, :caption => :label_latest_login_user_list
+ menu.push :homework, {:controller => 'admin', :action => 'homework'}, :caption => :label_user_homework
end
#Modified by young
diff --git a/public/images/nav_icon.png b/public/images/nav_icon.png
new file mode 100644
index 000000000..2c824efaf
Binary files /dev/null and b/public/images/nav_icon.png differ
diff --git a/public/images/news_icon_small.png b/public/images/news_icon_small.png
new file mode 100644
index 000000000..4a835556e
Binary files /dev/null and b/public/images/news_icon_small.png differ
diff --git a/public/javascripts/course.js b/public/javascripts/course.js
index 6ba202b28..be29fdc30 100644
--- a/public/javascripts/course.js
+++ b/public/javascripts/course.js
@@ -412,6 +412,24 @@ function regex_homework_name()
}
}
+//处理迟交扣分
+function check_late_penalty()
+{
+ var obj = $("input[name='late_penalty']");
+ var regex = /^\d+$/;
+ if(regex.test(obj.val()))
+ {
+ if(obj.val() > 50)
+ {
+ obj.val("50");
+ }
+ }
+ else
+ {
+ obj.val("0");
+ }
+}
+
//验证匿评数量
function regex_evaluation_num()
{
diff --git a/public/javascripts/header.js b/public/javascripts/header.js
index 06748d726..d33b80e3d 100644
--- a/public/javascripts/header.js
+++ b/public/javascripts/header.js
@@ -46,6 +46,54 @@ $(document).ready(function () {
addCourseSlipMenu();
});
+//消息提醒
+function MessageAddSlipMenu () {
+ var loggedas = $('#current_message_li a:first');
+ var sub_menu = $('#message_sub_menu');
+ loggedas.mouseenter(function() {
+ sub_menu.show();
+ $('#my_projects_message_ul').hide();
+ $('#my_courses_message_ul').hide();
+ });
+ sub_menu.mouseleave(function() {
+ sub_menu.hide();
+ $('#my_projects_message_ul').hide();
+ $('#my_courses_message_ul').hide();
+ });
+}
+
+function MessageAddProjectSlipMenu () {
+ var loggedas = $('#my_projects_message_li');
+ var project_sub_menu = $('#my_projects_message_ul');
+ var course_sub_menu = $('#my_courses_message_ul');
+ loggedas.mouseenter(function() {
+ course_sub_menu.hide();
+ project_sub_menu.show();
+ });
+ loggedas.mouseleave(function() {
+ project_sub_menu.hide();
+ course_sub_menu.hide();
+ });
+}
+function MessageAddCourseSlipMenu () {
+ var loggedas = $('#my_courses_message_li');
+ var project_sub_menu = $('#my_projects_message_ul');
+ var course_sub_menu = $('#my_courses_message_ul');
+ loggedas.mouseenter(function() {
+ project_sub_menu.hide();
+ course_sub_menu.show();
+ });
+ loggedas.mouseleave(function() {
+ course_sub_menu.hide();
+ project_sub_menu.hide();
+ });
+}
+
+$(document).ready(function () {
+ MessageAddSlipMenu();
+ MessageAddProjectSlipMenu ();
+ MessageAddCourseSlipMenu();
+});
//将右侧的最小高度设置成左侧高度,美化界面
$(document).ready(function () {
$("#RSide").css("min-height",$("#LSide").height()-30);
diff --git a/public/stylesheets/courses.css b/public/stylesheets/courses.css
index 921e79c7e..1393431d7 100644
--- a/public/stylesheets/courses.css
+++ b/public/stylesheets/courses.css
@@ -55,7 +55,7 @@ a:hover.problem_pic{border:1px solid #64bdd9;}
.problem_txt{ width:610px; margin-left:10px; color:#777777;word-break: break-all;word-wrap: break-word;}
a.problem_name{ color:#ff5722;max-width:60px;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
a:hover.problem_name{ color:#d33503;}
-a.problem_tit{ color:#0781b4; max-width:410px; display:block; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;}
+a.problem_tit{ color:#0781b4; max-width:410px; display:block; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;vertical-align: top;}
a.pro_mes_w{ height:20px; float:right;display:block; color:#999999;}
a:hover.problem_tit{ color:#09658c; }
.problem_main{ border-bottom:1px dashed #d4d4d4; padding-bottom:10px; margin-bottom:10px;}
diff --git a/public/stylesheets/images/resource_icon_list.png b/public/stylesheets/images/resource_icon_list.png
new file mode 100644
index 000000000..1b5bc6f58
Binary files /dev/null and b/public/stylesheets/images/resource_icon_list.png differ
diff --git a/public/stylesheets/polls.css b/public/stylesheets/polls.css
index 83fa5089b..9f7b2d021 100644
--- a/public/stylesheets/polls.css
+++ b/public/stylesheets/polls.css
@@ -130,7 +130,7 @@ a:hover.btn_de{ background:#ff5d31;}
a.btn_pu{ border:1px solid #3cb761; color:#3cb761; }
a:hover.btn_pu{ background:#3cb761;}
.pollsbtn_grey{ border:1px solid #b1b1b1; color:#b1b1b1; padding:0px 9px; height:19px; padding-top:3px; }
-.polls_title_w { width:300px; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
+.polls_title_w { max-width:280px; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
.polls_title_st { max-width:530px; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;}
.polls_de_grey{ color:#b1b1b1; margin-top:3px;}
.ml5{ margin-left:5px;}
diff --git a/public/stylesheets/public_new.css b/public/stylesheets/public_new.css
index 7389dff8a..83e8189b3 100644
--- a/public/stylesheets/public_new.css
+++ b/public/stylesheets/public_new.css
@@ -6,8 +6,8 @@ div,img,tr,td,table{ border:0;}
table,tr,td{border:0;cellspacing:0; cellpadding:0;}
ol,ul,li{ list-style-type:none}
a:link,a:visited{color:#7f7f7f;text-decoration:none;}
-a:hover,a:active{color:#000;}
-img{max-width: 100%;}
+a:hover,a:active{color:#15bccf;}
+/*img{max-width: 100%;}*/
/*常用*/
select,input,textarea{ border:1px solid #64bdd9; background:#fff; color:#000; padding-left:5px; }
@@ -445,3 +445,207 @@ div.ke-statusbar{height:1px; border-top:none;}
/*a.f_grey {color:#666666;}*/
/*a.f_grey:hover {color:#000000;}*/
+
+/*主类容左右分栏*/
+#LSide{ width:240px; }
+#RSide{ width:730px; margin-left:10px; background:#fff; padding:10px; margin-bottom:10px;}
+
+
+/*资源库*/
+.resources {width:730px; background-color:#ffffff;}
+.resourcesBanner {width:730px; height:40px; background-color:#eaeaea; margin-bottom:10px;}
+.bannerName {background:#64bdd9; color:#ffffff; height:40px; line-height:40px; width:90px; text-align:center; font-weight:normal; vertical-align:middle; font-size: 16px; float:left;}
+.resourcesSelect {width:40px; height:40px; float:right; position:relative;}
+.resourcesSelected {width:25px; height:20px;}
+.resourcesIcon {margin-top:15px; display:block; position:relative; background:url(images/resource_icon_list.png) 0px 0px no-repeat; width:25px; height:20px;}
+.resourcesIcon:hover { background:url(images/resource_icon_list.png) 0px -25px no-repeat;}
+.resourcesType {width:50px; background-color:#ffffff; float:left; list-style:none; position:absolute; border:1px solid #eaeaea; border-radius:5px; top:35px; padding:5px 10px; left:-30px; font-size:12px; color:#888888; display:none;}
+a.resourcesGrey {font-size:12px; color:#888888;}
+a.resourcesGrey:hover {font-size:12px; color:#15bccf;}
+.resourcesBanner ul li:hover ul.resourcesType {display:block;}
+ul li:hover ul {display:block;}
+.resourcesUploadBox {float:right; width:103px; height:34px; background-color:#64bdd9; line-height:34px; vertical-align:middle; text-align:center; margin-left:12px;}
+.uploadIcon {background:url(images/resource_icon_list.png) -35px 10px no-repeat; float:left; display:block; width:30px; height:30px; margin-left:-3px;}
+a.uploadText {color:#ffffff; font-size:14px;}
+.resourcesSearchloadBox {border:1px solid #e6e6e6; width:225px; float:right; background-color:#ffffff;}
+.searchResource {border:none; outline:none; background-color:#ffffff; width:184px; height:32px; padding-left:10px; display:block; float:left;}
+.searchIcon{width:31px; height:32px; background-color:#ffffff; background:url(images/resource_icon_list.png) -40px -15px no-repeat; display:block; float:left;}
+.resourcesSearchBanner {height:34px; margin-bottom:10px;}
+.resourcesListTab {width:730px; height:40px; background-color:#f6f6f6; border-bottom:1px solid #eaeaea; font-size:14px; color:#7a7a7a;}
+.resourcesListCheckbox {width:40px; height:40px; line-height:40px; text-align:center; vertical-align:middle;}
+.resourcesCheckbox {padding:0px; margin:0px; margin-top:14px; width:12px; height:12px;}
+.resourcesListName {width:135px; height:40px; line-height:40px; text-align:left;}
+.resourcesListSize {width:110px; height:40px; line-height:40px; text-align:center;}
+.resourcesListType {width:150px; height:40px; line-height:40px; text-align:center;}
+.resourcesListUploader {width:130px; height:40px; line-height:40px; text-align:center;}
+.resourcesListTime {width:165px; height:40px; line-height:40px; text-align:center;}
+.resourcesList {width:730px; height:39px; background-color:#ffffff; border-bottom:1px dashed #eaeaea; color:#9a9a9a; font-size:12px;}
+a.resourcesBlack {font-size:12px; color:#4c4c4c;}
+a.resourcesBlack:hover {font-size:12px; color:#000000;}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 80px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ font-size: 12px;
+ text-align: left;
+ background-color: #fff;
+ -webkit-background-clip: padding-box;
+ background-clip: padding-box;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
+}
+.dropdown-menu > li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 1.5;
+ color:#616060;
+ white-space: nowrap;
+}
+.dropdown-menu > li > a:hover{
+ color: #ffffff;
+ text-decoration: none;
+ background-color: #64bdd9;
+ outline:none;
+}
+
+/*发送资源弹窗*/
+/*.resourceShareContainer {width:100%; height:100%; background:#666; filter:alpha(opacity=50); opacity:0.5; -moz-opacity:0.5; position:absolute; left:0; top:0; z-index:-999;}*/
+.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:140px; 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;}
+.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;}
+.courseSend {width:260px; height:15px; line-height:15px; margin-bottom:10px;}
+.courseSendCheckbox {padding:0px; margin:0px; width:12px; height:12px; margin-right:10px; display:inline-block; margin-top:2px;}
+.sendCourseName {font-size:12px; color:#5f6060;}
+.courseSendSubmit {width:50px; height:25px; line-height:25px; text-align:center; vertical-align:middle; background-color:#64bdd9; margin-right:25px; float:left;}
+.courseSendCancel {width:50px; height:25px; line-height:25px; text-align:center; vertical-align:middle; background-color:#c1c1c1; float:left}
+a.sendSourceText {font-size:14px; color:#ffffff;}
+
+/*上传资源弹窗*/
+.resourceUploadPopup {width:400px; height:auto; border:3px solid #15bccf; padding-left:16px; padding-bottom:16px; background-color:#ffffff; position:absolute; top:50%; left:50%; margin-left:-200px; z-index:1000;}
+.uploadText {font-size:16px; color:#15bccf; line-height:16px; padding-top:20px; width:140px; display:inline-block;}
+.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:#64bdd9; border-radius:3px; float:left; margin-right:12px;}
+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;}
+
+
+/*新个人主页框架css*/
+.navContainer {width:100%; margin:0 auto; background-color:#15bccf;}
+.homepageContentContainer {width:100%; margin:0 auto; background-color:#eaebed;}
+.homepageContent {width:1000px; background-color:#eaebed; margin:0 auto;}
+.navHomepage {width:1000px; height:54px; background-color:#15bccf; margin:0 auto;}
+.navHomepageLogo {width:60px; height:54px; line-height:54px; vertical-align:middle; margin-left:2px; margin-right:40px;}
+.navHomepageMenu {margin-right:40px;display:inline-block;height:54px; line-height:54px; vertical-align:middle;}
+.navHomepageSearchBox {width:380px; border:none; outline:none; height:32px; margin-top:11px; background-color:#ffffff;}
+.navHomepageSearchInput {width:345px; height:32px; outline:none; border:none; float:left; padding-left:5px;; margin:0;}
+.homepageSearchIcon {width:30px; height:32px; background:url(../images/nav_icon.png) -8px 3px no-repeat; float:left;}
+a.homepageSearchIcon:hover {background:url(../images/nav_icon.png) -49px 3px no-repeat;}
+.navHomepageNews {width:30px; display:block; float:right; margin-top:12px; position:relative;}
+.homepageNewsIcon {background:url(../images/nav_icon.png) -5px -85px no-repeat; width:30px; height:29px; display:block;}
+.newsActive {width:10px; height:10px; border-radius:50%; border:2px solid #ffffff; background-color:#ff0000; position:absolute; left:17px; top:5px;}
+.navHomepageProfile {width:65px; display:block; float:right; margin-top:8px; margin-left:33px;}
+.homepageProfileMenuIcon {background:url(../images/nav_icon.png) -8px -175px no-repeat; width:20px; height:25px; float:left; margin-top:15px;}
+a.homepageProfileMenuIcon:hover {background:url(../images/nav_icon.png) -8px -175px no-repeat; width:12px; height:12px; float:left;}
+.homepageLeft {width:240px; float:left; margin-right:10px;}
+.homepageRight {width:750px; float:left;}
+.homepagePortraitContainer {width:238px; height:348px; border:1px solid #dddddd; background-color:#ffffff; margin-top:15px;}
+.homepagePortraitImage {width:208px; height:208px; margin:15px 16px 14px 16px;}
+.homepageFollow {}
+.homepageEditProfile {}
+.homepageImageName {font-size:16px; color:#484848; margin-left:15px; display:inline-block; margin-right:8px;}
+.homepageImageSex {float:left; top:116px; left:5px; width:14px; height:14px; display:inline-block;}
+.homepageSignature {font-size:12px; color:#888888; margin-left:15px; margin-top:5px; margin-bottom:15px;}
+.homepageImageBlock {margin:0 26px; float:left; text-align:center; display:inline-block;}
+.homepageImageNumber {font-size:12px; color:#484848;}
+.homepageImageText {width:26px; font-size:12px; color:#888888;}
+.homepageVerDiv {height:28px; vertical-align:middle; width:1px; float:left; display:inline-block; background-color:#d1d1d1; margin-top:3px;}
+.homepageLeftMenuContainer {width:238px; border:1px solid #dddddd; border-bottom:none; background-color:#ffffff; margin-top:10px;}
+.homepageLeftMenuBlock {border-bottom:1px solid #dddddd; height:50px; line-height:50px; vertical-align:middle;}
+a.homepageMenuText {color:#484848; font-size:16px; margin-left:20px;}
+.homepageLeftLabelContainer {width:238px; border:1px solid #dddddd; background-color:#ffffff; margin-top:10px;}
+.homepageRightBanner {}
+.newsType {width:60px; background-color:#ffffff; float:left; list-style:none; position:absolute; border:1px solid #eaeaea; border-radius:5px; top:35px; padding:5px 10px; left:-40px; font-size:12px; color:#888888; display:none; line-height:2;}
+.homepageRightBlock {}
+.homepageNewsList {width:710px; height:39px; line-height:39px; vertical-align:middle; border-bottom:1px dashed #eaeaea; margin:0 auto;}
+.homepageNewsPortrait {width:40px; display:block; margin-top:7px;}
+.homepageNewsPublisher {width:95px; font-size:12px; color:#15bccf; display:block;}
+.homepageNewsType {width:95px; font-size:12px; color:#888888; display:block;}
+.homepageNewsContent {width:405px; font-size:12px; color:#4b4b4b; display:block;}
+.homepageNewsTime {width:75px; font-size:12px; color:#888888; display:block; text-align:right;}
+a.homepageWhite {color:#ffffff;}
+a.homepageWhite:hover {color:#a1ebff}
+a.newsGrey {color:#4b4b4b;}
+a.newsGrey:hover {color:#000000;}
+a.newsBlue {color:#15bccf;}
+a.newsBlue:hover {color:#0781b4;}
+a.resourcesGrey {font-size:12px; color:#888888;}
+a.resourcesGrey:hover {font-size:12px; color:#15bccf;}
+
+
+/***** Flash & error messages ****/
+#errorExplanation, div.flash, .nodata, .warning, .conflict {
+ padding: 4px 4px 4px 30px;
+ margin-bottom: 12px;
+ font-size: 1.1em;
+ border: 2px solid;
+}
+
+div.flash {margin-top: 8px;}
+
+div.flash.error, #errorExplanation {
+ background: url(../images/exclamation.png) 8px 50% no-repeat;
+ background-color: #ffe3e3;
+ border-color: #dd0000;
+ color: #880000;
+}
+
+div.flash.notice {
+ background: url(../images/true.png) 8px 5px no-repeat;
+ background-color: #dfffdf;
+ border-color: #9fcf9f;
+ color: #005f00;
+}
+
+div.flash.warning, .conflict {
+ background: url(../images/warning.png) 8px 5px no-repeat;
+ background-color: #FFEBC1;
+ border-color: #FDBF3B;
+ color: #A6750C;
+ text-align: left;
+}
+
+.nodata, .warning {
+ text-align: center;
+ background-color: #FFEBC1;
+ border-color: #FDBF3B;
+ color: #A6750C;
+}
+
+#errorExplanation ul { font-size: 0.9em;}
+#errorExplanation h2, #errorExplanation p { display: none; }
+
+.conflict-details {font-size:80%;}
+/***** end Flash & error messages ****/
+
+/*消息铃铛样式*/
+.navHomepageNews {width:30px; display:block; float:right; margin-top:4px; position:relative; margin-right: 8px;}
+.newsActive {width:6px; height:6px; border-radius:50%; border:2px solid #ffffff; background-color:#ff0000; position:absolute; left:20px; top:8px;z-index:999}
diff --git a/spec/factories/course_messages.rb b/spec/factories/course_messages.rb
new file mode 100644
index 000000000..7b2523adc
--- /dev/null
+++ b/spec/factories/course_messages.rb
@@ -0,0 +1,10 @@
+FactoryGirl.define do
+ factory :course_message do
+ user_id 1
+course_id 1
+course_message_id 1
+course_message_type "MyString"
+viewed 1
+ end
+
+end
diff --git a/spec/factories/forge_messages.rb b/spec/factories/forge_messages.rb
new file mode 100644
index 000000000..05bc84cc1
--- /dev/null
+++ b/spec/factories/forge_messages.rb
@@ -0,0 +1,10 @@
+FactoryGirl.define do
+ factory :forge_message do
+ user_id 1
+project_id 1
+forge_message_id 1
+forge_message_type "MyString"
+viewed 1
+ end
+
+end
diff --git a/spec/models/course_message_spec.rb b/spec/models/course_message_spec.rb
new file mode 100644
index 000000000..cddcdc0a1
--- /dev/null
+++ b/spec/models/course_message_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe CourseMessage, :type => :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/spec/models/forge_message_spec.rb b/spec/models/forge_message_spec.rb
new file mode 100644
index 000000000..ce6cd7e26
--- /dev/null
+++ b/spec/models/forge_message_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe ForgeMessage, :type => :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end