Spaces:
Sleeping
Sleeping
import streamlit as st | |
import sqlite3 | |
import random | |
from datetime import datetime | |
import pandas as pd | |
import plotly.express as px | |
from pathlib import Path | |
# تنظیمات اولیه دیتابیس | |
class DatabaseManager: | |
def __init__(self): | |
self.conn = sqlite3.connect('banking_assistant.db') | |
self.create_tables() | |
def create_tables(self): | |
c = self.conn.cursor() | |
# جدول مکالمات | |
c.execute(''' | |
CREATE TABLE IF NOT EXISTS conversations ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
user_message TEXT, | |
assistant_response TEXT, | |
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, | |
feedback INTEGER DEFAULT 0 | |
) | |
''') | |
# جدول پایگاه دانش | |
c.execute(''' | |
CREATE TABLE IF NOT EXISTS knowledge_base ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
question TEXT, | |
answer TEXT, | |
category TEXT, | |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP | |
) | |
''') | |
# جدول تنظیمات | |
c.execute(''' | |
CREATE TABLE IF NOT EXISTS settings ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
theme TEXT DEFAULT 'light', | |
language TEXT DEFAULT 'fa', | |
created_at DATETIME DEFAULT CURRENT_TIMESTAMP | |
) | |
''') | |
self.conn.commit() | |
# تنظیمات استایل و تم | |
THEMES = { | |
'light': { | |
'bg_color': '#e0e5ec', | |
'text_color': '#333', | |
'shadow': '9px 9px 16px #b8b9be, -9px -9px 16px #ffffff' | |
}, | |
'dark': { | |
'bg_color': '#2d3436', | |
'text_color': '#fff', | |
'shadow': '9px 9px 16px #1a1d1e, -9px -9px 16px #404b4d' | |
}, | |
'blue': { | |
'bg_color': '#e3f2fd', | |
'text_color': '#1976d2', | |
'shadow': '9px 9px 16px #c1cdd4, -9px -9px 16px #ffffff' | |
} | |
} | |
def load_custom_styles(theme='light'): | |
return f""" | |
<style> | |
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;200;300;400;500;600;700;800;900&display=swap'); | |
/* تنظیمات پایه */ | |
* {{ | |
font-family: 'Vazirmatn', sans-serif; | |
direction: rtl; | |
transition: all 0.3s ease; | |
}} | |
body {{ | |
background: {THEMES[theme]['bg_color']}; | |
color: {THEMES[theme]['text_color']}; | |
}} | |
/* هدر اصلی */ | |
.main-header {{ | |
background: {THEMES[theme]['bg_color']}; | |
padding: 2rem; | |
border-radius: 25px; | |
box-shadow: {THEMES[theme]['shadow']}; | |
margin-bottom: 2rem; | |
text-align: center; | |
position: relative; | |
overflow: hidden; | |
}} | |
.main-header::before {{ | |
content: ''; | |
position: absolute; | |
top: -50%; | |
left: -50%; | |
width: 200%; | |
height: 200%; | |
background: linear-gradient( | |
45deg, | |
transparent 0%, | |
rgba(255, 255, 255, 0.1) 50%, | |
transparent 100% | |
); | |
animation: shine 3s infinite; | |
}} | |
/* باکس چت */ | |
.chat-container {{ | |
background: {THEMES[theme]['bg_color']}; | |
border-radius: 20px; | |
padding: 2rem; | |
margin: 1rem 0; | |
box-shadow: {THEMES[theme]['shadow']}; | |
max-height: 70vh; | |
overflow-y: auto; | |
scroll-behavior: smooth; | |
}} | |
/* پیامها */ | |
.message {{ | |
margin: 1rem 0; | |
padding: 1rem; | |
border-radius: 15px; | |
position: relative; | |
animation: messageSlide 0.3s ease-out; | |
}} | |
.message.user {{ | |
background: linear-gradient(135deg, #0073e6 0%, #0056b3 100%); | |
color: white; | |
margin-left: 2rem; | |
box-shadow: 0 4px 15px rgba(0, 115, 230, 0.2); | |
}} | |
.message.assistant {{ | |
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); | |
color: #343a40; | |
margin-right: 2rem; | |
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); | |
}} | |
/* ورودی چت */ | |
.chat-input-container {{ | |
background: {THEMES[theme]['bg_color']}; | |
padding: 1.5rem; | |
border-radius: 15px; | |
box-shadow: {THEMES[theme]['shadow']}; | |
margin-top: 1rem; | |
display: flex; | |
align-items: center; | |
gap: 1rem; | |
}} | |
.chat-input {{ | |
flex: 1; | |
padding: 1rem; | |
border: none; | |
border-radius: 10px; | |
background: rgba(255, 255, 255, 0.1); | |
backdrop-filter: blur(10px); | |
color: {THEMES[theme]['text_color']}; | |
font-size: 1rem; | |
transition: all 0.3s ease; | |
}} | |
.chat-input:focus {{ | |
outline: none; | |
box-shadow: 0 0 0 3px rgba(0, 115, 230, 0.3); | |
}} | |
/* دکمهها */ | |
.button {{ | |
padding: 0.8rem 1.5rem; | |
border: none; | |
border-radius: 10px; | |
background: linear-gradient(135deg, #0073e6 0%, #0056b3 100%); | |
color: white; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
font-weight: 500; | |
display: flex; | |
align-items: center; | |
gap: 0.5rem; | |
}} | |
.button:hover {{ | |
transform: translateY(-2px); | |
box-shadow: 0 5px 15px rgba(0, 115, 230, 0.3); | |
}} | |
.button:active {{ | |
transform: translateY(0); | |
}} | |
/* انیمیشنها */ | |
@keyframes messageSlide {{ | |
from {{ | |
opacity: 0; | |
transform: translateY(20px); | |
}} | |
to {{ | |
opacity: 1; | |
transform: translateY(0); | |
}} | |
}} | |
@keyframes shine {{ | |
0% {{ | |
transform: translateX(-100%) rotate(45deg); | |
}} | |
100% {{ | |
transform: translateX(100%) rotate(45deg); | |
}} | |
}} | |
/* اسکرولبار سفارشی */ | |
::-webkit-scrollbar {{ | |
width: 8px; | |
}} | |
::-webkit-scrollbar-track {{ | |
background: {THEMES[theme]['bg_color']}; | |
}} | |
::-webkit-scrollbar-thumb {{ | |
background: #0073e6; | |
border-radius: 4px; | |
}} | |
::-webkit-scrollbar-thumb:hover {{ | |
background: #0056b3; | |
}} | |
</style> | |
""" | |
class BankingAssistant: | |
def __init__(self): | |
self.db = DatabaseManager() | |
self.model = BankingModel() # اضافه کردن مدل | |
if 'theme' not in st.session_state: | |
st.session_state.theme = 'light' | |
if 'messages' not in st.session_state: | |
st.session_state.messages = [] | |
self.add_message('assistant', """ | |
👋 سلام! من دستیار هوشمند بانکی شما هستم. | |
میتوانم در موارد زیر به شما کمک کنم: | |
📊 مشاهده وضعیت حساب | |
💳 انتقال وجه | |
📝 درخواست تسهیلات | |
🏦 اطلاعات شعب | |
چطور میتوانم کمکتان کنم؟ | |
""") | |
def add_message(self, role, content): | |
timestamp = datetime.now().strftime("%H:%M") | |
st.session_state.messages.append({ | |
'role': role, | |
'content': content, | |
'timestamp': timestamp | |
}) | |
# ذخیره در دیتابیس | |
if role == 'user': | |
self.db.conn.execute( | |
'INSERT INTO conversations (user_message, timestamp) VALUES (?, ?)', | |
(content, timestamp) | |
) | |
else: | |
self.db.conn.execute( | |
'UPDATE conversations SET assistant_response = ? WHERE id = last_insert_rowid()', | |
(content,) | |
) | |
self.db.conn.commit() | |
def render_chat_interface(self): | |
st.markdown(load_custom_styles(st.session_state.theme), unsafe_allow_html=True) | |
# هدر اصلی | |
st.markdown(""" | |
<div class="main-header"> | |
<h1>🏦 دستیار هوشمند بانکی</h1> | |
<p>پاسخگوی 24 ساعته شما</p> | |
</div> | |
""", unsafe_allow_html=True) | |
# باکس چت | |
st.markdown('<div class="chat-container">', unsafe_allow_html=True) | |
for msg in st.session_state.messages: | |
class_name = "user" if msg['role'] == 'user' else "assistant" | |
st.markdown(f""" | |
<div class="message {class_name}"> | |
{msg['content']} | |
<small style="position: absolute; bottom: 5px; {'right' if class_name == 'user' else 'left'}: 10px; opacity: 0.7;"> | |
{msg['timestamp']} | |
</small> | |
</div> | |
""", unsafe_allow_html=True) | |
st.markdown('</div>', unsafe_allow_html=True) | |
# باکس ورودی | |
st.markdown(""" | |
<div class="chat-input-container"> | |
<button class="action-button">🎤</button> | |
<input type="text" class="chat-input" placeholder="پیام خود را بنویسید..."> | |
<button class="button"> | |
<span>ارسال</span> | |
<span>➤</span> | |
</button> | |
</div> | |
""", unsafe_allow_html=True) | |
class AdminDashboard: | |
def __init__(self, db_manager): | |
self.db = db_manager | |
def render_dashboard(self): | |
st.markdown(""" | |
<div class="admin-header"> | |
<h2>🔐 پنل مدیریت</h2> | |
</div> | |
""", unsafe_allow_html=True) | |
# نمودارهای تحلیلی | |
col1, col2 = st.columns(2) | |
with col1: | |
self.render_conversation_stats() | |
with col2: | |
self.render_feedback_chart() | |
# مدیریت پایگاه دانش | |
st.markdown(""" | |
<div class="admin-section"> | |
<h3>📚 مدیریت پایگاه دانش</h3> | |
</div> | |
""", unsafe_allow_html=True) | |
# افزودن دانش جدید | |
with st.expander("➕ افزودن مورد جدید"): | |
category = st.selectbox( | |
"دستهبندی", | |
["عمومی", "حسابها", "تسهیلات", "کارت", "شعب"] | |
) | |
question = st.text_area("سوال") | |
answer = st.text_area("پاسخ") | |
if st.button("ذخیره"): | |
self.db.conn.execute( | |
'INSERT INTO knowledge_base (question, answer, category) VALUES (?, ?, ?)', | |
(question, answer, category) | |
) | |
self.db.conn.commit() | |
st.success("✅ با موفقیت ذخیره شد") | |
def render_conversation_stats(self): | |
# دریافت آمار مکالمات | |
df = pd.read_sql_query(""" | |
SELECT | |
date(timestamp) as date, | |
COUNT(*) as count | |
FROM conversations | |
GROUP BY date(timestamp) | |
ORDER BY date DESC | |
LIMIT 7 | |
""", self.db.conn) | |
fig = px.line( | |
df, | |
x='date', | |
y='count', | |
title='آمار مکالمات 7 روز اخیر', | |
labels={'count': 'تعداد مکالمات', 'date': 'تاریخ'} | |
) | |
fig.update_layout( | |
font_family="Vazirmatn", | |
plot_bgcolor='rgba(0,0,0,0)', | |
paper_bgcolor='rgba(0,0,0,0)', | |
) | |
st.plotly_chart(fig) | |
def render_feedback_chart(self): | |
# نمودار بازخوردها | |
df = pd.read_sql_query(""" | |
SELECT | |
feedback, | |
COUNT(*) as count | |
FROM conversations | |
WHERE feedback != 0 | |
GROUP BY feedback | |
""", self.db.conn) | |
fig = px.pie( | |
df, | |
values='count', | |
names='feedback', | |
title='نمودار بازخوردها', | |
color_discrete_sequence=px.colors.sequential.Blues | |
) | |
fig.update_layout( | |
font_family="Vazirmatn", | |
plot_bgcolor='rgba(0,0,0,0)', | |
paper_bgcolor='rgba(0,0,0,0)', | |
) | |
st.plotly_chart(fig) | |
def main(): | |
st.set_page_config( | |
page_title="دستیار هوشمند بانکی", | |
page_icon="🏦", | |
layout="wide", | |
initial_sidebar_state="expanded" | |
) | |
assistant = BankingAssistant() | |
# منوی کناری | |
with st.sidebar: | |
st.markdown("### ⚙️ تنظیمات") | |
theme = st.selectbox( | |
"انتخاب تم", | |
options=['light', 'dark', 'blue'], | |
index=['light', 'dark', 'blue'].index(st.session_state.theme) | |
) | |
if theme != st.session_state.theme: | |
st.session_state.theme = theme | |
st.experimental_rerun() | |
if st.button("🔐 ورود مدیر"): | |
st.session_state.show_login = True | |
# نمایش فرم لاگین | |
if st.session_state.get('show_login', False): | |
with st.form("login_form"): | |
username = st.text_input("نام کاربری") | |
password = st.text_input("رمز عبور", type="password") | |
if st.form_submit_button("ورود"): | |
if username == "admin" and password == "admin": # در حالت واقعی باید امنتر باشد | |
st.session_state.admin_logged_in = True | |
st.session_state.show_login = False | |
st.experimental_rerun() | |
else: | |
st.error("نام کاربری یا رمز عبور اشتباه است") | |
# نمایش داشبورد مدیر | |
if st.session_state.get('admin_logged_in', False): | |
admin = AdminDashboard(assistant.db) | |
admin.render_dashboard() | |
else: | |
assistant.render_chat_interface() | |
if __name__ == "__main__": | |
main() | |