""" @AUTHOR: zhuo @NAME: zhuojiaxuan @software: PyCharm @DATE: 2025/08/05 11:17 """ from django.db import transaction from django.views.generic.base import View from AgentModel.models import AgentMenu, AgentRoleMenu, AgentUserRole, AgentRole from Ansjer.cn_config.test_settings import LOGGING from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject from Service.CommonService import CommonService import time import json class AgentMenuView(View): def get(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.GET, request, operation) def post(self, request, *args, **kwargs): request.encoding = 'utf-8' operation = kwargs.get('operation') return self.validation(request.POST, request, operation) def validation(self, request_dict, request, operation): language = request_dict.get('language', 'en') response = ResponseObject(language, 'pc') tko = TokenObject(request.META.get('HTTP_AUTHORIZATION'), returntpye='pc') if tko.code != 0: return response.json(tko.code) response.lang = tko.lang userID = tko.userID if operation == 'getList': return self.getList(userID, request_dict, response) elif operation == 'doAdd': return self.doAdd(userID, request_dict, response) elif operation == 'doEdit': return self.doEdit(userID, request_dict, response) elif operation == 'doDelete': return self.doDelete(userID, request_dict, response) elif operation == 'getUserMenus': return self.getUserMenus(userID, request_dict, response) elif operation == 'getParentMenus': return self.getParentMenus(userID, request_dict, response) elif operation == 'getMenuDetail': return self.getMenuDetail(userID, request_dict, response) else: return response.json(404) #获取菜单列表 def getList(self, userID, request_dict, response): menu_name = request_dict.get('menu_name', '') pageNo = request_dict.get('pageNo', None) pageSize = request_dict.get('pageSize', None) # 如果不传分页参数,返回树形结构 if not pageNo or not pageSize: return self.getMenuTree(userID, request_dict, response) # 分页查询 page = int(pageNo) line = int(pageSize) if menu_name: menu_qs = AgentMenu.objects.filter(title__contains=menu_name).order_by('sort', 'id') else: menu_qs = AgentMenu.objects.all().order_by('sort', 'id') count = menu_qs.count() menu_qs = menu_qs[(page - 1) * line:page * line] list_data = [] for menu in menu_qs: parent_name = '' if menu.parentId > 0: try: parent_menu = AgentMenu.objects.get(id=menu.parentId) parent_name = parent_menu.title except AgentMenu.DoesNotExist: parent_name = '未知父菜单' list_data.append({ 'id': menu.id, 'parentId': menu.parentId, 'parentName': parent_name, 'path': menu.path, 'name': menu.name, 'component': menu.component, 'menutype': menu.menutype, 'menu_code': menu.menu_code, 'title': menu.title, 'icon': menu.icon, 'sort': menu.sort, 'hidden': menu.hidden, 'status': 1, # 默认启用 }) return response.json(0, {'list': list_data, 'total': count}) # 获取可作为父菜单的菜单列表 def getParentMenus(self, userID, request_dict, response): menus = AgentMenu.objects.filter(menutype=1).order_by('sort') # 只有菜单类型可以作为父菜单 list_data = [] for menu in menus: list_data.append({ 'id': menu.id, 'title': menu.title, 'parentId': menu.parentId }) return response.json(0, {'list': list_data}) # 获取菜单详情 def getMenuDetail(self, userID, request_dict, response): menu_id = request_dict.get('id', '') if not menu_id: return response.json(444, "缺少菜单ID") try: menu = AgentMenu.objects.get(id=menu_id) data = { 'id': menu.id, 'parentId': menu.parentId, 'path': menu.path, 'name': menu.name, 'component': menu.component, 'menutype': menu.menutype, 'menu_code': menu.menu_code, 'title': menu.title, 'icon': menu.icon, 'sort': menu.sort, 'hidden': menu.hidden } return response.json(0, data) except AgentMenu.DoesNotExist: return response.json(404, "菜单不存在") def doAdd(self, userID, request_dict, response): print(f"开始处理菜单添加 - userID: {userID}") data_dict = CommonService.request_dict_to_dict(request_dict) # 获取菜单类型 menutype = int(data_dict.get('menutype', 1)) # 根据菜单类型决定必填字段 required_fields = ['title', 'name', 'menutype'] # 仅当菜单类型为1(菜单)时,path和component为必填 if menutype == 1: # 菜单类型 required_fields.extend(['path']) for field in required_fields: if not data_dict.get(field): return response.json(444, f"缺少必填字段: {field}") # 按钮类型(menutype=2),确保有父级菜单 if menutype == 2 and int(data_dict.get('parentId', 0)) == 0: return response.json(500, "按钮类型必须指定父级菜单") path = data_dict.get('path') # 只有当提供了path且不为空时才检查唯一性 if path and AgentMenu.objects.filter(path=path).exists(): return response.json(500, "路径已存在,请修改后重试") name = data_dict.get('name') if AgentMenu.objects.filter(name=name).exists(): return response.json(500, "路由名称已存在,请修改后重试") parent_id = int(data_dict.get('parentId', 0)) if parent_id > 0 and not AgentMenu.objects.filter(id=parent_id).exists(): return response.json(500, "父菜单不存在") # 设置默认值 data_dict.setdefault('parentId', 0) data_dict.setdefault('component', '') data_dict.setdefault('path', '') data_dict.setdefault('hidden', False) data_dict.setdefault('icon', '') data_dict.setdefault('sort', 0) data_dict.setdefault('menu_code', '') try: with transaction.atomic(): menu = AgentMenu.objects.create(**data_dict) print(f"菜单创建成功 - ID: {menu.id}") # 自动给管理员角色分配新菜单权限 try: admin_roles = AgentRole.objects.filter(role_name__in=['admin', '管理员']) for admin_role in admin_roles: AgentRoleMenu.objects.get_or_create( role=admin_role, menu=menu ) print(f"权限分配完成") except Exception as e: print(f"自动分配权限失败: {str(e)}") success_response = response.json(0, { 'id': menu.id, 'message': "菜单创建成功" }) print(f"返回成功响应: {success_response}") return success_response except Exception as e: print(f"菜单创建异常: {str(e)}") return response.json(500, f"菜单创建失败: {str(e)}") def doEdit(self, userID, request_dict, response): print(f"开始处理菜单编辑 - userID: {userID}") data_dict = CommonService.request_dict_to_dict(request_dict) menu_id = data_dict.get('id') if not menu_id: return response.json(444, "缺少菜单ID") if not AgentMenu.objects.filter(id=menu_id).exists(): return response.json(404, "菜单不存在") # 移除id字段,避免更新主键 data_dict.pop('id', None) # 获取菜单类型 menutype = int(data_dict.get('menutype', 1)) # 如果是按钮类型(menutype=2),确保有父级菜单 if menutype == 2 and int(data_dict.get('parentId', 0)) == 0: return response.json(500, "按钮类型必须指定父级菜单") path = data_dict.get('path') # 只有当提供了path且不为空时才检查唯一性 if path and AgentMenu.objects.exclude(id=menu_id).filter(path=path).exists(): return response.json(500, "路径已存在,请修改后重试") name = data_dict.get('name') if name and AgentMenu.objects.exclude(id=menu_id).filter(name=name).exists(): return response.json(500, "路由名称已存在,请修改后重试") parent_id = data_dict.get('parentId') if parent_id and int(parent_id) == int(menu_id): return response.json(500, "不能设置自己为父菜单") # 明确处理字段类型 if 'parentId' in data_dict and data_dict['parentId'] is not None: data_dict['parentId'] = int(data_dict['parentId']) if 'sort' in data_dict and data_dict['sort'] is not None: data_dict['sort'] = int(data_dict['sort']) # 明确处理布尔类型字段 if 'hidden' in data_dict: if isinstance(data_dict['hidden'], str): data_dict['hidden'] = data_dict['hidden'].lower() == 'true' # 处理菜单类型 if 'menutype' in data_dict and data_dict['menutype'] is not None: data_dict['menutype'] = int(data_dict['menutype']) try: # 直接通过ID更新记录 rows_updated = AgentMenu.objects.filter(id=menu_id).update(**data_dict) print(f"更新结果: {rows_updated} 行被更新") if rows_updated: return response.json(0, "菜单更新成功") return response.json(500, "菜单更新失败:未找到匹配记录") except Exception as e: print(f"菜单更新失败: {str(e)}") return response.json(500, f"菜单更新失败: {str(e)}") def doDelete(self, userID, request_dict, response): menu_id = request_dict.get('id', '') if not menu_id: return response.json(444, "缺少菜单ID") try: menu = AgentMenu.objects.get(id=menu_id) except AgentMenu.DoesNotExist: return response.json(404, "菜单不存在") # 若有子菜单,需先删除子菜单 if AgentMenu.objects.filter(parentId=menu_id).exists(): return response.json(500, "该菜单下存在子菜单,请先删除子菜单") try: menu.delete() return response.json(0, "菜单删除成功") except Exception as e: return response.json(500, f"菜单删除失败: {str(e)}") def getUserMenus(self, userID, request_dict, response): """获取用户菜单 """ try: print(f"获取用户菜单 - userID: {userID}") # 根据用户ID获取用户的角色 user_roles = AgentUserRole.objects.filter(user_id=userID).values_list('role_id', flat=True) print(f"用户角色IDs: {list(user_roles)}") if not user_roles: print("用户没有分配角色,返回空菜单") return response.json(0, {'list': []}) # 根据用户角色获取所有可访问的菜单ID menu_ids = AgentRoleMenu.objects.filter( role_id__in=user_roles ).values_list('menu_id', flat=True).distinct() print(f"用户可访问的菜单IDs: {list(menu_ids)}") if not menu_ids: print("用户角色没有分配菜单权限") return response.json(0, {'list': []}) # 获取菜单数据(返回平铺结构,让前端构建树) menus = AgentMenu.objects.filter( id__in=menu_ids ).order_by('sort', 'id') list_data = [] for menu in menus: list_data.append({ 'id': menu.id, 'parentId': menu.parentId, 'path': menu.path, 'name': menu.name, 'component': menu.component, 'menutype': menu.menutype, 'menu_code': menu.menu_code, 'title': menu.title, 'icon': menu.icon, 'sort': menu.sort, 'hidden': menu.hidden, 'status': 1, }) print("实际返回菜单数据:", list_data) print(f"返回菜单数据: {len(list_data)} 条") return response.json(0, {'list': list_data}) except Exception as e: print(f"获取用户菜单失败: {str(e)}") return response.json(500, f"获取用户菜单失败: {str(e)}")