项目论坛丢失了的编辑功能

贴吧的置顶锁定功能,目前只针对管理员开放
贴吧列表搜索功能重构
增加1/2帖子显示数目
取出楼主,防止输入帖子id让回复作为主贴显示
首页取新帖子
帖子下载内容随意删除功能
This commit is contained in:
yanxd 2013-12-11 08:52:55 +08:00
parent 23785999f1
commit 0bc2b8f2b3
13 changed files with 228 additions and 150 deletions

View File

@ -2,9 +2,13 @@
class ForumsController < ApplicationController
# GET /forums
# GET /forums.json
before_filter :find_forum_if_available
before_filter :authenticate_user_edit, :only => [:edit, :update]
before_filter :authenticate_user_destroy, :only => [:destroy]
helper :sort
include SortHelper
PageLimit = 20
def index
@ -26,15 +30,33 @@ class ForumsController < ApplicationController
# GET /forums/1
# GET /forums/1.json
def show
@memo = Memo.new
@offset, @limit = api_offset_and_limit({:limit => 10})
@forum = Forum.find(params[:id])
@memos_all = @forum.topics
@topic_count = @memos_all.count
@topic_pages = Paginator.new @topic_count, @limit, params['page']
sort_init 'updated_at', 'desc'
sort_update 'created_at' => "#{Memo.table_name}.created_at",
'replies' => "#{Memo.table_name}.replies_count",
'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)"
@memo = Memo.new(:forum => @forum)
@topic_count = @forum.topics.count
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
@memos = @forum.topics.
reorder("#{Memo.table_name}.sticky DESC").
includes(:last_reply).
limit(@topic_pages.per_page).
offset(@topic_pages.offset).
order(sort_clause).
preload(:author, {:last_reply => :author}).
all
# @offset, @limit = api_offset_and_limit({:limit => 10})
# @forum = Forum.find(params[:id])
# @memos_all = @forum.topics
# @topic_count = @memos_all.count
# @topic_pages = Paginator.new @topic_count, @limit, params['page']
@offset ||= @topic_pages.offset
@memos = @memos_all.offset(@offset).limit(@limit).all
# @offset ||= @topic_pages.offset
# @memos = @memos_all.offset(@offset).limit(@limit).all
respond_to do |format|
format.html {
render :layout => 'base_forums'
@ -144,20 +166,20 @@ class ForumsController < ApplicationController
private
def find_forum
@forum = Forum.find(params[:id])
def find_forum_if_available
@forum = Forum.find(params[:id]) if params[:id]
rescue ActiveRecord::RecordNotFound
render_404
nil
end
def authenticate_user_edit
find_forum
find_forum_if_available
render_403 unless @forum.editable_by? User.current
end
def authenticate_user_destroy
find_forum
find_forum_if_available
render_403 unless @forum.destroyable_by? User.current
end
end

View File

@ -52,15 +52,22 @@ class MemosController < ApplicationController
end
end
REPLIES_PER_PAGE = 20 unless const_defined?(:REPLIES_PER_PAGE)
def show
pre_count = 20
@current_count = pre_count * (params['page'].to_i - 1) if params['page'].to_i > 0
@offset, @limit = api_offset_and_limit({:limit => pre_count})
@replies_all = @memo.replies
@reply_count = @replies_all.count
@reply_pages = Paginator.new @reply_count, @limit, params['page']
@offset ||= @reply_pages.offset
@replies = @replies_all.offset(@offset).limit(@limit).all
pre_count = REPLIES_PER_PAGE
@memo = @memo.root # 取出楼主防止输入帖子id让回复作为主贴显示
page = params[:page]
@reply_count = @memo.children.count
@reply_pages = Paginator.new @reply_count, pre_count, page
@replies = @memo.children.
includes(:author, :attachments).
reorder("#{Memo.table_name}.created_at ASC").
limit(@reply_pages.per_page).
offset(@reply_pages.offset).
all
@mome_new = Memo.new
@ -76,12 +83,15 @@ class MemosController < ApplicationController
end
def edit
@replying = true
end
def update
respond_to do |format|
if(@memo.update_attribute(:subject, params[:memo][:subject]) &&
@memo.update_attribute(:content, params[:memo][:content]))
if( @memo.update_attribute(:subject, params[:memo][:subject]) &&
@memo.update_attribute(:content, params[:memo][:content]) &&
@memo.update_attribute(:sticky, params[:memo][:sticky]) &&
@memo.update_attribute(:lock, params[:memo][:lock]))
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
format.html {redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}"}
else

View File

@ -6,7 +6,7 @@ class Memo < ActiveRecord::Base
validates_presence_of :author_id, :forum_id, :subject
validates :content, presence: true
validates_length_of :subject, maximum: 50
validates_length_of :content, maximum: 2048
validates_length_of :content, maximum: 3072
validate :cannot_reply_to_locked_topic, :on => :create
acts_as_tree :counter_cache => :replies_count, :order => "#{Memo.table_name}.created_at ASC"
@ -50,7 +50,7 @@ class Memo < ActiveRecord::Base
# }
def cannot_reply_to_locked_topic
errors.add :base, 'Topic is locked' if root.locked? && self != root
errors.add :base, l(:label_memo_locked) if root.locked? && self != root
end
# def update_memos_forum
@ -69,7 +69,7 @@ class Memo < ActiveRecord::Base
end
def sticky=(arg)
write_attribute :sticky, (arg == true || arg.to_s == '1' ? 1 : 0)
write_attribute :sticky, (arg == true || arg.to_s == 'true' ? true : false)
end
def sticky?

View File

@ -9,7 +9,7 @@
<td>
<table width="630px" border="0">
<tr>
<td valign="top" width="500px"><%= link_to h(topic.subject), forum_memo_path(@forum, topic) %></td>
<td valign="top" width="500px" class="<%= topic.sticky ? 'sticky' : '' %> <%= topic.locked? ? 'locked' : '' %>"><%= link_to h(topic.subject), forum_memo_path(@forum, topic) %></td>
<td align="right" rowspan="3">
<table class="borad-count">
<tr>

View File

@ -1,4 +1,5 @@
<!-- <h1>New memo</h1> -->
<% @replying ||= false %>
<h3><%=l(:label_memo_edit)%></h3>
<%= labelled_form_for(@memo, :url => forum_memo_path(@memo.forum_id, @memo)) do |f| %>
<% if @memo.errors.any? %>
@ -12,7 +13,17 @@
</div>
<% end %>
<div class="actions">
<p><%= f.text_field :subject, :required => true %></p>
<p><%= f.text_field :subject, :required => true, :size => 96 %></p>
<p>
<% unless @replying %>
<% if @memo.safe_attribute? 'sticky' %>
<%= f.check_box :sticky %> <%= label_tag 'memo_sticky', l(:label_board_sticky) %>
<% end %>
<% if @memo.safe_attribute? 'lock' %>
<%= f.check_box :lock %> <%= label_tag 'memo_locked', l(:label_board_locked) %>
<% end %>
<% end %>
</p>
<p><%= f.text_area :content, :required => true, :size => 80, id: 'editor01' %></p>
<script type="text/javascript">var ckeditor=CKEDITOR.replace('editor01');</script>
<br/>

View File

@ -1,71 +1,3 @@
<style type="text/css">
/** {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-box-sizing: border-box;
}*/
.lz {
position:relative;
min-height: 200px;
margin: 10px 2px;
border-radius: 5px;
box-shadow: 1px 1px 6px #97EBF4;
border: 1px solid #F1F1F1;
}
.lz-left{
float: left;
margin: 2%;
padding: 0;
}
.memo-section{
width: auto;
margin-left: 15%;
padding-top: 1%;
border-left: 2px dotted #EEE;
}
.memo-title{
margin: 1em 0;
padding-left: 1%;
padding-bottom: 1%;
font-weight: bold;
border-bottom: 1px dashed rgb(204, 204, 204);
}
.memo-content{
padding: 1%;
margin: 1%;
margin-bottom: 40px;
background-color: #F6F6F6;
}
.memo-timestamp{
position: absolute;
bottom: 0px;
right: 0;
margin: 20px;
}
.replies{
overflow:hidden;
max-width: 100%;
float: right;
/*max-width: 90%;*/
}
.reply-box{
float: right;
width: 640px;
padding: 3%;
/*border: 2px solid #C6F3F9;*/
border-top: 2px double #C6F3F9;
/*border-radius: 10px;*/
}
.comments img {
overflow:hidden;
/*width: 100%;*/
max-width: 500px;
height: auto !important;
width:expression(this.width > 500 ? "500px" : this.width+"px");
}
</style>
<!-- < %= forum_breadcrum%> -->
<div class="lz">
<div class="lz-left">
<div class=""><%= link_to image_tag(url_to_avatar(@memo.author), :class => "avatar"), user_path(@memo.author) %></div>
@ -95,7 +27,7 @@
) if @memo.destroyable_by?(User.current) %>
</div>
<div class="memo-title"><%= label_tag l(:field_subject) %>: <%=h @memo.subject %></div>
<div class="memo-title <%= @memo.sticky ? 'sticky' : '' %> <%= @memo.locked? ? 'locked' : '' %>"><%= label_tag l(:field_subject) %>: <%=h @memo.subject %></div>
<div class="memo-content">
<!-- < %= textilizable(@memo, :content) %> -->
<%= raw @memo.content %>
@ -149,7 +81,7 @@
<!-- <div class="wiki">< %=h reply.content.html_safe %></div> -->
<p>
<% if reply.attachments.any?%>
<% options = {:author => true, :deletable => true} %>
<% options = {:author => true, :deletable => false} %>
<%= render :partial => 'attachments/links', :locals => {:attachments => reply.attachments, :options => options} %>
<% end %>
</p>

