import json import pytz from django.core.paginator import Paginator from django.db import transaction from django.http import JsonResponse, Http404 from django.shortcuts import render, get_object_or_404 from django.template.loader import render_to_string from django.urls import reverse from django.utils import timezone from django.views.decorators.http import require_http_methods from rest_framework import status from rest_framework.decorators import api_view, permission_classes from rest_framework.pagination import PageNumberPagination from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from application.opa_mgnt.forms import * from application.opa_mgnt.models import * from application.opa_mgnt.serializers import WebsiteExpirationModificationRecordSerializer from common.auth import custom_permission_required from common.utils.page_helper import paginate_query_and_assign_numbers @custom_permission_required('opa_mgnt.view_socialmediaaccountregistration') def sma_reg_list_view(request): """ 基础数据-运营管理-新媒体账号登记-列表视图 """ query_set = SocialMediaAccountRegistration.objects.filter().order_by('-record_id') platform = request.GET.get('platform', '') if platform: query_set = query_set.filter(platform__icontains=platform) items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10) query_params = '&platform={}'.format(platform) template_name = "运营管理-新媒体账号登记-Excel上传模板.xlsx" context = { "model_config": 'opa_mgnt.SocialMediaAccountRegistration', "items": items, "breadcrumb_list": [ {"title": "首页", "name": "index"}, {"title": "运营管理", "name": "index"}, {"title": "新媒体账号登记", "name": "sma_reg_list"} ], "filters": [ {"type": "text", "id": "platform", "name": "platform", "label": "所属平台", "placeholder": "请输入所属平台"} ], "excel_upload_config": { "template_name": template_name, "template_url": reverse("dl_excel_tpl", kwargs={'template_name': template_name}), "parse_url": reverse("ep_common_parse"), "save_url": reverse("save_excel_table_data") }, "query_params": query_params, "table_exclude_field_name": ['record_id', 'password'], "form_action_url": reverse('sma_reg_list'), "modify_url": reverse("sma_reg_list_modify"), "add_url": reverse("sma_reg_list_add"), "delete_url": reverse("sma_reg_list_delete"), "add_button": True, "import_excel_button": True } return render(request, 'sma_reg_list_inherit.html', context) @custom_permission_required('opa_mgnt.add_socialmediaaccountregistration') def sma_reg_list_add(request): """ 基础数据-运营管理-新媒体账号登记-添加视图 """ if request.method == 'POST': form = SocialMediaAccountRegistrationForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "添加成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': form = SocialMediaAccountRegistrationForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @custom_permission_required('opa_mgnt.change_socialmediaaccountregistration') def sma_reg_list_modify(request): """ 基础数据-运营管理-新媒体账号登记-修改视图 """ if request.method == 'POST': if 'id' in request.POST: instance = SocialMediaAccountRegistration.objects.get(record_id=request.POST['id']) form = SocialMediaAccountRegistrationForm(request.POST, instance=instance) else: form = SocialMediaAccountRegistrationForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "保存成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': if 'id' in request.GET: try: instance = SocialMediaAccountRegistration.objects.get(record_id=request.GET['id']) form = SocialMediaAccountRegistrationForm(instance=instance) except SocialMediaAccountRegistration.DoesNotExist: raise Http404("对象不存在") else: form = SocialMediaAccountRegistrationForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @require_http_methods(["POST"]) @custom_permission_required('opa_mgnt.delete_socialmediaaccountregistration') def sma_reg_list_delete(request): """ 基础数据-运营管理-新媒体账号登记-删除视图 """ target_id = request.POST.get('id') if target_id: SocialMediaAccountRegistration.objects.filter(record_id=target_id).delete() return JsonResponse({"message": "删除成功"}) else: return JsonResponse({"message": "请求参数错误"}, status=400) @require_http_methods(["GET"]) def view_followers_history(request, account_id): account = get_object_or_404(SocialMediaAccountRegistration, pk=account_id) history = account.followers_history.all().order_by('-update_time') page_number = request.GET.get('page', 1) paginator = Paginator(history, 10) # 每页显示10条记录 page_obj = paginator.get_page(page_number) data = { 'results': [ { 'id': record.id, 'follows': record.follows, 'update_time': record.update_time.strftime('%Y-%m-%d %H:%M:%S') } for record in page_obj ], 'has_next': page_obj.has_next(), 'has_previous': page_obj.has_previous(), 'page': page_obj.number, 'total_pages': paginator.num_pages } return JsonResponse(data) @require_http_methods(["POST"]) @transaction.atomic def add_followers_history(request, account_id): cst = pytz.timezone('Asia/Shanghai') account = get_object_or_404(SocialMediaAccountRegistration, pk=account_id) data = json.loads(request.body) current_time = timezone.now().astimezone(cst) new_record = SocialMediaAccountFollowersHistory.objects.create( account=account, follows=data['follows'], update_time=current_time ) # 更新主表中的粉丝数 account.follows = data['follows'] account.save() return JsonResponse({ 'id': new_record.id, 'follows': new_record.follows, 'update_time': new_record.update_time.strftime('%Y-%m-%d %H:%M:%S') }) @require_http_methods(["PUT"]) @transaction.atomic def edit_followers_history(request, record_id): record = get_object_or_404(SocialMediaAccountFollowersHistory, pk=record_id) data = json.loads(request.body) record.follows = data['follows'] record.save() # 如果这是最新的记录,也更新主表中的粉丝数 latest_record = record.account.followers_history.latest('update_time') if record == latest_record: record.account.follows = data['follows'] record.account.save() return JsonResponse({ 'id': record.id, 'follows': record.follows, 'update_time': record.update_time.strftime('%Y-%m-%d %H:%M:%S') }) @require_http_methods(["DELETE"]) @transaction.atomic def delete_followers_history(request, record_id): record = get_object_or_404(SocialMediaAccountFollowersHistory, pk=record_id) account = record.account record.delete() # 删除后,更新主表中的粉丝数为最新记录的粉丝数 latest_record = account.followers_history.order_by('-update_time').first() if latest_record: account.follows = latest_record.follows account.save() return JsonResponse({'success': True}) @custom_permission_required('opa_mgnt.view_accountoperationmanagement') def acc_op_mgmt_list_view(request): """ 基础数据-运营管理-账号运营管理记录-查看视图 """ query_set = AccountOperationManagement.objects.filter().order_by('-record_id') platform = request.GET.get('platform', '') if platform: query_set = query_set.filter(platform__icontains=platform) items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10) query_params = '&platform={}'.format(platform) template_name = "运营管理-账号运营管理记录-Excel上传模板.xlsx" context = { "model_config": 'opa_mgnt.AccountOperationManagement', "items": items, "breadcrumb_list": [ {"title": "首页", "name": "index"}, {"title": "运营管理", "name": "index"}, {"title": "账号运营管理记录", "name": "acc_op_mgmt_list"} ], "filters": [ {"type": "text", "id": "platform", "name": "platform", "label": "所属平台", "placeholder": "请输入所属平台"} ], "excel_upload_config": { "template_name": template_name, "template_url": reverse("dl_excel_tpl", kwargs={'template_name': template_name}), "parse_url": reverse("ep_common_parse"), "save_url": reverse("save_excel_table_data") }, "query_params": query_params, "form_action_url": reverse('acc_op_mgmt_list'), "modify_url": reverse("acc_op_mgmt_list_modify"), "add_url": reverse("acc_op_mgmt_list_add"), "delete_url": reverse("acc_op_mgmt_list_delete"), "table_exclude_field_name": ["record_id"], # Add any fields you want to exclude "add_button": True, "import_excel_button": True } return render(request, 'acc_op_list_inherit.html', context) # return render(request, 'items_list.html', context) @custom_permission_required('opa_mgnt.add_accountoperationmanagement') def acc_op_mgmt_list_add(request): """ 基础数据-运营管理-账号运营管理记录-添加视图 """ if request.method == 'POST': form = AccountOperationManagementForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "添加成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': form = AccountOperationManagementForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @custom_permission_required('opa_mgnt.change_accountoperationmanagement') def acc_op_mgmt_list_modify(request): """ 基础数据-运营管理-账号运营管理记录-修改视图 """ if request.method == 'POST': if 'record_id' in request.POST: instance = AccountOperationManagement.objects.get(record_id=request.POST['record_id']) form = AccountOperationManagementForm(request.POST, instance=instance) else: form = AccountOperationManagementForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "保存成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': if 'id' in request.GET: try: instance = AccountOperationManagement.objects.get(record_id=request.GET['id']) form = AccountOperationManagementForm(instance=instance) except AccountOperationManagement.DoesNotExist: raise Http404("对象不存在") else: form = AccountOperationManagementForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @require_http_methods(["POST"]) @custom_permission_required('opa_mgnt.delete_accountoperationmanagement') def acc_op_mgmt_list_delete(request): """ 基础数据-运营管理-账号运营管理记录-删除视图 """ target_id = request.POST.get('id') if target_id: AccountOperationManagement.objects.filter(record_id=target_id).delete() return JsonResponse({"message": "删除成功"}) else: return JsonResponse({"message": "请求参数错误"}, status=400) @require_http_methods(["GET"]) @custom_permission_required('opa_mgnt.view_accountupdaterecord') def view_update_records(request, account_id): account = get_object_or_404(AccountOperationManagement, pk=account_id) records = account.update_records.all().order_by('-update_time') shanghai_tz = pytz.timezone('Asia/Shanghai') page_number = request.GET.get('page', 1) paginator = Paginator(records, 5) # 每页显示10条记录 page_obj = paginator.get_page(page_number) data = { 'results': [ { 'id': record.record_id, 'views': record.views, 'favorites': record.favorites, 'comments': record.comments, 'shares': record.shares, 'likes': record.likes, 'update_time': record.update_time.astimezone(shanghai_tz).strftime('%Y-%m-%d %H:%M:%S') } for record in page_obj ], 'has_next': page_obj.has_next(), 'has_previous': page_obj.has_previous(), 'page': page_obj.number, 'total_pages': paginator.num_pages } return JsonResponse(data) @require_http_methods(["POST"]) @custom_permission_required('opa_mgnt.add_accountupdaterecord') def add_update_record(request, account_id): cst = pytz.timezone('Asia/Shanghai') account = get_object_or_404(AccountOperationManagement, pk=account_id) data = json.loads(request.body) current_time = timezone.now().astimezone(cst) with transaction.atomic(): # 创建新的更新记录 new_record = AccountUpdateRecord.objects.create( account_operation=account, views=data['views'], favorites=data['favorites'], comments=data['comments'], shares=data['shares'], likes=data['likes'], update_time=current_time ) # 更新主表 AccountOperationManagement 中的数据 account.views = data['views'] account.favorites = data['favorites'] account.comments = data['comments'] account.shares = data['shares'] account.likes = data['likes'] account.update_time = current_time account.save() return JsonResponse({ 'id': new_record.record_id, 'views': new_record.views, 'favorites': new_record.favorites, 'comments': new_record.comments, 'shares': new_record.shares, 'likes': new_record.likes, 'update_time': new_record.update_time.strftime('%Y-%m-%d %H:%M:%S') }) @require_http_methods(["PUT"]) @custom_permission_required('opa_mgnt.change_accountupdaterecord') def edit_update_record(request, record_id): record = get_object_or_404(AccountUpdateRecord, pk=record_id) data = json.loads(request.body) record.views = data['views'] record.favorites = data['favorites'] record.comments = data['comments'] record.shares = data['shares'] record.likes = data['likes'] record.save() return JsonResponse({ 'id': record.record_id, 'views': record.views, 'favorites': record.favorites, 'comments': record.comments, 'shares': record.shares, 'likes': record.likes, 'update_time': record.update_time.strftime('%Y-%m-%d %H:%M:%S') }) @require_http_methods(["DELETE"]) @custom_permission_required('opa_mgnt.delete_accountupdaterecord') def delete_update_record(request, record_id): record = get_object_or_404(AccountUpdateRecord, pk=record_id) record.delete() return JsonResponse({'success': True}) @custom_permission_required('opa_mgnt.view_websiteregistration') def web_reg_list_view(request): """ 基础数据-运营管理-网站登记-查看视图 """ query_set = WebsiteRegistration.objects.filter().order_by('-record_id') website_name = request.GET.get('website_name', '') if website_name: query_set = query_set.filter(website_name__icontains=website_name) items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10) query_params = '&website_name={}'.format(website_name) template_name = "运营管理-网站登记-Excel上传模板.xlsx" context = { "model_config": 'opa_mgnt.WebsiteRegistration', "items": items, "breadcrumb_list": [ {"title": "首页", "name": "index"}, {"title": "运营管理", "name": "index"}, {"title": "网站登记", "name": "web_reg_list"} ], "filters": [ {"type": "text", "id": "website_name", "name": "website_name", "label": "官网名称", "placeholder": "请输入官网名称"} ], "excel_upload_config": { "template_name": template_name, "template_url": reverse("dl_excel_tpl", kwargs={'template_name': template_name}), "parse_url": reverse("ep_common_parse"), "save_url": reverse("save_excel_table_data") }, "query_params": query_params, "form_action_url": reverse('web_reg_list'), "modify_url": reverse("web_reg_list_modify"), "add_url": reverse("web_reg_list_add"), "delete_url": reverse("web_reg_list_delete"), "table_exclude_field_name": ["record_id"], # Add any fields you want to exclude "add_button": True, } return render(request, 'web_reg_list.html', context) @custom_permission_required('opa_mgnt.add_websiteregistration') def web_reg_list_add(request): """ 基础数据-运营管理-网站登记-添加视图 """ if request.method == 'POST': form = WebsiteRegistrationForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "添加成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': form = WebsiteRegistrationForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @custom_permission_required('opa_mgnt.change_websiteregistration') def web_reg_list_modify(request): """ 基础数据-运营管理-网站登记-修改视图 """ if request.method == 'POST': if 'record_id' in request.POST: instance = WebsiteRegistration.objects.get(record_id=request.POST['record_id']) form = WebsiteRegistrationForm(request.POST, instance=instance) else: form = WebsiteRegistrationForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "保存成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': if 'id' in request.GET: try: instance = WebsiteRegistration.objects.get(record_id=request.GET['id']) form = WebsiteRegistrationForm(instance=instance) except WebsiteRegistration.DoesNotExist: raise Http404("对象不存在") else: form = WebsiteRegistrationForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @custom_permission_required('opa_mgnt.delete_websiteregistration') def web_reg_list_delete(request): """ 基础数据-运营管理-网站登记-删除视图 """ target_id = request.POST.get('id') if target_id: WebsiteRegistration.objects.filter(record_id=target_id).delete() return JsonResponse({"message": "删除成功"}) else: return JsonResponse({"message": "请求参数错误"}, status=400) class StandardResultsSetPagination(PageNumberPagination): page_size = 5 page_size_query_param = 'page_size' max_page_size = 100 @api_view(['GET']) @permission_classes([IsAuthenticated]) def website_expiration_modification_records(request, website_id): try: website = WebsiteRegistration.objects.get(pk=website_id) except WebsiteRegistration.DoesNotExist: return Response({"detail": "网站登记记录不存在"}, status=status.HTTP_404_NOT_FOUND) modification_records = WebsiteExpirationModificationRecord.objects.filter(website_registration=website).order_by( '-modification_date') paginator = StandardResultsSetPagination() result_page = paginator.paginate_queryset(modification_records, request) serializer = WebsiteExpirationModificationRecordSerializer(result_page, many=True) return paginator.get_paginated_response(serializer.data) @api_view(['POST']) @permission_classes([IsAuthenticated]) def add_website_expiration_modification_record(request): data = request.data.copy() try: website = WebsiteRegistration.objects.get(pk=data.get('website_registration')) except WebsiteRegistration.DoesNotExist: return Response({"detail": "网站登记记录不存在"}, status=status.HTTP_404_NOT_FOUND) serializer = WebsiteExpirationModificationRecordSerializer(data=data) if serializer.is_valid(): record = serializer.save() website.expiration_date = record.new_expiration_date website.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) @custom_permission_required('opa_mgnt.view_websitemaintenancerecord') def web_maint_rec_list_view(request): """ 基础数据-运营管理-网站运维记录-查看视图 """ query_set = WebsiteMaintenanceRecord.objects.filter().order_by('-record_id') website_name = request.GET.get('website_name', '') if website_name: query_set = query_set.filter(website_name__icontains=website_name) items = paginate_query_and_assign_numbers(request=request, queryset=query_set, per_page=10) query_params = '&website_name={}'.format(website_name) template_name = "运营管理-网站运维记录-Excel上传模板.xlsx" context = { "model_config": 'opa_mgnt.WebsiteMaintenanceRecord', "items": items, "breadcrumb_list": [ {"title": "首页", "name": "index"}, {"title": "运营管理", "name": "index"}, {"title": "网站运维记录", "name": "web_maint_rec_list"} ], "filters": [ {"type": "text", "id": "website_name", "name": "website_name", "label": "官网名称", "placeholder": "请输入官网名称"} ], "excel_upload_config": { "template_name": template_name, "template_url": reverse("dl_excel_tpl", kwargs={'template_name': template_name}), "parse_url": reverse("ep_common_parse"), "save_url": reverse("save_excel_table_data") }, "query_params": query_params, "form_action_url": reverse('web_maint_rec_list'), "modify_url": reverse("web_maint_rec_list_modify"), "add_url": reverse("web_maint_rec_list_add"), "delete_url": reverse("web_maint_rec_list_delete"), "table_exclude_field_name": ["record_id"], # Add any fields you want to exclude "add_button": True, "import_excel_button": True } return render(request, 'items_list.html', context) @custom_permission_required('opa_mgnt.add_websitemaintenancerecord') def web_maint_rec_list_add(request): """ 基础数据-运营管理-网站运维记录-添加视图 """ if request.method == 'POST': form = WebsiteMaintenanceRecordForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "添加成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': form = WebsiteMaintenanceRecordForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @custom_permission_required('opa_mgnt.change_websitemaintenancerecord') def web_maint_rec_list_modify(request): """ 基础数据-运营管理-网站运维记录-修改视图 """ if request.method == 'POST': if 'record_id' in request.POST: instance = WebsiteMaintenanceRecord.objects.get(record_id=request.POST['record_id']) form = WebsiteMaintenanceRecordForm(request.POST, instance=instance) else: form = WebsiteMaintenanceRecordForm(request.POST) if form.is_valid(): form.save() return JsonResponse({"message": "保存成功"}) else: form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html, "errors": form.errors}, status=400) elif request.method == 'GET': if 'id' in request.GET: try: instance = WebsiteMaintenanceRecord.objects.get(record_id=request.GET['id']) form = WebsiteMaintenanceRecordForm(instance=instance) except WebsiteMaintenanceRecord.DoesNotExist: raise Http404("对象不存在") else: form = WebsiteMaintenanceRecordForm() form_html = render_to_string('form_partial.html', {'form': form}, request) return JsonResponse({"form_html": form_html}) else: return JsonResponse({"message": "无效的请求方法"}, status=405) @require_http_methods(["POST"]) @custom_permission_required('opa_mgnt.delete_websitemaintenancerecord') def web_maint_rec_list_delete(request): """ 基础数据-运营管理-网站运维记录-删除视图 """ target_id = request.POST.get('id') if target_id: WebsiteMaintenanceRecord.objects.filter(record_id=target_id).delete() return JsonResponse({"message": "删除成功"}) else: return JsonResponse({"message": "请求参数错误"}, status=400)