Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1331,13 +1331,12 @@ print()
|
|
| 1331 |
print('='*70)
|
| 1332 |
|
| 1333 |
# ======================================================================
|
| 1334 |
-
#
|
| 1335 |
-
#
|
| 1336 |
-
# ============================================================
|
| 1337 |
|
| 1338 |
import gradio as gr
|
| 1339 |
print('='*70)
|
| 1340 |
-
print('🖥️ KHỞI TẠO GRADIO INTERFACE')
|
| 1341 |
print('='*70)
|
| 1342 |
print()
|
| 1343 |
|
|
@@ -1358,8 +1357,6 @@ def admin_add(code, name, docs, coquan, time_val, lephi, note, steps):
|
|
| 1358 |
'time': time_val, 'lephi': lephi, 'note': note, 'steps': steps
|
| 1359 |
}
|
| 1360 |
admin_procedures.append(new_proc)
|
| 1361 |
-
# For simplicity, we are not updating DICHVUCONG_DATA or Pinecone here directly
|
| 1362 |
-
# In a real application, you would update the backend data source
|
| 1363 |
return f"✅ Đã thêm: {code} - {name}", get_procedures_list()
|
| 1364 |
|
| 1365 |
# Chat function với AI Process PRO
|
|
@@ -1385,12 +1382,7 @@ def process_chat_pro(audio, text, history, persona="thuong"):
|
|
| 1385 |
result = ai_process_pro(query, use_memory=True)
|
| 1386 |
|
| 1387 |
# Format response
|
| 1388 |
-
response = f"""
|
| 1389 |
-
|
| 1390 |
-
{result['response']}
|
| 1391 |
-
|
| 1392 |
-
---
|
| 1393 |
-
_⏱️ Xử lý: {result['process_time']}s | 📄 Tài liệu: {result['docs_count']} | 🌡️ Temp: {result['temperature']}_"""
|
| 1394 |
|
| 1395 |
history.append({"role": "user", "content": query})
|
| 1396 |
history.append({"role": "assistant", "content": response})
|
|
@@ -1446,7 +1438,7 @@ footer {display: none !important;}
|
|
| 1446 |
padding: 20px 30px;
|
| 1447 |
display: flex;
|
| 1448 |
align-items: center;
|
| 1449 |
-
margin: -20px -20px
|
| 1450 |
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
| 1451 |
color: white;
|
| 1452 |
}
|
|
@@ -1475,6 +1467,40 @@ footer {display: none !important;}
|
|
| 1475 |
font-weight: 300 !important;
|
| 1476 |
}
|
| 1477 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1478 |
/* Tinh chỉnh Nút bấm */
|
| 1479 |
button.primary {
|
| 1480 |
background-color: #0056b3 !important;
|
|
@@ -1511,7 +1537,7 @@ button.primary:hover {
|
|
| 1511 |
# Khởi tạo giao diện với Theme base màu xanh thanh lịch
|
| 1512 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"), css=custom_css) as demo:
|
| 1513 |
|
| 1514 |
-
# 1. TOPBAR CHUYÊN NGHIỆP
|
| 1515 |
gr.HTML("""
|
| 1516 |
<div class="admin-topbar">
|
| 1517 |
<div class="admin-icon">🏛️</div>
|
|
@@ -1520,10 +1546,42 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"), cs
|
|
| 1520 |
<p>Giải đáp thông tin thủ tục - Nhanh chóng, Chính xác, Hỗ trợ 24/7</p>
|
| 1521 |
</div>
|
| 1522 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1523 |
""")
|
| 1524 |
|
| 1525 |
with gr.Tabs():
|
| 1526 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1527 |
with gr.Tab("💬 Trợ lý AI"):
|
| 1528 |
with gr.Row():
|
| 1529 |
with gr.Column(scale=7):
|
|
@@ -1540,7 +1598,7 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"), cs
|
|
| 1540 |
btn_send = gr.Button('GỬI CÂU HỎI', variant='primary')
|
| 1541 |
btn_clear = gr.Button('Làm mới')
|
| 1542 |
|
| 1543 |
-
# --- Ô HƯỚNG DẪN NHỎ
|
| 1544 |
gr.HTML("""
|
| 1545 |
<div style="
|
| 1546 |
margin-top: 15px;
|
|
@@ -1574,26 +1632,32 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"), cs
|
|
| 1574 |
inputs=[audio_in, msg_in]
|
| 1575 |
)
|
| 1576 |
|
| 1577 |
-
#
|
| 1578 |
btn_send.click(process_chat_pro, [audio_in, msg_in, chat], [chat, audio_out, msg_in])
|
| 1579 |
msg_in.submit(process_chat_pro, [audio_in, msg_in, chat], [chat, audio_out, msg_in])
|
| 1580 |
btn_clear.click(clear_chat_pro, [], [chat, audio_out, msg_in])
|
|
|
|
|
|
|
| 1581 |
with gr.Tab("⚙️ Admin Panel"):
|
| 1582 |
-
gr.Markdown("### 🔐 Xác thực quyền quản trị")
|
| 1583 |
|
| 1584 |
-
|
| 1585 |
-
|
| 1586 |
-
|
| 1587 |
-
|
| 1588 |
-
|
| 1589 |
-
|
| 1590 |
-
)
|
| 1591 |
-
|
|
|
|
| 1592 |
|
| 1593 |
# Group chứa nội dung Admin - Mặc định ẩn (visible=False)
|
| 1594 |
admin_content = gr.Group(visible=False)
|
| 1595 |
|
| 1596 |
with admin_content:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1597 |
gr.Markdown("---")
|
| 1598 |
gr.Markdown("### ➕ Thêm thủ tục mới (AI sẽ học ngay)")
|
| 1599 |
with gr.Row():
|
|
@@ -1613,32 +1677,41 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"), cs
|
|
| 1613 |
add_output = gr.Textbox(label="Kết quả xử lý")
|
| 1614 |
procedures_list = gr.Markdown(value=get_procedures_list())
|
| 1615 |
|
| 1616 |
-
# --- Logic
|
| 1617 |
-
def
|
| 1618 |
-
|
| 1619 |
-
|
| 1620 |
-
gr.Info("Đăng nhập thành công!
|
| 1621 |
-
return gr.update(visible=True), gr.update(visible=False)
|
| 1622 |
-
else:
|
| 1623 |
-
# Nếu sai: Giữ ẩn nội dung và hiện cảnh báo
|
| 1624 |
-
raise gr.Error("Mật khẩu không chính xác. Vui lòng thử lại!")
|
| 1625 |
return gr.update(visible=False), gr.update(visible=True)
|
|
|
|
|
|
|
|
|
|
| 1626 |
|
| 1627 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1628 |
btn_login.click(
|
| 1629 |
-
|
| 1630 |
-
inputs=[input_pass],
|
| 1631 |
-
outputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1632 |
)
|
| 1633 |
|
| 1634 |
-
# Sự kiện
|
| 1635 |
btn_add.click(
|
| 1636 |
admin_add,
|
| 1637 |
[admin_code, admin_name, admin_docs, admin_coquan, admin_time, admin_lephi, admin_note, admin_steps],
|
| 1638 |
[add_output, procedures_list]
|
| 1639 |
)
|
| 1640 |
|
| 1641 |
-
# Memory Tab
|
| 1642 |
with gr.Tab("🧠 Memory Manager"):
|
| 1643 |
gr.Markdown("### 📊 Quản lý bộ nhớ hội thoại")
|
| 1644 |
|
|
|
|
| 1331 |
print('='*70)
|
| 1332 |
|
| 1333 |
# ======================================================================
|
| 1334 |
+
# PHẦN 12.5: GRADIO INTERFACE (BẢN ĐẦY ĐỦ: CÓ TRANG CHỦ, BẢN TIN & FULL LOGIN)
|
| 1335 |
+
# ======================================================================
|
|
|
|
| 1336 |
|
| 1337 |
import gradio as gr
|
| 1338 |
print('='*70)
|
| 1339 |
+
print('🖥️ KHỞI TẠO GRADIO INTERFACE CHUẨN')
|
| 1340 |
print('='*70)
|
| 1341 |
print()
|
| 1342 |
|
|
|
|
| 1357 |
'time': time_val, 'lephi': lephi, 'note': note, 'steps': steps
|
| 1358 |
}
|
| 1359 |
admin_procedures.append(new_proc)
|
|
|
|
|
|
|
| 1360 |
return f"✅ Đã thêm: {code} - {name}", get_procedures_list()
|
| 1361 |
|
| 1362 |
# Chat function với AI Process PRO
|
|
|
|
| 1382 |
result = ai_process_pro(query, use_memory=True)
|
| 1383 |
|
| 1384 |
# Format response
|
| 1385 |
+
response = f"""{result['response']}\n\n--- \n_⏱️ Xử lý: {result['process_time']}s | 📄 Tài liệu: {result['docs_count']} | 🌡️ Temp: {result['temperature']}_"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1386 |
|
| 1387 |
history.append({"role": "user", "content": query})
|
| 1388 |
history.append({"role": "assistant", "content": response})
|
|
|
|
| 1438 |
padding: 20px 30px;
|
| 1439 |
display: flex;
|
| 1440 |
align-items: center;
|
| 1441 |
+
margin: -20px -20px 0px -20px; /* Kết nối sát sạt với khối bản tin bên dưới */
|
| 1442 |
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
| 1443 |
color: white;
|
| 1444 |
}
|
|
|
|
| 1467 |
font-weight: 300 !important;
|
| 1468 |
}
|
| 1469 |
|
| 1470 |
+
/* Khung bọc khu vực Bản tin điện tử nằm ngay dưới Topbar */
|
| 1471 |
+
.global-news-container {
|
| 1472 |
+
background: #ffffff;
|
| 1473 |
+
padding: 15px 20px;
|
| 1474 |
+
margin: 0px -20px 20px -20px; /* Tràn lề tạo dải liền mạch sát mép */
|
| 1475 |
+
border-bottom: 1px solid #dee2e6;
|
| 1476 |
+
box-shadow: 0 2px 8px rgba(0,0,0,0.02);
|
| 1477 |
+
}
|
| 1478 |
+
.section-title-news {
|
| 1479 |
+
color: #1e3c72;
|
| 1480 |
+
font-weight: 600;
|
| 1481 |
+
margin-bottom: 12px;
|
| 1482 |
+
border-bottom: 2px solid #e9ecef;
|
| 1483 |
+
padding-bottom: 6px;
|
| 1484 |
+
font-size: 15px;
|
| 1485 |
+
}
|
| 1486 |
+
.news-grid {
|
| 1487 |
+
display: grid;
|
| 1488 |
+
grid-template-columns: repeat(3, 1fr);
|
| 1489 |
+
gap: 15px;
|
| 1490 |
+
}
|
| 1491 |
+
@media (max-width: 768px) {
|
| 1492 |
+
.news-grid {
|
| 1493 |
+
grid-template-columns: 1fr;
|
| 1494 |
+
}
|
| 1495 |
+
}
|
| 1496 |
+
.news-card {
|
| 1497 |
+
background: #f8fafc;
|
| 1498 |
+
padding: 14px 16px;
|
| 1499 |
+
border-left: 4px solid #1e3c72;
|
| 1500 |
+
border-radius: 6px;
|
| 1501 |
+
box-shadow: 0 2px 4px rgba(0,0,0,0.02);
|
| 1502 |
+
}
|
| 1503 |
+
|
| 1504 |
/* Tinh chỉnh Nút bấm */
|
| 1505 |
button.primary {
|
| 1506 |
background-color: #0056b3 !important;
|
|
|
|
| 1537 |
# Khởi tạo giao diện với Theme base màu xanh thanh lịch
|
| 1538 |
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", neutral_hue="slate"), css=custom_css) as demo:
|
| 1539 |
|
| 1540 |
+
# 1. TOPBAR CHUYÊN NGHIỆP KẾT HỢP BẢN TIN ĐIỆN TỬ 3 Ô CỐ ĐỊNH CO GIÃN
|
| 1541 |
gr.HTML("""
|
| 1542 |
<div class="admin-topbar">
|
| 1543 |
<div class="admin-icon">🏛️</div>
|
|
|
|
| 1546 |
<p>Giải đáp thông tin thủ tục - Nhanh chóng, Chính xác, Hỗ trợ 24/7</p>
|
| 1547 |
</div>
|
| 1548 |
</div>
|
| 1549 |
+
|
| 1550 |
+
<div class="global-news-container">
|
| 1551 |
+
<div class="section-title-news">📰 BẢN TIN ĐIỆN TỬ DỊCH VỤ CÔNG MỚI NHẤT</div>
|
| 1552 |
+
<div class="news-grid">
|
| 1553 |
+
<div class="news-card">
|
| 1554 |
+
<strong style="color: #1e3c72; font-size: 14px;">🔥 Số hóa 100% kết quả thủ tục hành chính công</strong>
|
| 1555 |
+
<p style="margin: 6px 0 0 0; font-size: 12px; color: #475569; line-height: 1.4;">Kế hoạch hành động mới thúc đẩy toàn bộ các đơn vị ứng dụng AI để giảm thiểu tối đa thời gian chờ cấp trả giấy tờ trực tiếp cho người dân...</p>
|
| 1556 |
+
</div>
|
| 1557 |
+
<div class="news-card">
|
| 1558 |
+
<strong style="color: #1e3c72; font-size: 14px;">✨ Tích hợp thẻ Căn cước mới lên hệ thống VNeID</strong>
|
| 1559 |
+
<p style="margin: 6px 0 0 0; font-size: 12px; color: #475569; line-height: 1.4;">Người dân có thể chủ động cập nhật các thông tin sinh trắc học tích hợp sẵn phục vụ các xác minh thủ tục tư pháp nhanh gọn.</p>
|
| 1560 |
+
</div>
|
| 1561 |
+
<div class="news-card">
|
| 1562 |
+
<strong style="color: #1e3c72; font-size: 14px;">⚠️ Khuyến cáo bảo mật tài khoản định danh cá nhân</strong>
|
| 1563 |
+
<p style="margin: 6px 0 0 0; font-size: 12px; color: #475569; line-height: 1.4;">Tuyệt đối không cung cấp mã OTP, mật khẩu ứng dụng dịch vụ công cho các cuộc gọi lạ giả mạo cơ quan nhà nước.</p>
|
| 1564 |
+
</div>
|
| 1565 |
+
</div>
|
| 1566 |
+
</div>
|
| 1567 |
""")
|
| 1568 |
|
| 1569 |
with gr.Tabs():
|
| 1570 |
+
|
| 1571 |
+
# TAB 1: TRANG CHỦ (Giới thiệu & Hướng dẫn sử dụng)
|
| 1572 |
+
with gr.Tab("🏠 Trang chủ"):
|
| 1573 |
+
gr.HTML("<div class='section-title'>📖 GIỚI THIỆU & HƯỚNG DẪN HỆ THỐNG</div>")
|
| 1574 |
+
gr.Markdown("""
|
| 1575 |
+
### 🏛️ Giới thiệu về Hệ thống Trợ lý ảo AI
|
| 1576 |
+
Hệ thống **Trợ lý ảo tư vấn hành chính công** được phát triển nhằm mục tiêu tối ưu hóa trải nghiệm dịch vụ công cho công dân. Ứng dụng công nghệ xử lý ngôn ngữ tự nhiên hiện đại phối hợp với kiến trúc bộ nhớ thông minh, trợ lý ảo hỗ trợ tìm kiếm chính xác điều kiện, lệ phí và các bước thực hiện của mọi thủ tục hành chính công một cách lập tức.
|
| 1577 |
+
|
| 1578 |
+
### 💡 Hướng dẫn sử dụng các phân hệ chức năng
|
| 1579 |
+
* **💬 Phân hệ Trợ lý AI:** Chuyển qua tab chat để tương tác trực tiếp với robot hỗ trợ. Bạn có thể tự do nhập liệu bằng văn bản hoặc sử dụng microphone ghi âm giọng nói. Hệ thống sẽ tích hợp công nghệ chuyển đổi văn bản thành giọng nói để phát loa phản hồi tự động.
|
| 1580 |
+
* **⚙️ Phân hệ Admin Panel:** Khu vực nghiệp vụ dành riêng cho cán bộ quản trị hệ thống nhằm thực hiện việc đăng nhập tài khoản cấp cao và cập nhật, sửa đổi kho cơ sở dữ liệu các thủ tục hành chính mới.
|
| 1581 |
+
* **🧠 Phân hệ Memory Manager:** Cho phép người dùng theo dõi trực quan các ngữ cảnh hội thoại lưu trữ trong bộ nhớ đệm AI ở phiên làm việc hiện hành.
|
| 1582 |
+
""")
|
| 1583 |
+
|
| 1584 |
+
# TAB 2: Chat Tab
|
| 1585 |
with gr.Tab("💬 Trợ lý AI"):
|
| 1586 |
with gr.Row():
|
| 1587 |
with gr.Column(scale=7):
|
|
|
|
| 1598 |
btn_send = gr.Button('GỬI CÂU HỎI', variant='primary')
|
| 1599 |
btn_clear = gr.Button('Làm mới')
|
| 1600 |
|
| 1601 |
+
# --- Ô HƯỚNG DẪN NHỎ ---
|
| 1602 |
gr.HTML("""
|
| 1603 |
<div style="
|
| 1604 |
margin-top: 15px;
|
|
|
|
| 1632 |
inputs=[audio_in, msg_in]
|
| 1633 |
)
|
| 1634 |
|
| 1635 |
+
# Các sự kiện click tương tác chat
|
| 1636 |
btn_send.click(process_chat_pro, [audio_in, msg_in, chat], [chat, audio_out, msg_in])
|
| 1637 |
msg_in.submit(process_chat_pro, [audio_in, msg_in, chat], [chat, audio_out, msg_in])
|
| 1638 |
btn_clear.click(clear_chat_pro, [], [chat, audio_out, msg_in])
|
| 1639 |
+
|
| 1640 |
+
# TAB 3: Admin Panel (Hệ thống Log In / Log Out như Google Account)
|
| 1641 |
with gr.Tab("⚙️ Admin Panel"):
|
|
|
|
| 1642 |
|
| 1643 |
+
# Khung form đăng nhập bảo mật ban đầu
|
| 1644 |
+
with gr.Row() as login_form:
|
| 1645 |
+
with gr.Column(scale=2):
|
| 1646 |
+
input_user = gr.Textbox(label="Tài khoản cán bộ", placeholder="Nhập tên tài khoản admin...")
|
| 1647 |
+
with gr.Column(scale=2):
|
| 1648 |
+
input_pass = gr.Textbox(label="Mật khẩu mã hóa", type="password", placeholder="Nhập mật khẩu khóa bảo mật...")
|
| 1649 |
+
with gr.Column(scale=1):
|
| 1650 |
+
gr.Markdown("<br>") # Căn chỉnh lề đẩy nút bấm thẳng hàng với ô nhập liệu
|
| 1651 |
+
btn_login = gr.Button("Đăng nhập 🔑", variant="primary")
|
| 1652 |
|
| 1653 |
# Group chứa nội dung Admin - Mặc định ẩn (visible=False)
|
| 1654 |
admin_content = gr.Group(visible=False)
|
| 1655 |
|
| 1656 |
with admin_content:
|
| 1657 |
+
with gr.Row():
|
| 1658 |
+
gr.Markdown("### 🏛️ KHU VỰC QUẢN TRỊ VIÊN CẤP CAO")
|
| 1659 |
+
btn_logout = gr.Button("Đăng xuất ↩️", variant="stop", scale=1, size="sm")
|
| 1660 |
+
|
| 1661 |
gr.Markdown("---")
|
| 1662 |
gr.Markdown("### ➕ Thêm thủ tục mới (AI sẽ học ngay)")
|
| 1663 |
with gr.Row():
|
|
|
|
| 1677 |
add_output = gr.Textbox(label="Kết quả xử lý")
|
| 1678 |
procedures_list = gr.Markdown(value=get_procedures_list())
|
| 1679 |
|
| 1680 |
+
# --- Logic xác thực Đăng nhập / Đăng xuất ---
|
| 1681 |
+
def check_admin_login(username, password):
|
| 1682 |
+
# ACCOUNT và ADMIN_PASSWORD cần được khai báo trước ở các phần trên của bạn
|
| 1683 |
+
if username == ACCOUNT and password == ADMIN_PASSWORD:
|
| 1684 |
+
gr.Info("Đăng nhập thành công! Hệ thống cán bộ đã mở khóa.")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1685 |
return gr.update(visible=False), gr.update(visible=True)
|
| 1686 |
+
else:
|
| 1687 |
+
gr.Warning("Tài khoản hoặc mật khẩu không chính xác. Vui lòng kiểm tra lại!")
|
| 1688 |
+
return gr.update(visible=True), gr.update(visible=False)
|
| 1689 |
|
| 1690 |
+
def admin_logout():
|
| 1691 |
+
gr.Info("Đã đăng xuất an toàn khỏi tài khoản cán bộ quản trị.")
|
| 1692 |
+
return gr.update(visible=True), gr.update(visible=False), gr.update(value=""), gr.update(value="")
|
| 1693 |
+
|
| 1694 |
+
# Liên kết sự kiện kích hoạt click đăng nhập / đăng xuất
|
| 1695 |
btn_login.click(
|
| 1696 |
+
check_admin_login,
|
| 1697 |
+
inputs=[input_user, input_pass],
|
| 1698 |
+
outputs=[login_form, admin_content]
|
| 1699 |
+
)
|
| 1700 |
+
|
| 1701 |
+
btn_logout.click(
|
| 1702 |
+
admin_logout,
|
| 1703 |
+
inputs=[],
|
| 1704 |
+
outputs=[login_form, admin_content, input_user, input_pass]
|
| 1705 |
)
|
| 1706 |
|
| 1707 |
+
# Sự kiện thêm dữ liệu thủ tục hành chính mới
|
| 1708 |
btn_add.click(
|
| 1709 |
admin_add,
|
| 1710 |
[admin_code, admin_name, admin_docs, admin_coquan, admin_time, admin_lephi, admin_note, admin_steps],
|
| 1711 |
[add_output, procedures_list]
|
| 1712 |
)
|
| 1713 |
|
| 1714 |
+
# TAB 4: Memory Tab
|
| 1715 |
with gr.Tab("🧠 Memory Manager"):
|
| 1716 |
gr.Markdown("### 📊 Quản lý bộ nhớ hội thoại")
|
| 1717 |
|