"""核对运行中AI查数接口与独立SQL;使用已有管理员会话,仅产生查询历史。""" import argparse import json import sys from decimal import Decimal from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) def main(): parser = argparse.ArgumentParser() parser.add_argument('--local', action='store_true') parser.add_argument('--url', default='http://127.0.0.1:18888') args = parser.parse_args() if args.local: from test_wsgi import app else: from app import app import requests from services.db import query from services.inventory_calc import SPECIAL_COST_PRICES price_case = 'CASE i.product_code ' + ' '.join('WHEN %s THEN %s' for _ in SPECIAL_COST_PRICES) + ' ELSE i.cost END' bindings = [v for pair in SPECIAL_COST_PRICES.items() for v in pair] expected = query(f""" SELECT COUNT(*) AS sku_count, COALESCE(SUM(i.qty),0) AS stock_qty, COALESCE(SUM(ROUND(i.qty * CAST(({price_case}) AS DECIMAL(24,10)),2)),0) AS inventory_value FROM ( SELECT product_code, SUM(available_qty) AS qty, MAX(cost_price) AS cost FROM inventory_detail WHERE data_date=(SELECT MAX(data_date) FROM inventory_detail) AND product_code NOT LIKE '%%-NL%%' AND product_name NOT LIKE '%%内料%%' GROUP BY product_code ) i JOIN products p ON p.product_code=i.product_code WHERE p.deleted_at IS NULL AND COALESCE(p.product_type,'') != '包材' AND COALESCE(p.product_name,'') NOT LIKE '%%内料%%' AND TRIM(p.brand)=%s """, [*bindings, 'Aromat Herbs'])[0] user = query("SELECT id,username,role FROM dashboard_users WHERE status=1 AND role='super_admin' ORDER BY id LIMIT 1")[0] serializer = app.session_interface.get_signing_serializer(app) cookie = serializer.dumps({'user_id': user['id'], 'username': user['username'], 'role': user['role'], 'must_change_password': False}) client = requests.Session() client.cookies.set(app.config.get('SESSION_COOKIE_NAME', 'session'), cookie) questions = ['查询品牌为Aromat Herbs的产品,库存*单价的总成本是多少', 'Aromat Herbs品牌库存总成本的具体数值是多少?', 'Aromat Herbs查一下这个品牌的商品数据目前的库存和库存金额分别是多少?'] summaries = [] for question in questions: response = client.post(args.url + '/api/ai/ask', json={'question': question}, timeout=90) response.raise_for_status() payload = response.json() assert payload.get('code') == 200, payload.get('msg') data = payload['data'] summary = data['datasets'][0]['summary'] for key in ('sku_count', 'stock_qty', 'inventory_value'): assert Decimal(str(summary[key])) == Decimal(str(expected[key])), (key, summary[key], str(expected[key])) assert data['data_date'] == summary['date'] summaries.append(data['summary']) print(json.dumps({'question': question, 'summary': data['summary'], 'detail_rows': len(data['rows']), 'unpriced_stock_sku_count': summary['unpriced_stock_sku_count']}, ensure_ascii=False)) assert len(set(summaries)) == 1, summaries print('PASS: three live answers agree with independent SQL') if __name__ == '__main__': main()