class ApplicationController < ActionController::Base include SeoConcern # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. before_action :log_browser_info before_action :set_content_type_for_rss, if: -> { request.format.rss? } # allow_browser versions: :modern # allow_browser versions: :modern, # patterns: [ # # 鸿蒙系统相关 # /OpenHarmony/, # 鸿蒙系统标识 # /ArkWeb\/[\d.]+/, # 鸿蒙浏览器内核 # /Mobile HuaweiBrowser/, # 华为浏览器(新格式) # /HuaweiBrowser\/[\d.]+/, # 华为浏览器(旧格式) # # # 夸克浏览器(更宽松的匹配) # /Quark[\s\/][\d.]+/, # 匹配 "Quark/7.4.6.681" 或 "Quark 7.4.6.681" # # /Mobile Safari/, # /Chrome\/[\d.]+/, # /Quark\/[\d.]+/, # /HuaweiBrowser\/[\d.]+/, # /MiuiBrowser\/[\d.]+/, # /VivoBrowser\/[\d.]+/, # /OppoBrowser\/[\d.]+/, # /UCBrowser\/[\d.]+/, # /QQBrowser\/[\d.]+/, # /MicroMessenger\/[\d.]+/, # /Alipay/, # /BaiduBoxApp/, # /baiduboxapp/i, # /SogouMobile/, # /Weibo/, # /DingTalk/, # /ToutiaoMicroApp/, # /BytedanceWebview/, # /ArkWeb/ # ], # on_failure: ->(browser) { # Rails.logger.warn <<~BROWSER_INFO # Browser Blocked: # User Agent: #{browser.ua} # Name: #{browser.name} # Version: #{browser.version} # Platform: #{browser.platform.name} # Device: #{browser.device.name} # Mobile: #{browser.mobile?} # Modern: #{browser.modern?} # Bot: #{browser.bot?} # BROWSER_INFO # } around_action :set_locale after_action :track_action def log_browser_info # 构建详细的浏览器信息 Rails.logger.debug "User Agent: #{request.user_agent}" # 如果是被拦截的浏览器,记录额外信息 # unless browser_allowed? # Rails.logger.info "User Agent: #{request.user_agent}" # end end protected def track_action ahoy.track "Viewed Application", request.path_parameters end def authenticate_admin_user! unless current_user&.admin? flash[:alert] = "您没有权限访问该页面。" redirect_to root_path end end private def set_locale(&action) I18n.locale = extract_locale || I18n.default_locale I18n.fallbacks[I18n.locale] = [ I18n.locale, I18n.default_locale ].uniq locale = params[:locale] || extract_locale_from_accept_language_header || I18n.default_locale I18n.with_locale(locale, &action) # 重定向到带有语言前缀的相同路径 # redirect_to "/#{locale}#{request.fullpath}" end def extract_locale_from_accept_language_header return I18n.default_locale.to_s unless request.env["HTTP_ACCEPT_LANGUAGE"] available_locales = I18n.available_locales.map(&:to_s) accept_language = request.env["HTTP_ACCEPT_LANGUAGE"].to_s # 修改正则表达式以匹配 'zh-CN' 这样的格式 if (full_locale = accept_language.scan(/^[a-z]{2}-[A-Z]{2}/).first) locale = full_locale else # 否则只匹配语言代码 (例如 'en') locale = accept_language.scan(/^[a-z]{2}/).first || I18n.default_locale.to_s end return locale if available_locales.include?(locale) # 尝试基础语言匹配(例如:当请求 'zh' 时匹配 'zh-CN') base_language = locale.split("-").first matching_locale = available_locales.find do |available_locale| available_locale.start_with?(base_language) end matching_locale ? matching_locale : I18n.default_locale.to_s end def sanitize_locale(locale) # 直接使用 I18n.available_locales locale = locale.to_sym I18n.available_locales.include?(locale) ? locale : I18n.default_locale end def extract_locale parsed_locale = params[:locale] I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil end def default_url_options { locale: I18n.locale } end def set_content_type_for_rss response.headers["Content-Type"] = "application/rss+xml; charset=utf-8" end end