chore: auto release commit (2026-09-14 15:11:41)
All checks were successful
技能自动化发布 / release (push) Successful in 9s
All checks were successful
技能自动化发布 / release (push) Successful in 9s
This commit is contained in:
248
scripts/service/rpa_invoice_service.py
Normal file
248
scripts/service/rpa_invoice_service.py
Normal file
@@ -0,0 +1,248 @@
|
||||
"""RPA发票数据服务:处理RPA提取的发票数据存储和查询。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sqlite3
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from db.connection import get_conn
|
||||
from db.display_metadata import upsert_table_metadata, seed_column_metadata_batch
|
||||
from db.rpa_invoice_schema import RPA_INVOICES_DDL, RPA_INVOICES_INDEX, RPA_INVOICES_COLUMNS
|
||||
from util.constants import LOG_LOGGER_NAME
|
||||
from util.logging_config import get_skill_logger
|
||||
|
||||
|
||||
def init_rpa_invoice_table() -> None:
|
||||
"""初始化RPA发票数据表。"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 创建表
|
||||
cursor.execute(RPA_INVOICES_DDL)
|
||||
cursor.execute(RPA_INVOICES_INDEX)
|
||||
|
||||
# 添加表元数据
|
||||
upsert_table_metadata(
|
||||
cursor,
|
||||
table_name="rpa_invoices",
|
||||
display_name="RPA发票提取",
|
||||
description="通过RPA从网站提取的发票数据",
|
||||
grid_help="查看RPA提取的发票数据,可按批次ID筛选",
|
||||
visible=1,
|
||||
readonly=1,
|
||||
default_sort_json='[{"column":"id","direction":"desc"}]',
|
||||
default_visible_columns_json='["id","batch_id","extraction_time","username","status","created_at"]',
|
||||
)
|
||||
|
||||
# 添加列元数据
|
||||
seed_column_metadata_batch(
|
||||
cursor,
|
||||
table_name="rpa_invoices",
|
||||
columns=RPA_INVOICES_COLUMNS,
|
||||
valid_column_names=[str(c["column_name"]) for c in RPA_INVOICES_COLUMNS],
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
|
||||
except Exception as e:
|
||||
logger = get_skill_logger()
|
||||
logger.error("init_rpa_invoice_table_failed error=%s", str(e))
|
||||
raise
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def save_rpa_invoice_data(
|
||||
batch_id: str,
|
||||
source_url: str,
|
||||
invoice_data: Dict[str, Any],
|
||||
username: str = "",
|
||||
status: str = "extracted",
|
||||
error_message: str = "",
|
||||
) -> int:
|
||||
"""保存RPA提取的发票数据。
|
||||
|
||||
Args:
|
||||
batch_id: 批次ID
|
||||
source_url: 来源网址
|
||||
invoice_data: 发票数据
|
||||
username: 操作用户
|
||||
status: 状态
|
||||
error_message: 错误信息
|
||||
|
||||
Returns:
|
||||
保存的记录ID
|
||||
"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 将发票数据转换为JSON字符串
|
||||
invoice_data_json = json.dumps(invoice_data, ensure_ascii=False)
|
||||
|
||||
# 插入数据
|
||||
cursor.execute("""
|
||||
INSERT INTO rpa_invoices (
|
||||
batch_id, source_url, username, invoice_data_json, status, error_message
|
||||
) VALUES (?, ?, ?, ?, ?, ?)
|
||||
""", (batch_id, source_url, username, invoice_data_json, status, error_message))
|
||||
|
||||
record_id = cursor.lastrowid
|
||||
conn.commit()
|
||||
|
||||
logger = get_skill_logger()
|
||||
logger.info(
|
||||
"rpa_invoice_saved record_id=%s batch_id=%s invoice_count=%s",
|
||||
record_id,
|
||||
batch_id,
|
||||
invoice_data.get("total_count", 0),
|
||||
)
|
||||
|
||||
return record_id
|
||||
|
||||
except Exception as e:
|
||||
logger = get_skill_logger()
|
||||
logger.error("save_rpa_invoice_data_failed error=%s", str(e))
|
||||
raise
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_rpa_invoice_data(record_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""获取RPA提取的发票数据。"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT * FROM rpa_invoices WHERE id = ?", (record_id,))
|
||||
row = cursor.fetchone()
|
||||
|
||||
if not row:
|
||||
return None
|
||||
|
||||
# 转换为字典
|
||||
columns = [desc[0] for desc in cursor.description]
|
||||
data = dict(zip(columns, row))
|
||||
|
||||
# 解析JSON数据
|
||||
if "invoice_data_json" in data and data["invoice_data_json"]:
|
||||
try:
|
||||
data["invoice_data"] = json.loads(data["invoice_data_json"])
|
||||
except json.JSONDecodeError:
|
||||
data["invoice_data"] = {}
|
||||
|
||||
return data
|
||||
|
||||
except Exception as e:
|
||||
logger = get_skill_logger()
|
||||
logger.error("get_rpa_invoice_data_failed error=%s", str(e))
|
||||
return None
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def list_rpa_invoices(
|
||||
limit: int = 20,
|
||||
batch_id: Optional[str] = None,
|
||||
username: Optional[str] = None,
|
||||
status: Optional[str] = None,
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""查询RPA提取的发票数据列表。"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 构建查询条件
|
||||
conditions = []
|
||||
params = []
|
||||
|
||||
if batch_id:
|
||||
conditions.append("batch_id = ?")
|
||||
params.append(batch_id)
|
||||
|
||||
if username:
|
||||
conditions.append("username = ?")
|
||||
params.append(username)
|
||||
|
||||
if status:
|
||||
conditions.append("status = ?")
|
||||
params.append(status)
|
||||
|
||||
where_clause = " AND ".join(conditions) if conditions else "1=1"
|
||||
|
||||
# 执行查询
|
||||
query = f"""
|
||||
SELECT id, batch_id, source_url, extraction_time, username, status, error_message, created_at
|
||||
FROM rpa_invoices
|
||||
WHERE {where_clause}
|
||||
ORDER BY id DESC
|
||||
LIMIT ?
|
||||
"""
|
||||
params.append(limit)
|
||||
|
||||
cursor.execute(query, params)
|
||||
rows = cursor.fetchall()
|
||||
|
||||
# 转换为字典列表
|
||||
columns = [desc[0] for desc in cursor.description]
|
||||
result = [dict(zip(columns, row)) for row in rows]
|
||||
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger = get_skill_logger()
|
||||
logger.error("list_rpa_invoices_failed error=%s", str(e))
|
||||
return []
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_rpa_invoice_stats() -> Dict[str, Any]:
|
||||
"""获取RPA提取统计信息。"""
|
||||
conn = get_conn()
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# 总记录数
|
||||
cursor.execute("SELECT COUNT(*) FROM rpa_invoices")
|
||||
total_count = cursor.fetchone()[0]
|
||||
|
||||
# 按状态统计
|
||||
cursor.execute("""
|
||||
SELECT status, COUNT(*) as count
|
||||
FROM rpa_invoices
|
||||
GROUP BY status
|
||||
""")
|
||||
status_stats = {row[0]: row[1] for row in cursor.fetchall()}
|
||||
|
||||
# 最近提取记录
|
||||
cursor.execute("""
|
||||
SELECT id, batch_id, extraction_time, username, status
|
||||
FROM rpa_invoices
|
||||
ORDER BY id DESC
|
||||
LIMIT 5
|
||||
""")
|
||||
recent_extractions = [
|
||||
{
|
||||
"id": row[0],
|
||||
"batch_id": row[1],
|
||||
"extraction_time": row[2],
|
||||
"username": row[3],
|
||||
"status": row[4],
|
||||
}
|
||||
for row in cursor.fetchall()
|
||||
]
|
||||
|
||||
return {
|
||||
"total_count": total_count,
|
||||
"status_stats": status_stats,
|
||||
"recent_extractions": recent_extractions,
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger = get_skill_logger()
|
||||
logger.error("get_rpa_invoice_stats_failed error=%s", str(e))
|
||||
return {"error": str(e)}
|
||||
finally:
|
||||
conn.close()
|
||||
Reference in New Issue
Block a user