feat(migrations): add Phase 4.0+4.1 verbose_name/help_text migrations

Generated by manage.py makemigrations after Phase 4.0 (model Meta verbose_name)
and Phase 4.1 (field-level verbose_name/help_text) were committed across all 9 apps.

Field-meta only (Alter field on Meta options); no schema changes.
This commit is contained in:
2026-04-30 09:47:44 +08:00
parent 8faa68b615
commit d00ff12ba0
9 changed files with 3880 additions and 0 deletions

View File

@@ -0,0 +1,626 @@
# Generated by Django 4.2.16 on 2026-04-30 01:46
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('org', '0002_alter_orgunit_options_alter_staff_options_and_more'),
]
operations = [
migrations.AlterField(
model_name='orgunit',
name='address_city',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='所在城市'),
),
migrations.AlterField(
model_name='orgunit',
name='address_detail',
field=models.CharField(blank=True, default='', max_length=200, verbose_name='详细地址'),
),
migrations.AlterField(
model_name='orgunit',
name='address_district',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='所在县区'),
),
migrations.AlterField(
model_name='orgunit',
name='attribute',
field=models.CharField(blank=True, choices=[('direct', '直营'), ('franchise', '加盟')], help_text='direct=直营 / franchise=加盟', max_length=10, null=True, verbose_name='经营属性'),
),
migrations.AlterField(
model_name='orgunit',
name='depth',
field=models.SmallIntegerField(default=0, help_text='根=0最大支持 8 层', verbose_name='节点深度'),
),
migrations.AlterField(
model_name='orgunit',
name='established_at',
field=models.DateField(blank=True, null=True, verbose_name='成立时间'),
),
migrations.AlterField(
model_name='orgunit',
name='ext_end',
field=models.IntegerField(blank=True, null=True, verbose_name='分机号结束'),
),
migrations.AlterField(
model_name='orgunit',
name='ext_start',
field=models.IntegerField(blank=True, null=True, verbose_name='分机号起始'),
),
migrations.AlterField(
model_name='orgunit',
name='is_active',
field=models.BooleanField(default=True, help_text='FALSE=已关闭部门,仍可在筛选中显示', verbose_name='是否启用'),
),
migrations.AlterField(
model_name='orgunit',
name='latitude',
field=models.DecimalField(blank=True, decimal_places=7, help_text='部门定位针 WGS84', max_digits=10, null=True, verbose_name='纬度'),
),
migrations.AlterField(
model_name='orgunit',
name='longitude',
field=models.DecimalField(blank=True, decimal_places=7, help_text='部门定位针 WGS84', max_digits=10, null=True, verbose_name='经度'),
),
migrations.AlterField(
model_name='orgunit',
name='manager',
field=models.ForeignKey(blank=True, help_text='循环依赖Application 层维护', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='managed_org_units', to='org.staff', verbose_name='部门负责人'),
),
migrations.AlterField(
model_name='orgunit',
name='name',
field=models.CharField(help_text='部门/组织名称', max_length=100, verbose_name='部门名称'),
),
migrations.AlterField(
model_name='orgunit',
name='parent',
field=models.ForeignKey(blank=True, help_text='父节点,根节点为 NULL', null=True, on_delete=django.db.models.deletion.RESTRICT, related_name='children', to='org.orgunit', verbose_name='父节点'),
),
migrations.AlterField(
model_name='orgunit',
name='path',
field=models.TextField(help_text='/root_id/.../self_id/,用于子树查询', verbose_name='物化路径'),
),
migrations.AlterField(
model_name='orgunit',
name='phone',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='部门联系电话'),
),
migrations.AlterField(
model_name='orgunit',
name='sort_order',
field=models.IntegerField(default=0, help_text='同级排序', verbose_name='排序顺序'),
),
migrations.AlterField(
model_name='orgunit',
name='type',
field=models.CharField(choices=[('company', '公司'), ('division', '事业部'), ('region', '大区'), ('area', '区域'), ('district', '片区'), ('store', '门店'), ('group', '店组'), ('functional', '职能部门')], help_text='company=公司 / division=事业部 / region=大区 / area=区域 / district=片区 / store=门店 / group=店组 / functional=职能', max_length=20, verbose_name='组织类型'),
),
migrations.AlterField(
model_name='staff',
name='avatar_key',
field=models.TextField(blank=True, default='', help_text='R2/S3 头像路径', verbose_name='头像存储路径'),
),
migrations.AlterField(
model_name='staff',
name='bank_account',
field=models.CharField(blank=True, default='', help_text='内部财务用', max_length=50, verbose_name='银行卡号'),
),
migrations.AlterField(
model_name='staff',
name='bank_name',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='银行名称'),
),
migrations.AlterField(
model_name='staff',
name='business_type',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='业务类型'),
),
migrations.AlterField(
model_name='staff',
name='email',
field=models.EmailField(blank=True, default='', max_length=255, verbose_name='邮箱'),
),
migrations.AlterField(
model_name='staff',
name='employee_no',
field=models.CharField(blank=True, help_text='系统自动生成或手动录入', max_length=30, null=True, unique=True, verbose_name='员工工号'),
),
migrations.AlterField(
model_name='staff',
name='extension',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='分机号'),
),
migrations.AlterField(
model_name='staff',
name='first_joined_at',
field=models.DateField(blank=True, help_text='计算工龄起点', null=True, verbose_name='首次入职日期'),
),
migrations.AlterField(
model_name='staff',
name='industry_exp_years',
field=models.SmallIntegerField(blank=True, help_text='单位:年', null=True, verbose_name='行业经验'),
),
migrations.AlterField(
model_name='staff',
name='is_active',
field=models.BooleanField(default=True, help_text='FALSE 时账号不可登录(联动 auth_user.is_active', verbose_name='是否启用'),
),
migrations.AlterField(
model_name='staff',
name='is_system_admin',
field=models.BooleanField(default=False, help_text='影响权限上限', verbose_name='是否系统管理员'),
),
migrations.AlterField(
model_name='staff',
name='job_category',
field=models.CharField(blank=True, default='', help_text='如「置业顾问」(经纪人判定字段)', max_length=50, verbose_name='职务类别'),
),
migrations.AlterField(
model_name='staff',
name='job_level',
field=models.SmallIntegerField(blank=True, null=True, verbose_name='职级'),
),
migrations.AlterField(
model_name='staff',
name='job_title',
field=models.CharField(blank=True, default='', help_text='如「高级业务员」', max_length=100, verbose_name='职务名称'),
),
migrations.AlterField(
model_name='staff',
name='joined_count',
field=models.SmallIntegerField(default=1, verbose_name='累计入职次数'),
),
migrations.AlterField(
model_name='staff',
name='mentor',
field=models.ForeignKey(blank=True, help_text='带教员工', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='mentees', to='org.staff', verbose_name='师傅'),
),
migrations.AlterField(
model_name='staff',
name='name',
field=models.CharField(max_length=50, verbose_name='真实姓名'),
),
migrations.AlterField(
model_name='staff',
name='nickname',
field=models.CharField(blank=True, default='', help_text='通讯录/显示名', max_length=50, verbose_name='昵称'),
),
migrations.AlterField(
model_name='staff',
name='org_unit',
field=models.ForeignKey(help_text='当前所属组织节点(门店或店组)', on_delete=django.db.models.deletion.RESTRICT, related_name='staff_members', to='org.orgunit', verbose_name='所属组织节点'),
),
migrations.AlterField(
model_name='staff',
name='partner_no',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='联号'),
),
migrations.AlterField(
model_name='staff',
name='phone_enc',
field=models.BinaryField(blank=True, help_text='AES-256-GCM 加密手机号', null=True, verbose_name='手机号(加密)'),
),
migrations.AlterField(
model_name='staff',
name='phone_hash',
field=models.CharField(blank=True, db_index=True, help_text='SHA-256 哈希,用于唯一性索引', max_length=64, null=True, verbose_name='手机号哈希'),
),
migrations.AlterField(
model_name='staff',
name='phone_hide',
field=models.BooleanField(default=False, verbose_name='通讯录隐藏手机号'),
),
migrations.AlterField(
model_name='staff',
name='recruit_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='recruited_staff', to='org.staff', verbose_name='招聘人'),
),
migrations.AlterField(
model_name='staff',
name='recruit_source',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='招聘来源'),
),
migrations.AlterField(
model_name='staff',
name='referrer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='referred_staff', to='org.staff', verbose_name='转介人'),
),
migrations.AlterField(
model_name='staff',
name='rejoined_at',
field=models.DateField(blank=True, null=True, verbose_name='最近复职日期'),
),
migrations.AlterField(
model_name='staff',
name='resigned_at',
field=models.DateField(blank=True, null=True, verbose_name='最近离职日期'),
),
migrations.AlterField(
model_name='staff',
name='role',
field=models.CharField(choices=[('agent', '经纪人'), ('store_manager', '店长'), ('area_manager', '区域经理'), ('admin', '系统管理员'), ('operator', '运营/行政'), ('system', '系统账号')], help_text='agent=经纪人 / store_manager=店长 / area_manager=区域经理 / admin=管理员 / operator=运营 / system=系统账号', max_length=30, verbose_name='系统角色'),
),
migrations.AlterField(
model_name='staff',
name='status',
field=models.CharField(choices=[('active', '在职'), ('probation', '试用'), ('resigned', '离职'), ('frozen', '冻结')], default='active', help_text='active=在职 / probation=试用期 / resigned=已离职 / frozen=账号冻结', max_length=20, verbose_name='员工状态'),
),
migrations.AlterField(
model_name='staff',
name='supervisor',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subordinates', to='org.staff', verbose_name='直属上级'),
),
migrations.AlterField(
model_name='staff',
name='user',
field=models.OneToOneField(blank=True, help_text='Django auth 登录账号', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='staff_profile', to=settings.AUTH_USER_MODEL, verbose_name='登录账号'),
),
migrations.AlterField(
model_name='staffaccount',
name='account_no',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='账号/手机号'),
),
migrations.AlterField(
model_name='staffaccount',
name='bound_at',
field=models.DateTimeField(blank=True, null=True, verbose_name='绑定时间'),
),
migrations.AlterField(
model_name='staffaccount',
name='is_bound',
field=models.BooleanField(default=False, verbose_name='是否已绑定'),
),
migrations.AlterField(
model_name='staffaccount',
name='is_real_name_match',
field=models.BooleanField(blank=True, help_text='中国网络经纪人专用', null=True, verbose_name='实名信息一致'),
),
migrations.AlterField(
model_name='staffaccount',
name='platform',
field=models.CharField(choices=[('fonrey', '房睿主账号'), ('58anjuke', '58安居客'), ('cnreic', '中国网络经纪人'), ('wechat_mp', '微信公众号')], help_text='fonrey=主账号 / 58anjuke=58安居客 / cnreic=中国网络经纪人 / wechat_mp=微信公众号', max_length=30, verbose_name='平台'),
),
migrations.AlterField(
model_name='staffaccount',
name='staff',
field=models.ForeignKey(help_text='证件信息随员工关联', on_delete=django.db.models.deletion.CASCADE, related_name='external_accounts', to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='staffeducation',
name='degree',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='学位'),
),
migrations.AlterField(
model_name='staffeducation',
name='end_date',
field=models.DateField(blank=True, null=True, verbose_name='结束日期'),
),
migrations.AlterField(
model_name='staffeducation',
name='enrollment_status',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='就读状态'),
),
migrations.AlterField(
model_name='staffeducation',
name='major',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='专业'),
),
migrations.AlterField(
model_name='staffeducation',
name='school',
field=models.CharField(max_length=200, verbose_name='学校'),
),
migrations.AlterField(
model_name='staffeducation',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='educations', to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='staffeducation',
name='stage',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='教育阶段'),
),
migrations.AlterField(
model_name='staffeducation',
name='start_date',
field=models.DateField(blank=True, null=True, verbose_name='开始日期'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='birthdate',
field=models.DateField(blank=True, null=True, verbose_name='出生日期'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='name',
field=models.CharField(max_length=50, verbose_name='姓名'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='occupation',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='职业'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='phone_enc',
field=models.BinaryField(blank=True, help_text='AES-256-GCM 加密', null=True, verbose_name='电话(加密)'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='relation',
field=models.CharField(max_length=30, verbose_name='称谓'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='family_members', to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='stafffamilymember',
name='work_unit',
field=models.CharField(blank=True, default='', max_length=200, verbose_name='工作单位'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='birthdate',
field=models.DateField(blank=True, null=True, verbose_name='出生日期'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='domicile_address',
field=models.CharField(blank=True, default='', max_length=200, verbose_name='户口所在地'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='domicile_type',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='户籍性质'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='education_level',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='最高学历'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='emergency_contact',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='紧急联系人'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='emergency_phone_enc',
field=models.BinaryField(blank=True, null=True, verbose_name='紧急联系人电话(加密)'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='ethnicity',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='民族'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='gender',
field=models.CharField(blank=True, choices=[('male', ''), ('female', ''), ('unknown', '未知')], default='', help_text='male=男 / female=女 / unknown=未知', max_length=10, verbose_name='性别'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='has_children',
field=models.BooleanField(blank=True, null=True, verbose_name='有无子女'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='id_number_enc',
field=models.BinaryField(blank=True, help_text='AES 加密', null=True, verbose_name='证件号码(加密)'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='id_number_hash',
field=models.CharField(blank=True, db_index=True, help_text='SHA-256 哈希,实名认证比对用', max_length=64, null=True, verbose_name='证件号码哈希'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='id_type',
field=models.CharField(blank=True, choices=[('id_card', '身份证'), ('passport', '护照'), ('other', '其他')], default='', help_text='id_card=身份证 / passport=护照 / other=其他', max_length=20, verbose_name='证件类型'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='id_verified',
field=models.BooleanField(default=False, verbose_name='是否实名认证'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='id_verified_at',
field=models.DateTimeField(blank=True, null=True, verbose_name='认证时间'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='marital_status',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='婚姻状况'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='native_place',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='籍贯'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='political_status',
field=models.CharField(blank=True, default='', max_length=20, verbose_name='政治面貌'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='residence_address',
field=models.CharField(blank=True, default='', max_length=200, verbose_name='居住地址'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='staff',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='personal_info', serialize=False, to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='updated_at',
field=models.DateTimeField(auto_now=True, verbose_name='最后更新时间'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='updated_personal_info', to='org.staff', verbose_name='最后修改人'),
),
migrations.AlterField(
model_name='staffpersonalinfo',
name='work_start_date',
field=models.DateField(blank=True, null=True, verbose_name='参加工作时间'),
),
migrations.AlterField(
model_name='staffremark',
name='content',
field=models.TextField(verbose_name='备注内容'),
),
migrations.AlterField(
model_name='staffremark',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_remarks', to='org.staff', verbose_name='创建人'),
),
migrations.AlterField(
model_name='staffremark',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='remarks', to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='staffrewardpunish',
name='category',
field=models.CharField(help_text='枚举由 lookup_items 维护org.reward_punish_category', max_length=50, verbose_name='奖惩类别'),
),
migrations.AlterField(
model_name='staffrewardpunish',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_reward_punish', to='org.staff', verbose_name='录入人'),
),
migrations.AlterField(
model_name='staffrewardpunish',
name='name',
field=models.CharField(help_text='与类别联动', max_length=100, verbose_name='奖惩名称'),
),
migrations.AlterField(
model_name='staffrewardpunish',
name='remarks',
field=models.TextField(blank=True, default='', verbose_name='备注'),
),
migrations.AlterField(
model_name='staffrewardpunish',
name='rp_date',
field=models.DateField(verbose_name='奖惩日期'),
),
migrations.AlterField(
model_name='staffrewardpunish',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reward_punish_records', to='org.staff', verbose_name='被奖惩员工'),
),
migrations.AlterField(
model_name='stafftraining',
name='certificate',
field=models.CharField(blank=True, default='', max_length=200, verbose_name='证书'),
),
migrations.AlterField(
model_name='stafftraining',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trainings', to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='stafftraining',
name='training_date',
field=models.DateField(blank=True, null=True, verbose_name='培训日期'),
),
migrations.AlterField(
model_name='stafftraining',
name='training_name',
field=models.CharField(max_length=200, verbose_name='培训名称'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='new_value',
field=models.JSONField(blank=True, help_text='结构同 old_value', null=True, verbose_name='变动后值'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='old_value',
field=models.JSONField(blank=True, help_text='格式:{"field": "org_unit_id", "value": "...", "label": "门店A"}', null=True, verbose_name='变动前值'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='operated_at',
field=models.DateTimeField(auto_now_add=True, verbose_name='系统操作时间'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='operator',
field=models.ForeignKey(help_text='必填,异动审计必须记录', on_delete=django.db.models.deletion.RESTRICT, related_name='operated_transfers', to='org.staff', verbose_name='操作人'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='remarks',
field=models.CharField(blank=True, default='', help_text='最多50字', max_length=50, verbose_name='备注'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='transfer_logs', to='org.staff', verbose_name='被操作员工'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='transfer_date',
field=models.DateField(help_text='可以是过去日期', verbose_name='异动生效日期'),
),
migrations.AlterField(
model_name='stafftransferlog',
name='transfer_type',
field=models.CharField(choices=[('onboard', '入职'), ('transfer', '调动'), ('resign', '离职'), ('rejoin', '复职'), ('supervisor_change', '上级变更'), ('role_change', '角色变更'), ('freeze', '冻结账号'), ('unfreeze', '恢复账号')], help_text='onboard=入职 / transfer=调动 / resign=离职 / rejoin=复职 / supervisor_change=上级变动 / role_change=角色变更 / freeze=账号冻结 / unfreeze=账号恢复', max_length=30, verbose_name='异动类型'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='company',
field=models.CharField(max_length=200, verbose_name='公司名称'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='end_date',
field=models.DateField(blank=True, null=True, verbose_name='结束日期'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='job_title',
field=models.CharField(blank=True, default='', max_length=100, verbose_name='职位'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='reason',
field=models.CharField(blank=True, default='', max_length=200, verbose_name='离职原因'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='reference_name',
field=models.CharField(blank=True, default='', max_length=50, verbose_name='证明人姓名'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='reference_phone',
field=models.CharField(blank=True, default='', max_length=30, verbose_name='证明人电话'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='staff',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='work_experiences', to='org.staff', verbose_name='所属员工'),
),
migrations.AlterField(
model_name='staffworkexperience',
name='start_date',
field=models.DateField(blank=True, null=True, verbose_name='开始日期'),
),
]