竞赛增加留言模块

This commit is contained in:
cxt 2017-01-11 10:16:25 +08:00
parent 720bd6e63e
commit c44af451ce
23 changed files with 252 additions and 17 deletions

View File

@ -9,7 +9,7 @@ class ContestsController < ApplicationController
include AvatarHelper
before_filter :find_contest, :only => [:show, :settings, :update, :destroy, :contest_activities, :search_member, :private_or_public, :switch_role, :set_invite_code_halt, :renew,
:member, :export_all_members]
:member, :export_all_members, :feedback]
before_filter :is_logged, :only => [:index, :new, :create]
before_filter :is_admin?, :only => [:settings, :set_invite_code_halt, :destroy]
before_filter :is_member?, :only => [:show, :contest_activities]
@ -115,6 +115,30 @@ class ContestsController < ApplicationController
@contest.update_attributes(:is_delete => true)
end
def feedback
if (User.current.admin? || @contest.is_public || (!@contest.is_public && User.current.member_of_contest?(@contest)))
ContestMessage.where(:user_id => User.current.id, :contest_id => @contest.id, :contest_message_type => 'JournalsForMessage', :contest_message_id => @contest.journals_for_messages.map{|jour|jour.id}).update_all(:viewed => true)
page = params[:page]
# Find the page of the requested reply
@jours = @contest.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
@jour_count = @jours.count
@limit = 10
if params[:r] && page.nil?
offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i])
page = 1 + offset / @limit
end
@jour = paginateHelper @jours,10
@state = false
@left_nav_type = 6
respond_to do |format|
format.html{render :layout => 'base_contests'}
format.api
end
else
render_403
end
end
def private_or_public
@contest.update_attributes(:is_public => !@contest.is_public)

View File

@ -109,6 +109,19 @@ class WordsController < ApplicationController
end
return
end
elsif @journal_destroyed.jour_type == "Contest"
@contest = Contest.find(@journal_destroyed.jour_id)
@jours_count = @contest.journals_for_messages.where('m_parent_id IS NULL').count
@user_activity_id = params[:user_activity_id] if params[:user_activity_id]
@activity = JournalsForMessage.where("id = #{params[:activity_id].to_i}").first if params[:activity_id]
unless @activity
if params[:user_activity_id] == params[:activity_id]
redirect_to feedback_contest_path(@contest)
else
redirect_to contest_activities_contest_path(@contest)
end
return
end
elsif @journal_destroyed.jour_type == 'HomeworkCommon'
@homework = HomeworkCommon.find @journal_destroyed.jour_id
if params[:user_activity_id]
@ -305,6 +318,18 @@ class WordsController < ApplicationController
end
end
def leave_contest_message
if User.current.logged?
@contest = Contest.find params[:id]
if params[:new_form][:content].size>0 && User.current.logged?
@contest.journals_for_messages << JournalsForMessage.new(:user_id => User.current.id, :notes => params[:new_form][:content], :reply_id => 0, :status => true, :is_readed => false)
end
redirect_to feedback_contest_path(@contest)
else
render_403
end
end
#作业的回复
def leave_homework_message
if User.current.logged?

View File

@ -4138,6 +4138,8 @@ def add_reply_adapter obj, options
Project.add_new_jour(nil, nil, obj.jour_id, options)
when 'Course'
Course.add_new_jour(nil, nil, obj.jour_id, options)
when 'Contest'
Contest.add_new_jour(nil, nil, obj.jour_id, options)
#when 'Bid'
# obj.jour.add_jour(nil, nil, nil, options)
#when 'Contest'

View File

@ -93,4 +93,8 @@ module ContestsHelper
end
mems
end
def contest_feedback_count
@contest.journals_for_messages.where('m_parent_id IS NULL').count
end
end

View File

