Files
Django/migrate_to_gvsdsdk_user.py

260 lines
9.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
migrate_to_gvsdsdk_user.py — 将 UserMain 用户体系迁移到 gvsdsdk.User + RBAC
使用方式:
cd /opt/.../django
python manage.py shell < migrate_to_gvsdsdk_user.py
或:
python manage.py shell
>>> exec(open('migrate_to_gvsdsdk_user.py').read())
"""
import uuid
import datetime
from django.db import transaction
from django.conf import settings
# === 配置 ===
TENANT_UUID = uuid.uuid4().bytes # 本租户 UUID所有角色共用
COMPANY_UUID = uuid.uuid4().bytes # 默认公司 UUID
# 角色映射user_type → (RoleName, RoleDesc)
ROLE_MAP = {
'normal': ('消费者', '普通消费者/老板'),
'dashou': ('打手', '接单打手'),
'shop': ('商家', '发布订单的商家'),
'guanshi': ('负责人', '管事/负责人'),
'admin': ('管理员', '系统管理员'),
'kefu': ('客服', '客服人员'),
'zuzhang': ('组长', '组长'),
'shenheguan': ('审核官', '审核官'),
}
# 权限映射:每个角色拥有的权限码
PERMISSION_MAP = {
'消费者': ['view_orders', 'create_order', 'view_own_profile'],
'打手': ['view_orders', 'accept_order', 'view_own_profile', 'withdraw'],
'商家': ['view_orders', 'create_order', 'view_own_profile', 'withdraw', 'manage_own_orders'],
'负责人': ['view_orders', 'view_own_profile', 'withdraw', 'invite_dashou', 'view_dashou_stats'],
'管理员': ['admin_access', 'manage_users', 'view_all_orders', 'manage_orders', 'view_stats', 'manage_fines'],
'客服': ['kefu_access', 'view_orders', 'manage_orders', 'apply_fine', 'view_stats'],
'组长': ['view_orders', 'view_own_profile', 'withdraw', 'invite_dashou'],
'审核官': ['view_orders', 'review_orders', 'view_own_profile', 'withdraw'],
}
def run_migration():
from gvsdsdk.models import User, Role, Permission, UserRole, RolePermission
from users.models import (
UserMain, UserBoss, UserDashou, UserShangjia, UserGuanshi,
UserZuzhang, UserShenheguan, AdminProfile, UserKefu,
UserSensitiveData
)
print("=" * 60)
print("开始迁移 UserMain → gvsdsdk.User + RBAC")
print("=" * 60)
# ========== 第1步创建租户下的角色和权限 ==========
print("\n[1/6] 创建角色和权限...")
created_roles = {}
created_perms = {}
for user_type, (role_name, role_desc) in ROLE_MAP.items():
# 创建角色
role, created = Role.objects.get_or_create(
RoleName=role_name,
TenantUUID=TENANT_UUID,
defaults={
'RoleUUID': uuid.uuid4().bytes,
'RoleDesc': role_desc,
'RoleStatus': 1,
'AssignScope': 0,
}
)
if created:
print(f" 创建角色: {role_name}")
created_roles[user_type] = role
# 创建该角色的权限
perm_codes = PERMISSION_MAP.get(role_name, [])
for perm_code in perm_codes:
perm, perm_created = Permission.objects.get_or_create(
PermCode=perm_code,
TenantUUID=TENANT_UUID,
defaults={
'PermUUID': uuid.uuid4().bytes,
'PermName': perm_code,
'PermCategory': role_name,
'PermStatus': 1,
}
)
if perm_created:
print(f" 创建权限: {perm_code}")
created_perms[perm_code] = perm
# 关联角色-权限
RolePermission.objects.get_or_create(
RoleUUID=role.RoleUUID,
PermUUID=perm.PermUUID,
defaults={
'RolePermUUID': uuid.uuid4().bytes,
}
)
# ========== 第2步迁移用户 ==========
print("\n[2/6] 迁移用户数据...")
user_main_qs = UserMain.objects.all()
total = user_main_qs.count()
print(f"{total} 个用户待迁移")
# 构建 yonghuid → UserUUID 映射
uid_map = {} # yonghuid → UserUUID (bytes)
for i, um in enumerate(user_main_qs):
if (i + 1) % 100 == 0:
print(f" 进度: {i+1}/{total}")
user_uuid = uuid.uuid4().bytes
# 创建 gvsdsdk User
user = User.objects.create(
UserUUID=user_uuid,
UserName=um.yonghuid, # 用 yonghuid 作为用户名
UserUID=um.yonghuid,
OpenID=um.openid or '',
UnionID=um.unionid or '',
Avatar=um.avatar or 'a_long/morentouxiang.jpg',
Phone=um.phone or '',
PhoneVerified=um.shoujihao_renzheng or False,
IP=um.ip or '',
UserAccountLicense=1,
UserPositionStatus=0,
UserCreateTime=um.create_time or datetime.datetime.utcnow(),
UserLastLoginDate=um.last_login_time or datetime.datetime.utcnow(),
IsStaff=(um.user_type == 'admin'),
IsSuperuser=(um.user_type == 'admin'),
)
uid_map[um.yonghuid] = user_uuid
# 创建 UserRole
user_type = um.user_type or 'normal'
role = created_roles.get(user_type)
if role:
UserRole.objects.create(
UserRoleUUID=uuid.uuid4().bytes,
UserUUID=user_uuid,
RoleUUID=role.RoleUUID,
CompanyUUID=COMPANY_UUID,
)
# 创建 UserSensitiveData
UserSensitiveData.objects.create(
user_uuid_id=user_uuid,
password=um.password or '',
zhifu=um.zhifu or '',
skzhanghao=um.skzhanghao or '',
shoujihao_renzheng=um.shoujihao_renzheng or False,
)
print(f" 用户迁移完成: {len(uid_map)}")
# ========== 第3步迁移扩展表 FK ==========
print("\n[3/6] 迁移扩展表 FK...")
ext_tables = [
('UserBoss', UserBoss, 'boss_profile'),
('UserDashou', UserDashou, 'dashou_profile'),
('UserShangjia', UserShangjia, 'shop_profile'),
('UserGuanshi', UserGuanshi, 'guanshi_profile'),
('UserZuzhang', UserZuzhang, 'zuzhang_profile'),
('UserShenheguan', UserShenheguan, 'shenheguan_profile'),
('AdminProfile', AdminProfile, 'admin_profile'),
('UserKefu', UserKefu, 'kefu_profile'),
]
for table_name, model, _ in ext_tables:
count = 0
for obj in model.objects.all():
old_user_id = obj.user_id # 旧 FK (UserMain.id)
# 通过旧 UserMain 查找 yonghuid → 新 UserUUID
try:
old_user = UserMain.objects.get(id=old_user_id)
new_uuid = uid_map.get(old_user.yonghuid)
if new_uuid:
obj.user_id = new_uuid # 更新 FK 为新 UserUUID
obj.save(update_fields=['user_id'])
count += 1
except UserMain.DoesNotExist:
pass
print(f" {table_name}: 迁移 {count}")
# ========== 第4步迁移其他引用 yonghuid 的表 ==========
print("\n[4/6] 迁移其他表的 yonghuid 引用...")
# Tixianjilu, TixianShenheJilu, TixianAutoRecord, Xiugaijilu, RankingRecord
# 这些表使用 yonghuid 字符串字段不需要修改UserUID 保留相同值)
print(" 这些表使用 yonghuid 字符串字段,值不变,无需迁移")
# ========== 第5步迁移 backend.UserRole ==========
print("\n[5/6] 迁移 backend.UserRole...")
from backend.models import UserRole as BackendUserRole
count = 0
for bur in BackendUserRole.objects.all():
# account_id 是手机号,查找对应的 UserMain → 新 UserUUID
try:
um = UserMain.objects.get(phone=bur.account_id)
new_uuid = uid_map.get(um.yonghuid)
if new_uuid:
# 查找对应的新角色
old_role = bur.role
# 尝试匹配角色名
role_name_map = {
'客服': 'kefu', '打手': 'dashou', '商家': 'shop',
'管事': 'guanshi', '管理员': 'admin', '组长': 'zuzhang',
'审核官': 'shenheguan', '消费者': 'normal',
}
new_role = None
for ut, r in created_roles.items():
if old_role.role_name in r.RoleName or old_role.role_code in ut:
new_role = r
break
if new_role:
UserRole.objects.get_or_create(
UserUUID=new_uuid,
RoleUUID=new_role.RoleUUID,
CompanyUUID=COMPANY_UUID,
defaults={'UserRoleUUID': uuid.uuid4().bytes}
)
count += 1
except UserMain.DoesNotExist:
pass
print(f" 迁移 {count} 条 backend.UserRole")
# ========== 第6步验证 ==========
print("\n[6/6] 验证迁移结果...")
new_user_count = User.objects.count()
new_role_count = Role.objects.filter(TenantUUID=TENANT_UUID).count()
new_perm_count = Permission.objects.filter(TenantUUID=TENANT_UUID).count()
new_ur_count = UserRole.objects.count()
print(f" gvsdsdk.User: {new_user_count}")
print(f" Role: {new_role_count}")
print(f" Permission: {new_perm_count}")
print(f" UserRole: {new_ur_count}")
print(f" UserSensitiveData: {UserSensitiveData.objects.count()}")
print("\n" + "=" * 60)
print("迁移完成!")
print(f"TENANT_UUID = {uuid.UUID(bytes=TENANT_UUID)}")
print(f"COMPANY_UUID = {uuid.UUID(bytes=COMPANY_UUID)}")
print("请将这两个 UUID 保存到 settings.py 中")
print("=" * 60)
if __name__ == '__main__':
run_migration()