from sqlalchemy import Column, Integer, String, Float, Boolean, DateTime, ForeignKey, Text, JSON, BigInteger from sqlalchemy.sql import func from app.core.database import Base class ChargingStation(Base): __tablename__ = "charging_stations" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(200), nullable=False) merchant_id = Column(Integer, ForeignKey("charging_merchants.id")) type = Column(String(50)) # public, private, dedicated address = Column(String(500)) latitude = Column(Float) longitude = Column(Float) price = Column(Float) # default price yuan/kWh activity = Column(Text) # promotions text status = Column(String(20), default="active") # active, disabled total_piles = Column(Integer, default=0) available_piles = Column(Integer, default=0) total_power_kw = Column(Float, default=0) photo_url = Column(String(500)) operating_hours = Column(String(100)) # e.g. "00:00-24:00" created_by = Column(Integer, ForeignKey("users.id")) created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) class ChargingPile(Base): __tablename__ = "charging_piles" id = Column(Integer, primary_key=True, autoincrement=True) station_id = Column(Integer, ForeignKey("charging_stations.id"), nullable=False) encoding = Column(String(100), unique=True) # terminal code name = Column(String(200)) type = Column(String(50)) # AC_slow, DC_fast, DC_superfast brand = Column(String(100)) model = Column(String(100)) rated_power_kw = Column(Float) connector_type = Column(String(50)) # GB_T, CCS, CHAdeMO status = Column(String(20), default="active") # active, disabled work_status = Column(String(20), default="offline") # idle, charging, fault, offline created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) class ChargingPriceStrategy(Base): __tablename__ = "charging_price_strategies" id = Column(Integer, primary_key=True, autoincrement=True) strategy_name = Column(String(200), nullable=False) station_id = Column(Integer, ForeignKey("charging_stations.id")) bill_model = Column(String(20)) # tou, flat description = Column(Text) status = Column(String(20), default="inactive") # active, inactive created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now()) class ChargingPriceParam(Base): __tablename__ = "charging_price_params" id = Column(Integer, primary_key=True, autoincrement=True) strategy_id = Column(Integer, ForeignKey("charging_price_strategies.id"), nullable=False) start_time = Column(String(10), nullable=False) # HH:MM end_time = Column(String(10), nullable=False) period_mark = Column(String(20)) # sharp, peak, flat, valley elec_price = Column(Float, nullable=False) # yuan/kWh service_price = Column(Float, default=0) # yuan/kWh created_at = Column(DateTime(timezone=True), server_default=func.now()) class ChargingOrder(Base): __tablename__ = "charging_orders" id = Column(Integer, primary_key=True, autoincrement=True) order_no = Column(String(50), unique=True, nullable=False) user_id = Column(Integer) user_name = Column(String(100)) phone = Column(String(20)) station_id = Column(Integer, ForeignKey("charging_stations.id")) station_name = Column(String(200)) pile_id = Column(Integer, ForeignKey("charging_piles.id")) pile_name = Column(String(200)) start_time = Column(DateTime(timezone=True)) end_time = Column(DateTime(timezone=True)) car_no = Column(String(20)) # license plate car_vin = Column(String(50)) charge_method = Column(String(20)) # plug_and_charge, app, card settle_type = Column(String(20)) # normal, manual, delayed, abnormal, offline pay_type = Column(String(20)) # balance, wechat, alipay settle_time = Column(DateTime(timezone=True)) settle_price = Column(Float) # settlement amount paid_price = Column(Float) # actual paid discount_amt = Column(Float, default=0) elec_amt = Column(Float) # electricity fee serve_amt = Column(Float) # service fee order_status = Column(String(20), default="charging") # charging, pending_pay, completed, failed, refunded charge_duration = Column(Integer) # seconds energy = Column(Float) # kWh delivered start_soc = Column(Float) # battery start % end_soc = Column(Float) # battery end % abno_cause = Column(Text) # abnormal reason order_source = Column(String(20)) # miniprogram, pc, app created_at = Column(DateTime(timezone=True), server_default=func.now()) class OccupancyOrder(Base): __tablename__ = "occupancy_orders" id = Column(Integer, primary_key=True, autoincrement=True) order_id = Column(Integer, ForeignKey("charging_orders.id")) pile_id = Column(Integer, ForeignKey("charging_piles.id")) start_time = Column(DateTime(timezone=True)) end_time = Column(DateTime(timezone=True)) occupancy_fee = Column(Float, default=0) status = Column(String(20), default="active") created_at = Column(DateTime(timezone=True), server_default=func.now()) class ChargingBrand(Base): __tablename__ = "charging_brands" id = Column(Integer, primary_key=True, autoincrement=True) brand_name = Column(String(100), nullable=False) logo_url = Column(String(500)) country = Column(String(50)) description = Column(Text) created_at = Column(DateTime(timezone=True), server_default=func.now()) class ChargingMerchant(Base): __tablename__ = "charging_merchants" id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(200), nullable=False) contact_person = Column(String(100)) phone = Column(String(20)) email = Column(String(100)) address = Column(String(500)) business_license = Column(String(100)) status = Column(String(20), default="active") settlement_type = Column(String(20)) # prepaid, postpaid created_at = Column(DateTime(timezone=True), server_default=func.now()) updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now())