@ -16,7 +16,7 @@ class Contest < ActiveRecord::Base
has_many :contestant_work_projects, :dependent => :destroy
has_many :boards, :dependent => :destroy, :order => "position ASC"
has_many :files
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
has_many :news, :dependent => :destroy, :include => :author
@ -131,4 +131,16 @@ class Contest < ActiveRecord::Base
logger.error "[Contest Model] ===> Auto create board when contest saved, because #{@board.full_messages}"
end
end
# 新增竞赛留言
def self.add_new_jour(user, notes, id, options={})
contest = Contest.find(id)
if options.count == 0
pjfm = contest.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0)
else
pjfm = contest.journals_for_messages.build(options)
end
pjfm.save
pjfm
end
end

View File

@ -76,7 +76,7 @@ class JournalsForMessage < ActiveRecord::Base
has_one :praise_tread_cache, as: :object, dependent: :destroy
validates :notes, presence: true, if: :is_homework_jour?
after_create :act_as_course_activity, :act_as_course_message,
after_create :act_as_course_activity, :act_as_course_message, :act_as_contest_activity,
act_as_at_message(:notes, :user_id), :act_as_user_feedback_message,
:act_as_principal_activity
# after_create :reset_counters!
@ -222,6 +222,13 @@ class JournalsForMessage < ActiveRecord::Base
end
end
#竞赛动态公共表记录
def act_as_contest_activity
if self.jour_type == 'Contest' && self.m_parent_id.nil?
self.contest_acts << ContestActivity.new(:user_id => self.user_id,:contest_id => self.jour_id)
end
end
# 课程/作品回复 留言消息通知
def act_as_course_message
if self.jour_type == 'StudentWorksScore'

View File

@ -47,7 +47,7 @@
<% when 'Poll' %>
<%#= render :partial => 'users/contest_poll', :locals => {:activity => act, :user_activity_id => activity.id, :is_course => 1} %>
<% when 'JournalsForMessage' %>
<%#= render :partial => 'users/contest_journalsformessage', :locals => {:activity => act, :user_activity_id => activity.id, :is_course => 1} %>
<%= render :partial => 'users/contest_journalsformessage', :locals => {:activity => act, :user_activity_id => activity.id, :is_contest => 1} %>
<% when 'Attachment' %>
<%#= render :partial => 'users/contest_attachment', :locals => {:activity => act, :user_activity_id => activity.id} %>
<% when 'Contest' %>

View File

@ -0,0 +1,19 @@
<%= content_for(:header_tags) do %>
<%= import_ke(enable_at: true, prettify: false, init_activity: true) %>
<%#= javascript_include_tag "init_KindEditor","user" %>
<% end %>
<%if jours %>
<% jours.each do |jour|%>
<script type="text/javascript">
$(function(){
sd_create_editor_from_data(<%= jour.id%>, null, "100%", "<%=jour.class.to_s%>");
});
</script>
<%= render :partial => 'users/contest_journalsformessage', :locals => {:activity => jour,:user_activity_id =>jour.id, :is_contest => 1} %>
<%#= render :partial => 'user_jours_new', :locals => {:jour => jour} %>
<%end%>
<% end%>
<% if (jours.count + page * 10) < count %>
<%= link_to "点击展开更多",feedback_contest_path(@contest.id, :page => page),:id => "show_more_jours",:remote => "true",:class => "loadMore mt10 f_grey"%>
<% end %>

View File

@ -12,7 +12,7 @@
<li><%= link_to "通知动态", contest_activities_contest_path(@contest, :type => 'news'), :class => "homepagePostTypeNotice postTypeGrey"%></li>
<!--<li><%#= link_to "资源库动态", {:controller => "courses", :action => "show", :type => "attachment"}, :class => "homepagePostTypeResource resourcesGrey"%></li>-->
<li><%= link_to "论坛动态", contest_activities_contest_path(@contest, :type => 'message'), :class => "homepagePostTypeForum postTypeGrey"%></li>
<!--<li><%#= link_to "留言动态", {:controller => "courses", :action => "show", :type => "journalsForMessage"}, :class => "homepagePostTypeMessage postTypeGrey"%></li>-->
<li><%= link_to "留言动态", contest_activities_contest_path(@contest, :type => 'journalsForMessage'), :class => "homepagePostTypeMessage postTypeGrey"%></li>
<!--<li><%#= link_to "问卷动态", {:controller => "courses", :action => "show", :type => "poll"}, :class => "homepagePostTypeQuiz postTypeGrey"%></li>-->
</ul>
</li>

