fix: Socket.io real-time güncelleme sistemi tamamen düzeltildi
- Socket.IO client modülü oluşturuldu (socketClient.js) - SvelteKit API route'larından Socket.IO event gönderimi için client kullanımı - fuel-slips API'de HTTP fetch yerine Socket.IO client kullanımı - Server'da API event'larını dinleyip broadcast etme eklendi - GoodsManagerContent component'inde Socket.IO dinleyicileri düzeltildi - Dashboard'da Mal Sorumlusu content render düzeltmesi - İbrahim Kara kullanıcısı ve mal sorumlusu kaydı eklendi - Login endpoint'inde goods_manager ID mapping düzeltmesi - fuel-slips/+page.svelte'de eksik fonksiyonlar eklendi - Kapsamlı debug logları tüm Socket.IO işlemlerine eklendi Çalışma prensibi: 1. Yakıt fişi oluşturulduğunda -> api-fuel-slip-assigned -> broadcast fuel-slip-assigned 2. Fiş onaylandığında/reddedildiğinde -> api-fuel-slip-updated -> broadcast fuel-slip-updated 3. Tüm değişiklikler anlık olarak ilgili ekranlarda güncelleniyor
This commit is contained in:
@@ -18,40 +18,78 @@
|
|||||||
let rejectionNotes = '';
|
let rejectionNotes = '';
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
|
console.log('🟢 GoodsManagerContent mounted, user:', user);
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
console.error('❌ User is null in GoodsManagerContent');
|
||||||
|
error = 'Kullanıcı bilgisi bulunamadı.';
|
||||||
|
loading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('🔌 Connecting to Socket.IO...');
|
||||||
// Socket.IO bağlantısı
|
// Socket.IO bağlantısı
|
||||||
socket = io('http://localhost:3000');
|
socket = io('http://localhost:3000');
|
||||||
|
|
||||||
|
console.log('👤 Goods Manager ID:', user.id);
|
||||||
|
|
||||||
// Yeni fiş atandığında bildirim
|
// Yeni fiş atandığında bildirim
|
||||||
socket.on('fuel-slip-assigned', (data) => {
|
socket.on('fuel-slip-assigned', (data) => {
|
||||||
|
console.log('Socket event received: fuel-slip-assigned', data);
|
||||||
if (data.goods_manager_id === user.id) {
|
if (data.goods_manager_id === user.id) {
|
||||||
|
console.log('✅ Slip assigned to this manager, reloading...');
|
||||||
loadAssignedSlips();
|
loadAssignedSlips();
|
||||||
successMessage = 'Yeni yakıt fişi atandı!';
|
successMessage = 'Yeni yakıt fişi atandı!';
|
||||||
setTimeout(() => successMessage = '', 3000);
|
setTimeout(() => successMessage = '', 3000);
|
||||||
|
} else {
|
||||||
|
console.log('ℹ️ Slip assigned to different manager:', data.goods_manager_id, 'vs', user.id);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fiş durumu güncellendiğinde listeyi yenile
|
// Fiş durumu güncellendiğinde listeyi yenile
|
||||||
socket.on('fuel-slip-updated', (data) => {
|
socket.on('fuel-slip-updated', (data) => {
|
||||||
|
console.log('Socket event received: fuel-slip-updated', data);
|
||||||
if (data.goods_manager_id === user.id) {
|
if (data.goods_manager_id === user.id) {
|
||||||
|
console.log('✅ Slip updated for this manager, reloading...');
|
||||||
loadAssignedSlips();
|
loadAssignedSlips();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
console.log('Socket.IO connected:', socket.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
console.log('Socket.IO disconnected');
|
||||||
|
});
|
||||||
|
|
||||||
await loadAssignedSlips();
|
await loadAssignedSlips();
|
||||||
});
|
});
|
||||||
|
|
||||||
async function loadAssignedSlips() {
|
async function loadAssignedSlips() {
|
||||||
|
if (!user) {
|
||||||
|
console.error('❌ Cannot load slips: user is null');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`📥 Loading slips for goods_manager_id: ${user.id}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`/api/fuel-slips?manager_id=${user.id}&status=pending`);
|
const url = `/api/fuel-slips?manager_id=${user.id}&status=pending`;
|
||||||
|
console.log('🌐 Fetching from:', url);
|
||||||
|
|
||||||
|
const response = await fetch(url);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
assignedSlips = data.fuelSlips || [];
|
assignedSlips = data.fuelSlips || [];
|
||||||
|
console.log('✅ Assigned slips loaded:', assignedSlips.length, assignedSlips);
|
||||||
} else {
|
} else {
|
||||||
|
console.error('❌ Failed to load slips, status:', response.status);
|
||||||
error = 'Atanan fişler yüklenemedi.';
|
error = 'Atanan fişler yüklenemedi.';
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error = 'Bağlantı hatası.';
|
error = 'Bağlantı hatası.';
|
||||||
console.error('Load assigned slips error:', err);
|
console.error('❌ Load assigned slips error:', err);
|
||||||
} finally {
|
} finally {
|
||||||
loading = false;
|
loading = false;
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/lib/server/socketClient.js
Normal file
44
src/lib/server/socketClient.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import { io } from 'socket.io-client';
|
||||||
|
|
||||||
|
let socket = null;
|
||||||
|
|
||||||
|
export function getSocketClient() {
|
||||||
|
if (!socket) {
|
||||||
|
socket = io('http://localhost:3000', {
|
||||||
|
transports: ['websocket', 'polling']
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
console.log('✅ Server-side Socket.IO client connected:', socket.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
console.log('❌ Server-side Socket.IO client disconnected');
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('connect_error', (err) => {
|
||||||
|
console.error('❌ Socket.IO connection error:', err.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function emitSocketEvent(event, data) {
|
||||||
|
const client = getSocketClient();
|
||||||
|
console.log(`📢 Attempting to emit event: ${event}, connected: ${client?.connected}`);
|
||||||
|
|
||||||
|
if (client && client.connected) {
|
||||||
|
console.log(`📢 Emitting API event to server: api-${event}`, data);
|
||||||
|
// API event olarak gönder, server broadcast edecek
|
||||||
|
client.emit(`api-${event}`, data);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.warn('⚠️ Socket not connected, cannot emit event');
|
||||||
|
// Bağlantı yoksa yeniden bağlanmayı dene
|
||||||
|
if (client && !client.connected) {
|
||||||
|
client.connect();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { json } from '@sveltejs/kit';
|
import { json } from '@sveltejs/kit';
|
||||||
|
import { emitSocketEvent } from '$lib/server/socketClient.js';
|
||||||
|
|
||||||
// Geçici veritabanı simülasyonu
|
// Geçici veritabanı simülasyonu
|
||||||
let fuelSlips = [
|
let fuelSlips = [
|
||||||
@@ -15,7 +16,7 @@ let fuelSlips = [
|
|||||||
km: 125420,
|
km: 125420,
|
||||||
personnel_id: 1,
|
personnel_id: 1,
|
||||||
personnel_info: { full_name: 'Ahmet Demir', rank: 'Üsteğmen' },
|
personnel_info: { full_name: 'Ahmet Demir', rank: 'Üsteğmen' },
|
||||||
goods_manager_id: 2,
|
goods_manager_id: 3,
|
||||||
goods_manager_info: { full_name: 'Ali Veli', rank: 'Binbaşı' },
|
goods_manager_info: { full_name: 'Ali Veli', rank: 'Binbaşı' },
|
||||||
fuel_manager_id: 1,
|
fuel_manager_id: 1,
|
||||||
fuel_manager_info: { full_name: 'Admin User', rank: 'Yüzbaşı' },
|
fuel_manager_info: { full_name: 'Admin User', rank: 'Yüzbaşı' },
|
||||||
@@ -36,7 +37,7 @@ let fuelSlips = [
|
|||||||
km: 87320,
|
km: 87320,
|
||||||
personnel_id: 2,
|
personnel_id: 2,
|
||||||
personnel_info: { full_name: 'Mustafa Çelik', rank: 'Astsubay' },
|
personnel_info: { full_name: 'Mustafa Çelik', rank: 'Astsubay' },
|
||||||
goods_manager_id: 2,
|
goods_manager_id: 3,
|
||||||
goods_manager_info: { full_name: 'Ali Veli', rank: 'Binbaşı' },
|
goods_manager_info: { full_name: 'Ali Veli', rank: 'Binbaşı' },
|
||||||
fuel_manager_id: 1,
|
fuel_manager_id: 1,
|
||||||
fuel_manager_info: { full_name: 'Admin User', rank: 'Yüzbaşı' },
|
fuel_manager_info: { full_name: 'Admin User', rank: 'Yüzbaşı' },
|
||||||
@@ -83,6 +84,7 @@ export async function GET({ request, url }) {
|
|||||||
export async function POST({ request }) {
|
export async function POST({ request }) {
|
||||||
try {
|
try {
|
||||||
const slipData = await request.json();
|
const slipData = await request.json();
|
||||||
|
console.log('📝 Creating new fuel slip with data:', slipData);
|
||||||
|
|
||||||
// Validasyon
|
// Validasyon
|
||||||
const requiredFields = [
|
const requiredFields = [
|
||||||
@@ -168,26 +170,21 @@ export async function POST({ request }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fuelSlips.push(newSlip);
|
fuelSlips.push(newSlip);
|
||||||
|
console.log('✅ Fuel slip created:', newSlip);
|
||||||
|
console.log('📊 Total slips now:', fuelSlips.length);
|
||||||
|
|
||||||
// Socket.IO ile mal sorumlusuna bildirim gönder
|
// Socket.IO ile mal sorumlusuna bildirim gönder
|
||||||
try {
|
const socketData = {
|
||||||
// Express sunucusuna Socket.IO olay gönder
|
goods_manager_id: newSlip.goods_manager_id,
|
||||||
const response = await fetch('http://localhost:3000/api/socket-notify', {
|
fuel_slip_id: newSlip.id,
|
||||||
method: 'POST',
|
message: `${newSlip.vehicle_info.plate} plakalı araç için yeni yakıt fişi`
|
||||||
headers: {
|
};
|
||||||
'Content-Type': 'application/json',
|
console.log('📢 Sending socket notification: fuel-slip-assigned', socketData);
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
// Socket client kullanarak bildirim gönder
|
||||||
event: 'fuel-slip-assigned',
|
const sent = emitSocketEvent('fuel-slip-assigned', socketData);
|
||||||
data: {
|
if (!sent) {
|
||||||
goods_manager_id: newSlip.goods_manager_id,
|
console.warn('⚠️ Socket notification could not be sent');
|
||||||
fuel_slip_id: newSlip.id,
|
|
||||||
message: `${newSlip.vehicle_info.plate} plakalı araç için yeni yakıt fişi`
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} catch (socketError) {
|
|
||||||
console.warn('Socket.IO bildirimi gönderilemedi:', socketError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return json({
|
return json({
|
||||||
@@ -229,27 +226,22 @@ export async function PUT({ request }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fuelSlips[slipIndex] = updatedSlip;
|
fuelSlips[slipIndex] = updatedSlip;
|
||||||
|
console.log('✅ Fuel slip updated:', updatedSlip);
|
||||||
|
|
||||||
// Socket.IO ile yakıt sorumlusuna bildirim gönder
|
// Socket.IO ile yakıt sorumlusuna bildirim gönder
|
||||||
try {
|
const socketData = {
|
||||||
const response = await fetch('http://localhost:3000/api/socket-notify', {
|
goods_manager_id: updatedSlip.goods_manager_id,
|
||||||
method: 'POST',
|
fuel_manager_id: updatedSlip.fuel_manager_id,
|
||||||
headers: {
|
fuel_slip_id: updatedSlip.id,
|
||||||
'Content-Type': 'application/json',
|
status: updatedSlip.status,
|
||||||
},
|
approval_notes: updatedSlip.approval_notes
|
||||||
body: JSON.stringify({
|
};
|
||||||
event: 'fuel-slip-updated',
|
console.log('📢 Sending socket notification: fuel-slip-updated', socketData);
|
||||||
data: {
|
|
||||||
goods_manager_id: updatedSlip.goods_manager_id,
|
// Socket client kullanarak bildirim gönder
|
||||||
fuel_manager_id: updatedSlip.fuel_manager_id,
|
const sent = emitSocketEvent('fuel-slip-updated', socketData);
|
||||||
fuel_slip_id: updatedSlip.id,
|
if (!sent) {
|
||||||
status: updatedSlip.status,
|
console.warn('⚠️ Socket notification could not be sent');
|
||||||
approval_notes: updatedSlip.approval_notes
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
} catch (socketError) {
|
|
||||||
console.warn('Socket.IO bildirimi gönderilemedi:', socketError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return json({
|
return json({
|
||||||
|
|||||||
@@ -14,10 +14,23 @@ let goodsManagers = [
|
|||||||
password: 'goods123',
|
password: 'goods123',
|
||||||
is_active: true,
|
is_active: true,
|
||||||
created_at: new Date().toISOString()
|
created_at: new Date().toISOString()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
full_name: 'İbrahim Kara',
|
||||||
|
rank: 'Yüzbaşı',
|
||||||
|
registration_number: 'GM002',
|
||||||
|
tc_kimlik: '98765432101',
|
||||||
|
phone: '05339876543',
|
||||||
|
email: 'ibrahim.kara@mil.tr',
|
||||||
|
username: 'ibrahim_kara',
|
||||||
|
password: 'kara123',
|
||||||
|
is_active: true,
|
||||||
|
created_at: new Date().toISOString()
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
let nextId = 4;
|
let nextId = 5;
|
||||||
|
|
||||||
// GET - Tüm mal sorumlularını listele
|
// GET - Tüm mal sorumlularını listele
|
||||||
export async function GET({ request }) {
|
export async function GET({ request }) {
|
||||||
|
|||||||
@@ -114,12 +114,22 @@
|
|||||||
|
|
||||||
// Fiş durumu güncellendiğinde listeyi yenile
|
// Fiş durumu güncellendiğinde listeyi yenile
|
||||||
socket.on('fuel-slip-updated', (data) => {
|
socket.on('fuel-slip-updated', (data) => {
|
||||||
|
console.log('Dashboard - fuel-slip-updated received:', data);
|
||||||
if (data.fuel_manager_id === user.id) {
|
if (data.fuel_manager_id === user.id) {
|
||||||
loadFuelData();
|
loadFuelData();
|
||||||
formSuccess = `Fiş durumu güncellendi: ${data.status === 'approved' ? 'Onaylandı' : 'Reddedildi'}`;
|
formSuccess = `Fiş durumu güncellendi: ${data.status === 'approved' ? 'Onaylandı' : 'Reddedildi'}`;
|
||||||
setTimeout(() => formSuccess = '', 3000);
|
setTimeout(() => formSuccess = '', 3000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
console.log('Dashboard - Socket.IO connected for fuel_manager:', socket.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eğer goods_manager ise socket bağlantısı kur (GoodsManagerContent component'i kendi socket'ini kullanacak)
|
||||||
|
if (user.role === 'goods_manager') {
|
||||||
|
console.log('Dashboard - goods_manager logged in, user:', user);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -371,7 +381,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (page === 'goods-manager' && user?.role === 'goods_manager') {
|
if (page === 'goods-manager' && user?.role === 'goods_manager') {
|
||||||
console.log('🎯 Setting showGoodsManager to true');
|
console.log('🎯 Navigating to goods-manager, user:', user);
|
||||||
showGoodsManager = true;
|
showGoodsManager = true;
|
||||||
showMobileMenu = false;
|
showMobileMenu = false;
|
||||||
return;
|
return;
|
||||||
@@ -696,31 +706,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{:else if user.role === 'goods_manager' && showGoodsManager}
|
{:else if user.role === 'goods_manager' && showGoodsManager}
|
||||||
<!-- Goods Manager Content -->
|
<!-- Goods Manager Content -->
|
||||||
<div class="goods-manager-content">
|
<GoodsManagerContent {user} />
|
||||||
<div class="content-header">
|
|
||||||
<h1 class="content-title">Atanan Yakıt Fişleri</h1>
|
|
||||||
<div class="stats-badge">
|
|
||||||
<span class="count">0</span>
|
|
||||||
<span>Bekleyen Fiş</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="empty-state">
|
|
||||||
<div class="empty-icon">
|
|
||||||
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
||||||
<path d="M9 11H3v10h6V11z"/>
|
|
||||||
<path d="M21 11h-6v10h6V11z"/>
|
|
||||||
<path d="M14 3v4h-4V3"/>
|
|
||||||
<path d="M17 7V3h-4v4"/>
|
|
||||||
<path d="M7 7V3H3v4"/>
|
|
||||||
<path d="M21 7v-4h-4v4"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<h3>Onay Bekleyen Fiş Yok</h3>
|
|
||||||
<p>Size atanan yeni yakıt fişleri olmadığında burada görünecekler.</p>
|
|
||||||
<p style="margin-top: 1rem; color: var(--primary-color); font-weight: 600;">✅ SPA navigasyonu başarıyla çalışıyor!</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{:else if user.role === 'admin'}
|
{:else if user.role === 'admin'}
|
||||||
<!-- Admin Dynamic Content -->
|
<!-- Admin Dynamic Content -->
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
let showFuelForm = false;
|
let showFuelForm = false;
|
||||||
let successMessage = '';
|
let successMessage = '';
|
||||||
let socket = null;
|
let socket = null;
|
||||||
let selectedUnit = '';
|
let selectedUnit = 'all';
|
||||||
let fuelSummary = { benzin: 0, motorin: 0 };
|
let fuelSummary = { benzin: 0, motorin: 0 };
|
||||||
|
|
||||||
// Form değişkenleri
|
// Form değişkenleri
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
|
|
||||||
// Fiş durumu güncellendiğinde listeyi yenile
|
// Fiş durumu güncellendiğinde listeyi yenile
|
||||||
socket.on('fuel-slip-updated', (data) => {
|
socket.on('fuel-slip-updated', (data) => {
|
||||||
|
console.log('Socket event received: fuel-slip-updated', data);
|
||||||
if (data.fuel_manager_id === user.id) {
|
if (data.fuel_manager_id === user.id) {
|
||||||
loadData();
|
loadData();
|
||||||
successMessage = `Fiş durumu güncellendi: ${data.status === 'approved' ? 'Onaylandı' : 'Reddedildi'}`;
|
successMessage = `Fiş durumu güncellendi: ${data.status === 'approved' ? 'Onaylandı' : 'Reddedildi'}`;
|
||||||
@@ -62,6 +63,14 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
console.log('Socket.IO connected:', socket.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
console.log('Socket.IO disconnected');
|
||||||
|
});
|
||||||
|
|
||||||
await loadData();
|
await loadData();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -131,7 +140,7 @@
|
|||||||
liters: '',
|
liters: '',
|
||||||
km: '',
|
km: '',
|
||||||
personnel_id: '',
|
personnel_id: '',
|
||||||
goods_manager_id: '',
|
goods_manager_id: goodsManagers.length > 0 ? goodsManagers[0].id : '',
|
||||||
notes: ''
|
notes: ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -215,6 +224,41 @@
|
|||||||
return type === 'benzin' ? '⛽' : '🛢️';
|
return type === 'benzin' ? '⛽' : '🛢️';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openFuelForm() {
|
||||||
|
showFuelForm = true;
|
||||||
|
error = '';
|
||||||
|
successMessage = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeFuelForm() {
|
||||||
|
showFuelForm = false;
|
||||||
|
resetForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFilteredSlips() {
|
||||||
|
if (!selectedUnit || selectedUnit === 'all') {
|
||||||
|
return fuelSlips;
|
||||||
|
}
|
||||||
|
return fuelSlips.filter(slip => slip.unit_name === selectedUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFilteredHistory() {
|
||||||
|
if (!selectedUnit || selectedUnit === 'all') {
|
||||||
|
return approvedRejectedSlips;
|
||||||
|
}
|
||||||
|
return approvedRejectedSlips.filter(slip => slip.unit_name === selectedUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPriorityClass(liters) {
|
||||||
|
if (liters > 100) return 'priority-high';
|
||||||
|
if (liters > 50) return 'priority-medium';
|
||||||
|
return 'priority-low';
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatFuelType(type) {
|
||||||
|
return type === 'benzin' ? 'Benzin' : 'Motorin';
|
||||||
|
}
|
||||||
|
|
||||||
function handleLogout() {
|
function handleLogout() {
|
||||||
localStorage.removeItem('user');
|
localStorage.removeItem('user');
|
||||||
goto('/');
|
goto('/');
|
||||||
@@ -331,6 +375,17 @@
|
|||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="force_command">Kuvvet Komutanlığı</label>
|
||||||
|
<input
|
||||||
|
id="force_command"
|
||||||
|
type="text"
|
||||||
|
class="form-input"
|
||||||
|
bind:value={formData.force_command}
|
||||||
|
placeholder="1. Komutan"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="unit_id">Birlik</label>
|
<label for="unit_id">Birlik</label>
|
||||||
<select id="unit_id" class="form-select" bind:value={formData.unit_id} required>
|
<select id="unit_id" class="form-select" bind:value={formData.unit_id} required>
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ const io = new Server(server, {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Export io for use in other modules
|
||||||
|
export { io };
|
||||||
|
|
||||||
const PORT = process.env.PORT || 3000;
|
const PORT = process.env.PORT || 3000;
|
||||||
|
|
||||||
// ES Module equivalent of __dirname
|
// ES Module equivalent of __dirname
|
||||||
@@ -93,7 +96,8 @@ async function initializeDatabase() {
|
|||||||
const users = [
|
const users = [
|
||||||
{ username: 'admin', password: 'admin123', role: 'admin', full_name: 'Sistem Yöneticisi' },
|
{ username: 'admin', password: 'admin123', role: 'admin', full_name: 'Sistem Yöneticisi' },
|
||||||
{ username: 'fuel', password: 'fuel123', role: 'fuel_manager', full_name: 'Yakıt Sorumlusu' },
|
{ username: 'fuel', password: 'fuel123', role: 'fuel_manager', full_name: 'Yakıt Sorumlusu' },
|
||||||
{ username: 'goods', password: 'goods123', role: 'goods_manager', full_name: 'Mal Sorumlusu' }
|
{ username: 'goods', password: 'goods123', role: 'goods_manager', full_name: 'Mal Sorumlusu' },
|
||||||
|
{ username: 'ibrahim_kara', password: 'kara123', role: 'goods_manager', full_name: 'İbrahim Kara' }
|
||||||
];
|
];
|
||||||
|
|
||||||
// Her kullanıcıyı kontrol et ve yoksa ekle
|
// Her kullanıcıyı kontrol et ve yoksa ekle
|
||||||
@@ -139,21 +143,35 @@ app.post('/api/login', async (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Session oluştur
|
// Session oluştur
|
||||||
req.session.user = {
|
let sessionUser = {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
full_name: user.full_name
|
full_name: user.full_name
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Eğer goods_manager ise, goods_managers API'den gerçek ID'yi al
|
||||||
|
if (user.role === 'goods_manager') {
|
||||||
|
try {
|
||||||
|
const goodsManagersRes = await fetch('http://localhost:3000/api/goods-managers');
|
||||||
|
if (goodsManagersRes.ok) {
|
||||||
|
const goodsData = await goodsManagersRes.json();
|
||||||
|
const goodsManager = goodsData.goodsManagers?.find(gm => gm.username === user.username);
|
||||||
|
if (goodsManager) {
|
||||||
|
sessionUser.id = goodsManager.id; // goods_manager ID'sini kullan
|
||||||
|
console.log(`✅ Goods manager logged in: ${user.full_name} (ID: ${goodsManager.id})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (fetchError) {
|
||||||
|
console.warn('⚠️ Could not fetch goods manager ID:', fetchError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
req.session.user = sessionUser;
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
message: 'Giriş başarılı.',
|
message: 'Giriş başarılı.',
|
||||||
user: {
|
user: sessionUser
|
||||||
id: user.id,
|
|
||||||
username: user.username,
|
|
||||||
role: user.role,
|
|
||||||
full_name: user.full_name
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -189,6 +207,7 @@ app.post('/api/socket-notify', (req, res) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Socket.IO ile olay yayınla
|
// Socket.IO ile olay yayınla
|
||||||
|
console.log(`📢 Socket.IO event emitted: ${event}`, data);
|
||||||
io.emit(event, data);
|
io.emit(event, data);
|
||||||
|
|
||||||
res.json({ message: 'Bildirim gönderildi.' });
|
res.json({ message: 'Bildirim gönderildi.' });
|
||||||
@@ -210,10 +229,21 @@ app.get('/api/users', (req, res) => {
|
|||||||
|
|
||||||
// Socket.IO bağlantıları
|
// Socket.IO bağlantıları
|
||||||
io.on('connection', (socket) => {
|
io.on('connection', (socket) => {
|
||||||
console.log('Bir kullanıcı bağlandı:', socket.id);
|
console.log('✅ Bir kullanıcı bağlandı:', socket.id);
|
||||||
|
|
||||||
|
// API'den gelen event'ları dinle ve broadcast et
|
||||||
|
socket.on('api-fuel-slip-assigned', (data) => {
|
||||||
|
console.log('📢 API event received: api-fuel-slip-assigned, broadcasting to all clients', data);
|
||||||
|
io.emit('fuel-slip-assigned', data);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('api-fuel-slip-updated', (data) => {
|
||||||
|
console.log('📢 API event received: api-fuel-slip-updated, broadcasting to all clients', data);
|
||||||
|
io.emit('fuel-slip-updated', data);
|
||||||
|
});
|
||||||
|
|
||||||
socket.on('disconnect', () => {
|
socket.on('disconnect', () => {
|
||||||
console.log('Bir kullanıcı ayrıldı:', socket.id);
|
console.log('❌ Bir kullanıcı ayrıldı:', socket.id);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user