feat(client): add Chinese verbose_name and help_text to all client fields (Phase 4.1 part 2/9)
Sync DATA_MODEL_CLIENT.md field-level Chinese annotations to Django models across 11 client tables (Client, ClientContact, ClientRequirement, ClientSchoolPreference, ClientFavoriteFolder, ClientFolderItem, ClientFollowLog, ClientFollowLogAttachment, ClientViewing, ClientPropertyMatch, ClientStatusLog). Pre-existing docstrings retained on ClientFollowLog (partitioned parent treated as unmanaged) and ClientStatusLog (immutable audit log).
This commit is contained in:
@@ -14,15 +14,25 @@ from core.models.base import UUIDPrimaryKeyModel
|
||||
|
||||
class ClientViewing(UUIDPrimaryKeyModel):
|
||||
client = models.ForeignKey(
|
||||
"fonrey_client.Client", on_delete=models.RESTRICT, related_name="viewings"
|
||||
"fonrey_client.Client",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="viewings",
|
||||
verbose_name="所属客源",
|
||||
help_text="带看记录仅软删除,不随客源删除",
|
||||
)
|
||||
property = models.ForeignKey(
|
||||
"fonrey_property.Property",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="client_viewings",
|
||||
verbose_name="带看房源",
|
||||
help_text="房源删除时保留带看记录",
|
||||
)
|
||||
viewing_type = models.CharField(
|
||||
max_length=20, choices=ClientViewingType.choices, default=ClientViewingType.VIEWING
|
||||
max_length=20,
|
||||
choices=ClientViewingType.choices,
|
||||
default=ClientViewingType.VIEWING,
|
||||
verbose_name="带看类型",
|
||||
help_text="appointment=预约 / viewing=带看 / revisit=复看 / empty=空看",
|
||||
)
|
||||
|
||||
agent = models.ForeignKey(
|
||||
@@ -31,28 +41,77 @@ class ClientViewing(UUIDPrimaryKeyModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="led_viewings",
|
||||
verbose_name="主带看经纪人",
|
||||
)
|
||||
companion_ids = ArrayField(
|
||||
models.UUIDField(),
|
||||
blank=True,
|
||||
default=list,
|
||||
verbose_name="陪看人员",
|
||||
help_text="员工 ID 数组(最多5人)",
|
||||
)
|
||||
cooperator_ids = ArrayField(
|
||||
models.UUIDField(),
|
||||
blank=True,
|
||||
default=list,
|
||||
verbose_name="合作带看人",
|
||||
help_text="员工 ID 数组(最多5人)",
|
||||
)
|
||||
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)
|
||||
scheduled_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="预约时间",
|
||||
)
|
||||
viewing_start_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="实际带看开始时间",
|
||||
)
|
||||
viewing_end_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="带看结束时间",
|
||||
)
|
||||
|
||||
situation = models.TextField(blank=True, default="")
|
||||
situation = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="带看情况",
|
||||
help_text="必填,≥6字",
|
||||
)
|
||||
client_intent = models.CharField(
|
||||
max_length=20, choices=ClientViewingIntent.choices, blank=True, default=""
|
||||
max_length=20,
|
||||
choices=ClientViewingIntent.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="客户意向",
|
||||
help_text="interested=感兴趣 / not_interested=不感兴趣 / negotiating=谈判中 / cancelled=取消",
|
||||
)
|
||||
viewing_progress = models.SmallIntegerField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="带看进度",
|
||||
help_text="1=一看,2=二看…,冗余字段,触发器维护",
|
||||
)
|
||||
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_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="创建时间",
|
||||
)
|
||||
deleted_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="删除时间",
|
||||
help_text="软删除时间戳;带看记录可软删除",
|
||||
)
|
||||
created_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="created_client_viewings",
|
||||
verbose_name="创建人",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -70,41 +129,79 @@ class ClientViewing(UUIDPrimaryKeyModel):
|
||||
|
||||
class ClientPropertyMatch(UUIDPrimaryKeyModel):
|
||||
client = models.ForeignKey(
|
||||
"fonrey_client.Client", on_delete=models.CASCADE, related_name="property_matches"
|
||||
"fonrey_client.Client",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="property_matches",
|
||||
verbose_name="所属客源",
|
||||
)
|
||||
property = models.ForeignKey(
|
||||
"fonrey_property.Property",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="client_matches",
|
||||
verbose_name="匹配房源",
|
||||
)
|
||||
|
||||
match_source = models.CharField(
|
||||
max_length=20,
|
||||
choices=ClientPropertyMatchSource.choices,
|
||||
default=ClientPropertyMatchSource.RECORDED,
|
||||
verbose_name="匹配来源",
|
||||
help_text="recorded=录客配房(基于录入需求) / system=系统配房(算法推荐)",
|
||||
)
|
||||
match_group = models.CharField(
|
||||
max_length=30, choices=ClientPropertyMatchGroup.choices, blank=True, default=""
|
||||
max_length=30,
|
||||
choices=ClientPropertyMatchGroup.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="匹配分组",
|
||||
help_text="quality_layout=优质户型 / price_reduced=降价 / hot=热门 / newly_listed=新上",
|
||||
)
|
||||
match_score = models.DecimalField(
|
||||
max_digits=5, decimal_places=2, null=True, blank=True
|
||||
max_digits=5,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="匹配度评分",
|
||||
help_text="0-100",
|
||||
)
|
||||
match_reasons = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="匹配原因详情",
|
||||
help_text='格式:[{"key": "budget", "match": true}, ...]',
|
||||
)
|
||||
match_reasons = models.JSONField(null=True, blank=True)
|
||||
|
||||
status = models.CharField(
|
||||
max_length=20,
|
||||
choices=ClientPropertyMatchStatus.choices,
|
||||
default=ClientPropertyMatchStatus.SUGGESTED,
|
||||
verbose_name="状态",
|
||||
help_text="suggested=待推送 / shared=已分享 / rejected=已反馈不合适 / viewed=客户已查看",
|
||||
)
|
||||
shared_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="分享时间",
|
||||
)
|
||||
feedback = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="反馈原因",
|
||||
help_text="lookup_items 维护",
|
||||
)
|
||||
calculated_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="配房计算时间",
|
||||
)
|
||||
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",
|
||||
verbose_name="创建人",
|
||||
help_text="触发配房操作的员工(录客配房时记录,系统配房可为NULL)",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -128,20 +225,51 @@ class ClientPropertyMatch(UUIDPrimaryKeyModel):
|
||||
class ClientStatusLog(models.Model):
|
||||
"""Audit log; record-level immutable (no deleted_at)."""
|
||||
|
||||
id = models.UUIDField(primary_key=True)
|
||||
id = models.UUIDField(
|
||||
primary_key=True,
|
||||
verbose_name="主键",
|
||||
)
|
||||
client = models.ForeignKey(
|
||||
"fonrey_client.Client", on_delete=models.RESTRICT, related_name="status_logs"
|
||||
"fonrey_client.Client",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="status_logs",
|
||||
verbose_name="所属客源",
|
||||
help_text="状态日志永久保留,RESTRICT 防止删除客源",
|
||||
)
|
||||
change_type = models.CharField(
|
||||
max_length=30, choices=ClientStatusLogChangeType.choices
|
||||
max_length=30,
|
||||
choices=ClientStatusLogChangeType.choices,
|
||||
verbose_name="变更类型",
|
||||
help_text="status_change=改状态 / grade_change=改等级 / to_public=转公客 / to_transacted=转成交 / to_invalid=转无效 / owner_change=改归属人 / source_change=改来源",
|
||||
)
|
||||
old_value = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="变更前快照",
|
||||
help_text='格式:{"status": "buying", "label": "求购"}',
|
||||
)
|
||||
new_value = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="变更后快照",
|
||||
)
|
||||
reason = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="变更理由",
|
||||
help_text="改状态必填,最多200字",
|
||||
)
|
||||
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"
|
||||
"org.Staff",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="client_status_changes",
|
||||
verbose_name="操作人",
|
||||
help_text="必填,状态变更审计用",
|
||||
)
|
||||
operated_at = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="操作时间",
|
||||
)
|
||||
operated_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "client_status_logs"
|
||||
|
||||
Reference in New Issue
Block a user