隐藏式商品/类型增加归属商家端类型,点单按归属写入抢单字段;抢单池只返回商家端类型。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -182,7 +182,9 @@ class CreateOrderView(APIView):
|
||||
if not user_openid:
|
||||
return Response({'code': 10, 'msg': '用户openid不存在', 'data': None})
|
||||
|
||||
# 创建订单主表数据
|
||||
# 创建订单主表数据(隐藏式有归属则用商家端类型的抢单要求)
|
||||
from utils.shangpin_guishu import resolve_order_qiangdan_fields
|
||||
qiangdan_fields = resolve_order_qiangdan_fields(shangpin)
|
||||
order_data = {
|
||||
'dingdan_id': dingdanid,
|
||||
'zhuangtai': 9, # 未付款状态
|
||||
@@ -191,15 +193,15 @@ class CreateOrderView(APIView):
|
||||
'dashou_fencheng': dashou_fencheng,
|
||||
'zhiding_id': zhiding_id_value,
|
||||
'shangpin_id': shangpin_id,
|
||||
'yaoqiuleixing': getattr(shangpin, 'yaoqiuleixing', None),
|
||||
'huiyuan_id': getattr(shangpin, 'huiyuan_id', ''),
|
||||
'yongjin': getattr(shangpin, 'yongjin', 0),
|
||||
'yaoqiuleixing': qiangdan_fields['yaoqiuleixing'],
|
||||
'huiyuan_id': qiangdan_fields['huiyuan_id'],
|
||||
'yongjin': qiangdan_fields['yongjin'],
|
||||
'jieshao': getattr(shangpin, 'jieshao', ''),
|
||||
'beizhu': beizhu,
|
||||
'nicheng': nicheng,
|
||||
'tupian':shangpin_tupian,
|
||||
'user1_id':f"Boss{request.user.yonghuid}",
|
||||
'leixing_id':shangpin.leixing_id
|
||||
'leixing_id': qiangdan_fields['leixing_id'],
|
||||
}
|
||||
|
||||
# 创建订单记录
|
||||
@@ -1034,7 +1036,9 @@ class VirtualCreateOrderView(APIView):
|
||||
with transaction.atomic():
|
||||
laoban_yonghuid = getattr(current_user, 'yonghuid', '')
|
||||
|
||||
# 订单主表
|
||||
# 订单主表(隐藏式有归属则用商家端类型的抢单要求)
|
||||
from utils.shangpin_guishu import resolve_order_qiangdan_fields
|
||||
qiangdan_fields = resolve_order_qiangdan_fields(shangpin)
|
||||
order_data = {
|
||||
'dingdan_id': dingdanid,
|
||||
'zhuangtai': 9,
|
||||
@@ -1043,15 +1047,15 @@ class VirtualCreateOrderView(APIView):
|
||||
'dashou_fencheng': dashou_fencheng,
|
||||
'zhiding_id': zhiding_id_value,
|
||||
'shangpin_id': shangpin_id,
|
||||
'yaoqiuleixing': getattr(shangpin, 'yaoqiuleixing', None),
|
||||
'huiyuan_id': getattr(shangpin, 'huiyuan_id', ''),
|
||||
'yongjin': getattr(shangpin, 'yongjin', 0),
|
||||
'yaoqiuleixing': qiangdan_fields['yaoqiuleixing'],
|
||||
'huiyuan_id': qiangdan_fields['huiyuan_id'],
|
||||
'yongjin': qiangdan_fields['yongjin'],
|
||||
'jieshao': getattr(shangpin, 'jieshao', ''),
|
||||
'beizhu': beizhu,
|
||||
'nicheng': nicheng,
|
||||
'tupian': shangpin_tupian,
|
||||
'user1_id': f"Boss{current_user.yonghuid}",
|
||||
'leixing_id': shangpin.leixing_id
|
||||
'leixing_id': qiangdan_fields['leixing_id'],
|
||||
}
|
||||
dingdan = Dingdan.objects.create(**order_data)
|
||||
|
||||
@@ -7731,7 +7735,7 @@ class DashouHuoquLeixingView(APIView):
|
||||
# 条件:shenhezhuangtai=1(正常状态)
|
||||
# 排序:先按 paixu 降序(数值大的在前),再按 id 升序
|
||||
leixing_queryset = ShangpinLeixing.objects.filter(
|
||||
shenhezhuangtai__in=[3, 4] # 商家端 + 点单隐藏式(抢单池可见)
|
||||
shenhezhuangtai=3 # 抢单池只展示商家端类型;隐藏式订单经归属映射到商家端类型
|
||||
).order_by('-paixu', 'id')
|
||||
'''leixing_queryset = ShangpinLeixing.objects.filter(
|
||||
shenhezhuangtai__in= [1,9] # 🔴 只取正常状态,排除审核专用
|
||||
|
||||
@@ -5373,6 +5373,7 @@ class GetProductBaseDataView(APIView):
|
||||
'tupian_url': t.tupian_url or '',
|
||||
'paixu': t.paixu,
|
||||
'shenhezhuangtai': t.shenhezhuangtai,
|
||||
'guishu_leixing_id': t.guishu_leixing_id,
|
||||
'product_count': product_count,
|
||||
})
|
||||
|
||||
@@ -5636,6 +5637,19 @@ class AddProductView(APIView):
|
||||
ewai_dashou_fencheng_str = request.data.get('ewai_dashou_fencheng', '0')
|
||||
jieshao = request.data.get('jieshao', '').strip()
|
||||
xiadan_xuzhi = request.data.get('xiadan_xuzhi', '').strip()
|
||||
try:
|
||||
shenhezhuangtai = int(request.data.get('shenhezhuangtai', 1))
|
||||
if shenhezhuangtai not in (1, 2, 3, 4):
|
||||
raise ValueError
|
||||
except (TypeError, ValueError):
|
||||
return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'})
|
||||
from utils.shangpin_guishu import parse_guishu_leixing_id
|
||||
guishu_leixing_id, guishu_err = parse_guishu_leixing_id(
|
||||
request.data.get('guishu_leixing_id'),
|
||||
shenhezhuangtai,
|
||||
)
|
||||
if guishu_err:
|
||||
return Response({'code': 400, 'msg': guishu_err})
|
||||
# 图片文件
|
||||
image_file = request.FILES.get('file') # 前端上传时字段名为 'file'
|
||||
|
||||
@@ -5767,7 +5781,8 @@ class AddProductView(APIView):
|
||||
kaioi_ewai_dashou_fencheng=kaioi_ewai,
|
||||
ewai_dashou_fencheng=ewai_fencheng,
|
||||
paixu=0, # 新商品默认排序最后
|
||||
shenhezhuangtai=1, # 正常状态
|
||||
shenhezhuangtai=shenhezhuangtai,
|
||||
guishu_leixing_id=guishu_leixing_id,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"创建商品失败: {str(e)}", exc_info=True)
|
||||
@@ -5890,7 +5905,7 @@ class GetProductDetailView(APIView):
|
||||
|
||||
# 查询所有商品类型、专区、会员(用于前端下拉选择)
|
||||
type_list = list(ShangpinLeixing.objects.all().values(
|
||||
'id', 'jieshao', 'tupian_url', 'shenhezhuangtai'
|
||||
'id', 'jieshao', 'tupian_url', 'shenhezhuangtai', 'guishu_leixing_id'
|
||||
))
|
||||
zone_list = list(ShangpinZhuanqu.objects.all().values(
|
||||
'id', 'mingzi', 'leixing_id', 'shenhezhuangtai'
|
||||
@@ -5920,6 +5935,7 @@ class GetProductDetailView(APIView):
|
||||
'ewai_dashou_fencheng': str(product.ewai_dashou_fencheng) if product.ewai_dashou_fencheng is not None else '0',
|
||||
'create_time': product.create_time.isoformat() if product.create_time else None,
|
||||
'shenhezhuangtai': product.shenhezhuangtai,
|
||||
'guishu_leixing_id': product.guishu_leixing_id,
|
||||
}
|
||||
|
||||
return Response({
|
||||
@@ -6016,6 +6032,14 @@ class UpdateProductView(APIView):
|
||||
except:
|
||||
shenhezhuangtai = 1
|
||||
|
||||
from utils.shangpin_guishu import parse_guishu_leixing_id
|
||||
guishu_leixing_id, guishu_err = parse_guishu_leixing_id(
|
||||
request.data.get('guishu_leixing_id'),
|
||||
shenhezhuangtai,
|
||||
)
|
||||
if guishu_err:
|
||||
return Response({'code': 400, 'msg': guishu_err})
|
||||
|
||||
# 校验类型和专区存在性
|
||||
if not ShangpinLeixing.objects.filter(id=leixing_id).exists():
|
||||
return Response({'code': 400, 'msg': '商品类型不存在'})
|
||||
@@ -6108,6 +6132,7 @@ class UpdateProductView(APIView):
|
||||
product.tupian_url = tupian_url
|
||||
product.guize_tupian = guize_tupian
|
||||
product.shenhezhuangtai = shenhezhuangtai
|
||||
product.guishu_leixing_id = guishu_leixing_id
|
||||
product.save()
|
||||
|
||||
return Response({'code': 0, 'msg': '商品修改成功', 'data': {'id': product.id}})
|
||||
@@ -7626,6 +7651,7 @@ class GetProductTypeZoneView(APIView):
|
||||
'huiyuan_id': t.huiyuan_id or '',
|
||||
'yongjin': float(t.yongjin) if t.yongjin is not None else None,
|
||||
'shenhezhuangtai': t.shenhezhuangtai,
|
||||
'guishu_leixing_id': t.guishu_leixing_id,
|
||||
'is_cross_enabled': t.is_cross_enabled,
|
||||
'is_special_type': t.is_special_type,
|
||||
'paixu': t.paixu,
|
||||
@@ -7727,6 +7753,14 @@ class ModifyProductTypeZoneView(APIView):
|
||||
except (TypeError, ValueError):
|
||||
return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'})
|
||||
|
||||
from utils.shangpin_guishu import parse_guishu_leixing_id
|
||||
guishu_leixing_id, guishu_err = parse_guishu_leixing_id(
|
||||
request.data.get('guishu_leixing_id'),
|
||||
shenhezhuangtai,
|
||||
)
|
||||
if guishu_err:
|
||||
return Response({'code': 400, 'msg': guishu_err})
|
||||
|
||||
is_cross_enabled = request.data.get('is_cross_enabled', False)
|
||||
is_cross_enabled = is_cross_enabled in [True, 'true', '1', 'on']
|
||||
is_special_type = request.data.get('is_special_type', False)
|
||||
@@ -7774,6 +7808,7 @@ class ModifyProductTypeZoneView(APIView):
|
||||
huiyuan_id=huiyuan_id,
|
||||
yongjin=yongjin,
|
||||
shenhezhuangtai=shenhezhuangtai,
|
||||
guishu_leixing_id=guishu_leixing_id,
|
||||
is_cross_enabled=is_cross_enabled,
|
||||
is_special_type=is_special_type,
|
||||
paixu=0
|
||||
@@ -7841,6 +7876,19 @@ class ModifyProductTypeZoneView(APIView):
|
||||
except (TypeError, ValueError):
|
||||
return Response({'code': 400, 'msg': '审核状态无效(必须为1/2/3/4)'})
|
||||
|
||||
# 归属商家端类型(隐藏式才有效;非隐藏式清空)
|
||||
if 'guishu_leixing_id' in request.data or shenhezhuangtai is not None:
|
||||
from utils.shangpin_guishu import parse_guishu_leixing_id
|
||||
target_status = changes.get('shenhezhuangtai', leixing.shenhezhuangtai)
|
||||
raw_guishu = request.data.get('guishu_leixing_id', leixing.guishu_leixing_id)
|
||||
if 'guishu_leixing_id' not in request.data and target_status != 4:
|
||||
raw_guishu = None
|
||||
guishu_id, guishu_err = parse_guishu_leixing_id(raw_guishu, target_status)
|
||||
if guishu_err:
|
||||
return Response({'code': 400, 'msg': guishu_err})
|
||||
if guishu_id != leixing.guishu_leixing_id:
|
||||
changes['guishu_leixing_id'] = guishu_id
|
||||
|
||||
# 跨平台互通
|
||||
is_cross = request.data.get('is_cross_enabled')
|
||||
if is_cross is not None:
|
||||
|
||||
33
shangpin/migrations/0011_guishu_leixing_id.py
Normal file
33
shangpin/migrations/0011_guishu_leixing_id.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('shangpin', '0010_gsfenhong_fenhong_leixing_unique'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='shangpin',
|
||||
name='guishu_leixing_id',
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
help_text='仅隐藏式商品使用;指向 shenhezhuangtai=3 的类型',
|
||||
null=True,
|
||||
verbose_name='归属商家端类型ID',
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='shangpinleixing',
|
||||
name='guishu_leixing_id',
|
||||
field=models.PositiveIntegerField(
|
||||
blank=True,
|
||||
db_index=True,
|
||||
help_text='仅隐藏式类型使用;指向 shenhezhuangtai=3 的类型',
|
||||
null=True,
|
||||
verbose_name='归属商家端类型ID',
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -40,6 +40,14 @@ class Shangpin(models.Model):
|
||||
verbose_name='审核状态',
|
||||
help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式',
|
||||
)
|
||||
# 隐藏式商品归属的商家端类型ID(点单写入订单抢单字段时用);默认无归属
|
||||
guishu_leixing_id = models.PositiveIntegerField(
|
||||
null=True,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
verbose_name='归属商家端类型ID',
|
||||
help_text='仅隐藏式商品使用;指向 shenhezhuangtai=3 的类型',
|
||||
)
|
||||
|
||||
class Meta:
|
||||
db_table = 'shangpin'
|
||||
@@ -70,6 +78,14 @@ class ShangpinLeixing(models.Model):
|
||||
verbose_name='审核状态',
|
||||
help_text='1=点单正常, 2=审核专用, 3=商家端, 4=点单隐藏式',
|
||||
)
|
||||
# 隐藏式类型归属的商家端类型ID;默认无归属
|
||||
guishu_leixing_id = models.PositiveIntegerField(
|
||||
null=True,
|
||||
blank=True,
|
||||
db_index=True,
|
||||
verbose_name='归属商家端类型ID',
|
||||
help_text='仅隐藏式类型使用;指向 shenhezhuangtai=3 的类型',
|
||||
)
|
||||
bankuai = models.ForeignKey(
|
||||
'dengji.Bankuai',
|
||||
on_delete=models.SET_NULL,
|
||||
|
||||
62
utils/shangpin_guishu.py
Normal file
62
utils/shangpin_guishu.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
隐藏式商品/类型归属商家端类型:点单写入订单抢单字段时使用。
|
||||
"""
|
||||
from shangpin.models import ShangpinLeixing
|
||||
|
||||
|
||||
def parse_guishu_leixing_id(raw, shenhezhuangtai=None):
|
||||
"""
|
||||
解析归属商家端类型 ID。
|
||||
非隐藏式(4)一律视为无归属;有值时必须指向 shenhezhuangtai=3 的类型。
|
||||
返回 (guishu_leixing_id|None, error_message|None)
|
||||
"""
|
||||
try:
|
||||
status = int(shenhezhuangtai) if shenhezhuangtai is not None else None
|
||||
except (TypeError, ValueError):
|
||||
status = None
|
||||
if status is not None and status != 4:
|
||||
return None, None
|
||||
|
||||
if raw is None or raw == '' or str(raw).lower() in ('null', 'none', 'undefined'):
|
||||
return None, None
|
||||
try:
|
||||
gid = int(raw)
|
||||
except (TypeError, ValueError):
|
||||
return None, '归属商家端类型ID无效'
|
||||
if gid <= 0:
|
||||
return None, None
|
||||
if not ShangpinLeixing.objects.filter(id=gid, shenhezhuangtai=3).exists():
|
||||
return None, '归属类型必须是商家端商品类型(审核状态=3)'
|
||||
return gid, None
|
||||
|
||||
|
||||
def resolve_order_qiangdan_fields(shangpin):
|
||||
"""
|
||||
点单写入 Dingdan 的抢单相关字段:
|
||||
- 商品或所属类型配置了 guishu_leixing_id → 用该商家端类型的 id/yaoqiuleixing/huiyuan_id/yongjin
|
||||
- 否则沿用商品自身字段
|
||||
"""
|
||||
guishu_id = getattr(shangpin, 'guishu_leixing_id', None)
|
||||
if not guishu_id and getattr(shangpin, 'leixing_id', None):
|
||||
own_type = ShangpinLeixing.objects.filter(id=shangpin.leixing_id).only(
|
||||
'guishu_leixing_id',
|
||||
).first()
|
||||
if own_type:
|
||||
guishu_id = own_type.guishu_leixing_id
|
||||
|
||||
if guishu_id:
|
||||
merchant = ShangpinLeixing.objects.filter(id=guishu_id, shenhezhuangtai=3).first()
|
||||
if merchant:
|
||||
return {
|
||||
'leixing_id': merchant.id,
|
||||
'yaoqiuleixing': merchant.yaoqiuleixing,
|
||||
'huiyuan_id': merchant.huiyuan_id or '',
|
||||
'yongjin': merchant.yongjin if merchant.yongjin is not None else 0,
|
||||
}
|
||||
|
||||
return {
|
||||
'leixing_id': shangpin.leixing_id,
|
||||
'yaoqiuleixing': getattr(shangpin, 'yaoqiuleixing', None),
|
||||
'huiyuan_id': getattr(shangpin, 'huiyuan_id', '') or '',
|
||||
'yongjin': getattr(shangpin, 'yongjin', 0) or 0,
|
||||
}
|
||||
Reference in New Issue
Block a user