修复订单多项统计和海运快慢报价上下文

This commit is contained in:
2026-11-06 11:48:41 +08:00
parent 311b9bd57d
commit 7b3b3d30ba
8 changed files with 274 additions and 47 deletions
+48 -23
View File
@@ -127,6 +127,24 @@ def quantity_number(value,intent):
return '约'+number(value,6)
def select_timed_rates(rates,slowest=False):
"""Compare numeric day ranges within one region, service kind and billing basis."""
ranked=[]
best={}
for rate in rates:
match=re.search(r'(?<![\d.])(\d+(?:\.\d+)?)\s*(?:[-—–~~至]\s*(\d+(?:\.\d+)?))?\s*(?:天|days?)',rate['eta'],re.I)
if not match:continue
low=Decimal(match[1])
high=Decimal(match[2] or match[1])
if low<=0 or high<low:continue
key=(rate['zone'],rate['kind'],rate['unit'],rate['tax'])
timing=(high,low) if slowest else (low,high)
ranked.append((rate,key,timing))
choose=max if slowest else min
best[key]=choose(best.get(key,timing),timing)
return [rate for rate,key,timing in ranked if timing==best[key]]
def render_rates(intent, book, destinations, remote_fees):
from .quote_fees import charge_details
from .quote_language import translate_quote
@@ -154,35 +172,42 @@ def render_rates(intent, book, destinations, remote_fees):
if part and intent.get('metal_chargeable_weight') is not None:
billing.update(metal_chargeable_weight=None,metal_scope='partial')
rates = match_rates(billing, book, destination)
if intent.get('mode') in ('cheapest','fastest') and rates:
if intent['mode']=='cheapest':
eligible=[r for r in rates if quantity(billing,r) is not None]
best={}
for rate in eligible:
key=(destination['zone'] or rate['zone'],rate['unit'],rate['tax'])
value=quantity(billing,rate)*Decimal(rate['price'])+charge_details(billing,rate,fees,book)['cny']
best[key]=min(best.get(key,value),value)
rates=[r for r in eligible if quantity(billing,r)*Decimal(r['price'])+charge_details(billing,r,fees,book)['cny']==best[(destination['zone'] or r['zone'],r['unit'],r['tax'])]] or rates
lines.append('按相同区域、计费单位及税费方式比较的较低价方案:')
else:
def eta_key(rate):
values=[Decimal(v) for v in re.findall(r'\d+(?:\.\d+)?',rate['eta'])]
return tuple(values[:2]) if values else (Decimal('Infinity'),)
earliest=min(eta_key(r) for r in rates)
rates=[r for r in rates if eta_key(r)==earliest]
lines.append('按资料中的参考时效,较快方案如下;提取不等于送达或签收:')
if intent.get('mode')=='cheapest' and rates:
eligible=[r for r in rates if quantity(billing,r) is not None]
best={}
for rate in eligible:
key=(destination['zone'] or rate['zone'],rate['unit'],rate['tax'])
value=quantity(billing,rate)*Decimal(rate['price'])+charge_details(billing,rate,fees,book)['cny']
best[key]=min(best.get(key,value),value)
rates=[r for r in eligible if quantity(billing,r)*Decimal(r['price'])+charge_details(billing,r,fees,book)['cny']==best[(destination['zone'] or r['zone'],r['unit'],r['tax'])]] or rates
lines.append('按相同区域、计费单位及税费方式比较的较低价方案:')
if not rates:
lines.append(f"{destination['label']}:当前资料没有匹配的线路价格,提供目的仓码或邮编可继续查询。")
continue
if destination['label'] != '美国':
lines.append(destination['label']+':')
selections=[('',rates)]
if intent.get('mode') in ('fastest','slowest','speed_compare'):
selections=[]
if intent['mode'] in ('fastest','speed_compare'):
selections.append(('最快参考方案',select_timed_rates(rates)))
if intent['mode'] in ('slowest','speed_compare'):
selections.append(('最慢参考方案',select_timed_rates(rates,slowest=True)))
lines.append('按相同区域、运输方式、计费单位及税费方式比较参考时效。最快按天数下限、最慢按天数上限选择。')
grouped = {}
for rate in rates:
key = (rate['service'], rate['origin'], rate['unit'], rate['tax'])
grouped.setdefault(key, []).append(rate)
for (service, origin, unit, tax), rows in grouped.items():
for selection,selected_rates in selections:
if selection and not selected_rates:
lines.append(selection+'暂时无法确定,匹配线路未列明可比较的天数。')
for rate in selected_rates:
key = (selection, rate['service'], rate['origin'], rate['unit'], rate['tax'], rate['eta'])
grouped.setdefault(key, []).append(rate)
last_selection=None
for (selection,service, origin, unit, tax,eta_source), rows in grouped.items():
if selection and selection!=last_selection:
lines.append(selection)
last_selection=selection
if intent.get('mode')=='time':
eta=rows[0]['eta'] or '当前资料未列明时效'
eta=eta_source or '当前资料未列明时效'
if rows[0]['kind']=='parcel' and '提取' not in eta:eta+='提取'
lines.append(f'- {service} · {origin}:{eta}。提取不等于送达或签收。')
continue
@@ -203,7 +228,7 @@ def render_rates(intent, book, destinations, remote_fees):
elif intent.get('cbm') and rate['unit']=='cbm':
lines.append('计费体积四舍五入后不足0.01CBM,最低计费体积需人工确认,不能按零费用出价。')
parts.append(rate_text)
eta = re.sub(r'\s*无时效赔偿', '', rows[0]['eta']).strip()
eta = re.sub(r'\s*无时效赔偿', '', eta_source).strip()
if rows[0]['kind']=='parcel' and eta and '提取' not in eta:eta+='提取'
elif rows[0]['kind']=='truck' and eta and '船开' not in eta:eta='开船后参考'+eta
lines.append(f"- {service} · {origin} · {'包税' if tax=='included' else '不包税'}:"+';'.join(parts)