View File

@ -90,6 +90,28 @@
</style>
<div class="lz">
<div class="contextual">
<%= watcher_link(@topic, User.current) %>
<%= link_to(
l(:button_quote),
{:action => 'quote', :id => @topic},
:remote => true,
:method => 'get',
:class => 'icon icon-comment',
:remote => true) if !@topic.locked? && authorize_for('messages', 'reply') %>
<%= link_to(
l(:button_edit),
{:action => 'edit', :id => @topic},
:class => 'icon icon-edit'
) if @message.editable_by?(User.current) %>
<%= link_to(
l(:button_delete),
{:action => 'destroy', :id => @topic},
:method => :post,
:data => {:confirm => l(:text_are_you_sure)},
:class => 'icon icon-del'
) if @message.destroyable_by?(User.current) %>
</div>
<div class="lz-left">
<div class=""><%= link_to image_tag(url_to_avatar(@topic.author), :class => "avatar"), user_path(@topic.author) %></div>
<p class=""><%=link_to @topic.author, user_path(@topic.author) %></p>

View File

@ -1,52 +1,3 @@
<style type='text/css'>
.tools a:link{
color: #116699;
text-decoration:none;
width:100px;
padding:3px 5px 0px 5px;
}
.tools a:visited{
color: #116699;
text-decoration:none;
padding:3px 5px 0px 5px;
width:100px;
}
.tools a:hover{
color:white;
padding:3px 3px 0px 20px;
width:88px;
text-decoration:none;
background-color:#539D26;
}
.tools a:active{
color:white;
padding:3px 3px 0px 20px;
width:88px;
text-decoration:none;
background-color:#BD06B4;
}
.tools ul{
list-style-type: none;
margin: 0px 0px 0px 10% ;
padding: 0;
}
.tools li{
background: url("/images/sidebar/tool_tag_alpha.png") 10px 30% no-repeat transparent;
color: #3e3e3e;
font-weight: 400;
line-height: 1.5em;
margin: 0px 0px 10px;
padding: 0px 0px 0px 30px;
font-size: 1.0em;
/*border-bottom: 1px solid #CCC;*/
}
.tools li:last-child{
border: none;
}
</style>
<div class="font_title_left">
<%= l(:label_project_tool)%>
</div>

