diff --git a/app/admin/ahoy_dashboard.rb b/app/admin/ahoy_dashboard.rb index 9db1609..32d60a8 100644 --- a/app/admin/ahoy_dashboard.rb +++ b/app/admin/ahoy_dashboard.rb @@ -37,6 +37,41 @@ ActiveAdmin.register_page "Ahoy Dashboard" do end end + columns do + column do + panel "今日热门城市" do + table_for City.by_popularity(:today, 10) do + column("城市") { |city| link_to(city.name, admin_city_path(city)) } + column("访问量") { |city| city.view_count } + end + end + end + column do + panel "本周热门城市" do + table_for City.by_popularity(:week, 10) do + column("城市") { |city| link_to(city.name, admin_city_path(city)) } + column("访问量") { |city| city.view_count } + end + end + end + column do + panel "月度热门城市" do + table_for City.by_popularity(:month, 10) do + column("城市") { |city| link_to(city.name, admin_city_path(city)) } + column("访问量") { |city| city.view_count } + end + end + end + column do + panel "年度热门城市" do + table_for City.by_popularity(:year, 10) do + column("城市") { |city| link_to(city.name, admin_city_path(city)) } + column("访问量") { |city| city.view_count } + end + end + end + end + columns do column do panel "最冷门活跃城市" do diff --git a/app/models/city.rb b/app/models/city.rb index 153bf92..c66e452 100644 --- a/app/models/city.rb +++ b/app/models/city.rb @@ -22,20 +22,45 @@ class City < ApplicationRecord scope :active, -> { where(active: true) } scope :inactive, -> { where(active: false) } - scope :by_popularity, -> { - if ActiveRecord::Base.connection.adapter_name.downcase == "sqlite" - joins("LEFT JOIN ahoy_events ON json_extract(ahoy_events.properties, '$.city_id') = cities.id - AND json_extract(ahoy_events.properties, '$.event_type') = 'city_view'") - .group("cities.id") - .select("cities.*, COUNT(ahoy_events.id) as visit_count") - .order("visit_count DESC") + # 在 City 模型中 + scope :by_popularity, ->(period = :year, limit = 100) { + # 根据时间周期确定时间范围 + time_range = + case period.to_sym + when :today + Time.current.beginning_of_day..Time.current.end_of_day + when :week + Time.current.beginning_of_week..Time.current.end_of_week + when :month + Time.current.beginning_of_month..Time.current.end_of_month + when :year + Time.current.beginning_of_year..Time.current.end_of_year + else + Time.current.beginning_of_year..Time.current.end_of_year + end + + # 根据数据库类型构建不同的查询 + base_query = if ActiveRecord::Base.connection.adapter_name.downcase == "sqlite" + joins(<<-SQL.squish) + LEFT JOIN ahoy_events ON + json_extract(ahoy_events.properties, '$.city_id') = cities.id + AND json_extract(ahoy_events.properties, '$.event_type') = 'city_view' + AND ahoy_events.time BETWEEN '#{time_range.begin}' AND '#{time_range.end}' + SQL else - joins("LEFT JOIN ahoy_events ON (ahoy_events.properties::jsonb->>'city_id')::integer = cities.id - AND ahoy_events.properties::jsonb->>'event_type' = 'city_view'") - .group("cities.id") - .select("cities.*, COUNT(ahoy_events.id) as visit_count") - .order("visit_count DESC") + joins(<<-SQL.squish) + LEFT JOIN ahoy_events ON + (ahoy_events.properties::jsonb->>'city_id')::integer = cities.id + AND ahoy_events.properties::jsonb->>'event_type' = 'city_view' + AND ahoy_events.time BETWEEN '#{time_range.begin}' AND '#{time_range.end}' + SQL end + + base_query + .group("cities.id") + .select("cities.*, COUNT(ahoy_events.id) as visit_count") + .order("visit_count DESC") + .limit(limit) } scope :least_popular_active, ->(limit = 100) {