ymt-python / main.py
hsailorj's picture
first commit
5c86d0a
Raw
History Blame Contribute Delete
7.68 kB
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from routers import auth, company, categories, products, product_certifications, product_media, product_packaging, membership, operation_log, contact, template, customer_relationship, member_level, r2_config, media, statistics
from database import engine, Base, get_db
from sqlalchemy.orm import Session
import json
import os
from pathlib import Path
from dotenv import load_dotenv
from datetime import datetime, timedelta
# 导入中间件
from middleware.trace import TraceMiddleware
# 导入日志模块
from utils.logger import logger
# 加载 .env 文件
load_dotenv()
# 导入模板配置
from config.templates import DEFAULT_TEMPLATES
# 导入会员等级配置
from config.member_levels import DEFAULT_MEMBER_LEVELS
# 导入默认公司和用户配置
from config.default_companies import DEFAULT_COMPANIES, DEFAULT_USERS
# 导入所有模型,确保它们被注册到Base
from models.user import User
from models.company import Company
from models.category import Category
from models.product import Product
from models.membership import Membership
from models.operation_log import OperationLog
from models.contact import Contact
from models.template import Template
from models.customer_relationship import CustomerRelationship
from models.member_level import MemberLevel
from models.company_r2_config import CompanyR2Config
from models.media import Media, MediaTag, MediaTagMapping, MediaDirectory
from models.site_visit import SiteVisit
from utils.auth import get_password_hash
# 数据库表创建已在database.py中处理
app = FastAPI(
title="外贸独立站 API",
description="用于外贸独立站的后端 API",
version="1.0.0"
)
# 配置 CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 在生产环境中应该设置具体的前端域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 添加 TraceMiddleware 中间件
app.add_middleware(TraceMiddleware)
# 挂载静态文件目录(用于访问上传的图片)
BASE_DIR = Path(__file__).parent
IMAGES_DIR = BASE_DIR / "images"
if IMAGES_DIR.exists():
app.mount("/images", StaticFiles(directory=str(IMAGES_DIR)), name="images")
# 注册路由
# 注意:更具体的路由(如 /{product_number}/media)必须在较不具体的路由(如 /{product_number})之前注册
app.include_router(auth.router, prefix="/api/auth", tags=["认证"])
app.include_router(product_media.router, prefix="/api/products", tags=["产品媒体"])
app.include_router(product_certifications.router, prefix="/api/products", tags=["产品认证"])
app.include_router(product_packaging.router, prefix="/api/products", tags=["产品包装"])
app.include_router(products.router, prefix="/api/products", tags=["产品"])
app.include_router(company.router, prefix="/api/company", tags=["公司信息"])
app.include_router(categories.router, prefix="/api/categories", tags=["类目"])
app.include_router(membership.router, prefix="/api/membership", tags=["会员充值"])
app.include_router(operation_log.router, prefix="/api/operation-logs", tags=["操作日志"])
app.include_router(contact.router, prefix="/api/contact", tags=["联系信息管理"])
app.include_router(template.router, prefix="/api/templates", tags=["模板管理"])
app.include_router(customer_relationship.router, prefix="/api/customer-relationships", tags=["客户关系管理"])
app.include_router(member_level.router, prefix="/api/member-levels", tags=["会员等级管理"])
app.include_router(r2_config.router, prefix="/api/r2-config", tags=["R2 配置管理"])
app.include_router(media.router, prefix="/api/media", tags=["媒体素材管理"])
app.include_router(statistics.router, prefix="/api/statistics", tags=["统计指标"])
# 初始化超级管理员用户和默认类目
@app.on_event("startup")
def startup_event():
try:
db = next(get_db())
# 检查是否已有超级管理员
superadmin = db.query(User).filter(User.is_superadmin == True).first()
if not superadmin:
# 创建超级管理员
superadmin = User(
username="admin",
email="admin@mail.yomaton.com",
password=get_password_hash("admin00"),
is_superadmin=True,
company_code="0000"
)
db.add(superadmin)
db.commit()
logger.info("超级管理员已创建: username=admin, password=admin00")
# 创建默认模板
for template_data in DEFAULT_TEMPLATES:
# 转换features和regions列表为JSON字符串
template_data["features"] = json.dumps(template_data["features"], ensure_ascii=False)
template_data["regions"] = json.dumps(template_data["regions"], ensure_ascii=False)
existing_template = db.query(Template).filter(Template.key == template_data["key"]).first()
if not existing_template:
new_template = Template(**template_data)
db.add(new_template)
db.commit()
logger.info("默认模板已创建")
# 创建默认会员等级
for level_data in DEFAULT_MEMBER_LEVELS:
existing_level = db.query(MemberLevel).filter(MemberLevel.level == level_data["level"]).first()
if not existing_level:
new_level = MemberLevel(**level_data)
db.add(new_level)
db.commit()
logger.info("默认会员等级已创建")
# 创建默认公司
for company_data in DEFAULT_COMPANIES:
existing_company = db.query(Company).filter(Company.company_code == company_data["company_code"]).first()
if not existing_company:
new_company = Company(**company_data)
db.add(new_company)
db.commit()
logger.info("默认公司已创建")
# 创建默认用户和会员信息
for user_data in DEFAULT_USERS:
existing_user = db.query(User).filter(User.username == user_data["username"]).first()
if not existing_user:
user_data_copy = user_data.copy()
user_data_copy["password"] = get_password_hash(user_data_copy["password"])
new_user = User(**user_data_copy)
db.add(new_user)
db.flush()
# 为用户创建默认会员信息
existing_membership = db.query(Membership).filter(Membership.company_code == user_data["company_code"]).first()
if not existing_membership:
new_membership = Membership(
company_code = user_data["company_code"],
level = 0, # 默认普通会员
start_date = datetime.now(),
end_date = datetime.now() + timedelta(days=365)
)
db.add(new_membership)
db.commit()
logger.info("默认用户和会员信息已创建")
except Exception as e:
logger.error(f"初始化数据时出错: {e}")
@app.get("/")
def read_root():
logger.info("访问根路径")
return {"message": "欢迎使用外贸独立站 API"}
@app.get("/health")
def health_check():
logger.info("健康检查")
return {"status": "healthy"}
if __name__ == "__main__":
import uvicorn
logger.info("启动应用服务器")
uvicorn.run(app, host="0.0.0.0", port=7860)