From 81d0dd0f07c3df7bdce528e71f15019fd003fa85 Mon Sep 17 00:00:00 2001 From: xiaji Date: Wed, 31 Dec 2025 09:01:57 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=B8=80=E4=B8=AA=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E7=9A=84=E5=BC=B9=E5=B9=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 44 + .trae/documents/Django弹幕活动应用实现计划.md | 225 +++++ activity/__init__.py | 0 activity/admin.py | 7 + activity/apps.py | 6 + activity/forms.py | 32 + activity/migrations/0001_initial.py | 58 ++ ...ysetting_qr_code_margin_bottom_and_more.py | 33 + activity/migrations/__init__.py | 0 activity/models.py | 59 ++ activity/templates/activity/admin_review.html | 111 +++ activity/templates/activity/index.html | 279 +++++++ activity/templates/activity/setting.html | 193 +++++ activity/templates/activity/submit.html | 123 +++ activity/templates/base.html | 22 + activity/tests.py | 3 + activity/urls.py | 10 + activity/utils.py | 780 ++++++++++++++++++ activity/views.py | 98 +++ add_default_blessings.py | 26 + add_test_danmus.py | 49 ++ create_setting.py | 21 + danmu_activity/__init__.py | 0 danmu_activity/asgi.py | 16 + danmu_activity/settings.py | 128 +++ danmu_activity/urls.py | 25 + danmu_activity/wsgi.py | 16 + manage.py | 22 + 28 files changed, 2386 insertions(+) create mode 100644 .gitignore create mode 100644 .trae/documents/Django弹幕活动应用实现计划.md create mode 100644 activity/__init__.py create mode 100644 activity/admin.py create mode 100644 activity/apps.py create mode 100644 activity/forms.py create mode 100644 activity/migrations/0001_initial.py create mode 100644 activity/migrations/0002_activitysetting_qr_code_margin_bottom_and_more.py create mode 100644 activity/migrations/__init__.py create mode 100644 activity/models.py create mode 100644 activity/templates/activity/admin_review.html create mode 100644 activity/templates/activity/index.html create mode 100644 activity/templates/activity/setting.html create mode 100644 activity/templates/activity/submit.html create mode 100644 activity/templates/base.html create mode 100644 activity/tests.py create mode 100644 activity/urls.py create mode 100644 activity/utils.py create mode 100644 activity/views.py create mode 100644 add_default_blessings.py create mode 100644 add_test_danmus.py create mode 100644 create_setting.py create mode 100644 danmu_activity/__init__.py create mode 100644 danmu_activity/asgi.py create mode 100644 danmu_activity/settings.py create mode 100644 danmu_activity/urls.py create mode 100644 danmu_activity/wsgi.py create mode 100644 manage.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..213f60f --- /dev/null +++ b/.gitignore @@ -0,0 +1,44 @@ +# Django项目常见的.gitignore配置 + +# 虚拟环境 +venv/ +env/ +ENV/ +.venv/ + +# Python编译文件 +__pycache__/ +*.py[cod] +*$py.class + +# Django相关 +local_settings.py +*.sqlite3 +*.db +*.log +media/ +staticfiles/ +.env + +# 测试相关 +pytest_cache/ +.tox/ +.coverage +htmlcov/ + +# IDE相关 +.idea/ +.vscode/ +*.swp +*.swo +*~ +.DS_Store + +# 脚本文件(根据项目情况可调整) +*.sh +*.bat + +# 其他 +.cache/ +*.egg-info/ +MANIFEST diff --git a/.trae/documents/Django弹幕活动应用实现计划.md b/.trae/documents/Django弹幕活动应用实现计划.md new file mode 100644 index 0000000..888a013 --- /dev/null +++ b/.trae/documents/Django弹幕活动应用实现计划.md @@ -0,0 +1,225 @@ +# Django弹幕活动应用实现计划 + +## 项目结构 + +``` +danmu_activity/ +├── danmu_activity/ # 项目配置目录 +│ ├── __init__.py +│ ├── settings.py +│ ├── urls.py +│ └── wsgi.py +├── activity/ # 主应用 +│ ├── __init__.py +│ ├── admin.py +│ ├── apps.py +│ ├── models.py # 数据库模型 +│ ├── views.py # 视图函数 +│ ├── urls.py # 应用路由 +│ ├── utils.py # 工具函数(如随机祝福语) +│ ├── static/ # 静态文件 +│ │ ├── css/ +│ │ ├── js/ +│ │ └── media/ # 上传的媒体文件 +│ └── templates/ # 模板文件 +│ ├── activity/ +│ └── admin/ +├── manage.py +└── requirements.txt +``` + +activity/forms.py 定义表单类(提交弹幕表单、活动设置表单、图片上传表单),替代模板原生表单,提升安全性和可维护性 + +
+ +templates/base.html 基础模板(统一页面布局、引入 Bootstrap/jQuery 公共资源,其他模板继承使用) +templates/404.html 自定义 404 错误页面(提升用户体验) +templates/500.html 自定义 500 错误页面(方便线上问题排查) + +## 数据库设计 + +### 1. 活动设置模型(ActivitySetting) + +* 背景图片(ImageField) + +* 背景视频(FileField) + +* 二维码图片(ImageField) + +* 二维码位置(CharField:top-left, top-right, bottom-left, bottom-right, center) + +* 弹幕字体颜色(CharField:十六进制颜色码) + +* 弹幕背景颜色(CharField:十六进制颜色码) + +* 全局背景颜色(CharField:十六进制颜色码) + +### 2. 祝福语模型(Blessing) + +* 内容(TextField) + +### 3. 弹幕消息模型(Danmu) + +* 姓名(CharField) + +* 祝福语(TextField) + +* 图片(ImageField, 可选) + +* 审核状态(BooleanField:默认False,未审核) + +* 创建时间(DateTimeField) + +## 视图设计 + +### 1. 主页面视图(index) + +* 显示全屏背景(图片/视频) + +* 显示二维码 + +* 实时显示已审核通过的弹幕 + +### 2. 扫码提交视图(submit) + +* 显示表单:姓名输入框、祝福语输入框(带5条随机推荐)、图片上传 + +* 提交后保存到数据库,等待审核 + +### 3. 管理员审核视图(admin\_review) + +* 显示所有未审核的弹幕 + +* 支持通过/不通过审核 + +### 4. 设置视图(setting) + +* 管理员可设置背景图片/视频、二维码图片、位置、弹幕颜色等 + +### 5. API视图 + +* 获取实时弹幕列表(JSON格式) + +## 模板设计 + +### 1. 主页面模板(index.html) + +* 全屏布局 + +* 背景图片/视频自适应 + +* 二维码定位显示 + +* 弹幕滚动效果 + +### 2. 提交表单模板(submit.html) + +* 响应式设计,适配手机 + +* 表单验证 + +* 随机祝福语推荐 + +* 图片上传预览 + +### 3. 审核页面模板(admin\_review\.html) + +* 表格展示待审核弹幕 + +* 操作按钮(通过/不通过) + +* 批量审核功能 + +* 筛选功能 + +* 时间 + +### 4. 设置页面模板(setting.html) + +* 表单设计,支持文件上传 + +* 实时预览效果 + +## 静态资源 + +### 1. CSS + +* 全屏布局样式 + +* 弹幕滚动动画 + +* 响应式设计 + +### 2. JavaScript + +* 实时获取弹幕(Ajax轮询) + +* 弹幕动画效果,从右向左滑动,多行显示, + +* 考虑到有些弹幕包含图片,计算图片的高度和宽度,不遮挡其它文字弹幕 + +* 表单验证和提交 + +### 3. 媒体文件 + +* 默认背景图片 + +* 默认二维码图片 + +* 上传的用户图片存储目录 + +## 工具函数 + +### 1. 随机祝福语生成 + +* 从数据库中随机获取5条祝福语 + +* 提供几百条预设祝福语 + +### 2. 媒体文件处理 + +* 图片压缩 + +* 视频格式验证 + +## 实现步骤 + +1. 初始化Django项目 +2. 创建应用和基本模型 +3. 实现管理员后台配置 +4. 添加预设祝福语 +5. 实现扫码提交功能 +6. 实现主页面弹幕显示 +7. 实现管理员审核功能 +8. 实现设置页面 +9. 添加CSS样式和JavaScript交互 +10. 测试和优化 + +## 技术栈 + +* Django 5.2.9 + +* Bootstrap 5(前端框架) + +* jQuery(简化DOM操作) + +* SQLite(开发环境数据库) + +## 安全考虑 + +* 图片上传验证和限制 + +* 管理员页面权限控制 + +* 防止XSS攻击 + +* CSRF保护 + +## 部署考虑 + +* 静态文件和媒体文件的部署 + +* 数据库迁移 + +* 性能优化(如弹幕缓存) + diff --git a/activity/__init__.py b/activity/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/activity/admin.py b/activity/admin.py new file mode 100644 index 0000000..891da05 --- /dev/null +++ b/activity/admin.py @@ -0,0 +1,7 @@ +from django.contrib import admin +from .models import ActivitySetting, Blessing, Danmu + +# Register your models here. +admin.site.register(ActivitySetting) +admin.site.register(Blessing) +admin.site.register(Danmu) diff --git a/activity/apps.py b/activity/apps.py new file mode 100644 index 0000000..687f354 --- /dev/null +++ b/activity/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ActivityConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'activity' diff --git a/activity/forms.py b/activity/forms.py new file mode 100644 index 0000000..6ab3c76 --- /dev/null +++ b/activity/forms.py @@ -0,0 +1,32 @@ +from django import forms +from .models import ActivitySetting, Danmu + +class DanmuForm(forms.ModelForm): + """弹幕提交表单""" + class Meta: + model = Danmu + fields = ['name', 'content', 'image'] + widgets = { + 'name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入您的姓名'}), + 'content': forms.Textarea(attrs={'class': 'form-control', 'placeholder': '请输入祝福语', 'rows': 3}), + 'image': forms.FileInput(attrs={'class': 'form-control'}), + } + +class ActivitySettingForm(forms.ModelForm): + """活动设置表单""" + class Meta: + model = ActivitySetting + fields = ['background_image', 'background_video', 'qr_code_image', 'qr_code_position', 'qr_code_margin_top', 'qr_code_margin_left', 'qr_code_margin_bottom', 'qr_code_margin_right', 'danmu_font_color', 'danmu_bg_color', 'global_bg_color'] + widgets = { + 'qr_code_position': forms.Select(attrs={'class': 'form-control'}), + 'qr_code_margin_top': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '距离上边距(px)'}), + 'qr_code_margin_left': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '距离左边距(px)'}), + 'qr_code_margin_bottom': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '距离下边距(px)'}), + 'qr_code_margin_right': forms.NumberInput(attrs={'class': 'form-control', 'placeholder': '距离右边距(px)'}), + 'danmu_font_color': forms.TextInput(attrs={'class': 'form-control', 'type': 'color'}), + 'danmu_bg_color': forms.TextInput(attrs={'class': 'form-control', 'type': 'color'}), + 'global_bg_color': forms.TextInput(attrs={'class': 'form-control', 'type': 'color'}), + 'background_image': forms.FileInput(attrs={'class': 'form-control'}), + 'background_video': forms.FileInput(attrs={'class': 'form-control'}), + 'qr_code_image': forms.FileInput(attrs={'class': 'form-control'}), + } \ No newline at end of file diff --git a/activity/migrations/0001_initial.py b/activity/migrations/0001_initial.py new file mode 100644 index 0000000..c00eb9d --- /dev/null +++ b/activity/migrations/0001_initial.py @@ -0,0 +1,58 @@ +# Generated by Django 5.0.6 on 2025-12-30 03:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='ActivitySetting', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('background_image', models.ImageField(blank=True, null=True, upload_to='activity_media/', verbose_name='背景图片')), + ('background_video', models.FileField(blank=True, null=True, upload_to='activity_media/', verbose_name='背景视频')), + ('qr_code_image', models.ImageField(blank=True, null=True, upload_to='activity_media/', verbose_name='二维码图片')), + ('qr_code_position', models.CharField(choices=[('top-left', '左上角'), ('top-right', '右上角'), ('bottom-left', '左下角'), ('bottom-right', '右下角'), ('center', '居中')], default='bottom-right', max_length=20, verbose_name='二维码位置')), + ('danmu_font_color', models.CharField(default='#FFFFFF', max_length=7, verbose_name='弹幕字体颜色')), + ('danmu_bg_color', models.CharField(default='#000000', max_length=7, verbose_name='弹幕背景颜色')), + ('global_bg_color', models.CharField(default='#F0F0F0', max_length=7, verbose_name='全局背景颜色')), + ], + options={ + 'verbose_name': '活动设置', + 'verbose_name_plural': '活动设置', + }, + ), + migrations.CreateModel( + name='Blessing', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('content', models.TextField(verbose_name='祝福语内容')), + ], + options={ + 'verbose_name': '祝福语', + 'verbose_name_plural': '祝福语', + }, + ), + migrations.CreateModel( + name='Danmu', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, verbose_name='姓名')), + ('content', models.TextField(blank=True, null=True, verbose_name='祝福语')), + ('image', models.ImageField(blank=True, null=True, upload_to='danmu_media/', verbose_name='图片')), + ('is_approved', models.BooleanField(default=False, verbose_name='审核状态')), + ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ], + options={ + 'verbose_name': '弹幕消息', + 'verbose_name_plural': '弹幕消息', + 'ordering': ['-created_at'], + }, + ), + ] diff --git a/activity/migrations/0002_activitysetting_qr_code_margin_bottom_and_more.py b/activity/migrations/0002_activitysetting_qr_code_margin_bottom_and_more.py new file mode 100644 index 0000000..c88aa89 --- /dev/null +++ b/activity/migrations/0002_activitysetting_qr_code_margin_bottom_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 5.0.6 on 2025-12-30 05:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('activity', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='activitysetting', + name='qr_code_margin_bottom', + field=models.IntegerField(default=20, verbose_name='距离下边距(px)'), + ), + migrations.AddField( + model_name='activitysetting', + name='qr_code_margin_left', + field=models.IntegerField(default=20, verbose_name='距离左边距(px)'), + ), + migrations.AddField( + model_name='activitysetting', + name='qr_code_margin_right', + field=models.IntegerField(default=20, verbose_name='距离右边距(px)'), + ), + migrations.AddField( + model_name='activitysetting', + name='qr_code_margin_top', + field=models.IntegerField(default=20, verbose_name='距离上边距(px)'), + ), + ] diff --git a/activity/migrations/__init__.py b/activity/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/activity/models.py b/activity/models.py new file mode 100644 index 0000000..61a260a --- /dev/null +++ b/activity/models.py @@ -0,0 +1,59 @@ +from django.db import models + +# Create your models here. + +class ActivitySetting(models.Model): + """活动设置模型""" + BACKGROUND_POSITION_CHOICES = ( + ('top-left', '左上角'), + ('top-right', '右上角'), + ('bottom-left', '左下角'), + ('bottom-right', '右下角'), + ('center', '居中'), + ) + + background_image = models.ImageField(upload_to='activity_media/', verbose_name='背景图片', blank=True, null=True) + background_video = models.FileField(upload_to='activity_media/', verbose_name='背景视频', blank=True, null=True) + qr_code_image = models.ImageField(upload_to='activity_media/', verbose_name='二维码图片', blank=True, null=True) + qr_code_position = models.CharField(max_length=20, choices=BACKGROUND_POSITION_CHOICES, default='bottom-right', verbose_name='二维码位置') + qr_code_margin_top = models.IntegerField(default=20, verbose_name='距离上边距(px)') + qr_code_margin_left = models.IntegerField(default=20, verbose_name='距离左边距(px)') + qr_code_margin_bottom = models.IntegerField(default=20, verbose_name='距离下边距(px)') + qr_code_margin_right = models.IntegerField(default=20, verbose_name='距离右边距(px)') + danmu_font_color = models.CharField(max_length=7, default='#FFFFFF', verbose_name='弹幕字体颜色') + danmu_bg_color = models.CharField(max_length=7, default='#000000', verbose_name='弹幕背景颜色') + global_bg_color = models.CharField(max_length=7, default='#F0F0F0', verbose_name='全局背景颜色') + + class Meta: + verbose_name = '活动设置' + verbose_name_plural = '活动设置' + + def __str__(self): + return '活动设置' + +class Blessing(models.Model): + """祝福语模型""" + content = models.TextField(verbose_name='祝福语内容') + + class Meta: + verbose_name = '祝福语' + verbose_name_plural = '祝福语' + + def __str__(self): + return self.content[:20] + +class Danmu(models.Model): + """弹幕消息模型""" + name = models.CharField(max_length=50, verbose_name='姓名') + content = models.TextField(verbose_name='祝福语', blank=True, null=True) + image = models.ImageField(upload_to='danmu_media/', verbose_name='图片', blank=True, null=True) + is_approved = models.BooleanField(default=False, verbose_name='审核状态') + created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') + + class Meta: + verbose_name = '弹幕消息' + verbose_name_plural = '弹幕消息' + ordering = ['-created_at'] + + def __str__(self): + return f'{self.name}: {self.content[:20]}' diff --git a/activity/templates/activity/admin_review.html b/activity/templates/activity/admin_review.html new file mode 100644 index 0000000..4b88c01 --- /dev/null +++ b/activity/templates/activity/admin_review.html @@ -0,0 +1,111 @@ +{% extends 'base.html' %} + +{% block css %} + +{% endblock %} + +{% block content %} +
+

