From 84e30d26af9b1c228dd609f9906032007dc3f869 Mon Sep 17 00:00:00 2001 From: jeremygan2021 Date: Sun, 1 Mar 2026 17:39:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/config/settings.py | 28 +++++++++---------- backend/shop/admin.py | 2 +- .../0039_vccourse_video_embed_code.py | 18 ++++++++++++ backend/shop/models.py | 1 + backend/shop/serializers.py | 13 +++++++++ frontend/src/pages/VCCourseDetail.jsx | 7 ++++- miniprogram/src/app.config.ts | 1 + miniprogram/src/pages/courses/detail.tsx | 27 +++++++++++++++++- miniprogram/src/pages/webview/index.config.ts | 3 ++ miniprogram/src/pages/webview/index.tsx | 14 ++++++++++ 10 files changed, 97 insertions(+), 17 deletions(-) create mode 100644 backend/shop/migrations/0039_vccourse_video_embed_code.py create mode 100644 miniprogram/src/pages/webview/index.config.ts create mode 100644 miniprogram/src/pages/webview/index.tsx diff --git a/backend/config/settings.py b/backend/config/settings.py index 954dc43..664f04c 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -101,19 +101,7 @@ DATABASES = { #从环境变量获取数据库配置 (Docker 环境会自动注入这些变量。 -DB_HOST = os.environ.get('DB_HOST', '6.6.6.66') -if DB_HOST: - DATABASES['default'] = { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': os.environ.get('DB_NAME', 'market'), - 'USER': os.environ.get('DB_USER', 'market'), - 'PASSWORD': os.environ.get('DB_PASSWORD', '123market'), - 'HOST': DB_HOST, - 'PORT': os.environ.get('DB_PORT', '5432'), - } - - -# DB_HOST = os.environ.get('DB_HOST', '121.43.104.161') +# DB_HOST = os.environ.get('DB_HOST', '6.6.6.66') # if DB_HOST: # DATABASES['default'] = { # 'ENGINE': 'django.db.backends.postgresql', @@ -121,10 +109,22 @@ if DB_HOST: # 'USER': os.environ.get('DB_USER', 'market'), # 'PASSWORD': os.environ.get('DB_PASSWORD', '123market'), # 'HOST': DB_HOST, -# 'PORT': os.environ.get('DB_PORT', '6433'), +# 'PORT': os.environ.get('DB_PORT', '5432'), # } +DB_HOST = os.environ.get('DB_HOST', '121.43.104.161') +if DB_HOST: + DATABASES['default'] = { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': os.environ.get('DB_NAME', 'market'), + 'USER': os.environ.get('DB_USER', 'market'), + 'PASSWORD': os.environ.get('DB_PASSWORD', '123market'), + 'HOST': DB_HOST, + 'PORT': os.environ.get('DB_PORT', '6433'), + } + + # Password validation # https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators diff --git a/backend/shop/admin.py b/backend/shop/admin.py index 7961fd6..4b800b8 100644 --- a/backend/shop/admin.py +++ b/backend/shop/admin.py @@ -264,7 +264,7 @@ class VCCourseAdmin(OrderableAdminMixin, ModelAdmin): 'fields': ('title', 'description', 'course_type', 'tag', 'price') }), ('视频设置', { - 'fields': ('is_video_course', 'video_url'), + 'fields': ('is_video_course', 'video_url', 'video_embed_code'), 'description': '设置是否为视频课程及视频链接' }), ('课程安排', { diff --git a/backend/shop/migrations/0039_vccourse_video_embed_code.py b/backend/shop/migrations/0039_vccourse_video_embed_code.py new file mode 100644 index 0000000..7b83943 --- /dev/null +++ b/backend/shop/migrations/0039_vccourse_video_embed_code.py @@ -0,0 +1,18 @@ +# Generated by Django 6.0.1 on 2026-03-01 09:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('shop', '0038_vccourse_is_video_course_vccourse_video_url'), + ] + + operations = [ + migrations.AddField( + model_name='vccourse', + name='video_embed_code', + field=models.TextField(blank=True, help_text='支持iframe嵌入代码,优先级高于视频URL', null=True, verbose_name='视频嵌入代码'), + ), + ] diff --git a/backend/shop/models.py b/backend/shop/models.py index 9295c2a..75f9eaf 100644 --- a/backend/shop/models.py +++ b/backend/shop/models.py @@ -365,6 +365,7 @@ class VCCourse(models.Model): # 视频课程相关 is_video_course = models.BooleanField(default=False, verbose_name="是否视频课程") video_url = models.URLField(blank=True, null=True, verbose_name="视频课程URL", help_text="仅当用户付费或报名后可见") + video_embed_code = models.TextField(blank=True, null=True, verbose_name="视频嵌入代码", help_text="支持iframe嵌入代码,优先级高于视频URL") # 课程时间安排 is_fixed_schedule = models.BooleanField(default=False, verbose_name="是否固定时间课程", help_text="勾选后,前端将显示具体的开课时间") diff --git a/backend/shop/serializers.py b/backend/shop/serializers.py index f343694..988d007 100644 --- a/backend/shop/serializers.py +++ b/backend/shop/serializers.py @@ -176,6 +176,7 @@ class VCCourseSerializer(serializers.ModelSerializer): display_detail_image = serializers.SerializerMethodField() course_type_display = serializers.CharField(source='get_course_type_display', read_only=True) video_url = serializers.SerializerMethodField() + video_embed_code = serializers.SerializerMethodField() is_purchased = serializers.SerializerMethodField() class Meta: @@ -234,6 +235,18 @@ class VCCourseSerializer(serializers.ModelSerializer): return None + def get_video_embed_code(self, obj): + """ + 仅当用户已付费/报名时返回视频嵌入代码 + """ + if not obj.is_video_course: + return None + + if self._check_purchased(obj): + return obj.video_embed_code + + return None + class ESP32ConfigSerializer(serializers.ModelSerializer): """ ESP32配置序列化器 diff --git a/frontend/src/pages/VCCourseDetail.jsx b/frontend/src/pages/VCCourseDetail.jsx index 7a4bb43..1e0e3e0 100644 --- a/frontend/src/pages/VCCourseDetail.jsx +++ b/frontend/src/pages/VCCourseDetail.jsx @@ -238,7 +238,12 @@ const VCCourseDetail = () => { position: 'relative', aspectRatio: '16/9' }}> - {course.video_url ? ( + {course.video_embed_code ? ( +
+ ) : course.video_url ? (