diff --git a/app/libs/forum.rb b/app/libs/forum.rb new file mode 100644 index 000000000..112ff2788 --- /dev/null +++ b/app/libs/forum.rb @@ -0,0 +1,20 @@ +module Forum + class << self + def forum_config + forum_config = {} + + begin + config = Rails.application.config_for(:configuration).symbolize_keys! + forum_config = config[:forum].symbolize_keys! + raise 'forum config missing' if forum_config.blank? + rescue => ex + raise ex if Rails.env.production? + + puts %Q{\033[33m [warning] forum config or configuration.yml missing, + please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m} + forum_config = {} + end + forum_config + end + end +end diff --git a/app/services/forum/client_service.rb b/app/services/forum/client_service.rb new file mode 100644 index 000000000..e3ff54691 --- /dev/null +++ b/app/services/forum/client_service.rb @@ -0,0 +1,94 @@ +class Forum::ClientService < ApplicationService + attr_reader :url, :params + + PAGINATE_DEFAULT_PAGE = 1 + PAGINATE_DEFAULT_LIMIT = 20 + + def initialize(options={}) + @url = options[:url] + @params = options[:params] + end + + def get(url, params={}) + conn(params).get do |req| + req.url full_url(url, 'get') + params.except(:token).each_pair do |key, value| + req.params["#{key}"] = value + end + end + + # response.headers.each do |k,v| + # puts "#{k}:#{v}" + # end #=> 响应头 + end + + private + def conn(auth={}) + @client ||= begin + Faraday.new(url: domain) do |req| + req.request :url_encoded + req.headers['Content-Type'] = 'application/json' + req.response :logger # 显示日志 + req.adapter Faraday.default_adapter + end + end + @client + end + + def base_url + Forum.forum_config[:base_url] + end + + def domain + Forum.forum_config[:domain] + end + + def api_url + [domain, base_url].join('') + end + + def full_url(api_rest, action='post') + url = [api_url, api_rest].join('').freeze + url = action === 'get' ? url : URI.escape(url) + url = URI.escape(url) unless url.ascii_only? + puts "[forum] request url: #{url}" + return url + end + + def render_response(response) + status = response.status + body = response&.body + + # log_error(status, body) + + body, message = get_body_by_status(status, body) + + [status, message, body] + end + + def get_body_by_status(status, body) + body, message = + case status + when 401 then [nil, "401"] + when 404 then [nil, "404"] + when 403 then [nil, "403"] + when 500 then [nil, "500"] + else + if body.present? + body = JSON.parse(body) + fix_body(body) + else + nil + end + end + + [body, message] + end + + def fix_body(body) + return [body, nil] if body.is_a?(Array) || body.is_a?(Hash) + + body['message'].blank? ? [body, nil] : [nil, body['message']] + end + +end diff --git a/app/services/forum/memos/get_service.rb b/app/services/forum/memos/get_service.rb new file mode 100644 index 000000000..c8ad56895 --- /dev/null +++ b/app/services/forum/memos/get_service.rb @@ -0,0 +1,21 @@ +class Forum::Memos::GetService < Forum::ClientService + attr_reader :memo_id + + def initialize(memo_id) + @memo_id = memo_id + end + + def call + response = get(url) + code, message, body = render_response(response) + if code == 200 && body["status"] == 0 + return body + else + return nil + end + end + + def url + "/memos/#{memo_id}.json".freeze + end +end \ No newline at end of file diff --git a/app/views/topics/_activity_forum.json.jbuilder b/app/views/topics/_activity_forum.json.jbuilder index 92254a645..cd624ba76 100644 --- a/app/views/topics/_activity_forum.json.jbuilder +++ b/app/views/topics/_activity_forum.json.jbuilder @@ -1,3 +1,4 @@ json.(activity_forum, :id, :title, :url) -json.visits 0 -json.created_time format_time(Time.now) \ No newline at end of file +request_memo = Forum::Memos::GetService.call(activity_forum&.uuid) +json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"] +json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"] \ No newline at end of file diff --git a/app/views/topics/_experience_forum.json.jbuilder b/app/views/topics/_experience_forum.json.jbuilder index d52703c32..762cf724e 100644 --- a/app/views/topics/_experience_forum.json.jbuilder +++ b/app/views/topics/_experience_forum.json.jbuilder @@ -1,3 +1,4 @@ json.(experience_forum, :id, :title, :url) -json.visits 0 -json.created_time format_time(Time.now) \ No newline at end of file +request_memo = Forum::Memos::GetService.call(activity_forum&.uuid) +json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"] +json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"] \ No newline at end of file diff --git a/app/views/topics/_pinned_forum.json.jbuilder b/app/views/topics/_pinned_forum.json.jbuilder index 18a5fdd16..b5febef9c 100644 --- a/app/views/topics/_pinned_forum.json.jbuilder +++ b/app/views/topics/_pinned_forum.json.jbuilder @@ -1,3 +1,4 @@ json.(pinned_forum, :id, :title, :url) -json.visits 0 -json.created_time format_time(Time.now) \ No newline at end of file +request_memo = Forum::Memos::GetService.call(activity_forum&.uuid) +json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"] +json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"] \ No newline at end of file diff --git a/app/views/topics/index.json.jbuilder b/app/views/topics/index.json.jbuilder index eb14988a7..102da6b11 100644 --- a/app/views/topics/index.json.jbuilder +++ b/app/views/topics/index.json.jbuilder @@ -1,24 +1,49 @@ json.partial! "commons/success" json.total_count @topics.total_count json.topics do - json.array! @topics.each do |topic| - case topic.type - when "Topic::ActivityForum" - json.partial! "activity_forum", locals: {activity_forum: topic} - when "Topic::Banner" - json.partial! "banner", locals: {banner: topic} - when "Topic::Card" - json.partial! "card", locals: {card: topic} - when "Topic::Cooperator" - json.partial! "cooperator", locals: {cooperator: topic} - when "Topic::ExcellentProject" - json.partial! "excellent_project", locals: {excellent_project: topic} - when "Topic::ExperienceForum" - json.partial! "experience_forum", locals: {experience_forum: topic} - when "Topic::PinnedForum" - json.partial! "pinned_forum", locals: {pinned_forum: topic} - else - json.nil! + if params[:group_size].present? + json.array! @topics.to_a.each_slice(params[:group_size].to_i).to_a.each do |group| + json.array! group.each do |topic| + case topic.type + when "Topic::ActivityForum" + json.partial! "activity_forum", locals: {activity_forum: topic} + when "Topic::Banner" + json.partial! "banner", locals: {banner: topic} + when "Topic::Card" + json.partial! "card", locals: {card: topic} + when "Topic::Cooperator" + json.partial! "cooperator", locals: {cooperator: topic} + when "Topic::ExcellentProject" + json.partial! "excellent_project", locals: {excellent_project: topic} + when "Topic::ExperienceForum" + json.partial! "experience_forum", locals: {experience_forum: topic} + when "Topic::PinnedForum" + json.partial! "pinned_forum", locals: {pinned_forum: topic} + else + json.nil! + end + end + end + else + json.array! @topics.each do |topic| + case topic.type + when "Topic::ActivityForum" + json.partial! "activity_forum", locals: {activity_forum: topic} + when "Topic::Banner" + json.partial! "banner", locals: {banner: topic} + when "Topic::Card" + json.partial! "card", locals: {card: topic} + when "Topic::Cooperator" + json.partial! "cooperator", locals: {cooperator: topic} + when "Topic::ExcellentProject" + json.partial! "excellent_project", locals: {excellent_project: topic} + when "Topic::ExperienceForum" + json.partial! "experience_forum", locals: {experience_forum: topic} + when "Topic::PinnedForum" + json.partial! "pinned_forum", locals: {pinned_forum: topic} + else + json.nil! + end end end end \ No newline at end of file diff --git a/config/configuration.yml.example b/config/configuration.yml.example index 4671e4166..a5fba4ec7 100644 --- a/config/configuration.yml.example +++ b/config/configuration.yml.example @@ -63,6 +63,10 @@ default: &default read_domain: '' base_url: '' + forum: + domain: '' + base_url: '/api' + production: <<: *default # 中间层地址