This commit is contained in:
@@ -205,12 +205,23 @@ class ActivitySignupAdmin(ModelAdmin):
|
||||
|
||||
@admin.register(Topic)
|
||||
class TopicAdmin(OrderableAdminMixin, ModelAdmin):
|
||||
list_display = ('title', 'category', 'author', 'get_related_item', 'reply_count', 'view_count', 'is_pinned', 'created_at', 'order_actions')
|
||||
list_filter = ('category', 'is_pinned', 'created_at', 'related_product', 'related_service', 'related_course')
|
||||
list_display = ('title', 'status', 'category', 'author', 'get_related_item', 'reply_count', 'view_count', 'is_pinned', 'created_at', 'order_actions')
|
||||
list_filter = ('status', 'category', 'is_pinned', 'created_at', 'related_product', 'related_service', 'related_course')
|
||||
search_fields = ('title', 'content', 'author__nickname')
|
||||
autocomplete_fields = ['author', 'related_product', 'related_service', 'related_course']
|
||||
inlines = [TopicMediaInline, ReplyInline]
|
||||
actions = ['reset_ordering']
|
||||
actions = ['reset_ordering', 'approve_topics', 'reject_topics']
|
||||
list_editable = ('status', 'is_pinned')
|
||||
|
||||
@admin.action(description="批量通过审核")
|
||||
def approve_topics(self, request, queryset):
|
||||
rows_updated = queryset.update(status='published')
|
||||
self.message_user(request, f"{rows_updated} 个帖子已通过审核")
|
||||
|
||||
@admin.action(description="批量拒绝")
|
||||
def reject_topics(self, request, queryset):
|
||||
rows_updated = queryset.update(status='rejected')
|
||||
self.message_user(request, f"{rows_updated} 个帖子已拒绝")
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
# 当帖子被置顶时(新建或修改状态),默认将排序值设为0
|
||||
@@ -232,7 +243,7 @@ class TopicAdmin(OrderableAdminMixin, ModelAdmin):
|
||||
|
||||
fieldsets = (
|
||||
('帖子内容', {
|
||||
'fields': ('title', 'category', 'content', 'is_pinned')
|
||||
'fields': ('title', 'status', 'category', 'content', 'is_pinned')
|
||||
}),
|
||||
('关联信息', {
|
||||
'fields': ('author', 'related_product', 'related_service', 'related_course'),
|
||||
|
||||
18
backend/community/migrations/0015_topic_status.py
Normal file
18
backend/community/migrations/0015_topic_status.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 6.0.1 on 2026-02-27 06:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('community', '0014_alter_topic_options_topic_order'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='topic',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('pending', '待审核'), ('published', '已发布'), ('rejected', '已拒绝')], default='published', max_length=20, verbose_name='状态'),
|
||||
),
|
||||
]
|
||||
@@ -127,6 +127,13 @@ class Topic(models.Model):
|
||||
)
|
||||
category = models.CharField(max_length=20, choices=CATEGORY_CHOICES, default='discussion', verbose_name="分类")
|
||||
|
||||
STATUS_CHOICES = (
|
||||
('pending', '待审核'),
|
||||
('published', '已发布'),
|
||||
('rejected', '已拒绝'),
|
||||
)
|
||||
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='published', verbose_name="状态")
|
||||
|
||||
content = models.TextField(verbose_name="内容", help_text="支持Markdown格式,支持插入图片")
|
||||
author = models.ForeignKey(WeChatUser, on_delete=models.CASCADE, related_name='topics', verbose_name="作者")
|
||||
|
||||
|
||||
@@ -120,14 +120,14 @@ class TopicSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Topic
|
||||
fields = [
|
||||
'id', 'title', 'category', 'content', 'author', 'author_info',
|
||||
'id', 'title', 'category', 'status', 'content', 'author', 'author_info',
|
||||
'related_product', 'product_info',
|
||||
'related_service', 'service_info',
|
||||
'related_course', 'course_info',
|
||||
'view_count', 'is_pinned', 'created_at', 'updated_at',
|
||||
'is_verified_owner', 'replies', 'media', 'media_ids'
|
||||
]
|
||||
read_only_fields = ['author', 'view_count', 'created_at', 'updated_at', 'is_verified_owner']
|
||||
read_only_fields = ['author', 'view_count', 'created_at', 'updated_at', 'is_verified_owner', 'status']
|
||||
|
||||
def create(self, validated_data):
|
||||
media_ids = validated_data.pop('media_ids', [])
|
||||
|
||||
@@ -262,11 +262,21 @@ class TopicViewSet(viewsets.ModelViewSet):
|
||||
ordering_fields = ['created_at', 'view_count', 'order']
|
||||
ordering = ['-is_pinned', 'order', '-created_at']
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super().get_queryset()
|
||||
# 列表接口仅显示已发布的帖子
|
||||
if self.action == 'list':
|
||||
qs = qs.filter(status='published')
|
||||
return qs
|
||||
|
||||
def perform_create(self, serializer):
|
||||
user = get_current_wechat_user(self.request)
|
||||
# Auth check is done in create or permission, but here we need user for save
|
||||
if user:
|
||||
serializer.save(author=user)
|
||||
# 如果关联了系统用户(user字段不为空),则是管理员/内部人员,直接发布
|
||||
# 否则进入审核流程
|
||||
status = 'published' if user.user else 'pending'
|
||||
serializer.save(author=user, status=status)
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
user = get_current_wechat_user(request)
|
||||
|
||||
@@ -152,8 +152,13 @@ const CreateTopicModal = ({ visible, onClose, onSuccess, initialValues, isEditMo
|
||||
await updateTopic(topicId, payload);
|
||||
message.success('修改成功');
|
||||
} else {
|
||||
await createTopic(payload);
|
||||
message.success('发布成功');
|
||||
const res = await createTopic(payload);
|
||||
const topic = res.data || res;
|
||||
if (topic.status === 'pending') {
|
||||
message.info('提交成功,请等待管理员审核');
|
||||
} else {
|
||||
message.success('发布成功');
|
||||
}
|
||||
}
|
||||
|
||||
form.resetFields();
|
||||
|
||||
@@ -105,12 +105,18 @@ const CreateTopic = () => {
|
||||
})
|
||||
Taro.showToast({ title: '更新成功', icon: 'success' })
|
||||
} else {
|
||||
await createTopic({
|
||||
const res = await createTopic({
|
||||
title,
|
||||
content,
|
||||
category: categories[categoryIndex].key
|
||||
})
|
||||
Taro.showToast({ title: '发布成功', icon: 'success' })
|
||||
|
||||
const topic = res.data || res
|
||||
if (topic.status === 'pending') {
|
||||
Taro.showToast({ title: '已提交,等待审核', icon: 'none', duration: 2000 })
|
||||
} else {
|
||||
Taro.showToast({ title: '发布成功', icon: 'success' })
|
||||
}
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
Reference in New Issue
Block a user