feat(property): add Chinese verbose_name and help_text to all property fields (Phase 4.1)
Sync DATA_MODEL_PROPERTY.md field-level Chinese annotations to Django models across 23 property tables. Adds verbose_name= and help_text= to every field in core.py, follow_keys.py, listings.py, media.py. Pre-existing partitioned-table docstrings on FollowLog/PropertyPhoto retained (signal Django ORM treats parent as unmanaged, RunSQL managed).
This commit is contained in:
@@ -16,31 +16,101 @@ class ListingHistory(UUIDPrimaryKeyModel):
|
||||
"fonrey_property.Property",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="listing_histories",
|
||||
verbose_name="所属房源",
|
||||
help_text="禁止级联删除,保留历史",
|
||||
)
|
||||
listing_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=PropertyListingType.choices,
|
||||
verbose_name="挂牌类型",
|
||||
help_text="for_sale=出售挂牌/for_rent=出租挂牌",
|
||||
)
|
||||
listing_type = models.CharField(max_length=20, choices=PropertyListingType.choices)
|
||||
status = models.CharField(
|
||||
max_length=10,
|
||||
choices=PropertyListingHistoryStatus.choices,
|
||||
default=PropertyListingHistoryStatus.ACTIVE,
|
||||
verbose_name="挂牌状态",
|
||||
help_text="active=挂牌中/ended=已结束",
|
||||
)
|
||||
|
||||
sale_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
rent_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
sale_unit_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
sale_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="本次挂牌售价快照",
|
||||
help_text="万元;出售挂牌时记录",
|
||||
)
|
||||
rent_price = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="本次挂牌租价快照",
|
||||
help_text="元/月;出租挂牌时记录",
|
||||
)
|
||||
sale_unit_price = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="本次挂牌售价单价",
|
||||
help_text="元/m²;由 sale_price ÷ area 计算后存储",
|
||||
)
|
||||
|
||||
ownership_years = models.CharField(max_length=30, blank=True, default="")
|
||||
is_only_house = models.BooleanField(null=True, blank=True)
|
||||
tax_included = models.CharField(max_length=15, blank=True, default="")
|
||||
sale_reason = models.TextField(blank=True, default="")
|
||||
ownership_years = models.CharField(
|
||||
max_length=30,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="房本年限快照",
|
||||
help_text='本次挂牌时的房本年限,如"满2年"',
|
||||
)
|
||||
is_only_house = models.BooleanField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="唯一住房状态快照",
|
||||
help_text="本次挂牌时的唯一住房状态",
|
||||
)
|
||||
tax_included = models.CharField(
|
||||
max_length=15,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="包税费方式快照",
|
||||
help_text="each_party=各付/net=到手/inclusive=包税",
|
||||
)
|
||||
sale_reason = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="售房原因快照",
|
||||
help_text="本次挂牌时的售房原因",
|
||||
)
|
||||
|
||||
seller_agent = 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="出售经纪人",
|
||||
help_text="本次挂牌的出售经纪人;人员离职后置 NULL,但 snapshot 保留",
|
||||
)
|
||||
seller_agent_snapshot = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="出售经纪人快照",
|
||||
help_text="{name, store_group, org_unit_name};防止人员变动后数据丢失",
|
||||
)
|
||||
seller_agent_snapshot = models.JSONField(null=True, blank=True)
|
||||
|
||||
started_at = models.DateTimeField(auto_now_add=False)
|
||||
ended_at = models.DateTimeField(null=True, blank=True)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
started_at = models.DateTimeField(
|
||||
auto_now_add=False,
|
||||
verbose_name="本次挂牌开始时间",
|
||||
)
|
||||
ended_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="本次挂牌结束时间",
|
||||
help_text="NULL=当前仍在挂牌中",
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
|
||||
|
||||
class Meta:
|
||||
db_table = "listing_histories"
|
||||
@@ -54,20 +124,88 @@ class ListingHistory(UUIDPrimaryKeyModel):
|
||||
|
||||
class PriceChange(UUIDPrimaryKeyModel):
|
||||
property = models.ForeignKey(
|
||||
"fonrey_property.Property", on_delete=models.RESTRICT, related_name="price_changes"
|
||||
"fonrey_property.Property",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="price_changes",
|
||||
verbose_name="所属房源",
|
||||
help_text="禁止级联删除,保留调价历史",
|
||||
)
|
||||
old_sale_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价前挂牌售价",
|
||||
help_text="万元;NULL=首次定价",
|
||||
)
|
||||
new_sale_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价后挂牌售价",
|
||||
help_text="万元",
|
||||
)
|
||||
old_bottom_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价前售底价",
|
||||
help_text="万元;NULL=未设置",
|
||||
)
|
||||
new_bottom_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价后售底价",
|
||||
help_text="万元;NULL=本次不变更底价",
|
||||
)
|
||||
old_record_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价前备案/核验价",
|
||||
help_text="万元;NULL=未设置",
|
||||
)
|
||||
new_record_price = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价后备案/核验价",
|
||||
help_text="万元;NULL=本次不变更",
|
||||
)
|
||||
old_rent_price = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价前挂牌租价",
|
||||
help_text="元/月;NULL=非出租类或未设置",
|
||||
)
|
||||
new_rent_price = models.DecimalField(
|
||||
max_digits=10,
|
||||
decimal_places=2,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="调价后挂牌租价",
|
||||
help_text="元/月",
|
||||
)
|
||||
old_sale_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
new_sale_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
old_bottom_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
new_bottom_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
old_record_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
new_record_price = models.DecimalField(max_digits=12, decimal_places=2, null=True, blank=True)
|
||||
old_rent_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
new_rent_price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
|
||||
|
||||
change_reason = models.TextField()
|
||||
changed_at = models.DateTimeField(auto_now_add=True)
|
||||
changed_by = models.ForeignKey("org.Staff", on_delete=models.RESTRICT)
|
||||
change_reason = models.TextField(
|
||||
verbose_name="调价原因",
|
||||
help_text='必填,最多 200 字;如"业主主动降价"',
|
||||
)
|
||||
changed_at = models.DateTimeField(auto_now_add=True, verbose_name="调价操作时间")
|
||||
changed_by = models.ForeignKey(
|
||||
"org.Staff",
|
||||
on_delete=models.RESTRICT,
|
||||
verbose_name="操作人",
|
||||
help_text="禁止置 NULL,保留审计追溯",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = "price_changes"
|
||||
@@ -81,12 +219,28 @@ class PriceChange(UUIDPrimaryKeyModel):
|
||||
|
||||
class Commission(TimeStampedModel):
|
||||
property = models.ForeignKey(
|
||||
"fonrey_property.Property", on_delete=models.CASCADE, related_name="commissions"
|
||||
"fonrey_property.Property",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="commissions",
|
||||
verbose_name="所属房源",
|
||||
)
|
||||
commission_type = models.CharField(
|
||||
max_length=50,
|
||||
verbose_name="委托类型",
|
||||
help_text="独家委托/非独家委托;由 lookup_items 维护",
|
||||
)
|
||||
period_start = models.DateField(verbose_name="委托开始日期")
|
||||
period_end = models.DateField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="委托结束日期",
|
||||
help_text="is_open_ended=true 时为 NULL",
|
||||
)
|
||||
is_open_ended = models.BooleanField(
|
||||
default=False,
|
||||
verbose_name="是否无固定结束日期",
|
||||
help_text="true=长期委托/false=有截止日期",
|
||||
)
|
||||
commission_type = models.CharField(max_length=50)
|
||||
period_start = models.DateField()
|
||||
period_end = models.DateField(null=True, blank=True)
|
||||
is_open_ended = models.BooleanField(default=False)
|
||||
|
||||
agent = models.ForeignKey(
|
||||
"org.Staff",
|
||||
@@ -94,15 +248,30 @@ class Commission(TimeStampedModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="commissions_as_agent",
|
||||
verbose_name="委托经纪人",
|
||||
help_text="人员离职后置 NULL",
|
||||
)
|
||||
agent_snapshot = models.JSONField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="经纪人快照",
|
||||
help_text="{name, store_group};防止人员变动后数据丢失",
|
||||
)
|
||||
agent_snapshot = models.JSONField(null=True, blank=True)
|
||||
|
||||
signing_method = models.CharField(max_length=50, blank=True, default="")
|
||||
signing_method = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="签约方式",
|
||||
help_text="选择后动态展示委托书模板",
|
||||
)
|
||||
|
||||
owner_type = models.CharField(
|
||||
max_length=20,
|
||||
choices=PropertyCommissionOwnerType.choices,
|
||||
default=PropertyCommissionOwnerType.OWNER,
|
||||
verbose_name="委托人类型",
|
||||
help_text="owner=产权人本人/authorized_third=被授权第三方",
|
||||
)
|
||||
property_owner_contact = models.ForeignKey(
|
||||
"fonrey_property.PropertyContact",
|
||||
@@ -110,18 +279,49 @@ class Commission(TimeStampedModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="commissions",
|
||||
verbose_name="关联联系人",
|
||||
help_text="若委托人已录入联系人则关联,否则填写下方姓名/证件",
|
||||
)
|
||||
owner_name = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="委托人姓名",
|
||||
)
|
||||
owner_id_type = models.CharField(
|
||||
max_length=20,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="委托人证件类型",
|
||||
help_text="如:身份证/护照",
|
||||
)
|
||||
owner_id_number = models.CharField(
|
||||
max_length=50,
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="委托人证件号明文",
|
||||
help_text="仅供参考;加密版本见 owner_id_number_enc",
|
||||
)
|
||||
owner_id_number_enc = models.BinaryField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="委托人证件号密文",
|
||||
help_text="AES-256-GCM 加密",
|
||||
)
|
||||
owner_name = models.CharField(max_length=50, blank=True, default="")
|
||||
owner_id_type = models.CharField(max_length=20, blank=True, default="")
|
||||
owner_id_number = models.CharField(max_length=50, blank=True, default="")
|
||||
owner_id_number_enc = models.BinaryField(null=True, blank=True)
|
||||
|
||||
remarks = models.TextField(blank=True, default="")
|
||||
remarks = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="备注",
|
||||
help_text="最多 200 字",
|
||||
)
|
||||
|
||||
status = models.CharField(
|
||||
max_length=20,
|
||||
choices=PropertyCommissionStatus.choices,
|
||||
default=PropertyCommissionStatus.ACTIVE,
|
||||
verbose_name="委托状态",
|
||||
help_text="active=有效/expired=已过期/cancelled=已取消",
|
||||
)
|
||||
|
||||
created_by = models.ForeignKey(
|
||||
@@ -130,6 +330,7 @@ class Commission(TimeStampedModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="created_commissions",
|
||||
verbose_name="创建人",
|
||||
)
|
||||
|
||||
class Meta:
|
||||
@@ -144,16 +345,35 @@ class Commission(TimeStampedModel):
|
||||
|
||||
class CommissionAttachment(UUIDPrimaryKeyModel):
|
||||
commission = models.ForeignKey(
|
||||
Commission, on_delete=models.CASCADE, related_name="attachments"
|
||||
Commission,
|
||||
on_delete=models.CASCADE,
|
||||
related_name="attachments",
|
||||
verbose_name="所属委托",
|
||||
help_text="委托删除时联级删除",
|
||||
)
|
||||
category = models.CharField(
|
||||
max_length=20, choices=PropertyCommissionAttachmentCategory.choices
|
||||
max_length=20,
|
||||
choices=PropertyCommissionAttachmentCategory.choices,
|
||||
verbose_name="附件分类",
|
||||
help_text="id_card=身份证/property_cert=产权证书/commission_letter=委托书/other=其他材料",
|
||||
)
|
||||
file_key = models.TextField()
|
||||
file_name = models.CharField(max_length=255)
|
||||
file_size = models.IntegerField(null=True, blank=True)
|
||||
sort_order = models.SmallIntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
file_key = models.TextField(
|
||||
verbose_name="附件存储路径",
|
||||
help_text="Cloudflare R2 对象路径",
|
||||
)
|
||||
file_name = models.CharField(max_length=255, verbose_name="原始文件名")
|
||||
file_size = models.IntegerField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="文件大小",
|
||||
help_text="bytes",
|
||||
)
|
||||
sort_order = models.SmallIntegerField(
|
||||
default=0,
|
||||
verbose_name="排序权重",
|
||||
help_text="数值越小越靠前",
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="上传时间")
|
||||
|
||||
class Meta:
|
||||
db_table = "commission_attachments"
|
||||
@@ -167,15 +387,22 @@ class NumberHolderApproval(UUIDPrimaryKeyModel):
|
||||
"fonrey_property.Property",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="number_holder_approvals",
|
||||
verbose_name="所属房源",
|
||||
)
|
||||
contact = models.ForeignKey(
|
||||
"fonrey_property.PropertyContact",
|
||||
on_delete=models.CASCADE,
|
||||
related_name="number_holder_approvals",
|
||||
verbose_name="申请变更的联系方",
|
||||
help_text="即号码方候选联系人",
|
||||
)
|
||||
|
||||
applicant = models.ForeignKey(
|
||||
"org.Staff", on_delete=models.RESTRICT, related_name="nh_applications"
|
||||
"org.Staff",
|
||||
on_delete=models.RESTRICT,
|
||||
related_name="nh_applications",
|
||||
verbose_name="申请人",
|
||||
help_text="提交号码方变更申请的经纪人;禁止置 NULL 保留审计",
|
||||
)
|
||||
approver = models.ForeignKey(
|
||||
"org.Staff",
|
||||
@@ -183,16 +410,30 @@ class NumberHolderApproval(UUIDPrimaryKeyModel):
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name="nh_approvals",
|
||||
verbose_name="审批人",
|
||||
help_text="上级审批人;审批前为 NULL",
|
||||
)
|
||||
|
||||
status = models.CharField(
|
||||
max_length=20,
|
||||
choices=PropertyNumberHolderApprovalStatus.choices,
|
||||
default=PropertyNumberHolderApprovalStatus.PENDING,
|
||||
verbose_name="审批状态",
|
||||
help_text="pending=待审批/approved=已通过/rejected=已驳回",
|
||||
)
|
||||
remarks = models.TextField(
|
||||
blank=True,
|
||||
default="",
|
||||
verbose_name="审批备注",
|
||||
help_text="审批人填写的意见或驳回原因",
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="申请提交时间")
|
||||
decided_at = models.DateTimeField(
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="审批决定时间",
|
||||
help_text="NULL=尚未审批",
|
||||
)
|
||||
remarks = models.TextField(blank=True, default="")
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
decided_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "number_holder_approvals"
|
||||
|
||||
Reference in New Issue
Block a user