| from flask_sqlalchemy import SQLAlchemy |
| from datetime import datetime |
| import uuid |
|
|
| db = SQLAlchemy() |
|
|
| class TravelList(db.Model): |
| id = db.Column(db.Integer, primary_key=True) |
| code = db.Column(db.String(20), unique=True, nullable=False) |
| title = db.Column(db.String(200), nullable=False, default='我們的旅遊清單') |
| created_at = db.Column(db.DateTime, default=datetime.utcnow) |
| updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) |
| |
| |
| items = db.relationship('TravelItem', backref='travel_list', lazy=True, cascade='all, delete-orphan') |
|
|
| def __repr__(self): |
| return f'<TravelList {self.code}>' |
|
|
| def to_dict(self): |
| return { |
| 'id': self.id, |
| 'code': self.code, |
| 'title': self.title, |
| 'created_at': self.created_at.isoformat() if self.created_at else None, |
| 'updated_at': self.updated_at.isoformat() if self.updated_at else None, |
| 'items': [item.to_dict() for item in sorted(self.items, key=lambda x: (x.completed, x.order, x.created_at))] |
| } |
|
|
| @staticmethod |
| def generate_code(): |
| """生成唯一的6位代碼""" |
| return str(uuid.uuid4())[:8].upper() |
|
|
| class TravelItem(db.Model): |
| id = db.Column(db.Integer, primary_key=True) |
| travel_list_id = db.Column(db.Integer, db.ForeignKey('travel_list.id'), nullable=False) |
| content = db.Column(db.Text, nullable=False) |
| completed = db.Column(db.Boolean, default=False, nullable=False) |
| order = db.Column(db.Integer, default=0) |
| created_at = db.Column(db.DateTime, default=datetime.utcnow) |
| updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) |
| completed_at = db.Column(db.DateTime, nullable=True) |
|
|
| def __repr__(self): |
| return f'<TravelItem {self.content[:50]}>' |
|
|
| def to_dict(self): |
| return { |
| 'id': self.id, |
| 'travel_list_id': self.travel_list_id, |
| 'content': self.content, |
| 'completed': self.completed, |
| 'order': self.order, |
| 'created_at': self.created_at.isoformat() if self.created_at else None, |
| 'updated_at': self.updated_at.isoformat() if self.updated_at else None, |
| 'completed_at': self.completed_at.isoformat() if self.completed_at else None |
| } |
|
|
| def mark_completed(self): |
| """標記為已完成""" |
| self.completed = True |
| self.completed_at = datetime.utcnow() |
| self.updated_at = datetime.utcnow() |
|
|
| def mark_uncompleted(self): |
| """標記為未完成""" |
| self.completed = False |
| self.completed_at = None |
| self.updated_at = datetime.utcnow() |
|
|
|
|