弹幕审核

+ + {% if danmus %} +
+ + + + + + + + + + + + {% for danmu in danmus %} + + + + + + + + {% endfor %} + +
姓名内容图片创建时间操作
{{ danmu.name }}{{ danmu.content }} + {% if danmu.image %} + 图片 + {% else %} + -无- + {% endif %} + {{ danmu.created_at|date:"Y-m-d H:i:s" }} +
+
+ {% csrf_token %} + + + +
+
+ {% csrf_token %} + + + +
+
+
+
+ {% else %} +
+

暂无待审核的弹幕

+
+ {% endif %} +
+{% endblock %} \ No newline at end of file diff --git a/activity/templates/activity/index.html b/activity/templates/activity/index.html new file mode 100644 index 0000000..f28ba16 --- /dev/null +++ b/activity/templates/activity/index.html @@ -0,0 +1,279 @@ +{% extends 'base.html' %} + +{% block css %} + +{% endblock %} + +{% block content %} +
+ {% if setting.background_video %} + + {% elif setting.background_image %} + 背景图片 + {% endif %} +
+ +
+ {% if setting.qr_code_image %} + 二维码 + {% else %} + + 默认二维码 + {% endif %} +
+ +
+ + {% for danmu in danmus %} +
+ {{ danmu.name }}: {{ danmu.content }} + {% if danmu.image %} + 图片 + {% endif %} +
+ {% endfor %} +
+{% endblock %} + +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/activity/templates/activity/setting.html b/activity/templates/activity/setting.html new file mode 100644 index 0000000..1e9723e --- /dev/null +++ b/activity/templates/activity/setting.html @@ -0,0 +1,193 @@ +{% extends 'base.html' %} + +{% block css %} + +{% endblock %} + +{% block content %} +
+

