XH_Digital_Management/application/perf_mgnt/views.py

406 lines
15 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.

import json
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.http import JsonResponse
from django.shortcuts import render, get_object_or_404
from django.urls import reverse
from django.utils import timezone
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
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 GroupBusinessTargetSerializer, EmployeePerformanceTargetSerializer, TargetAuditSerializer
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)
# 准备上下文
context = {
'items': items,
'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': '老客户新业务'},
],
},
], # 筛选框配置
"form_action_url": 'gbo_list',
'breadcrumb_list': [
{'title': '首页', 'name': 'index'},
{'title': '基础数据', 'name': 'index'},
{'title': '集团经营目标表', 'name': 'gbo_list'},
], # 面包屑
'query_params': query_params, # 查询参数字符串
'table_columns': [
{'header': '一级部门', 'field': 'primary_department'},
{'header': '年份', 'field': 'year'},
{'header': '项目性质', 'field': 'project_nature'},
{'header': '销售额(元)', 'field': 'sales'},
{'header': '收入总目标(元)', 'field': 'total_revenue_target'},
{'header': '新增收入目标(元)', 'field': 'new_revenue_target'},
{'header': '存量收入目标(元)', 'field': 'existing_revenue_target'},
{'header': '成本限额(元)', 'field': 'cost_limit'},
{'header': '毛利润(元)', 'field': 'gross_profit'},
{'header': '费用限额(元)', 'field': 'expense_limit'},
{'header': '营业利润(元)', 'field': 'operating_profit'},
{'header': '操作', 'field': 'actions'},
],
"modify_records_url": reverse('gbo_audit_record_list')
}
return render(request, 'perf_mgnt/gbo_list.html', context)
@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)
@api_view(['POST'])
def create_group_business_target(request):
if request.method == 'POST':
serializer = GroupBusinessTargetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@csrf_exempt
def add_target_audit(request):
if request.method == 'POST':
data = json.loads(request.body)
target_id = data.get('target_id')
modified_field = data.get('modified_field')
old_value = data.get('old_value')
new_value = data.get('new_value')
modified_by = data.get('modified_by')
target = get_object_or_404(GroupBusinessTarget, pk=target_id)
# Update the target with the new value
field_map = {
'销售额': 'sales',
'收入总目标': 'total_revenue_target',
'新增收入目标': 'new_revenue_target',
'存量收入目标': 'existing_revenue_target',
'成本限额': 'cost_limit',
'毛利润': 'gross_profit',
'费用限额': 'expense_limit',
'营业利润': 'operating_profit'
}
if modified_field in field_map:
setattr(target, field_map[modified_field], new_value)
target.save()
# Create audit record
audit_record = TargetAudit.objects.create(
target_id=target,
modified_field=modified_field,
old_value=old_value,
new_value=new_value,
modified_by=modified_by
)
return JsonResponse({
'status': 'success',
'audit_id': audit_record.audit_id
})
return JsonResponse({'status': 'fail', 'message': 'Invalid request'}, status=400)
@api_view(['POST'])
def create_employee_performance_target(request):
if request.method == 'POST':
serializer = EmployeePerformanceTargetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class EmployeePerformanceTargetListView(View):
def get(self, request):
# 获取查询参数
name = request.GET.get('name', '')
department = request.GET.get('department', '')
year = request.GET.get('year', '')
project_nature = request.GET.get('project_nature', '')
# 过滤查询集
queryset = EmployeePerformanceTarget.objects.all()
if name:
queryset = queryset.filter(name=name)
if department:
queryset = queryset.filter(department=department)
if year:
queryset = queryset.filter(year=year)
if project_nature:
queryset = queryset.filter(project_nature=project_nature)
# 分页
page = request.GET.get('page', 1)
paginator = Paginator(queryset, 2) # 每页10条记录
try:
targets = paginator.page(page)
except PageNotAnInteger:
targets = paginator.page(1)
except EmptyPage:
targets = paginator.page(paginator.num_pages)
# 序列化数据
target_list = [{
'target_id': target.target_id,
'name': target.name,
'department': target.department,
'year': target.year,
'project_nature': target.get_project_nature_display(),
'sales_target': target.sales_target,
'total_revenue_target': target.total_revenue_target,
'new_revenue_target': target.new_revenue_target,
'existing_revenue_target': target.existing_revenue_target,
} for target in targets]
pagination_html = render(request, 'pagination_ps.html', {
'page': targets.number,
'pages': paginator.num_pages,
'has_next': targets.has_next(),
'has_previous': targets.has_previous(),
'total': paginator.count,
'start_index': targets.start_index(),
'end_index': targets.end_index(),
'range': range(1, paginator.num_pages + 1)
}).content.decode('utf-8')
# 返回JSON响应
return JsonResponse({
'targets': target_list,
'pagination_html': pagination_html,
})
@csrf_exempt
def add_employee_target_audit(request):
if request.method == 'POST':
data = json.loads(request.body)
target_id = data.get('target_id')
modified_field = data.get('modified_field')
old_value = data.get('old_value')
new_value = data.get('new_value')
modified_by = data.get('modified_by')
target = get_object_or_404(EmployeePerformanceTarget, pk=target_id)
# Update the target with the new value
field_map = {
'销售额目标': 'sales_target',
'收入总目标': 'total_revenue_target',
'新增收入目标': 'new_revenue_target',
'存量收入目标': 'existing_revenue_target'
}
if modified_field in field_map:
setattr(target, field_map[modified_field], new_value)
target.save()
# Create audit record
audit_record = EmployeeTargetAudit.objects.create(
target_id=target,
modified_field=modified_field,
old_value=old_value,
new_value=new_value,
modified_by=modified_by,
modification_date=timezone.now()
)
return JsonResponse({
'status': 'success',
'audit_id': audit_record.audit_id
})
return JsonResponse({'status': 'fail', 'message': 'Invalid request'}, status=400)
def get_employee_target_audit_records(request):
page_number = request.GET.get('page', 1)
per_page = 2 # 每页显示的记录数
audit_records = EmployeeTargetAudit.objects.all().order_by('-modification_date')
paginator = Paginator(audit_records, per_page)
page_obj = paginator.get_page(page_number)
records = []
for record in page_obj:
target = record.target_id
records.append({
'name': target.name,
'year': target.year,
'department': target.department,
'modified_field': record.modified_field,
'old_value': record.old_value,
'new_value': record.new_value,
'modification_date': record.modification_date.strftime('%Y-%m-%d %H:%M:%S'),
'modified_by': record.modified_by
})
return JsonResponse({
'records': records,
'page': page_obj.number,
'num_pages': paginator.num_pages,
'has_previous': page_obj.has_previous(),
'has_next': page_obj.has_next(),
})
# 集团经营目标表
def group_business_objectives(request):
context = {
'filters': [
{
'type': 'select',
'id': 'primary_department',
'label': '一级部门',
'options': [
{'value': '天信', 'display': '天信'},
{'value': '混改', 'display': '混改'},
{'value': '艾力芬特', 'display': '艾力芬特'},
{'value': '星河', 'display': '星河'},
{'value': '星海', 'display': '星海'},
],
},
{
'type': 'select',
'id': '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',
'label': '项目性质',
'options': [
{'value': '新增', 'display': '新增'},
{'value': '存续', 'display': '存续'},
{'value': '新增及存续', 'display': '新增及存续'},
{'value': '老客户新业务', 'display': '老客户新业务'},
],
},
],
}
return render(request, 'perf_mgnt/gbo_list.html', context=context)
def employee_performance_targets(request):
return render(request, 'perf_mgnt/employee_performance_targets.html')