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:
2026-04-30 09:19:58 +08:00
parent 3638fc0302
commit e67b07a7c8
5 changed files with 678 additions and 121 deletions

View File

@@ -10,29 +10,86 @@ class ClientFollowLog(models.Model):
Managed via RunSQL; Django ORM treats parent as unmanaged.
"""
id = models.UUIDField(primary_key=True)
created_at = models.DateTimeField()
id = models.UUIDField(
primary_key=True,
verbose_name="主键",
)
created_at = models.DateTimeField(
verbose_name="创建时间",
help_text="分区键",
)
client = models.ForeignKey(
"fonrey_client.Client",
on_delete=models.CASCADE,
related_name="follow_logs",
verbose_name="所属客源",
help_text="跟进日志随客源级联删除",
)
log_type = models.CharField(max_length=30, choices=ClientFollowLogType.choices)
purpose = models.CharField(max_length=50, blank=True, default="")
content = models.TextField(blank=True, default="")
log_tag = models.CharField(max_length=50, blank=True, default="")
change_detail = models.JSONField(null=True, blank=True)
log_type = models.CharField(
max_length=30,
choices=ClientFollowLogType.choices,
verbose_name="跟进类型",
help_text="written=写入跟进 / modified=修改跟进 / sensitive_view=敏感信息查看(不可删) / other=其他跟进 / system=系统日志",
)
purpose = models.CharField(
max_length=50,
blank=True,
default="",
verbose_name="跟进目的",
help_text="lookup_items 维护23项",
)
content = models.TextField(
blank=True,
default="",
verbose_name="跟进内容",
help_text="最少6字最多500字",
)
log_tag = models.CharField(
max_length=50,
blank=True,
default="",
verbose_name="跟进标签",
help_text="has_recording=有录音 / has_photo=有图片 / not_satisfied=对房源不满意 / still_considering=还在考虑 / ready_to_deposit=可交定金",
)
change_detail = models.JSONField(
null=True,
blank=True,
verbose_name="字段变更明细",
help_text='修改跟进专用,格式:{"field": "grade", "old": "C", "new": "B", "label": "等级"}',
)
is_public = models.BooleanField(default=True)
is_deletable = models.BooleanField(default=True)
is_public = models.BooleanField(
default=True,
verbose_name="是否公开",
help_text="FALSE=仅本人及上级可见",
)
is_deletable = models.BooleanField(
default=True,
verbose_name="是否可删除",
help_text="敏感信息查看类型为 FALSE不可删除",
)
operator = models.ForeignKey(
"org.Staff", null=True, blank=True, on_delete=models.SET_NULL
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
verbose_name="操作人",
)
operator_snapshot = models.JSONField(
null=True,
blank=True,
verbose_name="操作人快照",
help_text="{name, store_group, role}(防止人员调动后显示异常)",
)
operator_snapshot = models.JSONField(null=True, blank=True)
deleted_at = models.DateTimeField(null=True, blank=True)
deleted_at = models.DateTimeField(
null=True,
blank=True,
verbose_name="删除时间",
help_text="仅 is_deletable=TRUE 时可软删",
)
class Meta:
db_table = "client_follow_logs"
@@ -43,14 +100,43 @@ class ClientFollowLog(models.Model):
class ClientFollowLogAttachment(UUIDPrimaryKeyModel):
follow_log_id = models.UUIDField() # cross-partitioned FK; not enforced via Django FK
file_key = models.TextField()
file_name = models.CharField(max_length=255)
file_size = models.IntegerField()
file_type = models.CharField(max_length=10, blank=True, default="")
has_location = models.BooleanField(default=False)
sort_order = models.SmallIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
follow_log_id = models.UUIDField(
verbose_name="所属跟进日志ID",
help_text="跨分区 FK不通过 Django FK 强制约束",
)
file_key = models.TextField(
verbose_name="文件存储路径",
help_text="R2/S3 存储路径",
)
file_name = models.CharField(
max_length=255,
verbose_name="文件名",
help_text="原始文件名(用于展示和下载)",
)
file_size = models.IntegerField(
verbose_name="文件大小",
help_text="单位bytes最大 20MB",
)
file_type = models.CharField(
max_length=10,
blank=True,
default="",
verbose_name="文件类型",
help_text="bmp / jpg / png / gif",
)
has_location = models.BooleanField(
default=False,
verbose_name="是否含位置信息",
help_text="是否含 GPS 位置信息",
)
sort_order = models.SmallIntegerField(
default=0,
verbose_name="排序顺序",
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name="创建时间",
)
class Meta:
db_table = "client_follow_log_attachments"