活动设置

+ +
+
+ {% csrf_token %} + +
+ {{ form.background_image.label_tag }} + {{ form.background_image }} + {% if form.background_image.errors %} +
{{ form.background_image.errors }}
+ {% endif %} + {% if setting.background_image %} +
+ 当前背景图片: + 当前背景图片 +
+ {% endif %} +
+ +
+ {{ form.background_video.label_tag }} + {{ form.background_video }} + {% if form.background_video.errors %} +
{{ form.background_video.errors }}
+ {% endif %} + {% if setting.background_video %} +
+ 当前背景视频:{{ setting.background_video.name }} +
+ {% endif %} +
+ +
+ {{ form.qr_code_image.label_tag }} + {{ form.qr_code_image }} + {% if form.qr_code_image.errors %} +
{{ form.qr_code_image.errors }}
+ {% endif %} + {% if setting.qr_code_image %} +
+ 当前二维码: + 当前二维码 +
+ {% endif %} +
+ +
+ {{ form.qr_code_position.label_tag }} + {{ form.qr_code_position }} + {% if form.qr_code_position.errors %} +
{{ form.qr_code_position.errors }}
+ {% endif %} +
+ +
+ + {{ form.danmu_font_color }} + {% if form.danmu_font_color.errors %} +
{{ form.danmu_font_color.errors }}
+ {% endif %} +
+ +
+ + {{ form.danmu_bg_color }} + {% if form.danmu_bg_color.errors %} +
{{ form.danmu_bg_color.errors }}
+ {% endif %} +
+ +
+ + {{ form.global_bg_color }} + {% if form.global_bg_color.errors %} +
{{ form.global_bg_color.errors }}
+ {% endif %} +
+ + +
+
+ +
+
预览效果:
+
+ {% if setting.background_image %} + 背景预览 + {% endif %} +
+ {% if setting.qr_code_image %} + 二维码预览 + {% else %} + + 二维码预览 + {% endif %} +
+
+ 示例弹幕 +
+
+
+
+{% endblock %} + +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/activity/templates/activity/submit.html b/activity/templates/activity/submit.html new file mode 100644 index 0000000..b503f90 --- /dev/null +++ b/activity/templates/activity/submit.html @@ -0,0 +1,123 @@ +{% extends 'base.html' %} + +{% block css %} + +{% endblock %} + +{% block content %} +
+

