This commit is contained in:
@@ -30,14 +30,14 @@ class TopicMediaInline(TabularInline):
|
|||||||
|
|
||||||
@admin.register(Activity)
|
@admin.register(Activity)
|
||||||
class ActivityAdmin(ModelAdmin):
|
class ActivityAdmin(ModelAdmin):
|
||||||
list_display = ('title', 'banner_display', 'start_time', 'location', 'signup_count', 'is_active', 'auto_confirm', 'created_at')
|
list_display = ('title', 'banner_display', 'start_time', 'location', 'signup_count', 'is_visible', 'is_active', 'auto_confirm', 'created_at')
|
||||||
list_filter = ('is_active', 'auto_confirm', 'start_time')
|
list_filter = ('is_visible', 'is_active', 'auto_confirm', 'start_time')
|
||||||
search_fields = ('title', 'location')
|
search_fields = ('title', 'location')
|
||||||
inlines = [ActivitySignupInline]
|
inlines = [ActivitySignupInline]
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
('基本信息', {
|
('基本信息', {
|
||||||
'fields': ('title', 'description', 'banner', 'banner_url', 'is_active', 'auto_confirm')
|
'fields': ('title', 'description', 'banner', 'banner_url', 'is_visible', 'is_active', 'auto_confirm')
|
||||||
}),
|
}),
|
||||||
('费用与时间', {
|
('费用与时间', {
|
||||||
'fields': ('is_paid', 'price', 'start_time', 'end_time', 'location'),
|
'fields': ('is_paid', 'price', 'start_time', 'end_time', 'location'),
|
||||||
|
|||||||
18
backend/community/migrations/0012_activity_is_visible.py
Normal file
18
backend/community/migrations/0012_activity_is_visible.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 6.0.1 on 2026-02-23 09:33
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('community', '0011_activity_auto_confirm_alter_activitysignup_status'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='activity',
|
||||||
|
name='is_visible',
|
||||||
|
field=models.BooleanField(default=True, help_text='关闭后将不在前端列表页显示', verbose_name='是否显示'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -19,6 +19,7 @@ class Activity(models.Model):
|
|||||||
price = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name="报名费用")
|
price = models.DecimalField(max_digits=10, decimal_places=2, default=0, verbose_name="报名费用")
|
||||||
|
|
||||||
is_active = models.BooleanField(default=True, verbose_name="是否启用")
|
is_active = models.BooleanField(default=True, verbose_name="是否启用")
|
||||||
|
is_visible = models.BooleanField(default=True, verbose_name="是否显示", help_text="关闭后将不在前端列表页显示")
|
||||||
auto_confirm = models.BooleanField(default=False, verbose_name="无需审核", help_text="开启后,付费活动支付成功或免费活动报名后直接显示报名成功,不需要审核")
|
auto_confirm = models.BooleanField(default=False, verbose_name="无需审核", help_text="开启后,付费活动支付成功或免费活动报名后直接显示报名成功,不需要审核")
|
||||||
|
|
||||||
# 常用报名信息开关
|
# 常用报名信息开关
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class ActivityViewSet(viewsets.ReadOnlyModelViewSet):
|
|||||||
"""
|
"""
|
||||||
社区活动接口
|
社区活动接口
|
||||||
"""
|
"""
|
||||||
queryset = Activity.objects.filter(is_active=True).order_by('-created_at')
|
queryset = Activity.objects.filter(is_active=True, is_visible=True).order_by('-created_at')
|
||||||
serializer_class = ActivitySerializer
|
serializer_class = ActivitySerializer
|
||||||
|
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
@@ -198,6 +198,32 @@ class ActivityViewSet(viewsets.ReadOnlyModelViewSet):
|
|||||||
signup_info=signup_info,
|
signup_info=signup_info,
|
||||||
status=status_val
|
status=status_val
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Send SMS for free activity signup (if confirmed)
|
||||||
|
if status_val == 'confirmed':
|
||||||
|
try:
|
||||||
|
from shop.sms_utils import notify_user_activity_signup_success
|
||||||
|
|
||||||
|
# Mock an order object for the SMS template
|
||||||
|
# The template expects: customer_name, wechat_user, phone_number
|
||||||
|
class MockOrder:
|
||||||
|
def __init__(self, user, signup_info):
|
||||||
|
# Ensure we get the name and phone from signup_info first
|
||||||
|
# signup_info keys might vary, let's try common ones
|
||||||
|
self.customer_name = signup_info.get('name') or signup_info.get('username') or user.nickname or "用户"
|
||||||
|
self.wechat_user = user
|
||||||
|
self.phone_number = signup_info.get('phone') or signup_info.get('mobile') or user.phone_number or ""
|
||||||
|
|
||||||
|
mock_order = MockOrder(user, signup_info)
|
||||||
|
|
||||||
|
# Check if we have a valid phone number before sending
|
||||||
|
if mock_order.phone_number:
|
||||||
|
notify_user_activity_signup_success(mock_order, signup)
|
||||||
|
else:
|
||||||
|
print(f"Skipping SMS for signup {signup.id}: No phone number found")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"发送免费活动报名短信失败: {str(e)}")
|
||||||
|
|
||||||
serializer = ActivitySignupSerializer(signup)
|
serializer = ActivitySignupSerializer(signup)
|
||||||
return Response(serializer.data, status=201)
|
return Response(serializer.data, status=201)
|
||||||
|
|
||||||
|
|||||||
@@ -123,6 +123,16 @@ def notify_user_activity_signup_success(order, signup):
|
|||||||
# 4. address
|
# 4. address
|
||||||
address = signup.activity.location or "线上活动"
|
address = signup.activity.location or "线上活动"
|
||||||
|
|
||||||
|
# 5. Handle phone number format (remove +86 or spaces if any)
|
||||||
|
phone_number = str(order.phone_number) if order.phone_number else ""
|
||||||
|
if phone_number:
|
||||||
|
phone_number = phone_number.replace("+86", "").replace(" ", "").strip()
|
||||||
|
|
||||||
|
# Ensure phone number is valid (11 digits)
|
||||||
|
if not phone_number or len(phone_number) != 11 or not phone_number.isdigit():
|
||||||
|
print(f"无效的手机号: {phone_number}, 跳过短信发送")
|
||||||
|
return
|
||||||
|
|
||||||
params = {
|
params = {
|
||||||
"user_nick": user_nick or "用户",
|
"user_nick": user_nick or "用户",
|
||||||
"unit_name": unit_name,
|
"unit_name": unit_name,
|
||||||
@@ -130,5 +140,5 @@ def notify_user_activity_signup_success(order, signup):
|
|||||||
"address": address
|
"address": address
|
||||||
}
|
}
|
||||||
|
|
||||||
print(f"准备发送活动报名成功通知: {order.phone_number}")
|
print(f"准备发送活动报名成功通知: {phone_number}")
|
||||||
send_sms(order.phone_number, "SMS_501990528", params)
|
send_sms(phone_number, "SMS_501990528", params)
|
||||||
Reference in New Issue
Block a user