Really-amin commited on
Commit
7da6612
1 Parent(s): 6e501ad

Upload 7 files

Browse files
Files changed (7) hide show
  1. admin_dashboard.py +402 -177
  2. app.py +77 -239
  3. banking_assistant.py +469 -0
  4. banking_model.py +146 -0
  5. filemanager.py +394 -0
  6. ml_banking_model.py +141 -0
  7. requirements.txt +12 -5
admin_dashboard.py CHANGED
@@ -1,189 +1,414 @@
1
- import React, { useState, useEffect } from 'react';
2
- import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
3
- import { Button } from '@/components/ui/button';
4
- import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
5
- import { Upload, RefreshCw, Users, BarChart2, ThumbsUp, Database } from 'lucide-react';
6
- import { Alert, AlertDescription } from '@/components/ui/alert';
7
-
8
- const AdminDashboard = () => {
9
- const [stats, setStats] = useState({
10
- accuracy: 95.5,
11
- interactions: 1234,
12
- satisfaction: 98,
13
- lastUpdate: new Date().toLocaleString(),
14
- averageResponseTime: 0.5,
15
- totalQuestions: 3500
16
- });
17
-
18
- const [learningData, setLearningData] = useState([
19
- { date: '2024-01', accuracy: 90 },
20
- { date: '2024-02', accuracy: 92 },
21
- { date: '2024-03', accuracy: 94 },
22
- { date: '2024-04', accuracy: 95.5 }
23
- ]);
24
-
25
- const [isUpdating, setIsUpdating] = useState(false);
26
- const [updateStatus, setUpdateStatus] = useState(null);
27
-
28
- const updateKnowledgeBase = async () => {
29
- setIsUpdating(true);
30
- setUpdateStatus('درحال به‌روزرسانی پایگاه دانش...');
31
-
32
- try {
33
- // ارسال درخواست به‌روزرسانی به سرور
34
- const response = await fetch('/api/update-knowledge-base', {
35
- method: 'POST',
36
- headers: {
37
- 'Content-Type': 'application/json',
38
- }
39
- });
40
-
41
- if (response.ok) {
42
- setUpdateStatus('به‌روزرسانی با موفقیت انجام شد');
43
- setStats(prev => ({
44
- ...prev,
45
- lastUpdate: new Date().toLocaleString()
46
- }));
47
- } else {
48
- throw new Error('خطا در به‌روزرسانی');
49
- }
50
- } catch (error) {
51
- setUpdateStatus('خطا در به‌روزرسانی پایگاه دانش');
52
- } finally {
53
- setIsUpdating(false);
54
- // پاک کردن پیام وضعیت بعد از 3 ثانیه
55
- setTimeout(() => setUpdateStatus(null), 3000);
 
 
 
 
 
 
 
 
 
 
56
  }
57
- };
58
-
59
- const handleFileUpload = async (event) => {
60
- const file = event.target.files[0];
61
- if (!file) return;
62
-
63
- const formData = new FormData();
64
- formData.append('file', file);
65
-
66
- try {
67
- const response = await fetch('/api/upload-document', {
68
- method: 'POST',
69
- body: formData
70
- });
71
-
72
- if (response.ok) {
73
- setUpdateStatus('فایل با موفقیت آپلود شد');
74
- } else {
75
- throw new Error('خطا در آپلود فایل');
76
- }
77
- } catch (error) {
78
- setUpdateStatus('خطا در آپلود فایل');
79
  }
80
- };
81
-
82
- return (
83
- <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 p-8 rtl">
84
- <div className="max-w-6xl mx-auto space-y-8">
85
- {/* Header */}
86
- <div className="text-center">
87
- <h1 className="text-4xl font-bold text-gray-800 mb-4">پنل مدیریت</h1>
88
- <p className="text-gray-600">آخرین به‌روزرسانی: {stats.lastUpdate}</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  </div>
 
 
 
 
 
 
 
 
 
90
 
91
- {/* Status Alert */}
92
- {updateStatus && (
93
- <Alert className="bg-white/30 backdrop-blur-lg">
94
- <AlertDescription>{updateStatus}</AlertDescription>
95
- </Alert>
96
- )}
97
-
98
- {/* Stats Cards */}
99
- <div className="grid md:grid-cols-3 gap-6">
100
- {/* Response Time Card */}
101
- <div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12),-8px_-8px_25px_rgba(255,255,255,0.9)] hover:transform hover:-translate-y-1">
102
- <div className="flex items-center justify-between">
103
- <BarChart2 className="text-blue-500" size={24} />
104
- <h3 className="text-lg font-semibold text-gray-700">زمان پاسخ‌دهی</h3>
 
 
 
 
 
105
  </div>
106
- <p className="text-3xl font-bold text-blue-600 mt-4">{stats.averageResponseTime}s</p>
107
- </div>
108
-
109
- {/* Questions Card */}
110
- <div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12),-8px_-8px_25px_rgba(255,255,255,0.9)] hover:transform hover:-translate-y-1">
111
- <div className="flex items-center justify-between">
112
- <Users className="text-green-500" size={24} />
113
- <h3 className="text-lg font-semibold text-gray-700">تعداد سوالات</h3>
114
  </div>
115
- <p className="text-3xl font-bold text-green-600 mt-4">{stats.totalQuestions}</p>
116
- </div>
117
-
118
- {/* Accuracy Card */}
119
- <div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12),-8px_-8px_25px_rgba(255,255,255,0.9)] hover:transform hover:-translate-y-1">
120
- <div className="flex items-center justify-between">
121
- <ThumbsUp className="text-purple-500" size={24} />
122
- <h3 className="text-lg font-semibold text-gray-700">دقت پاسخ‌گویی</h3>
123
  </div>
124
- <p className="text-3xl font-bold text-purple-600 mt-4">{stats.accuracy}%</p>
125
- </div>
126
  </div>
 
 
127
 
128
- {/* Chart Section */}
129
- <Card className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)]">
130
- <CardHeader>
131
- <CardTitle>روند یادگیری</CardTitle>
132
- </CardHeader>
133
- <CardContent>
134
- <div className="h-64">
135
- <ResponsiveContainer width="100%" height="100%">
136
- <LineChart data={learningData}>
137
- <CartesianGrid strokeDasharray="3 3" />
138
- <XAxis dataKey="date" />
139
- <YAxis domain={[80, 100]} />
140
- <Tooltip />
141
- <Line
142
- type="monotone"
143
- dataKey="accuracy"
144
- stroke="#4F46E5"
145
- strokeWidth={2}
146
- dot={{ fill: '#4F46E5' }}
147
- />
148
- </LineChart>
149
- </ResponsiveContainer>
150
- </div>
151
- </CardContent>
152
- </Card>
153
-
154
- {/* Actions Section */}
155
- <div className="grid md:grid-cols-2 gap-6">
156
- {/* Update Knowledge Base Button */}
157
- <Button
158
- onClick={updateKnowledgeBase}
159
- disabled={isUpdating}
160
- className="bg-gradient-to-r from-blue-500 to-indigo-600 text-white rounded-xl p-4 flex items-center justify-center gap-2 shadow-[5px_5px_20px_rgba(0,0,0,0.1)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12)] hover:transform hover:-translate-y-1"
161
- >
162
- <Database className={`w-5 h-5 ${isUpdating ? 'animate-spin' : ''}`} />
163
- {isUpdating ? 'در حال به‌روزرسانی...' : 'به‌روزرسانی پایگاه دانش'}
164
- </Button>
165
-
166
- {/* File Upload Section */}
167
- <div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)]">
168
- <div className="flex items-center justify-center w-full">
169
- <label className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed rounded-xl border-gray-300 cursor-pointer bg-white/50 hover:bg-white/70 transition-all duration-300">
170
- <div className="flex flex-col items-center justify-center pt-5 pb-6">
171
- <Upload className="w-8 h-8 text-gray-500 mb-2" />
172
- <p className="text-sm text-gray-500">برای آپلود فایل کلیک کنید</p>
173
- </div>
174
- <input
175
- type="file"
176
- className="hidden"
177
- onChange={handleFileUpload}
178
- accept=".txt,.pdf,.docx"
179
- />
180
- </label>
181
- </div>
182
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  </div>
184
- </div>
185
  </div>
186
- );
187
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
 
