- 4张表: voucher_template, voucher_rule, voucher_instance, voucher_usage_log - 可配置规则引擎: registry + validators + engine - 8种内置规则: min_amount, max_amount, applicable_product_type, applicable_product, exclude_product, max_usage_count, valid_period, user_level - CRUD定义 + API接口 + 前端页面 - SQL建表脚本 + RBAC权限配置 - 一次性使用,不找零
101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
"""内置规则校验器,每种规则一个函数,返回 (bool, error_msg)"""
|
||
|
||
from decimal import Decimal
|
||
from datetime import datetime
|
||
from .registry import register_rule
|
||
|
||
|
||
@register_rule('min_amount')
|
||
def check_min_amount(config, context):
|
||
"""最低消费门槛"""
|
||
min_val = Decimal(str(config.get('min_value', 0)))
|
||
request_amount = Decimal(str(context.get('request_amount', 0)))
|
||
if request_amount < min_val:
|
||
return False, f"未达最低消费 {min_val} 元"
|
||
return True, None
|
||
|
||
|
||
@register_rule('max_amount')
|
||
def check_max_amount(config, context):
|
||
"""最高消费限制"""
|
||
max_val = Decimal(str(config.get('max_value', 0)))
|
||
if max_val <= 0:
|
||
return True, None
|
||
request_amount = Decimal(str(context.get('request_amount', 0)))
|
||
if request_amount > max_val:
|
||
return False, f"超过最高消费 {max_val} 元"
|
||
return True, None
|
||
|
||
|
||
@register_rule('applicable_product_type')
|
||
def check_product_type(config, context):
|
||
"""限定产品类型(大类:llm/image/video/audio)"""
|
||
allowed_types = config.get('product_types', [])
|
||
if not allowed_types:
|
||
return True, None
|
||
current_type = context.get('product_type', '')
|
||
if current_type and current_type not in allowed_types:
|
||
return False, f"仅限 {', '.join(allowed_types)} 类型使用"
|
||
return True, None
|
||
|
||
|
||
@register_rule('applicable_product')
|
||
def check_specific_product(config, context):
|
||
"""限定特定产品(具体模型名)"""
|
||
allowed_products = config.get('products', [])
|
||
if not allowed_products:
|
||
return True, None
|
||
current_product = context.get('product_name', '')
|
||
if current_product and current_product not in allowed_products:
|
||
return False, f"仅限 {', '.join(allowed_products)} 使用"
|
||
return True, None
|
||
|
||
|
||
@register_rule('exclude_product')
|
||
def check_exclude_product(config, context):
|
||
"""排除特定产品"""
|
||
excluded = config.get('products', [])
|
||
if not excluded:
|
||
return True, None
|
||
current_product = context.get('product_name', '')
|
||
if current_product and current_product in excluded:
|
||
return False, f"{current_product} 不可使用此代金券"
|
||
return True, None
|
||
|
||
|
||
@register_rule('max_usage_count')
|
||
def check_max_usage_count(config, context):
|
||
"""最大使用次数"""
|
||
max_count = int(config.get('max_count', 0))
|
||
if max_count == 0:
|
||
return True, None
|
||
used_count = int(context.get('used_count', 0))
|
||
if used_count >= max_count:
|
||
return False, f"已达最大使用次数 {max_count} 次"
|
||
return True, None
|
||
|
||
|
||
@register_rule('valid_period')
|
||
def check_valid_period(config, context):
|
||
"""有效期检查(通常由 instance 的 valid_from/valid_to 自动处理,此规则用于额外限制)"""
|
||
now = datetime.now()
|
||
valid_from = context.get('valid_from')
|
||
valid_to = context.get('valid_to')
|
||
if valid_from and now < valid_from:
|
||
return False, "代金券尚未生效"
|
||
if valid_to and now > valid_to:
|
||
return False, "代金券已过期"
|
||
return True, None
|
||
|
||
|
||
@register_rule('user_level')
|
||
def check_user_level(config, context):
|
||
"""用户等级限制"""
|
||
required_level = int(config.get('min_level', 0))
|
||
if required_level == 0:
|
||
return True, None
|
||
user_level = int(context.get('user_level', 0))
|
||
if user_level < required_level:
|
||
return False, f"需 {required_level} 级以上用户"
|
||
return True, None
|