feat: 商家派单金额限额改为后台可配置,派单接口读取XcxSysPeizhi
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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='商家派单最高金额(元)',
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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})
|
||||
|
||||
|
||||
|
||||
39
utils/shangjia_paifa_config.py
Normal file
39
utils/shangjia_paifa_config.py
Normal 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)
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user