from django.db import models from core.enums import ( PropertyAttachmentCategory, PropertyFieldSurveyStatus, PropertyPhotoCategory, PropertySurveyPhotoCategory, ) from core.models.base import UUIDPrimaryKeyModel class FieldSurvey(UUIDPrimaryKeyModel): property = models.ForeignKey( "fonrey_property.Property", on_delete=models.CASCADE, related_name="field_surveys" ) status = models.CharField( max_length=10, choices=PropertyFieldSurveyStatus.choices, default=PropertyFieldSurveyStatus.DRAFT, ) gps_latitude = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True) gps_longitude = models.DecimalField(max_digits=10, decimal_places=7, null=True, blank=True) gps_accuracy = models.DecimalField(max_digits=6, decimal_places=2, null=True, blank=True) description = models.TextField(blank=True, default="") submitted_at = models.DateTimeField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) created_by = models.ForeignKey("org.Staff", on_delete=models.RESTRICT) class Meta: db_table = "field_surveys" verbose_name = "实勘记录" verbose_name_plural = "实勘记录" indexes = [ models.Index(fields=["property"], name="idx_fs_property"), models.Index(fields=["property", "status"], name="idx_fs_submitted"), ] class SurveyPhoto(UUIDPrimaryKeyModel): survey = models.ForeignKey(FieldSurvey, on_delete=models.CASCADE, related_name="photos") category = models.CharField(max_length=20, choices=PropertySurveyPhotoCategory.choices) file_key = models.TextField() thumbnail_key = models.TextField(blank=True, default="") file_size = models.IntegerField(null=True, blank=True) width = models.IntegerField(null=True, blank=True) height = models.IntegerField(null=True, blank=True) sort_order = models.SmallIntegerField(default=0) is_vr_screenshot = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "survey_photos" verbose_name = "实勘照片" verbose_name_plural = "实勘照片" indexes = [ models.Index(fields=["survey"], name="idx_sp_survey"), models.Index(fields=["survey", "category"], name="idx_sp_category"), ] class PropertyPhoto(models.Model): """Partitioned table (PARTITION BY RANGE created_at). Managed via RunSQL; Django ORM treats parent as unmanaged. """ id = models.UUIDField(primary_key=True) created_at = models.DateTimeField() property = models.ForeignKey( "fonrey_property.Property", on_delete=models.CASCADE, related_name="photos" ) category = models.CharField(max_length=20, choices=PropertyPhotoCategory.choices) file_key = models.TextField() thumbnail_key = models.TextField(blank=True, default="") file_name = models.CharField(max_length=255, blank=True, default="") file_size = models.IntegerField(null=True, blank=True) width = models.IntegerField(null=True, blank=True) height = models.IntegerField(null=True, blank=True) is_cover = models.BooleanField(default=False) sort_order = models.SmallIntegerField(default=0) updated_at = models.DateTimeField(auto_now=True) created_by = models.ForeignKey( "org.Staff", null=True, blank=True, on_delete=models.SET_NULL ) class Meta: db_table = "property_photos" verbose_name = "房源图片" verbose_name_plural = "房源图片" managed = False unique_together = (("id", "created_at"),) class PropertyAttachment(UUIDPrimaryKeyModel): property = models.ForeignKey( "fonrey_property.Property", on_delete=models.CASCADE, related_name="attachments" ) category = models.CharField( max_length=20, choices=PropertyAttachmentCategory.choices, default=PropertyAttachmentCategory.OTHER, ) file_key = models.TextField() file_name = models.CharField(max_length=255) file_size = models.IntegerField() file_type = models.CharField(max_length=50, blank=True, default="") sort_order = models.SmallIntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) created_by = models.ForeignKey( "org.Staff", null=True, blank=True, on_delete=models.SET_NULL ) class Meta: db_table = "property_attachments" verbose_name = "房源附件" verbose_name_plural = "房源附件" indexes = [ models.Index(fields=["property"], name="idx_pa_property"), models.Index(fields=["property", "category"], name="idx_pa_category"), ] class PropertyTag(UUIDPrimaryKeyModel): name = models.CharField(max_length=50) color = models.CharField(max_length=7, blank=True, default="") is_system = models.BooleanField(default=False) sort_order = models.IntegerField(default=0) is_active = models.BooleanField(default=True) class Meta: db_table = "property_tags" verbose_name = "房源标签" verbose_name_plural = "房源标签" class PropertyTagRelation(models.Model): property = models.ForeignKey( "fonrey_property.Property", on_delete=models.CASCADE, related_name="tag_relations" ) tag = models.ForeignKey( PropertyTag, on_delete=models.CASCADE, related_name="property_relations" ) class Meta: db_table = "property_tag_relations" verbose_name = "房源标签关联" verbose_name_plural = "房源标签关联" constraints = [ models.UniqueConstraint(fields=["property", "tag"], name="uq_ptr_property_tag"), ] indexes = [ models.Index(fields=["property"], name="idx_ptr_property"), models.Index(fields=["tag"], name="idx_ptr_tag"), ] class PropertyFavorite(models.Model): staff = models.ForeignKey( "org.Staff", on_delete=models.CASCADE, related_name="favorite_properties" ) property = models.ForeignKey( "fonrey_property.Property", on_delete=models.CASCADE, related_name="favorited_by" ) created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = "property_favorites" verbose_name = "房源收藏" verbose_name_plural = "房源收藏" constraints = [ models.UniqueConstraint(fields=["staff", "property"], name="uq_pfav_staff_property"), ] indexes = [models.Index(fields=["staff"], name="idx_pfav_staff")]