diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/Ai_Admin.iml b/.idea/Ai_Admin.iml new file mode 100644 index 0000000..9c6bfac --- /dev/null +++ b/.idea/Ai_Admin.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/WebSite.iml b/.idea/WebSite.iml new file mode 100644 index 0000000..a9541da --- /dev/null +++ b/.idea/WebSite.iml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/deployment.xml b/.idea/deployment.xml new file mode 100644 index 0000000..8c7f6c0 --- /dev/null +++ b/.idea/deployment.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..35c73dd --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,19 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..6277239 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..63f7602 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/webServers.xml b/.idea/webServers.xml new file mode 100644 index 0000000..43757f6 --- /dev/null +++ b/.idea/webServers.xml @@ -0,0 +1,21 @@ + + + + + + \ No newline at end of file diff --git a/WebAdmin/__init__.py b/WebAdmin/__init__.py deleted file mode 100755 index e69de29..0000000 diff --git a/WebAdmin/__pycache__/AccessLog.cpython-310.pyc b/WebAdmin/__pycache__/AccessLog.cpython-310.pyc index f2cd8ee..cf0669a 100755 Binary files a/WebAdmin/__pycache__/AccessLog.cpython-310.pyc and b/WebAdmin/__pycache__/AccessLog.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/__init__.cpython-310.pyc b/WebAdmin/__pycache__/__init__.cpython-310.pyc deleted file mode 100755 index 0f90eb0..0000000 Binary files a/WebAdmin/__pycache__/__init__.cpython-310.pyc and /dev/null differ diff --git a/WebAdmin/__pycache__/__init__.cpython-311.pyc b/WebAdmin/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index a523662..0000000 Binary files a/WebAdmin/__pycache__/__init__.cpython-311.pyc and /dev/null differ diff --git a/WebAdmin/__pycache__/admin.cpython-310.pyc b/WebAdmin/__pycache__/admin.cpython-310.pyc index e3e4ed0..fb4ac82 100755 Binary files a/WebAdmin/__pycache__/admin.cpython-310.pyc and b/WebAdmin/__pycache__/admin.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/admin_views.cpython-310.pyc b/WebAdmin/__pycache__/admin_views.cpython-310.pyc index 7382a24..c0a95e0 100755 Binary files a/WebAdmin/__pycache__/admin_views.cpython-310.pyc and b/WebAdmin/__pycache__/admin_views.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/admin_views.cpython-311.pyc b/WebAdmin/__pycache__/admin_views.cpython-311.pyc deleted file mode 100644 index f8db708..0000000 Binary files a/WebAdmin/__pycache__/admin_views.cpython-311.pyc and /dev/null differ diff --git a/WebAdmin/__pycache__/ali_pay.cpython-310.pyc b/WebAdmin/__pycache__/ali_pay.cpython-310.pyc index 9d69f41..704d66f 100755 Binary files a/WebAdmin/__pycache__/ali_pay.cpython-310.pyc and b/WebAdmin/__pycache__/ali_pay.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/aliyun_sms.cpython-310.pyc b/WebAdmin/__pycache__/aliyun_sms.cpython-310.pyc index 277869d..7330708 100755 Binary files a/WebAdmin/__pycache__/aliyun_sms.cpython-310.pyc and b/WebAdmin/__pycache__/aliyun_sms.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/api.cpython-310.pyc b/WebAdmin/__pycache__/api.cpython-310.pyc index dfd1442..06bb401 100755 Binary files a/WebAdmin/__pycache__/api.cpython-310.pyc and b/WebAdmin/__pycache__/api.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/apps.cpython-310.pyc b/WebAdmin/__pycache__/apps.cpython-310.pyc index 04780e7..1c6a76d 100755 Binary files a/WebAdmin/__pycache__/apps.cpython-310.pyc and b/WebAdmin/__pycache__/apps.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/audio.cpython-310.pyc b/WebAdmin/__pycache__/audio.cpython-310.pyc index 4a2b927..6f5ca2a 100755 Binary files a/WebAdmin/__pycache__/audio.cpython-310.pyc and b/WebAdmin/__pycache__/audio.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/base.cpython-310.pyc b/WebAdmin/__pycache__/base.cpython-310.pyc index c30b315..9ae1f99 100755 Binary files a/WebAdmin/__pycache__/base.cpython-310.pyc and b/WebAdmin/__pycache__/base.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/create_avatar_video.cpython-310.pyc b/WebAdmin/__pycache__/create_avatar_video.cpython-310.pyc index d24e428..dd7009c 100755 Binary files a/WebAdmin/__pycache__/create_avatar_video.cpython-310.pyc and b/WebAdmin/__pycache__/create_avatar_video.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/create_music_video.cpython-310.pyc b/WebAdmin/__pycache__/create_music_video.cpython-310.pyc index 4951edf..a70f67d 100755 Binary files a/WebAdmin/__pycache__/create_music_video.cpython-310.pyc and b/WebAdmin/__pycache__/create_music_video.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/create_text_img_video.cpython-310.pyc b/WebAdmin/__pycache__/create_text_img_video.cpython-310.pyc index 5a1e7fd..0f01b67 100755 Binary files a/WebAdmin/__pycache__/create_text_img_video.cpython-310.pyc and b/WebAdmin/__pycache__/create_text_img_video.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/create_tiktok_video.cpython-310.pyc b/WebAdmin/__pycache__/create_tiktok_video.cpython-310.pyc index 1bf9bb4..92b8186 100755 Binary files a/WebAdmin/__pycache__/create_tiktok_video.cpython-310.pyc and b/WebAdmin/__pycache__/create_tiktok_video.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/mail.cpython-310.pyc b/WebAdmin/__pycache__/mail.cpython-310.pyc index d365253..b4a8eb2 100755 Binary files a/WebAdmin/__pycache__/mail.cpython-310.pyc and b/WebAdmin/__pycache__/mail.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/middleware.cpython-310.pyc b/WebAdmin/__pycache__/middleware.cpython-310.pyc new file mode 100644 index 0000000..d9ee0d7 Binary files /dev/null and b/WebAdmin/__pycache__/middleware.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/models.cpython-310.pyc b/WebAdmin/__pycache__/models.cpython-310.pyc index 9e62a3e..62d2cea 100755 Binary files a/WebAdmin/__pycache__/models.cpython-310.pyc and b/WebAdmin/__pycache__/models.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/paypal_payment.cpython-310.pyc b/WebAdmin/__pycache__/paypal_payment.cpython-310.pyc index 44ca4f5..4eb9d63 100755 Binary files a/WebAdmin/__pycache__/paypal_payment.cpython-310.pyc and b/WebAdmin/__pycache__/paypal_payment.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/paypal_webhook.cpython-310.pyc b/WebAdmin/__pycache__/paypal_webhook.cpython-310.pyc index e17f208..2e24010 100755 Binary files a/WebAdmin/__pycache__/paypal_webhook.cpython-310.pyc and b/WebAdmin/__pycache__/paypal_webhook.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/signals.cpython-310.pyc b/WebAdmin/__pycache__/signals.cpython-310.pyc index e98ad26..0ff175e 100755 Binary files a/WebAdmin/__pycache__/signals.cpython-310.pyc and b/WebAdmin/__pycache__/signals.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/task.cpython-310.pyc b/WebAdmin/__pycache__/task.cpython-310.pyc index 05a1abe..ddc2b2a 100755 Binary files a/WebAdmin/__pycache__/task.cpython-310.pyc and b/WebAdmin/__pycache__/task.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/task_all.cpython-310.pyc b/WebAdmin/__pycache__/task_all.cpython-310.pyc new file mode 100644 index 0000000..d53ed99 Binary files /dev/null and b/WebAdmin/__pycache__/task_all.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/urls.cpython-310.pyc b/WebAdmin/__pycache__/urls.cpython-310.pyc index b82e304..77572d8 100755 Binary files a/WebAdmin/__pycache__/urls.cpython-310.pyc and b/WebAdmin/__pycache__/urls.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/user.cpython-310.pyc b/WebAdmin/__pycache__/user.cpython-310.pyc index 16ebebf..350bbd9 100755 Binary files a/WebAdmin/__pycache__/user.cpython-310.pyc and b/WebAdmin/__pycache__/user.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/utils.cpython-310.pyc b/WebAdmin/__pycache__/utils.cpython-310.pyc index 0f344b7..9c28f5b 100755 Binary files a/WebAdmin/__pycache__/utils.cpython-310.pyc and b/WebAdmin/__pycache__/utils.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/views.cpython-310.pyc b/WebAdmin/__pycache__/views.cpython-310.pyc index d7ef94e..2014801 100755 Binary files a/WebAdmin/__pycache__/views.cpython-310.pyc and b/WebAdmin/__pycache__/views.cpython-310.pyc differ diff --git a/WebAdmin/__pycache__/文章.cpython-310.pyc b/WebAdmin/__pycache__/文章.cpython-310.pyc new file mode 100644 index 0000000..99186c6 Binary files /dev/null and b/WebAdmin/__pycache__/文章.cpython-310.pyc differ diff --git a/WebAdmin/admin_views.py b/WebAdmin/admin_views.py index beb9553..e89c36b 100755 --- a/WebAdmin/admin_views.py +++ b/WebAdmin/admin_views.py @@ -1,12 +1,36 @@ import json +import os import re -from django.contrib.auth import authenticate, login as auth_login +import uuid +from datetime import datetime +from django.contrib.auth import logout + +from django.contrib.auth import authenticate, login as auth_login, update_session_auth_hash +from django.core.exceptions import ValidationError +from django.core.serializers.json import DjangoJSONEncoder +from django.db import IntegrityError +from django.db.models import Count, Sum from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt -from django.shortcuts import render, redirect +from django.shortcuts import render, redirect,get_object_or_404 from django.contrib.auth.decorators import login_required from allauth.account.auth_backends import AuthenticationBackend -from .models import User +from django.views.decorators.http import require_http_methods +from django.views.generic import View +from django.core.cache import cache +from captcha.image import ImageCaptcha +import random +from WebSite import settings +from .models import User, WebsiteInfo, Article, Order, VideoGeneration +from django.http import JsonResponse, HttpResponse +import string + +def generate_captcha(request): + image = ImageCaptcha() + captcha_text = ''.join(random.choices(string.ascii_uppercase + string.digits, k=4)) # 生成随机验证码 + cache.set('captcha', captcha_text, timeout=300) # 存储验证码 + image_data = image.generate(captcha_text) + return HttpResponse(image_data, content_type='image/png') @csrf_exempt def admin_login_view(request): @@ -18,9 +42,14 @@ def admin_login_view(request): body = json.loads(request.body) username = body.get('username') password = body.get('password') + captcha_input = body.get('captcha') + captcha_stored = cache.get('captcha') + + if captcha_input != captcha_stored: + return JsonResponse({'code': 400, 'message': '验证码错误'}) + user = authenticate(request, username=username, password=password) if user is not None: - user.backend = 'allauth.account.auth_backends.AuthenticationBackend' auth_login(request, user) return JsonResponse({'code': 200, 'message': '登录成功'}) else: @@ -35,3 +64,469 @@ def admin_login_view(request): @login_required def admin_home_view(request): return render(request, 'admin/home.html') + +@login_required +@require_http_methods(["GET", "POST"]) +@csrf_exempt # 根据需要选择是否使用 +def admin_article_list(request): + articles = list(Article.objects.all().values('id', 'chinese_title', 'english_title', 'published_at', 'status')) + if request.method == 'GET': + # GET 请求返回页面 + return render(request, 'admin/article-list.html', {"articles":articles}) + + elif request.method == 'POST': + # 获取文章列表并转换为 JSON 格式 + articles = list(Article.objects.all().values('id', 'chinese_title', 'english_title', 'published_at', 'status')) + + # 手动格式化 published_at 字段为字符串 + for article in articles: + if article['published_at']: + article['published_at'] = article['published_at'].strftime('%Y-%m-%d %H:%M:%S') + else: + article['published_at'] = '未发布' + + # 返回适配 layui 表格的数据格式 + data = { + "code": 200, + "msg": "成功", + "count": len(articles), # 返回文章数量 + "data": articles # 直接返回文章数据 + } + return JsonResponse(data) # 返回 JSON 响应 +@login_required +def ArticleDetailView(request, pk, lang): + # 确认用户登录 + if not request.user.is_authenticated: + return redirect('admin_login') + + # 获取指定的文章 + article = get_object_or_404(Article, pk=pk) + + # 根据 URL 中的 lang 参数选择显示的语言 + if lang == 'en': + title = article.english_title + keywords = article.english_keywords + content = article.english_content + else: + title = article.chinese_title + keywords = article.chinese_keywords + content = article.chinese_content + + # 渲染模板并传递数据 + context = { + 'title': title, + 'keywords': keywords, + 'content': content, + 'published_at': article.published_at, + } + + return render(request, 'admin/article_detail.html', context) + +@login_required +@csrf_exempt # 根据需要选择是否使用 +def admin_site_info_view(request): + website_info = WebsiteInfo.objects.first() + + if request.method == 'POST': + try: + # 获取 JSON 数据 + data = json.loads(request.body) + + # 从数据中提取信息 + domain_en = data.get('domain_en', '') + title_en = data.get('title_en', '') + keywords_en = data.get('keywords_en', '') + description_en = data.get('description_en', '') + domain_zh = data.get('domain_zh', '') + title_zh = data.get('title_zh', '') + keywords_zh = data.get('keywords_zh', '') + description_zh = data.get('description_zh', '') + + # 数据验证(示例) + if not domain_en or not domain_zh: + return JsonResponse({ + 'code': 400, + 'message': '域名不能为空', + 'data': {} + }) + + # 更新网站配置信息 + website_info.domain_en = domain_en + website_info.title_en = title_en + website_info.keywords_en = keywords_en + website_info.description_en = description_en + website_info.domain_zh = domain_zh + website_info.title_zh = title_zh + website_info.keywords_zh = keywords_zh + website_info.description_zh = description_zh + website_info.save() + + # 返回统一的响应格式 + return JsonResponse({ + 'code': 200, + 'message': '保存成功', + 'data': {} + }) + + except json.JSONDecodeError: + return JsonResponse({ + 'code': 400, + 'message': '无效的 JSON 格式', + 'data': {} + }) + except ValidationError as ve: + return JsonResponse({ + 'code': 400, + 'message': str(ve), + 'data': {} + }) + except IntegrityError: + return JsonResponse({ + 'code': 500, + 'message': '数据库错误,请重试', + 'data': {} + }) + except Exception as e: + return JsonResponse({ + 'code': 500, + 'message': '服务器错误,请重试', + 'data': {'error': str(e)} + }) + + # 返回网站配置信息 + # data = { + # 'domain_en': website_info.domain_en, + # 'title_en': website_info.title_en, + # 'keywords_en': website_info.keywords_en, + # 'description_en': website_info.description_en, + # 'domain_zh': website_info.domain_zh, + # 'title_zh': website_info.title_zh, + # 'keywords_zh': website_info.keywords_zh, + # 'description_zh': website_info.description_zh, + # } + else: + return render(request, 'admin/site-info.html', {"website_info": website_info}) + + +@login_required +@csrf_exempt +def save_article(request, pk=None): + if request.method == "GET": + # 如果传递了文章 ID,则为编辑模式,否则为添加模式 + article = get_object_or_404(Article, pk=pk) if pk else None + + return render(request, 'admin/add-article.html', { + 'article': article, # 传递文章对象给模板 + 'page_title': '修改文章' if article else '添加文章', + }) + + elif request.method == "POST": + try: + data = json.loads(request.body) + chinese_title = data.get('chinese_title', '') + english_title = data.get('english_title', '') + chinese_content = data.get('chinese_content', '') + english_content = data.get('english_content', '') + image_url = data.get('image_url', '') + status = data.get('status', 'pending') + + # 检查是否传递了文章 ID 以判断是编辑还是添加 + if pk: + article = get_object_or_404(Article, pk=pk) + else: + article = Article() + + # 设置文章内容 + article.chinese_title = chinese_title + article.english_title = english_title + article.chinese_content = chinese_content + article.english_content = english_content + article.image_url = image_url + article.status = status + article.published_at = datetime.now() if status == 'published' else None + + # 保存文章 + article.save() + + return JsonResponse({'code': 200, 'message': '文章保存成功', 'article_id': article.id}) + + except Exception as e: + return JsonResponse({'code': 500, 'message': str(e)}) +# 图片上传接口(专用于编辑器) +@login_required +@csrf_exempt +@require_http_methods(["POST"]) +def upload_editor_image(request): + """ + 上传图片并返回图片URL,供富文本编辑器使用 + """ + try: + # 验证用户是否已登录 + if not request.user.is_authenticated: + return JsonResponse({'code': 401, 'message': '用户未登录'}) + + # 检查是否包含上传的图片 + if 'file' not in request.FILES: + return JsonResponse({'code': 400, 'message': '没有上传图片'}) + + # 获取上传的图片文件 + image_file = request.FILES['file'] + + # 使用 UUID 为文件生成唯一名称,并保存到服务器指定目录 + file_extension = image_file.name.split('.')[-1] + filename = f"{uuid.uuid4()}.{file_extension}" + file_path = os.path.join(settings.MEDIA_ROOT, 'editor_images', filename) + + # 将文件写入服务器 + with open(file_path, 'wb') as f: + for chunk in image_file.chunks(): + f.write(chunk) + + # 生成图片的访问 URL + image_url = f"{settings.DOMAIN}{settings.MEDIA_URL}editor_images/{filename}" + data_json={ + "code": 0 + ,"msg": "图片上传成功" + ,"data": { + "src": image_url + ,"title": None + } + } + return JsonResponse(data_json) + + except Exception as e: + return JsonResponse({'code': 500, 'message': str(e)}) + +class ArticleManagementView(View): + def delete(self, request, article_id): + if not request.user.is_authenticated or not request.user.is_staff: + return JsonResponse({'code': 403, 'message': '没有权限执行此操作'}) + + try: + article = Article.objects.get(id=article_id) + article.delete() + return JsonResponse({'code': 200, 'message': '删除成功'}) + except Article.DoesNotExist: + return JsonResponse({'code': 404, 'message': '文章未找到'}) + + def post(self, request, article_id): + if not request.user.is_authenticated or not request.user.is_staff: + return JsonResponse({'code': 403, 'message': '没有权限执行此操作'}) + + try: + article = Article.objects.get(id=article_id) + # 审核文章逻辑 + article.status = 'published' # 假设审核通过状态设为 published + article.published_at = datetime.now() # 设置当前时间为发布时间 + article.save() + return JsonResponse({'code': 200, 'message': '审核成功'}) + except Article.DoesNotExist: + return JsonResponse({'code': 404, 'message': '文章未找到'}) + +from django.core.paginator import Paginator, EmptyPage, InvalidPage + + +@login_required +@require_http_methods(["GET", "POST"]) +@csrf_exempt +def admin_user_list(request): + if request.method == 'GET': + # GET 请求返回页面 + return render(request, 'admin/user-list.html') + + elif request.method == 'POST': + # 获取分页参数 + page = request.POST.get('page', 1) + limit = request.POST.get('limit', 10) + + # 获取用户列表并转换为 JSON 格式,按照注册时间最新排序 + users_queryset = User.objects.all().order_by('-created_at').values( + 'id', 'username', 'email', 'phone', 'is_member', 'points', 'created_at', + 'login_count', 'last_login_ip', 'source' + ) + + paginator = Paginator(users_queryset, limit) + current_page = paginator.page(page) + + # 格式化创建时间字段 + users = list(current_page.object_list) + for user in users: + if user['created_at']: + user['created_at'] = user['created_at'].strftime('%Y-%m-%d %H:%M:%S') + + # 返回适配 layui 表格的数据格式 + data = { + "code": 0, + "msg": "成功", + "count": paginator.count, # 总记录数 + "data": users + } + return JsonResponse(data) + +@login_required +@require_http_methods(["GET", "POST"]) +@csrf_exempt +def admin_task_list(request): + if request.method == 'GET': + # GET 请求返回页面 + return render(request, 'admin/task-list.html') + + elif request.method == 'POST': + # 获取分页参数 + try: + page = int(request.POST.get('page', 1)) + limit = int(request.POST.get('limit', 10)) + except ValueError: + page = 1 + limit = 10 + + # 获取所有任务按时间排序 + tasks_queryset = VideoGeneration.objects.all().order_by('-created_at') + + # 统计不同类型视频数量、状态数量 + video_type_count = VideoGeneration.objects.values('slug').annotate(count=Count('slug')) + status_count = { + 'completed': tasks_queryset.filter(status='completed').count(), + 'in_progress': tasks_queryset.filter(status='in_progress').count(), + 'failed': tasks_queryset.filter(status='failed').count(), + } + + # 分页 + paginator = Paginator(tasks_queryset, limit) + try: + current_page = paginator.page(page) + except (EmptyPage, InvalidPage): + current_page = paginator.page(1) + + # 格式化时间字段并构建任务列表 + tasks = [] + for task in current_page.object_list: + tasks.append({ + 'id': task.id, + 'video_id': task.video_id, + 'user_id': task.user_id, + 'text': task.text if task.text else '无生成文本', + 'slug': task.slug, + 'time_duration': task.time_duration if task.time_duration else '无时长', + 'video_url': task.video_url, + 'created_at': task.created_at.strftime('%Y-%m-%d %H:%M:%S'), + 'status': task.status, + }) + + # 返回适配layui表格的数据格式 + data = { + "code": 0, + "msg": "成功", + "count": paginator.count, + "data": tasks, + "video_type_count": list(video_type_count), # 各种类型视频数量 + "status_count": status_count # 各个状态数量 + } + + return JsonResponse(data) + +@login_required +@require_http_methods(["GET", "POST"]) +@csrf_exempt +def admin_order_list(request): + if request.method == 'GET': + return render(request, 'admin/order-list.html') + + elif request.method == 'POST': + # 获取订单列表 + order_queryset = Order.objects.all().order_by('-created_at') + + # 获取分页参数 + page = int(request.POST.get('page', 1)) + limit = int(request.POST.get('limit', 10)) + + # 分页处理 + paginator = Paginator(order_queryset, limit) + orders = paginator.get_page(page) + + # 转换数据为 JSON 格式 + order_data = list(orders.object_list.values('order_id', 'username', 'plan__title', 'amount', 'payment_method', 'status', 'created_at')) + + # 手动格式化创建时间字段 + for order in order_data: + order['created_at'] = order['created_at'].strftime('%Y-%m-%d %H:%M:%S') + # 翻译支付方式和状态 + order['payment_method'] = '支付宝' if order['payment_method'] == 'alipay' else '贝宝' + order['status'] = { + 'pending': '待处理', + 'completed': '已完成', + 'canceled': '已取消', + 'failed': '失败' + }.get(order['status'], order['status']) + + # 支付方式统计 + payment_method_count = Order.objects.values('payment_method').annotate(count=Count('payment_method')) + + # 各个状态的订单数量 + status_count = { + 'completed': Order.objects.filter(status='completed').count(), + 'failed': Order.objects.filter(status='failed').count(), + 'canceled': Order.objects.filter(status='canceled').count(), + 'pending': Order.objects.filter(status='pending').count(), + } + + # 支付方式金额统计(仅统计已完成的订单) + total_income_by_payment_method = Order.objects.filter(status='completed').values('payment_method').annotate( + total_income=Sum('amount') + ) + + # 转换支付方式为中文名称 + total_income_by_payment_method = [ + { + 'payment_method': '支付宝' if method['payment_method'] == 'alipay' else '贝宝', + 'total_income': method['total_income'] + } + for method in total_income_by_payment_method + ] + + # 返回数据 + data = { + "code": 0, + "msg": "成功", + "count": paginator.count, + "data": order_data, + "payment_method_count": list(payment_method_count), + "status_count": status_count, + "total_income_by_payment_method": total_income_by_payment_method + } + return JsonResponse(data) + + +@login_required +@require_http_methods(["POST"]) +@csrf_exempt +def admin_change_password(request): + user = request.user + data = json.loads(request.body) + old_password = data.get('old_password') + new_password = data.get('new_password') + # 验证旧密码 + if not user.check_password(old_password): + return JsonResponse({'code': 400, 'msg': '旧密码错误'}) + + # 验证新密码是否为空 + if not new_password: + return JsonResponse({'code': 400, 'msg': '新密码不能为空'}) + + # 更新密码 + user.set_password(new_password) + user.save() + + # 确保更新密码后不会自动退出登录 + update_session_auth_hash(request, user) + + return JsonResponse({'code': 200, 'msg': '密码修改成功'}) + + +@login_required +@require_http_methods(["POST", "GET"]) +def admin_logout(request): + # 退出登录 + logout(request) + # 重定向到登录页面 + return redirect('admin_login') \ No newline at end of file diff --git a/WebAdmin/create_text_img_video.py b/WebAdmin/create_text_img_video.py index 4db165c..80031ee 100755 --- a/WebAdmin/create_text_img_video.py +++ b/WebAdmin/create_text_img_video.py @@ -166,7 +166,8 @@ def text_to_video(request): pid=uuid, media_type=f'{model}_text_to_video', slug=f'text-to-video', - ratio=f"{width}:{height}" + ratio=f"{width}:{height}", + time_duration=time_duration ) video_generation.save() @@ -279,7 +280,8 @@ def image_to_video(request): pid=uuid, media_type=f'{model}_img_to_video', slug=f'img-to-video', - ratio="auto" # 图片自适应宽高 + ratio="auto", # 图片自适应宽高 + time_duration=time_duration ) video_generation.save() diff --git a/WebAdmin/migrations/0001_initial.py b/WebAdmin/migrations/0001_initial.py index 68fcdd1..c276f17 100755 --- a/WebAdmin/migrations/0001_initial.py +++ b/WebAdmin/migrations/0001_initial.py @@ -1,16 +1,225 @@ -# Generated by Django 5.0.7 on 2024-07-16 15:57 +# Generated by Django 5.0.7 on 2024-09-23 22:59 +import datetime +import django.contrib.auth.models +import django.contrib.auth.validators import django.db.models.deletion -from datetime import datetime +import django.utils.timezone +from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True - dependencies = [] + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ] operations = [ + migrations.CreateModel( + name="Article", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("chinese_title", models.CharField(max_length=255)), + ("english_title", models.CharField(max_length=255)), + ("chinese_keywords", models.TextField()), + ("english_keywords", models.TextField()), + ("chinese_content", models.TextField()), + ("english_content", models.TextField()), + ("source_url", models.URLField(blank=True, null=True)), + ("published_at", models.DateTimeField(blank=True, null=True)), + ("image_url", models.URLField(blank=True, null=True)), + ( + "status", + models.CharField( + choices=[("published", "已发布"), ("pending", "待审核")], + default="draft", + max_length=10, + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ], + options={ + "verbose_name": "Article", + "verbose_name_plural": "Article", + "ordering": ["-created_at"], + }, + ), + migrations.CreateModel( + name="EmailVerificationCode", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("email", models.EmailField(max_length=254)), + ("code", models.CharField(max_length=6)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("is_used", models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name="Plan", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=100, unique=True)), + ("description", models.TextField()), + ("price", models.DecimalField(decimal_places=2, max_digits=10)), + ("credits_per_month", models.IntegerField(default=0)), + ("created_at", models.DateTimeField(default=datetime.datetime.now)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("is_promotional", models.BooleanField(default=False)), + ("unlimited_exports", models.BooleanField(default=False)), + ("smart_music_sync", models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name="SMSVerificationCode", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("phone_number", models.CharField(max_length=15)), + ("code", models.CharField(max_length=6)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("is_used", models.BooleanField(default=False)), + ], + ), + migrations.CreateModel( + name="WebsiteInfo", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "domain_en", + models.CharField(default=True, max_length=255, verbose_name="域名"), + ), + ( + "domain_zh", + models.CharField(default=True, max_length=255, verbose_name="域名"), + ), + ( + "title_en", + models.CharField(default=True, max_length=255, verbose_name="英文标题"), + ), + ( + "title_zh", + models.CharField(default=True, max_length=255, verbose_name="中文标题"), + ), + ("keywords_en", models.TextField(default=True, verbose_name="英文关键词")), + ("keywords_zh", models.TextField(default=True, verbose_name="中文关键词")), + ("description_en", models.TextField(default=True, verbose_name="英文描述")), + ("description_zh", models.TextField(default=True, verbose_name="中文描述")), + ( + "created_at", + models.DateTimeField(auto_now_add=True, verbose_name="创建时间"), + ), + ( + "updated_at", + models.DateTimeField(auto_now=True, verbose_name="更新时间"), + ), + ], + options={ + "verbose_name": "网站信息", + "verbose_name_plural": "网站信息", + "db_table": "website_info", + "ordering": ["-created_at"], + }, + ), + migrations.CreateModel( + name="WebsiteAccessLog", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("ip_address", models.GenericIPAddressField(verbose_name="访问IP")), + ( + "browser_language", + models.CharField( + blank=True, max_length=200, null=True, verbose_name="浏览器语言" + ), + ), + ( + "referrer", + models.TextField(blank=True, null=True, verbose_name="来源URL"), + ), + ("request_path", models.CharField(max_length=255, verbose_name="请求路径")), + ( + "request_method", + models.CharField(max_length=10, verbose_name="请求方法"), + ), + ( + "user_agent", + models.TextField(blank=True, null=True, verbose_name="用户代理"), + ), + ( + "device_type", + models.CharField( + blank=True, max_length=50, null=True, verbose_name="设备类型" + ), + ), + ( + "access_time", + models.DateTimeField(auto_now_add=True, verbose_name="访问时间"), + ), + ( + "access_time_bj", + models.DateTimeField(blank=True, null=True, verbose_name="北京时间"), + ), + ( + "access_date", + models.DateField(blank=True, null=True, verbose_name="访问日期"), + ), + ], + options={ + "verbose_name": "网站访问日志", + "verbose_name_plural": "网站访问日志", + "db_table": "website_access_log", + "unique_together": {("ip_address", "access_date")}, + }, + ), migrations.CreateModel( name="User", fields=[ @@ -23,26 +232,84 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), - ("username", models.CharField(max_length=150, unique=True)), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "username", + models.CharField( + error_messages={ + "unique": "A user with that username already exists." + }, + help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[ + django.contrib.auth.validators.UnicodeUsernameValidator() + ], + verbose_name="username", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), ( "email", models.EmailField( - blank=True, max_length=254, null=True, unique=True + blank=True, max_length=254, verbose_name="email address" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" ), ), ( "phone", models.CharField(blank=True, max_length=20, null=True, unique=True), ), - ( - "password_hash", - models.CharField(blank=True, max_length=128, null=True), - ), ( "google_id", models.CharField(blank=True, max_length=50, null=True, unique=True), ), - ("is_active", models.BooleanField(default=True)), ("is_member", models.BooleanField(default=False)), ("points", models.IntegerField(default=0)), ("referral_code", models.CharField(max_length=50, unique=True)), @@ -50,8 +317,30 @@ class Migration(migrations.Migration): "commission_rate", models.DecimalField(decimal_places=2, default=0.0, max_digits=5), ), - ("created_at", models.DateTimeField(default=datetime.now)), + ("created_at", models.DateTimeField(default=datetime.datetime.now)), ("updated_at", models.DateTimeField(auto_now=True)), + ("login_count", models.IntegerField(default=0)), + ("last_login_ip", models.GenericIPAddressField(blank=True, null=True)), + ("membership_start", models.DateTimeField(blank=True, null=True)), + ("membership_end", models.DateTimeField(blank=True, null=True)), + ( + "openid_used", + models.CharField( + blank=True, max_length=150, null=True, unique=True + ), + ), + ("source", models.CharField(default="web", max_length=50)), + ( + "groups", + models.ManyToManyField( + blank=True, + help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", + related_name="user_set", + related_query_name="user", + to="auth.group", + verbose_name="groups", + ), + ), ( "invited_by", models.ForeignKey( @@ -59,13 +348,32 @@ class Migration(migrations.Migration): null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="invitees", - to="WebAdmin.user", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "user_permissions", + models.ManyToManyField( + blank=True, + help_text="Specific permissions for this user.", + related_name="user_set", + related_query_name="user", + to="auth.permission", + verbose_name="user permissions", ), ), ], + options={ + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, + }, + managers=[ + ("objects", django.contrib.auth.models.UserManager()), + ], ), migrations.CreateModel( - name="Referral", + name="VideoGeneration", fields=[ ( "id", @@ -76,25 +384,42 @@ class Migration(migrations.Migration): verbose_name="ID", ), ), + ("video_id", models.CharField(default="", max_length=255)), + ("text", models.TextField(null=True)), + ("voice_name", models.CharField(max_length=50, null=True)), ( - "commission_amount", - models.DecimalField(decimal_places=2, max_digits=10), + "style", + models.CharField(default="general", max_length=50, null=True), ), - ("created_at", models.DateTimeField(default=datetime.now)), + ("rate", models.IntegerField(default=0, null=True)), + ("media_type", models.CharField(max_length=50, null=True)), + ("ratio", models.CharField(max_length=10)), + ("audio_url", models.URLField(blank=True, null=True)), + ("video_url", models.URLField(blank=True, null=True)), ( - "referee", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="referrals_received", - to="WebAdmin.user", + "status", + models.CharField( + choices=[ + ("pending", "Pending"), + ("in_progress", "In Progress"), + ("completed", "Completed"), + ("failed", "Failed"), + ], + default="pending", + max_length=20, ), ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("updated_at", models.DateTimeField(auto_now=True)), + ("slug", models.CharField(max_length=50)), + ("pid", models.CharField(default="", max_length=50, null=True)), + ("extension_count", models.IntegerField(default=0)), + ("time_duration", models.IntegerField(default=0)), ( - "referrer", + "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, - related_name="referrals_made", - to="WebAdmin.user", + to=settings.AUTH_USER_MODEL, ), ), ], @@ -112,13 +437,170 @@ class Migration(migrations.Migration): ), ), ("source", models.CharField(max_length=50)), - ("created_at", models.DateTimeField(default=datetime.now)), + ("created_at", models.DateTimeField(default=datetime.datetime.now)), ( "user", models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="WebAdmin.user" + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, ), ), ], ), + migrations.CreateModel( + name="TransactionHistory", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "feature", + models.CharField( + choices=[ + ("text-to-video", "AI文生视频"), + ("img-to-video", "AI图生视频"), + ("create-tiktok-video", "AI长视频生成"), + ("music-to-video", "音乐视频生成"), + ("create-avatar-video", "虚拟形象视频生成"), + ], + max_length=50, + verbose_name="功能类型", + ), + ), + ("points_spent", models.IntegerField(verbose_name="消费积分")), + ( + "char_count", + models.IntegerField(blank=True, null=True, verbose_name="字符数量"), + ), + ( + "description", + models.TextField(blank=True, null=True, verbose_name="操作描述"), + ), + ( + "transaction_date", + models.DateTimeField( + default=datetime.datetime.now, verbose_name="消费时间" + ), + ), + ("previous_points_balance", models.IntegerField(verbose_name="消费前积分")), + ("new_points_balance", models.IntegerField(verbose_name="消费后积分")), + ("success", models.BooleanField(default=True, verbose_name="是否成功")), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="transactions", + to=settings.AUTH_USER_MODEL, + verbose_name="用户", + ), + ), + ], + options={ + "verbose_name": "消费明细", + "verbose_name_plural": "消费明细", + "db_table": "transaction_history", + "ordering": ["-transaction_date"], + }, + ), + migrations.CreateModel( + name="Referral", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "commission_amount", + models.DecimalField(decimal_places=2, max_digits=10), + ), + ("created_at", models.DateTimeField(default=datetime.datetime.now)), + ( + "referee", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="referrals_received", + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "referrer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="referrals_made", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Order", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("order_id", models.CharField(max_length=100, unique=True)), + ("username", models.CharField(max_length=150)), + ( + "amount", + models.DecimalField(decimal_places=2, default=0.0, max_digits=10), + ), + ( + "payment_method", + models.CharField( + choices=[("alipay", "Alipay"), ("paypal", "PayPal")], + max_length=10, + ), + ), + ( + "status", + models.CharField( + choices=[ + ("pending", "Pending"), + ("completed", "Completed"), + ("canceled", "Canceled"), + ("failed", "Failed"), + ], + default="pending", + max_length=10, + ), + ), + ("created_at", models.DateTimeField(default=datetime.datetime.now)), + ("updated_at", models.DateTimeField(auto_now=True)), + ( + "plan", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="WebAdmin.plan" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + options={ + "verbose_name": "Order", + "verbose_name_plural": "Orders", + "ordering": ["-created_at"], + }, + ), ] diff --git a/WebAdmin/migrations/0002_user_last_login_ip_user_login_count.py b/WebAdmin/migrations/0002_user_last_login_ip_user_login_count.py deleted file mode 100755 index f44807d..0000000 --- a/WebAdmin/migrations/0002_user_last_login_ip_user_login_count.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-16 17:33 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0001_initial"), - ] - - operations = [ - migrations.AddField( - model_name="user", - name="last_login_ip", - field=models.GenericIPAddressField(blank=True, null=True), - ), - migrations.AddField( - model_name="user", - name="login_count", - field=models.IntegerField(default=0), - ), - ] diff --git a/WebAdmin/migrations/0003_alter_user_options_alter_user_managers_and_more.py b/WebAdmin/migrations/0003_alter_user_options_alter_user_managers_and_more.py deleted file mode 100755 index a01172e..0000000 --- a/WebAdmin/migrations/0003_alter_user_options_alter_user_managers_and_more.py +++ /dev/null @@ -1,135 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-16 18:04 - -import django.contrib.auth.models -import django.contrib.auth.validators -from datetime import datetime -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0002_user_last_login_ip_user_login_count"), - ("auth", "0012_alter_user_first_name_max_length"), - ] - - operations = [ - migrations.AlterModelOptions( - name="user", - options={"verbose_name": "user", "verbose_name_plural": "users"}, - ), - migrations.AlterModelManagers( - name="user", - managers=[ - ("objects", django.contrib.auth.models.UserManager()), - ], - ), - migrations.RemoveField( - model_name="user", - name="password_hash", - ), - migrations.AddField( - model_name="user", - name="date_joined", - field=models.DateTimeField( - default=datetime.now, verbose_name="date joined" - ), - ), - migrations.AddField( - model_name="user", - name="first_name", - field=models.CharField( - blank=True, max_length=150, verbose_name="first name" - ), - ), - migrations.AddField( - model_name="user", - name="groups", - field=models.ManyToManyField( - blank=True, - help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.", - related_name="user_set", - related_query_name="user", - to="auth.group", - verbose_name="groups", - ), - ), - migrations.AddField( - model_name="user", - name="is_staff", - field=models.BooleanField( - default=False, - help_text="Designates whether the user can log into this admin site.", - verbose_name="staff status", - ), - ), - migrations.AddField( - model_name="user", - name="is_superuser", - field=models.BooleanField( - default=False, - help_text="Designates that this user has all permissions without explicitly assigning them.", - verbose_name="superuser status", - ), - ), - migrations.AddField( - model_name="user", - name="last_login", - field=models.DateTimeField( - blank=True, null=True, verbose_name="last login" - ), - ), - migrations.AddField( - model_name="user", - name="last_name", - field=models.CharField( - blank=True, max_length=150, verbose_name="last name" - ), - ), - migrations.AddField( - model_name="user", - name="password", - field=models.CharField(default=1, max_length=128, verbose_name="password"), - preserve_default=False, - ), - migrations.AddField( - model_name="user", - name="user_permissions", - field=models.ManyToManyField( - blank=True, - help_text="Specific permissions for this user.", - related_name="user_set", - related_query_name="user", - to="auth.permission", - verbose_name="user permissions", - ), - ), - migrations.AlterField( - model_name="user", - name="email", - field=models.EmailField( - blank=True, default=1, max_length=254, verbose_name="email address" - ), - preserve_default=False, - ), - migrations.AlterField( - model_name="user", - name="is_active", - field=models.BooleanField( - default=True, - help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", - verbose_name="active", - ), - ), - migrations.AlterField( - model_name="user", - name="username", - field=models.CharField( - error_messages={"unique": "A user with that username already exists."}, - help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", - max_length=150, - unique=True, - validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], - verbose_name="username", - ), - ), - ] diff --git a/WebAdmin/migrations/0004_emailverificationcode_smsverificationcode.py b/WebAdmin/migrations/0004_emailverificationcode_smsverificationcode.py deleted file mode 100755 index 21098c8..0000000 --- a/WebAdmin/migrations/0004_emailverificationcode_smsverificationcode.py +++ /dev/null @@ -1,48 +0,0 @@ -# Generated by Django 5.0.7 on 2024-07-20 03:57 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0003_alter_user_options_alter_user_managers_and_more"), - ] - - operations = [ - migrations.CreateModel( - name="EmailVerificationCode", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("email", models.EmailField(max_length=254)), - ("code", models.CharField(max_length=6)), - ("created_at", models.DateTimeField(auto_now_add=True)), - ("is_used", models.BooleanField(default=False)), - ], - ), - migrations.CreateModel( - name="SMSVerificationCode", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("phone_number", models.CharField(max_length=15)), - ("code", models.CharField(max_length=6)), - ("created_at", models.DateTimeField(auto_now_add=True)), - ("is_used", models.BooleanField(default=False)), - ], - ), - ] diff --git a/WebAdmin/migrations/0005_videogeneration.py b/WebAdmin/migrations/0005_videogeneration.py deleted file mode 100755 index f7f3cce..0000000 --- a/WebAdmin/migrations/0005_videogeneration.py +++ /dev/null @@ -1,60 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-03 10:13 - -import django.db.models.deletion -from datetime import datetime - -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0004_emailverificationcode_smsverificationcode"), - ] - - operations = [ - migrations.CreateModel( - name="VideoGeneration", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("text", models.TextField()), - ("voice_name", models.CharField(max_length=50)), - ("style", models.CharField(default="general", max_length=50)), - ("rate", models.IntegerField(default=0)), - ("media_type", models.CharField(max_length=50)), - ("ratio", models.CharField(max_length=10)), - ("audio_url", models.URLField(blank=True, null=True)), - ("video_url", models.URLField(blank=True, null=True)), - ( - "status", - models.CharField( - choices=[ - ("pending", "Pending"), - ("in_progress", "In Progress"), - ("completed", "Completed"), - ("failed", "Failed"), - ], - default="pending", - max_length=20, - ), - ), - ("created_at", models.DateTimeField(default=datetime.now)), - ("updated_at", models.DateTimeField(auto_now=True)), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ], - ), - ] diff --git a/WebAdmin/migrations/0006_videogeneration_slug.py b/WebAdmin/migrations/0006_videogeneration_slug.py deleted file mode 100755 index 90afbc0..0000000 --- a/WebAdmin/migrations/0006_videogeneration_slug.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-03 14:09 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0005_videogeneration"), - ] - - operations = [ - migrations.AddField( - model_name="videogeneration", - name="slug", - field=models.CharField(default=1, max_length=50), - preserve_default=False, - ), - ] diff --git a/WebAdmin/migrations/0007_plan.py b/WebAdmin/migrations/0007_plan.py deleted file mode 100755 index 2e8b6cc..0000000 --- a/WebAdmin/migrations/0007_plan.py +++ /dev/null @@ -1,37 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-24 04:16 - -from datetime import datetime - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0006_videogeneration_slug"), - ] - - operations = [ - migrations.CreateModel( - name="Plan", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("title", models.CharField(max_length=100, unique=True)), - ("description", models.TextField()), - ("price", models.DecimalField(decimal_places=2, max_digits=10)), - ("credits_per_month", models.IntegerField(default=0)), - ("created_at", models.DateTimeField(default=datetime.now)), - ("updated_at", models.DateTimeField(auto_now=True)), - ("is_promotional", models.BooleanField(default=False)), - ("unlimited_exports", models.BooleanField(default=False)), - ("smart_music_sync", models.BooleanField(default=False)), - ], - ), - ] diff --git a/WebAdmin/migrations/0008_order.py b/WebAdmin/migrations/0008_order.py deleted file mode 100755 index 0fef2f6..0000000 --- a/WebAdmin/migrations/0008_order.py +++ /dev/null @@ -1,62 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-24 12:15 - -import django.db.models.deletion -from datetime import datetime - -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0007_plan"), - ] - - operations = [ - migrations.CreateModel( - name="Order", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("order_id", models.CharField(max_length=100, unique=True)), - ("username", models.CharField(max_length=150)), - ("amount", models.DecimalField(decimal_places=2, max_digits=10)), - ( - "payment_method", - models.CharField( - choices=[("alipay", "Alipay"), ("paypal", "PayPal")], - max_length=10, - ), - ), - ( - "status", - models.CharField( - choices=[ - ("pending", "Pending"), - ("completed", "Completed"), - ("canceled", "Canceled"), - ("failed", "Failed"), - ], - default="pending", - max_length=10, - ), - ), - ("created_at", models.DateTimeField(default=datetime.now)), - ("updated_at", models.DateTimeField(auto_now=True)), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ], - ), - ] diff --git a/WebAdmin/migrations/0009_user_membership_end_user_membership_start.py b/WebAdmin/migrations/0009_user_membership_end_user_membership_start.py deleted file mode 100755 index d54af39..0000000 --- a/WebAdmin/migrations/0009_user_membership_end_user_membership_start.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-24 13:08 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0008_order"), - ] - - operations = [ - migrations.AddField( - model_name="user", - name="membership_end", - field=models.DateTimeField(blank=True, null=True), - ), - migrations.AddField( - model_name="user", - name="membership_start", - field=models.DateTimeField(blank=True, null=True), - ), - ] diff --git a/WebAdmin/migrations/0010_alter_order_options_order_plan.py b/WebAdmin/migrations/0010_alter_order_options_order_plan.py deleted file mode 100755 index c5cc28e..0000000 --- a/WebAdmin/migrations/0010_alter_order_options_order_plan.py +++ /dev/null @@ -1,31 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-26 13:02 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0009_user_membership_end_user_membership_start"), - ] - - operations = [ - migrations.AlterModelOptions( - name="order", - options={ - "ordering": ["-created_at"], - "verbose_name": "Order", - "verbose_name_plural": "Orders", - }, - ), - migrations.AddField( - model_name="order", - name="plan", - field=models.ForeignKey( - default=1, - on_delete=django.db.models.deletion.CASCADE, - to="WebAdmin.plan", - ), - preserve_default=False, - ), - ] diff --git a/WebAdmin/migrations/0011_alter_order_amount.py b/WebAdmin/migrations/0011_alter_order_amount.py deleted file mode 100755 index 5f06cdf..0000000 --- a/WebAdmin/migrations/0011_alter_order_amount.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-26 13:06 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0010_alter_order_options_order_plan"), - ] - - operations = [ - migrations.AlterField( - model_name="order", - name="amount", - field=models.DecimalField(decimal_places=2, default=0.0, max_digits=10), - ), - ] diff --git a/WebAdmin/migrations/0012_remove_videogeneration_id_videogeneration_video_id.py b/WebAdmin/migrations/0012_remove_videogeneration_id_videogeneration_video_id.py deleted file mode 100755 index 0494c8e..0000000 --- a/WebAdmin/migrations/0012_remove_videogeneration_id_videogeneration_video_id.py +++ /dev/null @@ -1,16 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-29 14:16 - -from django.db import migrations, models - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0011_alter_order_amount"), - ] - - operations = [ - migrations.AddField( - model_name="videogeneration", - name="video_id", - field=models.AutoField(primary_key=True, serialize=False), - ), - ] diff --git a/WebAdmin/migrations/0012_videogeneration_video_id.py b/WebAdmin/migrations/0012_videogeneration_video_id.py deleted file mode 100755 index f5a3d7d..0000000 --- a/WebAdmin/migrations/0012_videogeneration_video_id.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-29 14:38 - -from django.db import migrations - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0011_alter_order_amount"), - ] - - operations = [ - # 这里不再有任何操作,因为我们手动删除了重复的字段添加 - # migrations.AddField( - # model_name="videogeneration", - # name="video_id", - # field=models.CharField(default="", max_length=255, unique=True), - # ), - ] diff --git a/WebAdmin/migrations/0013_videogeneration_video_id.py b/WebAdmin/migrations/0013_videogeneration_video_id.py deleted file mode 100755 index 887df12..0000000 --- a/WebAdmin/migrations/0013_videogeneration_video_id.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-29 14:51 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0012_videogeneration_video_id"), - ] - - operations = [ - migrations.AddField( - model_name="videogeneration", - name="video_id", - field=models.CharField(default="", max_length=255, unique=True), - ), - ] diff --git a/WebAdmin/migrations/0014_videogeneration_pid.py b/WebAdmin/migrations/0014_videogeneration_pid.py deleted file mode 100755 index 3d22c85..0000000 --- a/WebAdmin/migrations/0014_videogeneration_pid.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.0.7 on 2024-08-30 02:50 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0013_videogeneration_video_id"), - ] - - operations = [ - migrations.AddField( - model_name="videogeneration", - name="pid", - field=models.CharField(default="", max_length=50, null=True), - ), - ] diff --git a/WebAdmin/migrations/0015_videogeneration_extension_count_and_more.py b/WebAdmin/migrations/0015_videogeneration_extension_count_and_more.py deleted file mode 100755 index e3fb993..0000000 --- a/WebAdmin/migrations/0015_videogeneration_extension_count_and_more.py +++ /dev/null @@ -1,42 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-14 10:14 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0014_videogeneration_pid"), - ] - - operations = [ - migrations.AddField( - model_name="videogeneration", - name="extension_count", - field=models.IntegerField(default=0), - ), - migrations.AlterField( - model_name="videogeneration", - name="media_type", - field=models.CharField(max_length=50, null=True), - ), - migrations.AlterField( - model_name="videogeneration", - name="rate", - field=models.IntegerField(default=0, null=True), - ), - migrations.AlterField( - model_name="videogeneration", - name="style", - field=models.CharField(default="general", max_length=50, null=True), - ), - migrations.AlterField( - model_name="videogeneration", - name="text", - field=models.TextField(null=True), - ), - migrations.AlterField( - model_name="videogeneration", - name="voice_name", - field=models.CharField(max_length=50, null=True), - ), - ] diff --git a/WebAdmin/migrations/0016_videogeneration_time_duration.py b/WebAdmin/migrations/0016_videogeneration_time_duration.py deleted file mode 100755 index c0f554b..0000000 --- a/WebAdmin/migrations/0016_videogeneration_time_duration.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-14 14:15 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0015_videogeneration_extension_count_and_more"), - ] - - operations = [ - migrations.AddField( - model_name="videogeneration", - name="time_duration", - field=models.IntegerField(default=0), - ), - ] diff --git a/WebAdmin/migrations/0017_user_openid_used_user_source.py b/WebAdmin/migrations/0017_user_openid_used_user_source.py deleted file mode 100755 index b7754cb..0000000 --- a/WebAdmin/migrations/0017_user_openid_used_user_source.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-15 06:08 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0016_videogeneration_time_duration"), - ] - - operations = [ - migrations.AddField( - model_name="user", - name="openid_used", - field=models.CharField(blank=True, max_length=150, null=True, unique=True), - ), - migrations.AddField( - model_name="user", - name="source", - field=models.CharField(default="web", max_length=50), - ), - ] diff --git a/WebAdmin/migrations/0018_transactionhistory.py b/WebAdmin/migrations/0018_transactionhistory.py deleted file mode 100755 index f4294e1..0000000 --- a/WebAdmin/migrations/0018_transactionhistory.py +++ /dev/null @@ -1,77 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-15 07:59 - -import django.db.models.deletion -from datetime import datetime - -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0017_user_openid_used_user_source"), - ] - - operations = [ - migrations.CreateModel( - name="TransactionHistory", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "feature", - models.CharField( - choices=[ - ("text-to-video", "AI文生视频"), - ("img-to-video", "AI图生视频"), - ("create-tiktok-video", "AI长视频生成"), - ("music-to-video", "音乐视频生成"), - ("create-avatar-video", "虚拟形象视频生成"), - ], - max_length=50, - verbose_name="功能类型", - ), - ), - ("points_spent", models.IntegerField(verbose_name="消费积分")), - ( - "char_count", - models.IntegerField(blank=True, null=True, verbose_name="字符数量"), - ), - ( - "description", - models.TextField(blank=True, null=True, verbose_name="操作描述"), - ), - ( - "transaction_date", - models.DateTimeField( - default=datetime.now, verbose_name="消费时间" - ), - ), - ("previous_points_balance", models.IntegerField(verbose_name="消费前积分")), - ("new_points_balance", models.IntegerField(verbose_name="消费后积分")), - ("success", models.BooleanField(default=True, verbose_name="是否成功")), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - related_name="transactions", - to=settings.AUTH_USER_MODEL, - verbose_name="用户", - ), - ), - ], - options={ - "verbose_name": "消费明细", - "verbose_name_plural": "消费明细", - "db_table": "transaction_history", - "ordering": ["-transaction_date"], - }, - ), - ] diff --git a/WebAdmin/migrations/0019_websiteinfo.py b/WebAdmin/migrations/0019_websiteinfo.py deleted file mode 100755 index c376ef0..0000000 --- a/WebAdmin/migrations/0019_websiteinfo.py +++ /dev/null @@ -1,50 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-15 08:05 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0018_transactionhistory"), - ] - - operations = [ - migrations.CreateModel( - name="WebsiteInfo", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "domain", - models.CharField(max_length=255, unique=True, verbose_name="域名"), - ), - ("title_en", models.CharField(max_length=255, verbose_name="英文标题")), - ("title_zh", models.CharField(max_length=255, verbose_name="中文标题")), - ("keywords_en", models.TextField(verbose_name="英文关键词")), - ("keywords_zh", models.TextField(verbose_name="中文关键词")), - ("description_en", models.TextField(verbose_name="英文描述")), - ("description_zh", models.TextField(verbose_name="中文描述")), - ( - "created_at", - models.DateTimeField(auto_now_add=True, verbose_name="创建时间"), - ), - ( - "updated_at", - models.DateTimeField(auto_now=True, verbose_name="更新时间"), - ), - ], - options={ - "verbose_name": "网站信息", - "verbose_name_plural": "网站信息", - "db_table": "website_info", - "ordering": ["-created_at"], - }, - ), - ] diff --git a/WebAdmin/migrations/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.py b/WebAdmin/migrations/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.py deleted file mode 100755 index 9418636..0000000 --- a/WebAdmin/migrations/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.py +++ /dev/null @@ -1,56 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-15 08:13 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0019_websiteinfo"), - ] - - operations = [ - migrations.RemoveField( - model_name="websiteinfo", - name="domain", - ), - migrations.AddField( - model_name="websiteinfo", - name="domain_en", - field=models.CharField(default=True, max_length=255, verbose_name="域名"), - ), - migrations.AddField( - model_name="websiteinfo", - name="domain_zh", - field=models.CharField(default=True, max_length=255, verbose_name="域名"), - ), - migrations.AlterField( - model_name="websiteinfo", - name="description_en", - field=models.TextField(default=True, verbose_name="英文描述"), - ), - migrations.AlterField( - model_name="websiteinfo", - name="description_zh", - field=models.TextField(default=True, verbose_name="中文描述"), - ), - migrations.AlterField( - model_name="websiteinfo", - name="keywords_en", - field=models.TextField(default=True, verbose_name="英文关键词"), - ), - migrations.AlterField( - model_name="websiteinfo", - name="keywords_zh", - field=models.TextField(default=True, verbose_name="中文关键词"), - ), - migrations.AlterField( - model_name="websiteinfo", - name="title_en", - field=models.CharField(default=True, max_length=255, verbose_name="英文标题"), - ), - migrations.AlterField( - model_name="websiteinfo", - name="title_zh", - field=models.CharField(default=True, max_length=255, verbose_name="中文标题"), - ), - ] diff --git a/WebAdmin/migrations/0021_websiteaccesslog.py b/WebAdmin/migrations/0021_websiteaccesslog.py deleted file mode 100755 index 9a13189..0000000 --- a/WebAdmin/migrations/0021_websiteaccesslog.py +++ /dev/null @@ -1,56 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-15 08:28 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more"), - ] - - operations = [ - migrations.CreateModel( - name="WebsiteAccessLog", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("ip_address", models.GenericIPAddressField(verbose_name="访问IP")), - ( - "browser_language", - models.CharField( - blank=True, max_length=50, null=True, verbose_name="浏览器语言" - ), - ), - ( - "referrer", - models.URLField(blank=True, null=True, verbose_name="来源URL"), - ), - ("request_path", models.CharField(max_length=255, verbose_name="请求路径")), - ( - "request_method", - models.CharField(max_length=10, verbose_name="请求方法"), - ), - ( - "access_time", - models.DateTimeField(auto_now_add=True, verbose_name="访问时间"), - ), - ( - "access_time_bj", - models.DateTimeField(blank=True, null=True, verbose_name="北京时间"), - ), - ], - options={ - "verbose_name": "网站访问日志", - "verbose_name_plural": "网站访问日志", - "db_table": "website_access_log", - "unique_together": {("ip_address", "access_time_bj")}, - }, - ), - ] diff --git a/WebAdmin/migrations/0022_alter_websiteaccesslog_unique_together_and_more.py b/WebAdmin/migrations/0022_alter_websiteaccesslog_unique_together_and_more.py deleted file mode 100755 index 983e03e..0000000 --- a/WebAdmin/migrations/0022_alter_websiteaccesslog_unique_together_and_more.py +++ /dev/null @@ -1,49 +0,0 @@ -# Generated by Django 5.0.7 on 2024-09-15 08:41 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("WebAdmin", "0021_websiteaccesslog"), - ] - - operations = [ - migrations.AlterUniqueTogether( - name="websiteaccesslog", - unique_together=set(), - ), - migrations.AddField( - model_name="websiteaccesslog", - name="access_date", - field=models.DateField(blank=True, null=True, verbose_name="访问日期"), - ), - migrations.AddField( - model_name="websiteaccesslog", - name="device_type", - field=models.CharField( - blank=True, max_length=50, null=True, verbose_name="设备类型" - ), - ), - migrations.AddField( - model_name="websiteaccesslog", - name="user_agent", - field=models.TextField(blank=True, null=True, verbose_name="用户代理"), - ), - migrations.AlterField( - model_name="websiteaccesslog", - name="browser_language", - field=models.CharField( - blank=True, max_length=200, null=True, verbose_name="浏览器语言" - ), - ), - migrations.AlterField( - model_name="websiteaccesslog", - name="referrer", - field=models.TextField(blank=True, null=True, verbose_name="来源URL"), - ), - migrations.AlterUniqueTogether( - name="websiteaccesslog", - unique_together={("ip_address", "access_date")}, - ), - ] diff --git a/WebAdmin/migrations/__pycache__/0001_initial.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0001_initial.cpython-310.pyc index 42af199..45f5511 100755 Binary files a/WebAdmin/migrations/__pycache__/0001_initial.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0001_initial.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0002_alter_article_options_alter_article_table.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0002_alter_article_options_alter_article_table.cpython-310.pyc new file mode 100644 index 0000000..d9abb55 Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0002_alter_article_options_alter_article_table.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0002_user_last_login_ip_user_login_count.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0002_user_last_login_ip_user_login_count.cpython-310.pyc index 76c017e..f9bafe3 100755 Binary files a/WebAdmin/migrations/__pycache__/0002_user_last_login_ip_user_login_count.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0002_user_last_login_ip_user_login_count.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0003_alter_article_table.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0003_alter_article_table.cpython-310.pyc new file mode 100644 index 0000000..6cfa6d0 Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0003_alter_article_table.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0003_alter_user_options_alter_user_managers_and_more.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0003_alter_user_options_alter_user_managers_and_more.cpython-310.pyc index 0214770..5260c4c 100755 Binary files a/WebAdmin/migrations/__pycache__/0003_alter_user_options_alter_user_managers_and_more.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0003_alter_user_options_alter_user_managers_and_more.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0004_emailverificationcode_smsverificationcode.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0004_emailverificationcode_smsverificationcode.cpython-310.pyc index e68010e..14b01cc 100755 Binary files a/WebAdmin/migrations/__pycache__/0004_emailverificationcode_smsverificationcode.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0004_emailverificationcode_smsverificationcode.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0005_videogeneration.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0005_videogeneration.cpython-310.pyc index 9720a53..28a8a06 100755 Binary files a/WebAdmin/migrations/__pycache__/0005_videogeneration.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0005_videogeneration.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0006_videogeneration_slug.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0006_videogeneration_slug.cpython-310.pyc index 4abdb70..2ce0cfc 100755 Binary files a/WebAdmin/migrations/__pycache__/0006_videogeneration_slug.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0006_videogeneration_slug.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0007_plan.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0007_plan.cpython-310.pyc index ab76f82..64c2863 100755 Binary files a/WebAdmin/migrations/__pycache__/0007_plan.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0007_plan.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0008_order.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0008_order.cpython-310.pyc index 8de8474..e1cd676 100755 Binary files a/WebAdmin/migrations/__pycache__/0008_order.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0008_order.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0009_user_membership_end_user_membership_start.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0009_user_membership_end_user_membership_start.cpython-310.pyc index dfec80f..759f80b 100755 Binary files a/WebAdmin/migrations/__pycache__/0009_user_membership_end_user_membership_start.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0009_user_membership_end_user_membership_start.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0010_alter_order_options_order_plan.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0010_alter_order_options_order_plan.cpython-310.pyc index de88a59..d3867a8 100755 Binary files a/WebAdmin/migrations/__pycache__/0010_alter_order_options_order_plan.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0010_alter_order_options_order_plan.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0011_alter_order_amount.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0011_alter_order_amount.cpython-310.pyc index 4b572ac..8181ad9 100755 Binary files a/WebAdmin/migrations/__pycache__/0011_alter_order_amount.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0011_alter_order_amount.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0012_remove_videogeneration_id_videogeneration_video_id.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0012_remove_videogeneration_id_videogeneration_video_id.cpython-310.pyc new file mode 100644 index 0000000..05b6010 Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0012_remove_videogeneration_id_videogeneration_video_id.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0012_videogeneration_video_id.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0012_videogeneration_video_id.cpython-310.pyc index a8316fa..0acc016 100755 Binary files a/WebAdmin/migrations/__pycache__/0012_videogeneration_video_id.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0012_videogeneration_video_id.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0013_videogeneration_video_id.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0013_videogeneration_video_id.cpython-310.pyc index 4494e0f..7d29b31 100755 Binary files a/WebAdmin/migrations/__pycache__/0013_videogeneration_video_id.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0013_videogeneration_video_id.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0014_videogeneration_pid.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0014_videogeneration_pid.cpython-310.pyc index 65cc350..37f6ad1 100755 Binary files a/WebAdmin/migrations/__pycache__/0014_videogeneration_pid.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0014_videogeneration_pid.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0015_videogeneration_extension_count_and_more.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0015_videogeneration_extension_count_and_more.cpython-310.pyc index 7943a67..fa4ca1f 100755 Binary files a/WebAdmin/migrations/__pycache__/0015_videogeneration_extension_count_and_more.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0015_videogeneration_extension_count_and_more.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0016_videogeneration_time_duration.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0016_videogeneration_time_duration.cpython-310.pyc index 52a0562..d28a274 100755 Binary files a/WebAdmin/migrations/__pycache__/0016_videogeneration_time_duration.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0016_videogeneration_time_duration.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0017_user_openid_used_user_source.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0017_user_openid_used_user_source.cpython-310.pyc index 3d3b450..37d0cdb 100755 Binary files a/WebAdmin/migrations/__pycache__/0017_user_openid_used_user_source.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0017_user_openid_used_user_source.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0018_transactionhistory.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0018_transactionhistory.cpython-310.pyc index 3d00139..08d3475 100755 Binary files a/WebAdmin/migrations/__pycache__/0018_transactionhistory.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0018_transactionhistory.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0019_websiteinfo.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0019_websiteinfo.cpython-310.pyc index 7d19cf4..66284fc 100755 Binary files a/WebAdmin/migrations/__pycache__/0019_websiteinfo.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0019_websiteinfo.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.cpython-310.pyc index 1731cc2..00f5fb2 100755 Binary files a/WebAdmin/migrations/__pycache__/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0020_remove_websiteinfo_domain_websiteinfo_domain_en_and_more.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0021_websiteaccesslog.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0021_websiteaccesslog.cpython-310.pyc index 0dd4fbf..868b429 100755 Binary files a/WebAdmin/migrations/__pycache__/0021_websiteaccesslog.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0021_websiteaccesslog.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0022_alter_websiteaccesslog_unique_together_and_more.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0022_alter_websiteaccesslog_unique_together_and_more.cpython-310.pyc index 3f60a66..476faf1 100755 Binary files a/WebAdmin/migrations/__pycache__/0022_alter_websiteaccesslog_unique_together_and_more.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/0022_alter_websiteaccesslog_unique_together_and_more.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0023_alter_user_date_joined.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0023_alter_user_date_joined.cpython-310.pyc new file mode 100644 index 0000000..10ded31 Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0023_alter_user_date_joined.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0023_merge_20240923_2244.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0023_merge_20240923_2244.cpython-310.pyc new file mode 100644 index 0000000..e3bf5ab Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0023_merge_20240923_2244.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0024_merge_20240923_2155.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0024_merge_20240923_2155.cpython-310.pyc new file mode 100644 index 0000000..f52d939 Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0024_merge_20240923_2155.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0025_article_alter_videogeneration_video_id.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0025_article_alter_videogeneration_video_id.cpython-310.pyc new file mode 100644 index 0000000..7fb726a Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0025_article_alter_videogeneration_video_id.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/0026_alter_videogeneration_created_at.cpython-310.pyc b/WebAdmin/migrations/__pycache__/0026_alter_videogeneration_created_at.cpython-310.pyc new file mode 100644 index 0000000..6c58577 Binary files /dev/null and b/WebAdmin/migrations/__pycache__/0026_alter_videogeneration_created_at.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/__init__.cpython-310.pyc b/WebAdmin/migrations/__pycache__/__init__.cpython-310.pyc index 4da53ea..1fa0e08 100755 Binary files a/WebAdmin/migrations/__pycache__/__init__.cpython-310.pyc and b/WebAdmin/migrations/__pycache__/__init__.cpython-310.pyc differ diff --git a/WebAdmin/migrations/__pycache__/admin_views.cpython-311.pyc b/WebAdmin/migrations/__pycache__/admin_views.cpython-311.pyc deleted file mode 100644 index 07a6cf3..0000000 Binary files a/WebAdmin/migrations/__pycache__/admin_views.cpython-311.pyc and /dev/null differ diff --git a/WebAdmin/migrations/admin_views.py b/WebAdmin/migrations/admin_views.py deleted file mode 100755 index e69de29..0000000 diff --git a/WebAdmin/models.py b/WebAdmin/models.py index 9e3d545..6b9090c 100755 --- a/WebAdmin/models.py +++ b/WebAdmin/models.py @@ -85,7 +85,7 @@ class VideoGeneration(models.Model): ('failed', 'Failed'), ] - video_id = models.CharField(max_length=255, unique=True, default='') + video_id = models.CharField(max_length=255, default='') user = models.ForeignKey(User, on_delete=models.CASCADE) # 生成请求的用户 text = models.TextField(null=True) # 输入文本 voice_name = models.CharField(max_length=50, null=True) # 选择的语音 @@ -96,7 +96,7 @@ class VideoGeneration(models.Model): audio_url = models.URLField(null=True, blank=True) # 生成的音频URL video_url = models.URLField(null=True, blank=True) # 生成的视频URL status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending') # 生成状态 - created_at = models.DateTimeField(default=datetime.now) # 创建时间 + created_at = models.DateTimeField(auto_now_add=True) # 创建时间 updated_at = models.DateTimeField(auto_now=True) # 更新时间 slug = models.CharField(max_length=50) # 生成视频的类型 pid = models.CharField(max_length=50, null=True, default='') # 生成视频的ID @@ -232,4 +232,30 @@ class WebsiteAccessLog(models.Model): def __str__(self): access_time_str = self.access_time_bj.strftime('%Y-%m-%d %H:%M:%S') if self.access_time_bj else 'N/A' - return f"{self.ip_address} - {access_time_str}" \ No newline at end of file + return f"{self.ip_address} - {access_time_str}" + + +class Article(models.Model): + STATUS_CHOICES = [ + ('published', '已发布'), + ('pending', '待审核'), + ] + + chinese_title = models.CharField(max_length=255) + english_title = models.CharField(max_length=255) + chinese_keywords = models.TextField() # 使用 TextField 允许存储更长的字符串 + english_keywords = models.TextField() + chinese_content = models.TextField() + english_content = models.TextField() + source_url = models.URLField(blank=True, null=True) + published_at = models.DateTimeField(blank=True, null=True) + image_url = models.URLField(blank=True, null=True) + status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending') + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + class Meta: + verbose_name = 'Article' + verbose_name_plural = 'Article' + ordering = ['-created_at'] + def __str__(self): + return self.chinese_title # 或者返回英文标题,根据需要选择 diff --git a/WebAdmin/urls.py b/WebAdmin/urls.py index 7b763f5..fc5817b 100755 --- a/WebAdmin/urls.py +++ b/WebAdmin/urls.py @@ -10,6 +10,7 @@ from . import ali_pay # 支付宝接口 from . import create_text_img_video # 支付宝接口 from . import AccessLog # 支付宝接口 from . import task_all # 扫描全部任务 +from . import 文章 # 网站首页文章 urlpatterns = [ #网站信息相关 path('api/website/', AccessLog.website_info_view, name='website_config'), #获取网站信息 @@ -70,6 +71,27 @@ urlpatterns = [ path('api/reset-password/', user.reset_password_view, name='reset_password'), # 重置密码API # 后台管理相关路由 - path('custom_admin/login/', admin_views.admin_login_view, name='admin_login'), # 后台登录视图 + path('custom_admin/3acf16259def65456fc2a68ab5e10d96/', admin_views.admin_login_view, name='admin_login'), # 后台登录视图 path('custom_admin/home/', admin_views.admin_home_view, name='admin_home'), # 后台主页视图 + path('custom_admin/change-password/', admin_views.admin_change_password, name='admin_change_password'),#修改管理员密码 + path('custom_admin/logout/', admin_views.admin_logout, name='admin_logout'),#退出登录 + path('custom_admin/home/site-info/', admin_views.admin_site_info_view, name='site-info'), # 基本信息 + path('custom_admin/home/article-list/', admin_views.admin_article_list, name='aricle-list'), # 文章列表 + path('custom_admin/home/user-list/', admin_views.admin_user_list, name='aricle-list'), # 文章列表 + path('custom_admin/home/task-list/', admin_views.admin_task_list, name='task-list'), # 用户列表 + path('custom_admin/home/order-list/', admin_views.admin_order_list, name='order-list'), # 订单列表 + # 文章保存(添加或编辑) + path('custom_admin/home/save-article/', admin_views.save_article, name='save_article'), # 添加文章 + path('custom_admin/home/save-article//', admin_views.save_article, name='edit_article'), # 编辑文章,带文章 ID + + # 图片上传专用于编辑器 + path('articles///', admin_views.ArticleDetailView, name='article_detail'), #查看文章 + path('api/upload_article_image/', admin_views.upload_editor_image, name='upload_editor_image'), + path('api/delete-article//', admin_views.ArticleManagementView.as_view(), name='delete_article'), + path('api/audit-article//', admin_views.ArticleManagementView.as_view(), name='audit_article'), + + path('admin/captcha/', admin_views.generate_captcha, name='captcha_image'), + + path('api/article-list/', 文章.article_list, name='admin_article_list'), # 文章列表页 + path('api/article///', 文章.article_detail, name='admin_article_detail'), # 文章详情页 ] diff --git a/WebAdmin/文章.py b/WebAdmin/文章.py new file mode 100644 index 0000000..5ffdaed --- /dev/null +++ b/WebAdmin/文章.py @@ -0,0 +1,113 @@ +from django.core.paginator import Paginator +from django.http import JsonResponse + +from django.core.exceptions import ValidationError +from django.utils.html import escape +from .models import Article +from django.shortcuts import get_object_or_404 +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger + +# 文章列表页视图,带分页和请求频率限制 +def article_list(request): + + # 获取分页参数 + page = request.GET.get('page', 1) # 当前页数,默认为第一页 + limit = request.GET.get('limit', 10) # 每页文章数,默认为10 + + # 获取所有文章,并按发布时间倒序排序 + articles = Article.objects.all().order_by('-published_at') + + # 使用 Paginator 进行分页 + paginator = Paginator(articles, limit) + + try: + current_page = paginator.page(page) # 获取当前页的数据 + except PageNotAnInteger: + current_page = paginator.page(1) # 如果请求的页数不存在,默认返回第一页 + except EmptyPage: + # 如果页码超出范围,返回空列表 + return JsonResponse({'code': 200, 'message': '没有更多数据', 'data': {}}) + + # 将文章列表转换为字典列表 + articles_list = list(current_page.object_list.values('id', 'chinese_title', 'english_title', 'published_at', 'status')) + + # 格式化文章的发布时间 + for article in articles_list: + article['published_at'] = article['published_at'].strftime('%Y-%m-%d %H:%M:%S') if article['published_at'] else '未发布' + + # 返回 JSON 数据,适配前端使用 + data = { + "code": 200, + "msg": "成功", + "count": paginator.count, # 文章总数 + "data": articles_list + } + + return JsonResponse(data) + +def article_detail(request, pk, lang): + try: + # 检查是否传入了危险参数 (如防止SQL注入等) + pk = escape(pk) # 对传入的主键进行转义,避免潜在的注入风险 + lang = escape(lang) # 对语言参数进行转义 + + # 检查参数是否有效 + if not pk or not lang: + raise ValidationError('参数不能为空') + + # 检查语言是否有效 + if lang not in ['zh', 'en']: + return JsonResponse({ + "code": 400, + "msg": "无效的语言参数", + "data": {} + }) + + # 获取指定的文章 + article = get_object_or_404(Article, pk=pk) + + # 根据语言参数返回不同语言的文章内容 + if lang == 'en': + title = article.english_title + keywords = article.english_keywords + content = article.english_content + else: + title = article.chinese_title + keywords = article.chinese_keywords + content = article.chinese_content + + # 构造响应数据 + data = { + "code": 200, + "msg": "成功", + "data": { + 'id': article.id, + 'title': title, + 'keywords': keywords, + 'content': content, + 'published_at': article.published_at.strftime('%Y-%m-%d %H:%M:%S') if article.published_at else '未发布', + 'status': article.status + } + } + return JsonResponse(data) + + except ValidationError as ve: + return JsonResponse({ + "code": 400, + "msg": str(ve), + "data": {} + }) + + except Article.DoesNotExist: + return JsonResponse({ + "code": 404, + "msg": "未找到对应的文章", + "data": {} + }) + + except Exception as e: + return JsonResponse({ + "code": 500, + "msg": "服务器内部错误", + "data": {"error": str(e)} + }) \ No newline at end of file diff --git a/WebSite.zip b/WebSite.zip new file mode 100644 index 0000000..c557035 Binary files /dev/null and b/WebSite.zip differ diff --git a/WebSite/__pycache__/__init__.cpython-310.pyc b/WebSite/__pycache__/__init__.cpython-310.pyc index 7d27869..6de6f8b 100755 Binary files a/WebSite/__pycache__/__init__.cpython-310.pyc and b/WebSite/__pycache__/__init__.cpython-310.pyc differ diff --git a/WebSite/__pycache__/settings.cpython-310.pyc b/WebSite/__pycache__/settings.cpython-310.pyc index 0b72c1f..0b429d2 100755 Binary files a/WebSite/__pycache__/settings.cpython-310.pyc and b/WebSite/__pycache__/settings.cpython-310.pyc differ diff --git a/WebSite/__pycache__/urls.cpython-310.pyc b/WebSite/__pycache__/urls.cpython-310.pyc index 5676562..1f89ac1 100755 Binary files a/WebSite/__pycache__/urls.cpython-310.pyc and b/WebSite/__pycache__/urls.cpython-310.pyc differ diff --git a/WebSite/__pycache__/wsgi.cpython-310.pyc b/WebSite/__pycache__/wsgi.cpython-310.pyc index c7ccfc6..57da765 100755 Binary files a/WebSite/__pycache__/wsgi.cpython-310.pyc and b/WebSite/__pycache__/wsgi.cpython-310.pyc differ diff --git a/WebSite/settings.py b/WebSite/settings.py index 8848087..79819b5 100755 --- a/WebSite/settings.py +++ b/WebSite/settings.py @@ -23,7 +23,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent SECRET_KEY = "django-insecure-!4a*kl(!=s*76xngra89q*86d&e8ya=l49!bibepo6p1(50+$s" # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = False +DEBUG = True ALLOWED_HOSTS = ['*'] # settings.py @@ -33,13 +33,14 @@ AUTH_USER_MODEL = 'WebAdmin.User' # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', + # 'django.contrib.admin', "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", 'WebAdmin.apps.WebadminConfig', + 'captcha', 'django.contrib.sites', # Django sites framework 'allauth', # Django allauth 'allauth.account', # Django allauth accounts @@ -149,7 +150,7 @@ TEMPLATES = [ WSGI_APPLICATION = "WebSite.wsgi.application" - +X_FRAME_OPTIONS='SAMEORIGIN' # Database # https://docs.djangoproject.com/en/5.0/ref/settings/#databases @@ -159,7 +160,7 @@ DATABASES = { { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'admin_data', # 数据库名称 - 'HOST': '127.0.0.1', # 数据库地址,本机 ip 地址 127.0.0.1 + 'HOST': '47.243.173.144', # 数据库地址,本机 ip 地址 127.0.0.1 'PORT': 3306, # mysql端口 'USER': 'admin_data', # 数据库用户名 'PASSWORD': 'kyRz3c3hGMmDADrW', # 数据库密码 diff --git a/WebSite/urls.py b/WebSite/urls.py index 8147bce..4212d72 100755 --- a/WebSite/urls.py +++ b/WebSite/urls.py @@ -19,7 +19,7 @@ from django.urls import path from django.urls import path, include from WebAdmin import views urlpatterns = [ - path('admin/', admin.site.urls), + # path('admin/', admin.site.urls), path('', include('WebAdmin.urls')), path('.well-known/pki-validation/1ECB936A2BFA886CCCAE51329C4219CF.txt',views.acme_challenge), path('accounts/', include('allauth.urls')), diff --git a/media/editor_images/06f6d230-d434-44df-bb3c-b9d0e9ea9337.jpg b/media/editor_images/06f6d230-d434-44df-bb3c-b9d0e9ea9337.jpg new file mode 100644 index 0000000..7b46149 Binary files /dev/null and b/media/editor_images/06f6d230-d434-44df-bb3c-b9d0e9ea9337.jpg differ diff --git a/media/editor_images/2f17b948-a8df-4e05-9122-0010dfe5b5b1.jpeg b/media/editor_images/2f17b948-a8df-4e05-9122-0010dfe5b5b1.jpeg new file mode 100644 index 0000000..9a25172 Binary files /dev/null and b/media/editor_images/2f17b948-a8df-4e05-9122-0010dfe5b5b1.jpeg differ diff --git a/media/editor_images/353337b5-f266-4774-aee8-54a8f6f13257.jpg b/media/editor_images/353337b5-f266-4774-aee8-54a8f6f13257.jpg new file mode 100644 index 0000000..7b46149 Binary files /dev/null and b/media/editor_images/353337b5-f266-4774-aee8-54a8f6f13257.jpg differ diff --git a/media/editor_images/54db240f-6cfa-499c-aadd-9b757828480e.jpeg b/media/editor_images/54db240f-6cfa-499c-aadd-9b757828480e.jpeg new file mode 100644 index 0000000..9a25172 Binary files /dev/null and b/media/editor_images/54db240f-6cfa-499c-aadd-9b757828480e.jpeg differ diff --git a/media/editor_images/6c7a946e-f802-41fa-86a1-272f9df9018e.jpg b/media/editor_images/6c7a946e-f802-41fa-86a1-272f9df9018e.jpg new file mode 100644 index 0000000..7b46149 Binary files /dev/null and b/media/editor_images/6c7a946e-f802-41fa-86a1-272f9df9018e.jpg differ diff --git a/media/editor_images/c0e5b23c-5b52-40d2-902e-61ca8555ba64.png b/media/editor_images/c0e5b23c-5b52-40d2-902e-61ca8555ba64.png new file mode 100644 index 0000000..c7e0c67 Binary files /dev/null and b/media/editor_images/c0e5b23c-5b52-40d2-902e-61ca8555ba64.png differ diff --git a/requirements.txt b/requirements.txt index 5450b50..09e9d91 100755 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/templates/admin/add-article.html b/templates/admin/add-article.html new file mode 100644 index 0000000..e07d224 --- /dev/null +++ b/templates/admin/add-article.html @@ -0,0 +1,262 @@ + + + + + + 网站信息管理 + + + + + + + +
+
+ {% csrf_token %} + + +
+
+
+
+ + {% if article.image_url %} + 封面图片 + {% else %} + + {% endif %} + +
+
+
+
+ + +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+
+ + +
+ +
+
+
+ + + + + + diff --git a/templates/admin/admin_login.html b/templates/admin/admin_login.html index a4f7e26..c2b1bb6 100755 --- a/templates/admin/admin_login.html +++ b/templates/admin/admin_login.html @@ -6,55 +6,82 @@ +
+ + + 验证码 +
- -
- -
-
-

