Spaces:
Sleeping
Sleeping
Bổ sung tính năng trả ra Toàn bộ sản phẩm
Browse files
app.py
CHANGED
|
@@ -10,7 +10,7 @@ import os
|
|
| 10 |
import uuid
|
| 11 |
|
| 12 |
|
| 13 |
-
API_BASE_URL = "
|
| 14 |
|
| 15 |
|
| 16 |
@dataclass
|
|
@@ -296,16 +296,51 @@ class DisplayService:
|
|
| 296 |
markdown_table = df.to_markdown(index=False)
|
| 297 |
return f"📄 **Thông số kỹ thuật**\n\n{markdown_table}"
|
| 298 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
@staticmethod
|
| 300 |
def show_advantages(state: ConversationState) -> str:
|
| 301 |
-
"""Generate advantages table"""
|
| 302 |
specs_map = state.specs_advantages
|
| 303 |
-
columns = ["Tên", "Ưu điểm nổi trội"]
|
| 304 |
-
table_data = []
|
| 305 |
|
| 306 |
if not specs_map:
|
| 307 |
return "💡 **Ưu điểm nổi trội**\n\nKhông có ưu điểm nào."
|
| 308 |
|
|
|
|
|
|
|
| 309 |
for prod_id, data in specs_map.items():
|
| 310 |
adv = data.get("advantages", "Không có ưu điểm")
|
| 311 |
model = data.get("model", "")
|
|
@@ -318,15 +353,15 @@ class DisplayService:
|
|
| 318 |
full_name = f"**{data['name']} {model}**"
|
| 319 |
|
| 320 |
if adv not in ["Không có ưu điểm", "", None]:
|
| 321 |
-
|
| 322 |
-
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
| 326 |
-
|
| 327 |
-
|
| 328 |
-
|
| 329 |
-
return
|
| 330 |
|
| 331 |
@staticmethod
|
| 332 |
def show_solution_packages(state: ConversationState) -> str:
|
|
@@ -339,6 +374,26 @@ class DisplayService:
|
|
| 339 |
markdown_table = "\n\n".join(packages)
|
| 340 |
return markdown_table
|
| 341 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 342 |
|
| 343 |
class UIService:
|
| 344 |
"""Handles UI-related operations"""
|
|
@@ -352,6 +407,7 @@ class UIService:
|
|
| 352 |
cl.Action(name="show_specs", value="specs", label="📄 Thông số kỹ thuật", payload={"action": "specs"}),
|
| 353 |
cl.Action(name="show_advantages", value="advantages", label="💡 Ưu điểm nổi trội", payload={"action": "advantages"}),
|
| 354 |
cl.Action(name="show_packages", value="packages", label="📦 Gói sản phẩm", payload={"action": "packages"}),
|
|
|
|
| 355 |
cl.Action(name="toggle_product_search", value="toggle_search", label=search_status, payload={"action": "toggle_search"}),
|
| 356 |
cl.Action(name="change_model", value="model", label="🔄 Đổi model", payload={"action": "model"}),
|
| 357 |
]
|
|
@@ -512,6 +568,16 @@ async def on_show_packages(action):
|
|
| 512 |
pkg_content = DisplayService.show_solution_packages(app_state)
|
| 513 |
await UIService.send_message_with_buttons(pkg_content, app_state, author="assistant")
|
| 514 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 515 |
|
| 516 |
@cl.action_callback("toggle_product_search")
|
| 517 |
async def on_toggle_product_search(action):
|
|
|
|
| 10 |
import uuid
|
| 11 |
|
| 12 |
|
| 13 |
+
API_BASE_URL = "sale-agent-m179.onrender.com"
|
| 14 |
|
| 15 |
|
| 16 |
@dataclass
|
|
|
|
| 296 |
markdown_table = df.to_markdown(index=False)
|
| 297 |
return f"📄 **Thông số kỹ thuật**\n\n{markdown_table}"
|
| 298 |
|
| 299 |
+
# @staticmethod
|
| 300 |
+
# def show_advantages(state: ConversationState) -> str:
|
| 301 |
+
# """Generate advantages table"""
|
| 302 |
+
# specs_map = state.specs_advantages
|
| 303 |
+
# columns = ["Tên", "Ưu điểm nổi trội"]
|
| 304 |
+
# table_data = []
|
| 305 |
+
|
| 306 |
+
# if not specs_map:
|
| 307 |
+
# return "💡 **Ưu điểm nổi trội**\n\nKhông có ưu điểm nào."
|
| 308 |
+
|
| 309 |
+
# for prod_id, data in specs_map.items():
|
| 310 |
+
# adv = data.get("advantages", "Không có ưu điểm")
|
| 311 |
+
# model = data.get("model", "")
|
| 312 |
+
# url = data.get("url", "")
|
| 313 |
+
|
| 314 |
+
# if adv not in ["Không có ưu điểm", "", None]:
|
| 315 |
+
# adv = adv.replace("\n", "")
|
| 316 |
+
|
| 317 |
+
# # Handle both products and solution packages
|
| 318 |
+
# if url:
|
| 319 |
+
# full_name = f"**[{data['name']} {model}]({url})**"
|
| 320 |
+
# else:
|
| 321 |
+
# full_name = f"**{data['name']} {model}**"
|
| 322 |
+
|
| 323 |
+
# if adv not in ["Không có ưu điểm", "", None]:
|
| 324 |
+
# table_data.append([full_name, adv])
|
| 325 |
+
|
| 326 |
+
# if table_data:
|
| 327 |
+
# df = pd.DataFrame(table_data, columns=columns)
|
| 328 |
+
# else:
|
| 329 |
+
# df = pd.DataFrame([["Không có ưu điểm", ""]], columns=columns)
|
| 330 |
+
|
| 331 |
+
# markdown_table = df.to_markdown(index=False)
|
| 332 |
+
# return f"💡 **Ưu điểm nổi trội**\n\n{markdown_table}"
|
| 333 |
+
|
| 334 |
@staticmethod
|
| 335 |
def show_advantages(state: ConversationState) -> str:
|
| 336 |
+
"""Generate advantages as bullet list instead of table"""
|
| 337 |
specs_map = state.specs_advantages
|
|
|
|
|
|
|
| 338 |
|
| 339 |
if not specs_map:
|
| 340 |
return "💡 **Ưu điểm nổi trội**\n\nKhông có ưu điểm nào."
|
| 341 |
|
| 342 |
+
content = "💡 **Ưu điểm nổi trội**\n\n"
|
| 343 |
+
|
| 344 |
for prod_id, data in specs_map.items():
|
| 345 |
adv = data.get("advantages", "Không có ưu điểm")
|
| 346 |
model = data.get("model", "")
|
|
|
|
| 353 |
full_name = f"**{data['name']} {model}**"
|
| 354 |
|
| 355 |
if adv not in ["Không có ưu điểm", "", None]:
|
| 356 |
+
content += f"### {full_name}\n"
|
| 357 |
+
|
| 358 |
+
# Split by newlines and create bullet points
|
| 359 |
+
advantages_list = [line.strip() for line in adv.split('\n') if line.strip()]
|
| 360 |
+
for advantage in advantages_list:
|
| 361 |
+
content += f"- {advantage}\n"
|
| 362 |
+
content += "\n"
|
| 363 |
+
|
| 364 |
+
return content
|
| 365 |
|
| 366 |
@staticmethod
|
| 367 |
def show_solution_packages(state: ConversationState) -> str:
|
|
|
|
| 374 |
markdown_table = "\n\n".join(packages)
|
| 375 |
return markdown_table
|
| 376 |
|
| 377 |
+
@staticmethod
|
| 378 |
+
def show_all_products_table(state: ConversationState):
|
| 379 |
+
outputs = state.outputs or {}
|
| 380 |
+
tags = outputs.get("tags", [])
|
| 381 |
+
|
| 382 |
+
if not outputs:
|
| 383 |
+
return "Không có dữ liệu sản phẩm"
|
| 384 |
+
|
| 385 |
+
try:
|
| 386 |
+
resp = requests.post(f"{API_BASE_URL}/products_by_category",
|
| 387 |
+
json={"outputs": outputs}, timeout=60)
|
| 388 |
+
|
| 389 |
+
if resp.status_code == 200:
|
| 390 |
+
data = resp.json()
|
| 391 |
+
return data.get("markdown_table", "Không có dữ liệu sản phẩm")
|
| 392 |
+
else:
|
| 393 |
+
return "Không có dữ liệu sản phẩm"
|
| 394 |
+
except Exception as e:
|
| 395 |
+
return f"Error: {e}"
|
| 396 |
+
|
| 397 |
|
| 398 |
class UIService:
|
| 399 |
"""Handles UI-related operations"""
|
|
|
|
| 407 |
cl.Action(name="show_specs", value="specs", label="📄 Thông số kỹ thuật", payload={"action": "specs"}),
|
| 408 |
cl.Action(name="show_advantages", value="advantages", label="💡 Ưu điểm nổi trội", payload={"action": "advantages"}),
|
| 409 |
cl.Action(name="show_packages", value="packages", label="📦 Gói sản phẩm", payload={"action": "packages"}),
|
| 410 |
+
cl.Action(name="show_all_products", value="all_products", label="🛒 Tất cả sản phẩm", payload={"action": "all_products"}),
|
| 411 |
cl.Action(name="toggle_product_search", value="toggle_search", label=search_status, payload={"action": "toggle_search"}),
|
| 412 |
cl.Action(name="change_model", value="model", label="🔄 Đổi model", payload={"action": "model"}),
|
| 413 |
]
|
|
|
|
| 568 |
pkg_content = DisplayService.show_solution_packages(app_state)
|
| 569 |
await UIService.send_message_with_buttons(pkg_content, app_state, author="assistant")
|
| 570 |
|
| 571 |
+
@cl.action_callback("show_all_products")
|
| 572 |
+
async def on_show_all_products(action):
|
| 573 |
+
"""Handle show all products action"""
|
| 574 |
+
app_state = ensure_session_state()
|
| 575 |
+
if app_state is None:
|
| 576 |
+
await cl.Message(content="Error: Session state not found", author="assistant").send()
|
| 577 |
+
return
|
| 578 |
+
|
| 579 |
+
all_products_content = DisplayService.show_all_products_table(app_state)
|
| 580 |
+
await UIService.send_message_with_buttons(all_products_content, app_state, author="assistant")
|
| 581 |
|
| 582 |
@cl.action_callback("toggle_product_search")
|
| 583 |
async def on_toggle_product_search(action):
|