"""Python mirror of DATA_MODEL/ENUMS.md v2.2. All values are lower_snake_case. Authority: ENUMS.md is the single source of truth. When ENUMS.md changes, update this file in the same commit. All models/serializers MUST import choices from here; never hardcode enum strings. """ from django.db import models # ────────────────────────────────────────────────────────────── # 2. Public / 平台级 固定枚举 # ────────────────────────────────────────────────────────────── class TenantPlan(models.TextChoices): BASIC = "basic", "基础版" PROFESSIONAL = "professional", "专业版" ENTERPRISE = "enterprise", "企业版" class TenantStatus(models.TextChoices): CREATING = "creating", "创建中" ACTIVE = "active", "正常" SUSPENDED = "suspended", "已挂起" PENDING_DELETE = "pending_delete", "待删除" DELETED = "deleted", "已删除" FAILED = "failed", "创建/初始化失败" class TenantSuspendedReason(models.TextChoices): OVERDUE = "overdue", "欠费" VIOLATION = "violation", "违规" REQUESTED = "requested", "客户申请" OTHER = "other", "其他" class PlatformAdminRole(models.TextChoices): SUPER_ADMIN = "super_admin", "超级管理员" OPS_OPERATOR = "ops_operator", "运营管理员" READ_ONLY_AUDITOR = "read_only_auditor", "只读审计员" class PlatformAuditResult(models.TextChoices): SUCCESS = "success", "成功" FAILED = "failed", "失败" class BackupScheduleFrequency(models.TextChoices): HOURLY = "hourly", "每小时" DAILY = "daily", "每日" WEEKLY = "weekly", "每周" class BackupStorageTarget(models.TextChoices): LOCAL = "local", "本地存储" S3 = "s3", "Amazon S3" R2 = "r2", "Cloudflare R2" GCS = "gcs", "Google Cloud Storage" class BackupTriggerType(models.TextChoices): AUTO = "auto", "自动触发" MANUAL = "manual", "手动触发" PRE_UPGRADE = "pre_upgrade", "升级前触发" PRE_RESTORE = "pre_restore", "恢复前触发" class BackupRecordStatus(models.TextChoices): PENDING = "pending", "待执行" IN_PROGRESS = "in_progress", "执行中" SUCCESS = "success", "成功" FAILED = "failed", "失败" class ExportTaskFormat(models.TextChoices): CSV = "csv", "CSV" JSON = "json", "JSON" SQL_DUMP = "sql_dump", "SQL 导出" class ExportTaskStatus(models.TextChoices): PENDING = "pending", "待执行" IN_PROGRESS = "in_progress", "执行中" SUCCESS = "success", "成功" FAILED = "failed", "失败" class UpgradeEventType(models.TextChoices): UPGRADE = "upgrade", "升级" ROLLBACK = "rollback", "回滚" class UpgradeType(models.TextChoices): APP = "app", "A类-应用升级" SCHEMA = "schema", "B类-数据库结构升级" FEATURE = "feature", "C类-功能开关升级" class UpgradeStrategy(models.TextChoices): FULL = "full", "全量发布" CANARY = "canary", "灰度发布" class UpgradeEventStatus(models.TextChoices): DRAFT = "draft", "草稿" PRE_CHECK = "pre_check", "预检查" PRE_BACKUP = "pre_backup", "预备份" BATCH_RUNNING = "batch_running", "批次执行中" BATCH_DONE = "batch_done", "批次完成" HALTED = "halted", "已暂停" SUCCEEDED = "succeeded", "已成功" FAILED = "failed", "失败" ROLLBACK_RUNNING = "rollback_running", "回滚中" ROLLED_BACK = "rolled_back", "已回滚" class UpgradeFailurePolicy(models.TextChoices): HALT_BATCH = "halt_batch", "失败即停止批次" CONTINUE = "continue", "失败继续" class ClientReleasePlatform(models.TextChoices): WIN32 = "win32", "Windows 客户端" class ClientReleaseArch(models.TextChoices): X64 = "x64", "x64 架构" ARM64 = "arm64", "ARM64 架构" class ClientReleaseType(models.TextChoices): NORMAL = "normal", "普通更新" FORCE = "force", "强制更新" class ClientReleaseStatus(models.TextChoices): DRAFT = "draft", "草稿" PUBLISHED = "published", "已发布" ARCHIVED = "archived", "已归档" # ────────────────────────────────────────────────────────────── # 3.1 login / account # ────────────────────────────────────────────────────────────── class UserAccountStatus(models.TextChoices): ACTIVE = "active", "启用" DISABLED = "disabled", "停用" LOCKED = "locked", "锁定" class LoginFailureReason(models.TextChoices): WRONG_PASSWORD = "wrong_password", "用户名或密码错误" WRONG_CAPTCHA = "wrong_captcha", "验证码错误" ACCOUNT_LOCKED = "account_locked", "账号锁定" ACCOUNT_DISABLED = "account_disabled", "账号停用" TENANT_NOT_FOUND = "tenant_not_found", "租户不存在" # ────────────────────────────────────────────────────────────── # 3.2 org # ────────────────────────────────────────────────────────────── class OrgUnitType(models.TextChoices): COMPANY = "company", "公司" DIVISION = "division", "事业部" REGION = "region", "大区" AREA = "area", "区域" DISTRICT = "district", "片区" STORE = "store", "门店" GROUP = "group", "店组" FUNCTIONAL = "functional", "职能部门" class OrgUnitAttribute(models.TextChoices): DIRECT = "direct", "直营" FRANCHISE = "franchise", "加盟" class StaffRole(models.TextChoices): AGENT = "agent", "经纪人" STORE_MANAGER = "store_manager", "店长" AREA_MANAGER = "area_manager", "区域经理" ADMIN = "admin", "系统管理员" OPERATOR = "operator", "运营/行政" SYSTEM = "system", "系统账号" class StaffStatus(models.TextChoices): ACTIVE = "active", "在职" PROBATION = "probation", "试用" RESIGNED = "resigned", "离职" FROZEN = "frozen", "冻结" class StaffGender(models.TextChoices): MALE = "male", "男" FEMALE = "female", "女" UNKNOWN = "unknown", "未知" class StaffIdType(models.TextChoices): ID_CARD = "id_card", "身份证" PASSPORT = "passport", "护照" OTHER = "other", "其他" class StaffTransferType(models.TextChoices): ONBOARD = "onboard", "入职" TRANSFER = "transfer", "调动" RESIGN = "resign", "离职" REJOIN = "rejoin", "复职" SUPERVISOR_CHANGE = "supervisor_change", "上级变更" ROLE_CHANGE = "role_change", "角色变更" FREEZE = "freeze", "冻结账号" UNFREEZE = "unfreeze", "恢复账号" class StaffAccountPlatform(models.TextChoices): FONREY = "fonrey", "房睿主账号" ANJUKE_58 = "58anjuke", "58安居客" CNREIC = "cnreic", "中国网络经纪人" WECHAT_MP = "wechat_mp", "微信公众号" # ────────────────────────────────────────────────────────────── # 3.3 permission # ────────────────────────────────────────────────────────────── class PermissionModule(models.TextChoices): HOME = "home", "首页" PROPERTY = "property", "房源" NEW_HOUSE = "new_house", "新房" CLIENT = "client", "客源" TRANSACTION = "transaction", "交易" DATA = "data", "数据" MARKETING = "marketing", "营销" HR = "hr", "人事OA" CONTRACT = "contract", "合同" TRINET = "trinet", "三网" SYSTEM = "system", "系统" MOBILE = "mobile", "移动端" SMART_STORE = "smart_store", "智能门店" RECHARGE = "recharge", "在线充值" class PermissionValueType(models.TextChoices): BOOLEAN = "boolean", "开关型" SCOPE = "scope", "范围型" INTEGER = "integer", "数值型" class PermissionRoleCategory(models.TextChoices): AGENT = "agent", "置业顾问" STORE_MANAGER = "store_manager", "店管" DIRECTOR = "director", "总经" OPERATOR = "operator", "运营/行政" CUSTOM = "custom", "自定义" class PermissionScopeLevel(models.TextChoices): NONE = "none", "无" SELF = "self", "本人" GROUP = "group", "本组" STORE = "store", "本门店" AREA = "area", "本区域" REGION = "region", "本大区" COMPANY = "company", "全公司" class PermissionOverrideMode(models.TextChoices): REPLACE = "replace", "覆盖" RESTRICT = "restrict", "限制" GRANT = "grant", "授予" class PermissionDataScopeType(models.TextChoices): SELF = "self", "本人" GROUP = "group", "本组" STORE = "store", "本门店" AREA = "area", "本区域" REGION = "region", "本大区" COMPANY = "company", "全公司" CUSTOM_UNIT = "custom_unit", "自定义组织单元" class PermissionChangeTargetType(models.TextChoices): ROLE = "role", "角色" ROLE_PERMISSION = "role_permission", "角色权限" STAFF_ROLE = "staff_role", "员工角色" STAFF_OVERRIDE = "staff_override", "员工权限覆盖" STAFF_SCOPE = "staff_scope", "员工数据范围" class PermissionChangeAction(models.TextChoices): CREATE = "create", "创建" UPDATE = "update", "更新" DELETE = "delete", "删除" ASSIGN = "assign", "分配" REVOKE = "revoke", "撤销" # ────────────────────────────────────────────────────────────── # 3.4 complex # ────────────────────────────────────────────────────────────── class SchoolType(models.TextChoices): PRIMARY = "primary", "小学" MIDDLE = "middle", "初中" HIGH = "high", "高中" K9 = "k9", "九年一贯制" K12 = "k12", "十二年一贯制" class SchoolNature(models.TextChoices): PUBLIC = "public", "公立" PRIVATE = "private", "私立" INTERNATIONAL = "international", "国际" class SchoolLevel(models.TextChoices): NORMAL = "normal", "普通" KEY = "key", "重点" TOP = "top", "名校" class ComplexBuildingType(models.TextChoices): SLAB = "slab", "板楼" TOWER = "tower", "塔楼" SLAB_TOWER = "slab_tower", "板塔结合" class ComplexWaterType(models.TextChoices): CIVIL = "civil", "民水" COMMERCIAL = "commercial", "商水" class ComplexElectricityType(models.TextChoices): CIVIL = "civil", "民电" COMMERCIAL = "commercial", "商电" class SchoolZoneType(models.TextChoices): GUARANTEED = "guaranteed", "对口" REFERENCE = "reference", "参考" LOTTERY = "lottery", "摇号" class ComplexPhotoCategory(models.TextChoices): COMPLEX = "complex", "楼盘图" LAYOUT = "layout", "户型图" VR = "vr", "VR图" OTHER = "other", "其他" # ────────────────────────────────────────────────────────────── # 3.5 property # ────────────────────────────────────────────────────────────── class PropertyType(models.TextChoices): RESIDENTIAL = "residential", "住宅" VILLA = "villa", "别墅" COMMERCIAL_RESIDENTIAL = "commercial_residential", "商住" SHOP = "shop", "商铺" OFFICE = "office", "写字楼" OTHER = "other", "其他" class PropertyStatus(models.TextChoices): FOR_SALE = "for_sale", "出售" FOR_RENT = "for_rent", "出租" FOR_SALE_RENT = "for_sale_rent", "租售" SUSPENDED = "suspended", "暂缓" SOLD_ELSEWHERE = "sold_elsewhere", "他售" RENTED_ELSEWHERE = "rented_elsewhere", "他租" SOLD = "sold", "成交" UNLISTED = "unlisted", "未挂牌" class PropertyAttribute(models.TextChoices): PUBLIC = "public", "公盘" PRIVATE = "private", "私盘" SPECIAL = "special", "特盘" SEALED = "sealed", "封盘" class PropertyOrientation(models.TextChoices): EAST = "east", "东" SOUTH = "south", "南" WEST = "west", "西" NORTH = "north", "北" SOUTHEAST = "southeast", "东南" NORTHEAST = "northeast", "东北" EAST_WEST = "east_west", "东西" SOUTH_NORTH = "south_north", "南北" NORTHWEST = "northwest", "西北" SOUTHWEST = "southwest", "西南" class PropertyDecoration(models.TextChoices): ROUGH = "rough", "毛坯" PLAIN = "plain", "清水" SIMPLE = "simple", "简装" MEDIUM = "medium", "中装" FINE = "fine", "精装" LUXURY = "luxury", "豪装" class PropertyHouseStatus(models.TextChoices): OWNER_OCCUPIED = "owner_occupied", "业主自住" VACANT = "vacant", "空置" TENANT_OCCUPIED = "tenant_occupied", "租客在住" UNKNOWN = "unknown", "未知" class PropertyViewingTime(models.TextChoices): ANYTIME = "anytime", "随时看房" BY_APPOINTMENT = "by_appointment", "预约看房" INCONVENIENT = "inconvenient", "不便看房" class PropertyGrade(models.TextChoices): A = "a", "A(急迫)" B = "b", "B(较强)" C = "c", "C(一般)" D = "d", "D(较弱)" class PropertyContactGender(models.TextChoices): MALE = "male", "先生" FEMALE = "female", "女士" class PropertyContactIdentity(models.TextChoices): OWNER = "owner", "业主" CONTACT = "contact", "联系人" SUBLETTER = "subletter", "转租人" TENANT = "tenant", "租客" AGENT = "agent", "代理人" CORPORATE = "corporate", "企业法人" class PropertyListingType(models.TextChoices): FOR_SALE = "for_sale", "出售挂牌" FOR_RENT = "for_rent", "出租挂牌" class PropertyListingHistoryStatus(models.TextChoices): ACTIVE = "active", "生效中" ENDED = "ended", "已结束" class PropertyFollowLogType(models.TextChoices): WRITTEN = "written", "手写跟进" MODIFIED = "modified", "修改跟进" SENSITIVE_OP = "sensitive_op", "敏感操作" SENSITIVE_VIEW = "sensitive_view", "敏感查看" OTHER = "other", "其他" SYSTEM = "system", "系统" class PropertyFollowAiTag(models.TextChoices): AI_FOR_SALE = "ai_for_sale", "AI判断可售" AI_NOT_FOR_SALE = "ai_not_for_sale", "AI判断不可售" class PropertyFollowAttachmentFileType(models.TextChoices): BMP = "bmp", "BMP" JPG = "jpg", "JPG" PNG = "png", "PNG" SVG = "svg", "SVG" GIF = "gif", "GIF" class PropertyKeyType(models.TextChoices): MECHANICAL = "mechanical", "机械钥匙" PASSWORD = "password", "密码钥匙" class PropertyCommissionOwnerType(models.TextChoices): OWNER = "owner", "产权人本人" AUTHORIZED_THIRD = "authorized_third", "授权第三方" class PropertyCommissionStatus(models.TextChoices): ACTIVE = "active", "有效" EXPIRED = "expired", "过期" CANCELLED = "cancelled", "取消" class PropertyCommissionAttachmentCategory(models.TextChoices): ID_CARD = "id_card", "身份证件" PROPERTY_CERT = "property_cert", "产权证明" COMMISSION_LETTER = "commission_letter", "委托书" OTHER = "other", "其他" class PropertyFieldSurveyStatus(models.TextChoices): DRAFT = "draft", "草稿" SUBMITTED = "submitted", "已提交" class PropertySurveyPhotoCategory(models.TextChoices): LAYOUT = "layout", "户型图" LIVING_ROOM = "living_room", "客厅" DINING_ROOM = "dining_room", "餐厅" BEDROOM = "bedroom", "卧室" BATHROOM = "bathroom", "卫生间" KITCHEN = "kitchen", "厨房" ENTRANCE = "entrance", "入户" BALCONY = "balcony", "阳台" STUDY = "study", "书房" INDOOR_OTHER = "indoor_other", "室内其他" OUTDOOR = "outdoor", "室外" class PropertyPhotoCategory(models.TextChoices): COVER = "cover", "封面" ENTRANCE = "entrance", "入户" LIVING_ROOM = "living_room", "客厅" DINING_ROOM = "dining_room", "餐厅" BEDROOM = "bedroom", "卧室" BATHROOM = "bathroom", "卫生间" KITCHEN = "kitchen", "厨房" BALCONY = "balcony", "阳台" STUDY = "study", "书房" INDOOR_OTHER = "indoor_other", "室内其他" OUTDOOR = "outdoor", "室外" PANORAMA = "panorama", "全景" class PropertyAttachmentCategory(models.TextChoices): ID_CARD = "id_card", "身份证件" PROPERTY_CERT = "property_cert", "产权证明" COMMISSION_LETTER = "commission_letter", "委托书" OTHER = "other", "其他" class PropertyNumberHolderApprovalStatus(models.TextChoices): PENDING = "pending", "待审批" APPROVED = "approved", "已通过" REJECTED = "rejected", "已驳回" # ────────────────────────────────────────────────────────────── # 3.6 client # ────────────────────────────────────────────────────────────── class ClientType(models.TextChoices): PRIVATE = "private", "私客" PUBLIC = "public", "公客" TRANSACTED = "transacted", "成交客" class ClientStatus(models.TextChoices): BUYING = "buying", "求购" RENTING = "renting", "求租" BUY_OR_RENT = "buy_or_rent", "租购" SUSPENDED = "suspended", "暂缓" BOUGHT = "bought", "已购" RENTED_DONE = "rented_done", "已租" PUBLIC = "public", "公客" INVALID = "invalid", "无效" class ClientGrade(models.TextChoices): A = "A", "A(急迫)" B = "B", "B(较强)" C = "C", "C(一般)" D = "D", "D(较弱)" E = "E", "E(暂不关注)" class ClientPropertyUsage(models.TextChoices): RESIDENTIAL = "residential", "住宅" VILLA = "villa", "别墅" COMMERCIAL_RESIDENTIAL = "commercial_residential", "商住" SHOP = "shop", "商铺" OFFICE = "office", "写字楼" OTHER = "other", "其他" class ClientBuyingPurpose(models.TextChoices): RIGID = "rigid", "刚需" INVESTMENT = "investment", "投资" SCHOOL_DISTRICT = "school_district", "学区" UPGRADE = "upgrade", "改善" COMMERCIAL = "commercial", "商用" OTHER = "other", "其他" class ClientPaymentMethod(models.TextChoices): FULL = "full", "全额" MORTGAGE = "mortgage", "商业贷款" MORTGAGE_FUND = "mortgage_fund", "商贷+公积金" FUND = "fund", "公积金" class ClientPropertiesOwned(models.TextChoices): NONE = "none", "无" LOCAL_NONE = "local_none", "本地无/外地有" LOCAL_HAS = "local_has", "本地有" class ClientIdType(models.TextChoices): ID_CARD = "id_card", "身份证" PASSPORT = "passport", "护照" HK_MACAO = "hk_macao", "港澳通行证" OTHER = "other", "其他" class ClientTransferToPublicType(models.TextChoices): MANUAL = "manual", "手动转公" AUTO = "auto", "自动转公" MARKETING_JUMP = "marketing_jump", "营销客跳公" RESOURCE_PUBLIC = "resource_public", "资料客素公" class ClientInvalidReason(models.TextChoices): INVALID_PHONE = "invalid_phone", "号码无效" PEER_AGENT = "peer_agent", "同行" AD = "ad", "广告推销" NO_INTENT = "no_intent", "无意向" OTHER = "other", "其他" class ClientTransactedType(models.TextChoices): BOUGHT = "bought", "我购" RENTED = "rented", "我租" class ClientTransactedPropertyType(models.TextChoices): SECOND_HAND = "second_hand", "二手" NEW_HOUSE = "new_house", "新房" class ClientActivityLevel(models.TextChoices): NEW_MATCHED = "new_matched", "新配对" ACTIVE_7D = "active_7d", "7日活跃" ACTIVE_30D = "active_30d", "30日活跃" ACTIVE_90D = "active_90d", "90日活跃" EXPIRING = "expiring", "即将过期" FROZEN = "frozen", "暂缓中" INVALID = "invalid", "无效" class ClientContactGender(models.TextChoices): MALE = "male", "先生" FEMALE = "female", "女士" class ClientRequirementType(models.TextChoices): SECOND_HAND = "second_hand", "二手" NEW_HOUSE = "new_house", "新房" RENTAL = "rental", "租房" class ClientFloorPreference(models.TextChoices): NO_FIRST = "no_first", "不要一楼" LOW = "low", "低楼层" MID = "mid", "中楼层" HIGH = "high", "高楼层" NO_TOP = "no_top", "不要顶楼" class ClientOrientation(models.TextChoices): EAST = "east", "东" SOUTH = "south", "南" WEST = "west", "西" NORTH = "north", "北" class ClientDecoration(models.TextChoices): ROUGH = "rough", "毛坯" PLAIN = "plain", "清水" SIMPLE = "simple", "简装" MEDIUM = "medium", "中装" FINE = "fine", "精装" LUXURY = "luxury", "豪装" class ClientBuildingAgeRange(models.TextChoices): WITHIN_5Y = "within_5y", "5年内" Y5_10 = "5_10y", "5-10年" Y10_15 = "10_15y", "10-15年" Y15_20 = "15_20y", "15-20年" OVER_20Y = "over_20y", "20年以上" class ClientFollowLogType(models.TextChoices): WRITTEN = "written", "写入跟进" MODIFIED = "modified", "修改跟进" SENSITIVE_VIEW = "sensitive_view", "敏感查看" OTHER = "other", "其他" SYSTEM = "system", "系统" class ClientViewingType(models.TextChoices): APPOINTMENT = "appointment", "预约" VIEWING = "viewing", "带看" REVISIT = "revisit", "复看" EMPTY = "empty", "空看" class ClientViewingIntent(models.TextChoices): INTERESTED = "interested", "感兴趣" NOT_INTERESTED = "not_interested", "不感兴趣" NEGOTIATING = "negotiating", "谈判中" CANCELLED = "cancelled", "取消" class ClientPropertyMatchSource(models.TextChoices): RECORDED = "recorded", "录客配房" SYSTEM = "system", "系统配房" class ClientPropertyMatchGroup(models.TextChoices): QUALITY_LAYOUT = "quality_layout", "优质户型" PRICE_REDUCED = "price_reduced", "降价" HOT = "hot", "热门" NEWLY_LISTED = "newly_listed", "新上" class ClientPropertyMatchStatus(models.TextChoices): SUGGESTED = "suggested", "待推送" SHARED = "shared", "已分享" REJECTED = "rejected", "已反馈不合适" VIEWED = "viewed", "客户已查看" class ClientStatusLogChangeType(models.TextChoices): STATUS_CHANGE = "status_change", "改状态" GRADE_CHANGE = "grade_change", "改等级" TO_PUBLIC = "to_public", "转公客" TO_TRANSACTED = "to_transacted", "转成交" TO_INVALID = "to_invalid", "转无效" OWNER_CHANGE = "owner_change", "改归属人" SOURCE_CHANGE = "source_change", "改来源" MERGE = "merge", "合并客源" # ────────────────────────────────────────────────────────────── # 3.7 setting # ────────────────────────────────────────────────────────────── class SettingValueType(models.TextChoices): BOOL = "bool", "布尔" INT = "int", "整数" STRING = "string", "字符串" ENUM = "enum", "枚举" class FieldRuleModule(models.TextChoices): PROPERTY = "property", "房源" CLIENT = "client", "客源" class FieldRuleEntityType(models.TextChoices): RESIDENTIAL = "residential", "住宅" VILLA = "villa", "别墅" COMMERCIAL_RESIDENTIAL = "commercial_residential", "商住" SHOP = "shop", "商铺" OFFICE = "office", "写字楼" OTHER = "other", "其他" class FieldRuleTradeStatus(models.TextChoices): SALE = "sale", "出售" RENT = "rent", "出租" SALE_RENT = "sale_rent", "租售" ALL = "all", "全部" class FieldRuleRequirement(models.TextChoices): REQUIRED = "required", "必填" OPTIONAL = "optional", "选填" HIDDEN = "hidden", "隐藏"