# coolbot_matcher - 一尘数据库号码匹配工具 # Version: 0.0.1 (2026-04-24) # 描述:从一尘数据库(coolbot_data)查询匹配的藏品号码 from typing import List from sqlalchemy import text from sqlalchemy.orm import Session from app.core.coolbot_db import coolbot_engine def match_pattern(col_number: str, pattern: str) -> bool: """匹配号码特征模式 通配符规则: - X = 任意数字 - A = 非4 - B = 非47 - C = 非347 - D = 非247 - E = 非2347 """ if not col_number or not pattern: return False if len(col_number) != len(pattern): return False for i, p in enumerate(pattern): c = col_number[i] if p == 'X': continue # 任意数字 elif p == 'A': if c == '4': return False elif p == 'B': if c == '4': return False if i < len(col_number) - 1 and col_number[i+1] == '7' and pattern[i+1] == 'X': return False elif p == 'C': if c in '347': return False elif p == 'D': if c in '247': return False elif p == 'E': if c in '2347': return False elif p == 'L': # L = 带4 if c != '4': return False elif p == 'N': # N = 无4 if c == '4': return False else: if c != p: return False return True def match_self_collections_count(db: Session, user_id: str, expect_number: str) -> int: """根据号码特征计算匹配藏品数量(从用户自有藏品) Args: db: 数据库会话 user_id: 用户ID expect_number: 期望号码,如 "J012345678" (固定J0前缀+8位特征) Returns: 匹配的藏品数量 """ from app.models.models import Collection if not expect_number or len(expect_number) != 10: return 0 if not expect_number.startswith('J0'): return 0 pattern = expect_number[2:] # 后8位 if not pattern: return 0 # 获取用户所有藏品 collections = db.query(Collection).filter( Collection.f99_91_user_id == user_id, Collection.f01_04_status == "in_collection" ).all() count = 0 for c in collections: number = c.f02_10_prefix_serial or '' if len(number) >= 10 and number.startswith('J0'): col_pattern = number[2:10] if match_pattern(col_pattern, pattern): count += 1 elif len(number) >= 8: col_pattern = number[:8] if match_pattern(col_pattern, pattern): count += 1 return count def match_collections_count_from_coolbot(expect_number: str) -> int: """根据号码特征计算匹配藏品数量(从coolbot_data数据库) Args: expect_number: 期望号码,如 "J012345678" (固定J0前缀+8位特征) Returns: 匹配的藏品数量 """ if not expect_number or len(expect_number) != 10: return 0 if not expect_number.startswith('J0'): return 0 pattern = expect_number[2:] # 后8位 if not pattern: return 0 query = text(""" SELECT id, crown_code FROM collections WHERE crown_code IS NOT NULL AND crown_code != '' AND LENGTH(crown_code) >= 10 AND crown_code LIKE 'J0%' """) try: with coolbot_engine.connect() as conn: result = conn.execute(query) match_count = 0 for row in result: crown_code = row[1] if crown_code and len(crown_code) >= 10: col_pattern = crown_code[2:10] if match_pattern(col_pattern, pattern): match_count += 1 return match_count except Exception as e: print(f"Error querying coolbot_data: {e}") return 0 def match_collections_list_from_coolbot(expect_number: str, limit: int = 20) -> List[dict]: """获取匹配的藏品列表(从coolbot_data数据库) Args: expect_number: 期望号码,如 "J012345678" limit: 返回的最大数量 Returns: 匹配的藏品列表 """ if not expect_number or len(expect_number) != 10: return [] if not expect_number.startswith('J0'): return [] pattern = expect_number[2:] # 后8位 if not pattern: return [] query = text(""" SELECT id, name, category, crown_code, price, post_title, post_url, author, post_crawled_at FROM collections WHERE crown_code IS NOT NULL AND crown_code != '' AND LENGTH(crown_code) >= 10 AND crown_code LIKE 'J0%' """) try: with coolbot_engine.connect() as conn: result = conn.execute(query) matched = [] for row in result: crown_code = row[3] if crown_code and len(crown_code) >= 10: col_pattern = crown_code[2:10] if match_pattern(col_pattern, pattern): matched.append({ "id": row[0], "name": row[1], "category": row[2], "crown_code": crown_code, "price": float(row[4]) if row[4] else None, "post_title": row[5], "post_url": row[6], "author": row[7], "post_crawled_at": row[8].isoformat() if row[8] else None }) if len(matched) >= limit: break return matched except Exception as e: print(f"Error querying coolbot_data: {e}") return []