Assistant / banking_assistant.py
Really-amin's picture
Upload 7 files
7da6612 verified
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()