189
- export default AdminDashboard;
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import plotly.graph_objects as go
3
+ import plotly.express as px
4
+ import numpy as np
5
+ from datetime import datetime, timedelta
6
+
7
+ import streamlit as st
8
+ import pandas as pd
9
+ from pathlib import Path
10
+
11
+ # تنظیمات صفحه
12
+ st.set_page_config(
13
+ page_title="داشبورد مدیریت",
14
+ page_icon="👤",
15
+ layout="wide"
16
+ )
17
+
18
+ # استایل‌های داشبورد
19
+ st.markdown("""
20
+ <style>
21
+ @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
22
+
23
+ * {
24
+ font-family: 'Vazirmatn', sans-serif;
25
+ direction: rtl;
26
+ }
27
+
28
+ .dashboard-container {
29
+ background: white;
30
+ border-radius: 15px;
31
+ padding: 25px;
32
+ margin: 20px 0;
33
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
34
+ }
35
+
36
+ .stat-card {
37
+ background: linear-gradient(135deg, #6B73FF 0%, #000DFF 100%);
38
+ color: white;
39
+ padding: 20px;
40
+ border-radius: 10px;
41
+ margin: 10px;
42
+ text-align: center;
43
+ }
44
+
45
+ .file-upload {
46
+ border: 2px dashed #ccc;
47
+ padding: 20px;
48
+ border-radius: 10px;
49
+ text-align: center;
50
+ margin: 20px 0;
51
+ transition: all 0.3s ease;
52
+ }
53
+
54
+ .file-upload:hover {
55
+ border-color: #2196F3;
56
+ }
57
+
58
+ .action-button {
59
+ background: #2196F3;
60
+ color: white;
61
+ padding: 10px 20px;
62
+ border: none;
63
+ border-radius: 5px;
64
+ cursor: pointer;
65
+ transition: all 0.3s ease;
66
  }
67
+
68
+ .action-button:hover {
69
+ background: #1976D2;
70
+ transform: scale(1.05);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
72
+
73
+ .file-list {
74
+ margin-top: 20px;
75
+ }
76
+
77
+ .file-item {
78
+ display: flex;
79
+ justify-content: space-between;
80
+ align-items: center;
81
+ padding: 15px;
82
+ background: #f5f5f5;
83
+ border-radius: 8px;
84
+ margin: 10px 0;
85
+ }
86
+
87
+ .delete-button {
88
+ background: #ff4444;
89
+ color: white;
90
+ padding: 5px 15px;
91
+ border: none;
92
+ border-radius: 5px;
93
+ cursor: pointer;
94
+ }
95
+
96
+ .delete-button:hover {
97
+ background: #cc0000;
98
+ }
99
+ </style>
100
+ """, unsafe_allow_html=True)
101
+
102
+ # هدر داشبورد
103
+ st.title("🎛️ داشبورد مدیریت")
104
+
105
+ # آمار کلی
106
+ col1, col2, col3 = st.columns(3)
107
+ with col1:
108
+ st.markdown("""
109
+ <div class="stat-card">
110
+ <h2>۱۲۳</h2>
111
+ <p>تعداد فایل‌ها</p>
112
+ </div>
113
+ """, unsafe_allow_html=True)
114
+
115
+ with col2:
116
+ st.markdown("""
117
+ <div class="stat-card">
118
+ <h2>۴۵۶</h2>
119
+ <p>تعداد پرسش‌ها</p>
120
  </div>
121
+ """, unsafe_allow_html=True)
122
+
123
+ with col3:
124
+ st.markdown("""
125
+ <div class="stat-card">
126
+ <h2>۷۸۹</h2>
127
+ <p>پاسخ‌های موفق</p>
128
+ </div>
129
+ """, unsafe_allow_html=True)
130
 
131
+ # بخش آپلود فایل
132
+ st.markdown("""
133
+ <div class="dashboard-container">
134
+ <h3>📤 آپلود فایل جدید</h3>
135
+ <div class="file-upload">
136
+ <p>فایل خود را اینجا رها کنید یا کلیک کنید</p>
137
+ <input type="file" accept=".csv,.json,.txt">
138
+ </div>
139
+ </div>
140
+ """, unsafe_allow_html=True)
141
+
142
+ # لیست فایل‌ها
143
+ st.markdown("""
144
+ <div class="dashboard-container">
145
+ <h3>📁 مدیریت فایل‌ها</h3>
146
+ <div class="file-list">
147
+ <div class="file-item">
148
+ <span>banking_data.csv</span>
149
+ <button class="delete-button">حذف</button>
150
  </div>
151
+ <div class="file-item">
152
+ <span>customer_qa.json</span>
153
+ <button class="delete-button">حذف</button>
 
 
 
 
 
154
  </div>
155
+ <div class="file-item">
156
+ <span>training_data.txt</span>
157
+ <button class="delete-button">حذف</button>
 
 
 
 
 
158
  </div>
 
 
159
  </div>
160
+ </div>
161
+ """, unsafe_allow_html=True)
162
 
163
+ # تنظیمات مدل
164
+ st.markdown("""
165
+ <div class="dashboard-container">
166
+ <h3>⚙️ تنظیمات مدل</h3>
167
+ <div style="margin: 20px 0;">
168
+ <label>دمای مدل:</label>
169
+ <input type="range" min="0" max="100" value="70">
170
+ </div>
171
+ <div style="margin: 20px 0;">
172
+ <label>حداکثر طول پاسخ:</label>
173
+ <input type="number" value="512">
174
+ </div>
175
+ <button class="action-button">ذخیره تنظیمات</button>
176
+ </div>
177
+ """, unsafe_allow_html=True)
178
+
179
+ if __name__ == "__main__":
180
+ st.markdown("""
181
+ <script>
182
+ // اضافه کردن عملکرد به دکمه‌ها
183
+ document.querySelectorAll('.delete-button').forEach(button => {
184
+ button.addEventListener('click', function() {
185
+ if (confirm('آیا از حذف این فایل اطمینان دارید؟')) {
186
+ this.closest('.file-item').remove();
187
+ }
188
+ });
189
+ });
190
+ </script>
191
+ """, unsafe_allow_html=True)
192
+
193
+ # اضافه کردن بخش نمودارها
194
+ st.markdown("""
195
+ <div class="dashboard-container">
196
+ <h3>📊 تحلیل عملکرد مدل</h3>
197
+ </div>
198
+ """, unsafe_allow_html=True)
199
+
200
+ # نمودار نرخ یادگیری
201
+ col1, col2 = st.columns(2)
202
+ with col1:
203
+ # نمودار نرخ یادگیری
204
+ dates = [datetime.now() - timedelta(days=x) for x in range(30)]
205
+ learning_rate = [0.001 * np.exp(-x/10) for x in range(30)]
206
+
207
+ fig_learning = go.Figure()
208
+ fig_learning.add_trace(go.Scatter(
209
+ x=dates,
210
+ y=learning_rate,
211
+ mode='lines+markers',
212
+ name='نرخ یادگیری',
213
+ line=dict(color='#2196F3', width=3)
214
+ ))
215
+ fig_learning.update_layout(
216
+ title='نرخ یادگیری در طول زمان',
217
+ xaxis_title='تاریخ',
218
+ yaxis_title='نرخ یادگیری',
219
+ template='plotly_white',
220
+ dir='rtl'
221
+ )
222
+ st.plotly_chart(fig_learning, use_container_width=True)
223
+
224
+ with col2:
225
+ # نمودار دقت مدل
226
+ accuracy_data = np.linspace(0.7, 0.95, 30)
227
+ fig_accuracy = go.Figure()
228
+ fig_accuracy.add_trace(go.Scatter(
229
+ x=dates,
230
+ y=accuracy_data,
231
+ mode='lines+markers',
232
+ name='دقت مدل',
233
+ line=dict(color='#4CAF50', width=3)
234
+ ))
235
+ fig_accuracy.update_layout(
236
+ title='پیشرفت دقت مدل',
237
+ xaxis_title='تاریخ',
238
+ yaxis_title='دقت',
239
+ template='plotly_white',
240
+ dir='rtl'
241
+ )
242
+ st.plotly_chart(fig_accuracy, use_container_width=True)
243
+
244
+ # نمودار پاسخ‌های صحیح و غلط
245
+ labels = ['پاسخ‌های صحیح', 'پاسخ‌های غلط']
246
+ values = [85, 15]
247
+ fig_pie = go.Figure(data=[go.Pie(
248
+ labels=labels,
249
+ values=values,
250
+ hole=.3,
251
+ marker_colors=['#4CAF50', '#f44336']
252
+ )])
253
+ fig_pie.update_layout(title='نسبت پاسخ‌های صحیح به غلط')
254
+ st.plotly_chart(fig_pie, use_container_width=True)
255
+
256
+ # چت‌بات آموزش سریع
257
+ st.markdown("""
258
+ <div class="dashboard-container">
259
+ <h3>🤖 آموزش سریع با چت‌بات</h3>
260
+ <div class="chat-trainer">
261
+ <input type="text" placeholder="دستور آموزشی خود را وارد کنید..." class="trainer-input">
262
+ <button class="action-button">ارسال دستور</button>
263
  </div>
 
264
  </div>
265
+ """, unsafe_allow_html=True)
266
+
267
+ # دکمه دسترسی به نالج بیس
268
+ st.markdown("""
269
+ <div class="dashboard-container">
270
+ <h3>📚 مدیریت نالج بیس</h3>
271
+ <button class="action-button" onclick="window.open('/filemanager.py')">
272
+ <i class="fas fa-folder-open"></i>
273
+ دسترسی به فایل منیجر
274
+ </button>
275
+ </div>
276
+ """, unsafe_allow_html=True)
277
+
278
+ # اضافه کردن استایل‌های جدید
279
+ st.markdown("""
280
+ <style>
281
+ .chat-trainer {
282
+ display: flex;
283
+ gap: 10px;
284
+ margin: 20px 0;
285
+ }
286
+
287
+ .trainer-input {
288
+ flex: 1;
289
+ padding: 12px;
290
+ border: 2px solid #f0f0f0;
291
+ border-radius: 8px;
292
+ font-size: 14px;
293
+ }
294
+
295
+ .plotly-chart {
296
+ background: white;
297
+ border-radius: 10px;
298
+ padding: 15px;
299
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
300
+ }
301
+ </style>
302
+ """, unsafe_allow_html=True)
303
+ # اضافه کردن نمودار هیت‌مپ برای نمایش ماتریس خطا
304
+ confusion_matrix = np.array([
305
+ [850, 50],
306
+ [30, 70]
307
+ ])
308
+
309
+ fig_heatmap = px.imshow(
310
+ confusion_matrix,
311
+ labels=dict(x="پیش‌بینی", y="مقدار واقعی"),
312
+ x=['مثبت', 'منفی'],
313
+ y=['مثبت', 'منفی'],
314
+ color_continuous_scale="RdBu",
315
+ title="ماتریس خطا"
316
+ )
317
+ fig_heatmap.update_layout(
318
+ template='plotly_white',
319
+ dir='rtl',
320
+ width=600,
321
+ height=500
322
+ )
323
+
324
+ # نمودار روند زمانی با قابلیت فیلتر
325
+ training_metrics = pd.DataFrame({
326
+ 'تاریخ': pd.date_range(start='2023-01-01', periods=100),
327
+ 'دقت': np.random.normal(0.85, 0.05, 100).cumsum()/100,
328
+ 'recall': np.random.normal(0.80, 0.05, 100).cumsum()/100,
329
+ 'f1_score': np.random.normal(0.82, 0.05, 100).cumsum()/100
330
+ })
331
+
332
+ fig_metrics = px.line(
333
+ training_metrics,
334
+ x='تاریخ',
335
+ y=['دقت', 'recall', 'f1_score'],
336
+ title='روند معیارهای ارزیابی',
337
+ labels={'value': 'مقدار', 'variable': 'معیار'},
338
+ template='plotly_white'
339
+ )
340
+ fig_metrics.update_layout(
341
+ showlegend=True,
342
+ legend_title_text='معیارها',
343
+ hovermode='x unified',
344
+ updatemenus=[
345
+ dict(
346
+ buttons=list([
347
+ dict(
348
+ args=[{"visible": [True, True, True]}],
349
+ label="همه",
350
+ method="restyle"
351
+ ),
352
+ dict(
353
+ args=[{"visible": [True, False, False]}],
354
+ label="دقت",
355
+ method="restyle"
356
+ ),
357
+ dict(
358
+ args=[{"visible": [False, True, False]}],
359
+ label="Recall",
360
+ method="restyle"
361
+ ),
362
+ dict(
363
+ args=[{"visible": [False, False, True]}],
364
+ label="F1 Score",
365
+ method="restyle"
366
+ )
367
+ ]),
368
+ direction="down",
369
+ showactive=True,
370
+ x=0.1,
371
+ y=1.1
372
+ )
373
+ ]
374
+ )
375
+
376
+ # نمودار توزیع خطا
377
+ errors = np.random.normal(0, 1, 1000)
378
+ fig_dist = px.histogram(
379
+ errors,
380
+ nbins=50,
381
+ title='توزیع خطای پیش‌بینی',
382
+ labels={'value': 'خطا', 'count': 'تعداد'},
383
+ template='plotly_white'
384
+ )
385
+ fig_dist.update_layout(
386
+ bargap=0.1,
387
+ showlegend=False
388
+ )
389
+
390
+ # اضافه کردن کنترل‌های تعاملی
391
+ st.sidebar.markdown("## تنظیمات نمودارها")
392
+ time_range = st.sidebar.slider(
393
+ "بازه زمانی (روز)",
394
+ min_value=7,
395
+ max_value=100,
396
+ value=30
397
+ )
398
+
399
+ metric_threshold = st.sidebar.number_input(
400
+ "آستانه دقت",
401
+ min_value=0.0,
402
+ max_value=1.0,
403
+ value=0.8,
404
+ step=0.05
405
+ )
406
 