View File

@ -782,6 +782,9 @@ en:
label_board_locked: Locked
label_board_sticky: Sticky
label_topic_plural: Topics
field_sticky: ''
field_locked: ''
field_lock: ''
label_message_plural: Messages
label_message_last: Last message
label_message_new: New message
@ -1577,6 +1580,7 @@ en:
label_forum: Forum
label_tags_forum_description: Forum description
label_tags_forum: Call forum
label_memo_locked: 'Topic is locked'

View File

@ -792,6 +792,9 @@ zh:
label_board_plural: 讨论区
label_board_locked: 锁定
label_board_sticky: 置顶
field_sticky: ''
field_locked: ''
field_lock: ''
label_topic_plural: 主题
label_message_plural: 帖子
label_message_last: 最新的帖子
@ -1743,3 +1746,4 @@ zh:
label_tags_forum_description: 贴吧描述
label_tags_forum: 贴吧名称
label_project_module_forums: 公共贴吧
label_memo_locked: 帖子已被锁定

View File

@ -18,12 +18,10 @@
RedmineApp::Application.routes.draw do
resources :forums do
collection do
get 'search_forum'
post 'search_forum'
match 'search_forum', :via => [:get, :post]
end
member do
get 'search_memo'
post 'search_memo'
match 'search_memo', :via => [:get, :post]
end
resources :memos do
collection do

