mini
All checks were successful
Deploy to Server / deploy (push) Successful in 40s

This commit is contained in:
jeremygan2021
2026-02-24 00:31:57 +08:00
parent 0d01a5f2a8
commit 441e080328
15 changed files with 535 additions and 106 deletions

View File

@@ -235,6 +235,10 @@ class VCCourseAdmin(OrderableAdminMixin, ModelAdmin):
('基本信息', {
'fields': ('title', 'description', 'course_type', 'tag', 'price')
}),
('课程安排', {
'fields': ('is_fixed_schedule', 'start_time', 'end_time'),
'description': '勾选“是否固定时间课程”后,请设置开始和结束时间'
}),
('讲师信息', {
'fields': ('instructor', 'instructor_title', 'instructor_desc', 'instructor_avatar', 'instructor_avatar_url'),
'description': '讲师头像上传和URL二选一优先使用URL'

View File

@@ -0,0 +1,23 @@
# Generated by Django 6.0.1 on 2026-02-23 15:58
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0032_order_activity'),
]
operations = [
migrations.AddField(
model_name='vccourse',
name='is_fixed_schedule',
field=models.BooleanField(default=False, help_text='勾选后,前端将显示具体的开课时间', verbose_name='是否固定时间课程'),
),
migrations.AddField(
model_name='vccourse',
name='schedule_time',
field=models.CharField(blank=True, help_text='例如:每周六晚 20:00', max_length=100, null=True, verbose_name='课程具体时间'),
),
]

View File

@@ -0,0 +1,27 @@
# Generated by Django 6.0.1 on 2026-02-23 16:02
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('shop', '0033_vccourse_is_fixed_schedule_vccourse_schedule_time'),
]
operations = [
migrations.RemoveField(
model_name='vccourse',
name='schedule_time',
),
migrations.AddField(
model_name='vccourse',
name='end_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='结束时间'),
),
migrations.AddField(
model_name='vccourse',
name='start_time',
field=models.DateTimeField(blank=True, null=True, verbose_name='开始时间'),
),
]

View File

@@ -348,6 +348,11 @@ class VCCourse(models.Model):
instructor_desc = models.TextField(blank=True, verbose_name="讲师简介", default="拥有多年开发经验,擅长...")
tag = models.CharField(max_length=20, blank=True, verbose_name="标签", help_text="例如: 热门, 推荐, 进阶")
# 课程时间安排
is_fixed_schedule = models.BooleanField(default=False, verbose_name="是否固定时间课程", help_text="勾选后,前端将显示具体的开课时间")
start_time = models.DateTimeField(blank=True, null=True, verbose_name="开始时间")
end_time = models.DateTimeField(blank=True, null=True, verbose_name="结束时间")
price = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name="价格", help_text="0表示免费")
content = models.TextField(blank=True, verbose_name="详细内容", help_text="支持Markdown或HTML")

View File

@@ -92,7 +92,7 @@ class CourseEnrollmentSerializer(serializers.ModelSerializer):
课程报名序列化器
"""
course_title = serializers.CharField(source='course.title', read_only=True)
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True)
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True, allow_null=True)
class Meta:
model = CourseEnrollment
@@ -124,7 +124,7 @@ class ServiceOrderSerializer(serializers.ModelSerializer):
"""
service_name = serializers.CharField(source='service.title', read_only=True)
# 接收前端传来的 ref_code
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True)
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True, allow_null=True)
class Meta:
model = ServiceOrder
@@ -212,7 +212,7 @@ class OrderSerializer(serializers.ModelSerializer):
salesperson_name = serializers.CharField(source='salesperson.name', read_only=True)
salesperson_code = serializers.CharField(source='salesperson.code', read_only=True)
# 接收前端传来的 ref_code用于查找 Salesperson
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True)
ref_code = serializers.CharField(write_only=True, required=False, allow_blank=True, allow_null=True)
class Meta:
model = Order

View File

@@ -268,8 +268,8 @@ def pay(request):
product = None
if order_type == 'course':
try:
product = VBCourse.objects.get(id=good_id)
except VBCourse.DoesNotExist:
product = VCCourse.objects.get(id=good_id)
except VCCourse.DoesNotExist:
print(f"课程不存在: {good_id}")
return Response({'error': f'找不到 ID 为 {good_id} 的课程'}, status=status.HTTP_404_NOT_FOUND)
else:
@@ -355,7 +355,8 @@ def pay(request):
print(f"微信支付 V3 Native 下单成功!")
print(f"订单 ID: {order.id}")
print(f"商户订单号: {out_trade_no}")
print(f"商品: {product.name} x {quantity}")
product_name = getattr(product, 'name', getattr(product, 'title', 'Unknown Product'))
print(f"商品: {product_name} x {quantity}")
print(f"总额: {total_price}")
print(f"code_url: {code_url}")
print(f"========================================")
@@ -596,6 +597,16 @@ class OrderViewSet(viewsets.ModelViewSet):
return queryset.filter(wechat_user=user).order_by('-created_at')
return queryset.order_by('-created_at')
def create(self, request, *args, **kwargs):
print(f"Creating order with data: {request.data}")
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
print(f"Order validation failed: {serializer.errors}")
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
"""
创建订单时自动关联当前微信用户