v1.2.91 行情录入优化版:批量录入冠字号矫正、价格提取、编码规则统一
This commit is contained in:
parent
2306e35dec
commit
4ac2492265
|
|
@ -452,19 +452,57 @@ def create_information(
|
|||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""发布资讯"""
|
||||
# 生成行情编号:日期 + 5位自然数(从00001开始)
|
||||
# 验证并矫正冠字号:必须是J0开头 + 8位数字 = 共10位
|
||||
if data.title:
|
||||
import re
|
||||
# 提取冠字号(J0开头后面跟数字)
|
||||
match = re.search(r'J0(\d+)', data.title)
|
||||
if match:
|
||||
num = match.group(1)
|
||||
# 必须是8位数字
|
||||
if len(num) > 8:
|
||||
# 多于8位:取前8位
|
||||
num = num[:8]
|
||||
elif len(num) < 8:
|
||||
# 少于8位:前面补0
|
||||
num = num.zfill(8)
|
||||
# 重新构建title,确保是J0开头
|
||||
original = match.group(0)
|
||||
data.title = data.title.replace(original, 'J0' + num, 1)
|
||||
else:
|
||||
# 如果不是J0开头,尝试转换
|
||||
other_match = re.search(r'J([1-9]\d{0,8})', data.title)
|
||||
if other_match:
|
||||
# 非J0开头的,尝试补0变成J0开头
|
||||
num = other_match.group(1).zfill(8)[:8]
|
||||
original = other_match.group(0)
|
||||
data.title = data.title.replace(original, 'J0' + num, 1)
|
||||
# 生成行情编号:年份后两位+月+日+当日序号(如260414001)
|
||||
# 序号在当天最大序号基础上+1
|
||||
deal_no = None
|
||||
if data.info_type == 'deal':
|
||||
today = datetime.now().strftime('%Y%m%d')
|
||||
# 查询当天已有行情数量
|
||||
from app.models.models import Information
|
||||
count_today = db.query(Information).filter(
|
||||
today = datetime.now().strftime('%y%m%d') # 如260414
|
||||
# 查询当天最大的deal_no
|
||||
max_deal = db.query(Information.deal_no).filter(
|
||||
Information.info_type == 'deal',
|
||||
Information.deal_no.like(f'DJ{today}%')
|
||||
).count()
|
||||
# 编号 = 日期 + 5位自然数(如 DJ2026041100001)
|
||||
seq = count_today + 1
|
||||
deal_no = f'DJ{today}{seq:05d}'
|
||||
Information.deal_no.isnot(None),
|
||||
Information.deal_no != '',
|
||||
Information.deal_no.like(f'{today}%')
|
||||
).order_by(Information.deal_no.desc()).first()
|
||||
|
||||
if max_deal and max_deal[0] and max_deal[0].startswith(today):
|
||||
# 当天已有编号,提取序号并+1
|
||||
try:
|
||||
current_seq = int(max_deal[0][6:]) # 取最后3位序号
|
||||
new_seq = current_seq + 1
|
||||
except:
|
||||
new_seq = 1
|
||||
else:
|
||||
# 新的一天,从001开始
|
||||
new_seq = 1
|
||||
|
||||
deal_no = f'{today}{new_seq:03d}'
|
||||
|
||||
info = Information(
|
||||
user_id=current_user.f99_90_id,
|
||||
|
|
@ -511,6 +549,12 @@ def create_information(
|
|||
view_count=info.view_count,
|
||||
contact_count=info.contact_count,
|
||||
created_at=info.created_at,
|
||||
packaging=info.packaging,
|
||||
is_graded=info.is_graded,
|
||||
grading_company=info.grading_company,
|
||||
grading_score=info.grading_score,
|
||||
category=info.category,
|
||||
deal_no=info.deal_no,
|
||||
user_name=current_user.f01_01_name,
|
||||
user_avatar=current_user.avatar,
|
||||
collection_name=None,
|
||||
|
|
@ -1277,7 +1321,45 @@ async def batch_parse_deals(text: str = Body(..., embed=True)):
|
|||
|
||||
# 尝试直接解析
|
||||
data = json.loads(content.strip())
|
||||
return {"success": True, "data": data}
|
||||
# 对AI返回的数据进行冠字号矫正 - 确保J0开头+8位数字
|
||||
def normalize_serial_ai(num_str):
|
||||
"""矫正冠字号:J0开头,8位数字,共10位"""
|
||||
if not num_str.startswith('J0'):
|
||||
return None
|
||||
num = num_str[2:] # 去掉J0
|
||||
diff = 8 - len(num)
|
||||
# 位数正好8位,不需要矫正
|
||||
if diff == 0:
|
||||
return num_str
|
||||
elif diff == -1:
|
||||
# 多1位:取前4位+最后4位
|
||||
if len(num) >= 4:
|
||||
result = num[:4] + num[-4:]
|
||||
if len(result) == 8:
|
||||
return 'J0' + result
|
||||
elif diff == 1:
|
||||
# 少1位:J0 + 0 + 数字
|
||||
return 'J0' + '0' + num
|
||||
elif diff == -2:
|
||||
# 多2位:取前4位+最后4位
|
||||
if len(num) >= 4:
|
||||
result = num[:4] + num[-4:]
|
||||
if len(result) == 8:
|
||||
return 'J0' + result
|
||||
elif diff == 2:
|
||||
# 少2位:J0 + 00 + 数字
|
||||
return 'J0' + '00' + num
|
||||
return None
|
||||
|
||||
# 矫正每条记录的冠字号
|
||||
corrected_data = []
|
||||
for item in data:
|
||||
if 'serial' in item:
|
||||
normalized = normalize_serial_ai(item['serial'])
|
||||
if normalized:
|
||||
item['serial'] = normalized
|
||||
corrected_data.append(item)
|
||||
return {"success": True, "data": corrected_data}
|
||||
except json.JSONDecodeError:
|
||||
# 尝试用正则提取
|
||||
match = re.search(r'\[.*\]', content, re.DOTALL)
|
||||
|
|
@ -1330,24 +1412,59 @@ def parse_deals_locally(text: str, default_packaging: str = '', default_date: st
|
|||
default_date = datetime.now().strftime('%Y-%m-%d')
|
||||
deal_date = extracted_date or default_date
|
||||
|
||||
# 冠字号矫正函数 - 确保是J0开头+8位数字
|
||||
def normalize_serial(num_str, needs_j0=False):
|
||||
"""矫正冠字号:J0开头,8位数字,共10位"""
|
||||
num = num_str
|
||||
# 如果是单独的7-9位数字(无J0前缀),取后8位
|
||||
if needs_j0 and len(num) > 8:
|
||||
num = num[-8:]
|
||||
|
||||
diff = 8 - len(num)
|
||||
|
||||
# 位数正好8位,不需要矫正
|
||||
if diff == 0:
|
||||
return 'J0' + num
|
||||
# 少1位(7位数字)→ J0 + 0 + 数字
|
||||
elif diff == 1:
|
||||
return 'J0' + '0' + num
|
||||
# 多1位(9位数字)→ J0 + 取前4位+后4位 = 8位数字
|
||||
elif diff == -1:
|
||||
if len(num) >= 8:
|
||||
result = num[:4] + num[-4:]
|
||||
return 'J0' + result
|
||||
return None # 无法矫正
|
||||
|
||||
lines = text.strip().split('\n')
|
||||
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
if not line or 'J0' not in line:
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# 提取冠字号 J0 + 8-9位数字
|
||||
serial_match = re.search(r'J0(\d{8,9})', line)
|
||||
# 提取冠字号:J0 + 至少7位数字(可能到10位),或者单独的7~9位数字
|
||||
# 优先匹配 J0开头,否则匹配单独的7-9位数字
|
||||
serial_num = None
|
||||
serial_match = re.search(r'J0(\d{7,11})', line)
|
||||
if not serial_match:
|
||||
# 尝试匹配单独的7-9位数字(前面是空格或行首)
|
||||
serial_match = re.search(r'(?:^|\s)(\d{7,9})(?:\s|$|\n)', line)
|
||||
if serial_match:
|
||||
# 单独的7-9位数字需要加上J0前缀
|
||||
num = serial_match.group(1)
|
||||
serial_num = num
|
||||
serial = normalize_serial(num, needs_j0=True)
|
||||
else:
|
||||
continue
|
||||
|
||||
else:
|
||||
# J0开头的7-9位数字
|
||||
serial_num = serial_match.group(1)
|
||||
if len(serial_num) == 9:
|
||||
serial_num = serial_num[:8]
|
||||
serial = 'J0' + serial_num
|
||||
serial = normalize_serial(serial_num, needs_j0=False)
|
||||
|
||||
# 提取价格 ¥xxx,xxx 或 xxx,xxx(必须在J0之后)
|
||||
if not serial:
|
||||
continue # 跳过无法矫正的数据
|
||||
|
||||
# 提取价格:在冠字号之后提取价格
|
||||
serial_pos = line.find(serial)
|
||||
after_serial = line[serial_pos + len(serial):]
|
||||
price_match = re.search(r'[¥¥]?\s*([1-9][\d,]{2,})', after_serial)
|
||||
|
|
@ -1356,13 +1473,13 @@ def parse_deals_locally(text: str, default_packaging: str = '', default_date: st
|
|||
price = int(price_match.group(1).replace(',', ''))
|
||||
|
||||
# 提取卖家(价格后面的中文字符)
|
||||
after_price_pos = after_serial.find(price_match.group(0)) + len(price_match.group(0))
|
||||
after_price = after_serial[after_price_pos:]
|
||||
after_price_pos = line.find(price_match.group(0)) + len(price_match.group(0))
|
||||
after_price = line[after_price_pos:]
|
||||
seller_match = re.search(r'([^\d\s¥¥]+?)(?:\s*$|\s*\n)', after_price)
|
||||
seller = seller_match.group(1).strip() if seller_match else ''
|
||||
|
||||
# 分类判断
|
||||
digits = serial_num
|
||||
# 分类判断(使用矫正后的冠字号去掉J0前缀的8位数字)
|
||||
digits = serial[2:] # 去掉J0前缀
|
||||
d = digits
|
||||
category = '通货'
|
||||
if not any(c in d for c in ['1','2','3','4','5','7']): category = '圆圆号'
|
||||
|
|
|
|||
Loading…
Reference in New Issue