BIN
public/images/zding.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -134,4 +134,128 @@ input[class='nyan-clean-gray']:active, .nyan-clean-gray:active {
#share_label {
line-height: 1.4em
}
.tools a:link{
color: #116699;
text-decoration:none;
width:100px;
padding:3px 5px 0px 5px;
}
.tools a:visited{
color: #116699;
text-decoration:none;
padding:3px 5px 0px 5px;
width:100px;
}
.tools a:hover{
color:white;
padding:3px 3px 0px 20px;
width:88px;
text-decoration:none;
background-color:#539D26;
}
.tools a:active{
color:white;
padding:3px 3px 0px 20px;
width:88px;
text-decoration:none;
background-color:#BD06B4;
}
.tools ul{
list-style-type: none;
margin: 0px 0px 0px 10% ;
padding: 0;
}
.tools li{
background: url("/images/sidebar/tool_tag_alpha.png") 10px 30% no-repeat transparent;
color: #3e3e3e;
font-weight: 400;
line-height: 1.5em;
margin: 0px 0px 10px;
padding: 0px 0px 0px 30px;
font-size: 1.0em;
/*border-bottom: 1px solid #CCC;*/
}
.tools li:last-child{
border: none;
}
/** {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-box-sizing: border-box;
}*/
.lz {
position:relative;
min-height: 200px;
margin: 10px 2px;
border-radius: 5px;
box-shadow: 1px 1px 6px #97EBF4;
border: 1px solid #F1F1F1;
}
.lz-left{
float: left;
margin: 2%;
padding: 0;
}
.memo-section{
width: auto;
margin-left: 15%;
padding-top: 1%;
border-left: 2px dotted #EEE;
}
.memo-title{
margin: 1em 0;
padding-left: 1%;
padding-bottom: 1%;
font-weight: bold;
border-bottom: 1px dashed rgb(204, 204, 204);
}
.memo-content{
padding: 1%;
margin: 1%;
margin-bottom: 40px;
background-color: #F8F8F8;
border-radius: 3px;
}
.memo-timestamp{
position: absolute;
bottom: 0px;
right: 0;
margin: 20px;
}
.replies{
overflow:hidden;
max-width: 100%;
float: right;
/*max-width: 90%;*/
}
.reply-box{
float: right;
width: 640px;
padding: 3%;
/*border: 2px solid #C6F3F9;*/
border-top: 2px double #C6F3F9;
/*border-radius: 10px;*/
}
.comments img {
overflow:hidden;
/*width: 100%;*/
max-width: 500px;
height: auto !important;
width:expression(this.width > 500 ? "500px" : this.width+"px");
}
table.content-text-list tbody tr td.sticky, div.memo-section .sticky{
background: url(../images/zding.gif) no-repeat 0 1px; padding-left: 35px;
/*background: url(../images/2uparrow.png) no-repeat 0 1px; padding-left: 20px;*/
font-weight: bold;
margin-left: 5px;
}
table.content-text-list tbody tr td.locked, div.memo-section .locked{
background: url(../images/locked.png) no-repeat 0 1px;
padding-left: 20px;
margin-left: 5px;
}