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:
@@ -20,80 +20,190 @@ from core.models.base import AuditedModel
|
||||
|
||||
|
||||
class Client(AuditedModel):
|
||||
client_no = models.CharField(max_length=30, unique=True)
|
||||
client_no = models.CharField(
|
||||
max_length=30,
|
||||
unique=True,
|
||||
verbose_name="客源编号",
|
||||
help_text="系统生成的客源编号,格式由运营配置(如 KY20260424001)",
|
||||
)
|
||||
client_type = models.CharField(
|
||||
max_length=20, choices=ClientType.choices, default=ClientType.PRIVATE
|
||||
max_length=20,
|
||||
choices=ClientType.choices,
|
||||
default=ClientType.PRIVATE,
|
||||
verbose_name="客源分类",
|
||||
help_text="private=私客 / public=公客 / transacted=成交客",
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=20, choices=ClientStatus.choices, default=ClientStatus.BUYING
|
||||
max_length=20,
|
||||
choices=ClientStatus.choices,
|
||||
default=ClientStatus.BUYING,
|
||||
verbose_name="客源状态",
|
||||
help_text="buying=求购 / renting=求租 / buy_or_rent=租购 / suspended=暂缓 / bought=已购 / rented_done=已租 / public=公客 / invalid=无效(详见 ENUMS)",
|
||||
)
|
||||
grade = models.CharField(
|
||||
max_length=5, choices=ClientGrade.choices, default=ClientGrade.C
|
||||
max_length=5,
|
||||
choices=ClientGrade.choices,
|
||||
default=ClientGrade.C,
|
||||
verbose_name="客源等级",
|
||||
help_text="A=A急迫 / B=较强 / C=一般 / D=较弱 / E=暂不关注",
|
||||
)
|
||||
property_usage = models.CharField(
|
||||
max_length=30,
|
||||
choices=ClientPropertyUsage.choices,
|
||||
default=ClientPropertyUsage.RESIDENTIAL,
|
||||
verbose_name="房屋用途",
|
||||
help_text="residential=住宅 / villa=别墅 / commercial_residential=商住 / shop=商铺 / office=写字楼 / other=其他",
|
||||
)
|
||||
buying_purpose = ArrayField(
|
||||
models.CharField(max_length=20, choices=ClientBuyingPurpose.choices),
|
||||
blank=True,
|
||||
default=list,
|
||||
verbose_name="购房目的",
|
||||
help_text="多选:rigid=刚需 / investment=投资 / school_district=学区 / upgrade=改善 / commercial=商用 / other=其他",
|
||||
)
|
||||
payment_method = models.CharField(
|
||||
max_length=30, choices=ClientPaymentMethod.choices, blank=True, default=""
|
||||
max_length=30,
|
||||
choices=ClientPaymentMethod.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="付款方式",
|
||||
help_text="full=全额 / mortgage=商业贷款 / mortgage_fund=商贷+公积金 / fund=公积金",
|
||||
)
|
||||
properties_owned = models.CharField(
|
||||
max_length=20, choices=ClientPropertiesOwned.choices, blank=True, default=""
|
||||
max_length=20,
|
||||
choices=ClientPropertiesOwned.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="名下房产",
|
||||
help_text="none=无 / local_none=本地无外地有 / local_has=本地有",
|
||||
)
|
||||
has_loan_record = models.BooleanField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="有无贷款记录",
|
||||
)
|
||||
has_loan_record = models.BooleanField(null=True, blank=True)
|
||||
|
||||
id_type = models.CharField(
|
||||
max_length=20, choices=ClientIdType.choices, blank=True, default=""
|
||||
max_length=20,
|
||||
choices=ClientIdType.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="证件类型",
|
||||
help_text="id_card=身份证 / passport=护照 / hk_macao=港澳台 / other=其他",
|
||||
)
|
||||
id_number_enc = models.BinaryField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="证件号码(加密)",
|
||||
help_text="AES 加密存储",
|
||||
)
|
||||
id_number_enc = models.BinaryField(null=True, blank=True)
|
||||
|
||||
source = models.CharField(max_length=50, blank=True, default="")
|
||||
remarks = models.TextField(blank=True, default="")
|
||||
source = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="客户来源",
|
||||
help_text="lookup_items 维护",
|
||||
)
|
||||
remarks = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="备注",
|
||||
help_text="最多200字",
|
||||
)
|
||||
|
||||
is_starred = models.BooleanField(default=False)
|
||||
is_pinned = models.BooleanField(default=False)
|
||||
is_big_value = models.BooleanField(default=False)
|
||||
is_protected = models.BooleanField(default=False)
|
||||
prefers_new_house = models.BooleanField(null=True, blank=True)
|
||||
is_starred = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否收藏",
|
||||
help_text="快速标记,详细收藏夹用 client_folder_items",
|
||||
)
|
||||
is_pinned = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否置顶",
|
||||
help_text="列表顶部置顶",
|
||||
)
|
||||
is_big_value = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否大价值客户",
|
||||
help_text="影响筛选展示",
|
||||
)
|
||||
is_protected = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否保护客",
|
||||
help_text="影响转公逻辑",
|
||||
)
|
||||
prefers_new_house = models.BooleanField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="偏好新房",
|
||||
help_text="用于筛选",
|
||||
)
|
||||
|
||||
transfer_to_public_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=ClientTransferToPublicType.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="转公客方式",
|
||||
help_text="manual=手动转公 / auto=自动转公(超时) / marketing_jump=营销客跳公 / resource_public=资料客素公",
|
||||
)
|
||||
transferred_public_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="进入公客池时间",
|
||||
)
|
||||
transferred_public_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
invalid_reason = models.CharField(
|
||||
max_length=30, choices=ClientInvalidReason.choices, blank=True, default=""
|
||||
max_length=30,
|
||||
choices=ClientInvalidReason.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="无效原因",
|
||||
help_text="invalid_phone=号码无效 / peer_agent=同行 / ad=广告推销 / no_intent=无意向 / other=其他",
|
||||
)
|
||||
invalidated_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="标记无效时间",
|
||||
)
|
||||
invalidated_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
transacted_at = models.DateField(null=True, blank=True)
|
||||
transacted_at = models.DateField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="成交日期",
|
||||
)
|
||||
transacted_property = models.ForeignKey(
|
||||
"fonrey_property.Property",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="transacted_clients",
|
||||
verbose_name="成交房源",
|
||||
help_text="成交关联的房源",
|
||||
)
|
||||
transacted_price = models.DecimalField(
|
||||
max_digits=12, decimal_places=2, null=True, blank=True
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="成交价格",
|
||||
help_text="单位:万元",
|
||||
)
|
||||
transacted_type = models.CharField(
|
||||
max_length=20, choices=ClientTransactedType.choices, blank=True, default=""
|
||||
max_length=20,
|
||||
choices=ClientTransactedType.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="成交类型",
|
||||
help_text="bought=我购 / rented=我租",
|
||||
)
|
||||
transacted_property_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=ClientTransactedPropertyType.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="成交房源类型",
|
||||
help_text="second_hand=二手 / new_house=新房",
|
||||
)
|
||||
|
||||
first_recorder = models.ForeignKey(
|
||||
@@ -102,6 +212,7 @@ class Client(AuditedModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="first_recorded_clients",
|
||||
verbose_name="首录人",
|
||||
)
|
||||
owner = models.ForeignKey(
|
||||
"org.Staff",
|
||||
@@ -109,6 +220,8 @@ class Client(AuditedModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="owned_clients",
|
||||
verbose_name="归属人",
|
||||
help_text="私客独占跟进人",
|
||||
)
|
||||
org_unit = models.ForeignKey(
|
||||
"org.OrgUnit",
|
||||
@@ -116,18 +229,47 @@ class Client(AuditedModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="clients",
|
||||
verbose_name="归属部门",
|
||||
help_text="冗余字段,加速筛选",
|
||||
)
|
||||
|
||||
activity_level = models.CharField(
|
||||
max_length=20, choices=ClientActivityLevel.choices, blank=True, default=""
|
||||
max_length=20,
|
||||
choices=ClientActivityLevel.choices,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="活跃度",
|
||||
help_text="new_matched=新配偶 / active_7d / active_30d / active_90d / expiring / frozen / invalid(异步计算)",
|
||||
)
|
||||
last_active_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="最后有效跟进时间",
|
||||
help_text="触发器维护",
|
||||
)
|
||||
last_follow_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="最后跟进时间",
|
||||
help_text="冗余字段,列表排序用",
|
||||
)
|
||||
last_active_at = models.DateTimeField(null=True, blank=True)
|
||||
last_follow_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
commission_date = models.DateField(null=True, blank=True)
|
||||
entrust_count = models.SmallIntegerField(default=1)
|
||||
commission_date = models.DateField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="委托日期",
|
||||
)
|
||||
entrust_count = models.SmallIntegerField(
|
||||
default=1,
|
||||
verbose_name="委托次数",
|
||||
help_text="成交后再委托则累加",
|
||||
)
|
||||
|
||||
version = models.IntegerField(default=1)
|
||||
version = models.IntegerField(
|
||||
default=1,
|
||||
verbose_name="版本号",
|
||||
help_text="乐观锁;每次 UPDATE +1;应用层检测 0 行受影响时抛 ConflictError",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "clients"
|
||||
|
||||
Reference in New Issue
Block a user