AI问数二期
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
from psycopg.types.json import Jsonb
|
||||
|
||||
@@ -35,9 +36,9 @@ def get_cube_report_state(
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT title, tenant_id, tenant_name, allow_global,
|
||||
SELECT title, tenant_id, tenant_name,
|
||||
current_cube, limit_source, response_message,
|
||||
created_at, updated_at
|
||||
request_content, created_at, updated_at
|
||||
FROM ai_cube_report_states
|
||||
WHERE dify_conversation_id = %s AND created_by = %s
|
||||
""",
|
||||
@@ -51,10 +52,10 @@ def get_cube_report_state(
|
||||
"title": row[0],
|
||||
"tenantId": str(row[1]) if row[1] is not None else None,
|
||||
"tenantName": row[2],
|
||||
"allowGlobal": row[3],
|
||||
"query": row[4],
|
||||
"limitSource": row[5],
|
||||
"message": row[6],
|
||||
"query": row[3],
|
||||
"limitSource": row[4],
|
||||
"message": row[5],
|
||||
"requestContent": row[6],
|
||||
"createdAt": row[7].isoformat() if row[7] else None,
|
||||
"updatedAt": row[8].isoformat() if row[8] else None,
|
||||
}
|
||||
@@ -65,12 +66,12 @@ def upsert_cube_report_state(
|
||||
conversation_id: str,
|
||||
user_id: str,
|
||||
title: str,
|
||||
tenant_id: str | None,
|
||||
tenant_id: str,
|
||||
tenant_name: str,
|
||||
allow_global: bool,
|
||||
query: dict[str, Any],
|
||||
limit_source: str,
|
||||
response_message: str,
|
||||
request_content: str,
|
||||
) -> None:
|
||||
normalized_source = "user" if limit_source == "user" else "system"
|
||||
with pg_pool.getConn() as conn:
|
||||
@@ -79,17 +80,17 @@ def upsert_cube_report_state(
|
||||
"""
|
||||
INSERT INTO ai_cube_report_states (
|
||||
dify_conversation_id, created_by, title, tenant_id,
|
||||
tenant_name, allow_global, current_cube, limit_source,
|
||||
response_message, created_at, updated_at
|
||||
tenant_name, current_cube, limit_source,
|
||||
response_message, request_content, created_at, updated_at
|
||||
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, NOW(), NOW())
|
||||
ON CONFLICT (dify_conversation_id) DO UPDATE SET
|
||||
title = EXCLUDED.title,
|
||||
tenant_id = EXCLUDED.tenant_id,
|
||||
tenant_name = EXCLUDED.tenant_name,
|
||||
allow_global = EXCLUDED.allow_global,
|
||||
current_cube = EXCLUDED.current_cube,
|
||||
limit_source = EXCLUDED.limit_source,
|
||||
response_message = EXCLUDED.response_message,
|
||||
request_content = EXCLUDED.request_content,
|
||||
updated_at = NOW()
|
||||
WHERE ai_cube_report_states.created_by = EXCLUDED.created_by
|
||||
""",
|
||||
@@ -99,10 +100,33 @@ def upsert_cube_report_state(
|
||||
title[:200] or "新数据对话",
|
||||
tenant_id,
|
||||
tenant_name[:200],
|
||||
allow_global,
|
||||
Jsonb(query),
|
||||
normalized_source,
|
||||
response_message,
|
||||
request_content,
|
||||
),
|
||||
)
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE ai_cube_saved_reports
|
||||
SET requirement = %s,
|
||||
tenant_id = %s,
|
||||
tenant_name = %s,
|
||||
cube_query = %s,
|
||||
limit_source = %s,
|
||||
response_message = %s,
|
||||
updated_at = NOW()
|
||||
WHERE dify_conversation_id = %s AND created_by = %s
|
||||
""",
|
||||
(
|
||||
request_content,
|
||||
tenant_id,
|
||||
tenant_name[:200],
|
||||
Jsonb(query),
|
||||
normalized_source,
|
||||
response_message,
|
||||
conversation_id,
|
||||
user_id,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -132,3 +156,185 @@ def delete_cube_report_state(conversation_id: str, user_id: str) -> None:
|
||||
""",
|
||||
(conversation_id, user_id),
|
||||
)
|
||||
|
||||
|
||||
def _saved_report_row(row) -> dict[str, Any]:
|
||||
return {
|
||||
"id": str(row[0]),
|
||||
"conversationId": str(row[1]),
|
||||
"title": row[2],
|
||||
"requirement": row[3],
|
||||
"tenantId": str(row[4]),
|
||||
"tenantName": row[5],
|
||||
"query": row[6],
|
||||
"limitSource": row[7],
|
||||
"message": row[8],
|
||||
"createdAt": row[9].isoformat() if row[9] else None,
|
||||
"updatedAt": row[10].isoformat() if row[10] else None,
|
||||
}
|
||||
|
||||
|
||||
def list_saved_cube_reports(
|
||||
*,
|
||||
user_id: str,
|
||||
tenant_id: str,
|
||||
page: int,
|
||||
page_size: int,
|
||||
keyword: str = "",
|
||||
) -> tuple[list[dict[str, Any]], int]:
|
||||
conditions = ["created_by = %s", "tenant_id = %s"]
|
||||
params: list[Any] = [user_id, tenant_id]
|
||||
if keyword:
|
||||
conditions.append("(title ILIKE %s OR requirement ILIKE %s)")
|
||||
value = f"%{keyword}%"
|
||||
params.extend([value, value])
|
||||
where_clause = " AND ".join(conditions)
|
||||
offset = (page - 1) * page_size
|
||||
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
f"SELECT COUNT(*) FROM ai_cube_saved_reports WHERE {where_clause}",
|
||||
tuple(params),
|
||||
)
|
||||
total = int(cur.fetchone()[0])
|
||||
cur.execute(
|
||||
f"""
|
||||
SELECT id, dify_conversation_id, title, requirement,
|
||||
tenant_id, tenant_name, cube_query, limit_source,
|
||||
response_message, created_at, updated_at
|
||||
FROM ai_cube_saved_reports
|
||||
WHERE {where_clause}
|
||||
ORDER BY updated_at DESC, id DESC
|
||||
LIMIT %s OFFSET %s
|
||||
""",
|
||||
(*params, page_size, offset),
|
||||
)
|
||||
items = [_saved_report_row(row) for row in cur.fetchall()]
|
||||
return items, total
|
||||
|
||||
|
||||
def get_saved_cube_report(report_id: str, user_id: str) -> dict[str, Any] | None:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT id, dify_conversation_id, title, requirement,
|
||||
tenant_id, tenant_name, cube_query, limit_source,
|
||||
response_message, created_at, updated_at
|
||||
FROM ai_cube_saved_reports
|
||||
WHERE id = %s AND created_by = %s
|
||||
""",
|
||||
(report_id, user_id),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return _saved_report_row(row) if row else None
|
||||
|
||||
|
||||
def get_saved_report_by_conversation(
|
||||
conversation_id: str, user_id: str
|
||||
) -> dict[str, Any] | None:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT id, dify_conversation_id, title, requirement,
|
||||
tenant_id, tenant_name, cube_query, limit_source,
|
||||
response_message, created_at, updated_at
|
||||
FROM ai_cube_saved_reports
|
||||
WHERE dify_conversation_id = %s AND created_by = %s
|
||||
""",
|
||||
(conversation_id, user_id),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return _saved_report_row(row) if row else None
|
||||
|
||||
|
||||
def list_saved_report_links(
|
||||
user_id: str, conversation_ids: list[str]
|
||||
) -> dict[str, str]:
|
||||
if not conversation_ids:
|
||||
return {}
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT dify_conversation_id, id
|
||||
FROM ai_cube_saved_reports
|
||||
WHERE created_by = %s
|
||||
AND dify_conversation_id = ANY(%s::varchar[])
|
||||
""",
|
||||
(user_id, conversation_ids),
|
||||
)
|
||||
return {str(row[0]): str(row[1]) for row in cur.fetchall()}
|
||||
|
||||
|
||||
def save_cube_report_from_state(
|
||||
*,
|
||||
conversation_id: str,
|
||||
user_id: str,
|
||||
title: str,
|
||||
) -> dict[str, Any] | None:
|
||||
report_id = str(uuid4())
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
INSERT INTO ai_cube_saved_reports (
|
||||
id, dify_conversation_id, created_by, title, requirement,
|
||||
tenant_id, tenant_name, cube_query, limit_source,
|
||||
response_message, created_at, updated_at
|
||||
)
|
||||
SELECT %s, dify_conversation_id, created_by, %s,
|
||||
request_content, tenant_id, tenant_name, current_cube,
|
||||
limit_source, response_message, NOW(), NOW()
|
||||
FROM ai_cube_report_states
|
||||
WHERE dify_conversation_id = %s
|
||||
AND created_by = %s
|
||||
AND tenant_id IS NOT NULL
|
||||
ON CONFLICT (created_by, dify_conversation_id) DO UPDATE SET
|
||||
requirement = EXCLUDED.requirement,
|
||||
tenant_id = EXCLUDED.tenant_id,
|
||||
tenant_name = EXCLUDED.tenant_name,
|
||||
cube_query = EXCLUDED.cube_query,
|
||||
limit_source = EXCLUDED.limit_source,
|
||||
response_message = EXCLUDED.response_message,
|
||||
updated_at = NOW()
|
||||
RETURNING id, dify_conversation_id, title, requirement,
|
||||
tenant_id, tenant_name, cube_query, limit_source,
|
||||
response_message, created_at, updated_at
|
||||
""",
|
||||
(
|
||||
report_id,
|
||||
title[:200] or "未命名报表",
|
||||
conversation_id,
|
||||
user_id,
|
||||
),
|
||||
)
|
||||
row = cur.fetchone()
|
||||
return _saved_report_row(row) if row else None
|
||||
|
||||
|
||||
def rename_saved_cube_report(report_id: str, user_id: str, title: str) -> None:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
UPDATE ai_cube_saved_reports
|
||||
SET title = %s, updated_at = NOW()
|
||||
WHERE id = %s AND created_by = %s
|
||||
""",
|
||||
(title[:200], report_id, user_id),
|
||||
)
|
||||
|
||||
|
||||
def delete_saved_cube_report(report_id: str, user_id: str) -> None:
|
||||
with pg_pool.getConn() as conn:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
DELETE FROM ai_cube_saved_reports
|
||||
WHERE id = %s AND created_by = %s
|
||||
""",
|
||||
(report_id, user_id),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user