diff --git a/app/views/admin/seminars/export.xlsx.axlsx b/app/views/admin/seminars/export.xlsx.axlsx index 43a9c4b..09c34fb 100644 --- a/app/views/admin/seminars/export.xlsx.axlsx +++ b/app/views/admin/seminars/export.xlsx.axlsx @@ -31,8 +31,17 @@ wb.add_worksheet(name: sheet_name) do |sheet| seminar_signup_fields = @seminar.seminar_signup_fields.where(:disabled=>false).asc(:sort_number, :_id).to_a + # 確定每個欄位是否需要多語言輸出 + field_multilang = {} seminar_signup_fields.each do |rf| - if rf.can_muti_lang_input? + # 檢查 option_list 是否有多個語言,或欄位本身標記為多語言 + has_multiple_langs = rf.option_list && rf.option_list.values.first && rf.option_list.values.first.is_a?(Hash) && rf.option_list.values.first.keys.size > 1 + field_multilang[rf.id] = rf.can_muti_lang_input? || has_multiple_langs + end + + # 標題列 + seminar_signup_fields.each do |rf| + if field_multilang[rf.id] @site_in_use_locales.each do |l| row << rf.title + " (#{t(l.to_s)})" end @@ -52,6 +61,15 @@ wb.add_worksheet(name: sheet_name) do |sheet| wrap_text_style = wb.styles.add_style({:alignment => {:horizontal => :center, :vertical => :center, :wrap_text => true}}) types = [:time] styles = [date_time_style] + + # 優化:一次性載入所有資料,避免 N+1 查詢 + signup_ids = @seminar_signups.map(&:id) + signup_values_index = {} + SeminarSignupValue.where(:seminar_signup_id.in => signup_ids).each do |sv| + key = "#{sv.seminar_signup_id}_#{sv.seminar_signup_field_id}" + signup_values_index[key] = sv + end + @seminar_signups.each_with_index do |signup, i| row2 = [] row2 << signup.created_at @@ -65,12 +83,47 @@ wb.add_worksheet(name: sheet_name) do |sheet| row2 << "#{signup[:email]} " row2 << "#{signup.note} " seminar_signup_fields.each do |rf| - if rf.can_muti_lang_input? + key = "#{signup.id}_#{rf.id}" + signup_value = signup_values_index[key] + + # 根據欄位是否需要多語言來輸出 + if field_multilang[rf.id] @site_in_use_locales.each do |l| - row2 << (@seminar.get_attribute_value(rf,signup.id).get_value_by_locale(l) rescue '') + if signup_value + # 處理陣列型別的 val + if signup_value.val.is_a?(Array) + # 陣列:對每個元素查詢 option_list 用逗號分隔 + display_value = signup_value.val.map { |v| rf.option_list[v.to_s]&.[](l.to_s) || rf.option_list[v.to_s]&.[]('en') }.compact.join(', ') rescue '' + elsif rf.option_list && rf.option_list[signup_value.val.to_s] + # 單個值且有 option_list + display_value = rf.option_list[signup_value.val.to_s][l.to_s] || rf.option_list[signup_value.val.to_s]['en'] rescue '' + else + # 沒有 option_list 直接用 val + display_value = signup_value.val.to_s + end + row2 << display_value + else + row2 << '' + end end else - row2 << (@seminar.get_attribute_value(rf,signup.id).get_value_by_locale(I18n.locale) rescue '') + # 非多語言欄位,只輸出一次 + if signup_value + # 處理陣列型別的 val + if signup_value.val.is_a?(Array) + # 陣列:對每個元素查詢 option_list 用逗號分隔 + display_value = signup_value.val.map { |v| rf.option_list[v.to_s]&.[]('en') }.compact.join(', ') rescue '' + elsif rf.option_list && rf.option_list[signup_value.val.to_s] + # 單個值且有 option_list + display_value = rf.option_list[signup_value.val.to_s]['en'] rescue '' + else + # 沒有 option_list 直接用 val + display_value = signup_value.val.to_s + end + row2 << display_value + else + row2 << '' + end end end if i == 0 @@ -82,4 +135,4 @@ wb.add_worksheet(name: sheet_name) do |sheet| sheet.add_row row2 , :types => types, :style => styles end -end \ No newline at end of file +end