View File

@ -0,0 +1,28 @@
<div class="homepageRight mt0 ml10">
<div class="homepageRightBanner mb10">
<div class="NewsBannerName pr"><span id="mesLabel">竞赛留言</span></div>
</div>
<div class="cl"></div>
<div id="messageContent">
<div class="resources"><%= link_to image_tag(url_to_avatar(User.current),:class=>"fl mr10", :width => "50", :height => "50"), :alt => "用户头像" %>
<div class="fl" style="width:658px;">
<%= form_for('new_form',:url => leave_contest_message_path(@contest.id), :html =>{:id => "contest_feedback_new"}, :method => "post") do |f|%>
<%= render :partial => "users/jour_form", :locals => {:f => f, :object => @contest} %>
<input id="private_flag" name="private" type="hidden" value="0"/>
<a href="javascript:void(0);" class="blue_n_btn fr mt5" id="submit_feedback_user" >留言</a>
<a href="javascript:void(0);" onclick="cancel_jour_submit()" class="greyBtn2 postReplySubmit mt5 mr15">取消</a>
<% end %>
</div>
</div>
<%=render :partial => "contest_jours_list", :locals => {:jours =>@jours, :page => 0, :count => @jour_count} %>
<div class="cl"></div>
</div><!--message_box end-->
</div>
<script type="text/javascript">
$(function(){
$("#submit_feedback_user").one('click',function() {
contest_jour_submit();
});
});
</script>

View File

@ -0,0 +1 @@
$("#show_more_jours").replaceWith("<%= escape_javascript( render :partial => 'contests/contest_jours_list',:locals => {:jours => @jours, :page => @page, :count => @jour_count} )%>");

View File

@ -71,7 +71,10 @@
<%= link_to "", contest_news_index_path(@contest,:is_new => 1), :class => "sy_class_add" %>
<% end %>
</li>
<!--<li id="sy_06" class="sy_icons_feedback"> <a href="">留言<span>26</span></a> <a href="javascript:void(0);" class="sy_class_add"></a></li>-->
<li id="sy_06" class="sy_icons_feedback">
<a href="<%= feedback_contest_path(@contest) %>">留言<span id="course_jour_count"><%=contest_feedback_count %></span></a>
<%= link_to( "", feedback_contest_path(@contest), :class => 'sy_class_add', :title =>"#{l(:label_course_feedback)}") if User.current.member_of_contest?(@contest) %>
</li>
</ul>
</div><!--sy_class_leftnav end-->
</div><!--sy_class_l end-->

View File

