# encoding=utf-8
class ShixunsService
include ApplicationHelper
include GamesHelper
LIMIT = 10
# reuturn star_info打星情况
def show_shixun params , current_user
shixun = Shixun . select ( [ :id , :identifier , :name , :fork_from , :user_id , :myshixuns_count , :trainee , :can_copy , :status , :propaedeutics ] ) . find_by_identifier ( params [ :identifier ] )
star_info = shixun . shixun_preference_info
image_url = url_to_avatar ( current_user )
username = current_user . try ( :show_name )
is_certification_teacher = current_user . is_certification_teacher
manager = current_user . manager_of_shixun? ( shixun , current_user )
owner = shixun . owner
watched = owner . watched_by? ( current_user )
myshixun = Myshixun . select ( [ :id , :user_id , :identifier , :shixun_id , :status ] ) . where ( :user_id = > current_user , :shixun_id = > shixun . id ) . first
if shixun . fork_from
fork_shixun = Shixun . select ( [ :id , :name , :user_id ] ) . find ( shixun . fork_from )
fork_info = { :name = > fork_shixun . name , :username = > fork_shixun . owner . try ( :show_name ) }
end
current_user = { :image_url = > image_url , :username = > username , :is_certification_teacher = > is_certification_teacher , :manager = > manager ,
:admin = > current_user . admin? , :mail = > current_user . try ( :mail ) , :login = > current_user . try ( :login ) }
creator = { :owner_id = > owner . id , :image_url = > url_to_avatar ( owner ) , :username = > owner . show_name , :watching = > owner . watcher_users . count ,
:shixun_count = > owner . shixuns . count , :login = > owner . login }
fork_count = Shixun . where ( :fork_from = > shixun . id ) . count
recommends = [ ]
recommend_shixuns = recommend_shixun ( shixun )
recommend_shixuns . each do | rec |
recommends << { :name = > rec . name , :myshixuns_count = > rec . myshixuns_count , :trainee = > rec . trainee , :image_url = > url_to_avatar ( rec ) , :identifier = > rec . identifier }
end
return { :current_user = > current_user , :shixun = > shixun . try ( :attributes ) , :fork_info = > fork_info , :creator = > creator , :star_info = > star_info ,
:myshixuns_count = > shixun . myshixuns_count , :shixun_score = > shixun . shixun_score , :shixun_level = > shixun . shixun_level ,
:fork_count = > fork_count , :recommend_shixuns = > recommends , :myshixun = > myshixun . try ( :attributes ) , :watched = > watched }
end
# 实训讨论帖子
def shixun_discuss params , current_user
page = params [ :page ] . to_i
offset = page * LIMIT
dis_id = params [ :container_id ] # 如: shixun_id
dis = Shixun . select ( [ :id , :user_id ] ) . find ( dis_id )
dis_type = params [ :container_type ] # 如:"Shixun"
# 总数,分页使用
if current_user . admin?
disscuss_count = Discuss . where ( dis_id : dis_id , dis_type : dis_type , root_id : nil ) . count
discusses = Discuss . where ( dis_id : dis_id , dis_type : dis_type , root_id : nil )
. includes ( :user , :praise_treads ) . limit ( LIMIT ) . offset ( offset )
else
disscusses = Discuss . where (
'dis_id = :dis_id and dis_type = :dis_type and root_id is null and (hidden = :hidden or user_id = :user_id)' ,
dis_id : dis_id , dis_type : dis_type , hidden : false , user_id : current_user . id
)
disscuss_count = disscusses . count
discusses = disscusses . includes ( :user , :praise_treads ) . limit ( LIMIT ) . offset ( offset )
end
base_data discusses , dis , current_user
{ children_list : @children_list , disscuss_count : disscuss_count }
end
# 获取某条消息的具体位置(比如在分页中的某一页)
def anchor params , current_user
discuss_id = params [ :discuss_id ] . to_i
dis_id = params [ :container_id ] # 如: shixun_id
dis = Shixun . select ( [ :id , :user_id ] ) . find ( dis_id )
dis_type = params [ :container_type ] # 如:"Shixun"
# 注意:此处查询的条件必须和列表的条件一致,否则结果定位可能会有问题
position_discusses = Discuss . find_by_sql ( " SELECT @rowno:=@rowno+1 as rowno, r.id from discusses r,(select @rowno:=0) m where root_id is null and
dis_id = #{dis_id} and dis_type='#{dis_type}' order by created_at desc")
disscuss_count = position_discusses . size
# 标记是否找到评论
find_status = false
if disscuss_count > 0
position = position_discusses . select { | discuss | discuss . id == discuss_id } . first . try ( :rowno )
page = position . to_i / LIMIT
offset = page * LIMIT
find_status = true if position
end
discusses = Discuss . limit ( LIMIT ) . where ( :dis_id = > dis_id , :dis_type = > dis_type , :root_id = > nil ) . includes ( :user , :praise_treads ) . offset ( offset )
base_data discusses , dis , current_user
Myshixun . find ( params [ :myshixun_id ] ) . update_attribute ( :onclick_time , Time . now )
return { :children_list = > @children_list , :disscuss_count = > disscuss_count , :page = > page . to_i , :find_status = > find_status }
end
# 判断当前用户是否有新的评论消息
def new_message params , current_user
onclick_time = Myshixun . find ( params [ :myshixun_id ] ) . try ( :onclick_time )
dis_id = params [ :container_id ]
dis_type = params [ :container_type ]
# 获取当前用户发布的帖子,如果帖子有非自己的回复则通知我
ids = Discuss . where ( " user_id =? and dis_id =? and dis_type =? and root_id is null " , current_user . id , dis_id , dis_type ) . pluck ( :id )
user_discuss = Discuss . where ( " user_id !=? and created_at >? " , current_user . id , onclick_time ) . where ( :root_id = > ids , :dis_id = > dis_id , :dis_type = > dis_type ) . first
return { :new_message = > user_discuss }
end
# 公共数据结构
# 注意: shixun_id如果是非实训类型的, 一定要主要其中的权限判断( 目前只适用于实训)
def base_data discusses , dis , current_user
@children_list = [ ]
# 目前只取十个, 不多N+1问题不大
# 需要彻底解决则需要改数据路结构, 比如Nested算法可以解决
if discusses . present?
discusses . each do | d |
# 总点赞数
praise_count = d . praises_count
user_praise = d . praise_treads . select { | pt | pt . user_id == current_user . id } . length > 0 ? true : false
manager = current_user . manager_of_shixun? ( dis , current_user )
game_url =
if manager
position = d . position . nil? ? 1 : d . position
challenge_id = dis . challenges . where ( position : position ) . pluck ( :id ) . first
game_identifier = Game . where ( user_id : current_user ,
challenge_id : challenge_id ) . pluck ( :identifier ) . first
" /tasks/ #{ game_identifier } "
else
" "
end
p_content =
if d . hidden
manager ? d . content : " 违规评论已被屏蔽! "
else
d . content
end
# 实训( TPM) 的管理员可以看到隐藏的评论
parents = { :id = > d . id , :content = > p_content , :time = > time_from_now ( d . created_at ) , :position = > d . position ,
:reward = > d . reward , :user = > d . user , :shixun_id = > dis . id , :hidden = > d . hidden , game_url : game_url ,
:manager = > manager , :praise_count = > praise_count , :user_praise = > user_praise , :admin = > current_user . admin? }
# 现在没有二级回复, 所以查询的时候直接从root_id取
children =
if current_user . admin?
Discuss . where ( root_id : d . id ) . includes ( :user ) . reorder ( " created_at asc " )
else
Discuss . where ( 'root_id = :root_id and (hidden = :hidden or user_id = :user_id)' ,
root_id : d . id , hidden : false , user_id : current_user . id ) . includes ( :user ) . reorder ( " created_at asc " )
end
@children_list << parents . merge (
{ :children = > ( children . map { | child |
[ :content = > ( child . hidden ? ( manager ? child . content : " 违规评论已被屏蔽! " ) : child . content ) ,
:time = > time_from_now ( child . created_at ) , :position = > child . position ,
:reward = > child . reward , :hidden = > child . hidden , :user = > d . user ,
:can_delete = > child . can_deleted? ( current_user ) ,
:id = > child . id ] } . flatten if children . present? )
} )
end
end
end
end