feat: 商家派单金额限额改为后台可配置,派单接口读取XcxSysPeizhi

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-01 11:00:33 +08:00
parent d53ddf51cc
commit 47c6e3b024
7 changed files with 134 additions and 13 deletions

View File

@@ -2556,15 +2556,11 @@ class ShangjiaPaifaView(APIView):
logger.warning(f"参数缺失: {request.data}")
return Response({'code': 400, 'msg': '缺少必填参数'})
# ----- 4. 价格验证 -----
try:
jiage = float(jiage_str)
if jiage < 10 or jiage > 10000:
return Response({'code': 400, 'msg': '价格需在10-10000元之间'})
if '.' in str(jiage_str) and len(str(jiage_str).split('.')[1]) > 2:
return Response({'code': 400, 'msg': '最多支持两位小数'})
except ValueError:
return Response({'code': 400, 'msg': '价格格式错误'})
# ----- 4. 价格验证(限额读后台配置,非写死)-----
from utils.shangjia_paifa_config import validate_shangjia_paifa_jiage
price_ok, price_msg, jiage = validate_shangjia_paifa_jiage(jiage_str)
if not price_ok:
return Response({'code': 400, 'msg': price_msg})
# ----- 5. 商品类型 -----
try:

View File

@@ -0,0 +1,29 @@
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('peizhi', '0019_xcx_sys_peizhi_shangpin_mode'),
]
operations = [
migrations.AddField(
model_name='xcxsyspeizhi',
name='shangjia_paifa_jiage_min',
field=models.DecimalField(
decimal_places=2, default=Decimal('10.00'), max_digits=10,
verbose_name='商家派单最低金额(元)',
),
),
migrations.AddField(
model_name='xcxsyspeizhi',
name='shangjia_paifa_jiage_max',
field=models.DecimalField(
decimal_places=2, default=Decimal('10000.00'), max_digits=10,
verbose_name='商家派单最高金额(元)',
),
),
]

View File

@@ -702,6 +702,12 @@ class XcxSysPeizhi(models.Model):
verbose_name='点单商品展示模式',
help_text='1=正常运营(shenhezhuangtai=1)2=审核专用(shenhezhuangtai=2)',
)
shangjia_paifa_jiage_min = models.DecimalField(
max_digits=10, decimal_places=2, default=10.00, verbose_name='商家派单最低金额(元)',
)
shangjia_paifa_jiage_max = models.DecimalField(
max_digits=10, decimal_places=2, default=10000.00, verbose_name='商家派单最高金额(元)',
)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:

View File

@@ -1733,12 +1733,18 @@ class ShangjiaTianjiaMobanView(APIView):
}, status=400)
# 4. 价格格式验证
from utils.shangjia_paifa_config import get_shangjia_paifa_jiage_limits
paifa_min, paifa_max = get_shangjia_paifa_jiage_limits()
try:
jiage_decimal = Decimal(str(jiage))
if jiage_decimal <= 0:
return Response({'code': 400, 'msg': '价格必须大于0', 'data': {}}, status=400)
if jiage_decimal > 10000:
return Response({'code': 400, 'msg': '价格不能超过10000元', 'data': {}}, status=400)
if jiage_decimal < paifa_min or jiage_decimal > paifa_max:
return Response({
'code': 400,
'msg': f'价格需在{paifa_min}-{paifa_max}元之间',
'data': {},
}, status=400)
except (InvalidOperation, ValueError, TypeError):
return Response({'code': 400, 'msg': '价格格式错误', 'data': {}}, status=400)
@@ -1921,10 +1927,16 @@ class ShangjiaGengxinMobanView(APIView):
# 修改价格
if new_jiage:
from utils.shangjia_paifa_config import get_shangjia_paifa_jiage_limits
paifa_min, paifa_max = get_shangjia_paifa_jiage_limits()
try:
jiage_decimal = Decimal(new_jiage)
if jiage_decimal <= 0 or jiage_decimal > 10000:
return Response({'code': 400, 'msg': '价格必须在0.1-10000元之间', 'data': {}}, status=400)
if jiage_decimal <= 0 or jiage_decimal < paifa_min or jiage_decimal > paifa_max:
return Response({
'code': 400,
'msg': f'价格需在{paifa_min}-{paifa_max}元之间',
'data': {},
}, status=400)
if jiage_decimal != moban.jiage:
moban.jiage = jiage_decimal
update_fields.append('jiage')

View File