@ -0,0 +1,65 @@
<div class="resources mt10" id="user_activity_<%= user_activity_id%>">
<div class="homepagePostBrief">
<div class="homepagePostPortrait">
<%= link_to image_tag(url_to_avatar(activity.user), :width => "50", :height => "50"), user_path(activity.user), :alt => "用户头像" %>
<%#= render :partial => 'users/show_detail_info', :locals => {:user => activity.user} %>
</div>
<div class="homepagePostDes">
<div class="homepagePostTo break_word">
<%= link_to activity.user.show_name, user_path(activity.user), :class => "newsBlue mr15" %>
TO
<% contest=Contest.find(activity.jour_id) %>
<% str = defined?(is_contest) && is_contest == 1 ? "竞赛留言" : "#{contest.name.to_s} | 竞赛留言" %>
<%= link_to str, feedback_contest_path(contest), :class => "newsBlue ml15" %>
</div>
<% if activity.parent %>
<% content = activity.parent.notes %>
<% else %>
<% content = activity.notes %>
<% end %>
<%=render :partial =>"users/intro_content", :locals=>{:user_activity_id =>user_activity_id, :content=>content} %>
<div class="cl"></div>
<div id="intro_content_show_<%= user_activity_id%>" class="fr" style="display:none;"><a href="javascript:void(0);" class="linkBlue">[展开]</a></div>
<div id="intro_content_hide_<%= user_activity_id%>" class="fr" style="display:none;"><a href="javascript:void(0);" class="linkBlue">[收起]</a></div>
<div class="cl"></div>
<div class="homepagePostDate fl">
留言时间:<%= format_time(activity.created_on) %>
</div>
<div class="homepagePostDate fl ml15">
更新时间:<%= format_time(ContestActivity.where("contest_act_type='#{activity.class}' and contest_act_id =#{activity.id}").first.updated_at) %>
</div>
<div class="cl"></div>
<% if defined?(is_contest) && is_contest == 1 && (activity.user == User.current || User.current.admin? || User.current.admin_of_contest?(contest))%>
<div class="homepagePostSetting">
<ul>
<li class="homepagePostSettingIcon">
<ul class="homepagePostSettiongText">
<li>
<a href="javascript:void(0)" class="postOptionLink" title="删除"
onclick="delete_confirm_box_3('<%= words_destroy_path(:object_id => activity, :user_id => activity.user.id,:user_activity_id => user_activity_id, :activity_id => activity.id)%>', '确定要删除该留言吗?')">删除</a>
<%#= link_to(l(:label_bid_respond_delete),
{:controller => 'words', :action => 'destroy', :object_id => activity, :user_id => activity.user.id,:user_activity_id => user_activity_id, :activity_id => activity.id},
:confirm => l(:text_are_you_sure), :method => 'delete',
:class => "postOptionLink", :title => l(:button_delete)) %>
</li>
</ul>
</li>
</ul>
</div>
<% end%>
</div>
<div class="cl"></div>
</div>
<div class="homepagePostReply">
<div id="activity_post_reply_<%=user_activity_id %>">
<%=render :partial => 'users/user_journal_post_reply', :locals => {:activity => activity, :user_activity_id => user_activity_id} %>
</div>
</div>
</div>
<script type="text/javascript">
$(function(){
user_card_show_hide();
});
</script>

View File

@ -23,7 +23,7 @@
<script type="text/javascript">
$(function(){
setTimeout(function(){
elocalStorage(jour_content_editor,'user_newfeedback_<%=User.current.id %>_<%=@user.id %>');
elocalStorage(jour_content_editor,'user_newfeedback_<%=User.current.id %>_<%=object.id %>');
}, 10000);
});
</script>

View File

@ -94,7 +94,7 @@
<% when 'Contest' %>
<%= render :partial => 'users/contest_create', :locals => {:activity => act, :user_activity_id => act.id} %>
<% when 'JournalsForMessage' %>
<%#= render :partial => 'users/contest_journalsformessage', :locals => {:activity => act, :user_activity_id => user_activity.id} %>
<%= render :partial => 'users/contest_journalsformessage', :locals => {:activity => act, :user_activity_id => user_activity.id} %>
<% end %>
<% when 'Principal' %>
<% case user_activity.act_type.to_s %>

View File

@ -13,7 +13,7 @@
<li><%= link_to "作品动态", {:controller => "users", :action => "contest_community", :type => "contest_work"}, :class => "homepagePostTypeAssignment postTypeGrey" %></li>
<li><%= link_to "通知动态", {:controller => "users", :action => "contest_community", :type => "contest_news"}, :class => "homepagePostTypeNotice postTypeGrey" %></li>
<li><%= link_to "论坛动态", {:controller => "users", :action => "contest_community", :type => "contest_message"}, :class => "homepagePostTypeForum postTypeGrey" %></li>
<!--<li><%#= link_to "竞赛留言", {:controller => "users", :action => "contest_community", :type => "contest_journals"}, :class => "homepagePostTypeMessage postTypeGrey" %></li>-->
<li><%= link_to "竞赛留言", {:controller => "users", :action => "contest_community", :type => "contest_journals"}, :class => "homepagePostTypeMessage postTypeGrey" %></li>
<% end %>
</ul>
</li>