登录中,请稍候...

+
+ + diff --git a/templates/admin/article-list.html b/templates/admin/article-list.html new file mode 100644 index 0000000..e68778a --- /dev/null +++ b/templates/admin/article-list.html @@ -0,0 +1,217 @@ + + + + + + 文章管理 + + + + + + +
+
+
+ +
+
+ + +
+
+ + + + +
+ + + +
+

总文章数量: 0

+

今日发表数量: 0

+

待审核数量: 0

+
+
+{% verbatim %} + + +{% endverbatim %} + + + + + diff --git a/templates/admin/article_detail.html b/templates/admin/article_detail.html new file mode 100644 index 0000000..5fe2a16 --- /dev/null +++ b/templates/admin/article_detail.html @@ -0,0 +1,181 @@ + + + + + {{ title }} + + + + + + +
+
+ + 光映 logo + +
+
+ + +
+
+

{{ title }}

+

发布时间:{{ published_at }}

+

{{ content }}

+
+
+ + + + + diff --git a/templates/admin/home.html b/templates/admin/home.html index 56a6051..6c3c693 100755 --- a/templates/admin/home.html +++ b/templates/admin/home.html @@ -1 +1,190 @@ -1 \ No newline at end of file +{% load static %} + + + + + 后台管理系统 + + + + + + + + + + + + + +
+
+ + +
+ +
+
+
+
+
+ + + + + + + + diff --git a/templates/admin/order-list.html b/templates/admin/order-list.html new file mode 100644 index 0000000..5bc50cf --- /dev/null +++ b/templates/admin/order-list.html @@ -0,0 +1,137 @@ + + + + +
+

