diff --git a/Gemfile b/Gemfile
index 491b512c..989571b6 100644
--- a/Gemfile
+++ b/Gemfile
@@ -14,6 +14,7 @@ gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'groupdate', '~> 4.1.0'
gem 'chartkick'
+gem 'grape', '~> 0.9.0'
gem 'grape-entity', '~> 0.7.1'
gem 'kaminari', '~> 1.1', '>= 1.1.1'
@@ -47,7 +48,7 @@ gem 'redcarpet', '~> 3.4'
gem 'rqrcode', '~> 0.10.1'
gem 'rqrcode_png'
-
+gem 'acts_as_tree', '~> 2.9', '>= 2.9.1'
gem 'acts-as-taggable-on', '~> 6.0'
# a tree structure
@@ -128,3 +129,4 @@ gem 'request_store'
gem 'harmonious_dictionary', '~> 0.0.1'
gem 'parallel', '~> 1.19', '>= 1.19.1'
+
diff --git a/Gemfile.lock b/Gemfile.lock
index c67bcd22..58b9a89f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -57,6 +57,8 @@ GEM
activerecord (>= 5.0, < 6.1)
acts_as_list (0.9.19)
activerecord (>= 3.0)
+ acts_as_tree (2.9.1)
+ activerecord (>= 3.0.0)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
ancestry (3.0.7)
@@ -68,6 +70,10 @@ GEM
autoprefixer-rails (9.7.4)
execjs
awesome_print (1.8.0)
+ axiom-types (0.1.1)
+ descendants_tracker (~> 0.0.4)
+ ice_nine (~> 0.11.0)
+ thread_safe (~> 0.3, >= 0.3.1)
axlsx (3.0.0.pre)
htmlentities (~> 4.3, >= 4.3.4)
mimemagic (~> 0.3)
@@ -103,11 +109,15 @@ GEM
archive-zip (~> 0.10)
nokogiri (~> 1.8)
chunky_png (1.3.11)
+ coercible (1.0.0)
+ descendants_tracker (~> 0.0.1)
concurrent-ruby (1.1.6)
connection_pool (2.2.2)
crass (1.0.6)
deep_cloneable (3.0.0)
activerecord (>= 3.1.0, < 7)
+ descendants_tracker (0.0.4)
+ thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.3)
diffy (3.3.0)
e2mmap (0.1.0)
@@ -121,6 +131,7 @@ GEM
multi_json
enumerize (2.3.1)
activesupport (>= 3.2)
+ equalizer (0.0.11)
erubi (1.9.0)
execjs (2.7.0)
faraday (0.15.4)
@@ -130,6 +141,16 @@ GEM
sass (>= 3.2)
globalid (0.4.2)
activesupport (>= 4.2.0)
+ grape (0.9.0)
+ activesupport
+ builder
+ hashie (>= 2.1.0)
+ multi_json (>= 1.3.2)
+ multi_xml (>= 0.5.2)
+ rack (>= 1.3.0)
+ rack-accept
+ rack-mount
+ virtus (>= 1.0.0)
grape-entity (0.7.1)
activesupport (>= 4.0)
multi_json (>= 1.3.2)
@@ -143,6 +164,7 @@ GEM
multi_xml (>= 0.5.2)
i18n (1.8.2)
concurrent-ruby (~> 1.0)
+ ice_nine (0.11.2)
io-like (0.3.1)
jaro_winkler (1.5.4)
jbuilder (2.10.0)
@@ -222,10 +244,14 @@ GEM
public_suffix (4.0.3)
puma (3.12.2)
rack (2.0.9)
+ rack-accept (0.4.5)
+ rack (>= 0.4)
rack-cors (1.1.1)
rack (>= 2.0.0)
rack-mini-profiler (2.0.1)
rack (>= 1.2.0)
+ rack-mount (0.8.3)
+ rack (>= 1.0.0)
rack-protection (2.0.8.1)
rack
rack-test (1.1.0)
@@ -415,6 +441,11 @@ GEM
uglifier (4.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.6.1)
+ virtus (1.0.5)
+ axiom-types (~> 0.1)
+ coercible (~> 1.0)
+ descendants_tracker (~> 0.0, >= 0.0.3)
+ equalizer (~> 0.0, >= 0.0.9)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
@@ -436,6 +467,7 @@ DEPENDENCIES
active_decorator
acts-as-taggable-on (~> 6.0)
acts_as_list
+ acts_as_tree (~> 2.9, >= 2.9.1)
ancestry
awesome_print
axlsx (~> 3.0.0.pre)
@@ -453,6 +485,7 @@ DEPENDENCIES
faraday (~> 0.15.4)
font-awesome-sass (= 4.7.0)
gitlab!
+ grape (~> 0.9.0)
grape-entity (~> 0.7.1)
groupdate (~> 4.1.0)
harmonious_dictionary (~> 0.0.1)
diff --git a/app/api/mobile/api.rb b/app/api/mobile/api.rb
new file mode 100644
index 00000000..7a3586bd
--- /dev/null
+++ b/app/api/mobile/api.rb
@@ -0,0 +1,107 @@
+#coding=utf-8
+# status值
+# 0:成功;-1:500错误;403:无权限;404:页面不存在
+
+module Mobile
+ require_relative 'middleware/error_handler'
+ require_relative 'apis/auth'
+ require_relative 'apis/memos'
+ require_relative 'apis/forum_sections'
+ require_relative 'apis/my_memos'
+ # require_relative 'apis/my_forums'
+
+ class API < Grape::API
+ version 'v1', using: :path
+ format :json
+ content_type :json, "application/json;charset=UTF-8"
+ # use ActionDispatch::Session::CookieStore
+ use Middleware::ErrorHandler
+
+ helpers do
+ def logger
+ API.logger
+ end
+
+ def authenticate!
+ begin
+ # current_user = User.find(2) if current_user.blank?
+ if params[:debug] == 'admin'
+ logger.info("Login as admin user, for test only")
+ User.current = User.find 1
+ elsif params[:debug] == 'normal'
+ logger.info("Login as normal user, for test only")
+ User.current = User.where(admin:false).first
+ end
+ rescue Exception => e
+ return {:status => -2, :message => 'Unauthorized. 用户认证失败.'}
+ end
+
+ end
+
+ # def manager_of_game
+ # myshixun_id = Game.where(:identifier => params[:identifier]).pluck(:myshixun_id).first
+ # myshixun = Myshixun.find(myshixun_id)
+ # unless (current_user.admin? || myshixun.user_id == current_user.id)
+ # return {}
+ # end
+ # end
+ #
+ def session
+ env['rack.session']
+ end
+
+ def current_user
+ openid = session[:wechat_openid]
+ if openid
+ uw = UserWechat.find_by_openid(openid)
+ return uw.user if uw
+ end
+
+ token = ApiKey.where(access_token: params[:token]).first
+ if token && !token.expired?
+ return User.find(token.user_id)
+ end
+
+ # 本地调试找不到用户信息
+ if Rails.env.development? && session[:user_id].blank?
+ # session[:user_id] = 12 #116
+ end
+
+ if session[:user_id].blank? || params[:debug].present?
+ if params[:debug] == 'admin'
+ Rails.logger.info("######________session_user_id________#############{session[:user_id]}")
+ logger.info("Login as admin user, for test only")
+ User.current = User.find 1
+ session[:user_id] = 1
+ elsif params[:debug] == 'normal'
+ logger.info("Login as normal user, for test only")
+ User.current = User.find 49
+ session[:user_id] = 49
+ else
+ session[:user_id] = 2
+ end
+ end
+
+ Rails.logger.info("####### session user_id is #{session[:user_id]}")
+ if session[:user_id]
+ user = (User.find(session[:user_id]) rescue nil)
+ return user if user
+ end
+ nil
+ end
+
+ def current_user_ip
+ env['REMOTE_ADDR']
+ end
+ end
+
+ mount Apis::Auth
+ mount Apis::Memos
+ mount Apis::ForumSections
+ mount Apis::MyMemos
+ # add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?
+
+ end
+end
+
+
diff --git a/app/api/mobile/apis/auth.rb b/app/api/mobile/apis/auth.rb
new file mode 100644
index 00000000..9f89d56d
--- /dev/null
+++ b/app/api/mobile/apis/auth.rb
@@ -0,0 +1,60 @@
+#coding=utf-8
+
+module Mobile
+
+ module Entities
+ class Auth < Grape::Entity
+ expose :token
+ expose :user, using: User
+ end
+ end
+
+ module Apis
+ class Auth < Grape::API
+ resource :auth do
+ desc "用户登录"
+ params do
+ requires :login, type: String, desc: 'Username or email'
+ requires :password, type: String, desc: 'Password'
+ end
+ post do
+ user,last_logon = ::User.try_to_login(params[:login], params[:password])
+ if user
+ ::ApiKey.delete_all(user_id: user.id)
+ key = ::ApiKey.create!(user_id: user.id)
+ api_user = ::UsersService.new.show_user({id:user.id})
+ present :data, {token: key.access_token, user: api_user}, using: Entities::Auth
+ present :status, 0
+ else
+ present :message, "无效的用户名或密码"
+ present :status,1
+ end
+ end
+
+ desc "用户登出"
+ params do
+ requires :token, type: String
+ end
+ delete do
+ authenticate!
+ ::ApiKey.delete_all(user_id: current_user.id)
+ {status: 0}
+ end
+
+ desc "忘记密码"
+ params do
+ requires :mail,type: String
+ end
+ post 'lost_password' do
+ us = UsersService.new
+ message = us.lost_password params
+ present :message, message
+ present :status, 0
+ end
+
+ end
+ end
+ end
+end
+
+
diff --git a/app/api/mobile/apis/forum_sections.rb b/app/api/mobile/apis/forum_sections.rb
new file mode 100644
index 00000000..a5ffc682
--- /dev/null
+++ b/app/api/mobile/apis/forum_sections.rb
@@ -0,0 +1,199 @@
+#coding=utf-8
+module Mobile
+ module Apis
+ class ForumSections < Grape::API
+ before {authenticate!}
+ content_type :json, 'application/json;charset=UTF-8'
+
+ resources :forum_sections do
+
+ desc "获取板块的筛选分类"
+ get "select_sections" do
+ ForumSectionsService.new.select_sections
+ end
+
+ desc "获取板块的全部分类"
+ get do
+ ForumSectionsService.new.index params
+ end
+
+ desc "申请版主"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ end
+ route_param :id do
+ post "user_apply" do
+ ForumSectionsService.new.user_apply params, current_user, current_user_ip
+ end
+ end
+
+ desc "发布公告"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :content, type: String, desc: "公告的内容"
+ end
+ route_param :id do
+ post "edit_notice" do
+ ForumSectionsService.new.edit_notice params
+ end
+ end
+
+ desc "版块的头部信息"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ end
+ route_param :id do
+ get "forum_section_header" do
+ ForumSectionsService.new.forum_section_header params, current_user
+ end
+ end
+
+ desc "新增二级版块"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :title, type: String, desc: "版块的名称"
+ end
+ route_param :id do
+ post 'create' do
+ ForumSectionsService.new.create params, current_user
+ end
+ end
+
+ desc "重命名"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :children_section_id, type: Integer, desc: "二级版块的id"
+ requires :title, type: String, desc: "版块的名称"
+ end
+ route_param :id do
+ post "rename" do
+ ForumSectionsService.new.rename params, current_user
+ end
+ end
+
+ desc "删除二级版块"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :children_section_id, type: Integer, desc: "二级版块的id"
+ end
+ route_param :id do
+ post "destroy" do
+ ForumSectionsService.new.destroy params, current_user
+ end
+ end
+
+ desc "排序"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :order_type, type: String, desc: "排序按desc,和asc排序"
+ end
+ route_param :id do
+ get "order_forums" do
+ ForumSectionsService.new.order_forums params, current_user
+ end
+ end
+
+ desc "搜索用户"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :page, type: Integer, desc: "初次(第一页)为0"
+ # requires :user_name, type: String, desc: "输入的关键字"
+ end
+ route_param :id do
+ get "search_users" do
+ ForumSectionsService.new.search_users params, current_user
+ end
+ end
+
+ desc "二级版块添加管理员"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :user_ids, type: Array, desc: "输入的关键字"
+ requires :children_section_id, type: Integer, desc: "二级版块的id"
+ end
+ route_param :id do
+ post "add_users" do
+ ForumSectionsService.new.add_users params, current_user
+ end
+ end
+
+
+ desc "管理员页面的版块管理"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ end
+ route_param :id do
+ get "managements" do
+ ForumSectionsService.new.managements params, current_user
+ end
+ end
+
+ desc "管理员页面的申请接口"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ end
+ route_param :id do
+ get "applied_forums" do
+ ForumSectionsService.new.applied_forums params, current_user
+ end
+ end
+
+ desc "管理员页面的申请处理"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :apply_id, type: Integer, desc: "申请的id"
+ requires :deal_type, type: Integer, desc: "处理的方式,1为同意,2为拒绝"
+ end
+ route_param :id do
+ post "deal_applies/:apply_id" do
+ ForumSectionsService.new.deal_applies params, current_user
+ end
+ end
+
+ desc "管理员页面的删除二级版主"
+ params do
+ requires :id, type: Integer, desc: "版块的id"
+ requires :moderator_id, type: Integer, desc: "版主的id"
+ end
+ route_param :id do
+ post "destroy_moderator/:moderator_id" do
+ ForumSectionsService.new.destroy_moderator params, current_user
+ end
+ end
+
+ desc "待审核的帖子"
+ params do
+ requires :id, type: Integer, desc: "版块的待审核id"
+ requires :page, type: String, desc: "初次(第一页)为0"
+ end
+ route_param :id do
+ get "unchecked_memos" do
+ ForumSectionsService.new.unchecked_memos params, current_user
+ end
+ end
+
+ desc "待审查的回复"
+ params do
+ requires :id, type: Integer, desc: "版块的待审核id"
+ requires :page, type: String, desc: "初次(第一页)为0"
+ end
+ route_param :id do
+ get "unchecked_replies" do
+ ForumSectionsService.new.unchecked_replies params, current_user
+ end
+ end
+
+ desc "已发布的帖子"
+ params do
+ requires :id, type: Integer, desc: "版块的待审核id"
+ requires :page, type: String, desc: "初次(第一页)为0"
+ end
+ route_param :id do
+ get "checked_memos" do
+ ForumSectionsService.new.checked_memos params, current_user
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/api/mobile/apis/memos.rb b/app/api/mobile/apis/memos.rb
new file mode 100644
index 00000000..8e4b82dc
--- /dev/null
+++ b/app/api/mobile/apis/memos.rb
@@ -0,0 +1,241 @@
+# encoding=utf-8
+module Mobile
+ module Apis
+ class Memos < Grape::API
+ before {authenticate!}
+ content_type :json, 'application/json;charset=UTF-8'
+
+ resources :memos do
+
+ desc "帖子详情推荐"
+ params do
+ requires :id, type: Integer, desc: "帖子详情推荐"
+ end
+ get ':id/related_memos' do
+ MemosService.new.related_memos params
+ end
+
+ desc "新建帖子"
+ get 'new' do
+ MemosService.new.new params, current_user, session
+ end
+
+ desc "新建保存帖子"
+ params do
+ requires :memo, type: Hash do
+ requires :subject, type: String, desc: "帖子名"
+ requires :content, type: String, desc: "帖子内容"
+ end
+ requires :forum_id, type: Integer, desc: "帖子类型"
+ end
+ post 'create' do
+ MemosService.new.create params, current_user
+ end
+
+ desc "帖子详情"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ end
+ get ':id' do
+ MemosService.new.show params, current_user
+ end
+
+ desc "收藏帖子"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ requires :is_watch, type: Integer, desc:"顶置: 1 关注,0 取消关注 "
+ end
+ route_param :id do
+ post 'watch_memo' do
+ MemosService.new.watch_memo params, current_user
+ end
+ end
+
+ desc "讨论区列表"
+ get do
+ MemosService.new.index params, current_user
+ end
+
+ desc "编辑帖子"
+ params do
+ requires :id, type: Integer, desc: "编辑帖子的ID"
+ end
+ route_param :id do
+ get 'edit' do
+ MemosService.new.edit params, current_user
+ end
+ end
+
+ desc "更新帖子"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ end
+ route_param :id do
+ post 'update' do
+ MemosService.new.update params, current_user
+ end
+ end
+
+ # TODO 本来可以跟实训评论一起用,但说不要动实训,所以另起一个方法
+ desc "隐藏帖子"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ end
+ route_param :id do
+ get :hidden do
+ Memo.find(params[:id]).update_attribute(:hidden, true)
+ {status: 0, message: "隐藏成功"}
+ end
+ end
+
+ desc "帖子设置审核通过/不通过"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ end
+ route_param :id do
+ post :memo_hidden do
+ MemosService.new.memo_hidden params, current_user
+ end
+ end
+
+ desc "回复帖子"
+ params do
+ requires :parent_id, type: Integer, desc: "给那个帖子的回复id"
+ requires :content, type: String, desc: "回复内容"
+ end
+ route_param :root_id do
+ post :reply do
+ MemosService.new.reply params, current_user
+ end
+ end
+
+ desc "隐藏回复帖子"
+ params do
+ requires :id, type: Integer, desc: "要隐藏的对象id。如:memo.id"
+ requires :hidden, type: String
+ end
+ route_param :id do
+ post 'hidden' do
+ MemosService.new.hidden(params, current_user)
+ return {:status => 1, :message => "success"}
+ end
+ end
+
+ desc "删除帖子/评论"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ end
+ route_param :id do
+ post "destroy" do
+ MemosService.new.destroy params, current_user
+ end
+ end
+ # delete ":id" do
+ # Memo.find(params[:id]).destroy
+ # end
+
+ desc "设置贴子顶置/取消顶置"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ requires :sticky, type: Integer, desc:"顶置: 1 置顶,0 取消置顶 "
+ end
+ route_param :id do
+ get "set-top-or-down" do
+ MemosService.new.set_top_or_down params, current_user
+ end
+ end
+
+ desc "设置贴子加精/取消加精推荐"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ requires :is_fine, type: Integer, desc:"加精: 1 加精,0 取消加精 "
+ end
+ route_param :id do
+ post "is_fine" do
+ MemosService.new.is_fine params, current_user
+ end
+ end
+
+ desc "用户禁言或取消禁言"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ requires :user_id, type: Integer, desc:"被禁言用户的id"
+ requires :banned, type: Integer, desc:"顶置: 1 禁言,0 取消禁言 "
+ end
+ route_param :id do
+ post "banned_user" do
+ MemosService.new.banned_user params, current_user
+ end
+ end
+
+ desc "帖子回复更多"
+ params do
+ requires :id, type: Integer, desc: "帖子ID"
+ requires :page, type: String, desc: "初次(第一页)为0"
+ end
+ route_param :id do
+ get "more_reply" do
+ MemosService.new.more_reply params, current_user
+ end
+ end
+
+ desc "版块的全部帖子"
+
+ params do
+ requires :id, type: Integer, desc: "版块的ID"
+ requires :page, type: String, desc: "初次(第一页)为0"
+ # requires :forum_type, type: String, desc: "列表页的分类选择"
+ end
+ get "forum_memos/:id" do
+ MemosService.new.forum_memos params, current_user
+ end
+
+ desc "版块的头部信息"
+
+ params do
+ requires :id, type: Integer, desc: "版块的ID"
+ end
+ get "forum_memos_head/:id" do
+ MemosService.new.forum_memos_head params, current_user
+ end
+
+ desc "版块的右侧信息"
+
+ params do
+ requires :id, type: Integer, desc: "版块的ID"
+ end
+ get "forum_memos_right/:id" do
+ MemosService.new.forum_memos_right params, current_user
+ end
+ # route_param :id do
+ #
+ # end
+ desc "版块的关注"
+ params do
+ requires :id, type: Integer, desc: "版块的ID"
+ requires :is_watch, type: Integer, desc:"顶置: 1 关注,0 取消关注 "
+ end
+ post "forum_memos/:id/is_watch" do
+ MemosService.new.is_watch params, current_user
+ end
+
+ desc "申请删除帖子"
+ params do
+ requires :id, type: Integer, desc: "帖子的id"
+ end
+ post ":id/confirm_delete" do
+ MemosService.new.confirm_delete params, current_user
+ end
+
+
+ # desc "版块的首页"
+ # params do
+ # requires :page, type: String, desc: "初次(第一页)为0"
+ # end
+ # get "index" do
+ # MemosService.new.index params, current_user
+ # end
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/api/mobile/apis/my_memos.rb b/app/api/mobile/apis/my_memos.rb
new file mode 100644
index 00000000..921e7700
--- /dev/null
+++ b/app/api/mobile/apis/my_memos.rb
@@ -0,0 +1,32 @@
+#coding=utf-8
+module Mobile
+ module Apis
+ class MyMemos < Grape::API
+ before {authenticate!}
+ content_type :json, 'application/json;charset=UTF-8'
+
+ resources :my_memos do
+ desc "我的话题"
+ get ":login/memos" do
+ MyMemosService.new.index params, current_user
+ end
+
+ desc "我感兴趣的话题"
+ get ":login/my_interested" do
+ MyMemosService.new.my_interested params, current_user
+ end
+
+ desc "我的回帖"
+ get ":login/replies_memos" do
+ MyMemosService.new.replies_memos params,current_user
+ end
+
+ desc "右侧推荐"
+ get "recommend_memos" do
+ MyMemosService.new.recommend_memos current_user
+ end
+
+ end
+ end
+ end
+end
diff --git a/app/api/mobile/exceptions/auth_exception.rb b/app/api/mobile/exceptions/auth_exception.rb
new file mode 100644
index 00000000..5dceab57
--- /dev/null
+++ b/app/api/mobile/exceptions/auth_exception.rb
@@ -0,0 +1,13 @@
+#coding=utf-8
+#
+module Mobile
+ module Exceptions
+ class AuthException < StandardError
+ attr_reader :err_code, :msg
+ def initialize(code, msg)
+ @err_code = code
+ @msg = msg
+ end
+ end
+ end
+end
diff --git a/app/api/mobile/middleware/error_handler.rb b/app/api/mobile/middleware/error_handler.rb
new file mode 100644
index 00000000..40eaa581
--- /dev/null
+++ b/app/api/mobile/middleware/error_handler.rb
@@ -0,0 +1,26 @@
+#coding=utf-8
+
+
+module Mobile
+ module Middleware
+ class ErrorHandler < Grape::Middleware::Base
+ def call!(env)
+ @env = env
+ begin
+ @app.call(@env)
+ rescue =>e
+ code = -1
+
+ message = {status: code, message: e.message }.to_json
+
+ Rails.logger.error e.inspect
+ Rails.logger.error e.backtrace.join("\n")
+ status = 200
+ headers = { 'Content-Type' => content_type }
+ Rack::Response.new([message], status, headers).finish
+ # throw :error, :message => e.message || options[:default_message], :status => 500
+ end
+ end
+ end
+ end
+end
diff --git a/app/controllers/admins/banned_users_controller.rb b/app/controllers/admins/banned_users_controller.rb
new file mode 100644
index 00000000..95ea0f70
--- /dev/null
+++ b/app/controllers/admins/banned_users_controller.rb
@@ -0,0 +1,65 @@
+class Admins::BannedUsersController < Admins::BaseController
+ # include Admins::BaseHelper
+
+ def index
+ @menu_type = 8
+ @sub_type = 6
+ #被禁言的用户
+ all_banned_users = BannedForum.includes(:memo, :author, user: :user_extensions)
+ banned_true = all_banned_users.where(is_banned: true)
+ @banned_users_size = banned_true.size
+ @banned_type = params[:banned_type] || "banned"
+ @search_params = params[:search] || nil
+ if @banned_type == "banned"
+ banned_users = banned_true
+
+ else
+ banned_users = all_banned_users.where(is_banned: false)
+ end
+
+ if @search_params.present?
+ banned_users = banned_users.joins(:user).where("LOWER(users.login) LIKE ? or LOWER(concat(users.lastname, users.firstname)) LIKE ?", "%#{@search_params}%", "%#{@search_params}%")
+ end
+
+ banned_users = banned_users.order("updated_at desc")
+
+ page = (params[:page] || 1).to_i
+ per_page = 15
+
+ @banned_users_count = banned_users.size
+ @banned_users_pages = Paginator.new @banned_users_count, per_page, page
+ @banned_users = banned_users.limit(@banned_users_pages.per_page).offset(@banned_users_pages.offset).to_a
+
+ end
+
+ def confirm_banned
+ if params[:user_id].blank? || params[:id].blank?
+ @status = -1
+ @message = "参数缺失"
+ else
+ before_users_banned = BannedForum.where(user_id:params[:user_id])
+
+ banned_params = {
+ user_id: params[:user_id],
+ author_id: current_user.id,
+ memo_id: params[:id],
+ is_banned: false,
+ banned_count: before_users_banned.present? ? (before_users_banned.last.banned_count + 1) : 1
+ }
+ new_banned = BannedForum.new(banned_params)
+ if new_banned.save
+ before_users_banned&.update_all(is_banned: false) if before_users_banned.present?
+ @status = 1
+ @message = "取消禁言成功"
+ else
+ @status = -1
+ @message = "取消禁言失败,请稍后重试"
+ end
+ end
+
+
+ end
+
+
+
+end
\ No newline at end of file
diff --git a/app/controllers/admins/forum_applies_controller.rb b/app/controllers/admins/forum_applies_controller.rb
new file mode 100644
index 00000000..26afc8f4
--- /dev/null
+++ b/app/controllers/admins/forum_applies_controller.rb
@@ -0,0 +1,88 @@
+class Admins::ForumAppliesController < Admins::BaseController
+ # include Admins::BaseHelper
+
+ def index
+ @menu_type = 8
+ @sub_type = 7
+ all_forum_applies = ApplyForum.includes(:forum_section,:reviews, user: :user_extensions)
+ @select_type = params[:select_type] || "unconfirm"
+ @section_name = params[:section_name] || nil
+ @search_name = params[:user_name] || nil
+ if @select_type == "unconfirm"
+ forum_applies = all_forum_applies.where(is_confirm: 0)
+ else
+ forum_applies = all_forum_applies.where(is_confirm: [1,2])
+ end
+
+ if @section_name.present?
+ forum_applies = forum_applies.joins(:forum_section).where("forum_sections.title like ?", "%#{@section_name}%")
+ end
+
+ if @search_name.present?
+ forum_applies = forum_applies.joins(:user).where("LOWER(users.login) LIKE ? or LOWER(concat(users.lastname, users.firstname)) LIKE ?", "%#{@search_name}%", "%#{@search_name}%")
+ end
+ forum_applies = forum_applies.order("apply_forums.updated_at desc")
+
+ page = (params[:page] || 1).to_i
+ per_page = 15
+
+ @forum_applies_count = forum_applies.size
+ @forum_applies_pages = Paginator.new @forum_applies_count, per_page, page
+ @forum_applies = forum_applies.limit(@forum_applies_pages.per_page).offset(@forum_applies_pages.offset).to_a
+
+ end
+
+ def confirm_apply
+ @forum_apply = ApplyForum.find(params[:id])
+ @is_confirm = params[:is_confirm].to_i
+
+ review_result = params[:review_result].to_i
+ review_params = {
+ review_status: review_result,
+ reason: params[:reason].present? ? params[:reason] : nil,
+ user_id: current_user.id,
+ reviewable_type: "ApplyForum",
+ reviewable_id: params[:id],
+ source: "apply_forum"
+ }
+ if Review.exists?(reviewable_type: "ApplyForum", reviewable_id: params[:id], source: "apply_forum")
+ this_review = Review.where(reviewable_type: "ApplyForum", reviewable_id: params[:id], source: "apply_forum").first
+ if this_review.update_attributes(review_params)
+ @status = 1
+ @message = "操作成功"
+ else
+ @status = -1
+ @message = "操作失败"
+ end
+ else
+ review = Review.new(review_params)
+ if review.save
+ @status = 1
+ @message = "操作成功"
+ else
+ @status = -1
+ @message = "操作失败"
+ end
+ end
+
+ if @status > 0
+ @forum_apply.update_attributes(is_confirm: (review_result+1),deal_time: Time.now)
+ exists_moder = ForumModerator.where(user_id: @forum_apply.user_id,forum_section_id: @forum_apply.forum_section_id)
+ if review_result == 1
+ exists_moder.delete_all if exists_moder.exists?
+ elsif review_result == 0
+ unless exists_moder.exists?
+ ForumModerator.create(user_id: @forum_apply.user_id, forum_section_id: @forum_apply.forum_section_id,is_children: @forum_apply.forum_section.try(:parent_id).present?)
+ end
+ end
+
+ Tiding.where(container_type: "ForumSection", container_id: @forum_apply.forum_section_id, status: 0).update_all(status: 1)
+ Tiding.create(:user_id => @forum_apply.user_id, :trigger_user_id => 1,
+ container_id: @forum_apply.forum_section_id, container_type: 'ForumSection',
+ :parent_container_id => @forum_apply.id, :parent_container_type => "ApplyForum",
+ :viewed => 0,status: 1, :tiding_type => "System",extra: "4")
+ end
+
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admins/forum_moderators_controller.rb b/app/controllers/admins/forum_moderators_controller.rb
new file mode 100644
index 00000000..e028890b
--- /dev/null
+++ b/app/controllers/admins/forum_moderators_controller.rb
@@ -0,0 +1,59 @@
+class Admins::ForumModeratorsController < Admins::BaseController
+ before_action :set_forum
+
+ def new
+
+ end
+
+ def create
+ user_ids = params[:member_ids]
+ is_children = @forum_section.parent_id.present?
+ if user_ids.present? && user_ids.size > 0
+ user_ids = user_ids.reject(&:blank?)
+ user_ids.each do |user_id|
+ unless ForumModerator.exists?(user_id: user_id, forum_section_id: @forum_section.id)
+ @forum_section.forum_moderators.create!(user_id: user_id, is_children: is_children)
+ end
+ unless is_children
+ children_forum_sections = @forum_section.children_forum
+ children_forum_sections.each do |children|
+ unless ForumModerator.exists?(user_id: user_id, forum_section_id: children.id)
+ children.forum_moderators.create!(user_id: user_id, is_children: true)
+ end
+ end
+ end
+ end
+
+ @forum_moderators = @forum_section.forum_moderators
+ @forum_status = 1
+ else
+ @forum_status = -1
+ end
+ end
+
+ def destroy
+ @forum_moderator = ForumModerator.find_by_id(params[:id])
+ @forum_moderator.destroy
+ end
+
+ def search_user
+ return_html = ""
+ user_name = params[:user_name].strip
+ if user_name.present?
+ users = User.where("( LOWER(login) LIKE ? or LOWER(concat(lastname, firstname)) LIKE ? or LOWER(mail) LIKE ? )",
+ "%#{user_name}%","%#{user_name}%","%#{user_name}%")
+ users.each do |u|
+ check_html = "#{u.try(:show_name)} "
+ return_html << check_html
+ end
+ end
+ render json: {html: return_html }
+ end
+
+ private
+
+ def set_forum
+ @forum_section = ForumSection.find_by_id(params[:forum_section_id])
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/admins/forum_sections_controller.rb b/app/controllers/admins/forum_sections_controller.rb
new file mode 100644
index 00000000..ac1933bc
--- /dev/null
+++ b/app/controllers/admins/forum_sections_controller.rb
@@ -0,0 +1,153 @@
+#论坛的板块设置
+class Admins::ForumSectionsController < Admins::BaseController
+ before_action :set_forum, except: [:index, :new,:create]
+
+ def index
+ @menu_type = 8
+ @sub_type = 5
+
+ forum_sections = ForumSection.roots.includes(:forum_moderators).order("position desc")
+ @max_position = forum_sections&.maximum(:position).to_i
+ @min_position = forum_sections&.minimum(:position).to_i
+ @forum_sections_count = forum_sections.count
+ page = (params[:page] || 1).to_i
+ per_page = 15
+ @forum_sections_pages = Paginator.new @forum_sections_count, per_page, page
+ @forum_sections = forum_sections.limit(@forum_sections_pages.per_page).offset(@forum_sections_pages.offset).to_a
+ end
+
+ def new
+ @parent_id = params[:parent_id]
+ end
+
+ def create
+ attachment_id = params[:attachments]&.first
+ positions = ForumSection.pluck(:position).select { |a| a.is_a? Integer }
+ positions = positions.max.to_i
+ if params[:parent_id].present?
+ @parent_forum = ForumSection.find_by_id(params[:parent_id])
+ end
+ if params[:title].blank?
+ forum_status = 0
+ forum_msg = "不能为空"
+ elsif params[:title].strip.length > 20
+ forum_status = 0
+ forum_msg = "不能超过最大限制:20个字符"
+ elsif ForumSection.exists?(title: params[:title].strip)
+ forum_status = 0
+ forum_msg = "不能重名"
+ else
+ forum_section_params = {
+ user_id: current_user.id,
+ title: params[:title].strip,
+ position: positions + 1,
+ parent_id: params[:parent_id],
+ is_recommend: false,
+ description: params[:description].to_s.truncate(200)
+ }
+ @forum_section = ForumSection.new(forum_section_params)
+ if @forum_section.save
+ if attachment_id.present?
+ attachment = Attachment.find(attachment_id)
+ attachment.container = @forum_section
+ attachment.save
+ @forum_section.attachment_id = attachment_id
+ @forum_section.save
+ end
+ forum_status = 1
+ forum_msg = "创建成功"
+ else
+ forum_status = -1
+ forum_msg = "创建失败,请重试"
+ end
+ end
+ @forum_status = {status: forum_status, msg: forum_msg}
+ end
+
+ def edit
+ @children_forum = params[:children_forum]
+ @attachment = @forum_section.image_attachment
+ end
+
+ def update
+ attachment_id = params[:attachments]&.first
+ if params[:title].blank?
+ forum_status = 0
+ forum_msg = "不能为空"
+ elsif params[:title].strip.length > 20
+ forum_status = 0
+ forum_msg = "不能超过最大限制:20个字符"
+ elsif params[:title].strip != @forum_section.title && ForumSection.exists?(title: params[:title].strip)
+ forum_status = 0
+ forum_msg = "不能重名"
+ else
+
+ if @forum_section.update_attributes(title: params[:title].strip, description: params[:description].to_s.truncate(200))
+
+ unless attachment_id.blank? || @forum_section.attachment_id.to_i == attachment_id.to_i
+ Attachment.where(id: @forum_section.attachment_id.to_i).destroy_all if @forum_section.attachment_id.present?
+ attachment = Attachment.find(attachment_id)
+ attachment.container = @forum_section
+ attachment.save
+ @forum_section.attachment_id = attachment_id
+ @forum_section.save
+ end
+ # if attachment_id.present?
+ # unless @forum_section.attachment_id.to_i == attachment_id.to_i
+ # if @forum_section.attachment_id.to_i != attachment_id.to_i
+ # Attachment.where(id: @forum_section.attachment_id.to_i).destroy_all
+ # end
+ # attachment = Attachment.find(attachment_id)
+ # attachment.container = @forum_section
+ # attachment.save
+ # @forum_section.attachment_id = attachment_id
+ # @forum_section.save
+ # end
+ # end
+ forum_status = 1
+ forum_msg = "更新成功"
+ else
+ forum_status = -1
+ forum_msg = "更新失败,请重试"
+ end
+ end
+ @edit_forum_status = {status: forum_status, msg: forum_msg}
+ end
+
+ def destroy
+ if @forum_section.destroy
+ delete_status = 1
+ delete_msg = "删除成功"
+ else
+ delete_status = -1
+ delete_msg = "删除失败,请稍后重试"
+ end
+ @delete_status = {status: delete_status, msg: delete_msg}
+ end
+
+ def order_forums
+ @children_forums = @forum_section.get_children_section("asc")
+ end
+
+ def recommend_forums
+ @forum_section.update_attribute(:is_recommend, params[:is_recommend])
+ end
+
+ def move
+ cate_opt = params[:opr]
+ cate_position = @forum_section.position.to_i
+ move_status = up_and_down(cate_opt,@forum_section,cate_position,"forum_section")
+ if move_status == 0
+ @c_msg = "移动成功"
+ else
+ @c_msg = "移动失败"
+ end
+ end
+
+ private
+
+ def set_forum
+ @forum_section = ForumSection.find_by_id(params[:id])
+ end
+
+end
diff --git a/app/controllers/admins/memos_controller.rb b/app/controllers/admins/memos_controller.rb
new file mode 100644
index 00000000..d61b906b
--- /dev/null
+++ b/app/controllers/admins/memos_controller.rb
@@ -0,0 +1,113 @@
+class Admins::MemosController < Admins::BaseController
+ # include Admins::BaseHelper
+ # 帖子
+ def index
+ @menu_type = 8
+ @sub_type = 3
+ @memo_hidden_type = params[:hidden] || ""
+
+ memos = Memo.where(parent_id: nil).includes(:author)
+ if @memo_hidden_type.present?
+ memos = memos.where(hidden: @memo_hidden_type.to_s == "hidden")
+ end
+ memos = memos.order("created_at desc")
+ @memos = paginate memos
+ respond_to do |format|
+ format.html
+ format.js
+ end
+ end
+
+ def apply_destroy_memos
+ @menu_type = 8
+ @sub_type = 2
+ memos = Memo.where(destroy_status: 1).includes(:author).order("created_at desc")
+ @memos = paginate memos
+ respond_to do |format|
+ format.html
+ format.js
+ end
+ end
+
+ def confirm_apply_destroy
+ memo = Memo.find(params[:id])
+ apply_status = params[:confirm]
+ if apply_status == "delete"
+ memo.destroy
+ extra = "d_2"
+ Tiding.create!(:user_id => memo.author_id, :trigger_user_id => 0,
+ container_id: memo.id, container_type: 'Memo',
+ :viewed => 0, :tiding_type => "System", :extra => "d_2")
+ else
+ memo.common!
+ memo.save
+ extra = "d_3"
+ Tiding.create!(:user_id => memo.author_id, :trigger_user_id => 0,
+ container_id: memo.id, container_type: 'Memo',
+ :viewed => 0, :tiding_type => "System", :extra => "d_3")
+ end
+ @status = 1
+ @message = "操作成功"
+ end
+
+ def memo_homepage_show
+ memo = Memo.find params[:id]
+ memo.update_column(:homepage_show, params[:checked]) unless memo.hidden?
+ render :json => {status: 1, message: "设置成功!"}
+ end
+
+ def memo_hidden
+ memo = Memo.find params[:id]
+ if params[:checked].to_s == 'true'
+ publish_time = Time.now
+ action_type = "passed"
+ extra = "1"
+ else
+ publish_time = nil
+ action_type = "refuse"
+ extra = "2"
+ end
+ memo.update_attributes(hidden: !(params[:checked].to_s == 'true'), published_at: publish_time) # 勾选代表不隐藏,所以要取反
+ CheckedAction.create!(user_id: current_user.id,checkable_type: "Memo",checkable_id: params[:id], action_type: action_type, action_at: Time.now)
+
+
+ if !memo.hidden? && memo.parent_id.present? && !memo.tidings.exists?(user_id: memo.parent.author_id,trigger_user_id: memo.author_id, extra: "3")
+ Tiding.create(:user_id => memo.parent.author_id, :trigger_user_id => memo.author_id,
+ container_id: memo.id, container_type: 'Memo',
+ :parent_container_id => memo.root_id, :parent_container_type => "Memo",
+ :viewed => 0, :tiding_type => "Comment", :extra => "3")
+
+ elsif !memo.hidden? && memo.parent_id.blank?
+ Tiding.create(:user_id => memo.author_id, :trigger_user_id => current_user.id,
+ container_id: memo.id, container_type: 'Memo',
+ :viewed => 0, :tiding_type => "Comment",:extra => extra)
+
+ end
+ render :json => {status: 1, message: "设置成功!"}
+ end
+
+ def delete_memo
+ memo = Memo.find params[:id]
+ memo.destroy if memo.hidden?
+ redirect_to memo.parent_id.present? ? memo_reply_list_managements_path : messages_list_managements_path
+ end
+
+ def memo_reply_list
+ @menu_type = 8
+ @sub_type = 4
+ @memo_hidden_type = params[:hidden] || ""
+ Rails.logger.info("======================sub_type==================#@sub_type")
+
+ memos = Memo.where("parent_id is not null").includes(:author, :parent)
+ if @memo_hidden_type.present?
+ memos = memos.where(hidden: @memo_hidden_type.to_s == "hidden")
+ end
+ memos = memos.order("created_at desc")
+ @memos = paginate memos
+ respond_to do |format|
+ format.html
+ format.js
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb
new file mode 100644
index 00000000..5f6466b7
--- /dev/null
+++ b/app/controllers/categories_controller.rb
@@ -0,0 +1,37 @@
+# encoding=utf-8
+class CategoriesController < ApplicationController
+ before_action :require_login, :except => [:all]
+ skip_before_action :session_expiration, :only => [:all]
+ include ApplicationHelper
+
+ # 所有类型,通过参数过滤
+ def all
+ render_react
+ end
+
+ def guide
+ render_react
+ end
+
+ def techShare
+ render_react
+ end
+
+ def show
+ render_react
+ end
+
+ def shixun_discuss
+ render_react
+ end
+
+ # 我的发布
+ def my_published
+
+ end
+
+ private
+ def render_react
+ render "/common/index", :layout => false
+ end
+end
diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb
new file mode 100644
index 00000000..f93964ce
--- /dev/null
+++ b/app/controllers/forums_controller.rb
@@ -0,0 +1,434 @@
+# encoding=utf-8
+# For react
+class ForumsController < ApplicationController
+ before_action :require_login, :only => [:new, :edit]
+ include ApplicationHelper
+
+ def show
+ render_react
+ end
+
+ def new
+ render_react
+ end
+
+ def index
+ render_react
+ end
+
+
+ def edit
+ render_react
+ end
+
+ def shixun_discuss
+ render_react
+ end
+
+ def manage
+ render_react
+ end
+
+ def detail
+ render_react
+ end
+
+ def theme
+ render_react
+ end
+
+ private
+ def render_react
+ render "/common/index", :layout => false
+ end
+
+end
+
+
+# # encoding: utf-8
+# # added by fq
+# class ForumsController < ApplicationController
+# layout "users_base"
+# include ApplicationHelper
+# # GET /forums
+# # GET /forums.json
+# before_action :find_forum_if_available
+# before_action :authenticate_user_edit, :only => [:edit, :update]
+# before_action :authenticate_user_destroy, :only => [:destroy]
+# before_action :require_login, :only => [:new, :create,:destroy,:update,:edit]
+# before_action :check_authentication
+#
+# helper :sort
+# include SortHelper
+#
+# PageLimit = 20
+# def create_feedback
+# if User.current.logged?
+# #@memo = Memo.new(params[:memo])
+# #@memo.forum_id = "1"
+# #@memo.author_id = User.current.id
+# #@forum = @memo.forum
+# cs = CommentService.new
+# @memo,message = cs.create_feedback params,User.current
+# respond_to do |format|
+# if !@memo.new_record?
+# if params[:direct]
+# format.html { redirect_to forums_path() }
+# else
+# format.html { redirect_to forum_path(@memo.forum) }
+# end
+# # format.html { redirect_to forum_path(@memo.forum) }
+# else
+# 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)"
+#
+# @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
+#
+# flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}"
+# # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id)
+# format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" }
+# format.json { render json: @memo.errors, status: :unprocessable_entity }
+# end
+# end
+# else
+# respond_to do |format|
+# format.html { redirect_to signin_path }
+# end
+# end
+# end
+#
+# def mail_feedback
+# @user = User.where(:id => params[:user_id]).first
+# unless @user.nil?
+# cs = CommentService.new
+# @memo, message = cs.create_feedback params, @user
+# end
+# respond_to do |format|
+# format.js
+# end
+# end
+#
+# def forum_create_memo
+# @memo = Memo.new
+# @my_forums_count = Forum.where(:creator_id => User.current.id).count
+# @my_memos_count = Memo.where(:author_id => User.current.id).count
+# @forums = Forum.reorder("topic_count desc,updated_at desc")
+# respond_to do |format|
+# format.js
+# format.html {render layout: 'base_new_forum'}
+# end
+# end
+#
+# def create_memo
+# @memo = Memo.new(params[:memo])
+# @memo.forum_id = @forum.id
+# @memo.author_id = User.current.id
+#
+# @memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
+#
+# respond_to do |format|
+# if @memo.save
+# if params[:asset_id]
+# ids = params[:asset_id].split(',')
+# update_kindeditor_assets_owner ids ,@memo.id,OwnerTypeHelper::MEMO
+# end
+# #end
+# format.html { redirect_to (forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))), notice: "#{l :label_memo_create_succ}" }
+# format.json { render json: @memo, status: :created, location: @memo }
+# else
+# 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)"
+#
+# @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
+# @memos
+# flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}"
+# # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id)
+# format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" }
+# format.json { render json: @memo.errors, status: :unprocessable_entity }
+# end
+# end
+# end
+#
+# # id: 1 问题反馈 3 操作指南 5 技术分享
+# def index
+#
+# render "/common/index", :layout => false
+# end
+#
+# # GET /forums/1
+# # GET /forums/1.json
+# def show
+# # 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)"
+# order = ""
+# @order_str = ""
+# if(params[:reorder_complex])
+# order = "#{Memo.table_name}.sticky desc, last_replies_memos.created_at #{params[:reorder_complex]}, #{Memo.table_name}.created_at #{params[:reorder_complex]}"
+# @order_str = "reorder_complex="+params[:reorder_complex]
+# elsif(params[:reorder_popu])
+# order = "#{Memo.table_name}.sticky desc, replies_count #{params[:reorder_popu]}"
+# @order_str = "reorder_popu="+params[:reorder_popu]
+# elsif(params[:reorder_time])
+# order = "#{Memo.table_name}.sticky desc, #{Memo.table_name}.updated_at #{params[:reorder_time]}"
+# @order_str = "reorder_time="+params[:reorder_time]
+# else
+# order = "#{Memo.table_name}.sticky desc, #{Memo.table_name}.updated_at desc"
+# @order_str = "reorder_time=desc"
+# end
+# @memo = Memo.new(:forum => @forum)
+# @topic_count = @forum.topics.count
+# @limit = 20
+# @is_remote = true
+# @topic_pages = Paginator.new @topic_count, @limit, params['page'] || 1
+# @memos = paginateHelper @forum.topics.includes(:last_reply).reorder(order).preload(:author, {:last_reply => :author}), @limit
+# @my_topic_count = Memo.where("forum_id = #{@memo.forum_id} and parent_id is null").count
+# @my_replies_count = Memo.where("forum_id = #{@memo.forum_id} and parent_id is not null").count
+# @errors = params[:errors]
+# # 推荐贴吧
+# @forums = Forum.where("id !=?", @forum.id).reorder("topic_count desc,updated_at desc").first(3)
+# respond_to do |format|
+# format.js
+# format.html {
+# render :layout => 'base_new_forum'
+# }# show.html.erb
+# format.json { render json: @forum }
+# end
+# end
+#
+# # GET /forums/new
+# # GET /forums/new.json
+# def new
+# @forum = Forum.new
+# respond_to do |format|
+# format.html # new.html.erb
+# format.js
+# format.json { render json: @forum }
+# end
+# end
+#
+# # GET /forums/1/edit
+# def edit
+# @forum = Forum.find(params[:id])
+# respond_to do |format|
+# format.html
+# format.js
+# end
+# end
+#
+# # POST /forums
+# # POST /forums.json
+# def create
+# @forum = Forum.new(params[:forum])
+# @forum.creator_id = User.current.id
+# if @forum.save
+# # Time 2015-03-24 17:07:05
+# # Author lizanle
+# # Description after save后需要进行资源记录的更新
+# # owner_type = 2 对应的是 forum
+# @save_flag = true
+# if params[:asset_id]
+# ids = params[:asset_id].split(',')
+# update_kindeditor_assets_owner ids, @forum.id, OwnerTypeHelper::FORUM
+# end
+# #end
+# respond_to do |format|
+# format.js{ redirect_to forums_path, notice: l(:label_forum_create_succ)}
+# format.html { redirect_to @forum, notice: l(:label_forum_create_succ) }
+# format.json { render json: @forum, status: :created, location: @forum }
+# end
+# else
+# @save_flag=false
+# respond_to do |format|
+# flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}"
+# format.js
+# format.html { render action: "new" }
+# format.json { render json: @forum.errors, status: :unprocessable_entity }
+# end
+# end
+# end
+#
+# # PUT /forums/1
+# # PUT /forums/1.json
+# def update
+# @forum = Forum.find(params[:id])
+# respond_to do |format|
+# if @forum.update_attributes(params[:forum])
+# format.js
+# format.html { redirect_to @forum, notice: l(:label_forum_update_succ) }
+# format.json { head :no_content }
+# else
+# flash.now[:error] = "#{l :label_forum_update_fail}: #{@forum.errors.full_messages[0]}"
+# format.js
+# format.html { render action: "edit" }
+# format.json { render json: @forum.errors, status: :unprocessable_entity }
+# end
+# end
+# end
+#
+# # DELETE /forums/1
+# # DELETE /forums/1.json
+# def destroy
+# @forum = Forum.find(params[:id])
+# @forum.destroy
+#
+# respond_to do |format|
+# format.html { redirect_to forums_url }
+# format.json { head :no_content }
+# end
+# end
+#
+# # 更新贴吧描述
+# def update_memo_description
+# @forum = Forum.find(params[:id])
+# if @forum.blank?
+# result = { :result => false }
+# else
+# forum_decription = params[:forum][:description]
+# @forum.update_attributes(:description => forum_decription )
+# result = { :result => true }
+# end
+# render :json => result
+# end
+#
+# def search_forum
+# # @forums = paginateHelper Forum.where("name LIKE '%#{params[:name]}%'")
+# q = "%#{params[:name].strip}%"
+# (redirect_to forums_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank?
+# @offset, @limit = api_offset_and_limit({:limit => 10})
+# @forums_all = Forum.where("name LIKE ?", q)
+# @forums_count = @forums_all.count
+# @forums_pages = Paginator.new @forums_count, @limit, params['page']
+#
+# @offset ||= @forums_pages.offset
+# @forums = @forums_all.offset(@offset).limit(@limit).all
+# respond_to do |format|
+# format.html {
+# render 'index'
+# }
+# format.json { render json: @forums }
+# end
+# end
+#
+# def search_memo
+# q = "%#{params[:name].strip}%"
+#
+# limit = PageLimit
+# @memo = Memo.new
+# @offset, @limit = api_offset_and_limit({:limit => limit})
+# @forum = Forum.find(params[:id])
+# @memos_all = @forum.topics.where("subject LIKE ?", q)
+# @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
+# respond_to do |format|
+# format.html {
+# render 'show', :layout => 'base_forums'
+# }
+# format.json { render json: @forum }
+# end
+# end
+#
+# #检查forum的名字
+# def check_forum_name
+# begin
+# forum_name = params[:forum_name]
+# if params[:forum_id]
+# result = Forum.where("name = '#{forum_name}' and id != #{params[:forum_id]}").first.blank? ? {:result => true} : {:result => false}
+# else
+# result = Forum.where(:name => forum_name).first.blank? ? {:result => true} : {:result => false}
+# end
+# rescue Exception => e
+# puts e
+# end
+# render :json => result
+# # if params[:forum_id]
+# # forum_name_exist = Forum.where("name = '#{params[:forum_name]}' and id != #{params[:forum_id]}").count >= 1 ? true : false
+# # else
+# # forum_name_exist = Forum.where("name = '#{params[:forum_name]}' ").count >= 1 ? true : false
+# # end
+# # render :text => forum_name_exist
+# end
+#
+#
+#
+#
+# #添加论坛tag
+# def add_forum_tag
+# @forum = Forum.find(params[:id])
+# unless @forum.nil?
+# @forum.tag_list.add(params[:tag_str].split(','))
+# @forum.save
+# end
+# respond_to do |format|
+# format.js {render :delete_forum_tag}
+# end
+# end
+#
+# #删除forum的tag
+# def delete_forum_tag
+# @tag_id = (ActsAsTaggableOn::Tag.find_by_name(params[:tag_name])).id
+# #forum的taggable_type = 5
+# @taggings = ActsAsTaggableOn::Tagging.find_by_tag_id_and_taggable_id_and_taggable_type(@tag_id,params[:id],'Forum')
+#
+# unless @taggings.nil?
+# @taggings.delete
+# end
+#
+# # 是否还有其他记录 引用了 tag_id
+# @tagging = ActsAsTaggableOn::Tagging.find_by_tag_id(@tag_id)
+# # 如果taggings表中记录已经不存在 ,那么检查tags表 作删除动作
+# if @tagging.nil?
+# @tag = ActsAsTaggableOn::Tag.find_by_id(@tag_id)
+# @tag.delete unless @tag.nil?
+# end
+# @forum = Forum.find(params[:id])
+# respond_to do |format|
+# format.js
+# end
+# end
+#
+# private
+#
+# 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_if_available
+# render_403 unless @forum.editable_by? User.current
+# end
+#
+# def authenticate_user_destroy
+# find_forum_if_available
+# render_403 unless @forum.destroyable_by? User.current
+# end
+# end
diff --git a/app/controllers/plates_controller.rb b/app/controllers/plates_controller.rb
new file mode 100644
index 00000000..ab2e7d2c
--- /dev/null
+++ b/app/controllers/plates_controller.rb
@@ -0,0 +1,30 @@
+class PlatesController < ApplicationController
+ def index
+ render_react
+ end
+
+ def show
+ render_react
+ end
+
+ def all
+ render_react
+ end
+
+ def is_fine
+ render_react
+ end
+
+ def my_memos
+ render_react
+ end
+
+ def my_topics
+ render_react
+ end
+
+ private
+ def render_react
+ render "/common/index", :layout => false
+ end
+end
diff --git a/app/helpers/api_helper.rb b/app/helpers/api_helper.rb
new file mode 100644
index 00000000..c03f7e05
--- /dev/null
+++ b/app/helpers/api_helper.rb
@@ -0,0 +1,553 @@
+# encoding: utf-8
+module ApiHelper
+ ONE_MINUTE = 60 * 1000
+ ONE_HOUR = 60 * ONE_MINUTE
+ ONE_DAY = 24 * ONE_HOUR
+ ONE_MONTH = 30 * ONE_DAY
+
+ ONE_YEAR = 12 * ONE_MONTH
+ #获取用户的工作单位
+ def get_user_work_unit user
+ work_unit = ""
+ if user.user_extensions.identity == 0 || user.user_extensions.identity == 1
+ work_unit = user.user_extensions.school.name unless user.user_extensions.school.nil?
+ elsif user.user_extensions.identity == 3
+ work_unit = user.user_extensions.occupation
+ elsif user.user_extensions.identity == 2
+ work_unit = user.firstname
+ end
+ work_unit
+ end
+
+ #获取用户地区
+ def get_user_location user
+ location = ""
+ location << (user.user_extensions.location || '')
+ location << (user.user_extensions.location_city || '')
+ location
+ end
+
+ def get_user_realname user
+ name = user.lastname + user.firstname
+ name.empty? || name.nil? || name == " " ? user.login : name
+ end
+
+ def get_assigned_homeworks(homeworks, n, index)
+ homeworks += homeworks
+ homeworks[index + 1 .. index + n]
+ end
+
+
+ def stars_to_json_like starts,show_jour,homework,show_name
+ result = []
+ starts.each do |s|
+ comment = get_homework_review homework,show_jour,s.rater
+ rater_name = show_name ? s.rater.login : l(:label_anonymous)
+ rater_id = show_name ? s.rater.id : ''
+ result << {:rater_id =>rater_id ,:rater_name => rater_name,:created_at => format_time(s.created_at),:stars => s.stars,:comment => comment}
+ end
+ result
+ end
+
+ #########################################################
+ #sw
+ #获取课程未匿评数量
+ #param: user => "用户", course_id => "查询的课程ID"
+ #return: 作业的数量
+ #########################################################
+ def get_course_anonymous_evaluation user,course
+ count = 0
+ if course
+ is_teacher = is_course_teacher user,course
+ if is_teacher #如果是老师,显示学生提交的作业数
+ course.homeworks.each do |bid|
+ count += bid.homeworks.count
+ end
+ else #如果是学生,显示未匿评的数量
+ course.homeworks.each do |bid|
+ count += get_student_not_batch_homework_list bid,user
+ end
+ end
+ end
+ [count,is_teacher]
+ end
+
+ def get_user_language user
+ (user.language.nil? || user.language == "") ? 'zh':user.language
+ end
+
+ # 学生获取课程作业的状态
+ def get_homework_status homework
+ homework_status = ""
+ if homework
+ if homework.homework_type == 1 && homework.homework_detail_manual
+ case homework.homework_detail_manual.comment_status
+ when 1
+ homework_status = show_homework_deadline homework
+ when 2
+ homework_status = "正在匿评"
+ when 3
+ homework_status = "匿评结束"
+ end
+ elsif homework.homework_type == 0
+ homework_status = "未启用匿评"
+ elsif homework.homework_type == 2
+ homework_status = "编程作业"
+ else
+ end
+ end
+ homework_status
+ end
+
+ #获取作业的是否可以匿评的描述
+ def homework_status_desc homework
+ if homework.homework_type == 1 && homework.homework_detail_manual #匿评作业
+ if homework.end_time >= Time.now
+ link = show_homework_deadline homework
+ elsif homework.student_works.count >= 2 #作业份数大于2
+ case homework.homework_detail_manual.comment_status
+ when 1
+ link = '启动匿评'
+ when 2
+ link = '关闭匿评'
+ when 3
+ link = " 匿评结束"
+ end
+ else
+ link = "提交作业数过少"
+ end
+ else
+ link = "未开启匿评作业"
+ end
+ link
+ end
+
+ #获取
+ def get_submit_sutdent_list homework
+ studentlist = []
+ if homework.is_a?(Hash) && homework.key?(:studentlist)
+ studentlist = homework[:studentlist]
+ else
+ homework.student_works.order("created_at desc").page(1).per(6).each do |work|
+ studentlist << work.user
+ end
+ end
+ studentlist
+ end
+
+ #计算作业的截止日期,剩余日期
+ def show_homework_deadline homework
+ day = 0
+ if (day = (Date.parse(homework.end_time.to_s) - Date.parse(Time.now.to_s)).to_i) > 0
+ "距作业截止还有" << day.to_s << "天"
+ else
+ "已截止,但可补交"
+ end
+ end
+
+ #获取作业中学生的匿评比率
+ # 匿评比率 = 学生总共评价的作业的作业份数 / 作业份数 * 分配数 * 100%
+ # 教辅匿评比率 = 教辅已经评价的作业份数 / 总的作业份数 * 100%
+ def get_evaluation_part homework,role
+ homework_eva_completed_task_num = 0
+ homework_eva_task_num = 0
+ #匿评作业 # 且匿评状态不是还没有开启匿评
+ if homework.homework_type == 1 && homework.homework_detail_manual && homework.homework_detail_manual.comment_status != 1
+ # 总共需要评价的任务数
+ homework_eva_task_num = homework.homework_detail_manual.evaluation_num * homework.student_works.count
+ unless homework_eva_task_num == 0 #总任务数不为0 的情况下
+ #获取已经评价了多少的份作业 student_work_score里记录了评价情况,每条记录有提交作业的id
+ #先求出提交作业的id集合
+ work_ids = "(" + homework.student_works.map(&:id).join(",") + ")"
+ #只要 student_work_score 中的 student_work_id在work_ids集合中,那么久说明这个任务被完成了
+
+ sql = "select count(1) from student_works_scores where reviewer_role = #{role} and student_work_id in #{work_ids} "
+ homework_eva_completed_task_num = ActiveRecord::Base.connection().select_value(sql)
+ end
+ end
+ if homework_eva_task_num == 0
+ 0
+ else
+ ( homework_eva_completed_task_num / homework_eva_task_num.to_f * 100 ) .round(1)
+ end
+
+ end
+
+ # 获取当前时间
+ def time_from_now time
+ lastUpdateTime = time.to_i*1000
+
+ currentTime = Time.now.to_i*1000
+ timePassed = currentTime - lastUpdateTime
+ timeIntoFormat = 0
+ updateAtValue = ""
+ if timePassed < 0
+ updateAtValue = "刚刚"
+ elsif timePassed < ONE_MINUTE
+ updateAtValue = "1分钟前"
+ elsif timePassed < ONE_HOUR
+ timeIntoFormat = timePassed / ONE_MINUTE
+ updateAtValue = timeIntoFormat.to_s + "分钟前"
+ elsif (timePassed < ONE_DAY)
+ timeIntoFormat = timePassed / ONE_HOUR
+ updateAtValue = timeIntoFormat.to_s + "小时前"
+ elsif (timePassed < ONE_MONTH)
+ timeIntoFormat = timePassed / ONE_DAY
+ updateAtValue = timeIntoFormat.to_s + "天前"
+ elsif (timePassed < ONE_YEAR)
+ timeIntoFormat = timePassed / ONE_MONTH
+ updateAtValue = timeIntoFormat.to_s + "个月前"
+ else
+ timeIntoFormat = timePassed / ONE_YEAR
+ updateAtValue = timeIntoFormat.to_s + "年前"
+ end
+ updateAtValue
+
+ end
+
+ # 获取当前时间
+ def time_from_future time
+ lastUpdateTime = time.to_i*1000
+
+ currentTime = Time.now.to_i*1000
+ timePassed = lastUpdateTime - currentTime;
+ timeIntoFormat = 0
+ updateAtValue = ""
+ if timePassed < 0
+ updateAtValue = "马上"
+ elsif timePassed < ONE_MINUTE
+ updateAtValue = "1分钟"
+ elsif timePassed < ONE_HOUR
+ timeIntoFormat = timePassed / ONE_MINUTE
+ updateAtValue = timeIntoFormat.to_s + "分钟"
+ elsif (timePassed < ONE_DAY)
+ timeIntoFormat = timePassed / ONE_HOUR
+ updateAtValue = timeIntoFormat.to_s + "小时"
+ elsif (timePassed < ONE_MONTH)
+ timeIntoFormat = timePassed / ONE_DAY
+ updateAtValue = timeIntoFormat.to_s + "天"
+ elsif (timePassed < ONE_YEAR)
+ timeIntoFormat = timePassed / ONE_MONTH
+ updateAtValue = timeIntoFormat.to_s + "个月"
+ else
+ timeIntoFormat = timePassed / ONE_YEAR
+ updateAtValue = timeIntoFormat.to_s + "年"
+ end
+ updateAtValue
+ end
+
+ # 计算到结束还有多长时间 **天**小时**分
+ def how_much_time time
+ result = ""
+ result = ((time - Time.now.to_i).to_i / (24*60*60)).to_s + " 天 "
+ result += (((time - Time.now.to_i).to_i % (24*60*60)) / (60*60)).to_s + " 小时 "
+ result += ((((time - Time.now.to_i).to_i % (24*60*60)) % (60*60)) / 60).to_s + " 分 "
+ end
+
+ #日期转换为时间
+ def convert_to_time date, num
+ if num == 0
+ date = date.to_s + " 00:00"
+ elsif num == 1
+ date = date.to_s + " 23:59"
+ end
+ return date
+ end
+
+ #获取用户
+ def get_user user_id
+ user = User.find user_id
+ user
+ end
+
+ #获取项目
+ def get_project project_id
+ project = Project.find project_id
+ project
+ end
+
+ #获取课程
+ def get_course course_id
+ course = Course.find course_id
+ course
+ end
+
+ #获取点赞数
+ def get_activity_praise_num(object)
+ obj_type = object.class
+ obj_id = object.id
+ record = PraiseTreadCache.find_by_object_id_and_object_type(obj_id,obj_type)
+ if record
+ return ((record.praise_num.nil? ? 0 : record.praise_num.to_i)-(record.tread_num.nil? ? 0 : record.tread_num.to_i))
+ else
+ return 0
+ end
+ end
+
+ #获取缺陷的优先级
+ def get_issue_priority_api value
+ issuetype = ""
+ if value == 4
+ issuetype = "紧急"
+ elsif value == 2
+ issuetype = "正常"
+ elsif value == 3
+ issuetype = "高"
+ elsif value == 1
+ issuetype = "低"
+ else
+ issuetype = "立刻"
+ end
+ end
+
+ def jdetails_to_strings(details, no_html=false, options={})
+ options[:only_path] = (options[:only_path] == false ? false : true)
+ options[:token] = options[:token] if options[:token]
+ strings = []
+ values_by_field = {}
+ details.each do |detail|
+
+ if detail.property == 'cf'
+ field_id = detail.prop_key
+ field = CustomField.find_by_id(field_id)
+ if field && field.multiple?
+ values_by_field[field_id] ||= {:added => [], :deleted => []}
+ if detail.old_value
+ values_by_field[field_id][:deleted] << detail.old_value
+ end
+ if detail.value
+ values_by_field[field_id][:added] << detail.value
+ end
+ next
+ end
+ end
+ strings << jshow_detail(detail, no_html, options)
+
+ end
+ values_by_field.each do |field_id, changes|
+ detail = JournalDetail.new(:property => 'cf', :prop_key => field_id)
+ if changes[:added].any?
+ detail.value = changes[:added]
+ strings << jshow_detail(detail, no_html, options)
+ elsif changes[:deleted].any?
+ detail.old_value = changes[:deleted]
+ strings << jshow_detail(detail, no_html, options)
+ end
+ end
+ strings
+ end
+
+ # Returns the textual representation of a single journal detail
+ def jshow_detail(detail, no_html=false, options={})
+ multiple = false
+ case detail.property
+ when 'attr'
+ field = detail.prop_key.to_s.gsub(/\_id$/, "")
+ label = l(("field_" + field).to_sym)
+ case detail.prop_key
+ when 'due_date', 'start_date'
+ value = format_date(detail.value.to_date) if detail.value
+ old_value = format_date(detail.old_value.to_date) if detail.old_value
+
+ when 'project_id', 'status_id', 'tracker_id', 'assigned_to_id',
+ 'priority_id', 'category_id', 'fixed_version_id'
+ value = find_name_by_reflection(field, detail.value)
+ old_value = find_name_by_reflection(field, detail.old_value)
+
+ when 'estimated_hours'
+ value = "%0.02f" % detail.value.to_f unless detail.value.blank?
+ old_value = "%0.02f" % detail.old_value.to_f unless detail.old_value.blank?
+
+ when 'parent_id'
+ label = l(:field_parent_issue)
+ value = "##{detail.value}" unless detail.value.blank?
+ old_value = "##{detail.old_value}" unless detail.old_value.blank?
+
+ when 'is_private'
+ value = l(detail.value == "0" ? :general_text_No : :general_text_Yes) unless detail.value.blank?
+ old_value = l(detail.old_value == "0" ? :general_text_No : :general_text_Yes) unless detail.old_value.blank?
+ end
+ when 'cf'
+ custom_field = CustomField.find_by_id(detail.prop_key)
+ if custom_field
+ multiple = custom_field.multiple?
+ label = custom_field.name
+ value = format_value(detail.value, custom_field.field_format) if detail.value
+ old_value = format_value(detail.old_value, custom_field.field_format) if detail.old_value
+ end
+ when 'attachment'
+ label = l(:label_attachment)
+ end
+ call_hook(:helper_issues_show_detail_after_setting,
+ {:detail => detail, :label => label, :value => value, :old_value => old_value })
+
+ label ||= detail.prop_key
+ value ||= detail.value
+ old_value ||= detail.old_value
+
+ unless no_html
+ label = content_tag('strong', label)
+ old_value = content_tag("i", old_value) if detail.old_value
+ old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank?
+ if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key)
+ # Link to the attachment if it has not been removed
+ if options[:token].nil?
+ value = atta.filename
+ else
+ value = atta.filename
+ end
+ # 放大镜搜索功能
+ # if options[:only_path] != false && atta.is_text?
+ # value += link_to(
+ # image_tag('magnifier.png'),
+ # :controller => 'attachments', :action => 'show',
+ # :id => atta, :filename => atta.filename
+ # )
+ # end
+ else
+ value = content_tag("i", value) if value
+ end
+ end
+ # 缺陷更新结果在消息中显示样式
+ if no_html == "message"
+ label = content_tag(:span, label, :class => "issue_update_message")
+ old_value = content_tag("span", old_value) if detail.old_value
+ old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank?
+ if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key)
+ # Link to the attachment if it has not been removed
+ if options[:token].nil?
+ value = atta.filename
+ else
+ value = atta.filename
+ end
+ else
+ value = content_tag(:span, value, :class => "issue_update_message_value") if value
+ end
+ end
+
+ if detail.property == 'attr' && detail.prop_key == 'description'
+ s = l(:text_journal_changed_no_detail, :label => label)
+ unless no_html
+ diff_link = link_to l(:label_diff),
+ {:controller => 'journals', :action => 'diff', :id => detail.journal_id,
+ :detail_id => detail.id, :only_path => options[:only_path]},
+ :title => l(:label_view_diff)
+ s << " (#{ diff_link })"
+ end
+ s.html_safe
+ elsif detail.value.present?
+ case detail.property
+ when 'attr', 'cf'
+ if detail.old_value.present?
+ l(:text_journal_changed, :label => label, :old => old_value, :new => value).html_safe
+ elsif multiple
+ l(:text_journal_added, :label => label, :value => value).html_safe
+ else
+ l(:text_journal_set_to, :label => label, :value => value).html_safe
+ end
+ when 'attachment'
+ l(:text_journal_added, :label => label, :value => value).html_safe
+ end
+ else
+ l(:text_journal_deleted, :label => label, :old => old_value).html_safe
+ end
+ end
+
+ #课程动态的更新
+ def update_course_activity_api type, id
+ course_activity = CourseActivity.where("course_act_type=? and course_act_id =?", type.to_s, id.to_i).first
+ if course_activity
+ course_activity.updated_at = Time.now
+ course_activity.save
+ end
+ end
+ #首页动态更新
+ def update_user_activity_api type, id
+ user_activity = UserActivity.where("act_type=? and act_id =?", type.to_s, id.to_i).first
+ if user_activity
+ user_activity.updated_at = Time.now
+ user_activity.save
+ end
+ end
+ #项目动态更新
+ def update_forge_activity_api type, id
+ forge_activity = ForgeActivity.where("forge_act_type=? and forge_act_id=?", type.to_s, id.to_i).first
+ if forge_activity
+ forge_activity.updated_at = Time.now
+ forge_activity.save
+ end
+ end
+ #组织动态更新
+ def update_org_activity_api type , id
+ org_activity = OrgActivity.where("org_act_type=? and org_act_id =?", type.to_s, id.to_i).first
+ if org_activity
+ org_activity.updated_at = Time.now
+ org_activity.save
+ end
+ end
+ #个人动态更新
+ def update_principal_activity_api type, id
+ principal_activity = PrincipalActivity.where("principal_act_type=? and principal_act_id =?", type.to_s, id.to_i).first
+ if principal_activity
+ principal_activity.updated_at = Time.now
+ principal_activity.save
+ end
+ end
+
+ #赞/取消赞
+ def praise_or_cancel(type,id,user,flag)
+ unless id.nil? and type.nil?
+ #首先创建或更新praise_tread 表
+ pt = PraiseTread.new
+ pt.user_id = user.id
+ pt.praise_tread_object_id = id.to_i
+ pt.praise_tread_object_type = type
+ pt.praise_or_tread = flag
+ pt.save
+ # end
+
+ #再创建或更新praise_tread_cache表
+ #@ptc = PraiseTreadCache.find_by_object_id_and_object_type(id,type)
+ ptc = PraiseTreadCache.where("object_id = ? and object_type = ?",id.to_i,type).first
+ ptc = ptc.nil? ? PraiseTreadCache.new : ptc
+ ptc.object_id = id.to_i
+ ptc.object_type = type
+ ptc.save
+ ptc.praise_plus(flag,1)
+ end
+ end
+
+ def praise_plus(flag,num)
+ case flag
+ when 1
+ self.update_attribute(:praise_num, self.praise_num.to_i + num)
+ end
+ end
+
+ def praise_minus(num)
+ self.update_attribute(:praise_num, self.praise_num.to_i - num)
+ end
+
+
+ class Errors
+ def self.define_error(arr)
+ @errors = {}
+ arr.each_with_index { |item, index|
+ if index %2 == 1
+ @errors[arr[index-1]] = item
+ end
+ }
+ if arr.count % 2== 1
+ @default_error = arr.last
+ else
+ @default_error = "未知错误"
+ end
+
+ end
+
+ def self.message(msg_id)
+ @errors[msg_id] || @default_error
+ end
+ end
+
+end
\ No newline at end of file
diff --git a/app/helpers/api_index_helper.rb b/app/helpers/api_index_helper.rb
new file mode 100644
index 00000000..47f26813
--- /dev/null
+++ b/app/helpers/api_index_helper.rb
@@ -0,0 +1,276 @@
+module ApiIndexHelper
+
+ #当前用户在论坛模块是否被禁言
+ def user_is_banned?(user)
+ return false if user.blank?
+ (user&.banned_forums&.where(is_banned: true).exists? && !user.admin?)
+ end
+
+ def format_for_current_user(current_user)
+ if current_user.present? && (current_user.id != 2)
+ {username: current_user.show_name,
+ login: current_user.login,
+ user_id: current_user.id,
+ image_url: "/images/#{url_to_avatar(current_user)}?#{Time.now.to_i}",
+ admin: current_user.admin?,
+ user_url: "/users/#{current_user.try(:login)}",
+ is_banned: user_is_banned?(current_user),
+ tidding_count: unviewed_tiddings(current_user)
+ }
+ else
+ {}
+ end
+ end
+
+ def format_common_user(user)
+ {username: user.show_name,
+ user_id: user.id,
+ login: user.login,
+ image_url: "/images/#{url_to_avatar(user)}?#{Time.now.to_i}",
+ admin: user.admin?,
+ user_url: "/users/#{user.try(:login)}"
+ }
+ end
+
+ def get_bread_crumb(forum_section, current_user)
+ if forum_section.present?
+ is_children = forum_section&.parent_id&.present?
+ children_bread_crumb = nil
+ if is_children
+ children_bread_crumb = {
+ title: forum_section.try(:title),
+ id: forum_section.try(:id)
+ }
+ forum_section_tag = {
+ title: forum_section.parent_forum.try(:title),
+ id:forum_section.try(:parent_id),
+ children_bread_crumb: children_bread_crumb
+ }
+ else
+ if forum_section&.children_forum.present?
+ children_bread_crumb = object_to_hash(forum_section&.children_forum&.select([:id, :title]))
+ end
+ # children_bread_crumb = object_to_hash(forum_section&.children_forum&.select([:id, :title])) if forum_section&.children_forum.present?
+ forum_section_tag = {
+ title: forum_section.try(:title),
+ id: forum_section.try(:id),
+ children_bread_crumb: children_bread_crumb
+ }
+ end
+ else
+ is_children = false
+ forum_section_tag = nil
+ end
+
+ {
+ is_children: is_children, #是否为二级分类
+ user:{login: current_user.try(:login), url: "/users/#{current_user.try(:login)}"},
+ forum: {title: "论坛交流", url: ""},
+ forum_tag: forum_section_tag
+ }
+ end
+
+ def get_user_ip(ip)
+ addr = "--"
+ unless ip.nil?
+ result = SM.find_by_ip(ip)
+ if result.present?
+ addr = "#{result[:province]}-#{result[:city]}"
+ end
+ end
+ return addr
+ end
+
+ def get_children_sections(children_sections)
+ children_forum_users = []
+ children_sections.each do |children|
+ children_users_array = []
+ children_users = children.forum_moderators.children_moder
+ children_users.each do |moder|
+ user = moder.user
+ children_user_hash = {
+ moderator_id: moder.id,
+ user_id: user.id,
+ login: user.login,
+ username: user.try(:show_name),
+ image_url: url_to_avatar(user),
+ user_url: "/users/#{user.try(:login)}"
+ }
+ children_users_array.push(children_user_hash)
+ end
+ children_forums = {
+ id: children.id,
+ title: children.title,
+ forum_moderators: children_users_array #二级分类的管理者
+ }
+ children_forum_users.push(children_forums)
+ end
+ children_forum_users
+ end
+
+ #论坛的全部一级分类和二级分类
+ def all_sections(is_detail)
+ forum_all_tags = []
+ forum_first_tags = ForumSection.roots.select([:id, :title, :ancestry, :position]).order("position desc")
+ forum_first_tags.each do |forum|
+ forum_second_tags = forum.children.includes(:user)
+ forum_hash =
+ {id: forum.id,
+ name: forum.title,
+ children_tags: set_children_sections(forum_second_tags,is_detail)
+ }
+ forum_all_tags.push(forum_hash)
+ end
+ forum_all_tags
+ end
+
+ # 将数据库对象转换成哈希对象
+ def object_to_hash objects
+ objects.map{|o| o.attributes.dup}
+ end
+
+ def set_children_sections(objects,is_detail)
+ children_sections_array = []
+ objects.find_each do |sec|
+ image = sec.attachments&.last
+ s_section = {
+ id: sec.id,
+ title: sec.title
+ }
+ if is_detail
+ s_section.merge!({
+ picture: image.present? ? "/attachments/download/" + "#{image.id}" + "/" + "#{image.filename}" : "",
+ description: sec.description,
+ memos_count: sec.visible_memos_count,
+ user_name: sec.user.try(:show_real_name),
+ user_login: sec.user.try(:login)
+ })
+ end
+ children_sections_array.push(s_section)
+ end
+ return children_sections_array
+ end
+
+ def unviewed_tiddings current_user
+ current_user_onclick_time = current_user.onclick_time.onclick_time
+ new_tidings_count = current_user.tidings.where("created_at > '#{current_user_onclick_time}'").length
+ new_pri_message_count = current_user.private_messages.where("created_at > '#{current_user_onclick_time}'").length
+ count = new_tidings_count + new_pri_message_count
+ return count
+ end
+
+ #给论坛管理员发信息
+ def create_user_tidings memo, type
+ memo_parent_id = ""
+ memo_parent_type = ""
+ if memo.parent_id.present?
+ memo_parent_id = memo.parent_id
+ memo_parent_type = "Memo"
+ end
+ admin_role_ids= AdminRole.includes(:admin_permissions).joins(:admin_permissions).where("admin_permissions.name = '#{type}'").pluck(:id)
+ user_ids = UserAdminRole.where(admin_role_id: admin_role_ids).pluck(:user_id).uniq
+ if user_ids.size > 0
+ user_ids.each do |id|
+ Tiding.create(:user_id => id, :trigger_user_id => memo.author_id,
+ container_id: memo.id, container_type: 'Memo',
+ :parent_container_id => memo_parent_id, :parent_container_type => memo_parent_type,
+ :viewed => 0, :tiding_type => "Memo")
+ end
+ else
+ Tiding.create(:user_id => 1, :trigger_user_id => memo.author_id,
+ container_id: memo.id, container_type: 'Memo',
+ :parent_container_id => memo_parent_id, :parent_container_type => memo_parent_type,
+ :viewed => 0, :tiding_type => "Memo")
+ end
+ end
+
+ def user_banned_permission current_user, forum_id
+ if current_user.present?
+ if forum_id.present?
+ user_forum_moder = ForumModerator.where(forum_section_id: forum_id,user_id: current_user.id).exists?
+ else
+ user_forum_moder = false
+ end
+ permission_user = (current_user.admin? || current_user.admin_permission?('forum_post') || user_forum_moder)
+ else
+ permission_user = false
+ end
+ permission_user
+ end
+
+
+ def rename_time_day(time)
+ return "" if time.blank?
+ time.strftime("%Y-%m-%d")
+ end
+
+ def rename_time_second(time)
+ return "" if time.blank?
+ time.strftime("%Y-%m-%d %H:%M:%S")
+ end
+
+ def rename_time_minute(time)
+ return "" if time.blank?
+ time.strftime("%Y-%m-%d %H:%M")
+ end
+
+ def get_memo_lists(all_memos, last_reply, current_user, show_hidden_memo)
+ memo_lists = []
+ all_memos.field_for_list.each do |memo|
+ if last_reply
+ last_memo = memo&.last_reply_memo(show_hidden_memo)
+ if last_memo
+ new_reply = {
+ username: last_memo&.author.try(:show_name),
+ user_login: last_memo&.author.try(:login),
+ user_id: last_memo&.author.try(:id),
+ content: last_memo&.content,
+ time: time_from_now(last_memo&.created_at),
+ published_time: rename_time_second(last_memo&.created_at)
+ }
+ end
+ end
+ memo_section = memo&.forum_section
+ memo_watched = memo.watched_by?(current_user)
+ banned_permission = user_banned_permission current_user, memo.forum_section_id
+ memo = {
+ id: memo.id,
+ subject: memo.try(:subject),
+ tag_name: memo.meno_tag_name,
+ sticky: memo.sticky,
+ is_fine: memo.is_fine,
+ is_original: memo.is_original,
+ username: memo.author.show_name,
+ image_url: "#{url_to_avatar(memo.author)}?#{Time.now.to_i}",
+ user_login: memo.author.try(:login),
+ user_id: memo.author.try(:id),
+ memo_watched:memo_watched,
+ replies_count: memo.can_see_reply_count(current_user),
+ praises_count: memo.praises_count,
+ viewed_count: memo.viewed_count,
+ published_time: rename_time_day(memo.published_at),
+ forum_section_id: memo_section.try(:id),
+ forum_section_title: memo_section.try(:title),
+ new_reply: new_reply || nil,
+ apply_destroy: current_user&.id == memo.author_id && memo.apply_destroy?,
+ banned_permission: banned_permission
+ }
+ memo_lists << memo
+ end
+ memo_lists
+ end
+
+ def get_all_sections(sections)
+ section_item = []
+ sections.each do |tag|
+ children_tags = tag.children.as_json(only: [:id, :title]).map{|k| k["forum_section"]}
+ section_item.push({
+ id: tag.id,
+ title: tag.title,
+ childrens: children_tags
+ })
+ end
+ return section_item
+ end
+
+end
diff --git a/app/models/api_key.rb b/app/models/api_key.rb
new file mode 100644
index 00000000..436b17cc
--- /dev/null
+++ b/app/models/api_key.rb
@@ -0,0 +1,20 @@
+class ApiKey < ApplicationRecord
+ attr_accessor :access_token, :active, :expires_at, :user_id
+ before_create :generate_access_token
+ before_create :set_experation
+
+ # validates_presence_of :user_id, :access_token
+
+ def expired?
+ DateTime.now >= self.expires_at
+ end
+
+ private
+ def generate_access_token
+ self.access_token = SecureRandom.hex
+ end
+
+ def set_experation
+ self.expires_at = DateTime.now + 30
+ end
+end
diff --git a/app/models/forum.rb b/app/models/forum.rb
new file mode 100644
index 00000000..88aafa67
--- /dev/null
+++ b/app/models/forum.rb
@@ -0,0 +1,2 @@
+class Forum < ApplicationRecord
+end
diff --git a/app/models/forum_section.rb b/app/models/forum_section.rb
index 121139a4..35d36b5d 100644
--- a/app/models/forum_section.rb
+++ b/app/models/forum_section.rb
@@ -9,8 +9,8 @@ class ForumSection < ApplicationRecord
has_many :memos, dependent: :destroy
has_one :section_notice, dependent: :destroy
# scope :group_today, -> {joins(:memos).where("memos.hidden = false and memos.created_at between ? and ?", Time.current.beginning_of_day, Time.current.end_of_day)}
- acts_as_watchable
- acts_as_attachable
+ # acts_as_watchable
+ # acts_as_attachable
def group_today
memos.where("memos.hidden = false and memos.created_at between ? and ?", Time.current.beginning_of_day, Time.current.end_of_day)
diff --git a/app/models/memo.rb b/app/models/memo.rb
index 666cc0b4..f4c1bc76 100644
--- a/app/models/memo.rb
+++ b/app/models/memo.rb
@@ -4,22 +4,21 @@
# is_fine 是否加精,默认为false
# hidden 是否隐藏
-require 'elasticsearch/model'
+# require 'elasticsearch/model'
class Memo < ApplicationRecord
-
- include Redmine::SafeAttributes
- include UserScoreHelper
- include ApplicationHelper
- include Elasticsearch::Model
+ # include Redmine::SafeAttributes
+ # include UserScoreHelper
+ include ApplicationHelper, Watchable
+ # include Elasticsearch::Model
#敏感词过滤
- include DunCheckAble
+ # include DunCheckAble
has_many :forums, :through => :memo_forums
belongs_to :forum_section, counter_cache: true
has_many :memo_forums, :dependent => :destroy
has_many :visit_actions, as: :visitable, dependent: :destroy
#用户是否禁言
has_many :banned_forums
- has_many_kindeditor_assets :assets, :dependent => :destroy
+ # has_many_kindeditor_assets :assets, :dependent => :destroy
has_many :tidings, :as => :container , :dependent => :destroy
belongs_to :author, :class_name => "User", :foreign_key => 'author_id'
validates_presence_of :author_id, :subject,:content
@@ -30,41 +29,42 @@ class Memo < ApplicationRecord
validate :cannot_reply_to_locked_topic, :on => :create
scope :total_replies, ->{where("hidden = false and root_id is not null")}
+ # scope :roots, -> {where()}
# 创意征集方式 0-默认,1-申请, ps. 删除后,该帖子即删除, 拒绝后,该帖子状态将为初始状态
- as_enum :memo_destroy_status, %i{common apply_destroy}, :column => 'destroy_status'
- acts_as_watchable
+ enum destroy_status: { common: 0, apply_destroy: 1 }
+ # acts_as_watchable
#elasticsearch kaminari init
- Kaminari::Hooks.init
- Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
- settings index: {
- number_of_shards: 5 ,
- analysis: {
- char_filter: {
- and_filter: {
- type: "mapping",
- mappings: [ "&=> and "]
- }
- },
- analyzer: {
- my_analyzer: {
- type: 'custom',
- tokenizer: 'standard',
- filter: ['classic'],
- char_filter: ['html_strip']
- }
- }
- }
- } do
- mappings dynamic: 'false' do
- indexes :subject, analyzer: 'smartcn',index_options: 'offsets'#, char_filter: 'html_strip'
- indexes :content, analyzer:'my_analyzer',index_options: 'offsets',search_analyzer: 'smartcn'
- indexes :updated_at,index:"not_analyzed" ,type:'date'
- end
- end
+ # Kaminari::Hooks.init
+ # Elasticsearch::Model::Response::Response.__send__ :include, Elasticsearch::Model::Response::Pagination::Kaminari
+ # settings index: {
+ # number_of_shards: 5 ,
+ # analysis: {
+ # char_filter: {
+ # and_filter: {
+ # type: "mapping",
+ # mappings: [ "&=> and "]
+ # }
+ # },
+ # analyzer: {
+ # my_analyzer: {
+ # type: 'custom',
+ # tokenizer: 'standard',
+ # filter: ['classic'],
+ # char_filter: ['html_strip']
+ # }
+ # }
+ # }
+ # } do
+ # mappings dynamic: 'false' do
+ # indexes :subject, analyzer: 'smartcn',index_options: 'offsets'#, char_filter: 'html_strip'
+ # indexes :content, analyzer:'my_analyzer',index_options: 'offsets',search_analyzer: 'smartcn'
+ # indexes :updated_at,index:"not_analyzed" ,type:'date'
+ # end
+ # end
acts_as_tree :counter_cache => :replies_count, :order => "#{Memo.table_name}.created_at ASC", dependent: :destroy
- acts_as_attachable
+ # acts_as_attachable
has_many :user_score_details, :class_name => 'UserScoreDetails',:as => :score_changeable_obj
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
has_one :praise_tread_cache, as: :object, dependent: :destroy
@@ -84,26 +84,26 @@ class Memo < ApplicationRecord
#:author => :author,
#:type => Proc.new {|o| o.parent_id.nil? ? 'Memo' : 'Reply'},
#:url => Proc.new {|o| {:controller => 'memos', :action => 'show', :forum_id => o.forum_id}.merge(o.parent_id.nil? ? {:id => o.id} : {:id => o.parent_id, :r => o.id, :anchor => "reply-#{o.id}"})}
- acts_as_activity_provider :author_key => :author_id,
- :func => 'memos',
- :timestamp => 'created_at'
+ # acts_as_activity_provider :author_key => :author_id,
+ # :func => 'memos',
+ # :timestamp => 'created_at'
# :find_options => {:type => 'memos'}
# acts_as_watchable
- safe_attributes "author_id",
- "subject",
- "content",
- "last_memo_id",
- "lock",
- "sticky",
- "parent_id",
- "replies_count",
- "root_id",
- "language"
+ # safe_attributes "author_id",
+ # "subject",
+ # "content",
+ # "last_memo_id",
+ # "lock",
+ # "sticky",
+ # "parent_id",
+ # "replies_count",
+ # "root_id",
+ # "language"
# after_create :add_author_as_watcher, :reset_counters!, :send_tiding
# after_create :add_author_as_watcher #浏览记录
- after_update
+ # after_update
# after_destroy :reset_counters!,:delete_kindeditor_assets #,:down_user_score -- 公共区发帖暂不计入得分,
# after_create :send_notification
# after_save :plusParentAndForum
@@ -137,32 +137,32 @@ class Memo < ApplicationRecord
end
- def self.search(query)
- __elasticsearch__.search(
- {
- query: {
- multi_match: {
- query: query,
- type:"most_fields",
- operator: "or",
- fields: ['subject','content^0.5']
- }
- },
- sort: {
- _score:{order: "desc" },
- updated_at:{order: "desc" }
- },
- highlight: {
- pre_tags: [''],
- post_tags: [' '],
- fields: {
- subject: {},
- content: {}
- }
- }
- }
- )
- end
+ # def self.search(query)
+ # __elasticsearch__.search(
+ # {
+ # query: {
+ # multi_match: {
+ # query: query,
+ # type:"most_fields",
+ # operator: "or",
+ # fields: ['subject','content^0.5']
+ # }
+ # },
+ # sort: {
+ # _score:{order: "desc" },
+ # updated_at:{order: "desc" }
+ # },
+ # highlight: {
+ # pre_tags: [''],
+ # post_tags: [' '],
+ # fields: {
+ # subject: {},
+ # content: {}
+ # }
+ # }
+ # }
+ # )
+ # end
def memo_parent
Memo.find(parent_id)
diff --git a/app/services/admins/banned_users/_banned_user_item.html.erb b/app/services/admins/banned_users/_banned_user_item.html.erb
new file mode 100644
index 00000000..de661c7d
--- /dev/null
+++ b/app/services/admins/banned_users/_banned_user_item.html.erb
@@ -0,0 +1,47 @@
+
+
+
+ <% if @banned_users_count == 0 %>
+ <%= render :partial => "welcome/no_data" %>
+ <% else %>
+ <% @banned_users.each do |ban| %>
+ <% user = ban.user %>
+ <% author = ban.author %>
+ <% memo = ban.memo %>
+ <% author_type = author.admin? ? "管理员" : "版主" %>
+
+ <%= image_tag(url_to_avatar(user),width:"50px",height:"50px",class:"radius mr15") %>
+
+
+ <%= link_to user.try(:show_name),user,class: "fl mr15 color-grey-3 font-16" %>
+ <%= time_from_now(ban.updated_at) %>
+ 第<%= ban.banned_count %> 次 被禁言
+
+ <% if @banned_type == "banned" %>
+ <% remove_ban_message = "是否确认解除"+"\"#{user.try(:show_name)}\""+"的禁言?" %>
+ <%= link_to "取消禁言", "javascript:void(0)", class: "color-blue_4C", onclick: "custom_confirm_remote_box('#{confirm_banned_admin_banned_users_path(user_id: user.id, id: memo.id)}','#{remove_ban_message}','post');"%>
+ <% else %>
+ <%= link_to author.try(:show_name), user_path(author), class: "" %>
+
+ <%= time_from_now(ban.updated_at) %>
+
+ <% end %>
+
+
+
+ 在【<%= link_to memo.subject.truncate(50), "forums/#{memo.id}", class: "color-blue_4C" %> 】被<%= author_type %>:<%= link_to author.try(:show_name), user_path(author), class: "" %> 禁言
+
+
+
+ <% end %>
+ <% end %>
+
+
+
+
+ <%= pagination_links_full @banned_users_pages, @banned_users_count, :per_page_links => false, :remote => true, :flag => true, :is_new => true %>
+
+
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/banned_users/_banned_users_items.html.erb b/app/services/admins/banned_users/_banned_users_items.html.erb
new file mode 100644
index 00000000..a95a5272
--- /dev/null
+++ b/app/services/admins/banned_users/_banned_users_items.html.erb
@@ -0,0 +1,31 @@
+
+
+ " >
+ <%= link_to "禁言用户 #{@banned_users_size > 0 ? "(#{@banned_users_size})" : ""}", admin_banned_users_path(banned_type: "banned"),remote: true %>
+
+ ">
+ <%= link_to "解除禁言记录", admin_banned_users_path(banned_type: "unbanned"),remote: true %>
+
+
+
+
+
+ <%= render partial: "admin/banned_users/banned_user_item" %>
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/banned_users/confirm_banned.js.erb b/app/services/admins/banned_users/confirm_banned.js.erb
new file mode 100644
index 00000000..719c32ea
--- /dev/null
+++ b/app/services/admins/banned_users/confirm_banned.js.erb
@@ -0,0 +1,4 @@
+<% if @status > 0 %>
+$("#banned-users-item-<%= params[:user_id] %>").remove()
+<% end %>
+op_know('<%= @message %>')
\ No newline at end of file
diff --git a/app/services/admins/banned_users/index.html.erb b/app/services/admins/banned_users/index.html.erb
new file mode 100644
index 00000000..125f526d
--- /dev/null
+++ b/app/services/admins/banned_users/index.html.erb
@@ -0,0 +1,3 @@
+
+ <%= render partial: "admin/banned_users/banned_users_items" %>
+
diff --git a/app/services/admins/banned_users/index.js.erb b/app/services/admins/banned_users/index.js.erb
new file mode 100644
index 00000000..281629fb
--- /dev/null
+++ b/app/services/admins/banned_users/index.js.erb
@@ -0,0 +1 @@
+$("#banned-users-container").html("<%= j render partial: "admin/banned_users/banned_users_items" %>")
\ No newline at end of file
diff --git a/app/services/admins/forum_applies/_forum_applies_items.html.erb b/app/services/admins/forum_applies/_forum_applies_items.html.erb
new file mode 100644
index 00000000..0e6343a5
--- /dev/null
+++ b/app/services/admins/forum_applies/_forum_applies_items.html.erb
@@ -0,0 +1,33 @@
+
+
+ " >
+ <%= link_to "待审批", admin_forum_applies_path(select_type: "unconfirm"),remote: true %>
+
+ ">
+ <%= link_to "已审批", admin_forum_applies_path(select_type: "confirm"),remote: true %>
+
+
+
+
+
+ <%= render partial: "admin/forum_applies/forum_apply_item" %>
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/forum_applies/_forum_apply_item.html.erb b/app/services/admins/forum_applies/_forum_apply_item.html.erb
new file mode 100644
index 00000000..32649077
--- /dev/null
+++ b/app/services/admins/forum_applies/_forum_apply_item.html.erb
@@ -0,0 +1,33 @@
+
+
+ <% if @forum_applies_count == 0 %>
+ <%= render :partial => "welcome/no_data" %>
+ <% else %>
+ <% @forum_applies.each do |apply| %>
+ <% user = apply&.user %>
+ <% if user.present? %>
+
+ <%= render partial: "admin/forum_applies/item_list", locals: {user: user, apply: apply} %>
+
+ <% end %>
+ <% end %>
+ <% end %>
+
+
+
+
+ <%= pagination_links_full @forum_applies_pages, @forum_applies_count, :per_page_links => false, :remote => true, :flag => true, :is_new => true %>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/forum_applies/_item_list.html.erb b/app/services/admins/forum_applies/_item_list.html.erb
new file mode 100644
index 00000000..f78f50ee
--- /dev/null
+++ b/app/services/admins/forum_applies/_item_list.html.erb
@@ -0,0 +1,51 @@
+<%= image_tag(url_to_avatar(user),width:"50px",height:"50px",class:"radius mr15") %>
+
+
+ <%= link_to user.try(:show_name),user_path(user),class: "fl mr15 color-grey-3 font-16" %>
+ <%= time_from_now(apply.updated_at) %>
+ IP:<%= user_ip_addr apply.user_ip %>
+
+ <% if apply.is_confirm != 0 %>
+ <% apply_user = apply&.reviews&.acted_forum&.last&.user %>
+ <% if apply_user.present? %>
+
+ <%= link_to apply_user.try(:show_name), user_path(apply_user) %>
+
+ <% end %>
+ <% if apply.is_confirm == 2 %>
+ 已拒绝
+ <% else %>
+ 已同意
+ 撤销审核
+ <% end %>
+ <% else %>
+ <%= link_to "私信", message_detail_user_path(current_user, :user_id => apply.user_id), :class => "edu-default-btn edu-orangeline-btn ml20 fl",target:"_blank" %>
+ 同意
+ 拒绝
+ <% end %>
+
+
+
+ 申请成为"<%= link_to apply.forum_section.try(:title), "/memos/forum_memos/#{apply.id}", class: "color-blue" %>"的版主
+
+ <% if apply.is_confirm == 2 %>
+
拒绝原因: <%= apply&.reviews&.apply_forum&.first&.reason.to_s %>
+ <% end %>
+ <% if apply.is_confirm != 2 %>
+ <%= labelled_form_for apply, :url => confirm_apply_admin_forum_apply_path(apply, is_confirm: apply.is_confirm), :html => {id:"refuseContent_#{apply.id}",class:"none",method: :post, remote: true} do |f| %>
+
+
+
<%= apply.is_confirm == 0 ? "拒绝原因" : "撤销审核原因" %>:
+
+
+
+ 取消
+ <%= f.submit "确定",class:"edu-default-btn edu-blueback-btn fl mr20" %>
+
+
+
+ <% end %>
+ <% end %>
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/forum_applies/confirm_apply.js.erb b/app/services/admins/forum_applies/confirm_apply.js.erb
new file mode 100644
index 00000000..14a6fa89
--- /dev/null
+++ b/app/services/admins/forum_applies/confirm_apply.js.erb
@@ -0,0 +1,9 @@
+
+<% if @status > 0%>
+ <% if @is_confirm == 0 %>
+ $("#forum-apply-action-<%= @forum_apply.id %>").remove()
+ <% else %>
+ $("#forum-apply-action-<%= @forum_apply.id %>").html("<%= j render partial: "admin/forum_applies/item_list", locals: {user: @forum_apply.user, apply: @forum_apply} %>")
+ <% end %>
+<% end %>
+op_know("<%= @message %>")
\ No newline at end of file
diff --git a/app/services/admins/forum_applies/index.html.erb b/app/services/admins/forum_applies/index.html.erb
new file mode 100644
index 00000000..a56be3dc
--- /dev/null
+++ b/app/services/admins/forum_applies/index.html.erb
@@ -0,0 +1,3 @@
+
+ <%= render partial: "admin/forum_applies/forum_applies_items" %>
+
diff --git a/app/services/admins/forum_applies/index.js.erb b/app/services/admins/forum_applies/index.js.erb
new file mode 100644
index 00000000..d562cde4
--- /dev/null
+++ b/app/services/admins/forum_applies/index.js.erb
@@ -0,0 +1 @@
+$("#forum-applies-container").html("<%= j render partial: "admin/forum_applies/forum_applies_items" %>")
\ No newline at end of file
diff --git a/app/services/admins/forum_moderators/_forum_moderator_item.html.erb b/app/services/admins/forum_moderators/_forum_moderator_item.html.erb
new file mode 100644
index 00000000..a432bc45
--- /dev/null
+++ b/app/services/admins/forum_moderators/_forum_moderator_item.html.erb
@@ -0,0 +1,9 @@
+<% if users.present? && users.size > 0 %>
+ <% users.each do |u| %>
+ <% user = u.user %>
+
+ <%= link_to user.try(:show_name), user_path(user) %>
+ <%= link_to " ".html_safe,admin_forum_section_forum_moderator_path(forum, u), method: :delete, data:{confirm: "确认删除吗?"}, remote: true, class: "color-grey-9" %>
+
+ <% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/forum_moderators/_new_forum_moderators.html.erb b/app/services/admins/forum_moderators/_new_forum_moderators.html.erb
new file mode 100644
index 00000000..5c4bdc9a
--- /dev/null
+++ b/app/services/admins/forum_moderators/_new_forum_moderators.html.erb
@@ -0,0 +1,28 @@
+
\ No newline at end of file
diff --git a/app/services/admins/forum_moderators/create.js.erb b/app/services/admins/forum_moderators/create.js.erb
new file mode 100644
index 00000000..13a2c2a0
--- /dev/null
+++ b/app/services/admins/forum_moderators/create.js.erb
@@ -0,0 +1,6 @@
+<% if @forum_status > 0 %>
+$("#forum_sections_moderators_<%= @forum_section.id %>").html("<%= j render partial: "admin/forum_moderators/forum_moderator_item", locals: {users: @forum_moderators, forum: @forum_section} %>")
+op_know("添加成功")
+<% else %>
+op_know("没有选择版主")
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/forum_moderators/destroy.js.erb b/app/services/admins/forum_moderators/destroy.js.erb
new file mode 100644
index 00000000..89ca697c
--- /dev/null
+++ b/app/services/admins/forum_moderators/destroy.js.erb
@@ -0,0 +1 @@
+$("#forum_section_moderator_user_<%= @forum_moderator.id %>").remove()
\ No newline at end of file
diff --git a/app/services/admins/forum_moderators/new.js.erb b/app/services/admins/forum_moderators/new.js.erb
new file mode 100644
index 00000000..2455beb2
--- /dev/null
+++ b/app/services/admins/forum_moderators/new.js.erb
@@ -0,0 +1,20 @@
+var htmlvalue = "<%= j render :partial => 'admin/forum_moderators/new_forum_moderators' %>";
+pop_box_new(htmlvalue, 520, 400);
+
+function search_forum_users(target) {
+ var t_value = $("#"+ target).val()
+ $.ajax({
+ type: "POST",
+ url:'/admin/forum_sections/<%= @forum_section.id %>/forum_moderators/search_user?user_name='+t_value,
+ dataType:'JSON',
+ success: function (data) {
+ if(data.html.length > 0){
+ $("#forum-moderators-show").removeClass("none").html(data.html)
+ $("#has-none-moderators").addClass("none")
+ }else{
+ $("#has-none-moderators").removeClass("none").html("没有找到该用户")
+ }
+ }
+ }
+ );
+}
\ No newline at end of file
diff --git a/app/services/admins/forum_moderators/search_user.js.erb b/app/services/admins/forum_moderators/search_user.js.erb
new file mode 100644
index 00000000..e69de29b
diff --git a/app/services/admins/forum_sections/_children_forum_detail.html.erb b/app/services/admins/forum_sections/_children_forum_detail.html.erb
new file mode 100644
index 00000000..0c4d5c49
--- /dev/null
+++ b/app/services/admins/forum_sections/_children_forum_detail.html.erb
@@ -0,0 +1,8 @@
+<%= children_forum.try(:title) %>
+
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/_children_forum_sections.html.erb b/app/services/admins/forum_sections/_children_forum_sections.html.erb
new file mode 100644
index 00000000..ae07955b
--- /dev/null
+++ b/app/services/admins/forum_sections/_children_forum_sections.html.erb
@@ -0,0 +1,10 @@
+<% if children_forums.size > 0 %>
+
+<% end %>
+
diff --git a/app/services/admins/forum_sections/_edit_forum.html.erb b/app/services/admins/forum_sections/_edit_forum.html.erb
new file mode 100644
index 00000000..1f12ecea
--- /dev/null
+++ b/app/services/admins/forum_sections/_edit_forum.html.erb
@@ -0,0 +1,50 @@
+<%=javascript_include_tag '../javascripts/attachments.js' %>
+
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/_forum_section_detail.html.erb b/app/services/admins/forum_sections/_forum_section_detail.html.erb
new file mode 100644
index 00000000..15c85195
--- /dev/null
+++ b/app/services/admins/forum_sections/_forum_section_detail.html.erb
@@ -0,0 +1,3 @@
+
+ <%= render partial: "admin/forum_sections/td_forum_section", locals: {forum: forum} %>
+
diff --git a/app/services/admins/forum_sections/_new_forum.html.erb b/app/services/admins/forum_sections/_new_forum.html.erb
new file mode 100644
index 00000000..9c105ae5
--- /dev/null
+++ b/app/services/admins/forum_sections/_new_forum.html.erb
@@ -0,0 +1,49 @@
+<%=javascript_include_tag '../javascripts/attachments.js' %>
+
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/_recommend_forum_sections.html.erb b/app/services/admins/forum_sections/_recommend_forum_sections.html.erb
new file mode 100644
index 00000000..b0600006
--- /dev/null
+++ b/app/services/admins/forum_sections/_recommend_forum_sections.html.erb
@@ -0,0 +1,18 @@
+
+ <%= form_tag(recommend_forums_admin_forum_section_path(forum), method: :post, remote: true) do %>
+
+ <%= radio_button_tag :is_recommend, 0, forum.is_recommend == 0, id: "forum_is_recommend_#{forum.id}_0", class: "magic-radio", onchange: "recommend_form_submit('forum_recommend_submit_#{forum.id}')" %>
+ 不推荐
+
+
+ <%= radio_button_tag :is_recommend, 1, forum.is_recommend == 1, id: "forum_is_recommend_#{forum.id}_1", class: "magic-radio", onchange: "recommend_form_submit('forum_recommend_submit_#{forum.id}')" %>
+ 左侧导航推荐
+
+
+ <%= radio_button_tag :is_recommend, 2, forum.is_recommend == 2, id: "forum_is_recommend_#{forum.id}_2", class: "magic-radio", onchange: "recommend_form_submit('forum_recommend_submit_#{forum.id}')" %>
+ 右侧展示推荐
+
+ <%= submit_tag "确认", class: "none", id: "forum_recommend_submit_#{forum.id}" %>
+ <% end %>
+
+
diff --git a/app/services/admins/forum_sections/_show_image_forum.html.erb b/app/services/admins/forum_sections/_show_image_forum.html.erb
new file mode 100644
index 00000000..7cbef963
--- /dev/null
+++ b/app/services/admins/forum_sections/_show_image_forum.html.erb
@@ -0,0 +1,8 @@
+<% if image_type == "partner" %>
+<%= image_tag(logo_url,class: "upload-partner-250") %>
+重新上传
+<% else %>
+<%= image_tag(logo_url,class: "avatar100") %>
+重新上传
+<% end %>
+<%= hidden_field_tag "attachments[]","#{attachment.id}", readonly: "true" %>
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/_td_forum_section.html.erb b/app/services/admins/forum_sections/_td_forum_section.html.erb
new file mode 100644
index 00000000..05ff9ba5
--- /dev/null
+++ b/app/services/admins/forum_sections/_td_forum_section.html.erb
@@ -0,0 +1,42 @@
+
+
+
+
+ <%= render partial: "admin/forum_sections/children_forum_sections", locals: {children_forums: forum.get_children_section("desc")} %>
+
+
+
+
+ <%= render partial: "admin/forum_sections/recommend_forum_sections", locals: {forum: forum} %>
+
+
+
+
+ <%= link_to " ".html_safe,new_admin_forum_section_forum_moderator_path(forum), class: "font-20 color-blue mr10", title: "添加版主", remote: true %>
+
+
+ <%= render partial: "admin/forum_moderators/forum_moderator_item", locals: {users: forum.forum_moderators, forum: forum} %>
+
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/_upload_logo.html.erb b/app/services/admins/forum_sections/_upload_logo.html.erb
new file mode 100644
index 00000000..5798bb81
--- /dev/null
+++ b/app/services/admins/forum_sections/_upload_logo.html.erb
@@ -0,0 +1,19 @@
+<%= file_field_tag 'attachments[dummy][file]',
+ :id => "_file_section_picture",
+ :class => ie8? ? '':'file_selector',
+ :onchange => "addInputFiles_board(this, '','"+"submit_resource"+"');",
+ :style => ie8? ? '': 'display:none',
+ accept: 'image/png,image/gif,image/jpeg,image/jpg,image/bmp',
+ :data => {
+ :max_file_size => 5120.kilobytes,
+ :max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(5120.kilobytes)),
+ :max_concurrent_uploads => 1,
+ :upload_path => upload_image_path(:format => 'js'),
+ :description_placeholder => l(:label_optional_description),
+ :field_is_public => l(:field_is_public),
+ :are_you_sure => l(:text_are_you_sure),
+ :file_count => l(:label_file_count),
+ :delete_all_files => l(:text_are_you_sure_all),
+ :label_file_uploding => l(:label_file_uploding),
+ :containerid => ""
+ } %>
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/create.js.erb b/app/services/admins/forum_sections/create.js.erb
new file mode 100644
index 00000000..3188d4ec
--- /dev/null
+++ b/app/services/admins/forum_sections/create.js.erb
@@ -0,0 +1,14 @@
+<% if @forum_status[:status] == 0 %>
+ $("#new_forum_section_notice").removeClass("none").html("<%= @forum_status[:msg] %>")
+ $("#new_forum_section_notice").siblings("input").addClass("error_tip");
+<% elsif @forum_status[:status] > 0 %>
+ op_know("<%= @forum_status[:msg] %>")
+ <% if params[:parent_id].present? %>
+ $("#forum-section-detail-<%= params[:parent_id] %>").html("<%= j render partial: "admin/forum_sections/td_forum_section", locals: {forum: @parent_forum} %>")
+ <% else %>
+ $("#forum-section-contents").prepend("<%= j render partial: "admin/forum_sections/forum_section_detail", locals: {forum: @forum_section} %>")
+ <% end %>
+
+<% else %>
+ op_know("<%= @forum_status[:msg] %>")
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/destroy.js.erb b/app/services/admins/forum_sections/destroy.js.erb
new file mode 100644
index 00000000..4502d31a
--- /dev/null
+++ b/app/services/admins/forum_sections/destroy.js.erb
@@ -0,0 +1,10 @@
+<% if @delete_status[:status] > 0 %>
+op_know("<%= @delete_status[:msg] %>")
+<% if params[:children_forum].present? %>
+$("#children-forum-detail-<%= @forum_section.id %>").remove()
+<% else %>
+$("#forum-section-detail-<%= @forum_section.id %>").remove()
+<% end %>
+<% else %>
+op_know("<%= @delete_status[:msg] %>")
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/edit.js.erb b/app/services/admins/forum_sections/edit.js.erb
new file mode 100644
index 00000000..b71ae586
--- /dev/null
+++ b/app/services/admins/forum_sections/edit.js.erb
@@ -0,0 +1,2 @@
+var htmlvalue = "<%= j render :partial => 'admin/forum_sections/edit_forum' %>";
+pop_box_new(htmlvalue, 520, 400);
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/index.html.erb b/app/services/admins/forum_sections/index.html.erb
new file mode 100644
index 00000000..68395932
--- /dev/null
+++ b/app/services/admins/forum_sections/index.html.erb
@@ -0,0 +1,3 @@
+
+ <%= render partial: "managements/forums_plateSetting.html.erb" %>
+
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/index.js.erb b/app/services/admins/forum_sections/index.js.erb
new file mode 100644
index 00000000..ea4191c9
--- /dev/null
+++ b/app/services/admins/forum_sections/index.js.erb
@@ -0,0 +1 @@
+$("#forum-section-container").html("<%= j render partial: "managements/forums_plateSetting.html.erb" %>")
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/move.js.erb b/app/services/admins/forum_sections/move.js.erb
new file mode 100644
index 00000000..731ea49f
--- /dev/null
+++ b/app/services/admins/forum_sections/move.js.erb
@@ -0,0 +1 @@
+notice_box_redirect("<%= admin_forum_sections_path %>", "<%= @c_msg %>")
diff --git a/app/services/admins/forum_sections/new.js.erb b/app/services/admins/forum_sections/new.js.erb
new file mode 100644
index 00000000..2b950c3f
--- /dev/null
+++ b/app/services/admins/forum_sections/new.js.erb
@@ -0,0 +1,2 @@
+var htmlvalue = "<%= j render :partial => 'admin/forum_sections/new_forum', locals: {parent_id: @parent_id} %>";
+pop_box_new(htmlvalue, 520, 400);
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/order_forums.js.erb b/app/services/admins/forum_sections/order_forums.js.erb
new file mode 100644
index 00000000..7d361ddb
--- /dev/null
+++ b/app/services/admins/forum_sections/order_forums.js.erb
@@ -0,0 +1 @@
+$("#children-forum-section-<%= @forum_section.id %>").html("<%= j render partial: "admin/forum_sections/children_forum_sections", locals: {children_forums: @children_forums} %>")
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/recommend_forums.js.erb b/app/services/admins/forum_sections/recommend_forums.js.erb
new file mode 100644
index 00000000..199010ef
--- /dev/null
+++ b/app/services/admins/forum_sections/recommend_forums.js.erb
@@ -0,0 +1 @@
+$("#forum-section-recommend-<%= @forum_section.id %>").html("<%= j render partial: "admin/forum_sections/recommend_forum_sections", locals: {forum: @forum_section} %>")
\ No newline at end of file
diff --git a/app/services/admins/forum_sections/update.js.erb b/app/services/admins/forum_sections/update.js.erb
new file mode 100644
index 00000000..27e73c86
--- /dev/null
+++ b/app/services/admins/forum_sections/update.js.erb
@@ -0,0 +1,13 @@
+<% if @edit_forum_status[:status] == 0 %>
+$("#edit_forum_section_notice").removeClass("none").html("<%= @edit_forum_status[:msg] %>")
+$("#edit_forum_section_notice").siblings("input").addClass("error_tip");
+<% elsif @edit_forum_status[:status] > 0 %>
+ op_know("<%= @edit_forum_status[:msg] %>")
+ <% if params[:children_forum].present? %>
+ $("#children-forum-detail-<%= @forum_section.id %>").html("<%= j render partial: "admin/forum_sections/children_forum_detail", locals: {children_forum: @forum_section} %>")
+ <% else %>
+ $("#forum-section-detail-<%= @forum_section.id %>").html("<%= j render partial: "admin/forum_sections/td_forum_section", locals: {forum: @forum_section} %>")
+ <% end %>
+<% else %>
+op_know("<%= @edit_forum_status[:msg] %>")
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/_attachments_links.html.erb b/app/services/admins/memos/_attachments_links.html.erb
new file mode 100644
index 00000000..0f6122c3
--- /dev/null
+++ b/app/services/admins/memos/_attachments_links.html.erb
@@ -0,0 +1,49 @@
+
+ <% for attachment in attachments %>
+
+
+
+ <% if options[:length] %>
+
+ <%= link_to_attachment attachment, :class => 'fl FilesName02', :download => true,:length => options[:length] -%>
+
(<%= number_to_human_size attachment.filesize , :precision => 0 %>)
+ <% if options[:deletable] %>
+ <%#= link_to image_tag('delete.png'), attachment_path(attachment),
+ :data => {:confirm => l(:text_are_you_sure)},
+ :method => :delete,
+ :class => 'delete',
+ #:remote => true,
+ #:id => "attachments_" + attachment.id.to_s,
+ :title => l(:button_delete) %>
+
+ <% end %>
+
+ <% else %>
+
+
+ <%= link_to_short_attachment attachment, :class => 'fl FilesName02 color-orange03', :download => true, :length => 45 -%>
+
+
+
+
+
+
<%= format_time attachment.created_on %>
+
+ <% if options[:deletable] %>
+
+ <% end %>
+
+
+ <% end %>
+ <% end %>
+ <% if defined?(thumbnails) && thumbnails %>
+ <% images = attachments.select(&:thumbnailable?) %>
+ <% if images.any? %>
+
+ <% images.each do |attachment| %>
+
<%= thumbnail_tag(attachment) %>
+ <% end %>
+
+ <% end %>
+ <% end %>
+
diff --git a/app/services/admins/memos/_common_reply_box.html.erb b/app/services/admins/memos/_common_reply_box.html.erb
new file mode 100644
index 00000000..a7b816c8
--- /dev/null
+++ b/app/services/admins/memos/_common_reply_box.html.erb
@@ -0,0 +1,128 @@
+
+
全部回复
+ <% unless count == 0 %>
+ (<%= count %>)
+ <% end %>
+
+
+ <% if User.current.admin? %>
+ ')"> 奖励
+ <% end %>
+ 回复
+
+
+
+ <%= render :partial => 'praise_tread/activity_praise', :locals => {:activity => memo, :user_activity_id => memo.id, :type => "Memo"} %>
+
+
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/memos/_form.html.erb b/app/services/admins/memos/_form.html.erb
new file mode 100644
index 00000000..9efee77d
--- /dev/null
+++ b/app/services/admins/memos/_form.html.erb
@@ -0,0 +1,313 @@
+<%= content_for(:header_tags) do %>
+ <%= import_ke(enable_at: false, prettify: false, init_activity: false) %>
+<% end %>
+
+
+
+
+
+<% if false %>
+<%= content_for(:header_tags) do %>
+ <%= import_ke(enable_at: false, prettify: false, init_activity: false) %>
+<% end %>
+
+
+
+
+
+ <%= f.text_field :subject,
+ :no_label => true,
+ :id => "memo_subject",
+ :maxlength => "50",
+ :style => "width:708px",
+ :onblur => "check_memo_name();",
+ :onfocus => "$('#memo_name_error_tips').hide();",
+ :onmouseover => "this.style.borderColor='#d9d9d9'",
+ :class => "wenba-tiwen-input",
+ :placeholder => "请输入标题" %>
+
+
+
+
+ <%= f.kindeditor :content, :editor_id => "memo_content", :height => 300, :no_label => true %>
+
+
+
+ <%= render :partial => 'forums/file_form', :locals => {:container => @memo} %>
+
+
+
+
+
+ <%= link_to "取消", forum_path(@forum), :class => "btn fr" %>
+
确定
+
+
+
+
+
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/_memo_all_replies.html.erb b/app/services/admins/memos/_memo_all_replies.html.erb
new file mode 100644
index 00000000..4870c34a
--- /dev/null
+++ b/app/services/admins/memos/_memo_all_replies.html.erb
@@ -0,0 +1,115 @@
+<%#= render :partial => "messages/common_reply_box", :locals => {:count => @reply_count, :activity => @topic, :no_children_comments => @replies, :is_teacher => is_teacher} %>
+<%= render :partial => "memos/common_reply_box", :locals => {:count => @reply_count, :memo => @memo, :no_children_comments => @replies} %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<% if false %>
+ <% @replies.each do |reply| %>
+
+
+
+
+ <%= link_to image_tag(url_to_avatar(reply.author), :width => 33,:height => 33), user_path(reply.author) %>
+
+
+
+ <%= render :partial => 'users/message_contents', :locals => {:comment => reply, :type => 'Memo', :user_activity_id => @memo.id}%>
+
+
+
<%= reply.content.gsub(/\/script/, "script").gsub(/script/, " script").html_safe %>
+
+
+
+
+
+ <%= render :partial => "praise_tread/praise", :locals => {:activity => reply, :user_activity_id => reply.id, :type => "reply"} %>
+
+
+ <%= link_to(
+ l(:button_reply),
+ {:action => 'quote', :id => reply},
+ :remote => true,
+ :method => 'get',
+ :title => l(:button_reply)) %>
+ ︿
+
+ <%= link_to(
+ l(:button_delete),
+ forum_memo_path(@memo.forum, reply),
+ :method => :delete,
+ :id => "delete_reply_#{reply.id}",
+ :class => 'fr mr20 undis',
+ :data => {:confirm => l(:text_are_you_sure)},
+ :title => l(:button_delete)
+ ) if @memo.author.id == User.current.id || User.current.admin? || User.current == @forum.creator %>
+
+
+
+
+
+
+
+
+ <% end %>
+ <% if @limit_count > @page * @limit + 10 %>
+
+
+ ↓
+ ↑
+ <%= link_to '点击展开更多回复', forum_memo_path(@memo.forum_id, @memo, :page => @page),:remote=>true %>
+
+
+ <% end %>
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/_my_count_message.html.erb b/app/services/admins/memos/_my_count_message.html.erb
new file mode 100644
index 00000000..d8b8708b
--- /dev/null
+++ b/app/services/admins/memos/_my_count_message.html.erb
@@ -0,0 +1,150 @@
+
+
+
<%= link_to image_tag(url_to_avatar(@forum.creator),:width => 60,:height => 60,:alt => '贴吧图像' ), user_path( @forum.creator) %>
+
+
+
+ <% user_name = @forum.creator.show_name.empty? ? @forum.creator.name : @forum.creator.show_name %>
+
吧主:
+
<%= user_name %>
+
+
+
+
+ <%= link_to @forum.name, forum_path(@forum), :class => "f16 fontBlue", :style => "word-break: break-all; word-wrap:break-word;white-space:pre-wrap;" %>
+
+
+
+
+ <% if @forum.creator.id == User.current.id %>
+
+ <%= link_to "编辑贴吧", edit_forum_path(@forum), :class => "linkGrey3", :remote => true %>
+
删除贴吧
+
+
+ <% end %>
+
+ <% unless params[:controller] == "forums" %>
+
+ <%= link_to "我要提问 ".html_safe, new_forum_memo_path(:forum_id => @forum) %>
+
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/services/admins/memos/_my_show_count_message.html.erb b/app/services/admins/memos/_my_show_count_message.html.erb
new file mode 100644
index 00000000..e1fa37a7
--- /dev/null
+++ b/app/services/admins/memos/_my_show_count_message.html.erb
@@ -0,0 +1,142 @@
+
+
+
<%= link_to image_tag(url_to_avatar(@forum.creator),:width => 60,:height => 60,:alt => '贴吧图像' ), user_path( @forum.creator) %>
+
+
+
+ <% user_name = @forum.creator.show_name.empty? ? @forum.creator.name : @forum.creator.show_name %>
+
吧主:
+
<%= user_name %>
+
+
+
+
+ <%= link_to @forum.name, forum_path(@forum), :class => "f16 fontBlue", :style => "word-break: break-all; word-wrap:break-word;white-space:pre-wrap;" %>
+
+
+
+
+ <% unless params[:controller] == "forums" %>
+
+ <%= link_to "我要提问 ".html_safe, new_forum_memo_path(:forum_id => @forum) %>
+
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/services/admins/memos/_new.html.erb b/app/services/admins/memos/_new.html.erb
new file mode 100644
index 00000000..153e93f2
--- /dev/null
+++ b/app/services/admins/memos/_new.html.erb
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/app/services/admins/memos/_praise_tread.html.erb b/app/services/admins/memos/_praise_tread.html.erb
new file mode 100644
index 00000000..f512f664
--- /dev/null
+++ b/app/services/admins/memos/_praise_tread.html.erb
@@ -0,0 +1,36 @@
+
+ <% if User.current.logged? %>
+ <% if horizontal %>
+
+
+ <% @is_valuate = is_praise_or_tread(obj,user_id)%>
+ <% if @is_valuate.size > 0 %>
+ <% @flag = @is_valuate.first.praise_or_tread %>
+ <% if @flag == 1 %>
+
<%= get_praise_num(obj)%>
+ <% end %>
+ <% else %>
+ <% if user_id == obj.author_id %>
+
+
<%= get_praise_num(obj)%>
+ <% elsif user_id == obj.forum.creator_id || User.current.admin? %>
+
<%= get_praise_num(obj) %>
+ <% else %>
+
+ <%# if OptionNumber.get_user_option_number(user_id).nil? || OptionNumber.get_user_option_number(user_id).total_score < 2 %>
+
+ <%#= link_to image_tag("/images/praise_tread/praise_true.png",weight:"22px", height:"22px",:title => l(:label_issue_praise)),
+ :controller=>"praise_tread",:action=>"praise_plus",:remote=>true,:obj_id => obj.id,:obj_type => obj.class,:horizontal => horizontal %>
+
<%= get_praise_num(obj)%>
+
+
+
+
+
+
+
+ <% end %>
+ <% end %>
+
+ <% end %>
+ <% end %>
diff --git a/app/services/admins/memos/_reply_box.html.erb b/app/services/admins/memos/_reply_box.html.erb
new file mode 100644
index 00000000..5ddd75d8
--- /dev/null
+++ b/app/services/admins/memos/_reply_box.html.erb
@@ -0,0 +1,20 @@
+<%= form_for(@memo_new, url: forum_memos_path, :html => {:multipart => true}) do |f| %>
+ <%= f.hidden_field :subject, :required => true, value: @memo.subject %>
+ <%= f.hidden_field :forum_id, :required => true, value: @memo.forum_id %>
+ <%= f.hidden_field :parent_id, :required => true, value: @memo.id %>
+
+ <%= hidden_field_tag :asset_id,params[:asset_id],:required => false,:style => 'display:none' %>
+ <%= hidden_field_tag :quote,"",:required => false,:style => 'display:none' %>
+ <%= label_tag(l(:label_reply_plural)) %>:
+
+ <%= f.kindeditor :content, :cols => 80, :rows => 15, :value => @content %>
+
+
+
+ <%= l(:label_attachment_plural) %>
+
+ <%= render :partial => 'attachments/form' %>
+
+
+ <%= f.submit value: l(:label_reply_plural), class: "replies" %>
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/_reply_message.html.erb b/app/services/admins/memos/_reply_message.html.erb
new file mode 100644
index 00000000..282a5223
--- /dev/null
+++ b/app/services/admins/memos/_reply_message.html.erb
@@ -0,0 +1,31 @@
+
+
+ <%= link_to image_tag(url_to_avatar(User.current), :width => "33", :height => "33"), user_path(User.current), :alt => "用户头像" %>
+
+
+
+
+
\ No newline at end of file
diff --git a/app/services/admins/memos/_topic_form.html.erb b/app/services/admins/memos/_topic_form.html.erb
new file mode 100644
index 00000000..9012fe24
--- /dev/null
+++ b/app/services/admins/memos/_topic_form.html.erb
@@ -0,0 +1,17 @@
+<%= labelled_form_for(@memo, :url => forum_memos_path) do |f| %>
+
+
+ <%= hidden_field_tag :asset_id,params[:asset_id],:required => false,:style => 'display:none' %>
+
<%= f.text_field :subject, :required => true, :size => 95, :style => 'width:98%' %>
+
<%= f.kindeditor :content,:width=>'99%', :required => true %>
+
+
+
+
<%= l(:label_attachment_plural) %>
+
+ <%= render :partial => 'attachments/form', :locals => {:container => @memo} %>
+
+
+ <%= f.submit :value => l(:label_memo_create), :style => "margin-left: 100px;"%> <%= link_to l(:button_back), forum_path(@forum) %>
+
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/create.js.erb b/app/services/admins/memos/create.js.erb
new file mode 100644
index 00000000..d6405143
--- /dev/null
+++ b/app/services/admins/memos/create.js.erb
@@ -0,0 +1 @@
+window.location.href='<%= forum_memo_path(:forum_id => @memo.forum_id, :id => @memo.id ) %>';
\ No newline at end of file
diff --git a/app/services/admins/memos/destroy.js.erb b/app/services/admins/memos/destroy.js.erb
new file mode 100644
index 00000000..051b3074
--- /dev/null
+++ b/app/services/admins/memos/destroy.js.erb
@@ -0,0 +1,6 @@
+<% if params[:user_activity_id] %>
+$("#message_replies_box").html("<%= escape_javascript(render :partial => 'memos/memo_all_replies') %>");
+sd_create_editor_from_data(<%= @memo.id %>,"","100%", "<%= @memo.class.to_s %>");
+<% else %>
+$("#memo_detail_<%= params[:id] %>").remove();
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/edit.html.erb b/app/services/admins/memos/edit.html.erb
new file mode 100644
index 00000000..96f503fb
--- /dev/null
+++ b/app/services/admins/memos/edit.html.erb
@@ -0,0 +1,15 @@
+
+
+
+ <%= @user.show_name %> > 讨论 > 编辑
+
+
+
+ <%#= labelled_form_for(@memo, :url => forum_memos_path(@forum)) do |f| %>
+ <%= form_for @memo, :url => forum_memo_path(@memo.forum_id, @memo), :html => {:multipart => true, :id => 'memo-form'} do |f| %>
+ <%= render :partial => "memos/form", :locals => {:f => f, :edit => true} %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/services/admins/memos/message_replies.js.erb b/app/services/admins/memos/message_replies.js.erb
new file mode 100644
index 00000000..545b65f4
--- /dev/null
+++ b/app/services/admins/memos/message_replies.js.erb
@@ -0,0 +1,9 @@
+<%# if @user_activity_id != @memo.id %>
+/* $("#activity_post_reply_<%#= @user_activity_id %>").html("<%#= escape_javascript(render :partial => 'users/course_message_post_reply',
+ :locals => { :activity => @memo,
+ :user_activity_id => @user_activity_id}) %>");
+ sd_create_editor_from_data(<%#= @user_activity_id%>,"","100%", "UserActivity");*/
+<%# else %>
+ $("#message_replies_box").html("<%= escape_javascript(render :partial => 'memos/memo_all_replies') %>");
+ sd_create_editor_from_data(<%= @memo.id %>,"","100%", "<%= @memo.class.to_s %>");
+<%# end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/new.html.erb b/app/services/admins/memos/new.html.erb
new file mode 100644
index 00000000..325febcc
--- /dev/null
+++ b/app/services/admins/memos/new.html.erb
@@ -0,0 +1,15 @@
+
+
+
+ <%= @user.show_name %> > 讨论区 > 新建
+
+
+
+ <%#= labelled_form_for(@memo, :url => forum_memos_path(@forum)) do |f| %>
+ <%= form_for @memo, :url => forum_memos_path(@forum), :html => {:multipart => true, :id => 'memo-form'} do |f| %>
+ <%= render :partial => "memos/form", :locals => {:f => f, :edit => false} %>
+ <% end %>
+
+
\ No newline at end of file
diff --git a/app/services/admins/memos/new.js.erb b/app/services/admins/memos/new.js.erb
new file mode 100644
index 00000000..e69de29b
diff --git a/app/services/admins/memos/quote.js.erb b/app/services/admins/memos/quote.js.erb
new file mode 100644
index 00000000..563973be
--- /dev/null
+++ b/app/services/admins/memos/quote.js.erb
@@ -0,0 +1,6 @@
+if($("#reply_message_<%= @memo.id%>").html() == "") {
+ $(".reply_to_message").html("");
+ $("#reply_message_<%= @memo.id%>").replaceWith("<%= escape_javascript(render :partial => 'memos/reply_message', :locals => {:reply => @memo}) %>");
+}else {
+ $("#reply_message_<%= @memo.id%>").html("");
+}
\ No newline at end of file
diff --git a/app/services/admins/memos/show.html.erb b/app/services/admins/memos/show.html.erb
new file mode 100644
index 00000000..2cb6d732
--- /dev/null
+++ b/app/services/admins/memos/show.html.erb
@@ -0,0 +1,233 @@
+<%= content_for(:header_tags) do %>
+ <%= import_ke(enable_at: false, prettify: false, init_activity: true) %>
+<% end %>
+
+
+
+
+ <%= @user.show_name %> > 讨论区
+
+
+
+ 帖子详情
+
+ <%= link_to '返回', forums_path(:type => @type, :page => @forum_page), :class => 'fr font-12 mr15 mt3 color-grey' %>
+
+
+
+
+
+
+
+ <%= @memo.content.html_safe %>
+
+
+
+ <% if @memo.attachments.any?%>
+ <% options = {:author => true, :deletable => @memo.deleted_attach_able_by?(User.current) } %>
+ <%= render :partial => 'attachments_links', :locals => {:attachments => @memo.attachments, :options => options, :is_float => true} %>
+ <% end %>
+
+
+
+ <%= render :partial => "memo_all_replies" %>
+
+
+
+
+
+
+
+
+
+<% if false %>
+ <%= content_for(:header_tags) do %>
+ <%= import_ke(enable_at: false, prettify: false, init_activity: true) %>
+ <%= javascript_include_tag 'forum' %>
+ <% end %>
+
+
+ <%= link_to "问吧", forums_path, :class => "c_blue" %> > <%= link_to @forum.name, forum_path(@forum), :class => "c_blue" %> > <%=h @memo.subject %>
+
+
+
+
+
+
+ <%= link_to image_tag(url_to_avatar(@memo.author),:width=>50,:height => 50,:alt=>'贴吧图像' ),user_path(@memo.author) %>
+
+
+ <% if @memo.author.id == User.current.id || User.current.admin? || User.current == @forum.creator %>
+
+
+
+
+ <% if @memo.author.id == User.current.id || User.current.admin? %>
+ 编辑
+ <% end %>
+ <% if User.current.admin? || User.current == @forum.creator %>
+ <% if @memo.sticky %>
+ 取消置顶
+ <% else %>
+ 置顶
+ <% end %>
+ <% end %>
+ 删除
+
+
+
+
+
+ <% end %>
+
+ <%= render :partial => "memos/praise_tread",:locals => {:obj => @memo,:show_flag => true,:user_id =>User.current.id,:horizontal => true}%>
+
+
+
+ <%= link_to @memo.author.show_name, user_path(@memo.author), :class => "linkBlue2", :target=> "_blank"%>
+
<%= format_date( @memo.created_at)%>
+
+
+ <%= @memo.content.html_safe%>
+
+
+
+ <% if @memo.attachments.any?%>
+ <% options = {:author => true, :deletable => @memo.deleted_attach_able_by?(User.current) } %>
+ <%= render :partial => 'attachments_links', :locals => {:attachments => @memo.attachments, :options => options, :is_float => true} %>
+ <% end %>
+
+
+
更新时间:<%= format_date(@memo.updated_at)%>
+
+
+
+
+
+
+
回复(<%= @reply_count %>)
+
+
+
+ <%= render :partial => 'memos/memo_all_replies' %>
+
+
+
+
<%= link_to image_tag(url_to_avatar(User.current), :width => "33", :height => "33"), user_path(User.current), :alt => "用户头像" %>
+
+ <% if User.current.logged? %>
+
+ <%= form_for('memo',:url=>forum_memos_path,:method => "post") do |f|%>
+ <%= f.hidden_field :subject, :required => true, value: @memo.subject %>
+ <%= f.hidden_field :forum_id, :required => true, value: @memo.forum_id %>
+ <%= f.hidden_field :parent_id, :required => true, value: @memo.id %>
+ <%= hidden_field_tag :quote,"",:required => false,:style => 'display:none' %>
+
+
+
发送
+
+
+ <% end%>
+
+ <% else %>
+ <%= render :partial => "users/show_unlogged" %>
+ <% end %>
+
+
+
+
+
+
+
+ <%= render :partial => "memos/my_show_count_message" %>
+
+
+
+
+
+<% end %>
\ No newline at end of file
diff --git a/app/services/admins/memos/show.js.erb b/app/services/admins/memos/show.js.erb
new file mode 100644
index 00000000..8ac3f619
--- /dev/null
+++ b/app/services/admins/memos/show.js.erb
@@ -0,0 +1 @@
+$("#more_memo_replies").replaceWith("<%= escape_javascript(render :partial => 'memos/memo_all_replies')%>");
\ No newline at end of file
diff --git a/app/services/admins/memos/update.js.erb b/app/services/admins/memos/update.js.erb
new file mode 100644
index 00000000..ddd19204
--- /dev/null
+++ b/app/services/admins/memos/update.js.erb
@@ -0,0 +1,5 @@
+<% if @flag%>
+window.location.href='<%= forum_memo_path(:forum_id=>@memo.forum_id,:id=>@memo.id ) %>'
+<%else%>
+$("#error").html('内容填写存在错误');
+<% end %>
\ No newline at end of file
diff --git a/app/services/forum_sections_service.rb b/app/services/forum_sections_service.rb
new file mode 100644
index 00000000..5146593c
--- /dev/null
+++ b/app/services/forum_sections_service.rb
@@ -0,0 +1,575 @@
+# encoding=utf-8
+
+class ForumSectionsService
+ include ApplicationHelper
+ include ApiIndexHelper
+ LIMIT = 10
+
+ def index params
+ index_sections = all_sections(params[:is_detail] || nil)
+ {status: 0, forum_sections: index_sections}
+ end
+
+ def select_sections
+ forum_root_tags = ForumSection.roots.select([:id, :title, :ancestry])
+ get_all_sections(forum_root_tags)
+ end
+
+ def create params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+
+ if params[:title].strip.length > 20
+ {status: -1, message: "不能超过最大限制:20个字符"}
+ elsif ForumSection.exists?(title: params[:title].strip)
+ {status: -1, message: "不能重名"}
+ else
+ forum_section_params = {
+ user_id: current_user.id,
+ title: params[:title].strip,
+ parent_id: params[:id],
+ is_recommend: false
+ }
+ forum_section = ForumSection.new(forum_section_params)
+ if forum_section.save
+ {status: 0, message: "创建成功", title: params[:title], childre_section_id: forum_section.id }
+ else
+ {status: -1, message: "保存失败"}
+ end
+ end
+ end
+
+ def rename params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+
+ if params[:title].strip.length > 20
+ {status: -1, message: "不能超过最大限制:20个字符"}
+ elsif ForumSection.exists?(title: params[:title].strip)
+ {status: -1, message: "不能重名"}
+ else
+ forum_section = ForumSection.find(params[:children_section_id])
+ if forum_section.update_attribute(:title, params[:title].strip)
+ {status: 0, message: "重命名成功", title: params[:title].strip, childre_section_id: params[:children_section_id] }
+ else
+ {status: -1, message: "重命名失败"}
+ end
+ end
+ end
+
+ def destroy params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ forum_section = ForumSection.find(params[:children_section_id])
+ if forum_section.destroy
+ {status: 0, message: "删除成功"}
+ else
+ {status: -1, message: "删除失败"}
+ end
+ end
+
+ def order_forums params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+
+ children_forums = @forum_section.children_forum.order("created_at #{params[:order_type]}")
+ children_forums_sections = get_children_sections(children_forums)
+ forum_tag = {
+ title: @forum_section.try(:title),
+ id: @forum_section.try(:id),
+ children_tags: children_forums_sections
+ }
+ {status:0, forum_tag: forum_tag }
+ end
+
+ def search_users params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+
+ search_users = []
+ user_name = params[:user_name].to_s.strip
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ offset = page * LIMIT
+ # if user_name.blank?
+ # users_count = 0
+ # else
+ #
+ # end
+ users = User.where("( LOWER(login) LIKE ? or LOWER(concat(lastname, firstname)) LIKE ? or LOWER(mail) LIKE ? )",
+ "%#{user_name}%","%#{user_name}%","%#{user_name}%")
+ users_count = users.size
+ users = users.order("created_on desc").limit(LIMIT).offset(offset)
+ users.each do |u|
+ user_item = {
+ id: u.id,
+ login: u.try(:login),
+ username: u.try(:show_name),
+ nickname: u.try(:nickname)
+ }
+ search_users.push(user_item)
+ end
+ {status:0, user_lists: search_users, users_count: users_count, limit: LIMIT}
+
+ end
+
+ def add_users params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ user_ids = params[:user_ids].reject(&:blank?)
+ children_forum_id = params[:children_section_id]
+
+ if user_ids.present?
+ forum_users = []
+ user_ids.each do |id|
+ unless ForumModerator.exists?(user_id: id, forum_section_id:children_forum_id)
+ moder_lists = {
+ user_id: id,
+ forum_section_id: children_forum_id,
+ is_children: true
+ }
+ new_forum_moder = ForumModerator.new(moder_lists)
+ if new_forum_moder.save
+ user = new_forum_moder.user
+ user_list = {
+ forum_moderator_id: new_forum_moder.id,
+ login: user.try(:login),
+ username: user.try(:show_name),
+ user_url: "/users/#{user.try(:login)}"
+ }
+ forum_users.push(user_list)
+ end
+ end
+ end
+
+ {status:0, message: "用户添加成功", user_lists: forum_users}
+ else
+ {status:-1, message: "请添加管理员"}
+ end
+
+
+ end
+
+ #一级版主的管理模块
+ def managements params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ bread_crumb = get_bread_crumb(@forum_section, current_user)
+
+ #当为一级分类时
+ # current_user_info = format_for_current_user current_user
+ if @forum_section.root?
+ children_forum_sections = @forum_section.children.select([:id,:title, :ancestry])
+ children_forum_users = get_children_sections(children_forum_sections)
+ forum_tag = {
+ title: @forum_section.try(:title),
+ id: @forum_section.try(:id),
+ children_tags: children_forum_users
+ }
+ else #当为二级分类时
+ forum_tag = {
+ title: @forum_section.try(:title),
+ id: @forum_section.try(:id)
+ }
+ end
+
+ # if @forum_section.parent_id.present?
+ # forum_tag = {
+ # title: @forum_section.try(:title),
+ # id: @forum_section.try(:id),
+ # }
+ # else #当为一级分类时
+ # children_forum_sections = ForumSection.where(parent_id: @forum_section.id).select([:id,:title])
+ # children_forum_users = get_children_sections(children_forum_sections)
+
+ # forum_tag = {
+ # title: @forum_section.try(:title),
+ # id: @forum_section.try(:id),
+ # children_tags: children_forum_users
+ # }
+ # end
+
+ user_management_sections = []
+ #当前用户具有的管理权限的版块
+ current_user_forum_ids = current_user.forum_moderators.pluck(:forum_section_id)
+ current_user_parent_forums = ForumSection.roots.where(id: current_user_forum_ids).select([:id,:title, :ancestry])
+ current_user_parent_forums.each do |section|
+ manage_children_forum_sections = section.children.select([:id,:title])
+ section_forum_tag = {
+ title: section.try(:title),
+ id: section.try(:id),
+ children_tags: object_to_hash(manage_children_forum_sections)
+ }
+ user_management_sections.push(section_forum_tag)
+ end
+
+ {status: 0, bread_crumb: bread_crumb, forum_tag: forum_tag, user_manage_sections: user_management_sections}
+
+ end
+
+ #处理申请的页面
+ def applied_forums params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ if @forum_section.parent_id.present?
+ applied_forum_moderators = {}
+ else
+ applied_forum_moderators = []
+ all_applied_forums = @forum_section.apply_forums.where(is_confirm: 0) #待审批的版主申请
+ if all_applied_forums.size > 0
+ all_applied_forums.each do |apply|
+ user = apply.user
+ forum_section = apply.forum_section
+ parent_forum_section_array = {}
+ if forum_section.parent_id.present?
+ parent_forum_section = forum_section.parent_forum
+ parent_forum_section_array = {
+ forum_title: parent_forum_section.try(:title),
+ forum_id: parent_forum_section.try(:id),
+ forum_url: "/memos/forum_memos/#{parent_forum_section.try(:id)}",
+ }
+ end
+ apply_user = {
+ apply_id: apply.id,
+ username: user.try(:show_name),
+ login: user.try(:login),
+ image_url: "#{url_to_avatar(user)}?#{Time.now.to_i}",
+ user_url: "/users/#{user.try(:login)}",
+ user_ip: apply.user_ip,
+ user_ip_address: get_user_ip(apply.user_ip),
+ time: time_from_now(apply.created_at),
+ forum_title: forum_section.try(:title),
+ forum_id: forum_section.try(:id),
+ forum_url: "/memos/forum_memos/#{forum_section.try(:id)}",
+ parent_forum: parent_forum_section_array
+ }
+ applied_forum_moderators.push(apply_user)
+ end
+ end
+ end
+
+ {status: 0, applied_moderators: applied_forum_moderators}
+ end
+
+ #处理版主的申请
+ def deal_applies params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ apply_forum = ApplyForum.find(params[:apply_id])
+ if apply_forum.present?
+ apply_forum.update_attributes(is_confirm: params[:deal_type].to_i, confirm_user_id: current_user.id, deal_time: Time.now)
+ forum_moder = ForumModerator.where(user_id: apply_forum.user_id,forum_section_id: params[:id])
+ if params[:deal_type].to_i == 2
+ forum_moder.delete_all if forum_moder.exists?
+ elsif params[:deal_type].to_i == 1
+ unless forum_moder.exists?
+ ForumModerator.create(user_id: apply_forum.user_id, forum_section_id: params[:id],is_children: @forum_section.try(:parent_id).present?)
+ end
+ end
+
+ review_params = {
+ review_status: params[:deal_type].to_i,
+ reason: nil,
+ user_id: current_user.id,
+ reviewable_type: "ApplyForum",
+ reviewable_id: params[:apply_id],
+ source: "apply_forum"
+ }
+ if Review.exists?(reviewable_type: "ApplyForum", reviewable_id: params[:apply_id], source: "apply_forum")
+ this_review = Review.where(reviewable_type: "ApplyForum", reviewable_id: params[:apply_id], source: "apply_forum").first
+ this_review.update_attributes(review_params)
+ else
+ Review.create(review_params)
+ end
+ status = 1
+ msg = "操作成功"
+ else
+ status = -1
+ msg = "操作失败"
+ end
+ {status: status, message: msg}
+ end
+
+ def destroy_moderator params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ forum_manager = ForumModerator.find(params[:moderator_id])
+ if forum_manager.present?
+ if forum_manager.destroy
+ status = 1
+ msg = "删除成功"
+ else
+ status = -1
+ msg = "删除失败"
+ end
+ else
+
+ status = -1
+ msg = "用户不存在"
+ end
+ {status: status, message: msg}
+ end
+
+
+ def user_apply params, current_user, user_ip
+ set_forum_section(params[:id])
+ if @forum_section.forum_moderators.exists?(user_id: current_user.id)
+ status = -1
+ msg = "您已经是该版块的版主"
+ elsif ApplyForum.exists?(user_id: current_user.id, is_confirm: [0,1])
+ status = -1
+ msg = "您已提交了版主申请"
+ else
+ apply_params = {
+ user_id: current_user.id,
+ user_ip: user_ip,
+ forum_section_id: params[:id],
+ is_confirm: 0
+ }
+ apply_forum = ApplyForum.new(apply_params)
+ if apply_forum.save
+ status = 0
+ msg = "申请成功"
+ if @forum_section.parent_id.present?
+ parent_section_id = @forum_section.parent_id
+ manager_ids = ForumModerator.where(forum_section_id: @forum_section.parent_id).pluck(:user_id)
+ extra = "2"
+ else
+ parent_section_id = ""
+ admin_role_ids= AdminRole.includes(:admin_permissions).joins(:admin_permissions).where("admin_permissions.name = 'forum_post'").pluck(:id)
+ manager_ids = UserAdminRole.where(admin_role_id: admin_role_ids).pluck(:user_id).uniq
+ extra = "1"
+ end
+ if manager_ids.size == 0
+ manager_ids = [1]
+ end
+ manager_ids.each do |id|
+ Tiding.create(:user_id => id, :trigger_user_id => current_user.id,
+ container_id: params[:id], container_type: 'ForumSection',
+ :parent_container_id => parent_section_id, :parent_container_type => "ForumSection",
+ :viewed => 0,status: 0, :tiding_type => "ForumSection",extra: extra)
+ end
+ else
+ status = -1
+ msg = "申请失败,请稍后重试"
+ end
+ end
+
+ {status: status, message: msg }
+ end
+
+ #待审核的帖子
+ def unchecked_memos params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+ select_section_ids = [params[:id]]
+ unless @forum_section.parent_id.present?
+ children_forums = @forum_section.children_forum.pluck(:id)
+ select_section_ids = select_section_ids + children_forums
+ end
+ select_section_ids.uniq
+
+ # page = params[:page].to_i
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+
+ offset = page * LIMIT
+ memo_forum_section_ids = MemoForum.where(forum_id: select_section_ids).pluck(:memo_id).uniq
+ memos_all = Memo.where(hidden:true, published_at: nil, parent_id: nil, id: memo_forum_section_ids).order("created_at desc")
+
+ # memos_all = Memo.where(hidden: true, parent_id: nil, id: memo_forum_section_ids).joins(:memo_forums).where("memo_forums.forum_id in (#{select_section_ids.join(",")})").order("created_at desc")
+ memos_count = memos_all.size
+
+ memos = memos_all.limit(LIMIT).offset(offset)
+ memos_lists = []
+ memos.each do |memo|
+ user = memo.author
+ is_banned = user_is_banned?(user)
+ if memo.memo_forums.exists?(is_children: true)
+ memo_min_sections = memo.memo_forums.where(is_children: true).first
+ else
+ memo_min_sections = memo.memo_forums.first
+ end
+ memo_last_section = memo_min_sections.forum_section
+
+ memo_list = {
+ memo_id: memo.id,
+ is_banned: is_banned,
+ memo_title: memo.subject,
+ username: user.try(:show_name),
+ login: user.try(:login),
+ image_url: "#{url_to_avatar(user)}?#{Time.now.to_i}",
+ user_url: "/users/#{user.try(:login)}",
+ user_id: user.try(:id),
+ time: time_from_now(memo.updated_at),
+ forum_title: memo_last_section.try(:title),
+ forum_id: memo_last_section.try(:id),
+ forum_url: "/memos/forum_memos/#{memo_last_section.try(:id)}",
+ }
+ memos_lists.push(memo_list)
+ end
+ {status:0, memos_count: memos_count, memos_lists: memos_lists, limit: LIMIT}
+ end
+
+ def unchecked_replies params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+
+ select_section_ids = [params[:id]]
+ unless @forum_section.parent_id.present?
+ children_forums = @forum_section.children_forum.pluck(:id)
+ select_section_ids = select_section_ids + children_forums
+ end
+ select_section_ids.uniq
+
+ # page = params[:page].to_i
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+
+ offset = page * LIMIT
+ #全部的父帖子
+ parent_memos_ids = Memo.where(parent_id: nil).joins(:memo_forums).where("memo_forums.forum_id in (#{select_section_ids.join(",")})").pluck(:id).uniq
+ memos_all = Memo.where(hidden:true,published_at: nil, parent_id: parent_memos_ids).order("created_at ASC")
+ memos_count = memos_all.size
+
+ memos = memos_all.limit(LIMIT).offset(offset)
+ memos_lists = []
+
+ memos.each do |memo|
+ user = memo.author
+ is_banned = user_is_banned?(user)
+ parent_memo = Memo.find_by_id(memo.parent_id)
+
+ memo_list = {
+ is_banned: is_banned,
+ reply_id: memo.id,
+ reply_content: memo.content,
+ username: user.try(:show_name),
+ login: user.try(:login),
+ image_url: "#{url_to_avatar(user)}?#{Time.now.to_i}",
+ user_url: "/users/#{user.try(:login)}",
+ user_id: user.try(:id),
+ time: time_from_now(memo.updated_at),
+ source_title: parent_memo.try(:subject),
+ source_id: parent_memo.try(:id),
+ }
+ memos_lists.push(memo_list)
+ end
+ {status:0, replies_count: memos_count, replies_lists: memos_lists, limit: LIMIT}
+ end
+
+ def checked_memos params, current_user
+ set_forum_section(params[:id])
+ return {status: -1, message: "请登录"} unless check_user_permission(current_user, params[:id])
+
+ select_section_ids = [params[:id]]
+ unless @forum_section.parent_id.present?
+ children_forums = @forum_section.children_forum.pluck(:id)
+ select_section_ids = select_section_ids + children_forums
+ end
+ select_section_ids.uniq
+
+ # page = params[:page].to_i
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+
+ offset = page * LIMIT
+ #全部的父帖子
+ memo_forum_section_ids = MemoForum.where(forum_id: select_section_ids).pluck(:memo_id).uniq
+ memos_all = Memo.where(hidden: false,parent_id: nil, id: memo_forum_section_ids).order("created_at desc")
+ # memos_all = Memo.where(hidden: false, parent_id: nil).joins(:memo_forums).where("memo_forums.forum_id in (#{select_section_ids.join(",")})")
+ if params[:type].present?
+ if params[:type] == "sticky"
+ memos_all = memos_all.where(sticky: true)
+ end
+
+ if params[:type] == "is_fine"
+ memos_all = memos_all.where(is_fine: true)
+ end
+ end
+ memos_all = memos_all.order("sticky desc, is_fine desc,published_at desc")
+
+ memos_count = memos_all.size
+
+ memos = memos_all.limit(LIMIT).offset(offset)
+ memos_lists = []
+
+ memos.each do |memo|
+ user = memo.author
+ is_banned = user_is_banned?(user)
+ if memo.memo_forums.exists?(is_children: true)
+ memo_min_sections = memo.memo_forums.where(is_children: true).first
+ else
+ memo_min_sections = memo.memo_forums.first
+ end
+ memo_last_section = memo_min_sections.forum_section
+
+ memo_list = {
+ memo_id: memo.id,
+ is_banned: is_banned,
+ memo_title: memo.subject,
+ username: user.try(:show_name),
+ login: user.try(:login),
+ image_url: "#{url_to_avatar(user)}?#{Time.now.to_i}",
+ user_url: "/users/#{user.try(:login)}",
+ time: time_from_now(memo.updated_at),
+ forum_title: memo_last_section.try(:title),
+ forum_id: memo_last_section.try(:id),
+ forum_url: "/memos/forum_memos/#{memo_last_section.try(:id)}",
+ is_fine: memo.is_fine,
+ sticky: memo.sticky
+ }
+ memos_lists.push(memo_list)
+ end
+ {status:0, memos_count: memos_count, memos_lists: memos_lists, limit: LIMIT}
+ end
+
+ def forum_section_header params, current_user
+ forum_section = ForumSection.find_by_id(params[:id])
+ bread_crumb = get_bread_crumb(forum_section, current_user)
+ {status: 0, bread_crumb: bread_crumb}
+ end
+
+
+ def edit_notice params
+ forum_section = ForumSection.find_by_id(params[:id])
+ return {status: -1, message: "版块不存在"} if forum_section.blank?
+ return {status: -1, message: "请输入公告内容"} if params[:content].blank?
+ notice = forum_section&.section_notice
+ if notice.present?
+ notice.update_attribute(:content, params[:content])
+ message = "公告修改成功"
+ else
+ SectionNotice.create!(forum_section_id: params[:id], content: params[:content], user_id: forum_section.user_id)
+ message = "公告添加成功"
+ end
+ return {status: 1, message: message}
+ end
+
+ protected
+
+ def set_forum_section(section_id)
+ @forum_section = ForumSection.find(section_id)
+ unless @forum_section.present?
+ {status: 404}
+ end
+ end
+
+ def check_user_permission(current_user, forum_id)
+ if current_user.blank?
+ check_user_permission = false
+ else
+ if @forum_section.parent_id.present?
+ parent_section_id = @forum_section.parent_id
+ else
+ parent_section_id = forum_id
+ end
+ check_user_permission = (current_user.admin? || ForumModerator.where(forum_section_id: parent_section_id, user_id: current_user.id) || current_user.admin_permission?('forum_post'))
+
+ end
+ check_user_permission
+ end
+
+ # 将数据库对象转换成哈希对象
+ def object_to_hash objects
+ objects.map{|o| o.attributes.dup}
+ end
+
+
+end
\ No newline at end of file
diff --git a/app/services/memos_service.rb b/app/services/memos_service.rb
new file mode 100644
index 00000000..75752b97
--- /dev/null
+++ b/app/services/memos_service.rb
@@ -0,0 +1,795 @@
+# encoding=utf-8
+class MemosService
+ include ApplicationHelper
+ include ApiIndexHelper
+ include ActionView::Helpers::NumberHelper
+ LIMIT = 10
+
+ def index params, current_user
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ index_limit = params[:limit] || 5
+ offset = page * index_limit.to_i
+ search = params[:search].to_s.strip
+ sort_name = params[:sort] || "published_at"
+
+ all_memos = Memo&.visible&.roots&.includes(:forum_section,author: :user_extensions)
+
+ all_hottest_memos = all_memos.hottest_five_memos
+ hottest_memos = object_to_hash(all_hottest_memos)
+
+ all_recommend_memos = all_memos.recommend_five_memos
+ recommend_memos = object_to_hash(all_recommend_memos)
+
+ if search.present?
+ all_memos = all_memos.where("subject like ?", "%#{search}%")
+ end
+
+ memos_count = all_memos.size # 帖子的总数
+ all_memos = all_memos.order_index(sort_name).limit(index_limit).offset(offset)
+
+ memo_lists = get_memo_lists(all_memos, false, current_user, false)
+
+ {status: 0,limit: index_limit, memos_count: memos_count,
+ hottest_memos: hottest_memos, recommend_memos: recommend_memos, memos: memo_lists}
+ end
+
+
+ def related_memos params
+ memo = Memo.find(params[:id])
+ return { status: 404 } if memo.hidden? && (!current_user || !(current_user.admin? || current_user.id == memo.author_id))
+ all_memos = Memo.visible.roots.where("id != ?", params[:id].to_i).includes(memo_forums: :forum_section,author: :user_extensions).related_search_name(memo.try(:subject).to_s).order_index("published_at").limit(5).offset(0)
+ memo_lists = get_memo_lists(all_memos, false, current_user, false)
+ {status: 0, memos: memo_lists}
+ end
+
+ def new params, current_user, session
+ return {status: -1, message: "您的账户已被禁言,如有疑问请联系版主或论坛管理员"} if user_is_banned?(current_user)
+ csrf_token = session[:_csrf_token] ||= SecureRandom.base64(32)
+ params_section = {}
+ if params[:section_id].present?
+ current_forum_section = ForumSection.find_by_id(params[:section_id])
+ params_section = {
+ id: current_forum_section.id,
+ title: current_forum_section.title,
+ parent_section_id: current_forum_section.ancestry,
+ parent_section_title: current_forum_section&.parent&.try(:title)
+ }
+ end
+
+ {status:0,:csrf_token => csrf_token, params_section: params_section}
+
+ end
+
+ # params 直接传params[:memo][:subject]
+ # subject标题
+ # content内容
+ # forum_id 话题类型
+ # sticky 是否置顶(创建时没入口)
+ # repertoire_name + language 技术标签
+ # attachments 附件
+ # attachment_id 是帖子的头像
+ def create params, current_user
+ return {status: -1, message: "请填写必填的内容"} if params[:memo][:subject].blank? || params[:memo][:content].blank? || params[:forum_id].blank? || params[:memo][:tag_id].blank? || params[:memo][:is_original].blank?
+ {status: -1, message: "请填写必填的内容"}
+ # elsif params[:memo][:content].length > 2000
+ # {status: -1, message: "不能超过2000个字符"}
+ return {status: -1, message: "您的账户已被禁言,如有疑问请联系版主或论坛管理员"} if user_is_banned?(current_user)
+ begin
+ memo = Memo.new(params[:memo])
+ memo.author = current_user
+ memo.forum_section_id = params[:children_forum_id].present? ? params[:children_forum_id] : params[:forum_id]
+
+ # memo.published_at = Time.now if params[:memo][:published_at].blank?
+ memo.hidden = true
+ # memo.save!
+ if memo.save
+ memo.update_attachments(params[:attachments]) if params[:attachments].present?
+ # 为了区分帖子头像,改变其类型为MemoIcon
+ create_user_tidings(memo, "forum_post")
+
+ if params[:attachment_id]
+ attachment = Attachment.find(params[:attachment_id])
+ attachment.update_attributes(:container_id => memo.id, :container_type => "Memo", :memo_image => true)
+ end
+ {status: 1, message: "帖子创建成功,请等待管理员审核", memo_id: memo.id}
+ else
+ {status: -1, message: memo.errors.messages.values[0][0]}
+ end
+ rescue => e
+ {status: -1, message: "出现错误"}
+ raise ActiveRecord::RollBack
+ end
+ end
+
+ # params
+ # :id 帖子id
+ # return
+ # :memo 帖子
+ # :memo_replies 帖子的回复
+ # :recommend_shixun 推荐实训
+ # :admin 当前用户是否是管理员
+ # :author_info 表示当前帖子用户的信息
+ def show params, current_user
+ memo = Memo.find(params[:id])
+ return { status: 404 } if memo.hidden? && (!current_user || !(current_user.admin? || current_user.id == memo.author_id))
+ is_banned = user_is_banned?(current_user)
+ forum_section = memo&.forum_section
+
+ watcher_params = {
+ visitable_type: "Memo",
+ visitable_id: params[:id],
+ user_id: current_user.id
+ }
+ #帖子的二级分类
+ forum_tag = {
+ title: forum_section.try(:title),
+ id: forum_section.try(:id)
+ }
+ # 消息总数
+ attachments_list = acttachements_info memo.attachments.where(:memo_image => false)
+ memo_image = memo.attachments.where(:memo_image => true).first
+ memo_image_info = {:id => memo_image.id, :filename => memo_image.filename, :url => "/attachments/download/" + "#{memo_image.id}" + "/" + "#{memo_image.filename}",
+ :filesize => memo_image.filesize} if memo_image
+
+ user_praise = PraiseTread.is_user_praise(memo.id, "Memo", current_user.try(:id)).exists?
+ memo.update_column(:viewed_count, memo.viewed_count + 1)
+ # 帖子的回复
+ memos = memo.reply_for_memo
+ unless current_user.try(:admin?) # 只有管理员和发布人能看到隐藏的回复
+ memos = memos.where("hidden = false or (hidden = true and author_id = ?)", current_user.try(:id))
+ end
+ memo_author = memo.author
+ memo_author_memos = memo_author.memos.visible.roots
+ memos = memos.includes(:praise_tread, :author).order_index("created_at").limit(LIMIT)
+ watched = memo_author.watched_by?(current_user)
+ banned_permission = user_banned_permission current_user, memo.forum_section_id #当前用户是否具有禁言的权限
+ memo_watched = memo.watched_by?(current_user)
+ # list = memo_list memos, current_user
+
+ is_md = memo.is_md
+
+ author_info = {username: memo_author.show_name,
+ watched: watched,
+ is_blocked: current_user&.blocked_for(memo_author.id),
+ is_blocked_by: memo_author&.blocked_for(current_user.id),
+ current_image_url: "/images/#{url_to_avatar(current_user)}?#{Time.now.to_i}",
+ image_url: "/images/#{url_to_avatar(memo_author)}?#{Time.now.to_i}",
+ identity: memo_author.identity,
+ login: memo_author.login,
+ user_id: memo_author.id,
+ description: memo_author&.user_extensions&.brief_introduction,
+ memos_count: memo_author_memos.posts.size,
+ replies_count: memo_author_memos.total_replies.size,
+ watchers_count: memo_author.watcher_users.size,
+ current_login: current_user.try(:login),
+ is_current_user: memo.author_id == current_user.try(:id)
+ }
+ recent_memos = memo_author_memos.posts.where("id != ?", params[:id].to_i).order_index("published_at").select([:id,:subject]).limit(3).as_json.map{|k| k["memo"]}
+
+ memo_info = {id: memo.id,
+ subject: memo.subject,
+ is_md: is_md,
+ content: memo.content,
+ time: time_from_now(memo.published_at.present? ? memo.published_at : memo.created_at),
+ published_time: rename_time_minute(memo.published_at),
+ hidden: memo.hidden,
+ memo_watched: memo_watched,
+ forum_tag: forum_tag, #类型
+ sticky: memo.sticky, # 置顶 1
+ is_fine: memo.is_fine, #是否加精
+ viewed_count: memo.viewed_count, #浏览
+ replies_count: memo.can_see_reply_count(current_user), #回复
+ praises_count: memo.praises_count, #赞数
+ reward: memo.reward,
+ attachment_url: attachments_list,
+ user_praise: user_praise,
+ tag_name: memo.meno_tag_name,
+ is_original: memo.is_original,
+ reprint_link: memo.reprint_link,
+ apply_destroy: current_user&.id == memo.author_id && memo.apply_destroy?,
+
+ }
+ if current_user
+ unless memo.children.blank?
+ memo.children.includes(:memo_messages).each do |child|
+ child.memo_messages.each do |memo_message|
+ memo_message.update_attributes(:viewed => true) if current_user.id == memo_message.user_id
+ end
+ end
+ end
+
+ query_memo_messages = memo.memo_messages
+ unless query_memo_messages
+ query_memo_messages.each do |query_memo_message|
+ query_memo_message.update_attributes(:viewed => true) if current_user.id == query_memo_message.user_id
+ end
+ end
+
+ if memo.author_id != current_user.id
+ if memo.visit_actions.exists?(watcher_params)
+ memo.visit_actions.where(watcher_params).first.update_attribute(:updated_at,Time.now)
+ else
+ VisitAction.create!(watcher_params)
+ end
+ end
+ end
+
+ {status: 0, memo: memo_info, author_info: author_info, memo_image_info: memo_image_info,
+ recent_memos: recent_memos,banned_permission: banned_permission, is_banned: is_banned, is_current_admin: current_user&.admin?, current_login: current_user&.login}
+ end
+
+ def more_reply params, current_user
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ limit = params[:limit] || 10
+ offset = page * limit.to_i
+ memo_id = params[:id]
+ memo = Memo.find(memo_id)
+
+ memos = memo.reply_for_memo
+ unless current_user.try(:admin?) # 只有管理员和发布人能看到隐藏的回复
+ memos = memos.where("hidden = false or (hidden = true and author_id = ?)", current_user.try(:id))
+ end
+
+
+ # 总数,分页使用
+ # memos_all = Memo.where(parent_id: memo_id, hidden: false)
+ memos_count = memos.count
+ memos = memos.includes(:praise_tread, :author).order_index("created_at").limit(limit).offset(offset)
+
+ list = memo_list memos, current_user
+ {:memo_replies => list, :memos_count => memos_count}
+ end
+
+
+
+ def confirm_delete params, current_user
+ memo = Memo.find(params[:id])
+ return {status: 404} unless memo.present?
+ return {status: -1, message: "您没有权限操作!"} unless current_user&.id == memo.author_id
+
+ if params[:is_apply].to_i == 1 #表示申请操作
+ memo.apply_destroy!
+ memo.save!
+ Tiding.create!(:user_id => 1, :trigger_user_id => current_user&.id,
+ container_id: memo.id, container_type: 'Memo',
+ :viewed => 0, :tiding_type => "apply_delete", :extra => "d_1")
+ {status: 1, message: "操作成功"}
+ else
+ memo.common!
+ memo.save!
+
+ Tiding.create!(:user_id => 1, :trigger_user_id => current_user&.id,
+ container_id: memo.id, container_type: 'Memo',
+ :viewed => 0, :tiding_type => "cancel_delete", :extra => "d_0")
+ {status: 1, message: "已取消申请删帖"}
+ end
+
+
+ end
+
+ def destroy params, current_user
+ user_permission = check_banned_permission current_user, params[:id]
+ memo = Memo.select([:id,:parent_id]).find(params[:id])
+ return {status: -1, message: "帖子不存在!"} unless memo.present?
+ return {status: -1, message: "您没有权限操作!"} unless user_permission
+ if memo.destroy
+ {status: 0, message: "帖子删除成功!"}
+ else
+ {status: -1, message: "帖子删除失败!"}
+ end
+ end
+
+ # 隐藏评论功能
+ def hidden params, current_user
+ memo = Memo.select([:id, :hidden]).find(params[:id])
+ if current_user.admin?
+ if params[:hidden] == "1"
+ memo.update_attribute(:hidden, true)
+ elsif params[:hidden] == "0"
+ memo.update_column("hidden", false)
+ end
+ else
+ raise("你没有权限")
+ end
+ end
+
+ def edit params, current_user
+ # memo_type = object_to_hash Forum.select([:id, :name])
+ # memo_tag = object_to_hash Label.select([:id, :name])
+ memo = Memo.select([:id, :subject, :content,:author_id,:tag_id, :is_original, :reprint_link, :forum_section_id]).find params[:id]
+ return {status: -1, message: "帖子不存在"} if memo.blank?
+ return {status: -1, message: "您的账户已被禁言,如有疑问请联系版主或论坛管理员"} if user_is_banned?(current_user)
+ return { status: -1, message: "您没有权限编辑" } unless current_user.present? && (current_user.admin? || (current_user.id == memo.author_id) || user_banned_permission(current_user, params[:id]))
+
+ attachments_list = acttachements_info memo.attachments.where(:memo_image => false)
+ memo_image = memo.attachments.where(:memo_image => true).first
+ memo_image_info = {:id => memo_image.id,
+ :filename => memo_image.filename,
+ :url => "/attachments/download/" + "#{memo_image.id}" + "/" + "#{memo_image.filename}",
+ :filesize => number_to_human_size(memo_image.filesize,significant: false, precision: 2)} if memo_image
+ banned_permission = user_banned_permission current_user, params[:id]
+ memo_forum_section = memo&.forum_section
+ if memo_forum_section&.parent.present?
+ forum_first = {
+ forum_id: memo_forum_section&.parent.try(:id),
+ forum_name: memo_forum_section&.parent.try(:title)
+ }
+ children_forum_first = {
+ children_forum_id: memo_forum_section.try(:id),
+ children_forum_name: memo_forum_section.try(:title)
+ }
+ else
+ forum_first = {
+ forum_id: memo_forum_section.try(:id),
+ forum_name: memo_forum_section.try(:title)
+ }
+ children_forum_first = {}
+ end
+ memo.attributes.merge!({banned_permission: banned_permission,
+ attachments_url: attachments_list,
+ memo_image_info: memo_image_info,
+ forum_section: forum_first,
+ children_forum_section: children_forum_first
+ })
+ end
+
+ def memo_hidden params, current_user
+ memo = Memo.find params[:id]
+ if params[:checked].to_s == 'true'
+ publish_time = Time.now
+ action_type = "passed"
+ extra = "1"
+ else
+ publish_time = Time.now
+ action_type = "refuse"
+ extra = "2"
+ end
+ memo.update_attributes(hidden: !(params[:checked].to_s == 'true'), published_at: publish_time) # 勾选代表不隐藏,所以要取反
+ CheckedAction.create!(user_id: current_user.id,checkable_type: "Memo",checkable_id: params[:id], action_type: action_type, action_at: Time.now)
+
+
+ if !memo.hidden? && memo.parent_id.present? && !memo.tidings.exists?(user_id: memo.parent.author_id,trigger_user_id: memo.author_id, extra: "3")
+ Tiding.create(:user_id => memo.parent.author_id, :trigger_user_id => memo.author_id,
+ container_id: memo.id, container_type: 'Memo',
+ :parent_container_id => memo.root_id, :parent_container_type => "Memo",
+ :viewed => 0, :tiding_type => "Comment", :extra => "3")
+
+ elsif !memo.hidden? && memo.parent_id.blank?
+ Tiding.create(:user_id => memo.author_id, :trigger_user_id => current_user.id,
+ container_id: memo.id, container_type: 'Memo',
+ :viewed => 0, :tiding_type => "Comment",:extra => extra)
+
+ end
+ {status: 1, message: "设置成功", is_hidden: memo.hidden}
+ end
+
+ def update params, current_user
+ if params[:memo][:subject].blank? || params[:memo][:content].blank? || params[:forum_id].blank? || params[:children_forum_id].blank?
+ {status: -1, message: "帖子内容不能为空"}
+ elsif user_is_banned?(current_user)
+ {status: -1, message: "您的账户已被禁言,如有疑问请联系版主或论坛管理员"}
+ else
+ memo = Memo.find params[:id]
+ return { status: 404 } if memo.hidden? && (!current_user || !(current_user.admin? || current_user.id == memo.author_id))
+ memo.update_attributes(params[:memo])
+ memo.update_attachments(params[:attachments]) if params[:attachments].present?
+ memo.forum_section_id = params[:children_forum_id].present? ? params[:children_forum_id] : params[:forum_id]
+ if memo.save!
+ if params[:attachment_id]
+ attachment = Attachment.find(params[:attachment_id])
+ attachment.update_attributes(:container_id => memo.id, :container_type => "Memo", :memo_image => true)
+ end
+
+ {status: 1, message: "帖子更新成功!"}
+ else
+ {status: -1, message: memo.errors.messages.values[0][0]}
+ end
+ end
+ end
+
+
+ # params
+ # parent_id: 给谁的回复(id)
+ # content: 回复的内容
+ def reply params, current_user
+ memo = Memo.find params[:parent_id]
+ return {status: -1, message: "您的账户已被禁言,如有疑问请联系版主或论坛管理员"} if user_is_banned?(current_user)
+ return {status: -1, message: "根据对方设置,暂时不能评论"} if memo.author.blocked_for(current_user&.id)
+ return { status: 404 } if memo.hidden? && (!current_user || !(current_user.admin? || current_user.id == memo.author_id))
+ begin
+ memo_params = {
+ parent_id: params[:parent_id] || nil,
+ content: params[:content].to_s,
+ subject: memo.subject,
+ author_id: current_user.id,
+ root_id: memo.root_id || memo.id,
+ hidden: true
+ }
+
+ reply = Memo.new(memo_params)
+
+ if reply.save
+ memo.update_attribute(:last_reply_on, Time.now)
+ memo.children << reply
+ create_user_tidings(reply, "forum_comment")
+ replies = {:id => reply.id, :content => reply.content, :time => time_from_now(reply.created_at), :user_id => reply.author_id,
+ :image_url => "/images/#{url_to_avatar(reply.author)}?#{Time.now.to_i}", :username => reply.author.show_name, :reward => memo.reward, :hidden => reply.hidden,
+ :praise_count => reply.praises_count,:user_login => reply.author.try(:login), replies_count: reply.can_see_reply_count(current_user)}
+ {
+ status: 0,
+ reply: replies
+ }
+ else
+ {status: -1, message: reply.errors.messages.values[0][0]}
+ end
+ rescue => e
+ {status: -1, message: "出现错误"}
+ raise ActiveRecord::RollBack
+ end
+ end
+
+ def watch_memo params, current_user
+ memo = Memo.find params[:id]
+ if params[:is_watch] == 1
+ if Watcher.exists?(watchable_type: "Memo", watchable_id: params[:id], user_id: current_user.id)
+ w_status = -1
+ w_msg = "您已收藏"
+ else
+ memo_watch = Watcher.new(watchable: memo, user_id: current_user.id)
+ if memo_watch.save
+ w_status = 0
+ w_msg = "收藏成功"
+ else
+ w_status = -1
+ w_msg = "收藏失败,请稍后重试"
+ end
+ end
+ else
+ if Watcher.exists?(watchable_type: "Memo", watchable_id: params[:id], user_id: current_user.id)
+ Watcher.where(watchable_type: "Memo", watchable_id: params[:id], user_id: current_user.id).destroy_all
+ w_status = 0
+ w_msg = "取消收藏成功"
+ else
+ w_status = -1
+ w_msg = "您还未添加收藏"
+ end
+ end
+ {status: w_status, message: w_msg}
+ end
+
+ # params:
+ # order: 排序
+ # sticky: 1 置顶,0 取消置顶
+ # id: 帖子ID
+ def set_top_or_down params, current_user
+ user_permission = check_banned_permission current_user, params[:id]
+ s_order = params[:order] || "updated_at"
+ if user_permission
+ if Memo.find(params[:id]).update_attribute(:sticky, params[:sticky])
+ set_status = 0
+ set_msg = "操作成功"
+ else
+ set_status = -1
+ set_msg = "操作失败"
+ end
+
+ else
+ set_status = -1
+ set_msg = "您没有权限"
+ end
+
+ memos = Memo.field_for_list.includes(:praise_tread, :author).where(:root_id => nil).order("sticky=1 desc, #{s_order} desc").limit(15)
+ memo_list = memo_data memos
+ {status: set_status, message: set_msg, memo_list: memo_list}
+
+ end
+
+
+ def banned_user params, current_user
+ user_permission = check_banned_permission current_user, params[:id]
+ if user_permission
+ last_banned_forum = BannedForum.where(user_id: params[:user_id])&.last
+ user_banned_count = last_banned_forum&.banned_count.to_i
+
+ if params[:banned].to_i == 1 #表示禁言
+ banned_params = {
+ user_id: params[:user_id],
+ author_id: current_user.id,
+ memo_id: params[:id],
+ is_banned: true,
+ banned_count: user_banned_count + 1
+ }
+ BannedForum.create!(banned_params)
+ {status: 0, message: "禁言成功"}
+ else
+ BannedForum.where(user_id: params[:user_id]).update_all(is_banned: false)
+ {status: 0, message: "取消禁言成功"}
+ end
+
+ else
+ {status: -1, message: "您没有权限操作"}
+ end
+ end
+
+ def is_fine params, current_user
+ user_permission = check_banned_permission current_user, params[:id]
+ if user_permission
+ if params[:is_fine] == 1
+ is_fine_b = true
+ else
+ is_fine_b = false
+ end
+ memo = Memo.find(params[:id]).update_attribute(:is_fine, is_fine_b)
+ if memo
+ {status: 0, message: "操作成功"}
+ else
+ {status: -1, message: "操作失败"}
+ end
+ else
+ {status: -1, message: "您没有权限操作"}
+ end
+ end
+
+ def forum_memos_head params, current_user
+ forum_section = ForumSection.find_by_id(params[:id])
+ return {status: -1, message: "版块不存在"} if forum_section.blank?
+ section_author = forum_section.user
+ forum_section_user = {username: section_author.try(:show_name), user_login: section_author.try(:login)}
+ forum_moders = []
+ if ForumModerator.exists?(forum_section_id: forum_section.id)
+ all_forum_moderators = forum_section.forum_moderators.includes(user: :user_extensions).select([:id, :user_id])
+ all_forum_moderators.each do |moder|
+ moder_user = moder.user
+ forum_moder = {
+ username: moder_user.show_name,
+ user_login: moder_user.try(:login)
+ }
+ forum_moders << forum_moder
+ end
+ end
+ today_memos = forum_section.group_today
+ publish_today_count = today_memos.roots.size
+ replies_today_count = today_memos.size - publish_today_count
+ bread_crumb = get_bread_crumb(forum_section, current_user)
+ banned_permission = user_banned_permission current_user, params[:id]
+ watched = forum_section.watched_by?(current_user)
+ {
+ watched: watched,
+ bread_crumb: bread_crumb,
+ publish_today_count: publish_today_count,
+ replies_today_count: replies_today_count,
+ forum_section: single_section_info(forum_section),
+ forum_section_user: forum_section_user,
+ forum_moders: forum_moders,
+ banned_permission: banned_permission
+ }
+ end
+
+ def forum_memos params, current_user
+ forum_section = ForumSection.find_by_id(params[:id])
+ sort_name = params[:sort] || "published_at"
+ return {status: -1, message: "版块不存在"} if forum_section.blank?
+
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ offset = page * LIMIT
+ all_memos = forum_section.memos.posts
+ select_type = params[:select_type]
+ case select_type.to_s
+ when "is_fine"
+ all_memos = all_memos.visible.where(is_fine: true)
+ when "my_memos"
+ all_memos = all_memos.where(author_id: current_user.id)
+ when "my_topics"
+ my_reply_memos = current_user.memos.visible.select([:id, :author_id, :hidden,:parent_id]).where("parent_id is not Null").pluck(:parent_id).uniq
+ all_memos = all_memos.where(id: my_reply_memos)
+ else
+ all_memos = all_memos.visible
+ end
+
+ if params[:search].present?
+ all_memos = all_memos.where("subject like '%#{params[:search].to_s.strip}%'")
+ end
+
+ # 总数,分页使用
+ all_memos = all_memos.order_index(sort_name)
+ memos_count = all_memos.size
+ all_memos = all_memos.limit(LIMIT).includes(:author, :praise_tread).offset(offset)
+
+ memo_lists = []
+ if all_memos.size > 0
+ memo_lists = get_memo_lists(all_memos, true, current_user, false)
+ end
+ {
+ memos_count: memos_count,
+ limit: LIMIT,
+ memos: memo_lists,
+ }
+ end
+
+ def forum_memos_right params, current_user
+ forum_section = ForumSection.find_by_id(params[:id])
+ notice = forum_section.section_notice
+ all_memos = forum_section.memos.posts.select(:author_id)
+ active_user_ids = all_memos.group("author_id").size.keys.uniq.first(6)
+ children_sections = ForumSection.where("ancestry is not null").order("watchers_count desc, memos_count desc").select([]).first(4)
+ new_childre_section = list_hot_sections(children_sections)
+ active_users = User.where(id: active_user_ids)
+ active_user_array = []
+ active_users.each do |user|
+ active_user_array.push({
+ username: user.show_name,
+ login: user.login,
+ image_url: "#{url_to_avatar(user)}?#{Time.now.to_i}"
+ })
+ end
+ {
+ username: forum_section.user.show_name,
+ user_login: forum_section.user.login,
+ notice: notice.try(:content),
+ recommend_forum_sections: new_childre_section,
+ active_users: active_user_array
+ }
+
+ end
+
+ def is_watch params, current_user
+ forum_section = ForumSection.find(params[:id])
+ children_sections = nil
+ children_sections = forum_section.descendants
+ if params[:is_watch] == 1
+ if Watcher.exists?(watchable_type: "ForumSection", watchable_id: params[:id], user_id: current_user.id)
+ w_status = -1
+ w_msg = "您已收藏"
+ else
+ Watcher.create(watchable: forum_section, user_id: current_user.id)
+ forum_section.increment!(:watchers_count)
+ if children_sections.present?
+ children_sections.each do |section|
+ Watcher.create!(watchable: section, user_id: current_user.id)
+ section.increment!(:watchers_count)
+ end
+ end
+ w_status = 0
+ w_msg = "收藏成功"
+ end
+ else
+ sections_ids = []
+ sections_ids = children_sections.pluck(:id) if children_sections.present?
+ forum_all_sections = [params[:id]] + sections_ids
+ forum_section.decrement!(:watchers_count)
+ if Watcher.exists?(watchable_type: "ForumSection", watchable_id: params[:id], user_id: current_user.id)
+ Watcher.where(watchable_type: "ForumSection", watchable_id: forum_all_sections, user_id: current_user.id).destroy_all
+ w_status = 0
+ w_msg = "取消收藏成功"
+ else
+ w_status = -1
+ w_msg = "您还未收藏"
+ end
+ end
+ {status: w_status, message: w_msg}
+
+ end
+
+ protected
+
+ def find_memo params
+ if params[:id].blank?
+ @memo = Memo.new
+ else
+ @memo = Memo.find params[:id]
+ end
+ end
+
+
+ # 将memos对象添加额外信息
+ def memo_data memos
+ memo_list = []
+ memos.each do |m|
+ forum_name = m.forums.map(&:name)
+ user_info = {username: m.author.show_name, login: m.author.login, image_url: "#{url_to_avatar(m.author)}?#{Time.now.to_i}", forum_name:forum_name, praise_count: m.praises_count}
+ memo_list << m.attributes.dup.merge(user_info)
+ end
+ memo_list
+ end
+
+ # 权限
+ def permission memo, current_user
+ if current_user.admin?
+ 1
+ elsif memo.author_id == current_user.id
+ 2
+ else
+ 3
+ end
+ end
+
+
+ def check_banned_permission current_user, memo_id
+ forum_id = MemoForum&.where(is_children: false, memo_id: memo_id)&.first.try(:forum_id).to_s
+ user_banned_permission current_user, forum_id
+ end
+
+ def tag_list reps
+ rep_list = []
+ reps.each do |r|
+ sub_ids = SubRepertoire.where(:repertoire_id => r.id).pluck(:id)
+ tag = object_to_hash TagRepertoire.where(:sub_repertoire_id => sub_ids).field_for_list.order("name asc")
+ rep_list << {:rep => r, :tag => tag}
+ end
+ return rep_list
+ end
+
+ def memo_list memos, current_user
+
+ return nil if memos.blank?
+ # parent_reply_ids = memos.where()
+ list = [] # 贴子的回复
+ memos.includes(:praise_tread).each do |memo|
+ is_banned = user_is_banned?(memo.author) #帖子的用户是否被禁言
+
+ # 用户是否点赞
+ user_praise = memo.praise_tread.exists?(user_id: current_user.try(:id).to_i)
+ permission = current_user ? current_user.manager_of_memo?(memo) : false
+ # 实训(TPM)的管理员可以看到隐藏的评论
+ replies = {:id => memo.id, :content => memo.content, :time => time_from_now(memo.created_at), :user_id => memo.author_id,
+ :image_url => "/images/#{url_to_avatar(memo.author)}?#{Time.now.to_i}", :username => memo.author.show_name, :reward => memo.reward, :hidden => memo.hidden,
+ :permission => permission, :praise_count => memo.praises_count, :user_praise => user_praise,
+ :user_login => memo.author.try(:login), :admin => current_user&.admin, is_banned: is_banned, replies_count: memo.can_see_reply_count(current_user)}
+ childrens = Memo.where(:parent_id => memo.id).includes(:author).reorder("created_at desc").limit(5)
+ unless current_user.try(:admin?) # 只有管理员和发布人能看到隐藏的回复
+ childrens = childrens.where("hidden = false or (hidden = true and author_id = ?)", current_user.try(:id))
+ end
+ children_list = [] # 子回复
+ childrens.each do |child|
+ children_praise = child.praise_tread.exists?(user_id: current_user.try(:id).to_i)
+ children_is_banned = user_is_banned?(child.author) #帖子的用户是否被禁言
+ children_list << {:id => child.id, :content => child.content, :time => time_from_now(child.created_at),:praise_count => memo.praises_count, :user_praise => children_praise,
+ :image_url => "/images/#{url_to_avatar(child.author)}?#{Time.now.to_i}", :username => child.author.show_name, :hidden => child.hidden, replies_count: child.can_see_reply_count(current_user),
+ :permission => permission, :user_login => child.author.try(:login), :user_id => child.author.try(:id), :parent_id => child.parent_id, is_banned: children_is_banned}
+ end
+ list << replies.merge({children: children_list})
+ end
+ list
+ end
+
+ # 帖子附件信息
+ def acttachements_info attachments
+ attachments_list = []
+ if attachments.present?
+ attachments.each do |attach|
+ attachments_list << {:id => attach.id,
+ :title => attach.filename,
+ :url => "/attachments/download/" + "#{attach.id}" + "/" + "#{attach.filename}",
+ :filesize => number_to_human_size(attach.filesize,significant: false, precision: 2)}
+ end
+ end
+ return attachments_list
+ end
+
+ # 判断编辑器存储的内容是否是html类型的(ke),目的为了区分ke和markdown
+ def editor_html update_time
+ # str.include?("" || "
" || "
" || " " || "") && update_time < "2018-06-23"
+ update_time < "2018-06-23"
+ end
+
+ def list_hot_sections(forum_sections)
+ new_sections = []
+ forum_sections.each do |sec|
+ single_info = single_section_info(sec)
+ new_sections.push(single_info)
+ end
+ return new_sections
+ end
+
+ def single_section_info(section)
+ image = section.image_attachment
+ return {
+ id: section.id,
+ title: section.title,
+ description: section.description,
+ memos_count: section.visible_memos_count,
+ watchers_count: section.watchers_count,
+ picture: image.present? ? "/attachments/download/" + "#{image.id}" + "/" + "#{image.filename}" : ""
+ }
+ end
+end
diff --git a/app/services/my_memos_service.rb b/app/services/my_memos_service.rb
new file mode 100644
index 00000000..fcdb68b1
--- /dev/null
+++ b/app/services/my_memos_service.rb
@@ -0,0 +1,134 @@
+class MyMemosService
+ include ApplicationHelper
+ include ApiIndexHelper
+
+ LIMIT = 10
+
+
+ def index params, current_user
+ memo_user = User.find_by_login(params[:login])
+ memo_type = params[:memo_type] || "memos"
+ return {status: -1, message: "用户不存在"} unless memo_user
+ return {status: 403, message: "没有权限"} if !%w(memos replies).include?(memo_type) && current_user&.login != params[:login]
+ return {status: 403, message: "没有权限"} if params[:is_hidden] == "hidden" && current_user&.login != params[:login]
+ banned_permission = user_banned_permission current_user, nil
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ index_limit = params[:limit] || 15
+ offset = page * index_limit.to_i
+ all_memos = ListMemosService.new.all_memos(memo_type, params, memo_user.id, current_user.id)
+ memos_count = all_memos.size # 帖子的总数
+ if memo_type == "replies"
+ all_memos = all_memos.order("last_reply_on desc")
+ else
+ all_memos = all_memos.order("sticky desc, is_fine desc, published_at desc, updated_at desc")
+ end
+ all_memos = all_memos.limit(index_limit.to_i).offset(offset)
+ show_last_reply = memo_type == "replies"
+ all_memo_lists = get_memo_lists(all_memos, show_last_reply, current_user, show_last_reply)
+ {
+ status: 0,
+ is_current_user: params[:login] == current_user&.login,
+ banned_permission: banned_permission,
+ limit: index_limit.to_i,
+ memos_count: memos_count,
+ memos: all_memo_lists
+ }
+
+ end
+
+ def my_interested params, current_user
+ return {status: -1, message: "请登录"} unless current_user
+ return {status: 403, message: "没有权限"} if current_user&.login != params[:login]
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ index_limit = params[:limit] || 32
+ offset = page * index_limit.to_i
+
+ watch_section_ids = Watcher.where(watchable_type: "ForumSection",user_id: current_user.id).pluck(:watchable_id)
+
+ forum_sections = ForumSection.where(id: watch_section_ids).select([:id,:title, :memos_count])
+ if params[:search].present?
+ forum_sections = forum_sections.where("title like ? ", "%#{params[:search].to_s.strip}%")
+ end
+ forum_sections_count = forum_sections.size # 帖子的总数
+ forum_sections = forum_sections.limit(index_limit).offset(offset)
+ all_forum_sections = forum_sections.as_json.map{|k,v| k["forum_section"]}
+ {
+ count: forum_sections_count,
+ forum_details: all_forum_sections,
+ }
+ end
+
+ def recommend_memos current_user
+ return {status: -1, message: "请登录"} unless current_user
+
+ all_memos = Memo.includes(memo_forums: :forum_section,author: :user_extensions)
+
+ all_hottest_memos = all_memos.visible.hottest_five_memos
+ hottest_memos = object_to_hash(all_hottest_memos)
+
+ all_recommend_memos = all_memos.visible.recommend_five_memos
+ recommend_memos = object_to_hash(all_recommend_memos)
+
+ {
+ status: 0,
+ hottest_memos: hottest_memos,
+ recommend_memos: recommend_memos,
+ }
+ end
+
+ def replies_memos params, current_user
+ return {status: -1, message: "请登录"} unless current_user
+ reply_root_ids = Memo.visible.user_replies(current_user.id).pluck(:root_id)
+ reply_memos = Memo.where(id: reply_root_ids)
+ page = params[:page].to_i > 0 ? (params[:page].to_i - 1) : 0
+ # page = params[:page].to_i
+ offset = page * 15
+ is_hidden = params[:is_hidden].present? && params[:is_hidden] != "show"
+ reply_memos = reply_memos.where(forum_section_id: params[:forum_section_id]) if params[:forum_section_id].present?
+ reply_memos = reply_memos.where(hidden: is_hidden) if is_hidden
+
+ reply_memos_count = reply_memos.size # 帖子的总数
+ reply_memos = reply_memos.order("updated_at desc").limit(15).offset(offset)
+ reply_list_memos = reply_memo_lists(reply_memos)
+ {
+ status: 0,
+ memos_count: reply_memos_count,
+ memos: reply_list_memos
+ }
+ end
+
+ private
+
+ def my_page_crumb(tab,current_user)
+ {
+ user:{login: current_user.try(:login), url: "/users/#{current_user.try(:login)}"},
+ forum: {title: "论坛交流", url: ""},
+ forum_tag: tab
+ }
+ end
+
+ def reply_memo_lists(memos)
+ memos_array = []
+ memos.each do |memo|
+ last_reply = memo&.last_reply_memo(false)
+ memo_list = {
+ id: memo.id,
+ subject: memo.subject,
+ reply_time: rename_time_second(last_reply&.created_at),
+ reply_content: last_reply&.content
+ }
+ memos_array.push(memo_list)
+ end
+ return memos_array
+ end
+
+ def get_sections_lists parent, forum_second_ids,children_section_ids
+ forum_second_tags = ForumSection.where(id: (forum_second_ids & children_section_ids).uniq)&.select([:id,:title])
+ {id: parent.id,
+ name: parent.title,
+ position: parent.position,
+ children_tags: object_to_hash(forum_second_tags)
+ }
+ end
+
+end
\ No newline at end of file
diff --git a/app/views/admins/memos/_memo_reply_list.html.erb b/app/views/admins/memos/_memo_reply_list.html.erb
new file mode 100644
index 00000000..15cd94c5
--- /dev/null
+++ b/app/views/admins/memos/_memo_reply_list.html.erb
@@ -0,0 +1,98 @@
+
+
+ ">
+ <%= link_to "已审核", memo_reply_list_managements_path(hidden: "show"), remote: true, class: "cancel-type-choose" %>
+
+ ">
+ <%= link_to "未审核", memo_reply_list_managements_path(hidden: "hidden"), remote: true, class: "cancel-type-choose" %>
+
+
+
+
+
+
+ 序号
+ 来源
+ 评论内容
+ 评论者
+ 评论时间
+ 审核
+ 操作
+
+
+
+ <% @memos.each_with_index do |memo,index| %>
+
+ <%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %>
+
+ <%= link_to(memo.root.subject, forum_path(memo.root)+"/detail", :target => "_blank") %>
+
+
+ <%= sanitize memo.content %>
+ <%
+=begin%>
+ <%= link_to(forum_path(memo.parent, reply_id: memo.id)+"/detail", :target => "_blank") do %>
+ <%= sanitize memo.content %>
+ <% end %>
+<%
+=end%>
+
+
+ <%= link_to(memo.try(:author).try(:show_name), user_path(memo.author)) %>
+ <%# if memo.try(:author).try(:realname) == ' '%>
+ <%#= link_to(memo.try(:author), user_path(memo.author)) %>
+ <%# else %>
+ <%#= link_to(memo.try(:author).try(:realname), user_path(memo.author)) %>
+ <%# end %>
+
+ <%= format_time(memo.created_at) %>
+
+ <%= check_box_tag(:hidden, 1, !memo.hidden?, id: "hidden-check-box-#{memo.id}", class: 'magic-checkbox', data: { id: memo.id, url: memo_hidden_managements_path, type: 'hidden' }) %>
+
+ 通过
+
+
+ <%= link_to '查看', forum_path(memo.root)+"/detail?reply_id=#{memo.id}", target: '_blank' %>
+ <%= link_to '删除', delete_memo_managements_path(id: memo.id), method: :delete, class: "delete-link-#{memo.id}", data: { confirm: '确认删除该回复吗?' }, style: memo.hidden? ? '' : 'display: none' %>
+
+
+ <% end %>
+
+
+
+
+
+ <%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false, :remote => true, :flag => true, :is_new => true %>
+
+
+
+
+
diff --git a/app/views/admins/memos/_message_list.html.erb b/app/views/admins/memos/_message_list.html.erb
new file mode 100644
index 00000000..d0b74ad9
--- /dev/null
+++ b/app/views/admins/memos/_message_list.html.erb
@@ -0,0 +1,99 @@
+
+
+ ">
+ <%= link_to "已审核", admins_memos_path(hidden: "show"), remote: true, class: "cancel-type-choose" %>
+
+ ">
+ <%= link_to "未审核", admins_memos_path(hidden: "hidden"), remote: true, class: "cancel-type-choose" %>
+
+
+
+
+
+
+
+ 序号
+ 作者
+ 标题
+ 发布时间
+ 回复数
+ 审核
+ 首页
+ 操作
+
+
+
+ <% @memos.each_with_index do |memo,index| %>
+
+ <%= (@obj_pages.page - 1) * @obj_pages.per_page + index + 1 %>
+
+ <%= link_to(memo.try(:author).try(:show_name), user_path(memo.author)) %>
+
+
+ <% if memo.parent_id.nil? || memo.subject.starts_with?('RE:')%>
+ <%= link_to(memo.subject, forum_path(memo)+"/detail") %>
+ <% else %>
+ <%= link_to("RE:"+memo.subject, forum_path(memo)+"/detail", :target => "_blank") %>
+ <% end %>
+
+ <%= format_time(memo.created_at) %>
+
+ <%= link_to(memo.replies_count, forum_path(memo)+"/detail") %>
+
+
+ <%= check_box_tag(:hidden, 1, !memo.hidden?, id: "hidden-check-box-#{memo.id}", class: 'magic-checkbox', data: { id: memo.id, url: memo_hidden_managements_path, type: 'hidden' }) %>
+
+ 通过
+
+
+
+
+ <%= check_box_tag(:home_show, 1, memo.homepage_show, id: "home_show_#{memo.id}", class: 'magic-checkbox', disabled: memo.hidden?,
+ data: { id: memo.id, url: memo_homepage_show_managements_path, type: 'home_show' }) %>
+
+
+
+
+
+ <%= link_to '查看', forum_path(memo), target: '_blank' %>
+ <%= link_to '删除', delete_memo_managements_path(id: memo.id), method: :delete, class: "delete-link-#{memo.id}", data: { confirm: '确认删除该帖子吗?' }, style: memo.hidden? ? '' : 'display: none' %>
+
+
+ <% end %>
+
+
+<%= render partial: 'admins/shared/paginate', locals: { objects: @memos } %>
+
\ No newline at end of file
diff --git a/app/views/admins/memos/index.html.erb b/app/views/admins/memos/index.html.erb
new file mode 100644
index 00000000..4f160949
--- /dev/null
+++ b/app/views/admins/memos/index.html.erb
@@ -0,0 +1,6 @@
+
+
+
+ <%= render :partial => "admins/memos/message_list" %>
+
+
\ No newline at end of file
diff --git a/app/views/admins/memos/messages_list.js.erb b/app/views/admins/memos/messages_list.js.erb
new file mode 100644
index 00000000..488e9e47
--- /dev/null
+++ b/app/views/admins/memos/messages_list.js.erb
@@ -0,0 +1 @@
+$("#leave_message").html('<%= escape_javascript( render :partial => 'admins/memos/message_list') %>');
\ No newline at end of file
diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb
index de56a547..40819501 100644
--- a/app/views/admins/shared/_sidebar.html.erb
+++ b/app/views/admins/shared/_sidebar.html.erb
@@ -28,7 +28,16 @@
<%= sidebar_item(admins_project_ignores_path, '忽略文件', icon: 'git', controller: 'admins-project_ignores') %>
<% end %>
-
+
+ <%= sidebar_item_group('#memos-submenu', '交流论坛', icon: 'columns') do %>
+ <%= sidebar_item(admins_memos_path, '帖子', icon: 'columns', controller: 'admins-memos') %>
+ <%= sidebar_item(apply_destroy_memos_admins_memos_path, '申请删帖', icon: 'trash', controller: 'admins-memos') %>
+ <%= sidebar_item(memo_reply_list_admins_memos_path, '回复', icon: 'mail-reply-all', controller: 'admins-project_categories') %>
+ <%= sidebar_item(admins_project_licenses_path, '版块配置', icon: 'tags', controller: 'admins-forum_sections') %>
+ <%= sidebar_item(admins_banned_users_path, '禁言列表', icon: 'ban', controller: 'admins-banned_users') %>
+ <%= sidebar_item(admins_forum_applies_path, '版主审批', icon: 'check-square-o', controller: 'admins-forum_applies') %>
+ <% end %>
+
<%= sidebar_item(admins_laboratories_path, '云上实验室', icon: 'cloud', controller: 'admins-laboratories') %>
diff --git a/config/application.rb b/config/application.rb
index fece76eb..9aaa900b 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -43,5 +43,12 @@ module Educoderplus
resource '/*', :headers => :any, :methods => [:get, :post, :delete, :options, :put]
end
end
+ config.middleware.use Rack::Cors do
+ allow do
+ origins '*'
+ # location of your API
+ resource '/api/*', :headers => :any, :methods => [:get, :post, :delete, :options, :put]
+ end
+ end
end
end
diff --git a/config/initializers/autoreload_grape.rb b/config/initializers/autoreload_grape.rb
new file mode 100644
index 00000000..5cbfa509
--- /dev/null
+++ b/config/initializers/autoreload_grape.rb
@@ -0,0 +1,26 @@
+# if Rails.env.development?
+# lib_ruby_files = Dir.glob(File.join("app/api/**", "*.rb"))
+# lib_reloader ||= ActiveSupport::FileUpdateChecker.new(lib_ruby_files) do
+# # lib_ruby_files.each do |lib_file|
+# # puts "start require #{lib_file}"
+# # require_dependency(lib_file)
+# # end
+# #
+
+# # binding.pry
+# # if Object.const_defined?(:Mobile)
+# # Object.send(:remove_const, :Mobile)
+# # end
+# #
+# # $".delete_if {|s| s.include?('api/mobile') }
+# # require File.join(Rails.root,"app/api/mobile/api.rb")
+# Rails.application.reload_routes!
+# end
+
+# ActionDispatch::Callbacks.to_prepare do
+# lib_reloader.execute_if_updated
+# end
+
+# end
+
+
diff --git a/config/routes.rb b/config/routes.rb
index c9a277ad..fe62b0a8 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -2,12 +2,34 @@ Rails.application.routes.draw do
require 'sidekiq/web'
require 'admin_constraint'
-
+ mount Mobile::API => '/api'
# mount Sidekiq::Web => '/sidekiq', :constraints => AdminConstraint.new
# Serve websocket cable requests in-process
mount ActionCable.server => '/cable'
-
+ resources :forums do
+ member do
+ get "detail"
+ end
+ collection do
+ match '/manage/:id/', :to => 'forums#manage', :via => :get
+ match '/theme/:id/', :to => 'forums#theme', :via => :get
+ resources :plates, only: [:show, :index] do
+ get 'all'
+ get 'is_fine'
+ get 'my_memos'
+ get 'my_topics'
+ end
+ resources :categories do
+ collection do
+ get 'all', :via => [:get, :post]
+ get 'guide', :via => [:get, :post]
+ get 'techShare'
+ get 'shixun_discuss'
+ end
+ end
+ end
+ end
get 'attachments/entries/get_file', to: 'attachments#get_file'
get 'attachments/download/:id', to: 'attachments#show'
get 'attachments/download/:id/:filename', to: 'attachments#show'
@@ -382,7 +404,7 @@ Rails.application.routes.draw do
end
# Project Area END
end
-
+
namespace :admins do
mount Sidekiq::Web => '/sidekiq'
get '/', to: 'dashboards#index'
@@ -395,6 +417,39 @@ Rails.application.routes.draw do
resources :project_categories
resources :project_licenses
resources :project_ignores
+ resources :banned_users do
+ collection do
+ post :confirm_banned
+ end
+ end
+ resources :memos, only: :index do
+ collection do
+ get 'apply_destroy_memos'
+ post 'confirm_apply_destroy'
+ post 'memo_homepage_show'
+ post 'memo_hidden'
+ delete 'delete_memo'
+ get 'memo_reply_list'
+ end
+ end
+ resources :forum_applies do
+ member do
+ post :confirm_apply
+ end
+ end
+ resources :forum_sections do
+ member do
+ get "order_forums"
+ post "recommend_forums"
+ post 'move'
+ end
+
+ resources :forum_moderators do
+ collection do
+ post "search_user"
+ end
+ end
+ end
resources :major_informations, only: [:index]
resources :ec_templates, only: [:index, :destroy] do
collection do
diff --git a/db/migrate/20201012055111_create_memos.rb b/db/migrate/20201012055133_create_memos.rb
similarity index 100%
rename from db/migrate/20201012055111_create_memos.rb
rename to db/migrate/20201012055133_create_memos.rb
diff --git a/db/migrate/20201012070356_create_forums.rb b/db/migrate/20201012070356_create_forums.rb
new file mode 100644
index 00000000..09c87374
--- /dev/null
+++ b/db/migrate/20201012070356_create_forums.rb
@@ -0,0 +1,18 @@
+class CreateForums < ActiveRecord::Migration[5.2]
+ def change
+ create_table :forums do |t|
+ t.string "name", :null => false
+ t.text "description"
+ t.integer "topic_count", :default => 0
+ t.integer "memo_count", :default => 0
+ t.integer "last_memo_id", :default => 0
+ t.integer "creator_id", :null => false
+ t.integer "sticky"
+ t.integer "locked"
+ t.integer "visits", :default => 0
+ t.timestamps
+ end
+ add_index :forums, :name
+ add_index :forums, :creator_id
+ end
+end
diff --git a/db/migrate/20201012084218_create_api_keys.rb b/db/migrate/20201012084218_create_api_keys.rb
new file mode 100644
index 00000000..c497f4b3
--- /dev/null
+++ b/db/migrate/20201012084218_create_api_keys.rb
@@ -0,0 +1,14 @@
+class CreateApiKeys < ActiveRecord::Migration[5.2]
+ def change
+ if ActiveRecord::Base.connection.tables.include?('api_keys')
+ drop_table :api_keys
+ end
+ create_table :api_keys do |t|
+ t.string "access_token"
+ t.datetime "expires_at"
+ t.integer "user_id"
+ t.boolean "active", :default => true
+ t.timestamps
+ end
+ end
+end
diff --git a/spec/models/api_key_spec.rb b/spec/models/api_key_spec.rb
new file mode 100644
index 00000000..8f87b0d6
--- /dev/null
+++ b/spec/models/api_key_spec.rb
@@ -0,0 +1,5 @@
+require 'rails_helper'
+
+RSpec.describe ApiKey, type: :model do
+ pending "add some examples to (or delete) #{__FILE__}"
+end
+ <% if User.current.admin? %> + ')">奖励| + <% end %> + <% if comment.creator_user == User.current %> + 删除 + | + <% end %> + <%= link_to( + '回复'.html_safe, + {:controller => 'users' ,:action => 'reply_to',:reply_id => comment.id, :type => memo.class.to_s, :user_activity_id => memo.id}, + :remote => true, + :method => 'get', + :title => l(:button_reply),:class => "color-grey") %> + | + + <%=render :partial=> "praise_tread/edu_praise", :locals => {:activity=>comment, :user_activity_id=>comment.id,:type=>"reply"}%> + +
+