View File

@ -18,7 +18,7 @@
<div class="resources"><%= link_to image_tag(url_to_avatar(User.current),:class=>"fl mr10", :width => "50", :height => "50"), :alt => "用户头像" %>
<div class="fl" style="width:658px;">
<%= form_for('new_form',:url => leave_user_message_path(@user.id), :html =>{:id => "user_feedback_new"}, :method => "post") do |f|%>
<%= render :partial => "jour_form", :locals => {:f => f} %>
<%= render :partial => "jour_form", :locals => {:f => f, :object => @user} %>
<input id="private_flag" name="private" type="hidden" value="0"/>
<a href="javascript:void(0);" class="blue_n_btn fr mt5" id="submit_feedback_user" >留言</a>
<a href="javascript:void(0);" class="greyBtn2 postReplySubmit mt5 mr15" id="private_submit_feedback_user">私信</a>

View File

@ -1,8 +1,6 @@
<% if @save_succ %>
<% if @user_activity_id %>
<% if @activity.jour_type == 'Principal' %>
$("#activity_post_reply_<%= @user_activity_id%>").html("<%= escape_javascript(render :partial => 'users/user_journal_post_reply', :locals => {:activity => @activity,:user_activity_id =>@user_activity_id}) %>");
<% elsif @activity.jour_type == 'Course' %>
<% if @activity.jour_type == 'Principal' || @activity.jour_type == 'Course' || @activity.jour_type == 'Contest' %>
$("#activity_post_reply_<%= @user_activity_id%>").html("<%= escape_javascript(render :partial => 'users/user_journal_post_reply', :locals => {:activity => @activity,:user_activity_id =>@user_activity_id}) %>");
<% end %>
//init_activity_KindEditor_data('<%#= @user_activity_id%>', "", "87%", "UserActivity");

View File

@ -28,7 +28,12 @@
<% else %>
$('#course_jour_count').html("<%= @jours_count %>");
<% end %>
<% elsif @user && @jours_count%>
<% elsif @contest && @jours_count%>
<% if @user_activity_id %>
$("#activity_post_reply_<%= @user_activity_id%>").html("<%= escape_javascript(render :partial => 'users/user_journal_post_reply', :locals => {:activity => @activity,:user_activity_id =>@user_activity_id}) %>");
sd_create_editor_from_data('<%= @user_activity_id%>', "", "100%", "UserActivity");
<% end %>
<% elsif @user && @jours_count%>
$('#jour_count').html("<%= @jours_count %>");
<% elsif @homework%>
$("#homework_post_reply_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/homework_post_reply', :locals => {:activity => @homework, :user_activity_id => @user_activity_id, :is_teacher => @is_teacher}) %>");

View File

@ -638,6 +638,7 @@ RedmineApp::Application.routes.draw do
get 'renew'
get 'member'
get 'export_all_members'
get 'feedback'
end
resources :boards
@ -1438,6 +1439,7 @@ RedmineApp::Application.routes.draw do
match 'projects/:id/feedback', :to => 'projects#feedback', :via => :get, :as => 'project_feedback'
match 'project/:id/share', :to => 'projects#share', :as => 'share_show' #share
post 'words/:id/leave_user_message', :to => 'words#leave_user_message', :as => "leave_user_message"
post 'words/:id/leave_contest_message', :to => 'words#leave_contest_message', :as => "leave_contest_message"
post 'words/:id/leave_syllabus_message', :to => 'words#leave_syllabus_message', :as => "leave_syllabus_message"
post 'words/:id/leave_homework_message', :to => 'words#leave_homework_message', :as => "leave_homework_message"
post 'words/:id/reply_to_homework', :to => 'words#reply_to_homework', :as => "reply_to_homework"

View File