订单列表

+ +
+ +
+

总订单数量: 0

+

支付宝订单数量: 0--¥:人民币

+

贝宝订单数量: 0--$:美金

+

待处理订单: 0

+

已完成订单: 0

+

已取消订单: 0

+

失败订单: 0

+
+
+ + + + + diff --git a/templates/admin/site-info.html b/templates/admin/site-info.html new file mode 100644 index 0000000..691f7b8 --- /dev/null +++ b/templates/admin/site-info.html @@ -0,0 +1,142 @@ +{% load static %} +{% block content %} + + +
+
网站信息
+
+
+ {% csrf_token %} +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+
+ +
+
+
+
+
+ + +{% endblock %} diff --git a/templates/admin/task-list.html b/templates/admin/task-list.html new file mode 100644 index 0000000..afc72e5 --- /dev/null +++ b/templates/admin/task-list.html @@ -0,0 +1,108 @@ + + + + + +
+

任务列表

+ +
+ +
+

总任务数量: 0

+

分类统计: + +

+

状态统计: + 成功: 0, + 失败: 0, + 进行中: 0, +

+
+
+{% verbatim %} + +{% endverbatim %} + diff --git a/templates/admin/user-list.html b/templates/admin/user-list.html new file mode 100644 index 0000000..d20246f --- /dev/null +++ b/templates/admin/user-list.html @@ -0,0 +1,116 @@ + + + + +
+

用户列表

+ +
+ +
+

总用户数量: 0

+
+
+ + + + + +