from django.apps import apps from django.contrib.auth.decorators import user_passes_test from functools import wraps from django.http import JsonResponse from django.shortcuts import redirect from django.core.exceptions import PermissionDenied from application.accounts.models import AccountProfile from application.pjt_mgnt.forms import ProjectLedgerForm, ProjectLedgerManagementForm def is_in_group(user, group_name): return user.groups.filter(name=group_name).exists() def group_required(group_name): return user_passes_test(lambda u: is_in_group(u, group_name)) def custom_permission_required(perm, raise_exception=False): def decorator(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): if request.user.has_perm(perm): return view_func(request, *args, **kwargs) if raise_exception: raise PermissionDenied return redirect('error_page') return _wrapped_view return decorator def permission_based_queryset(app_name, model_name, id_field, leader_field=None, department_field=None): def decorator(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): current_user = request.user try: account_profile = AccountProfile.objects.get(user=current_user) employee = account_profile.employee_information except AccountProfile.DoesNotExist: return JsonResponse({'message': '您的账户未关联到员工信息,请联系管理员。'}, status=405) model = apps.get_model(app_name, model_name) if account_profile.role == 'all_permissions': query_set = model.objects.all().order_by(f'-{id_field}') elif account_profile.role == 'department_permissions': filter_kwargs = {department_field: employee.primary_department} query_set = model.objects.filter(**filter_kwargs).order_by(f'-{id_field}') elif department_field and not leader_field and account_profile.role in ['department_permissions', 'own_permissions']: filter_kwargs = {department_field: employee.primary_department} query_set = model.objects.filter(**filter_kwargs).order_by(f'-{id_field}') elif leader_field and account_profile.role == 'own_permissions': filter_kwargs = {leader_field: employee.name} query_set = model.objects.filter(**filter_kwargs).order_by(f'-{id_field}') else: query_set = model.objects.none() request.query_set = query_set return view_func(request, *args, **kwargs) return _wrapped_view return decorator def dynamic_form_selection(view_func): @wraps(view_func) def _wrapped_view(request, *args, **kwargs): current_user = request.user try: account_profile = AccountProfile.objects.get(user=current_user) user_department = account_profile.employee_information.primary_department except AccountProfile.DoesNotExist: return JsonResponse({'message': '您的账户未关联到员工信息,请联系管理员。'}, status=405) if user_department == '中后台': request.form_class = ProjectLedgerManagementForm else: request.form_class = ProjectLedgerForm return view_func(request, *args, **kwargs) return _wrapped_view