@ -1749,7 +1749,7 @@ function delete_confirm_box(url, str){
pop_box_new(htmlvalue, 300, 140);
}
//点击删除时的确认弹框: 走destroy方法
//点击删除时的确认弹框: 走destroy方法,remote为true
function delete_confirm_box_2(url, str){
var htmlvalue = '<div id="muban_popup_box" style="width:300px;"><div class="muban_popup_top"><h3 class="fl">提示</h3><a href="javascript:void(0);" class="muban_icons_close fr"></a></div>'+
'<div class="clear mt15"><p class="text_c f14 fontGrey7">' + str + '</p><div class="cl"></div><a href="'+ url +'" class="fr sy_btn_blue mt10" style="margin-right: 92px;" data-method="delete" data-remote="true">确定</a>'+
@ -1757,6 +1757,14 @@ function delete_confirm_box_2(url, str){
pop_box_new(htmlvalue, 300, 140);
}
//点击删除时的确认弹框: 走destroy方法
function delete_confirm_box_3(url, str){
var htmlvalue = '<div id="muban_popup_box" style="width:300px;"><div class="muban_popup_top"><h3 class="fl">提示</h3><a href="javascript:void(0);" class="muban_icons_close fr"></a></div>'+
'<div class="clear mt15"><p class="text_c f14 fontGrey7">' + str + '</p><div class="cl"></div><a href="'+ url +'" class="fr sy_btn_blue mt10" style="margin-right: 92px;" data-method="delete">确定</a>'+
'<a href="javascript:void(0);" class="fr sy_btn_grey mt10 mr10" onclick="hideModal();">取消</a></div></div>';
pop_box_new(htmlvalue, 300, 140);
}
//提示框:只有一个确定按钮,点击关闭弹框
function notice_box(str){
var htmlvalue = '<div id="muban_popup_box" style="width:300px;"><div class="muban_popup_top"><h3 class="fl">提示</h3><a href="javascript:void(0);" class="muban_icons_close fr"></a></div>'+

View File

@ -144,3 +144,35 @@ function regex_evaluation_num(){
return false;
}
}
//留言
function contest_jour_submit(){
if(jourReplyVerify()){
jour_content_editor.sync();//提交内容之前要sync不然服务器端取不到值
$("#contest_feedback_new").submit();
}
}
function jourReplyVerify() {
var content = jour_content_editor.html();//$.trim($("#message_content").val());
if (jour_content_editor.isEmpty()) {
$("#jour_content_span").text("留言不能为空");
$("#jour_content_span").css('color', '#ff0000');
$("#submit_feedback_user").one('click',function() {
contest_jour_submit();
});
return false;
}
else {
$("#jour_content_span").text("填写正确");
$("#jour_content_span").css('color', '#008000');
return true;
}
}
function cancel_jour_submit(){
jour_content_editor.html("");
$("#jour_content_span").text("");
$("#jour_content_span").hide();
}

View File

@ -185,8 +185,8 @@ a.homepagePostTypeResource {background:url(../images/homepage_icon.png) no-repea
a.homepagePostTypeForum {background:url(../images/homepage_icon.png) -10px -310px no-repeat; padding-left:23px;}
a.homepagePostTypeQuiz {background:url(../images/homepage_icon.png) -90px -124px no-repeat; padding-left:23px;}
a.homepagePostTypeQuestion {background:url(../images/homepage_icon.png) -10px -273px no-repeat; padding-left:23px;}
a.homepagePostTypeMine {background:url(../images/homepage_icon.png) -187px -277px no-repeat; padding-left:23px;}
a.homepagePostTypeAll {background:url(../images/homepage_icon.png) -185px -308px no-repeat; padding-left:23px;}
a.homepagePostTypeMine {background:url(../images/homepage_icon.png) -189px -277px no-repeat; padding-left:23px;}
a.homepagePostTypeAll {background:url(../images/homepage_icon.png) -187px -308px no-repeat; padding-left:23px;}
a.homepagePostTypeMessage {background:url(../images/homepage_icon.png) -3px -518px no-repeat; padding-left:23px;}
.homepagePostTypeMore {width:180px; border-top:1px dashed #dddddd; margin-top:5px;}
a.homepageTypeUnread {background:url(/images/homepage_icon.png) -6px -579px no-repeat; padding-left:23px;}