201 lines
9.1 KiB
Python
201 lines
9.1 KiB
Python
"""
|
||
一键写入微信小程序审核专用商品(shenhezhuangtai=2)。
|
||
|
||
内容定位:正能量电竞休闲社区服务,不含代练/代打/上分/护航等敏感表述。
|
||
|
||
用法:
|
||
python manage.py seed_audit_shangpin
|
||
python manage.py seed_audit_shangpin --dry-run
|
||
python manage.py seed_audit_shangpin --force # 删除本脚本写入的审核数据后重建
|
||
|
||
审核展示开关(小程序点单页)在 xcx_sys_peizhi.shangpin_shenhe_mode:
|
||
1 = 正常商品(shenhezhuangtai=1)
|
||
2 = 审核商品(shenhezhuangtai=2)
|
||
"""
|
||
from decimal import Decimal
|
||
|
||
from django.core.management.base import BaseCommand
|
||
from django.db import transaction
|
||
|
||
from shangpin.models import Shangpin, ShangpinLeixing, ShangpinZhuanqu
|
||
|
||
# 与 UserMain 默认头像一致,前端 OSS 拼接后可正常显示
|
||
DEFAULT_PRODUCT_IMAGE = 'a_long/morentouxiang.jpg'
|
||
|
||
AUDIT_TYPE_NAME = '电竞休闲体验'
|
||
|
||
ZONES = [
|
||
('萌新入门', 300),
|
||
('休闲娱乐', 200),
|
||
('团队社交', 100),
|
||
]
|
||
|
||
ORDER_NOTICE = (
|
||
'【服务说明】本平台倡导健康、文明、积极的电竞娱乐文化。'
|
||
'本商品为陪伴交流、科普讲解或休闲娱乐体验,不提供代练、代打、'
|
||
'代上分、账号托管等非正规服务。未成年人请在监护人指导下合理消费。'
|
||
)
|
||
|
||
# (专区名, 标题, 价格, 对外销量, 排序权重, 介绍)
|
||
PRODUCTS = [
|
||
('萌新入门', '新手友好入门体验', '19.90', 128, 2000,
|
||
'面向新朋友的轻松入门体验,了解基础操作与文明游戏礼仪,氛围轻松无压力。'),
|
||
('萌新入门', '游戏礼仪小课堂', '9.90', 256, 1990,
|
||
'学习友好沟通、尊重队友、拒绝辱骂,共建文明电竞社区环境。'),
|
||
('萌新入门', '萌新问答互助时段', '16.60', 88, 1980,
|
||
'有疑问随时交流,老手耐心解答,帮助你更快熟悉平台与游戏规则。'),
|
||
('萌新入门', '健康游戏习惯科普', '6.60', 312, 1970,
|
||
'科普合理作息与用眼健康,倡导适度游戏、劳逸结合的正向生活方式。'),
|
||
('萌新入门', '电竞文化科普讲解', '15.90', 145, 1960,
|
||
'了解电子竞技发展历程与职业精神,感受积极向上的电竞文化魅力。'),
|
||
|
||
('休闲娱乐', '休闲语音陪伴开黑', '29.90', 520, 1950,
|
||
'轻松组队聊天、分享趣事,主打陪伴与放松,不承诺任何段位或战绩结果。'),
|
||
('休闲娱乐', '周末放松娱乐局', '35.90', 430, 1940,
|
||
'低压娱乐对局体验,重在过程开心,适合工作之余放松心情。'),
|
||
('休闲娱乐', '友谊组队活动票', '19.90', 367, 1930,
|
||
'结识志同道合的小伙伴,一起享受游戏乐趣,友谊第一、比赛第二。'),
|
||
('休闲娱乐', '正能量互动体验包', '32.00', 278, 1920,
|
||
'传递鼓励与支持,营造互相尊重、积极向上的互动氛围。'),
|
||
('休闲娱乐', '赛事热点讨论会', '26.00', 156, 1910,
|
||
'围绕热门赛事交流观赛心得与战术理解,纯讨论分享,不涉及任何代打服务。'),
|
||
|
||
('团队社交', '团队配合趣味体验', '49.90', 203, 1900,
|
||
'通过趣味协作任务培养默契,锻炼沟通表达能力,体验团队合作乐趣。'),
|
||
('团队社交', '团队破冰小游戏', '22.00', 189, 1890,
|
||
'适合新成员快速融入,轻松破冰、认识队友,提升社群归属感。'),
|
||
('团队社交', '语音互动陪伴30分钟', '28.00', 402, 1880,
|
||
'30分钟语音陪伴交流,可聊天、可娱乐,内容健康阳光、拒绝低俗。'),
|
||
('团队社交', '友谊第一体验套餐', '38.00', 167, 1870,
|
||
'强调尊重与包容,享受一起游戏的快乐,传递体育精神与友谊价值。'),
|
||
('团队社交', '文明电竞社群入门', '20.00', 233, 1860,
|
||
'了解社群规范与文明公约,做有礼貌、有担当的电竞爱好者。'),
|
||
|
||
('休闲娱乐', '观赛解说体验票', '39.90', 98, 1850,
|
||
'专业视角解读精彩赛事瞬间,提升观赛体验,纯观赏与讲解性质。'),
|
||
('萌新入门', '正向沟通陪练体验', '25.90', 174, 1840,
|
||
'练习清晰表达与耐心倾听,提升团队协作中的沟通效率与友好度。'),
|
||
('团队社交', '健康生活游戏倡议', '8.80', 445, 1830,
|
||
'倡导合理安排游戏时间,关注身心健康,做理性、成熟的电竞玩家。'),
|
||
('休闲娱乐', '电竞精神主题分享', '18.80', 121, 1820,
|
||
'分享坚持、拼搏、尊重对手的电竞精神,传递青春正能量。'),
|
||
('团队社交', '社群文明公约学习', '12.90', 298, 1810,
|
||
'学习平台文明公约与社区守则,共同维护清朗、健康的交流空间。'),
|
||
]
|
||
|
||
|
||
AUDIT_PRODUCT_TITLES = [row[1] for row in PRODUCTS]
|
||
|
||
|
||
class Command(BaseCommand):
|
||
help = '写入审核专用商品数据(类型+专区+商品,shenhezhuangtai=2)'
|
||
|
||
def add_arguments(self, parser):
|
||
parser.add_argument('--dry-run', action='store_true', help='只预览,不写库')
|
||
parser.add_argument('--force', action='store_true', help='删除本脚本创建的审核数据后重建')
|
||
|
||
def handle(self, *args, **options):
|
||
dry_run = options['dry_run']
|
||
force = options['force']
|
||
|
||
if force and not dry_run:
|
||
self._delete_seed_data()
|
||
|
||
existing = Shangpin.objects.filter(
|
||
biaoqian__in=AUDIT_PRODUCT_TITLES,
|
||
shenhezhuangtai=2,
|
||
).count()
|
||
if existing >= len(PRODUCTS) and not force:
|
||
self.stdout.write(self.style.WARNING(
|
||
f'已存在 {existing} 条审核种子商品,跳过。如需重建请加 --force'
|
||
))
|
||
return
|
||
|
||
if dry_run:
|
||
self.stdout.write(self.style.NOTICE('【预览模式】将写入以下结构:'))
|
||
self.stdout.write(f' 类型 1 个: {AUDIT_TYPE_NAME} (shenhezhuangtai=2)')
|
||
self.stdout.write(f' 专区 {len(ZONES)} 个')
|
||
self.stdout.write(f' 商品 {len(PRODUCTS)} 个 (shenhezhuangtai=2)')
|
||
for z, title, price, *_ in PRODUCTS[:5]:
|
||
self.stdout.write(f' - [{z}] {title} ¥{price}')
|
||
self.stdout.write(' ...')
|
||
return
|
||
|
||
with transaction.atomic():
|
||
leixing, _ = ShangpinLeixing.objects.get_or_create(
|
||
jieshao=AUDIT_TYPE_NAME,
|
||
shenhezhuangtai=2,
|
||
defaults={
|
||
'tupian_url': DEFAULT_PRODUCT_IMAGE,
|
||
'paixu': 9999,
|
||
'is_cross_enabled': False,
|
||
'is_special_type': False,
|
||
},
|
||
)
|
||
|
||
zone_map = {}
|
||
for name, paixu in ZONES:
|
||
zone, _ = ShangpinZhuanqu.objects.get_or_create(
|
||
mingzi=name,
|
||
leixing_id=leixing.id,
|
||
shenhezhuangtai=2,
|
||
defaults={'paixu': paixu},
|
||
)
|
||
zone_map[name] = zone
|
||
|
||
created = 0
|
||
skipped = 0
|
||
for zone_name, title, price, sales, sort_weight, desc in PRODUCTS:
|
||
zhuanqu = zone_map[zone_name]
|
||
if Shangpin.objects.filter(
|
||
biaoqian=title,
|
||
shenhezhuangtai=2,
|
||
zhuanqu_id=zhuanqu.id,
|
||
).exists():
|
||
skipped += 1
|
||
continue
|
||
Shangpin.objects.create(
|
||
biaoqian=title,
|
||
jiage=Decimal(price),
|
||
kucun=999,
|
||
leixing_id=leixing.id,
|
||
zhuanqu_id=zhuanqu.id,
|
||
zhenshi_xiaoliang=0,
|
||
duiwai_xiaoliang=sales,
|
||
jieshao=desc,
|
||
xiadan_xuzhi=ORDER_NOTICE,
|
||
tupian_url=DEFAULT_PRODUCT_IMAGE,
|
||
yaoqiuleixing=None,
|
||
huiyuan_id=None,
|
||
yongjin=None,
|
||
kaioi_ewai_dashou_fencheng=False,
|
||
ewai_dashou_fencheng=None,
|
||
paixu=sort_weight,
|
||
shenhezhuangtai=2,
|
||
)
|
||
created += 1
|
||
|
||
self.stdout.write(self.style.SUCCESS(
|
||
f'完成:类型 id={leixing.id},专区 {len(zone_map)} 个,'
|
||
f'新建商品 {created} 个,跳过已存在 {skipped} 个。'
|
||
))
|
||
self.stdout.write('请将 xcx_sys_peizhi.shangpin_shenhe_mode 设为 2 后,小程序点单页即展示审核商品。')
|
||
|
||
def _delete_seed_data(self):
|
||
"""仅删除本脚本商品标题列表中的审核商品,以及关联审核类型/专区。"""
|
||
deleted_products, _ = Shangpin.objects.filter(
|
||
biaoqian__in=AUDIT_PRODUCT_TITLES,
|
||
shenhezhuangtai=2,
|
||
).delete()
|
||
deleted_zones, _ = ShangpinZhuanqu.objects.filter(
|
||
mingzi__in=[z[0] for z in ZONES],
|
||
shenhezhuangtai=2,
|
||
).delete()
|
||
deleted_types, _ = ShangpinLeixing.objects.filter(
|
||
jieshao=AUDIT_TYPE_NAME,
|
||
shenhezhuangtai=2,
|
||
).delete()
|
||
self.stdout.write(self.style.WARNING(
|
||
f'--force 已清理:商品 {deleted_products},专区 {deleted_zones},类型 {deleted_types}'
|
||
))
|