Files
fonrey/apps/client/models/viewing_match.py
ishenwei 79c3cf2924 feat(models): add Chinese verbose_name to all 74 models (Phase 4.0)
为所有 Django 模型添加 Meta.verbose_name 和 verbose_name_plural(中文表名),
覆盖 10 个 app 的全部 74 个业务模型。

Phase 4.0 范围:
- 仅 Meta 类级别中文名(用于 Django Admin、drf-spectacular OpenAPI title、错误信息)
- 字段级 verbose_name= 和 help_text= 留待 Phase 4.1(待 PM 补全 DATA_MODEL 后同步)

变更:
- 20 个 models 文件改动(每个模型 +2 行)
- 8 个 0002/0003 迁移文件(Meta options 变更)
- apps/tenant/migrations/0001_initial.py(之前漏生成的 tenant 模型迁移)

manage.py check: 0 issues。
2026-04-29 19:10:38 +08:00

154 lines
5.1 KiB
Python

from django.contrib.postgres.fields import ArrayField
from django.db import models
from core.enums import (
ClientPropertyMatchGroup,
ClientPropertyMatchSource,
ClientPropertyMatchStatus,
ClientStatusLogChangeType,
ClientViewingIntent,
ClientViewingType,
)
from core.models.base import UUIDPrimaryKeyModel
class ClientViewing(UUIDPrimaryKeyModel):
client = models.ForeignKey(
"fonrey_client.Client", on_delete=models.RESTRICT, related_name="viewings"
)
property = models.ForeignKey(
"fonrey_property.Property",
on_delete=models.RESTRICT,
related_name="client_viewings",
)
viewing_type = models.CharField(
max_length=20, choices=ClientViewingType.choices, default=ClientViewingType.VIEWING
)
agent = models.ForeignKey(
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="led_viewings",
)
companion_ids = ArrayField(models.UUIDField(), blank=True, default=list)
cooperator_ids = ArrayField(models.UUIDField(), blank=True, default=list)
scheduled_at = models.DateTimeField(null=True, blank=True)
viewing_start_at = models.DateTimeField(null=True, blank=True)
viewing_end_at = models.DateTimeField(null=True, blank=True)
situation = models.TextField(blank=True, default="")
client_intent = models.CharField(
max_length=20, choices=ClientViewingIntent.choices, blank=True, default=""
)
viewing_progress = models.SmallIntegerField(null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
deleted_at = models.DateTimeField(null=True, blank=True)
created_by = models.ForeignKey(
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="created_client_viewings",
)
class Meta:
db_table = "client_viewings"
verbose_name = "带看记录"
verbose_name_plural = "带看记录"
indexes = [
models.Index(
fields=["client", "-viewing_start_at"], name="idx_cv_client_time"
),
models.Index(fields=["property"], name="idx_cv_property"),
models.Index(fields=["agent"], name="idx_cv_agent"),
]
class ClientPropertyMatch(UUIDPrimaryKeyModel):
client = models.ForeignKey(
"fonrey_client.Client", on_delete=models.CASCADE, related_name="property_matches"
)
property = models.ForeignKey(
"fonrey_property.Property",
on_delete=models.CASCADE,
related_name="client_matches",
)
match_source = models.CharField(
max_length=20,
choices=ClientPropertyMatchSource.choices,
default=ClientPropertyMatchSource.RECORDED,
)
match_group = models.CharField(
max_length=30, choices=ClientPropertyMatchGroup.choices, blank=True, default=""
)
match_score = models.DecimalField(
max_digits=5, decimal_places=2, null=True, blank=True
)
match_reasons = models.JSONField(null=True, blank=True)
status = models.CharField(
max_length=20,
choices=ClientPropertyMatchStatus.choices,
default=ClientPropertyMatchStatus.SUGGESTED,
)
shared_at = models.DateTimeField(null=True, blank=True)
feedback = models.CharField(max_length=50, blank=True, default="")
calculated_at = models.DateTimeField(auto_now_add=True)
created_by = models.ForeignKey(
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="created_matches",
)
class Meta:
db_table = "client_property_matches"
verbose_name = "智能配房"
verbose_name_plural = "智能配房"
constraints = [
models.UniqueConstraint(
fields=["client", "property"], name="uq_client_match_pair"
),
]
indexes = [
models.Index(
fields=["client", "match_source", "match_group"],
name="idx_cpm_client_grp",
),
models.Index(fields=["client", "status"], name="idx_cpm_status"),
]
class ClientStatusLog(models.Model):
"""Audit log; record-level immutable (no deleted_at)."""
id = models.UUIDField(primary_key=True)
client = models.ForeignKey(
"fonrey_client.Client", on_delete=models.RESTRICT, related_name="status_logs"
)
change_type = models.CharField(
max_length=30, choices=ClientStatusLogChangeType.choices
)
old_value = models.JSONField(null=True, blank=True)
new_value = models.JSONField(null=True, blank=True)
reason = models.TextField(blank=True, default="")
operator = models.ForeignKey(
"org.Staff", on_delete=models.RESTRICT, related_name="client_status_changes"
)
operated_at = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = "client_status_logs"
verbose_name = "客源状态变更日志"
verbose_name_plural = "客源状态变更日志"
indexes = [
models.Index(fields=["client", "-operated_at"], name="idx_csl_client"),
models.Index(fields=["change_type", "-operated_at"], name="idx_csl_type"),
]