407
+ # نمایش نمودارها با چینش جدید
408
+ col1, col2 = st.columns(2)
409
+ with col1:
410
+ st.plotly_chart(fig_metrics, use_container_width=True)
411
+ st.plotly_chart(fig_heatmap, use_container_width=True)
412
+ with col2:
413
+ st.plotly_chart(fig_dist, use_container_width=True)
414
+ st.plotly_chart(fig_pie, use_container_width=True)
app.py CHANGED
@@ -1,239 +1,77 @@
1
- import streamlit as st
2
- import time
3
- import random
4
- from datetime import datetime
5
-
6
- # تنظیمات صفحه
7
- st.set_page_config(page_title="چت‌بات هوشمند", page_icon="🤖", layout="wide")
8
-
9
- # CSS سفارشی برای بهبود ظاهر و انیمیشن‌ها
10
- st.markdown("""
11
- <style>
12
- @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;500;700&display=swap');
13
-
14
- body {
15
- font-family: 'Vazirmatn', sans-serif;
16
- background-color: #f8fafc;
17
- }
18
-
19
- .chat-container {
20
- max-width: 800px;
21
- margin: auto;
22
- border-radius: 15px;
23
- overflow: hidden;
24
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
25
- }
26
-
27
- .header {
28
- background: linear-gradient(45deg, #4a90e2, #50e3c2);
29
- color: white;
30
- padding: 20px;
31
- text-align: center;
32
- position: relative;
33
- }
34
-
35
- .header .status {
36
- position: absolute;
37
- top: 20px;
38
- right: 20px;
39
- color: #10b981;
40
- font-weight: bold;
41
- }
42
-
43
- .chat-messages {
44
- background: #ffffff;
45
- padding: 20px;
46
- height: 500px;
47
- overflow-y: auto;
48
- border-top: 1px solid #ddd;
49
- border-bottom: 1px solid #ddd;
50
- }
51
-
52
- .message {
53
- margin-bottom: 15px;
54
- padding: 10px 15px;
55
- border-radius: 12px;
56
- max-width: 75%;
57
- animation: fadeIn 0.3s;
58
- position: relative;
59
- }
60
-
61
- @keyframes fadeIn {
62
- from { opacity: 0; transform: translateY(20px); }
63
- to { opacity: 1; transform: translateY(0); }
64
- }
65
-
66
- .message.user {
67
- background: #e0f7fa;
68
- align-self: flex-end;
69
- }
70
-
71
- .message.bot {
72
- background: #f1f1f1;
73
- align-self: flex-start;
74
- }
75
-
76
- .timestamp {
77
- font-size: 0.8em;
78
- color: #888;
79
- margin-top: 5px;
80
- text-align: right;
81
- }
82
-
83
- .quick-replies {
84
- display: flex;
85
- flex-wrap: wrap;
86
- gap: 10px;
87
- margin-top: 15px;
88
- }
89
-
90
- .quick-reply {
91
- background: #4a90e2;
92
- color: white;
93
- padding: 8px 16px;
94
- border-radius: 15px;
95
- cursor: pointer;
96
- font-weight: 500;
97
- transition: background 0.3s ease;
98
- }
99
-
100
- .quick-reply:hover {
101
- background: #357ab7;
102
- }
103
-
104
- .chat-input {
105
- display: flex;
106
- gap: 10px;
107
- align-items: center;
108
- padding: 20px;
109
- background: #f8fafc;
110
- }
111
-
112
- .chat-input input[type="text"] {
113
- flex-grow: 1;
114
- padding: 10px;
115
- border-radius: 5px;
116
- border: 1px solid #ddd;
117
- font-size: 1rem;
118
- }
119
-
120
- .chat-input button {
121
- background: #4a90e2;
122
- color: white;
123
- padding: 10px 20px;
124
- border: none;
125
- border-radius: 5px;
126
- cursor: pointer;
127
- transition: background 0.3s;
128
- }
129
-
130
- .chat-input button:hover {
131
- background: #357ab7;
132
- }
133
-
134
- .admin-panel {
135
- background: #ffffff;
136
- border-radius: 10px;
137
- padding: 20px;
138
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
139
- margin-bottom: 20px;
140
- }
141
-
142
- .statistics {
143
- padding: 10px 0;
144
- border-bottom: 1px solid #ddd;
145
- }
146
-
147
- </style>
148
- """, unsafe_allow_html=True)
149
-
150
- # داده‌های اولیه
151
- if 'conversation_history' not in st.session_state:
152
- st.session_state.conversation_history = []
153
-
154
- if 'is_typing' not in st.session_state:
155
- st.session_state.is_typing = False
156
-
157
- quick_replies = ["راهنمای استفاده", "تماس با پشتیبانی", "گزارش مشکل", "بخشنامه‌های جدید"]
158
-
159
- # توابع چت‌بات
160
- def get_bot_response(user_message):
161
- time.sleep(1) # شبیه‌سازی تایپ کردن
162
- return random.choice(["سلام! چطور می‌تونم کمک کنم؟", "لطفاً سوال خود را مطرح کنید.", "در خدمت شما هستم."])
163
-
164
- def add_message(sender, message):
165
- st.session_state.conversation_history.append({
166
- 'sender': sender,
167
- 'message': message,
168
- 'timestamp': datetime.now().strftime("%H:%M")
169
- })
170
-
171
- # هدر
172
- st.markdown("""
173
- <div class="header">
174
- <h2>چت‌بات هوشمند</h2>
175
- <div class="status">آنلاین</div>
176
- </div>
177
- """, unsafe_allow_html=True)
178
-
179
- # نمایش پیام‌ها
180
- st.markdown("<div class='chat-container'><div class='chat-messages'>", unsafe_allow_html=True)
181
- for message in st.session_state.conversation_history:
182
- sender_class = "user" if message['sender'] == "user" else "bot"
183
- st.markdown(f"""
184
- <div class='message {sender_class}'>
185
- <div>{message['message']}</div>
186
- <div class='timestamp'>{message['timestamp']}</div>
187
- </div>
188
- """, unsafe_allow_html=True)
189
- st.markdown("</div></div>", unsafe_allow_html=True)
190
-
191
- # پاسخ‌های سریع
192
- st.markdown("<div class='quick-replies'>", unsafe_allow_html=True)
193
- for reply in quick_replies:
194
- if st.button(reply):
195
- add_message("user", reply)
196
- bot_response = get_bot_response(reply)
197
- add_message("bot", bot_response)
198
- st.experimental_rerun()
199
- st.markdown("</div>", unsafe_allow_html=True)
200
-
201
- # ورودی کاربر
202
- st.markdown("<div class='chat-input'>", unsafe_allow_html=True)
203
- user_message = st.text_input("", placeholder="پیام خود را وارد کنید...", label_visibility="collapsed")
204
- send_button = st.button("ارسال")
205
-
206
- if send_button and user_message:
207
- add_message("user", user_message)
208
- st.session_state.is_typing = True
209
- bot_response = get_bot_response(user_message)
210
- add_message("bot", bot_response)
211
- st.session_state.is_typing = False
212
- st.experimental_rerun()
213
-
214
- st.markdown("</div>", unsafe_allow_html=True)
215
-
216
- # پنل مدیریت در سایدبار
217
- with st.sidebar:
218
- st.markdown("<div class='admin-panel'><h3>پنل مدیریت</h3>", unsafe_allow_html=True)
219
-
220
- # نمایش آمار
221
- total_messages = len(st.session_state.conversation_history)
222
- user_messages = sum(1 for msg in st.session_state.conversation_history if msg['sender'] == 'user')
223
- bot_messages = total_messages - user_messages
224
-
225
- st.markdown(f"""
226
- <div class="statistics">پیام‌های کل: {total_messages}</div>
227
- <div class="statistics">پیام‌های کاربر: {user_messages}</div>
228
- <div class="statistics">پیام‌های ربات: {bot_messages}</div>
229
- """, unsafe_allow_html=True)
230
-
231
- # دکمه پاک کردن تاریخچه
232
- if st.button("پاک کردن تاریخچه"):
233
- st.session_state.conversation_history = []
234
- st.experimental_rerun()
235
-
236
- # تنظیمات ظاهری
237
- st.markdown("### تنظیمات ظاهری")
238
- font_size = st.slider("اندازه فونت", 12, 20, 14)
239
- st.markdown(f"<style>.message {{ font-size: {font_size}px; }}</style>", unsafe_allow_html=True)
 
