200 行
10 KiB
Python

"""Import products, versions, guides, customize, courses, selector, winter-camp, seasonal data."""
import json, os, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
DATA_DIR = '/opt/gw/hulai-website/data'
def load(name):
path = os.path.join(DATA_DIR, name)
if os.path.exists(path):
with open(path, 'r', encoding='utf-8') as f:
return json.load(f)
return None
from app.database import SessionLocal
db = SessionLocal()
# === PRODUCTS ===
from app.models.product import ProductConfig, ProductVersion, ProductVersionHighlight, SummerCamp, SummerCampPrinciple, SummerCampActivity, SummerCampItinerary, SummerCampFaq, SelectionGuide
d = load('products.json')
if d and not db.query(ProductConfig).first():
cfg = ProductConfig(narrative=d.get('narrative',''), pricing_philosophy=d.get('pricingPhilosophy'))
db.add(cfg)
db.flush()
for i, v in enumerate(d.get('versions', [])):
ver = ProductVersion(config_id=cfg.id, version_id=v['id'], name=v['name'],
days=v.get('days'), nights=v.get('nights'), audience=v.get('audience',''),
description=v.get('description',''), tag=v.get('tag',''), sort_order=i)
db.add(ver)
db.flush()
for h in v.get('highlights', []):
db.add(ProductVersionHighlight(version_id=ver.id, text=h))
# Summer camp
sc = d.get('summerCamp')
if sc:
camp = SummerCamp(config_id=cfg.id, name=sc.get('name',''), positioning=sc.get('positioning',''),
days=sc.get('days',0), nights=sc.get('nights',0),
sessions_json=sc.get('sessions',{}), difference_from_v9=sc.get('differenceFromV9',''))
db.add(camp)
db.flush()
for p in sc.get('principles', []):
db.add(SummerCampPrinciple(camp_id=camp.id, text=p))
for a in sc.get('coreActivities', []):
db.add(SummerCampActivity(camp_id=camp.id, text=a))
for it in sc.get('itinerary', []):
db.add(SummerCampItinerary(camp_id=camp.id, text=it))
for f in sc.get('faq', []):
db.add(SummerCampFaq(camp_id=camp.id, question=f['question'], answer=f['answer']))
# Selection guide
sg = d.get('selectionGuide')
if sg:
db.add(SelectionGuide(config_id=cfg.id,
by_vacation_length=sg.get('byVacationLength',[]),
by_child_age=sg.get('byChildAge',[]),
by_preference=sg.get('byPreference',[])))
print('products imported')
# === VERSIONS ===
from app.models.version import VersionConfig, VersionUpgrade, VersionHighlight, VersionCompare, VersionTimeline, VersionTimelineChange, VersionPhilosophy
d = load('versions.json')
if d and not db.query(VersionConfig).first():
stats = d.get('stats', {})
quote = d.get('quote', {})
cfg = VersionConfig(stats_iterations=stats.get('iterations',''), stats_years=stats.get('years',''),
stats_guests=stats.get('guests',''), quote_text=quote.get('text',''), quote_author=quote.get('author',''))
db.add(cfg)
db.flush()
for i, u in enumerate(d.get('upgrades2026', [])):
db.add(VersionUpgrade(config_id=cfg.id, tag=u.get('tag',''), name=u.get('name',''),
description=u.get('description',''), reason=u.get('reason',''), sort_order=i))
for i, h in enumerate(d.get('highlights', [])):
db.add(VersionHighlight(config_id=cfg.id, label=h.get('label',''), text=h.get('text',''), sort_order=i))
cmp = d.get('compareV8V9')
if cmp:
db.add(VersionCompare(config_id=cfg.id, headers=cmp.get('headers',[]), rows=cmp.get('rows',[])))
for i, t in enumerate(d.get('timeline', [])):
tl = VersionTimeline(config_id=cfg.id, version=t.get('version',''), date=t.get('date',''),
title=t.get('title',''), reason=t.get('reason',''), sort_order=i)
db.add(tl)
db.flush()
for c in t.get('changes', []):
db.add(VersionTimelineChange(timeline_id=tl.id, type=c.get('type',''), text=c.get('text','')))
for i, p in enumerate(d.get('philosophy', [])):
db.add(VersionPhilosophy(config_id=cfg.id, label=p.get('label',''), text=p.get('text',''), sort_order=i))
print('versions imported')
# === GUIDES ===
from app.models.guide import GuideConfig, GuideSection
d = load('guides.json')
if d and not db.query(GuideConfig).first():
cfg = GuideConfig(page_intro=d.get('pageIntro',''))
db.add(cfg)
db.flush()
for i, s in enumerate(d.get('sections', [])):
extra = {k: v for k, v in s.items() if k not in ('id','title','subtitle','icon','content')}
db.add(GuideSection(config_id=cfg.id, section_id=s['id'], title=s.get('title',''),
subtitle=s.get('subtitle',''), icon=s.get('icon',''), content=s.get('content',''),
data=extra if extra else None, sort_order=i))
print('guides imported')
# === CUSTOMIZE CONFIG ===
from app.models.customize_config import CustomizeConfig
d = load('customize.json')
if d and not db.query(CustomizeConfig).first():
db.add(CustomizeConfig(trust_stats=d.get('trustStats',[]), durations=d.get('durations',[]),
activities=d.get('activities',[]), budgets=d.get('budgets',[]),
process=d.get('process',[]), contact=d.get('contact',{})))
print('customize imported')
# === COURSES ===
from app.models.courses import CoursesConfig
d = load('courses.json')
if d and not db.query(CoursesConfig).first():
db.add(CoursesConfig(modules=d.get('modules',[]), age_groups=d.get('ageGroups',[]), faqs=d.get('faq',[])))
print('courses imported')
# === SELECTOR ===
from app.models.selector import SelectorConfig
d = load('selector.json')
if d and not db.query(SelectorConfig).first():
rules = {}
if d.get('scoring'): rules['scoring'] = d['scoring']
if d.get('matchReasons'): rules['matchReasons'] = d['matchReasons']
db.add(SelectorConfig(questions=d.get('questions',[]), rules=rules))
print('selector imported')
# === WINTER CAMP ===
from app.models.winter_camp import WinterCampConfig, WinterCampHotel, WinterCampItinerary, WinterCampFaq
d = load('winter-camp.json')
if d and not db.query(WinterCampConfig).first():
cfg = WinterCampConfig(name=d.get('name',''), positioning=d.get('positioning',''),
days=d.get('days',0), nights=d.get('nights',0), max_families=d.get('maxFamilies',0),
total_sessions=d.get('totalSessions',0), age_range=d.get('ageRange',''),
deposit=d.get('deposit',''), season=d.get('season',''), route=d.get('route',''),
why_hulunbuir=d.get('whyHulunbuir',''), closing_note=d.get('closingNote',''),
photographer=d.get('photographer',{}), winter_clothing=d.get('winterClothing',{}),
camp_advantages=d.get('campAdvantages',[]), service_config=d.get('serviceConfig',[]),
camp_essentials=d.get('campEssentials',[]))
db.add(cfg)
db.flush()
for i, h in enumerate(d.get('hotels', [])):
db.add(WinterCampHotel(name=h['name'], star=h.get('star',''), nights=h.get('nights',0),
description=h.get('description',''), sort_order=i))
for i, day in enumerate(d.get('itinerary', [])):
db.add(WinterCampItinerary(day=day.get('day',i+1), title=day.get('title',''),
summary=day.get('summary',''), highlights=day.get('highlights',[]),
hotel=day.get('hotel',''), sort_order=i))
for i, f in enumerate(d.get('faq', [])):
db.add(WinterCampFaq(question=f.get('q',''), answer=f.get('a',''), sort_order=i))
print('winter-camp imported')
# === SEASONAL PRODUCTS (autumn + winter) ===
from app.models.seasonal_product import SeasonalProductConfig, SeasonalProductVersion, SeasonalProductHighlight, SeasonalProductTimeline
for season, filename in [('autumn', 'autumn-products.json'), ('winter', 'winter-products.json')]:
d = load(filename)
if d and not db.query(SeasonalProductConfig).filter_by(season=season).first():
cfg = SeasonalProductConfig(season=season, brand_name=d.get('brand',''),
version_label=d.get('version',''), season_label=d.get('season',''),
narrative=d.get('narrative',''), style=d.get('style',''),
selection_guide=d.get('selectionGuide'))
db.add(cfg)
db.flush()
for i, v in enumerate(d.get('versions', [])):
db.add(SeasonalProductVersion(season=season, version_id=v['id'], name=v['name'],
days=v.get('days'), nights=v.get('nights'), tag=v.get('tag',''),
line=v.get('line',''), route=v.get('route',''), audience=v.get('audience',''),
description=v.get('description',''), highlights=v.get('highlights',[]),
itinerary=v.get('itinerary',[]), sort_order=i))
for cat_key, cat_name in [('highlights','shared'), ('southHighlights','south'), ('northHighlights','north')]:
for i, h in enumerate(d.get(cat_key, [])):
db.add(SeasonalProductHighlight(season=season, category=cat_name,
title=h.get('title',''), description=h.get('description',''), sort_order=i))
for i, t in enumerate(d.get('timeline', [])):
db.add(SeasonalProductTimeline(season=season, version=t.get('version',''),
date=t.get('date',''), title=t.get('title',''),
changes=t.get('changes',[]), reason=t.get('reason',''), sort_order=i))
print(f'{season}-products imported')
# === CALENDAR ===
from app.models.calendar import CalendarMonth
d = load('calendar.json')
if d and not db.query(CalendarMonth).first():
months = d.get('months', d) if isinstance(d, dict) else d
if isinstance(months, list):
for m in months:
db.add(CalendarMonth(year=m.get('year',2026), month=m.get('month',1),
title=m.get('title',''), weather=m.get('weather',''),
clothing=m.get('clothing',''), events=m.get('events',[])))
print('calendar imported')
elif isinstance(months, dict) and 'months' in months:
for m in months['months']:
db.add(CalendarMonth(year=m.get('year',2026), month=m.get('month',1),
title=m.get('title',''), weather=m.get('weather',''),
clothing=m.get('clothing',''), events=m.get('events',[])))
print('calendar imported')
db.commit()
print('=== All product data imported ===')
db.close()