Compare commits
No commits in common. "master" and "new" have entirely different histories.
|
|
@ -1,5 +1,3 @@
|
||||||
= EPaper
|
= EPaper
|
||||||
|
|
||||||
This project rocks and uses MIT-LICENSE.
|
This project rocks and uses MIT-LICENSE.
|
||||||
|
|
||||||
ERB files such as showpaper.html.erb, index.html.erb, widget.html.erb, and show.html.erb may need to be manually added to the layout.
|
|
||||||
|
|
@ -1,25 +1,5 @@
|
||||||
require 'rubyXL'
|
|
||||||
|
|
||||||
class Admin::EPaperSubscribersController < OrbitAdminController
|
class Admin::EPaperSubscribersController < OrbitAdminController
|
||||||
|
|
||||||
RackTempMiddleExist = defined?(Rack::TempfileReaper)
|
|
||||||
RACK_TEMPFILES = defined?(Rack::RACK_TEMPFILES) ? Rack::RACK_TEMPFILES : 'rack.tempfiles'
|
|
||||||
Is_Rails5 = (Rails.version.to_f >= 5)
|
|
||||||
|
|
||||||
if RackTempMiddleExist
|
|
||||||
if Is_Rails5
|
|
||||||
def fix_tempfile_reaper
|
|
||||||
request.set_header(RACK_TEMPFILES, [])
|
|
||||||
end
|
|
||||||
else
|
|
||||||
def fix_tempfile_reaper
|
|
||||||
env[RACK_TEMPFILES] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
def fix_tempfile_reaper; end
|
|
||||||
end
|
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
super
|
super
|
||||||
@app_title = "e_paper"
|
@app_title = "e_paper"
|
||||||
|
|
@ -32,21 +12,21 @@ class Admin::EPaperSubscribersController < OrbitAdminController
|
||||||
@filter_fields.delete(:status)
|
@filter_fields.delete(:status)
|
||||||
@filter_fields.delete(:category)
|
@filter_fields.delete(:category)
|
||||||
@filter_fields.delete(:tags)
|
@filter_fields.delete(:tags)
|
||||||
|
|
||||||
@subscribers = EPaperSubscriber.order_by(sort)
|
@subscribers = EPaperSubscriber.order_by(sort)
|
||||||
@subscribers = search_data(@subscribers, [:email]).page(params[:page]).per(10)
|
|
||||||
|
|
||||||
|
@subscribers = search_data(@subscribers,[:email]).page(params[:page]).per(10)
|
||||||
@thread = (params[:thread_id] ? Multithread.find(params[:thread_id]) : nil rescue nil)
|
@thread = (params[:thread_id] ? Multithread.find(params[:thread_id]) : nil rescue nil)
|
||||||
if @thread && @thread.status[:status] == 'finish'
|
if @thread && @thread.status[:status] == 'finish'
|
||||||
@thread = nil
|
@thread = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
render :partial => "index" if request.xhr?
|
render :partial => "index" if request.xhr?
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
subscriber = EPaperSubscriber.find(params[:id]) rescue nil
|
subscriber = EPaperSubscriber.find(params[:id]) rescue nil
|
||||||
subscriber.destroy if subscriber
|
if !subscriber.nil?
|
||||||
|
subscriber.destroy
|
||||||
|
end
|
||||||
redirect_to admin_e_paper_subscribers_path
|
redirect_to admin_e_paper_subscribers_path
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -54,249 +34,136 @@ class Admin::EPaperSubscribersController < OrbitAdminController
|
||||||
@epaper_subscribers = EPaperSubscriber.where(:email.nin=>[nil,""]).desc(:created_at)
|
@epaper_subscribers = EPaperSubscriber.where(:email.nin=>[nil,""]).desc(:created_at)
|
||||||
@subscribers = @epaper_subscribers.where(:subscribed.ne=>false)
|
@subscribers = @epaper_subscribers.where(:subscribed.ne=>false)
|
||||||
@unsubscribers = @epaper_subscribers.where(:subscribed=>false)
|
@unsubscribers = @epaper_subscribers.where(:subscribed=>false)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.xlsx {
|
format.xlsx {
|
||||||
response.headers['Content-Disposition'] =
|
response.headers['Content-Disposition'] = 'attachment; filename="'+Site.first.title+'-'+I18n.t('e_paper.e_paper')+'-'+I18n.t('e_paper.subscriber')+'.xlsx"'
|
||||||
'attachment; filename="' +
|
|
||||||
Site.first.title + '-' +
|
|
||||||
I18n.t('e_paper.e_paper') + '-' +
|
|
||||||
I18n.t('e_paper.subscriber') + '.xlsx"'
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_subscribers_modal
|
def get_subscribers_modal
|
||||||
@epaper_subscribers = EPaperSubscriber.where(:email.nin=>[nil,""]).desc(:created_at)
|
@epaper_subscribers = EPaperSubscriber.where(:email.nin=>[nil,""]).desc(:created_at)
|
||||||
@subscribers = @epaper_subscribers.where(:subscribed.ne=>false)
|
@subscribers = @epaper_subscribers.where(:subscribed.ne=>false)
|
||||||
@unsubscribers = @epaper_subscribers.where(:subscribed=>false)
|
@unsubscribers = @epaper_subscribers.where(:subscribed=>false)
|
||||||
render :partial => 'modal_select', :layout => false
|
render :partial => 'modal_select', :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
def import_from_excel
|
def import_from_excel
|
||||||
thread = Multithread.where(:key=>'import_epaper_subscribers').first
|
thread = Multithread.where(:key=>'import_epaper_subscribers').first
|
||||||
if thread.nil?
|
if thread.nil?
|
||||||
thread = Multithread.create(:key=>'import_epaper_subscribers', :status=>{:status=>'Processing'})
|
thread = Multithread.create(:key=>'import_epaper_subscribers',:status=>{:status=>'Processing'})
|
||||||
else
|
else
|
||||||
thread.update(:status=>{:status=>'Processing'})
|
thread.update(:status=>{:status=>'Processing'})
|
||||||
end
|
end
|
||||||
|
|
||||||
file = params["import_file"]
|
|
||||||
tempfile = file.tempfile
|
|
||||||
|
|
||||||
ObjectSpace.undefine_finalizer(tempfile)
|
|
||||||
fix_tempfile_reaper
|
|
||||||
|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
workbook = RubyXL::Parser.parse(tempfile)
|
workbook = RubyXL::Parser.parse(params["import_file"].tempfile)
|
||||||
|
|
||||||
subscribe_sheet = workbook['Subscribe']
|
subscribe_sheet = workbook['Subscribe']
|
||||||
unsubscribe_sheet = workbook['Unsubscribe']
|
unsubscribe_sheet = workbook['Unsubscribe']
|
||||||
|
all_count = (subscribe_sheet ? (subscribe_sheet.count - 1) : 0) + (unsubscribe_sheet ? (unsubscribe_sheet.count - 1) : 0)
|
||||||
all_count =
|
|
||||||
(subscribe_sheet ? (subscribe_sheet.count - 1) : 0) +
|
|
||||||
(unsubscribe_sheet ? (unsubscribe_sheet.count - 1) : 0)
|
|
||||||
|
|
||||||
puts_every_count = [all_count * 3 / 100, 1].max
|
puts_every_count = [all_count * 3 / 100, 1].max
|
||||||
current_count = 0
|
current_count = 0
|
||||||
finish_percent = 0
|
finish_percent = 0
|
||||||
|
thread.update(:status=>{:status=>'Importing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
thread.update(
|
|
||||||
:status=>{
|
|
||||||
:status=>'Importing',
|
|
||||||
'all_count'=>all_count,
|
|
||||||
'current_count'=>current_count,
|
|
||||||
'finish_percent'=>finish_percent,
|
|
||||||
'pid'=>Process.pid
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
# 修改點:迴圈外先準備一個陣列,收集匯入失敗的列,最後要回報給使用者
|
|
||||||
failed_rows = []
|
|
||||||
existing_subscribers = {}
|
|
||||||
EPaperSubscriber.all.each { |s| existing_subscribers[s.email] = s }
|
|
||||||
|
|
||||||
if subscribe_sheet
|
|
||||||
subscribe_sheet.each_with_index do |row, i|
|
subscribe_sheet.each_with_index do |row, i|
|
||||||
next if i < 1
|
next if i < 1
|
||||||
next if row.nil?
|
c0 = row.cells[0]
|
||||||
email = row.cells[0]&.value
|
c1 = row.cells[1]
|
||||||
next if email.blank?
|
if c0
|
||||||
|
email = c0.value
|
||||||
# 修改點:查詢前先用跟 model 一樣的清洗規則處理 email,避免「查詢用原始字串、儲存用清洗後字串」不一致造成誤判成新資料
|
if email.present?
|
||||||
fixed_email = email.to_s.gsub(/[ ]/,'').sub(/;$/, '').downcase
|
subscriber = EPaperSubscriber.where(:email=>email).first
|
||||||
|
if subscriber.nil?
|
||||||
if fixed_email.count('@') > 1
|
subscriber = EPaperSubscriber.new(:email=>email)
|
||||||
failed_rows << { row: i + 1, email: email.to_s, reason: '一個欄位包含多個信箱,請拆成單獨一列後重新匯入' }
|
end
|
||||||
current_count += 1
|
language = c1.value
|
||||||
next
|
if language.blank?
|
||||||
|
language = I18n.locale.to_s
|
||||||
end
|
end
|
||||||
begin
|
|
||||||
# 修改點:改用記憶體 Hash 查詢,取代資料庫查詢
|
|
||||||
subscriber = existing_subscribers[fixed_email] || EPaperSubscriber.new(:email=>fixed_email)
|
|
||||||
subscriber.subscribed = true
|
subscriber.subscribed = true
|
||||||
subscriber.language = row.cells[1]&.value.presence || I18n.locale.to_s
|
subscriber.language = language
|
||||||
subscriber.save!
|
subscriber.save
|
||||||
# 修改點:存檔成功後更新 Hash,避免同一份檔案裡後面重複出現的同一個email又找不到
|
end
|
||||||
existing_subscribers[subscriber.email] = subscriber
|
|
||||||
rescue => e
|
|
||||||
failed_rows << { row: i + 1, email: email.to_s, reason: e.message }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
current_count += 1
|
current_count += 1
|
||||||
if current_count % puts_every_count == 0
|
if current_count % puts_every_count == 0
|
||||||
finish_percent = (current_count * 100.0 / all_count).round(1)
|
finish_percent = (current_count * 100.0 / all_count).round(1)
|
||||||
thread.update(:status=>{:status=>'Importing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
thread.update(:status=>{:status=>'Importing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if unsubscribe_sheet
|
|
||||||
unsubscribe_sheet.each_with_index do |row, i|
|
unsubscribe_sheet.each_with_index do |row, i|
|
||||||
next if i < 1
|
next if i < 1
|
||||||
# 修改點:對齊Subscribe那段,整列空白時row本身是nil,要先擋掉
|
c0 = row.cells[0]
|
||||||
next if row.nil?
|
c1 = row.cells[1]
|
||||||
email = row.cells[0]&.value
|
if c0
|
||||||
next if email.blank?
|
email = c0.value
|
||||||
|
if email.present?
|
||||||
# 修改點:對齊Subscribe那段,查詢前先用同一套清洗規則處理email
|
subscriber = EPaperSubscriber.where(:email=>email).first
|
||||||
fixed_email = email.to_s.gsub(/[ ]/,'').sub(/;$/, '').downcase
|
if subscriber.nil?
|
||||||
|
subscriber = EPaperSubscriber.new(:email=>email)
|
||||||
# 修改點:對齊Subscribe那段,擋下一格塞多個信箱的資料
|
end
|
||||||
if fixed_email.count('@') > 1
|
language = c1.value
|
||||||
failed_rows << { row: i + 1, email: email.to_s, reason: '一個欄位包含多個信箱,請拆成單獨一列後重新匯入' }
|
if language.blank?
|
||||||
current_count += 1
|
language = I18n.locale.to_s
|
||||||
next
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# 修改點:對齊Subscribe那段,改用記憶體Hash查詢取代資料庫查詢
|
|
||||||
# 修改點:save改save!並包begin/rescue,例外不再讓整條Thread死掉
|
|
||||||
begin
|
|
||||||
subscriber = existing_subscribers[fixed_email] || EPaperSubscriber.new(:email=>fixed_email)
|
|
||||||
subscriber.subscribed = false
|
subscriber.subscribed = false
|
||||||
subscriber.language = row.cells[1]&.value.presence || I18n.locale.to_s
|
subscriber.language = language
|
||||||
subscriber.save!
|
subscriber.save
|
||||||
existing_subscribers[subscriber.email] = subscriber
|
end
|
||||||
rescue => e
|
|
||||||
failed_rows << { row: i + 1, email: email.to_s, reason: e.message }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
current_count += 1
|
current_count += 1
|
||||||
if current_count % puts_every_count == 0
|
if current_count % puts_every_count == 0
|
||||||
finish_percent = (current_count * 100.0 / all_count).round(1)
|
finish_percent = (current_count * 100.0 / all_count).round(1)
|
||||||
thread.update(:status=>{:status=>'Importing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
thread.update(:status=>{:status=>'Importing','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
finish_percent = 100
|
||||||
|
thread.update(:status=>{:status=>'finish','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
end
|
end
|
||||||
|
|
||||||
thread.update(
|
|
||||||
:status=>{
|
|
||||||
:status=>'finish',
|
|
||||||
'all_count'=>all_count,
|
|
||||||
'current_count'=>current_count,
|
|
||||||
'finish_percent'=>100,
|
|
||||||
'failed_rows'=>failed_rows
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
redirect_to admin_e_paper_subscribers_path(thread_id: thread.id)
|
redirect_to admin_e_paper_subscribers_path(thread_id: thread.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def last_import_result
|
|
||||||
thread = Multithread.where(:key=>'import_epaper_subscribers').first
|
|
||||||
stalled = false
|
|
||||||
if thread && thread.status['status'] == 'Importing' && thread.status['pid']
|
|
||||||
begin
|
|
||||||
Process.kill(0, thread.status['pid'])
|
|
||||||
rescue Errno::ESRCH
|
|
||||||
stalled = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
render :partial => 'last_import_result', locals: { thread: thread, stalled: stalled }
|
|
||||||
end
|
|
||||||
|
|
||||||
def download_excel_format
|
def download_excel_format
|
||||||
@subscribers = []
|
@subscribers = []
|
||||||
@unsubscribers = []
|
@unsubscribers = []
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.xlsx {
|
format.xlsx {
|
||||||
response.headers['Content-Disposition'] =
|
response.headers['Content-Disposition'] = 'attachment; filename="'+Site.first.title+'-'+I18n.t('e_paper.e_paper')+'-'+I18n.t('e_paper.subscriber')+'excel_format.xlsx"'
|
||||||
'attachment; filename="' +
|
|
||||||
Site.first.title + '-' +
|
|
||||||
I18n.t('e_paper.e_paper') + '-' +
|
|
||||||
I18n.t('e_paper.subscriber') + 'excel_format.xlsx"'
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch_delete_subscribers
|
def batch_delete_subscribers
|
||||||
@thread = (params[:thread_id] ? Multithread.find(params[:thread_id]) : nil rescue nil)
|
@thread = (params[:thread_id] ? Multithread.find(params[:thread_id]) : nil rescue nil)
|
||||||
if @thread && @thread.status[:status] == 'finish'
|
if @thread && @thread.status[:status] == 'finish'
|
||||||
@thread = nil
|
@thread = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_subscribers
|
def delete_subscribers
|
||||||
subscriber_ids = params['subscriber_ids']
|
subscriber_ids = params['subscriber_ids']
|
||||||
|
|
||||||
thread = Multithread.where(:key=>'delete_epaper_subscribers').first
|
thread = Multithread.where(:key=>'delete_epaper_subscribers').first
|
||||||
if thread.nil?
|
if thread.nil?
|
||||||
thread = Multithread.create(
|
thread = Multithread.create(:key=>'delete_epaper_subscriber',:status=>{:status=>'Processing'})
|
||||||
:key=>'delete_epaper_subscribers',
|
|
||||||
:status=>{:status=>'Processing'}
|
|
||||||
)
|
|
||||||
else
|
else
|
||||||
thread.update(:status=>{:status=>'Processing'})
|
thread.update(:status=>{:status=>'Processing'})
|
||||||
end
|
end
|
||||||
|
if subscriber_ids
|
||||||
if subscriber_ids.present?
|
|
||||||
all_count = subscriber_ids.count
|
all_count = subscriber_ids.count
|
||||||
puts_every_count = [all_count * 3 / 100, 1].max
|
puts_every_count = [all_count * 3 / 100, 1].max
|
||||||
current_count = 0
|
current_count = 0
|
||||||
finish_percent = 0
|
finish_percent = 0
|
||||||
|
thread.update(:status=>{:status=>'Deleting','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
thread.update(
|
|
||||||
:status=>{
|
|
||||||
:status=>'Deleting',
|
|
||||||
'all_count'=>all_count,
|
|
||||||
'current_count'=>current_count,
|
|
||||||
'finish_percent'=>finish_percent
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
EPaperSubscriber.where(:id.in=>subscriber_ids).to_a.each do |s|
|
EPaperSubscriber.where(:id.in=>subscriber_ids).to_a.each do |s|
|
||||||
s.destroy
|
s.destroy
|
||||||
current_count += 1
|
current_count += 1
|
||||||
|
|
||||||
if current_count % puts_every_count == 0
|
if current_count % puts_every_count == 0
|
||||||
finish_percent = (current_count * 100.0 / all_count).round(1)
|
finish_percent = (current_count * 100.0 / all_count).round(1)
|
||||||
thread.update(
|
thread.update(:status=>{:status=>'Deleting','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
:status=>{
|
|
||||||
:status=>'Deleting',
|
|
||||||
'all_count'=>all_count,
|
|
||||||
'current_count'=>current_count,
|
|
||||||
'finish_percent'=>finish_percent
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
finish_percent = 100
|
||||||
thread.update(
|
thread.update(:status=>{:status=>'finish','all_count'=>all_count,'current_count'=>current_count,'finish_percent'=>finish_percent})
|
||||||
:status=>{
|
|
||||||
:status=>'finish',
|
|
||||||
'all_count'=>all_count,
|
|
||||||
'current_count'=>current_count,
|
|
||||||
'finish_percent'=>100
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
thread.update(:status=>{:status=>'finish'})
|
thread.update(:status=>{:status=>'finish'})
|
||||||
end
|
end
|
||||||
|
|
||||||
redirect_to admin_e_paper_subscribers_batch_delete_subscribers_path(thread_id: thread.id)
|
redirect_to admin_e_paper_subscribers_batch_delete_subscribers_path(thread_id: thread.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
class EPapersController < ApplicationController
|
class EPapersController < ApplicationController
|
||||||
FrontendMethods = ["papers", "topics","showpaper"]
|
FrontendMethods = ["papers", "topics"]
|
||||||
EmptyImg = "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA="
|
EmptyImg = "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA="
|
||||||
EmptyImgUrl = "#{EmptyImg}\" style=\"display: none;"
|
EmptyImgUrl = "#{EmptyImg}\" style=\"display: none;"
|
||||||
def self.custom_widget_data
|
def self.custom_widget_data
|
||||||
|
|
@ -91,7 +91,7 @@ class EPapersController < ApplicationController
|
||||||
{
|
{
|
||||||
"title" => criteria.title,
|
"title" => criteria.title,
|
||||||
"description" => criteria.description,
|
"description" => criteria.description,
|
||||||
"link_to_show" => OrbitHelper.url_to_show(criteria.to_param) + "?method=showpaper"
|
"link_to_show" => OrbitHelper.url_to_show(criteria.to_param) + "?method=topics"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
{
|
{
|
||||||
|
|
@ -129,58 +129,6 @@ class EPapersController < ApplicationController
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def showpaper
|
|
||||||
params = OrbitHelper.params
|
|
||||||
return {} if params[:uid].blank?
|
|
||||||
|
|
||||||
criteria = PaperCriteria.where(:uid => params[:uid]).first
|
|
||||||
return {} if criteria.nil?
|
|
||||||
|
|
||||||
banner_image = nil
|
|
||||||
if criteria.banner_image.present?
|
|
||||||
banner_image = EPaperImage.find(criteria.banner_image).image.url
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
topics = EPaperTopic.where(
|
|
||||||
:period.gte => criteria.start_date,
|
|
||||||
:period.lte => criteria.end_date
|
|
||||||
).desc(:period)
|
|
||||||
|
|
||||||
papers = topics.group_by(&:category)
|
|
||||||
|
|
||||||
data = []
|
|
||||||
papers_sorted = get_all_categories.map do |v|
|
|
||||||
tmp = papers.select{|cat,topic_list| (cat.id==v.id rescue false)}
|
|
||||||
tmp.count==0 ? nil : tmp
|
|
||||||
end.compact
|
|
||||||
|
|
||||||
papers_sorted.each do |paper|
|
|
||||||
paper.each do |category, topic_list|
|
|
||||||
topics_data = Array(topic_list).compact.collect do |topic|
|
|
||||||
{
|
|
||||||
"title" => topic.title,
|
|
||||||
"link_to_show" => OrbitHelper.url_to_show(topic.to_param),
|
|
||||||
"description" => topic.description,
|
|
||||||
"img_url" => topic.image.url || EmptyImgUrl,
|
|
||||||
"img_url_thumb" => topic.image.thumb.url || EmptyImgUrl,
|
|
||||||
"category_title" => category.title
|
|
||||||
}
|
|
||||||
end
|
|
||||||
data << {
|
|
||||||
"category_title" => category.title,
|
|
||||||
"category_link" => "#{params["url"]}/#{params["page"]}?method=topics&category=#{category.id.to_s}",
|
|
||||||
"topics" => topics_data
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
{
|
|
||||||
"categories" => data,
|
|
||||||
"extras" => {}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def topics
|
def topics
|
||||||
params = OrbitHelper.params
|
params = OrbitHelper.params
|
||||||
if params[:uid].present?
|
if params[:uid].present?
|
||||||
|
|
@ -249,7 +197,7 @@ class EPapersController < ApplicationController
|
||||||
{
|
{
|
||||||
"title" => criteria.title,
|
"title" => criteria.title,
|
||||||
"description" => criteria.description,
|
"description" => criteria.description,
|
||||||
"link_to_show" => OrbitHelper.widget_item_url(criteria.to_param) + "?method=showpaper"
|
"link_to_show" => OrbitHelper.widget_item_url(criteria.to_param) + "?method=topics"
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
{
|
{
|
||||||
|
|
@ -315,7 +263,7 @@ class EPapersController < ApplicationController
|
||||||
{
|
{
|
||||||
"categories" => data,
|
"categories" => data,
|
||||||
"extras" => {
|
"extras" => {
|
||||||
"read_more" => OrbitHelper.widget_more_url + "?method=showpaper"
|
"read_more" => OrbitHelper.widget_more_url + "?method=topics"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
@ -352,7 +300,7 @@ class EPapersController < ApplicationController
|
||||||
{
|
{
|
||||||
"categories" => data,
|
"categories" => data,
|
||||||
"extras" => {
|
"extras" => {
|
||||||
"read_more" => OrbitHelper.widget_more_url + "?method=showpaper"
|
"read_more" => OrbitHelper.widget_more_url + "?method=topics"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,14 @@ class EPaperSubscriber
|
||||||
field :subscribed, type: Boolean, :default => true
|
field :subscribed, type: Boolean, :default => true
|
||||||
field :language
|
field :language
|
||||||
field :last_paper_sent
|
field :last_paper_sent
|
||||||
|
|
||||||
before_save do
|
before_save do
|
||||||
self.fix_email
|
self.fix_email
|
||||||
# 修改點:用 throw(:abort) 取代 return false(Rails 5+ block 內不可用 return)
|
if self.class.where(:email=>self.email, :language=>self.language,:subscribed=>true).count != 0
|
||||||
# 修改點:排除自己這筆(self.id.ne=>self.id),避免更新既有紀錄時把自己算成重複
|
return false
|
||||||
if self.class.where(:id.ne=>self.id, :email=>self.email, :language=>self.language, :subscribed=>true).count != 0
|
|
||||||
throw(:abort)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def fix_email(save_flag=false)
|
def fix_email(save_flag=false)
|
||||||
# 修改點:加上 .downcase,統一大小寫,避免 ABC@Gmail.com 跟 abc@gmail.com 被當成兩筆
|
self.email = self.email.to_s.gsub(/[ ]/,'').sub(/;$/, '')
|
||||||
self.email = self.email.to_s.gsub(/[ ]/,'').sub(/;$/, '').downcase
|
|
||||||
self.save if save_flag
|
self.save if save_flag
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -53,7 +53,9 @@
|
||||||
content_tag(:div, link_to(t("e_paper.export"), admin_e_paper_subscribers_export_excel_path + '.xlsx', :class=>"btn btn-success"), class: "pull-right")
|
content_tag(:div, link_to(t("e_paper.export"), admin_e_paper_subscribers_export_excel_path + '.xlsx', :class=>"btn btn-success"), class: "pull-right")
|
||||||
%>
|
%>
|
||||||
<div class="dropup upload-button pull-right">
|
<div class="dropup upload-button pull-right">
|
||||||
<button class="btn btn-default" id="show-last-import-result" type="button">查看最近一次匯入</button>
|
<% if @thread %>
|
||||||
|
<button class="show_progress btn btn-primary" type="button"><%= t("e_paper.show_progress") %></button>
|
||||||
|
<% end %>
|
||||||
<button class="btn btn-info dropdown-toggle" type="button" data-toggle="dropdown">
|
<button class="btn btn-info dropdown-toggle" type="button" data-toggle="dropdown">
|
||||||
<i class="icon-upload-alt icon-white"></i><%= t('personal_journal.upload') %>
|
<i class="icon-upload-alt icon-white"></i><%= t('personal_journal.upload') %>
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
|
|
@ -92,20 +94,7 @@
|
||||||
window.clearTimeout(window.time_out_id);
|
window.clearTimeout(window.time_out_id);
|
||||||
window.setTimeout(function(){
|
window.setTimeout(function(){
|
||||||
$("#threadModal").modal("hide");
|
$("#threadModal").modal("hide");
|
||||||
// 修改點:is_finish後檢查failed_rows,有內容才組成清單提醒,取代原本單純alert(status)
|
|
||||||
var failed_rows = data["failed_rows"];
|
|
||||||
if(failed_rows && failed_rows.length > 0){
|
|
||||||
var msg = "匯入完成,但有 " + failed_rows.length + " 筆資料匯入失敗:\n\n";
|
|
||||||
failed_rows.slice(0, 20).forEach(function(r){
|
|
||||||
msg += "第" + r["row"] + "列 (" + r["email"] + "):" + r["reason"] + "\n";
|
|
||||||
});
|
|
||||||
if(failed_rows.length > 20){
|
|
||||||
msg += "\n...等共 " + failed_rows.length + " 筆,僅顯示前20筆";
|
|
||||||
}
|
|
||||||
alert(msg);
|
|
||||||
}else{
|
|
||||||
alert(data["status"]);
|
alert(data["status"]);
|
||||||
}
|
|
||||||
}, 3000);
|
}, 3000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -118,15 +107,10 @@
|
||||||
$("#threadModal").on('shown.bs.modal',function(){
|
$("#threadModal").on('shown.bs.modal',function(){
|
||||||
window.time_out_id = window.setTimeout(update_thread, 1000);
|
window.time_out_id = window.setTimeout(update_thread, 1000);
|
||||||
})
|
})
|
||||||
|
$("#threadModal").modal("show");
|
||||||
|
$(".show_progress").click(function(){
|
||||||
|
$("#threadModal").modal("show");
|
||||||
|
})
|
||||||
}
|
}
|
||||||
$("#show-last-import-result").click(function(){
|
|
||||||
$.get("<%=admin_e_paper_subscribers_last_import_result_path%>", function(html){
|
|
||||||
if($("#lastImportResultModal").length == 0){
|
|
||||||
$("body").append('<div id="lastImportResultModal" class="modal hide fade" tabindex="-1"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h3>上次匯入結果</h3></div><div id="lastImportResultBody"></div><div class="modal-footer"><button class="btn" data-dismiss="modal">關閉</button></div></div></div></div>');
|
|
||||||
}
|
|
||||||
$("#lastImportResultBody").html(html);
|
|
||||||
$("#lastImportResultModal").modal("show");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
<div class="modal-body">
|
|
||||||
<p style="color:#888;font-size:0.9em;">此畫面顯示的是查詢當下的狀態,若匯入仍在進行中,請關閉後重新點擊按鈕以取得最新進度。</p>
|
|
||||||
|
|
||||||
<% if thread.nil? %>
|
|
||||||
<p>目前沒有匯入紀錄。</p>
|
|
||||||
<% elsif stalled %>
|
|
||||||
<p style="color:#c00;font-weight:bold;">匯入似乎已意外中斷(原本處理這次匯入的伺服器程序已經不存在,可能是伺服器重啟或未預期的錯誤所致)。</p>
|
|
||||||
<p>中斷前已處理:<%= thread.status['current_count'] %> / <%= thread.status['all_count'] %>(<%= thread.status['finish_percent'] %>%),這些資料已寫入資料庫,不會消失。如需完成剩餘資料,請重新上傳檔案。</p>
|
|
||||||
<% else %>
|
|
||||||
<p>狀態:<%= thread.status['status'] %>/已處理 <%= thread.status['current_count'] %> / <%= thread.status['all_count'] %>(<%= thread.status['finish_percent'] %>%)</p>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if thread %>
|
|
||||||
<% failed_rows = thread.status['failed_rows'] || [] %>
|
|
||||||
<% if failed_rows.empty? %>
|
|
||||||
<p>沒有失敗紀錄。</p>
|
|
||||||
<% else %>
|
|
||||||
<p>共 <%= failed_rows.count %> 筆匯入失敗:</p>
|
|
||||||
<table class="table">
|
|
||||||
<thead><tr><th>列號</th><th>Email</th><th>原因</th></tr></thead>
|
|
||||||
<tbody>
|
|
||||||
<% failed_rows.each do |r| %>
|
|
||||||
<tr>
|
|
||||||
<td><%= r['row'] %></td>
|
|
||||||
<td><%= r['email'] %></td>
|
|
||||||
<td><%= r['reason'] %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<%= render_view %>
|
|
||||||
|
|
@ -33,7 +33,6 @@ Rails.application.routes.draw do
|
||||||
get 'e_paper_subscribers/export_excel', to: 'e_paper_subscribers#export_excel'
|
get 'e_paper_subscribers/export_excel', to: 'e_paper_subscribers#export_excel'
|
||||||
get 'e_paper_subscribers/download_excel_format', to: 'e_paper_subscribers#download_excel_format'
|
get 'e_paper_subscribers/download_excel_format', to: 'e_paper_subscribers#download_excel_format'
|
||||||
post 'e_paper_subscribers/import_from_excel', to: 'e_paper_subscribers#import_from_excel'
|
post 'e_paper_subscribers/import_from_excel', to: 'e_paper_subscribers#import_from_excel'
|
||||||
get 'e_paper_subscribers/last_import_result', to: 'e_paper_subscribers#last_import_result'
|
|
||||||
get 'e_paper_subscribers/get_subscribers_modal', to: 'e_paper_subscribers#get_subscribers_modal'
|
get 'e_paper_subscribers/get_subscribers_modal', to: 'e_paper_subscribers#get_subscribers_modal'
|
||||||
get 'e_paper_subscribers/batch_delete_subscribers', to: 'e_paper_subscribers#batch_delete_subscribers'
|
get 'e_paper_subscribers/batch_delete_subscribers', to: 'e_paper_subscribers#batch_delete_subscribers'
|
||||||
post 'e_paper_subscribers/delete_subscribers', to: 'e_paper_subscribers#delete_subscribers'
|
post 'e_paper_subscribers/delete_subscribers', to: 'e_paper_subscribers#delete_subscribers'
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
<div class="epaper-index2" data-list="categories" data-level="0">
|
|
||||||
<h3><a href="{{category_link}}">{{category_title}}</a></h3>
|
|
||||||
<div data-list="topics" data-level="1">
|
|
||||||
<div class="epaper-index2-container row">
|
|
||||||
<h4><a href="{{link_to_show}}">{{title}}</a>
|
|
||||||
<a href="{{link_to_show}}"><span>{{category_title}}</span></a>
|
|
||||||
</h4>
|
|
||||||
<div class="epaper-leftimg col-lg-5 col-xs-12">
|
|
||||||
<img src="{{img_url_thumb}}" alt="{{title}}">
|
|
||||||
</div>
|
|
||||||
<div class="epaper-rightContent col-lg-7 col-xs-12" >
|
|
||||||
<div class="epaper-description"><a href="{{link_to_show}}">{{description}}</a></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
Loading…
Reference in New Issue