import json from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from django.http import JsonResponse from django.shortcuts import render from django.urls import reverse from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.decorators import api_view, permission_classes from common.utils.page_helper import paginate_query_and_assign_numbers from .models import GroupBusinessTarget, TargetAudit, EmployeeTargetAudit, EmployeePerformanceTarget from .serializers import TargetAuditSerializer, EmployeeTargetAuditSerializer def gbo_list_view(request): # 声明查询集 query_set = GroupBusinessTarget.objects.filter().order_by('-target_id') # 获取查询参数 primary_department = request.GET.get('primary_department', '') year = request.GET.get('year', '') project_nature = request.GET.get('project_nature', '') # 根据提供的参数进行筛选 if primary_department: query_set = query_set.filter(primary_department=primary_department) if year: query_set = query_set.filter(year=year) if project_nature: query_set = query_set.filter(project_nature=project_nature) # 对查询结果进行分页,每页10条记录 items = paginate_query_and_assign_numbers( request=request, queryset=query_set, per_page=10 ) # 构建上下文查询参数字符串 query_params = '&primary_department={}&year={}&project_nature={}'.format(primary_department, year, project_nature) # Excel上传模板 template_name = "业绩管理-集团经营目标-Excel上传模板.xlsx" # 构建上下文 context = { "model_config": 'perf_mgnt.GroupBusinessTarget', "items": items, "breadcrumb_list": [ {"title": "首页", "name": "index"}, {"title": "基础数据", "name": "index"}, {"title": "集团经营目标表", "name": "gbo_list"} ], "filters": [ { "type": "select", "id": "primary_department", "name": "primary_department", "label": "一级部门", "options": [ {"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"}, {"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"}, {"value": "星海", "display": "星海"} ] }, { "type": "select", "id": "year", "name": "year", "label": "年份", "options": [ {"value": "2024", "display": "2024"}, {"value": "2023", "display": "2023"}, {"value": "2022", "display": "2022"}, {"value": "2021", "display": "2021"}, {"value": "2020", "display": "2020"} ] }, { "type": "select", "id": "project_nature", "name": "project_nature", "label": "项目性质", "options": [ {"value": "新增", "display": "新增"}, {"value": "存续", "display": "存续"}, {"value": "新增及存续", "display": "新增及存续"}, {"value": "老客户新业务", "display": "老客户新业务"} ] } ], "excel_upload_config": { "template_url": reverse("download_template", kwargs={'template_name': template_name}), "parse_url": reverse("common_excel_parse"), "save_url": reverse("save_excel_table_data"), "fields_preview_config": { "target_id": {"type": "text", "width": "180px"}, "primary_department": {"type": "select", "options": ["天信", "混改", "艾力芬特", "星河", "星海"], "width": "180px"}, "year": {"type": "select", "options": ["2024", "2023", "2022", "2021", "2020"], "width": "180px"}, "project_nature": {"type": "select", "options": ["新增", "存续", "新增及存续", "老客户新业务"], "width": "180px"}, "sales": {"type": "text", "width": "180px"}, "total_revenue_target": {"type": "text", "width": "180px"}, "new_revenue_target": {"type": "text", "width": "180px"}, "existing_revenue_target": {"type": "text", "width": "180px"}, "cost_limit": {"type": "text", "width": "180px"}, "gross_profit": {"type": "text", "width": "180px"}, "expense_limit": {"type": "text", "width": "180px"}, "operating_profit": {"type": "text", "width": "180px"}, "actions": {"type": "actions", "width": "100px"} } }, "query_params": query_params, "form_action_url": 'gbo_list', "modify_url": reverse("gbo_list_modify"), "add_url": reverse("gbo_list_add"), "delete_url": reverse("gbo_list_delete"), } return render(request, '../templates/list.html', context) def gbo_list_add(request): """ 添加集团经营目标数据 """ # 获取表单数据 primary_department = request.POST.get('primary_department') year = request.POST.get('year') project_nature = request.POST.get('project_nature') sales = request.POST.get('sales') total_revenue_target = request.POST.get('total_revenue_target') new_revenue_target = request.POST.get('new_revenue_target') existing_revenue_target = request.POST.get('existing_revenue_target') cost_limit = request.POST.get('cost_limit') gross_profit = request.POST.get('gross_profit') expense_limit = request.POST.get('expense_limit') operating_profit = request.POST.get('operating_profit') # 创建新的集团经营目标数据 new_gbo_data = GroupBusinessTarget( primary_department=primary_department, year=year, project_nature=project_nature, sales=sales, total_revenue_target=total_revenue_target, new_revenue_target=new_revenue_target, existing_revenue_target=existing_revenue_target, cost_limit=cost_limit, gross_profit=gross_profit, expense_limit=expense_limit, operating_profit=operating_profit ) new_gbo_data.save() # 返回添加成功的消息 return JsonResponse({'message': '添加成功'}) def gbo_list_delete(request): if request.method == 'GET': target_id = request.GET.get('target_id') try: target = GroupBusinessTarget.objects.get(target_id=target_id) target.delete() return JsonResponse({'message': '删除成功'}, status=200) except GroupBusinessTarget.DoesNotExist: return JsonResponse({'message': '记录不存在'}, status=404) except Exception as e: return JsonResponse({'message': '删除失败', 'error': str(e)}, status=400) return JsonResponse({'message': '无效的请求方法'}, status=405) def gbo_list_modify(request): """ 修改集团经营目标数据 """ try: # 获取表单数据 target_id = request.POST.get('target_id') primary_department = request.POST.get('primary_department') year = request.POST.get('year') project_nature = request.POST.get('project_nature') sales = request.POST.get('sales') total_revenue_target = request.POST.get('total_revenue_target') new_revenue_target = request.POST.get('new_revenue_target') existing_revenue_target = request.POST.get('existing_revenue_target') cost_limit = request.POST.get('cost_limit') gross_profit = request.POST.get('gross_profit') expense_limit = request.POST.get('expense_limit') operating_profit = request.POST.get('operating_profit') # 获取需要修改的对象 target = GroupBusinessTarget.objects.get(target_id=target_id) # 获取当前用户 modified_by = request.user.username # 比较新旧数据,找出修改的字段 changes = [] if target.primary_department != primary_department: changes.append(('primary_department', target.primary_department, primary_department)) if target.year != int(year): changes.append(('year', target.year, year)) if target.project_nature != project_nature: changes.append(('project_nature', target.project_nature, project_nature)) if target.sales != float(sales): changes.append(('sales', target.sales, sales)) if target.total_revenue_target != float(total_revenue_target): changes.append(('total_revenue_target', target.total_revenue_target, total_revenue_target)) if target.new_revenue_target != float(new_revenue_target): changes.append(('new_revenue_target', target.new_revenue_target, new_revenue_target)) if target.existing_revenue_target != float(existing_revenue_target): changes.append(('existing_revenue_target', target.existing_revenue_target, existing_revenue_target)) if target.cost_limit != float(cost_limit): changes.append(('cost_limit', target.cost_limit, cost_limit)) if target.gross_profit != float(gross_profit): changes.append(('gross_profit', target.gross_profit, gross_profit)) if target.expense_limit != float(expense_limit): changes.append(('expense_limit', target.expense_limit, expense_limit)) if target.operating_profit != float(operating_profit): changes.append(('operating_profit', target.operating_profit, operating_profit)) FIELD_NAME_MAP = { 'primary_department': '一级部门', 'year': '年份', 'project_nature': '项目性质', 'sales': '销售额', 'total_revenue_target': '收入总目标', 'new_revenue_target': '新增收入目标', 'existing_revenue_target': '存量收入目标', 'cost_limit': '成本限额', 'gross_profit': '毛利润', 'expense_limit': '费用限额', 'operating_profit': '营业利润' } # 生成修改记录 for field, old_value, new_value in changes: TargetAudit.objects.create( target_id=target, modified_field=FIELD_NAME_MAP.get(field, field), old_value=old_value, new_value=new_value, modified_by=modified_by ) # 修改数据 target.primary_department = primary_department target.year = year target.project_nature = project_nature target.sales = sales target.total_revenue_target = total_revenue_target target.new_revenue_target = new_revenue_target target.existing_revenue_target = existing_revenue_target target.cost_limit = cost_limit target.gross_profit = gross_profit target.expense_limit = expense_limit target.operating_profit = operating_profit # 保存修改 target.save() return JsonResponse({'message': '修改成功'}, status=200) except GroupBusinessTarget.DoesNotExist: return JsonResponse({'message': '记录不存在'}, status=404) except Exception as e: return JsonResponse({'message': '修改失败', 'error': str(e)}, status=400) @api_view(['GET']) @permission_classes([IsAuthenticated]) def gbo_audit_record_list_view(request): """ 获取集团目标修改记录,支持分页。 """ # 设置每页显示的记录数,默认为10 per_page = request.GET.get('per_page', 5) page_number = request.GET.get('page', 1) # 获取所有修改记录的查询集 queryset = TargetAudit.objects.all().order_by('-modification_date') # 使用Django的Paginator进行分页处理 paginator = Paginator(queryset, per_page) try: page_obj = paginator.page(page_number) except EmptyPage: page_obj = paginator.page(paginator.num_pages) # 如果页码太大,显示最后一页 except PageNotAnInteger: page_obj = paginator.page(1) # 如果页码不是整数,显示第一页 # 序列化分页后的数据 serializer = TargetAuditSerializer(page_obj, many=True) # 构造响应数据,包含分页信息 response_data = { 'modal_title': '集团经营目标修改记录', 'columns': ['修改对象', '修改字段', '旧值', '新值', '修改时间', '修改人'], 'records': serializer.data, 'page': page_obj.number, 'num_pages': paginator.num_pages, 'has_previous': page_obj.has_previous(), 'has_next': page_obj.has_next(), 'start_index': page_obj.start_index(), 'end_index': page_obj.end_index(), 'total_items': paginator.count } return Response(response_data) def emt_list_view(request): # 声明查询集 query_set = EmployeePerformanceTarget.objects.filter().order_by('-target_id') # 获取查询参数 name = request.GET.get('name', '') department = request.GET.get('department', '') year = request.GET.get('year', '') project_nature = request.GET.get('project_nature', '') # 根据提供的参数进行筛选 if name: query_set = query_set.filter(name=name) if department: query_set = query_set.filter(department=department) if year: query_set = query_set.filter(year=year) if project_nature: query_set = query_set.filter(project_nature=project_nature) # 对查询结果进行分页,每页10条记录 items = paginate_query_and_assign_numbers( request=request, queryset=query_set, per_page=10 ) # 构建上下文查询参数字符串 query_params = '&name={}&department={}&year={}&project_nature={}'.format(name, department, year, project_nature) # Excel上传模板 template_name = "业绩管理-员工业绩目标-Excel上传模板.xlsx" # 构建上下文 context = { "model_config": 'perf_mgnt.EmployeePerformanceTarget', "items": items, "breadcrumb_list": [ {"title": "首页", "name": "index"}, {"title": "业绩管理", "name": "index"}, {"title": "员工业绩目标表", "name": "emt_list"} ], "filters": [ {"type": "text", "id": "name", "name": "name", "label": "姓名", "placeholder": "请输入姓名"}, { "type": "select", "id": "department", "name": "department", "label": "一级部门", "options": [ {"value": "天信", "display": "天信"}, {"value": "混改", "display": "混改"}, {"value": "艾力芬特", "display": "艾力芬特"}, {"value": "星河", "display": "星河"}, {"value": "星海", "display": "星海"} ] }, { "type": "select", "id": "year", "name": "year", "label": "年份", "options": [ {"value": "2024", "display": "2024"}, {"value": "2023", "display": "2023"}, {"value": "2022", "display": "2022"}, {"value": "2021", "display": "2021"}, {"value": "2020", "display": "2020"} ] }, { "type": "select", "id": "project_nature", "name": "project_nature", "label": "项目性质", "options": [ {"value": "新增", "display": "新增"}, {"value": "存续", "display": "存续"}, {"value": "新增及存续", "display": "新增及存续"}, {"value": "老客户新业务", "display": "老客户新业务"} ] } ], "excel_upload_config": { "template_url": reverse("download_template", kwargs={'template_name': template_name}), "parse_url": reverse("common_excel_parse"), "save_url": reverse("save_excel_table_data"), "fields_preview_config": { "target_id": {"type": "text", "width": "180px"}, "name": {"type": "text", "width": "180px"}, "department": {"type": "select", "options": ["天信", "混改", "艾力芬特", "星河", "星海"], "width": "180px"}, "year": {"type": "select", "options": ["2024", "2023", "2022", "2021", "2020"], "width": "180px"}, "project_nature": {"type": "select", "options": ["新增", "存续", "新增及存续", "老客户新业务"], "width": "180px"}, "sales_target": {"type": "text", "width": "180px"}, "total_revenue_target": {"type": "text", "width": "180px"}, "new_revenue_target": {"type": "text", "width": "180px"}, "existing_revenue_target": {"type": "text", "width": "180px"}, "actions": {"type": "actions", "width": "100px"} } }, "query_params": query_params, "form_action_url": 'emt_list', "modify_url": reverse("emt_list_modify"), "add_url": reverse("emt_list_add"), "delete_url": reverse("emt_list_delete"), } return render(request, '../templates/list.html', context) def emt_list_add(request): if request.method == 'POST': data = { 'name': request.POST.get('name'), 'department': request.POST.get('department'), 'year': request.POST.get('year'), 'project_nature': request.POST.get('project_nature'), 'sales_target': request.POST.get('sales_target'), 'total_revenue_target': request.POST.get('total_revenue_target'), 'new_revenue_target': request.POST.get('new_revenue_target'), 'existing_revenue_target': request.POST.get('existing_revenue_target') } EmployeePerformanceTarget.objects.create(**data) return JsonResponse({"message": "添加成功"}) return JsonResponse({"message": "无效的请求方法"}, status=405) def emt_list_modify(request): if request.method == 'POST': target_id = request.POST.get('target_id') data = { 'name': request.POST.get('name'), 'department': request.POST.get('department'), 'year': int(request.POST.get('year')), 'project_nature': request.POST.get('project_nature'), 'sales_target': float(request.POST.get('sales_target')), 'total_revenue_target': float(request.POST.get('total_revenue_target')), 'new_revenue_target': float(request.POST.get('new_revenue_target')), 'existing_revenue_target': float(request.POST.get('existing_revenue_target')) } target = EmployeePerformanceTarget.objects.get(target_id=target_id) changes = [] if 1: for key, value in data.items(): if getattr(target, key) != value: changes.append((key, getattr(target, key), value)) FIELD_NAME_MAP = { 'name': '姓名', 'department': '一级部门', 'year': '年份', 'project_nature': '项目性质', 'sales_target': '销售额目标(元)', 'total_revenue_target': '收入总目标(元)', 'new_revenue_target': '新增收入目标(元)', 'existing_revenue_target': '存量收入目标(元)' } for field, old_value, new_value in changes: EmployeeTargetAudit.objects.create( target_id=target, modified_field=FIELD_NAME_MAP.get(field, field), old_value=old_value, new_value=new_value, modified_by=request.user.username ) EmployeePerformanceTarget.objects.filter(target_id=target_id).update(**data) return JsonResponse({"message": "修改成功"}) return JsonResponse({"message": "无效的请求方法"}, status=405) def emt_list_delete(request): if request.method == 'GET': target_id = request.GET.get('target_id') EmployeePerformanceTarget.objects.filter(target_id=target_id).delete() return JsonResponse({"message": "删除成功"}) return JsonResponse({"message": "无效的请求方法"}, status=405) @api_view(['GET']) @permission_classes([IsAuthenticated]) def emt_audit_record_list(request): per_page = request.GET.get('per_page', 10) page_number = request.GET.get('page', 1) queryset = EmployeeTargetAudit.objects.all().order_by('-modification_date') paginator = Paginator(queryset, per_page) try: page_obj = paginator.page(page_number) except EmptyPage: page_obj = paginator.page(paginator.num_pages) except PageNotAnInteger: page_obj = paginator.page(1) serializer = EmployeeTargetAuditSerializer(page_obj, many=True) response_data = { 'modal_title': '修改记录', 'columns': ['修改对象', '修改字段', '旧值', '新值', '修改时间', '修改人'], 'records': serializer.data, 'page': page_obj.number, 'num_pages': paginator.num_pages, 'has_previous': page_obj.has_previous(), 'has_next': page_obj.has_next(), 'start_index': page_obj.start_index(), 'end_index': page_obj.end_index(), 'total_items': paginator.count } return Response(response_data)