jiachenlong/backend/app/utils/coolbot_matcher.py

209 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 []