Add stale record cleanup logic in NFU personal data sync

This commit is contained in:
rulingcom 2026-08-04 17:34:37 +08:00
parent a40b9523f2
commit 6adf45a47b
1 changed files with 250 additions and 117 deletions

View File

@ -9,16 +9,16 @@ module NfuSyncPlugin
begin
uri = URI("#{API_BASE_URL}/#{endpoint}/#{teacher_id}")
response = Net::HTTP.get_response(uri)
if response.is_a?(Net::HTTPSuccess)
JSON.parse(response.body)
else
puts "API 錯誤: #{response.code}"
[]
nil
end
rescue => e
puts "連接 API 失敗: #{e.message}"
[]
nil
end
end
@ -60,7 +60,6 @@ module NfuSyncPlugin
def convert_publish_date(date_str)
return nil if date_str.blank?
# 從 "Jun-25" 轉換為 "2025-06-01T00:00:00Z"
begin
date_obj = Date.parse("#{date_str}-01")
DateTime.new(date_obj.year, date_obj.month, 1, 0, 0, 0).to_time.utc
@ -80,18 +79,20 @@ module NfuSyncPlugin
def get_sync_data(member, environment = :test)
return {} if member.sid.blank?
result = {}
# 期刊論文 (VRW_PERIODICAL)
result["_api_status"] = {}
periodicals = query_api('periodicals', member.sid)
result["journal"] = periodicals.map do |row|
result["_api_status"]["journal"] = !periodicals.nil?
result["journal"] = (periodicals || []).map do |row|
vol, issue = extract_volume_issue(row[7])
start_page, end_page = extract_page_numbers(row[9])
year = extract_year_only(row[13])
{
"ukey" => row[0],
"teacher_sid" => row[1],
"Thesis_name" => row[2],
"Journal_name" => row[3],
"author" => row[4],
@ -109,10 +110,12 @@ module NfuSyncPlugin
}
end
# 專書
result["books"] = query_api('books', member.sid).map do |row|
books_raw = query_api('books', member.sid)
result["_api_status"]["books"] = !books_raw.nil?
result["books"] = (books_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"book_title" => row[2],
"publisher" => row[3],
"author" => row[4],
@ -125,11 +128,12 @@ module NfuSyncPlugin
}
end
# 研討會論文 (VRW_RESEARCH_ACT)
research_acts = query_api('research_acts', member.sid)
result["conference"] = research_acts.map do |row|
result["_api_status"]["conference"] = !research_acts.nil?
result["conference"] = (research_acts || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"Thesis_name" => row[2],
"Research_name" => row[3],
"Country" => row[4],
@ -142,10 +146,12 @@ module NfuSyncPlugin
}
end
# 研究計畫
result["project"] = query_api('plans', member.sid).map do |row|
project_raw = query_api('plans', member.sid)
result["_api_status"]["project"] = !project_raw.nil?
result["project"] = (project_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"project_title" => row[2],
"job_title" => row[3],
"project_type" => row[4],
@ -154,10 +160,12 @@ module NfuSyncPlugin
}
end
# 專利
result["patent"] = query_api('patents', member.sid).map do |row|
patent_raw = query_api('patents', member.sid)
result["_api_status"]["patent"] = !patent_raw.nil?
result["patent"] = (patent_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"patent_title" => row[2],
"patent_country" => row[3],
"authors" => row[4],
@ -168,10 +176,12 @@ module NfuSyncPlugin
}
end
# 獲獎
result["award"] = query_api('awards', member.sid).map do |row|
award_raw = query_api('awards', member.sid)
result["_api_status"]["award"] = !award_raw.nil?
result["award"] = (award_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"award_name" => row[2],
"award_order" => row[3],
"award_unit" => row[4],
@ -180,40 +190,48 @@ module NfuSyncPlugin
}
end
# 授課課程
result["course"] = query_api('courses', member.sid).map do |row|
course_raw = query_api('courses', member.sid)
result["_api_status"]["course"] = !course_raw.nil?
result["course"] = (course_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"course_class" => row[2],
"course_name" => row[3],
"url" => row[4]
}
end
# 學歷
result["education"] = query_api('educations', member.sid).map do |row|
education_raw = query_api('educations', member.sid)
result["_api_status"]["education"] = !education_raw.nil?
result["education"] = (education_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"degree" => row[2],
"school_name" => row[3],
"department" => row[4]
}
end
# 證照
result["certification"] = query_api('certifications', member.sid).map do |row|
certification_raw = query_api('certifications', member.sid)
result["_api_status"]["certification"] = !certification_raw.nil?
result["certification"] = (certification_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"title" => row[2],
"issued_by" => row[4],
"acquired_date" => row[3]
}
end
# 指導學生競賽
result["award_contest"] = query_api('award_contests', member.sid).map do |row|
award_contest_raw = query_api('award_contests', member.sid)
result["_api_status"]["award_contest"] = !award_contest_raw.nil?
result["award_contest"] = (award_contest_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"awarding_unit" => row[2],
"award_name" => row[3],
"competition_name" => row[4],
@ -225,10 +243,12 @@ module NfuSyncPlugin
}
end
# 教師演講
result["activity"] = query_api('talks', member.sid).map do |row|
activity_raw = query_api('talks', member.sid)
result["_api_status"]["activity"] = !activity_raw.nil?
result["activity"] = (activity_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"activity_name" => row[2],
"activity_organizer" => row[3],
"participation_status" => row[4],
@ -238,10 +258,12 @@ module NfuSyncPlugin
}
end
# 先期技術移轉
result["pretechtran"] = query_api('pretechtrans', member.sid).map do |row|
pretechtran_raw = query_api('pretechtrans', member.sid)
result["_api_status"]["pretechtran"] = !pretechtran_raw.nil?
result["pretechtran"] = (pretechtran_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"patent_title" => row[3],
"manufacturer_name" => row[4],
"participating_teachers" => row[5],
@ -252,10 +274,12 @@ module NfuSyncPlugin
}
end
# 技術移轉
result["techtran"] = query_api('techtrans', member.sid).map do |row|
techtran_raw = query_api('techtrans', member.sid)
result["_api_status"]["techtran"] = !techtran_raw.nil?
result["techtran"] = (techtran_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"patent_title" => row[2],
"manufacturer_name" => row[3],
"participating_teachers" => row[4],
@ -265,10 +289,12 @@ module NfuSyncPlugin
}
end
# 教師專業服務
result["pro_service"] = query_api('pro_services', member.sid).map do |row|
pro_service_raw = query_api('pro_services', member.sid)
result["_api_status"]["pro_service"] = !pro_service_raw.nil?
result["pro_service"] = (pro_service_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"volunteer_name" => row[4],
"volunteer_organizer" => row[2],
"volunteer_type" => row[3],
@ -277,20 +303,22 @@ module NfuSyncPlugin
}
end
# 教師經歷
result["experience"] = query_api('experiences', member.sid).map do |row|
experience_raw = query_api('experiences', member.sid)
result["_api_status"]["experience"] = !experience_raw.nil?
result["experience"] = (experience_raw || []).map do |row|
{
"ukey" => row[0],
"exp_unit" => row[2],
"exp_dept" => row[3],
"ukey" => row[0],
"teacher_sid" => row[1],
"exp_unit" => row[2],
"exp_dept" => row[3],
"exp_gnam_name" => row[4],
"exp_stardate" => row[5],
"exp_enddate" => row[6]
"exp_stardate" => row[5],
"exp_enddate" => row[6]
}
end
# 教師基本資料
result["teacher"] = query_api('teachers', member.sid).map do |row|
teacher_raw = query_api('teachers', member.sid)
result["teacher"] = (teacher_raw || []).map do |row|
{
"chinese_name" => row[1],
"english_name" => row[2],
@ -304,10 +332,12 @@ module NfuSyncPlugin
}
end
# 研究所論文指導
result["dissertation"] = query_api('dissertations', member.sid).map do |row|
dissertation_raw = query_api('dissertations', member.sid)
result["_api_status"]["dissertation"] = !dissertation_raw.nil?
result["dissertation"] = (dissertation_raw || []).map do |row|
{
"ukey" => row[0],
"teacher_sid" => row[1],
"paper_title_zh" => row[2],
"paper_title_en" => row[3],
"graduation_year" => row[4],
@ -324,9 +354,16 @@ module NfuSyncPlugin
result
end
# 期刊論文
def sync_journal_papers(query_result, member)
puts "Journal Paper for user: #{member.email}"
if query_result["_api_status"]["journal"]
new_ukeys = query_result["journal"].map { |jp_data| jp_data["ukey"] }
JournalPaper.where(member_profile_id: [member.id]).each do |jp|
jp.delete if jp.rss2_id.present? && !new_ukeys.include?(jp.rss2_id)
end
end
query_result["journal"].to_a.each do |jp_data|
jp = JournalPaper.where(:rss2_id => jp_data["ukey"]).first || JournalPaper.new
jp.rss2_id = jp_data["ukey"]
@ -340,22 +377,22 @@ module NfuSyncPlugin
jp.form_to_end = jp_data["end_page"].to_s if jp_data["end_page"].present?
jp.year = jp_data["year"].to_s if jp_data["year"].present?
jp.publication_date = jp_data["publish_date"] if jp_data["publish_date"].present?
if jp_data["journal_level"].present?
level = JournalLevel.where(:title => jp_data["journal_level"]).first_or_create(:title_translations => localize_data(jp_data["journal_level"]))
jp.journal_level_ids = [level.id]
end
if jp_data["journal_type"].present?
jtype = JournalPaperType.where(:title => jp_data["journal_type"]).first_or_create(:title_translations => localize_data(jp_data["journal_type"]))
jp.journal_paper_type_id = jtype.id
end
if jp_data["author_type"].present?
atype = JournalPaperAuthorType.where(:title => jp_data["author_type"]).first_or_create(:title_translations => localize_data(jp_data["author_type"]))
jp.journal_paper_author_type_ids = [atype.id]
end
jp.associated_project = jp_data["plan_name"] if jp_data["plan_name"].present?
jp.member_profile_id = [member.id]
puts "Journal Paper #{jp.id} saved" if jp.save
@ -364,10 +401,18 @@ module NfuSyncPlugin
def sync_books(query_result, member)
puts "books for user: #{member.email}"
if query_result["_api_status"]["books"]
new_ukeys = query_result["books"].map { |book| book["ukey"] }
Book.where(member_profile_id: member.id).each do |bk|
bk.delete if bk.rss2_id.present? && !new_ukeys.include?(bk.rss2_id)
end
end
query_result["books"].to_a.each do |book|
bk = Book.where(:rss2_id => book["ukey"]).first
bk.delete if bk
bk = Book.new
bk.rss2_id = book["ukey"]
bk.book_title_translations = localize_data(book["book_title"])
@ -376,12 +421,12 @@ module NfuSyncPlugin
bk.language = book["language"]
bk.isbn = book["isbn"]
bk.publish_date = book["publish_date"] if book["publish_date"].present?
if book["book_type"].present?
btype = BookType.where(:title => book["book_type"]).first_or_create(:title_translations => localize_data(book["book_type"]))
bk.book_type_id = btype.id
end
bk.year = book["year"]
bk.member_profile_id = member.id
puts "books #{bk.id} saved" if bk.save
@ -390,6 +435,14 @@ module NfuSyncPlugin
def sync_conference_papers(query_result, member)
puts "Conference Paper for user: #{member.email}"
if query_result["_api_status"]["conference"]
new_ukeys = query_result["conference"].map { |cp_data| cp_data["ukey"] }
WritingConference.where(member_profile_id: member.id).each do |cp|
cp.delete if cp.rss2_id.present? && !new_ukeys.include?(cp.rss2_id)
end
end
query_result["conference"].to_a.each do |cp_data|
cp = WritingConference.where(:rss2_id => cp_data["ukey"]).first || WritingConference.new
cp.rss2_id = cp_data["ukey"]
@ -401,12 +454,12 @@ module NfuSyncPlugin
cp.period_end_date = DateTime.parse(cp_data["End_date"]).to_date if cp_data["End_date"].present?
cp.year = cp_data["Year"].to_s if cp_data["Year"].present?
cp.url = cp_data["Research_url"] if cp_data["Research_url"].present?
if cp_data["Author_type"].present?
atype = ConferenceAuthorType.where(:title => cp_data["Author_type"]).first_or_create(:title_translations => localize_data(cp_data["Author_type"]))
cp.conference_author_type_ids = [atype.id]
end
cp.member_profile_id = member.id
puts "conference paper #{cp.id} saved" if cp.save
end
@ -414,10 +467,18 @@ module NfuSyncPlugin
def sync_projects(query_result, member)
puts "Projects for user: #{member.email}"
if query_result["_api_status"]["project"]
new_ukeys = query_result["project"].map { |pj| pj["ukey"] }
Project.where(member_profile_id: member.id).each do |pj|
pj.delete if pj.rss2_id.present? && !new_ukeys.include?(pj.rss2_id)
end
end
query_result["project"].to_a.each do |pj|
pj_obj = Project.where(:rss2_id => pj["ukey"]).first
pj_obj.delete if pj_obj
pj_obj = Project.new
pj_obj.rss2_id = pj["ukey"]
pj_obj.project_title_translations = localize_data(pj["project_title"])
@ -425,12 +486,12 @@ module NfuSyncPlugin
pj_obj.period_start_date = DateTime.parse(pj["period_start_date"]).to_date if pj["period_start_date"].present?
pj_obj.period_end_date = DateTime.parse(pj["period_end_date"]).to_date if pj["period_end_date"].present?
pj_obj.year = DateTime.parse(pj["period_start_date"]).year if pj["period_start_date"].present?
if pj["project_type"].present?
ptype = ProjectType.where(:title => pj["project_type"]).first_or_create(:title_translations => localize_data(pj["project_type"]))
pj_obj.project_type_id = ptype.id
end
pj_obj.member_profile_id = member.id
puts "Project #{pj_obj.id} saved" if pj_obj.save
end
@ -438,10 +499,18 @@ module NfuSyncPlugin
def sync_patents(query_result, member)
puts "Patents for user: #{member.email}"
if query_result["_api_status"]["patent"]
new_ukeys = query_result["patent"].map { |pt| pt["ukey"] }
Patent.where(member_profile_id: member.id).each do |pt|
pt.delete if pt.rss2_id.present? && !new_ukeys.include?(pt.rss2_id)
end
end
query_result["patent"].to_a.each do |pt|
patent = Patent.where(:rss2_id => pt["ukey"]).first
patent.delete if patent
patent = Patent.new
patent.rss2_id = pt["ukey"]
patent.patent_title_translations = localize_data(pt["patent_title"])
@ -451,12 +520,12 @@ module NfuSyncPlugin
patent.progress_status = pt["progress_status"]
patent.publish_date = DateTime.parse(pt["application_date"]).to_date if pt["application_date"].present?
patent.year = DateTime.parse(pt["application_date"]).year if pt["application_date"].present?
if pt["patent_type"].present?
ptype = PatentType.where(:title => pt["patent_type"]).first_or_create(:title_translations => localize_data(pt["patent_type"]))
patent.patent_type_ids = [ptype.id]
end
patent.member_profile_id = member.id
puts "Patent #{patent.id} saved" if patent.save
end
@ -464,29 +533,34 @@ module NfuSyncPlugin
def sync_honors(query_result, member)
puts "Honors for user: #{member.email}"
if query_result["_api_status"]["award"]
new_ukeys = query_result["award"].map { |hn| hn["ukey"] }
Honor.where(member_profile_id: member.id).each do |hn|
hn.delete if hn.rss2_id.present? && !new_ukeys.include?(hn.rss2_id)
end
end
query_result["award"].to_a.each do |hn|
# 先保存舊的 UID
old_uid = Honor.where(:rss2_id => hn["ukey"]).first&.uid
# 刪除舊記錄
honor = Honor.where(:rss2_id => hn["ukey"]).first
honor.delete if honor
# 重建新記錄,恢復 UID
honor = Honor.new
honor.rss2_id = hn["ukey"]
honor.uid = old_uid # 恢復舊的 UID
honor.uid = old_uid
honor.award_name_translations = localize_data(hn["award_name"])
honor.awarding_unit_translations = localize_data(hn["award_unit"].to_s.strip)
honor.note = hn["join_teacher"]
honor.award_date = DateTime.parse(hn["award_date"]).to_date if hn["award_date"].present?
honor.year = DateTime.parse(hn["award_date"]).year if hn["award_date"].present?
if hn["award_order"].present?
htype = HonorType.where(:title => hn["award_order"]).first_or_create(:title_translations => localize_data(hn["award_order"]))
honor.honor_type_id = htype.id
end
honor.member_profile_id = member.id
puts "Honor #{honor.id} saved" if honor.save
end
@ -494,12 +568,20 @@ module NfuSyncPlugin
def sync_courses(query_result, member)
puts "Courses for user: #{member.email}"
if query_result["_api_status"]["course"]
new_ukeys = query_result["course"].map { |cs| cs["ukey"] }
Course.where(member_profile_id: member.id).each do |cs|
cs.delete if cs.rss2_id.present? && !new_ukeys.include?(cs.rss2_id)
end
end
query_result["course"].to_a.each do |cs|
old_uid = Course.where(:rss2_id => cs["ukey"]).first&.uid
course = Course.where(:rss2_id => cs["ukey"]).first
course.delete if course
course = Course.new
course.rss2_id = cs["ukey"]
course.uid = old_uid
@ -513,10 +595,18 @@ module NfuSyncPlugin
def sync_diplomas(query_result, member)
puts "Diplomas for user: #{member.email}"
if query_result["_api_status"]["education"]
new_ukeys = query_result["education"].map { |edu| edu["ukey"] }
Diploma.where(member_profile_id: member.id).each do |edu|
edu.delete if edu.rss2_id.present? && !new_ukeys.include?(edu.rss2_id)
end
end
query_result["education"].to_a.each do |edu|
diploma = Diploma.where(:rss2_id => edu["ukey"]).first
diploma.delete if diploma
diploma = Diploma.new
diploma.rss2_id = edu["ukey"]
diploma.school_name_translations = localize_data(edu["school_name"])
@ -529,15 +619,20 @@ module NfuSyncPlugin
def sync_certificates(query_result, member)
puts "Certificates for user: #{member.email}"
if query_result["_api_status"]["certification"]
new_ukeys = query_result["certification"].map { |cert| cert["ukey"] }
Certificate.where(member_profile_id: member.id).each do |cert|
cert.delete if cert.rss2_id.present? && !new_ukeys.include?(cert.rss2_id)
end
end
query_result["certification"].to_a.each do |cert|
# 先保存舊的 UID
old_uid = Certificate.where(:rss2_id => cert["ukey"]).first&.uid
# 刪除舊記錄
certificate = Certificate.where(:rss2_id => cert["ukey"]).first
certificate.delete if certificate
# 重建新記錄,恢復 UID
certificate = Certificate.new
certificate.rss2_id = cert["ukey"]
certificate.uid = old_uid
@ -551,12 +646,20 @@ module NfuSyncPlugin
def sync_award_contests(query_result, member)
puts "Award Contests for user: #{member.email}"
if query_result["_api_status"]["award_contest"]
new_ukeys = query_result["award_contest"].map { |ac| ac["ukey"] }
Competition.where(member_profile_id: member.id).each do |ac|
ac.delete if ac.rss2_id.present? && !new_ukeys.include?(ac.rss2_id)
end
end
query_result["award_contest"].to_a.each do |ac|
old_uid = Competition.where(:rss2_id => ac["ukey"]).first&.uid
competition = Competition.where(:rss2_id => ac["ukey"]).first
competition.delete if competition
competition = Competition.new
competition.rss2_id = ac["ukey"]
competition.uid = old_uid
@ -576,12 +679,20 @@ module NfuSyncPlugin
def sync_activities(query_result, member)
puts "Activities for user: #{member.email}"
if query_result["_api_status"]["activity"]
new_ukeys = query_result["activity"].map { |act| act["ukey"] }
Activity.where(member_profile_id: member.id).each do |act|
act.delete if act.rss2_id.present? && !new_ukeys.include?(act.rss2_id)
end
end
query_result["activity"].to_a.each do |act|
old_uid = Activity.where(:rss2_id => act["ukey"]).first&.uid
activity = Activity.where(:rss2_id => act["ukey"]).first
activity.delete if activity
activity = Activity.new
activity.rss2_id = act["ukey"]
activity.uid = old_uid
@ -599,13 +710,20 @@ module NfuSyncPlugin
def sync_technology_transfers(query_result, member)
puts "Technology Transfers for user: #{member.email}"
# 先期技術移轉
all_tech = (query_result["pretechtran"] || []) + (query_result["techtran"] || [])
if query_result["_api_status"]["pretechtran"] && query_result["_api_status"]["techtran"]
new_ukeys = all_tech.map { |tech| tech["ukey"] }
TechnologyTransfer.where(member_profile_id: member.id).each do |tt|
tt.delete if tt.rss2_id.present? && !new_ukeys.include?(tt.rss2_id)
end
end
(query_result["pretechtran"] || []).each do |tech|
sync_single_technology_transfer(tech, member)
end
# 技術移轉
(query_result["techtran"] || []).each do |tech|
sync_single_technology_transfer(tech, member)
end
@ -613,10 +731,10 @@ module NfuSyncPlugin
def sync_single_technology_transfer(tech, member)
old_uid = TechnologyTransfer.where(:rss2_id => tech["ukey"]).first&.uid
tt = TechnologyTransfer.where(:rss2_id => tech["ukey"]).first
tt.delete if tt
tt = TechnologyTransfer.new
tt.rss2_id = tech["ukey"]
tt.uid = old_uid
@ -627,22 +745,30 @@ module NfuSyncPlugin
tt.license_end_date = DateTime.parse(tech["license_end_date"]).to_date if tech["license_end_date"].present?
tt.year = DateTime.parse(tech["license_start_date"]).year if tech["license_start_date"].present?
tt.note = "#{tech["school_year"]}學年" if tech["school_year"].present?
category = TechnologyTransferCategory.where(:title => tech["category"]).first_or_create(:title_translations => localize_data(tech["category"]))
tt.technology_transfer_category_id = category.id
tt.member_profile_id = member.id
puts "TechnologyTransfer #{tt.id} saved" if tt.save
end
def sync_volunteer_services(query_result, member)
puts "Volunteer Services for user: #{member.email}"
if query_result["_api_status"]["pro_service"]
new_ukeys = query_result["pro_service"].map { |vs| vs["ukey"] }
VolunteerService.where(member_profile_id: member.id).each do |vs|
vs.delete if vs.rss2_id.present? && !new_ukeys.include?(vs.rss2_id)
end
end
query_result["pro_service"].to_a.each do |vs|
old_uid = VolunteerService.where(:rss2_id => vs["ukey"]).first&.uid
service = VolunteerService.where(:rss2_id => vs["ukey"]).first
service.delete if service
service = VolunteerService.new
service.rss2_id = vs["ukey"]
service.uid = old_uid
@ -659,6 +785,14 @@ module NfuSyncPlugin
def sync_experiences(query_result, member)
puts "Experiences for user: #{member.email}"
if query_result["_api_status"]["experience"]
new_ukeys = query_result["experience"].map { |exp| exp["ukey"] }
Experience.where(member_profile_id: member.id).each do |exp|
exp.delete if exp.rss2_id.present? && !new_ukeys.include?(exp.rss2_id)
end
end
query_result["experience"].to_a.each do |exp|
old_uid = Experience.where(:rss2_id => exp["ukey"]).first&.uid
@ -681,21 +815,17 @@ module NfuSyncPlugin
def sync_teachers(query_result, member)
puts "Teachers for user: #{member.email}"
return if query_result["teacher"].to_a.empty?
teacher = query_result["teacher"].first
# 更新 MemberProfile 基本欄位
member.last_name_translations = { zh_tw: teacher["chinese_name"], en: teacher["english_name"] }
member.first_name_translations = { zh_tw: "", en: "" }
member.email = teacher["email"]
member.office_tel = teacher["phone"]
if member.save
puts "MemberProfile #{member.id} updated"
end
# 更新或建立 attribute_values
# 定義需要同步的 attribute 欄位及對應的 Oracle 欄位
attributes_config = [
{ title_zh_tw: "單位", key: "1", value: teacher["dept"] },
{ title_zh_tw: "職稱", key: "2", value: teacher["job_title"] },
@ -703,7 +833,7 @@ module NfuSyncPlugin
{ title_zh_tw: "學歷", key: "4", value: teacher["education"] },
{ title_zh_tw: "學術專長及研究", key: "5", value: teacher["research"] }
]
attributes_config.each do |config|
sync_teacher_attribute(member, config)
end
@ -711,12 +841,20 @@ module NfuSyncPlugin
def sync_dissertations(query_result, member)
puts "Dissertations for user: #{member.email}"
if query_result["_api_status"]["dissertation"]
new_ukeys = query_result["dissertation"].map { |dis| dis["ukey"] }
ThesisGuidancePaper.where(member_profile_id: [member.id]).each do |dis|
dis.delete if dis.rss2_id.present? && !new_ukeys.include?(dis.rss2_id)
end
end
query_result["dissertation"].to_a.each do |dis|
old_uid = ThesisGuidancePaper.where(:rss2_id => dis["ukey"]).first&.uid
paper = ThesisGuidancePaper.where(:rss2_id => dis["ukey"]).first
paper.delete if paper
paper = ThesisGuidancePaper.new
paper.rss2_id = dis["ukey"]
paper.uid = old_uid
@ -735,13 +873,11 @@ module NfuSyncPlugin
private
def sync_teacher_attribute(member, config)
# 比對或建立 attribute_field
teacher_role = Role.where(:'title.en' => /teacher/i).first
return unless teacher_role
role_id = teacher_role.id
teacher_role = Role.where(:'title.en' => /teacher/i).first
return unless teacher_role
role_id = teacher_role.id
attribute_field = AttributeField.where(:role_id => role_id, 'title.zh_tw' => config[:title_zh_tw]).first
unless attribute_field
# 自動建立 attribute_field
attribute_field = AttributeField.new
attribute_field.role_id = role_id
attribute_field.title_translations = localize_data(config[:title_zh_tw])
@ -753,26 +889,24 @@ module NfuSyncPlugin
attribute_field.save
puts "Created new AttributeField: #{config[:title_zh_tw]}"
end
# 更新或建立 attribute_value
attribute_value = AttributeValue.where(:attribute_field_id => attribute_field.id, :member_profile_id => member.id).first
if attribute_value
attribute_value.delete
end
attribute_value = AttributeValue.new
attribute_value.attribute_field_id = attribute_field.id
attribute_value.member_profile_id = member.id
attribute_value.key = config[:key]
# 設定多語言欄位
if config[:value].present?
attribute_value_translations = localize_data(config[:value])
attribute_value.en = attribute_value_translations[:en]
attribute_value.zh_tw = attribute_value_translations[:zh_tw]
end
if attribute_value.save
puts "AttributeValue saved for #{config[:title_zh_tw]}"
end
@ -792,7 +926,7 @@ namespace :sync_nfu_personal_plugins do
Timeout.timeout(3) { api_running = Net::HTTP.get_response(URI(api_url)).is_a?(Net::HTTPSuccess) }
rescue
end
unless api_running
puts "🚀 啟動 NFU Oracle API 伺服器..."
api_dir = File.expand_path('../../sync_nfu_personal_data/api', __FILE__)
@ -834,4 +968,3 @@ namespace :sync_nfu_personal_plugins do
puts "✅ 同步完成!"
end
end