@@ -114,6 +114,12 @@ class XcxSysPeizhiQueryView(APIView):
'weixin_key_path': row.weixin_key_path if row else wx_cfg.WEIXIN_KEY_PATH,
'notify_base_url': row.notify_base_url if row else wx_cfg.NOTIFY_BASE_URL,
'shangpin_shenhe_mode': row.shangpin_shenhe_mode if row else wx_cfg.SHANGPIN_SHENHE_MODE,
'shangjia_paifa_jiage_min': str(
row.shangjia_paifa_jiage_min if row else wx_cfg.SHANGJIA_PAIFA_JIAGE_MIN
),
'shangjia_paifa_jiage_max': str(
row.shangjia_paifa_jiage_max if row else wx_cfg.SHANGJIA_PAIFA_JIAGE_MAX
),
'from_database': bool(row),
}
return Response({'code': 0, 'msg': 'success', 'data': data})
@@ -131,6 +137,7 @@ class XcxSysPeizhiUpdateView(APIView):
'weixin_template_max_per_minute', 'weixin_template_batch_size', 'weixin_broadcast_enabled',
'weixin_broadcast_workers', 'weixin_mchid', 'weixin_shanghu_miyao', 'weixin_notify_url',
'weixin_cert_path', 'weixin_key_path', 'notify_base_url', 'shangpin_shenhe_mode',
'shangjia_paifa_jiage_min', 'shangjia_paifa_jiage_max',
})
def post(self, request):
@@ -155,10 +162,26 @@ class XcxSysPeizhiUpdateView(APIView):
if mode not in (1, 2):
continue
row.shangpin_shenhe_mode = mode
elif key in ('shangjia_paifa_jiage_min', 'shangjia_paifa_jiage_max'):
from decimal import Decimal, InvalidOperation
try:
amount = Decimal(str(val))
except (InvalidOperation, ValueError, TypeError):
continue
if amount <= 0:
continue
row.__setattr__(key, amount)
else:
row.__setattr__(key, str(val).strip())
row.save()
clear_xcx_sys_peizhi_cache()
row = XcxSysPeizhi.objects.first()
if row and row.shangjia_paifa_jiage_min > row.shangjia_paifa_jiage_max:
row.shangjia_paifa_jiage_min, row.shangjia_paifa_jiage_max = (
row.shangjia_paifa_jiage_max, row.shangjia_paifa_jiage_min,
)
row.save(update_fields=['shangjia_paifa_jiage_min', 'shangjia_paifa_jiage_max'])
clear_xcx_sys_peizhi_cache()
return Response({'code': 0, 'msg': '配置已更新', 'data': None})

View File

@@ -0,0 +1,39 @@
"""商家派单金额限额 — 读 XcxSysPeizhi后台可配"""
from decimal import Decimal, InvalidOperation
from utils.xcx_sys_config import wx_cfg
DEFAULT_MIN = Decimal('10')
DEFAULT_MAX = Decimal('10000')
def get_shangjia_paifa_jiage_limits():
"""返回 (min, max) Decimal"""
min_v = getattr(wx_cfg, 'SHANGJIA_PAIFA_JIAGE_MIN', None) or DEFAULT_MIN
max_v = getattr(wx_cfg, 'SHANGJIA_PAIFA_JIAGE_MAX', None) or DEFAULT_MAX
min_v = Decimal(str(min_v))
max_v = Decimal(str(max_v))
if min_v > max_v:
min_v, max_v = max_v, min_v
return min_v, max_v
def validate_shangjia_paifa_jiage(jiage_str):
"""
校验派单金额
@return (ok, msg, jiage_float|None)
"""
if jiage_str is None or str(jiage_str).strip() == '':
return False, '缺少价格', None
jiage_raw = str(jiage_str).strip()
try:
jiage = Decimal(jiage_raw)
except (InvalidOperation, ValueError, TypeError):
return False, '价格格式错误', None
if '.' in jiage_raw and len(jiage_raw.split('.')[1]) > 2:
return False, '最多支持两位小数', None
min_v, max_v = get_shangjia_paifa_jiage_limits()
if jiage < min_v or jiage > max_v:
return False, f'价格需在{min_v}-{max_v}元之间', None
return True, '', float(jiage)

View File

@@ -3,6 +3,8 @@
"""
import logging
from decimal import Decimal
from django.conf import settings
from django.core.cache import cache
@@ -126,6 +128,20 @@ class WxConfig:
return int(row.shangpin_shenhe_mode)
return 2
@property
def SHANGJIA_PAIFA_JIAGE_MIN(self):
row = _load_row()
if row is not None and row.shangjia_paifa_jiage_min is not None:
return row.shangjia_paifa_jiage_min
return Decimal('10')
@property
def SHANGJIA_PAIFA_JIAGE_MAX(self):
row = _load_row()
if row is not None and row.shangjia_paifa_jiage_max is not None:
return row.shangjia_paifa_jiage_max
return Decimal('10000')
wx_cfg = WxConfig()