发送祝福

+ +
+ {% csrf_token %} + +
+ {{ form.name.label_tag }} + {{ form.name }} + {% if form.name.errors %} +
{{ form.name.errors }}
+ {% endif %} +
+ +
+ {{ form.content.label_tag }} + {{ form.content }} + {% if form.content.errors %} +
{{ form.content.errors }}
+ {% endif %} +
+ +
+
推荐祝福语:
+
+ {% for blessing in random_blessings %} +
+ {{ blessing.content }} +
+ {% empty %} +
暂无推荐祝福语
+ {% endfor %} +
+
+ +
+ {{ form.image.label_tag }} + {{ form.image }} + {% if form.image.errors %} +
{{ form.image.errors }}
+ {% endif %} +
+ + +
+
+{% endblock %} + +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/activity/templates/base.html b/activity/templates/base.html new file mode 100644 index 0000000..3dd91bb --- /dev/null +++ b/activity/templates/base.html @@ -0,0 +1,22 @@ + + + + + + 弹幕活动 + + + + {% block css %}{% endblock %} + + + {% block content %}{% endblock %} + + + + + + + {% block js %}{% endblock %} + + \ No newline at end of file diff --git a/activity/tests.py b/activity/tests.py new file mode 100644 index 0000000..de8bdc0 --- /dev/null +++ b/activity/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/activity/urls.py b/activity/urls.py new file mode 100644 index 0000000..8f4e7b3 --- /dev/null +++ b/activity/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.index, name='index'), + path('submit/', views.submit, name='submit'), + path('admin-review/', views.admin_review, name='admin_review'), + path('setting/', views.setting, name='setting'), + path('api/danmu/', views.api_danmu, name='api_danmu'), +] \ No newline at end of file diff --git a/activity/utils.py b/activity/utils.py new file mode 100644 index 0000000..71059e2 --- /dev/null +++ b/activity/utils.py @@ -0,0 +1,780 @@ +from .models import Blessing + +def add_default_blessings(): + """添加预设的祝福语""" + default_blessings = [ + "身体健康,万事如意!", + "事业有成,步步高升!", + "家庭幸福,和睦美满!", + "学业进步,前程似锦!", + "财源广进,招财进宝!", + "心想事成,美梦成真!", + "吉祥如意,福星高照!", + "平安顺遂,一生无忧!", + "开心快乐,笑口常开!", + "好运连连,喜事不断!", + "青春永驻,活力四射!", + "一帆风顺,马到成功!", + "花开富贵,金玉满堂!", + "福禄双全,寿比南山!", + "喜气洋洋,红红火火!", + "年年有余,岁岁平安!", + "吉祥如意,万事亨通!", + "笑口常开,好运自然来!", + "身体健康,吃嘛嘛香!", + "工作顺利,事业有成!", + "家庭和睦,幸福美满!", + "学业有成,前途无量!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!", + "财源滚滚,财运亨通!", + "心想事成,万事如意!", + "平安健康,快乐每一天!", + "吉祥如意,福寿双全!", + "一帆风顺,前程似锦!", + "红红火火,喜气洋洋!", + "金玉满堂,富贵荣华!", + "福星高照,好运连连!", + "寿比南山,福如东海!", + "吉祥如意,百事可乐!", + "开心快乐,幸福美满!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业进步,天天向上!", + "身体健康,平安快乐!", + "吉祥如意,万事大吉!", + "好运连连,喜事临门!", + "笑口常开,青春永驻!", + "一帆风顺,万事如意!", + "花开富贵,吉祥如意!", + "福禄寿喜,样样俱全!", + "喜气洋洋,万事如意!", + "年年有余,吉祥如意!", + "吉祥如意,心想事成!", + "平安健康,幸福快乐!", + "事业有成,家庭幸福!", + "学业进步,前程似锦!", + "财源广进,福星高照!", + "心想事成,美梦成真!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,好运连连!", + "金玉满堂,万事如意!", + "福星高照,幸福安康!", + "寿比南山,万事如意!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财运亨通!", + "家庭和睦,幸福美满!", + "学业有成,前途光明!", + "财源滚滚,好运不断!", + "心想事成,吉祥如意!", + "平安健康,快乐幸福!", + "吉祥如意,福寿双全!", + "一帆风顺,前程无量!", + "喜气洋洋,吉祥如意!", + "花开富贵,万事如意!", + "福禄寿喜,吉祥如意!", + "吉祥如意,年年有余!", + "年年有余,万事如意!", + "吉祥如意,万事大吉!", + "好运连连,幸福美满!", + "笑口常开,健康长寿!", + "一帆风顺,吉祥如意!", + "花开富贵,福寿安康!", + "金玉满堂,吉祥如意!", + "福星高照,吉祥安康!", + "寿比南山,万事如意!", + "吉祥如意,百事可乐!", + "开心快乐,平安健康!", + "事业有成,家庭美满!", + "学业进步,天天向上!", + "财源广进,好运连连!", + "心想事成,幸福美满!", + "平安健康,万事如意!", + "吉祥如意,福寿安康!", + "一帆风顺,马到成功!", + "红红火火,吉祥如意!", + "金玉满堂,富贵吉祥!", + "福星高照,幸福美满!", + "寿比南山,福如东海!", + "吉祥如意,百事亨通!", + "开心快乐,健康平安!", + "事业有成,财源广进!", + "家庭幸福,万事如意!", + "学业有成,前途似锦!" + ] + + # 批量创建祝福语,如果已存在则跳过 + for blessing_content in default_blessings: + Blessing.objects.get_or_create(content=blessing_content) + + return f"已添加或更新 {len(default_blessings)} 条祝福语" \ No newline at end of file diff --git a/activity/views.py b/activity/views.py new file mode 100644 index 0000000..e65b0d0 --- /dev/null +++ b/activity/views.py @@ -0,0 +1,98 @@ +from django.shortcuts import render, redirect +from django.http import JsonResponse +from .models import ActivitySetting, Blessing, Danmu +from .forms import DanmuForm, ActivitySettingForm + +# Create your views here. +def index(request): + """主页面视图""" + setting = ActivitySetting.objects.first() or ActivitySetting.objects.create() + danmus = Danmu.objects.filter(is_approved=True).order_by('-created_at') + + context = { + 'setting': setting, + 'danmus': danmus, + } + + return render(request, 'activity/index.html', context) + +def submit(request): + """扫码提交视图""" + random_blessings = Blessing.objects.order_by('?')[:5] + + if request.method == 'POST': + form = DanmuForm(request.POST, request.FILES) + if form.is_valid(): + form.save() + return redirect('index') + else: + form = DanmuForm() + + context = { + 'form': form, + 'random_blessings': random_blessings, + } + + return render(request, 'activity/submit.html', context) + +def admin_review(request): + """管理员审核视图""" + danmus = Danmu.objects.filter(is_approved=False).order_by('-created_at') + + if request.method == 'POST': + danmu_id = request.POST.get('danmu_id') + action = request.POST.get('action') + + if danmu_id and action: + try: + danmu = Danmu.objects.get(id=danmu_id) + if action == 'approve': + danmu.is_approved = True + danmu.save() + elif action == 'reject': + danmu.delete() + except Danmu.DoesNotExist: + pass + + return redirect('admin_review') + + context = { + 'danmus': danmus, + } + + return render(request, 'activity/admin_review.html', context) + +def setting(request): + """设置视图""" + setting = ActivitySetting.objects.first() or ActivitySetting.objects.create() + + if request.method == 'POST': + form = ActivitySettingForm(request.POST, request.FILES, instance=setting) + if form.is_valid(): + form.save() + return redirect('index') + else: + form = ActivitySettingForm(instance=setting) + + context = { + 'form': form, + 'setting': setting, + } + + return render(request, 'activity/setting.html', context) + +def api_danmu(request): + """获取实时弹幕API""" + danmus = Danmu.objects.filter(is_approved=True).order_by('-created_at')[:50] + danmu_list = [ + { + 'id': danmu.id, + 'name': danmu.name, + 'content': danmu.content, + 'image': danmu.image.url if danmu.image else None, + 'created_at': danmu.created_at.strftime('%Y-%m-%d %H:%M:%S'), + } + for danmu in danmus + ] + + return JsonResponse({'danmus': danmu_list}) diff --git a/add_default_blessings.py b/add_default_blessings.py new file mode 100644 index 0000000..aa45c4a --- /dev/null +++ b/add_default_blessings.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +"""添加预设祝福语脚本""" +import os +import sys + +# 添加项目根目录到Python路径 +sys.path.append(os.path.dirname(os.path.abspath(__file__))) + +# 导入Django设置 +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'danmu_activity.settings') + +# 初始化Django +import django +django.setup() + +# 导入添加祝福语的函数 +from activity.utils import add_default_blessings + +def main(): + """主函数""" + print("开始添加预设祝福语...") + add_default_blessings() + print("预设祝福语添加完成!") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/add_test_danmus.py b/add_test_danmus.py new file mode 100644 index 0000000..3a5c54d --- /dev/null +++ b/add_test_danmus.py @@ -0,0 +1,49 @@ +import os +import sys +import django + +# 设置Django环境 +sys.path.append(os.path.dirname(os.path.abspath(__file__))) +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'danmu_activity.settings') +django.setup() + +from activity.models import Danmu + +def add_test_danmus(): + """添加测试弹幕数据""" + test_danmus = [ + { + 'name': '测试用户1', + 'content': '这是第一条测试弹幕!', + 'is_approved': True + }, + { + 'name': '测试用户2', + 'content': '这是第二条测试弹幕,祝活动圆满成功!', + 'is_approved': True + }, + { + 'name': '测试用户3', + 'content': '这是第三条测试弹幕,大家玩得开心!', + 'is_approved': True + }, + { + 'name': '测试用户4', + 'content': '这是第四条测试弹幕,感谢组织者!', + 'is_approved': True + }, + { + 'name': '测试用户5', + 'content': '这是第五条测试弹幕,祝大家身体健康!', + 'is_approved': True + } + ] + + print("开始添加测试弹幕...") + for danmu_data in test_danmus: + Danmu.objects.create(**danmu_data) + + print(f"成功添加 {len(test_danmus)} 条测试弹幕!") + +if __name__ == '__main__': + add_test_danmus() \ No newline at end of file diff --git a/create_setting.py b/create_setting.py new file mode 100644 index 0000000..f8267aa --- /dev/null +++ b/create_setting.py @@ -0,0 +1,21 @@ +import os +import sys +import django + +# 设置Django环境 +sys.path.append(os.path.dirname(os.path.abspath(__file__))) +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'danmu_activity.settings') +django.setup() + +from activity.models import ActivitySetting + +def create_activity_setting(): + """创建活动设置(如果不存在)""" + if not ActivitySetting.objects.exists(): + setting = ActivitySetting.objects.create() + print("活动设置已创建") + else: + print("活动设置已存在") + +if __name__ == '__main__': + create_activity_setting() \ No newline at end of file diff --git a/danmu_activity/__init__.py b/danmu_activity/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/danmu_activity/asgi.py b/danmu_activity/asgi.py new file mode 100644 index 0000000..1318a7f --- /dev/null +++ b/danmu_activity/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for danmu_activity project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'danmu_activity.settings') + +application = get_asgi_application() diff --git a/danmu_activity/settings.py b/danmu_activity/settings.py new file mode 100644 index 0000000..bd36987 --- /dev/null +++ b/danmu_activity/settings.py @@ -0,0 +1,128 @@ +""" +Django settings for danmu_activity project. + +Generated by 'django-admin startproject' using Django 5.0.6. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/5.0/ref/settings/ +""" + +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-@k0^k91t_(@73sr$a&uo8h)(j8r_^(rtyg)__u*@cpbvw3lk2t' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'activity', +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'danmu_activity.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +WSGI_APPLICATION = 'danmu_activity.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/5.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': BASE_DIR / 'db.sqlite3', + } +} + + +# Password validation +# https://docs.djangoproject.com/en/5.0/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/5.0/topics/i18n/ + +LANGUAGE_CODE = 'zh-hans' + +TIME_ZONE = 'Asia/Shanghai' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/5.0/howto/static-files/ + +STATIC_URL = 'static/' + +# Media files +MEDIA_URL = 'media/' +MEDIA_ROOT = BASE_DIR / 'media' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/danmu_activity/urls.py b/danmu_activity/urls.py new file mode 100644 index 0000000..c16d48d --- /dev/null +++ b/danmu_activity/urls.py @@ -0,0 +1,25 @@ +""" +URL configuration for danmu_activity project. + +The `urlpatterns` list routes URLs to views. For more information please see: + https://docs.djangoproject.com/en/5.0/topics/http/urls/ +Examples: +Function views + 1. Add an import: from my_app import views + 2. Add a URL to urlpatterns: path('', views.home, name='home') +Class-based views + 1. Add an import: from other_app.views import Home + 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') +Including another URLconf + 1. Import the include() function: from django.urls import include, path + 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) +""" +from django.contrib import admin +from django.urls import path, include +from django.conf import settings +from django.conf.urls.static import static + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('activity.urls')), +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/danmu_activity/wsgi.py b/danmu_activity/wsgi.py new file mode 100644 index 0000000..80bec31 --- /dev/null +++ b/danmu_activity/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for danmu_activity project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'danmu_activity.settings') + +application = get_wsgi_application() diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..005d7a4 --- /dev/null +++ b/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'danmu_activity.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main()