Files
fonrey/apps/client/models/core.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

150 lines
4.9 KiB
Python

from django.contrib.postgres.fields import ArrayField
from django.db import models
from core.enums import (
ClientActivityLevel,
ClientBuyingPurpose,
ClientGrade,
ClientIdType,
ClientInvalidReason,
ClientPaymentMethod,
ClientPropertiesOwned,
ClientPropertyUsage,
ClientStatus,
ClientTransactedPropertyType,
ClientTransactedType,
ClientTransferToPublicType,
ClientType,
)
from core.models.base import AuditedModel
class Client(AuditedModel):
client_no = models.CharField(max_length=30, unique=True)
client_type = models.CharField(
max_length=20, choices=ClientType.choices, default=ClientType.PRIVATE
)
status = models.CharField(
max_length=20, choices=ClientStatus.choices, default=ClientStatus.BUYING
)
grade = models.CharField(
max_length=5, choices=ClientGrade.choices, default=ClientGrade.C
)
property_usage = models.CharField(
max_length=30,
choices=ClientPropertyUsage.choices,
default=ClientPropertyUsage.RESIDENTIAL,
)
buying_purpose = ArrayField(
models.CharField(max_length=20, choices=ClientBuyingPurpose.choices),
blank=True,
default=list,
)
payment_method = models.CharField(
max_length=30, choices=ClientPaymentMethod.choices, blank=True, default=""
)
properties_owned = models.CharField(
max_length=20, choices=ClientPropertiesOwned.choices, blank=True, default=""
)
has_loan_record = models.BooleanField(null=True, blank=True)
id_type = models.CharField(
max_length=20, choices=ClientIdType.choices, blank=True, default=""
)
id_number_enc = models.BinaryField(null=True, blank=True)
source = models.CharField(max_length=50, blank=True, default="")
remarks = models.TextField(blank=True, default="")
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)
transfer_to_public_type = models.CharField(
max_length=20,
choices=ClientTransferToPublicType.choices,
blank=True,
default="",
)
transferred_public_at = models.DateTimeField(null=True, blank=True)
invalid_reason = models.CharField(
max_length=30, choices=ClientInvalidReason.choices, blank=True, default=""
)
invalidated_at = models.DateTimeField(null=True, blank=True)
transacted_at = models.DateField(null=True, blank=True)
transacted_property = models.ForeignKey(
"fonrey_property.Property",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="transacted_clients",
)
transacted_price = models.DecimalField(
max_digits=12, decimal_places=2, null=True, blank=True
)
transacted_type = models.CharField(
max_length=20, choices=ClientTransactedType.choices, blank=True, default=""
)
transacted_property_type = models.CharField(
max_length=20,
choices=ClientTransactedPropertyType.choices,
blank=True,
default="",
)
first_recorder = models.ForeignKey(
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="first_recorded_clients",
)
owner = models.ForeignKey(
"org.Staff",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="owned_clients",
)
org_unit = models.ForeignKey(
"org.OrgUnit",
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name="clients",
)
activity_level = models.CharField(
max_length=20, choices=ClientActivityLevel.choices, blank=True, default=""
)
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)
version = models.IntegerField(default=1)
class Meta:
db_table = "clients"
verbose_name = "客源"
verbose_name_plural = "客源"
indexes = [
models.Index(fields=["client_type", "status"], name="idx_clients_type_stat"),
models.Index(fields=["owner"], name="idx_clients_owner"),
models.Index(fields=["org_unit"], name="idx_clients_org_unit"),
models.Index(
fields=["activity_level", "-last_active_at"],
name="idx_clients_activity",
),
models.Index(fields=["grade"], name="idx_clients_grade"),
models.Index(
fields=["-transferred_public_at"], name="idx_clients_transferred"
),
models.Index(fields=["-last_follow_at"], name="idx_clients_last_follow"),
]