update api loket admin

This commit is contained in:
Fanrouver
2026-01-26 14:37:05 +07:00
parent 6c0835227d
commit 083fe3e364
4 changed files with 488 additions and 320 deletions

No files matched your search

+45 -59
View File
@@ -262,37 +262,31 @@ export const useLoketStore = defineStore('loket', () => {
/**
* Fetch loket data dari API backend
* Mengikuti pattern dari clinicStore.fetchRegulerClinics()
* Filter hanya loket dengan pembayaran JKN (REGULER)
* Sort berdasarkan nama loket (urut dari 1)
* MENGGUNAKAN endpoint /api/v1/klinik/reguler untuk memetakan Loket -> Clinics
*/
const fetchLoketFromAPI = async (force = false, retryCount = 0) => {
// Guard: singleton pattern - prevent duplicate fetch
if (activeFetchPromise && retryCount === 0) {
console.log('⏳ Loket fetch in progress, reusing existing request...');
return activeFetchPromise;
}
// Guard: Skip if data already exists and not forced
const hasData = loketData.value && loketData.value.length > 0;
const hasData = apiLoketData.value && apiLoketData.value.length > 0;
if (hasData && !force && retryCount === 0) {
return { success: true, message: 'Data sudah tersedia' };
}
// Define the actual fetch operation
const performFetch = async () => {
isLoadingAPI.value = true;
apiError.value = null;
try {
console.log(`🔄 Fetching loket from API (Try ${retryCount + 1})...`);
const response = await fetch('http://10.10.150.131:8089/api/v1/klinik/loket');
console.log(`🔄 Fetching clinics for loket config (Try ${retryCount + 1})...`);
// Endpoint ini memberikan list klinik, setiap klinik punya list loket
const response = await fetch('http://10.10.150.131:8089/api/v1/klinik/reguler');
if (!response.ok) {
// Handle Rate Limiting with exponential backoff
if (response.status === 429 && retryCount < 3) {
const delay = (retryCount + 1) * 1500;
console.warn(`⚠️ Rate limit hit (429). Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
activeFetchPromise = null;
return fetchLoketFromAPI(force, retryCount + 1);
@@ -301,81 +295,73 @@ export const useLoketStore = defineStore('loket', () => {
}
const rawData = await response.json();
console.log('📦 Raw API Response received');
console.log('📦 Raw data:', rawData);
const clinics = rawData.data || [];
// Extract data array
const data = rawData.data || rawData;
if (!Array.isArray(data)) {
throw new Error('Data format tidak valid. Expected array.');
}
// AGGREGATE: Build Loket Map from Clinics
const loketMap = new Map();
console.log('📊 Total items from API:', data.length);
clinics.forEach(clinic => {
if (clinic.loket && Array.isArray(clinic.loket)) {
clinic.loket.forEach(l => {
const id = parseInt(l.idloket);
if (!loketMap.has(id)) {
loketMap.set(id, {
id: id,
namaLoket: l.namaloket,
kodeLoket: l.kodeloket,
kuota: clinic.kuota || 100, // Fallback
pelayanan: [],
_spesialisDetail: [],
pembayaran: 'JKN',
source: 'api',
loketAktif: true
});
}
const loketObj = loketMap.get(id);
// Add clinic code to pelayanan if not already there
if (!loketObj.pelayanan.includes(clinic.code)) {
loketObj.pelayanan.push(clinic.code);
loketObj._spesialisDetail.push({
idklinik: clinic.idklinik,
namaklinik: clinic.namaklinik,
code: clinic.code
});
}
});
}
});
// Filter hanya JKN (REGULER) dan transform ke format internal
const lokets = data
.filter(item => {
const hasJKN = item.pembayaran?.some(p => p.pembayaran === 'JKN');
if (!hasJKN) {
console.warn('⚠️ Loket skipped (no JKN):', item.namaloket, 'pembayaran:', item.pembayaran);
}
return hasJKN;
})
.map((item) => ({
id: parseInt(item.idloket),
no: 0, // Will be set after sort
namaLoket: item.namaloket,
kodeLoket: item.kodeloket,
kuota: parseInt(item.kuotaloket),
pelayanan: item.spesialis?.map(s => s.idklinik) || [],
pembayaran: 'JKN',
keterangan: item.tipevisit?.map(t => t.tipevisit).join(', ') || 'ONLINE',
statusPelayanan: item.tipeloket || 'REGULER',
loketAktif: item.loketaktif,
jenisLoket: item.jenisloket,
// Simpan detail lengkap spesialis untuk display nama klinik
_spesialisDetail: item.spesialis || [],
}));
const lokets = Array.from(loketMap.values());
// Sort by nama loket (extract number and sort: LOKET 1, 2, 3,... 14)
// Sort by nama loket (LOKET 1, 2, ...)
lokets.sort((a, b) => {
const numA = parseInt(a.namaLoket.match(/\d+/)?.[0] || 0);
const numB = parseInt(b.namaLoket.match(/\d+/)?.[0] || 0);
return numA - numB;
});
// Update `no` field to sequential after sort
// Set No sequential
lokets.forEach((loket, idx) => {
loket.no = idx + 1;
loket.source = 'api'; // Mark as API data
});
console.log(`${lokets.length} loket JKN berhasil di-filter dan dimuat dari API`);
console.log('✅ Loket data:', lokets.map(l => ({ id: l.id, namaLoket: l.namaLoket, pembayaran: l.pembayaran })));
// Update API store - TIDAK di-persist
apiLoketData.value = lokets;
lastSyncTimestamp.value = new Date().toISOString();
console.log(`${lokets.length} loket JKN berhasil dimuat dari API`);
return {
success: true,
message: `${lokets.length} loket berhasil dimuat`,
message: `${lokets.length} loket berhasil dipetakan dari klinik`,
data: lokets
};
} catch (error) {
console.error('❌ Error fetching loket:', error);
console.error('❌ Error fetching loket config:', error);
apiError.value = error.message;
return {
success: false,
message: `Gagal memuat data: ${error.message}`
};
return { success: false, message: `Gagal memuat: ${error.message}` };
} finally {
isLoadingAPI.value = false;
activeFetchPromise = null;
console.log('✅ API fetch flow completed');
}
};