1
+ import streamlit as st
2
+ from admin_dashboard import AdminDashboard
3
+ from banking_assistant import BankingAssistant
4
+ from banking_model import BankingModelTrainer
5
+ from ml_banking_model import MLBankingEngine
6
+
7
+ class BankingSystem:
8
+ def __init__(self):
9
+ self.ml_engine = MLBankingEngine()
10
+ self.model_trainer = BankingModelTrainer()
11
+ self.assistant = BankingAssistant()
12
+ self.admin = AdminDashboard()
13
+ self.setup_page_config()
14
+ self.initialize_session_state()
15
+
16
+ def setup_page_config(self):
17
+ st.set_page_config(
18
+ page_title="سیستم بانکداری هوشمند",
19
+ page_icon="🏦",
20
+ layout="wide",
21
+ initial_sidebar_state="expanded"
22
+ )
23
+
24
+ def initialize_session_state(self):
25
+ if 'theme' not in st.session_state:
26
+ st.session_state.theme = 'light'
27
+ if 'user_role' not in st.session_state:
28
+ st.session_state.user_role = 'user'
29
+ if 'authenticated' not in st.session_state:
30
+ st.session_state.authenticated = False
31
+
32
+ def render_login(self):
33
+ st.markdown("""
34
+ <div style='text-align: center; padding: 50px;'>
35
+ <h1>🏦 سیستم بانکداری هوشمند</h1>
36
+ <p>لطفا وارد شوید</p>
37
+ </div>
38
+ """, unsafe_allow_html=True)
39
+
40
+ col1, col2, col3 = st.columns([1,2,1])
41
+ with col2:
42
+ username = st.text_input("نام کاربری")
43
+ password = st.text_input("رمز عبور", type="password")
44
+
45
+ if st.button("ورود"):
46
+ if username == "admin" and password == "admin":
47
+ st.session_state.user_role = 'admin'
48
+ st.session_state.authenticated = True
49
+ st.experimental_rerun()
50
+ elif username and password:
51
+ st.session_state.user_role = 'user'
52
+ st.session_state.authenticated = True
53
+ st.experimental_rerun()
54
+
55
+ def render_header(self):
56
+ st.markdown("""
57
+ <div style='display: flex; justify-content: space-between; align-items: center; padding: 1rem; background: white; box-shadow: 0 2px 4px rgba(0,0,0,0.1);'>
58
+ <h2>🏦 سیستم بانکداری هوشمند</h2>
59
+ <div>
60
+ <button onclick='logout()'>خروج</button>
61
+ </div>
62
+ </div>
63
+ """, unsafe_allow_html=True)
64
+
65
+ def main(self):
66
+ if not st.session_state.authenticated:
67
+ self.render_login()
68
+ else:
69
+ self.render_header()
70
+ if st.session_state.user_role == 'admin':
71
+ self.admin.render_dashboard()
72
+ else:
73
+ self.assistant.render_chat_interface()
74
+
75
+ if __name__ == "__main__":
76
+ system = BankingSystem()
77
+ system.main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
banking_assistant.py ADDED
@@ -0,0 +1,469 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import sqlite3
3
+ import random
4
+ from datetime import datetime
5
+ import pandas as pd
6
+ import plotly.express as px
7
+ from pathlib import Path
8
+
9
+ # تنظیمات اولیه دیتابیس
10
+ class DatabaseManager:
11
+ def __init__(self):
12
+ self.conn = sqlite3.connect('banking_assistant.db')
13
+ self.create_tables()
14
+
15
+ def create_tables(self):
16
+ c = self.conn.cursor()
17
+ # جدول مکالمات
18
+ c.execute('''
19
+ CREATE TABLE IF NOT EXISTS conversations (
20
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
21
+ user_message TEXT,
22
+ assistant_response TEXT,
23
+ timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
24
+ feedback INTEGER DEFAULT 0
25
+ )
26
+ ''')
27
+
28
+ # جدول پایگاه دانش
29
+ c.execute('''
30
+ CREATE TABLE IF NOT EXISTS knowledge_base (
31
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
32
+ question TEXT,
33
+ answer TEXT,
34
+ category TEXT,
35
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
36
+ )
37
+ ''')
38
+
39
+ # جدول تنظیمات
40
+ c.execute('''
41
+ CREATE TABLE IF NOT EXISTS settings (
42
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
43
+ theme TEXT DEFAULT 'light',
44
+ language TEXT DEFAULT 'fa',
45
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
46
+ )
47
+ ''')
48
+ self.conn.commit()
49
+
50
+ # تنظیمات استایل و تم
51
+ THEMES = {
52
+ 'light': {
53
+ 'bg_color': '#e0e5ec',
54
+ 'text_color': '#333',
55
+ 'shadow': '9px 9px 16px #b8b9be, -9px -9px 16px #ffffff'
56
+ },
57
+ 'dark': {
58
+ 'bg_color': '#2d3436',
59
+ 'text_color': '#fff',
60
+ 'shadow': '9px 9px 16px #1a1d1e, -9px -9px 16px #404b4d'
61
+ },
62
+ 'blue': {
63
+ 'bg_color': '#e3f2fd',
64
+ 'text_color': '#1976d2',
65
+ 'shadow': '9px 9px 16px #c1cdd4, -9px -9px 16px #ffffff'
66
+ }
67
+ }
68
+ def load_custom_styles(theme='light'):
69
+ return f"""
70
+ <style>
71
+ @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;200;300;400;500;600;700;800;900&display=swap');
72
+
73
+ /* تنظیمات پایه */
74
+ * {{
75
+ font-family: 'Vazirmatn', sans-serif;
76
+ direction: rtl;
77
+ transition: all 0.3s ease;
78
+ }}
79
+
80
+ body {{
81
+ background: {THEMES[theme]['bg_color']};
82
+ color: {THEMES[theme]['text_color']};
83
+ }}
84
+
85
+ /* هدر اصلی */
86
+ .main-header {{
87
+ background: {THEMES[theme]['bg_color']};
88
+ padding: 2rem;
89
+ border-radius: 25px;
90
+ box-shadow: {THEMES[theme]['shadow']};
91
+ margin-bottom: 2rem;
92
+ text-align: center;
93
+ position: relative;
94
+ overflow: hidden;
95
+ }}
96
+
97
+ .main-header::before {{
98
+ content: '';
99
+ position: absolute;
100
+ top: -50%;
101
+ left: -50%;
102
+ width: 200%;
103
+ height: 200%;
104
+ background: linear-gradient(
105
+ 45deg,
106
+ transparent 0%,
107
+ rgba(255, 255, 255, 0.1) 50%,
108
+ transparent 100%
109
+ );
110
+ animation: shine 3s infinite;
111
+ }}
112
+
113
+ /* باکس چت */
114
+ .chat-container {{
115
+ background: {THEMES[theme]['bg_color']};
116
+ border-radius: 20px;
117
+ padding: 2rem;
118
+ margin: 1rem 0;
119
+ box-shadow: {THEMES[theme]['shadow']};
120
+ max-height: 70vh;
121
+ overflow-y: auto;
122
+ scroll-behavior: smooth;
123
+ }}
124
+
125
+ /* پیام‌ها */
126
+ .message {{
127
+ margin: 1rem 0;
128
+ padding: 1rem;
129
+ border-radius: 15px;
130
+ position: relative;
131
+ animation: messageSlide 0.3s ease-out;
132
+ }}
133
+
134
+ .message.user {{
135
+ background: linear-gradient(135deg, #0073e6 0%, #0056b3 100%);
136
+ color: white;
137
+ margin-left: 2rem;
138
+ box-shadow: 0 4px 15px rgba(0, 115, 230, 0.2);
139
+ }}
140
+
141
+ .message.assistant {{
142
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
143
+ color: #343a40;
144
+ margin-right: 2rem;
145
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
146
+ }}
147
+
148
+ /* ورودی چت */
149
+ .chat-input-container {{
150
+ background: {THEMES[theme]['bg_color']};
151
+ padding: 1.5rem;
152
+ border-radius: 15px;
153
+ box-shadow: {THEMES[theme]['shadow']};
154
+ margin-top: 1rem;
155
+ display: flex;
156
+ align-items: center;
157
+ gap: 1rem;
158
+ }}
159
+
160
+ .chat-input {{
161
+ flex: 1;
162
+ padding: 1rem;
163
+ border: none;
164
+ border-radius: 10px;
165
+ background: rgba(255, 255, 255, 0.1);
166
+ backdrop-filter: blur(10px);
167
+ color: {THEMES[theme]['text_color']};
168
+ font-size: 1rem;
169
+ transition: all 0.3s ease;
170
+ }}
171
+
172
+ .chat-input:focus {{
173
+ outline: none;
174
+ box-shadow: 0 0 0 3px rgba(0, 115, 230, 0.3);
175
+ }}
176
+
177
+ /* دکمه‌ها */
178
+ .button {{
179
+ padding: 0.8rem 1.5rem;
180
+ border: none;
181
+ border-radius: 10px;
182
+ background: linear-gradient(135deg, #0073e6 0%, #0056b3 100%);
183
+ color: white;
184
+ cursor: pointer;
185
+ transition: all 0.3s ease;
186
+ font-weight: 500;
187
+ display: flex;
188
+ align-items: center;
189
+ gap: 0.5rem;
190
+ }}
191
+
192
+ .button:hover {{
193
+ transform: translateY(-2px);
194
+ box-shadow: 0 5px 15px rgba(0, 115, 230, 0.3);
195
+ }}
196
+
197
+ .button:active {{
198
+ transform: translateY(0);
199
+ }}
200
+
201
+ /* انیمیشن‌ها */
202
+ @keyframes messageSlide {{
203
+ from {{
204
+ opacity: 0;
205
+ transform: translateY(20px);
206
+ }}
207
+ to {{
208
+ opacity: 1;
209
+ transform: translateY(0);
210
+ }}
211
+ }}
212
+
213
+ @keyframes shine {{
214
+ 0% {{
215
+ transform: translateX(-100%) rotate(45deg);
216
+ }}
217
+ 100% {{
218
+ transform: translateX(100%) rotate(45deg);
219
+ }}
220
+ }}
221
+
222
+ /* اسکرولبار سفارشی */
223
+ ::-webkit-scrollbar {{
224
+ width: 8px;
225
+ }}
226
+
227
+ ::-webkit-scrollbar-track {{
228
+ background: {THEMES[theme]['bg_color']};
229
+ }}
230
+
231
+ ::-webkit-scrollbar-thumb {{
232
+ background: #0073e6;
233
+ border-radius: 4px;
234
+ }}
235
+
236
+ ::-webkit-scrollbar-thumb:hover {{
237
+ background: #0056b3;
238
+ }}
239
+ </style>
240
+ """
241
+ class BankingAssistant:
242
+ def __init__(self):
243
+ self.db = DatabaseManager()
244
+ self.model = BankingModel() # اضافه کردن مدل
245
+ if 'theme' not in st.session_state:
246
+ st.session_state.theme = 'light'
247
+ if 'messages' not in st.session_state:
248
+ st.session_state.messages = []
249
+ self.add_message('assistant', """
250
+ 👋 سلام! من دستیار هوشمند بانکی شما هستم.
251
+
252
+ می‌توانم در موارد زیر به شما کمک کنم:
253
+ 📊 مشاهده وضعیت حساب
254
+ 💳 انتقال وجه
255
+ 📝 درخواست تسهیلات
256
+ 🏦 اطلاعات شعب
257
+
258
+ چطور می‌توانم کمکتان کنم؟
259
+ """)
260
+
261
+ def add_message(self, role, content):
262
+ timestamp = datetime.now().strftime("%H:%M")
263
+ st.session_state.messages.append({
264
+ 'role': role,
265
+ 'content': content,
266
+ 'timestamp': timestamp
267
+ })
268
+
269
+ # ذخیره در دیتابیس
270
+ if role == 'user':
271
+ self.db.conn.execute(
272
+ 'INSERT INTO conversations (user_message, timestamp) VALUES (?, ?)',
273
+ (content, timestamp)
274
+ )
275
+ else:
276
+ self.db.conn.execute(
277
+ 'UPDATE conversations SET assistant_response = ? WHERE id = last_insert_rowid()',
278
+ (content,)
279
+ )
280
+ self.db.conn.commit()
281
+
282
+ def render_chat_interface(self):
283
+ st.markdown(load_custom_styles(st.session_state.theme), unsafe_allow_html=True)
284
+
285
+ # هدر اصلی
286
+ st.markdown("""
287
+ <div class="main-header">
288
+ <h1>🏦 دستیار هوشمند بانکی</h1>
289
+ <p>پاسخگوی 24 ساعته شما</p>
290
+ </div>
291
+ """, unsafe_allow_html=True)
292
+
293
+ # باکس چت
294
+ st.markdown('<div class="chat-container">', unsafe_allow_html=True)
295
+
296
+ for msg in st.session_state.messages:
297
+ class_name = "user" if msg['role'] == 'user' else "assistant"
298
+ st.markdown(f"""
299
+ <div class="message {class_name}">
300
+ {msg['content']}
301
+ <small style="position: absolute; bottom: 5px; {'right' if class_name == 'user' else 'left'}: 10px; opacity: 0.7;">
302
+ {msg['timestamp']}
303
+ </small>
304
+ </div>
305
+ """, unsafe_allow_html=True)
306
+
307
+ st.markdown('</div>', unsafe_allow_html=True)
308
+
309
+ # باکس ورودی
310
+ st.markdown("""
311
+ <div class="chat-input-container">
312
+ <button class="action-button">🎤</button>
313
+ <input type="text" class="chat-input" placeholder="پیام خود را بنویسید...">
314
+ <button class="button">
315
+ <span>ارسال</span>
316
+ <span>➤</span>
317
+ </button>
318
+ </div>
319
+ """, unsafe_allow_html=True)
320
+
321
+
322
+ class AdminDashboard:
323
+ def __init__(self, db_manager):
324
+ self.db = db_manager
325
+
326
+ def render_dashboard(self):
327
+ st.markdown("""
328
+ <div class="admin-header">
329
+ <h2>🔐 پنل مدیریت</h2>
330
+ </div>
331
+ """, unsafe_allow_html=True)
332
+
333
+ # نمودارهای تحلیلی
334
+ col1, col2 = st.columns(2)
335
+
336
+ with col1:
337
+ self.render_conversation_stats()
338
+
339
+ with col2:
340
+ self.render_feedback_chart()
341
+
342
+ # مدیریت پایگاه دانش
343
+ st.markdown("""
344
+ <div class="admin-section">
345
+ <h3>📚 مدیریت پایگاه دانش</h3>
346
+ </div>
347
+ """, unsafe_allow_html=True)
348
+
349
+ # افزودن دانش جدید
350
+ with st.expander("➕ افزودن مورد جدید"):
351
+ category = st.selectbox(
352
+ "دسته‌بندی",
353
+ ["عمومی", "حساب‌ها", "تسهیلات", "کارت", "شعب"]
354
+ )
355
+ question = st.text_area("سوال")
356
+ answer = st.text_area("پاسخ")
357
+
358
+ if st.button("ذخیره"):
359
+ self.db.conn.execute(
360
+ 'INSERT INTO knowledge_base (question, answer, category) VALUES (?, ?, ?)',
361
+ (question, answer, category)
362
+ )
363
+ self.db.conn.commit()
364
+ st.success("✅ با موفقیت ذخیره شد")
365
+
366
+ def render_conversation_stats(self):
367
+ # دریافت آمار مکالمات
368
+ df = pd.read_sql_query("""
369
+ SELECT
370
+ date(timestamp) as date,
371
+ COUNT(*) as count
372
+ FROM conversations
373
+ GROUP BY date(timestamp)
374
+ ORDER BY date DESC
375
+ LIMIT 7
376
+ """, self.db.conn)
377
+
378
+ fig = px.line(
379
+ df,
380
+ x='date',
381
+ y='count',
382
+ title='آمار مکالمات 7 روز اخیر',
383
+ labels={'count': 'تعداد مکالمات', 'date': 'تاریخ'}
384
+ )
385
+
386
+ fig.update_layout(
387
+ font_family="Vazirmatn",
388
+ plot_bgcolor='rgba(0,0,0,0)',
389
+ paper_bgcolor='rgba(0,0,0,0)',
390
+ )
391
+
392
+ st.plotly_chart(fig)
393
+
394
+ def render_feedback_chart(self):
395
+ # نمودار بازخوردها
396
+ df = pd.read_sql_query("""
397
+ SELECT
398
+ feedback,
399
+ COUNT(*) as count
400
+ FROM conversations
401
+ WHERE feedback != 0
402
+ GROUP BY feedback
403
+ """, self.db.conn)
404
+
405
+ fig = px.pie(
406
+ df,
407
+ values='count',
408
+ names='feedback',
409
+ title='نمودار بازخوردها',
410
+ color_discrete_sequence=px.colors.sequential.Blues
411
+ )
412
+
413
+ fig.update_layout(
414
+ font_family="Vazirmatn",
415
+ plot_bgcolor='rgba(0,0,0,0)',
416
+ paper_bgcolor='rgba(0,0,0,0)',
417
+ )
418
+
419
+ st.plotly_chart(fig)
420
+
421
+ def main():
422
+ st.set_page_config(
423
+ page_title="دستیار هوشمند بانکی",
424
+ page_icon="🏦",
425
+ layout="wide",
426
+ initial_sidebar_state="expanded"
427
+ )
428
+
429
+ assistant = BankingAssistant()
430
+
431
+ # منوی کناری
432
+ with st.sidebar:
433
+ st.markdown("### ⚙️ تنظیمات")
434
+ theme = st.selectbox(
435
+ "انتخاب تم",
436
+ options=['light', 'dark', 'blue'],
437
+ index=['light', 'dark', 'blue'].index(st.session_state.theme)
438
+ )
439
+
440
+ if theme != st.session_state.theme:
441
+ st.session_state.theme = theme
442
+ st.experimental_rerun()
443
+
444
+ if st.button("🔐 ورود مدیر"):
445
+ st.session_state.show_login = True
446
+
447
+ # نمایش فرم لاگین
448
+ if st.session_state.get('show_login', False):
449
+ with st.form("login_form"):
450
+ username = st.text_input("نام کاربری")
451
+ password = st.text_input("رمز عبور", type="password")
452
+
453
+ if st.form_submit_button("ورود"):
454
+ if username == "admin" and password == "admin": # در حالت واقعی باید امن‌تر باشد
455
+ st.session_state.admin_logged_in = True
456
+ st.session_state.show_login = False
457
+ st.experimental_rerun()
458
+ else:
459
+ st.error("نام کاربری یا رمز عبور اشتباه است")
460
+
461
+ # نمایش داشبورد مدیر
462
+ if st.session_state.get('admin_logged_in', False):
463
+ admin = AdminDashboard(assistant.db)
464
+ admin.render_dashboard()
465
+ else:
466
+ assistant.render_chat_interface()
467
+
468
+ if __name__ == "__main__":
469
+ main()
banking_model.py ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import torch
3
+ from transformers import (
4
+ AutoModelForCausalLM,
5
+ AutoTokenizer,
6
+ TrainingArguments,
7
+ Trainer,
8
+ DataCollatorForLanguageModeling
9
+ )
10
+ from datasets import Dataset
11
+ import json
12
+ from pathlib import Path
13
+
14
+ class BankingModelTrainer:
15
+ def __init__(
16
+ self,
17
+ base_model_name="meta-llama/Llama-2-13b-chat-hf",
18
+ output_dir="./fine_tuned_model",
19
+ max_length=512
20
+ ):
21
+ self.base_model_name = base_model_name
22
+ self.output_dir = Path(output_dir)
23
+ self.max_length = max_length
24
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
25
+
26
+ # تنظیمات مدل Llama-2
27
+ model_config = {
28
+ "device_map": "auto",
29
+ "torch_dtype": torch.bfloat16,
30
+ "low_cpu_mem_usage": True,
31
+ "max_memory": {0: "10GB"},
32
+ "load_in_8bit": True
33
+ }
34
+
35
+ # تنظیمات اولیه مدل و توکنایزر
36
+ self.tokenizer = AutoTokenizer.from_pretrained(base_model_name)
37
+ self.model = AutoModelForCausalLM.from_pretrained(
38
+ base_model_name,
39
+ **model_config
40
+ )
41
+
42
+ def prepare_data(self, data_path):
43
+ # خواندن دیتا از فایل
44
+ if data_path.endswith('.csv'):
45
+ df = pd.read_csv(data_path)
46
+ elif data_path.endswith('.json'):
47
+ with open(data_path, 'r', encoding='utf-8') as f:
48
+ data = json.load(f)
49
+ df = pd.DataFrame(data)
50
+ else:
51
+ raise ValueError("فرمت فایل باید CSV یا JSON باشد")
52
+
53
+ # پردازش و آماده‌سازی دیتا
54
+ def prepare_examples(examples):
55
+ conversations = []
56
+ for q, a in zip(examples['question'], examples['answer']):
57
+ # فرمت Llama-2 برای مکالمه
58
+ conv = f"[INST] {q} [/INST] {a}"
59
+ conversations.append(conv)
60
+
61
+ # توکنایز کردن با تنظیمات Llama-2
62
+ encodings = self.tokenizer(
63
+ conversations,
64
+ truncation=True,
65
+ padding=True,
66
+ max_length=self.max_length,
67
+ return_tensors="pt"
68
+ )
69
+
70
+ return encodings
71
+
72
+ dataset = Dataset.from_pandas(df)
73
+ tokenized_dataset = dataset.map(
74
+ prepare_examples,
75
+ batched=True,
76
+ remove_columns=dataset.column_names
77
+ )
78
+
79
+ return tokenized_dataset
80
+
81
+ def train(self, dataset, epochs=3, batch_size=4):
82
+ training_args = TrainingArguments(
83
+ output_dir=str(self.output_dir),
84
+ num_train_epochs=epochs,
85
+ per_device_train_batch_size=batch_size,
86
+ gradient_accumulation_steps=4,
87
+ save_steps=500,
88
+ logging_steps=100,
89
+ learning_rate=2e-5, # کاهش نرخ یادگیری برای Llama-2
90
+ warmup_steps=100,
91
+ fp16=True, # فعال کردن fp16 برای Llama-2
92
+ save_total_limit=2,
93
+ logging_dir=str(self.output_dir / "logs"),
94
+ gradient_checkpointing=True # فعال کردن gradient checkpointing
95
+ )
96
+
97
+ data_collator = DataCollatorForLanguageModeling(
98
+ tokenizer=self.tokenizer,
99
+ mlm=False
100
+ )
101
+
102
+ trainer = Trainer(
103
+ model=self.model,
104
+ args=training_args,
105
+ train_dataset=dataset,
106
+ data_collator=data_collator
107
+ )
108
+
109
+ trainer.train()
110
+
111
+ self.model.save_pretrained(self.output_dir)
112
+ self.tokenizer.save_pretrained(self.output_dir)
113
+
114
+ def generate_response(self, prompt):
115
+ # فرمت Llama-2 برای پرامپت
116
+ formatted_prompt = f"[INST] {prompt} [/INST]"
117
+ inputs = self.tokenizer.encode(
118
+ formatted_prompt,
119
+ return_tensors="pt"
120
+ ).to(self.device)
121
+
122
+ outputs = self.model.generate(
123
+ inputs,
124
+ max_length=self.max_length,
125
+ num_return_sequences=1,
126
+ temperature=0.7,
127
+ top_p=0.9,
128
+ do_sample=True,
129
+ pad_token_id=self.tokenizer.eos_token_id,
130
+ repetition_penalty=1.2 # اضافه کردن جریمه تکرار
131
+ )
132
+
133
+ response = self.tokenizer.decode(
134
+ outputs[0],
135
+ skip_special_tokens=True
136
+ )
137
+ # حذف پرامپت از پاسخ
138
+ response = response.replace(formatted_prompt, "").strip()
139
+ return response
140
+
141
+ if __name__ == "__main__":
142
+ trainer = BankingModelTrainer()
143
+ dataset = trainer.prepare_data("banking_qa.json")
144
+ trainer.train(dataset)
145
+ response = trainer.generate_response("شرایط وام مسکن چیست؟")
146
+ print(response)
filemanager.py ADDED
@@ -0,0 +1,394 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from pathlib import Path
3
+ from datetime import datetime
4
+ import zipfile
5
+ from PIL import Image
6
+ import time
7
+ import humanize
8
+
9
+ # تنظیمات صفحه
10
+ st.set_page_config(
11
+ page_title="سیستم مدیریت فایل",
12
+ page_icon="💼",
13
+ layout="wide",
14
+ initial_sidebar_state="expanded"
15
+ )
16
+
17
+ # استایل‌های سفارشی با تم چت‌بات
18
+ CUSTOM_CSS = """
19
+ <style>
20
+ /* فونت و تنظیمات پایه */
21
+ @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
22
+
23
+ * {
24
+ font-family: 'Vazirmatn', sans-serif;
25
+ direction: rtl;
26
+ }
27
+
28
+ /* کانتینر اصلی */
29
+ .main-container {
30
+ max-width: 1200px;
31
+ margin: 0 auto;
32
+ padding: 2rem;
33
+ background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
34
+ border-radius: 20px;
35
+ box-shadow: 0 8px 32px rgba(31, 38, 135, 0.15);
36
+ }
37
+
38
+ /* کارت فایل */
39
+ .file-card {
40
+ background: white;
41
+ border-radius: 15px;
42
+ padding: 1.5rem;
43
+ margin: 1rem 0;
44
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
45
+ transition: all 0.3s ease;
46
+ animation: slideIn 0.3s ease-out;
47
+ }
48
+
49
+ .file-card:hover {
50
+ transform: translateY(-5px);
51
+ box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
52
+ }
53
+
54
+ /* دکمه‌های عملیات */
55
+ .action-button {
56
+ background: #2196F3;
57
+ color: white;
58
+ border: none;
59
+ border-radius: 10px;
60
+ padding: 0.8rem 1.2rem;
61
+ cursor: pointer;
62
+ transition: all 0.3s ease;
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 0.5rem;
66
+ }
67
+
68
+ .action-button:hover {
69
+ background: #1976D2;
70
+ transform: scale(1.05);
71
+ }
72
+
73
+ /* ناحیه آپلود */
74
+ .upload-area {
75
+ border: 2px dashed #2196F3;
76
+ border-radius: 15px;
77
+ padding: 2rem;
78
+ text-align: center;
79
+ background: rgba(255, 255, 255, 0.9);
80
+ cursor: pointer;
81
+ transition: all 0.3s ease;
82
+ }
83
+
84
+ .upload-area:hover {
85
+ border-color: #1976D2;
86
+ background: rgba(255, 255, 255, 1);
87
+ }
88
+
89
+ /* نوار پیشرفت */
90
+ .progress-bar {
91
+ height: 4px;
92
+ background: #e0e0e0;
93
+ border-radius: 2px;
94
+ overflow: hidden;
95
+ margin: 1rem 0;
96
+ }
97
+
98
+ .progress-fill {
99
+ height: 100%;
100
+ background: #2196F3;
101
+ width: 0%;
102
+ animation: fillProgress 2s ease-out forwards;
103
+ }
104
+
105
+ /* انیمیشن‌ها */
106
+ @keyframes slideIn {
107
+ from {
108
+ opacity: 0;
109
+ transform: translateY(20px);
110
+ }
111
+ to {
112
+ opacity: 1;
113
+ transform: translateY(0);
114
+ }
115
+ }
116
+
117
+ @keyframes fillProgress {
118
+ from { width: 0%; }
119
+ to { width: 100%; }
120
+ }
121
+
122
+ /* فیلتر و جستجو */
123
+ .search-box {
124
+ display: flex;
125
+ gap: 1rem;
126
+ margin-bottom: 2rem;
127
+ }
128
+
129
+ .search-input {
130
+ flex: 1;
131
+ padding: 0.8rem 1.2rem;
132
+ border: 2px solid #e0e0e0;
133
+ border-radius: 10px;
134
+ font-size: 1rem;
135
+ transition: all 0.3s ease;
136
+ }
137
+
138
+ .search-input:focus {
139
+ border-color: #2196F3;
140
+ outline: none;
141
+ }
142
+
143
+ /* پیام‌های اطلاع‌رسانی */
144
+ .info-message {
145
+ background: rgba(33, 150, 243, 0.1);
146
+ border-left: 4px solid #2196F3;
147
+ padding: 1rem;
148
+ border-radius: 0 10px 10px 0;
149
+ margin: 1rem 0;
150
+ }
151
+ </style>
152
+ """
153
+
154
+ st.markdown(CUSTOM_CSS, unsafe_allow_html=True)
155
+
156
+ class FileManager:
157
+ def __init__(self):
158
+ self.root_path = Path("uploads")
159
+ self.root_path.mkdir(exist_ok=True)
160
+
161
+ def get_file_info(self, filename):
162
+ """دریافت اطلاعات کامل فایل"""
163
+ path = self.root_path / filename
164
+ stats = path.stat()
165
+ return {
166
+ 'size': humanize.naturalsize(stats.st_size),
167
+ 'modified': datetime.fromtimestamp(stats.st_mtime).strftime('%Y/%m/%d %H:%M'),
168
+ 'type': path.suffix[1:].upper(),
169
+ 'icon': self._get_file_icon(path.suffix)
170
+ }
171
+
172
+ def _get_file_icon(self, suffix):
173
+ """انتخاب آیکون مناسب برای هر نوع فایل"""
174
+ icons = {
175
+ '.txt': '📄',
176
+ '.pdf': '📕',
177
+ '.jpg': '🖼️',
178
+ '.jpeg': '🖼️',
179
+ '.png': '🖼️',
180
+ '.gif': '🎞️',
181
+ '.zip': '📦',
182
+ '.mp3': '🎵',
183
+ '.mp4': '🎥',
184
+ '.doc': '📘',
185
+ '.docx': '📘',
186
+ '.xls': '📊',
187
+ '.xlsx': '📊',
188
+ }
189
+ return icons.get(suffix.lower(), '📎')
190
+
191
+ def upload_file(self, file):
192
+ """آپلود فایل با نمایش پیشرفت"""
193
+ try:
194
+ progress_text = st.empty()
195
+ progress_bar = st.progress(0)
196
+
197
+ dest_path = self.root_path / file.name
198
+ total_size = file.size
199
+
200
+ with open(dest_path, "wb") as f:
201
+ bytes_data = file.getbuffer()
202
+ f.write(bytes_data)
203
+
204
+ # شبیه‌سازی پیشرفت آپلود
205
+ for i in range(100):
206
+ time.sleep(0.01)
207
+ progress = (i + 1) / 100
208
+ progress_bar.progress(progress)
209
+ progress_text.text(f"در حال آپلود... {int(progress * 100)}%")
210
+
211
+ progress_text.empty()
212
+ progress_bar.empty()
213
+
214
+ return "success", f"✅ فایل '{file.name}' با موفقیت آپلود شد"
215
+ except Exception as e:
216
+ return "error", f"❌ خطا در آپلود فایل: {str(e)}"
217
+
218
+ def list_files(self, search_term="", file_type=None):
219
+ """لیست فایل‌ها با قابلیت جستجو و فیلتر"""
220
+ files = []
221
+ for f in self.root_path.iterdir():
222
+ if f.is_file():
223
+ if file_type and file_type != "همه" and f.suffix.lower() != file_type.lower():
224
+ continue
225
+ if search_term and search_term.lower() not in f.name.lower():
226
+ continue
227
+ files.append(f.name)
228
+ return sorted(files)
229
+
230
+ def preview_file(self, filename):
231
+ """پیش‌نمایش پیشرفته فایل"""
232
+ try:
233
+ path = self.root_path / filename
234
+ if path.suffix.lower() in ['.jpg', '.jpeg', '.png', '.gif']:
235
+ img = Image.open(path)
236
+ return "image", img
237
+ elif path.suffix.lower() == '.txt':
238
+ with open(path, "r", encoding="utf-8") as f:
239
+ content = f.read(1000)
240
+ if len(content) >= 1000:
241
+ content += "\n...[ادامه متن]"
242
+ return "text", content
243
+ return "unsupported", "⚠️ پیش‌نمایش برای این نوع فایل در دسترس نیست"
244
+ except Exception as e:
245
+ return "error", f"❌ خطا در نمایش فایل: {str(e)}"
246
+
247
+ def compress_files(self, files):
248
+ """فشرده‌سازی فایل‌ها با نمایش پیشرفت"""
249
+ try:
250
+ if not files:
251
+ return "error", "⚠️ لطفاً حداقل یک فایل انتخاب کنید"
252
+
253
+ zip_name = f"compressed_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip"
254
+ zip_path = self.root_path / zip_name
255
+
256
+ progress_text = st.empty()
257
+ progress_bar = st.progress(0)
258
+
259
+ with zipfile.ZipFile(zip_path, 'w') as zipf:
260
+ for i, file in enumerate(files, 1):
261
+ file_path = self.root_path / file
262
+ zipf.write(file_path, file)
263
+ progress = i / len(files)
264
+ progress_bar.progress(progress)
265
+ progress_text.text(f"در حال فشرده‌سازی... {int(progress * 100)}%")
266
+
267
+ progress_text.empty()
268
+ progress_bar.empty()
269
+
270
+ return "success", f"✅ فایل‌ها با موفقیت در '{zip_name}' فشرده شدند"
271
+ except Exception as e:
272
+ return "error", f"❌ خطا در فشرده‌سازی: {str(e)}"
273
+
274
+ def main():
275
+ st.markdown('<div class="main-container">', unsafe_allow_html=True)
276
+ st.title("💼 سیستم مدیریت فایل پیشرفته")
277
+
278
+ file_manager = FileManager()
279
+
280
+ # بخش آپلود فایل
281
+ st.markdown("""
282
+ <div class="upload-area">
283
+ <h3>📤 آپلود فایل</h3>
284
+ <p>فایل خود را اینجا رها کنید یا کلیک کنید</p>
285
+ <div class="progress-bar">
286
+ <div class="progress-fill"></div>
287
+ </div>
288
+ </div>
289
+ """, unsafe_allow_html=True)
290
+
291
+ uploaded_file = st.file_uploader(
292
+ "",
293
+ type=["jpg", "jpeg", "png", "gif", "txt", "pdf", "doc", "docx", "xls", "xlsx", "mp3", "mp4", "zip"],
294
+ accept_multiple_files=False
295
+ )
296
+
297
+ if uploaded_file:
298
+ status, message = file_manager.upload_file(uploaded_file)
299
+ if status == "success":
300
+ st.success(message)
301
+ else:
302
+ st.error(message)
303
+
304
+ # بخش جستجو و فیلتر
305
+ col1, col2 = st.columns([2, 1])
306
+ with col1:
307
+ search_term = st.text_input("🔍 جستجوی فایل", placeholder="نام فایل را وارد کنید...")
308
+ with col2:
309
+ file_type = st.selectbox(
310
+ "📁 نوع فایل",
311
+ ["همه", ".jpg", ".jpeg", ".png", ".gif", ".txt", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".mp3", ".mp4", ".zip"]
312
+ )
313
+
314
+ # نمایش لیست فایل‌ها
315
+ files = file_manager.list_files(search_term, file_type)
316
+
317
+ if not files:
318
+ st.markdown("""
319
+ <div class="info-message">
320
+ 📭 هیچ فایلی یافت نشد
321
+ </div>
322
+ """, unsafe_allow_html=True)
323
+ else:
324
+ for file in files:
325
+ file_info = file_manager.get_file_info(file)
326
+
327
+ with st.container():
328
+ st.markdown(f"""
329
+ <div class="file-card">
330
+ <div style="display: flex; justify-content: space-between; align-items: center;">
331
+ <div>
332
+ <h3>{file_info['icon']} {file}</h3>
333
+ <p>اندازه: {file_info['size']} | نوع: {file_info['type']} | آخرین تغییر: {file_info['modified']}</p>
334
+ </div>
335
+ </div>
336
+ </div>
337
+ """, unsafe_allow_html=True)
338
+
339
+ col1, col2, col3, col4 = st.columns([1, 1, 1, 1])
340
+
341
+ with col1:
342
+ if st.button("👁️ نمایش", key=f"preview_{file}"):
343
+ preview_type, preview_content = file_manager.preview_file(file)
344
+ if preview_type == "image":
345
+ st.image(preview_content, use_column_width=True)
346
+ elif preview_type == "text":
347
+ st.text(preview_content)
348
+ else:
349
+ st.warning(preview_content)
350
+
351
+ with col2:
352
+ if st.button("🗑️ حذف", key=f"delete_{file}"):
353
+ if st.session_state.get('admin_logged_in', False):
354
+ status, message = file_manager.delete_file(file)
355
+ st.success(message) if status == "success" else st.error(message)
356
+ else:
357
+ st.error("⛔ فقط مدیر می‌تواند فایل‌ها را حذف کند")
358
+
359
+ with col3:
360
+ with open(file_manager.root_path / file, 'rb') as f:
361
+ st.download_button(
362
+ "⬇️ دانلود",
363
+ f.read(),
364
+ file_name=file,
365
+ key=f"download_{file}"
366
+ )
367
+
368
+ # بخش فشرده‌سازی
369
+ st.markdown("""
370
+ <div class="file-card">
371
+ <h3>🗜️ فشرده‌سازی فایل‌ها</h3>
372
+ </div>
373
+ """, unsafe_allow_html=True)
374
+
375
+ selected_files = st.multiselect(
376
+ "فایل‌های مورد نظر را انتخاب کنید",
377
+ files,
378
+ key="compress_files"
379
+ )
380
+
381
+ if st.button("📦 ساخت فایل ZIP"):
382
+ if selected_files:
383
+ status, message = file_manager.compress_files(selected_files)
384
+ if status == "success":
385
+ st.success(message)
386
+ else:
387
+ st.error(message)
388
+ else:
389
+ st.warning("⚠️ لطفاً حداقل یک فایل انتخاب کنید")
390
+
391
+ st.markdown('</div>', unsafe_allow_html=True)
392
+
393
+ if __name__ == "__main__":
394
+ main()
ml_banking_model.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from pathlib import Path
3
+ import torch
4
+ from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer
5
+ from peft import LoraConfig, get_peft_model
6
+ import pandas as pd
7
+ from datasets import Dataset
8
+ import json
9
+ import psutil
10
+ import time
11
+ from datetime import datetime
12
+ import onnx
13
+ import onnxruntime
14
+ from functools import lru_cache
15
+ import logging
16
+ from typing import Dict, List, Optional
17
+
18
+ class BankingModel:
19
+ def __init__(self):
20
+ # تنظیم لاگر
21
+ self._setup_logging()
22
+
23
+ # ساخت پوشه‌ها
24
+ self.base_dir = Path.cwd()
25
+ self.dirs = {
26
+ 'model': self.base_dir / "trained_model",
27
+ 'data': self.base_dir / "data",
28
+ 'logs': self.base_dir / "logs",
29
+ 'backup': self.base_dir / "backups",
30
+ 'cache': self.base_dir / "cache",
31
+ 'reports': self.base_dir / "reports"
32
+ }
33
+
34
+ for dir_path in self.dirs.values():
35
+ dir_path.mkdir(exist_ok=True)
36
+
37
+ # تنظیمات مدل برای CPU
38
+ self.model_name = "meta-llama/Llama-2-13b-chat-hf"
39
+ self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
40
+
41
+ # بهینه‌سازی برای CPU
42
+ self.model = AutoModelForCausalLM.from_pretrained(
43
+ self.model_name,
44
+ device_map='cpu',
45
+ torch_dtype=torch.float32,
46
+ low_cpu_mem_usage=True
47
+ )
48
+
49
+ # تنظیمات LoRA
50
+ self._setup_lora()
51
+
52
+ # مقداردهی کش
53
+ self.response_cache = {}
54
+
55
+ # شروع مانیتورینگ
56
+ self.start_monitoring()
57
+
58
+ def _setup_logging(self):
59
+ """راه‌اندازی سیستم لاگینگ"""
60
+ logging.basicConfig(
61
+ filename=f'logs/model_{datetime.now().strftime("%Y%m%d")}.log',
62
+ level=logging.INFO,
63
+ format='%(asctime)s - %(levelname)s - %(message)s'
64
+ )
65
+ self.logger = logging.getLogger(__name__)
66
+
67
+ def _setup_lora(self):
68
+ """تنظیم LoRA برای CPU"""
69
+ self.lora_config = LoraConfig(
70
+ r=8, # کاهش برای CPU
71
+ lora_alpha=16,
72
+ target_modules=["q_proj", "v_proj"],
73
+ lora_dropout=0.05,
74
+ bias="none",
75
+ task_type="CAUSAL_LM"
76
+ )
77
+ self.model = get_peft_model(self.model, self.lora_config)
78
+
79
+ @lru_cache(maxsize=1000)
80
+ def cached_predict(self, text: str) -> str:
81
+ """پیش‌بینی با استفاده از کش"""
82
+ return self.predict(text)
83
+
84
+ def create_backup(self):
85
+ """ایجاد نسخه پشتیبان"""
86
+ backup_time = datetime.now().strftime("%Y%m%d_%H%M%S")
87
+ backup_path = self.dirs['backup'] / f"model_backup_{backup_time}"
88
+ self.save_model(backup_path)
89
+ self.logger.info(f"Backup created at {backup_path}")
90
+
91
+ def monitor_resources(self) -> Dict:
92
+ """مانیتورینگ منابع سیستم"""
93
+ cpu_percent = psutil.cpu_percent(interval=1)
94
+ memory = psutil.virtual_memory()
95
+ return {
96
+ 'cpu_usage': cpu_percent,
97
+ 'memory_used': memory.percent,
98
+ 'memory_available': memory.available / (1024 * 1024 * 1024) # GB
99
+ }
100
+
101
+ def start_monitoring(self):
102
+ """شروع مانیتورینگ مداوم"""
103
+ self.monitoring_data = []
104
+ self.monitoring_start_time = time.time()
105
+
106
+ def log_performance(self, input_text: str, response: str, response_time: float):
107
+ """ثبت عملکرد مدل"""
108
+ performance_data = {
109
+ 'timestamp': datetime.now().isoformat(),
110
+ 'input_length': len(input_text),
111
+ 'response_length': len(response),
112
+ 'response_time': response_time,
113
+ 'resources': self.monitor_resources()
114
+ }
115
+
116
+ with open(self.dirs['reports'] / 'performance.jsonl', 'a') as f:
117
+ f.write(json.dumps(performance_data) + '\n')
118
+
119
+ def export_to_onnx(self):
120
+ """تبدیل مدل به ONNX برای اجرای سریع‌تر"""
121
+ dummy_input = self.tokenizer("test input", return_tensors="pt")
122
+ onnx_path = self.dirs['model'] / "model.onnx"
123
+
124
+ torch.onnx.export(
125
+ self.model,
126
+ (dummy_input['input_ids'],),
127
+ onnx_path,
128
+ opset_version=12,
129
+ input_names=['input_ids'],
130
+ output_names=['output']
131
+ )
132
+ self.logger.info(f"Model exported to ONNX at {onnx_path}")
133
+
134
+ def generate_report(self) -> Dict:
135
+ """تولید گزارش عملکرد"""
136
+ with open(self.dirs['reports'] / 'performance.jsonl', 'r') as f:
137
+ data = [json.loads(line) for line in f]
138
+
139
+ return {
140
+ 'total_requests': len(data),
141
+ 'avg_response_time': sum(d['response_time'] for d in
requirements.txt CHANGED
@@ -1,5 +1,12 @@
1
- streamlit
2
- transformers
3
- torch
4
- gradio
5
- requests
 
 
 
 
 
 
 
 
1
+ torch==2.1.0
2
+ transformers==4.35.0
3
+ peft==0.5.0
4
+ bitsandbytes==0.41.0
5
+ accelerate==0.24.0
6
+ datasets==2.14.0
7
+ pandas==2.1.0
8
+ scikit-learn==1.3.0
9
+ sentencepiece==0.1.99
10
+ pytest==7.4.2
11
+ black==23.9.1
12
+ flake8==6.1.0