diff --git a/users/management/commands/generate_test_data.py b/users/management/commands/generate_test_data.py new file mode 100644 index 0000000..b59d069 --- /dev/null +++ b/users/management/commands/generate_test_data.py @@ -0,0 +1,521 @@ +# generate_test_data.py +import os + +import django + +# 设置 Django 环境 +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings') +django.setup() + +from django.core.management.base import BaseCommand +from django.db import transaction +from django.contrib.auth.hashers import make_password +from users.models import Department, Menu, Role, User + + +class Command(BaseCommand): + help = '生成有逻辑的测试数据(可重复运行,自动跳过已存在项)' + + def handle(self, *args, **options): + self.stdout.write("🚀 开始生成测试数据(幂等模式)...") + + try: + with transaction.atomic(): + departments = self._create_departments() + menus = self._create_menus() + roles = self._create_roles(menus) + self._create_users(departments, roles) + except Exception as e: + self.stderr.write(f"❌ 生成失败: {e}") + return + + self.stdout.write( + self.style.SUCCESS("✅ 测试数据生成完成!可安全重复运行。") + ) + self.stdout.write("\n📌 登录信息:") + self.stdout.write(" - 超级管理员: admin / admin123") + self.stdout.write(" - 技术经理: techmgr / tech123") + self.stdout.write(" - HR专员: hr1 / hr123") + + def _get_or_create_dept(self, name, parent=None, order=0): + """获取或创建部门(按名称+父部门唯一)""" + dept, created = Department.objects.get_or_create( + name=name, + parent=parent, + defaults={'order': order} + ) + if created: + self.stdout.write(f" ➕ 部门: {dept.name}") + return dept + + def _create_departments(self): + self.stdout.write("🔄 同步部门结构...") + company = self._get_or_create_dept("总公司", None, 0) + tech = self._get_or_create_dept("技术部", company, 1) + hr = self._get_or_create_dept("人力资源部", company, 2) + finance = self._get_or_create_dept("财务部", company, 3) + backend = self._get_or_create_dept("后端开发组", tech, 1) + frontend = self._get_or_create_dept("前端开发组", tech, 2) + recruitment = self._get_or_create_dept("招聘组", hr, 1) + + return { + 'company': company, + 'tech': tech, + 'hr': hr, + 'finance': finance, + 'backend': backend, + 'frontend': frontend, + 'recruitment': recruitment, + } + + def _get_or_create_menu(self, code, defaults): + """按 code 获取或创建菜单""" + menu, created = Menu.objects.get_or_create(code=code, defaults=defaults) + if created: + self.stdout.write(f" ➕ 菜单: {menu.name} ({menu.code})") + return menu + + def _create_menus(self): + self.stdout.write("🔄 同步菜单结构...") + + # ======================== + # 1. 系统管理(保持不变) + # ======================== + system = self._get_or_create_menu("system", { + "name": "系统管理", + "menu_type": 0, + "permission_code": "system:settings", + "order_num": 1 + }) + + user_menu = self._get_or_create_menu("user", { + "name": "用户管理", + "parent": system, + "path": "/system/user", + "component": "system/UserManage", + "permission_code": "user:list", + "menu_type": 1, + "order_num": 1 + }) + role_menu = self._get_or_create_menu("role", { + "name": "角色管理", + "parent": system, + "path": "/system/role", + "component": "system/RoleManage", + "permission_code": "role:list", + "menu_type": 1, + "order_num": 2 + }) + menu_menu = self._get_or_create_menu("menu", { + "name": "菜单管理", + "parent": system, + "path": "/system/menu", + "component": "system/Menu", + "permission_code": "menu:list", + "menu_type": 1, + "order_num": 3 + }) + dept_menu = self._get_or_create_menu("dept", { + "name": "部门管理", + "parent": system, + "path": "/system/dept", + "component": "system/DeptManage", + "permission_code": "dept:list", + "menu_type": 1, + "order_num": 4 + }) + + # --- 系统管理: list 权限(关键补充!)--- + self._get_or_create_menu("user_list", { + "name": "查看用户列表", + "parent": user_menu, + "permission_code": "user:list", + "menu_type": 2 + }) + self._get_or_create_menu("role_list", { + "name": "查看角色列表", + "parent": role_menu, + "permission_code": "role:list", + "menu_type": 2 + }) + self._get_or_create_menu("menu_list", { + "name": "查看菜单列表", + "parent": menu_menu, + "permission_code": "menu:list", + "menu_type": 2 + }) + # ================= 新增:菜单管理的按钮权限 ================= + self._get_or_create_menu("menu_list", { + "name": "查看菜单列表", + "parent": menu_menu, + "permission_code": "menu:list", + "menu_type": 2 + }) + self._get_or_create_menu("menu_create", { + "name": "新增菜单", + "parent": menu_menu, + "permission_code": "menu:create", + "menu_type": 2 + }) + self._get_or_create_menu("menu_update", { + "name": "编辑菜单", + "parent": menu_menu, + "permission_code": "menu:update", + "menu_type": 2 + }) + self._get_or_create_menu("menu_delete", { + "name": "删除菜单", + "parent": menu_menu, + "permission_code": "menu:delete", + "menu_type": 2 + }) + self._get_or_create_menu("dept_list", { + "name": "查看部门列表", + "parent": dept_menu, + "permission_code": "dept:list", + "menu_type": 2 + }) + # ================= 新增:部门管理的按钮权限 ================= + self._get_or_create_menu("dept_list", { + "name": "查看部门列表", + "parent": dept_menu, + "permission_code": "dept:list", + "menu_type": 2 + }) + self._get_or_create_menu("dept_create", { + "name": "新增部门", + "parent": dept_menu, + "permission_code": "dept:create", + "menu_type": 2 + }) + self._get_or_create_menu("dept_update", { + "name": "编辑部门", + "parent": dept_menu, + "permission_code": "dept:update", + "menu_type": 2 + }) + self._get_or_create_menu("dept_delete", { + "name": "删除部门", + "parent": dept_menu, + "permission_code": "dept:delete", + "menu_type": 2 + }) + # --- 系统管理: 其他按钮权限 --- + self._get_or_create_menu("user_create", { + "name": "新增用户", + "parent": user_menu, + "permission_code": "user:create", + "menu_type": 2 + }) + self._get_or_create_menu("user_update", { + "name": "编辑用户", + "parent": user_menu, + "permission_code": "user:update", + "menu_type": 2 + }) + self._get_or_create_menu("user_delete", { + "name": "删除用户", + "parent": user_menu, + "permission_code": "user:delete", + "menu_type": 2 + }) + self._get_or_create_menu("user_reset_pwd", { + "name": "重置密码", + "parent": user_menu, + "permission_code": "user:reset_password", + "menu_type": 2 + }) + self._get_or_create_menu("role_assign", { + "name": "分配角色", + "parent": role_menu, + "permission_code": "user:assign_roles", + "menu_type": 2 + }) + self._get_or_create_menu("role_create", { + "name": "新增角色", + "parent": role_menu, + "permission_code": "role:create", + "menu_type": 2 + }) + self._get_or_create_menu("role_update", { + "name": "编辑角色", + "parent": role_menu, + "permission_code": "role:update", + "menu_type": 2 + }) + self._get_or_create_menu("role_delete", { + "name": "删除角色", + "parent": role_menu, + "permission_code": "role:delete", + "menu_type": 2 + }) + self._get_or_create_menu("role_set_perms", { + "name": "设置权限", + "parent": role_menu, + "permission_code": "role:set_permissions", + "menu_type": 2 + }) + # ======================== + # 2. 内容管理(仅保留动态内容类) + # ======================== + content = self._get_or_create_menu("content", { + "name": "内容管理", + "menu_type": 0, + "permission_code": "system:content", + "order_num": 2 + }) + + # 仅保留这些在“内容管理”下 + dynamic_content_models = [ + ("article", "文章管理", 1, "ArticleList"), + ("carousel", "轮播图管理", 2, "CarouselList"), + ("notice", "公告管理", 3, "NoticeList"), + ("newssection", "新闻栏目", 4, "NewsSection"), + ("news", "新闻管理", 5, "NewsList"), + ] + + content_menus = {} + for code, name, order, component in dynamic_content_models: + menu = self._get_or_create_menu(code, { + "name": name, + "parent": content, + "path": f"/content/{code}", + "component": f"content/{component}", + "permission_code": f"{code}:list", + "menu_type": 1, + "order_num": order + }) + content_menus[code] = menu + + # 添加 list + CRUD 权限 + self._get_or_create_menu(f"{code}_list", { + "name": f"查看{name}", + "parent": menu, + "permission_code": f"{code}:list", + "menu_type": 2 + }) + self._get_or_create_menu(f"{code}_create", { + "name": f"新增{name}", + "parent": menu, + "permission_code": f"{code}:create", + "menu_type": 2 + }) + self._get_or_create_menu(f"{code}_update", { + "name": f"编辑{name}", + "parent": menu, + "permission_code": f"{code}:update", + "menu_type": 2 + }) + self._get_or_create_menu(f"{code}_delete", { + "name": f"删除{name}", + "parent": menu, + "permission_code": f"{code}:delete", + "menu_type": 2 + }) + + # --- 公告特殊权限(保持不变)--- + notice_menu = content_menus["notice"] + self._get_or_create_menu("notice_mark_read", { + "name": "标记公告已读", + "parent": notice_menu, + "permission_code": "notice:mark_as_read", + "menu_type": 2 + }) + self._get_or_create_menu("notice_view_receipts", { + "name": "查看公告回执", + "parent": notice_menu, + "permission_code": "notice:view_receipts", + "menu_type": 2 + }) + + # ======================== + # 3. 新增:站点配置(原属于内容管理的静态配置类) + # ======================== + site_config = self._get_or_create_menu("site_config", { + "name": "站点配置", + "menu_type": 0, + "order_num": 3 # 排在内容管理之后 + }) + + site_config_models = [ + ("baseinfo", "基础信息", 1, "BaseInfo"), + ("mainmenu", "主导航菜单", 2, "MainMenu"), + ("picturelink", "图片链接", 3, "PictureLink"), + ("friendlink", "友情链接", 4, "FriendLink"), + ("linkcategory", "链接分类", 5, "LinkCategory"), + ] + + for code, name, order, component in site_config_models: + menu = self._get_or_create_menu(code, { + "name": name, + "parent": site_config, + "path": f"/config/{code}", + "component": f"config/{component}", # 建议组件路径也调整为 config/ + "permission_code": f"{code}:list", + "menu_type": 1, + "order_num": order + }) + content_menus[code] = menu # 仍加入字典以便返回 + + # 添加 list + CRUD 权限 + self._get_or_create_menu(f"{code}_list", { + "name": f"查看{name}", + "parent": menu, + "permission_code": f"{code}:list", + "menu_type": 2 + }) + self._get_or_create_menu(f"{code}_create", { + "name": f"新增{name}", + "parent": menu, + "permission_code": f"{code}:create", + "menu_type": 2 + }) + self._get_or_create_menu(f"{code}_update", { + "name": f"编辑{name}", + "parent": menu, + "permission_code": f"{code}:update", + "menu_type": 2 + }) + self._get_or_create_menu(f"{code}_delete", { + "name": f"删除{name}", + "parent": menu, + "permission_code": f"{code}:delete", + "menu_type": 2 + }) + + return { + 'system': system, + 'user': user_menu, + 'role': role_menu, + 'menu': menu_menu, + 'dept': dept_menu, + 'content': content, + 'site_config': site_config, # 新增返回 + **content_menus, + } + + def _get_or_create_role(self, code, name, description, status=True): + """按 code 获取或创建角色""" + role, created = Role.objects.get_or_create( + code=code, + defaults={ + 'name': name, + 'description': description, + 'status': status + } + ) + if created: + self.stdout.write(f" ➕ 角色: {role.name}") + return role + + def _create_roles(self, menus): + self.stdout.write("🔄 同步角色权限...") + + admin_role = self._get_or_create_role( + "admin", "超级管理员", "拥有全部权限" + ) + tech_manager_role = self._get_or_create_role( + "tech_manager", "技术部经理", "管理技术部用户" + ) + hr_role = self._get_or_create_role( + "hr_staff", "HR专员", "查看员工信息" + ) + employee_role = self._get_or_create_role( + "employee", "普通员工", "无管理权限" + ) + + # 分配菜单权限(幂等设置) + all_menus = Menu.objects.all() + admin_role.menus.set(all_menus) + + tech_manager_role.menus.set([ + menus['user'], menus['role'], menus['dept'], + Menu.objects.get(permission_code="user:create"), + Menu.objects.get(permission_code="user:delete"), + Menu.objects.get(permission_code="user:assign_roles"), + ]) + + hr_role.menus.set([menus['user']]) + employee_role.menus.set([]) + + return { + 'admin': admin_role, + 'tech_manager': tech_manager_role, + 'hr': hr_role, + 'employee': employee_role, + } + + def _get_or_create_user(self, username, defaults, roles): + """获取或创建用户,并设置角色""" + user, created = User.objects.get_or_create( + username=username, + defaults=defaults + ) + if created: + self.stdout.write(f" ➕ 用户: {user.cname} ({user.username})") + # 无论是否新建,都确保角色正确(幂等) + user.roles.set(roles) + return user + + def _create_users(self, departments, roles): + self.stdout.write("🔄 同步用户账号...") + + self._get_or_create_user( + "admin", + { + "cname": "系统管理员", + "phone": "13800000000", + "password": make_password("adminadmin"), + "dept": departments['company'], + "is_active": True, + }, + [roles['admin']] + ) + + self._get_or_create_user( + "techmgr", + { + "cname": "张经理", + "phone": "13800000001", + "password": make_password("adminadmin"), + "dept": departments['tech'], + "is_active": True, + }, + [roles['tech_manager']] + ) + + self._get_or_create_user( + "dev1", + { + "cname": "李开发", + "phone": "13800000002", + "password": make_password("adminadmin"), + "dept": departments['backend'], + "is_active": True, + }, + [roles['employee']] + ) + + self._get_or_create_user( + "hr1", + { + "cname": "王HR", + "phone": "13800000003", + "password": make_password("adminadmin"), + "dept": departments['hr'], + "is_active": True, + }, + [roles['hr']] + ) + + self._get_or_create_user( + "finance1", + { + "cname": "赵会计", + "phone": "13800000004", + "password": make_password("adminadmin"), + "dept": departments['finance'], + "is_active": True, + }, + [roles['employee']] + )